Compare commits

...

66 commits
1.1 ... master

Author SHA1 Message Date
Norbi Peti 04053f9b13
Merge pull request #5 from NorbiPeti/directvb
Directly using VirtualBox from Java
2019-04-19 01:29:21 +02:00
Norbi Peti 0a6fa7a9a1
Readme video update 2019-04-19 01:26:59 +02:00
Norbi Peti 3b838199af
Readmeee 2019-04-12 19:20:15 +02:00
Norbi Peti 99e02f8e7b
Fixes
Fixed double event handling after failed start attempt
Added stopEvents() call I kinda forgot to add
Made full rendering a (default) option
2019-04-12 01:25:29 +02:00
Norbi Peti ff4ab589e6
Merge remote-tracking branch 'origin/directvb' into directvb 2019-04-10 22:19:30 +02:00
Norbi Peti f7c72f2f67
Exception handling stuff
Java: 2019.04.07.
PXC: 2019.03.10.
2019-04-10 22:18:01 +02:00
Norbi Peti 18e1981a2a Only sending changed map data 2019-04-10 17:59:36 +02:00
Norbi Peti 3da76f075f Conditional shading 2019-04-08 15:44:44 +02:00
Norbi Peti 6124aba2f3
Merge branch 'master' into directvb 2019-04-06 02:22:59 +02:00
Norbi Peti dd9b850da8
Recreating session, fixes
Compiled and added MSCOM library
2019-04-06 01:25:44 +02:00
Norbi Peti 8fbf044530
Progress error reporting on start fail 2019-04-05 20:03:05 +02:00
Norbi Peti bc88724847 Readme 2019-04-01 15:49:22 +02:00
Norbi Peti d35c2bf4b3
Sender and mouse locker fixes
Sender stuff is a couple days old
2019-03-28 17:34:18 +01:00
Norbi Peti e26489d864
Black screen, event fixes, error detection
Only getting map fields once to speed things up
Rendering black screen on first render, which also helps initialize Aparapi
Disabling event handlers on stop (can't unregister)
Removed and moved unlockMachine() calls from event handlers
Detecting failed machine start
Added note about sudo
2019-03-25 01:55:45 +01:00
Norbi Peti c8ea718787
Fixes, events
- Unlocking machine on power off
- Removed change debug messages
- Fixed missing break in command handling
- Added timing (updates seem to be 1ms max, changes 66ms)
-- Screen rendering for the first time takes long, as expected
- Handling errors such as powering off while getting bitmap
- Added support for any case key names
- Fixed typo for 'period' key
- Fixed state event (probably)
2019-03-22 02:29:39 +01:00
Norbi Peti 5e98afe66a
Created event framework
It uses a similar system to Bukkit's
Hopefully it works
2019-03-21 00:46:54 +01:00
Norbi Peti e75b841d33 Using events instead of polling
Using events for locking, startup progress and stopping
2019-03-20 15:47:27 +01:00
Norbi Peti 2724e123fa Event handling, separate computer class 2019-03-20 13:50:19 +01:00
Norbi Peti 0dad9fdb84 Moved files to packages and Maven structure 2019-03-20 12:35:26 +01:00
Norbi Peti 4aee453274 Added support for selecting machine on start
And also checking if there's already a running machine
And if the given machine is not found
Removed screen updating every 5 seconds, now it only checks if the machine is turned off
Always reassigning the machine
2019-03-18 12:43:24 +01:00
Norbi Peti 794ba3e042
IT WORKS! IT WORKS FAST!
Removed previous DirectRenderer
Fixed map ID for renderers
Moved everything related to the kernel to a new class in hopes of fixing the array being 0 length (apparently it was lambdas)
Storing a reference of the pixels and converted colors at each renderer
Implemented matchColor in a CL-compatible way
Added and removed pixel array length check - it kept overindexing at first, but that got fixed eventually and the check crashed Aparapi in GPU mode
Work of today
2019-03-16 23:28:18 +01:00
Norbi Peti 19b9f1fad6
Initial tests of GPU rendering
Successfully rendered to the map via the GPU (well not really, it falls back to an alternative algorithm)
Dropping the PXCLib - finally realized that the GPU speed massively increases after the first pass
2019-03-11 00:21:31 +01:00
Norbi Peti f029fc22ec
Benchmarking, PXC debugging 2019-03-06 23:41:35 +01:00
Norbi Peti 11de752732 Readme update & testing Aparapi 2019-03-06 13:36:03 +01:00
Norbi Peti 3ad67c9390
Logging everything, error handling attempt
Also a bunch of TODOs
2019-02-26 14:13:32 +01:00
Norbi Peti 865526f4d0
Some fixes
Feb 7
2019-02-19 15:10:23 +01:00
Norbi Peti aa6d7bc236
Better separation of (non-)direct mode 2019-02-07 18:32:50 +01:00
Norbi Peti 9a9b487a98
Cleanup, update, fix
Cleanup: Removed the VBoxJava source code
Update: Updated to VirtualBox 6.0
Fix: Added correct class file to put in the API on updates and (probably) fixed the keyboard
2018-12-21 23:24:13 +01:00
Norbi Peti 1c77835855
Progressing 2018-11-28 21:48:05 +01:00
Norbi Peti 7ed8cfd8d0
Converting from BGRA to RGB 2018-11-27 22:20:38 +01:00
Norbi Peti 0a04568a2b
Main logic almost done
Correct map choosing needs to be done
It should only update the changed areas
2018-11-17 01:04:54 +01:00
Norbi Peti 2ea5c1c4bd
Added functions 2018-11-14 23:54:37 +01:00
Norbi Peti 026edffed4
Java-C connection works
Pointers can be passed freely
2018-11-14 23:00:58 +01:00
Norbi Peti cc7cd15efa
Test lib with makefile
640*480*4 bytes are a lot to process one-by-one
2018-11-14 19:15:58 +01:00
Norbi Peti dea4205a0e
Trying things
I have managed to get some part of the screen in some way, then I tried to make it faster and now it doesn't work
2018-09-22 02:27:58 +02:00
Norbi Peti 2ccf1d976e
WE HAVE A POINTER
Turns out there IS pointer handling in the library, only the wrapper generator isn't prepared for pointers
In the end, all I did was editing the generated source file from byte[] to long[]
2018-09-21 00:43:50 +02:00
Norbi Peti 5dd5546dc1
Add VBoxJXPCOM source
Successfully compiled VirtualBox
2018-07-06 23:27:58 +02:00
Norbi Peti b95109a591
Update README.md 2018-07-06 14:31:33 +02:00
Norbi Peti beff502f0c
Update README.md 2018-07-06 14:30:38 +02:00
Norbi Peti f933d417b7 Testing Windows impl.
DLL location and hardening issues
2018-07-05 18:49:00 +02:00
Norbi Peti 123bce5027
Still no display 2018-06-16 01:55:42 +02:00
Norbi Peti a888795be5 Fiiiiiiixes 2017-12-23 21:04:06 +01:00
Norbi Peti 0af3905f86 Fixes
Off by one error and things like that
2017-12-22 23:49:17 +01:00
Norbi Peti 5d6b705299 FIXED "Not supported" bug in VirtualBox
https://marc.info/?l=vbox-dev&m=142780789819967&w=2
(Must run as sudo currently)
Some other fixes related to rendering
2017-12-21 22:23:23 +01:00
Norbi Peti e16b1cbccf Update, made some progress too
Currently only 'runs' as root, but that doesn't work either
2017-12-19 23:05:41 +01:00
Norbi Peti dfc86e8371 Fixed double start, and some older changes
Fiiinally got VBox working inside a VM spending a day on it. I was/am
tired. Now I have it set up and it's really easy to debug.

No errors, at first start anyways, but the machine only goes Starting
for a very short amount of time then it's off again.
2017-10-15 03:55:16 +02:00
Norbi Peti f031fc0b9a opefully fix(es) and always running mouse task 2017-09-02 22:58:38 +02:00
Norbi Peti 5b9a6c5b4a Fixed /c alias (hopefully)
Updated readme a while ago
Deleted CSharp part a while ago
2017-08-18 00:31:39 +02:00
Norbi Peti cf137b2e0b Fixed lock type... Now it works! Kind of
YEAH
2017-08-08 23:19:32 +02:00
Norbi Peti d94f4b699d Waiting on "spawning" after lock 2017-08-08 15:51:38 +02:00
Norbi Peti 169285a111 Fixes, actually rendering on each update, etc.
Updated version
Removed Movecraft as a soft dependency
AllPixels is set on each change
The direct renderer only renders on change and updates (altough it'd
actually only render once before)
2017-08-04 17:12:23 +02:00
Norbi Peti 042c67a30b Made the machine run in our process, fixes 2017-08-04 14:01:03 +02:00
Norbi Peti 57a6ff818b Delayed query on change, improved code a bit
Removed Movecraft dependency as well
2017-07-18 02:03:18 +02:00
Norbi Peti 3e1691f4e9 Fixes, figuring things out, copied features
Added screen update task and the save state code from CSharp and things
like that.
2017-07-14 02:58:01 +02:00
Norbi Peti 02f3883c12 Partially impl. the frame buffer & deleted SM 2017-06-24 23:38:05 +02:00
Norbi Peti 9ef0b00caa Implemented computer methods, fixes 2017-06-24 19:20:20 +02:00
Norbi Peti 02a3686c30 Mostly done with direct renderer, refactoring 2017-06-24 14:52:23 +02:00
Norbi Peti 57ee4c885d Added Movecraft to Mvn repo 2017-01-11 21:29:28 +01:00
Norbi Peti ed321a0850 Started XPCOM version (#1) 2017-01-11 21:21:52 +01:00
Norbi Peti 8f2690443e (Re)Added JNI4NET... 2016-12-30 01:34:46 +01:00
Norbi Peti 58691f1777 Added POM... 2016-12-30 01:30:21 +01:00
Norbi Peti cf4389cb9e Attempted to use web service 2016-12-30 01:20:47 +01:00
Norbi Peti 4ca3529ee6 Accessing VirtualBox directly (XPCOM) 2016-12-29 23:30:02 +01:00
Norbi Peti c4f12ea063 Update README.md 2016-12-28 21:54:44 +01:00
Norbi Peti 06b785ff4a Converted to Maven project, fixes
- Put all the needed libraries inside the JAR
- Shaded all the dependencies
- Updated VirtualBox interop
- Spent hours fixing bugs for all of the above
2016-12-28 21:45:47 +01:00
Norbi Peti ba257f3cf1 Added gitignore 2016-12-28 18:47:28 +01:00
87 changed files with 3124 additions and 3275 deletions

63
.gitattributes vendored Normal file
View file

@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

715
.gitignore vendored
View file

@ -1,245 +1,470 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.imlasd
libpxc.so
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.imlasd
#################
## Eclipse
#################
*.pydevproject
.metadata/
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
target/
.project
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
*.pubxml
*.publishproj
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#############
## Windows detritus
#############
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac crap
.DS_Store
#############
## Python
#############
*.py[cod]
# Packages
*.egg
*.egg-info
dist/
build/
eggs/
parts/
var/
sdist/
develop-eggs/
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
#Translations
*.mo
#Mr Developer
.mr.developer.cfg
.metadata/*
TheButtonAutoFlair/out/artifacts/Autoflair/Autoflair.jar
*.iml
*.name
.idea/compiler.xml

View file

@ -1,50 +1,50 @@
# The Computer
A working modern computer in Minecraft made using VirtualBox, jni4net, C# and Java. No clientside mods required.
A working modern computer in Minecraft made using VirtualBox and Java. No clientside mods required.
I started working on this project on 2015. december 5. However I did not write much code in that time as I had to figure out how things work.
I plan on making a series where I show the whole process of creating this project.
## Video
##Video
[![Original video](https://img.youtube.com/vi/VxSyDfxPd3s/0.jpg)](https://www.youtube.com/watch?v=VxSyDfxPd3s)
[![Video](https://img.youtube.com/vi/K4t98YUIm4M/0.jpg)](https://www.youtube.com/watch?v=K4t98YUIm4M)
## Installation requirements
*Note: only the server host has to meet these requirements.*
### Currently compiled for (and tested on):
*If you don't meet these requirements, you will need to compile the files for yourself. Please help the community by sending the compiled version to me so more people can download it.*
* A non-Windows OS supported by VirtualBox
* Root (sudo) privileges
* Enough resources to run another OS
* Windows 7 64-bit
* VirtualBox 5
* Spgiot/Bukkit 1.8/1.9 (with Movecraft for the mouse craft type)
* Microsoft .NET Framework 4.5
### Tested versions:
*If you don't meet these requirements, you may need to compile the files for yourself. If you do please send the compiled version to me so more people can download it.*
* OS X; Ubuntu 16.04/18.04
* VirtualBox 6.0
* Spgiot/Bukkit 1.12
* Java 8
### Possibly works with (untested):
* Any version of Windows which supports .NET 4.5
* Other VirtualBox versions (code modifications are probably necessary)
* Other Spigot/Bukkit versions
* Microsoft .NET Framework 4 (code modifications *are* necessary)
* Other Java versions
*The fast rendering method currently only supports 1.12.2.*
*Due to jni4net support limitations the plugin does not support other operating systems.*
### Tested on:
*The requirements vary greatly depending on what OS you want to run ingame but here are my specs that can run Overwatch in Minecraft.*
* CPU: Intel® Pentium(R) CPU G3460 @ 3.50GHz × 2
* RAM: 8 GB
* GPU: NVidia GeForce GTX 650 1 GB
*Due to VirtualBox Java binding support limitations the plugin does not support Windows currently.*
## Installation
**Warning:** The first loaded world on the server (the one specified in server.properties) will **lose** the first 20 maps, though it might be only a temporary effect, it might restore after the server starts up without the plugin. *(Untested.)*
**Warning:** The first loaded world on the server (the one specified in server.properties) will temporarily **lose** the first 20 maps, although it will be back to normal if the server is loaded without the plugin.
* Install all the requirements
* Add a virtual PC if you don't have any (the first one will be started)
* Install VirtualBox
* *Using sudo,* add a virtual PC if you don't have any (the first one will be started by default)
* Install an OS and Guest Additions, if you haven't already
* Put the jar file into <server>/plugins directory
* Put the dll file into <server>/plugins/VirtualComputer directory - if it doesn't exist, create it
* Make sure your server is set to a world that you don't mind your maps deleted from
* Start your server
* *Using sudo,* start your server
## Usage
*Please give appropriate credit and link to this page if you use this machine in one of your videos/creations/etc. You can also send me your video and I may put it here if I like it.*
*Please give appropriate credit and link to this page if you use this machine in one of your videos/creations/etc.*
### Display
*Note:* You can create as many displays as you want, but all of them will show the same.
*Note: You can create as many displays as you want, but all of them will show the same currently.*
To create a display, make a 5 wide 4 high wall of item frames, then put the maps 0-19 on them starting from the top left and going downwards. You can give the maps with this command:
@ -55,22 +55,40 @@ Where you'll need to increment 0 for each map.
It is also recommended to start the virtual machine first so you can distinguish the different parts of the display while placing it.
#### Keyboard
You can either open the chat keyboard using /computer input key, or you can use /computer key \<keyname\>. You can find key names [here](https://github.com/NorbiPeti/VirtualComputer/blob/master/VirtualComputerSender/VirtualKeys.cs). Note that not all keys are currently supported.
You can either open the chat keyboard using /computer input key, or you can use /computer key \<keyname\>. You can find key names [here](https://github.com/NorbiPeti/VirtualComputer/blob/directvb/VirtualComputer/src/sznp/virtualcomputer/Scancode.java).
#### Mouse
You can "lock" the physical mouse to the virtual one with /computer input mouse, or you can move the mouse (including scrolling) with /computer mouse \<dx\> \<dy\> \<dz\> \<dw\>, where dx specifies the amount of pixels to move right, and dy specifies the amount of pixels to move down, while dz and dw specify the scrolling vertically (positive values scroll down) and horizontally.
To set the locked mouse speed, use /computer input mspeed \<integer\>. The difference in look position will be multiplied with this number. Recommended values are between 1 and 10 (inclusive). Default: 1.
You can also use the "mouse" Movecraft craft type to move the mouse, though it's a bit unreliable.
You can press a mouse button with /computer mouse <buttonname>. For example: /computer mouse leftbutton. You can find all the button names [here](https://github.com/NorbiPeti/VirtualComputer/blob/master/VirtualComputerSender/MouseBS.cs).
You can press a mouse button with /computer mouse <buttonname>. For example: /computer mouse leftbutton. Usable key names:
* LeftButton
* RightButton
* MiddleButton
* WheelUp
* WheelDown
* XButton1
* XButton2
#### Sounds
Due to the way it works, it automatically plays every sound from the virtual machine **on the host computer**. This is built into VBoxHeadless, it seems. In order to make the sounds play for every connected player, we'd need a clientside mod.
Due to the way it works, it automatically plays every sound from the virtual machine **on the host computer**. This is built into the VM, it seems. In order to make the sounds play for every connected player, we'd need a clientside mod.
### Special thanks:
* The creators of VirtualBox for making it open-source and easy to use (though I had minor issues but those was because .NET had a few marshaling errors with booleans and that I needed to learn how machines work - especially keyboards)
* The creators of jni4net, after I figured it out, it was quite easy to use
* Minecraft player iie for testing and suggesting the Movecraft mouse and other ideas not related to this project
* The creator(s) of SketchMap, a plugin which I edited to create the display
* The creators of VirtualBox for making it open-source and kind of easy to use (though I had minor issues as the documentation doesn't really tell me how to write a new frontend :P and that I needed to learn how machines work - especially keyboards)
* @iiegit for testing and more testing for the non-Windows version and helping a lot to get it on /r/sequence
# Known issues
## Port remains open (cannot bind to port)
**Fix:** Close all VirtualBox instances and wait 10 seconds.
**Cause:** Possibly it happens because the plugin creates the VBoxSVC process, which thus inherits file descriptors such as the open server port.
## OpenCL error
```
Check your environment. Failed to load codegen native library or possibly failed to locate opencl native library (opencl.dll/opencl.so). Ensure that OpenCL is in your PATH (windows) or in LD_LIBRARY_PATH (linux).
```
**Fix:** On Ubuntu you can install the needed library with `sudo apt install ocl-icd-opencl-dev`

View file

@ -1,10 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="lib" path="D:/Z - Norbi cucca/0 Projektek/TheButtonMCAutoFlairProto/Spigot server (build)/spigot-1.8.7.jar"/>
<classpathentry kind="lib" path="D:/Downloads/jni4net-0.8.8.0-bin/lib/jni4net.j-0.8.8.0.jar"/>
<classpathentry kind="lib" path="D:/Z - Norbi cucca/0 Projektek/TheButtonMCAutoFlairProto/Spigot server/plugins/VirtualComputer/VirtualComputerSender.j4n.jar"/>
<classpathentry kind="lib" path="D:/Z - Norbi cucca/0 Projektek/TheButtonMCAutoFlairProto/Spigot server/plugins/_/Movecraft.jar"/>
<classpathentry kind="output" path="bin"/>
<classpathentry including="**/*.java" kind="src" output="target/classes" path="src">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View file

@ -10,8 +10,14 @@
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -1,295 +1,13 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=next_line
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=next_line
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_block=next_line
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=next_line
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=next_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=next_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=next_line
org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=next_line
org.eclipse.jdt.core.formatter.brace_position_for_switch=next_line
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=next_line
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
org.eclipse.jdt.core.formatter.comment.format_header=false
org.eclipse.jdt.core.formatter.comment.format_html=true
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
org.eclipse.jdt.core.formatter.comment.format_source_code=true
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
org.eclipse.jdt.core.formatter.comment.line_length=80
org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
org.eclipse.jdt.core.formatter.compact_else_if=true
org.eclipse.jdt.core.formatter.continuation_indentation=2
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_empty_lines=false
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
org.eclipse.jdt.core.formatter.indentation.size=4
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.join_lines_in_comments=true
org.eclipse.jdt.core.formatter.join_wrapped_lines=true
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
org.eclipse.jdt.core.formatter.lineSplit=80
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
org.eclipse.jdt.core.formatter.tabulation.char=tab
org.eclipse.jdt.core.formatter.tabulation.size=4
org.eclipse.jdt.core.formatter.use_on_off_tags=false
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter

View file

@ -0,0 +1,5 @@
Compile the Visual Studio project (VirtualComputerSender), put the DLL into the Java project folder (VirtualComputer). Install Movecraft in Maven using
install:install-file -Dfile="<path-to-Movecraft.jar>" -DgroupId=net.countercraft -DartifactId=Movecraft -Dversion=3.0.0 -Dpackaging=jar -DgeneratePom=true
Compile the project using Maven. The compiled JAR should have everything included.

View file

@ -0,0 +1,144 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.github.NorbiPeti</groupId>
<artifactId>VirtualComputer</artifactId>
<version>2.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgs>
<arg>-g</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration />
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>XPCOM</id>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>org.virtualbox:VirtualBox-MSCOM</exclude>
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>MSCOM</id>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>org.virtualbox:VirtualBox</exclude>
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>repo</id>
<url>file://${basedir}/repo</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.12-R0.1-SNAPSHOT</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>commons-lang</artifactId>
<groupId>commons-lang</groupId>
</exclusion>
<exclusion>
<artifactId>json-simple</artifactId>
<groupId>com.googlecode.json-simple</groupId>
</exclusion>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
<exclusion>
<artifactId>gson</artifactId>
<groupId>com.google.code.gson</groupId>
</exclusion>
<exclusion>
<artifactId>snakeyaml</artifactId>
<groupId>org.yaml</groupId>
</exclusion>
<exclusion>
<artifactId>bungeecord-chat</artifactId>
<groupId>net.md-5</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.virtualbox</groupId>
<artifactId>VirtualBox-MSCOM</artifactId>
<version>6.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

Binary file not shown.

View file

@ -0,0 +1,3 @@
If a new version is released, copy this to the JAR into org/mozilla/interfaces
This fixes the source bitmap pointer return type in the Java API.

View file

@ -0,0 +1 @@
lombok.var.flagUsage = ALLOW

View file

@ -1,8 +0,0 @@
name: VirtualComputer
main: sznp.virtualcomputer.PluginMain
version: 1.1
commands:
computer:
usage: Use /computer start|stop
alias: c
softdepend: [Movecraft]

150
VirtualComputer/pom.xml Normal file
View file

@ -0,0 +1,150 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.github.NorbiPeti</groupId>
<artifactId>VirtualComputer</artifactId>
<version>2.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgs>
<arg>-g</arg> <!-- LocalVariableTable -->
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>repo</id>
<url>file://${basedir}/repo</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.12-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.virtualbox</groupId>
<artifactId>VirtualBox</artifactId>
<version>6.0</version>
</dependency>
<dependency>
<groupId>org.virtualbox</groupId>
<artifactId>VirtualBox-MSCOM</artifactId>
<version>6.0</version>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna -->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.jnr/jnr-ffi -->
<dependency>
<groupId>com.github.jnr</groupId>
<artifactId>jnr-ffi</artifactId>
<version>2.1.7</version>
</dependency>
<dependency>
<groupId>com.aparapi</groupId>
<artifactId>aparapi</artifactId>
<version>1.10.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.16</version>
</dependency>
<dependency> <!-- javax.annotations.Nullable -->
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
<profiles>
<profile>
<id>XPCOM</id>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>org.virtualbox:VirtualBox-MSCOM</exclude>
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>MSCOM</id>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>org.virtualbox:VirtualBox</exclude>
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.virtualbox</groupId>
<artifactId>VirtualBox-MSCOM</artifactId>
<version>6.0</version>
<description>POM was created from install:install-file</description>
</project>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>org.virtualbox</groupId>
<artifactId>VirtualBox-MSCOM</artifactId>
<versioning>
<release>6.0</release>
<versions>
<version>6.0</version>
</versions>
<lastUpdated>20190405225845</lastUpdated>
</versioning>
</metadata>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.virtualbox</groupId>
<artifactId>VirtualBox</artifactId>
<version>5.1</version>
<description>POM was created from install:install-file</description>
</project>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.virtualbox</groupId>
<artifactId>VirtualBox</artifactId>
<version>5.2</version>
<description>POM was created from install:install-file</description>
</project>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.virtualbox</groupId>
<artifactId>VirtualBox</artifactId>
<version>6.0</version>
<description>POM was created from install:install-file</description>
</project>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>org.virtualbox</groupId>
<artifactId>VirtualBox</artifactId>
<versioning>
<release>6.0</release>
<versions>
<version>5.1</version>
<version>5.2</version>
<version>6.0</version>
</versions>
<lastUpdated>20181221211412</lastUpdated>
</versioning>
</metadata>

View file

@ -1,217 +0,0 @@
package com.mcplugindev.slipswhitley.sketchmap;
/*
* This file was originally taken from https://github.com/slipswhitley/SketchMap
*/
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import com.mcplugindev.slipswhitley.sketchmap.file.SketchMapFileException;
import com.mcplugindev.slipswhitley.sketchmap.map.RelativeLocation;
import com.mcplugindev.slipswhitley.sketchmap.map.SketchMap;
//import com.mcplugindev.slipswhitley.sketchmap.map.SketchMap.BaseFormat;
public class SketchMapAPI
{
public static SketchMap getMapByID(String id)
{
for (SketchMap map : SketchMap.getLoadedMaps())
{
if (map.getID().equalsIgnoreCase(id))
{
return map;
}
}
return null;
}
public static List<ItemStack> getOrderedItemSet(SketchMap map)
{
List<ItemStack> items = new ArrayList<ItemStack>();
for (int y = 0; y < map.getLengthY(); y++)
{
for (int x = 0; x < map.getLengthX(); x++)
{
for (RelativeLocation loc : map.getMapCollection().keySet())
{
if (loc.getX() != x || loc.getY() != y)
{
continue;
}
ItemStack iStack = new ItemStack(Material.MAP, 1);
iStack.setDurability(SketchMapUtils.getMapID(map
.getMapCollection().get(loc)));
ItemMeta iMeta = iStack.getItemMeta();
iMeta.setDisplayName(ChatColor.GREEN + "SketchMap ID: "
+ ChatColor.GOLD + map.getID() + ChatColor.GREEN
+ " Pos-X: " + ChatColor.GOLD + (x + 1)
+ ChatColor.GREEN + " Pos-Y: " + ChatColor.GOLD
+ (y + 1));
iMeta.setLore(Arrays.asList(new String[] { ChatColor.GRAY
+ "SketchMap ID: " + map.getID()
}));
iStack.setItemMeta(iMeta);
items.add(iStack);
}
}
}
return items;
}
public static SketchMap loadSketchMapFromFile(File file)
throws SketchMapFileException
{
YamlConfiguration config = null;
try
{
config = YamlConfiguration.loadConfiguration(file);
} catch (Exception ex)
{
throw new SketchMapFileException("Invalid SketchMap File \""
+ file.getName() + "\"");
}
String[] fieldSet = { "x-panes", "y-panes", "public-protected",
"map-collection", "base-format", "map-image", };
for (String field : fieldSet)
{
if (!config.isSet(field))
{
throw new SketchMapFileException(
"Unable to load SketchMap file \"" + file.getName()
+ "\" missing field \"" + field + "\"");
}
}
Integer xPanes = config.getInt("x-panes");
if (xPanes == null || xPanes < 1)
{
throw new SketchMapFileException("Unable to load SketchMap file \""
+ file.getName() + "\" invalid field \"x-panes\"");
}
Integer yPanes = config.getInt("y-panes");
if (yPanes == null || yPanes < 1)
{
throw new SketchMapFileException("Unable to load SketchMap file \""
+ file.getName() + "\" invalid field \"y-panes\"");
}
Boolean publicProtected = config.getBoolean("public-protected");
if (publicProtected == null)
{
throw new SketchMapFileException("Unable to load SketchMap file \""
+ file.getName() + "\" invalid field \"public-protected\"");
}
List<String> mapList = config.getStringList("map-collection");
if (mapList == null)
{
throw new SketchMapFileException("Unable to load SketchMap file \""
+ file.getName() + "\" invalid field \"map-collection\"");
}
Map<Short, RelativeLocation> mapCollection = new HashMap<Short, RelativeLocation>();
for (String map : mapList)
{
String[] split = map.split(" ");
if (split.length != 2)
{
throw new SketchMapFileException(
"Unable to load SketchMap file \"" + file.getName()
+ "\" cannot parse field in \"map-colection\"");
}
RelativeLocation loc = RelativeLocation.fromString(split[0]);
if (loc == null)
{
throw new SketchMapFileException(
"Unable to load SketchMap file \"" + file.getName()
+ "\" cannot parse field in \"map-colection\"");
}
Short id = null;
try
{
id = Short.parseShort(split[1]);
} catch (Exception ex)
{
throw new SketchMapFileException(
"Unable to load SketchMap file \"" + file.getName()
+ "\" cannot parse field in \"map-colection\"");
}
mapCollection.put(id, loc);
}
//BaseFormat format = null;
/*
* try {
* format = BaseFormat.valueOf(config.getString("base-format"));
* }
* catch (Exception ex) {
* throw new SketchMapFileException("Unable to load SketchMap file \"" +
* file.getName()
* + "\" cannot parse BaseFormat from field \"base-format\"");
* }
*/
String b64Img = config.getString("map-image");
if (b64Img == null)
{
throw new SketchMapFileException("Unable to load SketchMap file \""
+ file.getName() + "\" invalid field \"map-image\"");
}
BufferedImage image = null;
try
{
image = SketchMapUtils.base64StringToImg(b64Img);
} catch (Exception ex)
{
throw new SketchMapFileException("Unable to load SketchMap file \""
+ file.getName()
+ "\" parse image from field \"map-image\"");
}
String imageID = file.getName().substring(0,
file.getName().lastIndexOf("."));
if (getMapByID(imageID) != null)
{
throw new SketchMapFileException("Unable to load SketchMap file \""
+ file.getName()
+ "\" A SketchMap by that ID already exists.");
}
return new SketchMap(image, imageID, yPanes, yPanes, publicProtected);
}
}

View file

@ -1,54 +0,0 @@
package com.mcplugindev.slipswhitley.sketchmap;
/*
* This file was originally taken from https://github.com/slipswhitley/SketchMap
*/
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.plugin.java.JavaPlugin;
import com.mcplugindev.slipswhitley.sketchmap.listener.PlayerListener;
public class SketchMapPlugin extends JavaPlugin
{
private static SketchMapPlugin plugin;
public void onEnable()
{
plugin = this;
setupListeners();
sendEnabledMessage();
}
private void sendEnabledMessage()
{
SketchMapUtils.sendColoredConsoleMessage(ChatColor.GREEN
+ "| |");
SketchMapUtils.sendColoredConsoleMessage(ChatColor.GREEN + "| "
+ ChatColor.AQUA + "SketchMap "
+ this.getDescription().getVersion() + " has been Enabled!"
+ ChatColor.GREEN + " |");
SketchMapUtils.sendColoredConsoleMessage(ChatColor.GREEN + "| "
+ ChatColor.AQUA + " Authors: SlipsWhitley & Fyrinlight"
+ ChatColor.GREEN + " |");
SketchMapUtils.sendColoredConsoleMessage(ChatColor.GREEN
+ "| |");
}
private void setupListeners()
{
Bukkit.getPluginManager().registerEvents(new PlayerListener(), this);
}
public static SketchMapPlugin getPlugin()
{
return plugin;
}
}

View file

@ -1,109 +0,0 @@
package com.mcplugindev.slipswhitley.sketchmap;
/*
* This file was originally taken from https://github.com/slipswhitley/SketchMap
*/
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Base64;
import java.util.HashSet;
import javax.imageio.ImageIO;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.bukkit.map.MapView;
public class SketchMapUtils
{
/**
*
* Image Utils
*
*/
public static BufferedImage resize(Image img, Integer width, Integer height)
{
img = img.getScaledInstance(width, height, Image.SCALE_SMOOTH);
if (img instanceof BufferedImage)
{
return (BufferedImage) img;
}
BufferedImage bimage = new BufferedImage(img.getWidth(null),
img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D bGr = bimage.createGraphics();
bGr.drawImage(img, 0, 0, null);
bGr.dispose();
return bimage;
}
public static BufferedImage base64StringToImg(final String base64String)
{
try
{
return ImageIO.read(new ByteArrayInputStream(Base64.getDecoder()
.decode(base64String)));
} catch (final IOException ioe)
{
throw new UncheckedIOException(ioe);
}
}
public static void sendColoredConsoleMessage(String msg)
{
ConsoleCommandSender sender = Bukkit.getConsoleSender();
sender.sendMessage(msg);
}
/**
* Deprecated Methods Here :'c
*/
@SuppressWarnings("deprecation")
public static short getMapID(MapView map)
{
return map.getId();
}
@SuppressWarnings("deprecation")
public static MapView getMapView(short id)
{
MapView map = Bukkit.getMap(id);
if (map != null)
{
return map;
}
return Bukkit.createMap(getDefaultWorld());
}
/**
*
*/
public static Block getTargetBlock(Player player, int i)
{
return player.getTargetBlock((HashSet<Material>) null, i);
}
public static World getDefaultWorld()
{
return Bukkit.getWorlds().get(0);
}
}

View file

@ -1,14 +0,0 @@
package com.mcplugindev.slipswhitley.sketchmap.file;
public class SketchMapFileException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
public SketchMapFileException(String message) {
super(message);
}
}

View file

@ -1,69 +0,0 @@
package com.mcplugindev.slipswhitley.sketchmap.listener;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
public class PlayerListener implements Listener {
@EventHandler
public void onPlayerInteract(PlayerInteractEntityEvent event) {
if(!(event.getRightClicked() instanceof ItemFrame)) {
return;
}
ItemFrame iFrame = (ItemFrame) event.getRightClicked();
ItemStack iHand = event.getPlayer().getItemInHand();
if(iHand.getType() != Material.MAP) {
return;
}
String lore = iHand.getItemMeta().getLore().get(0);
if(!ChatColor.stripColor(lore).startsWith("SketchMap ID:")) {
return;
}
if(iFrame.getItem().getType() != Material.AIR) {
return;
}
if(event.isCancelled()) {
return;
}
event.setCancelled(true);
ItemStack frameItem = iHand.clone();
frameItem.setAmount(1);
ItemMeta frameIMeta = frameItem.getItemMeta();
frameIMeta.setDisplayName("");
frameItem.setItemMeta(frameIMeta);
iFrame.setItem(frameItem);
Player player = event.getPlayer();
if(player.getGameMode() == GameMode.CREATIVE) {
return;
}
if(iHand.getAmount() == 1) {
player.getInventory().setItemInHand(new ItemStack(Material.AIR));
return;
}
iHand.setAmount(iHand.getAmount() - 1);
}
}

View file

@ -1,53 +0,0 @@
package com.mcplugindev.slipswhitley.sketchmap.map;
import java.awt.image.BufferedImage;
import java.util.concurrent.TimeUnit;
import org.bukkit.entity.Player;
import org.bukkit.map.MapCanvas;
import org.bukkit.map.MapRenderer;
import org.bukkit.map.MapView;
public class ImageRenderer extends MapRenderer
{
private BufferedImage image;
public ImageRenderer(BufferedImage image)
{
this.image = image;
}
private int progress = 0;
public static int updatepixels = 15;
@Override
public void render(MapView view, MapCanvas canvas, Player player)
{
long time = System.nanoTime();
try
{
canvas.drawImage(0, progress * updatepixels, image.getSubimage(0,
progress * updatepixels, 128, (progress * updatepixels
+ updatepixels >= 128 ? 128 - progress
* updatepixels : updatepixels)));
if (progress < 128 / updatepixels)
progress++;
else
progress = 0;
long diff = System.nanoTime() - time;
if (TimeUnit.NANOSECONDS.toMillis(diff) > 40)
{
System.out.println("Map rendering took "
+ TimeUnit.NANOSECONDS.toMillis(diff) + " ms");
}
} catch (Exception e)
{
e.printStackTrace();
System.out.println("Progess: " + progress);
System.out.println("UpdatePixels: " + updatepixels);
}
}
}

View file

@ -1,53 +0,0 @@
package com.mcplugindev.slipswhitley.sketchmap.map;
public class RelativeLocation {
private int x;
private int y;
public RelativeLocation (int x, int y) {
this.x = x;
this.y = y;
}
public String toString() {
return x + ":" + y;
}
public static RelativeLocation fromString(String str) {
String[] args = str.split(":");
if(args.length != 2) {
return null;
}
int x = 0;
int y = 0;
try {
x = Integer.parseInt(args[0]);
y = Integer.parseInt(args[1]);
}
catch (Exception ex) {
return null;
}
return new RelativeLocation (x, y);
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}

View file

@ -1,220 +0,0 @@
package com.mcplugindev.slipswhitley.sketchmap.map;
/*
* This file was originally taken from https://github.com/slipswhitley/SketchMap
*/
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.map.MapView;
import com.mcplugindev.slipswhitley.sketchmap.SketchMapUtils;
public class SketchMap
{
public BufferedImage image;
private String mapID;
private Integer xPanes;
private Integer yPanes;
private Boolean publicProtected;
//private BaseFormat format;
private Map<RelativeLocation, MapView> mapCollection;
/**
*
* Create SketchMap using New Maps
*
*/
public SketchMap(BufferedImage image, String mapID, int xPanes, int yPanes,
boolean publicProtected)
{
this.image = SketchMapUtils.resize(image, xPanes * 128, yPanes * 128);
this.mapID = mapID;
this.xPanes = xPanes;
this.yPanes = yPanes;
this.publicProtected = publicProtected;
//this.format = format;
this.mapCollection = new HashMap<RelativeLocation, MapView>();
getLoadedMaps().add(this);
loadSketchMap();
}
private void loadSketchMap()
{
for (int x = 0; x < xPanes; x++)
{
for (int y = 0; y < yPanes; y++)
{
initMap(x, y,
Bukkit.createMap(SketchMapUtils.getDefaultWorld()));
}
}
}
/**
*
* Create SketchMap using Specified Maps
*
*/
public SketchMap(BufferedImage image, String mapID, int xPanes, int yPanes,
boolean publicProtected, Map<Short, RelativeLocation> mapCollection)
{
this.image = SketchMapUtils.resize(image, xPanes * 128, yPanes * 128);
this.mapID = mapID;
this.xPanes = xPanes;
this.yPanes = yPanes;
this.publicProtected = publicProtected;
//this.format = format;
this.mapCollection = new HashMap<RelativeLocation, MapView>();
getLoadedMaps().add(this);
loadSketchMap(mapCollection);
}
private void loadSketchMap(Map<Short, RelativeLocation> mapCollection)
{
for (Short mapID : mapCollection.keySet())
{
RelativeLocation loc = mapCollection.get(mapID);
initMap(loc.getX(), loc.getY(), SketchMapUtils.getMapView(mapID));
}
}
/**
*
*
*
*/
private void initMap(int x, int y, MapView mapView)
{
BufferedImage subImage = image.getSubimage(x * 128, y * 128, 128, 128);
mapView.getRenderers().clear();
mapView.addRenderer(new ImageRenderer(subImage));
mapCollection.put(new RelativeLocation(x, y), mapView);
}
/**
*
* Get Object information
*
*/
public String getID()
{
return mapID;
}
public BufferedImage getImage()
{
return image;
}
public int getLengthX()
{
return xPanes;
}
public int getLengthY()
{
return yPanes;
}
public boolean isPublicProtected()
{
return publicProtected;
}
public Map<RelativeLocation, MapView> getMapCollection()
{
return mapCollection;
}
/*
* public BaseFormat getBaseFormat() {
* return format;
* }
*/
/**
*
* Map Functions
*
*
*/
public void delete()
{
getLoadedMaps().remove(this);
try
{
this.finalize();
} catch (Throwable e)
{
}
}
/**
*
* Static Methods
*
*/
private static Set<SketchMap> sketchMaps;
public static Set<SketchMap> getLoadedMaps()
{
if (sketchMaps == null)
{
sketchMaps = new HashSet<SketchMap>();
}
return sketchMaps;
}
/*
* public enum BaseFormat {
* PNG,
* JPEG;
*
* public String getExtension() {
* if(this == BaseFormat.PNG) {
* return "png";
* }
* if(this == BaseFormat.JPEG) {
* return "jpg";
* }
* return null;
* }
*
* public static BaseFormat fromExtension(String ext) {
* if(ext.equalsIgnoreCase("png")) {
* return BaseFormat.PNG;
*
* }
* if(ext.equalsIgnoreCase("jpg")) {
* return BaseFormat.JPEG;
* }
* return null;
* }
* }
*/
}

View file

@ -0,0 +1,162 @@
package sznp.virtualcomputer;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.virtualbox_6_0.VBoxException;
public class Commands implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (args.length == 0)
return false;
switch (args[0].toLowerCase()) {
case "start":
case "poweron":
case "on":
case "startup":
int c = getMachineIndex(args);
if (c == -1) {
sender.sendMessage("§cUsage: /" + label + " start [index]");
return true;
}
Computer.getInstance().Start(sender, c);
break;
case "stop":
case "poweroff":
case "off":
case "shutdown":
case "kill":
Computer.getInstance().Stop(sender);
break;
case "powerbutton":
case "pwrbtn":
case "powerbtn":
c = getMachineIndex(args);
if (c == -1) {
sender.sendMessage("§cUsage: /" + label + " powerbutton [index]");
return true;
}
Computer.getInstance().PowerButton(sender, c);
break;
case "reset":
case "restart":
Computer.getInstance().Reset(sender);
break;
case "fix":
case "fixscreen":
Computer.getInstance().FixScreen(sender);
break;
case "key":
case "press":
case "presskey":
case "keypress":
if (args.length < 2) {
sender.sendMessage("§cUsage: /computer key <key> [down/up|duration(ticks)]");
return true;
}
if (args.length < 3)
Computer.getInstance().PressKey(sender, args[1], "");
else
Computer.getInstance().PressKey(sender, args[1], args[2]);
break;
case "mouse":
boolean showusage = true;
if (args.length < 6) {
try {
// Command overloading, because I can :P
if (args.length > 4) // 4<x<6
{
Computer.getInstance().UpdateMouse(sender, Integer.parseInt(args[1]), Integer.parseInt(args[2]),
Integer.parseInt(args[3]), Integer.parseInt(args[4]), "", false);
showusage = false;
} else {
if (args.length == 3) {
Computer.getInstance().UpdateMouse(sender, 0, 0, 0, 0, args[1], args[2].equals("down"));
showusage = false;
} else if (args.length == 2) {
Computer.getInstance().UpdateMouse(sender, 0, 0, 0, 0, args[1]);
showusage = false;
}
}
}
catch (VBoxException e) {
e.printStackTrace();
}
catch (Exception ignored) { //It will show the usage here
}
}
if (showusage) {
sender.sendMessage("§cUsage: /computer mouse <relx> <rely> <relz> <relw>");
sender.sendMessage("§cOr: /computer mouse <button> [up/down]");
}
break;
case "input":
case "show":
case "showinput":
case "shinput": {
if (!(sender instanceof Player)) {
sender.sendMessage("§cError: Only players can use this command.");
return true;
}
if (args.length < 2) {
sender.sendMessage("§cUsage: /computer input <key|mouse>");
return true;
}
switch (args[1].toLowerCase()) {
case "key":
case "keyboard":
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender.getName()
+ " [\"\",{\"text\":\" [0]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D0\"}},{\"text\":\" [1]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D1\"}},{\"text\":\" [2]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D2\"}},{\"text\":\" [3]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D3\"}},{\"text\":\" [4]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D4\"}},{\"text\":\" [5]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D5\"}},{\"text\":\" [6]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D6\"}},{\"text\":\" [7]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D7\"}},{\"text\":\" [8]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D8\"}},{\"text\":\" [9]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D9\"}}]");
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender.getName()
+ " [\"\",{\"text\":\" [Tab]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key Tab\"}},{\"text\":\" [Q]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key Q\"}},{\"text\":\" [W]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key W\"}},{\"text\":\" [E]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key E\"}},{\"text\":\" [R]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key R\"}},{\"text\":\" [T]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key T\"}},{\"text\":\" [Y]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key Y\"}},{\"text\":\" [U]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key U\"}},{\"text\":\" [I]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key I\"}},{\"text\":\" [O]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key O\"}},{\"text\":\" [P]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key P\"}}]");
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender.getName()
+ " [\"\",{\"text\":\" [CapsLock]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key CapsLock\"}},{\"text\":\" [A]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key A\"}},{\"text\":\" [S]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key S\"}},{\"text\":\" [D]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D\"}},{\"text\":\" [F]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key F\"}},{\"text\":\" [G]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key G\"}},{\"text\":\" [H]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key H\"}},{\"text\":\" [J]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key J\"}},{\"text\":\" [K]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key K\"}},{\"text\":\" [L]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key L\"}},{\"text\":\" [Enter]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key Enter\"}}]");
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender.getName()
+ " [\"\",{\"text\":\" [Z]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key Z\"}},{\"text\":\" [X]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key X\"}},{\"text\":\" [C]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key C\"}},{\"text\":\" [V]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key V\"}},{\"text\":\" [B]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key B\"}},{\"text\":\" [N]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key N\"}},{\"text\":\" [M]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key M\"}}]");
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender.getName()
+ " [\"\",{\"text\":\" [Ctrl]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key ControlLeft\"}},{\"text\":\" [Alt]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key AltLeft\"}},{\"text\":\" [Space]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key Space\"}},{\"text\":\" [AltGr]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key AltRight\"}},{\"text\":\" [Ctrl]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key ControlRight\"}}]");
break;
case "mouse":
MouseLockerPlayerListener.toggleLock((Player) sender);
break;
case "mspeed":
case "mousespeed":
if (args.length < 3) {
sender.sendMessage("§cUsage: /computer input mspeed <number>");
return true;
}
try {
MouseLockerPlayerListener.LockedSpeed = Float.parseFloat(args[2]);
} catch(NumberFormatException e) {
sender.sendMessage("§cThe speed must be a number.");
break;
}
sender.sendMessage("§aMouse speed set to " + MouseLockerPlayerListener.LockedSpeed);
}
break;
}
}
return true;
}
/**
* Checks the 2nd parameter
*
* @return The index of the machine or -1 on usage error
*/
private int getMachineIndex(String[] args) {
int c = 0;
if (args.length >= 2) {
try {
c = Integer.parseInt(args[1]);
} catch (Exception ignored) {
return -1;
}
}
return c;
}
}

View file

@ -0,0 +1,235 @@
package sznp.virtualcomputer;
import com.google.common.collect.Lists;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.virtualbox_6_0.*;
import sznp.virtualcomputer.events.MachineEventHandler;
import sznp.virtualcomputer.events.VBoxEventHandler;
import sznp.virtualcomputer.renderer.GPURenderer;
import sznp.virtualcomputer.renderer.MCFrameBuffer;
import sznp.virtualcomputer.util.Scancode;
import javax.annotation.Nullable;
import java.util.Arrays;
public final class Computer {
@Getter
private static Computer instance;
private final PluginMain plugin;
private ISession session;
private IVirtualBox vbox;
private IMachine machine;
private MachineEventHandler handler;
private IEventListener listener;
private VirtualBoxManager manager;
@java.beans.ConstructorProperties({"plugin"})
public Computer(PluginMain plugin, VirtualBoxManager manager, IVirtualBox vbox) {
this.plugin = plugin;
this.manager = manager;
session = manager.getSessionObject();
this.vbox = vbox;
if (instance != null) throw new IllegalStateException("A computer already exists!");
instance = this;
}
public void Start(CommandSender sender, int index) {// TODO: Add touchscreen support (#2)
if (session.getState() == SessionState.Locked) {
sender.sendMessage("§cThe machine is already running!");
return;
}
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
if (vbox.getMachines().size() <= index) {
sendMessage(sender, "§cMachine not found!");
return;
}
try {
sendMessage(sender, "§eStarting computer...");
machine = vbox.getMachines().get(index);
session.setName("minecraft");
// machine.launchVMProcess(session, "headless", "").waitForCompletion(10000); - This creates a *process*, we don't want that anymore
machine.lockMachine(session, LockType.VM); // We want the machine inside *our* process <-- Need the VM type to have console access
VBoxEventHandler.getInstance().setup(machine.getId(), sender); //TODO: Sometimes null
} catch (VBoxException e) {
if (e.getResultCode() == 0x80070005) { //lockMachine: "The object functionality is limited"
sendMessage(sender, "§6Cannot start computer, the machine may be inaccessible");
sendMessage(sender, "§6Make sure that the server is running as root (sudo)");
//TODO: If we have VirtualBox open, it won't close the server's port
//TODO: "The object in question already exists." on second start
//machine.launchVMProcess(session, "headless", "").waitForCompletion(10000); //No privileges, start the 'old' way
//session.getConsole().getDisplay().attachFramebuffer(0L, new IFramebuffer(new MCFrameBuffer(session.getConsole().getDisplay(), false)));
//sendMessage(sender, "§6Computer started with slower screen. Run as root to use a faster method.");
} else {
sendMessage(sender, "§cFailed to start computer: " + e.getMessage());
}
}
});
}
/**
* Gets called when the machine is locked after {@link #Start(CommandSender, int)}
*
* @param sender The sender which started the machine
*/
public void onLock(CommandSender sender) {
machine = session.getMachine(); // This is the Machine object we can work with
final IConsole console = session.getConsole();
if (handler != null)
handler.disable();
handler = new MachineEventHandler(Computer.this, sender);
listener = handler.registerTo(console.getEventSource());
IProgress progress = console.powerUp(); // https://marc.info/?l=vbox-dev&m=142780789819967&w=2
handler.setProgress(progress);
handler.registerTo(progress.getEventSource()); //TODO: Show progress bar some way?
console.getDisplay().attachFramebuffer(0L,
new IFramebuffer(new MCFrameBuffer(console.getDisplay(), true)));
}
private void sendMessage(@Nullable CommandSender sender, String message) {
if (sender != null)
sender.sendMessage(message);
plugin.getLogger().warning((sender == null ? "" : sender.getName() + ": ") + ChatColor.stripColor(message));
}
public void Stop(CommandSender sender) {
if (checkMachineNotRunning(sender)) {
if (session.getState().equals(SessionState.Locked)) {
onMachineStop(sender); //Needed for session reset
sendMessage(sender, "§eComputer was already off, released it.");
}
return;
}
sendMessage(sender, "§eStopping computer...");
session.getConsole().powerDown();
}
public void PowerButton(CommandSender sender, int index) {
sendMessage(sender, "§ePressing powerbutton...");
Bukkit.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override
public void run() {
if (session.getState() != SessionState.Locked || session.getMachine() == null) {
Start(sender, index);
} else {
session.getConsole().powerButton();
sendMessage(sender, "§ePowerbutton pressed.");
}
}
});
}
public void Reset(CommandSender sender) {
if (checkMachineNotRunning(sender))
return;
sendMessage(sender, "§eResetting computer...");
session.getConsole().reset();
sendMessage(sender, "§eComputer reset.");
}
public void FixScreen(CommandSender sender) {
if (checkMachineNotRunning(sender))
return;
sendMessage(sender, "§eFixing screen...");
session.getConsole().getDisplay().setSeamlessMode(false);
session.getConsole().getDisplay().setVideoModeHint(0L, true, false, 0, 0, 640L, 480L, 32L);
sendMessage(sender, "§eScreen fixed.");
}
public boolean checkMachineNotRunning(@Nullable CommandSender sender) {
if (session.getState() != SessionState.Locked || machine.getState() != MachineState.Running) {
if (sender != null)
sender.sendMessage("§cMachine isn't running.");
return true;
}
return false;
}
public void PressKey(CommandSender sender, String key, String stateorduration) {
if (checkMachineNotRunning(sender))
return;
int durationorstate;
if (stateorduration.length() == 0)
durationorstate = 0;
else if (stateorduration.equalsIgnoreCase("down"))
durationorstate = -1;
else if (stateorduration.equalsIgnoreCase("up"))
durationorstate = -2;
else
durationorstate = Short.parseShort(stateorduration);
int code = Scancode.getCode("sc_" + key.toLowerCase());
if (code == -1) {
sender.sendMessage("§cUnknown key: " + key);
return;
}
// Release key scan code concept taken from VirtualBox source code (KeyboardImpl.cpp:putCAD())
// +128
if (durationorstate != -2)
session.getConsole().getKeyboard().putScancode(code);
Runnable sendrelease = () -> session.getConsole().getKeyboard().putScancodes(Lists.newArrayList(code + 128,
Scancode.sc_controlLeft.Code + 128, Scancode.sc_shiftLeft.Code + 128, Scancode.sc_altLeft.Code + 128));
if (durationorstate == 0 || durationorstate == -2)
sendrelease.run();
if (durationorstate > 0) {
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, sendrelease, durationorstate);
}
}
public void UpdateMouse(CommandSender sender, int x, int y, int z, int w, String mbs, boolean down) throws Exception {
if (checkMachineNotRunning(sender))
return;
int state = 0;
if (mbs.length() > 0 && down)
state = Arrays.stream(MouseButtonState.values()).filter(mousebs -> mousebs.name().equalsIgnoreCase(mbs))
.findAny().orElseThrow(() -> new Exception("Unknown mouse button")).value();
session.getConsole().getMouse().putMouseEvent(x, y, z, w, state);
}
public void UpdateMouse(CommandSender sender, int x, int y, int z, int w, String mbs) throws Exception {
if (checkMachineNotRunning(sender))
return;
UpdateMouse(sender, x, y, z, w, mbs, true);
UpdateMouse(sender, x, y, z, w, mbs, false);
}
public void onMachineStart(CommandSender sender) {
sendMessage(sender, "§eComputer started.");
}
public void onMachineStop(CommandSender sender) {
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
if (session.getState() == SessionState.Locked) {
session.unlockMachine(); //Needs to be outside of the event handler
handler = null;
machine = null;
session = manager.getSessionObject();
sendMessage(sender, "§eComputer powered off."); //This block runs later
}
});
GPURenderer.update(new byte[1], 0, 0, 0, 0, 640, 480); //Black screen
stopEvents();
MouseLockerPlayerListener.computerStop();
}
public void stopEvents() {
/*if(session!=null && listener!=null)
session.getConsole().getEventSource().unregisterListener(listener);*/
if (listener != null)
handler.disable();
listener = null;
}
public void pluginDisable(CommandSender ccs) {
stopEvents();
if (session.getState() == SessionState.Locked) {
if (session.getMachine().getState().equals(MachineState.Running)) {
ccs.sendMessage("§aSaving machine state...");
session.getMachine().saveState().waitForCompletion(10000);
}
session.unlockMachine();
}
}
}

View file

@ -0,0 +1,57 @@
package sznp.virtualcomputer;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class MouseLockerPlayerListener implements Runnable, Listener {
private static final Map<Player, Location> LockedPlayers = new HashMap<>();
public static float LockedSpeed = 5;
@Override
public void run() {
for (Entry<Player, Location> entry : LockedPlayers.entrySet()) {
float yaw1 = entry.getValue().getYaw();
float pitch1 = entry.getValue().getPitch();
float yaw2 = entry.getKey().getLocation().getYaw();
float pitch2 = entry.getKey().getLocation().getPitch();
if (yaw2 - yaw1 == 0 || pitch2 - pitch1 == 0)
return;
try {
Computer.getInstance().UpdateMouse(null, (int) ((yaw2 - yaw1) * LockedSpeed),
(int) ((pitch2 - pitch1) * LockedSpeed), 0, 0, "");
} catch (Exception e) { //Should not happen
e.printStackTrace();
}
entry.getKey().teleport(entry.getValue(), TeleportCause.PLUGIN);
}
}
@EventHandler
public void onPlayerLeave(PlayerQuitEvent event) {
LockedPlayers.remove(event.getPlayer());
}
public static void toggleLock(Player player) {
if (!MouseLockerPlayerListener.LockedPlayers.containsKey(player)) {
MouseLockerPlayerListener.LockedPlayers.put(player, player.getLocation());
player.sendMessage("§aMouse locked.");
} else {
MouseLockerPlayerListener.LockedPlayers.remove(player);
player.sendMessage("§bMouse unlocked.");
}
}
public static void computerStop() {
LockedPlayers.clear();
}
}

View file

@ -0,0 +1,129 @@
package sznp.virtualcomputer;
import jnr.ffi.LibraryLoader;
import lombok.val;
import org.bukkit.Bukkit;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask;
import org.virtualbox_6_0.IEventListener;
import org.virtualbox_6_0.IVirtualBox;
import org.virtualbox_6_0.VirtualBoxManager;
import sznp.virtualcomputer.events.VBoxEventHandler;
import sznp.virtualcomputer.renderer.BukkitRenderer;
import sznp.virtualcomputer.renderer.GPURenderer;
import sznp.virtualcomputer.renderer.IRenderer;
import sznp.virtualcomputer.util.Utils;
import sznp.virtualcomputer.util.VBoxLib;
import java.io.File;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.function.Predicate;
public class PluginMain extends JavaPlugin {
private static final int MCX = 5;
private static final int MCY = 4;
private BukkitTask mousetask;
private IEventListener listener;
public static PluginMain Instance;
//public static ByteBuffer allpixels = ByteBuffer.allocate(640 * 480 * 4); // It's set on each change
/**
* Only used if {@link #direct} is false.
*/
public static ByteBuffer allpixels; // It's set on each change
private static ArrayList<IRenderer> renderers = new ArrayList<>();
/*
* Only used if {@link #direct} is true.
*/
//public static PXCLib pxc;
public static boolean direct;
public static boolean sendAll;
// Fired when plugin is first enabled
@Override
public void onEnable() {
Instance = this;
try {
ConsoleCommandSender ccs = getServer().getConsoleSender();
this.getCommand("computer").setExecutor(new Commands());
sendAll = getConfig().getBoolean("sendAll", true);
ccs.sendMessage("§bInitializing VirtualBox...");
String vbpath = System.getProperty("os.name").toLowerCase().contains("mac")
? "/Applications/VirtualBox.app/Contents/MacOS"
: "/opt/virtualbox";
//noinspection ConstantConditions
Predicate<File> notGoodDir= ff->!ff.isDirectory() || Arrays.stream(ff.list()).noneMatch(s -> s.contains("xpcom"));
if (notGoodDir.test(new File(vbpath)))
vbpath = "/usr/lib/virtualbox";
if(notGoodDir.test(new File(vbpath)))
error("Could not find VirtualBox! Download from https://www.virtualbox.org/wiki/Downloads");
if (System.getProperty("vbox.home") == null || System.getProperty("vbox.home").isEmpty())
System.setProperty("vbox.home", vbpath);
if (System.getProperty("sun.boot.library.path") == null
|| System.getProperty("sun.boot.library.path").isEmpty())
System.setProperty("sun.boot.library.path", vbpath);
if (System.getProperty("java.library.path") == null || System.getProperty("java.library.path").isEmpty())
System.setProperty("java.library.path", vbpath);
Utils.addLibraryPath(vbpath);
final VirtualBoxManager manager = VirtualBoxManager.createInstance(getDataFolder().getAbsolutePath());
VBoxLib vbl = LibraryLoader.create(VBoxLib.class).load("vboxjxpcom"); //TODO: Test for MSCOM
vbl.RTR3InitExe(0, "", 0);
IVirtualBox vbox = manager.getVBox();
listener = new VBoxEventHandler().registerTo(vbox.getEventSource());
new Computer(this, manager, vbox); //Saves itself
ccs.sendMessage("§bLoading Screen...");
try {
//throw new NoClassDefFoundError("Test error pls ignore");
for (short i = 0; i < MCX; i++)
for (short j = 0; j < MCY; j++)
renderers.add(new GPURenderer((short) (j * 5 + i), Bukkit.getWorlds().get(0), i, j));
//pxc = LibraryLoader.create(PXCLib.class).search(getDataFolder().getAbsolutePath()).load("pxc");
direct=true;
ccs.sendMessage("§bUsing Direct Renderer, all good");
} catch (NoClassDefFoundError | Exception e) {
for (short i = 0; i < 20; i++)
renderers.add(new BukkitRenderer(i, Bukkit.getWorlds().get(0), i * 128 * 128 * 4));
direct=false;
e.printStackTrace();
ccs.sendMessage("§6Compatibility error, using slower renderer");
}
ccs.sendMessage("§bLoaded!");
val mlpl = new MouseLockerPlayerListener();
mousetask = getServer().getScheduler().runTaskTimer(this, mlpl, 0, 0);
getServer().getPluginManager().registerEvents(mlpl, this);
} catch (final Exception e) {
e.printStackTrace();
error(e.getMessage());
}
}
private void error(String message) {
getLogger().severe("A fatal error occured, disabling plugin!");
Bukkit.getPluginManager().disablePlugin(this);
throw new RuntimeException(message);
}
// Fired when plugin is disabled
@Override
public void onDisable() {
ConsoleCommandSender ccs = getServer().getConsoleSender();
if (mousetask != null)
mousetask.cancel();
/*try {
source.unregisterListener(listener);
} catch (VBoxException e) { //"Listener was never registered"
e.printStackTrace(); - VBox claims the listener was never registered (can double register as well)
}*/
if (listener != null)
((VBoxEventHandler) listener.getTypedWrapped()).disable(); //The save progress wait locks with the event
if (Computer.getInstance() != null)
Computer.getInstance().pluginDisable(ccs);
ccs.sendMessage("§aHuh.");
saveConfig();
}
}

View file

@ -0,0 +1,107 @@
package sznp.virtualcomputer;
import com.aparapi.Kernel;
import com.aparapi.Range;
import com.sun.jna.Pointer;
import jnr.ffi.LibraryLoader;
import org.bukkit.Color;
import org.bukkit.map.MapPalette;
import sznp.virtualcomputer.util.PXCLib;
import java.io.File;
import java.lang.reflect.Field;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.stream.IntStream;
public class Test {
private int[] x = new int[]{10};
@SuppressWarnings("deprecation")
public static void main(String[] args) {
/*System.out.println(new File("").getAbsolutePath());
PXCLib pxc = LibraryLoader.create(PXCLib.class).search(new File("").getAbsolutePath()).load("pxc");
ByteBuffer bb = ByteBuffer.allocateDirect(2);
long[] x = new long[]{Pointer.nativeValue(Native.getDirectBufferPointer(bb))};
pxc.convert(new int[]{5, 10}, x);
System.out.println(bb.get(0)); //19 AYY //TO!DO: Use setSource, we don't want to wrap the native array*/
//final int[] a={5,6,8,2,3,10,5,26,5,416,41,85,416,41};
//final int[] b={10,80,10,3,32,20,56,85,51,968,156,5894,10,60,52};
//final int[] a={5,6};
//final int[] b={10,80};
int[] a = IntStream.range(0, 640 * 480).toArray();
final int[] res = new int[a.length];
//java.awt.Color tc=new java.awt.Color(0);
/*GPURenderer gr;
try {
gr=new GPURenderer((short) 0, null, 0, 0);
} catch (Exception e) {
e.printStackTrace();
return;
}*/
//gr.pixels=new byte[1];
int[] x = new Test().x;
Kernel kernel=new Kernel() {
@Override
public void run() {
int i=getGlobalId();
//System.out.println(i);
//res[i]=a[i]+b[i];
//res[i]= MapPalette.matchColor(a[i] & 0x0000FF, a[i] & 0x00FF00 >> 8, a[i] & 0xFF0000 >> 16);
//res[i] = a[i];
//res[i]=tc.getBlue();
//gr.pixels[0]=5;
res[i] = x[0];
//GPURenderer.px[0]=10;
//GPURendererInternal.test[0]=10; - LAMBDAS
}
};
long t = System.nanoTime();
kernel.put(a).execute(Range.create(res.length)).get(res);
//System.out.println(Arrays.toString(res));
System.out.println(a[10]);
System.out.println("OpenCL time: "+(System.nanoTime()-t)/1000000f+"ms");
a[50] = 652; //Massive speedups after the fist pass
t = System.nanoTime();
kernel.put(a).execute(Range.create(res.length)).get(res);
System.out.println(a[10]);
System.out.println("Second OpenCL time: " + (System.nanoTime() - t) / 1000000f + "ms");
t=System.nanoTime();
for (int i = 0; i < res.length; i++) {
Color c = Color.fromBGR(a[i]);
res[i]= MapPalette.matchColor(c.getRed(), c.getGreen(), c.getBlue());
}
System.out.println("For loop time: "+(System.nanoTime()-t)/1000000f+"ms");
t=System.nanoTime();
System.arraycopy(a, 0, res, 0, res.length);
System.out.println("Sys time: "+(System.nanoTime()-t)/1000000f+"ms");
PXCLib pxc = LibraryLoader.create(PXCLib.class).search(new File("").getAbsolutePath()).load("pxc");
ByteBuffer bb = ByteBuffer.allocateDirect(640 * 480 * 4);
try {
Field f=Buffer.class.getDeclaredField("address");
f.setAccessible(true);
long addr= (long) f.get(bb);
pxc.setSource(addr, 640, 480, 5, 4);
t = System.nanoTime();
long p = pxc.updateAndGetMap(0, 0, 640, 480, null);
if (p == 0) return;
byte[] img = new Pointer(p).getByteArray(0, 128 * 128);
System.out.println("img[50]: " + img[50]);
System.out.println("Native time: " + (System.nanoTime() - t) / 1000000f + "ms");
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
kernel = new Kernel() {
@Override
public void run() {
PXCLib pxc = LibraryLoader.create(PXCLib.class).search(new File("").getAbsolutePath()).load("pxc");
pxc.updateAndGetMap(0, 0, 0, 0, null);
}
};
kernel.execute(Range.create(1));
}
}

View file

@ -0,0 +1,63 @@
package sznp.virtualcomputer.events;
import lombok.val;
import org.bukkit.Bukkit;
import org.mozilla.interfaces.IEvent;
import org.mozilla.interfaces.IEventListener;
import org.virtualbox_6_0.IEventSource;
import org.virtualbox_6_0.VBoxEventType;
import sznp.virtualcomputer.util.COMObjectBase;
import sznp.virtualcomputer.util.Utils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Map;
/**
* A Bukkit-like event system which calls the appropriate methods on an event.
*/
public abstract class EventHandlerBase extends COMObjectBase implements IEventListener {
/**
* The events to listen for. It will only look for these handlers.
*/
private final Map<VBoxEventType, Class<? extends org.virtualbox_6_0.IEvent>> eventMap;
private boolean enabled = true;
protected EventHandlerBase(Map<VBoxEventType, Class<? extends org.virtualbox_6_0.IEvent>> eventMap) {
//this.eventMap = eventMap.entrySet().stream().collect(Collectors.toMap(e -> e.getKey().value(), Map.Entry::getValue));
this.eventMap = eventMap;
}
@Override
public final void handleEvent(IEvent iEvent) {
//val cl=eventMap.get((int)iEvent.getType()); - We can afford to search through the events for this handler
if (!enabled)
return;
val kv = eventMap.entrySet().stream().filter(e -> e.getKey().value() == iEvent.getType()).findAny();
if (!kv.isPresent()) return; //Event not supported
val cl = kv.get().getValue();
for (Method method : getClass().getMethods()) {
if (method.isAnnotationPresent(org.bukkit.event.EventHandler.class)
&& method.getParameterCount() == 1 && method.getParameterTypes()[0] == cl) {
try {
method.invoke(this, Utils.getEvent(iEvent, cl));
return;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
Bukkit.getLogger().warning("Error while handling VirtualBox event!");
e.getCause().printStackTrace();
}
}
}
}
public <T extends EventHandlerBase> org.virtualbox_6_0.IEventListener registerTo(IEventSource source) {
return Utils.registerListener(source, this, new ArrayList<>(eventMap.keySet()));
}
public void disable() {
enabled = false;
}
}

View file

@ -0,0 +1,67 @@
package sznp.virtualcomputer.events;
import com.google.common.collect.ImmutableMap;
import lombok.Setter;
import lombok.experimental.var;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.event.EventHandler;
import org.virtualbox_6_0.IProgress;
import org.virtualbox_6_0.IStateChangedEvent;
import org.virtualbox_6_0.VBoxEventType;
import sznp.virtualcomputer.Computer;
import sznp.virtualcomputer.PluginMain;
import java.util.logging.Logger;
public class MachineEventHandler extends EventHandlerBase {
private final Computer computer;
private final CommandSender sender;
private boolean starting = false;
@Setter
private IProgress progress;
public MachineEventHandler(Computer computer, CommandSender sender) {
super(ImmutableMap.of(VBoxEventType.OnStateChanged, IStateChangedEvent.class));
//VBoxEventType.OnProgressPercentageChanged, IProgressPercentageChangedEvent.class)); - Doesn't fire at all, the complete event only fires on success
this.computer = computer;
this.sender = sender;
}
@EventHandler
public void handleStateChange(IStateChangedEvent event) { //https://www.virtualbox.org/sdkref/_virtual_box_8idl.html#a80b08f71210afe16038e904a656ed9eb
switch (event.getState()) {
case Stuck:
computer.Stop(null);
break;
case PoweredOff:
case Saved:
if (starting) {
sender.sendMessage("§cFailed to start computer! See the console for more details.");
sender.sendMessage("§cMake sure that 2D and 3D acceleration is disabled.");
starting = false;
Bukkit.getScheduler().runTaskAsynchronously(PluginMain.Instance, () -> {
progress.waitForCompletion(-1);
if (progress != null && progress.getCompleted() && progress.getResultCode() != 0) {
Logger l = PluginMain.Instance.getLogger();
l.warning("Result code: " + Integer.toHexString(progress.getResultCode()));
for (var info = progress.getErrorInfo(); info != null; info = info.getNext()) {
l.warning("----------------");
l.warning("VBox: " + info.getText());
l.warning("Component: " + info.getComponent());
}
}
});
}
computer.onMachineStop(sender);
break;
case Starting:
starting = true;
break;
case Running:
starting = false;
computer.onMachineStart(sender);
break;
}
}
}

View file

@ -0,0 +1,34 @@
package sznp.virtualcomputer.events;
import com.google.common.collect.ImmutableMap;
import lombok.Getter;
import org.bukkit.command.CommandSender;
import org.bukkit.event.EventHandler;
import org.virtualbox_6_0.ISessionStateChangedEvent;
import org.virtualbox_6_0.SessionState;
import org.virtualbox_6_0.VBoxEventType;
import sznp.virtualcomputer.Computer;
public class VBoxEventHandler extends EventHandlerBase {
public VBoxEventHandler() {
super(ImmutableMap.of(VBoxEventType.OnSessionStateChanged, ISessionStateChangedEvent.class));
instance = this;
}
@Getter
private static VBoxEventHandler instance;
private String machineID;
private CommandSender sender;
@EventHandler
public void onSessionStateChange(ISessionStateChangedEvent event) {
if (!event.getMachineId().equals(machineID)) return;
if (event.getState() == SessionState.Locked) //Need to check here, because we can't access the console yet
Computer.getInstance().onLock(sender);
}
public void setup(String machineID, CommandSender sender) {
this.machineID = machineID;
this.sender = sender;
}
}

View file

@ -0,0 +1,83 @@
package sznp.virtualcomputer.renderer;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.map.MapCanvas;
import org.bukkit.map.MapRenderer;
import org.bukkit.map.MapView;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.nio.ByteBuffer;
import java.util.concurrent.TimeUnit;
public class BukkitRenderer extends MapRenderer implements IRenderer {
private ByteBuffer allpixels;
private BufferedImage image;
private int startindex;
/**
* The raw pixel data from the machine in BGRA format
*/
public void setAllPixels(ByteBuffer allpixels) {
this.allpixels = allpixels;
}
/**
* Generic implementation, should work on most versions
*
* @param id
* The ID of the current map
* @param world
* The world to create new maps in
* @param startindex
* The index to start from in allpixels
*/
public BukkitRenderer(short id, World world, int startindex) {
MapView map = IRenderer.prepare(id, world);
map.addRenderer(this);
this.startindex = startindex;
image = new BufferedImage(128, 128, BufferedImage.TYPE_INT_RGB);
}
private int progress = 0;
public static int updatepixels = 15;
@Override
public void render(MapView view, MapCanvas canvas, Player player) {
if (allpixels == null)
return;
long time = System.nanoTime();
final int[] a = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); // Directly update the bytes of the image
// (byte) bgra to rgb (int)
for (int i = startindex, j = 0; i < startindex + 128 * 128; i = i + 4, j++) {
int b, g, r;
b = allpixels.get(i) & 0xFF; //TODO: <-- IndexOutOfBoundsException sometimes
g = allpixels.get(i + 1) & 0xFF;
r = allpixels.get(i + 2) & 0xFF;
a[j] = (r << 16) | (g << 8) | b;
}
try {
canvas.drawImage(0, progress * updatepixels, image.getSubimage(0, progress * updatepixels, 128,
(progress * updatepixels + updatepixels >= 128 ? 128 - progress * updatepixels : updatepixels)));
if (progress < 128 / updatepixels)
progress++;
else
progress = 0;
long diff = System.nanoTime() - time;
if (TimeUnit.NANOSECONDS.toMillis(diff) > 40) {
System.out.println("Map rendering took " + TimeUnit.NANOSECONDS.toMillis(diff) + " ms");
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("Progess: " + progress);
System.out.println("UpdatePixels: " + updatepixels);
}
}
}

View file

@ -0,0 +1,117 @@
package sznp.virtualcomputer.renderer;
import net.minecraft.server.v1_12_R1.WorldMap;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.map.MapCanvas;
import org.bukkit.map.MapPalette;
import org.bukkit.map.MapRenderer;
import org.bukkit.map.MapView;
import sznp.virtualcomputer.PluginMain;
import sznp.virtualcomputer.util.Timing;
import java.awt.*;
import java.lang.reflect.Field;
import java.util.ArrayList;
public class GPURenderer extends MapRenderer implements IRenderer {
private byte[] buffer;
private final GPURendererInternal kernel;
private WorldMap wmap;
private int mapx, mapy;
//Store at central location after conversion
private static int[] colors_;
private int changedX = 0, changedY = 0, changedWidth = 640, changedHeight = 480;
private static ArrayList<GPURenderer> renderers = new ArrayList<>();
public GPURenderer(short id, World world, int mapx, int mapy) throws Exception {
MapView map = IRenderer.prepare(id, world);
if (map == null) {
kernel = null;
return; //Testing
}
if (colors_ == null) {
Field field = MapPalette.class.getDeclaredField("colors");
field.setAccessible(true);
Color[] cs = (Color[]) field.get(null);
colors_ = new int[cs.length];
for (int i = 0; i < colors_.length; i++) {
colors_[i] = cs[i].getRGB();
}
}
this.mapx = mapx;
this.mapy = mapy;
Field field = map.getClass().getDeclaredField("worldMap");
field.setAccessible(true);
wmap = (WorldMap) field.get(map);
kernel = new GPURendererInternal(mapx, mapy, colors_);
renderers.add(this);
map.addRenderer(this);
}
@Override
public void render(MapView map, MapCanvas canvas, Player player) {
Timing t = new Timing();
try {
if (kernel.isRendered()) return;
if (buffer == null) { //The buffer remains the same, as the canvas remains the same
Field field = canvas.getClass().getDeclaredField("buffer");
field.setAccessible(true);
buffer = (byte[]) field.get(canvas);
}
if (!PluginMain.sendAll) {
synchronized (kernel) {
if (changedX >= (mapx + 1) * 128 || changedY >= (mapy + 1) * 128
|| changedX + changedWidth < mapx * 128 || changedY + changedHeight < mapy * 128) {
kernel.ignoreChange();
return; //No change for this map
}
}
//System.out.println("changed: (" + changedX + ", " + changedY + ") " + changedWidth + "x" + changedHeight);
//System.out.println("map: (" + mapx + ", " + mapy + ")");
int x = changedX - mapx * 128;
int y = changedY - mapy * 128;
if (x < 0) x = 0;
if (y < 0) y = 0;
int xx = x + changedWidth >= 128 ? 127 : x + changedWidth;
int yy = y + changedHeight >= 128 ? 127 : y + changedHeight;
//System.out.println("local: ("+x+", "+y+") "+w+"x"+h);
kernel.render(buffer);
wmap.flagDirty(x, y);
wmap.flagDirty(xx, yy); // Send the changes only
changedX = Integer.MAX_VALUE; //Finished rendering
changedY = Integer.MAX_VALUE; //TODO: Render as soon as we receive new image
changedWidth = -1; //Finished rendering
changedHeight = -1;
} else {
kernel.render(buffer);
wmap.flagDirty(0, 0);
wmap.flagDirty(127, 127); // Send everything
}
} catch (Exception e) {
e.printStackTrace();
}
if (t.elapsedMS() > 60)
System.out.println("Map rendering took " + t.elapsedMS() + "ms");
}
public static void update(byte[] pixels, int width, int height, int changedX, int changedY, int changedWidth, int changedHeight) {
for (GPURenderer r : renderers) {
synchronized (r.kernel) {
if (!PluginMain.sendAll) {
if (changedX < r.changedX)
r.changedX = changedX;
if (changedY < r.changedY)
r.changedY = changedY;
if (changedWidth > r.changedWidth)
r.changedWidth = changedWidth;
if (changedHeight > r.changedHeight)
r.changedHeight = changedHeight;
}
r.kernel.setPixels(pixels, width, height);
}
}
}
}

View file

@ -0,0 +1,109 @@
package sznp.virtualcomputer.renderer;
import com.aparapi.Kernel;
import com.aparapi.Range;
import lombok.Getter;
//Accessing the GPURenderer results in ArrayIndexOutOfBoundsExceptions - IT'S THE LAMBDAS
public class GPURendererInternal extends Kernel {
private int mapx;
private int mapy;
private int width;
private int height;
private byte[] pixels;
//Can't use static fields because it leads to incorrect CL code
private int[] colors;
@SuppressWarnings({"FieldCanBeLocal", "unused"})
private byte[] buffer; //References the map buffer
private Range range;
@Getter
private boolean rendered;
//public static byte[] test=new byte[1]; - LAMBDAS
public GPURendererInternal(int mapx, int mapy, int[] colors) {
this.mapx = mapx;
this.mapy = mapy;
this.colors = colors;
range = Range.create2D(128, 128);
//Do an intial draw of a black screen with Aparapi so it doesn't lag at start
pixels = new byte[1];
width = height = 0;
rendered = false;
}
@Override
public void run() {
//Single booleans not found (no such field error)
int mx = getGlobalId(0);
int my = getGlobalId(1);
int imgx = mx + mapx * 128;
int imgy = my + mapy * 128;
int imgi = (imgy * width + imgx) * 4;
if (imgx >= width || imgy >= height) { //Array length check --> Unhandled exception string
buffer[my * 128 + mx] = matchColor(0, 0, 0);
//buffer[my*128+mx]=10; - LAMBDAS
return;
}
buffer[my * 128 + mx] = matchColor(pixels[imgi] & 0xFF, pixels[imgi + 1] & 0xFF, pixels[imgi + 2] & 0xFF); //Byte.toUnsignedInt
//buffer[my*128+mx]=10; - LAMBDAS
//Unhandled exception string (used & 255, after using toUnsignedInt on the blue color) - Not that, see above
}
//Modified version of MapPalette.matchColor
private byte matchColor(int b, int g, int r) {
int index = 0;
double best = -1;
for (int i = 4; i < colors.length; i++) {
double distance = distance(b, g, r, colors[i]);
if (distance < best || best == -1) {
best = distance;
index = i;
}
}
// Minecraft has 143 colors, some of which have negative byte representations
return (byte) (index < 128 ? index : -129 + (index - 127));
}
//Can't use getXY prefix because it treats it as a getter
private double distance(int b1, int g1, int r1, int c2) {
int red2 = color(c2, RED);
double rmean = (r1 + red2) / 2.0;
double r = r1 - red2;
double g = g1 - color(c2, GREEN);
int b = b1 - color(c2, BLUE);
double weightR = 2 + rmean / 256.0;
double weightG = 4.0;
double weightB = 2 + (255 - rmean) / 256.0;
return weightR * r * r + weightG * g * g + weightB * b * b;
}
private static int color(int bgra, int oc) {
return (bgra >> (oc * 8)) & 0xFF;
}
private static final int RED = 2;
private static final int GREEN = 1;
private static final int BLUE = 0;
//Aparapi fails with lambdas
void setPixels(byte[] pixels, int width, int height) {
this.pixels = pixels;
this.width = width;
this.height = height;
rendered = false;
}
void render(byte[] buffer) {
if (pixels == null || rendered) return;
this.buffer = buffer;
put(buffer).put(pixels).execute(range).get(buffer);
rendered = true;
}
void ignoreChange() {
rendered = true;
}
}

View file

@ -0,0 +1,17 @@
package sznp.virtualcomputer.renderer;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.map.MapView;
public interface IRenderer {
static MapView prepare(short id, World world) {
if (world == null) return null; //Testing
@SuppressWarnings("deprecation")
MapView map = Bukkit.getMap(id);
if (map == null)
map = Bukkit.createMap(world);
map.getRenderers().clear();
return map;
}
}

View file

@ -0,0 +1,154 @@
package sznp.virtualcomputer.renderer;
import com.sun.jna.Pointer;
import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitTask;
import org.mozilla.interfaces.IFramebuffer;
import org.mozilla.interfaces.IFramebufferOverlay;
import org.mozilla.interfaces.nsISupports;
import org.mozilla.xpcom.Mozilla;
import org.virtualbox_6_0.*;
import sznp.virtualcomputer.PluginMain;
import sznp.virtualcomputer.util.Timing;
import java.util.Arrays;
public class MCFrameBuffer implements IFramebuffer {
private IDisplay display;
private Holder<IDisplaySourceBitmap> holder = new Holder<>();
public MCFrameBuffer(IDisplay display, boolean VBoxDirect) { //TODO: Implement param
this.display = display;
}
@Override
public nsISupports queryInterface(String id) {
return Mozilla.queryInterface(this, id);
}
@Override
public long getBitsPerPixel() {
return 32;
}
@Override
public long getBytesPerLine() {
return 640L;
}
@Override
public long[] getCapabilities(long[] arg0) {
try {
System.out.println("Capabilities queried");
System.out.println("Capabilities: " + Arrays.toString(arg0));
return new long[]{FramebufferCapabilities.UpdateImage.value()};
}
catch(Exception e) {
e.printStackTrace();
return new long[]{};
}
}
@Override
public long getHeight() {
return 480;
}
@Override
public long getHeightReduction() {
return 0;
}
@Override
public IFramebufferOverlay getOverlay() {
return null;
}
@Override
public long getPixelFormat() {
return BitmapFormat.BGRA.value();
}
@Override
public long getVisibleRegion(byte arg0, long arg1) {
return 0;
}
@Override
public long getWidth() {
return 640;
}
@Override
public long getWinId() {
return 0; // Zero means no win id
}
@Override
public void notify3DEvent(long arg0, byte[] arg1) {
}
private BukkitTask tt;
private Pointer pointer;
private int width;
private int height;
@Override
public void notifyChange(long screenId, long xOrigin, long yOrigin, long width, long height) {
if (tt != null)
tt.cancel();
tt = Bukkit.getScheduler().runTaskAsynchronously(PluginMain.Instance, () -> {
try {
display.querySourceBitmap(0L, holder);
long[] ptr = new long[1], w = new long[1], h = new long[1], bpp = new long[1], bpl = new long[1], pf = new long[1];
holder.value.getTypedWrapped().queryBitmapInfo(ptr, w, h, bpp, bpl, pf);
if (PluginMain.direct) {
pointer = new Pointer(ptr[0]);
this.width = (int) w[0];
this.height = (int) h[0];
GPURenderer.update(pointer.getByteArray(0L, (int) (w[0] * h[0] * 4)), (int) w[0], (int) h[0], 0, 0, this.width, this.height);
} else {
PluginMain.allpixels = new Pointer(ptr[0]).getByteBuffer(0L, width * height * 4);
if (width * height > 640 * 480)
PluginMain.allpixels.limit(640 * 480 * 4);
else
PluginMain.allpixels.limit((int) (width * height * 4));
}
} catch (VBoxException e) {
if (e.getResultCode() == 0x80070005)
return; // Machine is being powered down
if (e.getResultCode() == 0x80004005) //The function "querySourceBitmap" returned an error condition: "Operation failed (NS_ERROR_FAILURE)"
System.out.println("I don't know why this happens, but stopping the computer helps.");
e.printStackTrace();
} catch (Throwable t) {
t.printStackTrace();
}
});
}
@Override
public void notifyUpdate(long x, long y, long width, long height) {
Timing t = new Timing();
GPURenderer.update(pointer.getByteArray(0L, this.width * this.height * 4), this.width, this.height, (int) x, (int) y, (int) width, (int) height);
if (t.elapsedMS() > 60) //Typically 1ms max
System.out.println("Update took " + t.elapsedMS() + "ms");
}
@Override
public void notifyUpdateImage(long arg0, long arg1, long arg2, long arg3, byte[] arg4) {
System.out.println("Update image!");
}
@Override
public void setVisibleRegion(byte arg0, long arg1) {
}
@Override
public void processVHWACommand(byte b, int i, boolean b1) {
}
@Override
public boolean videoModeSupported(long arg0, long arg1, long arg2) {
return true;
}
}

View file

@ -0,0 +1,11 @@
package sznp.virtualcomputer.util;
import org.mozilla.interfaces.nsISupports;
import org.mozilla.xpcom.Mozilla;
public abstract class COMObjectBase implements nsISupports {
public nsISupports queryInterface(String id) {
return Mozilla.queryInterface(this, id);
}
}

View file

@ -0,0 +1,30 @@
package sznp.virtualcomputer.util;
import jnr.ffi.Pointer;
@SuppressWarnings("unused")
public interface PXCLib {
/**
* Testing only
* @param px Input array
* @param out Output array
* @return 0
*/
int convert(int[] px, long[] out);
/**
* Set source bitmap
* @param address Bitmap address from VirtualBox
* @param w Width of the screen
* @param h Height of the screen
* @param mcx Width of the screen in maps
* @param mcy Height of the screen in maps
*/
void setSource(long address, int w, int h, int mcx, int mcy);
/**
* Updates map and returns it's content, where affected
* @return Partial map data [mapc][data]
*/
long updateAndGetMap(int x, int y, int width, int height, Pointer out_changed); //TODO: Only update parts that actually updated and return them per-map (flagDirty)
}

View file

@ -0,0 +1,136 @@
package sznp.virtualcomputer.util;
/*
The scancode values come from:
- http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc (March 16), 2000).
- http://www.computer-engineering.org/ps2keyboard/scancodes1.html
- using MapVirtualKeyEx( VK_*), MAPVK_VK_TO_VSC_EX), 0 ) with the english us keyboard layout
- reading win32 WM_INPUT keyboard messages.
*/
import java.util.HashMap;
@SuppressWarnings("unused")
public enum Scancode { // https://handmade.network/forums/t/2011-keyboard_inputs_-_scancodes,_raw_input,_text_input,_key_names
sc_escape(0x01), sc_1(0x02), sc_2(0x03), sc_3(0x04), sc_4(0x05), sc_5(0x06), sc_6(0x07), sc_7(0x08), sc_8(
0x09), sc_9(0x0A), sc_0(0x0B), sc_minus(0x0C), sc_equals(0x0D), sc_backspace(0x0E), sc_tab(0x0F), sc_q(
0x10), sc_w(0x11), sc_e(0x12), sc_r(0x13), sc_t(0x14), sc_y(0x15), sc_u(0x16), sc_i(0x17), sc_o(
0x18), sc_p(0x19), sc_bracketLeft(0x1A), sc_bracketRight(0x1B), sc_enter(
0x1C), sc_controlLeft(0x1D), sc_a(0x1E), sc_s(0x1F), sc_d(
0x20), sc_f(0x21), sc_g(0x22), sc_h(0x23), sc_j(0x24), sc_k(0x25), sc_l(
0x26), sc_semicolon(0x27), sc_apostrophe(0x28), sc_grave(
0x29), sc_shiftLeft(0x2A), sc_backslash(0x2B), sc_z(
0x2C), sc_x(0x2D), sc_c(0x2E), sc_v(0x2F), sc_b(
0x30), sc_n(0x31), sc_m(0x32), sc_comma(
0x33), sc_period(0x34), sc_slash(
0x35), sc_shiftRight(
0x36), sc_numpad_multiply(
0x37), sc_altLeft(
0x38), sc_space(
0x39), sc_capsLock(
0x3A), sc_f1(
0x3B), sc_f2(
0x3C), sc_f3(
0x3D), sc_f4(
0x3E), sc_f5(
0x3F), sc_f6(
0x40), sc_f7(
0x41), sc_f8(
0x42), sc_f9(
0x43), sc_f10(
0x44), sc_numLock(
0x45), sc_scrollLock(
0x46), sc_numpad_7(
0x47), sc_numpad_8(
0x48), sc_numpad_9(
0x49), sc_numpad_minus(
0x4A), sc_numpad_4(
0x4B), sc_numpad_5(
0x4C), sc_numpad_6(
0x4D), sc_numpad_plus(
0x4E), sc_numpad_1(
0x4F), sc_numpad_2(
0x50), sc_numpad_3(
0x51), sc_numpad_0(
0x52), sc_numpad_period(
0x53), sc_alt_printScreen(
0x54), /*
* Alt
* +
* print
* screen.
* MapVirtualKeyEx(
* VK_SNAPSHOT
* )
* ,
* MAPVK_VK_TO_VSC_EX
* )
* ,
* 0
* )
* returns
* scancode
* 0x54.
*/
sc_bracketAngle(0x56), /* Key between the left shift and Z. */
sc_f11(0x57), sc_f12(0x58), sc_oem_1(0x5a), /* VK_OEM_WSCTRL */
sc_oem_2(0x5b), /* VK_OEM_FINISH */
sc_oem_3(0x5c), /* VK_OEM_JUMP */
sc_eraseEOF(0x5d), sc_oem_4(0x5e), /* VK_OEM_BACKTAB */
sc_oem_5(0x5f), /* VK_OEM_AUTO */
sc_zoom(0x62), sc_help(0x63), sc_f13(0x64), sc_f14(0x65), sc_f15(0x66), sc_f16(0x67), sc_f17(0x68), sc_f18(
0x69), sc_f19(
0x6a), sc_f20(0x6b), sc_f21(0x6c), sc_f22(0x6d), sc_f23(0x6e), sc_oem_6(0x6f), /* VK_OEM_PA3 */
sc_katakana(0x70), sc_oem_7(0x71), /* VK_OEM_RESET */
sc_f24(0x76), sc_sbcschar(0x77), sc_convert(0x79), sc_nonconvert(0x7B), /* VK_OEM_PA1 */
sc_media_previous(0xE010), sc_media_next(0xE019), sc_numpad_enter(0xE01C), sc_controlRight(0xE01D), sc_volume_mute(
0xE020), sc_launch_app2(0xE021), sc_media_play(0xE022), sc_media_stop(
0xE024), sc_volume_down(0xE02E), sc_volume_up(
0xE030), sc_browser_home(0xE032), sc_numpad_divide(0xE035), sc_printScreen(0xE037),
/*
* sc_printScreen: - make: 0xE02A 0xE037 - break: 0xE0B7 0xE0AA - MapVirtualKeyEx( VK_SNAPSHOT), MAPVK_VK_TO_VSC_EX), 0 ) returns scancode 0x54; - There is no VK_KEYDOWN with VK_SNAPSHOT.
*/
sc_altRight(0xE038), sc_cancel(0xE046), /* CTRL + Pause */
sc_home(0xE047), sc_arrowUp(0xE048), sc_pageUp(0xE049), sc_arrowLeft(0xE04B), sc_arrowRight(0xE04D), sc_end(
0xE04F), sc_arrowDown(0xE050), sc_pageDown(0xE051), sc_insert(0xE052), sc_delete(0xE053), sc_metaLeft(
0xE05B), sc_metaRight(0xE05C), sc_application(0xE05D), sc_power(0xE05E), sc_sleep(0xE05F), sc_wake(
0xE063), sc_browser_search(0xE065), sc_browser_favorites(0xE066), sc_browser_refresh(
0xE067), sc_browser_stop(0xE068), sc_browser_forward(0xE069), sc_browser_back(
0xE06A), sc_launch_app1(
0xE06B), sc_launch_email(0xE06C), sc_launch_media(0xE06D),
sc_pause(0xE11D45);
/*
* sc_pause: - make: 0xE11D 45 0xE19D C5 - make in raw input: 0xE11D 0x45 - break: none - No repeat when you hold the key down - There are no break so I don't know how the key down/up is expected
* to work. Raw input sends "keydown" and "keyup" messages), and it appears that the keyup message is sent directly after the keydown message (you can't hold the key down) so depending on when
* GetMessage or PeekMessage will return messages), you may get both a keydown and keyup message "at the same time". If you use VK messages most of the time you only get keydown messages), but
* some times you get keyup messages too. - when pressed at the same time as one or both control keys, generates a 0xE046 (sc_cancel) and the string for that scancode is "break".
*/
private static final HashMap<String, Integer> scanCodes = new HashMap<>();
static {
for (Scancode sc : values())
scanCodes.put(sc.toString().toLowerCase(), sc.Code);
}
/**
* Gets the scancode from a lowercased string (O(1))
*
* @param keyLowerCased The key name, lowercased (sc_...)
* @return The code or -1 if not found
*/
public static int getCode(String keyLowerCased) {
Integer code = scanCodes.get(keyLowerCased);
if (code == null) return -1;
return code;
}
public int Code;
Scancode(int code) {
Code = code;
}
}

View file

@ -0,0 +1,9 @@
package sznp.virtualcomputer.util;
public class Timing {
private long start = System.nanoTime();
public long elapsedMS() {
return (System.nanoTime() - start) / 1000000L;
}
}

View file

@ -0,0 +1,61 @@
package sznp.virtualcomputer.util;
import lombok.val;
import org.mozilla.interfaces.IEventListener;
import org.virtualbox_6_0.IEvent;
import org.virtualbox_6_0.IEventSource;
import org.virtualbox_6_0.VBoxEventType;
import org.virtualbox_6_0.xpcom.IUnknown;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;
public class Utils {
/**
* Adds the specified path to the java library path
*
* @param pathToAdd the path to add
* @throws Exception
*/
public static void addLibraryPath(String pathToAdd) throws Exception {
final Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths");
usrPathsField.setAccessible(true);
// get array of paths
final String[] paths = (String[]) usrPathsField.get(null);
// check if the path to add is already present
for (String path : paths) {
if (path.equals(pathToAdd)) {
return;
}
}
// add the new path
final String[] newPaths = Arrays.copyOf(paths, paths.length + 1);
newPaths[newPaths.length - 1] = pathToAdd;
usrPathsField.set(null, newPaths);
}
//public static void registerListener(IEventSource source, IEventListener listener, VBoxEventType... types) {
public static org.virtualbox_6_0.IEventListener registerListener(IEventSource source, IEventListener listener, List<VBoxEventType> types) {
val ret = new org.virtualbox_6_0.IEventListener(listener);
source.registerListener(ret, types, true);
return ret;
}
@SuppressWarnings("unchecked")
public static <T extends IEvent> T getEvent(org.mozilla.interfaces.IEvent event, Class<T> cl) {
//if (event.getType() != type.value()) return null;
//return (T) T.queryInterface(new IEvent(event)); - Probably won't work
try {
val method = cl.getMethod("queryInterface", IUnknown.class);
return (T) method.invoke(null, new IEvent(event));
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
return null;
}
}
}

View file

@ -0,0 +1,5 @@
package sznp.virtualcomputer.util;
public interface VBoxLib {
void RTR3InitExe(int argc, String argv, int somethingzero);
}

View file

@ -0,0 +1,10 @@
package sznp.virtualcomputer.util;
import com.sun.jna.Library;
import com.sun.jna.Native;
public interface WinLib extends Library {
WinLib INSTANCE = Native.loadLibrary("VirtualComputerWin", WinLib.class);
public void init();
}

View file

@ -0,0 +1,7 @@
name: VirtualComputer
main: sznp.virtualcomputer.PluginMain
version: 2.0
commands:
computer:
usage: Use /computer start|stop|reset|key|mouse|input|fix
aliases: c

View file

@ -1,201 +0,0 @@
package sznp.virtualcomputer;
import net.countercraft.movecraft.craft.Craft;
import net.countercraft.movecraft.craft.CraftManager;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class Commands implements CommandExecutor
{
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label,
String[] args)
{
switch (cmd.getName().toLowerCase())
{
case "computer":
{
if (args.length == 0)
return false;
switch (args[0].toLowerCase())
{
case "start":
PluginMain.getPlugin(PluginMain.class).Start(sender);
break;
case "stop":
PluginMain.getPlugin(PluginMain.class).Stop(sender);
break;
case "debug":
World w = Bukkit.getWorlds().get(0);
Craft[] crafts = CraftManager.getInstance().getCraftsInWorld(w);
sender.sendMessage("World: " + w);
sender.sendMessage("Crafts: " + crafts);
sender.sendMessage("Craft type: "
+ crafts[0].getType().getCraftName());
sender.sendMessage("DX: " + crafts[0].getLastDX());
sender.sendMessage("DY: " + crafts[0].getLastDY());
sender.sendMessage("DZ: " + crafts[0].getLastDZ());
sender.sendMessage("MouseSpeed: " + PluginMain.MouseSpeed);
sender.sendMessage("Block: "
+ Bukkit.getWorlds()
.get(0)
.getBlockAt(crafts[0].getMinX(),
crafts[0].getMinY() - 1,
crafts[0].getMinZ()).getType()); // Block:
// AIR
break;
case "powerbutton":
PluginMain.getPlugin(PluginMain.class).PowerButton(sender);
break;
case "reset":
PluginMain.getPlugin(PluginMain.class).Reset(sender);
break;
case "fix":
PluginMain.getPlugin(PluginMain.class).FixScreen(sender);
break;
case "key":
if (args.length < 2)
{
sender.sendMessage("§cUsage: /computer key <key> [down/up|interval]");
return true;
}
if (args.length < 3)
PluginMain.getPlugin(PluginMain.class).PressKey(sender,
args[1], "");
else
PluginMain.getPlugin(PluginMain.class).PressKey(sender,
args[1], args[2]);
break;
case "mouse":
boolean showusage = true;
if (args.length < 6)
{
// Command overloading, because I can :P
if (args.length > 4) // 4<x<6
{
PluginMain.getPlugin(PluginMain.class).UpdateMouse(
sender, Integer.parseInt(args[1]),
Integer.parseInt(args[2]),
Integer.parseInt(args[3]),
Integer.parseInt(args[4]), "", false);
showusage = false;
} else
{
if (args.length == 3)
{
PluginMain.getPlugin(PluginMain.class).UpdateMouse(
sender, 0, 0, 0, 0, args[1],
(args[2].equals("down")));
showusage = false;
} else if (args.length == 2)
{
PluginMain.getPlugin(PluginMain.class).UpdateMouse(
sender, 0, 0, 0, 0, args[1]);
showusage = false;
}
}
}
if (showusage)
{
sender.sendMessage("§cUsage: /computer mouse <relx> <rely> <relz> <relw>");
sender.sendMessage("§cOr: /computer mouse <button> [up/down]");
}
break;
case "mspeed":
if (args.length < 2)
{
sender.sendMessage("§cUsage: /computer mspeed <speed>");
return true;
}
PluginMain.MouseSpeed = Integer.parseInt(args[1]);
sender.sendMessage("Mouse speed set to " + args[1]);
break;
case "input":
{
if (!(sender instanceof Player))
{
sender.sendMessage("§cError: Only players can use this command.");
return true;
}
if (args.length < 2)
{
sender.sendMessage("§cUsage: /computer input <key|mouse>");
return true;
}
if (args[1].equalsIgnoreCase("key"))
{
Bukkit.getServer()
.dispatchCommand(
Bukkit.getConsoleSender(),
"tellraw "
+ sender.getName()
+ " [\"\",{\"text\":\" [0]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D0\"}},{\"text\":\" [1]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D1\"}},{\"text\":\" [2]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D2\"}},{\"text\":\" [3]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D3\"}},{\"text\":\" [4]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D4\"}},{\"text\":\" [5]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D5\"}},{\"text\":\" [6]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D6\"}},{\"text\":\" [7]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D7\"}},{\"text\":\" [8]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D8\"}},{\"text\":\" [9]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D9\"}}]");
Bukkit.getServer()
.dispatchCommand(
Bukkit.getConsoleSender(),
"tellraw "
+ sender.getName()
+ " [\"\",{\"text\":\" [Tab]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key Tab\"}},{\"text\":\" [Q]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key Q\"}},{\"text\":\" [W]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key W\"}},{\"text\":\" [E]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key E\"}},{\"text\":\" [R]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key R\"}},{\"text\":\" [T]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key T\"}},{\"text\":\" [Y]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key Y\"}},{\"text\":\" [U]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key U\"}},{\"text\":\" [I]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key I\"}},{\"text\":\" [O]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key O\"}},{\"text\":\" [P]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key P\"}}]");
Bukkit.getServer()
.dispatchCommand(
Bukkit.getConsoleSender(),
"tellraw "
+ sender.getName()
+ " [\"\",{\"text\":\" [CapsLock]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key CapsLock\"}},{\"text\":\" [A]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key A\"}},{\"text\":\" [S]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key S\"}},{\"text\":\" [D]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key D\"}},{\"text\":\" [F]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key F\"}},{\"text\":\" [G]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key G\"}},{\"text\":\" [H]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key H\"}},{\"text\":\" [J]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key J\"}},{\"text\":\" [K]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key K\"}},{\"text\":\" [L]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key L\"}},{\"text\":\" [Return]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key Return\"}}]");
Bukkit.getServer()
.dispatchCommand(
Bukkit.getConsoleSender(),
"tellraw "
+ sender.getName()
+ " [\"\",{\"text\":\" [Z]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key Z\"}},{\"text\":\" [X]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key X\"}},{\"text\":\" [C]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key C\"}},{\"text\":\" [V]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key V\"}},{\"text\":\" [B]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key B\"}},{\"text\":\" [N]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key N\"}},{\"text\":\" [M]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key M\"}}]");
Bukkit.getServer()
.dispatchCommand(
Bukkit.getConsoleSender(),
"tellraw "
+ sender.getName()
+ " [\"\",{\"text\":\" [Ctrl]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key ControlLeft\"}},{\"text\":\" [Alt]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key AltLeft\"}},{\"text\":\" [Space]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key Space\"}},{\"text\":\" [AltGr]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key AltRight\"}},{\"text\":\" [Ctrl]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key ControlRight\"}}]");
} else if (args[1].equalsIgnoreCase("mouse"))
{
if (!(sender instanceof Player))
{
sender.sendMessage("§cOnly ingame players can use this command.");
return true;
}
if (!MouseLockerPlayerListener.LockedPlayers
.contains(sender))
{
MouseLockerPlayerListener.LockedPlayers
.add((Player) sender);
sender.sendMessage("§aMouse locked.");
} else
{
MouseLockerPlayerListener.LockedPlayers.remove(sender);
sender.sendMessage("§bMouse unlocked.");
}
} else if (args[1].equalsIgnoreCase("mspeed"))
{
if (args.length < 3)
{
sender.sendMessage("§cUsage: /computer input mspeed <integer>");
return true;
}
MouseLockerPlayerListener.LockedSpeed = Float
.parseFloat(args[2]);
sender.sendMessage("§aMouse speed set to "
+ MouseLockerPlayerListener.LockedSpeed);
}
break;
}
}
return true;
}
}
return false;
}
}

View file

@ -1,90 +0,0 @@
package sznp.virtualcomputer;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class JarUtils {
public static boolean extractFromJar(final String fileName,
final String dest) throws IOException {
if (getRunningJar() == null) {
return false;
}
final File file = new File(dest);
if (file.isDirectory()) {
file.mkdir();
return false;
}
if (!file.exists()) {
file.getParentFile().mkdirs();
}
final JarFile jar = getRunningJar();
final Enumeration<JarEntry> e = jar.entries();
while (e.hasMoreElements()) {
final JarEntry je = e.nextElement();
if (!je.getName().contains(fileName)) {
continue;
}
final InputStream in = new BufferedInputStream(
jar.getInputStream(je));
final OutputStream out = new BufferedOutputStream(
new FileOutputStream(file));
copyInputStream(in, out);
jar.close();
return true;
}
jar.close();
return false;
}
private final static void copyInputStream(final InputStream in,
final OutputStream out) throws IOException {
try {
final byte[] buff = new byte[4096];
int n;
while ((n = in.read(buff)) > 0) {
out.write(buff, 0, n);
}
} finally {
out.flush();
out.close();
in.close();
}
}
public static URL getJarUrl(final File file) throws IOException {
return new URL("jar:" + file.toURI().toURL().toExternalForm() + "!/");
}
public static JarFile getRunningJar() throws IOException {
if (!RUNNING_FROM_JAR) {
return null; // null if not running from jar
}
String path = new File(JarUtils.class.getProtectionDomain()
.getCodeSource().getLocation().getPath()).getAbsolutePath();
path = URLDecoder.decode(path, "UTF-8");
return new JarFile(path);
}
private static boolean RUNNING_FROM_JAR = false;
static {
final URL resource = JarUtils.class.getClassLoader().getResource(
"plugin.yml");
if (resource != null) {
RUNNING_FROM_JAR = true;
}
}
}

View file

@ -1,34 +0,0 @@
package sznp.virtualcomputer;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
public class MouseLockerPlayerListener implements Listener
{
public static List<Player> LockedPlayers = new ArrayList<Player>();
public static float LockedSpeed = 1;
@EventHandler
public void onPlayerMoveMouse(PlayerMoveEvent e)
{
if (!LockedPlayers.contains(e.getPlayer()))
return;
float yaw1 = e.getFrom().getYaw();
float pitch1 = e.getFrom().getPitch();
float yaw2 = e.getTo().getYaw();
float pitch2 = e.getTo().getPitch();
if (yaw2 - yaw1 == 0 || pitch2 - pitch1 == 0)
return;
PluginMain.Instance.UpdateMouse(null,
(int) ((yaw2 - yaw1) * LockedSpeed),
(int) ((pitch2 - pitch1) * LockedSpeed), 0, 0, "");
e.setTo(e.getFrom());
}
}

View file

@ -1,263 +0,0 @@
package sznp.virtualcomputer;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import net.countercraft.movecraft.craft.Craft;
import net.countercraft.movecraft.craft.CraftManager;
import net.sf.jni4net.Bridge;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.plugin.java.JavaPlugin;
import virtualcomputersender.Computer;
import com.mcplugindev.slipswhitley.sketchmap.map.RelativeLocation;
import com.mcplugindev.slipswhitley.sketchmap.map.SketchMap;
public class PluginMain extends JavaPlugin
{
private Computer computer;
private SketchMap smap;
public static PluginMain Instance;
// Fired when plugin is first enabled
@Override
public void onEnable()
{
Instance = this;
try
{
ConsoleCommandSender ccs = getServer().getConsoleSender();
this.getCommand("computer").setExecutor(new Commands());
ccs.sendMessage("§bExtracting necessary libraries...");
final File[] libs = new File[] { // added to class path
new File(getDataFolder(), "jni4net.j-0.8.8.0.jar"),
new File(getDataFolder(), "VirtualComputerSender.j4n.jar") };
final File[] libs2 = new File[] {
new File(getDataFolder(), "jni4net.j-0.8.8.0.jar"),
new File(getDataFolder(), "jni4net.n-0.8.8.0.dll"),
new File(getDataFolder(), "jni4net.n.w64.v40-0.8.8.0.dll") };
for (final File lib : libs2)
{
if (!lib.exists())
{
JarUtils.extractFromJar(lib.getName(),
lib.getAbsolutePath());
}
}
for (final File lib : libs)
{
if (!lib.exists())
{
getLogger().warning(
"Failed to load plugin! Could not find lib: "
+ lib.getName());
Bukkit.getServer().getPluginManager().disablePlugin(this);
return;
}
addClassPath(JarUtils.getJarUrl(lib));
}
ccs.sendMessage("§bInitializing bridge...");
// Bridge.setVerbose(true);
// Bridge.setDebug(true);
Bridge.init(new File(getDataFolder(),
"jni4net.n.w64.v40-0.8.8.0.dll").getAbsoluteFile());
Bridge.LoadAndRegisterAssemblyFrom(new File(getDataFolder(),
"VirtualComputerSender.j4n.dll"));
ccs.sendMessage("§bInititalizing VirtualBox interface...");
computer = new Computer();
ccs.sendMessage("§bLoading SketchMap...");
img = new BufferedImage(640, 480, BufferedImage.TYPE_INT_ARGB);
HashMap<Short, RelativeLocation> map = new HashMap<>();
for (int i = 0; i < 5; i++)
for (int j = 0; j < 4; j++)
map.put((short) (i * 4 + j), new RelativeLocation(i, j));
smap = new SketchMap(img, "Screen", 5, 4, false, map);
ccs.sendMessage("§bLoaded!");
DoStart();
} catch (final Exception e)
{
e.printStackTrace();
}
}
// Fired when plugin is disabled
@Override
public void onDisable()
{
ConsoleCommandSender ccs = getServer().getConsoleSender();
ccs.sendMessage("§aHuh.");
saveConfig();
}
private volatile BufferedImage img;
private volatile int taskid = -1;
public void Start(CommandSender sender)
{
sender.sendMessage("§eStarting computer...");
computer.Start();
sender.sendMessage("§eComputer started.");
DoStart();
}
public static int MouseSpeed = 1;
@SuppressWarnings("deprecation")
private void DoStart()
{
if (taskid == -1)
taskid = this.getServer().getScheduler()
.scheduleAsyncRepeatingTask(this, new Runnable()
{
public void run()
{
final int[] a = ((DataBufferInt) smap.image
.getRaster().getDataBuffer()).getData();
final int[] data = computer.GetScreenPixelColors();
System.arraycopy(data, 0, a, 0, data.length);
}
}, 1, 10);
if (getServer().getPluginManager().isPluginEnabled("Movecraft"))
{
this.getServer().getScheduler()
.scheduleSyncRepeatingTask(this, new Runnable()
{
public void run()
{
Craft[] crafts = CraftManager
.getInstance()
.getCraftsInWorld(Bukkit.getWorlds().get(0));
if (crafts == null)
return;
for (Craft c : crafts)
{
if (c.getType().getCraftName()
.equalsIgnoreCase("mouse"))
{
int dx = c.getLastDX();
// int dy = c.getLastDY();
int dz = c.getLastDZ();
if (Bukkit
.getWorlds()
.get(0)
.getBlockAt(c.getMinX(),
c.getMinY() - 1,
c.getMinZ()).getType() != Material.AIR
&& (dx != 0 || dz != 0))
UpdateMouse(null, dx * MouseSpeed, dz
* MouseSpeed, 0, 0, "");
c.setLastDX(0);
c.setLastDZ(0);
}
}
}
}, 1, 1);
}
getServer().getPluginManager().registerEvents(
new MouseLockerPlayerListener(), this);
}
public void Stop(CommandSender sender)
{
sender.sendMessage("§eStopping computer...");
computer.PowerOff();
sender.sendMessage("§eComputer stopped.");
}
@SuppressWarnings("deprecation")
public void PowerButton(CommandSender sender)
{
sender.sendMessage("§eStarting/stoppping computer...");
final CommandSender s = sender;
getServer().getScheduler().scheduleAsyncDelayedTask(this,
new Runnable()
{
@Override
public void run()
{
if (computer.PowerButton())
{
DoStart();
s.sendMessage("§eComputer started.");
} else
s.sendMessage("§ePowerbutton pressed.");
}
});
}
public void Reset(CommandSender sender)
{
sender.sendMessage("§eResetting computer...");
computer.Reset();
sender.sendMessage("§eComputer reset.");
}
public void FixScreen(CommandSender sender)
{
sender.sendMessage("§eFixing screen...");
computer.FixScreen();
sender.sendMessage("§eScreen fixed.");
}
public void PressKey(CommandSender sender, String key,
String stateorduration)
{
if (stateorduration.length() == 0)
computer.PressKey(key, (short) 0);
else if (stateorduration.equalsIgnoreCase("down"))
computer.PressKey(key, (short) -1);
else if (stateorduration.equalsIgnoreCase("up"))
computer.PressKey(key, (short) -2);
else
computer.PressKey(key, Short.parseShort(stateorduration));
}
public void UpdateMouse(CommandSender sender, int x, int y, int z, int w,
String mbs, boolean down)
{
if (down)
computer.UpdateMouse(x, y, z, w, mbs);
else
computer.UpdateMouse(x, y, z, w, "");
}
public void UpdateMouse(CommandSender sender, int x, int y, int z, int w,
String mbs)
{
UpdateMouse(sender, x, y, z, w, mbs, true);
UpdateMouse(sender, x, y, z, w, mbs, false);
}
private void addClassPath(final URL url) throws IOException
{
final URLClassLoader sysloader = (URLClassLoader) ClassLoader
.getSystemClassLoader();
final Class<URLClassLoader> sysclass = URLClassLoader.class;
try
{
final Method method = sysclass.getDeclaredMethod("addURL",
new Class[] { URL.class });
method.setAccessible(true);
method.invoke(sysloader, new Object[] { url });
} catch (final Throwable t)
{
t.printStackTrace();
throw new IOException("Error adding " + url
+ " to system classloader");
}
}
}

View file

@ -1,28 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VirtualComputerSender", "VirtualComputerSender\VirtualComputerSender.csproj", "{5EF12535-ACDF-4D60-8E32-087F5A277946}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5EF12535-ACDF-4D60-8E32-087F5A277946}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5EF12535-ACDF-4D60-8E32-087F5A277946}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5EF12535-ACDF-4D60-8E32-087F5A277946}.Debug|x64.ActiveCfg = Debug|x64
{5EF12535-ACDF-4D60-8E32-087F5A277946}.Debug|x64.Build.0 = Debug|x64
{5EF12535-ACDF-4D60-8E32-087F5A277946}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5EF12535-ACDF-4D60-8E32-087F5A277946}.Release|Any CPU.Build.0 = Release|Any CPU
{5EF12535-ACDF-4D60-8E32-087F5A277946}.Release|x64.ActiveCfg = Release|x64
{5EF12535-ACDF-4D60-8E32-087F5A277946}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
</startup>
</configuration>

View file

@ -1,145 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using VirtualBox;
namespace VirtualComputerSender //Copyright © NorbiPeti 2015-2016
{
public class Computer
{ //Self-note: Don't add/edit public members
private VirtualBoxClass vbox;
private Session session;
public Computer()
{
vbox = new VirtualBoxClass();
session = new Session();
}
public void Start()
{
var machine = (IMachine)vbox.Machines.GetValue(0);
var progress = machine.LaunchVMProcess(session, "headless", "");
progress.WaitForCompletion(100000);
var fb = new MCFrameBuffer(session.Console.Display);
Screen = fb.Screen; //fb.Screen is assigned on object creation
session.Console.Display.AttachFramebuffer(0, fb);
session.Console.Display.SetSeamlessMode(0);
}
public bool PowerButton()
{
if (session.State != SessionState.SessionState_Locked || session.Machine == null)
{
Start();
return true;
}
else
{
session.Console.PowerButton();
if (session.State != SessionState.SessionState_Locked)
Screen = null;
return false;
}
}
public void PowerOff()
{
if (session.State == SessionState.SessionState_Locked)
{
session.Console.PowerDown().WaitForCompletion(10000);
Screen = null;
}
}
public void Reset()
{
if (session.State == SessionState.SessionState_Locked)
session.Console.Reset();
}
private volatile int[] Screen;
public int[] GetScreenPixelColors()
{
if (Screen == null)
{
Screen = new int[640 * 480];
for (int i = 0; i < Screen.Length; i++)
Screen[i] = Color.Black.ToArgb();
}
return Screen;
}
[DllImport("user32.dll")]
static extern uint MapVirtualKey(uint uCode, uint uMapType);
const uint MAPVK_VK_TO_VSC = 0x00;
const uint MAPVK_VSC_TO_VK = 0x01;
const uint MAPVK_VK_TO_CHAR = 0x02;
const uint MAPVK_VSC_TO_VK_EX = 0x03;
const uint MAPVK_VK_TO_VSC_EX = 0x04;
public void PressKey(string key, short durationorstate)
{
if (session.State == SessionState.SessionState_Locked)
{
int code = 0;
if (key == "testall")
{
int x = 0;
session.Console.Keyboard.PutScancodes(new int[128].Select(i => x++).ToArray());
return;
}
//Virtual key code taken from Kennedy.ManagedHooks project
//Release key scan code concept taken from VirtualBox source code (KeyboardImpl.cpp:putCAD())
//+128
code = (int)MapVirtualKey((uint)(VirtualKeys)Enum.Parse(typeof(VirtualKeys), key, true), MAPVK_VK_TO_VSC);
int codeShift = (int)MapVirtualKey((uint)VirtualKeys.ShiftLeft, MAPVK_VK_TO_VSC);
int codeCtrl = (int)MapVirtualKey((uint)VirtualKeys.ControlLeft, MAPVK_VK_TO_VSC);
int codeAlt = (int)MapVirtualKey((uint)VirtualKeys.AltLeft, MAPVK_VK_TO_VSC);
if (durationorstate != -2) //<-- 2016.02.22.
session.Console.Keyboard.PutScancode(code);
if (durationorstate == 0 || durationorstate == -2)
session.Console.Keyboard.PutScancodes(new int[] { code + 128, codeCtrl + 128, codeShift + 128, codeAlt + 128 });
if (durationorstate > 0)
{
Timer t = new Timer();
t.Tick += delegate
{
session.Console.Keyboard.PutScancode(code + 128);
t.Stop();
};
t.Interval = durationorstate;
t.Start();
}
}
}
public void UpdateMouse(int x, int y, int z, int w, string mbs)
{
if (session.State != SessionState.SessionState_Locked)
return;
int state = 0;
if (mbs.Length > 0)
state = (int)(MouseBS)Enum.Parse(typeof(MouseBS), mbs, true);
session.Console.Mouse.PutMouseEvent(x, y, z, w, state);
}
public void FixScreen()
{
session.Console.Display.SetSeamlessMode(0);
session.Console.Display.SetVideoModeHint(0, 1, 0, 0, 0, 640, 480, 32);
}
~Computer()
{
if (session.State == SessionState.SessionState_Locked)
session.Machine.SaveState();
}
}
}

View file

@ -1,59 +0,0 @@
namespace VirtualComputerSender
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.panel1 = new System.Windows.Forms.Panel();
this.SuspendLayout();
//
// panel1
//
this.panel1.BackColor = System.Drawing.Color.Black;
this.panel1.Location = new System.Drawing.Point(12, 12);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(800, 600);
this.panel1.TabIndex = 0;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(861, 662);
this.Controls.Add(this.panel1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Panel panel1;
}
}

View file

@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using VirtualBox;
namespace VirtualComputerSender //Copyright © NorbiPeti 2015-2016
{
public partial class Form1: Form
{
private static Form1 Instance;
public Form1()
{
Instance = this;
InitializeComponent();
Screen = panel1.CreateGraphics();
var vbox = new VirtualBoxClass();
var session = new Session();
var machine = (IMachine)vbox.Machines.GetValue(0);
var progress = machine.LaunchVMProcess(session, "headless", "");
progress.WaitForCompletion(100000);
session.Console.Display.AttachFramebuffer(0, new NetFrameBuffer(session.Console.Display));
}
public static Graphics Screen;
}
}

View file

@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -1,179 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using VirtualBox;
namespace VirtualComputerSender //Copyright © NorbiPeti 2015-2016
{
public class MCFrameBuffer : IFramebuffer
{
private IDisplay Display;
private Timer LastFullUpdateTimer;
private UdpClient Client;
public MCFrameBuffer(IDisplay display)
{
Display = display;
LastFullUpdateTimer = new Timer();
LastFullUpdateTimer.Interval = 5000;
LastFullUpdateTimer.Elapsed += UpdateScreen;
Client = new UdpClient();
Client.Connect(new IPEndPoint(IPAddress.Loopback, 5896));
LastFullUpdateTimer.Start();
}
private void UpdateScreen(object sender, EventArgs args)
{
Display.InvalidateAndUpdateScreen(0);
}
public IntPtr Address
{
get
{
return IntPtr.Zero;
}
}
public const uint CBitsPerPixel = 32;
public uint BitsPerPixel
{
get
{
return CBitsPerPixel;
}
}
public uint BytesPerLine
{
get
{
return ScreenWidth;
}
}
public uint Height
{
get
{
Console.WriteLine("Screen height queried.");
return ScreenHeight;
}
}
public uint HeightReduction
{
get
{
return 2;
}
}
public IFramebufferOverlay Overlay
{
get
{
return null;
}
}
public BitmapFormat PixelFormat
{
get
{
return BitmapFormat.BitmapFormat_RGBA;
}
}
public uint Width
{
get
{
Console.WriteLine("Screen width queried.");
return ScreenWidth;
}
}
public long WinId
{
get
{
return 0;
}
}
public Array Capabilities
{
get
{
return new FramebufferCapabilities[] { FramebufferCapabilities.FramebufferCapabilities_UpdateImage };
}
}
public uint GetVisibleRegion(ref byte aRectangles, uint aCount)
{
throw new InvalidOperationException("This should not be used.");
}
public void NotifyUpdate(uint aX, uint aY, uint aWidth, uint aHeight)
{
}
public void ProcessVHWACommand(ref byte aCommand)
{
}
public void SetVisibleRegion(ref byte aRectangles, uint aCount)
{
}
public int VideoModeSupported(uint aWidth, uint aHeight, uint aBpp)
{
return 1;
}
public const int ScreenWidth = 640;
public const int ScreenHeight = 480;
public volatile int[] Screen = new int[640 * 480];
public void NotifyUpdateImage(uint aX, uint aY, uint aWidth, uint aHeight, Array aImage)
{
Task.Run(() =>
{
var img = (byte[])aImage;
int x = 0;
for (int j = (int)aY; j < aHeight && j < ScreenHeight; j++)
{
for (int i = (int)aX; i < aWidth && i < ScreenWidth; i++)
{
if (x + 4 > aImage.Length)
return;
Screen[640 * j + i] = Color.FromArgb(img[x + 2], img[x + 1], img[x]).ToArgb();
x += 4;
}
x += (int)aX * 4;
int add = ((int)(aX + aWidth) - ScreenWidth);
if (add > 0)
x += add * 4;
}
});
}
public void NotifyChange(uint aScreenId, uint aXOrigin, uint aYOrigin, uint aWidth, uint aHeight)
{
}
public void Notify3DEvent(uint aType, Array aData)
{
}
}
}

View file

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VirtualComputerSender
{
public enum MouseBS
{
LeftButton = 1,
MiddleButton = 4,
RightButton = 2,
WheelDown = 16,
WheelUp = 8,
XButton1 = 32,
XButton2 = 64
}
}

View file

@ -1,195 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using VirtualBox;
namespace VirtualComputerSender //Copyright © NorbiPeti 2015-2016
{
public class NetFrameBuffer : IFramebuffer
{
private IDisplay Display;
private Timer LastFullUpdateTimer;
private UdpClient Client;
public NetFrameBuffer(IDisplay display)
{
//address = Marshal.AllocHGlobal(1440 * 900 * 4);
Display = display;
LastFullUpdateTimer = new Timer();
LastFullUpdateTimer.Interval = 60000;
LastFullUpdateTimer.Elapsed += UpdateScreen;
Client = new UdpClient();
Client.Connect(new IPEndPoint(IPAddress.Loopback, 5896));
LastFullUpdateTimer.Start();
}
private void UpdateScreen(object sender, EventArgs args)
{
Display.InvalidateAndUpdateScreen(0);
}
public IntPtr Address
{
get
{
return IntPtr.Zero;
}
}
public const uint CBitsPerPixel = 32;
public uint BitsPerPixel
{
get
{
return CBitsPerPixel;
}
}
public uint BytesPerLine
{
get
{
return ScreenWidth;
}
}
public uint Height
{
get
{
return ScreenHeight;
}
}
public uint HeightReduction
{
get
{
return 2;
}
}
public IFramebufferOverlay Overlay
{
get
{
return null;
}
}
public BitmapFormat PixelFormat
{
get
{
return BitmapFormat.BitmapFormat_RGBA;
}
}
public uint Width
{
get
{
return ScreenWidth;
}
}
public long WinId
{
get
{
return 0;
}
}
public Array Capabilities
{
get
{
return new FramebufferCapabilities[] { FramebufferCapabilities.FramebufferCapabilities_UpdateImage };
}
}
public uint GetVisibleRegion(ref byte aRectangles, uint aCount)
{
throw new InvalidOperationException("This should not be used.");
}
public void NotifyUpdate(uint aX, uint aY, uint aWidth, uint aHeight)
{
//throw new InvalidOperationException("This should not be used. (Only UpdateImage.)");
}
public void ProcessVHWACommand(ref byte aCommand)
{
}
public void SetVisibleRegion(ref byte aRectangles, uint aCount)
{
}
public int VideoModeSupported(uint aWidth, uint aHeight, uint aBpp)
{
return 1;
}
public const int ScreenWidth = 640;
public const int ScreenHeight = 480;
private Color[,] Screen = new Color[640, 480];
public void NotifyUpdateImage(uint aX, uint aY, uint aWidth, uint aHeight, Array aImage)
{
var img = aImage.Cast<byte>().ToArray();
int x = 0;
//if (aImage.Length > 1152000)
//Form1.Screen.Clear(Color.Black);
//else
//{
//Display.SetSeamlessMode(1);
/*if (aWidth == 800 && aHeight == 600)
Display.SetVideoModeHint(0, 1, 0, 0, 0, NetFrameBuffer.ScreenWidth, NetFrameBuffer.ScreenHeight, NetFrameBuffer.CBitsPerPixel);*/
for (int j = (int)aY; j < aHeight && j < ScreenHeight; j++)
{
for (int i = (int)aX; i < aWidth && i < ScreenWidth; i++)
{
if (x + 4 > aImage.Length)
return;
//Form1.Screen.FillRectangle(new SolidBrush(Color.FromArgb(255, img[x + 2], img[x + 1], img[x])), i, j, 1, 1);
Screen[i, j] = Color.FromArgb(img[x + 2], img[x + 1], img[x]);
x += 4;
}
x += (int)aX * 4;
int add = ((int)(aX + aWidth) - ScreenWidth);
if (add > 0)
x += add * 4;
}
/*var ms = new MemoryStream();
var bw = new BinaryWriter(ms);
bw.Write(Convert.ToInt32(aX));
bw.Write(Convert.ToInt32(aY));
bw.Write(Convert.ToInt32(aWidth));
bw.Write(Convert.ToInt32(aHeight));
bw.Write(img);
bw.Flush();
Client.Send(BitConverter.GetBytes(Convert.ToInt32(ms.Length)), 4);
Client.Send(ms.ToArray(), Convert.ToInt32(ms.Length));
bw.Close();*/
//}
}
public void NotifyChange(uint aScreenId, uint aXOrigin, uint aYOrigin, uint aWidth, uint aHeight)
{
}
public void Notify3DEvent(uint aType, Array aData)
{
}
}
}

View file

@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace VirtualComputerSender
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}

View file

@ -1,63 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace VirtualComputerSender.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("VirtualComputerSender.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View file

@ -1,117 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -1,26 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace VirtualComputerSender.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View file

@ -1,7 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View file

@ -1,159 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{5EF12535-ACDF-4D60-8E32-087F5A277946}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>VirtualComputerSender</RootNamespace>
<AssemblyName>VirtualComputerSender</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<IsWebBootstrapper>false</IsWebBootstrapper>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\..\TheButtonMCAutoFlairProto\Spigot server\plugins\VirtualComputer\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Computer.cs" />
<Compile Include="Form1.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<Compile Include="MCFrameBuffer.cs" />
<Compile Include="MouseBS.cs" />
<Compile Include="NetFrameBuffer.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="VirtualKeys.cs" />
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.5.2">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.5.2 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<COMReference Include="VirtualBox">
<Guid>{D7569351-1750-46F0-936E-BD127D5BC264}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>3</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>False</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -1,129 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace VirtualComputerSender
{
internal enum VirtualKeys
{
Back = 0x08,
Tab = 0x09,
Clear = 0x0C,
Return = 0x0D,
ShiftLeft = 0xA0,
ControlLeft = 0xA2,
ShiftRight = 0xA1,
ControlRight = 0xA3,
AltLeft = 0xA4,
AltRight = 0xA5,
Menu = 0x12,
Pause = 0x13,
Capital = 0x14,
Escape = 0x1B,
Space = 0x20,
Prior = 0x21,
Next = 0x22,
End = 0x23,
Home = 0x24,
Left = 0x25,
Up = 0x26,
Right = 0x27,
Down = 0x28,
Select = 0x29,
Print = 0x2A,
Execute = 0x2B,
Snapshot = 0x2C,
Insert = 0x2D,
Delete = 0x2E,
Help = 0x2F,
D0 = 0x30,
D1 = 0x31,
D2 = 0x32,
D3 = 0x33,
D4 = 0x34,
D5 = 0x35,
D6 = 0x36,
D7 = 0x37,
D8 = 0x38,
D9 = 0x39,
A = 0x41,
B = 0x42,
C = 0x43,
D = 0x44,
E = 0x45,
F = 0x46,
G = 0x47,
H = 0x48,
I = 0x49,
J = 0x4A,
K = 0x4B,
L = 0x4C,
M = 0x4D,
N = 0x4E,
O = 0x4F,
P = 0x50,
Q = 0x51,
R = 0x52,
S = 0x53,
T = 0x54,
U = 0x55,
V = 0x56,
W = 0x57,
X = 0x58,
Y = 0x59,
Z = 0x5A,
LWindows = 0x5B,
RWindows = 0x5C,
Apps = 0x5D,
NumPad0 = 0x60,
NumPad1 = 0x61,
NumPad2 = 0x62,
NumPad3 = 0x63,
NumPad4 = 0x64,
NumPad5 = 0x65,
NumPad6 = 0x66,
NumPad7 = 0x67,
NumPad8 = 0x68,
NumPad9 = 0x69,
Multiply = 0x6A,
Add = 0x6B,
Separator = 0x6C,
Subtract = 0x6D,
Decimal = 0x6E,
Divide = 0x6F,
F1 = 0x70,
F2 = 0x71,
F3 = 0x72,
F4 = 0x73,
F5 = 0x74,
F6 = 0x75,
F7 = 0x76,
F8 = 0x77,
F9 = 0x78,
F10 = 0x79,
F11 = 0x7A,
F12 = 0x7B,
F13 = 0x7C,
F14 = 0x7D,
F15 = 0x7E,
F16 = 0x7F,
F17 = 0x80,
F18 = 0x81,
F19 = 0x82,
F20 = 0x83,
F21 = 0x84,
F22 = 0x85,
F23 = 0x86,
F24 = 0x87,
NumLock = 0x90,
Scroll = 0x91,
}
}

View file

@ -0,0 +1,34 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26403.7
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VirtualComputerWindows", "VirtualComputerWindows\VirtualComputerWindows.csproj", "{5E734F17-FF74-4187-A6E4-B7E1DAB272F8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5E734F17-FF74-4187-A6E4-B7E1DAB272F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5E734F17-FF74-4187-A6E4-B7E1DAB272F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5E734F17-FF74-4187-A6E4-B7E1DAB272F8}.Debug|x64.ActiveCfg = Debug|x64
{5E734F17-FF74-4187-A6E4-B7E1DAB272F8}.Debug|x64.Build.0 = Debug|x64
{5E734F17-FF74-4187-A6E4-B7E1DAB272F8}.Debug|x86.ActiveCfg = Debug|x86
{5E734F17-FF74-4187-A6E4-B7E1DAB272F8}.Debug|x86.Build.0 = Debug|x86
{5E734F17-FF74-4187-A6E4-B7E1DAB272F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5E734F17-FF74-4187-A6E4-B7E1DAB272F8}.Release|Any CPU.Build.0 = Release|Any CPU
{5E734F17-FF74-4187-A6E4-B7E1DAB272F8}.Release|x64.ActiveCfg = Release|x64
{5E734F17-FF74-4187-A6E4-B7E1DAB272F8}.Release|x64.Build.0 = Release|x64
{5E734F17-FF74-4187-A6E4-B7E1DAB272F8}.Release|x86.ActiveCfg = Release|x86
{5E734F17-FF74-4187-A6E4-B7E1DAB272F8}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using VirtualBox;
namespace VirtualComputerWindows
{
public static class Exports
{
[DllImport(@"C:\Program Files\Oracle\VirtualBox\VBoxRT.dll", CallingConvention = CallingConvention.StdCall)]
private static extern void RTR3InitExe(int argc, string argv, int zeroflags);
/*[DllImport(@"C:\Program Files\Oracle\VirtualBox\VBoxVMM.dll", CallingConvention = CallingConvention.StdCall)]
private static extern int VMMDoHmTest(IntPtr vmstruct);*/
private static VirtualBoxClient vbc;
public static async Task<IVirtualBox> Init() => await Task.Run(() =>
{
try
{
//Environment.SetEnvironmentVariable("VBOX_HOME", @"C:\Program Files\Oracle\VirtualBox\");
//TODO: Only finds the VBoxVMM.dll when placed in the VirtualBox dir (regardless of working dir)
//Even then there are hardening issues: VERR_SUPDRV_NOT_BUDDING_VM_PROCESS_1
//https://www.virtualbox.org/svn/vbox/trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
vbc = new VirtualBoxClientClass();
var vbox = vbc.VirtualBox;
RTR3InitExe(0, "", 0);
var ses = vbc.Session;
var machine = vbox.Machines.GetValue(0) as IMachine;
ses.Name = "minecraft";
machine.LockMachine(ses, LockType.LockType_VM);
Console.WriteLine("Locking...");
while (ses.State != SessionState.SessionState_Locked) ;
Console.WriteLine("Locked");
machine = ses.Machine;
Console.WriteLine("Powering up...");
ses.Console.PowerUp().WaitForCompletion(10000);
Console.WriteLine("Framebuffer attach");
ses.Console.Display.AttachFramebuffer(0, new VBFB(ses.Console.Display));
return vbox;
}
catch(Exception e)
{
Console.WriteLine(e);
Console.ReadLine();
return null;
}
});
public static void Main()
{
Init();
Console.ReadLine();
}
}
}

View file

@ -2,34 +2,34 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("VirtualComputerSender")]
[assembly: AssemblyTitle("VirtualComputerWindows")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("VirtualComputerSender")]
[assembly: AssemblyCopyright("Copyright © NorbiPeti 2015-2016")]
[assembly: AssemblyProduct("VirtualComputerWindows")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("5ef12535-acdf-4d60-8e32-087f5a277946")]
[assembly: Guid("5e734f17-ff74-4187-a6e4-b7e1dab272f8")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]

View file

@ -0,0 +1,75 @@
using System;
using VirtualBox;
namespace VirtualComputerWindows
{
internal class VBFB : IFramebuffer
{
private IDisplay display;
public VBFB(IDisplay display)
{
this.display = display;
}
public void NotifyUpdate(uint aX, uint aY, uint aWidth, uint aHeight)
{
Console.WriteLine("Update: " + aX + " " + aY + " " + aWidth + " " + aHeight);
}
public void NotifyUpdateImage(uint aX, uint aY, uint aWidth, uint aHeight, Array aImage)
{
Console.WriteLine("UpdateImage: " + aX + " " + aY + " " + aWidth + " " + aHeight);
}
public void NotifyChange(uint aScreenId, uint aXOrigin, uint aYOrigin, uint aWidth, uint aHeight)
{
Console.WriteLine("Change: " + aXOrigin + " " + aYOrigin + " " + aWidth + " " + aHeight);
display.QuerySourceBitmap(0, out var isd);
var addr = new IntPtr();
isd.QueryBitmapInfo(addr, out var w, out var h, out var bpp, out var bpl, out var bf);
Console.WriteLine("Bitmap info: " + addr + " " + w + " " + h + " " + bpp + " " + bpl + " " + bf);
}
public int VideoModeSupported(uint aWidth, uint aHeight, uint aBpp)
{
return 1;
}
public uint GetVisibleRegion(ref byte aRectangles, uint aCount)
{
return aCount;
}
public void SetVisibleRegion(ref byte aRectangles, uint aCount)
{
}
public void ProcessVHWACommand(ref byte aCommand, int aEnmCmd, int aFromGuest)
{
}
public void Notify3DEvent(uint aType, Array aData)
{
}
public uint Width => 640;
public uint Height => 480;
public uint BitsPerPixel => 32;
public uint BytesPerLine => 640 * 4;
public BitmapFormat PixelFormat => BitmapFormat.BitmapFormat_BGRA;
public uint HeightReduction => 0;
public IFramebufferOverlay Overlay => null;
public long WinId => 0;
//public Array Capabilities => new[] { FramebufferCapabilities.FramebufferCapabilities_UpdateImage };
public Array Capabilities => new FramebufferCapabilities[] { };
}
}

View file

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{5E734F17-FF74-4187-A6E4-B7E1DAB272F8}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>VirtualComputerWindows</RootNamespace>
<AssemblyName>VirtualComputerWindows</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
<DllExportNamespace>VirtualComputerWindows</DllExportNamespace>
<DllExportDDNSCecil>true</DllExportDDNSCecil>
<DllExportSkipOnAnyCpu>false</DllExportSkipOnAnyCpu>
<DllExportOrdinalsBase>1</DllExportOrdinalsBase>
<DllExportGenExpLib>false</DllExportGenExpLib>
<DllExportOurILAsm>false</DllExportOurILAsm>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Exports.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="VBFB.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<COMReference Include="VirtualBox">
<Guid>{D7569351-1750-46F0-936E-BD127D5BC264}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>3</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>False</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="../packages/DllExport.1.5.2/tools/net.r_eg.DllExport.targets" Condition="Exists('../packages/DllExport.1.5.2/tools/net.r_eg.DllExport.targets')" />
</Project>

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.InteropServices" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net462" />
</packages>

3
libpxc/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
obj/
out/

11
libpxc/makefile Normal file
View file

@ -0,0 +1,11 @@
CC=gcc
# CFLAGS=-I.
pxct: pxct.c pxc
$(CC) -Wall pxct.c -Lout -lpxc -Wl,-rpath=out -o out/pxct
pxc: pxc.c
$(CC) -Wall -O4 -c -fpic pxc.c -o obj/pxc.o
$(CC) -Wall -shared obj/pxc.o -o out/libpxc.so
cp out/libpxc.so ../

183
libpxc/pxc.c Normal file
View file

@ -0,0 +1,183 @@
#include <stdio.h>
#include <stdlib.h>
#define MAPSIZE 128
#if MAPSIZE>255
#error MAPSIZE must be a short value
#endif
//---------------------------------------------------------------------
// http://www.pixelbeat.org/programming/gcc/static_assert.html
#define ct_assert(e) {enum { ct_assert_value = 1/(!!(e)) };}
//---------------------------------------------------------------------
typedef long long int addr;
typedef struct { //RGB
unsigned int red : 8;
unsigned int green : 8;
unsigned int blue : 8;
} Color; //Used for Bukkit's initializers (for simplicity)
typedef struct { //BGRA
unsigned int blue : 8;
unsigned int green : 8;
unsigned int red : 8;
unsigned int alpha : 8;
} NativeColor; //Used for the screen data
char matchColor(NativeColor nc);
void* image=NULL;
void* maps=NULL; //Per map data (1st map, second map etc.)
short width, height, mapcx, mapcy;
void setSource(addr address, short w, short h, short mcx, short mcy) {
ct_assert(sizeof(char)==1); //Compile-time assert
ct_assert(sizeof(Color)==4); //Compile-time assert
image=(void*)address;
maps=malloc(MAPSIZE*MAPSIZE*mcx*mcy); //1 byte per pixel
width=w, height=h, mapcx=mcx, mapcy=mcy;
printf("PXC: w=%d h=%d mcx=%d mcy=%d\n", w, h, mcx, mcy);
}
NativeColor* getNativeColor(int x, int y) {
if(x<0||x>width||y<0||y>height) return NULL;
return ((NativeColor*)image)+x+y*width;
}
char* getMapColor(int x, int y) {
if(x<0||x>width||y<0||y>height) return NULL;
int mc=x/MAPSIZE+y/MAPSIZE*mapcx;
return maps+mc*MAPSIZE*MAPSIZE; //TODO: Use
}
//May return 0
void* updateAndGetMap(int x, int y, int w, int h, int** out_changed) { //TODO: Support the parameters
if(image==NULL || maps==NULL) return 0;
for(int l=y; l<y+h; l++) {
//printf("PXC: l=%d\n", l);
for(int k=x; k<x+w; k++) {
//printf("PXC: k=%d\n", k);
char *mapp=getMapColor(k, l);
char color=matchColor(*getNativeColor(k, l));
//NativeColor x={.red=0, .green=0, .blue=255, .alpha=255};
//*mapp=matchColor(x);
*mapp=color;
//printf("PXC: mapp: %d %d - %x\n", k, l, *mapp); //TODO: The bottom of the image
//printf("PXC: mapcx: %d mapcy: %d\n", k, l); //TODO: Has nothing
}
}
printf("PXC: ret maps=%p\n", maps);
return maps; //TODO: Return changed only
}
const Color colors[] = {
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
{89, 125, 39}, {109, 153, 48}, {127, 178, 56}, {67, 94, 29},
{174, 164, 115}, {213, 201, 140}, {247, 233, 163}, {130, 123, 86},
{140, 140, 140}, {171, 171, 171}, {199, 199, 199}, {105, 105, 105},
{180, 0, 0}, {220, 0, 0}, {255, 0, 0}, {135, 0, 0},
{112, 112, 180}, {138, 138, 220}, {160, 160, 255}, {84, 84, 135},
{117, 117, 117}, {144, 144, 144}, {167, 167, 167}, {88, 88, 88},
{0, 87, 0}, {0, 106, 0}, {0, 124, 0}, {0, 65, 0},
{180, 180, 180}, {220, 220, 220}, {255, 255, 255}, {135, 135, 135},
{115, 118, 129}, {141, 144, 158}, {164, 168, 184}, {86, 88, 97},
{106, 76, 54}, {130, 94, 66}, {151, 109, 77}, {79, 57, 40},
{79, 79, 79}, {96, 96, 96}, {112, 112, 112}, {59, 59, 59},
{45, 45, 180}, {55, 55, 220}, {64, 64, 255}, {33, 33, 135},
{100, 84, 50}, {123, 102, 62}, {143, 119, 72}, {75, 63, 38},
{180, 177, 172}, {220, 217, 211}, {255, 252, 245}, {135, 133, 129},
{152, 89, 36}, {186, 109, 44}, {216, 127, 51}, {114, 67, 27},
{125, 53, 152}, {153, 65, 186}, {178, 76, 216}, {94, 40, 114},
{72, 108, 152}, {88, 132, 186}, {102, 153, 216}, {54, 81, 114},
{161, 161, 36}, {197, 197, 44}, {229, 229, 51}, {121, 121, 27},
{89, 144, 17}, {109, 176, 21}, {127, 204, 25}, {67, 108, 13},
{170, 89, 116}, {208, 109, 142}, {242, 127, 165}, {128, 67, 87},
{53, 53, 53}, {65, 65, 65}, {76, 76, 76}, {40, 40, 40},
{108, 108, 108}, {132, 132, 132}, {153, 153, 153}, {81, 81, 81},
{53, 89, 108}, {65, 109, 132}, {76, 127, 153}, {40, 67, 81},
{89, 44, 125}, {109, 54, 153}, {127, 63, 178}, {67, 33, 94},
{36, 53, 125}, {44, 65, 153}, {51, 76, 178}, {27, 40, 94},
{72, 53, 36}, {88, 65, 44}, {102, 76, 51}, {54, 40, 27},
{72, 89, 36}, {88, 109, 44}, {102, 127, 51}, {54, 67, 27},
{108, 36, 36}, {132, 44, 44}, {153, 51, 51}, {81, 27, 27},
{17, 17, 17}, {21, 21, 21}, {25, 25, 25}, {13, 13, 13},
{176, 168, 54}, {215, 205, 66}, {250, 238, 77}, {132, 126, 40},
{64, 154, 150}, {79, 188, 183}, {92, 219, 213}, {48, 115, 112},
{52, 90, 180}, {63, 110, 220}, {74, 128, 255}, {39, 67, 135},
{0, 153, 40}, {0, 187, 50}, {0, 217, 58}, {0, 114, 30},
{91, 60, 34}, {111, 74, 42}, {129, 86, 49}, {68, 45, 25},
{79, 1, 0}, {96, 1, 0}, {112, 2, 0}, {59, 1, 0},
{147, 124, 113}, {180, 152, 138}, {209, 177, 161}, {110, 93, 85},
{112, 57, 25}, {137, 70, 31}, {159, 82, 36}, {84, 43, 19},
{105, 61, 76}, {128, 75, 93}, {149, 87, 108}, {78, 46, 57},
{79, 76, 97}, {96, 93, 119}, {112, 108, 138}, {59, 57, 73},
{131, 93, 25}, {160, 114, 31}, {186, 133, 36}, {98, 70, 19},
{72, 82, 37}, {88, 100, 45}, {103, 117, 53}, {54, 61, 28},
{112, 54, 55}, {138, 66, 67}, {160, 77, 78}, {84, 40, 41},
{40, 28, 24}, {49, 35, 30}, {57, 41, 35}, {30, 21, 18},
{95, 75, 69}, {116, 92, 84}, {135, 107, 98}, {71, 56, 51},
{61, 64, 64}, {75, 79, 79}, {87, 92, 92}, {46, 48, 48},
{86, 51, 62}, {105, 62, 75}, {122, 73, 88}, {64, 38, 46},
{53, 43, 64}, {65, 53, 79}, {76, 62, 92}, {40, 32, 48},
{53, 35, 24}, {65, 43, 30}, {76, 50, 35}, {40, 26, 18},
{53, 57, 29}, {65, 70, 36}, {76, 82, 42}, {40, 43, 22},
{100, 42, 32}, {122, 51, 39}, {142, 60, 46}, {75, 31, 24},
{26, 15, 11}, {31, 18, 13}, {37, 22, 16}, {19, 11, 8}
};
//Code from Bukkit's MapPalette class
double getDistance(Color c1, Color c2) {
double rmean = (c1.red + c2.red) / 2.0;
double r = c1.red - c2.red;
double g = c1.green - c2.green;
int b = c1.blue - c2.blue;
double weightR = 2 + rmean / 256.0;
double weightG = 4.0;
double weightB = 2 + (255 - rmean) / 256.0;
return weightR * r * r + weightG * g * g + weightB * b * b;
}
//Code from Bukkit's MapPalette class
char matchColor(NativeColor nc) {
//if (nc.alpha < 128) return 0;
Color color={.red=nc.red, .green=nc.green, .blue=nc.blue};
char index = 0;
double best = -1;
for (short i = 4; i < sizeof(colors)/sizeof(Color); i++) {
double distance = getDistance(color, colors[i]);
if (distance < best || best == -1) {
best = distance;
index = i;
}
}
// Minecraft has 143 colors, some of which have negative byte representations
//return (byte) (index < 128 ? index : -129 + (index - 127));
return index;
}
//Testing only
int convert(int px[], int *out[]) {
printf("convert...\n");
printf("px0: %d\n", px[0]);
*out[0]=19;
return 0;
}
void __attribute__ ((constructor)) initLibrary(void) {
//
// Function that is called when the library is loaded
//
printf("Library is initialized\n");
}
void __attribute__ ((destructor)) cleanUpLibrary(void) {
//
// Function that is called when the library is »closed«.
//
printf("Library is exited\n");
}

31
libpxc/pxct.c Normal file
View file

@ -0,0 +1,31 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* https://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html
gcc -Wall -c -fpic pxc.c
gcc -Wall -shared pxc.o -o pxc.so
gcc -Wall pxct.c -L. -lpxc -Wl,-rpath=.
*/
int convert(int px[], int *out[]);
typedef long long int addr;
void setSource(addr address, short w, short h, short mcx, short mcy);
void* updateAndGetMap(int x, int y, int w, int h, int** out_changed);
int main() {
printf("Setting source...");
void* p = malloc(640*480*4);
setSource((addr)p, 640, 480, 5, 4);
printf("Adding random values...\n");
srand(time(NULL));
unsigned int* xp=p;
for(int i=0; i<640*480; i++)
*(xp++)=rand();
printf("Updating map...");
void* x=updateAndGetMap(0, 0, 320, 240, NULL);
free(p);
return 0;
}