Directly using VirtualBox from Java #5
6 changed files with 52 additions and 51 deletions
|
@ -113,13 +113,7 @@ public class Commands implements CommandExecutor {
|
||||||
+ " [\"\",{\"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\"}}]");
|
+ " [\"\",{\"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;
|
break;
|
||||||
case "mouse":
|
case "mouse":
|
||||||
if (!MouseLockerPlayerListener.LockedPlayers.containsKey(sender)) {
|
MouseLockerPlayerListener.toggleLock((Player) sender);
|
||||||
MouseLockerPlayerListener.LockedPlayers.put((Player) sender, ((Player) sender).getLocation());
|
|
||||||
sender.sendMessage("§aMouse locked.");
|
|
||||||
} else {
|
|
||||||
MouseLockerPlayerListener.LockedPlayers.remove(sender);
|
|
||||||
sender.sendMessage("§bMouse unlocked.");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case "mspeed":
|
case "mspeed":
|
||||||
case "mousespeed":
|
case "mousespeed":
|
||||||
|
|
|
@ -76,13 +76,12 @@ public final class Computer {
|
||||||
public void onLock(CommandSender sender) {
|
public void onLock(CommandSender sender) {
|
||||||
machine = session.getMachine(); // This is the Machine object we can work with
|
machine = session.getMachine(); // This is the Machine object we can work with
|
||||||
final IConsole console = session.getConsole();
|
final IConsole console = session.getConsole();
|
||||||
handler = new MachineEventHandler(Computer.this);
|
handler = new MachineEventHandler(Computer.this, sender);
|
||||||
listener = handler.registerTo(console.getEventSource());
|
listener = handler.registerTo(console.getEventSource());
|
||||||
IProgress progress = console.powerUp(); // https://marc.info/?l=vbox-dev&m=142780789819967&w=2
|
IProgress progress = console.powerUp(); // https://marc.info/?l=vbox-dev&m=142780789819967&w=2
|
||||||
handler.registerTo(progress.getEventSource()); //TODO: Show progress bar some way?
|
handler.registerTo(progress.getEventSource()); //TODO: Show progress bar some way?
|
||||||
console.getDisplay().attachFramebuffer(0L,
|
console.getDisplay().attachFramebuffer(0L,
|
||||||
new IFramebuffer(new MCFrameBuffer(console.getDisplay(), true)));
|
new IFramebuffer(new MCFrameBuffer(console.getDisplay(), true)));
|
||||||
sendMessage(sender, "§eComputer started.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendMessage(@Nullable CommandSender sender, String message) {
|
private void sendMessage(@Nullable CommandSender sender, String message) {
|
||||||
|
@ -192,20 +191,20 @@ public final class Computer {
|
||||||
UpdateMouse(sender, x, y, z, w, mbs, false);
|
UpdateMouse(sender, x, y, z, w, mbs, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onMachineStop() {
|
public void onMachineStart(CommandSender sender) {
|
||||||
System.out.println("Unlocking machine...");
|
sendMessage(sender, "§eComputer started.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onMachineStop(CommandSender sender) {
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
||||||
if (session.getState() == SessionState.Locked) {
|
if (session.getState() == SessionState.Locked) {
|
||||||
System.out.println("Unlocking...");
|
|
||||||
session.unlockMachine(); //Needs to be outside of the event handler
|
session.unlockMachine(); //Needs to be outside of the event handler
|
||||||
System.out.println("Machine unlocked.");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
System.out.println("Setting pixels...");
|
|
||||||
GPURendererInternal.setPixels(new byte[1], 0, 0); //Black screen
|
GPURendererInternal.setPixels(new byte[1], 0, 0); //Black screen
|
||||||
System.out.println("Stopping events...");
|
|
||||||
stopEvents();
|
stopEvents();
|
||||||
plugin.getLogger().info("Computer powered off.");
|
MouseLockerPlayerListener.computerStop();
|
||||||
|
sendMessage(sender, "§eComputer powered off.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopEvents() {
|
public void stopEvents() {
|
||||||
|
|
|
@ -2,14 +2,17 @@ package sznp.virtualcomputer;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
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 org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
public class MouseLockerPlayerListener implements Runnable {
|
public class MouseLockerPlayerListener implements Runnable, Listener {
|
||||||
public static Map<Player, Location> LockedPlayers = new HashMap<>();
|
private static final Map<Player, Location> LockedPlayers = new HashMap<>();
|
||||||
public static float LockedSpeed = 5;
|
public static float LockedSpeed = 5;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -28,4 +31,23 @@ public class MouseLockerPlayerListener implements Runnable {
|
||||||
entry.getKey().teleport(entry.getValue(), TeleportCause.PLUGIN);
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package sznp.virtualcomputer;
|
package sznp.virtualcomputer;
|
||||||
|
|
||||||
import jnr.ffi.LibraryLoader;
|
import jnr.ffi.LibraryLoader;
|
||||||
|
import lombok.val;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.ConsoleCommandSender;
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
@ -92,7 +93,9 @@ public class PluginMain extends JavaPlugin {
|
||||||
ccs.sendMessage("§6Compatibility error, using slower renderer");
|
ccs.sendMessage("§6Compatibility error, using slower renderer");
|
||||||
}
|
}
|
||||||
ccs.sendMessage("§bLoaded!");
|
ccs.sendMessage("§bLoaded!");
|
||||||
mousetask = getServer().getScheduler().runTaskTimer(this, new MouseLockerPlayerListener(), 0, 0);
|
val mlpl = new MouseLockerPlayerListener();
|
||||||
|
mousetask = getServer().getScheduler().runTaskTimer(this, mlpl, 0, 0);
|
||||||
|
getServer().getPluginManager().registerEvents(mlpl, this);
|
||||||
|
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package sznp.virtualcomputer.events;
|
package sznp.virtualcomputer.events;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.virtualbox_6_0.IProgressTaskCompletedEvent;
|
import org.virtualbox_6_0.IProgressTaskCompletedEvent;
|
||||||
import org.virtualbox_6_0.IStateChangedEvent;
|
import org.virtualbox_6_0.IStateChangedEvent;
|
||||||
|
@ -9,17 +10,18 @@ import sznp.virtualcomputer.Computer;
|
||||||
|
|
||||||
public class MachineEventHandler extends EventHandlerBase {
|
public class MachineEventHandler extends EventHandlerBase {
|
||||||
private final Computer computer;
|
private final Computer computer;
|
||||||
|
private final CommandSender sender;
|
||||||
private boolean starting = false;
|
private boolean starting = false;
|
||||||
|
|
||||||
public MachineEventHandler(Computer computer) {
|
public MachineEventHandler(Computer computer, CommandSender sender) {
|
||||||
super(ImmutableMap.of(VBoxEventType.OnStateChanged, IStateChangedEvent.class,
|
super(ImmutableMap.of(VBoxEventType.OnStateChanged, IStateChangedEvent.class,
|
||||||
VBoxEventType.OnProgressTaskCompleted, IProgressTaskCompletedEvent.class));
|
VBoxEventType.OnProgressTaskCompleted, IProgressTaskCompletedEvent.class));
|
||||||
this.computer = computer;
|
this.computer = computer;
|
||||||
|
this.sender = sender;
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void handleStateChange(IStateChangedEvent event) { //https://www.virtualbox.org/sdkref/_virtual_box_8idl.html#a80b08f71210afe16038e904a656ed9eb
|
public void handleStateChange(IStateChangedEvent event) { //https://www.virtualbox.org/sdkref/_virtual_box_8idl.html#a80b08f71210afe16038e904a656ed9eb
|
||||||
System.out.println("State event: " + event.getState());
|
|
||||||
switch (event.getState()) {
|
switch (event.getState()) {
|
||||||
case Stuck:
|
case Stuck:
|
||||||
computer.Stop(null);
|
computer.Stop(null);
|
||||||
|
@ -27,17 +29,18 @@ public class MachineEventHandler extends EventHandlerBase {
|
||||||
case PoweredOff:
|
case PoweredOff:
|
||||||
case Saved:
|
case Saved:
|
||||||
if (starting) {
|
if (starting) {
|
||||||
System.out.println("Failed to start computer! See the VM's log for more details.");
|
sender.sendMessage("§cFailed to start computer! See the VM's log for more details.");
|
||||||
starting = false; //TODO: Sender
|
sender.sendMessage("§cMake sure that 2D and 3D acceleration is disabled.");
|
||||||
|
starting = false;
|
||||||
}
|
}
|
||||||
computer.onMachineStop();
|
computer.onMachineStop(sender);
|
||||||
break;
|
break;
|
||||||
case Starting:
|
case Starting:
|
||||||
starting = true;
|
starting = true;
|
||||||
break;
|
break;
|
||||||
case Running:
|
case Running:
|
||||||
System.out.println("Computer is running.");
|
|
||||||
starting = false;
|
starting = false;
|
||||||
|
computer.onMachineStart(sender);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ public class MCFrameBuffer implements IFramebuffer {
|
||||||
@Override
|
@Override
|
||||||
public long[] getCapabilities(long[] arg0) {
|
public long[] getCapabilities(long[] arg0) {
|
||||||
try {
|
try {
|
||||||
|
System.out.println("Capabilities queried");
|
||||||
System.out.println("Capabilities: " + Arrays.toString(arg0));
|
System.out.println("Capabilities: " + Arrays.toString(arg0));
|
||||||
return new long[]{FramebufferCapabilities.UpdateImage.value()};
|
return new long[]{FramebufferCapabilities.UpdateImage.value()};
|
||||||
}
|
}
|
||||||
|
@ -94,24 +95,14 @@ public class MCFrameBuffer implements IFramebuffer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notifyChange(long screenId, long xOrigin, long yOrigin, long width, long height) {
|
public void notifyChange(long screenId, long xOrigin, long yOrigin, long width, long height) {
|
||||||
//Timing ti=new Timing();
|
|
||||||
//System.out.println("Change - " + width + "x" + height);
|
|
||||||
if (tt != null)
|
if (tt != null)
|
||||||
tt.cancel();
|
tt.cancel();
|
||||||
/*
|
|
||||||
* if (width > 640 || height > 480) { tt = Bukkit.getScheduler().runTaskTimerAsynchronously(PluginMain.Instance, () -> display.setVideoModeHint(0L, true, false, 0, 0, 640L, 480L, 32L), 5, 5);
|
|
||||||
* return; // Don't even try to render too large resolutions }
|
|
||||||
*/
|
|
||||||
tt = Bukkit.getScheduler().runTaskAsynchronously(PluginMain.Instance, () -> {
|
tt = Bukkit.getScheduler().runTaskAsynchronously(PluginMain.Instance, () -> {
|
||||||
try {
|
try {
|
||||||
display.querySourceBitmap(0L, holder);
|
display.querySourceBitmap(0L, holder);
|
||||||
//byte[] arr = PluginMain.allpixels.array();
|
|
||||||
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];
|
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);
|
holder.value.getTypedWrapped().queryBitmapInfo(ptr, w, h, bpp, bpl, pf);
|
||||||
//System.out.println("Arr0:" + ptr[0]);
|
|
||||||
//System.out.println("whbppbplpf: " + w[0] + " " + h[0] + " " + bpp[0] + " " + bpl[0] + " " + pf[0]);
|
|
||||||
if (PluginMain.direct) {
|
if (PluginMain.direct) {
|
||||||
//PluginMain.pxc.setSource(ptr[0], (int)w[0], (int)h[0], PluginMain.MCX, PluginMain.MCY);
|
|
||||||
pointer = new Pointer(ptr[0]);
|
pointer = new Pointer(ptr[0]);
|
||||||
this.width = (int) w[0];
|
this.width = (int) w[0];
|
||||||
this.height = (int) h[0];
|
this.height = (int) h[0];
|
||||||
|
@ -123,8 +114,6 @@ public class MCFrameBuffer implements IFramebuffer {
|
||||||
else
|
else
|
||||||
PluginMain.allpixels.limit((int) (width * height * 4));
|
PluginMain.allpixels.limit((int) (width * height * 4));
|
||||||
}
|
}
|
||||||
//System.out.println("Change!");
|
|
||||||
//System.out.println("Change task took "+ti.elapsedMS()+"ms");
|
|
||||||
} catch (VBoxException e) {
|
} catch (VBoxException e) {
|
||||||
if (e.getResultCode() == 0x80070005)
|
if (e.getResultCode() == 0x80070005)
|
||||||
return; // Machine is being powered down
|
return; // Machine is being powered down
|
||||||
|
@ -134,20 +123,11 @@ public class MCFrameBuffer implements IFramebuffer {
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
}
|
}
|
||||||
}); // Wait 1/4th of a second - Don't
|
});
|
||||||
//System.out.println("Change took "+ti.elapsedMS()+"ms");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notifyUpdate(long x, long y, long width, long height) {
|
public void notifyUpdate(long x, long y, long width, long height) {
|
||||||
/*if(tttt != null)
|
|
||||||
tttt.cancel();*/ //We are getting updates, but the pixel array isn't updated - VB reacts slowly
|
|
||||||
/*tttt = Bukkit.getScheduler().runTaskLaterAsynchronously(PluginMain.Instance, () -> {
|
|
||||||
for (IRenderer r : PluginMain.renderers)
|
|
||||||
if (r instanceof DirectRenderer)
|
|
||||||
((DirectRenderer) r).render(PluginMain.allpixels, x, y, width, height);
|
|
||||||
System.out.println("Update!"); - The render is done each tick
|
|
||||||
}, 5);*/
|
|
||||||
Timing t = new Timing();
|
Timing t = new Timing();
|
||||||
GPURendererInternal.setPixels(pointer.getByteArray(0L, (this.width * this.height * 4)), this.width, this.height); //TODO: Only copy changed part
|
GPURendererInternal.setPixels(pointer.getByteArray(0L, (this.width * this.height * 4)), this.width, this.height); //TODO: Only copy changed part
|
||||||
if (t.elapsedMS() > 60) //Typically 1ms max
|
if (t.elapsedMS() > 60) //Typically 1ms max
|
||||||
|
|
Loading…
Reference in a new issue