diff --git a/VirtualComputer/src/main/java/sznp/virtualcomputer/Commands.java b/VirtualComputer/src/main/java/sznp/virtualcomputer/Commands.java index 68b911a..8060bb7 100644 --- a/VirtualComputer/src/main/java/sznp/virtualcomputer/Commands.java +++ b/VirtualComputer/src/main/java/sznp/virtualcomputer/Commands.java @@ -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\"}}]"); break; case "mouse": - if (!MouseLockerPlayerListener.LockedPlayers.containsKey(sender)) { - MouseLockerPlayerListener.LockedPlayers.put((Player) sender, ((Player) sender).getLocation()); - sender.sendMessage("§aMouse locked."); - } else { - MouseLockerPlayerListener.LockedPlayers.remove(sender); - sender.sendMessage("§bMouse unlocked."); - } + MouseLockerPlayerListener.toggleLock((Player) sender); break; case "mspeed": case "mousespeed": diff --git a/VirtualComputer/src/main/java/sznp/virtualcomputer/Computer.java b/VirtualComputer/src/main/java/sznp/virtualcomputer/Computer.java index 70885c4..a096283 100644 --- a/VirtualComputer/src/main/java/sznp/virtualcomputer/Computer.java +++ b/VirtualComputer/src/main/java/sznp/virtualcomputer/Computer.java @@ -31,7 +31,7 @@ public final class Computer { this.plugin = plugin; this.session = session; this.vbox = vbox; - if(instance!=null) throw new IllegalStateException("A computer already exists!"); + if (instance != null) throw new IllegalStateException("A computer already exists!"); instance = this; } @@ -76,19 +76,18 @@ public final class Computer { public void onLock(CommandSender sender) { machine = session.getMachine(); // This is the Machine object we can work with final IConsole console = session.getConsole(); - handler = new MachineEventHandler(Computer.this); + 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.registerTo(progress.getEventSource()); //TODO: Show progress bar some way? console.getDisplay().attachFramebuffer(0L, new IFramebuffer(new MCFrameBuffer(console.getDisplay(), true))); - 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)); + if (sender != null) + sender.sendMessage(message); + plugin.getLogger().warning((sender == null ? "" : sender.getName() + ": ") + ChatColor.stripColor(message)); } public void Stop(CommandSender sender) { @@ -192,20 +191,20 @@ public final class Computer { UpdateMouse(sender, x, y, z, w, mbs, false); } - public void onMachineStop() { - System.out.println("Unlocking machine..."); + public void onMachineStart(CommandSender sender) { + sendMessage(sender, "§eComputer started."); + } + + public void onMachineStop(CommandSender sender) { Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { if (session.getState() == SessionState.Locked) { - System.out.println("Unlocking..."); 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 - System.out.println("Stopping events..."); stopEvents(); - plugin.getLogger().info("Computer powered off."); + MouseLockerPlayerListener.computerStop(); + sendMessage(sender, "§eComputer powered off."); } public void stopEvents() { diff --git a/VirtualComputer/src/main/java/sznp/virtualcomputer/MouseLockerPlayerListener.java b/VirtualComputer/src/main/java/sznp/virtualcomputer/MouseLockerPlayerListener.java index 07785fd..9918815 100644 --- a/VirtualComputer/src/main/java/sznp/virtualcomputer/MouseLockerPlayerListener.java +++ b/VirtualComputer/src/main/java/sznp/virtualcomputer/MouseLockerPlayerListener.java @@ -2,14 +2,17 @@ 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 { - public static Map LockedPlayers = new HashMap<>(); +public class MouseLockerPlayerListener implements Runnable, Listener { + private static final Map LockedPlayers = new HashMap<>(); public static float LockedSpeed = 5; @Override @@ -28,4 +31,23 @@ public class MouseLockerPlayerListener implements Runnable { 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(); + } } diff --git a/VirtualComputer/src/main/java/sznp/virtualcomputer/PluginMain.java b/VirtualComputer/src/main/java/sznp/virtualcomputer/PluginMain.java index b4ec080..0e5538f 100644 --- a/VirtualComputer/src/main/java/sznp/virtualcomputer/PluginMain.java +++ b/VirtualComputer/src/main/java/sznp/virtualcomputer/PluginMain.java @@ -1,6 +1,7 @@ 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; @@ -92,7 +93,9 @@ public class PluginMain extends JavaPlugin { ccs.sendMessage("§6Compatibility error, using slower renderer"); } 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) { e.printStackTrace(); diff --git a/VirtualComputer/src/main/java/sznp/virtualcomputer/events/MachineEventHandler.java b/VirtualComputer/src/main/java/sznp/virtualcomputer/events/MachineEventHandler.java index cf42dd5..f4c2173 100644 --- a/VirtualComputer/src/main/java/sznp/virtualcomputer/events/MachineEventHandler.java +++ b/VirtualComputer/src/main/java/sznp/virtualcomputer/events/MachineEventHandler.java @@ -1,6 +1,7 @@ package sznp.virtualcomputer.events; import com.google.common.collect.ImmutableMap; +import org.bukkit.command.CommandSender; import org.bukkit.event.EventHandler; import org.virtualbox_6_0.IProgressTaskCompletedEvent; import org.virtualbox_6_0.IStateChangedEvent; @@ -9,17 +10,18 @@ import sznp.virtualcomputer.Computer; public class MachineEventHandler extends EventHandlerBase { private final Computer computer; + private final CommandSender sender; private boolean starting = false; - public MachineEventHandler(Computer computer) { + public MachineEventHandler(Computer computer, CommandSender sender) { super(ImmutableMap.of(VBoxEventType.OnStateChanged, IStateChangedEvent.class, VBoxEventType.OnProgressTaskCompleted, IProgressTaskCompletedEvent.class)); this.computer = computer; + this.sender = sender; } @EventHandler 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()) { case Stuck: computer.Stop(null); @@ -27,17 +29,18 @@ public class MachineEventHandler extends EventHandlerBase { case PoweredOff: case Saved: if (starting) { - System.out.println("Failed to start computer! See the VM's log for more details."); - starting = false; //TODO: Sender + sender.sendMessage("§cFailed to start computer! See the VM's log for more details."); + sender.sendMessage("§cMake sure that 2D and 3D acceleration is disabled."); + starting = false; } - computer.onMachineStop(); + computer.onMachineStop(sender); break; case Starting: starting = true; break; case Running: - System.out.println("Computer is running."); starting = false; + computer.onMachineStart(sender); break; } } diff --git a/VirtualComputer/src/main/java/sznp/virtualcomputer/renderer/MCFrameBuffer.java b/VirtualComputer/src/main/java/sznp/virtualcomputer/renderer/MCFrameBuffer.java index 8d10fe3..c8a5d6b 100644 --- a/VirtualComputer/src/main/java/sznp/virtualcomputer/renderer/MCFrameBuffer.java +++ b/VirtualComputer/src/main/java/sznp/virtualcomputer/renderer/MCFrameBuffer.java @@ -39,6 +39,7 @@ public class MCFrameBuffer implements IFramebuffer { @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()}; } @@ -94,24 +95,14 @@ public class MCFrameBuffer implements IFramebuffer { @Override 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) 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, () -> { try { 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]; 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) { - //PluginMain.pxc.setSource(ptr[0], (int)w[0], (int)h[0], PluginMain.MCX, PluginMain.MCY); pointer = new Pointer(ptr[0]); this.width = (int) w[0]; this.height = (int) h[0]; @@ -123,8 +114,6 @@ public class MCFrameBuffer implements IFramebuffer { else PluginMain.allpixels.limit((int) (width * height * 4)); } - //System.out.println("Change!"); - //System.out.println("Change task took "+ti.elapsedMS()+"ms"); } catch (VBoxException e) { if (e.getResultCode() == 0x80070005) return; // Machine is being powered down @@ -134,20 +123,11 @@ public class MCFrameBuffer implements IFramebuffer { } catch (Throwable t) { t.printStackTrace(); } - }); // Wait 1/4th of a second - Don't - //System.out.println("Change took "+ti.elapsedMS()+"ms"); + }); } @Override 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(); 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