Fixes for Windows and MSCOM implementation
Still can't pass Java objects to COM
This commit is contained in:
parent
586ab05033
commit
580d48d7d0
15 changed files with 295 additions and 22 deletions
|
@ -9,6 +9,7 @@
|
|||
<version>2.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<build>
|
||||
<finalName>VirtualComputer</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
|
@ -36,7 +37,15 @@
|
|||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>9</source>
|
||||
<target>9</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency> <!-- This has the least additional (platform-dependent) code -->
|
||||
|
@ -55,7 +64,7 @@
|
|||
<version>2.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>sznp.virtualcomputer</groupId>
|
||||
<groupId>io.github.NorbiPeti</groupId>
|
||||
<artifactId>VirtualComputer-MSCOM</artifactId>
|
||||
<version>2.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
@ -87,7 +96,7 @@
|
|||
<artifactSet>
|
||||
<excludes>
|
||||
<exclude>org.virtualbox:VirtualBox-MSCOM</exclude>
|
||||
<exclude>sznp.virtualcomputer:VirtualComputer-MSCOM</exclude>
|
||||
<exclude>io.github.NorbiPeti:VirtualComputer-MSCOM</exclude>
|
||||
</excludes>
|
||||
</artifactSet>
|
||||
<!-- <minimizeJar>true</minimizeJar> -->
|
||||
|
@ -130,7 +139,7 @@
|
|||
<artifactSet>
|
||||
<excludes>
|
||||
<exclude>org.virtualbox:VirtualBox</exclude>
|
||||
<exclude>sznp.virtualcomputer:VirtualComputer-XPCOM</exclude>
|
||||
<exclude>io.github.NorbiPeti:VirtualComputer-XPCOM</exclude>
|
||||
</excludes>
|
||||
</artifactSet>
|
||||
</configuration>
|
||||
|
|
|
@ -273,7 +273,8 @@ public final class Computer {
|
|||
GPURenderer.update(new byte[1], 0, 0, 0, 0, 640, 480); //Black screen
|
||||
stopEvents();
|
||||
MouseLockerPlayerListener.computerStop();
|
||||
framebuffer.stop();
|
||||
if (framebuffer != null)
|
||||
framebuffer.stop();
|
||||
}
|
||||
|
||||
public void stopEvents() {
|
||||
|
@ -286,7 +287,8 @@ public final class Computer {
|
|||
|
||||
public void pluginDisable(CommandSender ccs) {
|
||||
stopEvents();
|
||||
framebuffer.stop();
|
||||
if (framebuffer != null)
|
||||
framebuffer.stop();
|
||||
if (session.getState() == SessionState.Locked) {
|
||||
if (session.getMachine().getState().equals(MachineState.Running)) {
|
||||
ccs.sendMessage("§aSaving machine state...");
|
||||
|
|
|
@ -33,7 +33,7 @@ public class PluginMain extends JavaPlugin {
|
|||
* Only used if {@link #direct} is false.
|
||||
*/
|
||||
public static ByteBuffer allpixels; // It's set on each change
|
||||
private static ArrayList<IRenderer> renderers = new ArrayList<>();
|
||||
private static final ArrayList<IRenderer> renderers = new ArrayList<>();
|
||||
/*
|
||||
* Only used if {@link #direct} is true.
|
||||
*/
|
||||
|
@ -50,14 +50,23 @@ public class PluginMain extends JavaPlugin {
|
|||
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";
|
||||
String osname = System.getProperty("os.name").toLowerCase();
|
||||
final boolean windows;
|
||||
String vbpath;
|
||||
{
|
||||
boolean win = false;
|
||||
vbpath = osname.contains("mac")
|
||||
? "/Applications/VirtualBox.app/Contents/MacOS"
|
||||
: (win = osname.contains("windows"))
|
||||
? "C:\\Program Files\\Oracle\\VirtualBox"
|
||||
: "/opt/virtualbox";
|
||||
windows = win;
|
||||
}
|
||||
//noinspection ConstantConditions
|
||||
Predicate<File> notGoodDir= ff->!ff.isDirectory() || Arrays.stream(ff.list()).noneMatch(s -> s.contains("xpcom"));
|
||||
Predicate<File> notGoodDir = ff -> !ff.isDirectory() || (!windows && 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)))
|
||||
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);
|
||||
|
@ -66,10 +75,12 @@ public class PluginMain extends JavaPlugin {
|
|||
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);
|
||||
Utils.addLibraryPath(vbpath); //TODO: Jacob DLL must be in the server folder
|
||||
final VirtualBoxManager manager = VirtualBoxManager.createInstance(getDataFolder().getAbsolutePath());
|
||||
VBoxLib vbl = LibraryLoader.create(VBoxLib.class).load("vboxjxpcom"); //TODO: Test for MSCOM
|
||||
vbl.RTR3InitExe(0, "", 0);
|
||||
if (!windows) {
|
||||
VBoxLib vbl = LibraryLoader.create(VBoxLib.class).load("vboxjxpcom");
|
||||
vbl.RTR3InitExe(0, "", 0);
|
||||
}
|
||||
IVirtualBox vbox = manager.getVBox();
|
||||
(listener = new VBoxEventHandler()).registerTo(vbox.getEventSource());
|
||||
new Computer(this, manager, vbox); //Saves itself
|
||||
|
@ -80,12 +91,12 @@ public class PluginMain extends JavaPlugin {
|
|||
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;
|
||||
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;
|
||||
direct = false;
|
||||
e.printStackTrace();
|
||||
ccs.sendMessage("§6Compatibility error, using slower renderer");
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package sznp.virtualcomputer.util;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
|
||||
|
@ -11,6 +13,14 @@ public class Utils {
|
|||
* @throws Exception
|
||||
*/
|
||||
public static void addLibraryPath(String pathToAdd) throws Exception {
|
||||
try {
|
||||
addLibraryPathOld(pathToAdd);
|
||||
} catch (Throwable t) {
|
||||
addLibraryPathNew(pathToAdd);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addLibraryPathOld(String pathToAdd) throws Exception {
|
||||
final Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths");
|
||||
usrPathsField.setAccessible(true);
|
||||
|
||||
|
@ -29,4 +39,14 @@ public class Utils {
|
|||
newPaths[newPaths.length - 1] = pathToAdd;
|
||||
usrPathsField.set(null, newPaths);
|
||||
}
|
||||
|
||||
private static void addLibraryPathNew(String pathToAdd) throws Exception {
|
||||
MethodHandles.Lookup cl = MethodHandles.privateLookupIn(ClassLoader.class, MethodHandles.lookup());
|
||||
VarHandle sys_paths = cl.findStaticVarHandle(ClassLoader.class, "sys_paths", String[].class);
|
||||
final String[] paths = (String[]) sys_paths.get();
|
||||
|
||||
final String[] newPaths = Arrays.copyOf(paths, paths.length + 1);
|
||||
newPaths[newPaths.length - 1] = pathToAdd;
|
||||
sys_paths.set((Object) newPaths);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
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>sznp.virtualcomputer</groupId>
|
||||
<artifactId>VirtualComputer-MSCOM</artifactId>
|
||||
<version>2.1-SNAPSHOT</version>
|
||||
|
||||
|
@ -22,6 +21,11 @@
|
|||
<optional>true
|
||||
</optional> <!-- https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.jacob-project</groupId>
|
||||
<artifactId>jacob</artifactId>
|
||||
<version>1.19</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,97 @@
|
|||
package sznp.virtualcomputer;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.virtualbox_6_1.BitmapFormat;
|
||||
import org.virtualbox_6_1.FramebufferCapabilities;
|
||||
import org.virtualbox_6_1.IFramebufferOverlay;
|
||||
import sznp.virtualcomputer.util.IMCFrameBuffer;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class COMFrameBuffer {
|
||||
private final IMCFrameBuffer frameBuffer;
|
||||
|
||||
public long getBitsPerPixel() {
|
||||
return 32;
|
||||
}
|
||||
|
||||
public long getBytesPerLine() {
|
||||
return 640L;
|
||||
}
|
||||
|
||||
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[]{};
|
||||
}
|
||||
}
|
||||
|
||||
public long getHeight() {
|
||||
return 480;
|
||||
}
|
||||
|
||||
public long getHeightReduction() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public IFramebufferOverlay getOverlay() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public long getPixelFormat() {
|
||||
return BitmapFormat.BGRA.value();
|
||||
}
|
||||
|
||||
public long getVisibleRegion(byte arg0, long arg1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long getWidth() {
|
||||
return 640;
|
||||
}
|
||||
|
||||
public long getWinId() {
|
||||
return 0; // Zero means no win id
|
||||
}
|
||||
|
||||
public void notify3DEvent(long type, byte[] data) {
|
||||
System.out.println("3D event! " + type + " - " + Arrays.toString(data));
|
||||
}
|
||||
|
||||
public void notifyChange(long screenId, long xOrigin, long yOrigin, long width, long height) {
|
||||
frameBuffer.notifyChange(screenId, xOrigin, yOrigin, width, height);
|
||||
}
|
||||
|
||||
public void notifyUpdate(long x, long y, long width, long height) {
|
||||
frameBuffer.notifyUpdate(x, y, width, height);
|
||||
}
|
||||
|
||||
public void notifyUpdateImage(long arg0, long arg1, long arg2, long arg3, byte[] arg4) {
|
||||
frameBuffer.notifyUpdateImage(arg0, arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
public void setVisibleRegion(byte arg0, long arg1) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Posts a Video HW Acceleration Command to the frame buffer for processing.<br />
|
||||
* <br />
|
||||
* The commands used for 2D video acceleration (DDraw surface creation/destroying, blitting, scaling, color conversion, overlaying, etc.) are posted from quest to the host to be processed by the host hardware.
|
||||
*
|
||||
* @param command Pointer to VBOXVHWACMD containing the command to execute.
|
||||
* @param enmCmd The validated VBOXVHWACMD::enmCmd value from the command.
|
||||
* @param fromGuest Set when the command origins from the guest, clear if host.
|
||||
*/ //https://www.virtualbox.org/browser/vbox/trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp#L4645
|
||||
public void processVHWACommand(byte command, int enmCmd, boolean fromGuest) {
|
||||
|
||||
}
|
||||
|
||||
public boolean videoModeSupported(long arg0, long arg1, long arg2) {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package sznp.virtualcomputer;
|
||||
|
||||
import org.virtualbox_6_1.IEvent;
|
||||
import sznp.virtualcomputer.util.COMObjectBase;
|
||||
import sznp.virtualcomputer.util.IEventHandler;
|
||||
|
||||
/**
|
||||
* A Bukkit-like event system which calls the appropriate methods on an event.
|
||||
*/
|
||||
public final class EventHandler extends COMObjectBase {
|
||||
private final IEventHandler handler;
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* New MSCOM event handler.
|
||||
*
|
||||
* @param handler The handle method that handles what needs to be handled
|
||||
*/
|
||||
public EventHandler(IEventHandler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
public final void handleEvent(IEvent iEvent) {
|
||||
if (!enabled)
|
||||
return;
|
||||
handler.handleEvent(iEvent);
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
enabled = false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package sznp.virtualcomputer.util;
|
||||
|
||||
import com.jacob.com.Dispatch;
|
||||
import com.jacob.com.Variant;
|
||||
|
||||
public abstract class COMObjectBase extends Dispatch {
|
||||
public COMObjectBase() {
|
||||
super("clsid:{67099191-32E7-4F6C-85EE-422304C71B90}");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package sznp.virtualcomputer.util;
|
||||
|
||||
import com.jacob.activeX.ActiveXComponent;
|
||||
import com.jacob.com.*;
|
||||
import lombok.val;
|
||||
import org.virtualbox_6_1.*;
|
||||
import org.virtualbox_6_1.mscom.Helper;
|
||||
import org.virtualbox_6_1.mscom.IUnknown;
|
||||
import sznp.virtualcomputer.COMFrameBuffer;
|
||||
import sznp.virtualcomputer.EventHandler;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
|
||||
public final class COMUtils {
|
||||
private COMUtils() {
|
||||
}
|
||||
|
||||
//public static void registerListener(IEventSource source, IEventListener listener, VBoxEventType... types) {
|
||||
public static org.virtualbox_6_1.IEventListener registerListener(IEventSource source, IEventHandler listener, List<VBoxEventType> types) {
|
||||
//new DispatchEvents(source.getTypedWrapped(), listener);
|
||||
val ret = new org.virtualbox_6_1.IEventListener(new EventHandler(listener));
|
||||
/*com.jacob.activeX.ActiveXComponent.createNewInstance("IEventListener");
|
||||
new ActiveXComponent("");
|
||||
source.registerListener(ret, types, true);*/
|
||||
//registerListener(source, new EventHandler(listener), types, true);
|
||||
System.out.println("Testing listener...");
|
||||
ret.handleEvent(null);
|
||||
System.out.println("Tested");
|
||||
return ret;
|
||||
//return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends IEvent> T getEvent(IEvent event, Class<T> cl) {
|
||||
try {
|
||||
val method = cl.getMethod("queryInterface", IUnknown.class);
|
||||
return (T) method.invoke(null, event);
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static IFramebuffer gimmeAFramebuffer(IMCFrameBuffer frameBuffer) {
|
||||
return new IFramebuffer(new Variant(new COMFrameBuffer(frameBuffer)).getDispatch());
|
||||
}
|
||||
|
||||
public static void queryBitmapInfo(IDisplaySourceBitmap bitmap, long[] ptr, long[] w, long[] h, long[] bpp, long[] bpl, long[] pf) {
|
||||
Dispatch.call(bitmap.getTypedWrapped(), "queryBitmapInfo", ptr, w, h, bpp, bpl, pf);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package sznp.virtualcomputer.util;
|
||||
|
||||
import org.virtualbox_6_1.IEvent;
|
||||
|
||||
public interface IEventHandler {
|
||||
void handleEvent(IEvent iEvent);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package sznp.virtualcomputer.util;
|
||||
|
||||
public interface IMCFrameBuffer {
|
||||
void notifyUpdate(long x, long y, long width, long height);
|
||||
|
||||
void notifyUpdateImage(long x, long y, long width, long height, byte[] image);
|
||||
|
||||
void notifyChange(long screenId, long xOrigin, long yOrigin, long width, long height);
|
||||
}
|
7
pom.xml
7
pom.xml
|
@ -15,8 +15,7 @@
|
|||
<packaging>pom</packaging>
|
||||
|
||||
<name>VirtualComputer</name>
|
||||
<!-- FIXME change it to the project's website -->
|
||||
<url>http://www.example.com</url>
|
||||
<url>https://github.com/NorbiPeti/VirtualComputer</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
@ -75,12 +74,12 @@
|
|||
<version>1.12-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency> <!-- Not using anything from here directly so we're not that dependent on versions -->
|
||||
<!-- <dependency> !- Not using anything from here directly so we're not that dependent on versions -
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>1.16.1-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependency> -->
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
BIN
repo/net/sf/jacob-project/jacob/1.19/jacob-1.19.jar
Normal file
BIN
repo/net/sf/jacob-project/jacob/1.19/jacob-1.19.jar
Normal file
Binary file not shown.
9
repo/net/sf/jacob-project/jacob/1.19/jacob-1.19.pom
Normal file
9
repo/net/sf/jacob-project/jacob/1.19/jacob-1.19.pom
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://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>net.sf.jacob-project</groupId>
|
||||
<artifactId>jacob</artifactId>
|
||||
<version>1.19</version>
|
||||
<description>POM was created from install:install-file</description>
|
||||
</project>
|
12
repo/net/sf/jacob-project/jacob/maven-metadata-local.xml
Normal file
12
repo/net/sf/jacob-project/jacob/maven-metadata-local.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<groupId>net.sf.jacob-project</groupId>
|
||||
<artifactId>jacob</artifactId>
|
||||
<versioning>
|
||||
<release>1.19</release>
|
||||
<versions>
|
||||
<version>1.19</version>
|
||||
</versions>
|
||||
<lastUpdated>20200811112851</lastUpdated>
|
||||
</versioning>
|
||||
</metadata>
|
Loading…
Reference in a new issue