From 99e02f8e7b5e28cc05a3ca436e6fe753978230eb Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Fri, 12 Apr 2019 01:25:29 +0200 Subject: [PATCH] Fixes Fixed double event handling after failed start attempt Added stopEvents() call I kinda forgot to add Made full rendering a (default) option --- VirtualComputer/dependency-reduced-pom.xml | 58 +++++++++++++++ .../java/sznp/virtualcomputer/Computer.java | 4 +- .../java/sznp/virtualcomputer/PluginMain.java | 8 +- .../events/MachineEventHandler.java | 2 +- .../virtualcomputer/renderer/GPURenderer.java | 74 ++++++++++++++----- .../renderer/GPURendererInternal.java | 27 +++---- 6 files changed, 132 insertions(+), 41 deletions(-) diff --git a/VirtualComputer/dependency-reduced-pom.xml b/VirtualComputer/dependency-reduced-pom.xml index 77d2b69..3e0d028 100644 --- a/VirtualComputer/dependency-reduced-pom.xml +++ b/VirtualComputer/dependency-reduced-pom.xml @@ -32,6 +32,58 @@ + + + XPCOM + + + + maven-shade-plugin + + + package + + shade + + + + + org.virtualbox:VirtualBox-MSCOM + + + + + + + + + + + MSCOM + + + + maven-shade-plugin + + + package + + shade + + + + + org.virtualbox:VirtualBox + + + + + + + + + + spigot-repo @@ -75,6 +127,12 @@ + + org.virtualbox + VirtualBox-MSCOM + 6.0 + compile + org.bukkit craftbukkit diff --git a/VirtualComputer/src/main/java/sznp/virtualcomputer/Computer.java b/VirtualComputer/src/main/java/sznp/virtualcomputer/Computer.java index 7ec38af..79592df 100644 --- a/VirtualComputer/src/main/java/sznp/virtualcomputer/Computer.java +++ b/VirtualComputer/src/main/java/sznp/virtualcomputer/Computer.java @@ -9,7 +9,6 @@ import org.virtualbox_6_0.*; import sznp.virtualcomputer.events.MachineEventHandler; import sznp.virtualcomputer.events.VBoxEventHandler; import sznp.virtualcomputer.renderer.GPURenderer; -import sznp.virtualcomputer.renderer.GPURendererInternal; import sznp.virtualcomputer.renderer.MCFrameBuffer; import sznp.virtualcomputer.util.Scancode; @@ -79,6 +78,8 @@ 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(); + 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 @@ -222,6 +223,7 @@ public final class Computer { } public void pluginDisable(CommandSender ccs) { + stopEvents(); if (session.getState() == SessionState.Locked) { if (session.getMachine().getState().equals(MachineState.Running)) { ccs.sendMessage("§aSaving machine state..."); diff --git a/VirtualComputer/src/main/java/sznp/virtualcomputer/PluginMain.java b/VirtualComputer/src/main/java/sznp/virtualcomputer/PluginMain.java index 427c400..f38ab70 100644 --- a/VirtualComputer/src/main/java/sznp/virtualcomputer/PluginMain.java +++ b/VirtualComputer/src/main/java/sznp/virtualcomputer/PluginMain.java @@ -40,6 +40,7 @@ public class PluginMain extends JavaPlugin { */ //public static PXCLib pxc; public static boolean direct; + public static boolean sendAll; // Fired when plugin is first enabled @Override @@ -48,6 +49,7 @@ public class PluginMain extends JavaPlugin { 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" @@ -109,13 +111,15 @@ public class PluginMain extends JavaPlugin { @Override public void onDisable() { ConsoleCommandSender ccs = getServer().getConsoleSender(); - mousetask.cancel(); + 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) }*/ - ((VBoxEventHandler) listener.getTypedWrapped()).disable(); //The save progress wait locks with the event + 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."); diff --git a/VirtualComputer/src/main/java/sznp/virtualcomputer/events/MachineEventHandler.java b/VirtualComputer/src/main/java/sznp/virtualcomputer/events/MachineEventHandler.java index 7191d53..259ae17 100644 --- a/VirtualComputer/src/main/java/sznp/virtualcomputer/events/MachineEventHandler.java +++ b/VirtualComputer/src/main/java/sznp/virtualcomputer/events/MachineEventHandler.java @@ -37,7 +37,7 @@ public class MachineEventHandler extends EventHandlerBase { case PoweredOff: case Saved: if (starting) { - sender.sendMessage("§cFailed to start computer! See the VM's log for more details."); + 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, () -> { diff --git a/VirtualComputer/src/main/java/sznp/virtualcomputer/renderer/GPURenderer.java b/VirtualComputer/src/main/java/sznp/virtualcomputer/renderer/GPURenderer.java index 0551f3e..1d4c412 100644 --- a/VirtualComputer/src/main/java/sznp/virtualcomputer/renderer/GPURenderer.java +++ b/VirtualComputer/src/main/java/sznp/virtualcomputer/renderer/GPURenderer.java @@ -7,23 +7,29 @@ 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 GPURendererInternal kernel; + private final GPURendererInternal kernel; private WorldMap wmap; private int mapx, mapy; //Store at central location after conversion private static int[] colors_; - private static int changedX, changedY, changedWidth, changedHeight; + private int changedX = 0, changedY = 0, changedWidth = 640, changedHeight = 480; + private static ArrayList renderers = new ArrayList<>(); public GPURenderer(short id, World world, int mapx, int mapy) throws Exception { MapView map = IRenderer.prepare(id, world); - if (map == null) return; //Testing + if (map == null) { + kernel = null; + return; //Testing + } if (colors_ == null) { Field field = MapPalette.class.getDeclaredField("colors"); @@ -40,8 +46,7 @@ public class GPURenderer extends MapRenderer implements IRenderer { field.setAccessible(true); wmap = (WorldMap) field.get(map); kernel = new GPURendererInternal(mapx, mapy, colors_); - - //System.setProperty("com.codegen.config.enable.NEW", "true"); + renderers.add(this); map.addRenderer(this); } @@ -56,16 +61,35 @@ public class GPURenderer extends MapRenderer implements IRenderer { field.setAccessible(true); buffer = (byte[]) field.get(canvas); } - if (changedX >= (mapx + 1) * 128 || changedY >= (mapy + 1) * 128 - || changedX + changedWidth < mapx * 128 || changedY + changedHeight < mapy * 128) - return; //No change for this map - TODO: Test - int x = changedX % 128; - int y = changedY % 128; - int w = x + changedWidth >= 128 ? 128 - x - 1 : changedWidth; - int h = y + changedHeight >= 128 ? 128 - y - 1 : changedHeight; - kernel.render(buffer); - wmap.flagDirty(x, y); - wmap.flagDirty(x + w, y + h); // Send the changes only + 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(); } @@ -74,10 +98,20 @@ public class GPURenderer extends MapRenderer implements IRenderer { } public static void update(byte[] pixels, int width, int height, int changedX, int changedY, int changedWidth, int changedHeight) { - GPURenderer.changedX = changedX; - GPURenderer.changedY = changedY; - GPURenderer.changedWidth = changedWidth; - GPURenderer.changedHeight = changedHeight; - GPURendererInternal.setPixels(pixels, width, height); + 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); + } + } } } diff --git a/VirtualComputer/src/main/java/sznp/virtualcomputer/renderer/GPURendererInternal.java b/VirtualComputer/src/main/java/sznp/virtualcomputer/renderer/GPURendererInternal.java index e1a723f..67896e3 100644 --- a/VirtualComputer/src/main/java/sznp/virtualcomputer/renderer/GPURendererInternal.java +++ b/VirtualComputer/src/main/java/sznp/virtualcomputer/renderer/GPURendererInternal.java @@ -4,9 +4,6 @@ import com.aparapi.Kernel; import com.aparapi.Range; import lombok.Getter; -import java.util.ArrayList; -import java.util.function.Consumer; - //Accessing the GPURenderer results in ArrayIndexOutOfBoundsExceptions - IT'S THE LAMBDAS public class GPURendererInternal extends Kernel { private int mapx; @@ -21,7 +18,6 @@ public class GPURendererInternal extends Kernel { private Range range; @Getter private boolean rendered; - private static ArrayList renderers = new ArrayList<>(); //public static byte[] test=new byte[1]; - LAMBDAS public GPURendererInternal(int mapx, int mapy, int[] colors) { @@ -34,8 +30,6 @@ public class GPURendererInternal extends Kernel { pixels = new byte[1]; width = height = 0; rendered = false; - - renderers.add(this); } @Override @@ -94,17 +88,12 @@ public class GPURendererInternal extends Kernel { private static final int GREEN = 1; private static final int BLUE = 0; - @SuppressWarnings("Convert2Lambda") //Aparapi fails with lambdas - static void setPixels(byte[] pixels, int width, int height) { - renderers.forEach(new Consumer() { - @Override //IT'S THE LAMBDAS (exception) - public void accept(GPURendererInternal r) { - r.pixels = pixels; - r.width = width; - r.height = height; - r.rendered = false; - } - }); + //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) { @@ -113,4 +102,8 @@ public class GPURendererInternal extends Kernel { put(buffer).put(pixels).execute(range).get(buffer); rendered = true; } + + void ignoreChange() { + rendered = true; + } }