Directly using VirtualBox from Java #5
6 changed files with 271 additions and 192 deletions
|
@ -5,6 +5,7 @@ import org.bukkit.command.Command;
|
|||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import sznp.virtualcomputer.events.Computer;
|
||||
|
||||
public class Commands implements CommandExecutor {
|
||||
|
||||
|
@ -22,14 +23,14 @@ public class Commands implements CommandExecutor {
|
|||
sender.sendMessage("§cUsage: /" + label + " start [index]");
|
||||
return true;
|
||||
}
|
||||
PluginMain.Instance.Start(sender, c);
|
||||
Computer.getInstance().Start(sender, c);
|
||||
break;
|
||||
case "stop":
|
||||
case "poweroff":
|
||||
case "off":
|
||||
case "shutdown":
|
||||
case "kill":
|
||||
PluginMain.Instance.Stop(sender);
|
||||
Computer.getInstance().Stop(sender);
|
||||
break;
|
||||
case "powerbutton":
|
||||
case "pwrbtn":
|
||||
|
@ -39,15 +40,15 @@ public class Commands implements CommandExecutor {
|
|||
sender.sendMessage("§cUsage: /" + label + " powerbutton [index]");
|
||||
return true;
|
||||
}
|
||||
PluginMain.Instance.PowerButton(sender, c);
|
||||
Computer.getInstance().PowerButton(sender, c);
|
||||
break;
|
||||
case "reset":
|
||||
case "restart":
|
||||
PluginMain.Instance.Reset(sender);
|
||||
Computer.getInstance().Reset(sender);
|
||||
break;
|
||||
case "fix":
|
||||
case "fixscreen":
|
||||
PluginMain.Instance.FixScreen(sender);
|
||||
Computer.getInstance().FixScreen(sender);
|
||||
break;
|
||||
case "key":
|
||||
case "press":
|
||||
|
@ -58,9 +59,9 @@ public class Commands implements CommandExecutor {
|
|||
return true;
|
||||
}
|
||||
if (args.length < 3)
|
||||
PluginMain.Instance.PressKey(sender, args[1], "");
|
||||
Computer.getInstance().PressKey(sender, args[1], "");
|
||||
else
|
||||
PluginMain.Instance.PressKey(sender, args[1], args[2]);
|
||||
Computer.getInstance().PressKey(sender, args[1], args[2]);
|
||||
break;
|
||||
case "mouse":
|
||||
boolean showusage = true;
|
||||
|
@ -68,15 +69,15 @@ public class Commands implements CommandExecutor {
|
|||
// Command overloading, because I can :P
|
||||
if (args.length > 4) // 4<x<6
|
||||
{
|
||||
PluginMain.Instance.UpdateMouse(sender, Integer.parseInt(args[1]), Integer.parseInt(args[2]),
|
||||
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) {
|
||||
PluginMain.Instance.UpdateMouse(sender, 0, 0, 0, 0, args[1], args[2].equals("down"));
|
||||
Computer.getInstance().UpdateMouse(sender, 0, 0, 0, 0, args[1], args[2].equals("down"));
|
||||
showusage = false;
|
||||
} else if (args.length == 2) {
|
||||
PluginMain.Instance.UpdateMouse(sender, 0, 0, 0, 0, args[1]);
|
||||
Computer.getInstance().UpdateMouse(sender, 0, 0, 0, 0, args[1]);
|
||||
showusage = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.bukkit.command.ConsoleCommandSender;
|
|||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.virtualbox_6_0.*;
|
||||
import sznp.virtualcomputer.events.VBoxEventHandler;
|
||||
import sznp.virtualcomputer.renderer.BukkitRenderer;
|
||||
import sznp.virtualcomputer.renderer.GPURenderer;
|
||||
import sznp.virtualcomputer.renderer.IRenderer;
|
||||
|
@ -22,6 +23,8 @@ import java.lang.reflect.Field;
|
|||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class PluginMain extends JavaPlugin {
|
||||
|
@ -75,12 +78,13 @@ public class PluginMain extends JavaPlugin {
|
|||
VBoxLib vbl = LibraryLoader.create(VBoxLib.class).load("vboxjxpcom");
|
||||
vbl.RTR3InitExe(0, "", 0);
|
||||
vbox = manager.getVBox();
|
||||
vbox.getEventSource().registerListener(new IEventListener(new VBoxEventHandler()), Arrays.asList(VBoxEventType.OnMachineStateChanged), true);
|
||||
session = manager.getSessionObject(); // TODO: Events
|
||||
ccs.sendMessage("§bLoading Screen...");
|
||||
try {
|
||||
//throw new NoClassDefFoundError("Test error pls ignore");
|
||||
for (short i = 0; i < 5; i++)
|
||||
for (short j = 0; j < 4; j++)
|
||||
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;
|
||||
|
@ -123,186 +127,6 @@ public class PluginMain extends JavaPlugin {
|
|||
saveConfig();
|
||||
}
|
||||
|
||||
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(this, () -> {
|
||||
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
|
||||
final Runnable tr = new Runnable() {
|
||||
public void run() {
|
||||
if (session.getState() != SessionState.Locked) { // https://www.virtualbox.org/sdkref/_virtual_box_8idl.html#ac82c179a797c0d7c249d1b98a8e3aa8f
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(PluginMain.this, this, 5);
|
||||
return; // "This state also occurs as a short transient state during an IMachine::lockMachine call."
|
||||
}
|
||||
machine = session.getMachine(); // This is the Machine object we can work with
|
||||
final IConsole console = session.getConsole();
|
||||
console.powerUp(); // https://marc.info/?l=vbox-dev&m=142780789819967&w=2
|
||||
console.getDisplay().attachFramebuffer(0L,
|
||||
new IFramebuffer(new MCFrameBuffer(console.getDisplay(), true)));
|
||||
startScreenTask(console, sender);
|
||||
}
|
||||
};
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(this, tr, 5);
|
||||
} catch (VBoxException e) {
|
||||
if (e.getResultCode() == 0x80070005) { //lockMachine: "The object functionality is limited"
|
||||
sendMessage(sender, "§6Cannot start computer, the machine may be inaccessible");
|
||||
return; //TODO: If we have VirtualBox open, it won't close the server's port
|
||||
//TODO: Can't detect if machine fails to start because of hardening issues
|
||||
//TODO: This error also occurs if the machine has failed to start at least once (always reassign the machine?)
|
||||
//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());
|
||||
return;
|
||||
}
|
||||
}
|
||||
sendMessage(sender, "§eComputer started.");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Right now only checks if the computer has turned off.
|
||||
*/
|
||||
private void startScreenTask(IConsole console, CommandSender sender) {
|
||||
if (screenupdatetask == null)
|
||||
screenupdatetask = Bukkit.getScheduler().runTaskTimerAsynchronously(PluginMain.this, () -> {
|
||||
/*if (session.getState().equals(SessionState.Locked) // Don't run until the machine is running
|
||||
&& console.getState().equals(MachineState.Running))
|
||||
console.getDisplay().invalidateAndUpdateScreen(0L);*/
|
||||
if (session.getState().equals(SessionState.Unlocked) // Stop if the machine stopped fully
|
||||
|| console.getState().equals(MachineState.PoweredOff)
|
||||
|| console.getState().equals(MachineState.Saved)) {
|
||||
if (session.getState().equals(SessionState.Locked)) {
|
||||
session.unlockMachine();
|
||||
sendMessage(sender, "Computer powered off, released it.");
|
||||
}
|
||||
screenupdatetask.cancel();
|
||||
screenupdatetask = null;
|
||||
}
|
||||
}, 100, 100); // Do a full update every 5 seconds
|
||||
}
|
||||
|
||||
private void sendMessage(CommandSender sender, String message) {
|
||||
sender.sendMessage(message);
|
||||
getLogger().warning(sender.getName() + ": " + ChatColor.stripColor(message));
|
||||
}
|
||||
|
||||
public void Stop(CommandSender sender) {
|
||||
if (checkMachineNotRunning(sender)) {
|
||||
if (session.getState().equals(SessionState.Locked)) {
|
||||
session.unlockMachine();
|
||||
sendMessage(sender, "§eComputer powered off, released it.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
sendMessage(sender, "§eStopping computer...");
|
||||
session.getConsole().powerDown().waitForCompletion(2000);
|
||||
session.unlockMachine();
|
||||
sendMessage(sender, "§eComputer stopped.");
|
||||
}
|
||||
|
||||
public void PowerButton(CommandSender sender, int index) {
|
||||
sendMessage(sender, "§ePressing powerbutton...");
|
||||
getServer().getScheduler().runTaskAsynchronously(this, 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;
|
||||
try {
|
||||
code = Scancode.valueOf("sc_" + key.toLowerCase()).Code;
|
||||
} catch (IllegalArgumentException e) {
|
||||
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(this, sendrelease, durationorstate);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateMouse(CommandSender sender, int x, int y, int z, int w, String mbs, boolean down) {
|
||||
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 RuntimeException("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) {
|
||||
if (checkMachineNotRunning(sender))
|
||||
return;
|
||||
UpdateMouse(sender, x, y, z, w, mbs, true);
|
||||
UpdateMouse(sender, x, y, z, w, mbs, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified path to the java library path
|
||||
*
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
package sznp.virtualcomputer.events;
|
||||
|
||||
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.PluginMain;
|
||||
import sznp.virtualcomputer.renderer.MCFrameBuffer;
|
||||
import sznp.virtualcomputer.util.Scancode;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
public final class Computer {
|
||||
@Getter
|
||||
private static Computer instance;
|
||||
|
||||
private final PluginMain plugin;
|
||||
private ISession session;
|
||||
private IVirtualBox vbox;
|
||||
private IMachine machine;
|
||||
|
||||
@java.beans.ConstructorProperties({"plugin"})
|
||||
public Computer(PluginMain plugin) {
|
||||
this.plugin = plugin;
|
||||
if(instance!=null) throw new IllegalStateException("A computer already exists!");
|
||||
instance=this; //TODO: Move some init stuff here
|
||||
}
|
||||
|
||||
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
|
||||
final Runnable tr = new Runnable() {
|
||||
public void run() {
|
||||
if (session.getState() != SessionState.Locked) { // https://www.virtualbox.org/sdkref/_virtual_box_8idl.html#ac82c179a797c0d7c249d1b98a8e3aa8f
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, this, 5);
|
||||
return; // "This state also occurs as a short transient state during an IMachine::lockMachine call."
|
||||
}
|
||||
machine = session.getMachine(); // This is the Machine object we can work with
|
||||
final IConsole console = session.getConsole();
|
||||
console.getEventSource().registerListener(new IEventListener(new MachineEventHandler(Computer.this)), Collections.singletonList(VBoxEventType.MachineEvent), true);
|
||||
console.powerUp(); // https://marc.info/?l=vbox-dev&m=142780789819967&w=2
|
||||
console.getDisplay().attachFramebuffer(0L,
|
||||
new IFramebuffer(new MCFrameBuffer(console.getDisplay(), true)));
|
||||
}
|
||||
};
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, tr, 5);
|
||||
} catch (VBoxException e) {
|
||||
if (e.getResultCode() == 0x80070005) { //lockMachine: "The object functionality is limited"
|
||||
sendMessage(sender, "§6Cannot start computer, the machine may be inaccessible");
|
||||
return; //TODO: If we have VirtualBox open, it won't close the server's port
|
||||
//TODO: Can't detect if machine fails to start because of hardening issues
|
||||
//TODO: This error also occurs if the machine has failed to start at least once (always reassign the machine?)
|
||||
//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());
|
||||
return;
|
||||
}
|
||||
}
|
||||
sendMessage(sender, "§eComputer started.");
|
||||
});
|
||||
}
|
||||
|
||||
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)) {
|
||||
session.unlockMachine();
|
||||
sendMessage(sender, "§eComputer powered off, released it.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
sendMessage(sender, "§eStopping computer...");
|
||||
session.getConsole().powerDown().waitForCompletion(2000);
|
||||
session.unlockMachine();
|
||||
sendMessage(sender, "§eComputer stopped.");
|
||||
}
|
||||
|
||||
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;
|
||||
try {
|
||||
code = Scancode.valueOf("sc_" + key.toLowerCase()).Code;
|
||||
} catch (IllegalArgumentException e) {
|
||||
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) {
|
||||
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 RuntimeException("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) {
|
||||
if (checkMachineNotRunning(sender))
|
||||
return;
|
||||
UpdateMouse(sender, x, y, z, w, mbs, true);
|
||||
UpdateMouse(sender, x, y, z, w, mbs, false);
|
||||
}
|
||||
|
||||
public void stopRendering() {
|
||||
//TODO
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package sznp.virtualcomputer.events;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.val;
|
||||
import org.mozilla.interfaces.IEvent;
|
||||
import org.mozilla.interfaces.IEventListener;
|
||||
import org.virtualbox_6_0.IStateChangedEvent;
|
||||
import org.virtualbox_6_0.MachineState;
|
||||
import sznp.virtualcomputer.renderer.MCFrameBuffer;
|
||||
import sznp.virtualcomputer.util.COMObjectBase;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class MachineEventHandler extends COMObjectBase implements IEventListener {
|
||||
private final Computer computer;
|
||||
@Override
|
||||
public void handleEvent(IEvent iEvent) {
|
||||
if(iEvent instanceof IStateChangedEvent) {
|
||||
val event=(IStateChangedEvent) iEvent; //https://www.virtualbox.org/sdkref/_virtual_box_8idl.html#a80b08f71210afe16038e904a656ed9eb
|
||||
switch (event.getState()) {
|
||||
case Stuck:
|
||||
computer.Stop(null);
|
||||
break;
|
||||
case PoweredOff:
|
||||
case Saved:
|
||||
computer.stopRendering();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package sznp.virtualcomputer.events;
|
||||
|
||||
import lombok.val;
|
||||
import org.mozilla.interfaces.IEvent;
|
||||
import org.mozilla.interfaces.IEventListener;
|
||||
import org.mozilla.interfaces.nsISupports;
|
||||
import org.mozilla.xpcom.Mozilla;
|
||||
import org.virtualbox_6_0.IMachineStateChangedEvent;
|
||||
import org.virtualbox_6_0.VBoxEventType;
|
||||
import sznp.virtualcomputer.util.COMObjectBase;
|
||||
|
||||
public class VBoxEventHandler extends COMObjectBase implements IEventListener {
|
||||
@Override
|
||||
public void handleEvent(IEvent iEvent) {
|
||||
if(iEvent.getType()== VBoxEventType.OnMachineStateChanged.value()) {
|
||||
val event=(IMachineStateChangedEvent) iEvent;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue