Fixes, events

- Unlocking machine on power off
- Removed change debug messages
- Fixed missing break in command handling
- Added timing (updates seem to be 1ms max, changes 66ms)
-- Screen rendering for the first time takes long, as expected
- Handling errors such as powering off while getting bitmap
- Added support for any case key names
- Fixed typo for 'period' key
- Fixed state event (probably)
This commit is contained in:
Norbi Peti 2019-03-22 02:29:39 +01:00
parent 5e98afe66a
commit c8ea718787
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
7 changed files with 63 additions and 17 deletions

View file

@ -111,6 +111,7 @@ public class Commands implements CommandExecutor {
+ " [\"\",{\"text\":\" [Z]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key Z\"}},{\"text\":\" [X]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key X\"}},{\"text\":\" [C]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key C\"}},{\"text\":\" [V]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key V\"}},{\"text\":\" [B]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key B\"}},{\"text\":\" [N]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key N\"}},{\"text\":\" [M]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key M\"}}]"); + " [\"\",{\"text\":\" [Z]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key Z\"}},{\"text\":\" [X]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key X\"}},{\"text\":\" [C]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key C\"}},{\"text\":\" [V]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key V\"}},{\"text\":\" [B]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key B\"}},{\"text\":\" [N]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key N\"}},{\"text\":\" [M]\",\"color\":\"green\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/computer key M\"}}]");
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender.getName() Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender.getName()
+ " [\"\",{\"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;
case "mouse": case "mouse":
if (!MouseLockerPlayerListener.LockedPlayers.containsKey(sender)) { if (!MouseLockerPlayerListener.LockedPlayers.containsKey(sender)) {
MouseLockerPlayerListener.LockedPlayers.put((Player) sender, ((Player) sender).getLocation()); MouseLockerPlayerListener.LockedPlayers.put((Player) sender, ((Player) sender).getLocation());

View file

@ -156,10 +156,8 @@ public final class Computer {
durationorstate = -2; durationorstate = -2;
else else
durationorstate = Short.parseShort(stateorduration); durationorstate = Short.parseShort(stateorduration);
int code; int code = Scancode.getCode("sc_" + key.toLowerCase());
try { if (code == -1) {
code = Scancode.valueOf("sc_" + key.toLowerCase()).Code;
} catch (IllegalArgumentException e) {
sender.sendMessage("§cUnknown key: " + key); sender.sendMessage("§cUnknown key: " + key);
return; return;
} }
@ -193,7 +191,8 @@ public final class Computer {
UpdateMouse(sender, x, y, z, w, mbs, false); UpdateMouse(sender, x, y, z, w, mbs, false);
} }
public void stopRendering() { public void onMachineStop() {
//TODO session.unlockMachine();
plugin.getLogger().info("Computer powered off.");
} }
} }

View file

@ -2,7 +2,6 @@ package sznp.virtualcomputer.events;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.virtualbox_6_0.IMachineStateChangedEvent;
import org.virtualbox_6_0.IProgressTaskCompletedEvent; import org.virtualbox_6_0.IProgressTaskCompletedEvent;
import org.virtualbox_6_0.IStateChangedEvent; import org.virtualbox_6_0.IStateChangedEvent;
import org.virtualbox_6_0.VBoxEventType; import org.virtualbox_6_0.VBoxEventType;
@ -12,7 +11,7 @@ public class MachineEventHandler extends EventHandlerBase {
private final Computer computer; private final Computer computer;
public MachineEventHandler(Computer computer) { public MachineEventHandler(Computer computer) {
super(ImmutableMap.of(VBoxEventType.OnMachineStateChanged, IMachineStateChangedEvent.class, super(ImmutableMap.of(VBoxEventType.OnStateChanged, IStateChangedEvent.class,
VBoxEventType.OnProgressTaskCompleted, IProgressTaskCompletedEvent.class)); VBoxEventType.OnProgressTaskCompleted, IProgressTaskCompletedEvent.class));
this.computer = computer; this.computer = computer;
} }
@ -25,7 +24,7 @@ public class MachineEventHandler extends EventHandlerBase {
break; break;
case PoweredOff: case PoweredOff:
case Saved: case Saved:
computer.stopRendering(); computer.onMachineStop();
} }
} }
} }

View file

@ -10,6 +10,7 @@ import org.bukkit.map.MapCanvas;
import org.bukkit.map.MapPalette; import org.bukkit.map.MapPalette;
import org.bukkit.map.MapRenderer; import org.bukkit.map.MapRenderer;
import org.bukkit.map.MapView; import org.bukkit.map.MapView;
import sznp.virtualcomputer.util.Timing;
import java.awt.*; import java.awt.*;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -53,6 +54,7 @@ public class GPURenderer extends MapRenderer implements IRenderer {
@Override @Override
public void render(MapView map, MapCanvas canvas, Player player) { public void render(MapView map, MapCanvas canvas, Player player) {
Timing t = new Timing();
try { try {
if (kernel.isRendered()) return; //TODO: Stop rendering after computer is stopped if (kernel.isRendered()) return; //TODO: Stop rendering after computer is stopped
Field field = canvas.getClass().getDeclaredField("buffer"); Field field = canvas.getClass().getDeclaredField("buffer");
@ -67,5 +69,7 @@ public class GPURenderer extends MapRenderer implements IRenderer {
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
if (t.elapsedMS() > 60)
System.out.println("Map rendering took " + t.elapsedMS() + "ms");
} }
} }

View file

@ -9,6 +9,7 @@ import org.mozilla.interfaces.nsISupports;
import org.mozilla.xpcom.Mozilla; import org.mozilla.xpcom.Mozilla;
import org.virtualbox_6_0.*; import org.virtualbox_6_0.*;
import sznp.virtualcomputer.PluginMain; import sznp.virtualcomputer.PluginMain;
import sznp.virtualcomputer.util.Timing;
import java.util.Arrays; import java.util.Arrays;
@ -93,21 +94,22 @@ 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) {
System.out.println("Change - " + width + "x" + 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); * 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 } * return; // Don't even try to render too large resolutions }
*/ */
tt = Bukkit.getScheduler().runTaskLaterAsynchronously(PluginMain.Instance, () -> { tt = Bukkit.getScheduler().runTaskAsynchronously(PluginMain.Instance, () -> {
try { try {
display.querySourceBitmap(0L, holder); display.querySourceBitmap(0L, holder);
//byte[] arr = PluginMain.allpixels.array(); //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("Arr0:" + ptr[0]);
System.out.println("whbppbplpf: " + w[0] + " " + h[0] + " " + bpp[0] + " " + bpl[0] + " " + pf[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); //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]);
@ -121,11 +123,19 @@ 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!");
//System.out.println("Change task took "+ti.elapsedMS()+"ms");
} catch (VBoxException e) {
if (e.getResultCode() == 0x80070005)
return; // Machine is being powered down
if (e.getResultCode() == 0x80004005) //The function "querySourceBitmap" returned an error condition: "Operation failed (NS_ERROR_FAILURE)"
System.out.println("I don't know why this happens, but stopping the computer helps.");
e.printStackTrace();
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
} }
}, 5); // Wait 1/4th of a second }); // Wait 1/4th of a second - Don't
//System.out.println("Change took "+ti.elapsedMS()+"ms");
} }
@Override @Override
@ -138,7 +148,10 @@ public class MCFrameBuffer implements IFramebuffer {
((DirectRenderer) r).render(PluginMain.allpixels, x, y, width, height); ((DirectRenderer) r).render(PluginMain.allpixels, x, y, width, height);
System.out.println("Update!"); - The render is done each tick System.out.println("Update!"); - The render is done each tick
}, 5);*/ }, 5);*/
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
System.out.println("Update took " + t.elapsedMS() + "ms");
} }
@Override @Override

View file

@ -8,6 +8,8 @@ The scancode values come from:
- reading win32 WM_INPUT keyboard messages. - reading win32 WM_INPUT keyboard messages.
*/ */
import java.util.HashMap;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public enum Scancode { // https://handmade.network/forums/t/2011-keyboard_inputs_-_scancodes,_raw_input,_text_input,_key_names public enum Scancode { // https://handmade.network/forums/t/2011-keyboard_inputs_-_scancodes,_raw_input,_text_input,_key_names
@ -21,7 +23,7 @@ public enum Scancode { // https://handmade.network/forums/t/2011-keyboard_inputs
0x29), sc_shiftLeft(0x2A), sc_backslash(0x2B), sc_z( 0x29), sc_shiftLeft(0x2A), sc_backslash(0x2B), sc_z(
0x2C), sc_x(0x2D), sc_c(0x2E), sc_v(0x2F), sc_b( 0x2C), sc_x(0x2D), sc_c(0x2E), sc_v(0x2F), sc_b(
0x30), sc_n(0x31), sc_m(0x32), sc_comma( 0x30), sc_n(0x31), sc_m(0x32), sc_comma(
0x33), sc_preiod(0x34), sc_slash( 0x33), sc_period(0x34), sc_slash(
0x35), sc_shiftRight( 0x35), sc_shiftRight(
0x36), sc_numpad_multiply( 0x36), sc_numpad_multiply(
0x37), sc_altLeft( 0x37), sc_altLeft(
@ -107,6 +109,25 @@ public enum Scancode { // https://handmade.network/forums/t/2011-keyboard_inputs
* some times you get keyup messages too. - when pressed at the same time as one or both control keys, generates a 0xE046 (sc_cancel) and the string for that scancode is "break". * some times you get keyup messages too. - when pressed at the same time as one or both control keys, generates a 0xE046 (sc_cancel) and the string for that scancode is "break".
*/ */
private static final HashMap<String, Integer> scanCodes = new HashMap<>();
static {
for (Scancode sc : values())
scanCodes.put(sc.toString().toLowerCase(), sc.Code);
}
/**
* Gets the scancode from a lowercased string (O(1))
*
* @param keyLowerCased The key name, lowercased (sc_...)
* @return The code or -1 if not found
*/
public static int getCode(String keyLowerCased) {
Integer code = scanCodes.get(keyLowerCased);
if (code == null) return -1;
return code;
}
public int Code; public int Code;
Scancode(int code) { Scancode(int code) {

View file

@ -0,0 +1,9 @@
package sznp.virtualcomputer.util;
public class Timing {
private long start = System.nanoTime();
public long elapsedMS() {
return (System.nanoTime() - start) / 1000000L;
}
}