From 85d694d1c034ced8ffd5c7d9df29007f90e2d3e7 Mon Sep 17 00:00:00 2001 From: Scribble Date: Thu, 10 Aug 2023 21:58:31 +0200 Subject: [PATCH 01/57] Changed Virtual Keylist to enums - Changed Keys from a Hashmap-List Kombi to an enum --- .../tasmod/virtual/VirtualInput.java | 1 + .../tasmod/virtual/VirtualKey.java | 1 + .../tasmod/virtual/VirtualKeybindings.java | 1 + .../tasmod/virtual/VirtualKeyboard.java | 1 + .../tasmod/virtual/VirtualKeyboard2.java | 140 ++++++++++++++++++ .../tasmod/virtual/VirtualKeyboardEvent.java | 1 + .../tasmod/virtual/VirtualMouse.java | 1 + .../tasmod/virtual/VirtualMouse2.java | 42 ++++++ .../tasmod/virtual/VirtualMouseEvent.java | 7 +- 9 files changed, 192 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java create mode 100644 src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index 6045dfab..4119a144 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -84,6 +84,7 @@ * @author Scribble * */ +@Deprecated public class VirtualInput implements EventPlayerJoinedClientSide{ /** diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey.java index 67cd7323..4b70aa8e 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey.java @@ -8,6 +8,7 @@ * @author Scribble * */ +@Deprecated public class VirtualKey implements Serializable { /** diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeybindings.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeybindings.java index c2130f56..998ace52 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeybindings.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeybindings.java @@ -31,6 +31,7 @@ * @author Scribble * */ +@Deprecated public class VirtualKeybindings { private static Minecraft mc = Minecraft.getMinecraft(); private static long cooldown = 50*5; diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java index 4bbcbccf..6f193594 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java @@ -13,6 +13,7 @@ import com.google.common.collect.Maps; import com.minecrafttas.tasmod.playback.PlaybackSerialiser; +@Deprecated public class VirtualKeyboard implements Serializable { /** diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java new file mode 100644 index 00000000..f159322b --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java @@ -0,0 +1,140 @@ +package com.minecrafttas.tasmod.virtual; + +public class VirtualKeyboard2 { + + private enum VirtualKeys { + ZERO(0), + ESC(1), + KEY_1(2), + KEY_2(3), + KEY_3(4), + KEY_4(5), + KEY_5(6), + KEY_6(7), + KEY_7(8), + KEY_8(9), + KEY_9(10), + KEY_0(11), + MINUS(12), + EQUALS(13), + BACK(14), + TAB(15), + Q(16), + W(17), + E(18), + R(19), + T(20), + Y(21), + U(22), + I(23), + O(24), + P(25), + LBRACKET(26), + RBRACKET(27), + RETURN(28), + LCONTROL(29), + A(30), + S(31), + D(32), + F(33), + G(34), + H(35), + J(36), + K(37), + L(38), + SEMICOLON(39), + APOSTROPHE(40), + GRAVE(41), + LSHIFT(42), + BACKSLASH(43), + Z(44), + X(45), + C(46), + V(47), + B(48), + N(49), + M(50), + COMMA(51), + PERIOD(52), + SLASH(53), + RSHIFT(54), + MULTIPLY(55), + ALT(56), + SPACE(57), + CAPSLOCK(58), + F1(59), + F2(60), + F3(61), + F4(62), + F5(63), + F6(64), + F7(65), + F8(66), + F9(67), + F10(68), + NUMLOCK(69), + SCROLL(70), + NUMPAD7(71), + NUMPAD8(72), + NUMPAD9(73), + SUBTRACT(74), + NUMPAD4(75), + NUMPAD5(76), + NUMPAD6(77), + ADD(78), + NUMPAD1(79), + NUMPAD2(80), + NUMPAD3(81), + NUMPAD0(82), + DECIMAL(83), + F11(87), + F12(88), + F13(100), + F14(101), + F15(102), + F16(103), + F17(104), + F18(105), + KANA(112), + F19(113), + CONVERT(121), + NOCONVERT(123), + YEN(125), + NUMPADEQUALS(141), + CIRCUMFLEX(144), + AT(145), + COLON(146), + UNDERLINE(147), + KANJI(148), + STOP(149), + NUMPADENTER(156), + RCONTROL(157), + NUMPADCOMMA(179), + DIVIDE(181), + PRINT(183), + ALT_GR(184), + PAUSE(197), + HOME(199), + UP(200), + PRIOR(201), + LEFT(203), + RIGHT(205), + END(207), + DOWN(208), + NEXT(209), + INSERT(210), + DELETE(211), + WIN(219), + APPS(221); + + private int keyID; + + private VirtualKeys(int keyID) { + this.keyID = keyID; + } + + public int getKeyID() { + return keyID; + } + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java index 90d2a9e0..ef114e48 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java @@ -1,5 +1,6 @@ package com.minecrafttas.tasmod.virtual; +@Deprecated public class VirtualKeyboardEvent { private int keycode; private boolean keystate; diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java index 8d3ea7cb..f5e38990 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java @@ -10,6 +10,7 @@ import com.google.common.collect.Maps; import com.minecrafttas.tasmod.playback.PlaybackSerialiser; +@Deprecated public class VirtualMouse implements Serializable { /** diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java new file mode 100644 index 00000000..a936aeae --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java @@ -0,0 +1,42 @@ +package com.minecrafttas.tasmod.virtual; + +public class VirtualMouse2 { + + /** + * Creates a keyboard where all keys are unpressed + */ + public VirtualMouse2() { + // TODO Auto-generated constructor stub + } + + + public static enum VirtualMouseButtons{ + MOUSEMOVED(-101), + LC(-100), + RC(-99), + MC(-98), + MBUTTON4(-97), + MBUTTON5(-96), + MBUTTON6(-95), + MBUTTON7(-94), + MBUTTON8(-93), + MBUTTON9(-92), + MBUTTON10(-91), + MBUTTON11(-90), + MBUTTON12(-89), + MBUTTON13(-88), + MBUTTON14(-87), + MBUTTON15(-86), + MBUTTON16(-85); + + private int keyID; + + private VirtualMouseButtons(int keyID) { + this.keyID = keyID; + } + + public int getKeyID() { + return keyID; + } + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java index ba912793..f7d715e4 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java @@ -6,6 +6,7 @@ * @author ScribbleLP * */ +@Deprecated public class VirtualMouseEvent { private int keycode; private boolean state; @@ -42,7 +43,7 @@ public int getMouseY() { } @Override - public String toString() { - return keycode+", "+state+", "+scrollwheel+", "+mouseX+", "+mouseY; - } + public String toString() { + return keycode+", "+state+", "+scrollwheel+", "+mouseX+", "+mouseY; + } } From 3861062326572ead71b049049ea05461550bf09f Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 6 Jan 2024 14:43:12 +0100 Subject: [PATCH 02/57] [Playback] Moved controller variable out of VirtualInput to TASmodClient --- .../com/minecrafttas/tasmod/TASmodClient.java | 14 +++- .../externalGui/InputContainerView.java | 18 ++--- .../com/minecrafttas/tasmod/gui/InfoHud.java | 16 ++-- .../tasmod/handlers/InterpolationHandler.java | 4 +- .../tasmod/handlers/LoadingScreenHandler.java | 2 +- .../tasmod/ktrng/KillTheRNGHandler.java | 2 +- .../tasmod/mixin/MixinEntityRenderer.java | 3 +- .../tasmod/mixin/MixinGuiScreen.java | 2 +- .../tasmod/mixin/MixinMinecraft.java | 2 +- .../playback/PlaybackControllerClient.java | 10 +-- .../savestates/SavestateHandlerClient.java | 6 +- .../tasmod/virtual/VirtualInput.java | 78 ++++++++----------- 12 files changed, 76 insertions(+), 81 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java index 53c950fe..b2cc8ee0 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java @@ -18,6 +18,7 @@ import com.minecrafttas.tasmod.handlers.LoadingScreenHandler; import com.minecrafttas.tasmod.networking.TASmodBufferBuilder; import com.minecrafttas.tasmod.networking.TASmodPackets; +import com.minecrafttas.tasmod.playback.PlaybackControllerClient; import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate; import com.minecrafttas.tasmod.playback.PlaybackSerialiser; import com.minecrafttas.tasmod.savestates.SavestateHandlerClient; @@ -83,7 +84,12 @@ public class TASmodClient implements ClientModInitializer, EventClientInit, Even public static SavestateHandlerClient savestateHandlerClient = new SavestateHandlerClient(); public static Client client; - + /** + * The container where all inputs get stored during recording or stored and + * ready to be played back + */ + public static PlaybackControllerClient controller = new PlaybackControllerClient(); + public static void createTASDir() { File tasDir=new File(tasdirectory); if(!tasDir.exists()) { @@ -156,7 +162,7 @@ protected boolean isKeyDown(KeyBinding i) { // Register packet handlers LOGGER.info(LoggerMarkers.Networking, "Registering network handlers on client"); - PacketHandlerRegistry.register(virtual.getContainer()); //TODO Move container/playbackcontroller out of virtual package + PacketHandlerRegistry.register(controller); //TODO Move container/playbackcontroller out of virtual package PacketHandlerRegistry.register(ticksyncClient); PacketHandlerRegistry.register(tickratechanger); PacketHandlerRegistry.register(savestateHandlerClient); @@ -176,7 +182,7 @@ public void onClientInit(Minecraft mc) { List blockedKeybindings = new ArrayList<>(); blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Tickrate 0 Key", "TASmod", Keyboard.KEY_F8, () -> TASmodClient.tickratechanger.togglePause()))); blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Advance Tick", "TASmod", Keyboard.KEY_F9, () -> TASmodClient.tickratechanger.advanceTick()))); - blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Recording/Playback Stop", "TASmod", Keyboard.KEY_F10, () -> TASmodClient.virtual.getContainer().setTASState(TASstate.NONE)))); + blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Recording/Playback Stop", "TASmod", Keyboard.KEY_F10, () -> TASmodClient.controller.setTASState(TASstate.NONE)))); blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Create Savestate", "TASmod", Keyboard.KEY_J, () -> { try { TASmodClient.client.send(new TASmodBufferBuilder(TASmodPackets.SAVESTATE_SAVE).writeInt(-1)); @@ -294,7 +300,7 @@ public GuiScreen onOpenGui(GuiScreen gui) { ticksyncClient.setEnabled(true); } } else if (gui instanceof GuiControls) { - TASmodClient.virtual.getContainer().setTASState(TASstate.NONE); // Set the TASState to nothing to avoid collisions + TASmodClient.controller.setTASState(TASstate.NONE); // Set the TASState to nothing to avoid collisions if (TASmodClient.tickratechanger.ticksPerSecond == 0) { TASmodClient.tickratechanger.pauseClientGame(false); // Unpause the game waszero = true; diff --git a/src/main/java/com/minecrafttas/tasmod/externalGui/InputContainerView.java b/src/main/java/com/minecrafttas/tasmod/externalGui/InputContainerView.java index 240c155b..c5677b09 100644 --- a/src/main/java/com/minecrafttas/tasmod/externalGui/InputContainerView.java +++ b/src/main/java/com/minecrafttas/tasmod/externalGui/InputContainerView.java @@ -118,23 +118,23 @@ public static void update(VirtualInput input) { if (model == null) { return; } - PlaybackControllerClient container = input.getContainer(); - if (container == null || container.isEmpty()) { + PlaybackControllerClient controller = TASmodClient.controller; + if (controller == null || controller.isEmpty()) { return; } - if (prevCount != container.size()) { - prevCount = container.size(); + if (prevCount != controller.size()) { + prevCount = controller.size(); model.getDataVector().clear(); - for (int i = 0; i < container.size(); i++) { - TickInputContainer tickContainer = container.get(i); + for (int i = 0; i < controller.size(); i++) { + TickInputContainer tickContainer = controller.get(i); addRow(i + 1, tickContainer.getKeyboard().toString(), tickContainer.getMouse().toString(), tickContainer.getSubticks().getPitch(), tickContainer.getSubticks().getYaw()); } - selectRow(container.index()); + selectRow(controller.index()); } - if (!container.isNothingPlaying()) { - selectRow(container.index()); + if (!controller.isNothingPlaying()) { + selectRow(controller.index()); } // selectRow(container.index()+1); diff --git a/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java b/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java index 715dffd7..0183348e 100644 --- a/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java +++ b/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java @@ -324,7 +324,7 @@ public boolean checkInit() { if (Minecraft.getMinecraft().currentScreen == this) { return "State"; } else { - TASstate state = TASmodClient.virtual.getContainer().getState(); + TASstate state = TASmodClient.controller.getState(); ChatFormatting format = ChatFormatting.WHITE; String out = ""; if (state == TASstate.PLAYBACK) { @@ -377,7 +377,7 @@ public boolean checkInit() { if (configuration.getProperty(title + "_x", "err").equals("err")) setDefaults(title, y); lists.add(new InfoLabel(title, Integer.parseInt(configuration.getProperty(title + "_x")), Integer.parseInt(configuration.getProperty(title + "_y")), Boolean.parseBoolean(configuration.getProperty(title + "_visible")), Boolean.parseBoolean(configuration.getProperty(title + "_rect")), () -> { if (Minecraft.getMinecraft().currentScreen == this) return "Desync"; - DesyncMonitoring dMonitor=TASmodClient.virtual.getContainer().desyncMonitor; + DesyncMonitoring dMonitor=TASmodClient.controller.desyncMonitor; return dMonitor.getStatus(Minecraft.getMinecraft().player); })); @@ -386,7 +386,7 @@ public boolean checkInit() { if (configuration.getProperty(title + "_x", "err").equals("err")) setDefaults(title, y); lists.add(new InfoLabel(title, Integer.parseInt(configuration.getProperty(title + "_x")), Integer.parseInt(configuration.getProperty(title + "_y")), Boolean.parseBoolean(configuration.getProperty(title + "_visible")), Boolean.parseBoolean(configuration.getProperty(title + "_rect")), () -> { if (Minecraft.getMinecraft().currentScreen == this) return "Desync Motion"; - DesyncMonitoring dMonitor=TASmodClient.virtual.getContainer().desyncMonitor; + DesyncMonitoring dMonitor=TASmodClient.controller.desyncMonitor; return dMonitor.getMotion(); })); @@ -395,7 +395,7 @@ public boolean checkInit() { if (configuration.getProperty(title + "_x", "err").equals("err")) setDefaults(title, y); lists.add(new InfoLabel(title, Integer.parseInt(configuration.getProperty(title + "_x")), Integer.parseInt(configuration.getProperty(title + "_y")), Boolean.parseBoolean(configuration.getProperty(title + "_visible")), Boolean.parseBoolean(configuration.getProperty(title + "_rect")), () -> { if (Minecraft.getMinecraft().currentScreen == this) return "Desync Position"; - DesyncMonitoring dMonitor=TASmodClient.virtual.getContainer().desyncMonitor; + DesyncMonitoring dMonitor=TASmodClient.controller.desyncMonitor; return dMonitor.getPos(); })); @@ -404,7 +404,7 @@ public boolean checkInit() { if (configuration.getProperty(title + "_x", "err").equals("err")) setDefaults(title, y); lists.add(new InfoLabel(title, Integer.parseInt(configuration.getProperty(title + "_x")), Integer.parseInt(configuration.getProperty(title + "_y")), Boolean.parseBoolean(configuration.getProperty(title + "_visible")), Boolean.parseBoolean(configuration.getProperty(title + "_rect")), () -> { if (Minecraft.getMinecraft().currentScreen == this) return "Desync KTRNG"; - DesyncMonitoring dMonitor=TASmodClient.virtual.getContainer().desyncMonitor; + DesyncMonitoring dMonitor=TASmodClient.controller.desyncMonitor; return dMonitor.getSeed(); })); @@ -414,7 +414,7 @@ public boolean checkInit() { if (configuration.getProperty(title + "_x", "err").equals("err")) setDefaults(title, y, true); lists.add(new InfoLabel(title, Integer.parseInt(configuration.getProperty(title + "_x")), Integer.parseInt(configuration.getProperty(title + "_y")), Boolean.parseBoolean(configuration.getProperty(title + "_visible")), Boolean.parseBoolean(configuration.getProperty(title + "_rect")), () -> { if (Minecraft.getMinecraft().currentScreen == this) return "PlaybackIndex"; - return Integer.toString(TASmodClient.virtual.getContainer().index()); + return Integer.toString(TASmodClient.controller.index()); })); y = height - 14; @@ -437,10 +437,10 @@ public boolean checkInit() { @Override public void onDrawHotbar() { // render custom info box if control byte is set - if (!ControlByteHandler.hideInfoBox && TASmodClient.virtual.getContainer().isPlayingback()) + if (!ControlByteHandler.hideInfoBox && TASmodClient.controller.isPlayingback()) drawRectWithText(ControlByteHandler.text, 10, 10, true); // skip rendering of control byte is set - if (!ControlByteHandler.shouldRenderHud && TASmodClient.virtual.getContainer().isPlayingback()) + if (!ControlByteHandler.shouldRenderHud && TASmodClient.controller.isPlayingback()) return; int xpos=40; int ypos=190; diff --git a/src/main/java/com/minecrafttas/tasmod/handlers/InterpolationHandler.java b/src/main/java/com/minecrafttas/tasmod/handlers/InterpolationHandler.java index 449be61f..a7a86d4e 100644 --- a/src/main/java/com/minecrafttas/tasmod/handlers/InterpolationHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/handlers/InterpolationHandler.java @@ -22,8 +22,8 @@ public class InterpolationHandler implements EventCamera { @Override public CameraData onCameraEvent(CameraData dataIn) { - if (TASmodClient.virtual.getContainer().isPlayingback() && ControlByteHandler.shouldInterpolate) { - TickInputContainer input = TASmodClient.virtual.getContainer().get(); + if (TASmodClient.controller.isPlayingback() && ControlByteHandler.shouldInterpolate) { + TickInputContainer input = TASmodClient.controller.get(); if (input == null) return dataIn; float nextPitch = input.getSubticks().getPitch(); diff --git a/src/main/java/com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java b/src/main/java/com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java index 089331e3..82323cb1 100644 --- a/src/main/java/com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java @@ -27,7 +27,7 @@ public class LoadingScreenHandler implements EventLaunchIntegratedServer, EventC @Override public void onLaunchIntegratedServer() { LOGGER.debug(LoggerMarkers.Event, "Starting the integrated server"); - PlaybackControllerClient container = TASmodClient.virtual.getContainer(); + PlaybackControllerClient container = TASmodClient.controller; if (!container.isNothingPlaying() && !container.isPaused()) { container.pause(true); } diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/KillTheRNGHandler.java b/src/main/java/com/minecrafttas/tasmod/ktrng/KillTheRNGHandler.java index 66d8533b..2cd67bb8 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/KillTheRNGHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/KillTheRNGHandler.java @@ -211,7 +211,7 @@ public void onClientPacket(PacketID id, ByteBuffer buf, String username) throws break; case KILLTHERNG_STARTSEED: - TASmodClient.virtual.getContainer().setStartSeed(seed); + TASmodClient.controller.setStartSeed(seed); break; default: diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/MixinEntityRenderer.java b/src/main/java/com/minecrafttas/tasmod/mixin/MixinEntityRenderer.java index 8e8e32d4..fa7c83a5 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/MixinEntityRenderer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/MixinEntityRenderer.java @@ -20,6 +20,7 @@ import net.minecraft.util.math.MathHelper; @Mixin(EntityRenderer.class) +@SuppressWarnings("unused") public class MixinEntityRenderer implements SubtickDuck { public double dX = 0; @@ -55,7 +56,7 @@ public void injectAtStartSection(float partialTicks, long nanoTime, CallbackInfo dX = 0; dY = 0; } - if (TASmodClient.virtual.getContainer().isPlayingback()) { + if (TASmodClient.controller.isPlayingback()) { dX = 0; dY = 0; } else { diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/MixinGuiScreen.java b/src/main/java/com/minecrafttas/tasmod/mixin/MixinGuiScreen.java index 73c5d859..b322f41d 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/MixinGuiScreen.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/MixinGuiScreen.java @@ -78,7 +78,7 @@ public int redirectGetEventButton() { @Redirect(method = "handleMouseInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventButtonState()Z", remap = false)) public boolean redirectGetEventButtonState() { - if (TASmodClient.virtual.getContainer().isPlayingback()) { + if (TASmodClient.controller.isPlayingback()) { Mouse.setCursorPosition(uncalcX(TASmodClient.virtual.getEventCursorX()), uncalcY(TASmodClient.virtual.getEventCursorY())); } return TASmodClient.virtual.getEventMouseState(); diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java index 4401621c..32f426b5 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java @@ -218,6 +218,6 @@ public boolean redirectGetEventKeyStateDPK() { @Inject(method = "runTick", at = @At(value = "RETURN")) public void injectRunTickReturn(CallbackInfo ci) { - TASmodClient.virtual.getContainer().nextTick(); + TASmodClient.controller.nextTick(); } } diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index 839a04c4..0aa36600 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -811,7 +811,7 @@ public static enum TASstate { public void setStateWhenOpened(TASstate state) { TASmodClient.openMainMenuScheduler.add(() -> { - PlaybackControllerClient container = TASmodClient.virtual.getContainer(); + PlaybackControllerClient container = TASmodClient.controller; if (state == TASstate.RECORDING) { long seed = TASmod.ktrngHandler.getGlobalSeedClient(); container.setStartSeed(seed); @@ -895,7 +895,7 @@ public void onClientPacket(PacketID id, ByteBuffer buf, String username) throws case PLAYBACK_FULLRECORD: setStateWhenOpened(TASstate.RECORDING); // Set the state to RECORDING when the main menu is opened - TASmodClient.virtual.getContainer().clear(); // Clear inputs + TASmodClient.controller.clear(); // Clear inputs // Schedule code to be executed on the next tick TASmodClient.tickSchedulerClient.add(() -> { @@ -923,11 +923,11 @@ public void onClientPacket(PacketID id, ByteBuffer buf, String username) throws case PLAYBACK_PLAYUNTIL: int until = ByteBufferBuilder.readInt(buf); - TASmodClient.virtual.getContainer().setPlayUntil(until); + TASmodClient.controller.setPlayUntil(until); break; case PLAYBACK_CLEAR_INPUTS: - TASmodClient.virtual.getContainer().clear(); + TASmodClient.controller.clear(); break; case PLAYBACK_TELEPORT: @@ -937,7 +937,7 @@ public void onClientPacket(PacketID id, ByteBuffer buf, String username) throws TASstate networkState = TASmodBufferBuilder.readTASState(buf); boolean verbose = TASmodBufferBuilder.readBoolean(buf); Task task = ()->{ - PlaybackControllerClient container = TASmodClient.virtual.getContainer(); + PlaybackControllerClient container = TASmodClient.controller; if (networkState != container.getState()) { String message = container.setTASStateClient(networkState, verbose); diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerClient.java b/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerClient.java index 23fb1f0e..8ac8559a 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerClient.java @@ -119,7 +119,7 @@ public static void savestate(String nameOfSavestate) throws SavestateException, File targetfile = new File(SavestateHandlerClient.savestateDirectory, nameOfSavestate + ".mctas"); - PlaybackControllerClient container = TASmodClient.virtual.getContainer(); + PlaybackControllerClient container = TASmodClient.controller; if (container.isRecording()) { TASmodClient.serialiser.saveToFileV1(targetfile, container); // If the container is recording, store it entirely } else if (container.isPlayingback()) { @@ -146,13 +146,13 @@ public static void loadstate(String nameOfSavestate) throws IOException { File targetfile = new File(savestateDirectory, nameOfSavestate + ".mctas"); - PlaybackControllerClient container = TASmodClient.virtual.getContainer(); + PlaybackControllerClient container = TASmodClient.controller; if (!container.isNothingPlaying()) { // If the file exists and the container is recording or playing, load the // clientSavestate if (targetfile.exists()) { TASmodClient.virtual.loadClientSavestate(TASmodClient.serialiser.fromEntireFileV1(targetfile)); } else { - TASmodClient.virtual.getContainer().setTASStateClient(TASstate.NONE, false); + TASmodClient.controller.setTASStateClient(TASstate.NONE, false); Minecraft.getMinecraft().player.sendMessage(new TextComponentString(ChatFormatting.YELLOW + "Inputs could not be loaded for this savestate,")); Minecraft.getMinecraft().player.sendMessage(new TextComponentString(ChatFormatting.YELLOW + "since the file doesn't exist. Stopping!")); LOGGER.warn(LoggerMarkers.Savestate, "Inputs could not be loaded for this savestate, since the file doesn't exist."); diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index 4119a144..95cd69fc 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -1,23 +1,22 @@ package com.minecrafttas.tasmod.virtual; -import static com.minecrafttas.tasmod.TASmod.LOGGER; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - import com.minecrafttas.mctcommon.events.EventClient.EventPlayerJoinedClientSide; import com.minecrafttas.tasmod.TASmodClient; import com.minecrafttas.tasmod.playback.PlaybackControllerClient; import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate; import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TickInputContainer; import com.minecrafttas.tasmod.util.PointerNormalizer; - import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import static com.minecrafttas.tasmod.TASmod.LOGGER; + /** * One of the core classes of this mod
*
@@ -84,15 +83,8 @@ * @author Scribble * */ -@Deprecated public class VirtualInput implements EventPlayerJoinedClientSide{ - /** - * The container where all inputs get stored during recording or stored and - * ready to be played back - */ - private PlaybackControllerClient container = new PlaybackControllerClient(); - // ===========================Keyboard================================= /** @@ -131,7 +123,7 @@ public VirtualInput(String fileToLoad) { if (fileToLoad != null) { try { loadInputs(fileToLoad); - container.setStateWhenOpened(TASstate.PLAYBACK); + TASmodClient.controller.setStateWhenOpened(TASstate.PLAYBACK); } catch (IOException e) { LOGGER.error("Cannot load inputs from the start of the TAS: {}", e.getMessage()); } @@ -248,8 +240,8 @@ public List getCurrentKeyboardPresses() { public List getNextKeyboardPresses() { List out = new ArrayList(); - if (container.isPlayingback() && container.get(container.index()) != null) { - container.get(container.index()).getKeyboard().getKeyList().forEach((keycodes, virtualkeys) -> { + if (TASmodClient.controller.isPlayingback() && TASmodClient.controller.get(TASmodClient.controller.index()) != null) { + TASmodClient.controller.get(TASmodClient.controller.index()).getKeyboard().getKeyList().forEach((keycodes, virtualkeys) -> { if (virtualkeys.isKeyDown()) { out.add(virtualkeys.getName()); } @@ -376,8 +368,8 @@ public List getCurrentMousePresses() { public List getNextMousePresses() { List out = new ArrayList(); - if (container.isPlayingback() && container.get(container.index()) != null) { - container.get(container.index()).getMouse().getKeyList().forEach((keycodes, virtualkeys) -> { + if (TASmodClient.controller.isPlayingback() && TASmodClient.controller.get(TASmodClient.controller.index()) != null) { + TASmodClient.controller.get(TASmodClient.controller.index()).getMouse().getKeyList().forEach((keycodes, virtualkeys) -> { if (virtualkeys.isKeyDown()) { out.add(virtualkeys.getName()); } @@ -394,7 +386,7 @@ public List getNextMousePresses() { } public void unpressEverything() { - container.unpressContainer(); + TASmodClient.controller.unpressContainer(); unpressNext(); } @@ -408,7 +400,7 @@ public void unpressNext() { VirtualSubticks currentSubtick = new VirtualSubticks(0, 0); public void updateSubtick(float pitch, float yaw) { - currentSubtick = container.addSubticksToContainer(new VirtualSubticks(pitch, yaw)); + currentSubtick = TASmodClient.controller.addSubticksToContainer(new VirtualSubticks(pitch, yaw)); } public float getSubtickPitch() { @@ -421,34 +413,30 @@ public float getSubtickYaw() { // =====================================Container=========================================== - public PlaybackControllerClient getContainer() { - return container; - } - /** * Updates the input container and the {@link #nextKeyboard} as well as * {@link #nextMouse}
* Gets executed each game tick */ public void updateContainer() { - nextKeyboard = container.addKeyboardToContainer(nextKeyboard); - nextMouse = container.addMouseToContainer(nextMouse); + nextKeyboard = TASmodClient.controller.addKeyboardToContainer(nextKeyboard); + nextMouse = TASmodClient.controller.addMouseToContainer(nextMouse); } /** - * Replaces the {@link #container}, used in + * Replaces the {@link TASmodClient#controller}, used in * * @param container to replace the current one */ public void setContainer(PlaybackControllerClient container) { - this.container = container; + TASmodClient.controller = container; } // =====================================Savestates=========================================== /** * Loads and preloads the inputs from the new InputContainer to - * {@link #container} + * {@link TASmodClient#controller} * * Saving a savestate is done via {@linkplain com.minecrafttas.tasmod.playback.PlaybackSerialiser#saveToFileV1(File, PlaybackControllerClient)} in {@linkplain com.minecrafttas.tasmod.savestates.SavestateHandlerClient#savestate(String)} * @@ -456,8 +444,8 @@ public void setContainer(PlaybackControllerClient container) { */ public void loadClientSavestate(PlaybackControllerClient savestatecontainer) { - if (container.isPlayingback()) { - preloadInput(container, savestatecontainer.size() - 1); // Preloading from the current container and + if (TASmodClient.controller.isPlayingback()) { + preloadInput(TASmodClient.controller, savestatecontainer.size() - 1); // Preloading from the current container and // from the second to last index of // the savestatecontainer. Since this is // executed during playback, @@ -467,11 +455,11 @@ public void loadClientSavestate(PlaybackControllerClient savestatecontainer) { // that the playback would immediately end // when you replace the container. - if (container.size() >= savestatecontainer.size()) { // Check if the current container is bigger than the + if (TASmodClient.controller.size() >= savestatecontainer.size()) { // Check if the current container is bigger than the // savestated one. try { - container.setIndex(savestatecontainer.size()); // Set the "playback" index of the current + TASmodClient.controller.setIndex(savestatecontainer.size()); // Set the "playback" index of the current // container to the latest index of the // savestatecontainer. Meaning this index will // be played next @@ -489,10 +477,10 @@ public void loadClientSavestate(PlaybackControllerClient savestatecontainer) { } savestatecontainer.setTASStateClient(TASstate.PLAYBACK); savestatecontainer.setStartLocation(start); - container = savestatecontainer; + TASmodClient.controller = savestatecontainer; } - } else if (container.isRecording()) { + } else if (TASmodClient.controller.isRecording()) { String start = savestatecontainer.getStartLocation(); preloadInput(savestatecontainer, savestatecontainer.size() - 1); // Preload the input of the savestate @@ -509,7 +497,7 @@ public void loadClientSavestate(PlaybackControllerClient savestatecontainer) { savestatecontainer.setTASStateClient(TASstate.RECORDING); savestatecontainer.setStartLocation(start); - container = savestatecontainer; // Replace the current container with the savestated container + TASmodClient.controller = savestatecontainer; // Replace the current container with the savestated container } } @@ -540,12 +528,12 @@ private void preloadInput(PlaybackControllerClient container, int index) { public void loadInputs(String filename) throws IOException { setContainer(TASmodClient.serialiser.fromEntireFileV1(new File(TASmodClient.tasdirectory + "/" + filename + ".mctas"))); - getContainer().fixTicks(); + TASmodClient.controller.fixTicks(); } public void saveInputs(String filename) throws IOException { TASmodClient.createTASDir(); - TASmodClient.serialiser.saveToFileV1(new File(TASmodClient.tasdirectory + "/" + filename + ".mctas"), TASmodClient.virtual.getContainer()); + TASmodClient.serialiser.saveToFileV1(new File(TASmodClient.tasdirectory + "/" + filename + ".mctas"), TASmodClient.controller); } // =====================================Debug=========================================== @@ -573,7 +561,7 @@ public InputEvent(int tick, List keyboardevent, List *
- * This however runs through the {@link VirtualInput#container} and generates + * This however runs through the {@link TASmodClient#controller} and generates * the input events on for debug purposes. * * @return @@ -582,10 +570,10 @@ public List getAllInputEvents() { List main = new ArrayList<>(); - for (int i = 0; i < container.size(); i++) { + for (int i = 0; i < TASmodClient.controller.size(); i++) { - TickInputContainer tick = container.get(i); - TickInputContainer nextTick = container.get(i + 1); + TickInputContainer tick = TASmodClient.controller.get(i); + TickInputContainer nextTick = TASmodClient.controller.get(i + 1); if (nextTick == null) { nextTick = new TickInputContainer(i + 1); // Fills the last tick in the container with an empty TickInputContainer From 34d875a6cc997ce047e33010d32facfcb364f15b Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 6 Jan 2024 17:48:27 +0100 Subject: [PATCH 03/57] [VirtualKeyboard] Added VirtualPeripheral - Added VirtualPeripheral as base class for Mouse and keyboard, Containing the button pressing code shared between both - Moved keyboard keys and mouse keys to VirtualKey. - Moved all key related functions into VirtualKey - Moved special unicodes into VirtualKey, making it possible to assign them to mosue buttons - Reworked getDifference and how to store presses alltogether (WIP) --- .../tasmod/virtual/VirtualEvent.java | 29 +++ .../tasmod/virtual/VirtualKey2.java | 213 +++++++++++++++++ .../tasmod/virtual/VirtualKeyboard.java | 2 +- .../tasmod/virtual/VirtualKeyboard2.java | 217 +++++++----------- .../tasmod/virtual/VirtualKeyboardEvent.java | 44 ++-- .../tasmod/virtual/VirtualMouse2.java | 34 +-- .../tasmod/virtual/VirtualMouseEvent.java | 1 - .../tasmod/virtual/VirtualPeripheral.java | 52 +++++ 8 files changed, 401 insertions(+), 191 deletions(-) create mode 100644 src/main/java/com/minecrafttas/tasmod/virtual/VirtualEvent.java create mode 100644 src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey2.java create mode 100644 src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualEvent.java new file mode 100644 index 00000000..e00d58a5 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualEvent.java @@ -0,0 +1,29 @@ +package com.minecrafttas.tasmod.virtual; + +public class VirtualEvent { + protected final int keycode; + protected final boolean keystate; + + public VirtualEvent(int keycode, boolean keystate) { + this.keycode = keycode; + this.keystate = keystate; + } + + public VirtualEvent(VirtualEvent event){ + this.keycode = event.keycode; + this.keystate = event.keystate; + } + + public int getKeyCode() { + return keycode; + } + + public boolean isState() { + return keystate; + } + + @Override + public String toString() { + return String.format("%s, %s", keycode, keystate); + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey2.java new file mode 100644 index 00000000..d0c3ba31 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey2.java @@ -0,0 +1,213 @@ +package com.minecrafttas.tasmod.virtual; + +public enum VirtualKey2 { + // Keyboard + ZERO(0), + ESC(1), + KEY_1(2), + KEY_2(3), + KEY_3(4), + KEY_4(5), + KEY_5(6), + KEY_6(7), + KEY_7(8), + KEY_8(9), + KEY_9(10), + KEY_0(11), + MINUS(12), + EQUALS(13), + BACK(14, '\b'), + TAB(15, '\u21A6'), + Q(16), + W(17), + E(18), + R(19), + T(20), + Y(21), + U(22), + I(23), + O(24), + P(25), + LBRACKET(26), + RBRACKET(27), + RETURN(28), + LCONTROL(29), + A(30), + S(31), + D(32), + F(33), + G(34), + H(35), + J(36), + K(37), + L(38), + SEMICOLON(39), + APOSTROPHE(40), + GRAVE(41), + LSHIFT(42), + BACKSLASH(43), + Z(44), + X(45), + C(46), + V(47), + B(48), + N(49), + M(50), + COMMA(51), + PERIOD(52), + SLASH(53), + RSHIFT(54), + MULTIPLY(55), + ALT(56), + SPACE(57), + CAPSLOCK(58), + F1(59), + F2(60), + F3(61), + F4(62), + F5(63), + F6(64), + F7(65), + F8(66), + F9(67), + F10(68), + NUMLOCK(69), + SCROLL(70), + NUMPAD7(71), + NUMPAD8(72), + NUMPAD9(73), + SUBTRACT(74), + NUMPAD4(75), + NUMPAD5(76), + NUMPAD6(77), + ADD(78), + NUMPAD1(79), + NUMPAD2(80), + NUMPAD3(81), + NUMPAD0(82), + DECIMAL(83), + F11(87), + F12(88), + F13(100), + F14(101), + F15(102), + F16(103), + F17(104), + F18(105), + KANA(112), + F19(113), + CONVERT(121), + NOCONVERT(123), + YEN(125), + NUMPADEQUALS(141), + CIRCUMFLEX(144), + AT(145), + COLON(146), + UNDERLINE(147), + KANJI(148), + STOP(149), + NUMPADENTER(156), + RCONTROL(157), + NUMPADCOMMA(179), + DIVIDE(181), + PRINT(183), + ALT_GR(184), + PAUSE(197), + HOME(199, '\u21E4'), + UP(200, '\u2191'), + PRIOR(201, '\u21E7'), + LEFT(203, '\u2190'), + RIGHT(205, '\u2192'), + END(207, '\u21E5'), + DOWN(208, '\u2193'), + NEXT(209, '\u21E9'), + INSERT(210), + DELETE(211), + WIN(219), + APPS(221), + + // Mouse + MOUSEMOVED(-101), + LC(-100), + RC(-99), + MC(-98), + MBUTTON4(-97), + MBUTTON5(-96), + MBUTTON6(-95), + MBUTTON7(-94), + MBUTTON8(-93), + MBUTTON9(-92), + MBUTTON10(-91), + MBUTTON11(-90), + MBUTTON12(-89), + MBUTTON13(-88), + MBUTTON14(-87), + MBUTTON15(-86), + MBUTTON16(-85); + + private final int keycode; + private final Character unicode; + + private VirtualKey2(int keycode) { + this(keycode, null); + } + + private VirtualKey2(int keycode, Character unicode){ + this.keycode = keycode; + this.unicode = unicode; + } + + public int getKeycode() { + return keycode; + } + + public Character getUnicode() { return unicode; } + + public static Integer getKeycode(String keyname) { + VirtualKey2 key = get(keyname); + if (key != null) + return key.getKeycode(); + return null; + } + + public static String getName(int keycode) { + VirtualKey2 key = get(keycode); + if (key != null) + return key.name(); + return Integer.toString(keycode); + } + + public static Character getUnicode(int keycode){ + VirtualKey2 key = get(keycode); + if(key!=null) + return key.getUnicode(); + return null; + } + + public static Character getUnicode(String keyname){ + VirtualKey2 key = get(keyname); + if(key!=null) + return key.getUnicode(); + return null; + } + + + + public static VirtualKey2 get(int keycode) { + for (VirtualKey2 key : values()) { + if (key.getKeycode() == keycode) { + return key; + } + } + return null; + } + + public static VirtualKey2 get(String keyname) { + for (VirtualKey2 key : values()) { + if (key.name().equalsIgnoreCase(keyname)) { + return key; + } + } + return null; + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java index 6f193594..69b1035a 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java @@ -286,7 +286,7 @@ public char encodeUnicode(int keycode, char character) { return '\u21E4'; case 200: // Arrow Up return '\u2191'; - case 201: // Next + case 201: // Prior return '\u21E7'; case 203: // Arrow Left return '\u2190'; diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java index f159322b..e184fe33 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java @@ -1,140 +1,89 @@ package com.minecrafttas.tasmod.virtual; -public class VirtualKeyboard2 { - - private enum VirtualKeys { - ZERO(0), - ESC(1), - KEY_1(2), - KEY_2(3), - KEY_3(4), - KEY_4(5), - KEY_5(6), - KEY_6(7), - KEY_7(8), - KEY_8(9), - KEY_9(10), - KEY_0(11), - MINUS(12), - EQUALS(13), - BACK(14), - TAB(15), - Q(16), - W(17), - E(18), - R(19), - T(20), - Y(21), - U(22), - I(23), - O(24), - P(25), - LBRACKET(26), - RBRACKET(27), - RETURN(28), - LCONTROL(29), - A(30), - S(31), - D(32), - F(33), - G(34), - H(35), - J(36), - K(37), - L(38), - SEMICOLON(39), - APOSTROPHE(40), - GRAVE(41), - LSHIFT(42), - BACKSLASH(43), - Z(44), - X(45), - C(46), - V(47), - B(48), - N(49), - M(50), - COMMA(51), - PERIOD(52), - SLASH(53), - RSHIFT(54), - MULTIPLY(55), - ALT(56), - SPACE(57), - CAPSLOCK(58), - F1(59), - F2(60), - F3(61), - F4(62), - F5(63), - F6(64), - F7(65), - F8(66), - F9(67), - F10(68), - NUMLOCK(69), - SCROLL(70), - NUMPAD7(71), - NUMPAD8(72), - NUMPAD9(73), - SUBTRACT(74), - NUMPAD4(75), - NUMPAD5(76), - NUMPAD6(77), - ADD(78), - NUMPAD1(79), - NUMPAD2(80), - NUMPAD3(81), - NUMPAD0(82), - DECIMAL(83), - F11(87), - F12(88), - F13(100), - F14(101), - F15(102), - F16(103), - F17(104), - F18(105), - KANA(112), - F19(113), - CONVERT(121), - NOCONVERT(123), - YEN(125), - NUMPADEQUALS(141), - CIRCUMFLEX(144), - AT(145), - COLON(146), - UNDERLINE(147), - KANJI(148), - STOP(149), - NUMPADENTER(156), - RCONTROL(157), - NUMPADCOMMA(179), - DIVIDE(181), - PRINT(183), - ALT_GR(184), - PAUSE(197), - HOME(199), - UP(200), - PRIOR(201), - LEFT(203), - RIGHT(205), - END(207), - DOWN(208), - NEXT(209), - INSERT(210), - DELETE(211), - WIN(219), - APPS(221); - - private int keyID; - - private VirtualKeys(int keyID) { - this.keyID = keyID; +import org.spongepowered.asm.mixin.Overwrite; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentLinkedQueue; + +public class VirtualKeyboard2 extends VirtualPeripheral implements Serializable{ + + private List charList; + + @Override + public void setPressed(int keycode, boolean keystate) { + if(keycode >= 0){ // Keyboard keys always have a keycode larger or equal than 0 + super.setPressed(keycode, keystate); } - - public int getKeyID() { - return keyID; + } + + @Override + protected List getDifference(T nextPeripheral) { + List eventList = new ArrayList<>(); + + ConcurrentLinkedQueue chars = new ConcurrentLinkedQueue<>(charList); + + /* Calculate symmetric difference */ + + /* + * Calculate unpressed keys + * this: W A S + * next: W S D + * ------------- + * A <- unpressed + * */ + this.pressedKeys.forEach(key -> { + if(!nextPeripheral.pressedKeys.contains(key)){ + eventList.add(new VirtualKeyboardEvent(key, false, Character.MIN_VALUE)); + } + }); + + /* + Calculate pressed keys + next: W S D + this: W A S + ------------- + D <- pressed + */ + nextPeripheral.pressedKeys.forEach(key -> { + if(!this.pressedKeys.contains(key)){ + eventList.add(new VirtualKeyboardEvent(key, true, chars.poll())); + } + }); + + /* + Add the rest of the characters as keyboard events. + This may happen when specifying more chars than keycodes + int the TASFile: + + Keyboard:H,E,L;Hello| + + This makes it easier to write words when working only with the TASfile, + otherwise you'd either need to add a keycode for each char or write it in new lines + */ + while(!chars.isEmpty()){ + eventList.add(new VirtualKeyboardEvent(VirtualKey2.ZERO.getKeycode(), true, chars.poll())); } + + return eventList; + } + + public void addChar(char character){ + charList.add(character); + } + + private void clearCharacters(){ + charList.clear(); + } + + public void clear(){ + super.clearPressedKeys(); + clearCharacters(); + } + + @Override + public String toString() { + return super.toString(); } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java index ef114e48..ac78a4cd 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java @@ -1,27 +1,23 @@ package com.minecrafttas.tasmod.virtual; -@Deprecated -public class VirtualKeyboardEvent { - private int keycode; - private boolean keystate; - private char character; - public VirtualKeyboardEvent(int keycode, boolean keystate, char character) { - this.keycode=keycode; - this.keystate=keystate; - this.character=character; - } - public int getKeyCode() { - return keycode; - } - public boolean isState() { - return keystate; - } - public char getCharacter() { - return character; - } - - @Override - public String toString() { - return keycode+", "+keystate+", "+character; - } +public class VirtualKeyboardEvent extends VirtualEvent { + private final Character character; + + public VirtualKeyboardEvent(int keycode, boolean keystate, Character character) { + super(keycode, keystate); + this.character = character; + } + public VirtualKeyboardEvent(VirtualEvent event, char character){ + super(event); + this.character = character; + } + + public char getCharacter() { + return character; + } + + @Override + public String toString() { + return String.format("%s, %s", super.toString(), character != null ? character : Character.MIN_VALUE); + } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java index a936aeae..ba6f1ce1 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java @@ -1,6 +1,8 @@ package com.minecrafttas.tasmod.virtual; -public class VirtualMouse2 { +import java.io.Serializable; + +public class VirtualMouse2 extends VirtualPeripheral implements Serializable { /** * Creates a keyboard where all keys are unpressed @@ -9,34 +11,4 @@ public VirtualMouse2() { // TODO Auto-generated constructor stub } - - public static enum VirtualMouseButtons{ - MOUSEMOVED(-101), - LC(-100), - RC(-99), - MC(-98), - MBUTTON4(-97), - MBUTTON5(-96), - MBUTTON6(-95), - MBUTTON7(-94), - MBUTTON8(-93), - MBUTTON9(-92), - MBUTTON10(-91), - MBUTTON11(-90), - MBUTTON12(-89), - MBUTTON13(-88), - MBUTTON14(-87), - MBUTTON15(-86), - MBUTTON16(-85); - - private int keyID; - - private VirtualMouseButtons(int keyID) { - this.keyID = keyID; - } - - public int getKeyID() { - return keyID; - } - } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java index f7d715e4..eede2b11 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java @@ -6,7 +6,6 @@ * @author ScribbleLP * */ -@Deprecated public class VirtualMouseEvent { private int keycode; private boolean state; diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java new file mode 100644 index 00000000..844c5315 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java @@ -0,0 +1,52 @@ +package com.minecrafttas.tasmod.virtual; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public abstract class VirtualPeripheral implements Serializable { + protected final Set pressedKeys; + + public VirtualPeripheral() { + this.pressedKeys = new HashSet<>(); + } + + public VirtualPeripheral(Set pressedKeys) { + this.pressedKeys = pressedKeys; + } + + public void setPressed(int keycode, boolean keystate) { + if (keystate) + pressedKeys.add(keycode); + else + pressedKeys.remove(keycode); + } + + public void setPressed(String keyname, boolean keystate) { + Integer keycode = VirtualKey2.getKeycode(keyname); + if (keycode != null) { + setPressed(keycode, keystate); + } + } + + public List getCurrentPresses() { + List out = new ArrayList<>(); + pressedKeys.forEach(keycode -> { + out.add(VirtualKey2.getName(keycode)); + }); + return out; + } + + protected void clearPressedKeys() { + pressedKeys.clear(); + } + + protected abstract List getDifference(T nextPeripheral); + + @Override + public String toString() { + return String.join(",", getCurrentPresses()); + } +} \ No newline at end of file From 056c09c9ae176f9109f28e116a57c181a408dcd6 Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 6 Jan 2024 18:03:48 +0100 Subject: [PATCH 04/57] [VirtualInput] Renamed VirtualSubticks to VirtualCamera, fixed format --- .../playback/PlaybackControllerClient.java | 14 +-- .../tasmod/playback/PlaybackSerialiser.java | 6 +- ...irtualSubticks.java => VirtualCamera.java} | 10 +- .../tasmod/virtual/VirtualEvent.java | 2 +- .../tasmod/virtual/VirtualInput.java | 8 +- .../tasmod/virtual/VirtualKey2.java | 16 +-- .../tasmod/virtual/VirtualKeyboard2.java | 110 +++++++++--------- .../tasmod/virtual/VirtualKeyboardEvent.java | 3 +- .../tasmod/virtual/VirtualMouse2.java | 8 +- .../tasmod/virtual/VirtualMouseEvent.java | 60 ++++------ 10 files changed, 115 insertions(+), 122 deletions(-) rename src/main/java/com/minecrafttas/tasmod/virtual/{VirtualSubticks.java => VirtualCamera.java} (72%) diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index 0aa36600..edd1c3eb 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -39,7 +39,7 @@ import com.minecrafttas.tasmod.virtual.VirtualInput; import com.minecrafttas.tasmod.virtual.VirtualKeyboard; import com.minecrafttas.tasmod.virtual.VirtualMouse; -import com.minecrafttas.tasmod.virtual.VirtualSubticks; +import com.minecrafttas.tasmod.virtual.VirtualCamera; import com.mojang.realmsclient.gui.ChatFormatting; import com.mojang.realmsclient.util.Pair; @@ -88,7 +88,7 @@ public class PlaybackControllerClient implements ClientPacketHandler { private VirtualMouse mouse = new VirtualMouse(); - private VirtualSubticks subticks = new VirtualSubticks(); + private VirtualCamera subticks = new VirtualCamera(); public final File directory = new File(Minecraft.getMinecraft().mcDataDir.getAbsolutePath() + File.separator + "saves" + File.separator + "tasfiles"); @@ -379,7 +379,7 @@ public VirtualMouse addMouseToContainer(VirtualMouse mouse) { * @param subticks Subticks to add * @return Subticks to retrieve */ - public VirtualSubticks addSubticksToContainer(VirtualSubticks subticks) { + public VirtualCamera addSubticksToContainer(VirtualCamera subticks) { if (state == TASstate.RECORDING) { this.subticks = subticks.clone(); } else if (state == TASstate.PLAYBACK) { @@ -734,9 +734,9 @@ public static class TickInputContainer implements Serializable { private VirtualMouse mouse; - private VirtualSubticks subticks; + private VirtualCamera subticks; - public TickInputContainer(int tick, VirtualKeyboard keyboard, VirtualMouse mouse, VirtualSubticks subticks) { + public TickInputContainer(int tick, VirtualKeyboard keyboard, VirtualMouse mouse, VirtualCamera subticks) { this.tick = tick; this.keyboard = keyboard; this.mouse = mouse; @@ -747,7 +747,7 @@ public TickInputContainer(int tick) { this.tick = tick; this.keyboard = new VirtualKeyboard(); this.mouse = new VirtualMouse(); - this.subticks = new VirtualSubticks(0, 0); + this.subticks = new VirtualCamera(0, 0); } @Override @@ -763,7 +763,7 @@ public VirtualMouse getMouse() { return mouse; } - public VirtualSubticks getSubticks() { + public VirtualCamera getSubticks() { return subticks; } diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java index 4a9ad482..fe2b8339 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java @@ -22,7 +22,7 @@ import com.minecrafttas.tasmod.virtual.VirtualKeyboard; import com.minecrafttas.tasmod.virtual.VirtualMouse; import com.minecrafttas.tasmod.virtual.VirtualMouse.PathNode; -import com.minecrafttas.tasmod.virtual.VirtualSubticks; +import com.minecrafttas.tasmod.virtual.VirtualCamera; import com.mojang.realmsclient.util.Pair; /** @@ -432,7 +432,7 @@ private List readPath(String section, int linenumber, VirtualMouse mou return path; } - private VirtualSubticks readSubtick(String section, int linenumber) throws IOException { + private VirtualCamera readSubtick(String section, int linenumber) throws IOException { section = section.replace("Camera:", ""); String[] split=section.split(";"); @@ -446,7 +446,7 @@ private VirtualSubticks readSubtick(String section, int linenumber) throws IOExc throw new IOException(split[0]+" or/and "+split[1]+" are not float numbers in line "+ linenumber); } - return new VirtualSubticks(x, y); + return new VirtualCamera(x, y); } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualSubticks.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCamera.java similarity index 72% rename from src/main/java/com/minecrafttas/tasmod/virtual/VirtualSubticks.java rename to src/main/java/com/minecrafttas/tasmod/virtual/VirtualCamera.java index 29efd22a..a3876eb5 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualSubticks.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCamera.java @@ -4,7 +4,7 @@ import com.minecrafttas.tasmod.playback.PlaybackSerialiser; -public class VirtualSubticks implements Serializable{ +public class VirtualCamera implements Serializable{ /** * */ @@ -12,12 +12,12 @@ public class VirtualSubticks implements Serializable{ private float pitch; private float yaw; - public VirtualSubticks() { + public VirtualCamera() { pitch = 0; yaw = 0; } - public VirtualSubticks(float pitch, float yaw) { + public VirtualCamera(float pitch, float yaw) { this.pitch = pitch; this.yaw = yaw; } @@ -31,8 +31,8 @@ public float getYaw() { } @Override - public VirtualSubticks clone() { - return new VirtualSubticks(pitch, yaw); + public VirtualCamera clone() { + return new VirtualCamera(pitch, yaw); } @Override diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualEvent.java index e00d58a5..e9f9392d 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualEvent.java @@ -9,7 +9,7 @@ public VirtualEvent(int keycode, boolean keystate) { this.keystate = keystate; } - public VirtualEvent(VirtualEvent event){ + public VirtualEvent(VirtualEvent event) { this.keycode = event.keycode; this.keystate = event.keystate; } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index 95cd69fc..4a9612e5 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -397,10 +397,10 @@ public void unpressNext() { // ======================================Subticks=========================================== - VirtualSubticks currentSubtick = new VirtualSubticks(0, 0); + VirtualCamera currentSubtick = new VirtualCamera(0, 0); public void updateSubtick(float pitch, float yaw) { - currentSubtick = TASmodClient.controller.addSubticksToContainer(new VirtualSubticks(pitch, yaw)); + currentSubtick = TASmodClient.controller.addSubticksToContainer(new VirtualCamera(pitch, yaw)); } public float getSubtickPitch() { @@ -542,9 +542,9 @@ public class InputEvent { public int tick; public List keyboardevent; public List mouseEvent; - public VirtualSubticks subticks; + public VirtualCamera subticks; - public InputEvent(int tick, List keyboardevent, List mouseEvent, VirtualSubticks subticks) { + public InputEvent(int tick, List keyboardevent, List mouseEvent, VirtualCamera subticks) { this.tick = tick; this.keyboardevent = keyboardevent; this.mouseEvent = mouseEvent; diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey2.java index d0c3ba31..98333546 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey2.java @@ -152,7 +152,7 @@ private VirtualKey2(int keycode) { this(keycode, null); } - private VirtualKey2(int keycode, Character unicode){ + private VirtualKey2(int keycode, Character unicode) { this.keycode = keycode; this.unicode = unicode; } @@ -161,7 +161,9 @@ public int getKeycode() { return keycode; } - public Character getUnicode() { return unicode; } + public Character getUnicode() { + return unicode; + } public static Integer getKeycode(String keyname) { VirtualKey2 key = get(keyname); @@ -177,22 +179,20 @@ public static String getName(int keycode) { return Integer.toString(keycode); } - public static Character getUnicode(int keycode){ + public static Character getUnicode(int keycode) { VirtualKey2 key = get(keycode); - if(key!=null) + if (key != null) return key.getUnicode(); return null; } - public static Character getUnicode(String keyname){ + public static Character getUnicode(String keyname) { VirtualKey2 key = get(keyname); - if(key!=null) + if (key != null) return key.getUnicode(); return null; } - - public static VirtualKey2 get(int keycode) { for (VirtualKey2 key : values()) { if (key.getKeycode() == keycode) { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java index e184fe33..9144be1e 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java @@ -1,43 +1,41 @@ package com.minecrafttas.tasmod.virtual; -import org.spongepowered.asm.mixin.Overwrite; - import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentLinkedQueue; -public class VirtualKeyboard2 extends VirtualPeripheral implements Serializable{ +public class VirtualKeyboard2 extends VirtualPeripheral implements Serializable { - private List charList; + private List charList; - @Override - public void setPressed(int keycode, boolean keystate) { - if(keycode >= 0){ // Keyboard keys always have a keycode larger or equal than 0 - super.setPressed(keycode, keystate); - } - } + @Override + public void setPressed(int keycode, boolean keystate) { + if (keycode >= 0) { // Keyboard keys always have a keycode larger or equal than 0 + super.setPressed(keycode, keystate); + } + } - @Override - protected List getDifference(T nextPeripheral) { - List eventList = new ArrayList<>(); + @Override + protected List getDifference(T nextPeripheral) { + List eventList = new ArrayList<>(); ConcurrentLinkedQueue chars = new ConcurrentLinkedQueue<>(charList); - /* Calculate symmetric difference */ - - /* - * Calculate unpressed keys - * this: W A S - * next: W S D - * ------------- - * A <- unpressed - * */ - this.pressedKeys.forEach(key -> { - if(!nextPeripheral.pressedKeys.contains(key)){ - eventList.add(new VirtualKeyboardEvent(key, false, Character.MIN_VALUE)); - } - }); + /* Calculate symmetric difference */ + + /* + * Calculate unpressed keys + * this: W A S + * next: W S D + * ------------- + * A <- unpressed + * */ + this.pressedKeys.forEach(key -> { + if (!nextPeripheral.pressedKeys.contains(key)) { + eventList.add(new VirtualKeyboardEvent(key, false, Character.MIN_VALUE)); + } + }); /* Calculate pressed keys @@ -46,11 +44,11 @@ protected List getDifferen ------------- D <- pressed */ - nextPeripheral.pressedKeys.forEach(key -> { - if(!this.pressedKeys.contains(key)){ - eventList.add(new VirtualKeyboardEvent(key, true, chars.poll())); - } - }); + nextPeripheral.pressedKeys.forEach(key -> { + if (!this.pressedKeys.contains(key)) { + eventList.add(new VirtualKeyboardEvent(key, true, chars.poll())); + } + }); /* Add the rest of the characters as keyboard events. @@ -62,28 +60,28 @@ protected List getDifferen This makes it easier to write words when working only with the TASfile, otherwise you'd either need to add a keycode for each char or write it in new lines */ - while(!chars.isEmpty()){ - eventList.add(new VirtualKeyboardEvent(VirtualKey2.ZERO.getKeycode(), true, chars.poll())); - } - - return eventList; - } - - public void addChar(char character){ - charList.add(character); - } - - private void clearCharacters(){ - charList.clear(); - } - - public void clear(){ - super.clearPressedKeys(); - clearCharacters(); - } - - @Override - public String toString() { - return super.toString(); - } + while (!chars.isEmpty()) { + eventList.add(new VirtualKeyboardEvent(VirtualKey2.ZERO.getKeycode(), true, chars.poll())); + } + + return eventList; + } + + public void addChar(char character) { + charList.add(character); + } + + private void clearCharacters() { + charList.clear(); + } + + public void clear() { + super.clearPressedKeys(); + clearCharacters(); + } + + @Override + public String toString() { + return super.toString(); + } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java index ac78a4cd..72837a03 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java @@ -7,7 +7,8 @@ public VirtualKeyboardEvent(int keycode, boolean keystate, Character character) super(keycode, keystate); this.character = character; } - public VirtualKeyboardEvent(VirtualEvent event, char character){ + + public VirtualKeyboardEvent(VirtualEvent event, char character) { super(event); this.character = character; } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java index ba6f1ce1..aec1c4a5 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java @@ -1,6 +1,7 @@ package com.minecrafttas.tasmod.virtual; import java.io.Serializable; +import java.util.List; public class VirtualMouse2 extends VirtualPeripheral implements Serializable { @@ -10,5 +11,10 @@ public class VirtualMouse2 extends VirtualPeripheral implements Serializable { public VirtualMouse2() { // TODO Auto-generated constructor stub } - + + @Override + protected List getDifference(T nextPeripheral) { + return null; + } + } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java index eede2b11..b5ae1bfe 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java @@ -2,47 +2,35 @@ /** * Template for recording Mouse.next() events. - * - * @author ScribbleLP * + * @author Scribble */ -public class VirtualMouseEvent { - private int keycode; - private boolean state; - private int scrollwheel; - private int mouseX; - private int mouseY; +public class VirtualMouseEvent extends VirtualEvent { + private int scrollwheel; + private int mouseX; + private int mouseY; - public VirtualMouseEvent(int keycode, boolean state, int scrollwheel, int mouseX, int mouseY) { - this.keycode = keycode; - this.state = state; - this.scrollwheel = scrollwheel; - this.mouseX = mouseX; - this.mouseY = mouseY; - } + public VirtualMouseEvent(int keycode, boolean state, int scrollwheel, int mouseX, int mouseY) { + super(keycode, state); + this.scrollwheel = scrollwheel; + this.mouseX = mouseX; + this.mouseY = mouseY; + } - public int getKeyCode() { - return keycode; - } + public int getScrollwheel() { + return scrollwheel; + } - public boolean isState() { - return state; - } + public int getMouseX() { + return mouseX; + } - public int getScrollwheel() { - return scrollwheel; - } + public int getMouseY() { + return mouseY; + } - public int getMouseX() { - return mouseX; - } - - public int getMouseY() { - return mouseY; - } - - @Override - public String toString() { - return keycode+", "+state+", "+scrollwheel+", "+mouseX+", "+mouseY; - } + @Override + public String toString() { + return String.format("%s, %s, %s, %s", super.toString(), scrollwheel, mouseX, mouseY); + } } From 49f8c92f05afa53ff1f31fa972cbb011e1e2345d Mon Sep 17 00:00:00 2001 From: Scribble Date: Sun, 7 Jan 2024 20:18:47 +0100 Subject: [PATCH 05/57] [VirtualInput] Finished keyboard and mouse, removed unicode hack - Added documentation - Finished get difference calcultion for mouse and keyboard - Getting ready for new VirtualInput - VirtualCamera (yet again) renamed to VirtualCameraAngle --- .../savestates/MixinNetHandlerPlayServer.java | 3 +- .../playback/PlaybackControllerClient.java | 14 +-- .../tasmod/playback/PlaybackSerialiser.java | 6 +- ...ualCamera.java => VirtualCameraAngle.java} | 10 +- .../tasmod/virtual/VirtualInput.java | 8 +- .../tasmod/virtual/VirtualKey2.java | 44 ++------ .../tasmod/virtual/VirtualKeybindings.java | 1 - .../tasmod/virtual/VirtualKeyboard.java | 2 +- .../tasmod/virtual/VirtualKeyboard2.java | 91 ++++++++++++---- .../tasmod/virtual/VirtualKeyboardEvent.java | 6 +- .../tasmod/virtual/VirtualMouse2.java | 100 +++++++++++++++++- .../tasmod/virtual/VirtualMouseEvent.java | 14 +-- .../tasmod/virtual/VirtualPeripheral.java | 54 ++++++++-- 13 files changed, 252 insertions(+), 101 deletions(-) rename src/main/java/com/minecrafttas/tasmod/virtual/{VirtualCamera.java => VirtualCameraAngle.java} (71%) diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/savestates/MixinNetHandlerPlayServer.java b/src/main/java/com/minecrafttas/tasmod/mixin/savestates/MixinNetHandlerPlayServer.java index 00641961..40d61059 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/savestates/MixinNetHandlerPlayServer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/savestates/MixinNetHandlerPlayServer.java @@ -12,8 +12,7 @@ @Mixin(NetHandlerPlayServer.class) public class MixinNetHandlerPlayServer { - - + @Redirect(method = "processPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/EntityPlayerMP;isInvulnerableDimensionChange()Z")) public boolean redirect_processPlayer(EntityPlayerMP parentIn) { return !parentIn.isInvulnerableDimensionChange() && TASmod.savestateHandlerServer.state!=SavestateState.LOADING; diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index edd1c3eb..cb626bb0 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -39,7 +39,7 @@ import com.minecrafttas.tasmod.virtual.VirtualInput; import com.minecrafttas.tasmod.virtual.VirtualKeyboard; import com.minecrafttas.tasmod.virtual.VirtualMouse; -import com.minecrafttas.tasmod.virtual.VirtualCamera; +import com.minecrafttas.tasmod.virtual.VirtualCameraAngle; import com.mojang.realmsclient.gui.ChatFormatting; import com.mojang.realmsclient.util.Pair; @@ -88,7 +88,7 @@ public class PlaybackControllerClient implements ClientPacketHandler { private VirtualMouse mouse = new VirtualMouse(); - private VirtualCamera subticks = new VirtualCamera(); + private VirtualCameraAngle subticks = new VirtualCameraAngle(); public final File directory = new File(Minecraft.getMinecraft().mcDataDir.getAbsolutePath() + File.separator + "saves" + File.separator + "tasfiles"); @@ -379,7 +379,7 @@ public VirtualMouse addMouseToContainer(VirtualMouse mouse) { * @param subticks Subticks to add * @return Subticks to retrieve */ - public VirtualCamera addSubticksToContainer(VirtualCamera subticks) { + public VirtualCameraAngle addSubticksToContainer(VirtualCameraAngle subticks) { if (state == TASstate.RECORDING) { this.subticks = subticks.clone(); } else if (state == TASstate.PLAYBACK) { @@ -734,9 +734,9 @@ public static class TickInputContainer implements Serializable { private VirtualMouse mouse; - private VirtualCamera subticks; + private VirtualCameraAngle subticks; - public TickInputContainer(int tick, VirtualKeyboard keyboard, VirtualMouse mouse, VirtualCamera subticks) { + public TickInputContainer(int tick, VirtualKeyboard keyboard, VirtualMouse mouse, VirtualCameraAngle subticks) { this.tick = tick; this.keyboard = keyboard; this.mouse = mouse; @@ -747,7 +747,7 @@ public TickInputContainer(int tick) { this.tick = tick; this.keyboard = new VirtualKeyboard(); this.mouse = new VirtualMouse(); - this.subticks = new VirtualCamera(0, 0); + this.subticks = new VirtualCameraAngle(0, 0); } @Override @@ -763,7 +763,7 @@ public VirtualMouse getMouse() { return mouse; } - public VirtualCamera getSubticks() { + public VirtualCameraAngle getSubticks() { return subticks; } diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java index fe2b8339..ce383fee 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java @@ -22,7 +22,7 @@ import com.minecrafttas.tasmod.virtual.VirtualKeyboard; import com.minecrafttas.tasmod.virtual.VirtualMouse; import com.minecrafttas.tasmod.virtual.VirtualMouse.PathNode; -import com.minecrafttas.tasmod.virtual.VirtualCamera; +import com.minecrafttas.tasmod.virtual.VirtualCameraAngle; import com.mojang.realmsclient.util.Pair; /** @@ -432,7 +432,7 @@ private List readPath(String section, int linenumber, VirtualMouse mou return path; } - private VirtualCamera readSubtick(String section, int linenumber) throws IOException { + private VirtualCameraAngle readSubtick(String section, int linenumber) throws IOException { section = section.replace("Camera:", ""); String[] split=section.split(";"); @@ -446,7 +446,7 @@ private VirtualCamera readSubtick(String section, int linenumber) throws IOExcep throw new IOException(split[0]+" or/and "+split[1]+" are not float numbers in line "+ linenumber); } - return new VirtualCamera(x, y); + return new VirtualCameraAngle(x, y); } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCamera.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java similarity index 71% rename from src/main/java/com/minecrafttas/tasmod/virtual/VirtualCamera.java rename to src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java index a3876eb5..f4947b97 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCamera.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java @@ -4,7 +4,7 @@ import com.minecrafttas.tasmod.playback.PlaybackSerialiser; -public class VirtualCamera implements Serializable{ +public class VirtualCameraAngle implements Serializable{ /** * */ @@ -12,12 +12,12 @@ public class VirtualCamera implements Serializable{ private float pitch; private float yaw; - public VirtualCamera() { + public VirtualCameraAngle() { pitch = 0; yaw = 0; } - public VirtualCamera(float pitch, float yaw) { + public VirtualCameraAngle(float pitch, float yaw) { this.pitch = pitch; this.yaw = yaw; } @@ -31,8 +31,8 @@ public float getYaw() { } @Override - public VirtualCamera clone() { - return new VirtualCamera(pitch, yaw); + public VirtualCameraAngle clone() { + return new VirtualCameraAngle(pitch, yaw); } @Override diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index 4a9612e5..17c3266d 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -397,10 +397,10 @@ public void unpressNext() { // ======================================Subticks=========================================== - VirtualCamera currentSubtick = new VirtualCamera(0, 0); + VirtualCameraAngle currentSubtick = new VirtualCameraAngle(0, 0); public void updateSubtick(float pitch, float yaw) { - currentSubtick = TASmodClient.controller.addSubticksToContainer(new VirtualCamera(pitch, yaw)); + currentSubtick = TASmodClient.controller.addSubticksToContainer(new VirtualCameraAngle(pitch, yaw)); } public float getSubtickPitch() { @@ -542,9 +542,9 @@ public class InputEvent { public int tick; public List keyboardevent; public List mouseEvent; - public VirtualCamera subticks; + public VirtualCameraAngle subticks; - public InputEvent(int tick, List keyboardevent, List mouseEvent, VirtualCamera subticks) { + public InputEvent(int tick, List keyboardevent, List mouseEvent, VirtualCameraAngle subticks) { this.tick = tick; this.keyboardevent = keyboardevent; this.mouseEvent = mouseEvent; diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey2.java index 98333546..ddce26b3 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey2.java @@ -16,8 +16,8 @@ public enum VirtualKey2 { KEY_0(11), MINUS(12), EQUALS(13), - BACK(14, '\b'), - TAB(15, '\u21A6'), + BACK(14), + TAB(15), Q(16), W(17), E(18), @@ -113,14 +113,14 @@ public enum VirtualKey2 { PRINT(183), ALT_GR(184), PAUSE(197), - HOME(199, '\u21E4'), - UP(200, '\u2191'), - PRIOR(201, '\u21E7'), - LEFT(203, '\u2190'), - RIGHT(205, '\u2192'), - END(207, '\u21E5'), - DOWN(208, '\u2193'), - NEXT(209, '\u21E9'), + HOME(199), + UP(200), + PRIOR(201), + LEFT(203), + RIGHT(205), + END(207), + DOWN(208), + NEXT(209), INSERT(210), DELETE(211), WIN(219), @@ -146,25 +146,15 @@ public enum VirtualKey2 { MBUTTON16(-85); private final int keycode; - private final Character unicode; private VirtualKey2(int keycode) { - this(keycode, null); - } - - private VirtualKey2(int keycode, Character unicode) { this.keycode = keycode; - this.unicode = unicode; } public int getKeycode() { return keycode; } - public Character getUnicode() { - return unicode; - } - public static Integer getKeycode(String keyname) { VirtualKey2 key = get(keyname); if (key != null) @@ -179,20 +169,6 @@ public static String getName(int keycode) { return Integer.toString(keycode); } - public static Character getUnicode(int keycode) { - VirtualKey2 key = get(keycode); - if (key != null) - return key.getUnicode(); - return null; - } - - public static Character getUnicode(String keyname) { - VirtualKey2 key = get(keyname); - if (key != null) - return key.getUnicode(); - return null; - } - public static VirtualKey2 get(int keycode) { for (VirtualKey2 key : values()) { if (key.getKeycode() == keycode) { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeybindings.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeybindings.java index 998ace52..c2130f56 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeybindings.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeybindings.java @@ -31,7 +31,6 @@ * @author Scribble * */ -@Deprecated public class VirtualKeybindings { private static Minecraft mc = Minecraft.getMinecraft(); private static long cooldown = 50*5; diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java index 69b1035a..31912546 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java @@ -306,7 +306,7 @@ public char encodeUnicode(int keycode, char character) { public VirtualKeyboardEvent decodeUnicode(char character) { switch (character) { case '\b': - return new VirtualKeyboardEvent(14, true, character); + return new VirtualKeyboardEvent(14, true, Character.MIN_VALUE); case '\u21A6': return new VirtualKeyboardEvent(15, true, Character.MIN_VALUE); case '\u2907': diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java index 9144be1e..0c02bf78 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java @@ -1,13 +1,43 @@ package com.minecrafttas.tasmod.virtual; +import org.apache.commons.lang3.StringUtils; + import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; public class VirtualKeyboard2 extends VirtualPeripheral implements Serializable { - private List charList; + /** + * The list of characters that were pressed on this keyboard. + */ + private final List charList; + + /** + * A queue of characters used in {@link #getDifference(VirtualPeripheral)}.
+ * Used for distributing characters to {@link VirtualKeyboardEvent}s in an order. + */ + private final ConcurrentLinkedQueue charQueue = new ConcurrentLinkedQueue<>(); + + /** + * Creates a keyboard with all keys unpressed + */ + public VirtualKeyboard2() { + super(); + this.charList = new ArrayList<>(); + } + + /** + * Creates a keyboard from existing variables + * @param pressedKeys The existing list of pressed keycodes + * @param charList The existing list of characters + */ + public VirtualKeyboard2(Set pressedKeys, List charList) { + super(pressedKeys); + this.charList = charList; + } @Override public void setPressed(int keycode, boolean keystate) { @@ -20,17 +50,17 @@ public void setPressed(int keycode, boolean keystate) { protected List getDifference(T nextPeripheral) { List eventList = new ArrayList<>(); - ConcurrentLinkedQueue chars = new ConcurrentLinkedQueue<>(charList); + charQueue.addAll(charList); - /* Calculate symmetric difference */ + /* Calculate symmetric difference of keycodes */ /* - * Calculate unpressed keys - * this: W A S - * next: W S D - * ------------- - * A <- unpressed - * */ + Calculate unpressed keys + this: W A S + next: W S D + ------------- + A <- unpressed + */ this.pressedKeys.forEach(key -> { if (!nextPeripheral.pressedKeys.contains(key)) { eventList.add(new VirtualKeyboardEvent(key, false, Character.MIN_VALUE)); @@ -46,7 +76,7 @@ protected List getDifferen */ nextPeripheral.pressedKeys.forEach(key -> { if (!this.pressedKeys.contains(key)) { - eventList.add(new VirtualKeyboardEvent(key, true, chars.poll())); + eventList.add(new VirtualKeyboardEvent(key, true, getOrDefault(charQueue.poll()))); } }); @@ -60,28 +90,47 @@ protected List getDifferen This makes it easier to write words when working only with the TASfile, otherwise you'd either need to add a keycode for each char or write it in new lines */ - while (!chars.isEmpty()) { - eventList.add(new VirtualKeyboardEvent(VirtualKey2.ZERO.getKeycode(), true, chars.poll())); + while (!charQueue.isEmpty()) { + eventList.add(new VirtualKeyboardEvent(0, false, getOrDefault(charQueue.poll()))); } return eventList; } - public void addChar(char character) { - charList.add(character); + private char getOrDefault(Character charr){ + if(charr==null){ + charr = Character.MIN_VALUE; + } + return charr; } - private void clearCharacters() { - charList.clear(); + /** + * Add a character to the {@link #charList}
+ * Null characters will be discarded; + * @param character The character to add + */ + public void addChar(char character) { + if(character != Character.MIN_VALUE) + charList.add(character); } - public void clear() { - super.clearPressedKeys(); - clearCharacters(); + @Override + public String toString() { + String charString = ""; + if (!charList.isEmpty()) { + for (Character charr : charList) { + charString = charString.concat(Character.toString(charr)); + } + charString = StringUtils.replace(charString, "\r", "\\n"); + charString = StringUtils.replace(charString, "\n", "\\n"); + } + + return String.format("%s;%s", super.toString(), charString); } @Override - public String toString() { - return super.toString(); + protected VirtualKeyboard2 clone() throws CloneNotSupportedException { + return new VirtualKeyboard2(this.pressedKeys, this.charList); } + } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java index 72837a03..3c0dad8c 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java @@ -1,9 +1,9 @@ package com.minecrafttas.tasmod.virtual; public class VirtualKeyboardEvent extends VirtualEvent { - private final Character character; + private final char character; - public VirtualKeyboardEvent(int keycode, boolean keystate, Character character) { + public VirtualKeyboardEvent(int keycode, boolean keystate, char character) { super(keycode, keystate); this.character = character; } @@ -19,6 +19,6 @@ public char getCharacter() { @Override public String toString() { - return String.format("%s, %s", super.toString(), character != null ? character : Character.MIN_VALUE); + return String.format("%s, %s", super.toString(), character); } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java index aec1c4a5..d6ab7915 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java @@ -1,20 +1,110 @@ package com.minecrafttas.tasmod.virtual; import java.io.Serializable; +import java.util.ArrayList; import java.util.List; +import java.util.Set; +import java.util.concurrent.ArrayBlockingQueue; public class VirtualMouse2 extends VirtualPeripheral implements Serializable { - + + /** + * The direction of the scrollWheel
+ *
+ * If the number is positive or negative depending on scroll direction. + */ + private final int scrollWheel; /** - * Creates a keyboard where all keys are unpressed + * X coordinate of the on-screen cursor, used in GUI screens.
+ * When null, no change to the cursor is applied. */ - public VirtualMouse2() { - // TODO Auto-generated constructor stub + private final Integer cursorX; + /** + * Y coordinate of the on-screen cursor, used in GUI screens.
+ * When null, no change to the cursor is applied. + */ + private final Integer cursorY; + + /** + * Creates a mouse with no buttons pressed and no data + */ + public VirtualMouse2(){ + super(); + this.scrollWheel = 0; + this.cursorX = null; + this.cursorY = null; + } + + /** + * Creates a mouse from existing values + * @param pressedKeys The list o {@link #pressedKeys} + * @param scrollWheel The {@link #scrollWheel} + * @param cursorX The {@link #cursorX} + * @param cursorY The {@link #cursorY} + */ + public VirtualMouse2(Set pressedKeys, int scrollWheel, Integer cursorX, Integer cursorY) { + super(pressedKeys); + this.scrollWheel = scrollWheel; + this.cursorX = cursorX; + this.cursorY = cursorY; + } + + @Override + protected void setPressed(int keycode, boolean keystate) { + if(keycode < 0){ + super.setPressed(keycode, keystate); + } } @Override protected List getDifference(T nextPeripheral) { - return null; + List eventList = new ArrayList<>(); + + int scrollWheelCopy = scrollWheel; + Integer cursorXCopy = cursorX; + Integer cursorYCopy = cursorY; + + /* Calculate symmetric difference of keycodes */ + + /* + Calculate unpressed keys + this: LC RC + next: LC MC + ------------- + RC <- unpressed + */ + for(int keycode : pressedKeys) { + if (!nextPeripheral.pressedKeys.contains(keycode)) { + eventList.add(new VirtualMouseEvent(keycode, false, scrollWheelCopy, cursorXCopy, cursorYCopy)); + scrollWheelCopy = 0; + cursorXCopy = null; + cursorYCopy = null; + } + }; + + /* + Calculate pressed keys + next: LC MC + this: LC RC + ------------- + MC <- pressed + */ + for(int keycode : nextPeripheral.pressedKeys) { + if (!this.pressedKeys.contains(keycode)) { + eventList.add(new VirtualMouseEvent(keycode, true, scrollWheelCopy, cursorXCopy, cursorYCopy)); + } + }; + + return eventList; + } + + @Override + public String toString() { + return String.format("%s;%s,%s,%s", super.toString(), scrollWheel, cursorX, cursorY); } + @Override + protected VirtualMouse2 clone() throws CloneNotSupportedException { + return new VirtualMouse2(this.pressedKeys, scrollWheel, cursorX, cursorY); + } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java index b5ae1bfe..06a4f0d3 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java @@ -6,11 +6,11 @@ * @author Scribble */ public class VirtualMouseEvent extends VirtualEvent { - private int scrollwheel; - private int mouseX; - private int mouseY; + private final int scrollwheel; + private final Integer mouseX; + private final Integer mouseY; - public VirtualMouseEvent(int keycode, boolean state, int scrollwheel, int mouseX, int mouseY) { + public VirtualMouseEvent(int keycode, boolean state, int scrollwheel, Integer mouseX, Integer mouseY) { super(keycode, state); this.scrollwheel = scrollwheel; this.mouseX = mouseX; @@ -21,16 +21,16 @@ public int getScrollwheel() { return scrollwheel; } - public int getMouseX() { + public Integer getMouseX() { return mouseX; } - public int getMouseY() { + public Integer getMouseY() { return mouseY; } @Override public String toString() { - return String.format("%s, %s, %s, %s", super.toString(), scrollwheel, mouseX, mouseY); + return String.format("%s, %s, %s, %s", super.toString(), scrollwheel, mouseX != null ? mouseX : " ", mouseY != null ? mouseY : " "); } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java index 844c5315..8f2855ab 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java @@ -6,24 +6,55 @@ import java.util.List; import java.util.Set; +/** + * Base class for {@link VirtualKeyboard2} and {@link VirtualMouse2}
+ *
+ * Contains the shared code for keeping track of which buttons are pressed.
+ * This works by storing the keycodes of the buttons in a set, as keycodes are supposed to be unique
+ *
+ * Generating {@link VirtualEvent}s is handled in the child classes. + * + * @author Scribble + */ public abstract class VirtualPeripheral implements Serializable { + + /** + * The list of keycodes that are currently pressed on this peripheral. + */ protected final Set pressedKeys; - public VirtualPeripheral() { + /** + * Create an empty peripheral with all keys unpressed + */ + protected VirtualPeripheral() { this.pressedKeys = new HashSet<>(); } - public VirtualPeripheral(Set pressedKeys) { + /** + * Create a peripheral with already existing pressed keys + * @param pressedKeys The existing pressedKeys + */ + protected VirtualPeripheral(Set pressedKeys) { this.pressedKeys = pressedKeys; } - public void setPressed(int keycode, boolean keystate) { + /** + * Set the specified keycode to pressed + * @param keycode The keycode to check + * @param keystate The keystate of the keycode + */ + protected void setPressed(int keycode, boolean keystate) { if (keystate) pressedKeys.add(keycode); else pressedKeys.remove(keycode); } + /** + * Set the specified keyname to pressed + * @param keyname The keyname to check + * @param keystate The keystate of the keyname + */ public void setPressed(String keyname, boolean keystate) { Integer keycode = VirtualKey2.getKeycode(keyname); if (keycode != null) { @@ -31,6 +62,9 @@ public void setPressed(String keyname, boolean keystate) { } } + /** + * @return A list of all currently pressed keynames + */ public List getCurrentPresses() { List out = new ArrayList<>(); pressedKeys.forEach(keycode -> { @@ -39,14 +73,18 @@ public List getCurrentPresses() { return out; } - protected void clearPressedKeys() { - pressedKeys.clear(); - } - + /** + * Calculates the difference between 2 peripherals via symmetric difference
+ * and returns a list of the changes between in form of {@link VirtualEvent}s + * + * @param nextPeripheral The peripheral that is comes after this one.
+ * If this one is loaded at tick 15, the nextPeripheral should be the one from tick 16 + * @return A list of {@link VirtualEvent}s + */ protected abstract List getDifference(T nextPeripheral); @Override public String toString() { return String.join(",", getCurrentPresses()); } -} \ No newline at end of file +} From f6e23692b8da008a5845edda7fdf093dbb22ff6d Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 13 Jan 2024 14:30:30 +0100 Subject: [PATCH 06/57] [VirtualInput] Added subtick list to keyboard - Deleted VirtualChar - Removed unnecessary constructor in VirtualPeripheral - Added getters in Peripheral and Keyboard - Added documentation - Added test for VirtualKeyboard --- .../tasmod/virtual/VirtualCameraAngle.java | 4 - .../tasmod/virtual/VirtualChar.java | 27 ----- .../tasmod/virtual/VirtualKeyboard2.java | 102 +++++++++++++--- .../tasmod/virtual/VirtualMouse2.java | 13 +- .../tasmod/virtual/VirtualMouseEvent.java | 2 + .../tasmod/virtual/VirtualPeripheral.java | 17 +-- .../virtual/keyboard/VirtualKeyboardTest.java | 111 ++++++++++++++++++ 7 files changed, 214 insertions(+), 62 deletions(-) delete mode 100644 src/main/java/com/minecrafttas/tasmod/virtual/VirtualChar.java create mode 100644 src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java index f4947b97..dfe08da6 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java @@ -5,10 +5,6 @@ import com.minecrafttas.tasmod.playback.PlaybackSerialiser; public class VirtualCameraAngle implements Serializable{ - /** - * - */ - private static final long serialVersionUID = -2038332459318568985L; private float pitch; private float yaw; diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualChar.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualChar.java deleted file mode 100644 index 3ed211a7..00000000 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualChar.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.minecrafttas.tasmod.virtual; - -import java.util.Map; - -import com.google.common.collect.Maps; - -@Deprecated -public class VirtualChar { - private char name; - private boolean pressed; - static Map keyChars= Maps.newHashMap(); - - public VirtualChar(char name, boolean pressed) { - this.name=name; - this.pressed=pressed; - keyChars.put(name, this); - } - public void setPressed(boolean pressed) { - this.pressed=pressed; - } - public char getName() { - return name; - } - public boolean isPressed() { - return pressed; - } -} diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java index 0c02bf78..24a7e2a8 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java @@ -1,13 +1,38 @@ package com.minecrafttas.tasmod.virtual; +import com.google.common.collect.ImmutableList; import org.apache.commons.lang3.StringUtils; import java.io.Serializable; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; +/** + * A state of the virtual keyboard at a given time.
+ *
+ * This class can be seen as a storage class,
+ * representing a state of the physical keyboard at a given time.
+ *
+ * This class aims to store the currently pressed keys and the list of characters that were entered in that time frame.
+ *
+ * A keyboard event coming from the physical keyboard may look like this:
+ *
+ *
+ * Keycode:17,Keystate:true,Character:w
+ * 
+ * This indicates that the key "W" is currently pressed.
+ * Therefore, the keycode 17 will be added to the set of {@link #pressedKeys} in {@link VirtualPeripheral}.
+ * This behaviour is also present in the {@link VirtualMouse2}.
+ *
+ * The character "w" coming from that keyboard event is added to the {@link #charList}.
+ * If shift were to be pressed while pressing the key,
+ * then the resulting keyboard event would hold a capitalized "W" as the character.
+ *
+ * + */ public class VirtualKeyboard2 extends VirtualPeripheral implements Serializable { /** @@ -22,11 +47,28 @@ public class VirtualKeyboard2 extends VirtualPeripheral implements Serializable private final ConcurrentLinkedQueue charQueue = new ConcurrentLinkedQueue<>(); /** - * Creates a keyboard with all keys unpressed + * A list of subtick keyboards.
+ * If subtickKeyboards is initialized, the object can be considered as a parent keyboard,
+ * able to house subtickKeyboards.
+ *
+ * If subtickKeyboards is null then the object is a "child"/subtickKeyboard stored in a parent list + */ + private final List subtickKeyboards; + + /** + * Creates an empty parent keyboard with all keys unpressed */ public VirtualKeyboard2() { - super(); - this.charList = new ArrayList<>(); + this(new HashSet<>(), new ArrayList<>(), new ArrayList<>()); + } + + /** + * Creates a subtick keyboard with {@link #subtickKeyboards} uninitialized + * @param pressedKeys The new list of pressed keycodes for this subtickKeyboard + * @param charList A list of characters for this subtickKeyboard + */ + public VirtualKeyboard2(Set pressedKeys, List charList){ + this(pressedKeys, charList, null); } /** @@ -34,9 +76,10 @@ public VirtualKeyboard2() { * @param pressedKeys The existing list of pressed keycodes * @param charList The existing list of characters */ - public VirtualKeyboard2(Set pressedKeys, List charList) { + public VirtualKeyboard2(Set pressedKeys, List charList, List subtickKeyboards) { super(pressedKeys); this.charList = charList; + this.subtickKeyboards = subtickKeyboards; } @Override @@ -62,7 +105,7 @@ protected List getDifferen A <- unpressed */ this.pressedKeys.forEach(key -> { - if (!nextPeripheral.pressedKeys.contains(key)) { + if (!nextPeripheral.getPressedKeys().contains(key)) { eventList.add(new VirtualKeyboardEvent(key, false, Character.MIN_VALUE)); } }); @@ -72,9 +115,9 @@ protected List getDifferen next: W S D this: W A S ------------- - D <- pressed + D <- pressed */ - nextPeripheral.pressedKeys.forEach(key -> { + nextPeripheral.getPressedKeys().forEach(key -> { if (!this.pressedKeys.contains(key)) { eventList.add(new VirtualKeyboardEvent(key, true, getOrDefault(charQueue.poll()))); } @@ -114,23 +157,52 @@ public void addChar(char character) { charList.add(character); } + public void clearCharList(){ + charList.clear(); + } + @Override public String toString() { - String charString = ""; - if (!charList.isEmpty()) { - for (Character charr : charList) { - charString = charString.concat(Character.toString(charr)); + if(subtickKeyboards == null){ + String charString = ""; + if (!charList.isEmpty()) { + for (Character charr : charList) { + charString = charString.concat(Character.toString(charr)); + } + charString = StringUtils.replace(charString, "\r", "\\n"); + charString = StringUtils.replace(charString, "\n", "\\n"); } - charString = StringUtils.replace(charString, "\r", "\\n"); - charString = StringUtils.replace(charString, "\n", "\\n"); + + return String.format("%s;%s", super.toString(), charString); } + else { + String charString = ""; + if (!charList.isEmpty()) { + for (Character charr : charList) { + charString = charString.concat(Character.toString(charr)); + } + charString = StringUtils.replace(charString, "\r", "\\n"); + charString = StringUtils.replace(charString, "\n", "\\n"); + } - return String.format("%s;%s", super.toString(), charString); + String out = String.format("%s;%s", super.toString(), charString); + for(VirtualKeyboard2 child : subtickKeyboards){ + out=out.concat("\n\t"+child.toString()); + } + return out; + } } @Override - protected VirtualKeyboard2 clone() throws CloneNotSupportedException { + protected VirtualKeyboard2 clone() { return new VirtualKeyboard2(this.pressedKeys, this.charList); } + public boolean isParent(){ + return subtickKeyboards!=null; + } + + public List getCharList() { + return ImmutableList.copyOf(charList); + } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java index d6ab7915..97941598 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java @@ -2,9 +2,9 @@ import java.io.Serializable; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.concurrent.ArrayBlockingQueue; public class VirtualMouse2 extends VirtualPeripheral implements Serializable { @@ -29,10 +29,7 @@ public class VirtualMouse2 extends VirtualPeripheral implements Serializable { * Creates a mouse with no buttons pressed and no data */ public VirtualMouse2(){ - super(); - this.scrollWheel = 0; - this.cursorX = null; - this.cursorY = null; + this(new HashSet<>(), 0, null, null); } /** @@ -74,7 +71,7 @@ protected List getDifferen RC <- unpressed */ for(int keycode : pressedKeys) { - if (!nextPeripheral.pressedKeys.contains(keycode)) { + if (!nextPeripheral.getPressedKeys().contains(keycode)) { eventList.add(new VirtualMouseEvent(keycode, false, scrollWheelCopy, cursorXCopy, cursorYCopy)); scrollWheelCopy = 0; cursorXCopy = null; @@ -89,7 +86,7 @@ protected List getDifferen ------------- MC <- pressed */ - for(int keycode : nextPeripheral.pressedKeys) { + for(int keycode : nextPeripheral.getPressedKeys()) { if (!this.pressedKeys.contains(keycode)) { eventList.add(new VirtualMouseEvent(keycode, true, scrollWheelCopy, cursorXCopy, cursorYCopy)); } @@ -104,7 +101,7 @@ public String toString() { } @Override - protected VirtualMouse2 clone() throws CloneNotSupportedException { + protected VirtualMouse2 clone() { return new VirtualMouse2(this.pressedKeys, scrollWheel, cursorX, cursorY); } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java index 06a4f0d3..16e36854 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java @@ -1,5 +1,7 @@ package com.minecrafttas.tasmod.virtual; +import com.minecrafttas.tasmod.virtual.VirtualEvent; + /** * Template for recording Mouse.next() events. * diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java index 8f2855ab..5a56b73f 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java @@ -1,8 +1,9 @@ package com.minecrafttas.tasmod.virtual; +import com.google.common.collect.ImmutableSet; + import java.io.Serializable; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; import java.util.Set; @@ -23,13 +24,6 @@ public abstract class VirtualPeripheral implements Serializable { */ protected final Set pressedKeys; - /** - * Create an empty peripheral with all keys unpressed - */ - protected VirtualPeripheral() { - this.pressedKeys = new HashSet<>(); - } - /** * Create a peripheral with already existing pressed keys * @param pressedKeys The existing pressedKeys @@ -87,4 +81,11 @@ public List getCurrentPresses() { public String toString() { return String.join(",", getCurrentPresses()); } + + /** + * @return An immutable set of pressed keycodes + */ + public Set getPressedKeys(){ + return ImmutableSet.copyOf(pressedKeys); + } } diff --git a/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java b/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java new file mode 100644 index 00000000..45de8551 --- /dev/null +++ b/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java @@ -0,0 +1,111 @@ +package tasmod.virtual.keyboard; + +import com.minecrafttas.tasmod.virtual.VirtualKey2; +import com.minecrafttas.tasmod.virtual.VirtualKeyboard2; +import org.junit.jupiter.api.Test; + +import java.util.*; + +import static org.junit.jupiter.api.Assertions.*; + +public class VirtualKeyboardTest { + + @Test + void testEmptyConstructor(){ + VirtualKeyboard2 test = new VirtualKeyboard2(); + assertTrue(test.getPressedKeys().isEmpty()); + assertTrue(test.getCharList().isEmpty()); + assertTrue(test.isParent()); + } + + @Test + void testSubtickConstructor(){ + Set testKeycodeSet = new HashSet<>(); + testKeycodeSet.add(VirtualKey2.W.getKeycode()); + testKeycodeSet.add(VirtualKey2.S.getKeycode()); + + List testCharList = new ArrayList<>(); + testCharList.add('w'); + testCharList.add('s'); + + VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, testCharList); + + assertIterableEquals(testKeycodeSet, test.getPressedKeys()); + assertIterableEquals(testCharList, test.getCharList()); + assertFalse(test.isParent()); + } + + @Test + void testSetPressedByKeycode(){ + VirtualKeyboard2 test = new VirtualKeyboard2(); + test.setPressed(VirtualKey2.W.getKeycode(), true); + + assertIterableEquals(Arrays.asList(VirtualKey2.W.getKeycode()), test.getPressedKeys()); + assertTrue(test.isParent()); + } + + @Test + void testSetPressedByKeyname(){ + VirtualKeyboard2 test = new VirtualKeyboard2(); + test.setPressed("W", true); + + assertIterableEquals(Arrays.asList(VirtualKey2.W.getKeycode()), test.getPressedKeys()); + assertTrue(test.isParent()); + } + + @Test + void testSetUnPressedByKeycode(){ + Set testKeycodeSet = new HashSet<>(); + testKeycodeSet.add(VirtualKey2.W.getKeycode()); + testKeycodeSet.add(VirtualKey2.S.getKeycode()); + VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, new ArrayList<>(), null); + test.setPressed(VirtualKey2.W.getKeycode(), false); + + assertIterableEquals(Arrays.asList(VirtualKey2.S.getKeycode()), test.getPressedKeys()); + } + + @Test + void testSetUnPressedByKeyname(){ + Set testKeycodeSet = new HashSet<>(); + testKeycodeSet.add(VirtualKey2.W.getKeycode()); + testKeycodeSet.add(VirtualKey2.S.getKeycode()); + VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, new ArrayList<>(), null); + test.setPressed("S", false); + + assertIterableEquals(Arrays.asList(VirtualKey2.W.getKeycode()), test.getPressedKeys()); + } + + @Test + void addCharacter(){ + VirtualKeyboard2 test = new VirtualKeyboard2(); + test.addChar('w'); + + assertIterableEquals(Arrays.asList('w'), test.getCharList()); + } + + @Test + void clearCharacters(){ + List testCharList = new ArrayList<>(); + testCharList.add('w'); + testCharList.add('s'); + VirtualKeyboard2 test = new VirtualKeyboard2(new HashSet<>(), testCharList); + test.clearCharList(); + + assertTrue(test.getCharList().isEmpty()); + } + + @Test + void testToString(){ + Set testKeycodeSet = new HashSet<>(); + testKeycodeSet.add(VirtualKey2.W.getKeycode()); + testKeycodeSet.add(VirtualKey2.S.getKeycode()); + + List testCharList = new ArrayList<>(); + testCharList.add('w'); + testCharList.add('s'); + + VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, testCharList, null); + + assertEquals("W,S;ws", test.toString()); + } +} From f004ae6c3c9d9c383aaf9c9134ba705e0bcde399 Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 13 Jan 2024 20:25:36 +0100 Subject: [PATCH 07/57] [VirtualInput] Moved subtick processing to VirtualPeripheral - Fixed package name errors - More implementation in VirtualKeyboard and VirtualMouse2 - More Documentation - More tests --- .../tasmod/virtual/VirtualEvent.java | 44 +++--- .../tasmod/virtual/VirtualInput2.java | 13 ++ .../tasmod/virtual/VirtualKeyboard2.java | 140 +++++++++++------- .../tasmod/virtual/VirtualKeyboardEvent.java | 6 +- .../tasmod/virtual/VirtualMouse2.java | 49 ++++-- .../tasmod/virtual/VirtualMouseEvent.java | 4 +- .../tasmod/virtual/VirtualPeripheral.java | 87 ++++++++--- .../virtual/keyboard/VirtualKeyboardTest.java | 60 ++++++++ 8 files changed, 295 insertions(+), 108 deletions(-) create mode 100644 src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualEvent.java index e9f9392d..0cedbca9 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualEvent.java @@ -1,29 +1,33 @@ package com.minecrafttas.tasmod.virtual; public class VirtualEvent { - protected final int keycode; - protected final boolean keystate; - public VirtualEvent(int keycode, boolean keystate) { - this.keycode = keycode; - this.keystate = keystate; - } + public static class VirtualButtonEvent extends VirtualEvent{ - public VirtualEvent(VirtualEvent event) { - this.keycode = event.keycode; - this.keystate = event.keystate; - } + protected final int keycode; + protected final boolean keystate; + + public VirtualButtonEvent(int keycode, boolean keystate) { + this.keycode = keycode; + this.keystate = keystate; + } - public int getKeyCode() { - return keycode; - } + public VirtualButtonEvent(VirtualButtonEvent event) { + this.keycode = event.keycode; + this.keystate = event.keystate; + } - public boolean isState() { - return keystate; - } + public int getKeyCode() { + return keycode; + } - @Override - public String toString() { - return String.format("%s, %s", keycode, keystate); - } + public boolean isState() { + return keystate; + } + + @Override + public String toString() { + return String.format("%s, %s", keycode, keystate); + } + } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java new file mode 100644 index 00000000..0bd411a2 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java @@ -0,0 +1,13 @@ +package com.minecrafttas.tasmod.virtual; + +public class VirtualInput2 { + + public VirtualInput2() { + } + + public void updateKeyboard(int keycode, boolean keystate, char character) { + + } + + +} diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java index 24a7e2a8..1cec460a 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java @@ -1,14 +1,17 @@ package com.minecrafttas.tasmod.virtual; -import com.google.common.collect.ImmutableList; -import org.apache.commons.lang3.StringUtils; - import java.io.Serializable; import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Queue; import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.StringUtils; + +import com.google.common.collect.ImmutableList; /** * A state of the virtual keyboard at a given time.
@@ -29,11 +32,12 @@ *
* The character "w" coming from that keyboard event is added to the {@link #charList}.
* If shift were to be pressed while pressing the key,
- * then the resulting keyboard event would hold a capitalized "W" as the character.
- *
- * + * then the resulting keyboard event would hold a capitalized "W" as the character. + * TODO Write Difference and VirtualKey once complete + * + * @author Scribble */ -public class VirtualKeyboard2 extends VirtualPeripheral implements Serializable { +public class VirtualKeyboard2 extends VirtualPeripheral implements Serializable { /** * The list of characters that were pressed on this keyboard. @@ -46,15 +50,6 @@ public class VirtualKeyboard2 extends VirtualPeripheral implements Serializable */ private final ConcurrentLinkedQueue charQueue = new ConcurrentLinkedQueue<>(); - /** - * A list of subtick keyboards.
- * If subtickKeyboards is initialized, the object can be considered as a parent keyboard,
- * able to house subtickKeyboards.
- *
- * If subtickKeyboards is null then the object is a "child"/subtickKeyboard stored in a parent list - */ - private final List subtickKeyboards; - /** * Creates an empty parent keyboard with all keys unpressed */ @@ -76,12 +71,26 @@ public VirtualKeyboard2(Set pressedKeys, List charList){ * @param pressedKeys The existing list of pressed keycodes * @param charList The existing list of characters */ - public VirtualKeyboard2(Set pressedKeys, List charList, List subtickKeyboards) { - super(pressedKeys); + public VirtualKeyboard2(Set pressedKeys, List charList, List subtick) { + super(pressedKeys, subtick); this.charList = charList; - this.subtickKeyboards = subtickKeyboards; } + /** + * Updates the keyboard, adds a new subtick to this keyboard + * @param keycode The keycode of this key + * @param keystate The keystate of this key, true for pressed + * @param character The character that is associated with that key. Can change between keyboards or whenever shift is held in combination. + */ + public void update(int keycode, boolean keystate, char character) { + setPressed(keycode, keystate); + addChar(character); + + if(isParent()) { + addSubtick(clone()); + } + } + @Override public void setPressed(int keycode, boolean keystate) { if (keycode >= 0) { // Keyboard keys always have a keycode larger or equal than 0 @@ -90,8 +99,8 @@ public void setPressed(int keycode, boolean keystate) { } @Override - protected List getDifference(T nextPeripheral) { - List eventList = new ArrayList<>(); + protected Queue getDifference(VirtualKeyboard2 nextPeripheral) { + Queue eventList = new ConcurrentLinkedQueue<>(); charQueue.addAll(charList); @@ -140,6 +149,17 @@ protected List getDifferen return eventList; } + @Override + protected Queue getVirtualEvents(VirtualKeyboard2 nextPeripheral) { + Queue eventList = new ConcurrentLinkedQueue<>(); + + getSubticks().forEach(keyboard -> { + eventList.addAll(keyboard.getDifference(nextPeripheral)); + }); + + return eventList; + } + private char getOrDefault(Character charr){ if(charr==null){ charr = Character.MIN_VALUE; @@ -161,48 +181,54 @@ public void clearCharList(){ charList.clear(); } + @Override + public String toString() { + if (isParent()) { + return getSubticks().stream().map(element -> element.toString()).collect(Collectors.joining("\n")); + } else { + return String.format("%s;%s", super.toString(), charListToString(charList)); + } + } + + private String charListToString(List charList) { + String charString = ""; + if (!charList.isEmpty()) { + charString = charList.stream().map(element -> element.toString()).collect(Collectors.joining()); + charString = StringUtils.replace(charString, "\r", "\\n"); + charString = StringUtils.replace(charString, "\n", "\\n"); + } + return charString; + } + + /** + * Clones this VirtualKeyboard without subticks + */ @Override - public String toString() { - if(subtickKeyboards == null){ - String charString = ""; - if (!charList.isEmpty()) { - for (Character charr : charList) { - charString = charString.concat(Character.toString(charr)); - } - charString = StringUtils.replace(charString, "\r", "\\n"); - charString = StringUtils.replace(charString, "\n", "\\n"); - } - - return String.format("%s;%s", super.toString(), charString); - } - else { - String charString = ""; - if (!charList.isEmpty()) { - for (Character charr : charList) { - charString = charString.concat(Character.toString(charr)); - } - charString = StringUtils.replace(charString, "\r", "\\n"); - charString = StringUtils.replace(charString, "\n", "\\n"); - } - - String out = String.format("%s;%s", super.toString(), charString); - for(VirtualKeyboard2 child : subtickKeyboards){ - out=out.concat("\n\t"+child.toString()); - } - return out; - } - } - - @Override - protected VirtualKeyboard2 clone() { + public VirtualKeyboard2 clone() { return new VirtualKeyboard2(this.pressedKeys, this.charList); } - public boolean isParent(){ - return subtickKeyboards!=null; - } public List getCharList() { return ImmutableList.copyOf(charList); } + + @Override + public boolean equals(Object obj) { + if(obj instanceof VirtualKeyboard2) { + VirtualKeyboard2 keyboard = (VirtualKeyboard2) obj; + + if(charList.size() != keyboard.charList.size()) { + return false; + } + + for (int i = 0; i < charList.size(); i++) { + if(charList.get(i)!=keyboard.charList.get(i)) { + return false; + } + } + return super.equals(obj); + } + return super.equals(obj); + } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java index 3c0dad8c..202afa10 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java @@ -1,6 +1,8 @@ package com.minecrafttas.tasmod.virtual; -public class VirtualKeyboardEvent extends VirtualEvent { +import com.minecrafttas.tasmod.virtual.VirtualEvent.VirtualButtonEvent; + +public class VirtualKeyboardEvent extends VirtualButtonEvent { private final char character; public VirtualKeyboardEvent(int keycode, boolean keystate, char character) { @@ -8,7 +10,7 @@ public VirtualKeyboardEvent(int keycode, boolean keystate, char character) { this.character = character; } - public VirtualKeyboardEvent(VirtualEvent event, char character) { + public VirtualKeyboardEvent(VirtualButtonEvent event, char character) { super(event); this.character = character; } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java index 97941598..ca554e0d 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java @@ -1,12 +1,13 @@ package com.minecrafttas.tasmod.virtual; import java.io.Serializable; -import java.util.ArrayList; import java.util.HashSet; -import java.util.List; +import java.util.Queue; import java.util.Set; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.stream.Collectors; -public class VirtualMouse2 extends VirtualPeripheral implements Serializable { +public class VirtualMouse2 extends VirtualPeripheral implements Serializable { /** * The direction of the scrollWheel
@@ -34,10 +35,11 @@ public VirtualMouse2(){ /** * Creates a mouse from existing values + * * @param pressedKeys The list o {@link #pressedKeys} * @param scrollWheel The {@link #scrollWheel} - * @param cursorX The {@link #cursorX} - * @param cursorY The {@link #cursorY} + * @param cursorX The {@link #cursorX} + * @param cursorY The {@link #cursorY} */ public VirtualMouse2(Set pressedKeys, int scrollWheel, Integer cursorX, Integer cursorY) { super(pressedKeys); @@ -48,14 +50,14 @@ public VirtualMouse2(Set pressedKeys, int scrollWheel, Integer cursorX, @Override protected void setPressed(int keycode, boolean keystate) { - if(keycode < 0){ + if (keycode < 0) { super.setPressed(keycode, keystate); } } @Override - protected List getDifference(T nextPeripheral) { - List eventList = new ArrayList<>(); + protected Queue getDifference(VirtualMouse2 nextPeripheral) { + Queue eventList = new ConcurrentLinkedQueue<>(); int scrollWheelCopy = scrollWheel; Integer cursorXCopy = cursorX; @@ -95,13 +97,40 @@ protected List getDifferen return eventList; } + @Override + protected Queue getVirtualEvents(VirtualMouse2 nextPeripheral) { + Queue eventList = new ConcurrentLinkedQueue<>(); + + getSubticks().forEach(keyboard -> { + eventList.addAll(keyboard.getDifference(nextPeripheral)); + }); + + return eventList; + } + @Override public String toString() { - return String.format("%s;%s,%s,%s", super.toString(), scrollWheel, cursorX, cursorY); + if (isParent()) { + return getSubticks().stream().map(element -> element.toString()).collect(Collectors.joining("\n")); + } else { + return String.format("%s;%s,%s,%s", super.toString(), scrollWheel, cursorX, cursorY); + } } @Override - protected VirtualMouse2 clone() { + public VirtualMouse2 clone() { return new VirtualMouse2(this.pressedKeys, scrollWheel, cursorX, cursorY); } + + @Override + public boolean equals(Object obj) { + if (obj instanceof VirtualMouse2) { + VirtualMouse2 mouse = (VirtualMouse2) obj; + return super.equals(obj) && + scrollWheel == mouse.scrollWheel && + cursorX == mouse.cursorX && + cursorY == mouse.cursorY; + } + return super.equals(obj); + } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java index 16e36854..ec01df06 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java @@ -1,13 +1,13 @@ package com.minecrafttas.tasmod.virtual; -import com.minecrafttas.tasmod.virtual.VirtualEvent; +import com.minecrafttas.tasmod.virtual.VirtualEvent.VirtualButtonEvent; /** * Template for recording Mouse.next() events. * * @author Scribble */ -public class VirtualMouseEvent extends VirtualEvent { +public class VirtualMouseEvent extends VirtualButtonEvent { private final int scrollwheel; private final Integer mouseX; private final Integer mouseY; diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java index 5a56b73f..32226fed 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java @@ -1,12 +1,14 @@ package com.minecrafttas.tasmod.virtual; -import com.google.common.collect.ImmutableSet; - import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import java.util.Queue; import java.util.Set; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; + /** * Base class for {@link VirtualKeyboard2} and {@link VirtualMouse2}
*
@@ -17,19 +19,32 @@ * * @author Scribble */ -public abstract class VirtualPeripheral implements Serializable { +public abstract class VirtualPeripheral> implements Serializable { /** * The list of keycodes that are currently pressed on this peripheral. */ protected final Set pressedKeys; - + /** + * A list of subtick keyboards.
+ * If subtickKeyboards is initialized, the object can be considered as a parent keyboard,
+ * able to house subtickKeyboards.
+ *
+ * If subtickKeyboards is null then the object is a "child"/subtickKeyboard stored in a parent list + */ + private final List subtickList; + /** * Create a peripheral with already existing pressed keys * @param pressedKeys The existing pressedKeys */ - protected VirtualPeripheral(Set pressedKeys) { + protected VirtualPeripheral(Set pressedKeys) { + this(pressedKeys, null); + } + + protected VirtualPeripheral(Set pressedKeys, List subtickList) { this.pressedKeys = pressedKeys; + this.subtickList = subtickList; } /** @@ -43,6 +58,10 @@ protected void setPressed(int keycode, boolean keystate) { else pressedKeys.remove(keycode); } + + protected void addSubtick(T peripheral) { + subtickList.add(peripheral); + } /** * Set the specified keyname to pressed @@ -67,16 +86,28 @@ public List getCurrentPresses() { return out; } - /** - * Calculates the difference between 2 peripherals via symmetric difference
- * and returns a list of the changes between in form of {@link VirtualEvent}s - * - * @param nextPeripheral The peripheral that is comes after this one.
- * If this one is loaded at tick 15, the nextPeripheral should be the one from tick 16 - * @return A list of {@link VirtualEvent}s - */ - protected abstract List getDifference(T nextPeripheral); + /** + * Calculates the difference between 2 peripherals via symmetric difference
+ * and returns a list of the changes between in form of {@link VirtualEvent}s + * + * @param nextPeripheral The peripheral that is comes after this one.
+ * If this one is loaded at tick 15, the nextPeripheral + * should be the one from tick 16 + * @return A list of {@link VirtualEvent}s + */ + protected abstract Queue getDifference(T nextPeripheral); + /** + * Calculates a list of {@link VirtualEvent}s to the next peripheral including + * the subticks. + * + * @param nextPeripheral The peripheral that is comes after this one.
+ * If this one is loaded at tick 15, the nextPeripheral + * should be the one from tick 16 + * @return A list of {@link VirtualEvent}s + */ + protected abstract Queue getVirtualEvents(T nextPeripheral); + @Override public String toString() { return String.join(",", getCurrentPresses()); @@ -85,7 +116,29 @@ public String toString() { /** * @return An immutable set of pressed keycodes */ - public Set getPressedKeys(){ - return ImmutableSet.copyOf(pressedKeys); - } + public Set getPressedKeys() { + return ImmutableSet.copyOf(pressedKeys); + } + + public List getSubticks() { + return ImmutableList.copyOf(subtickList); + } + + public boolean isParent() { + return subtickList != null; + } + + @Override + public boolean equals(Object obj) { + if(obj instanceof VirtualPeripheral) { + VirtualPeripheral peripheral = (VirtualPeripheral) obj; + for (Integer keycode : pressedKeys) { + if(!peripheral.pressedKeys.contains(keycode)) { + return false; + } + } + return true; + } + return super.equals(obj); + } } diff --git a/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java b/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java index 45de8551..e05839e5 100644 --- a/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java +++ b/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java @@ -105,7 +105,67 @@ void testToString(){ testCharList.add('s'); VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, testCharList, null); + VirtualKeyboard2 test2 = new VirtualKeyboard2(testKeycodeSet, new ArrayList<>(), null); assertEquals("W,S;ws", test.toString()); + assertEquals("W,S;", test2.toString()); + } + + @Test + void testEquals() { + Set testKeycodeSet = new HashSet<>(); + testKeycodeSet.add(VirtualKey2.W.getKeycode()); + testKeycodeSet.add(VirtualKey2.S.getKeycode()); + + List testCharList = new ArrayList<>(); + testCharList.add('w'); + testCharList.add('s'); + + VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, testCharList, null); + VirtualKeyboard2 test2 = new VirtualKeyboard2(testKeycodeSet, testCharList, null); + + assertEquals(test, test2); + } + + @Test + void testNotEquals() { + Set testKeycodeSet = new HashSet<>(); + testKeycodeSet.add(VirtualKey2.W.getKeycode()); + testKeycodeSet.add(VirtualKey2.S.getKeycode()); + + List testCharList = new ArrayList<>(); + testCharList.add('w'); + testCharList.add('s'); + + List testCharList2 = new ArrayList<>(); + testCharList2.add('w'); + testCharList2.add('S'); + + List testCharList3 = new ArrayList<>(); + testCharList3.add('w'); + + VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, testCharList, null); + VirtualKeyboard2 test2 = new VirtualKeyboard2(testKeycodeSet, testCharList2, null); + VirtualKeyboard2 test3 = new VirtualKeyboard2(testKeycodeSet, testCharList3, null); + + assertNotEquals(test, test2); + assertNotEquals(test, test3); + assertNotEquals(test, null); + } + + @Test + void testClone() { + Set testKeycodeSet = new HashSet<>(); + testKeycodeSet.add(VirtualKey2.W.getKeycode()); + testKeycodeSet.add(VirtualKey2.S.getKeycode()); + + List testCharList = new ArrayList<>(); + testCharList.add('w'); + testCharList.add('s'); + + VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, testCharList, null); + VirtualKeyboard2 test2 = test.clone(); + + assertEquals(test, test2); } } From 5303e858c6de4aee5bfff432660b90e495d5836f Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 15 Jan 2024 21:56:59 +0100 Subject: [PATCH 08/57] [VirtualInput] Start rewriting VI, moved playback mixins into a seperate file - Added copyFrom, copying only the internals without creating new objects --- .../tasmod/mixin/MixinMinecraft.java | 128 +----------------- .../mixin/playbackhooks/MixinMinecraft.java | 112 +++++++++++++++ .../tasmod/virtual/VirtualInput2.java | 30 +++- .../tasmod/virtual/VirtualKeyboard2.java | 9 +- .../tasmod/virtual/VirtualMouse2.java | 14 +- .../tasmod/virtual/VirtualPeripheral.java | 9 ++ src/main/resources/tasmod.mixin.json | 1 + 7 files changed, 172 insertions(+), 131 deletions(-) create mode 100644 src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java index 32f426b5..c61cb858 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java @@ -2,8 +2,6 @@ import java.io.IOException; -import org.lwjgl.input.Keyboard; -import org.lwjgl.input.Mouse; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -16,7 +14,6 @@ import com.minecrafttas.tasmod.TASmodClient; import com.minecrafttas.tasmod.events.EventClient.EventClientTickPost; import com.minecrafttas.tasmod.savestates.SavestateHandlerServer; -import com.minecrafttas.tasmod.util.Ducks.GuiScreenDuck; import com.minecrafttas.tasmod.util.Ducks.SubtickDuck; import net.minecraft.client.Minecraft; @@ -35,20 +32,7 @@ public abstract class MixinMinecraft { @Inject(method = "runGameLoop", at = @At(value = "HEAD")) public void injectRunGameLoop(CallbackInfo ci) { - TASmodClient.gameLoopSchedulerClient.runAllTasks(); - - while (Keyboard.next()) { - TASmodClient.virtual.updateNextKeyboard(Keyboard.getEventKey(), Keyboard.getEventKeyState(), Keyboard.getEventCharacter()); - } - while (Mouse.next()) { - if(this.currentScreen == null) { - TASmodClient.virtual.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), Mouse.getEventX(), Mouse.getEventY(), TASmodClient.tickratechanger.ticksPerSecond==0); - } else { - GuiScreenDuck screen = (GuiScreenDuck) currentScreen; - TASmodClient.virtual.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), screen.calcX(Mouse.getEventX()), screen.calcY(Mouse.getEventY()), TASmodClient.tickratechanger.ticksPerSecond==0); - } - } } // ===================================================================================================================================== @@ -92,132 +76,24 @@ public void inject_shutdownMinecraftApplet(CallbackInfo ci) { } } - // ===================================================================================================================================== - @Inject(method = "runTick", at = @At(value = "HEAD")) public void injectRunTick(CallbackInfo ci) throws IOException { if (SavestateHandlerServer.wasLoading) { SavestateHandlerServer.wasLoading = false; if(Minecraft.getMinecraft().player!=null) { //The player can be null when loading a savestate and quitting to the main menu - SavestateHandlerServer.playerLoadSavestateEventClient(); + SavestateHandlerServer.playerLoadSavestateEventClient(); // TODO Replace with event } } } - // ===================================================================================================================================== - - @Inject(method = "runTickKeyboard", at = @At(value = "HEAD")) - public void injectRunTickKeyboard(CallbackInfo ci) { - TASmodClient.virtual.updateCurrentKeyboard(); - } - - // ===================================================================================================================================== - - @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;next()Z", remap = false)) - public boolean redirectKeyboardNext() { - return TASmodClient.virtual.nextKeyboardEvent(); - } - - // ===================================================================================================================================== - - @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKey()I", remap = false)) - public int redirectKeyboardGetEventKey() { - return TASmodClient.virtual.getEventKeyboardKey(); - } - - // ===================================================================================================================================== - - @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventCharacter()C", remap = false)) - public char redirectKeyboardGetEventCharacter() { - return TASmodClient.virtual.getEventKeyboardCharacter(); - } - - // ===================================================================================================================================== - - @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;isKeyDown(I)Z", remap = false)) - public boolean redirectIsKeyDown(int keyCode) { - return TASmodClient.virtual.isKeyDown(keyCode); - } - - // ===================================================================================================================================== - - @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKeyState()Z", remap = false)) - public boolean redirectGetEventState() { - return TASmodClient.virtual.getEventKeyboardState(); - } - - // ===================================================================================================================================== - - @Inject(method = "runTickMouse", at = @At(value = "HEAD")) - public void injectRunTickMouse(CallbackInfo ci) { - TASmodClient.virtual.updateCurrentMouseEvents(); - } - - // ===================================================================================================================================== - - @Redirect(method = "runTickMouse", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;next()Z", remap = false)) - public boolean redirectMouseNext() { - return TASmodClient.virtual.nextMouseEvent(); - } - - // ===================================================================================================================================== - - @Redirect(method = "runTickMouse", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventButton()I", remap = false)) - public int redirectMouseGetEventButton() { - -// if(!VirtualKeybindings.isKeyCodeAlwaysBlocked(ClientProxy.virtual.getEventMouseKey()-100)) { -// TASmod.ktrngHandler.nextPlayerInput(); // Advance ktrng seed on player input -// } - return TASmodClient.virtual.getEventMouseKey() + 100; - } - - // ===================================================================================================================================== - - @Redirect(method = "runTickMouse", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventButtonState()Z", remap = false)) - public boolean redirectGetEventButtonState() { - return TASmodClient.virtual.getEventMouseState(); - } - - // ===================================================================================================================================== - @ModifyConstant(method = "runTickMouse", constant = @Constant(longValue = 200L)) public long fixMouseWheel(long twohundredLong) { return (long) Math.max(4000F / TASmodClient.tickratechanger.ticksPerSecond, 200L); } - // ===================================================================================================================================== - - @Redirect(method = "runTickMouse", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventDWheel()I", remap = false)) - public int redirectGetEventDWheel() { - return TASmodClient.virtual.getEventMouseScrollWheel(); - } - - // ===================================================================================================================================== - - @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKey()I", remap = false)) - public int redirectGetEventKeyDPK() { - return TASmodClient.virtual.getEventKeyboardKey(); - } - - // ===================================================================================================================================== - - @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventCharacter()C", remap = false)) - public char redirectGetEventCharacterDPK() { - return TASmodClient.virtual.getEventKeyboardCharacter(); - } - - // ===================================================================================================================================== - - @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKeyState()Z", remap = false)) - public boolean redirectGetEventKeyStateDPK() { - return TASmodClient.virtual.getEventKeyboardState(); - } - - // ===================================================================================================================================== - @Inject(method = "runTick", at = @At(value = "RETURN")) public void injectRunTickReturn(CallbackInfo ci) { - TASmodClient.controller.nextTick(); + TASmodClient.controller.nextTick(); // TODO Replace with event } } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java new file mode 100644 index 00000000..4a5c2dbb --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java @@ -0,0 +1,112 @@ +package com.minecrafttas.tasmod.mixin.playbackhooks; + +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.minecrafttas.tasmod.TASmodClient; +import com.minecrafttas.tasmod.util.Ducks.GuiScreenDuck; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiScreen; + +@Mixin(Minecraft.class) +public class MixinMinecraft { + + @Shadow + private GuiScreen currentScreen; + + @Inject(method = "runGameLoop", at = @At(value = "HEAD")) + public void playback_injectRunGameLoop(CallbackInfo ci) { + while (Keyboard.next()) { + TASmodClient.virtual.updateNextKeyboard(Keyboard.getEventKey(), Keyboard.getEventKeyState(), Keyboard.getEventCharacter()); + } + while (Mouse.next()) { + if(this.currentScreen == null) { + TASmodClient.virtual.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), Mouse.getEventX(), Mouse.getEventY(), TASmodClient.tickratechanger.ticksPerSecond==0); + } else { + GuiScreenDuck screen = (GuiScreenDuck) currentScreen; + TASmodClient.virtual.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), screen.calcX(Mouse.getEventX()), screen.calcY(Mouse.getEventY()), TASmodClient.tickratechanger.ticksPerSecond==0); + } + } + } + + @Inject(method = "runTickKeyboard", at = @At(value = "HEAD")) + public void playback_injectRunTickKeyboard(CallbackInfo ci) { + TASmodClient.virtual.updateCurrentKeyboard(); + } + + @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;next()Z", remap = false)) + public boolean playback_redirectKeyboardNext() { + return TASmodClient.virtual.nextKeyboardEvent(); + } + + @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKey()I", remap = false)) + public int playback_redirectKeyboardGetEventKey() { + return TASmodClient.virtual.getEventKeyboardKey(); + } + + @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventCharacter()C", remap = false)) + public char playback_redirectKeyboardGetEventCharacter() { + return TASmodClient.virtual.getEventKeyboardCharacter(); + } + + @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;isKeyDown(I)Z", remap = false)) + public boolean playback_redirectIsKeyDown(int keyCode) { + return TASmodClient.virtual.isKeyDown(keyCode); + } + + @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKeyState()Z", remap = false)) + public boolean playback_redirectGetEventState() { + return TASmodClient.virtual.getEventKeyboardState(); + } + + @Inject(method = "runTickMouse", at = @At(value = "HEAD")) + public void playback_injectRunTickMouse(CallbackInfo ci) { + TASmodClient.virtual.updateCurrentMouseEvents(); + } + + @Redirect(method = "runTickMouse", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;next()Z", remap = false)) + public boolean playback_redirectMouseNext() { + return TASmodClient.virtual.nextMouseEvent(); + } + + @Redirect(method = "runTickMouse", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventButton()I", remap = false)) + public int playback_redirectMouseGetEventButton() { + +// if(!VirtualKeybindings.isKeyCodeAlwaysBlocked(ClientProxy.virtual.getEventMouseKey()-100)) { +// TASmod.ktrngHandler.nextPlayerInput(); // Advance ktrng seed on player input +// } + return TASmodClient.virtual.getEventMouseKey() + 100; + } + + @Redirect(method = "runTickMouse", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventButtonState()Z", remap = false)) + public boolean playback_redirectGetEventButtonState() { + return TASmodClient.virtual.getEventMouseState(); + } + + @Redirect(method = "runTickMouse", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventDWheel()I", remap = false)) + public int playback_redirectGetEventDWheel() { + return TASmodClient.virtual.getEventMouseScrollWheel(); + } + + @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKey()I", remap = false)) + public int playback_redirectGetEventKeyDPK() { + return TASmodClient.virtual.getEventKeyboardKey(); + } + + @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventCharacter()C", remap = false)) + public char playback_redirectGetEventCharacterDPK() { + return TASmodClient.virtual.getEventKeyboardCharacter(); + } + + @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKeyState()Z", remap = false)) + public boolean playback_redirectGetEventKeyStateDPK() { + return TASmodClient.virtual.getEventKeyboardState(); + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java index 0bd411a2..d3da194f 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java @@ -1,11 +1,39 @@ package com.minecrafttas.tasmod.virtual; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; + public class VirtualInput2 { + private VirtualKeyboard2 currentKeyboard; + + private VirtualKeyboard2 nextKeyboard = new VirtualKeyboard2(); + + private Queue keyboardEventQueue = new ConcurrentLinkedQueue(); + + private VirtualMouse2 currentMouse; + + private VirtualMouse2 nextMouse = new VirtualMouse2(); + + private Queue mouseEventQueue = new ConcurrentLinkedQueue(); + + private VirtualCameraAngle cameraAngle; + public VirtualInput2() { + this(new VirtualKeyboard2(), new VirtualMouse2(), new VirtualCameraAngle(0, 0)); + } + + public VirtualInput2(VirtualKeyboard2 preloadedKeyboard, VirtualMouse2 preloadedMouse, VirtualCameraAngle preloadedCamera) { + this.currentKeyboard = preloadedKeyboard; + this.currentMouse = preloadedMouse; + this.cameraAngle = preloadedCamera; } - public void updateKeyboard(int keycode, boolean keystate, char character) { + public void updateNextKeyboard(int keycode, boolean keystate, char character) { + + } + + public void updateCurrentKeyboard() { } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java index 1cec460a..085a791a 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java @@ -207,8 +207,15 @@ private String charListToString(List charList) { public VirtualKeyboard2 clone() { return new VirtualKeyboard2(this.pressedKeys, this.charList); } + - + @Override + public void copyFrom(VirtualKeyboard2 keyboard) { + super.copyFrom(keyboard); + clearCharList(); + charList.addAll(keyboard.charList); + } + public List getCharList() { return ImmutableList.copyOf(charList); } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java index ca554e0d..dc796af7 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java @@ -14,17 +14,17 @@ public class VirtualMouse2 extends VirtualPeripheral implements S *
* If the number is positive or negative depending on scroll direction. */ - private final int scrollWheel; + private int scrollWheel; /** * X coordinate of the on-screen cursor, used in GUI screens.
* When null, no change to the cursor is applied. */ - private final Integer cursorX; + private Integer cursorX; /** * Y coordinate of the on-screen cursor, used in GUI screens.
* When null, no change to the cursor is applied. */ - private final Integer cursorY; + private Integer cursorY; /** * Creates a mouse with no buttons pressed and no data @@ -122,6 +122,14 @@ public VirtualMouse2 clone() { return new VirtualMouse2(this.pressedKeys, scrollWheel, cursorX, cursorY); } + @Override + protected void copyFrom(VirtualMouse2 mouse) { + super.copyFrom(mouse); + this.scrollWheel = mouse.scrollWheel; + this.cursorX = mouse.cursorX; + this.cursorY = mouse.cursorY; + } + @Override public boolean equals(Object obj) { if (obj instanceof VirtualMouse2) { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java index 32226fed..9c21e043 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java @@ -141,4 +141,13 @@ public boolean equals(Object obj) { } return super.equals(obj); } + + /** + * Copies the data from another virtual peripheral into this peripheral without creating a new objects. + * @param keyboard + */ + protected void copyFrom(T peripheral) { + this.pressedKeys.clear(); + this.pressedKeys.addAll(peripheral.pressedKeys); + } } diff --git a/src/main/resources/tasmod.mixin.json b/src/main/resources/tasmod.mixin.json index b91afa5c..c6b05aa5 100644 --- a/src/main/resources/tasmod.mixin.json +++ b/src/main/resources/tasmod.mixin.json @@ -47,6 +47,7 @@ "events.MixinGuiIngame", //Playbackhooks + "playbackhooks.MixinMinecraft", "playbackhooks.MixinGameSettings", "playbackhooks.MixinGuiChat", "playbackhooks.MixinGuiClickableScrolledSelectionListProxy", From 3f2b56c636eee9de16740e67a029614ce9829a02 Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 15 Jan 2024 23:04:28 +0100 Subject: [PATCH 09/57] [Bug] Fixed #67 again - Removed unnecessary TODO in comments... --- .../com/minecrafttas/tasmod/TASmodClient.java | 4 ++-- .../mixin/playbackhooks/MixinGuiContainer.java | 15 +++++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java index b2cc8ee0..ab939a29 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java @@ -162,7 +162,7 @@ protected boolean isKeyDown(KeyBinding i) { // Register packet handlers LOGGER.info(LoggerMarkers.Networking, "Registering network handlers on client"); - PacketHandlerRegistry.register(controller); //TODO Move container/playbackcontroller out of virtual package + PacketHandlerRegistry.register(controller); PacketHandlerRegistry.register(ticksyncClient); PacketHandlerRegistry.register(tickratechanger); PacketHandlerRegistry.register(savestateHandlerClient); @@ -258,7 +258,7 @@ public void onPlayerJoinedClientSide(EntityPlayerSP player) { gameLoopSchedulerClient.add(()->{ try { // connect to server and authenticate - client = new Client(IP, PORT, TASmodPackets.values(), mc.getSession().getUsername(), local); //TODO set timeout by tickrate + client = new Client(IP, PORT, TASmodPackets.values(), mc.getSession().getUsername(), local); } catch (Exception e) { LOGGER.error("Unable to connect TASmod client: {}", e.getMessage()); e.printStackTrace(); diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiContainer.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiContainer.java index a539960e..88c5c634 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiContainer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiContainer.java @@ -1,11 +1,14 @@ package com.minecrafttas.tasmod.mixin.playbackhooks; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; import com.minecrafttas.tasmod.TASmodClient; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.gui.inventory.GuiContainer; @Mixin(GuiContainer.class) @@ -20,8 +23,12 @@ private boolean redirectIsKeyDown2(int i) { return TASmodClient.virtual.isKeyDown(i); } -// @Redirect(method = "keyTyped", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/settings/KeyBinding;isActiveAndMatches(I)Z", remap = false)) //TODO Fix if #67 occurs -// public boolean redirectIsActiveAndMatches(KeyBinding keyBindInventory, int keyCode) { -// return keyBindInventory.isActiveAndMatches(keyCode) && !((GuiContainer)(Object)this).isFocused(); -// } + @Redirect(method = "keyTyped", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;closeScreen()V")) + public void redirectCloseScreen(EntityPlayerSP player) { + Minecraft mc = Minecraft.getMinecraft(); + if(TASmodClient.virtual.isKeyDown(mc.gameSettings.keyBindInventory.getKeyCode()) && ((GuiContainer)(Object)this).isFocused()) { + return; + } + player.closeScreen(); + } } From 49bc1c3ab661bd0b92d5ea8c6cddc99a252b8226 Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 16 Jan 2024 14:05:12 +0100 Subject: [PATCH 10/57] [VirtualInput] Fixed clone, add tests - Minor documentation changes --- .../tasmod/virtual/VirtualKeyboard2.java | 12 +- .../tasmod/virtual/VirtualKeyboardEvent.java | 9 ++ .../tasmod/virtual/VirtualMouse2.java | 5 +- .../tasmod/virtual/VirtualPeripheral.java | 4 +- .../virtual/keyboard/VirtualKeyboardTest.java | 104 +++++++++++++++++- 5 files changed, 122 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java index 085a791a..c1350ead 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java @@ -45,7 +45,7 @@ public class VirtualKeyboard2 extends VirtualPeripheral implem private final List charList; /** - * A queue of characters used in {@link #getDifference(VirtualPeripheral)}.
+ * A queue of characters used in {@link #getDifference(VirtualKeyboard2)}.
* Used for distributing characters to {@link VirtualKeyboardEvent}s in an order. */ private final ConcurrentLinkedQueue charQueue = new ConcurrentLinkedQueue<>(); @@ -58,7 +58,7 @@ public VirtualKeyboard2() { } /** - * Creates a subtick keyboard with {@link #subtickKeyboards} uninitialized + * Creates a subtick keyboard with {@link #subtickList} uninitialized * @param pressedKeys The new list of pressed keycodes for this subtickKeyboard * @param charList A list of characters for this subtickKeyboard */ @@ -99,10 +99,10 @@ public void setPressed(int keycode, boolean keystate) { } @Override - protected Queue getDifference(VirtualKeyboard2 nextPeripheral) { + public Queue getDifference(VirtualKeyboard2 nextPeripheral) { Queue eventList = new ConcurrentLinkedQueue<>(); - charQueue.addAll(charList); + charQueue.addAll(nextPeripheral.charList); /* Calculate symmetric difference of keycodes */ @@ -150,7 +150,7 @@ protected Queue getDifference(VirtualKeyboard2 nextPeriphe } @Override - protected Queue getVirtualEvents(VirtualKeyboard2 nextPeripheral) { + public Queue getVirtualEvents(VirtualKeyboard2 nextPeripheral) { Queue eventList = new ConcurrentLinkedQueue<>(); getSubticks().forEach(keyboard -> { @@ -205,7 +205,7 @@ private String charListToString(List charList) { */ @Override public VirtualKeyboard2 clone() { - return new VirtualKeyboard2(this.pressedKeys, this.charList); + return new VirtualKeyboard2(new HashSet<>(this.pressedKeys), new ArrayList<>(this.charList)); } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java index 202afa10..f6163982 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java @@ -23,4 +23,13 @@ public char getCharacter() { public String toString() { return String.format("%s, %s", super.toString(), character); } + + @Override + public boolean equals(Object obj) { + if(obj instanceof VirtualKeyboardEvent){ + VirtualKeyboardEvent e = (VirtualKeyboardEvent) obj; + return keycode == e.keycode && keystate == e.keystate && character == e.character; + } + return super.equals(obj); + } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java index dc796af7..780ec7e2 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java @@ -117,9 +117,12 @@ public String toString() { } } + /** + * Clones this VirtualMouse without subticks + */ @Override public VirtualMouse2 clone() { - return new VirtualMouse2(this.pressedKeys, scrollWheel, cursorX, cursorY); + return new VirtualMouse2(new HashSet<>(this.pressedKeys), scrollWheel, cursorX, cursorY); } @Override diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java index 9c21e043..29638684 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java @@ -143,8 +143,8 @@ public boolean equals(Object obj) { } /** - * Copies the data from another virtual peripheral into this peripheral without creating a new objects. - * @param keyboard + * Copies the data from another virtual peripheral into this peripheral without creating a new object. + * @param peripheral The peripheral to copy from */ protected void copyFrom(T peripheral) { this.pressedKeys.clear(); diff --git a/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java b/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java index e05839e5..4e70f304 100644 --- a/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java +++ b/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java @@ -2,14 +2,20 @@ import com.minecrafttas.tasmod.virtual.VirtualKey2; import com.minecrafttas.tasmod.virtual.VirtualKeyboard2; +import com.minecrafttas.tasmod.virtual.VirtualKeyboardEvent; import org.junit.jupiter.api.Test; +import java.lang.reflect.Array; import java.util.*; +import java.util.concurrent.ConcurrentLinkedQueue; import static org.junit.jupiter.api.Assertions.*; public class VirtualKeyboardTest { + /** + * Test the empty constructor + */ @Test void testEmptyConstructor(){ VirtualKeyboard2 test = new VirtualKeyboard2(); @@ -18,6 +24,9 @@ void testEmptyConstructor(){ assertTrue(test.isParent()); } + /** + * Test constructor with premade keycode sets + */ @Test void testSubtickConstructor(){ Set testKeycodeSet = new HashSet<>(); @@ -35,6 +44,9 @@ void testSubtickConstructor(){ assertFalse(test.isParent()); } + /** + * Test setting the keycodes via setPressed to "pressed" + */ @Test void testSetPressedByKeycode(){ VirtualKeyboard2 test = new VirtualKeyboard2(); @@ -44,6 +56,9 @@ void testSetPressedByKeycode(){ assertTrue(test.isParent()); } + /** + * Test setting the keynames via setPressed to "pressed" + */ @Test void testSetPressedByKeyname(){ VirtualKeyboard2 test = new VirtualKeyboard2(); @@ -53,6 +68,9 @@ void testSetPressedByKeyname(){ assertTrue(test.isParent()); } + /** + * Test setting the keycodes via setPressed to "unpressed" + */ @Test void testSetUnPressedByKeycode(){ Set testKeycodeSet = new HashSet<>(); @@ -64,6 +82,9 @@ void testSetUnPressedByKeycode(){ assertIterableEquals(Arrays.asList(VirtualKey2.S.getKeycode()), test.getPressedKeys()); } + /** + * Test setting the keynames via setPressed to "unpressed" + */ @Test void testSetUnPressedByKeyname(){ Set testKeycodeSet = new HashSet<>(); @@ -75,6 +96,9 @@ void testSetUnPressedByKeyname(){ assertIterableEquals(Arrays.asList(VirtualKey2.W.getKeycode()), test.getPressedKeys()); } + /** + * Test adding a character to the keyboard + */ @Test void addCharacter(){ VirtualKeyboard2 test = new VirtualKeyboard2(); @@ -83,6 +107,9 @@ void addCharacter(){ assertIterableEquals(Arrays.asList('w'), test.getCharList()); } + /** + * Test clearing all characters + */ @Test void clearCharacters(){ List testCharList = new ArrayList<>(); @@ -94,6 +121,9 @@ void clearCharacters(){ assertTrue(test.getCharList().isEmpty()); } + /** + * Test the toString method without subticks + */ @Test void testToString(){ Set testKeycodeSet = new HashSet<>(); @@ -110,7 +140,10 @@ void testToString(){ assertEquals("W,S;ws", test.toString()); assertEquals("W,S;", test2.toString()); } - + + /** + * Test equals method + */ @Test void testEquals() { Set testKeycodeSet = new HashSet<>(); @@ -126,7 +159,10 @@ void testEquals() { assertEquals(test, test2); } - + + /** + * Test where equals will fail + */ @Test void testNotEquals() { Set testKeycodeSet = new HashSet<>(); @@ -152,7 +188,10 @@ void testNotEquals() { assertNotEquals(test, test3); assertNotEquals(test, null); } - + + /** + * Test cloning the keyboard + */ @Test void testClone() { Set testKeycodeSet = new HashSet<>(); @@ -168,4 +207,63 @@ void testClone() { assertEquals(test, test2); } + + /** + * Test copy from method + */ + @Test + void testCopyFrom(){ + Set testKeycodeSet = new HashSet<>(); + testKeycodeSet.add(VirtualKey2.W.getKeycode()); + testKeycodeSet.add(VirtualKey2.S.getKeycode()); + + List testCharList = new ArrayList<>(); + testCharList.add('w'); + testCharList.add('s'); + VirtualKeyboard2 copyFrom = new VirtualKeyboard2(testKeycodeSet, testCharList); + + Set testKeycodeSet2 = new HashSet<>(); + testKeycodeSet.add(VirtualKey2.A.getKeycode()); + testKeycodeSet.add(VirtualKey2.D.getKeycode()); + + List testCharList2 = new ArrayList<>(); + testCharList.add('a'); + testCharList.add('d'); + VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet2, testCharList2); + + test.copyFrom(copyFrom); + + assertIterableEquals(test.getPressedKeys(), copyFrom.getPressedKeys()); + assertIterableEquals(test.getCharList(), copyFrom.getCharList()); + } + + /** + * Test subtick list being filled via update + */ + @Test + void testUpdate(){ + VirtualKeyboard2 test = new VirtualKeyboard2(); + test.update(VirtualKey2.W.getKeycode(), true, 'w'); + test.update(VirtualKey2.A.getKeycode(), true, 'A'); + + List expected = new ArrayList<>(); + expected.add(new VirtualKeyboard2(Set.of(VirtualKey2.W.getKeycode()), List.of('w'))); + expected.add(new VirtualKeyboard2(Set.of(VirtualKey2.W.getKeycode(), VirtualKey2.A.getKeycode()), List.of('w', 'A'))); + + assertIterableEquals(expected, test.getSubticks()); + } + + /** + * Tests getDifference + */ + @Test + void testGetDifference(){ + VirtualKeyboard2 test = new VirtualKeyboard2(Set.of(VirtualKey2.W.getKeycode()), List.of('w')); + VirtualKeyboard2 test2 = new VirtualKeyboard2(Set.of(VirtualKey2.W.getKeycode(), VirtualKey2.S.getKeycode()), List.of('S')); + + Queue actual = test.getDifference(test2); + Queue expected = new ConcurrentLinkedQueue<>(List.of(new VirtualKeyboardEvent(VirtualKey2.S.getKeycode(), true, 'S'))); + + assertIterableEquals(expected, actual); + } } From 260a4dc72aa831305d785daaa8196399a22deb8a Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 16 Jan 2024 22:10:04 +0100 Subject: [PATCH 11/57] [VirtualInput] Added keyboard handling to virtual input - Remade "copyFrom" to "moveFrom" and making it clear the keyboard that is put in - Added more documentation to MixinMinecraft - Attempted to reduce memory footprint in Virtual keyboard and mouse --- .../mixin/playbackhooks/MixinMinecraft.java | 62 ++++++++++-- .../tasmod/virtual/VirtualInput2.java | 45 ++++++--- .../tasmod/virtual/VirtualKeyboard2.java | 71 ++++++++------ .../tasmod/virtual/VirtualMouse2.java | 41 ++++---- .../tasmod/virtual/VirtualPeripheral.java | 44 ++++----- .../virtual/keyboard/VirtualKeyboardTest.java | 98 +++++++++---------- 6 files changed, 215 insertions(+), 146 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java index 4a5c2dbb..c353a121 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java @@ -11,6 +11,9 @@ import com.minecrafttas.tasmod.TASmodClient; import com.minecrafttas.tasmod.util.Ducks.GuiScreenDuck; +import com.minecrafttas.tasmod.virtual.VirtualInput; +import com.minecrafttas.tasmod.virtual.VirtualInput2; +import com.minecrafttas.tasmod.virtual.VirtualKeyboardEvent; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; @@ -21,50 +24,95 @@ public class MixinMinecraft { @Shadow private GuiScreen currentScreen; + /** + * Runs every frame. Polls all the keys from LWJGL and updates {@link VirtualInput2} accordingly + * @param ci CBI + */ @Inject(method = "runGameLoop", at = @At(value = "HEAD")) public void playback_injectRunGameLoop(CallbackInfo ci) { while (Keyboard.next()) { - TASmodClient.virtual.updateNextKeyboard(Keyboard.getEventKey(), Keyboard.getEventKeyState(), Keyboard.getEventCharacter()); + TASmodClient.virtual.updateNextKeyboard( + Keyboard.getEventKey(), + Keyboard.getEventKeyState(), + Keyboard.getEventCharacter()); } while (Mouse.next()) { if(this.currentScreen == null) { - TASmodClient.virtual.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), Mouse.getEventX(), Mouse.getEventY(), TASmodClient.tickratechanger.ticksPerSecond==0); + TASmodClient.virtual.updateNextMouse( + Mouse.getEventButton(), + Mouse.getEventButtonState(), + Mouse.getEventDWheel(), + Mouse.getEventX(), + Mouse.getEventY(), + TASmodClient.tickratechanger.ticksPerSecond==0); } else { GuiScreenDuck screen = (GuiScreenDuck) currentScreen; - TASmodClient.virtual.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), screen.calcX(Mouse.getEventX()), screen.calcY(Mouse.getEventY()), TASmodClient.tickratechanger.ticksPerSecond==0); + TASmodClient.virtual.updateNextMouse( + Mouse.getEventButton(), + Mouse.getEventButtonState(), + Mouse.getEventDWheel(), + screen.calcX(Mouse.getEventX()), + screen.calcY(Mouse.getEventY()), + TASmodClient.tickratechanger.ticksPerSecond==0); //TODO Remove and put into VirtualInput itself } } } + /** + * Run at the start of run tick keyboard. Runs every tick + * @param ci CBI + */ @Inject(method = "runTickKeyboard", at = @At(value = "HEAD")) public void playback_injectRunTickKeyboard(CallbackInfo ci) { TASmodClient.virtual.updateCurrentKeyboard(); } + /** + * Redirects a {@link Keyboard#next()}. Starts running every tick and continues as long as there are {@link VirtualKeyboardEvent}s in {@link VirtualInput} + * @return If {@link VirtualKeyboardEvent}s are present in {@link VirtualInput2} + */ @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;next()Z", remap = false)) public boolean playback_redirectKeyboardNext() { return TASmodClient.virtual.nextKeyboardEvent(); } + /** + * Runs everytime {@link #playback_redirectKeyboardNext()} has an event ready. Redirects {@link Keyboard#getEventKeyState()} + * @return The keycode for the current event in {@link VirtualInput2} + */ @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKey()I", remap = false)) public int playback_redirectKeyboardGetEventKey() { return TASmodClient.virtual.getEventKeyboardKey(); } + /** + * Runs everytime {@link #playback_redirectKeyboardNext()} has an event ready. Redirects {@link Keyboard#getEventCharacter()} + * @return The character for the current event in {@link VirtualInput2} + */ @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventCharacter()C", remap = false)) public char playback_redirectKeyboardGetEventCharacter() { return TASmodClient.virtual.getEventKeyboardCharacter(); } + /** + * Runs everytime {@link #playback_redirectKeyboardNext()} has an event ready. Redirects {@link Keyboard#getEventKeyState()} + * @return Whether the key is down in {@link VirtualInput2} + */ + @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKeyState()Z", remap = false)) + public boolean playback_redirectGetEventState() { + return TASmodClient.virtual.getEventKeyboardState(); + } + + /** + * Runs everytime {@link #playback_redirectKeyboardNext()} has an event ready. Redirects {@link Keyboard#isKeyDown(int)} + * @return Whether the key is down in {@link VirtualInput2} + */ @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;isKeyDown(I)Z", remap = false)) public boolean playback_redirectIsKeyDown(int keyCode) { return TASmodClient.virtual.isKeyDown(keyCode); } - @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKeyState()Z", remap = false)) - public boolean playback_redirectGetEventState() { - return TASmodClient.virtual.getEventKeyboardState(); - } + // ============================ Mouse @Inject(method = "runTickMouse", at = @At(value = "HEAD")) public void playback_injectRunTickMouse(CallbackInfo ci) { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java index d3da194f..e0a279f5 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java @@ -3,21 +3,15 @@ import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; +import com.minecrafttas.tasmod.mixin.playbackhooks.MixinMinecraft; + public class VirtualInput2 { private VirtualKeyboard2 currentKeyboard; - private VirtualKeyboard2 nextKeyboard = new VirtualKeyboard2(); - private Queue keyboardEventQueue = new ConcurrentLinkedQueue(); + private VirtualKeyboardEvent currentKeyboardEvent; - private VirtualMouse2 currentMouse; - - private VirtualMouse2 nextMouse = new VirtualMouse2(); - - private Queue mouseEventQueue = new ConcurrentLinkedQueue(); - - private VirtualCameraAngle cameraAngle; public VirtualInput2() { this(new VirtualKeyboard2(), new VirtualMouse2(), new VirtualCameraAngle(0, 0)); @@ -28,14 +22,39 @@ public VirtualInput2(VirtualKeyboard2 preloadedKeyboard, VirtualMouse2 preloaded this.currentMouse = preloadedMouse; this.cameraAngle = preloadedCamera; } - + public void updateNextKeyboard(int keycode, boolean keystate, char character) { - + nextKeyboard.update(keycode, keystate, character); } - public void updateCurrentKeyboard() { - + /** + * Runs when the next keyboard tick is about to occur.
+ * Used to load {@link #nextKeyboard} into {@link #currentKeyboard}, creating {@link VirtualKeyboardEvent}s in the process. + * @see MixinMinecraft#playback_injectRunTickKeyboard(org.spongepowered.asm.mixin.injection.callback.CallbackInfo) + */ + public void nextKeyboardTick() { + currentKeyboard.getVirtualEvents(nextKeyboard, keyboardEventQueue); + currentKeyboard.moveFrom(nextKeyboard); } + public boolean nextKeyboardSubtick() { + return (currentKeyboardEvent = keyboardEventQueue.poll()) != null; + } + + public int getEventKeyboardKey() { + return currentKeyboardEvent.getKeyCode(); + } + + public boolean getEventKeyboardState() { + return currentKeyboardEvent.isState(); + } + + public char getEventKeyboardCharacter() { + return currentKeyboardEvent.getCharacter(); + } + private VirtualMouse2 currentMouse; + private VirtualMouse2 nextMouse = new VirtualMouse2(); + private Queue mouseEventQueue = new ConcurrentLinkedQueue(); + private VirtualCameraAngle cameraAngle; } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java index c1350ead..dfb705fd 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java @@ -98,11 +98,18 @@ public void setPressed(int keycode, boolean keystate) { } } - @Override - public Queue getDifference(VirtualKeyboard2 nextPeripheral) { - Queue eventList = new ConcurrentLinkedQueue<>(); + /** + * Calculates the difference between 2 keyboards via symmetric difference
+ * and returns a list of the changes between them in form of {@link VirtualKeyboardEvent}s + * + * @param nextKeyboard The keyboard that is comes after this one.
+ * If this one is loaded at tick 15, the nextPeripheral + * should be the one from tick 16 + * @param reference The queue to fill. Passed in by reference. + */ + public void getDifference(VirtualKeyboard2 nextKeyboard, Queue reference) { - charQueue.addAll(nextPeripheral.charList); + charQueue.addAll(nextKeyboard.charList); /* Calculate symmetric difference of keycodes */ @@ -114,8 +121,8 @@ public Queue getDifference(VirtualKeyboard2 nextPeripheral A <- unpressed */ this.pressedKeys.forEach(key -> { - if (!nextPeripheral.getPressedKeys().contains(key)) { - eventList.add(new VirtualKeyboardEvent(key, false, Character.MIN_VALUE)); + if (!nextKeyboard.getPressedKeys().contains(key)) { + reference.add(new VirtualKeyboardEvent(key, false, Character.MIN_VALUE)); } }); @@ -126,9 +133,9 @@ public Queue getDifference(VirtualKeyboard2 nextPeripheral ------------- D <- pressed */ - nextPeripheral.getPressedKeys().forEach(key -> { + nextKeyboard.getPressedKeys().forEach(key -> { if (!this.pressedKeys.contains(key)) { - eventList.add(new VirtualKeyboardEvent(key, true, getOrDefault(charQueue.poll()))); + reference.add(new VirtualKeyboardEvent(key, true, getOrMinChar(charQueue.poll()))); } }); @@ -143,30 +150,35 @@ public Queue getDifference(VirtualKeyboard2 nextPeripheral otherwise you'd either need to add a keycode for each char or write it in new lines */ while (!charQueue.isEmpty()) { - eventList.add(new VirtualKeyboardEvent(0, false, getOrDefault(charQueue.poll()))); + reference.add(new VirtualKeyboardEvent(0, false, getOrMinChar(charQueue.poll()))); } - return eventList; - } - - @Override - public Queue getVirtualEvents(VirtualKeyboard2 nextPeripheral) { - Queue eventList = new ConcurrentLinkedQueue<>(); - - getSubticks().forEach(keyboard -> { - eventList.addAll(keyboard.getDifference(nextPeripheral)); - }); - - return eventList; } - private char getOrDefault(Character charr){ + private char getOrMinChar(Character charr){ if(charr==null){ charr = Character.MIN_VALUE; } return charr; } + /** + * Calculates a list of {@link VirtualKeyboardEvent}s to the next peripheral, including + * the subticks. + * + * @see VirtualKeyboard2#getDifference(VirtualKeyboard2, Queue) + * + * @param nextKeyboard The peripheral that is comes after this one.
+ * If this one is loaded at tick 15, the nextPeripheral + * should be the one from tick 16 + * @param reference The queue to fill. Passed in by reference. + */ + public void getVirtualEvents(VirtualKeyboard2 nextKeyboard, Queue reference) { + getSubticks().forEach(keyboard -> { + keyboard.getDifference(nextKeyboard, reference); + }); + } + /** * Add a character to the {@link #charList}
* Null characters will be discarded; @@ -177,10 +189,12 @@ public void addChar(char character) { charList.add(character); } - public void clearCharList(){ + @Override + protected void clear(){ + super.clear(); charList.clear(); } - + @Override public String toString() { if (isParent()) { @@ -210,16 +224,17 @@ public VirtualKeyboard2 clone() { @Override - public void copyFrom(VirtualKeyboard2 keyboard) { - super.copyFrom(keyboard); - clearCharList(); + public void moveFrom(VirtualKeyboard2 keyboard) { + super.moveFrom(keyboard); + charList.clear(); charList.addAll(keyboard.charList); + keyboard.clear(); } public List getCharList() { return ImmutableList.copyOf(charList); } - + @Override public boolean equals(Object obj) { if(obj instanceof VirtualKeyboard2) { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java index 780ec7e2..9433ad21 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java @@ -4,7 +4,6 @@ import java.util.HashSet; import java.util.Queue; import java.util.Set; -import java.util.concurrent.ConcurrentLinkedQueue; import java.util.stream.Collectors; public class VirtualMouse2 extends VirtualPeripheral implements Serializable { @@ -55,9 +54,7 @@ protected void setPressed(int keycode, boolean keystate) { } } - @Override - protected Queue getDifference(VirtualMouse2 nextPeripheral) { - Queue eventList = new ConcurrentLinkedQueue<>(); + public void getDifference(VirtualMouse2 nextPeripheral, Queue reference) { int scrollWheelCopy = scrollWheel; Integer cursorXCopy = cursorX; @@ -74,7 +71,7 @@ protected Queue getDifference(VirtualMouse2 nextPeripheral) { */ for(int keycode : pressedKeys) { if (!nextPeripheral.getPressedKeys().contains(keycode)) { - eventList.add(new VirtualMouseEvent(keycode, false, scrollWheelCopy, cursorXCopy, cursorYCopy)); + reference.add(new VirtualMouseEvent(keycode, false, scrollWheelCopy, cursorXCopy, cursorYCopy)); scrollWheelCopy = 0; cursorXCopy = null; cursorYCopy = null; @@ -90,24 +87,31 @@ protected Queue getDifference(VirtualMouse2 nextPeripheral) { */ for(int keycode : nextPeripheral.getPressedKeys()) { if (!this.pressedKeys.contains(keycode)) { - eventList.add(new VirtualMouseEvent(keycode, true, scrollWheelCopy, cursorXCopy, cursorYCopy)); + reference.add(new VirtualMouseEvent(keycode, true, scrollWheelCopy, cursorXCopy, cursorYCopy)); } }; - - return eventList; } - @Override - protected Queue getVirtualEvents(VirtualMouse2 nextPeripheral) { - Queue eventList = new ConcurrentLinkedQueue<>(); - - getSubticks().forEach(keyboard -> { - eventList.addAll(keyboard.getDifference(nextPeripheral)); + public void getVirtualEvents(VirtualMouse2 nextPeripheral, Queue reference) { + getSubticks().forEach(mouse -> { + mouse.getDifference(nextPeripheral, reference); }); - - return eventList; } + @Override + protected void clear() { + super.clear(); + clearMouseData(); + + } + + private void clearMouseData() { + scrollWheel = 0; + cursorX = null; + cursorY = null; + } + + @Override public String toString() { if (isParent()) { @@ -126,11 +130,12 @@ public VirtualMouse2 clone() { } @Override - protected void copyFrom(VirtualMouse2 mouse) { - super.copyFrom(mouse); + protected void moveFrom(VirtualMouse2 mouse) { + super.moveFrom(mouse); this.scrollWheel = mouse.scrollWheel; this.cursorX = mouse.cursorX; this.cursorY = mouse.cursorY; + mouse.clear(); } @Override diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java index 29638684..98e8c71e 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java @@ -3,7 +3,6 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.List; -import java.util.Queue; import java.util.Set; import com.google.common.collect.ImmutableList; @@ -32,7 +31,7 @@ public abstract class VirtualPeripheral> implemen *
* If subtickKeyboards is null then the object is a "child"/subtickKeyboard stored in a parent list */ - private final List subtickList; + protected final List subtickList; /** * Create a peripheral with already existing pressed keys @@ -86,28 +85,6 @@ public List getCurrentPresses() { return out; } - /** - * Calculates the difference between 2 peripherals via symmetric difference
- * and returns a list of the changes between in form of {@link VirtualEvent}s - * - * @param nextPeripheral The peripheral that is comes after this one.
- * If this one is loaded at tick 15, the nextPeripheral - * should be the one from tick 16 - * @return A list of {@link VirtualEvent}s - */ - protected abstract Queue getDifference(T nextPeripheral); - - /** - * Calculates a list of {@link VirtualEvent}s to the next peripheral including - * the subticks. - * - * @param nextPeripheral The peripheral that is comes after this one.
- * If this one is loaded at tick 15, the nextPeripheral - * should be the one from tick 16 - * @return A list of {@link VirtualEvent}s - */ - protected abstract Queue getVirtualEvents(T nextPeripheral); - @Override public String toString() { return String.join(",", getCurrentPresses()); @@ -128,6 +105,19 @@ public boolean isParent() { return subtickList != null; } + public boolean isKeyDown(int keycode) { + return pressedKeys.contains(keycode); + } + + public boolean isKeyDown(String keyname) { + return pressedKeys.contains(VirtualKey2.getKeycode(keyname)); + } + + protected void clear() { + pressedKeys.clear(); + subtickList.clear(); + } + @Override public boolean equals(Object obj) { if(obj instanceof VirtualPeripheral) { @@ -143,10 +133,10 @@ public boolean equals(Object obj) { } /** - * Copies the data from another virtual peripheral into this peripheral without creating a new object. - * @param peripheral The peripheral to copy from + * Moves the data from another virtual peripheral into this peripheral without creating a new object. + * @param peripheral The peripheral to move from */ - protected void copyFrom(T peripheral) { + protected void moveFrom(T peripheral) { this.pressedKeys.clear(); this.pressedKeys.addAll(peripheral.pressedKeys); } diff --git a/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java b/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java index 4e70f304..6df1c2d3 100644 --- a/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java +++ b/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java @@ -1,15 +1,24 @@ package tasmod.virtual.keyboard; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.ConcurrentLinkedQueue; + +import org.junit.jupiter.api.Test; + import com.minecrafttas.tasmod.virtual.VirtualKey2; import com.minecrafttas.tasmod.virtual.VirtualKeyboard2; import com.minecrafttas.tasmod.virtual.VirtualKeyboardEvent; -import org.junit.jupiter.api.Test; - -import java.lang.reflect.Array; -import java.util.*; -import java.util.concurrent.ConcurrentLinkedQueue; - -import static org.junit.jupiter.api.Assertions.*; public class VirtualKeyboardTest { @@ -100,27 +109,13 @@ void testSetUnPressedByKeyname(){ * Test adding a character to the keyboard */ @Test - void addCharacter(){ + void testAddCharacter(){ VirtualKeyboard2 test = new VirtualKeyboard2(); test.addChar('w'); assertIterableEquals(Arrays.asList('w'), test.getCharList()); } - /** - * Test clearing all characters - */ - @Test - void clearCharacters(){ - List testCharList = new ArrayList<>(); - testCharList.add('w'); - testCharList.add('s'); - VirtualKeyboard2 test = new VirtualKeyboard2(new HashSet<>(), testCharList); - test.clearCharList(); - - assertTrue(test.getCharList().isEmpty()); - } - /** * Test the toString method without subticks */ @@ -209,32 +204,29 @@ void testClone() { } /** - * Test copy from method + * Test move from method */ @Test - void testCopyFrom(){ - Set testKeycodeSet = new HashSet<>(); - testKeycodeSet.add(VirtualKey2.W.getKeycode()); - testKeycodeSet.add(VirtualKey2.S.getKeycode()); - - List testCharList = new ArrayList<>(); - testCharList.add('w'); - testCharList.add('s'); - VirtualKeyboard2 copyFrom = new VirtualKeyboard2(testKeycodeSet, testCharList); - - Set testKeycodeSet2 = new HashSet<>(); - testKeycodeSet.add(VirtualKey2.A.getKeycode()); - testKeycodeSet.add(VirtualKey2.D.getKeycode()); - - List testCharList2 = new ArrayList<>(); - testCharList.add('a'); - testCharList.add('d'); - VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet2, testCharList2); - - test.copyFrom(copyFrom); - - assertIterableEquals(test.getPressedKeys(), copyFrom.getPressedKeys()); - assertIterableEquals(test.getCharList(), copyFrom.getCharList()); + void testMoveFrom(){ + VirtualKeyboard2 moveFrom = new VirtualKeyboard2(); + VirtualKeyboard2 actual = new VirtualKeyboard2(); + + moveFrom.update(VirtualKey2.W.getKeycode(), true, 'w'); + moveFrom.update(VirtualKey2.A.getKeycode(), true, 'a'); + + VirtualKeyboard2 expected = moveFrom.clone(); + + actual.update(VirtualKey2.S.getKeycode(), true, 's'); + actual.update(VirtualKey2.D.getKeycode(), true, 'd'); + + + actual.moveFrom(moveFrom); + + assertIterableEquals(expected.getPressedKeys(), actual.getPressedKeys()); + assertIterableEquals(expected.getCharList(), actual.getCharList()); + + assertEquals(new VirtualKeyboard2(), moveFrom); + assertTrue(moveFrom.getSubticks().isEmpty()); } /** @@ -247,8 +239,8 @@ void testUpdate(){ test.update(VirtualKey2.A.getKeycode(), true, 'A'); List expected = new ArrayList<>(); - expected.add(new VirtualKeyboard2(Set.of(VirtualKey2.W.getKeycode()), List.of('w'))); - expected.add(new VirtualKeyboard2(Set.of(VirtualKey2.W.getKeycode(), VirtualKey2.A.getKeycode()), List.of('w', 'A'))); + expected.add(new VirtualKeyboard2(new HashSet(Arrays.asList(VirtualKey2.W.getKeycode())), Arrays.asList('w'))); + expected.add(new VirtualKeyboard2(new HashSet(Arrays.asList(VirtualKey2.W.getKeycode(), VirtualKey2.A.getKeycode())), Arrays.asList('w', 'A'))); assertIterableEquals(expected, test.getSubticks()); } @@ -258,11 +250,11 @@ void testUpdate(){ */ @Test void testGetDifference(){ - VirtualKeyboard2 test = new VirtualKeyboard2(Set.of(VirtualKey2.W.getKeycode()), List.of('w')); - VirtualKeyboard2 test2 = new VirtualKeyboard2(Set.of(VirtualKey2.W.getKeycode(), VirtualKey2.S.getKeycode()), List.of('S')); - - Queue actual = test.getDifference(test2); - Queue expected = new ConcurrentLinkedQueue<>(List.of(new VirtualKeyboardEvent(VirtualKey2.S.getKeycode(), true, 'S'))); + VirtualKeyboard2 test = new VirtualKeyboard2(new HashSet<>(Arrays.asList(VirtualKey2.W.getKeycode())), Arrays.asList('w')); + VirtualKeyboard2 test2 = new VirtualKeyboard2(new HashSet<>(Arrays.asList(VirtualKey2.W.getKeycode(), VirtualKey2.S.getKeycode())), Arrays.asList('S')); + Queue actual = new ConcurrentLinkedQueue<>(); + test.getDifference(test2, actual); + Queue expected = new ConcurrentLinkedQueue<>(Arrays.asList(new VirtualKeyboardEvent(VirtualKey2.S.getKeycode(), true, 'S'))); assertIterableEquals(expected, actual); } From e70b8fe201ef284558878ed330ed99b7d5ae054e Mon Sep 17 00:00:00 2001 From: Scribble Date: Wed, 17 Jan 2024 13:35:32 +0100 Subject: [PATCH 12/57] [VirtualInput] Added inner classes for keyboard and mouse in VirtualInput - Added missing constructors and methods in Events and Mouse --- .../com/minecrafttas/tasmod/TASmodClient.java | 3 +- .../mixin/playbackhooks/MixinMinecraft.java | 4 +- .../tasmod/virtual/VirtualInput2.java | 217 +++++++++++++++--- .../tasmod/virtual/VirtualKeyboardEvent.java | 4 + .../tasmod/virtual/VirtualMouse2.java | 11 + .../tasmod/virtual/VirtualMouseEvent.java | 3 + 6 files changed, 204 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java index ab939a29..1e1e8eee 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java @@ -1,10 +1,10 @@ package com.minecrafttas.tasmod; -import com.minecrafttas.mctcommon.LanguageManager; import com.minecrafttas.mctcommon.Configuration; import com.minecrafttas.mctcommon.Configuration.ConfigOptions; import com.minecrafttas.mctcommon.KeybindManager; import com.minecrafttas.mctcommon.KeybindManager.Keybind; +import com.minecrafttas.mctcommon.LanguageManager; import com.minecrafttas.mctcommon.events.EventClient.EventClientInit; import com.minecrafttas.mctcommon.events.EventClient.EventOpenGui; import com.minecrafttas.mctcommon.events.EventClient.EventPlayerJoinedClientSide; @@ -28,6 +28,7 @@ import com.minecrafttas.tasmod.util.Scheduler; import com.minecrafttas.tasmod.util.ShieldDownloader; import com.minecrafttas.tasmod.virtual.VirtualInput; +import com.minecrafttas.tasmod.virtual.VirtualInput2; import com.minecrafttas.tasmod.virtual.VirtualKeybindings; import net.fabricmc.api.ClientModInitializer; import net.minecraft.client.Minecraft; diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java index c353a121..1045f46a 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java @@ -25,11 +25,13 @@ public class MixinMinecraft { private GuiScreen currentScreen; /** - * Runs every frame. Polls all the keys from LWJGL and updates {@link VirtualInput2} accordingly + * Runs every frame. + * @see VirtualInput2#update(GuiScreen) * @param ci CBI */ @Inject(method = "runGameLoop", at = @At(value = "HEAD")) public void playback_injectRunGameLoop(CallbackInfo ci) { +// TASmodClient.virtual.update(currentScreen); while (Keyboard.next()) { TASmodClient.virtual.updateNextKeyboard( Keyboard.getEventKey(), diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java index e0a279f5..f336c709 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java @@ -1,60 +1,205 @@ package com.minecrafttas.tasmod.virtual; +import com.minecrafttas.tasmod.mixin.playbackhooks.MixinMinecraft; +import com.minecrafttas.tasmod.util.Ducks; +import com.minecrafttas.tasmod.util.PointerNormalizer; +import net.minecraft.client.gui.GuiScreen; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; -import com.minecrafttas.tasmod.mixin.playbackhooks.MixinMinecraft; - +/** + * Main component for redirecting inputs.
+ *
+ * This class mimics the LWJGL classes {@link org.lwjgl.input.Keyboard} and {@link org.lwjgl.input.Mouse}.
+ *
+ */ public class VirtualInput2 { - - private VirtualKeyboard2 currentKeyboard; - private VirtualKeyboard2 nextKeyboard = new VirtualKeyboard2(); - private Queue keyboardEventQueue = new ConcurrentLinkedQueue(); - private VirtualKeyboardEvent currentKeyboardEvent; - - + private final VirtualKeyboardInput keyboardInput; + private final VirtualMouseInput mouseInput; + public VirtualInput2() { this(new VirtualKeyboard2(), new VirtualMouse2(), new VirtualCameraAngle(0, 0)); } - + public VirtualInput2(VirtualKeyboard2 preloadedKeyboard, VirtualMouse2 preloadedMouse, VirtualCameraAngle preloadedCamera) { - this.currentKeyboard = preloadedKeyboard; - this.currentMouse = preloadedMouse; + keyboardInput = new VirtualKeyboardInput(preloadedKeyboard); + mouseInput = new VirtualMouseInput(preloadedMouse); this.cameraAngle = preloadedCamera; } - - public void updateNextKeyboard(int keycode, boolean keystate, char character) { - nextKeyboard.update(keycode, keystate, character); - } - + /** - * Runs when the next keyboard tick is about to occur.
- * Used to load {@link #nextKeyboard} into {@link #currentKeyboard}, creating {@link VirtualKeyboardEvent}s in the process. - * @see MixinMinecraft#playback_injectRunTickKeyboard(org.spongepowered.asm.mixin.injection.callback.CallbackInfo) + * Updates the logic for {@link #keyboardInput}, {@link #mouseInput} and {@link #cameraAngle}
+ * Runs every frame + * @see MixinMinecraft#playback_injectRunGameLoop(CallbackInfo) + * @param currentScreen The current screen from Minecraft.class. + * Used for checking if the mouse logic should be adapted to GUIScreens */ - public void nextKeyboardTick() { - currentKeyboard.getVirtualEvents(nextKeyboard, keyboardEventQueue); - currentKeyboard.moveFrom(nextKeyboard); + public void update(GuiScreen currentScreen){ + while (Keyboard.next()) { + keyboardInput.updateNextKeyboard( + Keyboard.getEventKey(), + Keyboard.getEventKeyState(), + Keyboard.getEventCharacter()); + } + while (Mouse.next()) { + if(currentScreen == null) { + mouseInput.updateNextMouse( + Mouse.getEventButton(), + Mouse.getEventButtonState(), + Mouse.getEventDWheel(), + null, + null); + } else { + Ducks.GuiScreenDuck screen = (Ducks.GuiScreenDuck) currentScreen; + mouseInput.updateNextMouse( + Mouse.getEventButton(), + Mouse.getEventButtonState(), + Mouse.getEventDWheel(), + screen.calcX(Mouse.getEventX()), + screen.calcY(Mouse.getEventY())); + } + } } - - public boolean nextKeyboardSubtick() { - return (currentKeyboardEvent = keyboardEventQueue.poll()) != null; + + public VirtualKeyboardInput getKeyboardInput() { + return keyboardInput; } - public int getEventKeyboardKey() { - return currentKeyboardEvent.getKeyCode(); + public VirtualMouseInput getMouseInput() { + return mouseInput; } - public boolean getEventKeyboardState() { - return currentKeyboardEvent.isState(); + public VirtualCameraAngle getCameraAngle() { + return cameraAngle; } - public char getEventKeyboardCharacter() { - return currentKeyboardEvent.getCharacter(); + /** + * Subclass of {@link VirtualInput} handling keyboard logic.
+ *
+ * Vanilla keyboard handling looks something like this: + *
+	 *		public void runTickKeyboard()  { // Executed every tick in runTick()
+	 *			while({@linkplain Keyboard#next()}){		// Polls KeyEvents from the keyboard
+	 *				int keycode = {@linkplain Keyboard#getEventKey()};	// Get the keycode for this KeyEvent
+	 *				boolean keystate = {@linkplain Keyboard#getEventKey()};	// Get the keystate (true for pressed, false for unpressed) for this keycode
+	 *				char character = {@linkplain Keyboard#getEventCharacter()}	// Get the character associated with the keycode.
+	 *
+	 *				Keybindings.updateKeybind(keycode, keystate, character) // Update vanilla keybindings which then run the logic.
+	 *			}
+	 *		}
+	 * 
+ * After redirecting the calls in {@link MixinMinecraft}, the resulting logic now looks like this: + *
+	 *		public void runTickKeyboard()  {
+	 *			{@linkplain #nextKeyboardTick()}
+	 *			while({@linkplain #nextKeyboardSubtick()}){
+	 *				int keycode = {@linkplain #getEventKeyboardKey()}};
+	 *				boolean keystate = {@linkplain #getEventKeyboardState()};
+	 *				char character = {@linkplain #getEventKeyboardCharacter()}
+	 *
+	 *				Keybindings.updateKeybind(keycode, keystate, character)
+	 *			}
+	 *		}
+	 * 
+ * + */ + private static class VirtualKeyboardInput { + private final VirtualKeyboard2 currentKeyboard; + private final VirtualKeyboard2 nextKeyboard = new VirtualKeyboard2(); + private final Queue keyboardEventQueue = new ConcurrentLinkedQueue(); + private VirtualKeyboardEvent currentKeyboardEvent = new VirtualKeyboardEvent(); + + public VirtualKeyboardInput(){ + this(new VirtualKeyboard2()); + } + + public VirtualKeyboardInput(VirtualKeyboard2 preloadedKeyboard){ + currentKeyboard = preloadedKeyboard; + } + + public void updateNextKeyboard(int keycode, boolean keystate, char character) { + nextKeyboard.update(keycode, keystate, character); + } + + /** + * Runs when the next keyboard tick is about to occur.
+ * Used to load {@link #nextKeyboard} into {@link #currentKeyboard}, creating {@link VirtualKeyboardEvent}s in the process. + * @see MixinMinecraft#playback_injectRunTickKeyboard(org.spongepowered.asm.mixin.injection.callback.CallbackInfo) + */ + public void nextKeyboardTick() { + currentKeyboard.getVirtualEvents(nextKeyboard, keyboardEventQueue); + currentKeyboard.moveFrom(nextKeyboard); + } + + public boolean nextKeyboardSubtick() { + return (currentKeyboardEvent = keyboardEventQueue.poll()) != null; + } + + public int getEventKeyboardKey() { + return currentKeyboardEvent.getKeyCode(); + } + + public boolean getEventKeyboardState() { + return currentKeyboardEvent.isState(); + } + + public char getEventKeyboardCharacter() { + return currentKeyboardEvent.getCharacter(); + } + } + + private static class VirtualMouseInput { + private final VirtualMouse2 currentMouse; + private final VirtualMouse2 nextMouse = new VirtualMouse2(); + private final Queue mouseEventQueue = new ConcurrentLinkedQueue<>(); + private VirtualMouseEvent currentMouseEvent = new VirtualMouseEvent(); + + public VirtualMouseInput(){ + this(new VirtualMouse2()); + } + + public VirtualMouseInput(VirtualMouse2 preloadedMouse){ + currentMouse = preloadedMouse; + } + + public void updateNextMouse(int keycode, boolean keystate, int scrollwheel, Integer cursorX, Integer cursorY) { + nextMouse.update(keycode, keystate, scrollwheel, cursorX, cursorY); + } + + public void nextMouseTick() { + currentMouse.getVirtualEvents(nextMouse, mouseEventQueue); + currentMouse.moveFrom(nextMouse); + } + + public boolean nextMouseSubtick() { + return (currentMouseEvent = mouseEventQueue.poll()) != null; + } + + public int getEventMouseKey() { + return currentMouseEvent.getKeyCode(); + } + + public boolean getEventMouseState() { + return currentMouseEvent.isState(); + } + + public int getEventMouseScrollWheel() { + return currentMouseEvent.getScrollwheel(); + } + + public int getEventCursorX() { + return PointerNormalizer.getCoordsX(currentMouseEvent.getMouseX()); + } + + public int getEventCursorY() { + return PointerNormalizer.getCoordsY(currentMouseEvent.getMouseY()); + } + } - - private VirtualMouse2 currentMouse; - private VirtualMouse2 nextMouse = new VirtualMouse2(); - private Queue mouseEventQueue = new ConcurrentLinkedQueue(); + private VirtualCameraAngle cameraAngle; } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java index f6163982..cd66b1a5 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java @@ -5,6 +5,10 @@ public class VirtualKeyboardEvent extends VirtualButtonEvent { private final char character; + public VirtualKeyboardEvent(){ + this(0, false, Character.MIN_VALUE); + } + public VirtualKeyboardEvent(int keycode, boolean keystate, char character) { super(keycode, keystate); this.character = character; diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java index 9433ad21..38c0f738 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java @@ -47,6 +47,17 @@ public VirtualMouse2(Set pressedKeys, int scrollWheel, Integer cursorX, this.cursorY = cursorY; } + public void update(int keycode, boolean keystate, int scrollwheel, Integer cursorX, Integer cursorY) { + setPressed(keycode, keystate); + this.scrollWheel = scrollwheel; + this.cursorX = cursorX; + this.cursorY = cursorY; + + if(isParent()) { + addSubtick(clone()); + } + } + @Override protected void setPressed(int keycode, boolean keystate) { if (keycode < 0) { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java index ec01df06..c7581cf6 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java @@ -12,6 +12,9 @@ public class VirtualMouseEvent extends VirtualButtonEvent { private final Integer mouseX; private final Integer mouseY; + public VirtualMouseEvent(){ + this(0, false, 0, null, null); + } public VirtualMouseEvent(int keycode, boolean state, int scrollwheel, Integer mouseX, Integer mouseY) { super(keycode, state); this.scrollwheel = scrollwheel; From 98e0aae510a378a61099906096be142410b13563 Mon Sep 17 00:00:00 2001 From: Scribble Date: Wed, 17 Jan 2024 22:08:05 +0100 Subject: [PATCH 13/57] [VirtualInput] Documentation --- .../mixin/playbackhooks/MixinMinecraft.java | 5 +- .../tasmod/virtual/VirtualInput2.java | 80 ++++++++++++++----- .../tasmod/virtual/VirtualKeyboard2.java | 14 ++-- 3 files changed, 71 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java index 1045f46a..9929f356 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java @@ -61,7 +61,7 @@ public void playback_injectRunGameLoop(CallbackInfo ci) { } /** - * Run at the start of run tick keyboard. Runs every tick + * Run at the start of run tick keyboard. Runs every tick. * @param ci CBI */ @Inject(method = "runTickKeyboard", at = @At(value = "HEAD")) @@ -71,6 +71,7 @@ public void playback_injectRunTickKeyboard(CallbackInfo ci) { /** * Redirects a {@link Keyboard#next()}. Starts running every tick and continues as long as there are {@link VirtualKeyboardEvent}s in {@link VirtualInput} + * @see com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#nextKeyboardSubtick() * @return If {@link VirtualKeyboardEvent}s are present in {@link VirtualInput2} */ @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;next()Z", remap = false)) @@ -80,7 +81,7 @@ public boolean playback_redirectKeyboardNext() { /** * Runs everytime {@link #playback_redirectKeyboardNext()} has an event ready. Redirects {@link Keyboard#getEventKeyState()} - * @return The keycode for the current event in {@link VirtualInput2} + * @return The keycode for the current event in {@link VirtualInput2.VirtualKeyboardInput} */ @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKey()I", remap = false)) public int playback_redirectKeyboardGetEventKey() { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java index f336c709..69e9884c 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java @@ -25,6 +25,12 @@ public VirtualInput2() { this(new VirtualKeyboard2(), new VirtualMouse2(), new VirtualCameraAngle(0, 0)); } + /** + * Creates a virtual input with pre-loaded values + * @param preloadedKeyboard + * @param preloadedMouse + * @param preloadedCamera + */ public VirtualInput2(VirtualKeyboard2 preloadedKeyboard, VirtualMouse2 preloadedMouse, VirtualCameraAngle preloadedCamera) { keyboardInput = new VirtualKeyboardInput(preloadedKeyboard); mouseInput = new VirtualMouseInput(preloadedMouse); @@ -82,45 +88,67 @@ public VirtualCameraAngle getCameraAngle() { *
* Vanilla keyboard handling looks something like this: *
-	 *		public void runTickKeyboard()  { // Executed every tick in runTick()
-	 *			while({@linkplain Keyboard#next()}){		// Polls KeyEvents from the keyboard
-	 *				int keycode = {@linkplain Keyboard#getEventKey()};	// Get the keycode for this KeyEvent
-	 *				boolean keystate = {@linkplain Keyboard#getEventKey()};	// Get the keystate (true for pressed, false for unpressed) for this keycode
-	 *				char character = {@linkplain Keyboard#getEventCharacter()}	// Get the character associated with the keycode.
+	 *	public void runTickKeyboard()  { // Executed every tick in runTick()
+	 *		while({@linkplain Keyboard#next()}){
+	 *			int keycode = {@linkplain Keyboard#getEventKey()};
+	 *			boolean keystate = {@linkplain Keyboard#getEventKey()};
+	 *			char character = {@linkplain Keyboard#getEventCharacter()}
 	 *
-	 *				Keybindings.updateKeybind(keycode, keystate, character) // Update vanilla keybindings which then run the logic.
-	 *			}
+	 *			Keybindings.updateKeybind(keycode, keystate, character)
 	 *		}
+	 *	}
 	 * 
* After redirecting the calls in {@link MixinMinecraft}, the resulting logic now looks like this: *
-	 *		public void runTickKeyboard()  {
-	 *			{@linkplain #nextKeyboardTick()}
-	 *			while({@linkplain #nextKeyboardSubtick()}){
-	 *				int keycode = {@linkplain #getEventKeyboardKey()}};
-	 *				boolean keystate = {@linkplain #getEventKeyboardState()};
-	 *				char character = {@linkplain #getEventKeyboardCharacter()}
+	 *	public void runTickKeyboard()  {
+	 *		{@linkplain #nextKeyboardTick()}
+	 *		while({@linkplain #nextKeyboardSubtick()}){
+	 *			int keycode = {@linkplain #getEventKeyboardKey()}};
+	 *			boolean keystate = {@linkplain #getEventKeyboardState()};
+	 *			char character = {@linkplain #getEventKeyboardCharacter()}
 	 *
-	 *				Keybindings.updateKeybind(keycode, keystate, character)
-	 *			}
+	 *			Keybindings.updateKeybind(keycode, keystate, character)
 	 *		}
+	 *	}
 	 * 
* */ private static class VirtualKeyboardInput { + /** + * The keyboard "state" that is currently recognized by the game,
+ * meaning it is a direct copy of the vanilla keybindings. Updated every tick.
+ * Updated in {@link #nextKeyboardTick()} + */ private final VirtualKeyboard2 currentKeyboard; + /** + * The "state" of the real physical keyboard.
+ * This is updated every frame.
+ * Updates {@link #currentKeyboard} in {@link #nextKeyboardTick()} + */ private final VirtualKeyboard2 nextKeyboard = new VirtualKeyboard2(); + /** + * Queue for keyboard events.
+ * Is filled in {@link #nextKeyboardTick()} and read in {@link #nextKeyboardSubtick()} + */ private final Queue keyboardEventQueue = new ConcurrentLinkedQueue(); + /** + * The current keyboard event where the vanilla keybindings are reading from.
+ * Updated in {@link #nextKeyboardSubtick()} and read out in {@link #getEventKeyboardKey()}, {@link #getEventKeyboardState()} and {@link #getEventKeyboardCharacter()} + */ private VirtualKeyboardEvent currentKeyboardEvent = new VirtualKeyboardEvent(); - public VirtualKeyboardInput(){ - this(new VirtualKeyboard2()); - } public VirtualKeyboardInput(VirtualKeyboard2 preloadedKeyboard){ currentKeyboard = preloadedKeyboard; } + /** + * Updates the next keyboard + * @see VirtualInput2#update(GuiScreen) + * @param keycode The keycode of this event + * @param keystate The keystate of this event + * @param character The character of this event + */ public void updateNextKeyboard(int keycode, boolean keystate, char character) { nextKeyboard.update(keycode, keystate, character); } @@ -135,18 +163,32 @@ public void nextKeyboardTick() { currentKeyboard.moveFrom(nextKeyboard); } + /** + * Runs in a while loop. Used for updating {@link #currentKeyboardEvent} and ending the while loop. + * @see MixinMinecraft#playback_redirectKeyboardNext() + * @return If a keyboard event is in {@link #keyboardEventQueue} + */ public boolean nextKeyboardSubtick() { return (currentKeyboardEvent = keyboardEventQueue.poll()) != null; } - + + /** + * @return The keycode of {@link #currentKeyboardEvent} + */ public int getEventKeyboardKey() { return currentKeyboardEvent.getKeyCode(); } + /** + * @return The keystate of {@link #currentKeyboardEvent} + */ public boolean getEventKeyboardState() { return currentKeyboardEvent.isState(); } + /** + * @return The character(s) of {@link #currentKeyboardEvent} + */ public char getEventKeyboardCharacter() { return currentKeyboardEvent.getCharacter(); } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java index dfb705fd..ed149ed6 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java @@ -113,13 +113,13 @@ public void getDifference(VirtualKeyboard2 nextKeyboard, Queue { if (!nextKeyboard.getPressedKeys().contains(key)) { reference.add(new VirtualKeyboardEvent(key, false, Character.MIN_VALUE)); From d52021621418ad98ec840c72b6e7020b41764825 Mon Sep 17 00:00:00 2001 From: Scribble Date: Thu, 18 Jan 2024 22:30:50 +0100 Subject: [PATCH 14/57] [VirtualInput] Adding subtick ability to CameraAngle --- .../tasmod/virtual/VirtualCameraAngle2.java | 69 +++++++++++++++++++ .../tasmod/virtual/VirtualInput2.java | 1 + 2 files changed, 70 insertions(+) create mode 100644 src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle2.java diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle2.java new file mode 100644 index 00000000..a0bd06d4 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle2.java @@ -0,0 +1,69 @@ +package com.minecrafttas.tasmod.virtual; + +import java.io.Serializable; +import java.util.List; +import java.util.Queue; + +public class VirtualCameraAngle2 implements Serializable { + private Float pitch; + private Float yaw; + + private final List subtickList; + + public VirtualCameraAngle2() { + this(null, null); + } + + public VirtualCameraAngle2(Float pitch, Float yaw) { + this(pitch, yaw, null); + } + + public VirtualCameraAngle2(Float pitch, Float yaw, List subtickList) { + this.pitch = pitch; + this.yaw = yaw; + this.subtickList = subtickList; + } + + public void update(Float pitch, Float yaw) { + this.pitch = pitch; + this.yaw = yaw; + if(isParent()) { + subtickList.add(clone()); + } + } + + public Float getPitch() { + return pitch; + } + + public Float getYaw() { + return yaw; + } + + public boolean isParent() { + return subtickList != null; + } + + public void getCameraAngleSubticks(Queue reference) { + reference.addAll(subtickList); + } + + @Override + public VirtualCameraAngle2 clone() { + return new VirtualCameraAngle2(pitch, yaw); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof VirtualCameraAngle2) { + VirtualCameraAngle2 angle = (VirtualCameraAngle2) obj; + return pitch == angle.pitch && yaw == angle.yaw; + } + return super.equals(obj); + } + + @Override + public String toString() { + return String.format("%s;%s", pitch, yaw); + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java index 69e9884c..ab343ef2 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java @@ -244,4 +244,5 @@ public int getEventCursorY() { } private VirtualCameraAngle cameraAngle; + } From 0c6a116dcd5d82659e7a82da42ecba95503669a1 Mon Sep 17 00:00:00 2001 From: Scribble Date: Fri, 19 Jan 2024 19:03:12 +0100 Subject: [PATCH 15/57] [VirtualInput] Created VirtualCameraAngleInput --- .../mixin/playbackhooks/MixinMinecraft.java | 47 ++++----- .../tasmod/virtual/VirtualCameraAngle2.java | 4 +- .../tasmod/virtual/VirtualInput2.java | 95 +++++++++++-------- .../tasmod/virtual/VirtualKeyboard2.java | 12 ++- .../tasmod/virtual/VirtualMouse2.java | 8 +- 5 files changed, 93 insertions(+), 73 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java index 9929f356..31fe25c3 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java @@ -88,15 +88,6 @@ public int playback_redirectKeyboardGetEventKey() { return TASmodClient.virtual.getEventKeyboardKey(); } - /** - * Runs everytime {@link #playback_redirectKeyboardNext()} has an event ready. Redirects {@link Keyboard#getEventCharacter()} - * @return The character for the current event in {@link VirtualInput2} - */ - @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventCharacter()C", remap = false)) - public char playback_redirectKeyboardGetEventCharacter() { - return TASmodClient.virtual.getEventKeyboardCharacter(); - } - /** * Runs everytime {@link #playback_redirectKeyboardNext()} has an event ready. Redirects {@link Keyboard#getEventKeyState()} * @return Whether the key is down in {@link VirtualInput2} @@ -106,6 +97,15 @@ public boolean playback_redirectGetEventState() { return TASmodClient.virtual.getEventKeyboardState(); } + /** + * Runs everytime {@link #playback_redirectKeyboardNext()} has an event ready. Redirects {@link Keyboard#getEventCharacter()} + * @return The character for the current event in {@link VirtualInput2} + */ + @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventCharacter()C", remap = false)) + public char playback_redirectKeyboardGetEventCharacter() { + return TASmodClient.virtual.getEventKeyboardCharacter(); + } + /** * Runs everytime {@link #playback_redirectKeyboardNext()} has an event ready. Redirects {@link Keyboard#isKeyDown(int)} * @return Whether the key is down in {@link VirtualInput2} @@ -115,6 +115,21 @@ public boolean playback_redirectIsKeyDown(int keyCode) { return TASmodClient.virtual.isKeyDown(keyCode); } + @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKey()I", remap = false)) + public int playback_redirectGetEventKeyDPK() { + return TASmodClient.virtual.getEventKeyboardKey(); + } + + @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKeyState()Z", remap = false)) + public boolean playback_redirectGetEventKeyStateDPK() { + return TASmodClient.virtual.getEventKeyboardState(); + } + + @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventCharacter()C", remap = false)) + public char playback_redirectGetEventCharacterDPK() { + return TASmodClient.virtual.getEventKeyboardCharacter(); + } + // ============================ Mouse @Inject(method = "runTickMouse", at = @At(value = "HEAD")) @@ -146,18 +161,4 @@ public int playback_redirectGetEventDWheel() { return TASmodClient.virtual.getEventMouseScrollWheel(); } - @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKey()I", remap = false)) - public int playback_redirectGetEventKeyDPK() { - return TASmodClient.virtual.getEventKeyboardKey(); - } - - @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventCharacter()C", remap = false)) - public char playback_redirectGetEventCharacterDPK() { - return TASmodClient.virtual.getEventKeyboardCharacter(); - } - - @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKeyState()Z", remap = false)) - public boolean playback_redirectGetEventKeyStateDPK() { - return TASmodClient.virtual.getEventKeyboardState(); - } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle2.java index a0bd06d4..94cbb38d 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle2.java @@ -45,7 +45,9 @@ public boolean isParent() { } public void getCameraAngleSubticks(Queue reference) { - reference.addAll(subtickList); + if(isParent()) { + reference.addAll(subtickList); + } } @Override diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java index ab343ef2..420e2406 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java @@ -14,12 +14,14 @@ /** * Main component for redirecting inputs.
*
- * This class mimics the LWJGL classes {@link org.lwjgl.input.Keyboard} and {@link org.lwjgl.input.Mouse}.
+ * This class mimics the LWJGL classes {@link org.lwjgl.input.Keyboard} and + * {@link org.lwjgl.input.Mouse}.
*
*/ public class VirtualInput2 { private final VirtualKeyboardInput keyboardInput; private final VirtualMouseInput mouseInput; + private final VirtualCameraAngleInput cameraAngleInput; public VirtualInput2() { this(new VirtualKeyboard2(), new VirtualMouse2(), new VirtualCameraAngle(0, 0)); @@ -27,6 +29,7 @@ public VirtualInput2() { /** * Creates a virtual input with pre-loaded values + * * @param preloadedKeyboard * @param preloadedMouse * @param preloadedCamera @@ -34,39 +37,29 @@ public VirtualInput2() { public VirtualInput2(VirtualKeyboard2 preloadedKeyboard, VirtualMouse2 preloadedMouse, VirtualCameraAngle preloadedCamera) { keyboardInput = new VirtualKeyboardInput(preloadedKeyboard); mouseInput = new VirtualMouseInput(preloadedMouse); - this.cameraAngle = preloadedCamera; + cameraAngleInput = new VirtualCameraAngleInput(preloadedCamera); } /** - * Updates the logic for {@link #keyboardInput}, {@link #mouseInput} and {@link #cameraAngle}
+ * Updates the logic for {@link #keyboardInput}, {@link #mouseInput} and + * {@link #cameraAngle}
* Runs every frame + * * @see MixinMinecraft#playback_injectRunGameLoop(CallbackInfo) - * @param currentScreen The current screen from Minecraft.class. - * Used for checking if the mouse logic should be adapted to GUIScreens + * @param currentScreen The current screen from Minecraft.class. Used for + * checking if the mouse logic should be adapted to + * GUIScreens */ - public void update(GuiScreen currentScreen){ + public void update(GuiScreen currentScreen) { while (Keyboard.next()) { - keyboardInput.updateNextKeyboard( - Keyboard.getEventKey(), - Keyboard.getEventKeyState(), - Keyboard.getEventCharacter()); + keyboardInput.updateNextKeyboard(Keyboard.getEventKey(), Keyboard.getEventKeyState(), Keyboard.getEventCharacter()); } while (Mouse.next()) { - if(currentScreen == null) { - mouseInput.updateNextMouse( - Mouse.getEventButton(), - Mouse.getEventButtonState(), - Mouse.getEventDWheel(), - null, - null); + if (currentScreen == null) { + mouseInput.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), null, null); } else { Ducks.GuiScreenDuck screen = (Ducks.GuiScreenDuck) currentScreen; - mouseInput.updateNextMouse( - Mouse.getEventButton(), - Mouse.getEventButtonState(), - Mouse.getEventDWheel(), - screen.calcX(Mouse.getEventX()), - screen.calcY(Mouse.getEventY())); + mouseInput.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), screen.calcX(Mouse.getEventX()), screen.calcY(Mouse.getEventY())); } } } @@ -79,14 +72,15 @@ public VirtualMouseInput getMouseInput() { return mouseInput; } - public VirtualCameraAngle getCameraAngle() { - return cameraAngle; + public VirtualCameraAngleInput getCameraAngle() { + return cameraAngleInput; } /** * Subclass of {@link VirtualInput} handling keyboard logic.
*
* Vanilla keyboard handling looks something like this: + * *
 	 *	public void runTickKeyboard()  { // Executed every tick in runTick()
 	 *		while({@linkplain Keyboard#next()}){
@@ -98,7 +92,10 @@ public VirtualCameraAngle getCameraAngle() {
 	 *		}
 	 *	}
 	 * 
- * After redirecting the calls in {@link MixinMinecraft}, the resulting logic now looks like this: + * + * After redirecting the calls in {@link MixinMinecraft}, the resulting logic + * now looks like this: + * *
 	 *	public void runTickKeyboard()  {
 	 *		{@linkplain #nextKeyboardTick()}
@@ -116,7 +113,8 @@ public VirtualCameraAngle getCameraAngle() {
 	private static class VirtualKeyboardInput {
 		/**
 		 * The keyboard "state" that is currently recognized by the game,
- * meaning it is a direct copy of the vanilla keybindings. Updated every tick.
+ * meaning it is a direct copy of the vanilla keybindings. Updated every + * tick.
* Updated in {@link #nextKeyboardTick()} */ private final VirtualKeyboard2 currentKeyboard; @@ -128,25 +126,29 @@ private static class VirtualKeyboardInput { private final VirtualKeyboard2 nextKeyboard = new VirtualKeyboard2(); /** * Queue for keyboard events.
- * Is filled in {@link #nextKeyboardTick()} and read in {@link #nextKeyboardSubtick()} + * Is filled in {@link #nextKeyboardTick()} and read in + * {@link #nextKeyboardSubtick()} */ private final Queue keyboardEventQueue = new ConcurrentLinkedQueue(); /** - * The current keyboard event where the vanilla keybindings are reading from.
- * Updated in {@link #nextKeyboardSubtick()} and read out in {@link #getEventKeyboardKey()}, {@link #getEventKeyboardState()} and {@link #getEventKeyboardCharacter()} + * The current keyboard event where the vanilla keybindings are reading + * from.
+ * Updated in {@link #nextKeyboardSubtick()} and read out in + * {@link #getEventKeyboardKey()}, {@link #getEventKeyboardState()} and + * {@link #getEventKeyboardCharacter()} */ private VirtualKeyboardEvent currentKeyboardEvent = new VirtualKeyboardEvent(); - - public VirtualKeyboardInput(VirtualKeyboard2 preloadedKeyboard){ + public VirtualKeyboardInput(VirtualKeyboard2 preloadedKeyboard) { currentKeyboard = preloadedKeyboard; } /** * Updates the next keyboard + * * @see VirtualInput2#update(GuiScreen) - * @param keycode The keycode of this event - * @param keystate The keystate of this event + * @param keycode The keycode of this event + * @param keystate The keystate of this event * @param character The character of this event */ public void updateNextKeyboard(int keycode, boolean keystate, char character) { @@ -155,7 +157,9 @@ public void updateNextKeyboard(int keycode, boolean keystate, char character) { /** * Runs when the next keyboard tick is about to occur.
- * Used to load {@link #nextKeyboard} into {@link #currentKeyboard}, creating {@link VirtualKeyboardEvent}s in the process. + * Used to load {@link #nextKeyboard} into {@link #currentKeyboard}, creating + * {@link VirtualKeyboardEvent}s in the process. + * * @see MixinMinecraft#playback_injectRunTickKeyboard(org.spongepowered.asm.mixin.injection.callback.CallbackInfo) */ public void nextKeyboardTick() { @@ -164,14 +168,16 @@ public void nextKeyboardTick() { } /** - * Runs in a while loop. Used for updating {@link #currentKeyboardEvent} and ending the while loop. + * Runs in a while loop. Used for updating {@link #currentKeyboardEvent} and + * ending the while loop. + * * @see MixinMinecraft#playback_redirectKeyboardNext() * @return If a keyboard event is in {@link #keyboardEventQueue} */ public boolean nextKeyboardSubtick() { return (currentKeyboardEvent = keyboardEventQueue.poll()) != null; } - + /** * @return The keycode of {@link #currentKeyboardEvent} */ @@ -200,11 +206,11 @@ private static class VirtualMouseInput { private final Queue mouseEventQueue = new ConcurrentLinkedQueue<>(); private VirtualMouseEvent currentMouseEvent = new VirtualMouseEvent(); - public VirtualMouseInput(){ + public VirtualMouseInput() { this(new VirtualMouse2()); } - public VirtualMouseInput(VirtualMouse2 preloadedMouse){ + public VirtualMouseInput(VirtualMouse2 preloadedMouse) { currentMouse = preloadedMouse; } @@ -243,6 +249,13 @@ public int getEventCursorY() { } - private VirtualCameraAngle cameraAngle; - + private static class VirtualCameraAngleInput { + + private VirtualCameraAngle cameraAngle; + + public VirtualCameraAngleInput(VirtualCameraAngle preloadedCamera) { + cameraAngle = preloadedCamera; + } + + } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java index ed149ed6..dbd30500 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java @@ -173,11 +173,13 @@ private char getOrMinChar(Character charr){ * should be the one from tick 16 * @param reference The queue to fill. Passed in by reference. */ - public void getVirtualEvents(VirtualKeyboard2 nextKeyboard, Queue reference) { - getSubticks().forEach(keyboard -> { - keyboard.getDifference(nextKeyboard, reference); - }); - } + public void getVirtualEvents(VirtualKeyboard2 nextKeyboard, Queue reference) { + if (isParent()) { + getSubticks().forEach(keyboard -> { + keyboard.getDifference(nextKeyboard, reference); + }); + } + } /** * Add a character to the {@link #charList}
diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java index 38c0f738..bbf163b8 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java @@ -104,9 +104,11 @@ public void getDifference(VirtualMouse2 nextPeripheral, Queue } public void getVirtualEvents(VirtualMouse2 nextPeripheral, Queue reference) { - getSubticks().forEach(mouse -> { - mouse.getDifference(nextPeripheral, reference); - }); + if(isParent()) { + getSubticks().forEach(mouse -> { + mouse.getDifference(nextPeripheral, reference); + }); + } } @Override From f5686e96fa21c69d75477b8b73b618eb5917ef49 Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 22 Jan 2024 20:48:17 +0100 Subject: [PATCH 16/57] [VirtualInput] Revert subticks for VirtualCameraAngle - Does not make sense if the camera is capped at 20 tps... --- .../tasmod/handlers/InterpolationHandler.java | 1 - .../mixin/playbackhooks/MixinMinecraft.java | 2 ++ .../tasmod/virtual/VirtualCameraAngle2.java | 21 ------------------- .../tasmod/virtual/VirtualInput2.java | 20 ++++++++++++++---- 4 files changed, 18 insertions(+), 26 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/handlers/InterpolationHandler.java b/src/main/java/com/minecrafttas/tasmod/handlers/InterpolationHandler.java index a7a86d4e..b2f08eac 100644 --- a/src/main/java/com/minecrafttas/tasmod/handlers/InterpolationHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/handlers/InterpolationHandler.java @@ -1,7 +1,6 @@ package com.minecrafttas.tasmod.handlers; import com.minecrafttas.mctcommon.events.EventClient.EventCamera; -import com.minecrafttas.mctcommon.events.EventClient.EventCamera.CameraData; import com.minecrafttas.tasmod.TASmodClient; import com.minecrafttas.tasmod.playback.ControlByteHandler; import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TickInputContainer; diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java index 31fe25c3..f3c46a63 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java @@ -161,4 +161,6 @@ public int playback_redirectGetEventDWheel() { return TASmodClient.virtual.getEventMouseScrollWheel(); } + // ============================ Camera Angle + } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle2.java index 94cbb38d..bd19eb24 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle2.java @@ -1,35 +1,24 @@ package com.minecrafttas.tasmod.virtual; import java.io.Serializable; -import java.util.List; -import java.util.Queue; public class VirtualCameraAngle2 implements Serializable { private Float pitch; private Float yaw; - private final List subtickList; public VirtualCameraAngle2() { this(null, null); } public VirtualCameraAngle2(Float pitch, Float yaw) { - this(pitch, yaw, null); - } - - public VirtualCameraAngle2(Float pitch, Float yaw, List subtickList) { this.pitch = pitch; this.yaw = yaw; - this.subtickList = subtickList; } public void update(Float pitch, Float yaw) { this.pitch = pitch; this.yaw = yaw; - if(isParent()) { - subtickList.add(clone()); - } } public Float getPitch() { @@ -40,16 +29,6 @@ public Float getYaw() { return yaw; } - public boolean isParent() { - return subtickList != null; - } - - public void getCameraAngleSubticks(Queue reference) { - if(isParent()) { - reference.addAll(subtickList); - } - } - @Override public VirtualCameraAngle2 clone() { return new VirtualCameraAngle2(pitch, yaw); diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java index 420e2406..dd2b5655 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java @@ -24,7 +24,7 @@ public class VirtualInput2 { private final VirtualCameraAngleInput cameraAngleInput; public VirtualInput2() { - this(new VirtualKeyboard2(), new VirtualMouse2(), new VirtualCameraAngle(0, 0)); + this(new VirtualKeyboard2(), new VirtualMouse2(), new VirtualCameraAngle2()); } /** @@ -34,7 +34,7 @@ public VirtualInput2() { * @param preloadedMouse * @param preloadedCamera */ - public VirtualInput2(VirtualKeyboard2 preloadedKeyboard, VirtualMouse2 preloadedMouse, VirtualCameraAngle preloadedCamera) { + public VirtualInput2(VirtualKeyboard2 preloadedKeyboard, VirtualMouse2 preloadedMouse, VirtualCameraAngle2 preloadedCamera) { keyboardInput = new VirtualKeyboardInput(preloadedKeyboard); mouseInput = new VirtualMouseInput(preloadedMouse); cameraAngleInput = new VirtualCameraAngleInput(preloadedCamera); @@ -251,11 +251,23 @@ public int getEventCursorY() { private static class VirtualCameraAngleInput { - private VirtualCameraAngle cameraAngle; + private VirtualCameraAngle2 cameraAngle; - public VirtualCameraAngleInput(VirtualCameraAngle preloadedCamera) { + public VirtualCameraAngleInput(VirtualCameraAngle2 preloadedCamera) { cameraAngle = preloadedCamera; } + + public void updateCameraAngle(float pitch, float yaw) { + cameraAngle.update(pitch, yaw); + } + + public float getPitch() { + return cameraAngle.getPitch(); + } + + public float getYaw() { + return cameraAngle.getYaw(); + } } } From 75406a80cd8202258e4bf1e7bff2afd858fed7c5 Mon Sep 17 00:00:00 2001 From: Scribble Date: Fri, 26 Jan 2024 22:22:01 +0100 Subject: [PATCH 17/57] [VirtualInput] Switched to new VirtualInput - Removed getters in VirtualInput and replaced them with public final variables for better readybility - Removed InputContainerView - Added isKeyDown() and willKeyBeDown() to VirtualInput --- .../com/minecrafttas/tasmod/TASmodClient.java | 29 ++- .../externalGui/InputContainerView.java | 187 ------------------ .../com/minecrafttas/tasmod/gui/InfoHud.java | 54 ++--- .../tasmod/mixin/MixinEntityRenderer.java | 6 +- .../tasmod/mixin/MixinGuiScreen.java | 24 +-- .../tasmod/mixin/MixinMinecraft.java | 1 - .../mixin/fixes/MixinMinecraftFullscreen.java | 4 +- .../mixin/playbackhooks/MixinGuiChat.java | 2 +- ...uiClickableScrolledSelectionListProxy.java | 2 +- .../MixinGuiContainerCreative.java | 4 +- .../mixin/playbackhooks/MixinGuiSlot.java | 6 +- .../mixin/playbackhooks/MixinMinecraft.java | 60 ++---- .../playback/PlaybackControllerClient.java | 42 ++-- .../savestates/SavestateHandlerClient.java | 2 +- .../tasmod/virtual/VirtualInput.java | 1 + .../tasmod/virtual/VirtualInput2.java | 69 ++++--- 16 files changed, 150 insertions(+), 343 deletions(-) delete mode 100644 src/main/java/com/minecrafttas/tasmod/externalGui/InputContainerView.java diff --git a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java index 1e1e8eee..0b87ef7b 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java @@ -1,5 +1,15 @@ package com.minecrafttas.tasmod; +import static com.minecrafttas.tasmod.TASmod.LOGGER; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.logging.log4j.Level; +import org.lwjgl.input.Keyboard; + import com.minecrafttas.mctcommon.Configuration; import com.minecrafttas.mctcommon.Configuration.ConfigOptions; import com.minecrafttas.mctcommon.KeybindManager; @@ -12,7 +22,6 @@ import com.minecrafttas.mctcommon.server.Client; import com.minecrafttas.mctcommon.server.PacketHandlerRegistry; import com.minecrafttas.mctcommon.server.Server; -import com.minecrafttas.tasmod.externalGui.InputContainerView; import com.minecrafttas.tasmod.gui.InfoHud; import com.minecrafttas.tasmod.handlers.InterpolationHandler; import com.minecrafttas.tasmod.handlers.LoadingScreenHandler; @@ -27,9 +36,9 @@ import com.minecrafttas.tasmod.util.LoggerMarkers; import com.minecrafttas.tasmod.util.Scheduler; import com.minecrafttas.tasmod.util.ShieldDownloader; -import com.minecrafttas.tasmod.virtual.VirtualInput; import com.minecrafttas.tasmod.virtual.VirtualInput2; import com.minecrafttas.tasmod.virtual.VirtualKeybindings; + import net.fabricmc.api.ClientModInitializer; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; @@ -39,20 +48,11 @@ import net.minecraft.client.multiplayer.ServerData; import net.minecraft.client.settings.KeyBinding; import net.minecraft.server.MinecraftServer; -import org.apache.logging.log4j.Level; -import org.lwjgl.input.Keyboard; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import static com.minecrafttas.tasmod.TASmod.LOGGER; public class TASmodClient implements ClientModInitializer, EventClientInit, EventPlayerJoinedClientSide, EventOpenGui{ - public static VirtualInput virtual; + public static VirtualInput2 virtual; public static TickSyncClient ticksyncClient; @@ -126,7 +126,7 @@ public void onInitializeClient() { } else { config.reset(ConfigOptions.FileToOpen); } - virtual=new VirtualInput(fileOnStart); +// virtual=new VirtualInput2(fileOnStart); TODO Move fileOnStart to PlaybackController // Initialize InfoHud hud = new InfoHud(); @@ -147,7 +147,7 @@ protected boolean isKeyDown(KeyBinding i) { // Register event listeners EventListenerRegistry.register(this); - EventListenerRegistry.register(virtual); +// EventListenerRegistry.register(virtual); TODO Remove if unnecessary EventListenerRegistry.register(hud); EventListenerRegistry.register(shieldDownloader); EventListenerRegistry.register(loadingScreenHandler); @@ -199,7 +199,6 @@ public void onClientInit(Minecraft mc) { } }))); blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Open InfoGui Editor", "TASmod", Keyboard.KEY_F6, () -> Minecraft.getMinecraft().displayGuiScreen(TASmodClient.hud)))); - blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Buffer View", "TASmod", Keyboard.KEY_NUMPAD0, () -> InputContainerView.startBufferView()))); blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Various Testing", "TASmod", Keyboard.KEY_F12, () -> { TASmodClient.client.disconnect(); }))); diff --git a/src/main/java/com/minecrafttas/tasmod/externalGui/InputContainerView.java b/src/main/java/com/minecrafttas/tasmod/externalGui/InputContainerView.java deleted file mode 100644 index c5677b09..00000000 --- a/src/main/java/com/minecrafttas/tasmod/externalGui/InputContainerView.java +++ /dev/null @@ -1,187 +0,0 @@ -package com.minecrafttas.tasmod.externalGui; - -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.EventQueue; -import java.awt.Font; -import java.awt.Rectangle; -import java.awt.Toolkit; -import java.util.Vector; - -import javax.swing.JFrame; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTable; -import javax.swing.UIManager; -import javax.swing.border.EmptyBorder; -import javax.swing.table.DefaultTableModel; - -import com.minecrafttas.mctcommon.events.EventClient.EventClientTick; -import com.minecrafttas.tasmod.TASmodClient; -import com.minecrafttas.tasmod.playback.PlaybackControllerClient; -import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TickInputContainer; -import com.minecrafttas.tasmod.virtual.VirtualInput; - -import net.minecraft.client.Minecraft; - -@Deprecated -public class InputContainerView extends JFrame implements EventClientTick{ - - private static final long serialVersionUID = -1823965270972132025L; - private JPanel contentPane; - private static JTable table; - private static DefaultTableModel model; - private static int prevCount = 0; - - /** - * Launch the application. - */ - public static void main(String[] args) { - EventQueue.invokeLater(new Runnable() { - public void run() { - try { - InputContainerView frame = new InputContainerView(); - frame.setVisible(true); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - } - - /** - * Create the frame. - */ - public InputContainerView() { - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (Exception e) { - } - setIconImage(Toolkit.getDefaultToolkit() - .getImage(InputContainerView.class.getResource("/assets/tasmod/textures/potion2.png"))); - setBackground(Color.WHITE); - setTitle("InputContainer View"); - setFont(new Font("Arial", Font.PLAIN, 12)); - setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - setBounds(100, 100, 673, 448); - contentPane = new JPanel(); - contentPane.setBackground(Color.WHITE); - contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); - contentPane.setLayout(new BorderLayout(0, 0)); - setContentPane(contentPane); - - JScrollPane scrollPane = new JScrollPane(); - contentPane.add(scrollPane, BorderLayout.CENTER); - - Vector title = new Vector(); - title.add("Ticks"); - title.add("Keyboard"); - title.add("Mouse"); - title.add("CameraX"); - title.add("CameraY"); - - model = new DefaultTableModel(title, 0); - - table = new JTable(model); - table.getColumnModel().getColumn(0).setPreferredWidth(5); - table.setBackground(Color.DARK_GRAY); - table.setForeground(Color.LIGHT_GRAY); - scrollPane.setViewportView(table); - - contentPane.add(table.getTableHeader(), BorderLayout.PAGE_START); - - } - -// private static void addEmptyRow() { -// addRow(0, "", "", 0F, 0F); -// } - - private static void addRow(int ticks, String keyboard, String mouse, float cameraX, float cameraY) { - Vector row = new Vector(5); - row.add(ticks); - row.add(keyboard); - row.add(mouse); - row.add(cameraX); - row.add(cameraY); - model.addRow(row); - } - - private static void selectRow(int ticks) { - if (ticks >= table.getRowCount()) { - ticks = table.getRowCount() - 1; - } - table.setRowSelectionInterval(ticks, ticks); - table.scrollRectToVisible(new Rectangle(table.getCellRect(ticks, 0, true))); - } - - public static void update(VirtualInput input) { - if (model == null) { - return; - } - PlaybackControllerClient controller = TASmodClient.controller; - if (controller == null || controller.isEmpty()) { - return; - } - if (prevCount != controller.size()) { - prevCount = controller.size(); - model.getDataVector().clear(); - - for (int i = 0; i < controller.size(); i++) { - TickInputContainer tickContainer = controller.get(i); - addRow(i + 1, tickContainer.getKeyboard().toString(), tickContainer.getMouse().toString(), - tickContainer.getSubticks().getPitch(), tickContainer.getSubticks().getYaw()); - } - selectRow(controller.index()); - } - if (!controller.isNothingPlaying()) { - selectRow(controller.index()); - } - -// selectRow(container.index()+1); -// input.getAllInputEvents().forEach(inputsevents->{ -// Vector row=new Vector(4); -// row.add(inputsevents.tick); -// -// String kbs=""; -// int count=0; -// for (VirtualKeyboardEvent keyb:inputsevents.keyboardevent) { -// kbs=kbs.concat("["+count+"]{"+keyb.toString()+"} "); -// count++; -// } -// -// row.add(kbs); -// -// count=0; -// String mbe=""; -// for (VirtualMouseEvent mouseb:inputsevents.mouseEvent) { -// mbe=mbe.concat("["+count+"]{"+mouseb.toString()+"} "); -// count++; -// } -// row.add(mbe); -// -// row.add(inputsevents.subticks.toString().replace("Camera:", "")); -// model.addRow(row); -// }); - - } - - public static void startBufferView() { - EventQueue.invokeLater(new Runnable() { - - @Override - public void run() { - try { - InputContainerView frame = new InputContainerView(); - frame.setVisible(true); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - } - - @Override - public void onClientTick(Minecraft mc) { - update(TASmodClient.virtual); - } -} diff --git a/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java b/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java index 0183348e..f948bf5b 100644 --- a/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java +++ b/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java @@ -343,13 +343,13 @@ public boolean checkInit() { } })); - title = "cursor"; - y += 14; - if (configuration.getProperty(title + "_x", "err").equals("err")) setDefaults(title, y); - lists.add(new InfoLabel(title, Integer.parseInt(configuration.getProperty(title + "_x")), Integer.parseInt(configuration.getProperty(title + "_y")), Boolean.parseBoolean(configuration.getProperty(title + "_visible")), Boolean.parseBoolean(configuration.getProperty(title + "_rect")), () -> { - if (Minecraft.getMinecraft().currentScreen == this) return "Mouse Position"; - return String.format("Mouse Cursor: " + TASmodClient.virtual.getNextMouse().getPath().get(0).cursorX + " " + TASmodClient.virtual.getNextMouse().getPath().get(0).cursorY); - })); +// title = "cursor"; +// y += 14; +// if (configuration.getProperty(title + "_x", "err").equals("err")) setDefaults(title, y); +// lists.add(new InfoLabel(title, Integer.parseInt(configuration.getProperty(title + "_x")), Integer.parseInt(configuration.getProperty(title + "_y")), Boolean.parseBoolean(configuration.getProperty(title + "_visible")), Boolean.parseBoolean(configuration.getProperty(title + "_rect")), () -> { +// if (Minecraft.getMinecraft().currentScreen == this) return "Mouse Position"; +// return String.format("Mouse Cursor: " + TASmodClient.virtual.getNextMouse().getPath().get(0).cursorX + " " + TASmodClient.virtual.getNextMouse().getPath().get(0).cursorY); +// })); TODO Remove? title = "trajectories"; y += 14; @@ -490,26 +490,26 @@ private void drawRectWithText(String text, int x, int y, boolean rect) { } private String keystrokes() { - if (Display.isActive()) { - String out1 = ""+ChatFormatting.WHITE; - for (String mouse : TASmodClient.virtual.getCurrentMousePresses()) { - out1 = out1.concat(mouse + " "); - } - out1=out1.concat(""+ChatFormatting.GREEN); - for (String mouse : TASmodClient.virtual.getNextMousePresses()) { - out1 = out1.concat(mouse + " "); - } - - String out2 = ""+ChatFormatting.WHITE; - for (String key : TASmodClient.virtual.getCurrentKeyboardPresses()) { - out2 = out2.concat(key + " "); - } - out2=out2.concat(""+ChatFormatting.GREEN); - for (String key : TASmodClient.virtual.getNextKeyboardPresses()) { - out2 = out2.concat(key + " "); - } - return out1+out2; - } +// if (Display.isActive()) { //TODO Update +// String out1 = ""+ChatFormatting.WHITE; +// for (String mouse : TASmodClient.virtual.getCurrentMousePresses()) { +// out1 = out1.concat(mouse + " "); +// } +// out1=out1.concat(""+ChatFormatting.GREEN); +// for (String mouse : TASmodClient.virtual.getNextMousePresses()) { +// out1 = out1.concat(mouse + " "); +// } +// +// String out2 = ""+ChatFormatting.WHITE; +// for (String key : TASmodClient.virtual.getCurrentKeyboardPresses()) { +// out2 = out2.concat(key + " "); +// } +// out2=out2.concat(""+ChatFormatting.GREEN); +// for (String key : TASmodClient.virtual.getNextKeyboardPresses()) { +// out2 = out2.concat(key + " "); +// } +// return out1+out2; +// } return ""; } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/MixinEntityRenderer.java b/src/main/java/com/minecrafttas/tasmod/mixin/MixinEntityRenderer.java index fa7c83a5..6e93746c 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/MixinEntityRenderer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/MixinEntityRenderer.java @@ -116,9 +116,9 @@ public void runSubtick(float partialTicks) { smoothCamPitch = 0.0F; mc.player.turn(f2, f3 * (float) i); } - TASmodClient.virtual.updateSubtick(mc.player.rotationPitch, mc.player.rotationYaw); - mc.player.rotationPitch = TASmodClient.virtual.getSubtickPitch(); - mc.player.rotationYaw = TASmodClient.virtual.getSubtickYaw(); + TASmodClient.virtual.CAMERA_ANGLE.updateCameraAngle(mc.player.rotationPitch, mc.player.rotationYaw); + mc.player.rotationPitch = TASmodClient.virtual.CAMERA_ANGLE.getPitch(); + mc.player.rotationYaw = TASmodClient.virtual.CAMERA_ANGLE.getYaw(); InterpolationHandler.rotationPitch = mc.player.rotationPitch; InterpolationHandler.rotationYaw = 180f + mc.player.rotationYaw; } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/MixinGuiScreen.java b/src/main/java/com/minecrafttas/tasmod/mixin/MixinGuiScreen.java index b322f41d..b80c5b0e 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/MixinGuiScreen.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/MixinGuiScreen.java @@ -22,56 +22,56 @@ public class MixinGuiScreen implements GuiScreenDuck { @Inject(method = "handleInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;isCreated()Z", shift = Shift.AFTER, remap = false)) public void injectAfterKeyboardCreated(CallbackInfo ci) { - TASmodClient.virtual.updateCurrentKeyboard(); + TASmodClient.virtual.KEYBOARD.nextKeyboardTick(); } // ===================================================================================================================================== @Redirect(method = "handleInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;next()Z", remap = false)) public boolean redirectKeyboardNext() { - return TASmodClient.virtual.nextKeyboardEvent(); + return TASmodClient.virtual.KEYBOARD.nextKeyboardSubtick(); } // ===================================================================================================================================== @Redirect(method = "handleKeyboardInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventCharacter()C", remap = false)) public char redirectGetEventCharacter() { - return TASmodClient.virtual.getEventKeyboardCharacter(); + return TASmodClient.virtual.KEYBOARD.getEventKeyboardCharacter(); } // ===================================================================================================================================== @Redirect(method = "handleKeyboardInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKey()I", remap = false)) public int redirectGetEventKey() { - return TASmodClient.virtual.getEventKeyboardKey(); + return TASmodClient.virtual.KEYBOARD.getEventKeyboardKey(); } // ===================================================================================================================================== @Redirect(method = "handleKeyboardInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKeyState()Z", remap = false)) public boolean redirectGetEventState() { - return TASmodClient.virtual.getEventKeyboardState(); + return TASmodClient.virtual.KEYBOARD.getEventKeyboardState(); } // ===================================================================================================================================== @Inject(method = "handleInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;isCreated()Z", shift = Shift.AFTER, remap = false)) public void injectAfterMouseCreated(CallbackInfo ci) { - TASmodClient.virtual.updateCurrentMouseEvents(); + TASmodClient.virtual.MOUSE.nextMouseTick(); } // ===================================================================================================================================== @Redirect(method = "handleInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;next()Z", remap = false)) public boolean redirectMouseNext() { - return TASmodClient.virtual.nextMouseEvent(); + return TASmodClient.virtual.MOUSE.nextMouseSubtick(); } // ===================================================================================================================================== @Redirect(method = "handleMouseInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventButton()I", remap = false)) public int redirectGetEventButton() { - return TASmodClient.virtual.getEventMouseKey() + 100; + return TASmodClient.virtual.MOUSE.getEventMouseKey() + 100; } // ===================================================================================================================================== @@ -79,23 +79,23 @@ public int redirectGetEventButton() { @Redirect(method = "handleMouseInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventButtonState()Z", remap = false)) public boolean redirectGetEventButtonState() { if (TASmodClient.controller.isPlayingback()) { - Mouse.setCursorPosition(uncalcX(TASmodClient.virtual.getEventCursorX()), uncalcY(TASmodClient.virtual.getEventCursorY())); + Mouse.setCursorPosition(uncalcX(TASmodClient.virtual.MOUSE.getEventCursorX()), uncalcY(TASmodClient.virtual.MOUSE.getEventCursorY())); } - return TASmodClient.virtual.getEventMouseState(); + return TASmodClient.virtual.MOUSE.getEventMouseState(); } // ===================================================================================================================================== @Redirect(method = "handleMouseInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventX()I", remap = false)) public int redirectGetEventX() { - return uncalcX(TASmodClient.virtual.getEventCursorX()); + return uncalcX(TASmodClient.virtual.MOUSE.getEventCursorX()); } // ===================================================================================================================================== @Redirect(method = "handleMouseInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventY()I", remap = false)) public int redirectGetEventY() { - return uncalcY(TASmodClient.virtual.getEventCursorY()); + return uncalcY(TASmodClient.virtual.MOUSE.getEventCursorY()); } // ===================================================================================================================================== diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java index c61cb858..643deb14 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java @@ -48,7 +48,6 @@ public void injectRunGameLoop(CallbackInfo ci) { @Redirect(method = "runGameLoop", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;runTick()V")) public void redirectRunTick(Minecraft mc) { - TASmodClient.virtual.updateContainer(); if (TASmodClient.tickratechanger.ticksPerSecond != 0) { ((SubtickDuck) this.entityRenderer).runSubtick(this.isGamePaused ? this.renderPartialTicksPaused : this.timer.renderPartialTicks); } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/fixes/MixinMinecraftFullscreen.java b/src/main/java/com/minecrafttas/tasmod/mixin/fixes/MixinMinecraftFullscreen.java index 0e23b416..5a1104c4 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/fixes/MixinMinecraftFullscreen.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/fixes/MixinMinecraftFullscreen.java @@ -15,11 +15,11 @@ public class MixinMinecraftFullscreen { @Shadow - public GameSettings gameSettings; + private GameSettings gameSettings; @Inject(method = "toggleFullscreen", at = @At("RETURN")) public void inject_toggleFullscreen(CallbackInfo ci) { int keyF11=this.gameSettings.keyBindFullscreen.getKeyCode(); - TASmodClient.virtual.getNextKeyboard().get(keyF11).setPressed(false); + TASmodClient.virtual.KEYBOARD.updateNextKeyboard(keyF11, false, Character.MIN_VALUE); } } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiChat.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiChat.java index 3d26d3e2..2df94994 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiChat.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiChat.java @@ -12,6 +12,6 @@ public class MixinGuiChat { @Redirect(method = "handleMouseInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventDWheel()I", remap = false)) public int redirectHandleMouseInput4() { - return TASmodClient.virtual.getEventMouseScrollWheel(); + return TASmodClient.virtual.MOUSE.getEventMouseScrollWheel(); } } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiClickableScrolledSelectionListProxy.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiClickableScrolledSelectionListProxy.java index 3dedb2bc..fb3f84ec 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiClickableScrolledSelectionListProxy.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiClickableScrolledSelectionListProxy.java @@ -12,6 +12,6 @@ public class MixinGuiClickableScrolledSelectionListProxy { @Redirect(method = "handleMouseInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventButtonState()Z", ordinal = 0, remap = false)) public boolean redirectHandleMouseInput() { - return TASmodClient.virtual.getEventMouseState(); + return TASmodClient.virtual.MOUSE.getEventMouseState(); } } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiContainerCreative.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiContainerCreative.java index 4e073014..bad22303 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiContainerCreative.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiContainerCreative.java @@ -12,11 +12,11 @@ public class MixinGuiContainerCreative { @Redirect(method = "handleMouseInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventDWheel()I", ordinal = 0, remap = false)) public int redirectHandleMouseInput() { - return TASmodClient.virtual.getEventMouseScrollWheel(); + return TASmodClient.virtual.MOUSE.getEventMouseScrollWheel(); } @Redirect(method = "drawScreen", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;isButtonDown(I)Z", ordinal = 0, remap = false)) public boolean redirectHandleMouseInput2(int i) { - return TASmodClient.virtual.isKeyDown(-100); + return TASmodClient.virtual.MOUSE.isKeyDown(-100); } } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiSlot.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiSlot.java index 36ad6055..3f566e6e 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiSlot.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiSlot.java @@ -12,11 +12,11 @@ public class MixinGuiSlot { @Redirect(method = "handleMouseInput", at = @At(value = "INVOKE",target = "Lorg/lwjgl/input/Mouse;getEventButtonState()Z",ordinal = 0, remap = false)) public boolean redirectHandleMouseInput() { - return TASmodClient.virtual.getEventMouseState(); + return TASmodClient.virtual.MOUSE.getEventMouseState(); } @Redirect(method = "handleMouseInput", at = @At(value = "INVOKE",target = "Lorg/lwjgl/input/Mouse;getEventButton()I",ordinal = 0, remap = false)) public int redirectHandleMouseInput2() { - return TASmodClient.virtual.getEventMouseKey(); + return TASmodClient.virtual.MOUSE.getEventMouseKey(); } @Redirect(method = "handleMouseInput", at = @At(value = "INVOKE",target = "Lorg/lwjgl/input/Mouse;isButtonDown(I)Z",ordinal = 0, remap = false)) public boolean redirectHandleMouseInput3(int i) { @@ -24,6 +24,6 @@ public boolean redirectHandleMouseInput3(int i) { } @Redirect(method = "handleMouseInput", at = @At(value = "INVOKE",target = "Lorg/lwjgl/input/Mouse;getEventDWheel()I",ordinal = 0, remap = false)) public int redirectHandleMouseInput4() { - return TASmodClient.virtual.getEventMouseScrollWheel(); + return TASmodClient.virtual.MOUSE.getEventMouseScrollWheel(); } } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java index f3c46a63..a531fa6f 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java @@ -1,7 +1,6 @@ package com.minecrafttas.tasmod.mixin.playbackhooks; import org.lwjgl.input.Keyboard; -import org.lwjgl.input.Mouse; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -10,7 +9,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.minecrafttas.tasmod.TASmodClient; -import com.minecrafttas.tasmod.util.Ducks.GuiScreenDuck; import com.minecrafttas.tasmod.virtual.VirtualInput; import com.minecrafttas.tasmod.virtual.VirtualInput2; import com.minecrafttas.tasmod.virtual.VirtualKeyboardEvent; @@ -31,33 +29,7 @@ public class MixinMinecraft { */ @Inject(method = "runGameLoop", at = @At(value = "HEAD")) public void playback_injectRunGameLoop(CallbackInfo ci) { -// TASmodClient.virtual.update(currentScreen); - while (Keyboard.next()) { - TASmodClient.virtual.updateNextKeyboard( - Keyboard.getEventKey(), - Keyboard.getEventKeyState(), - Keyboard.getEventCharacter()); - } - while (Mouse.next()) { - if(this.currentScreen == null) { - TASmodClient.virtual.updateNextMouse( - Mouse.getEventButton(), - Mouse.getEventButtonState(), - Mouse.getEventDWheel(), - Mouse.getEventX(), - Mouse.getEventY(), - TASmodClient.tickratechanger.ticksPerSecond==0); - } else { - GuiScreenDuck screen = (GuiScreenDuck) currentScreen; - TASmodClient.virtual.updateNextMouse( - Mouse.getEventButton(), - Mouse.getEventButtonState(), - Mouse.getEventDWheel(), - screen.calcX(Mouse.getEventX()), - screen.calcY(Mouse.getEventY()), - TASmodClient.tickratechanger.ticksPerSecond==0); //TODO Remove and put into VirtualInput itself - } - } + TASmodClient.virtual.update(currentScreen); } /** @@ -66,7 +38,7 @@ public void playback_injectRunGameLoop(CallbackInfo ci) { */ @Inject(method = "runTickKeyboard", at = @At(value = "HEAD")) public void playback_injectRunTickKeyboard(CallbackInfo ci) { - TASmodClient.virtual.updateCurrentKeyboard(); + TASmodClient.virtual.KEYBOARD.nextKeyboardTick(); } /** @@ -76,7 +48,7 @@ public void playback_injectRunTickKeyboard(CallbackInfo ci) { */ @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;next()Z", remap = false)) public boolean playback_redirectKeyboardNext() { - return TASmodClient.virtual.nextKeyboardEvent(); + return TASmodClient.virtual.KEYBOARD.nextKeyboardSubtick(); } /** @@ -85,7 +57,7 @@ public boolean playback_redirectKeyboardNext() { */ @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKey()I", remap = false)) public int playback_redirectKeyboardGetEventKey() { - return TASmodClient.virtual.getEventKeyboardKey(); + return TASmodClient.virtual.KEYBOARD.getEventKeyboardKey(); } /** @@ -94,7 +66,7 @@ public int playback_redirectKeyboardGetEventKey() { */ @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKeyState()Z", remap = false)) public boolean playback_redirectGetEventState() { - return TASmodClient.virtual.getEventKeyboardState(); + return TASmodClient.virtual.KEYBOARD.getEventKeyboardState(); } /** @@ -103,7 +75,7 @@ public boolean playback_redirectGetEventState() { */ @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventCharacter()C", remap = false)) public char playback_redirectKeyboardGetEventCharacter() { - return TASmodClient.virtual.getEventKeyboardCharacter(); + return TASmodClient.virtual.KEYBOARD.getEventKeyboardCharacter(); } /** @@ -112,34 +84,34 @@ public char playback_redirectKeyboardGetEventCharacter() { */ @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;isKeyDown(I)Z", remap = false)) public boolean playback_redirectIsKeyDown(int keyCode) { - return TASmodClient.virtual.isKeyDown(keyCode); + return TASmodClient.virtual.KEYBOARD.isKeyDown(keyCode); } @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKey()I", remap = false)) public int playback_redirectGetEventKeyDPK() { - return TASmodClient.virtual.getEventKeyboardKey(); + return TASmodClient.virtual.KEYBOARD.getEventKeyboardKey(); } @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKeyState()Z", remap = false)) public boolean playback_redirectGetEventKeyStateDPK() { - return TASmodClient.virtual.getEventKeyboardState(); + return TASmodClient.virtual.KEYBOARD.getEventKeyboardState(); } @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventCharacter()C", remap = false)) public char playback_redirectGetEventCharacterDPK() { - return TASmodClient.virtual.getEventKeyboardCharacter(); + return TASmodClient.virtual.KEYBOARD.getEventKeyboardCharacter(); } // ============================ Mouse @Inject(method = "runTickMouse", at = @At(value = "HEAD")) public void playback_injectRunTickMouse(CallbackInfo ci) { - TASmodClient.virtual.updateCurrentMouseEvents(); + TASmodClient.virtual.MOUSE.nextMouseTick(); } @Redirect(method = "runTickMouse", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;next()Z", remap = false)) public boolean playback_redirectMouseNext() { - return TASmodClient.virtual.nextMouseEvent(); + return TASmodClient.virtual.MOUSE.nextMouseSubtick(); } @Redirect(method = "runTickMouse", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventButton()I", remap = false)) @@ -148,19 +120,17 @@ public int playback_redirectMouseGetEventButton() { // if(!VirtualKeybindings.isKeyCodeAlwaysBlocked(ClientProxy.virtual.getEventMouseKey()-100)) { // TASmod.ktrngHandler.nextPlayerInput(); // Advance ktrng seed on player input // } - return TASmodClient.virtual.getEventMouseKey() + 100; + return TASmodClient.virtual.MOUSE.getEventMouseKey() + 100; } @Redirect(method = "runTickMouse", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventButtonState()Z", remap = false)) public boolean playback_redirectGetEventButtonState() { - return TASmodClient.virtual.getEventMouseState(); + return TASmodClient.virtual.MOUSE.getEventMouseState(); } @Redirect(method = "runTickMouse", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventDWheel()I", remap = false)) public int playback_redirectGetEventDWheel() { - return TASmodClient.virtual.getEventMouseScrollWheel(); + return TASmodClient.virtual.MOUSE.getEventMouseScrollWheel(); } - // ============================ Camera Angle - } diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index cb626bb0..c3a9e115 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -232,7 +232,7 @@ public String setTASStateClient(TASstate stateIn, boolean verbose) { return verbose ? TextFormatting.GREEN + "Pausing a recording" : ""; case NONE: LOGGER.debug(LoggerMarkers.Playback, "Stopping a recording"); - TASmodClient.virtual.unpressEverything(); + TASmodClient.virtual.unpress(); state = TASstate.NONE; return verbose ? TextFormatting.GREEN + "Stopping the recording" : ""; } @@ -246,12 +246,12 @@ public String setTASStateClient(TASstate stateIn, boolean verbose) { LOGGER.debug(LoggerMarkers.Playback, "Pausing a playback"); state = TASstate.PAUSED; tempPause = TASstate.PLAYBACK; - TASmodClient.virtual.unpressEverything(); + TASmodClient.virtual.unpress(); return verbose ? TextFormatting.GREEN + "Pausing a playback" : ""; case NONE: LOGGER.debug(LoggerMarkers.Playback, "Stopping a playback"); Minecraft.getMinecraft().gameSettings.chatLinks = true; - TASmodClient.virtual.unpressEverything(); + TASmodClient.virtual.unpress(); state = TASstate.NONE; return verbose ? TextFormatting.GREEN + "Stopping the playback" : ""; } @@ -847,15 +847,15 @@ public void onClientPacket(PacketID id, ByteBuffer buf, String username) throws case PLAYBACK_SAVE: name = TASmodBufferBuilder.readString(buf); - try { - TASmodClient.virtual.saveInputs(name); - } catch (IOException e) { - if (mc.world != null) - mc.ingameGUI.getChatGUI().printChatMessage(new TextComponentString(TextFormatting.RED + e.getMessage())); - else - e.printStackTrace(); - return; - } +// try { +// TASmodClient.virtual.saveInputs(name); TODO Move to PlaybackController +// } catch (IOException e) { +// if (mc.world != null) +// mc.ingameGUI.getChatGUI().printChatMessage(new TextComponentString(TextFormatting.RED + e.getMessage())); +// else +// e.printStackTrace(); +// return; +// } if (mc.world != null) mc.ingameGUI.getChatGUI().printChatMessage(new TextComponentString(TextFormatting.GREEN + "Saved inputs to " + name + ".mctas")); else @@ -864,15 +864,15 @@ public void onClientPacket(PacketID id, ByteBuffer buf, String username) throws case PLAYBACK_LOAD: name = TASmodBufferBuilder.readString(buf); - try { - TASmodClient.virtual.loadInputs(name); - } catch (IOException e) { - if (mc.world != null) - mc.ingameGUI.getChatGUI().printChatMessage(new TextComponentString(TextFormatting.RED + e.getMessage())); - else - e.printStackTrace(); - return; - } +// try { +// TASmodClient.virtual.loadInputs(name); TODO Move to PlaybackController +// } catch (IOException e) { +// if (mc.world != null) +// mc.ingameGUI.getChatGUI().printChatMessage(new TextComponentString(TextFormatting.RED + e.getMessage())); +// else +// e.printStackTrace(); +// return; +// } if (mc.world != null) mc.ingameGUI.getChatGUI().printChatMessage(new TextComponentString(TextFormatting.GREEN + "Loaded inputs from " + name + ".mctas")); else diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerClient.java b/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerClient.java index 8ac8559a..d5d82e37 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerClient.java @@ -150,7 +150,7 @@ public static void loadstate(String nameOfSavestate) throws IOException { if (!container.isNothingPlaying()) { // If the file exists and the container is recording or playing, load the // clientSavestate if (targetfile.exists()) { - TASmodClient.virtual.loadClientSavestate(TASmodClient.serialiser.fromEntireFileV1(targetfile)); +// TASmodClient.virtual.loadClientSavestate(TASmodClient.serialiser.fromEntireFileV1(targetfile)); TODO Move to PlaybackController } else { TASmodClient.controller.setTASStateClient(TASstate.NONE, false); Minecraft.getMinecraft().player.sendMessage(new TextComponentString(ChatFormatting.YELLOW + "Inputs could not be loaded for this savestate,")); diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index 17c3266d..4c108f4f 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -83,6 +83,7 @@ * @author Scribble * */ +@Deprecated public class VirtualInput implements EventPlayerJoinedClientSide{ // ===========================Keyboard================================= diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java index dd2b5655..96feaaac 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java @@ -19,9 +19,9 @@ *
*/ public class VirtualInput2 { - private final VirtualKeyboardInput keyboardInput; - private final VirtualMouseInput mouseInput; - private final VirtualCameraAngleInput cameraAngleInput; + public final VirtualKeyboardInput KEYBOARD; + public final VirtualMouseInput MOUSE; + public final VirtualCameraAngleInput CAMERA_ANGLE; public VirtualInput2() { this(new VirtualKeyboard2(), new VirtualMouse2(), new VirtualCameraAngle2()); @@ -35,13 +35,13 @@ public VirtualInput2() { * @param preloadedCamera */ public VirtualInput2(VirtualKeyboard2 preloadedKeyboard, VirtualMouse2 preloadedMouse, VirtualCameraAngle2 preloadedCamera) { - keyboardInput = new VirtualKeyboardInput(preloadedKeyboard); - mouseInput = new VirtualMouseInput(preloadedMouse); - cameraAngleInput = new VirtualCameraAngleInput(preloadedCamera); + KEYBOARD = new VirtualKeyboardInput(preloadedKeyboard); + MOUSE = new VirtualMouseInput(preloadedMouse); + CAMERA_ANGLE = new VirtualCameraAngleInput(preloadedCamera); } /** - * Updates the logic for {@link #keyboardInput}, {@link #mouseInput} and + * Updates the logic for {@link #KEYBOARD}, {@link #MOUSE} and * {@link #cameraAngle}
* Runs every frame * @@ -52,30 +52,39 @@ public VirtualInput2(VirtualKeyboard2 preloadedKeyboard, VirtualMouse2 preloaded */ public void update(GuiScreen currentScreen) { while (Keyboard.next()) { - keyboardInput.updateNextKeyboard(Keyboard.getEventKey(), Keyboard.getEventKeyState(), Keyboard.getEventCharacter()); + KEYBOARD.updateNextKeyboard(Keyboard.getEventKey(), Keyboard.getEventKeyState(), Keyboard.getEventCharacter()); } while (Mouse.next()) { if (currentScreen == null) { - mouseInput.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), null, null); + MOUSE.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), null, null); } else { Ducks.GuiScreenDuck screen = (Ducks.GuiScreenDuck) currentScreen; - mouseInput.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), screen.calcX(Mouse.getEventX()), screen.calcY(Mouse.getEventY())); + MOUSE.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), screen.calcX(Mouse.getEventX()), screen.calcY(Mouse.getEventY())); } } } - public VirtualKeyboardInput getKeyboardInput() { - return keyboardInput; + public boolean isKeyDown(int keycode) { + if(keycode >= 0) { + return KEYBOARD.isKeyDown(keycode); + } else { + return MOUSE.isKeyDown(keycode); + } } - - public VirtualMouseInput getMouseInput() { - return mouseInput; + + public boolean willKeyBeDown(int keycode) { + if(keycode >= 0) { + return KEYBOARD.willKeyBeDown(keycode); + } else { + return MOUSE.willKeyBeDown(keycode); + } } - - public VirtualCameraAngleInput getCameraAngle() { - return cameraAngleInput; + + public void unpress() { + KEYBOARD.nextKeyboard.clear(); + MOUSE.nextMouse.clear(); } - + /** * Subclass of {@link VirtualInput} handling keyboard logic.
*
@@ -110,7 +119,7 @@ public VirtualCameraAngleInput getCameraAngle() { * * */ - private static class VirtualKeyboardInput { + public class VirtualKeyboardInput { /** * The keyboard "state" that is currently recognized by the game,
* meaning it is a direct copy of the vanilla keybindings. Updated every @@ -198,9 +207,17 @@ public boolean getEventKeyboardState() { public char getEventKeyboardCharacter() { return currentKeyboardEvent.getCharacter(); } + + public boolean isKeyDown(int keycode) { + return currentKeyboard.isKeyDown(keycode); + } + + public boolean willKeyBeDown(int keycode) { + return nextKeyboard.isKeyDown(keycode); + } } - private static class VirtualMouseInput { + public class VirtualMouseInput { private final VirtualMouse2 currentMouse; private final VirtualMouse2 nextMouse = new VirtualMouse2(); private final Queue mouseEventQueue = new ConcurrentLinkedQueue<>(); @@ -247,9 +264,17 @@ public int getEventCursorY() { return PointerNormalizer.getCoordsY(currentMouseEvent.getMouseY()); } + public boolean isKeyDown(int keycode) { + return currentMouse.isKeyDown(keycode); + } + + public boolean willKeyBeDown(int keycode) { + return nextMouse.isKeyDown(keycode); + } + } - private static class VirtualCameraAngleInput { + public class VirtualCameraAngleInput { private VirtualCameraAngle2 cameraAngle; From 05a0e49f53345359da051ac34969d9c2d0a1334e Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 29 Jan 2024 22:30:37 +0100 Subject: [PATCH 18/57] [VirtualInput] Fixed getVirtualEvents generating the wrong events - Added VirtualInputTest --- .../com/minecrafttas/tasmod/TASmodClient.java | 2 +- .../tasmod/virtual/VirtualKeyboard2.java | 11 +- .../tasmod/virtual/VirtualMouse2.java | 5 +- .../virtual/keyboard/VirtualInputTest.java | 110 ++++++++++++++++++ .../virtual/keyboard/VirtualKeyboardTest.java | 9 +- 5 files changed, 128 insertions(+), 9 deletions(-) create mode 100644 src/test/java/tasmod/virtual/keyboard/VirtualInputTest.java diff --git a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java index 0b87ef7b..ae3d8a29 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java @@ -126,7 +126,7 @@ public void onInitializeClient() { } else { config.reset(ConfigOptions.FileToOpen); } -// virtual=new VirtualInput2(fileOnStart); TODO Move fileOnStart to PlaybackController + virtual=new VirtualInput2(); //TODO Move fileOnStart to PlaybackController // Initialize InfoHud hud = new InfoHud(); diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java index dbd30500..3364118f 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java @@ -83,6 +83,7 @@ public VirtualKeyboard2(Set pressedKeys, List charList, List * @param character The character that is associated with that key. Can change between keyboards or whenever shift is held in combination. */ public void update(int keycode, boolean keystate, char character) { + charList.clear(); setPressed(keycode, keystate); addChar(character); @@ -175,9 +176,11 @@ private char getOrMinChar(Character charr){ */ public void getVirtualEvents(VirtualKeyboard2 nextKeyboard, Queue reference) { if (isParent()) { - getSubticks().forEach(keyboard -> { - keyboard.getDifference(nextKeyboard, reference); - }); + VirtualKeyboard2 currentSubtick = this; + for(VirtualKeyboard2 subtick : nextKeyboard.getSubticks()) { + currentSubtick.getDifference(subtick, reference); + currentSubtick = subtick; + } } } @@ -205,7 +208,7 @@ public String toString() { return String.format("%s;%s", super.toString(), charListToString(charList)); } } - + private String charListToString(List charList) { String charString = ""; if (!charList.isEmpty()) { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java index bbf163b8..7514a528 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java @@ -105,8 +105,8 @@ public void getDifference(VirtualMouse2 nextPeripheral, Queue public void getVirtualEvents(VirtualMouse2 nextPeripheral, Queue reference) { if(isParent()) { - getSubticks().forEach(mouse -> { - mouse.getDifference(nextPeripheral, reference); + nextPeripheral.getSubticks().forEach(mouse -> { + getDifference(mouse, reference); }); } } @@ -115,7 +115,6 @@ public void getVirtualEvents(VirtualMouse2 nextPeripheral, Queue expected = new ArrayList<>(); expected.add(new VirtualKeyboard2(new HashSet(Arrays.asList(VirtualKey2.W.getKeycode())), Arrays.asList('w'))); - expected.add(new VirtualKeyboard2(new HashSet(Arrays.asList(VirtualKey2.W.getKeycode(), VirtualKey2.A.getKeycode())), Arrays.asList('w', 'A'))); + expected.add(new VirtualKeyboard2(new HashSet(Arrays.asList(VirtualKey2.W.getKeycode(), VirtualKey2.A.getKeycode())), Arrays.asList('A'))); assertIterableEquals(expected, test.getSubticks()); } @@ -258,4 +259,10 @@ void testGetDifference(){ assertIterableEquals(expected, actual); } + + @Test + @Disabled + void testGetVirtualEvents() { + //TODO + } } From 420b51fd2d58522f20bcae8336730d44fd453c87 Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 29 Jan 2024 22:44:04 +0100 Subject: [PATCH 19/57] [Actions] Updated action versions --- .github/workflows/build.yml | 10 +++++----- .github/workflows/buildandupload.yml | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6845779c..b1c30f93 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,27 +9,27 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.5.0 + - uses: actions/checkout@v4 - name: Set up JDK 17 for x64 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' architecture: x64 - name: Setup Gradle - uses: gradle/gradle-build-action@v2.4.0 + uses: gradle/actions/setup-gradle@v3 with: gradle-version: 8.4 - name: Build TASmod with Gradle run: gradle build - name: Upload Test Report - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: always() with: name: TestResult path: build/test-results/test/*.xml - name: Upload TASmod-Dev-Build - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: TASmod-Dev-Build path: build/libs diff --git a/.github/workflows/buildandupload.yml b/.github/workflows/buildandupload.yml index f163ffee..c7892576 100644 --- a/.github/workflows/buildandupload.yml +++ b/.github/workflows/buildandupload.yml @@ -10,21 +10,21 @@ jobs: runs-on: ubuntu-latest if: github.repository == 'MinecraftTAS/TASmod' steps: - - uses: actions/checkout@v3.5.0 + - uses: actions/checkout@v4 - name: Set up JDK 17 for x64 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' architecture: x64 - name: Setup Gradle - uses: gradle/gradle-build-action@v2.4.0 + uses: gradle/actions/setup-gradle@v3 with: gradle-version: 8.4 - name: Build TASmod with Gradle run: gradle build - name: Upload artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: TASmod-Dev-Build path: build/libs From db7f8fbc147bceb8bac4952fe4e4e04fed15d66f Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 29 Jan 2024 23:06:58 +0100 Subject: [PATCH 20/57] Revert "[Actions] Updated action versions" - test-reporter breaks with the new versions This reverts commit 420b51fd2d58522f20bcae8336730d44fd453c87. --- .github/workflows/build.yml | 10 +++++----- .github/workflows/buildandupload.yml | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b1c30f93..6845779c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,27 +9,27 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v3.5.0 - name: Set up JDK 17 for x64 - uses: actions/setup-java@v4 + uses: actions/setup-java@v3 with: java-version: '17' distribution: 'temurin' architecture: x64 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/gradle-build-action@v2.4.0 with: gradle-version: 8.4 - name: Build TASmod with Gradle run: gradle build - name: Upload Test Report - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v3 if: always() with: name: TestResult path: build/test-results/test/*.xml - name: Upload TASmod-Dev-Build - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v3 with: name: TASmod-Dev-Build path: build/libs diff --git a/.github/workflows/buildandupload.yml b/.github/workflows/buildandupload.yml index c7892576..f163ffee 100644 --- a/.github/workflows/buildandupload.yml +++ b/.github/workflows/buildandupload.yml @@ -10,21 +10,21 @@ jobs: runs-on: ubuntu-latest if: github.repository == 'MinecraftTAS/TASmod' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v3.5.0 - name: Set up JDK 17 for x64 - uses: actions/setup-java@v4 + uses: actions/setup-java@v3 with: java-version: '17' distribution: 'temurin' architecture: x64 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/gradle-build-action@v2.4.0 with: gradle-version: 8.4 - name: Build TASmod with Gradle run: gradle build - name: Upload artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v3 with: name: TASmod-Dev-Build path: build/libs From 64656d03c844323eeba25f7e4653d0c557c9366b Mon Sep 17 00:00:00 2001 From: Scribble Date: Wed, 31 Jan 2024 22:14:53 +0100 Subject: [PATCH 21/57] [VirtualInput] Added delay to subticks The parent tick is now always the most recent state, while the subtickList contains previous states of the peripheral in question. - Added getAll next to getSubtick, to also return the parent peripheral --- .../tasmod/virtual/VirtualKeyboard2.java | 15 +++---- .../tasmod/virtual/VirtualMouse2.java | 12 +++--- .../tasmod/virtual/VirtualPeripheral.java | 30 +++++++++++++ .../virtual/keyboard/VirtualInputTest.java | 30 ++++++++++--- .../virtual/keyboard/VirtualKeyboardTest.java | 43 ++++++++++++++++--- 5 files changed, 107 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java index 3364118f..0da89dc5 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java @@ -49,7 +49,7 @@ public class VirtualKeyboard2 extends VirtualPeripheral implem * Used for distributing characters to {@link VirtualKeyboardEvent}s in an order. */ private final ConcurrentLinkedQueue charQueue = new ConcurrentLinkedQueue<>(); - + /** * Creates an empty parent keyboard with all keys unpressed */ @@ -75,7 +75,7 @@ public VirtualKeyboard2(Set pressedKeys, List charList, List super(pressedKeys, subtick); this.charList = charList; } - + /** * Updates the keyboard, adds a new subtick to this keyboard * @param keycode The keycode of this key @@ -83,13 +83,12 @@ public VirtualKeyboard2(Set pressedKeys, List charList, List * @param character The character that is associated with that key. Can change between keyboards or whenever shift is held in combination. */ public void update(int keycode, boolean keystate, char character) { + if(isParent() && !ignoreFirstUpdate()) { + addSubtick(clone()); + } charList.clear(); setPressed(keycode, keystate); addChar(character); - - if(isParent()) { - addSubtick(clone()); - } } @Override @@ -177,7 +176,7 @@ private char getOrMinChar(Character charr){ public void getVirtualEvents(VirtualKeyboard2 nextKeyboard, Queue reference) { if (isParent()) { VirtualKeyboard2 currentSubtick = this; - for(VirtualKeyboard2 subtick : nextKeyboard.getSubticks()) { + for(VirtualKeyboard2 subtick : nextKeyboard.getAll()) { currentSubtick.getDifference(subtick, reference); currentSubtick = subtick; } @@ -203,7 +202,7 @@ protected void clear(){ @Override public String toString() { if (isParent()) { - return getSubticks().stream().map(element -> element.toString()).collect(Collectors.joining("\n")); + return getAll().stream().map(element -> element.toString()).collect(Collectors.joining("\n")); } else { return String.format("%s;%s", super.toString(), charListToString(charList)); } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java index 7514a528..30f4d13e 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java @@ -103,11 +103,13 @@ public void getDifference(VirtualMouse2 nextPeripheral, Queue }; } - public void getVirtualEvents(VirtualMouse2 nextPeripheral, Queue reference) { - if(isParent()) { - nextPeripheral.getSubticks().forEach(mouse -> { - getDifference(mouse, reference); - }); + public void getVirtualEvents(VirtualMouse2 nextMouse, Queue reference) { + if (isParent()) { + VirtualMouse2 currentSubtick = this; + for(VirtualMouse2 subtick : nextMouse.getAll()) { + currentSubtick.getDifference(subtick, reference); + currentSubtick = subtick; + } } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java index 98e8c71e..ec347130 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java @@ -33,6 +33,11 @@ public abstract class VirtualPeripheral> implemen */ protected final List subtickList; + /** + * When creating an empty + */ + private boolean ignoreFirstUpdate = false; + /** * Create a peripheral with already existing pressed keys * @param pressedKeys The existing pressedKeys @@ -44,6 +49,7 @@ protected VirtualPeripheral(Set pressedKeys) { protected VirtualPeripheral(Set pressedKeys, List subtickList) { this.pressedKeys = pressedKeys; this.subtickList = subtickList; + ignoreFirstUpdate = subtickList != null && subtickList.isEmpty(); // TODO Change, to something more robust } /** @@ -97,10 +103,28 @@ public Set getPressedKeys() { return ImmutableSet.copyOf(pressedKeys); } + /** + * @return An immutable list of subticks + */ public List getSubticks() { return ImmutableList.copyOf(subtickList); } + /** + * Gets all peripheral states in an immutable list.
+ *
+ * This list is comprised of {@link #subtickList} and the current peripheral state added after that
+ * This will result in a list where the first element is the oldest state and the last being the current state. + * @return An immutable list of keyboard states + */ + @SuppressWarnings("unchecked") + public List getAll() { + return ImmutableList.builder() + .addAll(subtickList) + .add((T)this) + .build(); + } + public boolean isParent() { return subtickList != null; } @@ -140,4 +164,10 @@ protected void moveFrom(T peripheral) { this.pressedKeys.clear(); this.pressedKeys.addAll(peripheral.pressedKeys); } + + protected boolean ignoreFirstUpdate() { + boolean ignore = ignoreFirstUpdate; + ignoreFirstUpdate = false; + return ignore; + } } diff --git a/src/test/java/tasmod/virtual/keyboard/VirtualInputTest.java b/src/test/java/tasmod/virtual/keyboard/VirtualInputTest.java index 6776a523..3f6d0561 100644 --- a/src/test/java/tasmod/virtual/keyboard/VirtualInputTest.java +++ b/src/test/java/tasmod/virtual/keyboard/VirtualInputTest.java @@ -1,8 +1,10 @@ package tasmod.virtual.keyboard; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import com.minecrafttas.tasmod.virtual.VirtualCameraAngle2; @@ -29,9 +31,27 @@ void testConstructor() { * Tests if a keyboard can be preloaded */ @Test - @Disabled - void testPreloadedKeyboard() { - //TODO + void testPreloadedConstructor() { + VirtualKeyboard2 preloadedKeyboard = new VirtualKeyboard2(); + VirtualMouse2 preloadedMouse = new VirtualMouse2(); + VirtualCameraAngle2 preloadedCameraAngle = new VirtualCameraAngle2(1f, 2f); + + preloadedKeyboard.update(VirtualKey2.W.getKeycode(), true, 'w'); + preloadedMouse.update(VirtualKey2.LC.getKeycode(), true, 15, null, null); + + + VirtualInput2 virtual = new VirtualInput2(preloadedKeyboard, preloadedMouse, preloadedCameraAngle); + + virtual.KEYBOARD.nextKeyboardTick(); + assertTrue(virtual.KEYBOARD.nextKeyboardSubtick()); + assertEquals(VirtualKey2.W.getKeycode(), virtual.KEYBOARD.getEventKeyboardKey()); + +// virtual.MOUSE.nextMouseTick(); +// assertTrue(virtual.MOUSE.nextMouseSubtick()); +// assertEquals(VirtualKey2.LC.getKeycode(), virtual.MOUSE.getEventMouseKey()); + + assertEquals(1f, virtual.CAMERA_ANGLE.getPitch()); + assertEquals(2f, virtual.CAMERA_ANGLE.getYaw()); } /** diff --git a/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java b/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java index 48200c86..d404031a 100644 --- a/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java +++ b/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java @@ -14,7 +14,6 @@ import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import com.minecrafttas.tasmod.virtual.VirtualKey2; @@ -243,7 +242,7 @@ void testUpdate(){ expected.add(new VirtualKeyboard2(new HashSet(Arrays.asList(VirtualKey2.W.getKeycode())), Arrays.asList('w'))); expected.add(new VirtualKeyboard2(new HashSet(Arrays.asList(VirtualKey2.W.getKeycode(), VirtualKey2.A.getKeycode())), Arrays.asList('A'))); - assertIterableEquals(expected, test.getSubticks()); + assertIterableEquals(expected, test.getAll()); } /** @@ -260,9 +259,43 @@ void testGetDifference(){ assertIterableEquals(expected, actual); } + /** + * Tests generating virtual events going from an unpressed keyboard to a pressed keyboard state + */ @Test - @Disabled - void testGetVirtualEvents() { - //TODO + void testGetVirtualEventsPress() { + VirtualKeyboard2 unpressed = new VirtualKeyboard2(); + + VirtualKeyboard2 pressed = new VirtualKeyboard2(); + pressed.update(VirtualKey2.W.getKeycode(), true, 'w'); + + // Load actual with the events + Queue actual = new ConcurrentLinkedQueue<>(); + unpressed.getVirtualEvents(pressed, actual); + + // Load expected + List expected = Arrays.asList(new VirtualKeyboardEvent(VirtualKey2.W.getKeycode(), true, 'w')); + + assertIterableEquals(expected, actual); + } + + /** + * Tests generating virtual events going from a pressed keyboard to an unpressed keyboard state + */ + @Test + void testGetVirtualEventsUnpress() { + VirtualKeyboard2 unpressed = new VirtualKeyboard2(); + + VirtualKeyboard2 pressed = new VirtualKeyboard2(); + pressed.update(VirtualKey2.W.getKeycode(), true, 'w'); + + // Load actual with the events + Queue actual = new ConcurrentLinkedQueue<>(); + pressed.getVirtualEvents(unpressed, actual); + + // Load expected + List expected = Arrays.asList(new VirtualKeyboardEvent(VirtualKey2.W.getKeycode(), false, Character.MIN_VALUE)); + + assertIterableEquals(expected, actual); } } From 0d30da5ee3d81252f149a76f1d2046a4d49f2217 Mon Sep 17 00:00:00 2001 From: Scribble Date: Thu, 1 Feb 2024 19:06:09 +0100 Subject: [PATCH 22/57] [VirtualInput] Added ignoreFirstUpdate to constructor --- .../tasmod/virtual/VirtualInput2.java | 6 +++--- .../tasmod/virtual/VirtualKeyboard2.java | 20 +++++++++++-------- .../tasmod/virtual/VirtualMouse2.java | 15 +++++++++----- .../tasmod/virtual/VirtualPeripheral.java | 16 ++++++--------- .../virtual/keyboard/VirtualKeyboardTest.java | 20 +++++++++---------- 5 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java index 96feaaac..2085d784 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java @@ -42,7 +42,7 @@ public VirtualInput2(VirtualKeyboard2 preloadedKeyboard, VirtualMouse2 preloaded /** * Updates the logic for {@link #KEYBOARD}, {@link #MOUSE} and - * {@link #cameraAngle}
+ * {@link #CAMERA_ANGLE}
* Runs every frame * * @see MixinMinecraft#playback_injectRunGameLoop(CallbackInfo) @@ -86,7 +86,7 @@ public void unpress() { } /** - * Subclass of {@link VirtualInput} handling keyboard logic.
+ * Subclass of {@link VirtualInput2} handling keyboard logic.
*
* Vanilla keyboard handling looks something like this: * @@ -276,7 +276,7 @@ public boolean willKeyBeDown(int keycode) { public class VirtualCameraAngleInput { - private VirtualCameraAngle2 cameraAngle; + private final VirtualCameraAngle2 cameraAngle; public VirtualCameraAngleInput(VirtualCameraAngle2 preloadedCamera) { cameraAngle = preloadedCamera; diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java index 0da89dc5..7a27699e 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java @@ -45,7 +45,7 @@ public class VirtualKeyboard2 extends VirtualPeripheral implem private final List charList; /** - * A queue of characters used in {@link #getDifference(VirtualKeyboard2)}.
+ * A queue of characters used in {@link #getDifference(VirtualKeyboard2, Queue)}.
* Used for distributing characters to {@link VirtualKeyboardEvent}s in an order. */ private final ConcurrentLinkedQueue charQueue = new ConcurrentLinkedQueue<>(); @@ -54,7 +54,7 @@ public class VirtualKeyboard2 extends VirtualPeripheral implem * Creates an empty parent keyboard with all keys unpressed */ public VirtualKeyboard2() { - this(new HashSet<>(), new ArrayList<>(), new ArrayList<>()); + this(new HashSet<>(), new ArrayList<>(), new ArrayList<>(), true); } /** @@ -63,7 +63,7 @@ public VirtualKeyboard2() { * @param charList A list of characters for this subtickKeyboard */ public VirtualKeyboard2(Set pressedKeys, List charList){ - this(pressedKeys, charList, null); + this(pressedKeys, charList, null, false); } /** @@ -71,8 +71,12 @@ public VirtualKeyboard2(Set pressedKeys, List charList){ * @param pressedKeys The existing list of pressed keycodes * @param charList The existing list of characters */ - public VirtualKeyboard2(Set pressedKeys, List charList, List subtick) { - super(pressedKeys, subtick); + public VirtualKeyboard2(Set pressedKeys, List charList, boolean ignoreFirstUpdate) { + this(pressedKeys, charList, null, ignoreFirstUpdate); + } + + public VirtualKeyboard2(Set pressedKeys, List charList, List subtick, boolean ignoreFirstUpdate) { + super(pressedKeys, subtick, ignoreFirstUpdate); this.charList = charList; } @@ -202,7 +206,7 @@ protected void clear(){ @Override public String toString() { if (isParent()) { - return getAll().stream().map(element -> element.toString()).collect(Collectors.joining("\n")); + return getAll().stream().map(VirtualKeyboard2::toString).collect(Collectors.joining("\n")); } else { return String.format("%s;%s", super.toString(), charListToString(charList)); } @@ -211,7 +215,7 @@ public String toString() { private String charListToString(List charList) { String charString = ""; if (!charList.isEmpty()) { - charString = charList.stream().map(element -> element.toString()).collect(Collectors.joining()); + charString = charList.stream().map(Object::toString).collect(Collectors.joining()); charString = StringUtils.replace(charString, "\r", "\\n"); charString = StringUtils.replace(charString, "\n", "\\n"); } @@ -223,7 +227,7 @@ private String charListToString(List charList) { */ @Override public VirtualKeyboard2 clone() { - return new VirtualKeyboard2(new HashSet<>(this.pressedKeys), new ArrayList<>(this.charList)); + return new VirtualKeyboard2(new HashSet<>(this.pressedKeys), new ArrayList<>(this.charList), isIgnoreFirstUpdate()); } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java index 30f4d13e..b020ed5e 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java @@ -2,6 +2,7 @@ import java.io.Serializable; import java.util.HashSet; +import java.util.List; import java.util.Queue; import java.util.Set; import java.util.stream.Collectors; @@ -29,7 +30,11 @@ public class VirtualMouse2 extends VirtualPeripheral implements S * Creates a mouse with no buttons pressed and no data */ public VirtualMouse2(){ - this(new HashSet<>(), 0, null, null); + this(new HashSet<>(), 0, null, null, null, true); + } + + public VirtualMouse2(Set pressedKeys, int scrollWheel, Integer cursorX, Integer cursorY, List subtick){ + this(pressedKeys, scrollWheel, cursorX, cursorY, subtick, false); } /** @@ -40,8 +45,8 @@ public VirtualMouse2(){ * @param cursorX The {@link #cursorX} * @param cursorY The {@link #cursorY} */ - public VirtualMouse2(Set pressedKeys, int scrollWheel, Integer cursorX, Integer cursorY) { - super(pressedKeys); + public VirtualMouse2(Set pressedKeys, int scrollWheel, Integer cursorX, Integer cursorY, List subtick, boolean ignoreFirstUpdate) { + super(pressedKeys, subtick, ignoreFirstUpdate); this.scrollWheel = scrollWheel; this.cursorX = cursorX; this.cursorY = cursorY; @@ -129,7 +134,7 @@ private void clearMouseData() { @Override public String toString() { if (isParent()) { - return getSubticks().stream().map(element -> element.toString()).collect(Collectors.joining("\n")); + return getSubticks().stream().map(VirtualMouse2::toString).collect(Collectors.joining("\n")); } else { return String.format("%s;%s,%s,%s", super.toString(), scrollWheel, cursorX, cursorY); } @@ -140,7 +145,7 @@ public String toString() { */ @Override public VirtualMouse2 clone() { - return new VirtualMouse2(new HashSet<>(this.pressedKeys), scrollWheel, cursorX, cursorY); + return new VirtualMouse2(new HashSet<>(this.pressedKeys), scrollWheel, cursorX, cursorY, null, ignoreFirstUpdate()); } @Override diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java index ec347130..38f08361 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java @@ -38,18 +38,10 @@ public abstract class VirtualPeripheral> implemen */ private boolean ignoreFirstUpdate = false; - /** - * Create a peripheral with already existing pressed keys - * @param pressedKeys The existing pressedKeys - */ - protected VirtualPeripheral(Set pressedKeys) { - this(pressedKeys, null); - } - - protected VirtualPeripheral(Set pressedKeys, List subtickList) { + protected VirtualPeripheral(Set pressedKeys, List subtickList, boolean ignoreFirstUpdate) { this.pressedKeys = pressedKeys; this.subtickList = subtickList; - ignoreFirstUpdate = subtickList != null && subtickList.isEmpty(); // TODO Change, to something more robust + this.ignoreFirstUpdate = ignoreFirstUpdate; } /** @@ -170,4 +162,8 @@ protected boolean ignoreFirstUpdate() { ignoreFirstUpdate = false; return ignore; } + + protected boolean isIgnoreFirstUpdate(){ + return ignoreFirstUpdate; + } } diff --git a/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java b/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java index d404031a..2be166a6 100644 --- a/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java +++ b/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java @@ -85,7 +85,7 @@ void testSetUnPressedByKeycode(){ Set testKeycodeSet = new HashSet<>(); testKeycodeSet.add(VirtualKey2.W.getKeycode()); testKeycodeSet.add(VirtualKey2.S.getKeycode()); - VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, new ArrayList<>(), null); + VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, new ArrayList<>()); test.setPressed(VirtualKey2.W.getKeycode(), false); assertIterableEquals(Arrays.asList(VirtualKey2.S.getKeycode()), test.getPressedKeys()); @@ -99,7 +99,7 @@ void testSetUnPressedByKeyname(){ Set testKeycodeSet = new HashSet<>(); testKeycodeSet.add(VirtualKey2.W.getKeycode()); testKeycodeSet.add(VirtualKey2.S.getKeycode()); - VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, new ArrayList<>(), null); + VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, new ArrayList<>()); test.setPressed("S", false); assertIterableEquals(Arrays.asList(VirtualKey2.W.getKeycode()), test.getPressedKeys()); @@ -129,8 +129,8 @@ void testToString(){ testCharList.add('w'); testCharList.add('s'); - VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, testCharList, null); - VirtualKeyboard2 test2 = new VirtualKeyboard2(testKeycodeSet, new ArrayList<>(), null); + VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, testCharList); + VirtualKeyboard2 test2 = new VirtualKeyboard2(testKeycodeSet, new ArrayList<>()); assertEquals("W,S;ws", test.toString()); assertEquals("W,S;", test2.toString()); @@ -149,8 +149,8 @@ void testEquals() { testCharList.add('w'); testCharList.add('s'); - VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, testCharList, null); - VirtualKeyboard2 test2 = new VirtualKeyboard2(testKeycodeSet, testCharList, null); + VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, testCharList); + VirtualKeyboard2 test2 = new VirtualKeyboard2(testKeycodeSet, testCharList); assertEquals(test, test2); } @@ -175,9 +175,9 @@ void testNotEquals() { List testCharList3 = new ArrayList<>(); testCharList3.add('w'); - VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, testCharList, null); - VirtualKeyboard2 test2 = new VirtualKeyboard2(testKeycodeSet, testCharList2, null); - VirtualKeyboard2 test3 = new VirtualKeyboard2(testKeycodeSet, testCharList3, null); + VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, testCharList); + VirtualKeyboard2 test2 = new VirtualKeyboard2(testKeycodeSet, testCharList2); + VirtualKeyboard2 test3 = new VirtualKeyboard2(testKeycodeSet, testCharList3); assertNotEquals(test, test2); assertNotEquals(test, test3); @@ -197,7 +197,7 @@ void testClone() { testCharList.add('w'); testCharList.add('s'); - VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, testCharList, null); + VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, testCharList); VirtualKeyboard2 test2 = test.clone(); assertEquals(test, test2); From d9be47ff2093191e27a3b49ad158151c916522f8 Mon Sep 17 00:00:00 2001 From: Scribble Date: Fri, 2 Feb 2024 11:37:41 +0100 Subject: [PATCH 23/57] [VirtualInput] Changed moveFrom back to copyFrom - Finished documentation for VirtualKeyboard --- .../tasmod/virtual/VirtualInput2.java | 4 +- .../tasmod/virtual/VirtualKeyboard2.java | 79 +++++++++++++------ .../tasmod/virtual/VirtualMouse2.java | 5 +- .../tasmod/virtual/VirtualPeripheral.java | 4 +- .../virtual/keyboard/VirtualKeyboardTest.java | 18 ++--- 5 files changed, 70 insertions(+), 40 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java index 2085d784..a72ac337 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java @@ -173,7 +173,7 @@ public void updateNextKeyboard(int keycode, boolean keystate, char character) { */ public void nextKeyboardTick() { currentKeyboard.getVirtualEvents(nextKeyboard, keyboardEventQueue); - currentKeyboard.moveFrom(nextKeyboard); + currentKeyboard.copyFrom(nextKeyboard); } /** @@ -237,7 +237,7 @@ public void updateNextMouse(int keycode, boolean keystate, int scrollwheel, Inte public void nextMouseTick() { currentMouse.getVirtualEvents(nextMouse, mouseEventQueue); - currentMouse.moveFrom(nextMouse); + currentMouse.copyFrom(nextMouse); } public boolean nextMouseSubtick() { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java index 7a27699e..c8888554 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java @@ -14,27 +14,57 @@ import com.google.common.collect.ImmutableList; /** - * A state of the virtual keyboard at a given time.
+ * Stores keyboard specific values in a given timeframe.
*
- * This class can be seen as a storage class,
- * representing a state of the physical keyboard at a given time.
+ * This keyboard mimics the {@link org.lwjgl.input.Keyboard} Minecraft is using. + *

KeyboardEvent

+ * {@link org.lwjgl.input.Keyboard} has the following outputs, when a key is pressed or unpressed on the physical keyboard: + *
    + *
  • int KeyCode: The unique keycode of the key
  • + *
  • boolean KeyState: The new state of the key. True for pressed, false for unpressed
  • + *
  • char KeyCharacter: The character associated for each key
  • + *
+ * While the keycode is the same between physical keyboards, the key character might differ.
+ * It is also common that one keycode has multiple characters associated with it, e.g.
+ * holding shift results in a capitalised character.
*
- * This class aims to store the currently pressed keys and the list of characters that were entered in that time frame.
- *
- * A keyboard event coming from the physical keyboard may look like this:
+ * These three outputs together are what we call a "KeyboardEvent" and might look like this: + *
+ *     17, true, w
+ * 
+ * For keycode, keystate, keycharacter
*
+ *

Updating the keyboard

+ * This keyboard stores it's values in "states".
+ * That means that all the keys that are currently pressed are stored in {@link #pressedKeys}.
+ * And this list is updated via a keyboard event in {@link #update(int, boolean, char)}.
+ *

Difference

+ * When comparing 2 keyboard states, we can generate a list of differences from them in form of {@link VirtualKeyboardEvent}s.
+ *
+ * 	this: W A S
+ *	next: W   S D
+ * 
+ * Since there are 2 differences between this and the next keyboard, + * this will result in 2 {@link VirtualKeyboardEvent}s. And combined with the {@link #charList} we can also get the associated characters: *
- * Keycode:17,Keystate:true,Character:w
+ *	30, false, null // A is unpressed
+ * 	32, true, d 	// D is pressed
  * 
- * This indicates that the key "W" is currently pressed.
- * Therefore, the keycode 17 will be added to the set of {@link #pressedKeys} in {@link VirtualPeripheral}.
- * This behaviour is also present in the {@link VirtualMouse2}.
+ *

Subticks

+ * Minecraft updates it's keyboard every tick. All the key events that occur inbetween are stored,
+ * then read out when a new tick has started.
We call these "inbetween" ticks subticks.
+ *

Parent-Subtick

+ * In a previous version of this keyboard, subticks were bundeled and flattened into one keyboard state.
+ * After all, Minecraft updates only occur once every tick, storing subticks seemed unnecessary.
+ *
+ * However this posed some usability issues when playing in a low game speed via {@link com.minecrafttas.tasmod.tickratechanger.TickrateChangerClient}.
+ * Now you had to hold the key until the next tick to get it recognised by the game.
*
- * The character "w" coming from that keyboard event is added to the {@link #charList}.
- * If shift were to be pressed while pressing the key,
- * then the resulting keyboard event would hold a capitalized "W" as the character. - * TODO Write Difference and VirtualKey once complete - * + * To fix this, now every subtick is stored as a keyboard state as well.
+ * When updating the keyboard in {@link #update(int, boolean, char)}, a clone of itself is created and stored in {@link #subtickList},
+ * with the difference that the subtick state has no {@link #subtickList}.
+ * In a nutshell, the keyboard stores it's past changes in {@link #subtickList} with the first being the oldest change. + * * @author Scribble */ public class VirtualKeyboard2 extends VirtualPeripheral implements Serializable { @@ -84,15 +114,15 @@ public VirtualKeyboard2(Set pressedKeys, List charList, List * Updates the keyboard, adds a new subtick to this keyboard * @param keycode The keycode of this key * @param keystate The keystate of this key, true for pressed - * @param character The character that is associated with that key. Can change between keyboards or whenever shift is held in combination. + * @param keycharacter The character that is associated with that key. Can change between keyboards or whenever shift is held in combination. */ - public void update(int keycode, boolean keystate, char character) { + public void update(int keycode, boolean keystate, char keycharacter) { if(isParent() && !ignoreFirstUpdate()) { addSubtick(clone()); } charList.clear(); setPressed(keycode, keystate); - addChar(character); + addChar(keycharacter); } @Override @@ -206,12 +236,16 @@ protected void clear(){ @Override public String toString() { if (isParent()) { - return getAll().stream().map(VirtualKeyboard2::toString).collect(Collectors.joining("\n")); + return getAll().stream().map(VirtualKeyboard2::toStringWithCharlist).collect(Collectors.joining("\n")); } else { - return String.format("%s;%s", super.toString(), charListToString(charList)); + return toStringWithCharlist(); } } + private String toStringWithCharlist(){ + return String.format("%s;%s", super.toString(), charListToString(charList)); + } + private String charListToString(List charList) { String charString = ""; if (!charList.isEmpty()) { @@ -232,11 +266,10 @@ public VirtualKeyboard2 clone() { @Override - public void moveFrom(VirtualKeyboard2 keyboard) { - super.moveFrom(keyboard); + public void copyFrom(VirtualKeyboard2 keyboard) { + super.copyFrom(keyboard); charList.clear(); charList.addAll(keyboard.charList); - keyboard.clear(); } public List getCharList() { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java index b020ed5e..b9063cbc 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java @@ -149,12 +149,11 @@ public VirtualMouse2 clone() { } @Override - protected void moveFrom(VirtualMouse2 mouse) { - super.moveFrom(mouse); + protected void copyFrom(VirtualMouse2 mouse) { + super.copyFrom(mouse); this.scrollWheel = mouse.scrollWheel; this.cursorX = mouse.cursorX; this.cursorY = mouse.cursorY; - mouse.clear(); } @Override diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java index 38f08361..ba45c0a2 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java @@ -149,10 +149,10 @@ public boolean equals(Object obj) { } /** - * Moves the data from another virtual peripheral into this peripheral without creating a new object. + * Copies the data from another virtual peripheral into this peripheral without creating a new object. * @param peripheral The peripheral to move from */ - protected void moveFrom(T peripheral) { + protected void copyFrom(T peripheral) { this.pressedKeys.clear(); this.pressedKeys.addAll(peripheral.pressedKeys); } diff --git a/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java b/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java index 2be166a6..88ca80b7 100644 --- a/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java +++ b/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java @@ -208,25 +208,23 @@ void testClone() { */ @Test void testMoveFrom(){ - VirtualKeyboard2 moveFrom = new VirtualKeyboard2(); + VirtualKeyboard2 copyFrom = new VirtualKeyboard2(); VirtualKeyboard2 actual = new VirtualKeyboard2(); - moveFrom.update(VirtualKey2.W.getKeycode(), true, 'w'); - moveFrom.update(VirtualKey2.A.getKeycode(), true, 'a'); + copyFrom.update(VirtualKey2.W.getKeycode(), true, 'w'); + copyFrom.update(VirtualKey2.A.getKeycode(), true, 'a'); - VirtualKeyboard2 expected = moveFrom.clone(); + VirtualKeyboard2 expected = copyFrom.clone(); actual.update(VirtualKey2.S.getKeycode(), true, 's'); actual.update(VirtualKey2.D.getKeycode(), true, 'd'); - - - actual.moveFrom(moveFrom); + + actual.copyFrom(copyFrom); assertIterableEquals(expected.getPressedKeys(), actual.getPressedKeys()); assertIterableEquals(expected.getCharList(), actual.getCharList()); - - assertEquals(new VirtualKeyboard2(), moveFrom); - assertTrue(moveFrom.getSubticks().isEmpty()); + + assertFalse(copyFrom.getSubticks().isEmpty()); } /** From f1b0e56ad21513cd5e9d9fe3a80912e48609704a Mon Sep 17 00:00:00 2001 From: Scribble Date: Fri, 2 Feb 2024 21:29:36 +0100 Subject: [PATCH 24/57] [VirtualInput] More documentation, added tests for VirtualMouse --- .../tasmod/virtual/VirtualInput2.java | 80 ++++++++++++- .../tasmod/virtual/VirtualKeyboard2.java | 8 +- .../tasmod/virtual/VirtualMouse2.java | 50 ++++++-- .../tasmod/virtual/VirtualPeripheral.java | 48 +++++++- .../{keyboard => }/VirtualInputTest.java | 2 +- .../{keyboard => }/VirtualKeyboardTest.java | 108 ++++++++++-------- .../java/tasmod/virtual/VirtualMouseTest.java | 58 ++++++++++ 7 files changed, 284 insertions(+), 70 deletions(-) rename src/test/java/tasmod/virtual/{keyboard => }/VirtualInputTest.java (99%) rename src/test/java/tasmod/virtual/{keyboard => }/VirtualKeyboardTest.java (72%) create mode 100644 src/test/java/tasmod/virtual/VirtualMouseTest.java diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java index a72ac337..8d1115b7 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java @@ -64,6 +64,14 @@ public void update(GuiScreen currentScreen) { } } + /** + * If the keyboard or mouse key is currently down. + * If keycode >= 0 then {@link VirtualKeyboardInput#isKeyDown(int)} will be called,
+ * otherwise {@link VirtualMouseInput#isKeyDown(int)} + * + * @param keycode The keycode in question + * @return If the key is down either on mouse or keyboard + */ public boolean isKeyDown(int keycode) { if(keycode >= 0) { return KEYBOARD.isKeyDown(keycode); @@ -72,6 +80,14 @@ public boolean isKeyDown(int keycode) { } } + /** + * If the keyboard or mouse key is will be down in the next tick. + * If keycode >= 0 then {@link VirtualKeyboardInput#willKeyBeDown(int)} will be called,
+ * otherwise {@link VirtualMouseInput#willKeyBeDown(int)} + * + * @param keycode The keycode in question + * @return If the key will be down either on mouse or keyboard + */ public boolean willKeyBeDown(int keycode) { if(keycode >= 0) { return KEYBOARD.willKeyBeDown(keycode); @@ -80,6 +96,9 @@ public boolean willKeyBeDown(int keycode) { } } + /** + * Unpresses all keys in {@link VirtualKeyboardInput#nextKeyboard} and {@link VirtualMouseInput#nextMouse} + */ public void unpress() { KEYBOARD.nextKeyboard.clear(); MOUSE.nextMouse.clear(); @@ -117,9 +136,10 @@ public void unpress() { * } * } * - * + * @see com.minecrafttas.tasmod.virtual.VirtualKeyboard2 */ public class VirtualKeyboardInput { + /** * The keyboard "state" that is currently recognized by the game,
* meaning it is a direct copy of the vanilla keybindings. Updated every @@ -127,18 +147,21 @@ public class VirtualKeyboardInput { * Updated in {@link #nextKeyboardTick()} */ private final VirtualKeyboard2 currentKeyboard; + /** * The "state" of the real physical keyboard.
* This is updated every frame.
* Updates {@link #currentKeyboard} in {@link #nextKeyboardTick()} */ private final VirtualKeyboard2 nextKeyboard = new VirtualKeyboard2(); + /** * Queue for keyboard events.
* Is filled in {@link #nextKeyboardTick()} and read in * {@link #nextKeyboardSubtick()} */ private final Queue keyboardEventQueue = new ConcurrentLinkedQueue(); + /** * The current keyboard event where the vanilla keybindings are reading * from.
@@ -148,6 +171,10 @@ public class VirtualKeyboardInput { */ private VirtualKeyboardEvent currentKeyboardEvent = new VirtualKeyboardEvent(); + /** + * Constructor to preload the {@link #currentKeyboard} with an existing keyboard + * @param preloadedKeyboard + */ public VirtualKeyboardInput(VirtualKeyboard2 preloadedKeyboard) { currentKeyboard = preloadedKeyboard; } @@ -208,15 +235,64 @@ public char getEventKeyboardCharacter() { return currentKeyboardEvent.getCharacter(); } + /** + * If the key is currently down and recognised by Minecraft + * @param keycode The keycode of the key in question + * @return Whether the key of the {@link #currentKeyboard} is down + */ public boolean isKeyDown(int keycode) { return currentKeyboard.isKeyDown(keycode); } + /** + * If the key will be down and recognised in the next tick by Minecraft.
+ * This is equal to checking if a key on the physical keyboard is pressed + * @param keycode The keycode of the key in question + * @return Whether the key of the {@link #nextKeyboard} is down + */ public boolean willKeyBeDown(int keycode) { return nextKeyboard.isKeyDown(keycode); } } + /** + * Subclass of {@link VirtualInput2} handling mouse logic.
+ *
+ * Vanilla mouse handling looks something like this: + * + *
+	 *	public void runTickMouse()  { // Executed every tick in runTick()
+	 *		while({@linkplain Mouse#next()}){
+	 *			int keycode = {@linkplain Mouse#getEventButton()};
+	 *			boolean keystate = {@linkplain Mouse#getEventButtonState()};
+	 *			int scrollWheel = {@linkplain Mouse#getEventDWheel()}
+	 *			int cursorX = {@linkplain Mouse#getEventX()} // Important in GUIs
+	 *			int cursorY = {@linkplain Mouse#getEventY()}
+	 *
+	 *			Keybindings.updateKeybind(keycode, keystate, etc...)
+	 *		}
+	 *	}
+	 * 
+ * + * After redirecting the calls in {@link MixinMinecraft}, the resulting logic + * now looks like this: + * + *
+	 *	public void runTickMouse()  { // Executed every tick in runTick()
+	 *		{@linkplain #nextMouseTick()}
+	 *		while({@linkplain #nextMouseSubtick}){
+	 *			int keycode = {@linkplain #getEventMouseKey};
+	 *			boolean keystate = {@linkplain #getEventButtonState()};
+	 *			int scrollWheel = {@linkplain #getEventMouseScrollWheel()}
+	 *			int cursorX = {@linkplain #getEventCursorX()} // Important in GUIs
+	 *			int cursorY = {@linkplain #getEventCursorY()}
+	 *
+	 *			Keybindings.updateKeybind(keycode, keystate, etc...)
+	 *		}
+	 *	}
+	 * 
+ * @see com.minecrafttas.tasmod.virtual.VirtualMouse2 + */ public class VirtualMouseInput { private final VirtualMouse2 currentMouse; private final VirtualMouse2 nextMouse = new VirtualMouse2(); @@ -275,7 +351,6 @@ public boolean willKeyBeDown(int keycode) { } public class VirtualCameraAngleInput { - private final VirtualCameraAngle2 cameraAngle; public VirtualCameraAngleInput(VirtualCameraAngle2 preloadedCamera) { @@ -293,6 +368,5 @@ public float getPitch() { public float getYaw() { return cameraAngle.getYaw(); } - } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java index c8888554..33275acf 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java @@ -32,8 +32,7 @@ *
  *     17, true, w
  * 
- * For keycode, keystate, keycharacter
- *
+ * For keycode, keystate, keycharacter *

Updating the keyboard

* This keyboard stores it's values in "states".
* That means that all the keys that are currently pressed are stored in {@link #pressedKeys}.
@@ -53,7 +52,7 @@ *

Subticks

* Minecraft updates it's keyboard every tick. All the key events that occur inbetween are stored,
* then read out when a new tick has started.
We call these "inbetween" ticks subticks.
- *

Parent-Subtick

+ *

Parent->Subtick

* In a previous version of this keyboard, subticks were bundeled and flattened into one keyboard state.
* After all, Minecraft updates only occur once every tick, storing subticks seemed unnecessary.
*
@@ -66,6 +65,7 @@ * In a nutshell, the keyboard stores it's past changes in {@link #subtickList} with the first being the oldest change. * * @author Scribble + * @see com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput */ public class VirtualKeyboard2 extends VirtualPeripheral implements Serializable { @@ -88,7 +88,7 @@ public VirtualKeyboard2() { } /** - * Creates a subtick keyboard with {@link #subtickList} uninitialized + * Creates a subtick keyboard with {@link VirtualPeripheral#subtickList} uninitialized * @param pressedKeys The new list of pressed keycodes for this subtickKeyboard * @param charList A list of characters for this subtickKeyboard */ diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java index b9063cbc..d47fa0fc 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java @@ -1,6 +1,7 @@ package com.minecrafttas.tasmod.virtual; import java.io.Serializable; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Queue; @@ -30,20 +31,43 @@ public class VirtualMouse2 extends VirtualPeripheral implements S * Creates a mouse with no buttons pressed and no data */ public VirtualMouse2(){ - this(new HashSet<>(), 0, null, null, null, true); + this(new HashSet<>(), 0, null, null, new ArrayList<>(), true); } - public VirtualMouse2(Set pressedKeys, int scrollWheel, Integer cursorX, Integer cursorY, List subtick){ + /** + * Creates a subtick mouse with {@link VirtualPeripheral#subtickList} uninitialized + * @param pressedKeys The new list of pressed keycodes for this subtickMouse + * @param scrollWheel The scroll wheel direction for this subtickMouse + * @param cursorX The X coordinate of the cursor for this subtickMouse + * @param cursorY The Y coordinate of the cursor for this subtickMouse + */ + public VirtualMouse2(Set pressedKeys, int scrollWheel, Integer cursorX, Integer cursorY) { + this(pressedKeys, scrollWheel, cursorX, cursorY, null, false); + } + + /** + * Creates a mouse from existing values with + * {@link VirtualPeripheral#ignoreFirstUpdate} set to false + * + * @param pressedKeys The list of {@link #pressedKeys} + * @param scrollWheel The {@link #scrollWheel} + * @param cursorX The {@link #cursorX} + * @param cursorY The {@link #cursorY} + * @param subtick The {@link VirtualPeripheral#subtickList} + */ + public VirtualMouse2(Set pressedKeys, int scrollWheel, Integer cursorX, Integer cursorY, List subtick) { this(pressedKeys, scrollWheel, cursorX, cursorY, subtick, false); } /** * Creates a mouse from existing values * - * @param pressedKeys The list o {@link #pressedKeys} - * @param scrollWheel The {@link #scrollWheel} - * @param cursorX The {@link #cursorX} - * @param cursorY The {@link #cursorY} + * @param pressedKeys The list of {@link #pressedKeys} + * @param scrollWheel The {@link #scrollWheel} + * @param cursorX The {@link #cursorX} + * @param cursorY The {@link #cursorY} + * @param subtick The {@link VirtualPeripheral#subtickList} + * @param ignoreFirstUpdate Whether the first call to {@link #update(int, boolean, int, Integer, Integer)} should create a new subtick */ public VirtualMouse2(Set pressedKeys, int scrollWheel, Integer cursorX, Integer cursorY, List subtick, boolean ignoreFirstUpdate) { super(pressedKeys, subtick, ignoreFirstUpdate); @@ -64,7 +88,7 @@ public void update(int keycode, boolean keystate, int scrollwheel, Integer curso } @Override - protected void setPressed(int keycode, boolean keystate) { + public void setPressed(int keycode, boolean keystate) { if (keycode < 0) { super.setPressed(keycode, keystate); } @@ -118,6 +142,18 @@ public void getVirtualEvents(VirtualMouse2 nextMouse, Queue r } } + public int getScrollWheel() { + return scrollWheel; + } + + public Integer getCursorX() { + return cursorX; + } + + public Integer getCursorY() { + return cursorY; + } + @Override protected void clear() { super.clear(); diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java index ba45c0a2..542f6006 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java @@ -25,19 +25,29 @@ public abstract class VirtualPeripheral> implemen */ protected final Set pressedKeys; /** - * A list of subtick keyboards.
- * If subtickKeyboards is initialized, the object can be considered as a parent keyboard,
- * able to house subtickKeyboards.
+ * A list of subtick peripherals.
+ * If a peripheral parent is updated, it first adds it's current state to the subtickList before updating.
+ * This makes the subtickList a list of previous peripheral states, with the first element being the oldest change.
*
- * If subtickKeyboards is null then the object is a "child"/subtickKeyboard stored in a parent list + * To distinguish a peripheral of being a subtick or a "parent", subtickList is either null or not null respectively (see {@link #isParent()})
*/ protected final List subtickList; /** - * When creating an empty + * The way the parent/subtick relationship is set up (see {@link #subtickList}),
+ * the subtickList contains all previous changes, while the parent contains the current state.
+ * To achieve this and to prevent a ghost state from being added to the subtickList,
+ * it is sometimes necessary to ignore the first time an addition is made to the subtickList,
+ * to delay the subtickList and make the parent the current state. */ private boolean ignoreFirstUpdate = false; + /** + * Creates a VirtualPeripheral + * @param pressedKeys The {@link #pressedKeys} + * @param subtickList The {@link #subtickList} + * @param ignoreFirstUpdate The {@link #ignoreFirstUpdate} state + */ protected VirtualPeripheral(Set pressedKeys, List subtickList, boolean ignoreFirstUpdate) { this.pressedKeys = pressedKeys; this.subtickList = subtickList; @@ -56,6 +66,10 @@ protected void setPressed(int keycode, boolean keystate) { pressedKeys.remove(keycode); } + /** + * Adds a peripheral to {@link #subtickList} + * @param peripheral The peripheral to add + */ protected void addSubtick(T peripheral) { subtickList.add(peripheral); } @@ -117,18 +131,34 @@ public List getAll() { .build(); } + /** + * @return If the peripheral is a parent and can add subticks + */ public boolean isParent() { return subtickList != null; } + /** + * If the key is available in {@link #pressedKeys} + * @param keycode The keycode in question + * @return If the key is pressed + */ public boolean isKeyDown(int keycode) { return pressedKeys.contains(keycode); } + /** + * If the key is available in {@link #pressedKeys} + * @param keyname The keyname in question + * @return If the key is pressed + */ public boolean isKeyDown(String keyname) { return pressedKeys.contains(VirtualKey2.getKeycode(keyname)); } + /** + * Clears pressed keys and subticks + */ protected void clear() { pressedKeys.clear(); subtickList.clear(); @@ -157,12 +187,20 @@ protected void copyFrom(T peripheral) { this.pressedKeys.addAll(peripheral.pressedKeys); } + /** + * Retrieves and sets {@link #ignoreFirstUpdate} to false + * @return If the first update should be ignored + */ protected boolean ignoreFirstUpdate() { boolean ignore = ignoreFirstUpdate; ignoreFirstUpdate = false; return ignore; } + /** + * @return If this peripheral should ignore it's first update + * @see #ignoreFirstUpdate + */ protected boolean isIgnoreFirstUpdate(){ return ignoreFirstUpdate; } diff --git a/src/test/java/tasmod/virtual/keyboard/VirtualInputTest.java b/src/test/java/tasmod/virtual/VirtualInputTest.java similarity index 99% rename from src/test/java/tasmod/virtual/keyboard/VirtualInputTest.java rename to src/test/java/tasmod/virtual/VirtualInputTest.java index 3f6d0561..6980e3b5 100644 --- a/src/test/java/tasmod/virtual/keyboard/VirtualInputTest.java +++ b/src/test/java/tasmod/virtual/VirtualInputTest.java @@ -1,4 +1,4 @@ -package tasmod.virtual.keyboard; +package tasmod.virtual; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java b/src/test/java/tasmod/virtual/VirtualKeyboardTest.java similarity index 72% rename from src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java rename to src/test/java/tasmod/virtual/VirtualKeyboardTest.java index 88ca80b7..85f825c8 100644 --- a/src/test/java/tasmod/virtual/keyboard/VirtualKeyboardTest.java +++ b/src/test/java/tasmod/virtual/VirtualKeyboardTest.java @@ -1,10 +1,6 @@ -package tasmod.virtual.keyboard; +package tasmod.virtual; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertIterableEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import java.util.ArrayList; import java.util.Arrays; @@ -20,17 +16,17 @@ import com.minecrafttas.tasmod.virtual.VirtualKeyboard2; import com.minecrafttas.tasmod.virtual.VirtualKeyboardEvent; -public class VirtualKeyboardTest { +class VirtualKeyboardTest { /** * Test the empty constructor */ @Test void testEmptyConstructor(){ - VirtualKeyboard2 test = new VirtualKeyboard2(); - assertTrue(test.getPressedKeys().isEmpty()); - assertTrue(test.getCharList().isEmpty()); - assertTrue(test.isParent()); + VirtualKeyboard2 actual = new VirtualKeyboard2(); + assertTrue(actual.getPressedKeys().isEmpty()); + assertTrue(actual.getCharList().isEmpty()); + assertTrue(actual.isParent()); } /** @@ -46,11 +42,11 @@ void testSubtickConstructor(){ testCharList.add('w'); testCharList.add('s'); - VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, testCharList); + VirtualKeyboard2 actual = new VirtualKeyboard2(testKeycodeSet, testCharList); - assertIterableEquals(testKeycodeSet, test.getPressedKeys()); - assertIterableEquals(testCharList, test.getCharList()); - assertFalse(test.isParent()); + assertIterableEquals(testKeycodeSet, actual.getPressedKeys()); + assertIterableEquals(testCharList, actual.getCharList()); + assertFalse(actual.isParent()); } /** @@ -58,11 +54,23 @@ void testSubtickConstructor(){ */ @Test void testSetPressedByKeycode(){ - VirtualKeyboard2 test = new VirtualKeyboard2(); - test.setPressed(VirtualKey2.W.getKeycode(), true); + VirtualKeyboard2 actual = new VirtualKeyboard2(); + actual.setPressed(VirtualKey2.W.getKeycode(), true); - assertIterableEquals(Arrays.asList(VirtualKey2.W.getKeycode()), test.getPressedKeys()); - assertTrue(test.isParent()); + assertIterableEquals(Arrays.asList(VirtualKey2.W.getKeycode()), actual.getPressedKeys()); + assertTrue(actual.isParent()); + } + + /** + * Test setting the keycodes via setPressed to "pressed" + */ + @Test + void testFailingSetPressedByKeycode(){ + VirtualKeyboard2 actual = new VirtualKeyboard2(); + actual.setPressed(VirtualKey2.LC.getKeycode(), true); + + assertTrue(actual.getPressedKeys().isEmpty()); + assertTrue(actual.isParent()); } /** @@ -70,11 +78,11 @@ void testSetPressedByKeycode(){ */ @Test void testSetPressedByKeyname(){ - VirtualKeyboard2 test = new VirtualKeyboard2(); - test.setPressed("W", true); + VirtualKeyboard2 actual = new VirtualKeyboard2(); + actual.setPressed("W", true); - assertIterableEquals(Arrays.asList(VirtualKey2.W.getKeycode()), test.getPressedKeys()); - assertTrue(test.isParent()); + assertIterableEquals(Arrays.asList(VirtualKey2.W.getKeycode()), actual.getPressedKeys()); + assertTrue(actual.isParent()); } /** @@ -85,10 +93,10 @@ void testSetUnPressedByKeycode(){ Set testKeycodeSet = new HashSet<>(); testKeycodeSet.add(VirtualKey2.W.getKeycode()); testKeycodeSet.add(VirtualKey2.S.getKeycode()); - VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, new ArrayList<>()); - test.setPressed(VirtualKey2.W.getKeycode(), false); + VirtualKeyboard2 actual = new VirtualKeyboard2(testKeycodeSet, new ArrayList<>()); + actual.setPressed(VirtualKey2.W.getKeycode(), false); - assertIterableEquals(Arrays.asList(VirtualKey2.S.getKeycode()), test.getPressedKeys()); + assertIterableEquals(Arrays.asList(VirtualKey2.S.getKeycode()), actual.getPressedKeys()); } /** @@ -99,10 +107,10 @@ void testSetUnPressedByKeyname(){ Set testKeycodeSet = new HashSet<>(); testKeycodeSet.add(VirtualKey2.W.getKeycode()); testKeycodeSet.add(VirtualKey2.S.getKeycode()); - VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, new ArrayList<>()); - test.setPressed("S", false); + VirtualKeyboard2 actual = new VirtualKeyboard2(testKeycodeSet, new ArrayList<>()); + actual.setPressed("S", false); - assertIterableEquals(Arrays.asList(VirtualKey2.W.getKeycode()), test.getPressedKeys()); + assertIterableEquals(Arrays.asList(VirtualKey2.W.getKeycode()), actual.getPressedKeys()); } /** @@ -110,10 +118,10 @@ void testSetUnPressedByKeyname(){ */ @Test void testAddCharacter(){ - VirtualKeyboard2 test = new VirtualKeyboard2(); - test.addChar('w'); + VirtualKeyboard2 actual = new VirtualKeyboard2(); + actual.addChar('w'); - assertIterableEquals(Arrays.asList('w'), test.getCharList()); + assertIterableEquals(Arrays.asList('w'), actual.getCharList()); } /** @@ -129,11 +137,11 @@ void testToString(){ testCharList.add('w'); testCharList.add('s'); - VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, testCharList); - VirtualKeyboard2 test2 = new VirtualKeyboard2(testKeycodeSet, new ArrayList<>()); + VirtualKeyboard2 actual = new VirtualKeyboard2(testKeycodeSet, testCharList); + VirtualKeyboard2 actual2 = new VirtualKeyboard2(testKeycodeSet, new ArrayList<>()); - assertEquals("W,S;ws", test.toString()); - assertEquals("W,S;", test2.toString()); + assertEquals("W,S;ws", actual.toString()); + assertEquals("W,S;", actual2.toString()); } /** @@ -149,10 +157,10 @@ void testEquals() { testCharList.add('w'); testCharList.add('s'); - VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, testCharList); - VirtualKeyboard2 test2 = new VirtualKeyboard2(testKeycodeSet, testCharList); + VirtualKeyboard2 actual = new VirtualKeyboard2(testKeycodeSet, testCharList); + VirtualKeyboard2 actual2 = new VirtualKeyboard2(testKeycodeSet, testCharList); - assertEquals(test, test2); + assertEquals(actual, actual2); } /** @@ -175,13 +183,13 @@ void testNotEquals() { List testCharList3 = new ArrayList<>(); testCharList3.add('w'); - VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, testCharList); + VirtualKeyboard2 actual = new VirtualKeyboard2(testKeycodeSet, testCharList); VirtualKeyboard2 test2 = new VirtualKeyboard2(testKeycodeSet, testCharList2); VirtualKeyboard2 test3 = new VirtualKeyboard2(testKeycodeSet, testCharList3); - assertNotEquals(test, test2); - assertNotEquals(test, test3); - assertNotEquals(test, null); + assertNotEquals(actual, test2); + assertNotEquals(actual, test3); + assertNotEquals(actual, null); } /** @@ -197,10 +205,10 @@ void testClone() { testCharList.add('w'); testCharList.add('s'); - VirtualKeyboard2 test = new VirtualKeyboard2(testKeycodeSet, testCharList); - VirtualKeyboard2 test2 = test.clone(); + VirtualKeyboard2 actual = new VirtualKeyboard2(testKeycodeSet, testCharList); + VirtualKeyboard2 test2 = actual.clone(); - assertEquals(test, test2); + assertEquals(actual, test2); } /** @@ -232,15 +240,15 @@ void testMoveFrom(){ */ @Test void testUpdate(){ - VirtualKeyboard2 test = new VirtualKeyboard2(); - test.update(VirtualKey2.W.getKeycode(), true, 'w'); - test.update(VirtualKey2.A.getKeycode(), true, 'A'); + VirtualKeyboard2 actual = new VirtualKeyboard2(); + actual.update(VirtualKey2.W.getKeycode(), true, 'w'); + actual.update(VirtualKey2.A.getKeycode(), true, 'A'); List expected = new ArrayList<>(); expected.add(new VirtualKeyboard2(new HashSet(Arrays.asList(VirtualKey2.W.getKeycode())), Arrays.asList('w'))); expected.add(new VirtualKeyboard2(new HashSet(Arrays.asList(VirtualKey2.W.getKeycode(), VirtualKey2.A.getKeycode())), Arrays.asList('A'))); - assertIterableEquals(expected, test.getAll()); + assertIterableEquals(expected, actual.getAll()); } /** diff --git a/src/test/java/tasmod/virtual/VirtualMouseTest.java b/src/test/java/tasmod/virtual/VirtualMouseTest.java new file mode 100644 index 00000000..3efd1945 --- /dev/null +++ b/src/test/java/tasmod/virtual/VirtualMouseTest.java @@ -0,0 +1,58 @@ +package tasmod.virtual; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import com.minecrafttas.tasmod.virtual.VirtualKey2; +import com.minecrafttas.tasmod.virtual.VirtualMouse2; + +class VirtualMouseTest { + + /** + * Test the empty constructor + */ + @Test + void testEmptyConstructor() { + VirtualMouse2 actual = new VirtualMouse2(); + assertTrue(actual.getPressedKeys().isEmpty()); + assertEquals(0, actual.getScrollWheel()); + assertNull(actual.getCursorX()); + assertNull(actual.getCursorY()); + assertTrue(actual.isParent()); + } + + /** + * Test constructor with premade keycode sets + */ + @Test + void testSubtickConstructor() { + Set expected = new HashSet<>(); + expected.add(VirtualKey2.LC.getKeycode()); + expected.add(VirtualKey2.RC.getKeycode()); + + VirtualMouse2 actual = new VirtualMouse2(expected, -15, 0, 2); + + assertIterableEquals(expected, actual.getPressedKeys()); + assertEquals(-15, actual.getScrollWheel()); + assertEquals(0, actual.getCursorX()); + assertEquals(2, actual.getCursorY()); + assertFalse(actual.isParent()); + } + + /** + * Test setting the keycodes via setPressed to "pressed" + */ + @Test + void testSetPressedByKeycode(){ + VirtualMouse2 actual = new VirtualMouse2(); + actual.setPressed(VirtualKey2.LC.getKeycode(), true); + + assertIterableEquals(Arrays.asList(VirtualKey2.LC.getKeycode()), actual.getPressedKeys()); + assertTrue(actual.isParent()); + } +} From 0d02654b591f5219747dfbec21c33f54ab1e300b Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 3 Feb 2024 15:17:06 +0100 Subject: [PATCH 25/57] [VirtualInput] Fixed pointer not being recognised - Various renames and documentation --- .../tasmod/mixin/MixinEntityRenderer.java | 1 - .../tasmod/mixin/MixinGuiScreen.java | 14 ++--- .../playbackhooks/MixinGuiContainer.java | 6 ++- .../mixin/playbackhooks/MixinMinecraft.java | 1 - .../com/minecrafttas/tasmod/util/Ducks.java | 52 +++++++++++++++++-- .../tasmod/virtual/VirtualInput2.java | 8 ++- .../tasmod/virtual/VirtualKeyboard2.java | 31 ++++++----- .../tasmod/virtual/VirtualMouse2.java | 41 ++++++++------- .../tasmod/virtual/VirtualPeripheral.java | 4 ++ .../tasmod/virtual/VirtualKeyboardTest.java | 2 +- 10 files changed, 111 insertions(+), 49 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/MixinEntityRenderer.java b/src/main/java/com/minecrafttas/tasmod/mixin/MixinEntityRenderer.java index 6e93746c..7f25bd41 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/MixinEntityRenderer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/MixinEntityRenderer.java @@ -20,7 +20,6 @@ import net.minecraft.util.math.MathHelper; @Mixin(EntityRenderer.class) -@SuppressWarnings("unused") public class MixinEntityRenderer implements SubtickDuck { public double dX = 0; diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/MixinGuiScreen.java b/src/main/java/com/minecrafttas/tasmod/mixin/MixinGuiScreen.java index b80c5b0e..0ced5b29 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/MixinGuiScreen.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/MixinGuiScreen.java @@ -79,7 +79,7 @@ public int redirectGetEventButton() { @Redirect(method = "handleMouseInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventButtonState()Z", remap = false)) public boolean redirectGetEventButtonState() { if (TASmodClient.controller.isPlayingback()) { - Mouse.setCursorPosition(uncalcX(TASmodClient.virtual.MOUSE.getEventCursorX()), uncalcY(TASmodClient.virtual.MOUSE.getEventCursorY())); + Mouse.setCursorPosition(rescaleX(TASmodClient.virtual.MOUSE.getEventCursorX()), rescaleY(TASmodClient.virtual.MOUSE.getEventCursorY())); } return TASmodClient.virtual.MOUSE.getEventMouseState(); } @@ -88,14 +88,14 @@ public boolean redirectGetEventButtonState() { @Redirect(method = "handleMouseInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventX()I", remap = false)) public int redirectGetEventX() { - return uncalcX(TASmodClient.virtual.MOUSE.getEventCursorX()); + return rescaleX(TASmodClient.virtual.MOUSE.getEventCursorX()); } // ===================================================================================================================================== @Redirect(method = "handleMouseInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventY()I", remap = false)) public int redirectGetEventY() { - return uncalcY(TASmodClient.virtual.MOUSE.getEventCursorY()); + return rescaleY(TASmodClient.virtual.MOUSE.getEventCursorY()); } // ===================================================================================================================================== @@ -131,22 +131,22 @@ private static boolean redirectIsAltKeyDown(int i) { private Minecraft mc; @Override - public int calcX(int X) { + public int unscaleX(int X) { return X * this.width / this.mc.displayWidth; } @Override - public int calcY(int Y) { + public int unscaleY(int Y) { return this.height - Y * this.height / this.mc.displayHeight - 1; } @Override - public int uncalcX(int X) { + public int rescaleX(int X) { return X * this.mc.displayWidth / this.width; } @Override - public int uncalcY(int Y) { + public int rescaleY(int Y) { return (this.mc.displayHeight * (this.height - Y - 1) / this.height); } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiContainer.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiContainer.java index 88c5c634..14d1636c 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiContainer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiContainer.java @@ -1,7 +1,6 @@ package com.minecrafttas.tasmod.mixin.playbackhooks; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @@ -13,6 +12,7 @@ @Mixin(GuiContainer.class) public class MixinGuiContainer { + @Redirect(method = "mouseClicked", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;isKeyDown(I)Z", ordinal = 0, remap = false)) private boolean redirectIsKeyDown(int i) { return TASmodClient.virtual.isKeyDown(i); @@ -23,6 +23,10 @@ private boolean redirectIsKeyDown2(int i) { return TASmodClient.virtual.isKeyDown(i); } + /** + * Fixes #67 + * @param player + */ @Redirect(method = "keyTyped", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;closeScreen()V")) public void redirectCloseScreen(EntityPlayerSP player) { Minecraft mc = Minecraft.getMinecraft(); diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java index a531fa6f..02dbc3c8 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java @@ -9,7 +9,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.minecrafttas.tasmod.TASmodClient; -import com.minecrafttas.tasmod.virtual.VirtualInput; import com.minecrafttas.tasmod.virtual.VirtualInput2; import com.minecrafttas.tasmod.virtual.VirtualKeyboardEvent; diff --git a/src/main/java/com/minecrafttas/tasmod/util/Ducks.java b/src/main/java/com/minecrafttas/tasmod/util/Ducks.java index c90caf28..4362b02c 100644 --- a/src/main/java/com/minecrafttas/tasmod/util/Ducks.java +++ b/src/main/java/com/minecrafttas/tasmod/util/Ducks.java @@ -15,6 +15,8 @@ * #TeamNoDucks * * Ducks now use up 66.66% less files on my hard drive! I call that a success. + * + * @author Pancake */ public class Ducks { @@ -26,13 +28,53 @@ public static interface ChunkProviderDuck { } /** - * Quacks the gui screen to spit out mouse positions independant of the display size + * Quacks the gui screen to spit out mouse positions independent of the display size */ public static interface GuiScreenDuck { - public int calcX(int X); - public int calcY(int Y); - public int uncalcX(int X); - public int uncalcY(int J); + + /** + * Calculates the true value of the pointer coordinate, by removing the scaling for custom screen sizes applied to it: + *
+		 * X * this.width / this.mc.displayWidth
+		 * 
+ * By storing the true value in the TASfile, we can play back the TAS even with a different GUI Scale applied to it + * @param x The scaled pointer coordinate + * @return The unscaled pointer coordinate + * @see #rescaleX(int) + */ + public int unscaleX(int x); + + /** + * Calculates the true value of the pointer coordinate, by removing the scaling for custom screen sizes applied to it: + *
+		 * this.height - Y * this.height / this.mc.displayHeight - 1
+		 * 
+ * By storing the true value in the TASfile, we can play back the TAS even with a different GUI Scale applied to it + * @param y The scaled pointer coordinate + * @return The unscaled pointer coordinate + * @see #rescaleY(int) + */ + public int unscaleY(int y); + + /** + * Reapplies the math for custom gui scales to the pointer coordinate: + *
+		 * X * this.mc.displayWidth / this.width
+		 * 
+ * @param x The unscaled pointer coordinate + * @return The scaled pointer coordinate + */ + public int rescaleX(int x); + + /** + * Reapplies the math for custom gui scales to the pointer coordinate: + *
+		 * (this.mc.displayHeight * (this.height - Y - 1) / this.height)
+		 * 
+ * @param y The unscaled pointer coordinate + * @return The scaled pointer coordinate + */ + public int rescaleY(int y); } /** diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java index 8d1115b7..288123f3 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java @@ -59,7 +59,11 @@ public void update(GuiScreen currentScreen) { MOUSE.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), null, null); } else { Ducks.GuiScreenDuck screen = (Ducks.GuiScreenDuck) currentScreen; - MOUSE.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), screen.calcX(Mouse.getEventX()), screen.calcY(Mouse.getEventY())); + int eventX = screen.unscaleX(Mouse.getEventX()); + int eventY = screen.unscaleY(Mouse.getEventY()); + eventX = PointerNormalizer.getNormalizedX(eventX); + eventY = PointerNormalizer.getNormalizedY(eventY); + MOUSE.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), eventX, eventY); } } } @@ -308,7 +312,7 @@ public VirtualMouseInput(VirtualMouse2 preloadedMouse) { } public void updateNextMouse(int keycode, boolean keystate, int scrollwheel, Integer cursorX, Integer cursorY) { - nextMouse.update(keycode, keystate, scrollwheel, cursorX, cursorY); + nextMouse.update(keycode-100, keystate, scrollwheel, cursorX, cursorY); } public void nextMouseTick() { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java index 33275acf..f14f9091 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java @@ -104,9 +104,16 @@ public VirtualKeyboard2(Set pressedKeys, List charList){ public VirtualKeyboard2(Set pressedKeys, List charList, boolean ignoreFirstUpdate) { this(pressedKeys, charList, null, ignoreFirstUpdate); } - - public VirtualKeyboard2(Set pressedKeys, List charList, List subtick, boolean ignoreFirstUpdate) { - super(pressedKeys, subtick, ignoreFirstUpdate); + + /** + * Creates a keyboard from existing variables + * @param pressedKeys The existing list of {@link VirtualPeripheral#pressedKeys} + * @param charList The {@link #charList} + * @param subtickList {@link VirtualPeripheral#subtickList} + * @param ignoreFirstUpdate The {@link VirtualPeripheral#ignoreFirstUpdate} + */ + public VirtualKeyboard2(Set pressedKeys, List charList, List subtickList, boolean ignoreFirstUpdate) { + super(pressedKeys, subtickList, ignoreFirstUpdate); this.charList = charList; } @@ -121,8 +128,8 @@ public void update(int keycode, boolean keystate, char keycharacter) { addSubtick(clone()); } charList.clear(); - setPressed(keycode, keystate); addChar(keycharacter); + setPressed(keycode, keystate); } @Override @@ -236,13 +243,13 @@ protected void clear(){ @Override public String toString() { if (isParent()) { - return getAll().stream().map(VirtualKeyboard2::toStringWithCharlist).collect(Collectors.joining("\n")); + return getAll().stream().map(VirtualKeyboard2::toString2).collect(Collectors.joining("\n")); } else { - return toStringWithCharlist(); + return toString2(); } } - private String toStringWithCharlist(){ + private String toString2(){ return String.format("%s;%s", super.toString(), charListToString(charList)); } @@ -264,7 +271,6 @@ public VirtualKeyboard2 clone() { return new VirtualKeyboard2(new HashSet<>(this.pressedKeys), new ArrayList<>(this.charList), isIgnoreFirstUpdate()); } - @Override public void copyFrom(VirtualKeyboard2 keyboard) { super.copyFrom(keyboard); @@ -272,10 +278,6 @@ public void copyFrom(VirtualKeyboard2 keyboard) { charList.addAll(keyboard.charList); } - public List getCharList() { - return ImmutableList.copyOf(charList); - } - @Override public boolean equals(Object obj) { if(obj instanceof VirtualKeyboard2) { @@ -294,4 +296,9 @@ public boolean equals(Object obj) { } return super.equals(obj); } + + + public List getCharList() { + return ImmutableList.copyOf(charList); + } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java index d47fa0fc..4acb4acf 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java @@ -77,19 +77,18 @@ public VirtualMouse2(Set pressedKeys, int scrollWheel, Integer cursorX, } public void update(int keycode, boolean keystate, int scrollwheel, Integer cursorX, Integer cursorY) { + if(isParent() && !ignoreFirstUpdate()) { + addSubtick(clone()); + } setPressed(keycode, keystate); this.scrollWheel = scrollwheel; this.cursorX = cursorX; this.cursorY = cursorY; - - if(isParent()) { - addSubtick(clone()); - } } @Override public void setPressed(int keycode, boolean keystate) { - if (keycode < 0) { + if (keycode < 0) { // Mouse buttons always have a keycode smaller than 0 super.setPressed(keycode, keystate); } } @@ -142,18 +141,6 @@ public void getVirtualEvents(VirtualMouse2 nextMouse, Queue r } } - public int getScrollWheel() { - return scrollWheel; - } - - public Integer getCursorX() { - return cursorX; - } - - public Integer getCursorY() { - return cursorY; - } - @Override protected void clear() { super.clear(); @@ -170,11 +157,15 @@ private void clearMouseData() { @Override public String toString() { if (isParent()) { - return getSubticks().stream().map(VirtualMouse2::toString).collect(Collectors.joining("\n")); + return getSubticks().stream().map(VirtualMouse2::toString2).collect(Collectors.joining("\n")); } else { - return String.format("%s;%s,%s,%s", super.toString(), scrollWheel, cursorX, cursorY); + return toString2(); } } + + private String toString2(){ + return String.format("%s;%s,%s,%s", super.toString(), scrollWheel, cursorX, cursorY); + } /** * Clones this VirtualMouse without subticks @@ -203,4 +194,16 @@ public boolean equals(Object obj) { } return super.equals(obj); } + + public int getScrollWheel() { + return scrollWheel; + } + + public Integer getCursorX() { + return cursorX; + } + + public Integer getCursorY() { + return cursorY; + } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java index 542f6006..5ddf1182 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java @@ -60,6 +60,9 @@ protected VirtualPeripheral(Set pressedKeys, List subtickList, boole * @param keystate The keystate of the keycode */ protected void setPressed(int keycode, boolean keystate) { + if (VirtualKeybindings.isKeyCodeAlwaysBlocked(keycode)) { //TODO Maybe a better system? + return; + } if (keystate) pressedKeys.add(keycode); else @@ -185,6 +188,7 @@ public boolean equals(Object obj) { protected void copyFrom(T peripheral) { this.pressedKeys.clear(); this.pressedKeys.addAll(peripheral.pressedKeys); + peripheral.subtickList.clear(); } /** diff --git a/src/test/java/tasmod/virtual/VirtualKeyboardTest.java b/src/test/java/tasmod/virtual/VirtualKeyboardTest.java index 85f825c8..c7d55baf 100644 --- a/src/test/java/tasmod/virtual/VirtualKeyboardTest.java +++ b/src/test/java/tasmod/virtual/VirtualKeyboardTest.java @@ -232,7 +232,7 @@ void testMoveFrom(){ assertIterableEquals(expected.getPressedKeys(), actual.getPressedKeys()); assertIterableEquals(expected.getCharList(), actual.getCharList()); - assertFalse(copyFrom.getSubticks().isEmpty()); + assertTrue(copyFrom.getSubticks().isEmpty()); } /** From 3710d8410ace15d3c72a7c5a62ecb579c921a322 Mon Sep 17 00:00:00 2001 From: Scribble Date: Sun, 4 Feb 2024 13:58:58 +0100 Subject: [PATCH 26/57] [VirtualInput] Add logger markers for keyboard and mouse updates --- .../java/com/minecrafttas/tasmod/util/LoggerMarkers.java | 4 ++++ .../com/minecrafttas/tasmod/virtual/VirtualInput2.java | 7 ++++++- src/main/resources/log4j.xml | 4 ++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/minecrafttas/tasmod/util/LoggerMarkers.java b/src/main/java/com/minecrafttas/tasmod/util/LoggerMarkers.java index c0fb439f..de235e6a 100644 --- a/src/main/java/com/minecrafttas/tasmod/util/LoggerMarkers.java +++ b/src/main/java/com/minecrafttas/tasmod/util/LoggerMarkers.java @@ -35,4 +35,8 @@ public class LoggerMarkers { public static final Marker Tickrate = MarkerManager.getMarker("Tickrate"); public static final Marker Playback = MarkerManager.getMarker("Playback"); + + public static final Marker Keyboard = MarkerManager.getMarker("Keyboard"); + + public static final Marker Mouse = MarkerManager.getMarker("Mouse"); } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java index 288123f3..62994df7 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java @@ -1,7 +1,9 @@ package com.minecrafttas.tasmod.virtual; +import com.minecrafttas.tasmod.TASmod; import com.minecrafttas.tasmod.mixin.playbackhooks.MixinMinecraft; import com.minecrafttas.tasmod.util.Ducks; +import com.minecrafttas.tasmod.util.LoggerMarkers; import com.minecrafttas.tasmod.util.PointerNormalizer; import net.minecraft.client.gui.GuiScreen; import org.lwjgl.input.Keyboard; @@ -192,6 +194,7 @@ public VirtualKeyboardInput(VirtualKeyboard2 preloadedKeyboard) { * @param character The character of this event */ public void updateNextKeyboard(int keycode, boolean keystate, char character) { + TASmod.LOGGER.debug(LoggerMarkers.Keyboard,"Update: {}, {}, {}, {}", keycode, keystate, character, Keyboard.areRepeatEventsEnabled()); nextKeyboard.update(keycode, keystate, character); } @@ -312,7 +315,9 @@ public VirtualMouseInput(VirtualMouse2 preloadedMouse) { } public void updateNextMouse(int keycode, boolean keystate, int scrollwheel, Integer cursorX, Integer cursorY) { - nextMouse.update(keycode-100, keystate, scrollwheel, cursorX, cursorY); + keycode-=100; + TASmod.LOGGER.debug(LoggerMarkers.Mouse,"Update: {} ({}), {}, {}", keycode, VirtualKey2.getName(keycode), keystate, scrollwheel, cursorX, cursorY); + nextMouse.update(keycode, keystate, scrollwheel, cursorX, cursorY); } public void nextMouseTick() { diff --git a/src/main/resources/log4j.xml b/src/main/resources/log4j.xml index 36586568..10071c0a 100644 --- a/src/main/resources/log4j.xml +++ b/src/main/resources/log4j.xml @@ -11,6 +11,10 @@ onMatch="${sys:tasmod.marker.tickrate:-ACCEPT}" onMismatch="NEUTRAL" /> + + From 106c29a786a133f7961722d9b80f5d51a0fb5bbc Mon Sep 17 00:00:00 2001 From: Scribble Date: Sun, 4 Feb 2024 14:02:15 +0100 Subject: [PATCH 27/57] [MCTCommon/Keybinds] Seperate isKeyDown methods for each keybind - Added the ability to add different "isKeyDown" function for each keybind. - Added a default "isKeyDown" function instead of an abstract method --- .../mctcommon/KeybindManager.java | 42 +++++++++++++++---- .../com/minecrafttas/tasmod/TASmodClient.java | 18 +++----- 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/minecrafttas/mctcommon/KeybindManager.java b/src/main/java/com/minecrafttas/mctcommon/KeybindManager.java index 2964a517..6bd55289 100644 --- a/src/main/java/com/minecrafttas/mctcommon/KeybindManager.java +++ b/src/main/java/com/minecrafttas/mctcommon/KeybindManager.java @@ -14,15 +14,19 @@ /** * Keybind manager + * * @author Pancake */ -public abstract class KeybindManager implements EventClientGameLoop { +public class KeybindManager implements EventClientGameLoop { + + private final IsKeyDownFunc defaultFunction; public static class Keybind { private KeyBinding keyBinding; private String category; private Runnable onKeyDown; + private IsKeyDownFunc isKeyDownFunc; /** * Initialize keybind @@ -33,9 +37,22 @@ public static class Keybind { * @param onKeyDown Will be run when the keybind is pressed */ public Keybind(String name, String category, int defaultKey, Runnable onKeyDown) { + this(name, category, defaultKey, onKeyDown, null); + } + + /** + * Initialize keybind with a different "isKeyDown" method + * + * @param name Name of keybind + * @param category Category of keybind + * @param defaultKey Default key of keybind + * @param onKeyDown Will be run when the keybind is pressed + */ + public Keybind(String name, String category, int defaultKey, Runnable onKeyDown, IsKeyDownFunc func) { this.keyBinding = new KeyBinding(name, defaultKey, category); this.category = category; this.onKeyDown = onKeyDown; + this.isKeyDownFunc = func; } } @@ -43,9 +60,13 @@ public Keybind(String name, String category, int defaultKey, Runnable onKeyDown) private List keybindings; /** - * Initialize keybind manager + * Initialize keybind manage + * + * @param defaultFunction The default function used to determine if a keybind is + * down. Can be overridden when registering a new keybind */ - public KeybindManager() { + public KeybindManager(IsKeyDownFunc defaultFunction) { + this.defaultFunction = defaultFunction; this.keybindings = new ArrayList<>(); } @@ -55,12 +76,14 @@ public KeybindManager() { @Override public void onRunClientGameLoop(Minecraft mc) { for (Keybind keybind : this.keybindings) - if (this.isKeyDown(keybind.keyBinding)) - keybind.onKeyDown.run(); + if (keybind.isKeyDownFunc == null) { + defaultFunction.isKeyDown(keybind.keyBinding); + } else { + if (keybind.isKeyDownFunc.isKeyDown(keybind.keyBinding)) + keybind.onKeyDown.run(); + } } - protected abstract boolean isKeyDown(KeyBinding i); - /** * Register new keybind * @@ -80,4 +103,9 @@ public KeyBinding registerKeybind(Keybind keybind) { return keyBinding; } + @FunctionalInterface + public static interface IsKeyDownFunc { + + public boolean isKeyDown(KeyBinding keybind); + } } \ No newline at end of file diff --git a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java index ae3d8a29..ea92d474 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java @@ -137,13 +137,7 @@ public void onInitializeClient() { // Initialize Ticksync ticksyncClient = new TickSyncClient(); // Initialize keybind manager - keybindManager = new KeybindManager() { - - protected boolean isKeyDown(KeyBinding i) { - return VirtualKeybindings.isKeyDownExceptTextfield(i); - }; - - }; + keybindManager = new KeybindManager(VirtualKeybindings::isKeyDownExceptTextfield); // Register event listeners EventListenerRegistry.register(this); @@ -181,9 +175,9 @@ protected boolean isKeyDown(KeyBinding i) { public void onClientInit(Minecraft mc) { // initialize keybindings List blockedKeybindings = new ArrayList<>(); - blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Tickrate 0 Key", "TASmod", Keyboard.KEY_F8, () -> TASmodClient.tickratechanger.togglePause()))); - blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Advance Tick", "TASmod", Keyboard.KEY_F9, () -> TASmodClient.tickratechanger.advanceTick()))); - blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Recording/Playback Stop", "TASmod", Keyboard.KEY_F10, () -> TASmodClient.controller.setTASState(TASstate.NONE)))); + blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Tickrate 0 Key", "TASmod", Keyboard.KEY_F8, () -> TASmodClient.tickratechanger.togglePause(), VirtualKeybindings::isKeyDown))); + blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Advance Tick", "TASmod", Keyboard.KEY_F9, () -> TASmodClient.tickratechanger.advanceTick(), VirtualKeybindings::isKeyDown))); + blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Recording/Playback Stop", "TASmod", Keyboard.KEY_F10, () -> TASmodClient.controller.setTASState(TASstate.NONE), VirtualKeybindings::isKeyDown))); blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Create Savestate", "TASmod", Keyboard.KEY_J, () -> { try { TASmodClient.client.send(new TASmodBufferBuilder(TASmodPackets.SAVESTATE_SAVE).writeInt(-1)); @@ -201,14 +195,14 @@ public void onClientInit(Minecraft mc) { blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Open InfoGui Editor", "TASmod", Keyboard.KEY_F6, () -> Minecraft.getMinecraft().displayGuiScreen(TASmodClient.hud)))); blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Various Testing", "TASmod", Keyboard.KEY_F12, () -> { TASmodClient.client.disconnect(); - }))); + }, VirtualKeybindings::isKeyDown))); blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Various Testing2", "TASmod", Keyboard.KEY_F7, () -> { try { TASmodClient.client = new Client("localhost", TASmod.networkingport-1, TASmodPackets.values(), mc.getSession().getProfile().getName(), true); } catch (Exception e) { e.printStackTrace(); } - }))); + }, VirtualKeybindings::isKeyDown))); blockedKeybindings.forEach(VirtualKeybindings::registerBlockedKeyBinding); createTASDir(); From 111e2ced1b8d60a44cd2c65186abce59037587cb Mon Sep 17 00:00:00 2001 From: Scribble Date: Sun, 4 Feb 2024 16:57:36 +0100 Subject: [PATCH 28/57] [VirtualInput] Fixed multiple issues copyFrom - Fixed unnecessary subtick generation when ignoreFirstUpdate was false - Fixed unnecessary subtick generation by not clearing the charlist of the next keyboard Characters - Fixed chat adding too many characters on a key press - Added support for repeat events Markers - Fixed logger failing in tests --- .../minecrafttas/mctcommon/Configuration.java | 1 - .../mctcommon/LanguageManager.java | 4 +- .../com/minecrafttas/tasmod/TASmodClient.java | 2 +- .../com/minecrafttas/tasmod/gui/InfoHud.java | 1 - .../tasmod/virtual/VirtualInput2.java | 47 +++++++++++++------ .../tasmod/virtual/VirtualKeyboard2.java | 32 ++++++++----- .../tasmod/virtual/VirtualPeripheral.java | 5 ++ .../java/tasmod/virtual/VirtualInputTest.java | 12 +++-- .../tasmod/virtual/VirtualKeyboardTest.java | 2 +- 9 files changed, 70 insertions(+), 36 deletions(-) diff --git a/src/main/java/com/minecrafttas/mctcommon/Configuration.java b/src/main/java/com/minecrafttas/mctcommon/Configuration.java index 8969a073..5d461f89 100644 --- a/src/main/java/com/minecrafttas/mctcommon/Configuration.java +++ b/src/main/java/com/minecrafttas/mctcommon/Configuration.java @@ -10,7 +10,6 @@ import java.util.Map; import java.util.Properties; -import org.apache.commons.io.FileUtils; /** * A very simple configuration class diff --git a/src/main/java/com/minecrafttas/mctcommon/LanguageManager.java b/src/main/java/com/minecrafttas/mctcommon/LanguageManager.java index 0cc90dfd..da3a4bce 100644 --- a/src/main/java/com/minecrafttas/mctcommon/LanguageManager.java +++ b/src/main/java/com/minecrafttas/mctcommon/LanguageManager.java @@ -88,7 +88,9 @@ private static HashMap loadJson(InputStream inputStream) { } Gson gson = new Gson(); HashMap template = new HashMap<>(); - HashMap out = (HashMap) gson.fromJson(new InputStreamReader(inputStream), template.getClass()); + + @SuppressWarnings("unchecked") + HashMap out = (HashMap) gson.fromJson(new InputStreamReader(inputStream), template.getClass()); out.forEach((key, value) -> { value = PATTERN.matcher(value).replaceAll("%$1s"); }); diff --git a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java index ea92d474..279b608b 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java @@ -126,7 +126,7 @@ public void onInitializeClient() { } else { config.reset(ConfigOptions.FileToOpen); } - virtual=new VirtualInput2(); //TODO Move fileOnStart to PlaybackController + virtual=new VirtualInput2(LOGGER); //TODO Move fileOnStart to PlaybackController // Initialize InfoHud hud = new InfoHud(); diff --git a/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java b/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java index f948bf5b..ae30b176 100644 --- a/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java +++ b/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java @@ -11,7 +11,6 @@ import org.apache.commons.lang3.tuple.Pair; import org.lwjgl.input.Keyboard; -import org.lwjgl.opengl.Display; import org.lwjgl.opengl.GL11; import com.minecrafttas.mctcommon.events.EventClient.EventClientTick; diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java index 62994df7..9ed658ac 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java @@ -1,17 +1,19 @@ package com.minecrafttas.tasmod.virtual; -import com.minecrafttas.tasmod.TASmod; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; + +import org.apache.logging.log4j.Logger; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + import com.minecrafttas.tasmod.mixin.playbackhooks.MixinMinecraft; import com.minecrafttas.tasmod.util.Ducks; import com.minecrafttas.tasmod.util.LoggerMarkers; import com.minecrafttas.tasmod.util.PointerNormalizer; -import net.minecraft.client.gui.GuiScreen; -import org.lwjgl.input.Keyboard; -import org.lwjgl.input.Mouse; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; +import net.minecraft.client.gui.GuiScreen; /** * Main component for redirecting inputs.
@@ -21,12 +23,13 @@ *
*/ public class VirtualInput2 { + private final Logger LOGGER; public final VirtualKeyboardInput KEYBOARD; public final VirtualMouseInput MOUSE; public final VirtualCameraAngleInput CAMERA_ANGLE; - public VirtualInput2() { - this(new VirtualKeyboard2(), new VirtualMouse2(), new VirtualCameraAngle2()); + public VirtualInput2(Logger logger) { + this(logger, new VirtualKeyboard2(), new VirtualMouse2(), new VirtualCameraAngle2()); } /** @@ -36,7 +39,8 @@ public VirtualInput2() { * @param preloadedMouse * @param preloadedCamera */ - public VirtualInput2(VirtualKeyboard2 preloadedKeyboard, VirtualMouse2 preloadedMouse, VirtualCameraAngle2 preloadedCamera) { + public VirtualInput2(Logger logger, VirtualKeyboard2 preloadedKeyboard, VirtualMouse2 preloadedMouse, VirtualCameraAngle2 preloadedCamera) { + this.LOGGER = logger; KEYBOARD = new VirtualKeyboardInput(preloadedKeyboard); MOUSE = new VirtualMouseInput(preloadedMouse); CAMERA_ANGLE = new VirtualCameraAngleInput(preloadedCamera); @@ -54,7 +58,7 @@ public VirtualInput2(VirtualKeyboard2 preloadedKeyboard, VirtualMouse2 preloaded */ public void update(GuiScreen currentScreen) { while (Keyboard.next()) { - KEYBOARD.updateNextKeyboard(Keyboard.getEventKey(), Keyboard.getEventKeyState(), Keyboard.getEventCharacter()); + KEYBOARD.updateNextKeyboard(Keyboard.getEventKey(), Keyboard.getEventKeyState(), Keyboard.getEventCharacter(), Keyboard.areRepeatEventsEnabled()); } while (Mouse.next()) { if (currentScreen == null) { @@ -194,10 +198,23 @@ public VirtualKeyboardInput(VirtualKeyboard2 preloadedKeyboard) { * @param character The character of this event */ public void updateNextKeyboard(int keycode, boolean keystate, char character) { - TASmod.LOGGER.debug(LoggerMarkers.Keyboard,"Update: {}, {}, {}, {}", keycode, keystate, character, Keyboard.areRepeatEventsEnabled()); - nextKeyboard.update(keycode, keystate, character); + updateNextKeyboard(keycode, keystate, character, false); } - + + /** + * Updates the next keyboard + * + * @see VirtualInput2#update(GuiScreen) + * @param keycode The keycode of this event + * @param keystate The keystate of this event + * @param character The character of this event + * @param repeatEventsEnabled If repeat events are enabled + */ + public void updateNextKeyboard(int keycode, boolean keystate, char character, boolean repeatEventsEnabled) { + LOGGER.debug(LoggerMarkers.Keyboard, "Update: {}, {}, {}, {}", keycode, keystate, character, repeatEventsEnabled); + nextKeyboard.update(keycode, keystate, character, repeatEventsEnabled); + } + /** * Runs when the next keyboard tick is about to occur.
* Used to load {@link #nextKeyboard} into {@link #currentKeyboard}, creating @@ -316,7 +333,7 @@ public VirtualMouseInput(VirtualMouse2 preloadedMouse) { public void updateNextMouse(int keycode, boolean keystate, int scrollwheel, Integer cursorX, Integer cursorY) { keycode-=100; - TASmod.LOGGER.debug(LoggerMarkers.Mouse,"Update: {} ({}), {}, {}", keycode, VirtualKey2.getName(keycode), keystate, scrollwheel, cursorX, cursorY); + LOGGER.debug(LoggerMarkers.Mouse,"Update: {} ({}), {}, {}", keycode, VirtualKey2.getName(keycode), keystate, scrollwheel, cursorX, cursorY); nextMouse.update(keycode, keystate, scrollwheel, cursorX, cursorY); } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java index f14f9091..c58734f2 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java @@ -3,6 +3,7 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Queue; import java.util.Set; @@ -84,7 +85,7 @@ public class VirtualKeyboard2 extends VirtualPeripheral implem * Creates an empty parent keyboard with all keys unpressed */ public VirtualKeyboard2() { - this(new HashSet<>(), new ArrayList<>(), new ArrayList<>(), true); + this(new LinkedHashSet<>(), new ArrayList<>(), new ArrayList<>(), true); } /** @@ -123,15 +124,19 @@ public VirtualKeyboard2(Set pressedKeys, List charList, List * @param keystate The keystate of this key, true for pressed * @param keycharacter The character that is associated with that key. Can change between keyboards or whenever shift is held in combination. */ - public void update(int keycode, boolean keystate, char keycharacter) { + public void update(int keycode, boolean keystate, char keycharacter, boolean repeatEventsEnabled) { if(isParent() && !ignoreFirstUpdate()) { addSubtick(clone()); } charList.clear(); - addChar(keycharacter); + addChar(keycharacter, repeatEventsEnabled); setPressed(keycode, keystate); } + public void update(int keycode, boolean keystate, char keycharacter) { + update(keycode, keystate, keycharacter, false); + } + @Override public void setPressed(int keycode, boolean keystate) { if (keycode >= 0) { // Keyboard keys always have a keycode larger or equal than 0 @@ -149,7 +154,6 @@ public void setPressed(int keycode, boolean keystate) { * @param reference The queue to fill. Passed in by reference. */ public void getDifference(VirtualKeyboard2 nextKeyboard, Queue reference) { - charQueue.addAll(nextKeyboard.charList); /* Calculate symmetric difference of keycodes */ @@ -161,11 +165,11 @@ public void getDifference(VirtualKeyboard2 nextKeyboard, Queue { + for(int key : pressedKeys) { if (!nextKeyboard.getPressedKeys().contains(key)) { reference.add(new VirtualKeyboardEvent(key, false, Character.MIN_VALUE)); } - }); + } /* Calculate pressed keys @@ -174,11 +178,13 @@ public void getDifference(VirtualKeyboard2 nextKeyboard, Queue { + int lastKey = 0; + for(int key : nextKeyboard.getPressedKeys()) { + lastKey = key; if (!this.pressedKeys.contains(key)) { reference.add(new VirtualKeyboardEvent(key, true, getOrMinChar(charQueue.poll()))); } - }); + } /* Add the rest of the characters as keyboard events. @@ -191,7 +197,7 @@ public void getDifference(VirtualKeyboard2 nextKeyboard, Queue Date: Sun, 4 Feb 2024 17:36:07 +0100 Subject: [PATCH 29/57] Update java requirement to 17 --- gradle.properties | 2 +- .../java/com/minecrafttas/tasmod/virtual/VirtualInput2.java | 2 +- src/main/resources/fabric.mod.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index 593c074c..a6f6a940 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,4 +16,4 @@ mod_email=scribble@minecrafttas.com # TASmod properties group=com.minecrafttas artifact=TASmod-1.12.2 -version=Beta1-SNAPSHOT +version=Beta1.0-SNAPSHOT diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java index 9ed658ac..2e1a1df9 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java @@ -211,7 +211,7 @@ public void updateNextKeyboard(int keycode, boolean keystate, char character) { * @param repeatEventsEnabled If repeat events are enabled */ public void updateNextKeyboard(int keycode, boolean keystate, char character, boolean repeatEventsEnabled) { - LOGGER.debug(LoggerMarkers.Keyboard, "Update: {}, {}, {}, {}", keycode, keystate, character, repeatEventsEnabled); + LOGGER.debug(LoggerMarkers.Keyboard, "Update: {}, {}, {}, {}", keycode, keystate, character); nextKeyboard.update(keycode, keystate, character, repeatEventsEnabled); } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index cf44a0fe..737e773b 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -32,6 +32,6 @@ "depends": { "fabricloader": ">=0.14.19", "minecraft": "1.12.2", - "java": ">=8" + "java": ">=17" } } \ No newline at end of file From e091afb2ce7397608bb40cd2d68775d98b504afa Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 5 Feb 2024 09:00:42 +0100 Subject: [PATCH 30/57] [VirtualInput] Fixed phantom press in keyboard, fixed mouse wheel - Removed cursor X and Y being nullable - Reordered getDifference and getVirtualEvents --- .../tasmod/virtual/VirtualInput.java | 4 +- .../tasmod/virtual/VirtualInput2.java | 18 +++---- .../tasmod/virtual/VirtualKeyboard2.java | 47 ++++++++--------- .../tasmod/virtual/VirtualMouse2.java | 51 ++++++++++--------- .../tasmod/virtual/VirtualMouseEvent.java | 22 ++++---- .../java/tasmod/virtual/VirtualInputTest.java | 20 ++++---- .../java/tasmod/virtual/VirtualMouseTest.java | 4 +- 7 files changed, 87 insertions(+), 79 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index 4c108f4f..1807f861 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -343,11 +343,11 @@ public int getEventMouseScrollWheel() { } public int getEventCursorX() { - return PointerNormalizer.getCoordsX(currentMouseEvent.getMouseX()); + return PointerNormalizer.getCoordsX(currentMouseEvent.getCursorX()); } public int getEventCursorY() { - return PointerNormalizer.getCoordsY(currentMouseEvent.getMouseY()); + return PointerNormalizer.getCoordsY(currentMouseEvent.getCursorY()); } public void clearNextMouse() { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java index 2e1a1df9..fc643200 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java @@ -35,9 +35,9 @@ public VirtualInput2(Logger logger) { /** * Creates a virtual input with pre-loaded values * - * @param preloadedKeyboard - * @param preloadedMouse - * @param preloadedCamera + * @param preloadedKeyboard A keyboard loaded at the beginning + * @param preloadedMouse A mouse loaded at the beginning + * @param preloadedCamera A camera loaded at the beginning */ public VirtualInput2(Logger logger, VirtualKeyboard2 preloadedKeyboard, VirtualMouse2 preloadedMouse, VirtualCameraAngle2 preloadedCamera) { this.LOGGER = logger; @@ -62,7 +62,7 @@ public void update(GuiScreen currentScreen) { } while (Mouse.next()) { if (currentScreen == null) { - MOUSE.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), null, null); + MOUSE.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), 0, 0); } else { Ducks.GuiScreenDuck screen = (Ducks.GuiScreenDuck) currentScreen; int eventX = screen.unscaleX(Mouse.getEventX()); @@ -306,7 +306,7 @@ public boolean willKeyBeDown(int keycode) { * {@linkplain #nextMouseTick()} * while({@linkplain #nextMouseSubtick}){ * int keycode = {@linkplain #getEventMouseKey}; - * boolean keystate = {@linkplain #getEventButtonState()}; + * boolean keystate = {@linkplain #getEventMouseState()} ()}; * int scrollWheel = {@linkplain #getEventMouseScrollWheel()} * int cursorX = {@linkplain #getEventCursorX()} // Important in GUIs * int cursorY = {@linkplain #getEventCursorY()} @@ -331,9 +331,9 @@ public VirtualMouseInput(VirtualMouse2 preloadedMouse) { currentMouse = preloadedMouse; } - public void updateNextMouse(int keycode, boolean keystate, int scrollwheel, Integer cursorX, Integer cursorY) { + public void updateNextMouse(int keycode, boolean keystate, int scrollwheel, int cursorX, int cursorY) { keycode-=100; - LOGGER.debug(LoggerMarkers.Mouse,"Update: {} ({}), {}, {}", keycode, VirtualKey2.getName(keycode), keystate, scrollwheel, cursorX, cursorY); + LOGGER.debug(LoggerMarkers.Mouse,"Update: {} ({}), {}, {}, {}, {}", keycode, VirtualKey2.getName(keycode), keystate, scrollwheel, cursorX, cursorY); nextMouse.update(keycode, keystate, scrollwheel, cursorX, cursorY); } @@ -359,11 +359,11 @@ public int getEventMouseScrollWheel() { } public int getEventCursorX() { - return PointerNormalizer.getCoordsX(currentMouseEvent.getMouseX()); + return PointerNormalizer.getCoordsX(currentMouseEvent.getCursorX()); } public int getEventCursorY() { - return PointerNormalizer.getCoordsY(currentMouseEvent.getMouseY()); + return PointerNormalizer.getCoordsY(currentMouseEvent.getCursorY()); } public boolean isKeyDown(int keycode) { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java index c58734f2..127f7928 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java @@ -129,7 +129,9 @@ public void update(int keycode, boolean keystate, char keycharacter, boolean rep addSubtick(clone()); } charList.clear(); - addChar(keycharacter, repeatEventsEnabled); + if (keystate) { + addChar(keycharacter, repeatEventsEnabled); + } setPressed(keycode, keystate); } @@ -144,6 +146,27 @@ public void setPressed(int keycode, boolean keystate) { } } + /** + * Calculates a list of {@link VirtualKeyboardEvent}s to the next peripheral, including + * the subticks. + * + * @see VirtualKeyboard2#getDifference(VirtualKeyboard2, Queue) + * + * @param nextKeyboard The peripheral that is comes after this one.
+ * If this one is loaded at tick 15, the nextPeripheral + * should be the one from tick 16 + * @param reference The queue to fill. Passed in by reference. + */ + public void getVirtualEvents(VirtualKeyboard2 nextKeyboard, Queue reference) { + if (isParent()) { + VirtualKeyboard2 currentSubtick = this; + for(VirtualKeyboard2 subtick : nextKeyboard.getAll()) { + currentSubtick.getDifference(subtick, reference); + currentSubtick = subtick; + } + } + } + /** * Calculates the difference between 2 keyboards via symmetric difference
* and returns a list of the changes between them in form of {@link VirtualKeyboardEvent}s @@ -209,27 +232,6 @@ private char getOrMinChar(Character charr){ return charr; } - /** - * Calculates a list of {@link VirtualKeyboardEvent}s to the next peripheral, including - * the subticks. - * - * @see VirtualKeyboard2#getDifference(VirtualKeyboard2, Queue) - * - * @param nextKeyboard The peripheral that is comes after this one.
- * If this one is loaded at tick 15, the nextPeripheral - * should be the one from tick 16 - * @param reference The queue to fill. Passed in by reference. - */ - public void getVirtualEvents(VirtualKeyboard2 nextKeyboard, Queue reference) { - if (isParent()) { - VirtualKeyboard2 currentSubtick = this; - for(VirtualKeyboard2 subtick : nextKeyboard.getAll()) { - currentSubtick.getDifference(subtick, reference); - currentSubtick = subtick; - } - } - } - /** * Add a character to the {@link #charList}
* Null characters will be discarded; @@ -305,7 +307,6 @@ public boolean equals(Object obj) { return super.equals(obj); } - public List getCharList() { return ImmutableList.copyOf(charList); } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java index 4acb4acf..ea4a755f 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java @@ -20,18 +20,18 @@ public class VirtualMouse2 extends VirtualPeripheral implements S * X coordinate of the on-screen cursor, used in GUI screens.
* When null, no change to the cursor is applied. */ - private Integer cursorX; + private int cursorX; /** * Y coordinate of the on-screen cursor, used in GUI screens.
* When null, no change to the cursor is applied. */ - private Integer cursorY; + private int cursorY; /** * Creates a mouse with no buttons pressed and no data */ public VirtualMouse2(){ - this(new HashSet<>(), 0, null, null, new ArrayList<>(), true); + this(new HashSet<>(), 0, 0, 0, new ArrayList<>(), true); } /** @@ -41,7 +41,7 @@ public VirtualMouse2(){ * @param cursorX The X coordinate of the cursor for this subtickMouse * @param cursorY The Y coordinate of the cursor for this subtickMouse */ - public VirtualMouse2(Set pressedKeys, int scrollWheel, Integer cursorX, Integer cursorY) { + public VirtualMouse2(Set pressedKeys, int scrollWheel, int cursorX, int cursorY) { this(pressedKeys, scrollWheel, cursorX, cursorY, null, false); } @@ -93,11 +93,25 @@ public void setPressed(int keycode, boolean keystate) { } } + public void getVirtualEvents(VirtualMouse2 nextMouse, Queue reference) { + if (isParent()) { + VirtualMouse2 currentSubtick = this; + for(VirtualMouse2 subtick : nextMouse.getAll()) { + currentSubtick.getDifference(subtick, reference); + currentSubtick = subtick; + } + } + } + public void getDifference(VirtualMouse2 nextPeripheral, Queue reference) { - int scrollWheelCopy = scrollWheel; - Integer cursorXCopy = cursorX; - Integer cursorYCopy = cursorY; + if(pressedKeys.equals(nextPeripheral.pressedKeys)){ + reference.add(new VirtualMouseEvent(VirtualKey2.MOUSEMOVED.getKeycode(), false, nextPeripheral.scrollWheel, nextPeripheral.cursorX, nextPeripheral.cursorY)); + return; + } + int scrollWheelCopy = nextPeripheral.scrollWheel; + int cursorXCopy = nextPeripheral.cursorX; + int cursorYCopy = nextPeripheral.cursorY; /* Calculate symmetric difference of keycodes */ @@ -112,8 +126,8 @@ public void getDifference(VirtualMouse2 nextPeripheral, Queue if (!nextPeripheral.getPressedKeys().contains(keycode)) { reference.add(new VirtualMouseEvent(keycode, false, scrollWheelCopy, cursorXCopy, cursorYCopy)); scrollWheelCopy = 0; - cursorXCopy = null; - cursorYCopy = null; + cursorXCopy = 0; + cursorYCopy = 0; } }; @@ -131,16 +145,6 @@ public void getDifference(VirtualMouse2 nextPeripheral, Queue }; } - public void getVirtualEvents(VirtualMouse2 nextMouse, Queue reference) { - if (isParent()) { - VirtualMouse2 currentSubtick = this; - for(VirtualMouse2 subtick : nextMouse.getAll()) { - currentSubtick.getDifference(subtick, reference); - currentSubtick = subtick; - } - } - } - @Override protected void clear() { super.clear(); @@ -149,8 +153,8 @@ protected void clear() { private void clearMouseData() { scrollWheel = 0; - cursorX = null; - cursorY = null; + cursorX = 0; + cursorY = 0; } @@ -181,6 +185,7 @@ protected void copyFrom(VirtualMouse2 mouse) { this.scrollWheel = mouse.scrollWheel; this.cursorX = mouse.cursorX; this.cursorY = mouse.cursorY; + mouse.clearMouseData(); } @Override @@ -199,11 +204,11 @@ public int getScrollWheel() { return scrollWheel; } - public Integer getCursorX() { + public int getCursorX() { return cursorX; } - public Integer getCursorY() { + public int getCursorY() { return cursorY; } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java index c7581cf6..36f15caa 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java @@ -9,33 +9,33 @@ */ public class VirtualMouseEvent extends VirtualButtonEvent { private final int scrollwheel; - private final Integer mouseX; - private final Integer mouseY; + private final int cursorX; + private final int cursorY; public VirtualMouseEvent(){ - this(0, false, 0, null, null); + this(0, false, 0, 0, 0); } - public VirtualMouseEvent(int keycode, boolean state, int scrollwheel, Integer mouseX, Integer mouseY) { + public VirtualMouseEvent(int keycode, boolean state, int scrollwheel, int cursorX, int cursorY) { super(keycode, state); this.scrollwheel = scrollwheel; - this.mouseX = mouseX; - this.mouseY = mouseY; + this.cursorX = cursorX; + this.cursorY = cursorY; } public int getScrollwheel() { return scrollwheel; } - public Integer getMouseX() { - return mouseX; + public Integer getCursorX() { + return cursorX; } - public Integer getMouseY() { - return mouseY; + public Integer getCursorY() { + return cursorY; } @Override public String toString() { - return String.format("%s, %s, %s, %s", super.toString(), scrollwheel, mouseX != null ? mouseX : " ", mouseY != null ? mouseY : " "); + return String.format("%s, %s, %s, %s", super.toString(), scrollwheel, cursorX, cursorY); } } diff --git a/src/test/java/tasmod/virtual/VirtualInputTest.java b/src/test/java/tasmod/virtual/VirtualInputTest.java index 833889b3..2d4a8cf7 100644 --- a/src/test/java/tasmod/virtual/VirtualInputTest.java +++ b/src/test/java/tasmod/virtual/VirtualInputTest.java @@ -17,7 +17,7 @@ class VirtualInputTest { - private Logger LOGGER = LogManager.getLogger("TASmod"); + private final Logger LOGGER = LogManager.getLogger("TASmod"); /** * Test constructor initializing keyboard, mouse and camera_angle @@ -41,7 +41,7 @@ void testPreloadedConstructor() { VirtualCameraAngle2 preloadedCameraAngle = new VirtualCameraAngle2(1f, 2f); preloadedKeyboard.update(VirtualKey2.W.getKeycode(), true, 'w'); - preloadedMouse.update(VirtualKey2.LC.getKeycode(), true, 15, null, null); + preloadedMouse.update(VirtualKey2.LC.getKeycode(), true, 15, 0, 0); VirtualInput2 virtual = new VirtualInput2(LOGGER, preloadedKeyboard, preloadedMouse, preloadedCameraAngle); @@ -50,9 +50,9 @@ void testPreloadedConstructor() { assertTrue(virtual.KEYBOARD.nextKeyboardSubtick()); assertEquals(VirtualKey2.W.getKeycode(), virtual.KEYBOARD.getEventKeyboardKey()); -// virtual.MOUSE.nextMouseTick(); -// assertTrue(virtual.MOUSE.nextMouseSubtick()); -// assertEquals(VirtualKey2.LC.getKeycode(), virtual.MOUSE.getEventMouseKey()); + virtual.MOUSE.nextMouseTick(); + assertTrue(virtual.MOUSE.nextMouseSubtick()); + assertEquals(VirtualKey2.LC.getKeycode(), virtual.MOUSE.getEventMouseKey()); assertEquals(1f, virtual.CAMERA_ANGLE.getPitch()); assertEquals(2f, virtual.CAMERA_ANGLE.getYaw()); @@ -80,7 +80,7 @@ void testKeyboardAddPresses() { // Read out values from the subtick assertEquals(VirtualKey2.W.getKeycode(), virtual.KEYBOARD.getEventKeyboardKey()); - assertEquals(true, virtual.KEYBOARD.getEventKeyboardState()); + assertTrue(virtual.KEYBOARD.getEventKeyboardState()); assertEquals('w', virtual.KEYBOARD.getEventKeyboardCharacter()); //A @@ -90,7 +90,7 @@ void testKeyboardAddPresses() { // Read out values from the subtick assertEquals(VirtualKey2.A.getKeycode(), virtual.KEYBOARD.getEventKeyboardKey()); - assertEquals(true, virtual.KEYBOARD.getEventKeyboardState()); + assertTrue(virtual.KEYBOARD.getEventKeyboardState()); assertEquals('a', virtual.KEYBOARD.getEventKeyboardCharacter()); //S @@ -107,6 +107,9 @@ void testKeyboardAddPresses() { assertFalse(virtual.KEYBOARD.nextKeyboardSubtick()); } + /** + * Test simulating button removals + */ @Test void testKeyboardRemovePresses() { VirtualKeyboard2 preloadedKeyboard = new VirtualKeyboard2(); @@ -116,7 +119,6 @@ void testKeyboardRemovePresses() { virtual.KEYBOARD.updateNextKeyboard(VirtualKey2.W.getKeycode(), false, Character.MIN_VALUE); - // Load the next keyboard events virtual.KEYBOARD.nextKeyboardTick(); @@ -125,7 +127,7 @@ void testKeyboardRemovePresses() { // Read out values from the subtick assertEquals(VirtualKey2.W.getKeycode(), virtual.KEYBOARD.getEventKeyboardKey()); - assertEquals(false, virtual.KEYBOARD.getEventKeyboardState()); + assertFalse(virtual.KEYBOARD.getEventKeyboardState()); assertEquals(Character.MIN_VALUE, virtual.KEYBOARD.getEventKeyboardCharacter()); // Check if subtick list is empty diff --git a/src/test/java/tasmod/virtual/VirtualMouseTest.java b/src/test/java/tasmod/virtual/VirtualMouseTest.java index 3efd1945..e7ce63c7 100644 --- a/src/test/java/tasmod/virtual/VirtualMouseTest.java +++ b/src/test/java/tasmod/virtual/VirtualMouseTest.java @@ -21,8 +21,8 @@ void testEmptyConstructor() { VirtualMouse2 actual = new VirtualMouse2(); assertTrue(actual.getPressedKeys().isEmpty()); assertEquals(0, actual.getScrollWheel()); - assertNull(actual.getCursorX()); - assertNull(actual.getCursorY()); + assertEquals(0, actual.getCursorX()); + assertEquals(0, actual.getCursorY()); assertTrue(actual.isParent()); } From 0b99d06354a73d92d0e543d89cb1169d0363b6f6 Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 5 Feb 2024 16:11:06 +0100 Subject: [PATCH 31/57] [VirtualInput] Added more tests to mouse - Fixed VirtualMouse#toString() missing the newest subtick - Switched to LinkedHashSet for Mouse to retain order --- .../tasmod/virtual/VirtualMouse2.java | 14 +- .../tasmod/virtual/VirtualKeyboardTest.java | 79 +++++++- .../java/tasmod/virtual/VirtualMouseTest.java | 184 +++++++++++++++++- 3 files changed, 251 insertions(+), 26 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java index ea4a755f..8b9d70a0 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java @@ -1,11 +1,7 @@ package com.minecrafttas.tasmod.virtual; import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Queue; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; public class VirtualMouse2 extends VirtualPeripheral implements Serializable { @@ -31,7 +27,7 @@ public class VirtualMouse2 extends VirtualPeripheral implements S * Creates a mouse with no buttons pressed and no data */ public VirtualMouse2(){ - this(new HashSet<>(), 0, 0, 0, new ArrayList<>(), true); + this(new LinkedHashSet<>(), 0, 0, 0, new ArrayList<>(), true); } /** @@ -42,7 +38,7 @@ public VirtualMouse2(){ * @param cursorY The Y coordinate of the cursor for this subtickMouse */ public VirtualMouse2(Set pressedKeys, int scrollWheel, int cursorX, int cursorY) { - this(pressedKeys, scrollWheel, cursorX, cursorY, null, false); + this(pressedKeys, scrollWheel, cursorX, cursorY, null); } /** @@ -161,7 +157,7 @@ private void clearMouseData() { @Override public String toString() { if (isParent()) { - return getSubticks().stream().map(VirtualMouse2::toString2).collect(Collectors.joining("\n")); + return getAll().stream().map(VirtualMouse2::toString2).collect(Collectors.joining("\n")); } else { return toString2(); } @@ -180,7 +176,7 @@ public VirtualMouse2 clone() { } @Override - protected void copyFrom(VirtualMouse2 mouse) { + public void copyFrom(VirtualMouse2 mouse) { super.copyFrom(mouse); this.scrollWheel = mouse.scrollWheel; this.cursorX = mouse.cursorX; diff --git a/src/test/java/tasmod/virtual/VirtualKeyboardTest.java b/src/test/java/tasmod/virtual/VirtualKeyboardTest.java index d5b6f4a6..399fb953 100644 --- a/src/test/java/tasmod/virtual/VirtualKeyboardTest.java +++ b/src/test/java/tasmod/virtual/VirtualKeyboardTest.java @@ -2,12 +2,7 @@ import static org.junit.jupiter.api.Assertions.*; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Queue; -import java.util.Set; +import java.util.*; import java.util.concurrent.ConcurrentLinkedQueue; import org.junit.jupiter.api.Test; @@ -129,7 +124,7 @@ void testAddCharacter(){ */ @Test void testToString(){ - Set testKeycodeSet = new HashSet<>(); + Set testKeycodeSet = new LinkedHashSet<>(); testKeycodeSet.add(VirtualKey2.W.getKeycode()); testKeycodeSet.add(VirtualKey2.S.getKeycode()); @@ -144,6 +139,19 @@ void testToString(){ assertEquals("W,S;", actual2.toString()); } + /** + * Test the toString method with subticks + */ + @Test + void testToStringSubticks(){ + VirtualKeyboard2 actual = new VirtualKeyboard2(); + + actual.update(VirtualKey2.W.getKeycode(), true, 'w'); + actual.update(VirtualKey2.S.getKeycode(), true, 's'); + + assertEquals("W;w\nW,S;s", actual.toString()); + } + /** * Test equals method */ @@ -212,10 +220,10 @@ void testClone() { } /** - * Test move from method + * Test copy from method */ @Test - void testMoveFrom(){ + void testCopyFrom(){ VirtualKeyboard2 copyFrom = new VirtualKeyboard2(); VirtualKeyboard2 actual = new VirtualKeyboard2(); @@ -233,6 +241,7 @@ void testMoveFrom(){ assertIterableEquals(expected.getCharList(), actual.getCharList()); assertTrue(copyFrom.getSubticks().isEmpty()); + assertTrue(copyFrom.getCharList().isEmpty()); } /** @@ -304,4 +313,56 @@ void testGetVirtualEventsUnpress() { assertIterableEquals(expected, actual); } + + /** + * Test repeat events enabled + */ + @Test + void testRepeatEvents(){ + VirtualKeyboard2 testKb = new VirtualKeyboard2(); + + int keycode = VirtualKey2.BACK.getKeycode(); + + // Update the keyboard multiple times with the same value + testKb.update(keycode, true, Character.MIN_VALUE, true); + testKb.update(keycode, true, Character.MIN_VALUE, true); + testKb.update(keycode, true, Character.MIN_VALUE, true); + + Queue actual = new ConcurrentLinkedQueue<>(); + // Fill "actual" with VirtualKeyboardEvents + new VirtualKeyboard2().getVirtualEvents(testKb, actual); + + List expected = new ArrayList<>(); + // Add expected VirtualKeyboardEvents + expected.add(new VirtualKeyboardEvent(keycode, true, Character.MIN_VALUE)); + expected.add(new VirtualKeyboardEvent(keycode, true, Character.MIN_VALUE)); + expected.add(new VirtualKeyboardEvent(keycode, true, Character.MIN_VALUE)); + + assertIterableEquals(expected, actual); + } + + /** + * Same as {@link #testRepeatEvents()} but with repeat events disabled + */ + @Test + void testRepeatEventsFail(){ + VirtualKeyboard2 testKb = new VirtualKeyboard2(); + + int keycode = VirtualKey2.BACK.getKeycode(); + // Update the keyboard multiple times with the same value. + testKb.update(keycode, true, Character.MIN_VALUE, false); + testKb.update(keycode, true, Character.MIN_VALUE, false); + testKb.update(keycode, true, Character.MIN_VALUE, false); + + Queue actual = new ConcurrentLinkedQueue<>(); + // Fill "actual" with VirtualKeyboardEvents + new VirtualKeyboard2().getVirtualEvents(testKb, actual); + + List expected = new ArrayList<>(); + + // Only one keyboard event should be added + expected.add(new VirtualKeyboardEvent(keycode, true, Character.MIN_VALUE)); + + assertIterableEquals(expected, actual); + } } diff --git a/src/test/java/tasmod/virtual/VirtualMouseTest.java b/src/test/java/tasmod/virtual/VirtualMouseTest.java index e7ce63c7..336f2a27 100644 --- a/src/test/java/tasmod/virtual/VirtualMouseTest.java +++ b/src/test/java/tasmod/virtual/VirtualMouseTest.java @@ -1,15 +1,13 @@ package tasmod.virtual; -import static org.junit.jupiter.api.Assertions.*; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -import org.junit.jupiter.api.Test; - import com.minecrafttas.tasmod.virtual.VirtualKey2; +import com.minecrafttas.tasmod.virtual.VirtualKeyboard2; import com.minecrafttas.tasmod.virtual.VirtualMouse2; +import org.junit.jupiter.api.Test; + +import java.util.*; + +import static org.junit.jupiter.api.Assertions.*; class VirtualMouseTest { @@ -55,4 +53,174 @@ void testSetPressedByKeycode(){ assertIterableEquals(Arrays.asList(VirtualKey2.LC.getKeycode()), actual.getPressedKeys()); assertTrue(actual.isParent()); } + + /** + * Test setting the keynames via setPressed to "pressed" + */ + @Test + void testSetPressedByKeyname(){ + VirtualMouse2 actual = new VirtualMouse2(); + actual.setPressed("LC", true); + + assertIterableEquals(Arrays.asList(VirtualKey2.LC.getKeycode()), actual.getPressedKeys()); + assertTrue(actual.isParent()); + } + + /** + * Test setting the keycodes via setPressed to "unpressed" + */ + @Test + void testSetUnPressedByKeycode(){ + Set testKeycodeSet = new HashSet<>(); + testKeycodeSet.add(VirtualKey2.LC.getKeycode()); + testKeycodeSet.add(VirtualKey2.MBUTTON9.getKeycode()); + VirtualMouse2 actual = new VirtualMouse2(testKeycodeSet, 0, 0, 0); + actual.setPressed(VirtualKey2.MBUTTON9.getKeycode(), false); + + assertIterableEquals(Arrays.asList(VirtualKey2.LC.getKeycode()), actual.getPressedKeys()); + } + + /** + * Test setting the keynames via setPressed to "unpressed" + */ + @Test + void testSetUnPressedByKeyname(){ + Set testKeycodeSet = new HashSet<>(); + testKeycodeSet.add(VirtualKey2.LC.getKeycode()); + testKeycodeSet.add(VirtualKey2.MBUTTON9.getKeycode()); + VirtualMouse2 actual = new VirtualMouse2(testKeycodeSet, 0, 0, 0); + actual.setPressed("MBUTTON9", false); + + assertIterableEquals(Arrays.asList(VirtualKey2.LC.getKeycode()), actual.getPressedKeys()); + } + + /** + * Test the toString method without subticks + */ + @Test + void testToString(){ + Set testKeycodeSet = new LinkedHashSet<>(); + testKeycodeSet.add(VirtualKey2.LC.getKeycode()); + testKeycodeSet.add(VirtualKey2.MC.getKeycode()); + + VirtualMouse2 actual = new VirtualMouse2(testKeycodeSet, 10, 100, 120); + + assertEquals("LC,MC;10,100,120", actual.toString()); + } + + /** + * Test the toString method with subticks + */ + @Test + void testToStringSubtick(){ + VirtualMouse2 actual = new VirtualMouse2(); + actual.update(VirtualKey2.LC.getKeycode(), true, 10, 100, 120); + actual.update(VirtualKey2.MC.getKeycode(), true, 0, 12, 3); + + assertEquals("LC;10,100,120\nLC,MC;0,12,3", actual.toString()); + } + + /** + * Test equals method + */ + @Test + void testEquals() { + Set testKeycodeSet = new HashSet<>(); + testKeycodeSet.add(VirtualKey2.W.getKeycode()); + testKeycodeSet.add(VirtualKey2.S.getKeycode()); + + + VirtualMouse2 actual = new VirtualMouse2(testKeycodeSet, -15, 129, 340); + VirtualMouse2 actual2 = new VirtualMouse2(testKeycodeSet, -15, 129, 340); + + assertEquals(actual, actual2); + } + + /** + * Test where equals will fail + */ + @Test + void testNotEquals() { + Set testKeycodeSet = new HashSet<>(); + testKeycodeSet.add(VirtualKey2.LC.getKeycode()); + + VirtualMouse2 actual = new VirtualMouse2(testKeycodeSet, -15, 1, 1); + + Set testKeycodeSet2 = new HashSet<>(); + testKeycodeSet.add(VirtualKey2.RC.getKeycode()); + VirtualMouse2 test2 = new VirtualMouse2(testKeycodeSet2, -15, 1, 1); + + + + VirtualMouse2 test3 = new VirtualMouse2(testKeycodeSet, -16, 1, 1); + + VirtualMouse2 test4 = new VirtualMouse2(testKeycodeSet, -15, 2, 1); + VirtualMouse2 test5 = new VirtualMouse2(testKeycodeSet, -15, 1, 2); + + assertNotEquals(actual, test2); + assertNotEquals(actual, test3); + assertNotEquals(actual, test4); + assertNotEquals(actual, test5); + assertNotEquals(actual, null); + } + + /** + * Test cloning the mouse + */ + @Test + void testClone() { + Set testKeycodeSet = new HashSet<>(); + testKeycodeSet.add(VirtualKey2.LC.getKeycode()); + testKeycodeSet.add(VirtualKey2.MC.getKeycode()); + + VirtualMouse2 actual = new VirtualMouse2(testKeycodeSet, 10, 3, 2); + VirtualMouse2 test2 = actual.clone(); + + assertEquals(actual, test2); + } + + /** + * Test copyFrom method + */ + @Test + void testCopyFrom() { + VirtualMouse2 copyFrom = new VirtualMouse2(); + VirtualMouse2 actual = new VirtualMouse2(); + + copyFrom.update(VirtualKey2.LC.getKeycode(), true, 0, 0, 0); + copyFrom.update(VirtualKey2.MOUSEMOVED.getKeycode(), false, 120, 10, 20); + + VirtualMouse2 expected = copyFrom.clone(); + + actual.update(VirtualKey2.MBUTTON12.getKeycode(), true, 0,0,0); + actual.update(VirtualKey2.MOUSEMOVED.getKeycode(), true, -120, -10, -10); + + actual.copyFrom(copyFrom); + + assertIterableEquals(expected.getPressedKeys(), actual.getPressedKeys()); + assertEquals(expected.getScrollWheel(), actual.getScrollWheel()); + assertEquals(expected.getCursorX(), actual.getCursorX()); + assertEquals(expected.getCursorY(), actual.getCursorY()); + + assertTrue(copyFrom.getSubticks().isEmpty()); + assertEquals(0, copyFrom.getScrollWheel()); + assertEquals(0, copyFrom.getCursorX()); + assertEquals(0, copyFrom.getCursorY()); + } + + /** + * Test subtick list being filled via update + */ + @Test + void testUpdate(){ + VirtualMouse2 actual = new VirtualMouse2(); + actual.update(VirtualKey2.LC.getKeycode(), true, -30, 118, 42); + actual.update(VirtualKey2.MOUSEMOVED.getKeycode(), false, 0, 23, 144); + + List expected = new ArrayList<>(); + expected.add(new VirtualMouse2(new HashSet(Arrays.asList(VirtualKey2.LC.getKeycode())), -30, 118, 42)); + expected.add(new VirtualMouse2(new HashSet(Arrays.asList(VirtualKey2.LC.getKeycode())), 0, 23, 144)); + + assertIterableEquals(expected, actual.getAll()); + } } From 625a9a370f4198449ae8cd34d050facde6d99b7d Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 5 Feb 2024 22:11:38 +0100 Subject: [PATCH 32/57] Reset java version to 8 --- build.gradle | 4 ++++ src/main/resources/fabric.mod.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index aa03ed92..7ba80f74 100644 --- a/build.gradle +++ b/build.gradle @@ -62,6 +62,10 @@ task downloadKTRNG(type: Copy) { into 'run/mods/' } +compileJava{ + options.release = 8 +} + // process fabric mod json processResources { inputs.property "version", project.version diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 737e773b..cf44a0fe 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -32,6 +32,6 @@ "depends": { "fabricloader": ">=0.14.19", "minecraft": "1.12.2", - "java": ">=17" + "java": ">=8" } } \ No newline at end of file From 09ebb2f56a86e307f39910a6d726194cb8a738b9 Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 6 Feb 2024 11:54:46 +0100 Subject: [PATCH 33/57] [VirtualInput] Moved and refactored MixinEntityRenderer --- .../tasmod/mixin/MixinEntityRenderer.java | 125 ------------------ .../tasmod/mixin/MixinMinecraft.java | 2 +- .../playbackhooks/MixinEntityRenderer.java | 124 +++++++++++++++++ .../com/minecrafttas/tasmod/util/Ducks.java | 2 +- src/main/resources/tasmod.mixin.json | 5 +- 5 files changed, 128 insertions(+), 130 deletions(-) delete mode 100644 src/main/java/com/minecrafttas/tasmod/mixin/MixinEntityRenderer.java create mode 100644 src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/MixinEntityRenderer.java b/src/main/java/com/minecrafttas/tasmod/mixin/MixinEntityRenderer.java deleted file mode 100644 index 7f25bd41..00000000 --- a/src/main/java/com/minecrafttas/tasmod/mixin/MixinEntityRenderer.java +++ /dev/null @@ -1,125 +0,0 @@ -package com.minecrafttas.tasmod.mixin; - -import org.lwjgl.input.Mouse; -import org.lwjgl.opengl.Display; -import org.objectweb.asm.Opcodes; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.At.Shift; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import com.minecrafttas.tasmod.TASmodClient; -import com.minecrafttas.tasmod.handlers.InterpolationHandler; -import com.minecrafttas.tasmod.util.Ducks.SubtickDuck; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.EntityRenderer; -import net.minecraft.util.math.MathHelper; - -@Mixin(EntityRenderer.class) -public class MixinEntityRenderer implements SubtickDuck { - - public double dX = 0; - public double dY = 0; - - @Shadow - private Minecraft mc; - @Shadow - private float smoothCamYaw; - @Shadow - private float smoothCamPitch; - @Shadow - private float smoothCamPartialTicks; - @Shadow - private float smoothCamFilterX; - @Shadow - private float smoothCamFilterY; - - @Inject(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/profiler/Profiler;startSection(Ljava/lang/String;)V", ordinal = 0, shift = Shift.AFTER)) - public void injectAtStartSection(float partialTicks, long nanoTime, CallbackInfo ci) { - // Calculate sensitivity - float f = this.mc.gameSettings.mouseSensitivity * 0.6F + 0.2F; - float f1 = f * f * f * 8.0F; - - // No Gui - if (this.mc.currentScreen == null) { - mc.mouseHelper.mouseXYChange(); - mc.getTutorial().handleMouse(mc.mouseHelper); - dX += mc.mouseHelper.deltaX; - dY += mc.mouseHelper.deltaY; - } else { - // In the gui - dX = 0; - dY = 0; - } - if (TASmodClient.controller.isPlayingback()) { - dX = 0; - dY = 0; - } else { - // Comment this out to disable interpolation, also comment out @SubscribeEvent - // in InterpolationEvents - if (this.mc.currentScreen == null) { - InterpolationHandler.rotationYaw = ((float) ((double) InterpolationHandler.rotationYaw + (double) mc.mouseHelper.deltaX * f1 * 0.15D)); - InterpolationHandler.rotationPitch = (float) ((double) InterpolationHandler.rotationPitch - (double) mc.mouseHelper.deltaY * f1 * 0.15D); - InterpolationHandler.rotationPitch = MathHelper.clamp(InterpolationHandler.rotationPitch, -90.0F, 90.0F); - } - } - } - - @Redirect(at = @At(value = "FIELD", target = "Lnet/minecraft/client/Minecraft;inGameHasFocus:Z", opcode = Opcodes.GETFIELD, ordinal = 1), method = "updateCameraAndRender") - public boolean stopVanilla(Minecraft mc) { - if (TASmodClient.tickratechanger.ticksPerSecond != 0) { - return false; - } else { - return mc.inGameHasFocus; - } - } - - @Override - public void runSubtick(float partialTicks) { - boolean flag = Display.isActive(); - if (flag && Minecraft.IS_RUNNING_ON_MAC && mc.inGameHasFocus && !Mouse.isInsideWindow()) { - Mouse.setGrabbed(false); - Mouse.setCursorPosition(Display.getWidth() / 2, Display.getHeight() / 2 - 20); - Mouse.setGrabbed(true); - } - - if (mc.inGameHasFocus && flag) { - mc.getTutorial().handleMouse(mc.mouseHelper); - float f = mc.gameSettings.mouseSensitivity * 0.6F + 0.2F; - float f1 = f * f * f * 8.0F; - float f2 = (float) dX * f1; - float f3 = (float) dY * f1; - int i = 1; - - dX = 0; - dY = 0; - - if (mc.gameSettings.invertMouse) { - i = -1; - } - - if (mc.gameSettings.smoothCamera) { - smoothCamYaw += f2; - smoothCamPitch += f3; - float f4 = partialTicks - smoothCamPartialTicks; - smoothCamPartialTicks = partialTicks; - f2 = smoothCamFilterX * f4; - f3 = smoothCamFilterY * f4; - mc.player.turn(f2, f3 * (float) i); - } else { - smoothCamYaw = 0.0F; - smoothCamPitch = 0.0F; - mc.player.turn(f2, f3 * (float) i); - } - TASmodClient.virtual.CAMERA_ANGLE.updateCameraAngle(mc.player.rotationPitch, mc.player.rotationYaw); - mc.player.rotationPitch = TASmodClient.virtual.CAMERA_ANGLE.getPitch(); - mc.player.rotationYaw = TASmodClient.virtual.CAMERA_ANGLE.getYaw(); - InterpolationHandler.rotationPitch = mc.player.rotationPitch; - InterpolationHandler.rotationYaw = 180f + mc.player.rotationYaw; - } - } -} diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java index 643deb14..d6acae24 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java @@ -49,7 +49,7 @@ public void injectRunGameLoop(CallbackInfo ci) { @Redirect(method = "runGameLoop", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;runTick()V")) public void redirectRunTick(Minecraft mc) { if (TASmodClient.tickratechanger.ticksPerSecond != 0) { - ((SubtickDuck) this.entityRenderer).runSubtick(this.isGamePaused ? this.renderPartialTicksPaused : this.timer.renderPartialTicks); + ((SubtickDuck) this.entityRenderer).runUpdate(this.isGamePaused ? this.renderPartialTicksPaused : this.timer.renderPartialTicks); } this.runTick(); TASmodClient.tickSchedulerClient.runAllTasks(); diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java new file mode 100644 index 00000000..c556a640 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java @@ -0,0 +1,124 @@ +package com.minecrafttas.tasmod.mixin.playbackhooks; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.minecrafttas.tasmod.TASmodClient; +import com.minecrafttas.tasmod.handlers.InterpolationHandler; +import com.minecrafttas.tasmod.util.Ducks.SubtickDuck; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.EntityRenderer; +import net.minecraft.util.math.MathHelper; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.Display; +import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +/** + * Redirects the camera to use {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualCameraAngleInput}.
+ * Also conforms the camera to 20tps as + */ +@Mixin(EntityRenderer.class) +public class MixinEntityRenderer implements SubtickDuck { + + @Shadow + private Minecraft mc; + @Shadow + private float smoothCamYaw; + @Shadow + private float smoothCamPitch; + @Shadow + private float smoothCamPartialTicks; + @Shadow + private float smoothCamFilterX; + @Shadow + private float smoothCamFilterY; + + @Unique + private int dX; + @Unique + private int dY; + + @Inject(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/profiler/Profiler;startSection(Ljava/lang/String;)V", ordinal = 0, shift = At.Shift.AFTER)) + public void playback_injectAtStartSection(float partialTicks, long nanoTime, CallbackInfo ci) { + // Calculate sensitivity + float f = this.mc.gameSettings.mouseSensitivity * 0.6F + 0.2F; + float f1 = f * f * f * 8.0F; + + if (this.mc.currentScreen == null) { // No Gui + mc.mouseHelper.mouseXYChange(); + mc.getTutorial().handleMouse(mc.mouseHelper); + dX += mc.mouseHelper.deltaX; + dY += mc.mouseHelper.deltaY; + } else { // In the gui + dX = 0; + dY = 0; + } + + if (TASmodClient.controller.isPlayingback()) { + dX = 0; + dY = 0; + } else { + // Comment this out to disable interpolation, also comment out @SubscribeEvent + // in InterpolationEvents + if (this.mc.currentScreen == null) { + InterpolationHandler.rotationYaw = ((float) ((double) InterpolationHandler.rotationYaw + (double) mc.mouseHelper.deltaX * f1 * 0.15D)); + InterpolationHandler.rotationPitch = (float) ((double) InterpolationHandler.rotationPitch - (double) mc.mouseHelper.deltaY * f1 * 0.15D); + InterpolationHandler.rotationPitch = MathHelper.clamp(InterpolationHandler.rotationPitch, -90.0F, 90.0F); + } + } + } + + @ModifyExpressionValue(method = "updateCameraAndRender", at = @At(value = "FIELD", target = "Lnet/minecraft/client/Minecraft;inGameHasFocus:Z", opcode = Opcodes.GETFIELD)) + public boolean playback_stopVanilla(boolean original){ + return original && TASmodClient.tickratechanger.ticksPerSecond == 0; + } + + @Override + public void runUpdate(float partialTicks) { + boolean flag = Display.isActive(); + if (flag && Minecraft.IS_RUNNING_ON_MAC && mc.inGameHasFocus && !Mouse.isInsideWindow()) { + Mouse.setGrabbed(false); + Mouse.setCursorPosition(Display.getWidth() / 2, Display.getHeight() / 2 - 20); + Mouse.setGrabbed(true); + } + + if (mc.inGameHasFocus && flag) { + mc.getTutorial().handleMouse(mc.mouseHelper); + float f = mc.gameSettings.mouseSensitivity * 0.6F + 0.2F; + float f1 = f * f * f * 8.0F; + float f2 = (float) dX * f1; + float f3 = (float) dY * f1; + int i = 1; + + dX = 0; + dY = 0; + + if (mc.gameSettings.invertMouse) { + i = -1; + } + + if (mc.gameSettings.smoothCamera) { + smoothCamYaw += f2; + smoothCamPitch += f3; + float f4 = partialTicks - smoothCamPartialTicks; + smoothCamPartialTicks = partialTicks; + f2 = smoothCamFilterX * f4; + f3 = smoothCamFilterY * f4; + mc.player.turn(f2, f3 * (float) i); + } else { + smoothCamYaw = 0.0F; + smoothCamPitch = 0.0F; + mc.player.turn(f2, f3 * (float) i); + } + TASmodClient.virtual.CAMERA_ANGLE.updateCameraAngle(mc.player.rotationPitch, mc.player.rotationYaw); + mc.player.rotationPitch = TASmodClient.virtual.CAMERA_ANGLE.getPitch(); + mc.player.rotationYaw = TASmodClient.virtual.CAMERA_ANGLE.getYaw(); + InterpolationHandler.rotationPitch = mc.player.rotationPitch; + InterpolationHandler.rotationYaw = 180f + mc.player.rotationYaw; + } + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/util/Ducks.java b/src/main/java/com/minecrafttas/tasmod/util/Ducks.java index 4362b02c..5b785a6a 100644 --- a/src/main/java/com/minecrafttas/tasmod/util/Ducks.java +++ b/src/main/java/com/minecrafttas/tasmod/util/Ducks.java @@ -81,7 +81,7 @@ public static interface GuiScreenDuck { * Quacks the subtick */ public static interface SubtickDuck { - public abstract void runSubtick(float partialTicks); + void runUpdate(float partialTicks); } } diff --git a/src/main/resources/tasmod.mixin.json b/src/main/resources/tasmod.mixin.json index c6b05aa5..2a2edb4a 100644 --- a/src/main/resources/tasmod.mixin.json +++ b/src/main/resources/tasmod.mixin.json @@ -27,7 +27,6 @@ //General "MixinMinecraft", "MixinTimer", - "MixinEntityRenderer", "MixinGuiScreen", "MixinInGameHud", @@ -40,14 +39,13 @@ //Keybinding "MixinTextfield", - "fixes.MixinMinecraftFullscreen", - //Join and leave game event on the client "events.MixinGuiMainMenu", "events.MixinGuiIngame", //Playbackhooks "playbackhooks.MixinMinecraft", + "playbackhooks.MixinEntityRenderer", "playbackhooks.MixinGameSettings", "playbackhooks.MixinGuiChat", "playbackhooks.MixinGuiClickableScrolledSelectionListProxy", @@ -63,6 +61,7 @@ "shields.MixinTileEntityItemStackRenderer", //Fixes + "fixes.MixinMinecraftFullscreen", "fixes.MixinNetworkManager" ] } \ No newline at end of file From 960a050089569bb564bb7e02e094600c217a9f00 Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 6 Feb 2024 22:52:50 +0100 Subject: [PATCH 34/57] Removed Forge-KTRNG as a dependency --- build.gradle | 18 +++++---- gradle.properties | 4 +- .../tasmod/ktrng/KTRNGMonitor.java | 3 +- .../tasmod/ktrng/KillTheRNGHandler.java | 38 +++++++++---------- .../tasmod/monitoring/DesyncMonitoring.java | 7 ++-- 5 files changed, 34 insertions(+), 36 deletions(-) diff --git a/build.gradle b/build.gradle index 7ba80f74..aff6995f 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,8 @@ configurations { dependencies { // tasmod dependencies embed group: 'com.dselent', name: 'bigarraylist', version: '1.1' - compileOnly group: 'com.minecrafttas', name: 'killtherng', version: '2.0' - downloadMod group: 'com.minecrafttas', name: 'killtherng-full', version: '2.0' // for downloadKTRNG task + //compileOnly group: 'com.minecrafttas', name: 'killtherng', version: '2.0' + //downloadMod group: 'com.minecrafttas', name: 'killtherng-full', version: '2.0' // for downloadKTRNG task // loom dependencies minecraft "com.mojang:minecraft:${project.minecraft_version}" @@ -54,13 +54,15 @@ dependencies { testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0' } + + // task for downloading KillTheRng -task downloadKTRNG(type: Copy) { - group 'tasmod' - description 'Download KillTheRNG to the run/mods/ folder of the project' - from configurations.downloadMod - into 'run/mods/' -} +//task downloadKTRNG(type: Copy) { + //group 'tasmod' + //description 'Download KillTheRNG to the run/mods/ folder of the project' + //from configurations.downloadMod + //into 'run/mods/' +//} compileJava{ options.release = 8 diff --git a/gradle.properties b/gradle.properties index a6f6a940..59afe362 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,8 +3,8 @@ org.gradle.jvmargs=-Xmx3G # Fabric properties minecraft_version=1.12.2 -loader_version=0.15.3 -loom_version=1.4-SNAPSHOT +loader_version=0.15.6 +loom_version=1.5-SNAPSHOT # Mod properties mod_name=Tool-Assisted Speedrun Mod diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGMonitor.java b/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGMonitor.java index 33778934..0a16d9e9 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGMonitor.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGMonitor.java @@ -1,10 +1,9 @@ package com.minecrafttas.tasmod.ktrng; -import com.minecrafttas.killtherng.custom.EventAnnotations.CaptureRandomness; public class KTRNGMonitor { - @CaptureRandomness(name = "jukeboxRecordDropPosition") +// @CaptureRandomness(name = "jukeboxRecordDropPosition") public static void monitor(long seed, String value) { // System.out.println(String.format("Seed: %s, Value: %s", seed, value)); } diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/KillTheRNGHandler.java b/src/main/java/com/minecrafttas/tasmod/ktrng/KillTheRNGHandler.java index 2cd67bb8..309644e5 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/KillTheRNGHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/KillTheRNGHandler.java @@ -4,8 +4,6 @@ import java.nio.ByteBuffer; -import com.minecrafttas.killtherng.KillTheRNG; -import com.minecrafttas.killtherng.SeedingModes; import com.minecrafttas.mctcommon.events.EventClient.EventPlayerJoinedClientSide; import com.minecrafttas.mctcommon.events.EventServer.EventServerTick; import com.minecrafttas.mctcommon.server.Client.Side; @@ -45,30 +43,30 @@ public KillTheRNGHandler(boolean isLoaded) { this.isLoaded = isLoaded; if (isLoaded) { - KillTheRNG.LOGGER.info("Connection established with TASmod"); - KillTheRNG.isLibrary = true; - KillTheRNG.mode = SeedingModes.TickChange; - - KillTheRNG.annotations.register(new KTRNGMonitor()); +// KillTheRNG.LOGGER.info("Connection established with TASmod"); +// KillTheRNG.isLibrary = true; +// KillTheRNG.mode = SeedingModes.TickChange; +// +// KillTheRNG.annotations.register(new KTRNGMonitor()); } else { LOGGER.info("KillTheRNG doesn't appear to be loaded"); } } public long advanceGlobalSeedServer() { - if (isLoaded()) { - return KillTheRNG.commonRandom.nextSeed(); - } else { +// if (isLoaded()) { +// return KillTheRNG.commonRandom.nextSeed(); +// } else { return 0; - } +// } } public long getGlobalSeedServer() { - if (isLoaded()) { - return KillTheRNG.commonRandom.GlobalServer.getSeed(); - } else { +// if (isLoaded()) { +// return KillTheRNG.commonRandom.GlobalServer.getSeed(); +// } else { return 0; - } +// } } public boolean isLoaded() { @@ -81,9 +79,9 @@ public boolean isLoaded() { */ @Environment(EnvType.CLIENT) public long getGlobalSeedClient() { - if (isLoaded()) - return KillTheRNG.clientRandom.GlobalClient.getSeed(); - else +// if (isLoaded()) +// return KillTheRNG.clientRandom.GlobalClient.getSeed(); +// else return 0; } @@ -95,13 +93,13 @@ public long getGlobalSeedClient() { @Environment(EnvType.CLIENT) public void setGlobalSeedClient(long seedIn) { if (isLoaded()) { - KillTheRNG.clientRandom.setSeedAll(seedIn); +// KillTheRNG.clientRandom.setSeedAll(seedIn); } } public void setGlobalSeedServer(long seedIn) { if (isLoaded()) { - KillTheRNG.commonRandom.setSeedAll(seedIn); +// KillTheRNG.commonRandom.setSeedAll(seedIn); } } diff --git a/src/main/java/com/minecrafttas/tasmod/monitoring/DesyncMonitoring.java b/src/main/java/com/minecrafttas/tasmod/monitoring/DesyncMonitoring.java index 4baeebde..4cf26ba6 100644 --- a/src/main/java/com/minecrafttas/tasmod/monitoring/DesyncMonitoring.java +++ b/src/main/java/com/minecrafttas/tasmod/monitoring/DesyncMonitoring.java @@ -6,7 +6,6 @@ import java.util.List; import com.dselent.bigarraylist.BigArrayList; -import com.minecrafttas.killtherng.custom.CustomRandom; import com.minecrafttas.tasmod.TASmod; import com.minecrafttas.tasmod.playback.PlaybackControllerClient; @@ -184,7 +183,7 @@ public String getSeed() { lastSeed = ""; } else { if(TASmod.ktrngHandler.isLoaded()) { - long distance = CustomRandom.distance(currentValues.seed, TASmod.ktrngHandler.getGlobalSeedClient()); + long distance = 0; //CustomRandom.distance(currentValues.seed, TASmod.ktrngHandler.getGlobalSeedClient()); if(distance == 0L) { lastSeed = ""; } else { @@ -244,9 +243,9 @@ public DesyncStatus getSeverity(int index, double[] playerValues, long seed) { if(this.seed != seed) { if(TASmod.ktrngHandler.isLoaded()) { - if(CustomRandom.distance(this.seed, seed)!=1) { +// if(CustomRandom.distance(this.seed, seed)!=1) { return DesyncStatus.SEED; - } +// } } else { return DesyncStatus.SEED; } From 21160877c7ec173aaa3f417acdc364dd4592ed96 Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 6 Feb 2024 22:54:03 +0100 Subject: [PATCH 35/57] Removed unnecessary refmap attributes --- build.gradle | 2 -- src/main/resources/mctcommon.mixin.json | 1 - src/main/resources/tasmod.mixin.json | 1 - 3 files changed, 4 deletions(-) diff --git a/build.gradle b/build.gradle index aff6995f..9a6b90ea 100644 --- a/build.gradle +++ b/build.gradle @@ -19,8 +19,6 @@ loom { // add log4jconfig log4jConfigs.from(file('src/main/resources/log4j.xml')) - // default refmap name - mixin.defaultRefmapName = "tasmod.refmap.json" } // dependency repositories diff --git a/src/main/resources/mctcommon.mixin.json b/src/main/resources/mctcommon.mixin.json index f070f007..40ea9253 100644 --- a/src/main/resources/mctcommon.mixin.json +++ b/src/main/resources/mctcommon.mixin.json @@ -2,7 +2,6 @@ "required": true, "minVersion": "0.8.5", "package": "com.minecrafttas.mctcommon.mixin", - "refmap": "tasmod.refmap.json", "compatibilityLevel": "JAVA_8", "mixins": [ "MixinMinecraftServer", diff --git a/src/main/resources/tasmod.mixin.json b/src/main/resources/tasmod.mixin.json index 2a2edb4a..115acd31 100644 --- a/src/main/resources/tasmod.mixin.json +++ b/src/main/resources/tasmod.mixin.json @@ -2,7 +2,6 @@ "required": true, "minVersion": "0.8.5", "package": "com.minecrafttas.tasmod.mixin", - "refmap": "tasmod.refmap.json", "compatibilityLevel": "JAVA_8", "mixins": [ From 297be0b9d19b85401dca818da2e8ba0f0fd5bf0c Mon Sep 17 00:00:00 2001 From: Scribble Date: Wed, 7 Feb 2024 22:23:35 +0100 Subject: [PATCH 36/57] [VirtualInput] Finished mouse documentation and tests - Moved MixinGuiScreen to package playbackhooks - Removed serial warnings in Exceptions --- .../exception/InvalidPacketException.java | 1 - .../PacketNotImplementedException.java | 1 - .../playbackhooks/MixinGameSettings.java | 14 +- .../mixin/playbackhooks/MixinGuiChat.java | 3 + ...uiClickableScrolledSelectionListProxy.java | 4 + .../playbackhooks/MixinGuiContainer.java | 13 +- .../{ => playbackhooks}/MixinGuiScreen.java | 26 ++- .../mixin/playbackhooks/MixinMinecraft.java | 52 ++++-- .../tasmod/virtual/VirtualInput2.java | 122 ++++++++++-- .../tasmod/virtual/VirtualKeyboard2.java | 46 +++-- .../tasmod/virtual/VirtualMouse2.java | 48 ++++- .../tasmod/virtual/VirtualMouseEvent.java | 70 ++++--- src/main/resources/tasmod.mixin.json | 2 +- .../java/tasmod/virtual/VirtualMouseTest.java | 173 +++++++++++++++++- 14 files changed, 475 insertions(+), 100 deletions(-) rename src/main/java/com/minecrafttas/tasmod/mixin/{ => playbackhooks}/MixinGuiScreen.java (86%) diff --git a/src/main/java/com/minecrafttas/mctcommon/server/exception/InvalidPacketException.java b/src/main/java/com/minecrafttas/mctcommon/server/exception/InvalidPacketException.java index ae1fef9e..fa8e389b 100644 --- a/src/main/java/com/minecrafttas/mctcommon/server/exception/InvalidPacketException.java +++ b/src/main/java/com/minecrafttas/mctcommon/server/exception/InvalidPacketException.java @@ -1,6 +1,5 @@ package com.minecrafttas.mctcommon.server.exception; -@SuppressWarnings("serial") public class InvalidPacketException extends Exception { public InvalidPacketException() { diff --git a/src/main/java/com/minecrafttas/mctcommon/server/exception/PacketNotImplementedException.java b/src/main/java/com/minecrafttas/mctcommon/server/exception/PacketNotImplementedException.java index 2731c798..95365017 100644 --- a/src/main/java/com/minecrafttas/mctcommon/server/exception/PacketNotImplementedException.java +++ b/src/main/java/com/minecrafttas/mctcommon/server/exception/PacketNotImplementedException.java @@ -4,7 +4,6 @@ import com.minecrafttas.mctcommon.server.interfaces.PacketHandlerBase; import com.minecrafttas.mctcommon.server.interfaces.PacketID; -@SuppressWarnings("serial") public class PacketNotImplementedException extends Exception { public PacketNotImplementedException(String msg) { diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGameSettings.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGameSettings.java index 6bd5398f..7c01c628 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGameSettings.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGameSettings.java @@ -11,12 +11,24 @@ @Mixin(GameSettings.class) public class MixinGameSettings { - + + /** + * Redirect Mouse.isButtonDown in keybindings + * @param i The keycode + * @param key The keybinding + * @return Whether the key is down + */ @Redirect(method = "isKeyDown", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;isButtonDown(I)Z", remap = false)) private static boolean redirectIsKeyDown1(int i, KeyBinding key) { return TASmodClient.virtual.isKeyDown(i + 100); } + /** + * Redirect Keyboard.isKeyDown in keybindings + * @param i The keycode + * @param key The keybinding + * @return Whether the key is down + */ @Redirect(method = "isKeyDown", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;isKeyDown(I)Z", remap = false)) private static boolean redirectIsKeyDown2(int i, KeyBinding key) { return TASmodClient.virtual.isKeyDown(i); diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiChat.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiChat.java index 2df94994..7b76c7eb 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiChat.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiChat.java @@ -10,6 +10,9 @@ @Mixin(GuiChat.class) public class MixinGuiChat { + /** + * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualMouseInput#getEventMouseScrollWheel()} + */ @Redirect(method = "handleMouseInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventDWheel()I", remap = false)) public int redirectHandleMouseInput4() { return TASmodClient.virtual.MOUSE.getEventMouseScrollWheel(); diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiClickableScrolledSelectionListProxy.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiClickableScrolledSelectionListProxy.java index fb3f84ec..40d6c916 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiClickableScrolledSelectionListProxy.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiClickableScrolledSelectionListProxy.java @@ -10,6 +10,10 @@ @Mixin(GuiClickableScrolledSelectionListProxy.class) public class MixinGuiClickableScrolledSelectionListProxy { + + /** + * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualMouseInput#getEventMouseState()} + */ @Redirect(method = "handleMouseInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventButtonState()Z", ordinal = 0, remap = false)) public boolean redirectHandleMouseInput() { return TASmodClient.virtual.MOUSE.getEventMouseState(); diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiContainer.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiContainer.java index 14d1636c..106a88ed 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiContainer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiContainer.java @@ -5,6 +5,7 @@ import org.spongepowered.asm.mixin.injection.Redirect; import com.minecrafttas.tasmod.TASmodClient; +import com.minecrafttas.tasmod.virtual.VirtualKey2; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; @@ -13,11 +14,21 @@ @Mixin(GuiContainer.class) public class MixinGuiContainer { + /** + * Redirects the check for {@link VirtualKey2#LSHIFT} and {@link VirtualKey2#RSHIFT} in mouseClicked + * @param i The keycode to check for + * @return If the keycode is down + */ @Redirect(method = "mouseClicked", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;isKeyDown(I)Z", ordinal = 0, remap = false)) private boolean redirectIsKeyDown(int i) { return TASmodClient.virtual.isKeyDown(i); } + /** + * Redirects the check for {@link VirtualKey2#LSHIFT} and {@link VirtualKey2#RSHIFT} in mouseReleased + * @param i The keycode to check for + * @return If the keycode is down + */ @Redirect(method = "mouseReleased", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;isKeyDown(I)Z", ordinal = 0, remap = false)) private boolean redirectIsKeyDown2(int i) { return TASmodClient.virtual.isKeyDown(i); @@ -25,7 +36,7 @@ private boolean redirectIsKeyDown2(int i) { /** * Fixes #67 - * @param player + * @param player The current player */ @Redirect(method = "keyTyped", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;closeScreen()V")) public void redirectCloseScreen(EntityPlayerSP player) { diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/MixinGuiScreen.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiScreen.java similarity index 86% rename from src/main/java/com/minecrafttas/tasmod/mixin/MixinGuiScreen.java rename to src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiScreen.java index 0ced5b29..1cfb45c7 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/MixinGuiScreen.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiScreen.java @@ -1,6 +1,5 @@ -package com.minecrafttas.tasmod.mixin; +package com.minecrafttas.tasmod.mixin.playbackhooks; -import org.lwjgl.input.Mouse; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -11,6 +10,8 @@ import com.minecrafttas.tasmod.TASmodClient; import com.minecrafttas.tasmod.util.Ducks.GuiScreenDuck; +import com.minecrafttas.tasmod.virtual.VirtualInput2; +import com.minecrafttas.tasmod.virtual.VirtualKeyboardEvent; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; @@ -18,22 +19,27 @@ @Mixin(GuiScreen.class) public class MixinGuiScreen implements GuiScreenDuck { - // ===================================================================================================================================== - + /** + * Run at the start of run handleInput. Runs every tick. + * @see com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#nextKeyboardTick() + * @param ci CBI + */ @Inject(method = "handleInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;isCreated()Z", shift = Shift.AFTER, remap = false)) public void injectAfterKeyboardCreated(CallbackInfo ci) { TASmodClient.virtual.KEYBOARD.nextKeyboardTick(); } - // ===================================================================================================================================== - + /** + * Redirects a {@link org.lwjgl.input.Keyboard#next()}. Starts running every tick and continues as long as there are {@link VirtualKeyboardEvent}s in {@link VirtualInput2} + * @see com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#nextKeyboardSubtick() + * @return If {@link VirtualKeyboardEvent}s are present in {@link VirtualInput2} + */ @Redirect(method = "handleInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;next()Z", remap = false)) public boolean redirectKeyboardNext() { return TASmodClient.virtual.KEYBOARD.nextKeyboardSubtick(); } - // ===================================================================================================================================== - + @Redirect(method = "handleKeyboardInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventCharacter()C", remap = false)) public char redirectGetEventCharacter() { return TASmodClient.virtual.KEYBOARD.getEventKeyboardCharacter(); @@ -78,8 +84,8 @@ public int redirectGetEventButton() { @Redirect(method = "handleMouseInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventButtonState()Z", remap = false)) public boolean redirectGetEventButtonState() { - if (TASmodClient.controller.isPlayingback()) { - Mouse.setCursorPosition(rescaleX(TASmodClient.virtual.MOUSE.getEventCursorX()), rescaleY(TASmodClient.virtual.MOUSE.getEventCursorY())); + if (TASmodClient.controller.isPlayingback()) { // TODO replace with event + org.lwjgl.input.Mouse.setCursorPosition(rescaleX(TASmodClient.virtual.MOUSE.getEventCursorX()), rescaleY(TASmodClient.virtual.MOUSE.getEventCursorY())); } return TASmodClient.virtual.MOUSE.getEventMouseState(); } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java index 02dbc3c8..07885e89 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java @@ -1,6 +1,5 @@ package com.minecrafttas.tasmod.mixin.playbackhooks; -import org.lwjgl.input.Keyboard; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -10,7 +9,9 @@ import com.minecrafttas.tasmod.TASmodClient; import com.minecrafttas.tasmod.virtual.VirtualInput2; +import com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualMouseInput; import com.minecrafttas.tasmod.virtual.VirtualKeyboardEvent; +import com.minecrafttas.tasmod.virtual.VirtualMouseEvent; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; @@ -31,8 +32,11 @@ public void playback_injectRunGameLoop(CallbackInfo ci) { TASmodClient.virtual.update(currentScreen); } + // ============================ Keyboard + /** * Run at the start of run tick keyboard. Runs every tick. + * @see com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#nextKeyboardTick() * @param ci CBI */ @Inject(method = "runTickKeyboard", at = @At(value = "HEAD")) @@ -41,7 +45,7 @@ public void playback_injectRunTickKeyboard(CallbackInfo ci) { } /** - * Redirects a {@link Keyboard#next()}. Starts running every tick and continues as long as there are {@link VirtualKeyboardEvent}s in {@link VirtualInput} + * Redirects a {@link org.lwjgl.input.Keyboard#next()}. Starts running every tick and continues as long as there are {@link VirtualKeyboardEvent}s in {@link VirtualInput2} * @see com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#nextKeyboardSubtick() * @return If {@link VirtualKeyboardEvent}s are present in {@link VirtualInput2} */ @@ -51,8 +55,7 @@ public boolean playback_redirectKeyboardNext() { } /** - * Runs everytime {@link #playback_redirectKeyboardNext()} has an event ready. Redirects {@link Keyboard#getEventKeyState()} - * @return The keycode for the current event in {@link VirtualInput2.VirtualKeyboardInput} + * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#getEventKeyboardKey()} */ @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKey()I", remap = false)) public int playback_redirectKeyboardGetEventKey() { @@ -60,8 +63,7 @@ public int playback_redirectKeyboardGetEventKey() { } /** - * Runs everytime {@link #playback_redirectKeyboardNext()} has an event ready. Redirects {@link Keyboard#getEventKeyState()} - * @return Whether the key is down in {@link VirtualInput2} + * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#getEventKeyboardState()} */ @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKeyState()Z", remap = false)) public boolean playback_redirectGetEventState() { @@ -69,8 +71,7 @@ public boolean playback_redirectGetEventState() { } /** - * Runs everytime {@link #playback_redirectKeyboardNext()} has an event ready. Redirects {@link Keyboard#getEventCharacter()} - * @return The character for the current event in {@link VirtualInput2} + * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#getEventKeyboardCharacter()} */ @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventCharacter()C", remap = false)) public char playback_redirectKeyboardGetEventCharacter() { @@ -78,7 +79,8 @@ public char playback_redirectKeyboardGetEventCharacter() { } /** - * Runs everytime {@link #playback_redirectKeyboardNext()} has an event ready. Redirects {@link Keyboard#isKeyDown(int)} + * Runs everytime {@link #playback_redirectKeyboardNext()} has an event ready. Redirects {@link org.lwjgl.input.Keyboard#isKeyDown(int)} + * @see com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#isKeyDown(int) * @return Whether the key is down in {@link VirtualInput2} */ @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;isKeyDown(I)Z", remap = false)) @@ -86,16 +88,25 @@ public boolean playback_redirectIsKeyDown(int keyCode) { return TASmodClient.virtual.KEYBOARD.isKeyDown(keyCode); } + /** + * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#getEventKeyboardKey()} + */ @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKey()I", remap = false)) public int playback_redirectGetEventKeyDPK() { return TASmodClient.virtual.KEYBOARD.getEventKeyboardKey(); } + /** + * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#getEventKeyboardState()} + */ @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKeyState()Z", remap = false)) public boolean playback_redirectGetEventKeyStateDPK() { return TASmodClient.virtual.KEYBOARD.getEventKeyboardState(); } + /** + * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#getEventKeyboardCharacter()} + */ @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventCharacter()C", remap = false)) public char playback_redirectGetEventCharacterDPK() { return TASmodClient.virtual.KEYBOARD.getEventKeyboardCharacter(); @@ -103,30 +114,45 @@ public char playback_redirectGetEventCharacterDPK() { // ============================ Mouse + /** + * Run at the start of run tick mouse. Runs every tick. + * @see com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualMouseInput#nextMouseTick() + * @param ci CBI + */ @Inject(method = "runTickMouse", at = @At(value = "HEAD")) public void playback_injectRunTickMouse(CallbackInfo ci) { TASmodClient.virtual.MOUSE.nextMouseTick(); } + /** + * Redirects a {@link org.lwjgl.input.Mouse#next()}. Starts running every tick and continues as long as there are {@link VirtualMouseEvent}s in {@link VirtualInput2} + * @see com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualMouseInput#nextMouseSubtick() + * @return If {@link VirtualMouseInput}s are present in {@link VirtualInput2} + */ @Redirect(method = "runTickMouse", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;next()Z", remap = false)) public boolean playback_redirectMouseNext() { return TASmodClient.virtual.MOUSE.nextMouseSubtick(); } + /** + * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualMouseInput#getEventMouseKey()} + */ @Redirect(method = "runTickMouse", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventButton()I", remap = false)) public int playback_redirectMouseGetEventButton() { - -// if(!VirtualKeybindings.isKeyCodeAlwaysBlocked(ClientProxy.virtual.getEventMouseKey()-100)) { -// TASmod.ktrngHandler.nextPlayerInput(); // Advance ktrng seed on player input -// } return TASmodClient.virtual.MOUSE.getEventMouseKey() + 100; } + /** + * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualMouseInput#getEventMouseState()} + */ @Redirect(method = "runTickMouse", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventButtonState()Z", remap = false)) public boolean playback_redirectGetEventButtonState() { return TASmodClient.virtual.MOUSE.getEventMouseState(); } + /** + * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualMouseInput#getEventMouseScrollWheel()} + */ @Redirect(method = "runTickMouse", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventDWheel()I", remap = false)) public int playback_redirectGetEventDWheel() { return TASmodClient.virtual.MOUSE.getEventMouseScrollWheel(); diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java index fc643200..db3f13d5 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java @@ -6,7 +6,6 @@ import org.apache.logging.log4j.Logger; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.minecrafttas.tasmod.mixin.playbackhooks.MixinMinecraft; import com.minecrafttas.tasmod.util.Ducks; @@ -24,10 +23,23 @@ */ public class VirtualInput2 { private final Logger LOGGER; + /** + * Instance of the {@link VirtualKeyboardInput} subclass, intended to improve readability. + */ public final VirtualKeyboardInput KEYBOARD; + /** + * Instance of the {@link VirtualMouseInput} subclass, intended to improve readability. + */ public final VirtualMouseInput MOUSE; + /** + * Instance of the {@link VirtualCameraAngleInput} subclass, intended to improve readability. + */ public final VirtualCameraAngleInput CAMERA_ANGLE; + /** + * Creates a new virtual input with an empty {@link VirtualKeyboardInput}, {@link VirtualMouseInput} and {@link VirtualCameraAngleInput} + * @param logger + */ public VirtualInput2(Logger logger) { this(logger, new VirtualKeyboard2(), new VirtualMouse2(), new VirtualCameraAngle2()); } @@ -35,9 +47,9 @@ public VirtualInput2(Logger logger) { /** * Creates a virtual input with pre-loaded values * - * @param preloadedKeyboard A keyboard loaded at the beginning - * @param preloadedMouse A mouse loaded at the beginning - * @param preloadedCamera A camera loaded at the beginning + * @param preloadedKeyboard A keyboard loaded when creating {@link VirtualKeyboardInput} + * @param preloadedMouse A mouse loaded when creating {@link VirtualMouseInput} + * @param preloadedCamera A camera loaded when creating {@link VirtualCameraAngleInput} */ public VirtualInput2(Logger logger, VirtualKeyboard2 preloadedKeyboard, VirtualMouse2 preloadedMouse, VirtualCameraAngle2 preloadedCamera) { this.LOGGER = logger; @@ -149,7 +161,6 @@ public void unpress() { * @see com.minecrafttas.tasmod.virtual.VirtualKeyboard2 */ public class VirtualKeyboardInput { - /** * The keyboard "state" that is currently recognized by the game,
* meaning it is a direct copy of the vanilla keybindings. Updated every @@ -157,33 +168,33 @@ public class VirtualKeyboardInput { * Updated in {@link #nextKeyboardTick()} */ private final VirtualKeyboard2 currentKeyboard; - /** * The "state" of the real physical keyboard.
* This is updated every frame.
* Updates {@link #currentKeyboard} in {@link #nextKeyboardTick()} */ private final VirtualKeyboard2 nextKeyboard = new VirtualKeyboard2(); - /** * Queue for keyboard events.
* Is filled in {@link #nextKeyboardTick()} and read in * {@link #nextKeyboardSubtick()} */ private final Queue keyboardEventQueue = new ConcurrentLinkedQueue(); - /** * The current keyboard event where the vanilla keybindings are reading * from.
* Updated in {@link #nextKeyboardSubtick()} and read out in - * {@link #getEventKeyboardKey()}, {@link #getEventKeyboardState()} and - * {@link #getEventKeyboardCharacter()} + *
    + *
  • {@link #getEventKeyboardKey()}
  • + *
  • {@link #getEventKeyboardState()}
  • + *
  • {@link #getEventKeyboardCharacter()}
  • + *
*/ private VirtualKeyboardEvent currentKeyboardEvent = new VirtualKeyboardEvent(); /** * Constructor to preload the {@link #currentKeyboard} with an existing keyboard - * @param preloadedKeyboard + * @param preloadedKeyboard The new {@link #currentKeyboard} */ public VirtualKeyboardInput(VirtualKeyboard2 preloadedKeyboard) { currentKeyboard = preloadedKeyboard; @@ -211,7 +222,7 @@ public void updateNextKeyboard(int keycode, boolean keystate, char character) { * @param repeatEventsEnabled If repeat events are enabled */ public void updateNextKeyboard(int keycode, boolean keystate, char character, boolean repeatEventsEnabled) { - LOGGER.debug(LoggerMarkers.Keyboard, "Update: {}, {}, {}, {}", keycode, keystate, character); + LOGGER.debug(LoggerMarkers.Keyboard, "Update: {}, {}, {}, {}", keycode, keystate, character); // Activate with -Dtasmod.marker.keyboard=ACCEPT in VM arguments (and -Dtasmod.log.level=debug) nextKeyboard.update(keycode, keystate, character, repeatEventsEnabled); } @@ -318,58 +329,135 @@ public boolean willKeyBeDown(int keycode) { * @see com.minecrafttas.tasmod.virtual.VirtualMouse2 */ public class VirtualMouseInput { + /** + * The mouse "state" that is currently recognized by the game,
+ * meaning it is a direct copy of the vanilla mouse. Updated every + * tick.
+ * Updated in {@link #nextMouseTick()} + */ private final VirtualMouse2 currentMouse; + /** + * The "state" of the real physical mouse.
+ * This is updated every frame.
+ * Updates {@link #currentMouse} in {@link #nextMouseTick()} + */ private final VirtualMouse2 nextMouse = new VirtualMouse2(); + /** + * Queue for keyboard events.
+ * Is filled in {@link #nextMouseTick()} and read in + * {@link #nextMouseSubtick()} + */ private final Queue mouseEventQueue = new ConcurrentLinkedQueue<>(); + /** + * The current mouse event where the vanilla mouse is reading + * from.
+ * Updated in {@link #nextMouseSubtick()} and read out in + *
    + *
  • {@link #getEventMouseKey()}
  • + *
  • {@link #getEventMouseState()}
  • + *
  • {@link #getEventMouseScrollWheel()}
  • + *
  • {@link #getEventCursorX()}
  • + *
  • {@link #getEventCursorY()}
  • + *
+ */ private VirtualMouseEvent currentMouseEvent = new VirtualMouseEvent(); - public VirtualMouseInput() { - this(new VirtualMouse2()); - } - + /** + * Constructor to preload the {@link #currentMouse} with an existing mouse + * @param preloadedMouse The new {@link #currentMouse} + */ public VirtualMouseInput(VirtualMouse2 preloadedMouse) { currentMouse = preloadedMouse; } + /** + * Updates the next keyboard + * + * @see VirtualInput2#update(GuiScreen) + * @param keycode The keycode of this event + * @param keystate The keystate of this event + * @param character The character of this event + * @param repeatEventsEnabled If repeat events are enabled + */ public void updateNextMouse(int keycode, boolean keystate, int scrollwheel, int cursorX, int cursorY) { keycode-=100; - LOGGER.debug(LoggerMarkers.Mouse,"Update: {} ({}), {}, {}, {}, {}", keycode, VirtualKey2.getName(keycode), keystate, scrollwheel, cursorX, cursorY); + LOGGER.debug(LoggerMarkers.Mouse,"Update: {} ({}), {}, {}, {}, {}", keycode, VirtualKey2.getName(keycode), keystate, scrollwheel, cursorX, cursorY); // Activate with -Dtasmod.marker.mouse=ACCEPT in VM arguments (and -Dtasmod.log.level=debug) nextMouse.update(keycode, keystate, scrollwheel, cursorX, cursorY); } + /** + * Runs when the next mouse tick is about to occur.
+ * Used to load {@link #nextMouse} into {@link #currentMouse}, creating + * {@link VirtualMouseEvent}s in the process. + * + * @see MixinMinecraft#playback_injectRunTickMouse(org.spongepowered.asm.mixin.injection.callback.CallbackInfo) + */ public void nextMouseTick() { currentMouse.getVirtualEvents(nextMouse, mouseEventQueue); currentMouse.copyFrom(nextMouse); } + /** + * Runs in a while loop. Used for updating {@link #currentMouseEvent} and + * ending the while loop. + * + * @see MixinMinecraft#playback_redirectMouseNext() + * @return If a mouse event is in {@link #mouseEventQueue} + */ public boolean nextMouseSubtick() { return (currentMouseEvent = mouseEventQueue.poll()) != null; } + /** + * @return The keycode of {@link #currentMouseEvent} + */ public int getEventMouseKey() { return currentMouseEvent.getKeyCode(); } + /** + * @return The keystate of {@link #currentMouseEvent} + */ public boolean getEventMouseState() { return currentMouseEvent.isState(); } + /** + * @return The scroll wheel of {@link #currentMouseEvent} + */ public int getEventMouseScrollWheel() { return currentMouseEvent.getScrollwheel(); } + /** + * @return The x coordinate of the cursor of {@link #currentMouseEvent} + */ public int getEventCursorX() { return PointerNormalizer.getCoordsX(currentMouseEvent.getCursorX()); } + /** + * @return The y coordinate of the cursor of {@link #currentMouseEvent} + */ public int getEventCursorY() { return PointerNormalizer.getCoordsY(currentMouseEvent.getCursorY()); } + /** + * If the key is currently down and recognised by Minecraft + * @param keycode The keycode of the key in question + * @return Whether the key of the {@link #currentMouse} is down + */ public boolean isKeyDown(int keycode) { return currentMouse.isKeyDown(keycode); } + /** + * If the key will be down and recognised in the next tick by Minecraft.
+ * This is equal to checking if a key on the physical mouse is pressed + * @param keycode The keycode of the key in question + * @return Whether the key of the {@link #nextMouse} is down + */ public boolean willKeyBeDown(int keycode) { return nextMouse.isKeyDown(keycode); } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java index 127f7928..55ee90fc 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java @@ -147,15 +147,15 @@ public void setPressed(int keycode, boolean keystate) { } /** - * Calculates a list of {@link VirtualKeyboardEvent}s to the next peripheral, including - * the subticks. + * Calculates a list of {@link VirtualKeyboardEvent}s to the next peripheral, + * including the subticks. * * @see VirtualKeyboard2#getDifference(VirtualKeyboard2, Queue) * - * @param nextKeyboard The peripheral that is comes after this one.
- * If this one is loaded at tick 15, the nextPeripheral - * should be the one from tick 16 - * @param reference The queue to fill. Passed in by reference. + * @param nextKeyboard The keyboard that comes after this one.
+ * If this one is loaded at tick 15, the nextKeyboard should + * be the one from tick 16 + * @param reference The queue to fill. Passed in by reference. */ public void getVirtualEvents(VirtualKeyboard2 nextKeyboard, Queue reference) { if (isParent()) { @@ -169,12 +169,13 @@ public void getVirtualEvents(VirtualKeyboard2 nextKeyboard, Queue - * and returns a list of the changes between them in form of {@link VirtualKeyboardEvent}s + * and returns a list of the changes between them in form of + * {@link VirtualKeyboardEvent}s * - * @param nextKeyboard The keyboard that is comes after this one.
- * If this one is loaded at tick 15, the nextPeripheral - * should be the one from tick 16 - * @param reference The queue to fill. Passed in by reference. + * @param nextKeyboard The keyboard that comes after this one.
+ * If this one is loaded at tick 15, the nextKeyboard should + * be the one from tick 16 + * @param reference The queue to fill. Passed in by reference. */ public void getDifference(VirtualKeyboard2 nextKeyboard, Queue reference) { charQueue.addAll(nextKeyboard.charList); @@ -211,13 +212,19 @@ public void getDifference(VirtualKeyboard2 nextKeyboard, Queue getCharList() { return ImmutableList.copyOf(charList); } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java index 8b9d70a0..f8e3d4a2 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java @@ -89,6 +89,18 @@ public void setPressed(int keycode, boolean keystate) { } } + /** + * Calculates a list of {@link VirtualMouseEvent}s, when comparing this mouse to + * the next mouse in the sequence,
+ * which also includes the subticks. + * + * @see VirtualMouse2#getDifference(VirtualMouse2, Queue) + * + * @param nextMouse The mouse that comes after this one.
+ * If this one is loaded at tick 15, the nextMouse should be + * the one from tick 16 + * @param reference The queue to fill. Passed in by reference. + */ public void getVirtualEvents(VirtualMouse2 nextMouse, Queue reference) { if (isParent()) { VirtualMouse2 currentSubtick = this; @@ -99,10 +111,30 @@ public void getVirtualEvents(VirtualMouse2 nextMouse, Queue r } } + /** + * Calculates the difference between 2 mice via symmetric difference
+ * and returns a list of the changes between them in form of + * {@link VirtualMouseEvent}s + * + * @param nextMouse The mouse that comes after this one.
+ * If this one is loaded at tick 15, the nextMouse should be + * the one from tick 16 + * @param reference The queue to fill. Passed in by reference. + */ public void getDifference(VirtualMouse2 nextPeripheral, Queue reference) { - + + /* + * Checks if pressedKeys are the same... + */ if(pressedKeys.equals(nextPeripheral.pressedKeys)){ - reference.add(new VirtualMouseEvent(VirtualKey2.MOUSEMOVED.getKeycode(), false, nextPeripheral.scrollWheel, nextPeripheral.cursorX, nextPeripheral.cursorY)); + + /** + * ...but scrollWheel, cursorX or cursorY are different. + * Without this, the scrollWheel would only work if a mouse button is pressed at the same time. + */ + if(!equals(nextPeripheral)) { + reference.add(new VirtualMouseEvent(VirtualKey2.MOUSEMOVED.getKeycode(), false, nextPeripheral.scrollWheel, nextPeripheral.cursorX, nextPeripheral.cursorY)); + } return; } int scrollWheelCopy = nextPeripheral.scrollWheel; @@ -147,6 +179,9 @@ protected void clear() { clearMouseData(); } + /** + * Resets mouse specific data to it's defaults + */ private void clearMouseData() { scrollWheel = 0; cursorX = 0; @@ -196,14 +231,23 @@ public boolean equals(Object obj) { return super.equals(obj); } + /** + * @return {@link #scrollWheel} + */ public int getScrollWheel() { return scrollWheel; } + /** + * @return {@link #cursorX} + */ public int getCursorX() { return cursorX; } + /** + * @return {@link #cursorY} + */ public int getCursorY() { return cursorY; } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java index 36f15caa..f0bcb276 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java @@ -8,34 +8,44 @@ * @author Scribble */ public class VirtualMouseEvent extends VirtualButtonEvent { - private final int scrollwheel; - private final int cursorX; - private final int cursorY; - - public VirtualMouseEvent(){ - this(0, false, 0, 0, 0); - } - public VirtualMouseEvent(int keycode, boolean state, int scrollwheel, int cursorX, int cursorY) { - super(keycode, state); - this.scrollwheel = scrollwheel; - this.cursorX = cursorX; - this.cursorY = cursorY; - } - - public int getScrollwheel() { - return scrollwheel; - } - - public Integer getCursorX() { - return cursorX; - } - - public Integer getCursorY() { - return cursorY; - } - - @Override - public String toString() { - return String.format("%s, %s, %s, %s", super.toString(), scrollwheel, cursorX, cursorY); - } + private final int scrollwheel; + private final int cursorX; + private final int cursorY; + + public VirtualMouseEvent() { + this(0, false, 0, 0, 0); + } + + public VirtualMouseEvent(int keycode, boolean state, int scrollwheel, int cursorX, int cursorY) { + super(keycode, state); + this.scrollwheel = scrollwheel; + this.cursorX = cursorX; + this.cursorY = cursorY; + } + + public int getScrollwheel() { + return scrollwheel; + } + + public Integer getCursorX() { + return cursorX; + } + + public Integer getCursorY() { + return cursorY; + } + + @Override + public String toString() { + return String.format("%s, %s, %s, %s", super.toString(), scrollwheel, cursorX, cursorY); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof VirtualMouseEvent) { + VirtualMouseEvent e = (VirtualMouseEvent) obj; + return keycode == e.keycode && keystate == e.keystate && scrollwheel == e.scrollwheel && cursorX == e.cursorX && cursorY == e.cursorY; + } + return super.equals(obj); + } } diff --git a/src/main/resources/tasmod.mixin.json b/src/main/resources/tasmod.mixin.json index 115acd31..efd2d938 100644 --- a/src/main/resources/tasmod.mixin.json +++ b/src/main/resources/tasmod.mixin.json @@ -26,7 +26,6 @@ //General "MixinMinecraft", "MixinTimer", - "MixinGuiScreen", "MixinInGameHud", //Savestates @@ -45,6 +44,7 @@ //Playbackhooks "playbackhooks.MixinMinecraft", "playbackhooks.MixinEntityRenderer", + "playbackhooks.MixinGuiScreen", "playbackhooks.MixinGameSettings", "playbackhooks.MixinGuiChat", "playbackhooks.MixinGuiClickableScrolledSelectionListProxy", diff --git a/src/test/java/tasmod/virtual/VirtualMouseTest.java b/src/test/java/tasmod/virtual/VirtualMouseTest.java index 336f2a27..2b39bf55 100644 --- a/src/test/java/tasmod/virtual/VirtualMouseTest.java +++ b/src/test/java/tasmod/virtual/VirtualMouseTest.java @@ -1,13 +1,27 @@ package tasmod.virtual; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.ConcurrentLinkedQueue; + +import org.junit.jupiter.api.Test; + import com.minecrafttas.tasmod.virtual.VirtualKey2; import com.minecrafttas.tasmod.virtual.VirtualKeyboard2; +import com.minecrafttas.tasmod.virtual.VirtualKeyboardEvent; import com.minecrafttas.tasmod.virtual.VirtualMouse2; -import org.junit.jupiter.api.Test; - -import java.util.*; - -import static org.junit.jupiter.api.Assertions.*; +import com.minecrafttas.tasmod.virtual.VirtualMouseEvent; class VirtualMouseTest { @@ -223,4 +237,153 @@ void testUpdate(){ assertIterableEquals(expected, actual.getAll()); } + + /** + * Tests getDifference + */ + @Test + void testGetDifference(){ + VirtualMouse2 test = new VirtualMouse2(new HashSet<>(Arrays.asList(VirtualKey2.LC.getKeycode())), 15, 0, 0); + VirtualMouse2 test2 = new VirtualMouse2(new HashSet<>(Arrays.asList(VirtualKey2.LC.getKeycode(), VirtualKey2.RC.getKeycode())), 30, 1, 2); + Queue actual = new ConcurrentLinkedQueue<>(); + test.getDifference(test2, actual); + Queue expected = new ConcurrentLinkedQueue<>(Arrays.asList(new VirtualMouseEvent(VirtualKey2.RC.getKeycode(), true, 30, 1, 2))); + + assertIterableEquals(expected, actual); + } + + /** + * Tests generating virtual events going from an unpressed mouse to a pressed mouse state + */ + @Test + void testGetVirtualEventsPress() { + VirtualMouse2 unpressed = new VirtualMouse2(); + + VirtualMouse2 pressed = new VirtualMouse2(); + pressed.update(VirtualKey2.LC.getKeycode(), true, 15, 10, 12); + + // Load actual with the events + Queue actual = new ConcurrentLinkedQueue<>(); + unpressed.getVirtualEvents(pressed, actual); + + // Load expected + List expected = Arrays.asList(new VirtualMouseEvent(VirtualKey2.LC.getKeycode(), true, 15, 10, 12)); + + assertIterableEquals(expected, actual); + } + + /** + * Tests generating virtual events going from a pressed mouse to an unpressed mouse state + */ + @Test + void testGetVirtualEventsUnpress() { + VirtualMouse2 unpressed = new VirtualMouse2(); + + VirtualMouse2 pressed = new VirtualMouse2(); + pressed.update(VirtualKey2.LC.getKeycode(), true, 15, 10, 12); + + // Load actual with the events + Queue actual = new ConcurrentLinkedQueue<>(); + pressed.getVirtualEvents(unpressed, actual); + + // Load expected + List expected = Arrays.asList(new VirtualMouseEvent(VirtualKey2.LC.getKeycode(), false, 0, 0, 0)); + + assertIterableEquals(expected, actual); + } + + /** + * Tests 2 updates having the same value. Should return no additional button events + */ + @Test + void testSameUpdate() { + VirtualMouse2 unpressed = new VirtualMouse2(); + + VirtualMouse2 pressed = new VirtualMouse2(); + pressed.update(VirtualKey2.LC.getKeycode(), true, 15, 10, 12); + pressed.update(VirtualKey2.LC.getKeycode(), true, 15, 10, 12); + + // Load actual with the events + Queue actual = new ConcurrentLinkedQueue<>(); + unpressed.getVirtualEvents(pressed, actual); + + // Load expected + List expected = Arrays.asList( + new VirtualMouseEvent(VirtualKey2.LC.getKeycode(), true, 15, 10, 12) // Should only have one keyboard event + ); + + assertIterableEquals(expected, actual); + } + + /** + * Tests 2 updates having the same pressed keys, but scrollWheel is different + */ + @Test + void testScrollWheelDifferent() { + VirtualMouse2 unpressed = new VirtualMouse2(); + + VirtualMouse2 pressed = new VirtualMouse2(); + pressed.update(VirtualKey2.LC.getKeycode(), true, 15, 10, 12); + pressed.update(VirtualKey2.LC.getKeycode(), true, -30, 10, 12); + + // Load actual with the events + Queue actual = new ConcurrentLinkedQueue<>(); + unpressed.getVirtualEvents(pressed, actual); + + // Load expected + List expected = Arrays.asList( + new VirtualMouseEvent(VirtualKey2.LC.getKeycode(), true, 15, 10, 12), + new VirtualMouseEvent(VirtualKey2.MOUSEMOVED.getKeycode(), false, -30, 10, 12) // Adds an additional "MOUSEMOVED" event with the scroll wheel + ); + + assertIterableEquals(expected, actual); + } + + /** + * Tests 2 updates having the same pressed keys, but scrollWheel is different + */ + @Test + void testCursorXDifferent() { + VirtualMouse2 unpressed = new VirtualMouse2(); + + VirtualMouse2 pressed = new VirtualMouse2(); + pressed.update(VirtualKey2.LC.getKeycode(), true, 15, 10, 12); + pressed.update(VirtualKey2.LC.getKeycode(), true, 15, 11, 12); + + // Load actual with the events + Queue actual = new ConcurrentLinkedQueue<>(); + unpressed.getVirtualEvents(pressed, actual); + + // Load expected + List expected = Arrays.asList( + new VirtualMouseEvent(VirtualKey2.LC.getKeycode(), true, 15, 10, 12), + new VirtualMouseEvent(VirtualKey2.MOUSEMOVED.getKeycode(), false, 15, 11, 12) // Adds an additional "MOUSEMOVED" event with the cursorX + ); + + assertIterableEquals(expected, actual); + } + + /** + * Tests 2 updates having the same pressed keys, but scrollWheel is different + */ + @Test + void testCursorYDifferent() { + VirtualMouse2 unpressed = new VirtualMouse2(); + + VirtualMouse2 pressed = new VirtualMouse2(); + pressed.update(VirtualKey2.LC.getKeycode(), true, 15, 10, 12); + pressed.update(VirtualKey2.LC.getKeycode(), true, 15, 10, 120); + + // Load actual with the events + Queue actual = new ConcurrentLinkedQueue<>(); + unpressed.getVirtualEvents(pressed, actual); + + // Load expected + List expected = Arrays.asList( + new VirtualMouseEvent(VirtualKey2.LC.getKeycode(), true, 15, 10, 12), + new VirtualMouseEvent(VirtualKey2.MOUSEMOVED.getKeycode(), false, 15, 10, 120) // Adds an additional "MOUSEMOVED" event with the cursorY + ); + + assertIterableEquals(expected, actual); + } } From 9b615c7a50a873146e0a78808f64187e7f28381b Mon Sep 17 00:00:00 2001 From: Scribble Date: Thu, 8 Feb 2024 11:48:54 +0100 Subject: [PATCH 37/57] [VirtualInput] Removing old VirtualInput --- .../com/minecrafttas/tasmod/TASmodClient.java | 6 +- .../playbackhooks/MixinEntityRenderer.java | 3 +- .../mixin/playbackhooks/MixinGuiChat.java | 3 +- ...uiClickableScrolledSelectionListProxy.java | 3 +- .../playbackhooks/MixinGuiContainer.java | 6 +- .../mixin/playbackhooks/MixinGuiScreen.java | 12 +- .../mixin/playbackhooks/MixinMinecraft.java | 48 +- .../playback/PlaybackControllerClient.java | 8 +- .../tasmod/playback/PlaybackSerialiser.java | 146 ++- .../tasmod/virtual/VirtualCameraAngle.java | 34 +- .../tasmod/virtual/VirtualCameraAngle2.java | 50 - .../tasmod/virtual/VirtualInput.java | 946 ++++++++---------- .../tasmod/virtual/VirtualInput2.java | 486 --------- .../tasmod/virtual/VirtualKey.java | 244 +++-- .../tasmod/virtual/VirtualKey2.java | 189 ---- .../tasmod/virtual/VirtualKeyboard.java | 648 ++++++------ .../tasmod/virtual/VirtualKeyboard2.java | 323 ------ .../tasmod/virtual/VirtualMouse.java | 508 ++++------ .../tasmod/virtual/VirtualMouse2.java | 254 ----- .../tasmod/virtual/VirtualPeripheral.java | 9 +- .../virtual/{ => event}/VirtualEvent.java | 2 +- .../{ => event}/VirtualKeyboardEvent.java | 4 +- .../{ => event}/VirtualMouseEvent.java | 4 +- .../java/tasmod/virtual/VirtualInputTest.java | 49 +- .../tasmod/virtual/VirtualKeyboardTest.java | 148 +-- .../java/tasmod/virtual/VirtualMouseTest.java | 180 ++-- 26 files changed, 1444 insertions(+), 2869 deletions(-) delete mode 100644 src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle2.java delete mode 100644 src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java delete mode 100644 src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey2.java delete mode 100644 src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java delete mode 100644 src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java rename src/main/java/com/minecrafttas/tasmod/virtual/{ => event}/VirtualEvent.java (93%) rename src/main/java/com/minecrafttas/tasmod/virtual/{ => event}/VirtualKeyboardEvent.java (88%) rename src/main/java/com/minecrafttas/tasmod/virtual/{ => event}/VirtualMouseEvent.java (89%) diff --git a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java index 279b608b..6e398c21 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java @@ -36,7 +36,7 @@ import com.minecrafttas.tasmod.util.LoggerMarkers; import com.minecrafttas.tasmod.util.Scheduler; import com.minecrafttas.tasmod.util.ShieldDownloader; -import com.minecrafttas.tasmod.virtual.VirtualInput2; +import com.minecrafttas.tasmod.virtual.VirtualInput; import com.minecrafttas.tasmod.virtual.VirtualKeybindings; import net.fabricmc.api.ClientModInitializer; @@ -52,7 +52,7 @@ public class TASmodClient implements ClientModInitializer, EventClientInit, EventPlayerJoinedClientSide, EventOpenGui{ - public static VirtualInput2 virtual; + public static VirtualInput virtual; public static TickSyncClient ticksyncClient; @@ -126,7 +126,7 @@ public void onInitializeClient() { } else { config.reset(ConfigOptions.FileToOpen); } - virtual=new VirtualInput2(LOGGER); //TODO Move fileOnStart to PlaybackController + virtual=new VirtualInput(LOGGER); //TODO Move fileOnStart to PlaybackController // Initialize InfoHud hud = new InfoHud(); diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java index c556a640..f4352ec7 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java @@ -4,6 +4,7 @@ import com.minecrafttas.tasmod.TASmodClient; import com.minecrafttas.tasmod.handlers.InterpolationHandler; import com.minecrafttas.tasmod.util.Ducks.SubtickDuck; +import com.minecrafttas.tasmod.virtual.VirtualInput; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.EntityRenderer; import net.minecraft.util.math.MathHelper; @@ -18,7 +19,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; /** - * Redirects the camera to use {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualCameraAngleInput}.
+ * Redirects the camera to use {@link VirtualInput.VirtualCameraAngleInput}.
* Also conforms the camera to 20tps as */ @Mixin(EntityRenderer.class) diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiChat.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiChat.java index 7b76c7eb..c4b0880d 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiChat.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiChat.java @@ -1,5 +1,6 @@ package com.minecrafttas.tasmod.mixin.playbackhooks; +import com.minecrafttas.tasmod.virtual.VirtualInput; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @@ -11,7 +12,7 @@ @Mixin(GuiChat.class) public class MixinGuiChat { /** - * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualMouseInput#getEventMouseScrollWheel()} + * @return {@link VirtualInput.VirtualMouseInput#getEventMouseScrollWheel()} */ @Redirect(method = "handleMouseInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventDWheel()I", remap = false)) public int redirectHandleMouseInput4() { diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiClickableScrolledSelectionListProxy.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiClickableScrolledSelectionListProxy.java index 40d6c916..bfa57dd3 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiClickableScrolledSelectionListProxy.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiClickableScrolledSelectionListProxy.java @@ -1,5 +1,6 @@ package com.minecrafttas.tasmod.mixin.playbackhooks; +import com.minecrafttas.tasmod.virtual.VirtualInput; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @@ -12,7 +13,7 @@ public class MixinGuiClickableScrolledSelectionListProxy { /** - * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualMouseInput#getEventMouseState()} + * @return {@link VirtualInput.VirtualMouseInput#getEventMouseState()} */ @Redirect(method = "handleMouseInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventButtonState()Z", ordinal = 0, remap = false)) public boolean redirectHandleMouseInput() { diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiContainer.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiContainer.java index 106a88ed..97dbf995 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiContainer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiContainer.java @@ -5,7 +5,7 @@ import org.spongepowered.asm.mixin.injection.Redirect; import com.minecrafttas.tasmod.TASmodClient; -import com.minecrafttas.tasmod.virtual.VirtualKey2; +import com.minecrafttas.tasmod.virtual.VirtualKey; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; @@ -15,7 +15,7 @@ public class MixinGuiContainer { /** - * Redirects the check for {@link VirtualKey2#LSHIFT} and {@link VirtualKey2#RSHIFT} in mouseClicked + * Redirects the check for {@link VirtualKey#LSHIFT} and {@link VirtualKey#RSHIFT} in mouseClicked * @param i The keycode to check for * @return If the keycode is down */ @@ -25,7 +25,7 @@ private boolean redirectIsKeyDown(int i) { } /** - * Redirects the check for {@link VirtualKey2#LSHIFT} and {@link VirtualKey2#RSHIFT} in mouseReleased + * Redirects the check for {@link VirtualKey#LSHIFT} and {@link VirtualKey#RSHIFT} in mouseReleased * @param i The keycode to check for * @return If the keycode is down */ diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiScreen.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiScreen.java index 1cfb45c7..0a8a330b 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiScreen.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinGuiScreen.java @@ -1,5 +1,6 @@ package com.minecrafttas.tasmod.mixin.playbackhooks; +import com.minecrafttas.tasmod.virtual.VirtualInput; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -10,8 +11,7 @@ import com.minecrafttas.tasmod.TASmodClient; import com.minecrafttas.tasmod.util.Ducks.GuiScreenDuck; -import com.minecrafttas.tasmod.virtual.VirtualInput2; -import com.minecrafttas.tasmod.virtual.VirtualKeyboardEvent; +import com.minecrafttas.tasmod.virtual.event.VirtualKeyboardEvent; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; @@ -21,7 +21,7 @@ public class MixinGuiScreen implements GuiScreenDuck { /** * Run at the start of run handleInput. Runs every tick. - * @see com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#nextKeyboardTick() + * @see VirtualInput.VirtualKeyboardInput#nextKeyboardTick() * @param ci CBI */ @Inject(method = "handleInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;isCreated()Z", shift = Shift.AFTER, remap = false)) @@ -30,9 +30,9 @@ public void injectAfterKeyboardCreated(CallbackInfo ci) { } /** - * Redirects a {@link org.lwjgl.input.Keyboard#next()}. Starts running every tick and continues as long as there are {@link VirtualKeyboardEvent}s in {@link VirtualInput2} - * @see com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#nextKeyboardSubtick() - * @return If {@link VirtualKeyboardEvent}s are present in {@link VirtualInput2} + * Redirects a {@link org.lwjgl.input.Keyboard#next()}. Starts running every tick and continues as long as there are {@link VirtualKeyboardEvent}s in {@link VirtualInput} + * @see VirtualInput.VirtualKeyboardInput#nextKeyboardSubtick() + * @return If {@link VirtualKeyboardEvent}s are present in {@link VirtualInput} */ @Redirect(method = "handleInput", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;next()Z", remap = false)) public boolean redirectKeyboardNext() { diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java index 07885e89..8f01ad90 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinMinecraft.java @@ -1,5 +1,6 @@ package com.minecrafttas.tasmod.mixin.playbackhooks; +import com.minecrafttas.tasmod.virtual.VirtualInput; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -8,10 +9,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.minecrafttas.tasmod.TASmodClient; -import com.minecrafttas.tasmod.virtual.VirtualInput2; -import com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualMouseInput; -import com.minecrafttas.tasmod.virtual.VirtualKeyboardEvent; -import com.minecrafttas.tasmod.virtual.VirtualMouseEvent; +import com.minecrafttas.tasmod.virtual.VirtualInput.VirtualMouseInput; +import com.minecrafttas.tasmod.virtual.event.VirtualKeyboardEvent; +import com.minecrafttas.tasmod.virtual.event.VirtualMouseEvent; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; @@ -24,7 +24,7 @@ public class MixinMinecraft { /** * Runs every frame. - * @see VirtualInput2#update(GuiScreen) + * @see VirtualInput#update(GuiScreen) * @param ci CBI */ @Inject(method = "runGameLoop", at = @At(value = "HEAD")) @@ -36,7 +36,7 @@ public void playback_injectRunGameLoop(CallbackInfo ci) { /** * Run at the start of run tick keyboard. Runs every tick. - * @see com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#nextKeyboardTick() + * @see VirtualInput.VirtualKeyboardInput#nextKeyboardTick() * @param ci CBI */ @Inject(method = "runTickKeyboard", at = @At(value = "HEAD")) @@ -45,9 +45,9 @@ public void playback_injectRunTickKeyboard(CallbackInfo ci) { } /** - * Redirects a {@link org.lwjgl.input.Keyboard#next()}. Starts running every tick and continues as long as there are {@link VirtualKeyboardEvent}s in {@link VirtualInput2} - * @see com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#nextKeyboardSubtick() - * @return If {@link VirtualKeyboardEvent}s are present in {@link VirtualInput2} + * Redirects a {@link org.lwjgl.input.Keyboard#next()}. Starts running every tick and continues as long as there are {@link VirtualKeyboardEvent}s in {@link VirtualInput} + * @see VirtualInput.VirtualKeyboardInput#nextKeyboardSubtick() + * @return If {@link VirtualKeyboardEvent}s are present in {@link VirtualInput} */ @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;next()Z", remap = false)) public boolean playback_redirectKeyboardNext() { @@ -55,7 +55,7 @@ public boolean playback_redirectKeyboardNext() { } /** - * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#getEventKeyboardKey()} + * @return {@link VirtualInput.VirtualKeyboardInput#getEventKeyboardKey()} */ @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKey()I", remap = false)) public int playback_redirectKeyboardGetEventKey() { @@ -63,7 +63,7 @@ public int playback_redirectKeyboardGetEventKey() { } /** - * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#getEventKeyboardState()} + * @return {@link VirtualInput.VirtualKeyboardInput#getEventKeyboardState()} */ @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKeyState()Z", remap = false)) public boolean playback_redirectGetEventState() { @@ -71,7 +71,7 @@ public boolean playback_redirectGetEventState() { } /** - * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#getEventKeyboardCharacter()} + * @return {@link VirtualInput.VirtualKeyboardInput#getEventKeyboardCharacter()} */ @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventCharacter()C", remap = false)) public char playback_redirectKeyboardGetEventCharacter() { @@ -80,8 +80,8 @@ public char playback_redirectKeyboardGetEventCharacter() { /** * Runs everytime {@link #playback_redirectKeyboardNext()} has an event ready. Redirects {@link org.lwjgl.input.Keyboard#isKeyDown(int)} - * @see com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#isKeyDown(int) - * @return Whether the key is down in {@link VirtualInput2} + * @see VirtualInput.VirtualKeyboardInput#isKeyDown(int) + * @return Whether the key is down in {@link VirtualInput} */ @Redirect(method = "runTickKeyboard", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;isKeyDown(I)Z", remap = false)) public boolean playback_redirectIsKeyDown(int keyCode) { @@ -89,7 +89,7 @@ public boolean playback_redirectIsKeyDown(int keyCode) { } /** - * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#getEventKeyboardKey()} + * @return {@link VirtualInput.VirtualKeyboardInput#getEventKeyboardKey()} */ @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKey()I", remap = false)) public int playback_redirectGetEventKeyDPK() { @@ -97,7 +97,7 @@ public int playback_redirectGetEventKeyDPK() { } /** - * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#getEventKeyboardState()} + * @return {@link VirtualInput.VirtualKeyboardInput#getEventKeyboardState()} */ @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventKeyState()Z", remap = false)) public boolean playback_redirectGetEventKeyStateDPK() { @@ -105,7 +105,7 @@ public boolean playback_redirectGetEventKeyStateDPK() { } /** - * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput#getEventKeyboardCharacter()} + * @return {@link VirtualInput.VirtualKeyboardInput#getEventKeyboardCharacter()} */ @Redirect(method = "dispatchKeypresses", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Keyboard;getEventCharacter()C", remap = false)) public char playback_redirectGetEventCharacterDPK() { @@ -116,7 +116,7 @@ public char playback_redirectGetEventCharacterDPK() { /** * Run at the start of run tick mouse. Runs every tick. - * @see com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualMouseInput#nextMouseTick() + * @see VirtualInput.VirtualMouseInput#nextMouseTick() * @param ci CBI */ @Inject(method = "runTickMouse", at = @At(value = "HEAD")) @@ -125,9 +125,9 @@ public void playback_injectRunTickMouse(CallbackInfo ci) { } /** - * Redirects a {@link org.lwjgl.input.Mouse#next()}. Starts running every tick and continues as long as there are {@link VirtualMouseEvent}s in {@link VirtualInput2} - * @see com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualMouseInput#nextMouseSubtick() - * @return If {@link VirtualMouseInput}s are present in {@link VirtualInput2} + * Redirects a {@link org.lwjgl.input.Mouse#next()}. Starts running every tick and continues as long as there are {@link VirtualMouseEvent}s in {@link VirtualInput} + * @see VirtualInput.VirtualMouseInput#nextMouseSubtick() + * @return If {@link VirtualMouseInput}s are present in {@link VirtualInput} */ @Redirect(method = "runTickMouse", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;next()Z", remap = false)) public boolean playback_redirectMouseNext() { @@ -135,7 +135,7 @@ public boolean playback_redirectMouseNext() { } /** - * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualMouseInput#getEventMouseKey()} + * @return {@link VirtualInput.VirtualMouseInput#getEventMouseKey()} */ @Redirect(method = "runTickMouse", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventButton()I", remap = false)) public int playback_redirectMouseGetEventButton() { @@ -143,7 +143,7 @@ public int playback_redirectMouseGetEventButton() { } /** - * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualMouseInput#getEventMouseState()} + * @return {@link VirtualInput.VirtualMouseInput#getEventMouseState()} */ @Redirect(method = "runTickMouse", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventButtonState()Z", remap = false)) public boolean playback_redirectGetEventButtonState() { @@ -151,7 +151,7 @@ public boolean playback_redirectGetEventButtonState() { } /** - * @return {@link com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualMouseInput#getEventMouseScrollWheel()} + * @return {@link VirtualInput.VirtualMouseInput#getEventMouseScrollWheel()} */ @Redirect(method = "runTickMouse", at = @At(value = "INVOKE", target = "Lorg/lwjgl/input/Mouse;getEventDWheel()I", remap = false)) public int playback_redirectGetEventDWheel() { diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index c3a9e115..b734f08f 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -683,9 +683,9 @@ private void tpPlayer(String startLocation) throws NumberFormatException { * Clears {@link #keyboard} and {@link #mouse} */ public void unpressContainer() { - LOGGER.trace(LoggerMarkers.Playback, "Unpressing container"); - keyboard.clear(); - mouse.clear(); +// LOGGER.trace(LoggerMarkers.Playback, "Unpressing container"); +// keyboard.clear(); +// mouse.clear(); } // ============================================================== @@ -747,7 +747,7 @@ public TickInputContainer(int tick) { this.tick = tick; this.keyboard = new VirtualKeyboard(); this.mouse = new VirtualMouse(); - this.subticks = new VirtualCameraAngle(0, 0); +// this.subticks = new VirtualCameraAngle(0, 0); } @Override diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java index ce383fee..0d3c2b98 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java @@ -1,29 +1,27 @@ package com.minecrafttas.tasmod.playback; -import static com.minecrafttas.tasmod.TASmod.LOGGER; - -import java.io.File; -import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.apache.commons.io.FileUtils; - import com.dselent.bigarraylist.BigArrayList; import com.minecrafttas.tasmod.TASmod; import com.minecrafttas.tasmod.monitoring.DesyncMonitoring; import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TickInputContainer; import com.minecrafttas.tasmod.util.FileThread; import com.minecrafttas.tasmod.util.LoggerMarkers; +import com.minecrafttas.tasmod.virtual.VirtualCameraAngle; import com.minecrafttas.tasmod.virtual.VirtualKey; import com.minecrafttas.tasmod.virtual.VirtualKeyboard; import com.minecrafttas.tasmod.virtual.VirtualMouse; -import com.minecrafttas.tasmod.virtual.VirtualMouse.PathNode; -import com.minecrafttas.tasmod.virtual.VirtualCameraAngle; import com.mojang.realmsclient.util.Pair; +import org.apache.commons.io.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static com.minecrafttas.tasmod.TASmod.LOGGER; /** * Saves a given {@linkplain PlaybackControllerClient} to a file. Is also able to read an input container from a file.
@@ -334,19 +332,19 @@ private VirtualKeyboard readKeyboard(String section, int linenumber) throws IOEx for (String key : splitKeys) { - VirtualKey vkey = null; - // Check if the key is a keycode - if (isNumeric(key)) { - vkey = keyboard.get(Integer.parseInt(key)); - } else { - vkey = keyboard.get(key); - } - - if (vkey == null) { - throw new IOException(key + " is not a recognised keyboard key in line " + linenumber); - } - - vkey.setPressed(true); +// VirtualKey vkey = null; +// // Check if the key is a keycode +// if (isNumeric(key)) { +// vkey = keyboard.get(Integer.parseInt(key)); +// } else { +// vkey = keyboard.get(key); +// } +// +// if (vkey == null) { +// throw new IOException(key + " is not a recognised keyboard key in line " + linenumber); +// } +// +// vkey.setPressed(true); } } @@ -357,7 +355,7 @@ private VirtualKeyboard readKeyboard(String section, int linenumber) throws IOEx } for (char onechar : chars) { - keyboard.addChar(onechar); +// keyboard.addChar(onechar); } return keyboard; } @@ -379,58 +377,58 @@ private VirtualMouse readMouse(String section, int linenumber) throws IOExceptio String[] splitButtons=buttons.split(","); for (String button : splitButtons) { - VirtualKey vkey = null; - // Check if the key is a keycode - if (isNumeric(button)) { - vkey = mouse.get(Integer.parseInt(button)); - } else { - vkey = mouse.get(button); - } - if (vkey == null) { - throw new IOException(button + " is not a recognised mouse key in line " + linenumber); - } - mouse.get(button).setPressed(true); +// VirtualKey vkey = null; +// // Check if the key is a keycode +// if (isNumeric(button)) { +// vkey = mouse.get(Integer.parseInt(button)); +// } else { +// vkey = mouse.get(button); +// } +// if (vkey == null) { +// throw new IOException(button + " is not a recognised mouse key in line " + linenumber); +// } +// mouse.get(button).setPressed(true); } } - mouse.setPath(readPath(path, linenumber, mouse)); +// mouse.setPath(readPath(path, linenumber, mouse)); return mouse; } - private List readPath(String section, int linenumber, VirtualMouse mouse) throws IOException { - List path = new ArrayList(); - - section = section.replace("[", "").replace("]", ""); - String[] pathNodes = section.split("->"); - - for (String pathNode : pathNodes) { - String[] split = pathNode.split(","); - - int length=split.length; - int scrollWheel = 0; - int cursorX = 0; - int cursorY = 0; - try { - scrollWheel = Integer.parseInt(split[length-3]); - cursorX = Integer.parseInt(split[length-2]); - cursorY = Integer.parseInt(split[length-1]); - } catch (NumberFormatException e) { - throw new IOException("'" + pathNode + "' couldn't be read in line " + linenumber+": Something is not a number"); - } catch (ArrayIndexOutOfBoundsException e) { - throw new IOException("'" + pathNode + "' couldn't be read in line " + linenumber+": Something is missing or is too much"); - } - PathNode node = mouse.new PathNode(); - for (int i=0; i readPath(String section, int linenumber, VirtualMouse mouse) throws IOException { +// List path = new ArrayList(); +// +// section = section.replace("[", "").replace("]", ""); +// String[] pathNodes = section.split("->"); +// +// for (String pathNode : pathNodes) { +// String[] split = pathNode.split(","); +// +// int length=split.length; +// int scrollWheel = 0; +// int cursorX = 0; +// int cursorY = 0; +// try { +// scrollWheel = Integer.parseInt(split[length-3]); +// cursorX = Integer.parseInt(split[length-2]); +// cursorY = Integer.parseInt(split[length-1]); +// } catch (NumberFormatException e) { +// throw new IOException("'" + pathNode + "' couldn't be read in line " + linenumber+": Something is not a number"); +// } catch (ArrayIndexOutOfBoundsException e) { +// throw new IOException("'" + pathNode + "' couldn't be read in line " + linenumber+": Something is missing or is too much"); +// } +// PathNode node = mouse.new PathNode(); +// for (int i=0; i - *
- * This mimics peripherals used to control minecraft which are: The keyboard, - * the mouse and the angle of the player, which is called "Subticks" in this - * case (this came from a time when the camera angle was actually updated on - * a subtick level).
- *
- * For each peripheral there are 2 states. The "current" state (e.g. - * {@linkplain #currentKeyboard}), which is the state of what the game - * actually currently recognizes and the "next" state (e.g. - * {@linkplain #nextKeyboard}) which either the buttons pressed on the - * keyboard, or the buttons pressed in the next playback tick.
- *
- * Outside of this class, there is a third state, which is the Vanilla Minecraft - * keybindings, which, in the best case, should be a copy of the "current" - * state.
- *

Events

To update the vanilla keybindings you need something called - * key events. An event for a keyboard might look like this
- *
- * 17,true,'w'
- *
- * Something like this is sent by the LWJGL methods to the vanilla methods to - * update the keybindings.
- * In this case it is the key with the keycode 17 (The 'W' key), in the state - * true which means it is pressed down. And the 'w' is the character that is - * associated with that key
- *
- * You can find a complete list of LWJGL keycodes in - * {@link VirtualKeyboard}.
+ * Main component for redirecting inputs.
*
- * If W is released, the key event for this would look something like this: - * 17, false, NULL
- * From that, the vanilla keybindings know which key is currently pressed down. - * As a bonus, the character 'w' is used when typing in a textfield.
- *

Emulating events

With the key events from LWJGL, so from the - * "physical keyboard", we can update the nextKeyboard in the - * {@link #updateNextKeyboard(int, boolean, char)} method.
- * This method is called every frame and also works in tickrate 0.
+ * This class mimics the LWJGL classes {@link org.lwjgl.input.Keyboard} and + * {@link org.lwjgl.input.Mouse}.
*
- * And on every tick, we call {@link #updateCurrentKeyboard()}, which updates - * the currentKeyboard with a copy of nextKeyboard.
- * However, we still need to update the Vanilla Minecraft keybinding by using - * key events.
- * To solve this problem we can use - * {@link VirtualKeyboard#getDifference(VirtualKeyboard)}, which compares 2 - * keyboards and extracts the key events from that.
- *
- * For instance if we have a keyboard, where nothing is pressed, then a keyboard - * where only "W" is pressed, we can assume that the key event responsible for - * that change 17,true,? is.
- * But as indicated by the ? we actually don't know the character that is typed - * there. And for that we need to store the characters seperately in the - * keyboard ({@link VirtualKeyboard#getCharList()}).
- *
- * The advantage of this system is: - *
    - *
  • Better support for savestates
  • - *
  • Better support for tickrate 0
  • - *
  • Less cluttering in the resulting files
  • - *
  • Recording support for the full keyboard/eventual modding support
  • - *
- * - * @author Scribble - * */ -@Deprecated -public class VirtualInput implements EventPlayerJoinedClientSide{ - - // ===========================Keyboard================================= - +public class VirtualInput { + private final Logger LOGGER; /** - * The state of the keyboard recognized by the game. Updated on a tick basis - *
- * See also: {@link VirtualInput} + * Instance of the {@link VirtualKeyboardInput} subclass, intended to improve readability. */ - private VirtualKeyboard currentKeyboard = new VirtualKeyboard(); - + public final VirtualKeyboardInput KEYBOARD; /** - * The state of the keyboard which will replace - * {@linkplain VirtualInput#currentKeyboard} in the next tick. Updated every - * frame
- * See also: {@link VirtualInput} + * Instance of the {@link VirtualMouseInput} subclass, intended to improve readability. */ - private VirtualKeyboard nextKeyboard = new VirtualKeyboard(); - - private List currentKeyboardEvents = new ArrayList(); - private Iterator currentKeyboardEventIterator = currentKeyboardEvents.iterator(); - - private VirtualKeyboardEvent currentKeyboardEvent = null; + public final VirtualMouseInput MOUSE; + /** + * Instance of the {@link VirtualCameraAngleInput} subclass, intended to improve readability. + */ + public final VirtualCameraAngleInput CAMERA_ANGLE; - public VirtualKeyboard getCurrentKeyboard() { - return currentKeyboard; + /** + * Creates a new virtual input with an empty {@link VirtualKeyboardInput}, {@link VirtualMouseInput} and {@link VirtualCameraAngleInput} + * @param logger + */ + public VirtualInput(Logger logger) { + this(logger, new VirtualKeyboard(), new VirtualMouse(), new VirtualCameraAngle()); } - public VirtualKeyboard getNextKeyboard() { - return nextKeyboard; - } - /** - * Loads the inputs and starts a TAS on initialize - * @param fileToLoad (Nullable) Loads this filename and starts playing back the TAS + * Creates a virtual input with pre-loaded values + * + * @param preloadedKeyboard A keyboard loaded when creating {@link VirtualKeyboardInput} + * @param preloadedMouse A mouse loaded when creating {@link VirtualMouseInput} + * @param preloadedCamera A camera loaded when creating {@link VirtualCameraAngleInput} */ - public VirtualInput(String fileToLoad) { - if (fileToLoad != null) { - try { - loadInputs(fileToLoad); - TASmodClient.controller.setStateWhenOpened(TASstate.PLAYBACK); - } catch (IOException e) { - LOGGER.error("Cannot load inputs from the start of the TAS: {}", e.getMessage()); - } - } + public VirtualInput(Logger logger, VirtualKeyboard preloadedKeyboard, VirtualMouse preloadedMouse, VirtualCameraAngle preloadedCamera) { + this.LOGGER = logger; + KEYBOARD = new VirtualKeyboardInput(preloadedKeyboard); + MOUSE = new VirtualMouseInput(preloadedMouse); + CAMERA_ANGLE = new VirtualCameraAngleInput(preloadedCamera); } - public void updateNextKeyboard(int keycode, boolean keystate, char character) { - -// System.out.println(keycode+" "+keystate+" "+character); - - if (keystate) { - character = nextKeyboard.encodeUnicode(keycode, character); - } else { - if (keycode == 15) { - character = '\u2907'; - } - } - nextKeyboard.addChar(character); - if (VirtualKeybindings.isKeyCodeAlwaysBlocked(keycode)) { - return; + /** + * Updates the logic for {@link #KEYBOARD}, {@link #MOUSE} and + * {@link #CAMERA_ANGLE}
+ * Runs every frame + * + * @see MixinMinecraft#playback_injectRunGameLoop(CallbackInfo) + * @param currentScreen The current screen from Minecraft.class. Used for + * checking if the mouse logic should be adapted to + * GUIScreens + */ + public void update(GuiScreen currentScreen) { + while (Keyboard.next()) { + KEYBOARD.updateNextKeyboard(Keyboard.getEventKey(), Keyboard.getEventKeyState(), Keyboard.getEventCharacter(), Keyboard.areRepeatEventsEnabled()); } - VirtualKey key = nextKeyboard.get(keycode); - - key.setPressed(keystate); - } - - public List getCurrentKeyboardEvents() { - return currentKeyboard.getDifference(nextKeyboard); - } - - public void updateCurrentKeyboard() { - currentKeyboardEvents = getCurrentKeyboardEvents(); - currentKeyboardEventIterator = currentKeyboardEvents.iterator(); - -// currentKeyboardEvents.forEach(action->{ -// System.out.println(action.toString()); -// }); - - nextKeyboard.clearCharList(); - - currentKeyboard = nextKeyboard.clone(); - } - - public boolean nextKeyboardEvent() { - boolean hasnext = currentKeyboardEventIterator.hasNext(); - if (hasnext) { - currentKeyboardEvent = currentKeyboardEventIterator.next(); + while (Mouse.next()) { + if (currentScreen == null) { + MOUSE.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), 0, 0); + } else { + Ducks.GuiScreenDuck screen = (Ducks.GuiScreenDuck) currentScreen; + int eventX = screen.unscaleX(Mouse.getEventX()); + int eventY = screen.unscaleY(Mouse.getEventY()); + eventX = PointerNormalizer.getNormalizedX(eventX); + eventY = PointerNormalizer.getNormalizedY(eventY); + MOUSE.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), eventX, eventY); + } } - return hasnext; - } - - public int getEventKeyboardKey() { - return currentKeyboardEvent.getKeyCode(); - } - - public boolean getEventKeyboardState() { - return currentKeyboardEvent.isState(); - } - - public char getEventKeyboardCharacter() { - return currentKeyboardEvent.getCharacter(); - } - - public void clearNextKeyboard() { - nextKeyboard.clear(); } + /** + * If the keyboard or mouse key is currently down. + * If keycode >= 0 then {@link VirtualKeyboardInput#isKeyDown(int)} will be called,
+ * otherwise {@link VirtualMouseInput#isKeyDown(int)} + * + * @param keycode The keycode in question + * @return If the key is down either on mouse or keyboard + */ public boolean isKeyDown(int keycode) { - if (keycode >= 0) - return currentKeyboard.get(keycode).isKeyDown(); - else - return currentMouse.get(keycode).isKeyDown(); - } - - public boolean isKeyDown(String keyname) { - if (currentKeyboard.get(keyname).isKeyDown()) { - return true; - } else if (currentMouse.get(keyname).isKeyDown()) { - return true; + if(keycode >= 0) { + return KEYBOARD.isKeyDown(keycode); } else { - return false; + return MOUSE.isKeyDown(keycode); } } - + + /** + * If the keyboard or mouse key is will be down in the next tick. + * If keycode >= 0 then {@link VirtualKeyboardInput#willKeyBeDown(int)} will be called,
+ * otherwise {@link VirtualMouseInput#willKeyBeDown(int)} + * + * @param keycode The keycode in question + * @return If the key will be down either on mouse or keyboard + */ public boolean willKeyBeDown(int keycode) { - if (keycode >= 0) - return nextKeyboard.get(keycode).isKeyDown(); - else - return nextMouse.get(keycode).isKeyDown(); - } - - public boolean willKeyBeDown(String keyname) { - if (nextKeyboard.get(keyname).isKeyDown()) { - return true; - } else if (nextMouse.get(keyname).isKeyDown()) { - return true; + if(keycode >= 0) { + return KEYBOARD.willKeyBeDown(keycode); } else { - return false; + return MOUSE.willKeyBeDown(keycode); } } - - public List getCurrentKeyboardPresses() { - List out = new ArrayList(); - - currentKeyboard.getKeyList().forEach((keycodes, virtualkeys) -> { - if (virtualkeys.isKeyDown()) { - out.add(virtualkeys.getName()); - } - }); - - return out; + + /** + * Unpresses all keys in {@link VirtualKeyboardInput#nextKeyboard} and {@link VirtualMouseInput#nextMouse} + */ + public void unpress() { + KEYBOARD.nextKeyboard.clear(); + MOUSE.nextMouse.clear(); } - - public List getNextKeyboardPresses() { - - List out = new ArrayList(); - if (TASmodClient.controller.isPlayingback() && TASmodClient.controller.get(TASmodClient.controller.index()) != null) { - TASmodClient.controller.get(TASmodClient.controller.index()).getKeyboard().getKeyList().forEach((keycodes, virtualkeys) -> { - if (virtualkeys.isKeyDown()) { - out.add(virtualkeys.getName()); - } - }); - } else { - nextKeyboard.getKeyList().forEach((keycodes, virtualkeys) -> { - if (virtualkeys.isKeyDown()) { - out.add(virtualkeys.getName()); - } - }); + + /** + * Subclass of {@link VirtualInput} handling keyboard logic.
+ *
+ * Vanilla keyboard handling looks something like this: + * + *
+	 *	public void runTickKeyboard()  { // Executed every tick in runTick()
+	 *		while({@linkplain Keyboard#next()}){
+	 *			int keycode = {@linkplain Keyboard#getEventKey()};
+	 *			boolean keystate = {@linkplain Keyboard#getEventKey()};
+	 *			char character = {@linkplain Keyboard#getEventCharacter()}
+	 *
+	 *			Keybindings.updateKeybind(keycode, keystate, character)
+	 *		}
+	 *	}
+	 * 
+ * + * After redirecting the calls in {@link MixinMinecraft}, the resulting logic + * now looks like this: + * + *
+	 *	public void runTickKeyboard()  {
+	 *		{@linkplain #nextKeyboardTick()}
+	 *		while({@linkplain #nextKeyboardSubtick()}){
+	 *			int keycode = {@linkplain #getEventKeyboardKey()}};
+	 *			boolean keystate = {@linkplain #getEventKeyboardState()};
+	 *			char character = {@linkplain #getEventKeyboardCharacter()}
+	 *
+	 *			Keybindings.updateKeybind(keycode, keystate, character)
+	 *		}
+	 *	}
+	 * 
+ * @see VirtualKeyboard + */ + public class VirtualKeyboardInput { + /** + * The keyboard "state" that is currently recognized by the game,
+ * meaning it is a direct copy of the vanilla keybindings. Updated every + * tick.
+ * Updated in {@link #nextKeyboardTick()} + */ + private final VirtualKeyboard currentKeyboard; + /** + * The "state" of the real physical keyboard.
+ * This is updated every frame.
+ * Updates {@link #currentKeyboard} in {@link #nextKeyboardTick()} + */ + private final VirtualKeyboard nextKeyboard = new VirtualKeyboard(); + /** + * Queue for keyboard events.
+ * Is filled in {@link #nextKeyboardTick()} and read in + * {@link #nextKeyboardSubtick()} + */ + private final Queue keyboardEventQueue = new ConcurrentLinkedQueue(); + /** + * The current keyboard event where the vanilla keybindings are reading + * from.
+ * Updated in {@link #nextKeyboardSubtick()} and read out in + *
    + *
  • {@link #getEventKeyboardKey()}
  • + *
  • {@link #getEventKeyboardState()}
  • + *
  • {@link #getEventKeyboardCharacter()}
  • + *
+ */ + private VirtualKeyboardEvent currentKeyboardEvent = new VirtualKeyboardEvent(); + + /** + * Constructor to preload the {@link #currentKeyboard} with an existing keyboard + * @param preloadedKeyboard The new {@link #currentKeyboard} + */ + public VirtualKeyboardInput(VirtualKeyboard preloadedKeyboard) { + currentKeyboard = preloadedKeyboard; } - return out; - } - - // =======================================Mouse============================================ - - private VirtualMouse currentMouse = new VirtualMouse(); - - private VirtualMouse nextMouse = new VirtualMouse(); - - private List currentMouseEvents = new ArrayList(); - private Iterator currentMouseEventIterator = currentMouseEvents.iterator(); - - private VirtualMouseEvent currentMouseEvent = null; - - public VirtualMouse getCurrentMouse() { - return currentMouse; - } - public VirtualMouse getNextMouse() { - return nextMouse; - } - - public void updateNextMouse(int keycode, boolean keystate, int scrollwheel, int cursorX, int cursorY, boolean filter) { - - boolean flag = true; - if (filter) { - flag = nextMouse.isSomethingDown() || scrollwheel != 0 || keycode != -1; + /** + * Updates the next keyboard + * + * @see VirtualInput#update(GuiScreen) + * @param keycode The keycode of this event + * @param keystate The keystate of this event + * @param character The character of this event + */ + public void updateNextKeyboard(int keycode, boolean keystate, char character) { + updateNextKeyboard(keycode, keystate, character, false); } - VirtualKey key = nextMouse.get(keycode - 100); - - if (VirtualKeybindings.isKeyCodeAlwaysBlocked(keycode - 100)) { - key.setPressed(false); - return; + /** + * Updates the next keyboard + * + * @see VirtualInput#update(GuiScreen) + * @param keycode The keycode of this event + * @param keystate The keystate of this event + * @param character The character of this event + * @param repeatEventsEnabled If repeat events are enabled + */ + public void updateNextKeyboard(int keycode, boolean keystate, char character, boolean repeatEventsEnabled) { + LOGGER.debug(LoggerMarkers.Keyboard, "Update: {}, {}, {}, {}", keycode, keystate, character); // Activate with -Dtasmod.marker.keyboard=ACCEPT in VM arguments (and -Dtasmod.log.level=debug) + nextKeyboard.update(keycode, keystate, character, repeatEventsEnabled); } - key.setPressed(keystate); - - nextMouse.setScrollWheel(scrollwheel); - - nextMouse.setCursor(PointerNormalizer.getNormalizedX(cursorX), PointerNormalizer.getNormalizedY(cursorY)); - - if (flag == true) - nextMouse.addPathNode(); - } - - public List getCurrentMouseEvents() { - return currentMouse.getDifference(nextMouse); - } - - public void updateCurrentMouseEvents() { - currentMouseEvents = getCurrentMouseEvents(); - currentMouseEventIterator = currentMouseEvents.iterator(); - - // Prints the mouse events given to the keybindings... very useful -// currentMouseEvents.forEach(action->{ -// System.out.println(action.toString()); -// }); - - resetNextMouseLists(); - - currentMouse = nextMouse.clone(); - } - - public void resetNextMouseLists() { - nextMouse.resetPath(); - } - - public boolean nextMouseEvent() { - boolean hasnext = currentMouseEventIterator.hasNext(); - if (hasnext) { - currentMouseEvent = currentMouseEventIterator.next(); + /** + * Runs when the next keyboard tick is about to occur.
+ * Used to load {@link #nextKeyboard} into {@link #currentKeyboard}, creating + * {@link VirtualKeyboardEvent}s in the process. + * + * @see MixinMinecraft#playback_injectRunTickKeyboard(org.spongepowered.asm.mixin.injection.callback.CallbackInfo) + */ + public void nextKeyboardTick() { + currentKeyboard.getVirtualEvents(nextKeyboard, keyboardEventQueue); + currentKeyboard.copyFrom(nextKeyboard); } - return hasnext; - } - - public int getEventMouseKey() { - return currentMouseEvent.getKeyCode(); - } - - public boolean getEventMouseState() { - return currentMouseEvent.isState(); - } - - public int getEventMouseScrollWheel() { - return currentMouseEvent.getScrollwheel(); - } - - public int getEventCursorX() { - return PointerNormalizer.getCoordsX(currentMouseEvent.getCursorX()); - } - - public int getEventCursorY() { - return PointerNormalizer.getCoordsY(currentMouseEvent.getCursorY()); - } - - public void clearNextMouse() { - nextMouse.clear(); - } - - public List getCurrentMousePresses() { - List out = new ArrayList(); - - currentMouse.getKeyList().forEach((keycodes, virtualkeys) -> { - if (virtualkeys.isKeyDown()) { - out.add(virtualkeys.getName()); - } - }); - - return out; - } - - public List getNextMousePresses() { - List out = new ArrayList(); - if (TASmodClient.controller.isPlayingback() && TASmodClient.controller.get(TASmodClient.controller.index()) != null) { - TASmodClient.controller.get(TASmodClient.controller.index()).getMouse().getKeyList().forEach((keycodes, virtualkeys) -> { - if (virtualkeys.isKeyDown()) { - out.add(virtualkeys.getName()); - } - }); - } else { - nextMouse.getKeyList().forEach((keycodes, virtualkeys) -> { - if (virtualkeys.isKeyDown()) { - out.add(virtualkeys.getName()); - } - }); + /** + * Runs in a while loop. Used for updating {@link #currentKeyboardEvent} and + * ending the while loop. + * + * @see MixinMinecraft#playback_redirectKeyboardNext() + * @return If a keyboard event is in {@link #keyboardEventQueue} + */ + public boolean nextKeyboardSubtick() { + return (currentKeyboardEvent = keyboardEventQueue.poll()) != null; } - return out; - } - - public void unpressEverything() { - TASmodClient.controller.unpressContainer(); - unpressNext(); - } - - public void unpressNext() { - clearNextKeyboard(); - clearNextMouse(); - } - - // ======================================Subticks=========================================== - - VirtualCameraAngle currentSubtick = new VirtualCameraAngle(0, 0); - - public void updateSubtick(float pitch, float yaw) { - currentSubtick = TASmodClient.controller.addSubticksToContainer(new VirtualCameraAngle(pitch, yaw)); - } - - public float getSubtickPitch() { - return currentSubtick.getPitch(); - } - - public float getSubtickYaw() { - return currentSubtick.getYaw(); - } + /** + * @return The keycode of {@link #currentKeyboardEvent} + */ + public int getEventKeyboardKey() { + return currentKeyboardEvent.getKeyCode(); + } - // =====================================Container=========================================== + /** + * @return The keystate of {@link #currentKeyboardEvent} + */ + public boolean getEventKeyboardState() { + return currentKeyboardEvent.isState(); + } - /** - * Updates the input container and the {@link #nextKeyboard} as well as - * {@link #nextMouse}
- * Gets executed each game tick - */ - public void updateContainer() { - nextKeyboard = TASmodClient.controller.addKeyboardToContainer(nextKeyboard); - nextMouse = TASmodClient.controller.addMouseToContainer(nextMouse); + /** + * @return The character(s) of {@link #currentKeyboardEvent} + */ + public char getEventKeyboardCharacter() { + return currentKeyboardEvent.getCharacter(); + } + + /** + * If the key is currently down and recognised by Minecraft + * @param keycode The keycode of the key in question + * @return Whether the key of the {@link #currentKeyboard} is down + */ + public boolean isKeyDown(int keycode) { + return currentKeyboard.isKeyDown(keycode); + } + + /** + * If the key will be down and recognised in the next tick by Minecraft.
+ * This is equal to checking if a key on the physical keyboard is pressed + * @param keycode The keycode of the key in question + * @return Whether the key of the {@link #nextKeyboard} is down + */ + public boolean willKeyBeDown(int keycode) { + return nextKeyboard.isKeyDown(keycode); + } } /** - * Replaces the {@link TASmodClient#controller}, used in + * Subclass of {@link VirtualInput} handling mouse logic.
+ *
+ * Vanilla mouse handling looks something like this: * - * @param container to replace the current one - */ - public void setContainer(PlaybackControllerClient container) { - TASmodClient.controller = container; - } - - // =====================================Savestates=========================================== - - /** - * Loads and preloads the inputs from the new InputContainer to - * {@link TASmodClient#controller} + *
+	 *	public void runTickMouse()  { // Executed every tick in runTick()
+	 *		while({@linkplain Mouse#next()}){
+	 *			int keycode = {@linkplain Mouse#getEventButton()};
+	 *			boolean keystate = {@linkplain Mouse#getEventButtonState()};
+	 *			int scrollWheel = {@linkplain Mouse#getEventDWheel()}
+	 *			int cursorX = {@linkplain Mouse#getEventX()} // Important in GUIs
+	 *			int cursorY = {@linkplain Mouse#getEventY()}
+	 *
+	 *			Keybindings.updateKeybind(keycode, keystate, etc...)
+	 *		}
+	 *	}
+	 * 
* - * Saving a savestate is done via {@linkplain com.minecrafttas.tasmod.playback.PlaybackSerialiser#saveToFileV1(File, PlaybackControllerClient)} in {@linkplain com.minecrafttas.tasmod.savestates.SavestateHandlerClient#savestate(String)} + * After redirecting the calls in {@link MixinMinecraft}, the resulting logic + * now looks like this: * - * @param savestatecontainer The container that should be loaded. + *
+	 *	public void runTickMouse()  { // Executed every tick in runTick()
+	 *		{@linkplain #nextMouseTick()}
+	 *		while({@linkplain #nextMouseSubtick}){
+	 *			int keycode = {@linkplain #getEventMouseKey};
+	 *			boolean keystate = {@linkplain #getEventMouseState()} ()};
+	 *			int scrollWheel = {@linkplain #getEventMouseScrollWheel()}
+	 *			int cursorX = {@linkplain #getEventCursorX()} // Important in GUIs
+	 *			int cursorY = {@linkplain #getEventCursorY()}
+	 *
+	 *			Keybindings.updateKeybind(keycode, keystate, etc...)
+	 *		}
+	 *	}
+	 * 
+ * @see VirtualMouse */ - public void loadClientSavestate(PlaybackControllerClient savestatecontainer) { - - if (TASmodClient.controller.isPlayingback()) { - preloadInput(TASmodClient.controller, savestatecontainer.size() - 1); // Preloading from the current container and - // from the second to last index of - // the savestatecontainer. Since this is - // executed during playback, - // we will only load the position of the - // savestate container and not replace the - // container itself. This is due to the fact - // that the playback would immediately end - // when you replace the container. - - if (TASmodClient.controller.size() >= savestatecontainer.size()) { // Check if the current container is bigger than the - // savestated one. - - try { - TASmodClient.controller.setIndex(savestatecontainer.size()); // Set the "playback" index of the current - // container to the latest index of the - // savestatecontainer. Meaning this index will - // be played next - } catch (IndexOutOfBoundsException e) { - e.printStackTrace(); - } - } else { - String start = savestatecontainer.getStartLocation(); - savestatecontainer.setStartLocation(""); - - try { - savestatecontainer.setIndex(savestatecontainer.size() - 1); - } catch (IndexOutOfBoundsException e) { - e.printStackTrace(); - } - savestatecontainer.setTASStateClient(TASstate.PLAYBACK); - savestatecontainer.setStartLocation(start); - TASmodClient.controller = savestatecontainer; - } + public class VirtualMouseInput { + /** + * The mouse "state" that is currently recognized by the game,
+ * meaning it is a direct copy of the vanilla mouse. Updated every + * tick.
+ * Updated in {@link #nextMouseTick()} + */ + private final VirtualMouse currentMouse; + /** + * The "state" of the real physical mouse.
+ * This is updated every frame.
+ * Updates {@link #currentMouse} in {@link #nextMouseTick()} + */ + private final VirtualMouse nextMouse = new VirtualMouse(); + /** + * Queue for keyboard events.
+ * Is filled in {@link #nextMouseTick()} and read in + * {@link #nextMouseSubtick()} + */ + private final Queue mouseEventQueue = new ConcurrentLinkedQueue<>(); + /** + * The current mouse event where the vanilla mouse is reading + * from.
+ * Updated in {@link #nextMouseSubtick()} and read out in + *
    + *
  • {@link #getEventMouseKey()}
  • + *
  • {@link #getEventMouseState()}
  • + *
  • {@link #getEventMouseScrollWheel()}
  • + *
  • {@link #getEventCursorX()}
  • + *
  • {@link #getEventCursorY()}
  • + *
+ */ + private VirtualMouseEvent currentMouseEvent = new VirtualMouseEvent(); + + /** + * Constructor to preload the {@link #currentMouse} with an existing mouse + * @param preloadedMouse The new {@link #currentMouse} + */ + public VirtualMouseInput(VirtualMouse preloadedMouse) { + currentMouse = preloadedMouse; + } - } else if (TASmodClient.controller.isRecording()) { - String start = savestatecontainer.getStartLocation(); - preloadInput(savestatecontainer, savestatecontainer.size() - 1); // Preload the input of the savestate + /** + * Updates the next keyboard + * + * @see VirtualInput#update(GuiScreen) + * @param keycode The keycode of this event + * @param keystate The keystate of this event + * @param character The character of this event + * @param repeatEventsEnabled If repeat events are enabled + */ + public void updateNextMouse(int keycode, boolean keystate, int scrollwheel, int cursorX, int cursorY) { + keycode-=100; + LOGGER.debug(LoggerMarkers.Mouse,"Update: {} ({}), {}, {}, {}, {}", keycode, VirtualKey.getName(keycode), keystate, scrollwheel, cursorX, cursorY); // Activate with -Dtasmod.marker.mouse=ACCEPT in VM arguments (and -Dtasmod.log.level=debug) + nextMouse.update(keycode, keystate, scrollwheel, cursorX, cursorY); + } - nextKeyboard = new VirtualKeyboard(); // Unpress the nextKeyboard and mouse to get rid of the preloaded inputs in the - // next keyboard. Note that these inputs are still loaded in the current - // keyboard - nextMouse = new VirtualMouse(); + /** + * Runs when the next mouse tick is about to occur.
+ * Used to load {@link #nextMouse} into {@link #currentMouse}, creating + * {@link VirtualMouseEvent}s in the process. + * + * @see MixinMinecraft#playback_injectRunTickMouse(org.spongepowered.asm.mixin.injection.callback.CallbackInfo) + */ + public void nextMouseTick() { + currentMouse.getVirtualEvents(nextMouse, mouseEventQueue); + currentMouse.copyFrom(nextMouse); + } - try { - savestatecontainer.setIndex(savestatecontainer.size()); - } catch(IndexOutOfBoundsException e) { - e.printStackTrace(); - } - - savestatecontainer.setTASStateClient(TASstate.RECORDING); - savestatecontainer.setStartLocation(start); - TASmodClient.controller = savestatecontainer; // Replace the current container with the savestated container + /** + * Runs in a while loop. Used for updating {@link #currentMouseEvent} and + * ending the while loop. + * + * @see MixinMinecraft#playback_redirectMouseNext() + * @return If a mouse event is in {@link #mouseEventQueue} + */ + public boolean nextMouseSubtick() { + return (currentMouseEvent = mouseEventQueue.poll()) != null; } - } - /** - * Preloads the specified index from, the container to {@link #nextMouse} and - * {@link #nextKeyboard} - * - * @param container The container from which the inputs should be pre loaded - * @param index The index of the container from which the inputs should be - * loaded - */ - private void preloadInput(PlaybackControllerClient container, int index) { - TickInputContainer tickcontainer = container.get(index); + /** + * @return The keycode of {@link #currentMouseEvent} + */ + public int getEventMouseKey() { + return currentMouseEvent.getKeyCode(); + } - if (tickcontainer != null) { - tickcontainer = tickcontainer.clone(); - nextKeyboard = tickcontainer.getKeyboard().clone(); - nextMouse = tickcontainer.getMouse().clone(); + /** + * @return The keystate of {@link #currentMouseEvent} + */ + public boolean getEventMouseState() { + return currentMouseEvent.isState(); + } - Minecraft.getMinecraft().runTickKeyboard(); // Letting mouse and keyboard tick once to load inputs into the - // "currentKeyboard" - Minecraft.getMinecraft().runTickMouse(); - } else { - LOGGER.warn("Can't preload inputs, specified inputs are null!"); + /** + * @return The scroll wheel of {@link #currentMouseEvent} + */ + public int getEventMouseScrollWheel() { + return currentMouseEvent.getScrollwheel(); } - } - // ================================Load/Save Inputs===================================== - - public void loadInputs(String filename) throws IOException { - setContainer(TASmodClient.serialiser.fromEntireFileV1(new File(TASmodClient.tasdirectory + "/" + filename + ".mctas"))); - TASmodClient.controller.fixTicks(); - } - - public void saveInputs(String filename) throws IOException { - TASmodClient.createTASDir(); - TASmodClient.serialiser.saveToFileV1(new File(TASmodClient.tasdirectory + "/" + filename + ".mctas"), TASmodClient.controller); - } - // =====================================Debug=========================================== + /** + * @return The x coordinate of the cursor of {@link #currentMouseEvent} + */ + public int getEventCursorX() { + return PointerNormalizer.getCoordsX(currentMouseEvent.getCursorX()); + } - public class InputEvent { - public int tick; - public List keyboardevent; - public List mouseEvent; - public VirtualCameraAngle subticks; + /** + * @return The y coordinate of the cursor of {@link #currentMouseEvent} + */ + public int getEventCursorY() { + return PointerNormalizer.getCoordsY(currentMouseEvent.getCursorY()); + } - public InputEvent(int tick, List keyboardevent, List mouseEvent, VirtualCameraAngle subticks) { - this.tick = tick; - this.keyboardevent = keyboardevent; - this.mouseEvent = mouseEvent; - this.subticks = subticks; + /** + * If the key is currently down and recognised by Minecraft + * @param keycode The keycode of the key in question + * @return Whether the key of the {@link #currentMouse} is down + */ + public boolean isKeyDown(int keycode) { + return currentMouse.isKeyDown(keycode); + } + + /** + * If the key will be down and recognised in the next tick by Minecraft.
+ * This is equal to checking if a key on the physical mouse is pressed + * @param keycode The keycode of the key in question + * @return Whether the key of the {@link #nextMouse} is down + */ + public boolean willKeyBeDown(int keycode) { + return nextMouse.isKeyDown(keycode); } + } - /** - * Gets all InputEvents from the current container.
- *
- * Container and input events differ in that input events are the events that - * get accepted by Minecraft in the runTickKeyboard.
- * The container however stores the current inputs and can calculate the - * corresponding input events from that, but it does it only when you are - * playing back or recording.
- *
- * This however runs through the {@link TASmodClient#controller} and generates - * the input events on for debug purposes. - * - * @return - */ - public List getAllInputEvents() { - - List main = new ArrayList<>(); - - for (int i = 0; i < TASmodClient.controller.size(); i++) { - - TickInputContainer tick = TASmodClient.controller.get(i); - TickInputContainer nextTick = TASmodClient.controller.get(i + 1); + public class VirtualCameraAngleInput { + private final VirtualCameraAngle cameraAngle; - if (nextTick == null) { - nextTick = new TickInputContainer(i + 1); // Fills the last tick in the container with an empty TickInputContainer - } - - VirtualKeyboard keyboard = tick.getKeyboard(); - List keyboardEventsList = keyboard.getDifference(nextTick.getKeyboard()); - - VirtualMouse mouse = tick.getMouse(); - List mouseEventsList = mouse.getDifference(nextTick.getMouse()); - - main.add(new InputEvent(tick.getTick(), keyboardEventsList, mouseEventsList, tick.getSubticks())); + public VirtualCameraAngleInput(VirtualCameraAngle preloadedCamera) { + cameraAngle = preloadedCamera; + } + + public void updateCameraAngle(float pitch, float yaw) { + cameraAngle.update(pitch, yaw); + } + + public float getPitch() { + return cameraAngle.getPitch(); + } + + public float getYaw() { + return cameraAngle.getYaw(); } - return main; - } - - @Override - public void onPlayerJoinedClientSide(EntityPlayerSP player) { - unpressNext(); } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java deleted file mode 100644 index db3f13d5..00000000 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput2.java +++ /dev/null @@ -1,486 +0,0 @@ -package com.minecrafttas.tasmod.virtual; - -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; - -import org.apache.logging.log4j.Logger; -import org.lwjgl.input.Keyboard; -import org.lwjgl.input.Mouse; - -import com.minecrafttas.tasmod.mixin.playbackhooks.MixinMinecraft; -import com.minecrafttas.tasmod.util.Ducks; -import com.minecrafttas.tasmod.util.LoggerMarkers; -import com.minecrafttas.tasmod.util.PointerNormalizer; - -import net.minecraft.client.gui.GuiScreen; - -/** - * Main component for redirecting inputs.
- *
- * This class mimics the LWJGL classes {@link org.lwjgl.input.Keyboard} and - * {@link org.lwjgl.input.Mouse}.
- *
- */ -public class VirtualInput2 { - private final Logger LOGGER; - /** - * Instance of the {@link VirtualKeyboardInput} subclass, intended to improve readability. - */ - public final VirtualKeyboardInput KEYBOARD; - /** - * Instance of the {@link VirtualMouseInput} subclass, intended to improve readability. - */ - public final VirtualMouseInput MOUSE; - /** - * Instance of the {@link VirtualCameraAngleInput} subclass, intended to improve readability. - */ - public final VirtualCameraAngleInput CAMERA_ANGLE; - - /** - * Creates a new virtual input with an empty {@link VirtualKeyboardInput}, {@link VirtualMouseInput} and {@link VirtualCameraAngleInput} - * @param logger - */ - public VirtualInput2(Logger logger) { - this(logger, new VirtualKeyboard2(), new VirtualMouse2(), new VirtualCameraAngle2()); - } - - /** - * Creates a virtual input with pre-loaded values - * - * @param preloadedKeyboard A keyboard loaded when creating {@link VirtualKeyboardInput} - * @param preloadedMouse A mouse loaded when creating {@link VirtualMouseInput} - * @param preloadedCamera A camera loaded when creating {@link VirtualCameraAngleInput} - */ - public VirtualInput2(Logger logger, VirtualKeyboard2 preloadedKeyboard, VirtualMouse2 preloadedMouse, VirtualCameraAngle2 preloadedCamera) { - this.LOGGER = logger; - KEYBOARD = new VirtualKeyboardInput(preloadedKeyboard); - MOUSE = new VirtualMouseInput(preloadedMouse); - CAMERA_ANGLE = new VirtualCameraAngleInput(preloadedCamera); - } - - /** - * Updates the logic for {@link #KEYBOARD}, {@link #MOUSE} and - * {@link #CAMERA_ANGLE}
- * Runs every frame - * - * @see MixinMinecraft#playback_injectRunGameLoop(CallbackInfo) - * @param currentScreen The current screen from Minecraft.class. Used for - * checking if the mouse logic should be adapted to - * GUIScreens - */ - public void update(GuiScreen currentScreen) { - while (Keyboard.next()) { - KEYBOARD.updateNextKeyboard(Keyboard.getEventKey(), Keyboard.getEventKeyState(), Keyboard.getEventCharacter(), Keyboard.areRepeatEventsEnabled()); - } - while (Mouse.next()) { - if (currentScreen == null) { - MOUSE.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), 0, 0); - } else { - Ducks.GuiScreenDuck screen = (Ducks.GuiScreenDuck) currentScreen; - int eventX = screen.unscaleX(Mouse.getEventX()); - int eventY = screen.unscaleY(Mouse.getEventY()); - eventX = PointerNormalizer.getNormalizedX(eventX); - eventY = PointerNormalizer.getNormalizedY(eventY); - MOUSE.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), eventX, eventY); - } - } - } - - /** - * If the keyboard or mouse key is currently down. - * If keycode >= 0 then {@link VirtualKeyboardInput#isKeyDown(int)} will be called,
- * otherwise {@link VirtualMouseInput#isKeyDown(int)} - * - * @param keycode The keycode in question - * @return If the key is down either on mouse or keyboard - */ - public boolean isKeyDown(int keycode) { - if(keycode >= 0) { - return KEYBOARD.isKeyDown(keycode); - } else { - return MOUSE.isKeyDown(keycode); - } - } - - /** - * If the keyboard or mouse key is will be down in the next tick. - * If keycode >= 0 then {@link VirtualKeyboardInput#willKeyBeDown(int)} will be called,
- * otherwise {@link VirtualMouseInput#willKeyBeDown(int)} - * - * @param keycode The keycode in question - * @return If the key will be down either on mouse or keyboard - */ - public boolean willKeyBeDown(int keycode) { - if(keycode >= 0) { - return KEYBOARD.willKeyBeDown(keycode); - } else { - return MOUSE.willKeyBeDown(keycode); - } - } - - /** - * Unpresses all keys in {@link VirtualKeyboardInput#nextKeyboard} and {@link VirtualMouseInput#nextMouse} - */ - public void unpress() { - KEYBOARD.nextKeyboard.clear(); - MOUSE.nextMouse.clear(); - } - - /** - * Subclass of {@link VirtualInput2} handling keyboard logic.
- *
- * Vanilla keyboard handling looks something like this: - * - *
-	 *	public void runTickKeyboard()  { // Executed every tick in runTick()
-	 *		while({@linkplain Keyboard#next()}){
-	 *			int keycode = {@linkplain Keyboard#getEventKey()};
-	 *			boolean keystate = {@linkplain Keyboard#getEventKey()};
-	 *			char character = {@linkplain Keyboard#getEventCharacter()}
-	 *
-	 *			Keybindings.updateKeybind(keycode, keystate, character)
-	 *		}
-	 *	}
-	 * 
- * - * After redirecting the calls in {@link MixinMinecraft}, the resulting logic - * now looks like this: - * - *
-	 *	public void runTickKeyboard()  {
-	 *		{@linkplain #nextKeyboardTick()}
-	 *		while({@linkplain #nextKeyboardSubtick()}){
-	 *			int keycode = {@linkplain #getEventKeyboardKey()}};
-	 *			boolean keystate = {@linkplain #getEventKeyboardState()};
-	 *			char character = {@linkplain #getEventKeyboardCharacter()}
-	 *
-	 *			Keybindings.updateKeybind(keycode, keystate, character)
-	 *		}
-	 *	}
-	 * 
- * @see com.minecrafttas.tasmod.virtual.VirtualKeyboard2 - */ - public class VirtualKeyboardInput { - /** - * The keyboard "state" that is currently recognized by the game,
- * meaning it is a direct copy of the vanilla keybindings. Updated every - * tick.
- * Updated in {@link #nextKeyboardTick()} - */ - private final VirtualKeyboard2 currentKeyboard; - /** - * The "state" of the real physical keyboard.
- * This is updated every frame.
- * Updates {@link #currentKeyboard} in {@link #nextKeyboardTick()} - */ - private final VirtualKeyboard2 nextKeyboard = new VirtualKeyboard2(); - /** - * Queue for keyboard events.
- * Is filled in {@link #nextKeyboardTick()} and read in - * {@link #nextKeyboardSubtick()} - */ - private final Queue keyboardEventQueue = new ConcurrentLinkedQueue(); - /** - * The current keyboard event where the vanilla keybindings are reading - * from.
- * Updated in {@link #nextKeyboardSubtick()} and read out in - *
    - *
  • {@link #getEventKeyboardKey()}
  • - *
  • {@link #getEventKeyboardState()}
  • - *
  • {@link #getEventKeyboardCharacter()}
  • - *
- */ - private VirtualKeyboardEvent currentKeyboardEvent = new VirtualKeyboardEvent(); - - /** - * Constructor to preload the {@link #currentKeyboard} with an existing keyboard - * @param preloadedKeyboard The new {@link #currentKeyboard} - */ - public VirtualKeyboardInput(VirtualKeyboard2 preloadedKeyboard) { - currentKeyboard = preloadedKeyboard; - } - - /** - * Updates the next keyboard - * - * @see VirtualInput2#update(GuiScreen) - * @param keycode The keycode of this event - * @param keystate The keystate of this event - * @param character The character of this event - */ - public void updateNextKeyboard(int keycode, boolean keystate, char character) { - updateNextKeyboard(keycode, keystate, character, false); - } - - /** - * Updates the next keyboard - * - * @see VirtualInput2#update(GuiScreen) - * @param keycode The keycode of this event - * @param keystate The keystate of this event - * @param character The character of this event - * @param repeatEventsEnabled If repeat events are enabled - */ - public void updateNextKeyboard(int keycode, boolean keystate, char character, boolean repeatEventsEnabled) { - LOGGER.debug(LoggerMarkers.Keyboard, "Update: {}, {}, {}, {}", keycode, keystate, character); // Activate with -Dtasmod.marker.keyboard=ACCEPT in VM arguments (and -Dtasmod.log.level=debug) - nextKeyboard.update(keycode, keystate, character, repeatEventsEnabled); - } - - /** - * Runs when the next keyboard tick is about to occur.
- * Used to load {@link #nextKeyboard} into {@link #currentKeyboard}, creating - * {@link VirtualKeyboardEvent}s in the process. - * - * @see MixinMinecraft#playback_injectRunTickKeyboard(org.spongepowered.asm.mixin.injection.callback.CallbackInfo) - */ - public void nextKeyboardTick() { - currentKeyboard.getVirtualEvents(nextKeyboard, keyboardEventQueue); - currentKeyboard.copyFrom(nextKeyboard); - } - - /** - * Runs in a while loop. Used for updating {@link #currentKeyboardEvent} and - * ending the while loop. - * - * @see MixinMinecraft#playback_redirectKeyboardNext() - * @return If a keyboard event is in {@link #keyboardEventQueue} - */ - public boolean nextKeyboardSubtick() { - return (currentKeyboardEvent = keyboardEventQueue.poll()) != null; - } - - /** - * @return The keycode of {@link #currentKeyboardEvent} - */ - public int getEventKeyboardKey() { - return currentKeyboardEvent.getKeyCode(); - } - - /** - * @return The keystate of {@link #currentKeyboardEvent} - */ - public boolean getEventKeyboardState() { - return currentKeyboardEvent.isState(); - } - - /** - * @return The character(s) of {@link #currentKeyboardEvent} - */ - public char getEventKeyboardCharacter() { - return currentKeyboardEvent.getCharacter(); - } - - /** - * If the key is currently down and recognised by Minecraft - * @param keycode The keycode of the key in question - * @return Whether the key of the {@link #currentKeyboard} is down - */ - public boolean isKeyDown(int keycode) { - return currentKeyboard.isKeyDown(keycode); - } - - /** - * If the key will be down and recognised in the next tick by Minecraft.
- * This is equal to checking if a key on the physical keyboard is pressed - * @param keycode The keycode of the key in question - * @return Whether the key of the {@link #nextKeyboard} is down - */ - public boolean willKeyBeDown(int keycode) { - return nextKeyboard.isKeyDown(keycode); - } - } - - /** - * Subclass of {@link VirtualInput2} handling mouse logic.
- *
- * Vanilla mouse handling looks something like this: - * - *
-	 *	public void runTickMouse()  { // Executed every tick in runTick()
-	 *		while({@linkplain Mouse#next()}){
-	 *			int keycode = {@linkplain Mouse#getEventButton()};
-	 *			boolean keystate = {@linkplain Mouse#getEventButtonState()};
-	 *			int scrollWheel = {@linkplain Mouse#getEventDWheel()}
-	 *			int cursorX = {@linkplain Mouse#getEventX()} // Important in GUIs
-	 *			int cursorY = {@linkplain Mouse#getEventY()}
-	 *
-	 *			Keybindings.updateKeybind(keycode, keystate, etc...)
-	 *		}
-	 *	}
-	 * 
- * - * After redirecting the calls in {@link MixinMinecraft}, the resulting logic - * now looks like this: - * - *
-	 *	public void runTickMouse()  { // Executed every tick in runTick()
-	 *		{@linkplain #nextMouseTick()}
-	 *		while({@linkplain #nextMouseSubtick}){
-	 *			int keycode = {@linkplain #getEventMouseKey};
-	 *			boolean keystate = {@linkplain #getEventMouseState()} ()};
-	 *			int scrollWheel = {@linkplain #getEventMouseScrollWheel()}
-	 *			int cursorX = {@linkplain #getEventCursorX()} // Important in GUIs
-	 *			int cursorY = {@linkplain #getEventCursorY()}
-	 *
-	 *			Keybindings.updateKeybind(keycode, keystate, etc...)
-	 *		}
-	 *	}
-	 * 
- * @see com.minecrafttas.tasmod.virtual.VirtualMouse2 - */ - public class VirtualMouseInput { - /** - * The mouse "state" that is currently recognized by the game,
- * meaning it is a direct copy of the vanilla mouse. Updated every - * tick.
- * Updated in {@link #nextMouseTick()} - */ - private final VirtualMouse2 currentMouse; - /** - * The "state" of the real physical mouse.
- * This is updated every frame.
- * Updates {@link #currentMouse} in {@link #nextMouseTick()} - */ - private final VirtualMouse2 nextMouse = new VirtualMouse2(); - /** - * Queue for keyboard events.
- * Is filled in {@link #nextMouseTick()} and read in - * {@link #nextMouseSubtick()} - */ - private final Queue mouseEventQueue = new ConcurrentLinkedQueue<>(); - /** - * The current mouse event where the vanilla mouse is reading - * from.
- * Updated in {@link #nextMouseSubtick()} and read out in - *
    - *
  • {@link #getEventMouseKey()}
  • - *
  • {@link #getEventMouseState()}
  • - *
  • {@link #getEventMouseScrollWheel()}
  • - *
  • {@link #getEventCursorX()}
  • - *
  • {@link #getEventCursorY()}
  • - *
- */ - private VirtualMouseEvent currentMouseEvent = new VirtualMouseEvent(); - - /** - * Constructor to preload the {@link #currentMouse} with an existing mouse - * @param preloadedMouse The new {@link #currentMouse} - */ - public VirtualMouseInput(VirtualMouse2 preloadedMouse) { - currentMouse = preloadedMouse; - } - - /** - * Updates the next keyboard - * - * @see VirtualInput2#update(GuiScreen) - * @param keycode The keycode of this event - * @param keystate The keystate of this event - * @param character The character of this event - * @param repeatEventsEnabled If repeat events are enabled - */ - public void updateNextMouse(int keycode, boolean keystate, int scrollwheel, int cursorX, int cursorY) { - keycode-=100; - LOGGER.debug(LoggerMarkers.Mouse,"Update: {} ({}), {}, {}, {}, {}", keycode, VirtualKey2.getName(keycode), keystate, scrollwheel, cursorX, cursorY); // Activate with -Dtasmod.marker.mouse=ACCEPT in VM arguments (and -Dtasmod.log.level=debug) - nextMouse.update(keycode, keystate, scrollwheel, cursorX, cursorY); - } - - /** - * Runs when the next mouse tick is about to occur.
- * Used to load {@link #nextMouse} into {@link #currentMouse}, creating - * {@link VirtualMouseEvent}s in the process. - * - * @see MixinMinecraft#playback_injectRunTickMouse(org.spongepowered.asm.mixin.injection.callback.CallbackInfo) - */ - public void nextMouseTick() { - currentMouse.getVirtualEvents(nextMouse, mouseEventQueue); - currentMouse.copyFrom(nextMouse); - } - - /** - * Runs in a while loop. Used for updating {@link #currentMouseEvent} and - * ending the while loop. - * - * @see MixinMinecraft#playback_redirectMouseNext() - * @return If a mouse event is in {@link #mouseEventQueue} - */ - public boolean nextMouseSubtick() { - return (currentMouseEvent = mouseEventQueue.poll()) != null; - } - - /** - * @return The keycode of {@link #currentMouseEvent} - */ - public int getEventMouseKey() { - return currentMouseEvent.getKeyCode(); - } - - /** - * @return The keystate of {@link #currentMouseEvent} - */ - public boolean getEventMouseState() { - return currentMouseEvent.isState(); - } - - /** - * @return The scroll wheel of {@link #currentMouseEvent} - */ - public int getEventMouseScrollWheel() { - return currentMouseEvent.getScrollwheel(); - } - - /** - * @return The x coordinate of the cursor of {@link #currentMouseEvent} - */ - public int getEventCursorX() { - return PointerNormalizer.getCoordsX(currentMouseEvent.getCursorX()); - } - - /** - * @return The y coordinate of the cursor of {@link #currentMouseEvent} - */ - public int getEventCursorY() { - return PointerNormalizer.getCoordsY(currentMouseEvent.getCursorY()); - } - - /** - * If the key is currently down and recognised by Minecraft - * @param keycode The keycode of the key in question - * @return Whether the key of the {@link #currentMouse} is down - */ - public boolean isKeyDown(int keycode) { - return currentMouse.isKeyDown(keycode); - } - - /** - * If the key will be down and recognised in the next tick by Minecraft.
- * This is equal to checking if a key on the physical mouse is pressed - * @param keycode The keycode of the key in question - * @return Whether the key of the {@link #nextMouse} is down - */ - public boolean willKeyBeDown(int keycode) { - return nextMouse.isKeyDown(keycode); - } - - } - - public class VirtualCameraAngleInput { - private final VirtualCameraAngle2 cameraAngle; - - public VirtualCameraAngleInput(VirtualCameraAngle2 preloadedCamera) { - cameraAngle = preloadedCamera; - } - - public void updateCameraAngle(float pitch, float yaw) { - cameraAngle.update(pitch, yaw); - } - - public float getPitch() { - return cameraAngle.getPitch(); - } - - public float getYaw() { - return cameraAngle.getYaw(); - } - } -} diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey.java index 4b70aa8e..2c175166 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey.java @@ -1,61 +1,189 @@ package com.minecrafttas.tasmod.virtual; -import java.io.Serializable; - -/** - * Class to store which keys on the keyboard have been pressed, similar to how Keybindings work.
- * - * @author Scribble - * - */ -@Deprecated -public class VirtualKey implements Serializable { - - /** - * - */ - private static final long serialVersionUID = 2186369910433056224L; - private String name; - private int keycode; - private boolean isKeyDown=false; - - public VirtualKey(String name, int keycode) { - this.name = name; - this.keycode = keycode; - } - - private VirtualKey(String name, int keycode, boolean isKeyDown) { - this.name = name; - this.keycode = keycode; - this.isKeyDown = isKeyDown; - } - - public String getName() { - return name; - } - - public int getKeycode() { - return keycode; - } - - public boolean isKeyDown() { - return isKeyDown; - } - - public void setPressed(boolean pressed) { - isKeyDown=pressed; - } - - @Override - public boolean equals(Object obj) { - VirtualKey key = (VirtualKey) obj; - if(key.isKeyDown!=isKeyDown) return false; - if(key.keycode!=keycode) return false; - return true; - } - - @Override - public VirtualKey clone() { - return new VirtualKey(name, keycode, isKeyDown); - } +public enum VirtualKey { + // Keyboard + ZERO(0), + ESC(1), + KEY_1(2), + KEY_2(3), + KEY_3(4), + KEY_4(5), + KEY_5(6), + KEY_6(7), + KEY_7(8), + KEY_8(9), + KEY_9(10), + KEY_0(11), + MINUS(12), + EQUALS(13), + BACK(14), + TAB(15), + Q(16), + W(17), + E(18), + R(19), + T(20), + Y(21), + U(22), + I(23), + O(24), + P(25), + LBRACKET(26), + RBRACKET(27), + RETURN(28), + LCONTROL(29), + A(30), + S(31), + D(32), + F(33), + G(34), + H(35), + J(36), + K(37), + L(38), + SEMICOLON(39), + APOSTROPHE(40), + GRAVE(41), + LSHIFT(42), + BACKSLASH(43), + Z(44), + X(45), + C(46), + V(47), + B(48), + N(49), + M(50), + COMMA(51), + PERIOD(52), + SLASH(53), + RSHIFT(54), + MULTIPLY(55), + ALT(56), + SPACE(57), + CAPSLOCK(58), + F1(59), + F2(60), + F3(61), + F4(62), + F5(63), + F6(64), + F7(65), + F8(66), + F9(67), + F10(68), + NUMLOCK(69), + SCROLL(70), + NUMPAD7(71), + NUMPAD8(72), + NUMPAD9(73), + SUBTRACT(74), + NUMPAD4(75), + NUMPAD5(76), + NUMPAD6(77), + ADD(78), + NUMPAD1(79), + NUMPAD2(80), + NUMPAD3(81), + NUMPAD0(82), + DECIMAL(83), + F11(87), + F12(88), + F13(100), + F14(101), + F15(102), + F16(103), + F17(104), + F18(105), + KANA(112), + F19(113), + CONVERT(121), + NOCONVERT(123), + YEN(125), + NUMPADEQUALS(141), + CIRCUMFLEX(144), + AT(145), + COLON(146), + UNDERLINE(147), + KANJI(148), + STOP(149), + NUMPADENTER(156), + RCONTROL(157), + NUMPADCOMMA(179), + DIVIDE(181), + PRINT(183), + ALT_GR(184), + PAUSE(197), + HOME(199), + UP(200), + PRIOR(201), + LEFT(203), + RIGHT(205), + END(207), + DOWN(208), + NEXT(209), + INSERT(210), + DELETE(211), + WIN(219), + APPS(221), + + // Mouse + MOUSEMOVED(-101), + LC(-100), + RC(-99), + MC(-98), + MBUTTON4(-97), + MBUTTON5(-96), + MBUTTON6(-95), + MBUTTON7(-94), + MBUTTON8(-93), + MBUTTON9(-92), + MBUTTON10(-91), + MBUTTON11(-90), + MBUTTON12(-89), + MBUTTON13(-88), + MBUTTON14(-87), + MBUTTON15(-86), + MBUTTON16(-85); + + private final int keycode; + + private VirtualKey(int keycode) { + this.keycode = keycode; + } + + public int getKeycode() { + return keycode; + } + + public static Integer getKeycode(String keyname) { + VirtualKey key = get(keyname); + if (key != null) + return key.getKeycode(); + return null; + } + + public static String getName(int keycode) { + VirtualKey key = get(keycode); + if (key != null) + return key.name(); + return Integer.toString(keycode); + } + + public static VirtualKey get(int keycode) { + for (VirtualKey key : values()) { + if (key.getKeycode() == keycode) { + return key; + } + } + return null; + } + + public static VirtualKey get(String keyname) { + for (VirtualKey key : values()) { + if (key.name().equalsIgnoreCase(keyname)) { + return key; + } + } + return null; + } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey2.java deleted file mode 100644 index ddce26b3..00000000 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey2.java +++ /dev/null @@ -1,189 +0,0 @@ -package com.minecrafttas.tasmod.virtual; - -public enum VirtualKey2 { - // Keyboard - ZERO(0), - ESC(1), - KEY_1(2), - KEY_2(3), - KEY_3(4), - KEY_4(5), - KEY_5(6), - KEY_6(7), - KEY_7(8), - KEY_8(9), - KEY_9(10), - KEY_0(11), - MINUS(12), - EQUALS(13), - BACK(14), - TAB(15), - Q(16), - W(17), - E(18), - R(19), - T(20), - Y(21), - U(22), - I(23), - O(24), - P(25), - LBRACKET(26), - RBRACKET(27), - RETURN(28), - LCONTROL(29), - A(30), - S(31), - D(32), - F(33), - G(34), - H(35), - J(36), - K(37), - L(38), - SEMICOLON(39), - APOSTROPHE(40), - GRAVE(41), - LSHIFT(42), - BACKSLASH(43), - Z(44), - X(45), - C(46), - V(47), - B(48), - N(49), - M(50), - COMMA(51), - PERIOD(52), - SLASH(53), - RSHIFT(54), - MULTIPLY(55), - ALT(56), - SPACE(57), - CAPSLOCK(58), - F1(59), - F2(60), - F3(61), - F4(62), - F5(63), - F6(64), - F7(65), - F8(66), - F9(67), - F10(68), - NUMLOCK(69), - SCROLL(70), - NUMPAD7(71), - NUMPAD8(72), - NUMPAD9(73), - SUBTRACT(74), - NUMPAD4(75), - NUMPAD5(76), - NUMPAD6(77), - ADD(78), - NUMPAD1(79), - NUMPAD2(80), - NUMPAD3(81), - NUMPAD0(82), - DECIMAL(83), - F11(87), - F12(88), - F13(100), - F14(101), - F15(102), - F16(103), - F17(104), - F18(105), - KANA(112), - F19(113), - CONVERT(121), - NOCONVERT(123), - YEN(125), - NUMPADEQUALS(141), - CIRCUMFLEX(144), - AT(145), - COLON(146), - UNDERLINE(147), - KANJI(148), - STOP(149), - NUMPADENTER(156), - RCONTROL(157), - NUMPADCOMMA(179), - DIVIDE(181), - PRINT(183), - ALT_GR(184), - PAUSE(197), - HOME(199), - UP(200), - PRIOR(201), - LEFT(203), - RIGHT(205), - END(207), - DOWN(208), - NEXT(209), - INSERT(210), - DELETE(211), - WIN(219), - APPS(221), - - // Mouse - MOUSEMOVED(-101), - LC(-100), - RC(-99), - MC(-98), - MBUTTON4(-97), - MBUTTON5(-96), - MBUTTON6(-95), - MBUTTON7(-94), - MBUTTON8(-93), - MBUTTON9(-92), - MBUTTON10(-91), - MBUTTON11(-90), - MBUTTON12(-89), - MBUTTON13(-88), - MBUTTON14(-87), - MBUTTON15(-86), - MBUTTON16(-85); - - private final int keycode; - - private VirtualKey2(int keycode) { - this.keycode = keycode; - } - - public int getKeycode() { - return keycode; - } - - public static Integer getKeycode(String keyname) { - VirtualKey2 key = get(keyname); - if (key != null) - return key.getKeycode(); - return null; - } - - public static String getName(int keycode) { - VirtualKey2 key = get(keycode); - if (key != null) - return key.name(); - return Integer.toString(keycode); - } - - public static VirtualKey2 get(int keycode) { - for (VirtualKey2 key : values()) { - if (key.getKeycode() == keycode) { - return key; - } - } - return null; - } - - public static VirtualKey2 get(String keyname) { - for (VirtualKey2 key : values()) { - if (key.name().equalsIgnoreCase(keyname)) { - return key; - } - } - return null; - } -} diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java index 31912546..ae96365d 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java @@ -2,381 +2,323 @@ import java.io.Serializable; import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; -import java.util.Map; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.stream.Collectors; +import com.minecrafttas.tasmod.virtual.event.VirtualKeyboardEvent; import org.apache.commons.lang3.StringUtils; -import org.lwjgl.input.Keyboard; -import com.google.common.collect.Maps; -import com.minecrafttas.tasmod.playback.PlaybackSerialiser; - -@Deprecated -public class VirtualKeyboard implements Serializable { - - /** - * - */ - private static final long serialVersionUID = 4694772261313303998L; - - private Map keyList; - - private List charList; - - /** - * Creates a copy of the virtual keyboard with the given key list - * - * @param keyListIn - */ - public VirtualKeyboard(Map keyListIn, List charListIn) { - Map copy = new HashMap(); - - keyListIn.forEach((key, value) -> { - copy.put(key, value.clone()); - }); - keyList = copy; - - List charCopy = new ArrayList(); - - charListIn.forEach(charAction -> { - charCopy.add(charAction); - }); - charList = charCopy; +import com.google.common.collect.ImmutableList; + +/** + * Stores keyboard specific values in a given timeframe.
+ *
+ * This keyboard mimics the {@link org.lwjgl.input.Keyboard} Minecraft is using. + *

KeyboardEvent

+ * {@link org.lwjgl.input.Keyboard} has the following outputs, when a key is pressed or unpressed on the physical keyboard: + *
    + *
  • int KeyCode: The unique keycode of the key
  • + *
  • boolean KeyState: The new state of the key. True for pressed, false for unpressed
  • + *
  • char KeyCharacter: The character associated for each key
  • + *
+ * While the keycode is the same between physical keyboards, the key character might differ.
+ * It is also common that one keycode has multiple characters associated with it, e.g.
+ * holding shift results in a capitalised character.
+ *
+ * These three outputs together are what we call a "KeyboardEvent" and might look like this: + *
+ *     17, true, w
+ * 
+ * For keycode, keystate, keycharacter + *

Updating the keyboard

+ * This keyboard stores it's values in "states".
+ * That means that all the keys that are currently pressed are stored in {@link #pressedKeys}.
+ * And this list is updated via a keyboard event in {@link #update(int, boolean, char)}.
+ *

Difference

+ * When comparing 2 keyboard states, we can generate a list of differences from them in form of {@link VirtualKeyboardEvent}s.
+ *
+ * 	this: W A S
+ *	next: W   S D
+ * 
+ * Since there are 2 differences between this and the next keyboard, + * this will result in 2 {@link VirtualKeyboardEvent}s. And combined with the {@link #charList} we can also get the associated characters: + *
+ *	30, false, null // A is unpressed
+ * 	32, true, d 	// D is pressed
+ * 
+ *

Subticks

+ * Minecraft updates it's keyboard every tick. All the key events that occur inbetween are stored,
+ * then read out when a new tick has started.
We call these "inbetween" ticks subticks.
+ *

Parent->Subtick

+ * In a previous version of this keyboard, subticks were bundeled and flattened into one keyboard state.
+ * After all, Minecraft updates only occur once every tick, storing subticks seemed unnecessary.
+ *
+ * However this posed some usability issues when playing in a low game speed via {@link com.minecrafttas.tasmod.tickratechanger.TickrateChangerClient}.
+ * Now you had to hold the key until the next tick to get it recognised by the game.
+ *
+ * To fix this, now every subtick is stored as a keyboard state as well.
+ * When updating the keyboard in {@link #update(int, boolean, char)}, a clone of itself is created and stored in {@link #subtickList},
+ * with the difference that the subtick state has no {@link #subtickList}.
+ * In a nutshell, the keyboard stores it's past changes in {@link #subtickList} with the first being the oldest change. + * + * @author Scribble + * @see VirtualInput.VirtualKeyboardInput + */ +public class VirtualKeyboard extends VirtualPeripheral implements Serializable { + + /** + * The list of characters that were pressed on this keyboard. + */ + private final List charList; + + /** + * A queue of characters used in {@link #getDifference(VirtualKeyboard, Queue)}.
+ * Used for distributing characters to {@link VirtualKeyboardEvent}s in an order. + */ + private final ConcurrentLinkedQueue charQueue = new ConcurrentLinkedQueue<>(); + + /** + * Creates an empty parent keyboard with all keys unpressed + */ + public VirtualKeyboard() { + this(new LinkedHashSet<>(), new ArrayList<>(), new ArrayList<>(), true); + } + + /** + * Creates a subtick keyboard with {@link VirtualPeripheral#subtickList} uninitialized + * @param pressedKeys The new list of pressed keycodes for this subtickKeyboard + * @param charList A list of characters for this subtickKeyboard + */ + public VirtualKeyboard(Set pressedKeys, List charList){ + this(pressedKeys, charList, null, false); + } + + /** + * Creates a keyboard from existing variables + * @param pressedKeys The existing list of pressed keycodes + * @param charList The existing list of characters + */ + public VirtualKeyboard(Set pressedKeys, List charList, boolean ignoreFirstUpdate) { + this(pressedKeys, charList, null, ignoreFirstUpdate); } - + /** - * Creates a Keyboard, where the keys are all unpressed + * Creates a keyboard from existing variables + * @param pressedKeys The existing list of {@link VirtualPeripheral#pressedKeys} + * @param charList The {@link #charList} + * @param subtickList {@link VirtualPeripheral#subtickList} + * @param ignoreFirstUpdate The {@link VirtualPeripheral#ignoreFirstUpdate} */ - public VirtualKeyboard() { - charList = new ArrayList(); - - keyList = Maps.newHashMap(); - keyList.put(0, new VirtualKey("0", 0)); - keyList.put(1, new VirtualKey("ESC", 1)); - keyList.put(2, new VirtualKey("KEY_1", 2)); - keyList.put(3, new VirtualKey("KEY_2", 3)); - keyList.put(4, new VirtualKey("KEY_3", 4)); - keyList.put(5, new VirtualKey("KEY_4", 5)); - keyList.put(6, new VirtualKey("KEY_5", 6)); - keyList.put(7, new VirtualKey("KEY_6", 7)); - keyList.put(8, new VirtualKey("KEY_7", 8)); - keyList.put(9, new VirtualKey("KEY_8", 9)); - keyList.put(10, new VirtualKey("KEY_9", 10)); - keyList.put(11, new VirtualKey("KEY_0", 11)); - keyList.put(12, new VirtualKey("MINUS", 12)); - keyList.put(13, new VirtualKey("EQUALS", 13)); - keyList.put(14, new VirtualKey("BACK", 14)); - keyList.put(15, new VirtualKey("TAB", 15)); - keyList.put(16, new VirtualKey("Q", 16)); - keyList.put(17, new VirtualKey("W", 17)); - keyList.put(18, new VirtualKey("E", 18)); - keyList.put(19, new VirtualKey("R", 19)); - keyList.put(20, new VirtualKey("T", 20)); - keyList.put(21, new VirtualKey("Y", 21)); - keyList.put(22, new VirtualKey("U", 22)); - keyList.put(23, new VirtualKey("I", 23)); - keyList.put(24, new VirtualKey("O", 24)); - keyList.put(25, new VirtualKey("P", 25)); - keyList.put(26, new VirtualKey("LBRACKET", 26)); - keyList.put(27, new VirtualKey("RBRACKET", 27)); - keyList.put(28, new VirtualKey("RETURN", 28)); - keyList.put(29, new VirtualKey("LCONTROL", 29)); - keyList.put(30, new VirtualKey("A", 30)); - keyList.put(31, new VirtualKey("S", 31)); - keyList.put(32, new VirtualKey("D", 32)); - keyList.put(33, new VirtualKey("F", 33)); - keyList.put(34, new VirtualKey("G", 34)); - keyList.put(35, new VirtualKey("H", 35)); - keyList.put(36, new VirtualKey("J", 36)); - keyList.put(37, new VirtualKey("K", 37)); - keyList.put(38, new VirtualKey("L", 38)); - keyList.put(39, new VirtualKey("SEMICOLON", 39)); - keyList.put(40, new VirtualKey("APOSTROPHE", 40)); - keyList.put(41, new VirtualKey("GRAVE", 41)); - keyList.put(42, new VirtualKey("LSHIFT", 42)); - keyList.put(43, new VirtualKey("BACKSLASH", 43)); - keyList.put(44, new VirtualKey("Z", 44)); - keyList.put(45, new VirtualKey("X", 45)); - keyList.put(46, new VirtualKey("C", 46)); - keyList.put(47, new VirtualKey("V", 47)); - keyList.put(48, new VirtualKey("B", 48)); - keyList.put(49, new VirtualKey("N", 49)); - keyList.put(50, new VirtualKey("M", 50)); - keyList.put(51, new VirtualKey("COMMA", 51)); - keyList.put(52, new VirtualKey("PERIOD", 52)); - keyList.put(53, new VirtualKey("SLASH", 53)); - keyList.put(54, new VirtualKey("RSHIFT", 54)); - keyList.put(55, new VirtualKey("MULTIPLY", 55)); - keyList.put(56, new VirtualKey("ALT", 56)); - keyList.put(57, new VirtualKey("SPACE", 57)); - keyList.put(58, new VirtualKey("CAPSLOCK", 58)); - keyList.put(59, new VirtualKey("F1", 59)); - keyList.put(60, new VirtualKey("F2", 60)); - keyList.put(61, new VirtualKey("F3", 61)); - keyList.put(62, new VirtualKey("F4", 62)); - keyList.put(63, new VirtualKey("F5", 63)); - keyList.put(64, new VirtualKey("F6", 64)); - keyList.put(65, new VirtualKey("F7", 65)); - keyList.put(66, new VirtualKey("F8", 66)); - keyList.put(67, new VirtualKey("F9", 67)); - keyList.put(68, new VirtualKey("F10", 68)); - keyList.put(69, new VirtualKey("NUMLOCK", 69)); - keyList.put(70, new VirtualKey("SCROLL", 70)); - keyList.put(71, new VirtualKey("NUMPAD7", 71)); - keyList.put(72, new VirtualKey("NUMPAD8", 72)); - keyList.put(73, new VirtualKey("NUMPAD9", 73)); - keyList.put(74, new VirtualKey("SUBTRACT", 74)); - keyList.put(75, new VirtualKey("NUMPAD4", 75)); - keyList.put(76, new VirtualKey("NUMPAD5", 76)); - keyList.put(77, new VirtualKey("NUMPAD6", 77)); - keyList.put(78, new VirtualKey("ADD", 78)); - keyList.put(79, new VirtualKey("NUMPAD1", 79)); - keyList.put(80, new VirtualKey("NUMPAD2", 80)); - keyList.put(81, new VirtualKey("NUMPAD3", 81)); - keyList.put(82, new VirtualKey("NUMPAD0", 82)); - keyList.put(83, new VirtualKey("DECIMAL", 83)); - keyList.put(87, new VirtualKey("F11", 87)); - keyList.put(88, new VirtualKey("F12", 88)); - keyList.put(100, new VirtualKey("F13", 100)); - keyList.put(101, new VirtualKey("F14", 101)); - keyList.put(102, new VirtualKey("F15", 102)); - keyList.put(103, new VirtualKey("F16", 103)); - keyList.put(104, new VirtualKey("F17", 104)); - keyList.put(105, new VirtualKey("F18", 105)); - keyList.put(112, new VirtualKey("KANA", 112)); - keyList.put(113, new VirtualKey("F19", 113)); - keyList.put(121, new VirtualKey("CONVERT", 121)); - keyList.put(123, new VirtualKey("NOCONVERT", 123)); - keyList.put(125, new VirtualKey("YEN", 125)); - keyList.put(141, new VirtualKey("NUMPADEQUALS", 141)); - keyList.put(144, new VirtualKey("CIRCUMFLEX", 144)); - keyList.put(145, new VirtualKey("AT", 145)); - keyList.put(146, new VirtualKey("COLON", 146)); - keyList.put(147, new VirtualKey("UNDERLINE", 147)); - keyList.put(148, new VirtualKey("KANJI", 148)); - keyList.put(149, new VirtualKey("STOP", 149)); - keyList.put(156, new VirtualKey("NUMPADENTER", 156)); - keyList.put(157, new VirtualKey("RCONTROL", 157)); - keyList.put(179, new VirtualKey("NUMPADCOMMA", 179)); - keyList.put(181, new VirtualKey("DIVIDE", 181)); - keyList.put(183, new VirtualKey("PRINT", 183)); - keyList.put(184, new VirtualKey("ALT_GR", 184)); - keyList.put(197, new VirtualKey("PAUSE", 197)); - keyList.put(199, new VirtualKey("HOME", 199)); - keyList.put(200, new VirtualKey("UP", 200)); - keyList.put(201, new VirtualKey("PRIOR", 201)); - keyList.put(203, new VirtualKey("LEFT", 203)); - keyList.put(205, new VirtualKey("RIGHT", 205)); - keyList.put(207, new VirtualKey("END", 207)); - keyList.put(208, new VirtualKey("DOWN", 208)); - keyList.put(209, new VirtualKey("NEXT", 209)); - keyList.put(210, new VirtualKey("INSERT", 210)); - keyList.put(211, new VirtualKey("DELETE", 211)); - keyList.put(219, new VirtualKey("WIN", 219)); - keyList.put(221, new VirtualKey("APPS", 221)); - } - - public void add(int keycode) { - String keyString = Integer.toString(keycode); - - keyList.put(keycode, new VirtualKey(keyString, keycode)); - } - - public VirtualKey get(int keycode) { - VirtualKey key = keyList.get(keycode); - if (key == null) { - add(keycode); - return keyList.get(keycode); - } else - return key; - } - - public VirtualKey get(String keyname) { - Collection list = keyList.values(); - VirtualKey out = null; - - for (VirtualKey key : list) { - if (key.getName().equalsIgnoreCase(keyname)) { - out = key; - } - } - return out; - } - - public List getCurrentPresses() { - List out = new ArrayList(); - - keyList.forEach((keycodes, virtualkeys) -> { - if (keycodes >= 0) { - if (virtualkeys.isKeyDown()) { - out.add(virtualkeys.getName()); - } - } - }); - - return out; - } - - public Map getKeyList() { - return this.keyList; - } - - public void addChar(char charin) { - charList.add(charin); - } - - public List getCharList() { - return charList; - } - - public String getCharListAsString() { - String out=""; - for(char chars: charList) { - out=out.concat(Character.toString(chars)); + public VirtualKeyboard(Set pressedKeys, List charList, List subtickList, boolean ignoreFirstUpdate) { + super(pressedKeys, subtickList, ignoreFirstUpdate); + this.charList = charList; + } + + /** + * Updates the keyboard, adds a new subtick to this keyboard + * @param keycode The keycode of this key + * @param keystate The keystate of this key, true for pressed + * @param keycharacter The character that is associated with that key. Can change between keyboards or whenever shift is held in combination. + */ + public void update(int keycode, boolean keystate, char keycharacter, boolean repeatEventsEnabled) { + if(isParent() && !ignoreFirstUpdate()) { + addSubtick(clone()); + } + charList.clear(); + if (keystate) { + addChar(keycharacter, repeatEventsEnabled); } - return out; - } - - public void clearCharList() { - charList.clear(); - } - - public void clear() { - keyList.forEach((keycode, key) -> { - key.setPressed(false); - }); - charList.clear(); - } - - public List getDifference(VirtualKeyboard keyboardToCompare) { - - List eventList = new ArrayList(); - - keyList.forEach((keycodes, virtualkeys) -> { - - VirtualKey keyToCompare = keyboardToCompare.get(keycodes); + setPressed(keycode, keystate); + } + + public void update(int keycode, boolean keystate, char keycharacter) { + update(keycode, keystate, keycharacter, false); + } + + @Override + public void setPressed(int keycode, boolean keystate) { + if (keycode >= 0) { // Keyboard keys always have a keycode larger or equal than 0 + super.setPressed(keycode, keystate); + } + } - if (!virtualkeys.equals(keyToCompare)) { - if (Keyboard.areRepeatEventsEnabled()) { - if (isUnicodeInList(keycodes)) { - return; - } - } - eventList.add(new VirtualKeyboardEvent(keycodes, keyToCompare.isKeyDown(), Character.MIN_VALUE)); - } - - }); - keyboardToCompare.charList.forEach(action -> { - if (Keyboard.areRepeatEventsEnabled()) { - eventList.add(decodeUnicode(action)); - } else { - eventList.add(new VirtualKeyboardEvent(0, true, action)); + /** + * Calculates a list of {@link VirtualKeyboardEvent}s to the next peripheral, + * including the subticks. + * + * @see VirtualKeyboard#getDifference(VirtualKeyboard, Queue) + * + * @param nextKeyboard The keyboard that comes after this one.
+ * If this one is loaded at tick 15, the nextKeyboard should + * be the one from tick 16 + * @param reference The queue to fill. Passed in by reference. + */ + public void getVirtualEvents(VirtualKeyboard nextKeyboard, Queue reference) { + if (isParent()) { + VirtualKeyboard currentSubtick = this; + for(VirtualKeyboard subtick : nextKeyboard.getAll()) { + currentSubtick.getDifference(subtick, reference); + currentSubtick = subtick; } - }); - return eventList; - } - - public char encodeUnicode(int keycode, char character) { - switch (keycode) { - case 15: // Tab - return '\u21A6'; - case 199: // Pos1 - return '\u21E4'; - case 200: // Arrow Up - return '\u2191'; - case 201: // Prior - return '\u21E7'; - case 203: // Arrow Left - return '\u2190'; - case 205: // Arrow Right - return '\u2192'; - case 207: // End - return '\u21E5'; - case 208: // Arrow Down - return '\u2193'; - case 209: // Next - return '\u21E9'; - default: - return character; - } - } - - public VirtualKeyboardEvent decodeUnicode(char character) { - switch (character) { - case '\b': - return new VirtualKeyboardEvent(14, true, Character.MIN_VALUE); - case '\u21A6': - return new VirtualKeyboardEvent(15, true, Character.MIN_VALUE); - case '\u2907': - return new VirtualKeyboardEvent(15, false, Character.MIN_VALUE); - case '\u21E4': - return new VirtualKeyboardEvent(199, true, Character.MIN_VALUE); - case '\u2191': - return new VirtualKeyboardEvent(200, true, Character.MIN_VALUE); - case '\u21E7': - return new VirtualKeyboardEvent(201, true, Character.MIN_VALUE); - case '\u2190': - return new VirtualKeyboardEvent(203, true, Character.MIN_VALUE); - case '\u2192': - return new VirtualKeyboardEvent(205, true, Character.MIN_VALUE); - case '\u21E5': - return new VirtualKeyboardEvent(207, true, Character.MIN_VALUE); - case '\u2193': - return new VirtualKeyboardEvent(208, true, Character.MIN_VALUE); - case '\u21E9': - return new VirtualKeyboardEvent(209, true, Character.MIN_VALUE); - default: - return new VirtualKeyboardEvent(0, true, character); } } - public boolean isUnicodeInList(int keycode) { - switch (keycode) { - case 14: - case 15: - case 199: - case 200: - case 201: - case 203: - case 205: - case 207: - case 208: - case 209: - return true; - default: - return false; + /** + * Calculates the difference between 2 keyboards via symmetric difference
+ * and returns a list of the changes between them in form of + * {@link VirtualKeyboardEvent}s + * + * @param nextKeyboard The keyboard that comes after this one.
+ * If this one is loaded at tick 15, the nextKeyboard should + * be the one from tick 16 + * @param reference The queue to fill. Passed in by reference. + */ + public void getDifference(VirtualKeyboard nextKeyboard, Queue reference) { + charQueue.addAll(nextKeyboard.charList); + + /* Calculate symmetric difference of keycodes */ + + /* + Calculate unpressed keys + this: W A S + next: W S D + ------------- + A <- unpressed + */ + for(int key : pressedKeys) { + if (!nextKeyboard.getPressedKeys().contains(key)) { + reference.add(new VirtualKeyboardEvent(key, false, Character.MIN_VALUE)); + } + } + + /* + Calculate pressed keys + next: W S D + this: W A S + ------------- + D <- pressed + */ + int lastKey = 0; + for(int key : nextKeyboard.getPressedKeys()) { + lastKey = key; + if (!this.pressedKeys.contains(key)) { + reference.add(new VirtualKeyboardEvent(key, true, getOrMinChar(charQueue.poll()))); + } + } + + /* + Add the rest of the characters as keyboard events. + Also responsible for holding the key and adding a lot of characters in chat. + + The LWJGL Keyboard has a method called "areRepeatEventsEnabled" which returns true, when the user is in a gui. + Additionally when a key is held, the Keyboard resends the same keyboard event, in this case to the update method of the VirtualKeyboard. + + What ends up happening is, that the subtickList is filled with multiple characters, which are then converted to keyboard events + here. + + However, some functionality like \b or the arrow keys have no associated character, Minecraft instead listens for the keycode. + Thats where the "lastKey" comes in. Since we are using a LinkedHashSet, as pressedKeys, we can get the last pressed keycode. + + So, to get the repeat events working, one needs a pressed key and any character. + + */ + while (!charQueue.isEmpty()) { + reference.add(new VirtualKeyboardEvent(lastKey, true, getOrMinChar(charQueue.poll()))); + } + + } + + private char getOrMinChar(Character charr){ + if(charr==null){ + charr = Character.MIN_VALUE; + } + return charr; + } + + /** + * Add a character to the {@link #charList}
+ * Null characters will be discarded; + * @param character The character to add + */ + public void addChar(char character, boolean repeatEventsEnabled) { + if(character != Character.MIN_VALUE || repeatEventsEnabled) { + charList.add(character); + } + } + + @Override + protected void clear(){ + super.clear(); + charList.clear(); + } + + @Override + public String toString() { + if (isParent()) { + return getAll().stream().map(VirtualKeyboard::toString2).collect(Collectors.joining("\n")); + } else { + return toString2(); } } - @Override - public VirtualKeyboard clone() { - return new VirtualKeyboard(keyList, charList); + private String toString2(){ + return String.format("%s;%s", super.toString(), charListToString(charList)); } - @Override - public String toString() { - List stringy = getCurrentPresses(); - String keyString = ""; - if (!stringy.isEmpty()) { - String seperator = ","; - for (int i = 0; i < stringy.size(); i++) { - if (i == stringy.size() - 1) { - seperator = ""; - } - keyString = keyString.concat(stringy.get(i) + seperator); - } - } + private String charListToString(List charList) { String charString = ""; if (!charList.isEmpty()) { - for (int i = 0; i < charList.size(); i++) { - charString = charString.concat(Character.toString(charList.get(i))); - } + charString = charList.stream().map(Object::toString).collect(Collectors.joining()); charString = StringUtils.replace(charString, "\r", "\\n"); charString = StringUtils.replace(charString, "\n", "\\n"); } - - return PlaybackSerialiser.SectionsV1.KEYBOARD.getName()+":"+keyString + ";" + charString; + return charString; } + + /** + * Clones this VirtualKeyboard without subticks + */ + @Override + public VirtualKeyboard clone() { + return new VirtualKeyboard(new HashSet<>(this.pressedKeys), new ArrayList<>(this.charList), isIgnoreFirstUpdate()); + } + + @Override + public void copyFrom(VirtualKeyboard keyboard) { + super.copyFrom(keyboard); + charList.clear(); + charList.addAll(keyboard.charList); + keyboard.charList.clear(); + } + + @Override + public boolean equals(Object obj) { + if(obj instanceof VirtualKeyboard) { + VirtualKeyboard keyboard = (VirtualKeyboard) obj; + + if(charList.size() != keyboard.charList.size()) { + return false; + } + + for (int i = 0; i < charList.size(); i++) { + if(charList.get(i)!=keyboard.charList.get(i)) { + return false; + } + } + return super.equals(obj); + } + return super.equals(obj); + } + + /** + * @return An immutable {@link #charList} + */ + public List getCharList() { + return ImmutableList.copyOf(charList); + } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java deleted file mode 100644 index 55ee90fc..00000000 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard2.java +++ /dev/null @@ -1,323 +0,0 @@ -package com.minecrafttas.tasmod.virtual; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Queue; -import java.util.Set; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.stream.Collectors; - -import org.apache.commons.lang3.StringUtils; - -import com.google.common.collect.ImmutableList; - -/** - * Stores keyboard specific values in a given timeframe.
- *
- * This keyboard mimics the {@link org.lwjgl.input.Keyboard} Minecraft is using. - *

KeyboardEvent

- * {@link org.lwjgl.input.Keyboard} has the following outputs, when a key is pressed or unpressed on the physical keyboard: - *
    - *
  • int KeyCode: The unique keycode of the key
  • - *
  • boolean KeyState: The new state of the key. True for pressed, false for unpressed
  • - *
  • char KeyCharacter: The character associated for each key
  • - *
- * While the keycode is the same between physical keyboards, the key character might differ.
- * It is also common that one keycode has multiple characters associated with it, e.g.
- * holding shift results in a capitalised character.
- *
- * These three outputs together are what we call a "KeyboardEvent" and might look like this: - *
- *     17, true, w
- * 
- * For keycode, keystate, keycharacter - *

Updating the keyboard

- * This keyboard stores it's values in "states".
- * That means that all the keys that are currently pressed are stored in {@link #pressedKeys}.
- * And this list is updated via a keyboard event in {@link #update(int, boolean, char)}.
- *

Difference

- * When comparing 2 keyboard states, we can generate a list of differences from them in form of {@link VirtualKeyboardEvent}s.
- *
- * 	this: W A S
- *	next: W   S D
- * 
- * Since there are 2 differences between this and the next keyboard, - * this will result in 2 {@link VirtualKeyboardEvent}s. And combined with the {@link #charList} we can also get the associated characters: - *
- *	30, false, null // A is unpressed
- * 	32, true, d 	// D is pressed
- * 
- *

Subticks

- * Minecraft updates it's keyboard every tick. All the key events that occur inbetween are stored,
- * then read out when a new tick has started.
We call these "inbetween" ticks subticks.
- *

Parent->Subtick

- * In a previous version of this keyboard, subticks were bundeled and flattened into one keyboard state.
- * After all, Minecraft updates only occur once every tick, storing subticks seemed unnecessary.
- *
- * However this posed some usability issues when playing in a low game speed via {@link com.minecrafttas.tasmod.tickratechanger.TickrateChangerClient}.
- * Now you had to hold the key until the next tick to get it recognised by the game.
- *
- * To fix this, now every subtick is stored as a keyboard state as well.
- * When updating the keyboard in {@link #update(int, boolean, char)}, a clone of itself is created and stored in {@link #subtickList},
- * with the difference that the subtick state has no {@link #subtickList}.
- * In a nutshell, the keyboard stores it's past changes in {@link #subtickList} with the first being the oldest change. - * - * @author Scribble - * @see com.minecrafttas.tasmod.virtual.VirtualInput2.VirtualKeyboardInput - */ -public class VirtualKeyboard2 extends VirtualPeripheral implements Serializable { - - /** - * The list of characters that were pressed on this keyboard. - */ - private final List charList; - - /** - * A queue of characters used in {@link #getDifference(VirtualKeyboard2, Queue)}.
- * Used for distributing characters to {@link VirtualKeyboardEvent}s in an order. - */ - private final ConcurrentLinkedQueue charQueue = new ConcurrentLinkedQueue<>(); - - /** - * Creates an empty parent keyboard with all keys unpressed - */ - public VirtualKeyboard2() { - this(new LinkedHashSet<>(), new ArrayList<>(), new ArrayList<>(), true); - } - - /** - * Creates a subtick keyboard with {@link VirtualPeripheral#subtickList} uninitialized - * @param pressedKeys The new list of pressed keycodes for this subtickKeyboard - * @param charList A list of characters for this subtickKeyboard - */ - public VirtualKeyboard2(Set pressedKeys, List charList){ - this(pressedKeys, charList, null, false); - } - - /** - * Creates a keyboard from existing variables - * @param pressedKeys The existing list of pressed keycodes - * @param charList The existing list of characters - */ - public VirtualKeyboard2(Set pressedKeys, List charList, boolean ignoreFirstUpdate) { - this(pressedKeys, charList, null, ignoreFirstUpdate); - } - - /** - * Creates a keyboard from existing variables - * @param pressedKeys The existing list of {@link VirtualPeripheral#pressedKeys} - * @param charList The {@link #charList} - * @param subtickList {@link VirtualPeripheral#subtickList} - * @param ignoreFirstUpdate The {@link VirtualPeripheral#ignoreFirstUpdate} - */ - public VirtualKeyboard2(Set pressedKeys, List charList, List subtickList, boolean ignoreFirstUpdate) { - super(pressedKeys, subtickList, ignoreFirstUpdate); - this.charList = charList; - } - - /** - * Updates the keyboard, adds a new subtick to this keyboard - * @param keycode The keycode of this key - * @param keystate The keystate of this key, true for pressed - * @param keycharacter The character that is associated with that key. Can change between keyboards or whenever shift is held in combination. - */ - public void update(int keycode, boolean keystate, char keycharacter, boolean repeatEventsEnabled) { - if(isParent() && !ignoreFirstUpdate()) { - addSubtick(clone()); - } - charList.clear(); - if (keystate) { - addChar(keycharacter, repeatEventsEnabled); - } - setPressed(keycode, keystate); - } - - public void update(int keycode, boolean keystate, char keycharacter) { - update(keycode, keystate, keycharacter, false); - } - - @Override - public void setPressed(int keycode, boolean keystate) { - if (keycode >= 0) { // Keyboard keys always have a keycode larger or equal than 0 - super.setPressed(keycode, keystate); - } - } - - /** - * Calculates a list of {@link VirtualKeyboardEvent}s to the next peripheral, - * including the subticks. - * - * @see VirtualKeyboard2#getDifference(VirtualKeyboard2, Queue) - * - * @param nextKeyboard The keyboard that comes after this one.
- * If this one is loaded at tick 15, the nextKeyboard should - * be the one from tick 16 - * @param reference The queue to fill. Passed in by reference. - */ - public void getVirtualEvents(VirtualKeyboard2 nextKeyboard, Queue reference) { - if (isParent()) { - VirtualKeyboard2 currentSubtick = this; - for(VirtualKeyboard2 subtick : nextKeyboard.getAll()) { - currentSubtick.getDifference(subtick, reference); - currentSubtick = subtick; - } - } - } - - /** - * Calculates the difference between 2 keyboards via symmetric difference
- * and returns a list of the changes between them in form of - * {@link VirtualKeyboardEvent}s - * - * @param nextKeyboard The keyboard that comes after this one.
- * If this one is loaded at tick 15, the nextKeyboard should - * be the one from tick 16 - * @param reference The queue to fill. Passed in by reference. - */ - public void getDifference(VirtualKeyboard2 nextKeyboard, Queue reference) { - charQueue.addAll(nextKeyboard.charList); - - /* Calculate symmetric difference of keycodes */ - - /* - Calculate unpressed keys - this: W A S - next: W S D - ------------- - A <- unpressed - */ - for(int key : pressedKeys) { - if (!nextKeyboard.getPressedKeys().contains(key)) { - reference.add(new VirtualKeyboardEvent(key, false, Character.MIN_VALUE)); - } - } - - /* - Calculate pressed keys - next: W S D - this: W A S - ------------- - D <- pressed - */ - int lastKey = 0; - for(int key : nextKeyboard.getPressedKeys()) { - lastKey = key; - if (!this.pressedKeys.contains(key)) { - reference.add(new VirtualKeyboardEvent(key, true, getOrMinChar(charQueue.poll()))); - } - } - - /* - Add the rest of the characters as keyboard events. - Also responsible for holding the key and adding a lot of characters in chat. - - The LWJGL Keyboard has a method called "areRepeatEventsEnabled" which returns true, when the user is in a gui. - Additionally when a key is held, the Keyboard resends the same keyboard event, in this case to the update method of the VirtualKeyboard. - - What ends up happening is, that the subtickList is filled with multiple characters, which are then converted to keyboard events - here. - - However, some functionality like \b or the arrow keys have no associated character, Minecraft instead listens for the keycode. - Thats where the "lastKey" comes in. Since we are using a LinkedHashSet, as pressedKeys, we can get the last pressed keycode. - - So, to get the repeat events working, one needs a pressed key and any character. - - */ - while (!charQueue.isEmpty()) { - reference.add(new VirtualKeyboardEvent(lastKey, true, getOrMinChar(charQueue.poll()))); - } - - } - - private char getOrMinChar(Character charr){ - if(charr==null){ - charr = Character.MIN_VALUE; - } - return charr; - } - - /** - * Add a character to the {@link #charList}
- * Null characters will be discarded; - * @param character The character to add - */ - public void addChar(char character, boolean repeatEventsEnabled) { - if(character != Character.MIN_VALUE || repeatEventsEnabled) { - charList.add(character); - } - } - - @Override - protected void clear(){ - super.clear(); - charList.clear(); - } - - @Override - public String toString() { - if (isParent()) { - return getAll().stream().map(VirtualKeyboard2::toString2).collect(Collectors.joining("\n")); - } else { - return toString2(); - } - } - - private String toString2(){ - return String.format("%s;%s", super.toString(), charListToString(charList)); - } - - private String charListToString(List charList) { - String charString = ""; - if (!charList.isEmpty()) { - charString = charList.stream().map(Object::toString).collect(Collectors.joining()); - charString = StringUtils.replace(charString, "\r", "\\n"); - charString = StringUtils.replace(charString, "\n", "\\n"); - } - return charString; - } - - /** - * Clones this VirtualKeyboard without subticks - */ - @Override - public VirtualKeyboard2 clone() { - return new VirtualKeyboard2(new HashSet<>(this.pressedKeys), new ArrayList<>(this.charList), isIgnoreFirstUpdate()); - } - - @Override - public void copyFrom(VirtualKeyboard2 keyboard) { - super.copyFrom(keyboard); - charList.clear(); - charList.addAll(keyboard.charList); - keyboard.charList.clear(); - } - - @Override - public boolean equals(Object obj) { - if(obj instanceof VirtualKeyboard2) { - VirtualKeyboard2 keyboard = (VirtualKeyboard2) obj; - - if(charList.size() != keyboard.charList.size()) { - return false; - } - - for (int i = 0; i < charList.size(); i++) { - if(charList.get(i)!=keyboard.charList.get(i)) { - return false; - } - } - return super.equals(obj); - } - return super.equals(obj); - } - - /** - * @return An immutable {@link #charList} - */ - public List getCharList() { - return ImmutableList.copyOf(charList); - } -} diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java index f5e38990..d2e7c552 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java @@ -1,348 +1,256 @@ package com.minecrafttas.tasmod.virtual; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import com.minecrafttas.tasmod.virtual.event.VirtualMouseEvent; -import com.google.common.collect.Maps; -import com.minecrafttas.tasmod.playback.PlaybackSerialiser; +import java.io.Serializable; +import java.util.*; +import java.util.stream.Collectors; -@Deprecated -public class VirtualMouse implements Serializable { +public class VirtualMouse extends VirtualPeripheral implements Serializable { /** - * + * The direction of the scrollWheel
+ *
+ * If the number is positive or negative depending on scroll direction. */ - private static final long serialVersionUID = -5389661329436686190L; - - private Map keyList = Maps.newHashMap(); - - private int scrollwheel = 0; - - private int cursorX = 0; - - private int cursorY = 0; - - public VirtualMouse(Map keyListIn, int scrollwheel, int cursorX, int cursorY, List path) { - Map copy = new HashMap(); - - keyListIn.forEach((key, value) -> { - copy.put(key, value.clone()); - }); - keyList = copy; - - this.scrollwheel = scrollwheel; - - this.cursorX = cursorX; - - this.cursorY = cursorY; - - List pathCopy = new ArrayList(); - path.forEach(pathNode -> { - pathCopy.add(pathNode); - }); - this.path = pathCopy; - - } - + private int scrollWheel; /** - * Creates a Keyboard, where the keys are all unpressed + * X coordinate of the on-screen cursor, used in GUI screens.
+ * When null, no change to the cursor is applied. */ - public VirtualMouse() { - keyList.put(-101, new VirtualKey("MOUSEMOVED", -101)); - keyList.put(-100, new VirtualKey("LC", -100)); - keyList.put(-99, new VirtualKey("RC", -99)); - keyList.put(-98, new VirtualKey("MC", -98)); - keyList.put(-97, new VirtualKey("MBUTTON4", -97)); - keyList.put(-96, new VirtualKey("MBUTTON5", -96)); - keyList.put(-95, new VirtualKey("MBUTTON6", -95)); - keyList.put(-94, new VirtualKey("MBUTTON7", -94)); - keyList.put(-93, new VirtualKey("MBUTTON8", -93)); - keyList.put(-92, new VirtualKey("MBUTTON9", -92)); - keyList.put(-91, new VirtualKey("MBUTTON10", -91)); - keyList.put(-90, new VirtualKey("MBUTTON11", -90)); - keyList.put(-89, new VirtualKey("MBUTTON12", -89)); - keyList.put(-88, new VirtualKey("MBUTTON13", -88)); - keyList.put(-87, new VirtualKey("MBUTTON14", -87)); - keyList.put(-86, new VirtualKey("MBUTTON15", -86)); - keyList.put(-85, new VirtualKey("MBUTTON16", -85)); - - this.scrollwheel = 0; - - this.cursorX = 0; - - this.cursorY = 0; - - addPathNode(); - } - - public void add(int keycode) { - String keyString = Integer.toString(keycode); + private int cursorX; + /** + * Y coordinate of the on-screen cursor, used in GUI screens.
+ * When null, no change to the cursor is applied. + */ + private int cursorY; - keyList.put(keycode, new VirtualKey(keyString, keycode)); + /** + * Creates a mouse with no buttons pressed and no data + */ + public VirtualMouse(){ + this(new LinkedHashSet<>(), 0, 0, 0, new ArrayList<>(), true); } - public VirtualKey get(int keycode) { - return keyList.get(keycode); + /** + * Creates a subtick mouse with {@link VirtualPeripheral#subtickList} uninitialized + * @param pressedKeys The new list of pressed keycodes for this subtickMouse + * @param scrollWheel The scroll wheel direction for this subtickMouse + * @param cursorX The X coordinate of the cursor for this subtickMouse + * @param cursorY The Y coordinate of the cursor for this subtickMouse + */ + public VirtualMouse(Set pressedKeys, int scrollWheel, int cursorX, int cursorY) { + this(pressedKeys, scrollWheel, cursorX, cursorY, null); } - public VirtualKey get(String keyname) { - Collection list = keyList.values(); - VirtualKey out = null; - - for (VirtualKey key : list) { - if (key.getName().equalsIgnoreCase(keyname)) { - out = key; - } - } - return out; + /** + * Creates a mouse from existing values with + * {@link VirtualPeripheral#ignoreFirstUpdate} set to false + * + * @param pressedKeys The list of {@link #pressedKeys} + * @param scrollWheel The {@link #scrollWheel} + * @param cursorX The {@link #cursorX} + * @param cursorY The {@link #cursorY} + * @param subtick The {@link VirtualPeripheral#subtickList} + */ + public VirtualMouse(Set pressedKeys, int scrollWheel, Integer cursorX, Integer cursorY, List subtick) { + this(pressedKeys, scrollWheel, cursorX, cursorY, subtick, false); } - public List getCurrentPresses() { - List out = new ArrayList(); - - keyList.forEach((keycodes, virtualkeys) -> { - if (keycodes <= 0) { - if (virtualkeys.isKeyDown()) { - out.add(virtualkeys.getName()); - } - } - }); - - return out; + /** + * Creates a mouse from existing values + * + * @param pressedKeys The list of {@link #pressedKeys} + * @param scrollWheel The {@link #scrollWheel} + * @param cursorX The {@link #cursorX} + * @param cursorY The {@link #cursorY} + * @param subtick The {@link VirtualPeripheral#subtickList} + * @param ignoreFirstUpdate Whether the first call to {@link #update(int, boolean, int, Integer, Integer)} should create a new subtick + */ + public VirtualMouse(Set pressedKeys, int scrollWheel, Integer cursorX, Integer cursorY, List subtick, boolean ignoreFirstUpdate) { + super(pressedKeys, subtick, ignoreFirstUpdate); + this.scrollWheel = scrollWheel; + this.cursorX = cursorX; + this.cursorY = cursorY; } - public Map getKeyList() { - return this.keyList; + public void update(int keycode, boolean keystate, int scrollwheel, Integer cursorX, Integer cursorY) { + if(isParent() && !ignoreFirstUpdate()) { + addSubtick(clone()); + } + setPressed(keycode, keystate); + this.scrollWheel = scrollwheel; + this.cursorX = cursorX; + this.cursorY = cursorY; } - public List getDifference(VirtualMouse mouseToCompare) { - List eventList = new ArrayList(); - - List path = mouseToCompare.getPath(); - - if (path.size() != 1) { - for (int i = 0; i < path.size() - 1; i++) { - PathNode currentNode = path.get(i); - PathNode nextNode = path.get(i + 1); - - boolean flag = false; - - for (VirtualKey key : nextNode.keyList.values()) { - if (!key.equals(currentNode.keyList.get(key.getKeycode()))) { - eventList.add(new VirtualMouseEvent(key.getKeycode(), key.isKeyDown(), nextNode.scrollwheel, nextNode.cursorX, nextNode.cursorY)); - flag = true; - break; - } - } - if (!flag) { - eventList.add(new VirtualMouseEvent(-101, false, nextNode.scrollwheel, nextNode.cursorX, nextNode.cursorY)); - } - - } - } else { - keyList.forEach((keycodes, virtualkeys) -> { - - VirtualKey keyToCompare = mouseToCompare.get(keycodes); - - if (!virtualkeys.equals(keyToCompare)) { - eventList.add(new VirtualMouseEvent(keycodes, keyToCompare.isKeyDown(), scrollwheel, cursorX, cursorY)); - } - - }); + @Override + public void setPressed(int keycode, boolean keystate) { + if (keycode < 0) { // Mouse buttons always have a keycode smaller than 0 + super.setPressed(keycode, keystate); } - return eventList; } - public boolean isSomethingDown() { - for (VirtualKey key : keyList.values()) { - if (key.isKeyDown()) { - return true; + /** + * Calculates a list of {@link VirtualMouseEvent}s, when comparing this mouse to + * the next mouse in the sequence,
+ * which also includes the subticks. + * + * @see VirtualMouse#getDifference(VirtualMouse, Queue) + * + * @param nextMouse The mouse that comes after this one.
+ * If this one is loaded at tick 15, the nextMouse should be + * the one from tick 16 + * @param reference The queue to fill. Passed in by reference. + */ + public void getVirtualEvents(VirtualMouse nextMouse, Queue reference) { + if (isParent()) { + VirtualMouse currentSubtick = this; + for(VirtualMouse subtick : nextMouse.getAll()) { + currentSubtick.getDifference(subtick, reference); + currentSubtick = subtick; } } - return false; } - public boolean isSomethingDown(Map keyList) { - for (VirtualKey key : keyList.values()) { - if (key.isKeyDown()) { - return true; + /** + * Calculates the difference between 2 mice via symmetric difference
+ * and returns a list of the changes between them in form of + * {@link VirtualMouseEvent}s + * + * @param nextMouse The mouse that comes after this one.
+ * If this one is loaded at tick 15, the nextMouse should be + * the one from tick 16 + * @param reference The queue to fill. Passed in by reference. + */ + public void getDifference(VirtualMouse nextPeripheral, Queue reference) { + + /* + * Checks if pressedKeys are the same... + */ + if(pressedKeys.equals(nextPeripheral.pressedKeys)){ + + /** + * ...but scrollWheel, cursorX or cursorY are different. + * Without this, the scrollWheel would only work if a mouse button is pressed at the same time. + */ + if(!equals(nextPeripheral)) { + reference.add(new VirtualMouseEvent(VirtualKey.MOUSEMOVED.getKeycode(), false, nextPeripheral.scrollWheel, nextPeripheral.cursorX, nextPeripheral.cursorY)); } + return; } - return false; + int scrollWheelCopy = nextPeripheral.scrollWheel; + int cursorXCopy = nextPeripheral.cursorX; + int cursorYCopy = nextPeripheral.cursorY; + + /* Calculate symmetric difference of keycodes */ + + /* + Calculate unpressed keys + this: LC RC + next: LC MC + ------------- + RC <- unpressed + */ + for(int keycode : pressedKeys) { + if (!nextPeripheral.getPressedKeys().contains(keycode)) { + reference.add(new VirtualMouseEvent(keycode, false, scrollWheelCopy, cursorXCopy, cursorYCopy)); + scrollWheelCopy = 0; + cursorXCopy = 0; + cursorYCopy = 0; + } + }; + + /* + Calculate pressed keys + next: LC MC + this: LC RC + ------------- + MC <- pressed + */ + for(int keycode : nextPeripheral.getPressedKeys()) { + if (!this.pressedKeys.contains(keycode)) { + reference.add(new VirtualMouseEvent(keycode, true, scrollWheelCopy, cursorXCopy, cursorYCopy)); + } + }; } @Override - public VirtualMouse clone() { - return new VirtualMouse(keyList, scrollwheel, cursorX, cursorY, path); - } - - public void setCursor(int x, int y) { - cursorX = x; - cursorY = y; + protected void clear() { + super.clear(); + clearMouseData(); } - - public void setScrollWheel(int scrollwheel) { - this.scrollwheel = scrollwheel; - } - - List path = new ArrayList(); - - public List getPath() { - return path; + + /** + * Resets mouse specific data to it's defaults + */ + private void clearMouseData() { + scrollWheel = 0; + cursorX = 0; + cursorY = 0; } - public String getPathAsString() { - String out=""; - for(PathNode node: path) { - out=out.concat(node.toString()); + + @Override + public String toString() { + if (isParent()) { + return getAll().stream().map(VirtualMouse::toString2).collect(Collectors.joining("\n")); + } else { + return toString2(); } - return out; - } - - public void addPathNode() { - path.add(new PathNode(keyList, scrollwheel, cursorX, cursorY)); } - - public void resetPath() { - path.clear(); - addPathNode(); + + private String toString2(){ + return String.format("%s;%s,%s,%s", super.toString(), scrollWheel, cursorX, cursorY); } - public class PathNode implements Serializable { - /** - * - */ - private static final long serialVersionUID = -2221602955260299028L; - - private Map keyList = Maps.newHashMap(); - - public int scrollwheel = 0; - - public int cursorX = 0; - - public int cursorY = 0; - - public PathNode(Map keyList, int scrollwheel, int cursorX, int cursorY) { - Map copy = new HashMap(); - - keyList.forEach((key, value) -> { - copy.put(key, value.clone()); - }); - this.keyList = copy; - this.scrollwheel = scrollwheel; - this.cursorX = cursorX; - this.cursorY = cursorY; - } - - public PathNode() { - keyList.put(-101, new VirtualKey("MOUSEMOVED", -101)); - keyList.put(-100, new VirtualKey("LC", -100)); - keyList.put(-99, new VirtualKey("RC", -99)); - keyList.put(-98, new VirtualKey("MC", -98)); - keyList.put(-97, new VirtualKey("MBUTTON3", -97)); - keyList.put(-96, new VirtualKey("MBUTTON4", -96)); - keyList.put(-95, new VirtualKey("MBUTTON5", -95)); - keyList.put(-94, new VirtualKey("MBUTTON6", -94)); - keyList.put(-93, new VirtualKey("MBUTTON7", -93)); - keyList.put(-92, new VirtualKey("MBUTTON8", -92)); - keyList.put(-91, new VirtualKey("MBUTTON9", -91)); - keyList.put(-90, new VirtualKey("MBUTTON10", -90)); - keyList.put(-89, new VirtualKey("MBUTTON11", -89)); - keyList.put(-88, new VirtualKey("MBUTTON12", -88)); - keyList.put(-87, new VirtualKey("MBUTTON13", -87)); - keyList.put(-86, new VirtualKey("MBUTTON14", -86)); - keyList.put(-85, new VirtualKey("MBUTTON15", -85)); - - this.scrollwheel = 0; - - this.cursorX = 0; - - this.cursorY = 0; - } - - @Override - public String toString() { - String keyString = ""; - List strings = new ArrayList(); - - keyList.forEach((keycodes, virtualkeys) -> { - if (virtualkeys.isKeyDown()) { - strings.add(virtualkeys.getName()); - } - }); - if (!strings.isEmpty()) { - String seperator = ","; - for (int i = 0; i < strings.size(); i++) { - if (i == strings.size() - 1) { - seperator = ""; - } - keyString = keyString.concat(strings.get(i) + seperator); - } - } - if (keyString.isEmpty()) { - return "MOUSEMOVED," + scrollwheel + "," + cursorX + "," + cursorY; - } else { - return keyString + "," + scrollwheel + "," + cursorX + "," + cursorY; - } - } - - public VirtualKey get(String keyname) { - Collection list = keyList.values(); - VirtualKey out = null; - - for (VirtualKey key : list) { - if (key.getName().equalsIgnoreCase(keyname)) { - out = key; - } - } - return out; - } - + /** + * Clones this VirtualMouse without subticks + */ + @Override + public VirtualMouse clone() { + return new VirtualMouse(new HashSet<>(this.pressedKeys), scrollWheel, cursorX, cursorY, null, ignoreFirstUpdate()); } - public void clear() { - keyList.forEach((keycode, key) -> { - key.setPressed(false); - }); - resetPath(); + @Override + public void copyFrom(VirtualMouse mouse) { + super.copyFrom(mouse); + this.scrollWheel = mouse.scrollWheel; + this.cursorX = mouse.cursorX; + this.cursorY = mouse.cursorY; + mouse.clearMouseData(); } - + @Override - public String toString() { - List stringy = getCurrentPresses(); - String keyString = ""; - if (!stringy.isEmpty()) { - String seperator = ","; - for (int i = 0; i < stringy.size(); i++) { - if (i == stringy.size() - 1) { - seperator = ""; - } - keyString = keyString.concat(stringy.get(i) + seperator); - } - } - String pathString = ""; - if (!path.isEmpty()) { - String seperator = "->"; - for (int i = 0; i < path.size(); i++) { - if (i == path.size() - 1) { - seperator = ""; - } - pathString = pathString.concat("[" + path.get(i).toString() + "]" + seperator); - } + public boolean equals(Object obj) { + if (obj instanceof VirtualMouse) { + VirtualMouse mouse = (VirtualMouse) obj; + return super.equals(obj) && + scrollWheel == mouse.scrollWheel && + cursorX == mouse.cursorX && + cursorY == mouse.cursorY; } - return PlaybackSerialiser.SectionsV1.MOUSE.getName()+":"+keyString + ";" + pathString; + return super.equals(obj); } - public void setPath(List path) { - List pathCopy = new ArrayList(); - path.forEach(pathNode -> { - pathCopy.add(pathNode); - }); - this.path = pathCopy; + /** + * @return {@link #scrollWheel} + */ + public int getScrollWheel() { + return scrollWheel; + } + + /** + * @return {@link #cursorX} + */ + public int getCursorX() { + return cursorX; + } + + /** + * @return {@link #cursorY} + */ + public int getCursorY() { + return cursorY; } - } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java deleted file mode 100644 index f8e3d4a2..00000000 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse2.java +++ /dev/null @@ -1,254 +0,0 @@ -package com.minecrafttas.tasmod.virtual; - -import java.io.Serializable; -import java.util.*; -import java.util.stream.Collectors; - -public class VirtualMouse2 extends VirtualPeripheral implements Serializable { - - /** - * The direction of the scrollWheel
- *
- * If the number is positive or negative depending on scroll direction. - */ - private int scrollWheel; - /** - * X coordinate of the on-screen cursor, used in GUI screens.
- * When null, no change to the cursor is applied. - */ - private int cursorX; - /** - * Y coordinate of the on-screen cursor, used in GUI screens.
- * When null, no change to the cursor is applied. - */ - private int cursorY; - - /** - * Creates a mouse with no buttons pressed and no data - */ - public VirtualMouse2(){ - this(new LinkedHashSet<>(), 0, 0, 0, new ArrayList<>(), true); - } - - /** - * Creates a subtick mouse with {@link VirtualPeripheral#subtickList} uninitialized - * @param pressedKeys The new list of pressed keycodes for this subtickMouse - * @param scrollWheel The scroll wheel direction for this subtickMouse - * @param cursorX The X coordinate of the cursor for this subtickMouse - * @param cursorY The Y coordinate of the cursor for this subtickMouse - */ - public VirtualMouse2(Set pressedKeys, int scrollWheel, int cursorX, int cursorY) { - this(pressedKeys, scrollWheel, cursorX, cursorY, null); - } - - /** - * Creates a mouse from existing values with - * {@link VirtualPeripheral#ignoreFirstUpdate} set to false - * - * @param pressedKeys The list of {@link #pressedKeys} - * @param scrollWheel The {@link #scrollWheel} - * @param cursorX The {@link #cursorX} - * @param cursorY The {@link #cursorY} - * @param subtick The {@link VirtualPeripheral#subtickList} - */ - public VirtualMouse2(Set pressedKeys, int scrollWheel, Integer cursorX, Integer cursorY, List subtick) { - this(pressedKeys, scrollWheel, cursorX, cursorY, subtick, false); - } - - /** - * Creates a mouse from existing values - * - * @param pressedKeys The list of {@link #pressedKeys} - * @param scrollWheel The {@link #scrollWheel} - * @param cursorX The {@link #cursorX} - * @param cursorY The {@link #cursorY} - * @param subtick The {@link VirtualPeripheral#subtickList} - * @param ignoreFirstUpdate Whether the first call to {@link #update(int, boolean, int, Integer, Integer)} should create a new subtick - */ - public VirtualMouse2(Set pressedKeys, int scrollWheel, Integer cursorX, Integer cursorY, List subtick, boolean ignoreFirstUpdate) { - super(pressedKeys, subtick, ignoreFirstUpdate); - this.scrollWheel = scrollWheel; - this.cursorX = cursorX; - this.cursorY = cursorY; - } - - public void update(int keycode, boolean keystate, int scrollwheel, Integer cursorX, Integer cursorY) { - if(isParent() && !ignoreFirstUpdate()) { - addSubtick(clone()); - } - setPressed(keycode, keystate); - this.scrollWheel = scrollwheel; - this.cursorX = cursorX; - this.cursorY = cursorY; - } - - @Override - public void setPressed(int keycode, boolean keystate) { - if (keycode < 0) { // Mouse buttons always have a keycode smaller than 0 - super.setPressed(keycode, keystate); - } - } - - /** - * Calculates a list of {@link VirtualMouseEvent}s, when comparing this mouse to - * the next mouse in the sequence,
- * which also includes the subticks. - * - * @see VirtualMouse2#getDifference(VirtualMouse2, Queue) - * - * @param nextMouse The mouse that comes after this one.
- * If this one is loaded at tick 15, the nextMouse should be - * the one from tick 16 - * @param reference The queue to fill. Passed in by reference. - */ - public void getVirtualEvents(VirtualMouse2 nextMouse, Queue reference) { - if (isParent()) { - VirtualMouse2 currentSubtick = this; - for(VirtualMouse2 subtick : nextMouse.getAll()) { - currentSubtick.getDifference(subtick, reference); - currentSubtick = subtick; - } - } - } - - /** - * Calculates the difference between 2 mice via symmetric difference
- * and returns a list of the changes between them in form of - * {@link VirtualMouseEvent}s - * - * @param nextMouse The mouse that comes after this one.
- * If this one is loaded at tick 15, the nextMouse should be - * the one from tick 16 - * @param reference The queue to fill. Passed in by reference. - */ - public void getDifference(VirtualMouse2 nextPeripheral, Queue reference) { - - /* - * Checks if pressedKeys are the same... - */ - if(pressedKeys.equals(nextPeripheral.pressedKeys)){ - - /** - * ...but scrollWheel, cursorX or cursorY are different. - * Without this, the scrollWheel would only work if a mouse button is pressed at the same time. - */ - if(!equals(nextPeripheral)) { - reference.add(new VirtualMouseEvent(VirtualKey2.MOUSEMOVED.getKeycode(), false, nextPeripheral.scrollWheel, nextPeripheral.cursorX, nextPeripheral.cursorY)); - } - return; - } - int scrollWheelCopy = nextPeripheral.scrollWheel; - int cursorXCopy = nextPeripheral.cursorX; - int cursorYCopy = nextPeripheral.cursorY; - - /* Calculate symmetric difference of keycodes */ - - /* - Calculate unpressed keys - this: LC RC - next: LC MC - ------------- - RC <- unpressed - */ - for(int keycode : pressedKeys) { - if (!nextPeripheral.getPressedKeys().contains(keycode)) { - reference.add(new VirtualMouseEvent(keycode, false, scrollWheelCopy, cursorXCopy, cursorYCopy)); - scrollWheelCopy = 0; - cursorXCopy = 0; - cursorYCopy = 0; - } - }; - - /* - Calculate pressed keys - next: LC MC - this: LC RC - ------------- - MC <- pressed - */ - for(int keycode : nextPeripheral.getPressedKeys()) { - if (!this.pressedKeys.contains(keycode)) { - reference.add(new VirtualMouseEvent(keycode, true, scrollWheelCopy, cursorXCopy, cursorYCopy)); - } - }; - } - - @Override - protected void clear() { - super.clear(); - clearMouseData(); - } - - /** - * Resets mouse specific data to it's defaults - */ - private void clearMouseData() { - scrollWheel = 0; - cursorX = 0; - cursorY = 0; - } - - - @Override - public String toString() { - if (isParent()) { - return getAll().stream().map(VirtualMouse2::toString2).collect(Collectors.joining("\n")); - } else { - return toString2(); - } - } - - private String toString2(){ - return String.format("%s;%s,%s,%s", super.toString(), scrollWheel, cursorX, cursorY); - } - - /** - * Clones this VirtualMouse without subticks - */ - @Override - public VirtualMouse2 clone() { - return new VirtualMouse2(new HashSet<>(this.pressedKeys), scrollWheel, cursorX, cursorY, null, ignoreFirstUpdate()); - } - - @Override - public void copyFrom(VirtualMouse2 mouse) { - super.copyFrom(mouse); - this.scrollWheel = mouse.scrollWheel; - this.cursorX = mouse.cursorX; - this.cursorY = mouse.cursorY; - mouse.clearMouseData(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof VirtualMouse2) { - VirtualMouse2 mouse = (VirtualMouse2) obj; - return super.equals(obj) && - scrollWheel == mouse.scrollWheel && - cursorX == mouse.cursorX && - cursorY == mouse.cursorY; - } - return super.equals(obj); - } - - /** - * @return {@link #scrollWheel} - */ - public int getScrollWheel() { - return scrollWheel; - } - - /** - * @return {@link #cursorX} - */ - public int getCursorX() { - return cursorX; - } - - /** - * @return {@link #cursorY} - */ - public int getCursorY() { - return cursorY; - } -} diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java index 21e7a917..f7d504f9 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java @@ -7,9 +7,10 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import com.minecrafttas.tasmod.virtual.event.VirtualEvent; /** - * Base class for {@link VirtualKeyboard2} and {@link VirtualMouse2}
+ * Base class for {@link VirtualKeyboard} and {@link VirtualMouse}
*
* Contains the shared code for keeping track of which buttons are pressed.
* This works by storing the keycodes of the buttons in a set, as keycodes are supposed to be unique
@@ -83,7 +84,7 @@ protected void addSubtick(T peripheral) { * @param keystate The keystate of the keyname */ public void setPressed(String keyname, boolean keystate) { - Integer keycode = VirtualKey2.getKeycode(keyname); + Integer keycode = VirtualKey.getKeycode(keyname); if (keycode != null) { setPressed(keycode, keystate); } @@ -95,7 +96,7 @@ public void setPressed(String keyname, boolean keystate) { public List getCurrentPresses() { List out = new ArrayList<>(); pressedKeys.forEach(keycode -> { - out.add(VirtualKey2.getName(keycode)); + out.add(VirtualKey.getName(keycode)); }); return out; } @@ -156,7 +157,7 @@ public boolean isKeyDown(int keycode) { * @return If the key is pressed */ public boolean isKeyDown(String keyname) { - return pressedKeys.contains(VirtualKey2.getKeycode(keyname)); + return pressedKeys.contains(VirtualKey.getKeycode(keyname)); } /** diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualEvent.java similarity index 93% rename from src/main/java/com/minecrafttas/tasmod/virtual/VirtualEvent.java rename to src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualEvent.java index 0cedbca9..ea376bfd 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualEvent.java @@ -1,4 +1,4 @@ -package com.minecrafttas.tasmod.virtual; +package com.minecrafttas.tasmod.virtual.event; public class VirtualEvent { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualKeyboardEvent.java similarity index 88% rename from src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java rename to src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualKeyboardEvent.java index cd66b1a5..5c0b0cc8 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboardEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualKeyboardEvent.java @@ -1,6 +1,6 @@ -package com.minecrafttas.tasmod.virtual; +package com.minecrafttas.tasmod.virtual.event; -import com.minecrafttas.tasmod.virtual.VirtualEvent.VirtualButtonEvent; +import com.minecrafttas.tasmod.virtual.event.VirtualEvent.VirtualButtonEvent; public class VirtualKeyboardEvent extends VirtualButtonEvent { private final char character; diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualMouseEvent.java similarity index 89% rename from src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java rename to src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualMouseEvent.java index f0bcb276..251eb865 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouseEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualMouseEvent.java @@ -1,6 +1,6 @@ -package com.minecrafttas.tasmod.virtual; +package com.minecrafttas.tasmod.virtual.event; -import com.minecrafttas.tasmod.virtual.VirtualEvent.VirtualButtonEvent; +import com.minecrafttas.tasmod.virtual.event.VirtualEvent.VirtualButtonEvent; /** * Template for recording Mouse.next() events. diff --git a/src/test/java/tasmod/virtual/VirtualInputTest.java b/src/test/java/tasmod/virtual/VirtualInputTest.java index 2d4a8cf7..ad71d15e 100644 --- a/src/test/java/tasmod/virtual/VirtualInputTest.java +++ b/src/test/java/tasmod/virtual/VirtualInputTest.java @@ -5,15 +5,12 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import com.minecrafttas.tasmod.virtual.*; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.junit.jupiter.api.Test; -import com.minecrafttas.tasmod.virtual.VirtualCameraAngle2; -import com.minecrafttas.tasmod.virtual.VirtualInput2; -import com.minecrafttas.tasmod.virtual.VirtualKey2; -import com.minecrafttas.tasmod.virtual.VirtualKeyboard2; -import com.minecrafttas.tasmod.virtual.VirtualMouse2; +import com.minecrafttas.tasmod.virtual.VirtualInput; class VirtualInputTest { @@ -24,7 +21,7 @@ class VirtualInputTest { */ @Test void testConstructor() { - VirtualInput2 virtual = new VirtualInput2(LOGGER); + VirtualInput virtual = new VirtualInput(LOGGER); assertNotNull(virtual.KEYBOARD); assertNotNull(virtual.MOUSE); @@ -36,23 +33,23 @@ void testConstructor() { */ @Test void testPreloadedConstructor() { - VirtualKeyboard2 preloadedKeyboard = new VirtualKeyboard2(); - VirtualMouse2 preloadedMouse = new VirtualMouse2(); - VirtualCameraAngle2 preloadedCameraAngle = new VirtualCameraAngle2(1f, 2f); + VirtualKeyboard preloadedKeyboard = new VirtualKeyboard(); + VirtualMouse preloadedMouse = new VirtualMouse(); + VirtualCameraAngle preloadedCameraAngle = new VirtualCameraAngle(1f, 2f); - preloadedKeyboard.update(VirtualKey2.W.getKeycode(), true, 'w'); - preloadedMouse.update(VirtualKey2.LC.getKeycode(), true, 15, 0, 0); + preloadedKeyboard.update(VirtualKey.W.getKeycode(), true, 'w'); + preloadedMouse.update(VirtualKey.LC.getKeycode(), true, 15, 0, 0); - VirtualInput2 virtual = new VirtualInput2(LOGGER, preloadedKeyboard, preloadedMouse, preloadedCameraAngle); + VirtualInput virtual = new VirtualInput(LOGGER, preloadedKeyboard, preloadedMouse, preloadedCameraAngle); virtual.KEYBOARD.nextKeyboardTick(); assertTrue(virtual.KEYBOARD.nextKeyboardSubtick()); - assertEquals(VirtualKey2.W.getKeycode(), virtual.KEYBOARD.getEventKeyboardKey()); + assertEquals(VirtualKey.W.getKeycode(), virtual.KEYBOARD.getEventKeyboardKey()); virtual.MOUSE.nextMouseTick(); assertTrue(virtual.MOUSE.nextMouseSubtick()); - assertEquals(VirtualKey2.LC.getKeycode(), virtual.MOUSE.getEventMouseKey()); + assertEquals(VirtualKey.LC.getKeycode(), virtual.MOUSE.getEventMouseKey()); assertEquals(1f, virtual.CAMERA_ANGLE.getPitch()); assertEquals(2f, virtual.CAMERA_ANGLE.getYaw()); @@ -63,12 +60,12 @@ void testPreloadedConstructor() { */ @Test void testKeyboardAddPresses() { - VirtualInput2 virtual = new VirtualInput2(LOGGER); + VirtualInput virtual = new VirtualInput(LOGGER); // Simulate pressing keys WAS on the keyboard - virtual.KEYBOARD.updateNextKeyboard(VirtualKey2.W.getKeycode(), true, 'w'); - virtual.KEYBOARD.updateNextKeyboard(VirtualKey2.A.getKeycode(), true, 'a'); - virtual.KEYBOARD.updateNextKeyboard(VirtualKey2.S.getKeycode(), true, 's'); + virtual.KEYBOARD.updateNextKeyboard(VirtualKey.W.getKeycode(), true, 'w'); + virtual.KEYBOARD.updateNextKeyboard(VirtualKey.A.getKeycode(), true, 'a'); + virtual.KEYBOARD.updateNextKeyboard(VirtualKey.S.getKeycode(), true, 's'); // Load the next keyboard events virtual.KEYBOARD.nextKeyboardTick(); @@ -79,7 +76,7 @@ void testKeyboardAddPresses() { assertTrue(virtual.KEYBOARD.nextKeyboardSubtick()); // Read out values from the subtick - assertEquals(VirtualKey2.W.getKeycode(), virtual.KEYBOARD.getEventKeyboardKey()); + assertEquals(VirtualKey.W.getKeycode(), virtual.KEYBOARD.getEventKeyboardKey()); assertTrue(virtual.KEYBOARD.getEventKeyboardState()); assertEquals('w', virtual.KEYBOARD.getEventKeyboardCharacter()); @@ -89,7 +86,7 @@ void testKeyboardAddPresses() { assertTrue(virtual.KEYBOARD.nextKeyboardSubtick()); // Read out values from the subtick - assertEquals(VirtualKey2.A.getKeycode(), virtual.KEYBOARD.getEventKeyboardKey()); + assertEquals(VirtualKey.A.getKeycode(), virtual.KEYBOARD.getEventKeyboardKey()); assertTrue(virtual.KEYBOARD.getEventKeyboardState()); assertEquals('a', virtual.KEYBOARD.getEventKeyboardCharacter()); @@ -99,7 +96,7 @@ void testKeyboardAddPresses() { assertTrue(virtual.KEYBOARD.nextKeyboardSubtick()); // Read out values from the subtick - assertEquals(VirtualKey2.S.getKeycode(), virtual.KEYBOARD.getEventKeyboardKey()); + assertEquals(VirtualKey.S.getKeycode(), virtual.KEYBOARD.getEventKeyboardKey()); assertEquals(true, virtual.KEYBOARD.getEventKeyboardState()); assertEquals('s', virtual.KEYBOARD.getEventKeyboardCharacter()); @@ -112,12 +109,12 @@ void testKeyboardAddPresses() { */ @Test void testKeyboardRemovePresses() { - VirtualKeyboard2 preloadedKeyboard = new VirtualKeyboard2(); + VirtualKeyboard preloadedKeyboard = new VirtualKeyboard(); - preloadedKeyboard.update(VirtualKey2.W.getKeycode(), true, 'w'); - VirtualInput2 virtual = new VirtualInput2(LOGGER, preloadedKeyboard, new VirtualMouse2(), new VirtualCameraAngle2()); + preloadedKeyboard.update(VirtualKey.W.getKeycode(), true, 'w'); + VirtualInput virtual = new VirtualInput(LOGGER, preloadedKeyboard, new VirtualMouse(), new VirtualCameraAngle()); - virtual.KEYBOARD.updateNextKeyboard(VirtualKey2.W.getKeycode(), false, Character.MIN_VALUE); + virtual.KEYBOARD.updateNextKeyboard(VirtualKey.W.getKeycode(), false, Character.MIN_VALUE); // Load the next keyboard events virtual.KEYBOARD.nextKeyboardTick(); @@ -126,7 +123,7 @@ void testKeyboardRemovePresses() { assertTrue(virtual.KEYBOARD.nextKeyboardSubtick()); // Read out values from the subtick - assertEquals(VirtualKey2.W.getKeycode(), virtual.KEYBOARD.getEventKeyboardKey()); + assertEquals(VirtualKey.W.getKeycode(), virtual.KEYBOARD.getEventKeyboardKey()); assertFalse(virtual.KEYBOARD.getEventKeyboardState()); assertEquals(Character.MIN_VALUE, virtual.KEYBOARD.getEventKeyboardCharacter()); diff --git a/src/test/java/tasmod/virtual/VirtualKeyboardTest.java b/src/test/java/tasmod/virtual/VirtualKeyboardTest.java index 399fb953..322bb8dd 100644 --- a/src/test/java/tasmod/virtual/VirtualKeyboardTest.java +++ b/src/test/java/tasmod/virtual/VirtualKeyboardTest.java @@ -7,9 +7,9 @@ import org.junit.jupiter.api.Test; -import com.minecrafttas.tasmod.virtual.VirtualKey2; -import com.minecrafttas.tasmod.virtual.VirtualKeyboard2; -import com.minecrafttas.tasmod.virtual.VirtualKeyboardEvent; +import com.minecrafttas.tasmod.virtual.VirtualKey; +import com.minecrafttas.tasmod.virtual.VirtualKeyboard; +import com.minecrafttas.tasmod.virtual.event.VirtualKeyboardEvent; class VirtualKeyboardTest { @@ -18,7 +18,7 @@ class VirtualKeyboardTest { */ @Test void testEmptyConstructor(){ - VirtualKeyboard2 actual = new VirtualKeyboard2(); + VirtualKeyboard actual = new VirtualKeyboard(); assertTrue(actual.getPressedKeys().isEmpty()); assertTrue(actual.getCharList().isEmpty()); assertTrue(actual.isParent()); @@ -30,14 +30,14 @@ void testEmptyConstructor(){ @Test void testSubtickConstructor(){ Set testKeycodeSet = new HashSet<>(); - testKeycodeSet.add(VirtualKey2.W.getKeycode()); - testKeycodeSet.add(VirtualKey2.S.getKeycode()); + testKeycodeSet.add(VirtualKey.W.getKeycode()); + testKeycodeSet.add(VirtualKey.S.getKeycode()); List testCharList = new ArrayList<>(); testCharList.add('w'); testCharList.add('s'); - VirtualKeyboard2 actual = new VirtualKeyboard2(testKeycodeSet, testCharList); + VirtualKeyboard actual = new VirtualKeyboard(testKeycodeSet, testCharList); assertIterableEquals(testKeycodeSet, actual.getPressedKeys()); assertIterableEquals(testCharList, actual.getCharList()); @@ -49,10 +49,10 @@ void testSubtickConstructor(){ */ @Test void testSetPressedByKeycode(){ - VirtualKeyboard2 actual = new VirtualKeyboard2(); - actual.setPressed(VirtualKey2.W.getKeycode(), true); + VirtualKeyboard actual = new VirtualKeyboard(); + actual.setPressed(VirtualKey.W.getKeycode(), true); - assertIterableEquals(Arrays.asList(VirtualKey2.W.getKeycode()), actual.getPressedKeys()); + assertIterableEquals(Arrays.asList(VirtualKey.W.getKeycode()), actual.getPressedKeys()); assertTrue(actual.isParent()); } @@ -61,8 +61,8 @@ void testSetPressedByKeycode(){ */ @Test void testFailingSetPressedByKeycode(){ - VirtualKeyboard2 actual = new VirtualKeyboard2(); - actual.setPressed(VirtualKey2.LC.getKeycode(), true); + VirtualKeyboard actual = new VirtualKeyboard(); + actual.setPressed(VirtualKey.LC.getKeycode(), true); assertTrue(actual.getPressedKeys().isEmpty()); assertTrue(actual.isParent()); @@ -73,10 +73,10 @@ void testFailingSetPressedByKeycode(){ */ @Test void testSetPressedByKeyname(){ - VirtualKeyboard2 actual = new VirtualKeyboard2(); + VirtualKeyboard actual = new VirtualKeyboard(); actual.setPressed("W", true); - assertIterableEquals(Arrays.asList(VirtualKey2.W.getKeycode()), actual.getPressedKeys()); + assertIterableEquals(Arrays.asList(VirtualKey.W.getKeycode()), actual.getPressedKeys()); assertTrue(actual.isParent()); } @@ -86,12 +86,12 @@ void testSetPressedByKeyname(){ @Test void testSetUnPressedByKeycode(){ Set testKeycodeSet = new HashSet<>(); - testKeycodeSet.add(VirtualKey2.W.getKeycode()); - testKeycodeSet.add(VirtualKey2.S.getKeycode()); - VirtualKeyboard2 actual = new VirtualKeyboard2(testKeycodeSet, new ArrayList<>()); - actual.setPressed(VirtualKey2.W.getKeycode(), false); + testKeycodeSet.add(VirtualKey.W.getKeycode()); + testKeycodeSet.add(VirtualKey.S.getKeycode()); + VirtualKeyboard actual = new VirtualKeyboard(testKeycodeSet, new ArrayList<>()); + actual.setPressed(VirtualKey.W.getKeycode(), false); - assertIterableEquals(Arrays.asList(VirtualKey2.S.getKeycode()), actual.getPressedKeys()); + assertIterableEquals(Arrays.asList(VirtualKey.S.getKeycode()), actual.getPressedKeys()); } /** @@ -100,12 +100,12 @@ void testSetUnPressedByKeycode(){ @Test void testSetUnPressedByKeyname(){ Set testKeycodeSet = new HashSet<>(); - testKeycodeSet.add(VirtualKey2.W.getKeycode()); - testKeycodeSet.add(VirtualKey2.S.getKeycode()); - VirtualKeyboard2 actual = new VirtualKeyboard2(testKeycodeSet, new ArrayList<>()); + testKeycodeSet.add(VirtualKey.W.getKeycode()); + testKeycodeSet.add(VirtualKey.S.getKeycode()); + VirtualKeyboard actual = new VirtualKeyboard(testKeycodeSet, new ArrayList<>()); actual.setPressed("S", false); - assertIterableEquals(Arrays.asList(VirtualKey2.W.getKeycode()), actual.getPressedKeys()); + assertIterableEquals(Arrays.asList(VirtualKey.W.getKeycode()), actual.getPressedKeys()); } /** @@ -113,7 +113,7 @@ void testSetUnPressedByKeyname(){ */ @Test void testAddCharacter(){ - VirtualKeyboard2 actual = new VirtualKeyboard2(); + VirtualKeyboard actual = new VirtualKeyboard(); actual.addChar('w', false); assertIterableEquals(Arrays.asList('w'), actual.getCharList()); @@ -125,15 +125,15 @@ void testAddCharacter(){ @Test void testToString(){ Set testKeycodeSet = new LinkedHashSet<>(); - testKeycodeSet.add(VirtualKey2.W.getKeycode()); - testKeycodeSet.add(VirtualKey2.S.getKeycode()); + testKeycodeSet.add(VirtualKey.W.getKeycode()); + testKeycodeSet.add(VirtualKey.S.getKeycode()); List testCharList = new ArrayList<>(); testCharList.add('w'); testCharList.add('s'); - VirtualKeyboard2 actual = new VirtualKeyboard2(testKeycodeSet, testCharList); - VirtualKeyboard2 actual2 = new VirtualKeyboard2(testKeycodeSet, new ArrayList<>()); + VirtualKeyboard actual = new VirtualKeyboard(testKeycodeSet, testCharList); + VirtualKeyboard actual2 = new VirtualKeyboard(testKeycodeSet, new ArrayList<>()); assertEquals("W,S;ws", actual.toString()); assertEquals("W,S;", actual2.toString()); @@ -144,10 +144,10 @@ void testToString(){ */ @Test void testToStringSubticks(){ - VirtualKeyboard2 actual = new VirtualKeyboard2(); + VirtualKeyboard actual = new VirtualKeyboard(); - actual.update(VirtualKey2.W.getKeycode(), true, 'w'); - actual.update(VirtualKey2.S.getKeycode(), true, 's'); + actual.update(VirtualKey.W.getKeycode(), true, 'w'); + actual.update(VirtualKey.S.getKeycode(), true, 's'); assertEquals("W;w\nW,S;s", actual.toString()); } @@ -158,15 +158,15 @@ void testToStringSubticks(){ @Test void testEquals() { Set testKeycodeSet = new HashSet<>(); - testKeycodeSet.add(VirtualKey2.W.getKeycode()); - testKeycodeSet.add(VirtualKey2.S.getKeycode()); + testKeycodeSet.add(VirtualKey.W.getKeycode()); + testKeycodeSet.add(VirtualKey.S.getKeycode()); List testCharList = new ArrayList<>(); testCharList.add('w'); testCharList.add('s'); - VirtualKeyboard2 actual = new VirtualKeyboard2(testKeycodeSet, testCharList); - VirtualKeyboard2 actual2 = new VirtualKeyboard2(testKeycodeSet, testCharList); + VirtualKeyboard actual = new VirtualKeyboard(testKeycodeSet, testCharList); + VirtualKeyboard actual2 = new VirtualKeyboard(testKeycodeSet, testCharList); assertEquals(actual, actual2); } @@ -177,8 +177,8 @@ void testEquals() { @Test void testNotEquals() { Set testKeycodeSet = new HashSet<>(); - testKeycodeSet.add(VirtualKey2.W.getKeycode()); - testKeycodeSet.add(VirtualKey2.S.getKeycode()); + testKeycodeSet.add(VirtualKey.W.getKeycode()); + testKeycodeSet.add(VirtualKey.S.getKeycode()); List testCharList = new ArrayList<>(); testCharList.add('w'); @@ -191,9 +191,9 @@ void testNotEquals() { List testCharList3 = new ArrayList<>(); testCharList3.add('w'); - VirtualKeyboard2 actual = new VirtualKeyboard2(testKeycodeSet, testCharList); - VirtualKeyboard2 test2 = new VirtualKeyboard2(testKeycodeSet, testCharList2); - VirtualKeyboard2 test3 = new VirtualKeyboard2(testKeycodeSet, testCharList3); + VirtualKeyboard actual = new VirtualKeyboard(testKeycodeSet, testCharList); + VirtualKeyboard test2 = new VirtualKeyboard(testKeycodeSet, testCharList2); + VirtualKeyboard test3 = new VirtualKeyboard(testKeycodeSet, testCharList3); assertNotEquals(actual, test2); assertNotEquals(actual, test3); @@ -206,15 +206,15 @@ void testNotEquals() { @Test void testClone() { Set testKeycodeSet = new HashSet<>(); - testKeycodeSet.add(VirtualKey2.W.getKeycode()); - testKeycodeSet.add(VirtualKey2.S.getKeycode()); + testKeycodeSet.add(VirtualKey.W.getKeycode()); + testKeycodeSet.add(VirtualKey.S.getKeycode()); List testCharList = new ArrayList<>(); testCharList.add('w'); testCharList.add('s'); - VirtualKeyboard2 actual = new VirtualKeyboard2(testKeycodeSet, testCharList); - VirtualKeyboard2 test2 = actual.clone(); + VirtualKeyboard actual = new VirtualKeyboard(testKeycodeSet, testCharList); + VirtualKeyboard test2 = actual.clone(); assertEquals(actual, test2); } @@ -224,16 +224,16 @@ void testClone() { */ @Test void testCopyFrom(){ - VirtualKeyboard2 copyFrom = new VirtualKeyboard2(); - VirtualKeyboard2 actual = new VirtualKeyboard2(); + VirtualKeyboard copyFrom = new VirtualKeyboard(); + VirtualKeyboard actual = new VirtualKeyboard(); - copyFrom.update(VirtualKey2.W.getKeycode(), true, 'w'); - copyFrom.update(VirtualKey2.A.getKeycode(), true, 'a'); + copyFrom.update(VirtualKey.W.getKeycode(), true, 'w'); + copyFrom.update(VirtualKey.A.getKeycode(), true, 'a'); - VirtualKeyboard2 expected = copyFrom.clone(); + VirtualKeyboard expected = copyFrom.clone(); - actual.update(VirtualKey2.S.getKeycode(), true, 's'); - actual.update(VirtualKey2.D.getKeycode(), true, 'd'); + actual.update(VirtualKey.S.getKeycode(), true, 's'); + actual.update(VirtualKey.D.getKeycode(), true, 'd'); actual.copyFrom(copyFrom); @@ -249,13 +249,13 @@ void testCopyFrom(){ */ @Test void testUpdate(){ - VirtualKeyboard2 actual = new VirtualKeyboard2(); - actual.update(VirtualKey2.W.getKeycode(), true, 'w'); - actual.update(VirtualKey2.A.getKeycode(), true, 'A'); + VirtualKeyboard actual = new VirtualKeyboard(); + actual.update(VirtualKey.W.getKeycode(), true, 'w'); + actual.update(VirtualKey.A.getKeycode(), true, 'A'); - List expected = new ArrayList<>(); - expected.add(new VirtualKeyboard2(new HashSet(Arrays.asList(VirtualKey2.W.getKeycode())), Arrays.asList('w'))); - expected.add(new VirtualKeyboard2(new HashSet(Arrays.asList(VirtualKey2.W.getKeycode(), VirtualKey2.A.getKeycode())), Arrays.asList('A'))); + List expected = new ArrayList<>(); + expected.add(new VirtualKeyboard(new HashSet(Arrays.asList(VirtualKey.W.getKeycode())), Arrays.asList('w'))); + expected.add(new VirtualKeyboard(new HashSet(Arrays.asList(VirtualKey.W.getKeycode(), VirtualKey.A.getKeycode())), Arrays.asList('A'))); assertIterableEquals(expected, actual.getAll()); } @@ -265,11 +265,11 @@ void testUpdate(){ */ @Test void testGetDifference(){ - VirtualKeyboard2 test = new VirtualKeyboard2(new HashSet<>(Arrays.asList(VirtualKey2.W.getKeycode())), Arrays.asList('w')); - VirtualKeyboard2 test2 = new VirtualKeyboard2(new HashSet<>(Arrays.asList(VirtualKey2.W.getKeycode(), VirtualKey2.S.getKeycode())), Arrays.asList('S')); + VirtualKeyboard test = new VirtualKeyboard(new HashSet<>(Arrays.asList(VirtualKey.W.getKeycode())), Arrays.asList('w')); + VirtualKeyboard test2 = new VirtualKeyboard(new HashSet<>(Arrays.asList(VirtualKey.W.getKeycode(), VirtualKey.S.getKeycode())), Arrays.asList('S')); Queue actual = new ConcurrentLinkedQueue<>(); test.getDifference(test2, actual); - Queue expected = new ConcurrentLinkedQueue<>(Arrays.asList(new VirtualKeyboardEvent(VirtualKey2.S.getKeycode(), true, 'S'))); + Queue expected = new ConcurrentLinkedQueue<>(Arrays.asList(new VirtualKeyboardEvent(VirtualKey.S.getKeycode(), true, 'S'))); assertIterableEquals(expected, actual); } @@ -279,17 +279,17 @@ void testGetDifference(){ */ @Test void testGetVirtualEventsPress() { - VirtualKeyboard2 unpressed = new VirtualKeyboard2(); + VirtualKeyboard unpressed = new VirtualKeyboard(); - VirtualKeyboard2 pressed = new VirtualKeyboard2(); - pressed.update(VirtualKey2.W.getKeycode(), true, 'w'); + VirtualKeyboard pressed = new VirtualKeyboard(); + pressed.update(VirtualKey.W.getKeycode(), true, 'w'); // Load actual with the events Queue actual = new ConcurrentLinkedQueue<>(); unpressed.getVirtualEvents(pressed, actual); // Load expected - List expected = Arrays.asList(new VirtualKeyboardEvent(VirtualKey2.W.getKeycode(), true, 'w')); + List expected = Arrays.asList(new VirtualKeyboardEvent(VirtualKey.W.getKeycode(), true, 'w')); assertIterableEquals(expected, actual); } @@ -299,17 +299,17 @@ void testGetVirtualEventsPress() { */ @Test void testGetVirtualEventsUnpress() { - VirtualKeyboard2 unpressed = new VirtualKeyboard2(); + VirtualKeyboard unpressed = new VirtualKeyboard(); - VirtualKeyboard2 pressed = new VirtualKeyboard2(); - pressed.update(VirtualKey2.W.getKeycode(), true, 'w'); + VirtualKeyboard pressed = new VirtualKeyboard(); + pressed.update(VirtualKey.W.getKeycode(), true, 'w'); // Load actual with the events Queue actual = new ConcurrentLinkedQueue<>(); pressed.getVirtualEvents(unpressed, actual); // Load expected - List expected = Arrays.asList(new VirtualKeyboardEvent(VirtualKey2.W.getKeycode(), false, Character.MIN_VALUE)); + List expected = Arrays.asList(new VirtualKeyboardEvent(VirtualKey.W.getKeycode(), false, Character.MIN_VALUE)); assertIterableEquals(expected, actual); } @@ -319,9 +319,9 @@ void testGetVirtualEventsUnpress() { */ @Test void testRepeatEvents(){ - VirtualKeyboard2 testKb = new VirtualKeyboard2(); + VirtualKeyboard testKb = new VirtualKeyboard(); - int keycode = VirtualKey2.BACK.getKeycode(); + int keycode = VirtualKey.BACK.getKeycode(); // Update the keyboard multiple times with the same value testKb.update(keycode, true, Character.MIN_VALUE, true); @@ -330,7 +330,7 @@ void testRepeatEvents(){ Queue actual = new ConcurrentLinkedQueue<>(); // Fill "actual" with VirtualKeyboardEvents - new VirtualKeyboard2().getVirtualEvents(testKb, actual); + new VirtualKeyboard().getVirtualEvents(testKb, actual); List expected = new ArrayList<>(); // Add expected VirtualKeyboardEvents @@ -346,9 +346,9 @@ void testRepeatEvents(){ */ @Test void testRepeatEventsFail(){ - VirtualKeyboard2 testKb = new VirtualKeyboard2(); + VirtualKeyboard testKb = new VirtualKeyboard(); - int keycode = VirtualKey2.BACK.getKeycode(); + int keycode = VirtualKey.BACK.getKeycode(); // Update the keyboard multiple times with the same value. testKb.update(keycode, true, Character.MIN_VALUE, false); testKb.update(keycode, true, Character.MIN_VALUE, false); @@ -356,7 +356,7 @@ void testRepeatEventsFail(){ Queue actual = new ConcurrentLinkedQueue<>(); // Fill "actual" with VirtualKeyboardEvents - new VirtualKeyboard2().getVirtualEvents(testKb, actual); + new VirtualKeyboard().getVirtualEvents(testKb, actual); List expected = new ArrayList<>(); diff --git a/src/test/java/tasmod/virtual/VirtualMouseTest.java b/src/test/java/tasmod/virtual/VirtualMouseTest.java index 2b39bf55..e7dc4b13 100644 --- a/src/test/java/tasmod/virtual/VirtualMouseTest.java +++ b/src/test/java/tasmod/virtual/VirtualMouseTest.java @@ -15,13 +15,11 @@ import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; +import com.minecrafttas.tasmod.virtual.VirtualMouse; import org.junit.jupiter.api.Test; -import com.minecrafttas.tasmod.virtual.VirtualKey2; -import com.minecrafttas.tasmod.virtual.VirtualKeyboard2; -import com.minecrafttas.tasmod.virtual.VirtualKeyboardEvent; -import com.minecrafttas.tasmod.virtual.VirtualMouse2; -import com.minecrafttas.tasmod.virtual.VirtualMouseEvent; +import com.minecrafttas.tasmod.virtual.VirtualKey; +import com.minecrafttas.tasmod.virtual.event.VirtualMouseEvent; class VirtualMouseTest { @@ -30,7 +28,7 @@ class VirtualMouseTest { */ @Test void testEmptyConstructor() { - VirtualMouse2 actual = new VirtualMouse2(); + VirtualMouse actual = new VirtualMouse(); assertTrue(actual.getPressedKeys().isEmpty()); assertEquals(0, actual.getScrollWheel()); assertEquals(0, actual.getCursorX()); @@ -44,10 +42,10 @@ void testEmptyConstructor() { @Test void testSubtickConstructor() { Set expected = new HashSet<>(); - expected.add(VirtualKey2.LC.getKeycode()); - expected.add(VirtualKey2.RC.getKeycode()); + expected.add(VirtualKey.LC.getKeycode()); + expected.add(VirtualKey.RC.getKeycode()); - VirtualMouse2 actual = new VirtualMouse2(expected, -15, 0, 2); + VirtualMouse actual = new VirtualMouse(expected, -15, 0, 2); assertIterableEquals(expected, actual.getPressedKeys()); assertEquals(-15, actual.getScrollWheel()); @@ -61,10 +59,10 @@ void testSubtickConstructor() { */ @Test void testSetPressedByKeycode(){ - VirtualMouse2 actual = new VirtualMouse2(); - actual.setPressed(VirtualKey2.LC.getKeycode(), true); + VirtualMouse actual = new VirtualMouse(); + actual.setPressed(VirtualKey.LC.getKeycode(), true); - assertIterableEquals(Arrays.asList(VirtualKey2.LC.getKeycode()), actual.getPressedKeys()); + assertIterableEquals(Arrays.asList(VirtualKey.LC.getKeycode()), actual.getPressedKeys()); assertTrue(actual.isParent()); } @@ -73,10 +71,10 @@ void testSetPressedByKeycode(){ */ @Test void testSetPressedByKeyname(){ - VirtualMouse2 actual = new VirtualMouse2(); + VirtualMouse actual = new VirtualMouse(); actual.setPressed("LC", true); - assertIterableEquals(Arrays.asList(VirtualKey2.LC.getKeycode()), actual.getPressedKeys()); + assertIterableEquals(Arrays.asList(VirtualKey.LC.getKeycode()), actual.getPressedKeys()); assertTrue(actual.isParent()); } @@ -86,12 +84,12 @@ void testSetPressedByKeyname(){ @Test void testSetUnPressedByKeycode(){ Set testKeycodeSet = new HashSet<>(); - testKeycodeSet.add(VirtualKey2.LC.getKeycode()); - testKeycodeSet.add(VirtualKey2.MBUTTON9.getKeycode()); - VirtualMouse2 actual = new VirtualMouse2(testKeycodeSet, 0, 0, 0); - actual.setPressed(VirtualKey2.MBUTTON9.getKeycode(), false); + testKeycodeSet.add(VirtualKey.LC.getKeycode()); + testKeycodeSet.add(VirtualKey.MBUTTON9.getKeycode()); + VirtualMouse actual = new VirtualMouse(testKeycodeSet, 0, 0, 0); + actual.setPressed(VirtualKey.MBUTTON9.getKeycode(), false); - assertIterableEquals(Arrays.asList(VirtualKey2.LC.getKeycode()), actual.getPressedKeys()); + assertIterableEquals(Arrays.asList(VirtualKey.LC.getKeycode()), actual.getPressedKeys()); } /** @@ -100,12 +98,12 @@ void testSetUnPressedByKeycode(){ @Test void testSetUnPressedByKeyname(){ Set testKeycodeSet = new HashSet<>(); - testKeycodeSet.add(VirtualKey2.LC.getKeycode()); - testKeycodeSet.add(VirtualKey2.MBUTTON9.getKeycode()); - VirtualMouse2 actual = new VirtualMouse2(testKeycodeSet, 0, 0, 0); + testKeycodeSet.add(VirtualKey.LC.getKeycode()); + testKeycodeSet.add(VirtualKey.MBUTTON9.getKeycode()); + VirtualMouse actual = new VirtualMouse(testKeycodeSet, 0, 0, 0); actual.setPressed("MBUTTON9", false); - assertIterableEquals(Arrays.asList(VirtualKey2.LC.getKeycode()), actual.getPressedKeys()); + assertIterableEquals(Arrays.asList(VirtualKey.LC.getKeycode()), actual.getPressedKeys()); } /** @@ -114,10 +112,10 @@ void testSetUnPressedByKeyname(){ @Test void testToString(){ Set testKeycodeSet = new LinkedHashSet<>(); - testKeycodeSet.add(VirtualKey2.LC.getKeycode()); - testKeycodeSet.add(VirtualKey2.MC.getKeycode()); + testKeycodeSet.add(VirtualKey.LC.getKeycode()); + testKeycodeSet.add(VirtualKey.MC.getKeycode()); - VirtualMouse2 actual = new VirtualMouse2(testKeycodeSet, 10, 100, 120); + VirtualMouse actual = new VirtualMouse(testKeycodeSet, 10, 100, 120); assertEquals("LC,MC;10,100,120", actual.toString()); } @@ -127,9 +125,9 @@ void testToString(){ */ @Test void testToStringSubtick(){ - VirtualMouse2 actual = new VirtualMouse2(); - actual.update(VirtualKey2.LC.getKeycode(), true, 10, 100, 120); - actual.update(VirtualKey2.MC.getKeycode(), true, 0, 12, 3); + VirtualMouse actual = new VirtualMouse(); + actual.update(VirtualKey.LC.getKeycode(), true, 10, 100, 120); + actual.update(VirtualKey.MC.getKeycode(), true, 0, 12, 3); assertEquals("LC;10,100,120\nLC,MC;0,12,3", actual.toString()); } @@ -140,12 +138,12 @@ void testToStringSubtick(){ @Test void testEquals() { Set testKeycodeSet = new HashSet<>(); - testKeycodeSet.add(VirtualKey2.W.getKeycode()); - testKeycodeSet.add(VirtualKey2.S.getKeycode()); + testKeycodeSet.add(VirtualKey.W.getKeycode()); + testKeycodeSet.add(VirtualKey.S.getKeycode()); - VirtualMouse2 actual = new VirtualMouse2(testKeycodeSet, -15, 129, 340); - VirtualMouse2 actual2 = new VirtualMouse2(testKeycodeSet, -15, 129, 340); + VirtualMouse actual = new VirtualMouse(testKeycodeSet, -15, 129, 340); + VirtualMouse actual2 = new VirtualMouse(testKeycodeSet, -15, 129, 340); assertEquals(actual, actual2); } @@ -156,20 +154,20 @@ void testEquals() { @Test void testNotEquals() { Set testKeycodeSet = new HashSet<>(); - testKeycodeSet.add(VirtualKey2.LC.getKeycode()); + testKeycodeSet.add(VirtualKey.LC.getKeycode()); - VirtualMouse2 actual = new VirtualMouse2(testKeycodeSet, -15, 1, 1); + VirtualMouse actual = new VirtualMouse(testKeycodeSet, -15, 1, 1); Set testKeycodeSet2 = new HashSet<>(); - testKeycodeSet.add(VirtualKey2.RC.getKeycode()); - VirtualMouse2 test2 = new VirtualMouse2(testKeycodeSet2, -15, 1, 1); + testKeycodeSet.add(VirtualKey.RC.getKeycode()); + VirtualMouse test2 = new VirtualMouse(testKeycodeSet2, -15, 1, 1); - VirtualMouse2 test3 = new VirtualMouse2(testKeycodeSet, -16, 1, 1); + VirtualMouse test3 = new VirtualMouse(testKeycodeSet, -16, 1, 1); - VirtualMouse2 test4 = new VirtualMouse2(testKeycodeSet, -15, 2, 1); - VirtualMouse2 test5 = new VirtualMouse2(testKeycodeSet, -15, 1, 2); + VirtualMouse test4 = new VirtualMouse(testKeycodeSet, -15, 2, 1); + VirtualMouse test5 = new VirtualMouse(testKeycodeSet, -15, 1, 2); assertNotEquals(actual, test2); assertNotEquals(actual, test3); @@ -184,11 +182,11 @@ void testNotEquals() { @Test void testClone() { Set testKeycodeSet = new HashSet<>(); - testKeycodeSet.add(VirtualKey2.LC.getKeycode()); - testKeycodeSet.add(VirtualKey2.MC.getKeycode()); + testKeycodeSet.add(VirtualKey.LC.getKeycode()); + testKeycodeSet.add(VirtualKey.MC.getKeycode()); - VirtualMouse2 actual = new VirtualMouse2(testKeycodeSet, 10, 3, 2); - VirtualMouse2 test2 = actual.clone(); + VirtualMouse actual = new VirtualMouse(testKeycodeSet, 10, 3, 2); + VirtualMouse test2 = actual.clone(); assertEquals(actual, test2); } @@ -198,16 +196,16 @@ void testClone() { */ @Test void testCopyFrom() { - VirtualMouse2 copyFrom = new VirtualMouse2(); - VirtualMouse2 actual = new VirtualMouse2(); + VirtualMouse copyFrom = new VirtualMouse(); + VirtualMouse actual = new VirtualMouse(); - copyFrom.update(VirtualKey2.LC.getKeycode(), true, 0, 0, 0); - copyFrom.update(VirtualKey2.MOUSEMOVED.getKeycode(), false, 120, 10, 20); + copyFrom.update(VirtualKey.LC.getKeycode(), true, 0, 0, 0); + copyFrom.update(VirtualKey.MOUSEMOVED.getKeycode(), false, 120, 10, 20); - VirtualMouse2 expected = copyFrom.clone(); + VirtualMouse expected = copyFrom.clone(); - actual.update(VirtualKey2.MBUTTON12.getKeycode(), true, 0,0,0); - actual.update(VirtualKey2.MOUSEMOVED.getKeycode(), true, -120, -10, -10); + actual.update(VirtualKey.MBUTTON12.getKeycode(), true, 0,0,0); + actual.update(VirtualKey.MOUSEMOVED.getKeycode(), true, -120, -10, -10); actual.copyFrom(copyFrom); @@ -227,13 +225,13 @@ void testCopyFrom() { */ @Test void testUpdate(){ - VirtualMouse2 actual = new VirtualMouse2(); - actual.update(VirtualKey2.LC.getKeycode(), true, -30, 118, 42); - actual.update(VirtualKey2.MOUSEMOVED.getKeycode(), false, 0, 23, 144); + VirtualMouse actual = new VirtualMouse(); + actual.update(VirtualKey.LC.getKeycode(), true, -30, 118, 42); + actual.update(VirtualKey.MOUSEMOVED.getKeycode(), false, 0, 23, 144); - List expected = new ArrayList<>(); - expected.add(new VirtualMouse2(new HashSet(Arrays.asList(VirtualKey2.LC.getKeycode())), -30, 118, 42)); - expected.add(new VirtualMouse2(new HashSet(Arrays.asList(VirtualKey2.LC.getKeycode())), 0, 23, 144)); + List expected = new ArrayList<>(); + expected.add(new VirtualMouse(new HashSet(Arrays.asList(VirtualKey.LC.getKeycode())), -30, 118, 42)); + expected.add(new VirtualMouse(new HashSet(Arrays.asList(VirtualKey.LC.getKeycode())), 0, 23, 144)); assertIterableEquals(expected, actual.getAll()); } @@ -243,11 +241,11 @@ void testUpdate(){ */ @Test void testGetDifference(){ - VirtualMouse2 test = new VirtualMouse2(new HashSet<>(Arrays.asList(VirtualKey2.LC.getKeycode())), 15, 0, 0); - VirtualMouse2 test2 = new VirtualMouse2(new HashSet<>(Arrays.asList(VirtualKey2.LC.getKeycode(), VirtualKey2.RC.getKeycode())), 30, 1, 2); + VirtualMouse test = new VirtualMouse(new HashSet<>(Arrays.asList(VirtualKey.LC.getKeycode())), 15, 0, 0); + VirtualMouse test2 = new VirtualMouse(new HashSet<>(Arrays.asList(VirtualKey.LC.getKeycode(), VirtualKey.RC.getKeycode())), 30, 1, 2); Queue actual = new ConcurrentLinkedQueue<>(); test.getDifference(test2, actual); - Queue expected = new ConcurrentLinkedQueue<>(Arrays.asList(new VirtualMouseEvent(VirtualKey2.RC.getKeycode(), true, 30, 1, 2))); + Queue expected = new ConcurrentLinkedQueue<>(Arrays.asList(new VirtualMouseEvent(VirtualKey.RC.getKeycode(), true, 30, 1, 2))); assertIterableEquals(expected, actual); } @@ -257,17 +255,17 @@ void testGetDifference(){ */ @Test void testGetVirtualEventsPress() { - VirtualMouse2 unpressed = new VirtualMouse2(); + VirtualMouse unpressed = new VirtualMouse(); - VirtualMouse2 pressed = new VirtualMouse2(); - pressed.update(VirtualKey2.LC.getKeycode(), true, 15, 10, 12); + VirtualMouse pressed = new VirtualMouse(); + pressed.update(VirtualKey.LC.getKeycode(), true, 15, 10, 12); // Load actual with the events Queue actual = new ConcurrentLinkedQueue<>(); unpressed.getVirtualEvents(pressed, actual); // Load expected - List expected = Arrays.asList(new VirtualMouseEvent(VirtualKey2.LC.getKeycode(), true, 15, 10, 12)); + List expected = Arrays.asList(new VirtualMouseEvent(VirtualKey.LC.getKeycode(), true, 15, 10, 12)); assertIterableEquals(expected, actual); } @@ -277,17 +275,17 @@ void testGetVirtualEventsPress() { */ @Test void testGetVirtualEventsUnpress() { - VirtualMouse2 unpressed = new VirtualMouse2(); + VirtualMouse unpressed = new VirtualMouse(); - VirtualMouse2 pressed = new VirtualMouse2(); - pressed.update(VirtualKey2.LC.getKeycode(), true, 15, 10, 12); + VirtualMouse pressed = new VirtualMouse(); + pressed.update(VirtualKey.LC.getKeycode(), true, 15, 10, 12); // Load actual with the events Queue actual = new ConcurrentLinkedQueue<>(); pressed.getVirtualEvents(unpressed, actual); // Load expected - List expected = Arrays.asList(new VirtualMouseEvent(VirtualKey2.LC.getKeycode(), false, 0, 0, 0)); + List expected = Arrays.asList(new VirtualMouseEvent(VirtualKey.LC.getKeycode(), false, 0, 0, 0)); assertIterableEquals(expected, actual); } @@ -297,11 +295,11 @@ void testGetVirtualEventsUnpress() { */ @Test void testSameUpdate() { - VirtualMouse2 unpressed = new VirtualMouse2(); + VirtualMouse unpressed = new VirtualMouse(); - VirtualMouse2 pressed = new VirtualMouse2(); - pressed.update(VirtualKey2.LC.getKeycode(), true, 15, 10, 12); - pressed.update(VirtualKey2.LC.getKeycode(), true, 15, 10, 12); + VirtualMouse pressed = new VirtualMouse(); + pressed.update(VirtualKey.LC.getKeycode(), true, 15, 10, 12); + pressed.update(VirtualKey.LC.getKeycode(), true, 15, 10, 12); // Load actual with the events Queue actual = new ConcurrentLinkedQueue<>(); @@ -309,7 +307,7 @@ void testSameUpdate() { // Load expected List expected = Arrays.asList( - new VirtualMouseEvent(VirtualKey2.LC.getKeycode(), true, 15, 10, 12) // Should only have one keyboard event + new VirtualMouseEvent(VirtualKey.LC.getKeycode(), true, 15, 10, 12) // Should only have one keyboard event ); assertIterableEquals(expected, actual); @@ -320,11 +318,11 @@ void testSameUpdate() { */ @Test void testScrollWheelDifferent() { - VirtualMouse2 unpressed = new VirtualMouse2(); + VirtualMouse unpressed = new VirtualMouse(); - VirtualMouse2 pressed = new VirtualMouse2(); - pressed.update(VirtualKey2.LC.getKeycode(), true, 15, 10, 12); - pressed.update(VirtualKey2.LC.getKeycode(), true, -30, 10, 12); + VirtualMouse pressed = new VirtualMouse(); + pressed.update(VirtualKey.LC.getKeycode(), true, 15, 10, 12); + pressed.update(VirtualKey.LC.getKeycode(), true, -30, 10, 12); // Load actual with the events Queue actual = new ConcurrentLinkedQueue<>(); @@ -332,8 +330,8 @@ void testScrollWheelDifferent() { // Load expected List expected = Arrays.asList( - new VirtualMouseEvent(VirtualKey2.LC.getKeycode(), true, 15, 10, 12), - new VirtualMouseEvent(VirtualKey2.MOUSEMOVED.getKeycode(), false, -30, 10, 12) // Adds an additional "MOUSEMOVED" event with the scroll wheel + new VirtualMouseEvent(VirtualKey.LC.getKeycode(), true, 15, 10, 12), + new VirtualMouseEvent(VirtualKey.MOUSEMOVED.getKeycode(), false, -30, 10, 12) // Adds an additional "MOUSEMOVED" event with the scroll wheel ); assertIterableEquals(expected, actual); @@ -344,11 +342,11 @@ void testScrollWheelDifferent() { */ @Test void testCursorXDifferent() { - VirtualMouse2 unpressed = new VirtualMouse2(); + VirtualMouse unpressed = new VirtualMouse(); - VirtualMouse2 pressed = new VirtualMouse2(); - pressed.update(VirtualKey2.LC.getKeycode(), true, 15, 10, 12); - pressed.update(VirtualKey2.LC.getKeycode(), true, 15, 11, 12); + VirtualMouse pressed = new VirtualMouse(); + pressed.update(VirtualKey.LC.getKeycode(), true, 15, 10, 12); + pressed.update(VirtualKey.LC.getKeycode(), true, 15, 11, 12); // Load actual with the events Queue actual = new ConcurrentLinkedQueue<>(); @@ -356,8 +354,8 @@ void testCursorXDifferent() { // Load expected List expected = Arrays.asList( - new VirtualMouseEvent(VirtualKey2.LC.getKeycode(), true, 15, 10, 12), - new VirtualMouseEvent(VirtualKey2.MOUSEMOVED.getKeycode(), false, 15, 11, 12) // Adds an additional "MOUSEMOVED" event with the cursorX + new VirtualMouseEvent(VirtualKey.LC.getKeycode(), true, 15, 10, 12), + new VirtualMouseEvent(VirtualKey.MOUSEMOVED.getKeycode(), false, 15, 11, 12) // Adds an additional "MOUSEMOVED" event with the cursorX ); assertIterableEquals(expected, actual); @@ -368,11 +366,11 @@ void testCursorXDifferent() { */ @Test void testCursorYDifferent() { - VirtualMouse2 unpressed = new VirtualMouse2(); + VirtualMouse unpressed = new VirtualMouse(); - VirtualMouse2 pressed = new VirtualMouse2(); - pressed.update(VirtualKey2.LC.getKeycode(), true, 15, 10, 12); - pressed.update(VirtualKey2.LC.getKeycode(), true, 15, 10, 120); + VirtualMouse pressed = new VirtualMouse(); + pressed.update(VirtualKey.LC.getKeycode(), true, 15, 10, 12); + pressed.update(VirtualKey.LC.getKeycode(), true, 15, 10, 120); // Load actual with the events Queue actual = new ConcurrentLinkedQueue<>(); @@ -380,8 +378,8 @@ void testCursorYDifferent() { // Load expected List expected = Arrays.asList( - new VirtualMouseEvent(VirtualKey2.LC.getKeycode(), true, 15, 10, 12), - new VirtualMouseEvent(VirtualKey2.MOUSEMOVED.getKeycode(), false, 15, 10, 120) // Adds an additional "MOUSEMOVED" event with the cursorY + new VirtualMouseEvent(VirtualKey.LC.getKeycode(), true, 15, 10, 12), + new VirtualMouseEvent(VirtualKey.MOUSEMOVED.getKeycode(), false, 15, 10, 120) // Adds an additional "MOUSEMOVED" event with the cursorY ); assertIterableEquals(expected, actual); From 80724e5df8d506ddeabb62dadb3e6b76638dcdf3 Mon Sep 17 00:00:00 2001 From: Scribble Date: Thu, 8 Feb 2024 22:14:22 +0100 Subject: [PATCH 38/57] [VirtualInput] Improving VirtualCameraAngle - Added Subtickable base class - Cleared MixinEntityRenderer for future rewrite --- .../tasmod/mixin/MixinMinecraft.java | 2 +- .../playbackhooks/MixinEntityRenderer.java | 99 ++----------------- .../com/minecrafttas/tasmod/util/Ducks.java | 2 +- .../tasmod/virtual/Subtickable.java | 88 +++++++++++++++++ .../tasmod/virtual/VirtualCameraAngle.java | 50 +++++++--- .../tasmod/virtual/VirtualInput.java | 21 ++-- .../tasmod/virtual/VirtualMouse.java | 14 +-- .../tasmod/virtual/VirtualPeripheral.java | 82 +-------------- .../java/tasmod/virtual/VirtualInputTest.java | 4 +- 9 files changed, 158 insertions(+), 204 deletions(-) create mode 100644 src/main/java/com/minecrafttas/tasmod/virtual/Subtickable.java diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java index d6acae24..ff7fad02 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java @@ -49,7 +49,7 @@ public void injectRunGameLoop(CallbackInfo ci) { @Redirect(method = "runGameLoop", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;runTick()V")) public void redirectRunTick(Minecraft mc) { if (TASmodClient.tickratechanger.ticksPerSecond != 0) { - ((SubtickDuck) this.entityRenderer).runUpdate(this.isGamePaused ? this.renderPartialTicksPaused : this.timer.renderPartialTicks); + ((SubtickDuck) this.entityRenderer).runUpdate(); } this.runTick(); TASmodClient.tickSchedulerClient.runAllTasks(); diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java index f4352ec7..e189ba8d 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java @@ -16,7 +16,9 @@ import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArgs; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.invoke.arg.Args; /** * Redirects the camera to use {@link VirtualInput.VirtualCameraAngleInput}.
@@ -27,99 +29,14 @@ public class MixinEntityRenderer implements SubtickDuck { @Shadow private Minecraft mc; - @Shadow - private float smoothCamYaw; - @Shadow - private float smoothCamPitch; - @Shadow - private float smoothCamPartialTicks; - @Shadow - private float smoothCamFilterX; - @Shadow - private float smoothCamFilterY; - - @Unique - private int dX; - @Unique - private int dY; - - @Inject(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/profiler/Profiler;startSection(Ljava/lang/String;)V", ordinal = 0, shift = At.Shift.AFTER)) - public void playback_injectAtStartSection(float partialTicks, long nanoTime, CallbackInfo ci) { - // Calculate sensitivity - float f = this.mc.gameSettings.mouseSensitivity * 0.6F + 0.2F; - float f1 = f * f * f * 8.0F; - - if (this.mc.currentScreen == null) { // No Gui - mc.mouseHelper.mouseXYChange(); - mc.getTutorial().handleMouse(mc.mouseHelper); - dX += mc.mouseHelper.deltaX; - dY += mc.mouseHelper.deltaY; - } else { // In the gui - dX = 0; - dY = 0; - } - if (TASmodClient.controller.isPlayingback()) { - dX = 0; - dY = 0; - } else { - // Comment this out to disable interpolation, also comment out @SubscribeEvent - // in InterpolationEvents - if (this.mc.currentScreen == null) { - InterpolationHandler.rotationYaw = ((float) ((double) InterpolationHandler.rotationYaw + (double) mc.mouseHelper.deltaX * f1 * 0.15D)); - InterpolationHandler.rotationPitch = (float) ((double) InterpolationHandler.rotationPitch - (double) mc.mouseHelper.deltaY * f1 * 0.15D); - InterpolationHandler.rotationPitch = MathHelper.clamp(InterpolationHandler.rotationPitch, -90.0F, 90.0F); - } - } + + @ModifyArgs(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;turn(FF)V")) + public void playback_redirectCamera(Args args) { } - - @ModifyExpressionValue(method = "updateCameraAndRender", at = @At(value = "FIELD", target = "Lnet/minecraft/client/Minecraft;inGameHasFocus:Z", opcode = Opcodes.GETFIELD)) - public boolean playback_stopVanilla(boolean original){ - return original && TASmodClient.tickratechanger.ticksPerSecond == 0; - } - + @Override - public void runUpdate(float partialTicks) { - boolean flag = Display.isActive(); - if (flag && Minecraft.IS_RUNNING_ON_MAC && mc.inGameHasFocus && !Mouse.isInsideWindow()) { - Mouse.setGrabbed(false); - Mouse.setCursorPosition(Display.getWidth() / 2, Display.getHeight() / 2 - 20); - Mouse.setGrabbed(true); - } - - if (mc.inGameHasFocus && flag) { - mc.getTutorial().handleMouse(mc.mouseHelper); - float f = mc.gameSettings.mouseSensitivity * 0.6F + 0.2F; - float f1 = f * f * f * 8.0F; - float f2 = (float) dX * f1; - float f3 = (float) dY * f1; - int i = 1; - - dX = 0; - dY = 0; - - if (mc.gameSettings.invertMouse) { - i = -1; - } - - if (mc.gameSettings.smoothCamera) { - smoothCamYaw += f2; - smoothCamPitch += f3; - float f4 = partialTicks - smoothCamPartialTicks; - smoothCamPartialTicks = partialTicks; - f2 = smoothCamFilterX * f4; - f3 = smoothCamFilterY * f4; - mc.player.turn(f2, f3 * (float) i); - } else { - smoothCamYaw = 0.0F; - smoothCamPitch = 0.0F; - mc.player.turn(f2, f3 * (float) i); - } - TASmodClient.virtual.CAMERA_ANGLE.updateCameraAngle(mc.player.rotationPitch, mc.player.rotationYaw); - mc.player.rotationPitch = TASmodClient.virtual.CAMERA_ANGLE.getPitch(); - mc.player.rotationYaw = TASmodClient.virtual.CAMERA_ANGLE.getYaw(); - InterpolationHandler.rotationPitch = mc.player.rotationPitch; - InterpolationHandler.rotationYaw = 180f + mc.player.rotationYaw; - } + public void runUpdate() { + TASmodClient.virtual.CAMERA_ANGLE.nextCameraTick(); } } diff --git a/src/main/java/com/minecrafttas/tasmod/util/Ducks.java b/src/main/java/com/minecrafttas/tasmod/util/Ducks.java index 5b785a6a..948f3f14 100644 --- a/src/main/java/com/minecrafttas/tasmod/util/Ducks.java +++ b/src/main/java/com/minecrafttas/tasmod/util/Ducks.java @@ -81,7 +81,7 @@ public static interface GuiScreenDuck { * Quacks the subtick */ public static interface SubtickDuck { - void runUpdate(float partialTicks); + void runUpdate(); } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/Subtickable.java b/src/main/java/com/minecrafttas/tasmod/virtual/Subtickable.java new file mode 100644 index 00000000..dcfb3ace --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/virtual/Subtickable.java @@ -0,0 +1,88 @@ +package com.minecrafttas.tasmod.virtual; + +import java.util.List; + +import com.google.common.collect.ImmutableList; + +public class Subtickable { + /** + * A list of subtick peripherals.
+ * If a peripheral parent is updated, it first adds it's current state to the subtickList before updating.
+ * This makes the subtickList a list of previous peripheral states, with the first element being the oldest change.
+ *
+ * To distinguish a peripheral of being a subtick or a "parent", subtickList is either null or not null respectively (see {@link #isParent()})
+ */ + protected final List subtickList; + /** + * The way the parent/subtick relationship is set up (see {@link #subtickList}),
+ * the subtickList contains all previous changes, while the parent contains the current state.
+ * To achieve this and to prevent a ghost state from being added to the subtickList,
+ * it is sometimes necessary to ignore the first time an addition is made to the subtickList,
+ * to delay the subtickList and make the parent the current state. + */ + private boolean ignoreFirstUpdate = false; + + protected Subtickable(List subtickList, boolean ignoreFirstUpdate) { + this.subtickList = subtickList; + this.ignoreFirstUpdate = ignoreFirstUpdate; + } + + /** + * Adds a peripheral to {@link #subtickList} + * @param peripheral The peripheral to add + */ + protected void addSubtick(T peripheral) { + subtickList.add(peripheral); + } + + /** + * @return An immutable list of subticks + */ + public List getSubticks() { + return ImmutableList.copyOf(subtickList); + } + + /** + * @return If the peripheral is a parent and can add subticks + */ + public boolean isParent() { + return subtickList != null; + } + + /** + * Gets all peripheral states in an immutable list.
+ *
+ * This list is comprised of {@link #subtickList} and the current peripheral state added after that
+ * This will result in a list where the first element is the oldest state and the last being the current state. + * @return An immutable list of keyboard states + */ + @SuppressWarnings("unchecked") + public List getAll() { + return ImmutableList.builder() + .addAll(subtickList) + .add((T)this) + .build(); + } + + /** + * Retrieves and sets {@link #ignoreFirstUpdate} to false + * @return If the first update should be ignored + */ + protected boolean ignoreFirstUpdate() { + boolean ignore = ignoreFirstUpdate; + ignoreFirstUpdate = false; + return ignore; + } + + /** + * @return If this peripheral should ignore it's first update + * @see #ignoreFirstUpdate + */ + protected boolean isIgnoreFirstUpdate(){ + return ignoreFirstUpdate; + } + + protected void resetFirstUpdate() { + ignoreFirstUpdate = true; + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java index 7a21921c..95943b2d 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java @@ -1,34 +1,48 @@ package com.minecrafttas.tasmod.virtual; import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; -public class VirtualCameraAngle implements Serializable { - private Float pitch; - private Float yaw; - - +public class VirtualCameraAngle extends Subtickable implements Serializable { + private float pitch; + private float yaw; + public VirtualCameraAngle() { - this(null, null); + this(0, 0, new ArrayList<>(), true); + } + + public VirtualCameraAngle(float pitch, float yaw) { + this(pitch, yaw, null); + } + + public VirtualCameraAngle(float pitch, float yaw, List subtickList) { + this(pitch, yaw, subtickList, false); } - public VirtualCameraAngle(Float pitch, Float yaw) { + public VirtualCameraAngle(float pitch, float yaw, List subtickList, boolean ignoreFirstUpdate) { + super(subtickList, ignoreFirstUpdate); this.pitch = pitch; this.yaw = yaw; } public void update(Float pitch, Float yaw) { + if(isParent() && !ignoreFirstUpdate()) { + addSubtick(clone()); + } this.pitch = pitch; this.yaw = yaw; } - public Float getPitch() { - return pitch; - } - - public Float getYaw() { - return yaw; + public void copyFrom(VirtualCameraAngle camera) { + this.pitch = camera.pitch; + this.yaw = camera.yaw; + this.subtickList.clear(); + this.subtickList.addAll(camera.subtickList); + camera.subtickList.clear(); + camera.resetFirstUpdate(); } - + @Override public VirtualCameraAngle clone() { return new VirtualCameraAngle(pitch, yaw); @@ -47,4 +61,12 @@ public boolean equals(Object obj) { public String toString() { return String.format("%s;%s", pitch, yaw); } + + public float getPitch() { + return pitch; + } + + public float getYaw() { + return yaw; + } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index fc8231cf..bdb0d7b8 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -467,22 +467,27 @@ public boolean willKeyBeDown(int keycode) { } public class VirtualCameraAngleInput { - private final VirtualCameraAngle cameraAngle; + private final VirtualCameraAngle currentCameraAngle; + private final VirtualCameraAngle nextCameraAngle = new VirtualCameraAngle(); public VirtualCameraAngleInput(VirtualCameraAngle preloadedCamera) { - cameraAngle = preloadedCamera; + currentCameraAngle = preloadedCamera; } - public void updateCameraAngle(float pitch, float yaw) { - cameraAngle.update(pitch, yaw); + public void updateNextCameraAngle(float pitch, float yaw) { + nextCameraAngle.update(pitch, yaw); } - public float getPitch() { - return cameraAngle.getPitch(); + public void nextCameraTick() { + currentCameraAngle.copyFrom(nextCameraAngle); } - public float getYaw() { - return cameraAngle.getYaw(); + public float getCurrentPitch() { + return currentCameraAngle.getPitch(); + } + + public float getCurrentYaw() { + return currentCameraAngle.getYaw(); } } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java index d2e7c552..fe1cca43 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java @@ -33,7 +33,7 @@ public VirtualMouse(){ } /** - * Creates a subtick mouse with {@link VirtualPeripheral#subtickList} uninitialized + * Creates a subtick mouse with {@link Subtickable#subtickList} uninitialized * @param pressedKeys The new list of pressed keycodes for this subtickMouse * @param scrollWheel The scroll wheel direction for this subtickMouse * @param cursorX The X coordinate of the cursor for this subtickMouse @@ -51,10 +51,10 @@ public VirtualMouse(Set pressedKeys, int scrollWheel, int cursorX, int * @param scrollWheel The {@link #scrollWheel} * @param cursorX The {@link #cursorX} * @param cursorY The {@link #cursorY} - * @param subtick The {@link VirtualPeripheral#subtickList} + * @param subtickList The {@link VirtualPeripheral#subtickList} */ - public VirtualMouse(Set pressedKeys, int scrollWheel, Integer cursorX, Integer cursorY, List subtick) { - this(pressedKeys, scrollWheel, cursorX, cursorY, subtick, false); + public VirtualMouse(Set pressedKeys, int scrollWheel, Integer cursorX, Integer cursorY, List subtickList) { + this(pressedKeys, scrollWheel, cursorX, cursorY, subtickList, false); } /** @@ -64,11 +64,11 @@ public VirtualMouse(Set pressedKeys, int scrollWheel, Integer cursorX, * @param scrollWheel The {@link #scrollWheel} * @param cursorX The {@link #cursorX} * @param cursorY The {@link #cursorY} - * @param subtick The {@link VirtualPeripheral#subtickList} + * @param subtickList The {@link VirtualPeripheral#subtickList} * @param ignoreFirstUpdate Whether the first call to {@link #update(int, boolean, int, Integer, Integer)} should create a new subtick */ - public VirtualMouse(Set pressedKeys, int scrollWheel, Integer cursorX, Integer cursorY, List subtick, boolean ignoreFirstUpdate) { - super(pressedKeys, subtick, ignoreFirstUpdate); + public VirtualMouse(Set pressedKeys, int scrollWheel, Integer cursorX, Integer cursorY, List subtickList, boolean ignoreFirstUpdate) { + super(pressedKeys, subtickList, ignoreFirstUpdate); this.scrollWheel = scrollWheel; this.cursorX = cursorX; this.cursorY = cursorY; diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java index f7d504f9..c27403d9 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java @@ -5,7 +5,6 @@ import java.util.List; import java.util.Set; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.minecrafttas.tasmod.virtual.event.VirtualEvent; @@ -19,29 +18,12 @@ * * @author Scribble */ -public abstract class VirtualPeripheral> implements Serializable { +public abstract class VirtualPeripheral> extends Subtickable implements Serializable { /** * The list of keycodes that are currently pressed on this peripheral. */ protected final Set pressedKeys; - /** - * A list of subtick peripherals.
- * If a peripheral parent is updated, it first adds it's current state to the subtickList before updating.
- * This makes the subtickList a list of previous peripheral states, with the first element being the oldest change.
- *
- * To distinguish a peripheral of being a subtick or a "parent", subtickList is either null or not null respectively (see {@link #isParent()})
- */ - protected final List subtickList; - - /** - * The way the parent/subtick relationship is set up (see {@link #subtickList}),
- * the subtickList contains all previous changes, while the parent contains the current state.
- * To achieve this and to prevent a ghost state from being added to the subtickList,
- * it is sometimes necessary to ignore the first time an addition is made to the subtickList,
- * to delay the subtickList and make the parent the current state. - */ - private boolean ignoreFirstUpdate = false; /** * Creates a VirtualPeripheral @@ -50,9 +32,8 @@ public abstract class VirtualPeripheral> implemen * @param ignoreFirstUpdate The {@link #ignoreFirstUpdate} state */ protected VirtualPeripheral(Set pressedKeys, List subtickList, boolean ignoreFirstUpdate) { + super(subtickList, ignoreFirstUpdate); this.pressedKeys = pressedKeys; - this.subtickList = subtickList; - this.ignoreFirstUpdate = ignoreFirstUpdate; } /** @@ -70,14 +51,6 @@ protected void setPressed(int keycode, boolean keystate) { pressedKeys.remove(keycode); } - /** - * Adds a peripheral to {@link #subtickList} - * @param peripheral The peripheral to add - */ - protected void addSubtick(T peripheral) { - subtickList.add(peripheral); - } - /** * Set the specified keyname to pressed * @param keyname The keyname to check @@ -113,35 +86,6 @@ public Set getPressedKeys() { return ImmutableSet.copyOf(pressedKeys); } - /** - * @return An immutable list of subticks - */ - public List getSubticks() { - return ImmutableList.copyOf(subtickList); - } - - /** - * Gets all peripheral states in an immutable list.
- *
- * This list is comprised of {@link #subtickList} and the current peripheral state added after that
- * This will result in a list where the first element is the oldest state and the last being the current state. - * @return An immutable list of keyboard states - */ - @SuppressWarnings("unchecked") - public List getAll() { - return ImmutableList.builder() - .addAll(subtickList) - .add((T)this) - .build(); - } - - /** - * @return If the peripheral is a parent and can add subticks - */ - public boolean isParent() { - return subtickList != null; - } - /** * If the key is available in {@link #pressedKeys} * @param keycode The keycode in question @@ -192,26 +136,4 @@ protected void copyFrom(T peripheral) { peripheral.subtickList.clear(); peripheral.resetFirstUpdate(); } - - /** - * Retrieves and sets {@link #ignoreFirstUpdate} to false - * @return If the first update should be ignored - */ - protected boolean ignoreFirstUpdate() { - boolean ignore = ignoreFirstUpdate; - ignoreFirstUpdate = false; - return ignore; - } - - /** - * @return If this peripheral should ignore it's first update - * @see #ignoreFirstUpdate - */ - protected boolean isIgnoreFirstUpdate(){ - return ignoreFirstUpdate; - } - - protected void resetFirstUpdate() { - ignoreFirstUpdate = true; - } } diff --git a/src/test/java/tasmod/virtual/VirtualInputTest.java b/src/test/java/tasmod/virtual/VirtualInputTest.java index ad71d15e..98e805be 100644 --- a/src/test/java/tasmod/virtual/VirtualInputTest.java +++ b/src/test/java/tasmod/virtual/VirtualInputTest.java @@ -51,8 +51,8 @@ void testPreloadedConstructor() { assertTrue(virtual.MOUSE.nextMouseSubtick()); assertEquals(VirtualKey.LC.getKeycode(), virtual.MOUSE.getEventMouseKey()); - assertEquals(1f, virtual.CAMERA_ANGLE.getPitch()); - assertEquals(2f, virtual.CAMERA_ANGLE.getYaw()); + assertEquals(1f, virtual.CAMERA_ANGLE.getCurrentPitch()); + assertEquals(2f, virtual.CAMERA_ANGLE.getCurrentYaw()); } /** From 2a992412c7318bc05d4a9ce9d62602281c91ee34 Mon Sep 17 00:00:00 2001 From: Scribble Date: Fri, 9 Feb 2024 20:49:37 +0100 Subject: [PATCH 39/57] [VirtualInput] Implemented subticks for cameraAngle --- .../mctcommon/mixin/MixinEntityRenderer.java | 40 -------------- .../com/minecrafttas/tasmod/TASmodClient.java | 2 +- .../tasmod/handlers/InterpolationHandler.java | 1 + .../playbackhooks/MixinEntityRenderer.java | 53 ++++++++++++++----- .../tasmod/virtual/VirtualCameraAngle.java | 25 +++++++-- .../tasmod/virtual/VirtualInput.java | 53 +++++++++++++++++-- .../event/VirtualCameraAngleEvent.java | 27 ++++++++++ .../java/tasmod/virtual/VirtualInputTest.java | 4 +- 8 files changed, 141 insertions(+), 64 deletions(-) delete mode 100644 src/main/java/com/minecrafttas/mctcommon/mixin/MixinEntityRenderer.java create mode 100644 src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualCameraAngleEvent.java diff --git a/src/main/java/com/minecrafttas/mctcommon/mixin/MixinEntityRenderer.java b/src/main/java/com/minecrafttas/mctcommon/mixin/MixinEntityRenderer.java deleted file mode 100644 index 16f7ff61..00000000 --- a/src/main/java/com/minecrafttas/mctcommon/mixin/MixinEntityRenderer.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.minecrafttas.mctcommon.mixin; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyArg; - -import com.minecrafttas.mctcommon.events.EventClient.EventCamera; -import com.minecrafttas.mctcommon.events.EventClient.EventCamera.CameraData; - -import net.minecraft.client.renderer.EntityRenderer; -import net.minecraft.client.renderer.GlStateManager; - -@Mixin(EntityRenderer.class) -public class MixinEntityRenderer { - - private float currentPitch; - - @ModifyArg(method = "orientCamera", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;rotate(FFFF)V", ordinal = 8), index = 0) - public float redirect_orientCameraPitch(float pitch) { - currentPitch = pitch; - return 0; - } - - @ModifyArg(method = "orientCamera", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;rotate(FFFF)V", ordinal = 9), index = 0) - public float redirect_orientCameraYawAnimal(float yawAnimal) { - return redirectCam(yawAnimal); - } - - @ModifyArg(method = "orientCamera", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;rotate(FFFF)V", ordinal = 10), index = 0) - public float redirect_orientCameraYaw(float yaw) { - return redirectCam(yaw); - } - - private float redirectCam(float yaw) { - CameraData data = EventCamera.fireCameraEvent(new CameraData(currentPitch, yaw)); - GlStateManager.rotate(data.pitch, 1.0f, 0.0f, 0.0f); - GlStateManager.rotate(data.roll, 0.0f, 0.0f, 1.0f); - return data.yaw; - } -} diff --git a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java index 6e398c21..49fe772c 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java @@ -147,7 +147,7 @@ public void onInitializeClient() { EventListenerRegistry.register(loadingScreenHandler); EventListenerRegistry.register(ticksyncClient); EventListenerRegistry.register(keybindManager); - EventListenerRegistry.register(interpolation); +// EventListenerRegistry.register(interpolation); EventListenerRegistry.register((EventOpenGui)(gui -> { if(gui instanceof GuiMainMenu) { openMainMenuScheduler.runAllTasks(); diff --git a/src/main/java/com/minecrafttas/tasmod/handlers/InterpolationHandler.java b/src/main/java/com/minecrafttas/tasmod/handlers/InterpolationHandler.java index b2f08eac..69e4df41 100644 --- a/src/main/java/com/minecrafttas/tasmod/handlers/InterpolationHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/handlers/InterpolationHandler.java @@ -14,6 +14,7 @@ * @author Pancake * */ +@Deprecated public class InterpolationHandler implements EventCamera { public static float rotationPitch = 0f; diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java index e189ba8d..3ec73e53 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java @@ -1,25 +1,23 @@ package com.minecrafttas.tasmod.mixin.playbackhooks; -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import com.minecrafttas.tasmod.TASmodClient; -import com.minecrafttas.tasmod.handlers.InterpolationHandler; -import com.minecrafttas.tasmod.util.Ducks.SubtickDuck; -import com.minecrafttas.tasmod.virtual.VirtualInput; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.EntityRenderer; -import net.minecraft.util.math.MathHelper; -import org.lwjgl.input.Mouse; -import org.lwjgl.opengl.Display; -import org.objectweb.asm.Opcodes; +import org.apache.commons.lang3.tuple.Triple; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.ModifyArgs; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.invoke.arg.Args; +import com.llamalad7.mixinextras.sugar.Share; +import com.llamalad7.mixinextras.sugar.ref.LocalFloatRef; +import com.minecrafttas.tasmod.TASmodClient; +import com.minecrafttas.tasmod.util.Ducks.SubtickDuck; +import com.minecrafttas.tasmod.virtual.VirtualInput; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.EntityRenderer; +import net.minecraft.client.renderer.GlStateManager; + /** * Redirects the camera to use {@link VirtualInput.VirtualCameraAngleInput}.
* Also conforms the camera to 20tps as @@ -33,10 +31,37 @@ public class MixinEntityRenderer implements SubtickDuck { @ModifyArgs(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;turn(FF)V")) public void playback_redirectCamera(Args args) { + TASmodClient.virtual.CAMERA_ANGLE.updateNextCameraAngle(args.get(0), args.get(1)); + + args.set(0, TASmodClient.virtual.CAMERA_ANGLE.getCurrentPitch()); + args.set(1, TASmodClient.virtual.CAMERA_ANGLE.getCurrentYaw()); } @Override public void runUpdate() { TASmodClient.virtual.CAMERA_ANGLE.nextCameraTick(); } + + @ModifyArg(method = "orientCamera", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;rotate(FFFF)V", ordinal = 8), index = 0) + public float redirect_orientCameraPitch(float pitch, @Share("pitch") LocalFloatRef sharedPitch) { + sharedPitch.set(pitch); + return 0; + } + + @ModifyArg(method = "orientCamera", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;rotate(FFFF)V", ordinal = 9), index = 0) + public float redirect_orientCameraYawAnimal(float yawAnimal, @Share("pitch") LocalFloatRef sharedPitch) { + return redirectCam(yawAnimal, sharedPitch.get()); + } + + @ModifyArg(method = "orientCamera", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;rotate(FFFF)V", ordinal = 10), index = 0) + public float redirect_orientCameraYaw(float yaw, @Share("pitch") LocalFloatRef sharedPitch) { + return redirectCam(yaw, sharedPitch.get()); + } + + private float redirectCam(float yaw, float pitch) { + Triple interpolated = TASmodClient.virtual.CAMERA_ANGLE.getInterpolatedState(pitch, pitch, yaw, TASmodClient.controller.isPlayingback()); + GlStateManager.rotate(interpolated.getLeft(), 1.0f, 0.0f, 0.0f); + GlStateManager.rotate(interpolated.getRight(), 0.0f, 0.0f, 1.0f); + return interpolated.getMiddle(); + } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java index 95943b2d..ab620a7a 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java @@ -4,6 +4,8 @@ import java.util.ArrayList; import java.util.List; +import com.minecrafttas.tasmod.virtual.event.VirtualCameraAngleEvent; + public class VirtualCameraAngle extends Subtickable implements Serializable { private float pitch; private float yaw; @@ -26,12 +28,29 @@ public VirtualCameraAngle(float pitch, float yaw, List subti this.yaw = yaw; } - public void update(Float pitch, Float yaw) { + public void update(float pitchDelta, float yawDelta) { if(isParent() && !ignoreFirstUpdate()) { addSubtick(clone()); } - this.pitch = pitch; - this.yaw = yaw; + this.pitch += pitchDelta; + this.yaw += yawDelta; + } + + public void getStates(List reference) { + if (isParent()) { + reference.addAll(subtickList); + reference.add(this); + } + } + + public VirtualCameraAngleEvent getCollected(VirtualCameraAngle nextCameraAngle) { + float pitchDelta = pitch; + float yawDelta = yaw; + for(VirtualCameraAngle subtick : nextCameraAngle.getAll()) { + pitchDelta+=subtick.pitch; + yawDelta+=subtick.yaw; + } + return new VirtualCameraAngleEvent(pitchDelta, yawDelta); } public void copyFrom(VirtualCameraAngle camera) { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index bdb0d7b8..08047474 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -1,20 +1,26 @@ package com.minecrafttas.tasmod.virtual; +import java.util.ArrayList; +import java.util.List; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; -import com.minecrafttas.tasmod.virtual.event.VirtualKeyboardEvent; -import com.minecrafttas.tasmod.virtual.event.VirtualMouseEvent; +import org.apache.commons.lang3.tuple.Triple; import org.apache.logging.log4j.Logger; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.minecrafttas.tasmod.mixin.playbackhooks.MixinMinecraft; import com.minecrafttas.tasmod.util.Ducks; import com.minecrafttas.tasmod.util.LoggerMarkers; import com.minecrafttas.tasmod.util.PointerNormalizer; +import com.minecrafttas.tasmod.virtual.event.VirtualCameraAngleEvent; +import com.minecrafttas.tasmod.virtual.event.VirtualKeyboardEvent; +import com.minecrafttas.tasmod.virtual.event.VirtualMouseEvent; import net.minecraft.client.gui.GuiScreen; +import net.minecraft.util.math.MathHelper; /** * Main component for redirecting inputs.
@@ -469,7 +475,10 @@ public boolean willKeyBeDown(int keycode) { public class VirtualCameraAngleInput { private final VirtualCameraAngle currentCameraAngle; private final VirtualCameraAngle nextCameraAngle = new VirtualCameraAngle(); - + private final List cameraAngleInterpolationStates = new ArrayList<>(); + private float currentPitchDelta = 0f; + private float currentYawDelta = 0f; + public VirtualCameraAngleInput(VirtualCameraAngle preloadedCamera) { currentCameraAngle = preloadedCamera; } @@ -479,15 +488,49 @@ public void updateNextCameraAngle(float pitch, float yaw) { } public void nextCameraTick() { + nextCameraAngle.getStates(cameraAngleInterpolationStates); + VirtualCameraAngleEvent event = currentCameraAngle.getCollected(nextCameraAngle); + currentPitchDelta = event.getDeltaPitch(); + currentYawDelta = event.getDeltaYaw(); currentCameraAngle.copyFrom(nextCameraAngle); } public float getCurrentPitch() { - return currentCameraAngle.getPitch(); + float out = currentPitchDelta; + if(currentPitchDelta != 0f) { + currentPitchDelta = 0f; + } + return out; } public float getCurrentYaw() { - return currentCameraAngle.getYaw(); + float out = currentYawDelta; + if(currentYawDelta != 0f) { + currentYawDelta = 0f; + } + return out; + } + + public Triple getInterpolatedState(float partialTick, float pitch, float yaw, boolean enable){ + if(!enable) { + return Triple.of(pitch, yaw, 0f); + } + + float interpolatedPitch = 0f; + float interpolatedYaw = 0f; + + if(cameraAngleInterpolationStates.size()==1) { // If no interpolation data was specified, interpolate over 2 values + interpolatedPitch = (float) MathHelper.clampedLerp(currentCameraAngle.getPitch(), cameraAngleInterpolationStates.get(0).getPitch(), partialTick); + interpolatedYaw = (float) MathHelper.clampedLerp(currentCameraAngle.getYaw(), cameraAngleInterpolationStates.get(0).getYaw() + 180, partialTick); + } else { + + int index = (int)MathHelper.clampedLerp(0, cameraAngleInterpolationStates.size(), partialTick); // Get interpolate index + + interpolatedPitch = cameraAngleInterpolationStates.get(index).getPitch(); + interpolatedYaw = cameraAngleInterpolationStates.get(index).getYaw(); + } + + return Triple.of(interpolatedPitch, interpolatedYaw, 0f); } } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualCameraAngleEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualCameraAngleEvent.java new file mode 100644 index 00000000..21e85aa4 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualCameraAngleEvent.java @@ -0,0 +1,27 @@ +package com.minecrafttas.tasmod.virtual.event; + +public class VirtualCameraAngleEvent extends VirtualEvent { + private float pitchDelta; + private float yawDelta; + + public VirtualCameraAngleEvent(float pitchDelta, float yawDelta) { + this.pitchDelta = pitchDelta; + this.yawDelta = yawDelta; + } + + public float getDeltaPitch() { + return pitchDelta; + } + + public float getDeltaYaw() { + return yawDelta; + } + + @Override + public boolean equals(Object obj) { + if(obj instanceof VirtualCameraAngleEvent) { + return ((VirtualCameraAngleEvent)obj).pitchDelta == pitchDelta && ((VirtualCameraAngleEvent)obj).yawDelta == yawDelta; + } + return super.equals(obj); + } +} diff --git a/src/test/java/tasmod/virtual/VirtualInputTest.java b/src/test/java/tasmod/virtual/VirtualInputTest.java index 98e805be..784f01c8 100644 --- a/src/test/java/tasmod/virtual/VirtualInputTest.java +++ b/src/test/java/tasmod/virtual/VirtualInputTest.java @@ -35,10 +35,11 @@ void testConstructor() { void testPreloadedConstructor() { VirtualKeyboard preloadedKeyboard = new VirtualKeyboard(); VirtualMouse preloadedMouse = new VirtualMouse(); - VirtualCameraAngle preloadedCameraAngle = new VirtualCameraAngle(1f, 2f); + VirtualCameraAngle preloadedCameraAngle = new VirtualCameraAngle(); preloadedKeyboard.update(VirtualKey.W.getKeycode(), true, 'w'); preloadedMouse.update(VirtualKey.LC.getKeycode(), true, 15, 0, 0); + preloadedCameraAngle.update(1, 2); VirtualInput virtual = new VirtualInput(LOGGER, preloadedKeyboard, preloadedMouse, preloadedCameraAngle); @@ -51,6 +52,7 @@ void testPreloadedConstructor() { assertTrue(virtual.MOUSE.nextMouseSubtick()); assertEquals(VirtualKey.LC.getKeycode(), virtual.MOUSE.getEventMouseKey()); + virtual.CAMERA_ANGLE.nextCameraTick(); assertEquals(1f, virtual.CAMERA_ANGLE.getCurrentPitch()); assertEquals(2f, virtual.CAMERA_ANGLE.getCurrentYaw()); } From 7506fe1ecf45d527efbe6202beb0cddc792abdd6 Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 10 Feb 2024 18:15:32 +0100 Subject: [PATCH 40/57] [VirtualInput] Fixed camera spinning uncontrollably --- .../com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java | 2 ++ src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java | 1 + src/main/resources/mctcommon.mixin.json | 1 - 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java index ab620a7a..8247b092 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java @@ -59,6 +59,8 @@ public void copyFrom(VirtualCameraAngle camera) { this.subtickList.clear(); this.subtickList.addAll(camera.subtickList); camera.subtickList.clear(); + camera.pitch = 0f; + camera.yaw = 0f; camera.resetFirstUpdate(); } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index 08047474..5ab072cd 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -484,6 +484,7 @@ public VirtualCameraAngleInput(VirtualCameraAngle preloadedCamera) { } public void updateNextCameraAngle(float pitch, float yaw) { + LOGGER.debug("Pitch: {}, Yaw: {}", pitch, yaw); nextCameraAngle.update(pitch, yaw); } diff --git a/src/main/resources/mctcommon.mixin.json b/src/main/resources/mctcommon.mixin.json index 40ea9253..ef08c74d 100644 --- a/src/main/resources/mctcommon.mixin.json +++ b/src/main/resources/mctcommon.mixin.json @@ -12,7 +12,6 @@ "MixinMinecraft", "MixinNetHandlerPlayClient", "MixinWorldClient", - "MixinEntityRenderer", "MixinLocale" ] } \ No newline at end of file From 672ade95838483be3ca7dd65be98d22db5fc28ca Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 12 Feb 2024 22:17:28 +0100 Subject: [PATCH 41/57] [VirtualInput] Switched to absolute camera angle coordinates --- .../playbackhooks/MixinEntityRenderer.java | 18 ++++++++-------- .../tasmod/virtual/VirtualCameraAngle.java | 18 +++------------- .../tasmod/virtual/VirtualInput.java | 21 ++++--------------- .../java/tasmod/virtual/VirtualInputTest.java | 1 + 4 files changed, 17 insertions(+), 41 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java index 3ec73e53..d47e5115 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java @@ -4,9 +4,10 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyArg; -import org.spongepowered.asm.mixin.injection.ModifyArgs; -import org.spongepowered.asm.mixin.injection.invoke.arg.Args; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.llamalad7.mixinextras.sugar.Share; import com.llamalad7.mixinextras.sugar.ref.LocalFloatRef; @@ -29,12 +30,11 @@ public class MixinEntityRenderer implements SubtickDuck { private Minecraft mc; - @ModifyArgs(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;turn(FF)V")) - public void playback_redirectCamera(Args args) { - TASmodClient.virtual.CAMERA_ANGLE.updateNextCameraAngle(args.get(0), args.get(1)); - - args.set(0, TASmodClient.virtual.CAMERA_ANGLE.getCurrentPitch()); - args.set(1, TASmodClient.virtual.CAMERA_ANGLE.getCurrentYaw()); + @Inject(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;turn(FF)V", shift = Shift.AFTER)) + public void playback_injectAfterTurn(CallbackInfo ci) { + TASmodClient.virtual.CAMERA_ANGLE.updateNextCameraAngle(mc.player.rotationPitch, mc.player.rotationYaw); + mc.player.rotationPitch = TASmodClient.virtual.CAMERA_ANGLE.getCurrentPitch(); + mc.player.rotationYaw = TASmodClient.virtual.CAMERA_ANGLE.getCurrentYaw(); } @Override @@ -59,7 +59,7 @@ public float redirect_orientCameraYaw(float yaw, @Share("pitch") LocalFloatRef s } private float redirectCam(float yaw, float pitch) { - Triple interpolated = TASmodClient.virtual.CAMERA_ANGLE.getInterpolatedState(pitch, pitch, yaw, TASmodClient.controller.isPlayingback()); + Triple interpolated = TASmodClient.virtual.CAMERA_ANGLE.getInterpolatedState(Minecraft.getMinecraft().timer.renderPartialTicks, pitch, yaw, TASmodClient.controller.isPlayingback()); GlStateManager.rotate(interpolated.getLeft(), 1.0f, 0.0f, 0.0f); GlStateManager.rotate(interpolated.getRight(), 0.0f, 0.0f, 1.0f); return interpolated.getMiddle(); diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java index 8247b092..b51b30be 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java @@ -28,12 +28,12 @@ public VirtualCameraAngle(float pitch, float yaw, List subti this.yaw = yaw; } - public void update(float pitchDelta, float yawDelta) { + public void update(float pitch, float yaw) { if(isParent() && !ignoreFirstUpdate()) { addSubtick(clone()); } - this.pitch += pitchDelta; - this.yaw += yawDelta; + this.pitch = pitch; + this.yaw = yaw; } public void getStates(List reference) { @@ -43,24 +43,12 @@ public void getStates(List reference) { } } - public VirtualCameraAngleEvent getCollected(VirtualCameraAngle nextCameraAngle) { - float pitchDelta = pitch; - float yawDelta = yaw; - for(VirtualCameraAngle subtick : nextCameraAngle.getAll()) { - pitchDelta+=subtick.pitch; - yawDelta+=subtick.yaw; - } - return new VirtualCameraAngleEvent(pitchDelta, yawDelta); - } - public void copyFrom(VirtualCameraAngle camera) { this.pitch = camera.pitch; this.yaw = camera.yaw; this.subtickList.clear(); this.subtickList.addAll(camera.subtickList); camera.subtickList.clear(); - camera.pitch = 0f; - camera.yaw = 0f; camera.resetFirstUpdate(); } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index 5ab072cd..1d75e7f2 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -476,45 +476,32 @@ public class VirtualCameraAngleInput { private final VirtualCameraAngle currentCameraAngle; private final VirtualCameraAngle nextCameraAngle = new VirtualCameraAngle(); private final List cameraAngleInterpolationStates = new ArrayList<>(); - private float currentPitchDelta = 0f; - private float currentYawDelta = 0f; public VirtualCameraAngleInput(VirtualCameraAngle preloadedCamera) { currentCameraAngle = preloadedCamera; } public void updateNextCameraAngle(float pitch, float yaw) { - LOGGER.debug("Pitch: {}, Yaw: {}", pitch, yaw); +// LOGGER.debug("Pitch: {}, Yaw: {}", pitch, yaw); nextCameraAngle.update(pitch, yaw); } public void nextCameraTick() { nextCameraAngle.getStates(cameraAngleInterpolationStates); - VirtualCameraAngleEvent event = currentCameraAngle.getCollected(nextCameraAngle); - currentPitchDelta = event.getDeltaPitch(); - currentYawDelta = event.getDeltaYaw(); currentCameraAngle.copyFrom(nextCameraAngle); } public float getCurrentPitch() { - float out = currentPitchDelta; - if(currentPitchDelta != 0f) { - currentPitchDelta = 0f; - } - return out; + return currentCameraAngle.getPitch(); } public float getCurrentYaw() { - float out = currentYawDelta; - if(currentYawDelta != 0f) { - currentYawDelta = 0f; - } - return out; + return currentCameraAngle.getYaw(); } public Triple getInterpolatedState(float partialTick, float pitch, float yaw, boolean enable){ if(!enable) { - return Triple.of(pitch, yaw, 0f); + return Triple.of(nextCameraAngle.getPitch(), nextCameraAngle.getYaw()+180, 0f); } float interpolatedPitch = 0f; diff --git a/src/test/java/tasmod/virtual/VirtualInputTest.java b/src/test/java/tasmod/virtual/VirtualInputTest.java index 784f01c8..b0acada1 100644 --- a/src/test/java/tasmod/virtual/VirtualInputTest.java +++ b/src/test/java/tasmod/virtual/VirtualInputTest.java @@ -8,6 +8,7 @@ import com.minecrafttas.tasmod.virtual.*; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import com.minecrafttas.tasmod.virtual.VirtualInput; From 7c58daf1682db8ece93b2a8db9da7867a8200225 Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 13 Feb 2024 13:36:03 +0100 Subject: [PATCH 42/57] [MCTCommon/Keybinds] Fixed default isKeyDown not being called --- .../com/minecrafttas/mctcommon/KeybindManager.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/minecrafttas/mctcommon/KeybindManager.java b/src/main/java/com/minecrafttas/mctcommon/KeybindManager.java index 6bd55289..d1d70caa 100644 --- a/src/main/java/com/minecrafttas/mctcommon/KeybindManager.java +++ b/src/main/java/com/minecrafttas/mctcommon/KeybindManager.java @@ -75,13 +75,13 @@ public KeybindManager(IsKeyDownFunc defaultFunction) { */ @Override public void onRunClientGameLoop(Minecraft mc) { - for (Keybind keybind : this.keybindings) - if (keybind.isKeyDownFunc == null) { - defaultFunction.isKeyDown(keybind.keyBinding); - } else { - if (keybind.isKeyDownFunc.isKeyDown(keybind.keyBinding)) - keybind.onKeyDown.run(); + for (Keybind keybind : this.keybindings){ + IsKeyDownFunc keyDown = keybind.isKeyDownFunc != null ? keybind.isKeyDownFunc : defaultFunction; + if(keyDown.isKeyDown(keybind.keyBinding)){ + keybind.onKeyDown.run(); } + } + } /** From 780274f453249f12d83e00d3a1e8f0a9119a0fb2 Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 13 Feb 2024 13:52:28 +0100 Subject: [PATCH 43/57] [Gui] Fixed "facing" in InfoHud --- src/main/java/com/minecrafttas/tasmod/TASmod.java | 2 +- src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java | 2 +- .../com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java | 3 --- .../java/com/minecrafttas/tasmod/virtual/VirtualInput.java | 5 +++-- src/test/java/tasmod/virtual/VirtualInputTest.java | 3 +-- 5 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/TASmod.java b/src/main/java/com/minecrafttas/tasmod/TASmod.java index db32c6a7..9e94df5f 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmod.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmod.java @@ -121,7 +121,7 @@ public void onServerInit(MinecraftServer server) { // Save Loadstate Count File savestateDirectory = new File(server.getDataDirectory() + File.separator + "saves" + File.separator + "savestates" + File.separator); try { - new SavestateTrackerFile(new File(savestateDirectory, server.getFolderName() + "-info.txt")); + new SavestateTrackerFile(new File(savestateDirectory, server.getFolderName() + "-info.txt")); // TODO Ew, remove } catch (IOException e) { e.printStackTrace(); } diff --git a/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java b/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java index ae30b176..2296e035 100644 --- a/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java +++ b/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java @@ -289,7 +289,7 @@ public boolean checkInit() { if (configuration.getProperty(title + "_x", "err").equals("err")) setDefaults(title, y); lists.add(new InfoLabel(title, Integer.parseInt(configuration.getProperty(title + "_x")), Integer.parseInt(configuration.getProperty(title + "_y")), Boolean.parseBoolean(configuration.getProperty(title + "_visible")), Boolean.parseBoolean(configuration.getProperty(title + "_rect")), () -> { if (Minecraft.getMinecraft().currentScreen == this) return "Facing"; - return String.format("%.2f %.2f", InterpolationHandler.rotationYaw, InterpolationHandler.rotationPitch); + return String.format("%.2f %.2f", Minecraft.getMinecraft().player.rotationPitch, Minecraft.getMinecraft().player.rotationYaw); })); title = "cticks"; diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java index b51b30be..c2096082 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java @@ -4,8 +4,6 @@ import java.util.ArrayList; import java.util.List; -import com.minecrafttas.tasmod.virtual.event.VirtualCameraAngleEvent; - public class VirtualCameraAngle extends Subtickable implements Serializable { private float pitch; private float yaw; @@ -49,7 +47,6 @@ public void copyFrom(VirtualCameraAngle camera) { this.subtickList.clear(); this.subtickList.addAll(camera.subtickList); camera.subtickList.clear(); - camera.resetFirstUpdate(); } @Override diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index 1d75e7f2..8e53e075 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -384,8 +384,9 @@ public VirtualMouseInput(VirtualMouse preloadedMouse) { * @see VirtualInput#update(GuiScreen) * @param keycode The keycode of this event * @param keystate The keystate of this event - * @param character The character of this event - * @param repeatEventsEnabled If repeat events are enabled + * @param scrollwheel The scrollWheel of this event + * @param cursorX The x coordinate of the cursor of this event + * @param cursorY The y coordinate of the cursot of this event */ public void updateNextMouse(int keycode, boolean keystate, int scrollwheel, int cursorX, int cursorY) { keycode-=100; diff --git a/src/test/java/tasmod/virtual/VirtualInputTest.java b/src/test/java/tasmod/virtual/VirtualInputTest.java index b0acada1..db451a25 100644 --- a/src/test/java/tasmod/virtual/VirtualInputTest.java +++ b/src/test/java/tasmod/virtual/VirtualInputTest.java @@ -40,7 +40,7 @@ void testPreloadedConstructor() { preloadedKeyboard.update(VirtualKey.W.getKeycode(), true, 'w'); preloadedMouse.update(VirtualKey.LC.getKeycode(), true, 15, 0, 0); - preloadedCameraAngle.update(1, 2); + preloadedCameraAngle.update(1f, 2f); VirtualInput virtual = new VirtualInput(LOGGER, preloadedKeyboard, preloadedMouse, preloadedCameraAngle); @@ -53,7 +53,6 @@ void testPreloadedConstructor() { assertTrue(virtual.MOUSE.nextMouseSubtick()); assertEquals(VirtualKey.LC.getKeycode(), virtual.MOUSE.getEventMouseKey()); - virtual.CAMERA_ANGLE.nextCameraTick(); assertEquals(1f, virtual.CAMERA_ANGLE.getCurrentPitch()); assertEquals(2f, virtual.CAMERA_ANGLE.getCurrentYaw()); } From 4371a783978a89a69ea428e6d8e52a08260b134b Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 13 Feb 2024 22:25:06 +0100 Subject: [PATCH 44/57] [VirtualInput] Added calculations for pitch and yaw --- .../playbackhooks/MixinEntityRenderer.java | 28 +++++++++++++------ .../tasmod/virtual/VirtualInput.java | 2 +- .../java/tasmod/virtual/VirtualInputTest.java | 1 - 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java index d47e5115..a3b08c70 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java @@ -4,10 +4,9 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.At.Shift; -import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyArg; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.ModifyArgs; +import org.spongepowered.asm.mixin.injection.invoke.arg.Args; import com.llamalad7.mixinextras.sugar.Share; import com.llamalad7.mixinextras.sugar.ref.LocalFloatRef; @@ -18,6 +17,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.EntityRenderer; import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.util.math.MathHelper; /** * Redirects the camera to use {@link VirtualInput.VirtualCameraAngleInput}.
@@ -30,11 +30,23 @@ public class MixinEntityRenderer implements SubtickDuck { private Minecraft mc; - @Inject(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;turn(FF)V", shift = Shift.AFTER)) - public void playback_injectAfterTurn(CallbackInfo ci) { - TASmodClient.virtual.CAMERA_ANGLE.updateNextCameraAngle(mc.player.rotationPitch, mc.player.rotationYaw); - mc.player.rotationPitch = TASmodClient.virtual.CAMERA_ANGLE.getCurrentPitch(); - mc.player.rotationYaw = TASmodClient.virtual.CAMERA_ANGLE.getCurrentYaw(); + @ModifyArgs(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;turn(FF)V")) + public void playback_injectAfterTurn(Args arguments) { + double pitchDelta = (double)(float) arguments.get(1); + double yawDelta = (double)(float) arguments.get(0); + + pitchDelta *=0.15D; + yawDelta *= 0.15D; + + float pitch = (float) ((double)mc.player.rotationPitch - pitchDelta); + pitch = MathHelper.clamp(pitch, -90.0F, 90.0F); + + float yaw = (float) ((double)mc.player.rotationYaw + yawDelta); + + TASmodClient.virtual.CAMERA_ANGLE.updateNextCameraAngle(pitch, yaw); + + arguments.set(0, 0f); + arguments.set(1, 0f); } @Override diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index 8e53e075..5bb6ab70 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -502,7 +502,7 @@ public float getCurrentYaw() { public Triple getInterpolatedState(float partialTick, float pitch, float yaw, boolean enable){ if(!enable) { - return Triple.of(nextCameraAngle.getPitch(), nextCameraAngle.getYaw()+180, 0f); + return Triple.of(pitch, yaw, 0f); } float interpolatedPitch = 0f; diff --git a/src/test/java/tasmod/virtual/VirtualInputTest.java b/src/test/java/tasmod/virtual/VirtualInputTest.java index db451a25..bf184b57 100644 --- a/src/test/java/tasmod/virtual/VirtualInputTest.java +++ b/src/test/java/tasmod/virtual/VirtualInputTest.java @@ -8,7 +8,6 @@ import com.minecrafttas.tasmod.virtual.*; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import com.minecrafttas.tasmod.virtual.VirtualInput; From 6da375496525018675b9d3156399fdb37a2331c8 Mon Sep 17 00:00:00 2001 From: Scribble Date: Wed, 14 Feb 2024 09:52:16 +0100 Subject: [PATCH 45/57] [VirtualInput] Test change to fix interpolation --- .../tasmod/mixin/MixinMinecraft.java | 2 +- .../playbackhooks/MixinEntityRenderer.java | 118 ++++++++++++------ .../com/minecrafttas/tasmod/util/Ducks.java | 2 +- .../tasmod/virtual/VirtualInput.java | 3 +- 4 files changed, 86 insertions(+), 39 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java index ff7fad02..d6acae24 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java @@ -49,7 +49,7 @@ public void injectRunGameLoop(CallbackInfo ci) { @Redirect(method = "runGameLoop", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;runTick()V")) public void redirectRunTick(Minecraft mc) { if (TASmodClient.tickratechanger.ticksPerSecond != 0) { - ((SubtickDuck) this.entityRenderer).runUpdate(); + ((SubtickDuck) this.entityRenderer).runUpdate(this.isGamePaused ? this.renderPartialTicksPaused : this.timer.renderPartialTicks); } this.runTick(); TASmodClient.tickSchedulerClient.runAllTasks(); diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java index a3b08c70..f5277eb3 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java @@ -1,23 +1,21 @@ package com.minecrafttas.tasmod.mixin.playbackhooks; -import org.apache.commons.lang3.tuple.Triple; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyArg; -import org.spongepowered.asm.mixin.injection.ModifyArgs; -import org.spongepowered.asm.mixin.injection.invoke.arg.Args; - import com.llamalad7.mixinextras.sugar.Share; import com.llamalad7.mixinextras.sugar.ref.LocalFloatRef; import com.minecrafttas.tasmod.TASmodClient; import com.minecrafttas.tasmod.util.Ducks.SubtickDuck; import com.minecrafttas.tasmod.virtual.VirtualInput; - import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.renderer.EntityRenderer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.util.math.MathHelper; +import org.apache.commons.lang3.tuple.Triple; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.Redirect; /** * Redirects the camera to use {@link VirtualInput.VirtualCameraAngleInput}.
@@ -26,38 +24,86 @@ @Mixin(EntityRenderer.class) public class MixinEntityRenderer implements SubtickDuck { - @Shadow - private Minecraft mc; + @Shadow + private Minecraft mc; +// @Shadow +// private float smoothCamYaw; +// @Shadow +// private float smoothCamPitch; +// @Shadow +// private float smoothCamPartialTicks; +// @Shadow +// private float smoothCamFilterX; +// @Shadow +// private float smoothCamFilterY; - - @ModifyArgs(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;turn(FF)V")) - public void playback_injectAfterTurn(Args arguments) { - double pitchDelta = (double)(float) arguments.get(1); - double yawDelta = (double)(float) arguments.get(0); - - pitchDelta *=0.15D; - yawDelta *= 0.15D; - - float pitch = (float) ((double)mc.player.rotationPitch - pitchDelta); - pitch = MathHelper.clamp(pitch, -90.0F, 90.0F); - - float yaw = (float) ((double)mc.player.rotationYaw + yawDelta); - - TASmodClient.virtual.CAMERA_ANGLE.updateNextCameraAngle(pitch, yaw); - - arguments.set(0, 0f); - arguments.set(1, 0f); - } - - @Override - public void runUpdate() { - TASmodClient.virtual.CAMERA_ANGLE.nextCameraTick(); - } + @Redirect(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;turn(FF)V")) + public void playback_injectAfterTurn(EntityPlayerSP player, float originalYawDelta, float originalPitchDelta) { + updateNextCameraAngle(player, originalYawDelta, originalPitchDelta); + } + + private void updateNextCameraAngle(EntityPlayerSP player, float originalYawDelta, float originalPitchDelta) { + double pitchDelta = originalPitchDelta; + double yawDelta = originalYawDelta; + + pitchDelta *=0.15D; + yawDelta *= 0.15D; + + float pitch = (float) ((double) player.rotationPitch - pitchDelta); + pitch = MathHelper.clamp(pitch, -90.0F, 90.0F); + + float yaw = (float) ((double) player.rotationYaw + yawDelta); + + TASmodClient.virtual.CAMERA_ANGLE.updateNextCameraAngle(pitch, yaw); + } + + @Override + public void runUpdate(float partialTicks) { +// boolean flag = Display.isActive(); +// if (mc.inGameHasFocus && flag) { +// mc.getTutorial().handleMouse(mc.mouseHelper); +// this.mc.mouseHelper.mouseXYChange(); +// float f = mc.gameSettings.mouseSensitivity * 0.6F + 0.2F; +// float f1 = f * f * f * 8.0F; +// float f2 = (float) this.mc.mouseHelper.deltaX * f1; +// float f3 = (float) this.mc.mouseHelper.deltaY * f1; +// int i = 1; +// +// if (mc.gameSettings.invertMouse) { +// i = -1; +// } +// +// if (mc.gameSettings.smoothCamera) { +// smoothCamYaw += f2; +// smoothCamPitch += f3; +// float f4 = partialTicks - smoothCamPartialTicks; +// smoothCamPartialTicks = partialTicks; +// f2 = smoothCamFilterX * f4; +// f3 = smoothCamFilterY * f4; +// updateNextCameraAngle(mc.player, f2, f3 * (float) i); +// } else { +// smoothCamYaw = 0.0F; +// smoothCamPitch = 0.0F; +// updateNextCameraAngle(mc.player, f2, f3 * (float) i); +// } + if(mc.player == null){ + return; + } + float prevPitch = mc.player.rotationPitch; + float prevYaw = mc.player.rotationYaw; + TASmodClient.virtual.CAMERA_ANGLE.nextCameraTick(); + mc.player.rotationPitch = TASmodClient.virtual.CAMERA_ANGLE.getCurrentPitch(); + mc.player.rotationYaw = TASmodClient.virtual.CAMERA_ANGLE.getCurrentYaw(); + + mc.player.prevRotationPitch = prevPitch; + mc.player.prevRotationYaw = prevYaw; +// } + } @ModifyArg(method = "orientCamera", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;rotate(FFFF)V", ordinal = 8), index = 0) public float redirect_orientCameraPitch(float pitch, @Share("pitch") LocalFloatRef sharedPitch) { sharedPitch.set(pitch); - return 0; + return 0f; } @ModifyArg(method = "orientCamera", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;rotate(FFFF)V", ordinal = 9), index = 0) diff --git a/src/main/java/com/minecrafttas/tasmod/util/Ducks.java b/src/main/java/com/minecrafttas/tasmod/util/Ducks.java index 948f3f14..5b785a6a 100644 --- a/src/main/java/com/minecrafttas/tasmod/util/Ducks.java +++ b/src/main/java/com/minecrafttas/tasmod/util/Ducks.java @@ -81,7 +81,7 @@ public static interface GuiScreenDuck { * Quacks the subtick */ public static interface SubtickDuck { - void runUpdate(); + void runUpdate(float partialTicks); } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index 5bb6ab70..7ed018c0 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -5,6 +5,7 @@ import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; +import com.minecrafttas.tasmod.TASmodClient; import org.apache.commons.lang3.tuple.Triple; import org.apache.logging.log4j.Logger; import org.lwjgl.input.Keyboard; @@ -502,7 +503,7 @@ public float getCurrentYaw() { public Triple getInterpolatedState(float partialTick, float pitch, float yaw, boolean enable){ if(!enable) { - return Triple.of(pitch, yaw, 0f); + return Triple.of(TASmodClient.virtual.CAMERA_ANGLE.nextCameraAngle.getPitch(), TASmodClient.virtual.CAMERA_ANGLE.nextCameraAngle.getYaw()+180, 0f); } float interpolatedPitch = 0f; From 51c32334412f07d25787fb34e872d6ce8a0ad18b Mon Sep 17 00:00:00 2001 From: Scribble Date: Thu, 15 Feb 2024 15:00:45 +0100 Subject: [PATCH 46/57] [VirtualInput] Fixing camera subticks --- .../playbackhooks/MixinEntityRenderer.java | 82 +++++++------------ .../tasmod/virtual/VirtualCameraAngle.java | 7 +- 2 files changed, 33 insertions(+), 56 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java index f5277eb3..ee4263b0 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java @@ -14,8 +14,10 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; /** * Redirects the camera to use {@link VirtualInput.VirtualCameraAngleInput}.
@@ -26,66 +28,39 @@ public class MixinEntityRenderer implements SubtickDuck { @Shadow private Minecraft mc; -// @Shadow -// private float smoothCamYaw; -// @Shadow -// private float smoothCamPitch; -// @Shadow -// private float smoothCamPartialTicks; -// @Shadow -// private float smoothCamFilterX; -// @Shadow -// private float smoothCamFilterY; - - @Redirect(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;turn(FF)V")) - public void playback_injectAfterTurn(EntityPlayerSP player, float originalYawDelta, float originalPitchDelta) { - updateNextCameraAngle(player, originalYawDelta, originalPitchDelta); - } - - private void updateNextCameraAngle(EntityPlayerSP player, float originalYawDelta, float originalPitchDelta) { - double pitchDelta = originalPitchDelta; - double yawDelta = originalYawDelta; - - pitchDelta *=0.15D; - yawDelta *= 0.15D; + @Shadow + private float smoothCamYaw; + @Shadow + private float smoothCamPitch; + @Shadow + private float smoothCamPartialTicks; + @Shadow + private float smoothCamFilterX; + @Shadow + private float smoothCamFilterY; - float pitch = (float) ((double) player.rotationPitch - pitchDelta); - pitch = MathHelper.clamp(pitch, -90.0F, 90.0F); + @Inject(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/profiler/Profiler;startSection(Ljava/lang/String;)V", ordinal = 0, shift = At.Shift.AFTER)) + public void playback_injectAtStartSection(float partialTicks, long nanoTime, CallbackInfo ci) { + // Calculate sensitivity + float f = this.mc.gameSettings.mouseSensitivity * 0.6F + 0.2F; + float f1 = f * f * f * 8.0F; - float yaw = (float) ((double) player.rotationYaw + yawDelta); + if (this.mc.currentScreen == null) { // No Gui + mc.mouseHelper.mouseXYChange(); + mc.getTutorial().handleMouse(mc.mouseHelper); + TASmodClient.virtual.CAMERA_ANGLE.updateNextCameraAngle((float) -(mc.mouseHelper.deltaY * f1 * 0.15D), (float) (mc.mouseHelper.deltaX * f1 * 0.15D)); + } + } - TASmodClient.virtual.CAMERA_ANGLE.updateNextCameraAngle(pitch, yaw); + @Redirect(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/EntityPlayerSP;turn(FF)V")) + public void playback_stopVanilla(EntityPlayerSP player, float deltaYaw, float deltaPitch){ + if(TASmodClient.tickratechanger.ticksPerSecond == 0){ + player.turn(deltaYaw, deltaPitch); + } } @Override public void runUpdate(float partialTicks) { -// boolean flag = Display.isActive(); -// if (mc.inGameHasFocus && flag) { -// mc.getTutorial().handleMouse(mc.mouseHelper); -// this.mc.mouseHelper.mouseXYChange(); -// float f = mc.gameSettings.mouseSensitivity * 0.6F + 0.2F; -// float f1 = f * f * f * 8.0F; -// float f2 = (float) this.mc.mouseHelper.deltaX * f1; -// float f3 = (float) this.mc.mouseHelper.deltaY * f1; -// int i = 1; -// -// if (mc.gameSettings.invertMouse) { -// i = -1; -// } -// -// if (mc.gameSettings.smoothCamera) { -// smoothCamYaw += f2; -// smoothCamPitch += f3; -// float f4 = partialTicks - smoothCamPartialTicks; -// smoothCamPartialTicks = partialTicks; -// f2 = smoothCamFilterX * f4; -// f3 = smoothCamFilterY * f4; -// updateNextCameraAngle(mc.player, f2, f3 * (float) i); -// } else { -// smoothCamYaw = 0.0F; -// smoothCamPitch = 0.0F; -// updateNextCameraAngle(mc.player, f2, f3 * (float) i); -// } if(mc.player == null){ return; } @@ -97,7 +72,6 @@ public void runUpdate(float partialTicks) { mc.player.prevRotationPitch = prevPitch; mc.player.prevRotationYaw = prevYaw; -// } } @ModifyArg(method = "orientCamera", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;rotate(FFFF)V", ordinal = 8), index = 0) diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java index c2096082..2b0677fb 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java @@ -1,5 +1,7 @@ package com.minecrafttas.tasmod.virtual; +import net.minecraft.util.math.MathHelper; + import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -30,8 +32,9 @@ public void update(float pitch, float yaw) { if(isParent() && !ignoreFirstUpdate()) { addSubtick(clone()); } - this.pitch = pitch; - this.yaw = yaw; + this.pitch += pitch; + this.pitch = MathHelper.clamp(this.pitch, -90.0F, 90.0F); + this.yaw += yaw; } public void getStates(List reference) { From e967e87bd7c65596447fe244918f948288bf89d6 Mon Sep 17 00:00:00 2001 From: Scribble Date: Thu, 15 Feb 2024 11:50:19 +0100 Subject: [PATCH 47/57] [VirtualInput] Fixed first leftclick not being recognized after joining a world --- .../com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java b/src/main/java/com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java index 82323cb1..47e983e9 100644 --- a/src/main/java/com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java @@ -62,6 +62,8 @@ public void onDoneLoadingWorld() { if (TASmod.getServerInstance() != null) { // Check if a server is running and if it's an integrated server LOGGER.debug(LoggerMarkers.Event, "Finished loading the world on the client"); loadingScreenDelay = 1; + + TASmodClient.virtual.unpress(); } } From 2e3da8b103338dfd4cab3e5d29b13747262a9f20 Mon Sep 17 00:00:00 2001 From: Scribble Date: Thu, 15 Feb 2024 11:53:35 +0100 Subject: [PATCH 48/57] [Util] Removed ModIncompatibleException - Can now be done via fabric.mod.json --- .../tasmod/util/ModIncompatibleException.java | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 src/main/java/com/minecrafttas/tasmod/util/ModIncompatibleException.java diff --git a/src/main/java/com/minecrafttas/tasmod/util/ModIncompatibleException.java b/src/main/java/com/minecrafttas/tasmod/util/ModIncompatibleException.java deleted file mode 100644 index f85575f0..00000000 --- a/src/main/java/com/minecrafttas/tasmod/util/ModIncompatibleException.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.minecrafttas.tasmod.util; - -public class ModIncompatibleException extends Exception{ - /** - * - */ - private static final long serialVersionUID = 9034388504854258444L; - public ModIncompatibleException() { - } - public ModIncompatibleException(String s) { - super(s); - } -} From 5681cd8ff4ee608849a4c654ba8279190fccce66 Mon Sep 17 00:00:00 2001 From: Scribble Date: Thu, 15 Feb 2024 14:00:44 +0100 Subject: [PATCH 49/57] [VirtualInput] More documentation and tests - [Util] Added documentation - [Util] Refactored PointerNormalizer - [Gui] Disabled trajectories from InfoHud - [VirtualInput] Refactored MixinEntityRenderer - [VirtualInput] Fixed camera angle resetting to 0 on restart --- .../com/minecrafttas/tasmod/gui/InfoHud.java | 24 +-- .../tasmod/handlers/LoadingScreenHandler.java | 2 +- .../playbackhooks/MixinEntityRenderer.java | 42 +++-- .../playback/PlaybackControllerClient.java | 6 +- .../com/minecrafttas/tasmod/util/Ducks.java | 4 + .../minecrafttas/tasmod/util/FileThread.java | 9 +- .../tasmod/util/PointerNormalizer.java | 84 +++++----- .../minecrafttas/tasmod/util/Scheduler.java | 1 - .../tasmod/util/ShieldDownloader.java | 5 + .../tasmod/virtual/VirtualCameraAngle.java | 120 +++++++++++++-- .../tasmod/virtual/VirtualInput.java | 47 ++++-- .../tasmod/virtual/VirtualKeyboard.java | 2 +- .../tasmod/virtual/VirtualMouse.java | 31 ++-- .../virtual/VirtualCameraAngleTest.java | 144 ++++++++++++++++++ .../java/tasmod/virtual/VirtualInputTest.java | 2 +- 15 files changed, 411 insertions(+), 112 deletions(-) create mode 100644 src/test/java/tasmod/virtual/VirtualCameraAngleTest.java diff --git a/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java b/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java index 2296e035..7cc413c3 100644 --- a/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java +++ b/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java @@ -350,18 +350,18 @@ public boolean checkInit() { // return String.format("Mouse Cursor: " + TASmodClient.virtual.getNextMouse().getPath().get(0).cursorX + " " + TASmodClient.virtual.getNextMouse().getPath().get(0).cursorY); // })); TODO Remove? - title = "trajectories"; - y += 14; - if (configuration.getProperty(title + "_x", "err").equals("err")) setDefaults(title, y); - lists.add(new InfoLabel(title, Integer.parseInt(configuration.getProperty(title + "_x")), Integer.parseInt(configuration.getProperty(title + "_y")), Boolean.parseBoolean(configuration.getProperty(title + "_visible")), Boolean.parseBoolean(configuration.getProperty(title + "_rect")), () -> { - if (Minecraft.getMinecraft().currentScreen == this) return "Trajectories"; - String message = "Invalid Item"; - Vec3d vec = TrajectoriesCalculator.calculate(); - if (vec != null) { - message = String.format("%.3f %.3f %.3f", vec.x, vec.y, vec.z); - } - return String.format("Trajectories: " + message); - })); +// title = "trajectories"; +// y += 14; +// if (configuration.getProperty(title + "_x", "err").equals("err")) setDefaults(title, y); +// lists.add(new InfoLabel(title, Integer.parseInt(configuration.getProperty(title + "_x")), Integer.parseInt(configuration.getProperty(title + "_y")), Boolean.parseBoolean(configuration.getProperty(title + "_visible")), Boolean.parseBoolean(configuration.getProperty(title + "_rect")), () -> { +// if (Minecraft.getMinecraft().currentScreen == this) return "Trajectories"; +// String message = "Invalid Item"; +// Vec3d vec = TrajectoriesCalculator.calculate(); +// if (vec != null) { +// message = String.format("%.3f %.3f %.3f", vec.x, vec.y, vec.z); +// } +// return String.format("Trajectories: " + message); +// })); title = "velocity"; y += 14; diff --git a/src/main/java/com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java b/src/main/java/com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java index 47e983e9..92bcb00b 100644 --- a/src/main/java/com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/handlers/LoadingScreenHandler.java @@ -63,7 +63,7 @@ public void onDoneLoadingWorld() { LOGGER.debug(LoggerMarkers.Event, "Finished loading the world on the client"); loadingScreenDelay = 1; - TASmodClient.virtual.unpress(); + TASmodClient.virtual.clear(); } } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java index ee4263b0..7fff25e5 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java @@ -1,27 +1,33 @@ package com.minecrafttas.tasmod.mixin.playbackhooks; +import org.apache.commons.lang3.tuple.Triple; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + import com.llamalad7.mixinextras.sugar.Share; import com.llamalad7.mixinextras.sugar.ref.LocalFloatRef; import com.minecrafttas.tasmod.TASmodClient; import com.minecrafttas.tasmod.util.Ducks.SubtickDuck; import com.minecrafttas.tasmod.virtual.VirtualInput; + import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.renderer.EntityRenderer; import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.util.math.MathHelper; -import org.apache.commons.lang3.tuple.Triple; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyArg; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; /** * Redirects the camera to use {@link VirtualInput.VirtualCameraAngleInput}.
- * Also conforms the camera to 20tps as + * To support handling the camera in TASes and to avoid desyncs via lag,
+ * it was decided to only update the camera every tick.
+ *
+ * To achieve this, some parts of the vanilla code were disabled, but get called every tick in {@link #runUpdate(float)} + * + * @author Scribble, Pancake */ @Mixin(EntityRenderer.class) public class MixinEntityRenderer implements SubtickDuck { @@ -45,7 +51,7 @@ public void playback_injectAtStartSection(float partialTicks, long nanoTime, Cal float f = this.mc.gameSettings.mouseSensitivity * 0.6F + 0.2F; float f1 = f * f * f * 8.0F; - if (this.mc.currentScreen == null) { // No Gui + if (this.mc.currentScreen == null && !TASmodClient.controller.isPlayingback() && mc.player != null) { // No Gui mc.mouseHelper.mouseXYChange(); mc.getTutorial().handleMouse(mc.mouseHelper); TASmodClient.virtual.CAMERA_ANGLE.updateNextCameraAngle((float) -(mc.mouseHelper.deltaY * f1 * 0.15D), (float) (mc.mouseHelper.deltaX * f1 * 0.15D)); @@ -64,11 +70,19 @@ public void runUpdate(float partialTicks) { if(mc.player == null){ return; } + TASmodClient.virtual.CAMERA_ANGLE.nextCameraTick(); + float prevPitch = mc.player.rotationPitch; float prevYaw = mc.player.rotationYaw; - TASmodClient.virtual.CAMERA_ANGLE.nextCameraTick(); - mc.player.rotationPitch = TASmodClient.virtual.CAMERA_ANGLE.getCurrentPitch(); - mc.player.rotationYaw = TASmodClient.virtual.CAMERA_ANGLE.getCurrentYaw(); + Float newPitch = TASmodClient.virtual.CAMERA_ANGLE.getCurrentPitch(); + Float newYaw = TASmodClient.virtual.CAMERA_ANGLE.getCurrentYaw(); + + if(newPitch == null) { + TASmodClient.virtual.CAMERA_ANGLE.setCamera(prevPitch, prevYaw); + return; + } + mc.player.rotationPitch = newPitch; + mc.player.rotationYaw = newYaw; mc.player.prevRotationPitch = prevPitch; mc.player.prevRotationYaw = prevYaw; diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index b734f08f..64247e25 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -232,7 +232,7 @@ public String setTASStateClient(TASstate stateIn, boolean verbose) { return verbose ? TextFormatting.GREEN + "Pausing a recording" : ""; case NONE: LOGGER.debug(LoggerMarkers.Playback, "Stopping a recording"); - TASmodClient.virtual.unpress(); + TASmodClient.virtual.clear(); state = TASstate.NONE; return verbose ? TextFormatting.GREEN + "Stopping the recording" : ""; } @@ -246,12 +246,12 @@ public String setTASStateClient(TASstate stateIn, boolean verbose) { LOGGER.debug(LoggerMarkers.Playback, "Pausing a playback"); state = TASstate.PAUSED; tempPause = TASstate.PLAYBACK; - TASmodClient.virtual.unpress(); + TASmodClient.virtual.clear(); return verbose ? TextFormatting.GREEN + "Pausing a playback" : ""; case NONE: LOGGER.debug(LoggerMarkers.Playback, "Stopping a playback"); Minecraft.getMinecraft().gameSettings.chatLinks = true; - TASmodClient.virtual.unpress(); + TASmodClient.virtual.clear(); state = TASstate.NONE; return verbose ? TextFormatting.GREEN + "Stopping the playback" : ""; } diff --git a/src/main/java/com/minecrafttas/tasmod/util/Ducks.java b/src/main/java/com/minecrafttas/tasmod/util/Ducks.java index 5b785a6a..533affea 100644 --- a/src/main/java/com/minecrafttas/tasmod/util/Ducks.java +++ b/src/main/java/com/minecrafttas/tasmod/util/Ducks.java @@ -81,6 +81,10 @@ public static interface GuiScreenDuck { * Quacks the subtick */ public static interface SubtickDuck { + /** + * Custom updating method for EntityRenderer, updating the player rotation + * @param partialTicks The partial ticks from the vanilla Minecraft timer + */ void runUpdate(float partialTicks); } diff --git a/src/main/java/com/minecrafttas/tasmod/util/FileThread.java b/src/main/java/com/minecrafttas/tasmod/util/FileThread.java index cdf61425..759c5af1 100644 --- a/src/main/java/com/minecrafttas/tasmod/util/FileThread.java +++ b/src/main/java/com/minecrafttas/tasmod/util/FileThread.java @@ -9,12 +9,17 @@ import java.util.ArrayList; import java.util.List; +/** + * Thread for writing files to disc + * + * @author Pancake + */ public class FileThread extends Thread { - private PrintWriter stream; + private final PrintWriter stream; private boolean end = false; - private List output = new ArrayList(); + private final List output = new ArrayList<>(); public FileThread(File fileLocation, boolean append) throws FileNotFoundException { stream = new PrintWriter(new OutputStreamWriter(new FileOutputStream(fileLocation, append), StandardCharsets.UTF_8)); diff --git a/src/main/java/com/minecrafttas/tasmod/util/PointerNormalizer.java b/src/main/java/com/minecrafttas/tasmod/util/PointerNormalizer.java index e9136f0d..12a6d2a2 100644 --- a/src/main/java/com/minecrafttas/tasmod/util/PointerNormalizer.java +++ b/src/main/java/com/minecrafttas/tasmod/util/PointerNormalizer.java @@ -5,37 +5,41 @@ import net.minecraft.client.gui.GuiWorldSelection; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.gui.inventory.GuiContainer; -import net.minecraft.client.gui.inventory.GuiContainerCreative; /** - * Adjusts the pointer/cursor of the playback to different gui scalings. - * - * This was the work of many hours of trial and error. - * - * Out of despair I reached out to Darkmoon to help me with this problem... - * - * @author ScribbleLP, Darkmoon + * Normalizes the cursor to be independent of gui scalings.
+ * That way, a TAS recorded in e.g. Gui Scale "Large" can also be played back on Gui Scale "Small" * + * @author Scribble, Darkmoon */ public class PointerNormalizer { + /** + * Mathematically removes scaling from the x coordinate + * @param pointerX The current pointer coordinate + * @return The normalized x coordinate + */ public static int getNormalizedX(int pointerX) { Minecraft mc = Minecraft.getMinecraft(); ScaledResolution scaled = new ScaledResolution(mc); - int out = (int) (pointerX - (scaled.getScaledWidth() / 2D)); - return out; + return (int) (pointerX - (scaled.getScaledWidth() / 2D)); } + /** + * Mathematically removes scaling from the y coordinate + * @param pointerY The current pointer coordinate + * @return The normalized y coordinate + */ public static int getNormalizedY(int pointerY) { Minecraft mc = Minecraft.getMinecraft(); ScaledResolution scaled = new ScaledResolution(mc); int out = pointerY; - if (mc.currentScreen instanceof GuiContainer || mc.currentScreen instanceof GuiContainerCreative) { + if (mc.currentScreen instanceof GuiContainer) { out = (int) (pointerY - (scaled.getScaledHeight() / 2D)); } else if (mc.currentScreen instanceof GuiWorldSelection|| mc.currentScreen instanceof GuiMultiplayer) { - + // TODO Figure out what to do here } else { out = (int) (pointerY - (scaled.getScaledHeight() / 4 + 72 + -16)); } @@ -43,62 +47,62 @@ public static int getNormalizedY(int pointerY) { return out; } - public static int getCoordsX(int normalizedX) { + /** + * Reapplies gui scaling to the normalized pointer x coordinate + * @param normalizedX The normalized pointer coordinate + * @return The scaled coordinate + */ + public static int reapplyScalingX(int normalizedX) { Minecraft mc = Minecraft.getMinecraft(); ScaledResolution scaled = new ScaledResolution(mc); int out = (int) Math.round(normalizedX + (scaled.getScaledWidth() / 2D)); - return limiterX(out, scaled); + return clamp(out, 0, scaled.getScaledWidth()); } - public static int getCoordsY(int normalizedY) { + /** + * Reapplies gui scaling to the normalized pointer y coordinate + * @param normalizedY The normalized pointer coordinate + * @return The scaled coordinate + */ + public static int reapplyScalingY(int normalizedY) { Minecraft mc = Minecraft.getMinecraft(); ScaledResolution scaled = new ScaledResolution(mc); int out = normalizedY; - if (mc.currentScreen instanceof GuiContainer || mc.currentScreen instanceof GuiContainerCreative) { + if (mc.currentScreen instanceof GuiContainer) { out = (int) Math.round(normalizedY + (scaled.getScaledHeight() / 2D)); } else if (mc.currentScreen instanceof GuiWorldSelection || mc.currentScreen instanceof GuiMultiplayer) { - + // TODO Figure out what to do here } else { out = (int) (normalizedY + (scaled.getScaledHeight() / 4 + 72 + -16)); } - return limiterY(out, scaled); - } - - private static int limiterX(int out, ScaledResolution scaled) { - int width = scaled.getScaledWidth(); - if (out > width) { - out = width; - } else if (out < 0) - out = 0; - return out; - } - - private static int limiterY(int out, ScaledResolution scaled) { - int height = scaled.getScaledHeight(); - if (out > height) { - out = height; - } else if (out < 0) - out = 0; - return out; + return clamp(out, 0, scaled.getScaledHeight()); } - private static int gcd(int a, int b) { - return (b == 0) ? a : gcd(b, a % b); + private static int clamp(int value, int lower, int upper) { + if (value < lower) { + return lower; + } else { + return Math.min(value, upper); + } } public static void printAspectRatio() { int height = Minecraft.getMinecraft().displayHeight; int width = Minecraft.getMinecraft().displayWidth; - int gcd = gcd(width, height); + int gcd = greatestCommonDivisor(width, height); if (gcd == 0) { System.out.println(gcd); } else { System.out.println(width / gcd + ":" + height / gcd); } } - + + private static int greatestCommonDivisor(int a, int b) { + return (b == 0) ? a : greatestCommonDivisor(b, a % b); + } + /* * Here lies 10 hours of work for something I didn't even use. This code * normalizes the pointers coordinates and scales it depending on the screen diff --git a/src/main/java/com/minecrafttas/tasmod/util/Scheduler.java b/src/main/java/com/minecrafttas/tasmod/util/Scheduler.java index fd13454b..9e462b3a 100644 --- a/src/main/java/com/minecrafttas/tasmod/util/Scheduler.java +++ b/src/main/java/com/minecrafttas/tasmod/util/Scheduler.java @@ -7,7 +7,6 @@ * A simple scheduling interface * * @author Scribble - * */ public class Scheduler { diff --git a/src/main/java/com/minecrafttas/tasmod/util/ShieldDownloader.java b/src/main/java/com/minecrafttas/tasmod/util/ShieldDownloader.java index 4f514c1e..2588c4e1 100644 --- a/src/main/java/com/minecrafttas/tasmod/util/ShieldDownloader.java +++ b/src/main/java/com/minecrafttas/tasmod/util/ShieldDownloader.java @@ -30,6 +30,11 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.util.ResourceLocation; +/** + * Downloads shield textures from + *
+ * Similar to {@link VirtualKeyboard} and {@link VirtualMouse} with the difference,
+ * that no difference calculation is applied and only the absolute camera coordinates are used.
+ * This makes the playback desync proof to different mouse sensitivity across PCs.
+ * + */ public class VirtualCameraAngle extends Subtickable implements Serializable { - private float pitch; - private float yaw; - + /** + * Controls the up/down coordinate of the camera. Clamped between -90 and +90 + */ + private Float pitch; + /** + * Controls the left/right coordinate of the camera. In this case the camera is clamped between -180 and +180 + */ + private Float yaw; + + /** + * Creates an empty camera angle with pitch and yaw = 0 + */ public VirtualCameraAngle() { - this(0, 0, new ArrayList<>(), true); + this(null, null, new ArrayList<>(), true); } - public VirtualCameraAngle(float pitch, float yaw) { + /** + * Creates a subtick camera angle with {@link Subtickable#subtickList} uninitialized + * @param pitch {@link #pitch} + * @param yaw {@link #yaw} + */ + public VirtualCameraAngle(Float pitch, Float yaw) { this(pitch, yaw, null); } - public VirtualCameraAngle(float pitch, float yaw, List subtickList) { + /** + * Creates a parent camera angle + * @param pitch {@link #pitch} + * @param yaw {@link #yaw} + * @param ignoreFirstUpdate {@link Subtickable#ignoreFirstUpdate} + */ + public VirtualCameraAngle(Float pitch, Float yaw, boolean ignoreFirstUpdate) { + this(pitch, yaw, new ArrayList<>(), ignoreFirstUpdate); + } + + /** + * Creates a camera angle with existing values + * @param pitch {@link #pitch} + * @param yaw {@link #yaw} + * @param subtickList {@link Subtickable#subtickList} + */ + public VirtualCameraAngle(Float pitch, Float yaw, List subtickList) { this(pitch, yaw, subtickList, false); } - - public VirtualCameraAngle(float pitch, float yaw, List subtickList, boolean ignoreFirstUpdate) { + + /** + * Creates a camera angle with initialized values + * @param pitch {@link VirtualCameraAngle#pitch} + * @param yaw {@link VirtualCameraAngle#yaw} + * @param subtickList {@link Subtickable#subtickList} + * @param ignoreFirstUpdate {@link Subtickable#ignoreFirstUpdate} + */ + public VirtualCameraAngle(Float pitch, Float yaw, List subtickList, boolean ignoreFirstUpdate) { super(subtickList, ignoreFirstUpdate); this.pitch = pitch; this.yaw = yaw; } - public void update(float pitch, float yaw) { + /** + * Updates the camera angle. + * @param pitchDelta The difference between absolute coordinates of the pitch, is added to {@link VirtualCameraAngle#pitch} + * @param yawDelta The difference between absolute coordinates of the yaw, is added to {@link VirtualCameraAngle#yaw} + */ + public void update(float pitchDelta, float yawDelta) { + if(pitch==null || yaw == null) { + return; + } if(isParent() && !ignoreFirstUpdate()) { addSubtick(clone()); } - this.pitch += pitch; - this.pitch = MathHelper.clamp(this.pitch, -90.0F, 90.0F); - this.yaw += yaw; + this.pitch = MathHelper.clamp(this.pitch + pitchDelta, -90.0F, 90.0F); + this.yaw += yawDelta; } + public void set(float pitch, float yaw) { + this.pitch = pitch; + this.yaw = yaw; + } + + /** + * A list of all camera states in this VirtualCameraAngle. + * It consists of: {@link Subtickable#subtickList} + this + * @param reference A list of VirtualCameraAngles with the newest being the current camera angle + */ public void getStates(List reference) { if (isParent()) { reference.addAll(subtickList); @@ -44,6 +107,10 @@ public void getStates(List reference) { } } + /** + * Copies the data from another camera angle into this camera without creating a new object. + * @param camera The camera to move from + */ public void copyFrom(VirtualCameraAngle camera) { this.pitch = camera.pitch; this.yaw = camera.yaw; @@ -52,6 +119,14 @@ public void copyFrom(VirtualCameraAngle camera) { camera.subtickList.clear(); } + public void clear() { + this.pitch = null; + this.yaw = null; + } + + /** + * Creates a clone of this object as a subtick + */ @Override public VirtualCameraAngle clone() { return new VirtualCameraAngle(pitch, yaw); @@ -61,21 +136,36 @@ public VirtualCameraAngle clone() { public boolean equals(Object obj) { if (obj instanceof VirtualCameraAngle) { VirtualCameraAngle angle = (VirtualCameraAngle) obj; - return pitch == angle.pitch && yaw == angle.yaw; + return (pitch != null && pitch.equals(angle.pitch)) && (yaw != null && yaw.equals(angle.yaw)); } return super.equals(obj); } @Override public String toString() { + if(isParent()) { + return getAll().stream().map(VirtualCameraAngle::toString2).collect(Collectors.joining("\n")); + } else { + return toString2(); + } + } + + private String toString2() { return String.format("%s;%s", pitch, yaw); } - public float getPitch() { + /** + * @return {@link #pitch} + */ + public Float getPitch() { return pitch; } - public float getYaw() { + /** + * @return {@link #yaw} + */ + public Float getYaw() { return yaw; } + } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index 7ed018c0..9d55fe88 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -5,7 +5,6 @@ import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; -import com.minecrafttas.tasmod.TASmodClient; import org.apache.commons.lang3.tuple.Triple; import org.apache.logging.log4j.Logger; import org.lwjgl.input.Keyboard; @@ -16,7 +15,6 @@ import com.minecrafttas.tasmod.util.Ducks; import com.minecrafttas.tasmod.util.LoggerMarkers; import com.minecrafttas.tasmod.util.PointerNormalizer; -import com.minecrafttas.tasmod.virtual.event.VirtualCameraAngleEvent; import com.minecrafttas.tasmod.virtual.event.VirtualKeyboardEvent; import com.minecrafttas.tasmod.virtual.event.VirtualMouseEvent; @@ -130,9 +128,10 @@ public boolean willKeyBeDown(int keycode) { /** * Unpresses all keys in {@link VirtualKeyboardInput#nextKeyboard} and {@link VirtualMouseInput#nextMouse} */ - public void unpress() { + public void clear() { KEYBOARD.nextKeyboard.clear(); MOUSE.nextMouse.clear(); + CAMERA_ANGLE.nextCameraAngle.clear(); } /** @@ -385,7 +384,7 @@ public VirtualMouseInput(VirtualMouse preloadedMouse) { * @see VirtualInput#update(GuiScreen) * @param keycode The keycode of this event * @param keystate The keystate of this event - * @param scrollwheel The scrollWheel of this event + * @param scrollwheel The scrollwheel direction of this event * @param cursorX The x coordinate of the cursor of this event * @param cursorY The y coordinate of the cursot of this event */ @@ -443,14 +442,14 @@ public int getEventMouseScrollWheel() { * @return The x coordinate of the cursor of {@link #currentMouseEvent} */ public int getEventCursorX() { - return PointerNormalizer.getCoordsX(currentMouseEvent.getCursorX()); + return PointerNormalizer.reapplyScalingX(currentMouseEvent.getCursorX()); } /** * @return The y coordinate of the cursor of {@link #currentMouseEvent} */ public int getEventCursorY() { - return PointerNormalizer.getCoordsY(currentMouseEvent.getCursorY()); + return PointerNormalizer.reapplyScalingY(currentMouseEvent.getCursorY()); } /** @@ -474,15 +473,37 @@ public boolean willKeyBeDown(int keycode) { } + /** + * Subclass of {@link VirtualInput} handling camera angle logic.
+ *
+ * Unlike {@link VirtualKeyboardInput} or {@link VirtualMouseInput} no subtick behaviour is implemented,
+ * making this a simple pitch and yaw storing class, allowing for redirection. + *
+ * In theory, subtick behaviour is possible, but only useful for interpolation,
+ * as the camera angle is only updated every tick (see {@link com.minecrafttas.tasmod.mixin.playbackhooks.MixinEntityRenderer}). + */ public class VirtualCameraAngleInput { + /** + * The current camera angle + */ private final VirtualCameraAngle currentCameraAngle; private final VirtualCameraAngle nextCameraAngle = new VirtualCameraAngle(); private final List cameraAngleInterpolationStates = new ArrayList<>(); - + + /** + * Constructor to preload the {@link #currentCameraAngle} with an existing camera angle + * @param preloadedCamera The new {@link #currentCameraAngle} + */ public VirtualCameraAngleInput(VirtualCameraAngle preloadedCamera) { currentCameraAngle = preloadedCamera; } - + + /** + * Update the camera angle + * @see com.minecrafttas.tasmod.mixin.playbackhooks.MixinEntityRenderer#runUpdate(float); + * @param pitch Absolute rotationPitch of the player + * @param yaw Absolute rotationYaw of the player + */ public void updateNextCameraAngle(float pitch, float yaw) { // LOGGER.debug("Pitch: {}, Yaw: {}", pitch, yaw); nextCameraAngle.update(pitch, yaw); @@ -493,17 +514,21 @@ public void nextCameraTick() { currentCameraAngle.copyFrom(nextCameraAngle); } - public float getCurrentPitch() { + public void setCamera(Float pitch, Float yaw) { + nextCameraAngle.set(pitch, yaw); + } + + public Float getCurrentPitch() { return currentCameraAngle.getPitch(); } - public float getCurrentYaw() { + public Float getCurrentYaw() { return currentCameraAngle.getYaw(); } public Triple getInterpolatedState(float partialTick, float pitch, float yaw, boolean enable){ if(!enable) { - return Triple.of(TASmodClient.virtual.CAMERA_ANGLE.nextCameraAngle.getPitch(), TASmodClient.virtual.CAMERA_ANGLE.nextCameraAngle.getYaw()+180, 0f); + return Triple.of(nextCameraAngle.getPitch()==null ? pitch : nextCameraAngle.getPitch(), nextCameraAngle.getYaw()==null? pitch : nextCameraAngle.getYaw()+180, 0f); } float interpolatedPitch = 0f; diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java index ae96365d..d12bea00 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java @@ -252,7 +252,7 @@ public void addChar(char character, boolean repeatEventsEnabled) { } @Override - protected void clear(){ + public void clear(){ super.clear(); charList.clear(); } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java index fe1cca43..4329fc05 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java @@ -6,6 +6,15 @@ import java.util.*; import java.util.stream.Collectors; +/** + * Stores the mouse specific values in a given timeframe
+ *
+ * Similar to {@link VirtualKeyboard}, but instead of a list of characters,
+ * it stores the state of the scroll wheel and the cursors x and y coordinate on screen. + * + * @author Scribble + * @see VirtualInput.VirtualMouseInput + */ public class VirtualMouse extends VirtualPeripheral implements Serializable { /** @@ -123,25 +132,25 @@ public void getVirtualEvents(VirtualMouse nextMouse, Queue re * the one from tick 16 * @param reference The queue to fill. Passed in by reference. */ - public void getDifference(VirtualMouse nextPeripheral, Queue reference) { + public void getDifference(VirtualMouse nextMouse, Queue reference) { /* * Checks if pressedKeys are the same... */ - if(pressedKeys.equals(nextPeripheral.pressedKeys)){ + if(pressedKeys.equals(nextMouse.pressedKeys)){ - /** + /* * ...but scrollWheel, cursorX or cursorY are different. * Without this, the scrollWheel would only work if a mouse button is pressed at the same time. */ - if(!equals(nextPeripheral)) { - reference.add(new VirtualMouseEvent(VirtualKey.MOUSEMOVED.getKeycode(), false, nextPeripheral.scrollWheel, nextPeripheral.cursorX, nextPeripheral.cursorY)); + if(!equals(nextMouse)) { + reference.add(new VirtualMouseEvent(VirtualKey.MOUSEMOVED.getKeycode(), false, nextMouse.scrollWheel, nextMouse.cursorX, nextMouse.cursorY)); } return; } - int scrollWheelCopy = nextPeripheral.scrollWheel; - int cursorXCopy = nextPeripheral.cursorX; - int cursorYCopy = nextPeripheral.cursorY; + int scrollWheelCopy = nextMouse.scrollWheel; + int cursorXCopy = nextMouse.cursorX; + int cursorYCopy = nextMouse.cursorY; /* Calculate symmetric difference of keycodes */ @@ -153,7 +162,7 @@ public void getDifference(VirtualMouse nextPeripheral, Queue RC <- unpressed */ for(int keycode : pressedKeys) { - if (!nextPeripheral.getPressedKeys().contains(keycode)) { + if (!nextMouse.getPressedKeys().contains(keycode)) { reference.add(new VirtualMouseEvent(keycode, false, scrollWheelCopy, cursorXCopy, cursorYCopy)); scrollWheelCopy = 0; cursorXCopy = 0; @@ -168,7 +177,7 @@ public void getDifference(VirtualMouse nextPeripheral, Queue ------------- MC <- pressed */ - for(int keycode : nextPeripheral.getPressedKeys()) { + for(int keycode : nextMouse.getPressedKeys()) { if (!this.pressedKeys.contains(keycode)) { reference.add(new VirtualMouseEvent(keycode, true, scrollWheelCopy, cursorXCopy, cursorYCopy)); } @@ -176,7 +185,7 @@ public void getDifference(VirtualMouse nextPeripheral, Queue } @Override - protected void clear() { + public void clear() { super.clear(); clearMouseData(); } diff --git a/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java b/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java new file mode 100644 index 00000000..1809c867 --- /dev/null +++ b/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java @@ -0,0 +1,144 @@ +package tasmod.virtual; + +import com.minecrafttas.tasmod.virtual.VirtualCameraAngle; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; +public class VirtualCameraAngleTest { + + /** + * Test the empty constructor + */ + @Test + void testEmptyConstructor(){ + VirtualCameraAngle actual = new VirtualCameraAngle(); + assertEquals(null, actual.getPitch()); + assertEquals(null, actual.getYaw()); + assertTrue(actual.isParent()); + } + + /** + * Test subtick constructor with premade pitch and value + */ + @Test + void testSubtickConstructor(){ + float x = 1f; + float y = 2f; + + VirtualCameraAngle actual = new VirtualCameraAngle(x, y); + assertEquals(1f, actual.getPitch()); + assertEquals(2f, actual.getYaw()); + assertFalse(actual.isParent()); + } + + /** + * Testing update function + */ + @Test + void testUpdate(){ + float x = 1f; + float y = 2f; + + VirtualCameraAngle actual = new VirtualCameraAngle(0f, 0f, true); + + actual.update(x, y); + + assertEquals(1f, actual.getPitch()); + assertEquals(2f, actual.getYaw()); + } + + /** + * Testing update function, but with a pitch higher/lower than 90/-90 + */ + @Test + void testUpdateWithBadPitch() { + VirtualCameraAngle actual = new VirtualCameraAngle(0f, 0f, true); + + actual.update(-100f, 0f); + + assertEquals(-90f, actual.getPitch()); + + actual.update(360f, 0f); + + assertEquals(90f, actual.getPitch()); + } + + /** + * Test copyfrom method + */ + @Test + void copyFrom() { + VirtualCameraAngle actual = new VirtualCameraAngle(); + actual.update(1f, 2f); + actual.update(3f, 4f); + } + + /** + * Test the toString method without subticks + */ + @Test + void testToString() { + float x = 1f; + float y = 2f; + + VirtualCameraAngle actual = new VirtualCameraAngle(x, y); + + assertEquals("1.0;2.0", actual.toString()); + } + + /** + * Test the toString method with subticks + */ + @Test + void testToStringSubticks() { + + VirtualCameraAngle actual = new VirtualCameraAngle(0f, 0f, true); + actual.update(1f, 2f); + actual.update(3f, 4f); + actual.update(5f, 6f); + + assertEquals("1.0;2.0\n4.0;6.0\n9.0;12.0", actual.toString()); + } + + /** + * Test cloning the camera angle + */ + @Test + void testClone(){ + float x = 1f; + float y = 2f; + + VirtualCameraAngle test = new VirtualCameraAngle(x, y); + + VirtualCameraAngle actual = test.clone(); + + assertEquals(1f, actual.getPitch()); + assertEquals(2f, actual.getYaw()); + } + + /** + * Test equals + */ + @Test + void testEquals(){ + float x = 1f; + float y = 2f; + + VirtualCameraAngle test = new VirtualCameraAngle(x, y); + VirtualCameraAngle test2 = new VirtualCameraAngle(x, y); + + assertEquals(test, test2); + } + + /** + * Test where equals will fail + */ + @Test + void testNotEquals(){ + + VirtualCameraAngle test = new VirtualCameraAngle(1f, 2f); + VirtualCameraAngle test2 = new VirtualCameraAngle(3f, 4f); + + assertNotEquals(test, test2); + } +} diff --git a/src/test/java/tasmod/virtual/VirtualInputTest.java b/src/test/java/tasmod/virtual/VirtualInputTest.java index bf184b57..30ce0947 100644 --- a/src/test/java/tasmod/virtual/VirtualInputTest.java +++ b/src/test/java/tasmod/virtual/VirtualInputTest.java @@ -35,7 +35,7 @@ void testConstructor() { void testPreloadedConstructor() { VirtualKeyboard preloadedKeyboard = new VirtualKeyboard(); VirtualMouse preloadedMouse = new VirtualMouse(); - VirtualCameraAngle preloadedCameraAngle = new VirtualCameraAngle(); + VirtualCameraAngle preloadedCameraAngle = new VirtualCameraAngle(0f, 0f); preloadedKeyboard.update(VirtualKey.W.getKeycode(), true, 'w'); preloadedMouse.update(VirtualKey.LC.getKeycode(), true, 15, 0, 0); From 3d2a8e43dcab3ffab406820218b62c33b93d25a7 Mon Sep 17 00:00:00 2001 From: Scribble Date: Fri, 16 Feb 2024 09:00:49 +0100 Subject: [PATCH 50/57] [VirtualInput] Add support for smoothCamera and invert mouse option --- .../playbackhooks/MixinEntityRenderer.java | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java index 7fff25e5..b5ae3d1a 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java @@ -48,13 +48,33 @@ public class MixinEntityRenderer implements SubtickDuck { @Inject(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/profiler/Profiler;startSection(Ljava/lang/String;)V", ordinal = 0, shift = At.Shift.AFTER)) public void playback_injectAtStartSection(float partialTicks, long nanoTime, CallbackInfo ci) { // Calculate sensitivity - float f = this.mc.gameSettings.mouseSensitivity * 0.6F + 0.2F; - float f1 = f * f * f * 8.0F; + float mouseSensititvity = this.mc.gameSettings.mouseSensitivity * 0.6F + 0.2F; + float mouseSensitivityCubed = mouseSensititvity * mouseSensititvity * mouseSensititvity * 8.0F; if (this.mc.currentScreen == null && !TASmodClient.controller.isPlayingback() && mc.player != null) { // No Gui mc.mouseHelper.mouseXYChange(); + float deltaPitch = mc.mouseHelper.deltaY * mouseSensitivityCubed; + float deltaYaw = mc.mouseHelper.deltaX * mouseSensitivityCubed; + + int invertMouse = 1; + if (this.mc.gameSettings.invertMouse) { + invertMouse = -1; + } + + if (this.mc.gameSettings.smoothCamera) { + this.smoothCamPitch += deltaPitch; + this.smoothCamYaw += deltaYaw; + float m = mouseSensititvity - this.smoothCamPartialTicks; + this.smoothCamPartialTicks = mouseSensititvity; + deltaPitch = this.smoothCamFilterY * m; + deltaYaw = this.smoothCamFilterX * m; + } else { + this.smoothCamYaw = 0.0F; + this.smoothCamPitch = 0.0F; + } + mc.getTutorial().handleMouse(mc.mouseHelper); - TASmodClient.virtual.CAMERA_ANGLE.updateNextCameraAngle((float) -(mc.mouseHelper.deltaY * f1 * 0.15D), (float) (mc.mouseHelper.deltaX * f1 * 0.15D)); + TASmodClient.virtual.CAMERA_ANGLE.updateNextCameraAngle((float) -((double)deltaPitch * 0.15D * invertMouse), (float) ((double)deltaYaw * 0.15D)); } } From 5935e4a1b7220780308c57cff0d70e35231aa356 Mon Sep 17 00:00:00 2001 From: Scribble Date: Fri, 16 Feb 2024 09:29:45 +0100 Subject: [PATCH 51/57] [VirtualInput] Added documentation for MixinEntityRenderer --- .../playbackhooks/MixinEntityRenderer.java | 79 +++++++++++++++---- 1 file changed, 65 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java index b5ae3d1a..76699ffd 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java @@ -45,13 +45,20 @@ public class MixinEntityRenderer implements SubtickDuck { @Shadow private float smoothCamFilterY; + /** + * Injects into the vanilla camera updating cycle, runs every frame. + * Updates {@link com.minecrafttas.tasmod.virtual.VirtualInput.VirtualCameraAngleInput#nextCameraAngle} + * @param partialTicks The partial ticks of the timer, unused + * @param nanoTime The nanoTime, unused + * @param ci CBI + */ @Inject(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/profiler/Profiler;startSection(Ljava/lang/String;)V", ordinal = 0, shift = At.Shift.AFTER)) public void playback_injectAtStartSection(float partialTicks, long nanoTime, CallbackInfo ci) { // Calculate sensitivity float mouseSensititvity = this.mc.gameSettings.mouseSensitivity * 0.6F + 0.2F; float mouseSensitivityCubed = mouseSensititvity * mouseSensititvity * mouseSensititvity * 8.0F; - if (this.mc.currentScreen == null && !TASmodClient.controller.isPlayingback() && mc.player != null) { // No Gui + if (this.mc.currentScreen == null && !TASmodClient.controller.isPlayingback() && mc.player != null) { mc.mouseHelper.mouseXYChange(); float deltaPitch = mc.mouseHelper.deltaY * mouseSensitivityCubed; float deltaYaw = mc.mouseHelper.deltaX * mouseSensitivityCubed; @@ -64,10 +71,10 @@ public void playback_injectAtStartSection(float partialTicks, long nanoTime, Cal if (this.mc.gameSettings.smoothCamera) { this.smoothCamPitch += deltaPitch; this.smoothCamYaw += deltaYaw; - float m = mouseSensititvity - this.smoothCamPartialTicks; + float partialSensitivity = mouseSensititvity - this.smoothCamPartialTicks; this.smoothCamPartialTicks = mouseSensititvity; - deltaPitch = this.smoothCamFilterY * m; - deltaYaw = this.smoothCamFilterX * m; + deltaPitch = this.smoothCamFilterY * partialSensitivity; + deltaYaw = this.smoothCamFilterX * partialSensitivity; } else { this.smoothCamYaw = 0.0F; this.smoothCamPitch = 0.0F; @@ -85,49 +92,93 @@ public void playback_stopVanilla(EntityPlayerSP player, float deltaYaw, float de } } + /** + * {@inheritDoc} + * Runs every tick + * @see VirtualInput.VirtualCameraAngleInput#nextCameraTick() + * @param partialTicks The partial ticks from the vanilla Minecraft timer + */ @Override public void runUpdate(float partialTicks) { if(mc.player == null){ return; } + // Update the currentCameraAngle TASmodClient.virtual.CAMERA_ANGLE.nextCameraTick(); - + + // Store current rotation to be used as prevRotationPitch/Yaw float prevPitch = mc.player.rotationPitch; float prevYaw = mc.player.rotationYaw; + + // Get the new pitch from the virtual input Float newPitch = TASmodClient.virtual.CAMERA_ANGLE.getCurrentPitch(); Float newYaw = TASmodClient.virtual.CAMERA_ANGLE.getCurrentYaw(); - - if(newPitch == null) { + + // If the pitch or yaw is null (usually on initialize or when the player joins the world), + // set nextCameraAngle to the current absolute camera coordinates. + // This ensures that the camera position is loaded correctly + if(newPitch == null || newYaw == null) { TASmodClient.virtual.CAMERA_ANGLE.setCamera(prevPitch, prevYaw); return; } + + // Update the rotation of the player mc.player.rotationPitch = newPitch; mc.player.rotationYaw = newYaw; + // Update the previous rotation of the player mc.player.prevRotationPitch = prevPitch; mc.player.prevRotationYaw = prevYaw; } - + + /** + * Redirects applying the pitch to the camera. + * @param pitch Original pitch of the camera + * @param sharedPitch MixinExtras parameter for sharing values between mixins + * @return 0f for disabeling this method + */ @ModifyArg(method = "orientCamera", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;rotate(FFFF)V", ordinal = 8), index = 0) public float redirect_orientCameraPitch(float pitch, @Share("pitch") LocalFloatRef sharedPitch) { sharedPitch.set(pitch); return 0f; } - + + /** + * Redirects applying the yaw to the animal camera + * @param yawAnimal Original yaw of the animal camera + * @param sharedPitch MixinExtras parameter for sharing values between mixins + * @return The redirected yaw + */ @ModifyArg(method = "orientCamera", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;rotate(FFFF)V", ordinal = 9), index = 0) public float redirect_orientCameraYawAnimal(float yawAnimal, @Share("pitch") LocalFloatRef sharedPitch) { - return redirectCam(yawAnimal, sharedPitch.get()); + return redirectCam(sharedPitch.get(), yawAnimal); } - + + /** + * Redirects applying the yaw to the camera + * @param yaw Original yaw of the camera + * @param sharedPitch MixinExtras parameter for sharing values between mixins + * @return The redirected yaw + */ @ModifyArg(method = "orientCamera", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;rotate(FFFF)V", ordinal = 10), index = 0) public float redirect_orientCameraYaw(float yaw, @Share("pitch") LocalFloatRef sharedPitch) { - return redirectCam(yaw, sharedPitch.get()); + return redirectCam(sharedPitch.get(), yaw); } - - private float redirectCam(float yaw, float pitch) { + + /** + * Turns the camera via GLStateManager + * @param pitch The pi + * @param yaw The yaw + * @see com.minecrafttas.tasmod.virtual.VirtualInput.VirtualCameraAngleInput#getInterpolatedState(float, float, float, boolean) + * @return The redirected yaw + */ + private float redirectCam(float pitch, float yaw) { Triple interpolated = TASmodClient.virtual.CAMERA_ANGLE.getInterpolatedState(Minecraft.getMinecraft().timer.renderPartialTicks, pitch, yaw, TASmodClient.controller.isPlayingback()); + // Update pitch GlStateManager.rotate(interpolated.getLeft(), 1.0f, 0.0f, 0.0f); + // Update roll GlStateManager.rotate(interpolated.getRight(), 0.0f, 0.0f, 1.0f); + // Update yaw return interpolated.getMiddle(); } } From c12a2c0f8436ec7c9652cab92ba463691415bdd5 Mon Sep 17 00:00:00 2001 From: Scribble Date: Fri, 16 Feb 2024 23:31:44 +0100 Subject: [PATCH 52/57] [VirtualInput] Finishing tests on VirtualCameraAngle - Added clear to Subtickable --- .../tasmod/virtual/Subtickable.java | 69 +-- .../tasmod/virtual/VirtualCameraAngle.java | 11 +- .../tasmod/virtual/VirtualPeripheral.java | 3 +- .../virtual/VirtualCameraAngleTest.java | 405 ++++++++++++------ .../tasmod/virtual/VirtualKeyboardTest.java | 42 ++ 5 files changed, 363 insertions(+), 167 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/Subtickable.java b/src/main/java/com/minecrafttas/tasmod/virtual/Subtickable.java index dcfb3ace..c0cd892b 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/Subtickable.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/Subtickable.java @@ -7,34 +7,42 @@ public class Subtickable { /** * A list of subtick peripherals.
- * If a peripheral parent is updated, it first adds it's current state to the subtickList before updating.
- * This makes the subtickList a list of previous peripheral states, with the first element being the oldest change.
+ * If a peripheral parent is updated, it first adds it's current state + * to the subtickList before updating.
+ * This makes the subtickList a list of previous peripheral states, with the + * first element being the oldest change.
*
- * To distinguish a peripheral of being a subtick or a "parent", subtickList is either null or not null respectively (see {@link #isParent()})
+ * To distinguish a peripheral of being a subtick or a "parent", subtickList is + * either null or not null respectively (see {@link #isParent()})
*/ protected final List subtickList; /** - * The way the parent/subtick relationship is set up (see {@link #subtickList}),
- * the subtickList contains all previous changes, while the parent contains the current state.
- * To achieve this and to prevent a ghost state from being added to the subtickList,
- * it is sometimes necessary to ignore the first time an addition is made to the subtickList,
+ * The way the parent/subtick relationship is set up (see + * {@link #subtickList}),
+ * the subtickList contains all previous changes, while the parent contains the + * current state.
+ * To achieve this and to prevent a ghost state from being added to the + * subtickList,
+ * it is sometimes necessary to ignore the first time an addition is made to the + * subtickList,
* to delay the subtickList and make the parent the current state. */ - private boolean ignoreFirstUpdate = false; - + private boolean ignoreFirstUpdate = false; + protected Subtickable(List subtickList, boolean ignoreFirstUpdate) { this.subtickList = subtickList; this.ignoreFirstUpdate = ignoreFirstUpdate; } - - /** - * Adds a peripheral to {@link #subtickList} - * @param peripheral The peripheral to add - */ - protected void addSubtick(T peripheral) { - subtickList.add(peripheral); - } - + + /** + * Adds a peripheral to {@link #subtickList} + * + * @param peripheral The peripheral to add + */ + protected void addSubtick(T peripheral) { + subtickList.add(peripheral); + } + /** * @return An immutable list of subticks */ @@ -48,24 +56,29 @@ public List getSubticks() { public boolean isParent() { return subtickList != null; } - + /** * Gets all peripheral states in an immutable list.
*
- * This list is comprised of {@link #subtickList} and the current peripheral state added after that
- * This will result in a list where the first element is the oldest state and the last being the current state. + * This list is comprised of {@link #subtickList} and the current peripheral + * state added after that
+ * This will result in a list where the first element is the oldest state and + * the last being the current state. + * * @return An immutable list of keyboard states */ @SuppressWarnings("unchecked") public List getAll() { - return ImmutableList.builder() - .addAll(subtickList) - .add((T)this) - .build(); + return ImmutableList.builder().addAll(subtickList).add((T) this).build(); + } + + protected void clear() { + subtickList.clear(); } - + /** * Retrieves and sets {@link #ignoreFirstUpdate} to false + * * @return If the first update should be ignored */ protected boolean ignoreFirstUpdate() { @@ -78,10 +91,10 @@ protected boolean ignoreFirstUpdate() { * @return If this peripheral should ignore it's first update * @see #ignoreFirstUpdate */ - protected boolean isIgnoreFirstUpdate(){ + protected boolean isIgnoreFirstUpdate() { return ignoreFirstUpdate; } - + protected void resetFirstUpdate() { ignoreFirstUpdate = true; } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java index e09ce2b4..aefb5a50 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java @@ -90,6 +90,11 @@ public void update(float pitchDelta, float yawDelta) { this.yaw += yawDelta; } + /** + * Setting the absolute camera coordinates directly + * @param pitch {@link #pitch} + * @param yaw {@link #yaw} + */ public void set(float pitch, float yaw) { this.pitch = pitch; this.yaw = yaw; @@ -119,9 +124,14 @@ public void copyFrom(VirtualCameraAngle camera) { camera.subtickList.clear(); } + /** + * Sets {@link #pitch} and {@link #yaw} to null + */ + @Override public void clear() { this.pitch = null; this.yaw = null; + super.clear(); } /** @@ -167,5 +177,4 @@ public Float getPitch() { public Float getYaw() { return yaw; } - } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java index c27403d9..1a5a1633 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java @@ -107,9 +107,10 @@ public boolean isKeyDown(String keyname) { /** * Clears pressed keys and subticks */ + @Override protected void clear() { pressedKeys.clear(); - subtickList.clear(); + super.clear(); } @Override diff --git a/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java b/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java index 1809c867..a6aa974b 100644 --- a/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java +++ b/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java @@ -1,144 +1,275 @@ package tasmod.virtual; -import com.minecrafttas.tasmod.virtual.VirtualCameraAngle; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.List; + import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; +import com.minecrafttas.tasmod.virtual.VirtualCameraAngle; + public class VirtualCameraAngleTest { - /** - * Test the empty constructor - */ - @Test - void testEmptyConstructor(){ - VirtualCameraAngle actual = new VirtualCameraAngle(); - assertEquals(null, actual.getPitch()); - assertEquals(null, actual.getYaw()); - assertTrue(actual.isParent()); - } - - /** - * Test subtick constructor with premade pitch and value - */ - @Test - void testSubtickConstructor(){ - float x = 1f; - float y = 2f; - - VirtualCameraAngle actual = new VirtualCameraAngle(x, y); - assertEquals(1f, actual.getPitch()); - assertEquals(2f, actual.getYaw()); - assertFalse(actual.isParent()); - } - - /** - * Testing update function - */ - @Test - void testUpdate(){ - float x = 1f; - float y = 2f; - - VirtualCameraAngle actual = new VirtualCameraAngle(0f, 0f, true); - - actual.update(x, y); - - assertEquals(1f, actual.getPitch()); - assertEquals(2f, actual.getYaw()); - } - - /** - * Testing update function, but with a pitch higher/lower than 90/-90 - */ - @Test - void testUpdateWithBadPitch() { - VirtualCameraAngle actual = new VirtualCameraAngle(0f, 0f, true); - - actual.update(-100f, 0f); - - assertEquals(-90f, actual.getPitch()); - - actual.update(360f, 0f); - - assertEquals(90f, actual.getPitch()); - } - - /** - * Test copyfrom method - */ - @Test - void copyFrom() { - VirtualCameraAngle actual = new VirtualCameraAngle(); - actual.update(1f, 2f); - actual.update(3f, 4f); - } - - /** - * Test the toString method without subticks - */ - @Test - void testToString() { - float x = 1f; - float y = 2f; - - VirtualCameraAngle actual = new VirtualCameraAngle(x, y); - - assertEquals("1.0;2.0", actual.toString()); - } - - /** - * Test the toString method with subticks - */ - @Test - void testToStringSubticks() { - - VirtualCameraAngle actual = new VirtualCameraAngle(0f, 0f, true); - actual.update(1f, 2f); - actual.update(3f, 4f); - actual.update(5f, 6f); - - assertEquals("1.0;2.0\n4.0;6.0\n9.0;12.0", actual.toString()); - } - - /** - * Test cloning the camera angle - */ - @Test - void testClone(){ - float x = 1f; - float y = 2f; - - VirtualCameraAngle test = new VirtualCameraAngle(x, y); - - VirtualCameraAngle actual = test.clone(); - - assertEquals(1f, actual.getPitch()); - assertEquals(2f, actual.getYaw()); - } - - /** - * Test equals - */ - @Test - void testEquals(){ - float x = 1f; - float y = 2f; - - VirtualCameraAngle test = new VirtualCameraAngle(x, y); - VirtualCameraAngle test2 = new VirtualCameraAngle(x, y); - - assertEquals(test, test2); - } - - /** - * Test where equals will fail - */ - @Test - void testNotEquals(){ - - VirtualCameraAngle test = new VirtualCameraAngle(1f, 2f); - VirtualCameraAngle test2 = new VirtualCameraAngle(3f, 4f); - - assertNotEquals(test, test2); - } + /** + * Test the empty constructor + */ + @Test + void testEmptyConstructor() { + VirtualCameraAngle actual = new VirtualCameraAngle(); + assertEquals(null, actual.getPitch()); + assertEquals(null, actual.getYaw()); + assertTrue(actual.isParent()); + } + + /** + * Test subtick constructor with premade pitch and value + */ + @Test + void testSubtickConstructor() { + float x = 1f; + float y = 2f; + + VirtualCameraAngle actual = new VirtualCameraAngle(x, y); + assertEquals(1f, actual.getPitch()); + assertEquals(2f, actual.getYaw()); + assertFalse(actual.isParent()); + } + + /** + * Testing update function + */ + @Test + void testUpdate() { + float x = 1f; + float y = 2f; + + VirtualCameraAngle actual = new VirtualCameraAngle(0f, 0f, true); + + actual.update(x, y); + + assertEquals(1f, actual.getPitch()); + assertEquals(2f, actual.getYaw()); + } + + /** + * Testing update function, but with a pitch higher/lower than 90/-90 + */ + @Test + void testUpdateWithBadPitch() { + VirtualCameraAngle actual = new VirtualCameraAngle(0f, 0f, true); + + actual.update(-100f, 0f); + assertEquals(-90f, actual.getPitch()); + + actual.update(360f, 0f); + assertEquals(90f, actual.getPitch()); + } + + /** + * Test updating a camera but pitch and yaw are null. The update should fail and + * pitch and yaw should still be null + */ + @Test + void testUpdateWithNull() { + float x = 1f; + float y = 2f; + + VirtualCameraAngle actual = new VirtualCameraAngle(); + + actual.update(x, y); + + assertEquals(null, actual.getPitch()); + assertEquals(null, actual.getYaw()); + + VirtualCameraAngle actual2 = new VirtualCameraAngle(1f, null); + actual2.update(x, y); + + assertEquals(null, actual.getPitch()); + assertEquals(null, actual.getYaw()); + } + + /** + * Test setting the camera + */ + @Test + void testSet() { + VirtualCameraAngle actual = new VirtualCameraAngle(); + actual.set(1f, 2f); + + actual.update(1f, 2f); + + assertEquals(2f, actual.getPitch()); + assertEquals(4f, actual.getYaw()); + } + + /** + * Test getting all states + */ + @Test + void testGetStates() { + VirtualCameraAngle test = new VirtualCameraAngle(); + test.set(0f, 0f); + test.update(1f, 1f); + test.update(1f, 1f); + test.update(1f, 1f); + + List actual = new ArrayList<>(); + + // Test get states on a subtick, should result in an empty array + VirtualCameraAngle test2 = new VirtualCameraAngle(0f, 0f); + + test2.getStates(actual); + + assertTrue(actual.isEmpty()); + + actual.clear(); + + test.getStates(actual); + + List expected = new ArrayList<>(); + + expected.add(new VirtualCameraAngle(1f, 1f)); + expected.add(new VirtualCameraAngle(2f, 2f)); + expected.add(new VirtualCameraAngle(3f, 3f)); + + assertIterableEquals(expected, actual); + } + + /** + * Test copyfrom method + */ + @Test + void copyFrom() { + VirtualCameraAngle expected = new VirtualCameraAngle(0f, 0f, true); + expected.update(1f, 2f); + expected.update(3f, 4f); + + VirtualCameraAngle actual = new VirtualCameraAngle(0f, 0f, true); + + actual.copyFrom(expected); + + // Test pitch and yaw + assertEquals(expected.getPitch(), actual.getPitch()); + assertEquals(expected.getYaw(), actual.getYaw()); + + // Test subticks + List expected2 = new ArrayList<>(); + expected2.add(new VirtualCameraAngle(1f, 2f)); + expected2.add(new VirtualCameraAngle(4f, 6f)); + + assertIterableEquals(expected2, actual.getAll()); + // Test expected subticks being cleared + + assertTrue(expected.getSubticks().isEmpty()); + } + + /** + * Test clearing the camera angle + */ + @Test + void testClear() { + VirtualCameraAngle actual = new VirtualCameraAngle(); + actual.set(0f, 0f); + actual.update(1f, 1f); + actual.update(1f, 1f); + actual.update(1f, 1f); + + actual.clear(); + + assertNull(actual.getPitch()); + assertNull(actual.getYaw()); + assertTrue(actual.getSubticks().isEmpty()); + } + + /** + * Test the toString method without subticks + */ + @Test + void testToString() { + float x = 1f; + float y = 2f; + + VirtualCameraAngle actual = new VirtualCameraAngle(x, y); + + assertEquals("1.0;2.0", actual.toString()); + } + + /** + * Test the toString method with subticks + */ + @Test + void testToStringSubticks() { + VirtualCameraAngle actual = new VirtualCameraAngle(0f, 0f, true); + actual.update(1f, 2f); + actual.update(3f, 4f); + actual.update(5f, 6f); + + assertEquals("1.0;2.0\n4.0;6.0\n9.0;12.0", actual.toString()); + } + + /** + * Test cloning the camera angle + */ + @Test + void testClone() { + float x = 1f; + float y = 2f; + + VirtualCameraAngle test = new VirtualCameraAngle(x, y); + + VirtualCameraAngle actual = test.clone(); + + assertEquals(1f, actual.getPitch()); + assertEquals(2f, actual.getYaw()); + } + + /** + * Test equals + */ + @Test + void testEquals() { + float x = 1f; + float y = 2f; + + VirtualCameraAngle test = new VirtualCameraAngle(x, y); + VirtualCameraAngle test2 = new VirtualCameraAngle(x, y); + + assertEquals(test, test2); + } + + /** + * Test where equals will fail + */ + @Test + void testNotEquals() { + + // Test pitch being different + VirtualCameraAngle test = new VirtualCameraAngle(1f, 4f); + VirtualCameraAngle test2 = new VirtualCameraAngle(3f, 4f); + assertNotEquals(test, test2); + + // Test yaw being different + test = new VirtualCameraAngle(1f, 2f); + test2 = new VirtualCameraAngle(1f, 3f); + assertNotEquals(test, test2); + + // Test pitch being null + test = new VirtualCameraAngle(null, 2f); + test2 = new VirtualCameraAngle(1f, 2f); + assertNotEquals(test, test2); + + // Test yaw being null + test = new VirtualCameraAngle(1f, null); + test2 = new VirtualCameraAngle(1f, 2f); + assertNotEquals(test, test2); + + // Test mismatched types + assertNotEquals(test, new Object()); + } } diff --git a/src/test/java/tasmod/virtual/VirtualKeyboardTest.java b/src/test/java/tasmod/virtual/VirtualKeyboardTest.java index 322bb8dd..2ce164b7 100644 --- a/src/test/java/tasmod/virtual/VirtualKeyboardTest.java +++ b/src/test/java/tasmod/virtual/VirtualKeyboardTest.java @@ -259,6 +259,16 @@ void testUpdate(){ assertIterableEquals(expected, actual.getAll()); } + + /** + * Tests update method on a subtick. Should not add a subtick + */ + @Test + void testUpdateOnSubtick() { + VirtualKeyboard actual = new VirtualKeyboard(new LinkedHashSet<>(), new ArrayList<>(), null, false); + + actual.update(VirtualKey.W.getKeycode(), true, 'w'); + } /** * Tests getDifference @@ -313,7 +323,39 @@ void testGetVirtualEventsUnpress() { assertIterableEquals(expected, actual); } + + /** + * Test clearing the keyboard + */ + @Test + void testClear(){ + VirtualKeyboard pressed = new VirtualKeyboard(); + pressed.update(VirtualKey.W.getKeycode(), true, 'w'); + pressed.update(VirtualKey.S.getKeycode(), true, 's'); + pressed.update(VirtualKey.A.getKeycode(), true, 'a'); + + pressed.clear(); + + assertTrue(pressed.getPressedKeys().isEmpty()); + assertTrue(pressed.getSubticks().isEmpty()); + assertTrue(pressed.getCharList().isEmpty()); + } + /** + * Tests virtualEvents behaviour on a subtick, should fail + */ + @Test + void testGetVirtualEventsOnSubtick() { + + VirtualKeyboard pressed = new VirtualKeyboard(new HashSet<>(), new ArrayList<>(), null, false); + + // Load actual with the events + Queue actual = new ConcurrentLinkedQueue<>(); + pressed.getVirtualEvents(pressed, actual); + + assertTrue(actual.isEmpty()); + } + /** * Test repeat events enabled */ From f4369e6261aab50b3cdb35e2befcc04aff4aec50 Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 19 Feb 2024 20:44:51 +0100 Subject: [PATCH 53/57] [PlaybackController] Added warnings that the feature does not work atm --- src/main/java/com/minecrafttas/tasmod/TASmodClient.java | 5 +++++ .../minecrafttas/tasmod/commands/CommandFullPlay.java | 9 +++++---- .../minecrafttas/tasmod/commands/CommandFullRecord.java | 1 + .../com/minecrafttas/tasmod/commands/CommandPlay.java | 1 + .../com/minecrafttas/tasmod/commands/CommandRecord.java | 1 + .../minecrafttas/tasmod/commands/CommandSavestate.java | 1 + 6 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java index 49fe772c..7c96bddb 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java @@ -48,6 +48,9 @@ import net.minecraft.client.multiplayer.ServerData; import net.minecraft.client.settings.KeyBinding; import net.minecraft.server.MinecraftServer; +import net.minecraft.util.text.ChatType; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.util.text.TextFormatting; public class TASmodClient implements ClientModInitializer, EventClientInit, EventPlayerJoinedClientSide, EventOpenGui{ @@ -179,6 +182,7 @@ public void onClientInit(Minecraft mc) { blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Advance Tick", "TASmod", Keyboard.KEY_F9, () -> TASmodClient.tickratechanger.advanceTick(), VirtualKeybindings::isKeyDown))); blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Recording/Playback Stop", "TASmod", Keyboard.KEY_F10, () -> TASmodClient.controller.setTASState(TASstate.NONE), VirtualKeybindings::isKeyDown))); blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Create Savestate", "TASmod", Keyboard.KEY_J, () -> { + Minecraft.getMinecraft().ingameGUI.addChatMessage(ChatType.CHAT, new TextComponentString("Savestates might not work correctly at the moment... rewriting a lot of core features, which might break this...")); try { TASmodClient.client.send(new TASmodBufferBuilder(TASmodPackets.SAVESTATE_SAVE).writeInt(-1)); } catch (Exception e) { @@ -186,6 +190,7 @@ public void onClientInit(Minecraft mc) { } }))); blockedKeybindings.add(keybindManager.registerKeybind(new Keybind("Load Latest Savestate", "TASmod", Keyboard.KEY_K, () -> { + Minecraft.getMinecraft().ingameGUI.addChatMessage(ChatType.CHAT, new TextComponentString(TextFormatting.RED+"Savestates might not work correctly at the moment... rewriting a lot of core features, which might break this...")); try { TASmodClient.client.send(new TASmodBufferBuilder(TASmodPackets.SAVESTATE_LOAD).writeInt(-1)); } catch (Exception e) { diff --git a/src/main/java/com/minecrafttas/tasmod/commands/CommandFullPlay.java b/src/main/java/com/minecrafttas/tasmod/commands/CommandFullPlay.java index d4d3f18b..1dc02367 100644 --- a/src/main/java/com/minecrafttas/tasmod/commands/CommandFullPlay.java +++ b/src/main/java/com/minecrafttas/tasmod/commands/CommandFullPlay.java @@ -14,7 +14,7 @@ import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextFormatting; -public class CommandFullPlay extends CommandBase{ +public class CommandFullPlay extends CommandBase { @Override public String getName() { @@ -28,17 +28,18 @@ public String getUsage(ICommandSender sender) { @Override public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { + sender.sendMessage(new TextComponentString(TextFormatting.RED + "This feature doesn't work at the moment!")); try { TASmod.savestateHandlerServer.loadState(0, false, false); } catch (LoadstateException e) { - sender.sendMessage(new TextComponentString(TextFormatting.RED+"Failed to load a savestate: "+e.getMessage())); + sender.sendMessage(new TextComponentString(TextFormatting.RED + "Failed to load a savestate: " + e.getMessage())); return; } catch (Exception e) { - sender.sendMessage(new TextComponentString(TextFormatting.RED+"Failed to load a savestate: "+e.getCause().toString())); + sender.sendMessage(new TextComponentString(TextFormatting.RED + "Failed to load a savestate: " + e.getCause().toString())); e.printStackTrace(); return; } finally { - TASmod.savestateHandlerServer.state=SavestateState.NONE; + TASmod.savestateHandlerServer.state = SavestateState.NONE; } TASmod.playbackControllerServer.setServerState(TASstate.PLAYBACK); try { diff --git a/src/main/java/com/minecrafttas/tasmod/commands/CommandFullRecord.java b/src/main/java/com/minecrafttas/tasmod/commands/CommandFullRecord.java index 585a50d1..09a1cfe5 100644 --- a/src/main/java/com/minecrafttas/tasmod/commands/CommandFullRecord.java +++ b/src/main/java/com/minecrafttas/tasmod/commands/CommandFullRecord.java @@ -28,6 +28,7 @@ public String getUsage(ICommandSender sender) { @Override public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { + sender.sendMessage(new TextComponentString(TextFormatting.RED+"This feature doesn't work at the moment!")); try { TASmod.savestateHandlerServer.saveState(0, false); } catch (SavestateException e) { diff --git a/src/main/java/com/minecrafttas/tasmod/commands/CommandPlay.java b/src/main/java/com/minecrafttas/tasmod/commands/CommandPlay.java index 2f03c713..64b0f027 100644 --- a/src/main/java/com/minecrafttas/tasmod/commands/CommandPlay.java +++ b/src/main/java/com/minecrafttas/tasmod/commands/CommandPlay.java @@ -38,6 +38,7 @@ public List getAliases() { @Override public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { + sender.sendMessage(new TextComponentString(TextFormatting.RED + "This feature doesn't work at the moment!")); if (!(sender instanceof EntityPlayer)) { return; } diff --git a/src/main/java/com/minecrafttas/tasmod/commands/CommandRecord.java b/src/main/java/com/minecrafttas/tasmod/commands/CommandRecord.java index 56f58e36..6373f781 100644 --- a/src/main/java/com/minecrafttas/tasmod/commands/CommandRecord.java +++ b/src/main/java/com/minecrafttas/tasmod/commands/CommandRecord.java @@ -38,6 +38,7 @@ public List getAliases() { @Override public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { + sender.sendMessage(new TextComponentString(TextFormatting.RED + "This feature doesn't work at the moment!")); if (!(sender instanceof EntityPlayer)) { return; } diff --git a/src/main/java/com/minecrafttas/tasmod/commands/CommandSavestate.java b/src/main/java/com/minecrafttas/tasmod/commands/CommandSavestate.java index 7aee1de1..0d997da9 100644 --- a/src/main/java/com/minecrafttas/tasmod/commands/CommandSavestate.java +++ b/src/main/java/com/minecrafttas/tasmod/commands/CommandSavestate.java @@ -37,6 +37,7 @@ public int getRequiredPermissionLevel() { @Override public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { + sender.sendMessage(new TextComponentString("Savestates might not work correctly at the moment... rewriting a lot of core features, which might break this...")); if (args.length == 0) { sendHelp(sender); } else if (args.length >= 1) { From c123ecc9d465f1bc2b783613d6acb9cabb3d297d Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 19 Feb 2024 21:55:57 +0100 Subject: [PATCH 54/57] [VirtualInput] VirtualInput.CAMERA tests - Moved -100 subtraction on eventKey to #update() to fix tests --- .../tasmod/virtual/VirtualInput.java | 77 +++++++---- .../java/tasmod/virtual/VirtualInputTest.java | 124 +++++++++++++++++- 2 files changed, 168 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index 9d55fe88..bebbcfef 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -81,14 +81,14 @@ public void update(GuiScreen currentScreen) { } while (Mouse.next()) { if (currentScreen == null) { - MOUSE.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), 0, 0); + MOUSE.updateNextMouse(Mouse.getEventButton()-100, Mouse.getEventButtonState(), Mouse.getEventDWheel(), 0, 0); } else { Ducks.GuiScreenDuck screen = (Ducks.GuiScreenDuck) currentScreen; int eventX = screen.unscaleX(Mouse.getEventX()); int eventY = screen.unscaleY(Mouse.getEventY()); eventX = PointerNormalizer.getNormalizedX(eventX); eventY = PointerNormalizer.getNormalizedY(eventY); - MOUSE.updateNextMouse(Mouse.getEventButton(), Mouse.getEventButtonState(), Mouse.getEventDWheel(), eventX, eventY); + MOUSE.updateNextMouse(Mouse.getEventButton()-100, Mouse.getEventButtonState(), Mouse.getEventDWheel(), eventX, eventY); } } } @@ -389,7 +389,6 @@ public VirtualMouseInput(VirtualMouse preloadedMouse) { * @param cursorY The y coordinate of the cursot of this event */ public void updateNextMouse(int keycode, boolean keystate, int scrollwheel, int cursorX, int cursorY) { - keycode-=100; LOGGER.debug(LoggerMarkers.Mouse,"Update: {} ({}), {}, {}, {}, {}", keycode, VirtualKey.getName(keycode), keystate, scrollwheel, cursorX, cursorY); // Activate with -Dtasmod.marker.mouse=ACCEPT in VM arguments (and -Dtasmod.log.level=debug) nextMouse.update(keycode, keystate, scrollwheel, cursorX, cursorY); } @@ -439,19 +438,33 @@ public int getEventMouseScrollWheel() { } /** - * @return The x coordinate of the cursor of {@link #currentMouseEvent} + * @return The scaled x coordinate of the cursor of {@link #currentMouseEvent} */ public int getEventCursorX() { - return PointerNormalizer.reapplyScalingX(currentMouseEvent.getCursorX()); + return PointerNormalizer.reapplyScalingX(getNormalizedCursorX()); } /** - * @return The y coordinate of the cursor of {@link #currentMouseEvent} + * @return The x coordinate of the cursor of {@link #currentMouseEvent} + */ + public int getNormalizedCursorX() { + return currentMouseEvent.getCursorX(); + } + + /** + * @return The scaled y coordinate of the cursor of {@link #currentMouseEvent} */ public int getEventCursorY() { - return PointerNormalizer.reapplyScalingY(currentMouseEvent.getCursorY()); + return PointerNormalizer.reapplyScalingY(getNormalizedCursorY()); } - + + /** + * @return The y coordinate of the cursor of {@link #currentMouseEvent} + */ + public int getNormalizedCursorY() { + return currentMouseEvent.getCursorY(); + } + /** * If the key is currently down and recognised by Minecraft * @param keycode The keycode of the key in question @@ -476,11 +489,14 @@ public boolean willKeyBeDown(int keycode) { /** * Subclass of {@link VirtualInput} handling camera angle logic.
*
- * Unlike {@link VirtualKeyboardInput} or {@link VirtualMouseInput} no subtick behaviour is implemented,
+ * Unlike {@link VirtualKeyboardInput} or {@link VirtualMouseInput} no subtick + * behaviour is implemented,
* making this a simple pitch and yaw storing class, allowing for redirection. *
- * In theory, subtick behaviour is possible, but only useful for interpolation,
- * as the camera angle is only updated every tick (see {@link com.minecrafttas.tasmod.mixin.playbackhooks.MixinEntityRenderer}). + * In theory, subtick behaviour is possible, but only useful for + * interpolation,
+ * as the camera angle is only updated every tick (see + * {@link com.minecrafttas.tasmod.mixin.playbackhooks.MixinEntityRenderer}). */ public class VirtualCameraAngleInput { /** @@ -489,9 +505,11 @@ public class VirtualCameraAngleInput { private final VirtualCameraAngle currentCameraAngle; private final VirtualCameraAngle nextCameraAngle = new VirtualCameraAngle(); private final List cameraAngleInterpolationStates = new ArrayList<>(); - + /** - * Constructor to preload the {@link #currentCameraAngle} with an existing camera angle + * Constructor to preload the {@link #currentCameraAngle} with an existing + * camera angle + * * @param preloadedCamera The new {@link #currentCameraAngle} */ public VirtualCameraAngleInput(VirtualCameraAngle preloadedCamera) { @@ -500,51 +518,52 @@ public VirtualCameraAngleInput(VirtualCameraAngle preloadedCamera) { /** * Update the camera angle + * * @see com.minecrafttas.tasmod.mixin.playbackhooks.MixinEntityRenderer#runUpdate(float); * @param pitch Absolute rotationPitch of the player - * @param yaw Absolute rotationYaw of the player + * @param yaw Absolute rotationYaw of the player */ public void updateNextCameraAngle(float pitch, float yaw) { // LOGGER.debug("Pitch: {}, Yaw: {}", pitch, yaw); nextCameraAngle.update(pitch, yaw); } - + public void nextCameraTick() { nextCameraAngle.getStates(cameraAngleInterpolationStates); currentCameraAngle.copyFrom(nextCameraAngle); } - + public void setCamera(Float pitch, Float yaw) { nextCameraAngle.set(pitch, yaw); } - + public Float getCurrentPitch() { return currentCameraAngle.getPitch(); } - + public Float getCurrentYaw() { return currentCameraAngle.getYaw(); } - - public Triple getInterpolatedState(float partialTick, float pitch, float yaw, boolean enable){ - if(!enable) { - return Triple.of(nextCameraAngle.getPitch()==null ? pitch : nextCameraAngle.getPitch(), nextCameraAngle.getYaw()==null? pitch : nextCameraAngle.getYaw()+180, 0f); + + public Triple getInterpolatedState(float partialTick, float pitch, float yaw, boolean enable) { + if (!enable) { + return Triple.of(nextCameraAngle.getPitch() == null ? pitch : nextCameraAngle.getPitch(), nextCameraAngle.getYaw() == null ? pitch : nextCameraAngle.getYaw() + 180, 0f); } - + float interpolatedPitch = 0f; float interpolatedYaw = 0f; - - if(cameraAngleInterpolationStates.size()==1) { // If no interpolation data was specified, interpolate over 2 values + + if (cameraAngleInterpolationStates.size() == 1) { // If no interpolation data was specified, interpolate over 2 values interpolatedPitch = (float) MathHelper.clampedLerp(currentCameraAngle.getPitch(), cameraAngleInterpolationStates.get(0).getPitch(), partialTick); interpolatedYaw = (float) MathHelper.clampedLerp(currentCameraAngle.getYaw(), cameraAngleInterpolationStates.get(0).getYaw() + 180, partialTick); } else { - - int index = (int)MathHelper.clampedLerp(0, cameraAngleInterpolationStates.size(), partialTick); // Get interpolate index - + + int index = (int) MathHelper.clampedLerp(0, cameraAngleInterpolationStates.size(), partialTick); // Get interpolate index + interpolatedPitch = cameraAngleInterpolationStates.get(index).getPitch(); interpolatedYaw = cameraAngleInterpolationStates.get(index).getYaw(); } - + return Triple.of(interpolatedPitch, interpolatedYaw, 0f); } } diff --git a/src/test/java/tasmod/virtual/VirtualInputTest.java b/src/test/java/tasmod/virtual/VirtualInputTest.java index 30ce0947..dc6a6b2c 100644 --- a/src/test/java/tasmod/virtual/VirtualInputTest.java +++ b/src/test/java/tasmod/virtual/VirtualInputTest.java @@ -5,12 +5,15 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; -import com.minecrafttas.tasmod.virtual.*; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.junit.jupiter.api.Test; +import com.minecrafttas.tasmod.virtual.VirtualCameraAngle; import com.minecrafttas.tasmod.virtual.VirtualInput; +import com.minecrafttas.tasmod.virtual.VirtualKey; +import com.minecrafttas.tasmod.virtual.VirtualKeyboard; +import com.minecrafttas.tasmod.virtual.VirtualMouse; class VirtualInputTest { @@ -28,6 +31,39 @@ void testConstructor() { assertNotNull(virtual.CAMERA_ANGLE); } + /** + * Testing isKeyDown + */ + @Test + void testIsKeyDown() { + VirtualKeyboard preloadedKeyboard = new VirtualKeyboard(); + VirtualMouse preloadedMouse = new VirtualMouse(); + VirtualCameraAngle preloadedCameraAngle = new VirtualCameraAngle(0f, 0f); + + preloadedKeyboard.update(VirtualKey.W.getKeycode(), true, 'w'); + preloadedMouse.update(VirtualKey.LC.getKeycode(), true, 15, 0, 0); + preloadedCameraAngle.update(1f, 2f); + + VirtualInput input = new VirtualInput(LOGGER, preloadedKeyboard, preloadedMouse, preloadedCameraAngle); + + assertTrue(input.isKeyDown(VirtualKey.W.getKeycode())); + assertTrue(input.isKeyDown(VirtualKey.LC.getKeycode())); + } + + /** + * Testing willKeyBeDown + */ + @Test + void testWillKeyBeDown() { + VirtualInput input = new VirtualInput(LOGGER); + + input.KEYBOARD.updateNextKeyboard(VirtualKey.W.getKeycode(), true, 'w'); + input.MOUSE.updateNextMouse(VirtualKey.LC.getKeycode(), true, 15, 0, 0); + + assertTrue(input.willKeyBeDown(VirtualKey.W.getKeycode())); + assertTrue(input.willKeyBeDown(VirtualKey.LC.getKeycode())); + } + /** * Tests if a keyboard can be preloaded */ @@ -71,7 +107,7 @@ void testKeyboardAddPresses() { // Load the next keyboard events virtual.KEYBOARD.nextKeyboardTick(); - //W + // W // Load new subtick assertTrue(virtual.KEYBOARD.nextKeyboardSubtick()); @@ -81,7 +117,7 @@ void testKeyboardAddPresses() { assertTrue(virtual.KEYBOARD.getEventKeyboardState()); assertEquals('w', virtual.KEYBOARD.getEventKeyboardCharacter()); - //A + // A // Load new subtick assertTrue(virtual.KEYBOARD.nextKeyboardSubtick()); @@ -91,7 +127,7 @@ void testKeyboardAddPresses() { assertTrue(virtual.KEYBOARD.getEventKeyboardState()); assertEquals('a', virtual.KEYBOARD.getEventKeyboardCharacter()); - //S + // S // Load new subtick assertTrue(virtual.KEYBOARD.nextKeyboardSubtick()); @@ -131,4 +167,84 @@ void testKeyboardRemovePresses() { // Check if subtick list is empty assertFalse(virtual.KEYBOARD.nextKeyboardSubtick()); } + + /** + * Test simulating mouse presses + */ + @Test + void testMousePresses() { + VirtualInput virtual = new VirtualInput(LOGGER); + + // Simulate mouse presses + virtual.MOUSE.updateNextMouse(VirtualKey.LC.getKeycode(), true, 15, 10, 20); + virtual.MOUSE.updateNextMouse(VirtualKey.MC.getKeycode(), true, -15, 30, 21); + + // Load the next mouse events + virtual.MOUSE.nextMouseTick(); + + // LC + + // Load the new subtick + assertTrue(virtual.MOUSE.nextMouseSubtick()); + + //Read out the values from the subtick + assertEquals(VirtualKey.LC.getKeycode(), virtual.MOUSE.getEventMouseKey()); + assertTrue(virtual.MOUSE.getEventMouseState()); + assertEquals(15, virtual.MOUSE.getEventMouseScrollWheel()); + assertEquals(10, virtual.MOUSE.getNormalizedCursorX()); + assertEquals(20, virtual.MOUSE.getNormalizedCursorY()); + + // MC + + // Load new subtick + assertTrue(virtual.MOUSE.nextMouseSubtick()); + + //Read out the values from the subtick + assertEquals(VirtualKey.MC.getKeycode(), virtual.MOUSE.getEventMouseKey()); + assertTrue(virtual.MOUSE.getEventMouseState()); + assertEquals(-15, virtual.MOUSE.getEventMouseScrollWheel()); + assertEquals(30, virtual.MOUSE.getNormalizedCursorX()); + assertEquals(21, virtual.MOUSE.getNormalizedCursorY()); + + // Check if subtick list is empty + assertFalse(virtual.MOUSE.nextMouseSubtick()); + } + + /** + * Test removing mouse presses + */ + @Test + void testMouseRemovePresses() { + VirtualMouse preloadedMouse = new VirtualMouse(); + preloadedMouse.update(VirtualKey.LC.getKeycode(), true, 15, 10, 20); + + // Load preloaded mouse + VirtualInput virtual = new VirtualInput(LOGGER, new VirtualKeyboard(), preloadedMouse, new VirtualCameraAngle()); + + // Unpress LC + virtual.MOUSE.updateNextMouse(VirtualKey.LC.getKeycode(), false, 10, 20, 30); + + // Load the next mouse events + virtual.MOUSE.nextMouseTick(); + + // Load new subtick + assertTrue(virtual.MOUSE.nextMouseSubtick()); + + assertEquals(VirtualKey.LC.getKeycode(), virtual.MOUSE.getEventMouseKey()); + assertFalse(virtual.MOUSE.getEventMouseState()); + assertEquals(10, virtual.MOUSE.getEventMouseScrollWheel()); + assertEquals(20, virtual.MOUSE.getNormalizedCursorX()); + assertEquals(30, virtual.MOUSE.getNormalizedCursorY()); + + // Check if subtick list is empty + assertFalse(virtual.MOUSE.nextMouseSubtick()); + } + + /** + * Test camera angle + */ + @Test + void testCameraAngles() { + + } } From 8dde4203adb26a7fec5b50193d3ce7946903541c Mon Sep 17 00:00:00 2001 From: Scribble Date: Wed, 21 Feb 2024 22:14:35 +0100 Subject: [PATCH 55/57] [VirtualInput] Add documentation for VirtualCameraAngleInput --- .../tasmod/virtual/VirtualInput.java | 117 +++++++++++++++--- 1 file changed, 102 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index bebbcfef..bab47891 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -11,6 +11,7 @@ import org.lwjgl.input.Mouse; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import com.minecrafttas.tasmod.mixin.playbackhooks.MixinEntityRenderer; import com.minecrafttas.tasmod.mixin.playbackhooks.MixinMinecraft; import com.minecrafttas.tasmod.util.Ducks; import com.minecrafttas.tasmod.util.LoggerMarkers; @@ -478,7 +479,7 @@ public boolean isKeyDown(int keycode) { * If the key will be down and recognised in the next tick by Minecraft.
* This is equal to checking if a key on the physical mouse is pressed * @param keycode The keycode of the key in question - * @return Whether the key of the {@link #nextMouse} is down + * @return Whether the key of the {@link #nextMouse} is down3 */ public boolean willKeyBeDown(int keycode) { return nextMouse.isKeyDown(keycode); @@ -489,21 +490,70 @@ public boolean willKeyBeDown(int keycode) { /** * Subclass of {@link VirtualInput} handling camera angle logic.
*
- * Unlike {@link VirtualKeyboardInput} or {@link VirtualMouseInput} no subtick - * behaviour is implemented,
- * making this a simple pitch and yaw storing class, allowing for redirection. + * Normally, the camera angle is updated every frame.
+ * This meant that inputs on mouse and keyboard, updated every tick,
+ * had to sync with the camera angle, updated every frame, which desynced in some edgecases.
*
- * In theory, subtick behaviour is possible, but only useful for - * interpolation,
- * as the camera angle is only updated every tick (see - * {@link com.minecrafttas.tasmod.mixin.playbackhooks.MixinEntityRenderer}). + * After extensive testing, the decision was made to conform the camera to update every tick,
+ * instead of every frame. By itself, this meant that moving the camera felt really laggy
+ *
+ * Therefore an interpolation system was created that seperated the camera angle from the player head rotation,
+ * which are usually the synced. + *
+ * While the camera is the angle displayed on screen, the player rotation is responsible for the logic,
+ * e.g. at which block the player is currently aiming.
+ * This calls for a similar architecture as the {@link VirtualKeyboardInput} and the {@link VirtualMouseInput}. + *
+ * The {@link VirtualCameraAngleInput#currentCameraAngle} represents the player rotation, updated every tick
+ * and the {@link VirtualCameraAngleInput#nextCameraAngle} represents the camera angle, updated every frame. + *
+ * In pseudocode, the tick conformed camera looks like this: + *
+	 * public void runGameLoop() {// The main update loop, every frame
+	 * 	for(int i;i
+	 * Note that the camera is updated after the tick function.
+	 * Now in this pseudocode, the following methods from this class are injected like so:
+	 * 
+	 * public void runGameLoop() {// The main update loop, every frame
+	 * 	for(int i;i
+	 * 
+	 * While there is "subtick" behavior in this implementation,
+ * it is only used for the interpolation of the camera angle and not for the player rotation.
+ * This way you can customize the interpolated frames during playback. */ public class VirtualCameraAngleInput { /** - * The current camera angle + * The current camera angle in game.
+ *
+ * Updated every tick in {@link #nextCameraTick()} */ private final VirtualCameraAngle currentCameraAngle; + /** + * The new camera angle
+ *
+ * updated every frame in {@link #updateNextCameraAngle(float, float)}
+ * and updates {@link #currentCameraAngle} in {@link #nextCameraTick()} + */ private final VirtualCameraAngle nextCameraAngle = new VirtualCameraAngle(); + /** + * States of the {@link #nextCameraAngle} made during the tick.
+ * Is updated in {@link #nextCameraTick()} + */ private final List cameraAngleInterpolationStates = new ArrayList<>(); /** @@ -517,34 +567,71 @@ public VirtualCameraAngleInput(VirtualCameraAngle preloadedCamera) { } /** - * Update the camera angle + * Update the camera angle.
+ *
+ * Runs every frame * * @see com.minecrafttas.tasmod.mixin.playbackhooks.MixinEntityRenderer#runUpdate(float); - * @param pitch Absolute rotationPitch of the player - * @param yaw Absolute rotationYaw of the player + * @param pitchDelta Relative rotationPitch delta from LWJGLs mouse delta. + * @param yawDelta Relative rotationYaw delta from LWJGLs mouse delta. */ - public void updateNextCameraAngle(float pitch, float yaw) { + public void updateNextCameraAngle(float pitchDelta, float yawDelta) { // LOGGER.debug("Pitch: {}, Yaw: {}", pitch, yaw); - nextCameraAngle.update(pitch, yaw); + nextCameraAngle.update(pitchDelta, yawDelta); } + /** + * Updates the {@link #currentCameraAngle} and {@link #cameraAngleInterpolationStates}.
+ * Runs every tick. + * + * @see MixinEntityRenderer#runUpdate(float) + */ public void nextCameraTick() { nextCameraAngle.getStates(cameraAngleInterpolationStates); currentCameraAngle.copyFrom(nextCameraAngle); } + /** + * Sets the camera coordinates directly.
+ *
+ * The camera angle is stored in absolute coordinates,
+ * which should match the vanilla coordinates displayed in F3
+ *
+ * This creates a problem when initializing the world, we don't know the camera angle the player has.
+ * Without this, the player would always start facing the 0;0 coordinate. + *
+ * To fix this, the camera is initialized with pitch and yaw being null. If that is the case,
+ * then the current player rotation is set with this method in {@link MixinEntityRenderer#runUpdate(float)} + * @param pitch The absolute player pitch + * @param yaw The absolute player yaw + */ public void setCamera(Float pitch, Float yaw) { nextCameraAngle.set(pitch, yaw); } + /** + * @return The absolute pitch coordinate of the player. May be null when it's initialized + */ public Float getCurrentPitch() { return currentCameraAngle.getPitch(); } - + + /** + * @return The absolute yaw coordinate of the player. May be null when it's initialized + */ public Float getCurrentYaw() { return currentCameraAngle.getYaw(); } + /** + * Gets the absolute coordinates of the camera angle + * + * @param partialTick The partial ticks of the timer + * @param pitch The original pitch of the camera + * @param yaw The original yaw of the camera + * @param enable Whether the custom interpolation is enabled. Enabled during playback. + * @return A triple of pitch, yaw and roll, as left, middle and right respectively + */ public Triple getInterpolatedState(float partialTick, float pitch, float yaw, boolean enable) { if (!enable) { return Triple.of(nextCameraAngle.getPitch() == null ? pitch : nextCameraAngle.getPitch(), nextCameraAngle.getYaw() == null ? pitch : nextCameraAngle.getYaw() + 180, 0f); From 7006c51dfd38139a04b2b5588d34a27125fde74e Mon Sep 17 00:00:00 2001 From: Scribble Date: Thu, 22 Feb 2024 12:01:46 +0100 Subject: [PATCH 56/57] [VirtualInput] Added tests for VirtualCameraAngleInput --- .../playbackhooks/MixinEntityRenderer.java | 2 +- .../tasmod/virtual/VirtualInput.java | 4 +- .../java/tasmod/virtual/VirtualInputTest.java | 113 +++++++++++++++++- 3 files changed, 112 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java index 76699ffd..ee008ef1 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java @@ -85,7 +85,7 @@ public void playback_injectAtStartSection(float partialTicks, long nanoTime, Cal } } - @Redirect(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/EntityPlayerSP;turn(FF)V")) + @Redirect(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;turn(FF)V")) public void playback_stopVanilla(EntityPlayerSP player, float deltaYaw, float deltaPitch){ if(TASmodClient.tickratechanger.ticksPerSecond == 0){ player.turn(deltaYaw, deltaPitch); diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index bab47891..b51a7a87 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -633,7 +633,7 @@ public Float getCurrentYaw() { * @return A triple of pitch, yaw and roll, as left, middle and right respectively */ public Triple getInterpolatedState(float partialTick, float pitch, float yaw, boolean enable) { - if (!enable) { + if (!enable) { // If interpolation is not enabled, return the values of nextCameraAngle return Triple.of(nextCameraAngle.getPitch() == null ? pitch : nextCameraAngle.getPitch(), nextCameraAngle.getYaw() == null ? pitch : nextCameraAngle.getYaw() + 180, 0f); } @@ -641,7 +641,7 @@ public Triple getInterpolatedState(float partialTick, float float interpolatedYaw = 0f; if (cameraAngleInterpolationStates.size() == 1) { // If no interpolation data was specified, interpolate over 2 values - interpolatedPitch = (float) MathHelper.clampedLerp(currentCameraAngle.getPitch(), cameraAngleInterpolationStates.get(0).getPitch(), partialTick); + interpolatedPitch = (float) MathHelper.clampedLerp(cameraAngleInterpolationStates.get(0).getPitch(), currentCameraAngle.getPitch(), partialTick); interpolatedYaw = (float) MathHelper.clampedLerp(currentCameraAngle.getYaw(), cameraAngleInterpolationStates.get(0).getYaw() + 180, partialTick); } else { diff --git a/src/test/java/tasmod/virtual/VirtualInputTest.java b/src/test/java/tasmod/virtual/VirtualInputTest.java index dc6a6b2c..060ce206 100644 --- a/src/test/java/tasmod/virtual/VirtualInputTest.java +++ b/src/test/java/tasmod/virtual/VirtualInputTest.java @@ -5,8 +5,10 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import org.apache.commons.lang3.tuple.Triple; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import com.minecrafttas.tasmod.virtual.VirtualCameraAngle; @@ -134,7 +136,7 @@ void testKeyboardAddPresses() { // Read out values from the subtick assertEquals(VirtualKey.S.getKeycode(), virtual.KEYBOARD.getEventKeyboardKey()); - assertEquals(true, virtual.KEYBOARD.getEventKeyboardState()); + assertTrue(virtual.KEYBOARD.getEventKeyboardState()); assertEquals('s', virtual.KEYBOARD.getEventKeyboardCharacter()); // Check if subtick list is empty @@ -241,10 +243,113 @@ void testMouseRemovePresses() { } /** - * Test camera angle + * Test camera angle on tick */ @Test - void testCameraAngles() { - + void testCurrentCameraAngles() { + VirtualInput virtual = new VirtualInput(LOGGER); + + virtual.CAMERA_ANGLE.setCamera(0f, 0f); + virtual.CAMERA_ANGLE.updateNextCameraAngle(10f, 20f); + virtual.CAMERA_ANGLE.updateNextCameraAngle(20f, 30f); + + virtual.CAMERA_ANGLE.nextCameraTick(); + + assertEquals(30f, virtual.CAMERA_ANGLE.getCurrentPitch()); + assertEquals(50f, virtual.CAMERA_ANGLE.getCurrentYaw()); + } + + /** + * Test interpolation but with no playback running. Returns the valuies of nextCameraAngle + */ + @Test + void testInterpolationDisabled(){ + VirtualInput virtual = new VirtualInput(LOGGER); + + virtual.CAMERA_ANGLE.setCamera(0f, 0f); + virtual.CAMERA_ANGLE.updateNextCameraAngle(10f, 20f); + virtual.CAMERA_ANGLE.updateNextCameraAngle(20f, 30f); + + Triple expected = Triple.of(30f, 50f+180f, 0f); + Triple actual = virtual.CAMERA_ANGLE.getInterpolatedState(0f, 1f, 2f, false); + + assertEquals(expected, actual); + } + + /** + * Test interpolation but with playback running. + */ + @Test + void testInterpolationEnabled(){ + VirtualInput virtual = new VirtualInput(LOGGER); + + virtual.CAMERA_ANGLE.setCamera(0f, 0f); + virtual.CAMERA_ANGLE.updateNextCameraAngle(0f, 0f); + virtual.CAMERA_ANGLE.updateNextCameraAngle(10f, 10f); + virtual.CAMERA_ANGLE.updateNextCameraAngle(10f, 10f); + virtual.CAMERA_ANGLE.updateNextCameraAngle(10f, 10f); + virtual.CAMERA_ANGLE.updateNextCameraAngle(10f, 10f); + virtual.CAMERA_ANGLE.updateNextCameraAngle(10f, 10f); + virtual.CAMERA_ANGLE.updateNextCameraAngle(10f, 10f); + virtual.CAMERA_ANGLE.updateNextCameraAngle(10f, 10f); + virtual.CAMERA_ANGLE.updateNextCameraAngle(10f, 10f); + virtual.CAMERA_ANGLE.updateNextCameraAngle(10f, 10f); + + virtual.CAMERA_ANGLE.nextCameraTick(); + + Triple expected = Triple.of(0f, 0f, 0f); + Triple actual = virtual.CAMERA_ANGLE.getInterpolatedState(0f, 0f, 0f, true); + assertEquals(expected, actual); + + expected = Triple.of(10f, 10f, 0f); + actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.1f, 0f, 0f, true); + assertEquals(expected, actual); + + expected = Triple.of(10f, 10f, 0f); + actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.199f, 0f, 0f, true); + assertEquals(expected, actual); + + expected = Triple.of(20f, 20f, 0f); + actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.2f, 0f, 0f, true); + assertEquals(expected, actual); + + expected = Triple.of(30f, 30f, 0f); + actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.3f, 0f, 0f, true); + assertEquals(expected, actual); + + expected = Triple.of(40f, 40f, 0f); + actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.4f, 0f, 0f, true); + assertEquals(expected, actual); + + expected = Triple.of(50f, 50f, 0f); + actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.5f, 0f, 0f, true); + assertEquals(expected, actual); + + expected = Triple.of(60f, 60f, 0f); + actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.6f, 0f, 0f, true); + assertEquals(expected, actual); + } + + /** + * Test interpolation but with playback running, but there are only 2 values + */ + @Test + @Disabled + void testInterpolationEnabledLegacy(){ + VirtualInput virtual = new VirtualInput(LOGGER); + + virtual.CAMERA_ANGLE.setCamera(0f, 0f); + + virtual.CAMERA_ANGLE.updateNextCameraAngle(10f, 10f); + + virtual.CAMERA_ANGLE.nextCameraTick(); + + Triple expected = Triple.of(0f, 0f, 0f); + Triple actual = virtual.CAMERA_ANGLE.getInterpolatedState(0f, 0f, 0f, true); + assertEquals(expected, actual); + + expected = Triple.of(10f, 10f, 0f); + actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.3f, 0f, 0f, true); + assertEquals(expected, actual); } } From 4a5e9f54dd1e505ee3fc5ab0ebea04bda6431404 Mon Sep 17 00:00:00 2001 From: Scribble Date: Thu, 22 Feb 2024 14:00:57 +0100 Subject: [PATCH 57/57] [VirtualInput] Various documentation improvements - Removed VirtualButtonEvent inner class in VirtualEvent --- .../tasmod/virtual/Subtickable.java | 8 ++-- .../tasmod/virtual/VirtualInput.java | 9 ++-- .../tasmod/virtual/VirtualKey.java | 5 +++ .../tasmod/virtual/VirtualKeybindings.java | 40 ++++++++++++------ .../tasmod/virtual/VirtualKeyboard.java | 4 +- .../event/VirtualCameraAngleEvent.java | 27 ------------ .../tasmod/virtual/event/VirtualEvent.java | 42 +++++++++---------- .../virtual/event/VirtualKeyboardEvent.java | 14 +++---- .../virtual/event/VirtualMouseEvent.java | 6 +-- 9 files changed, 71 insertions(+), 84 deletions(-) delete mode 100644 src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualCameraAngleEvent.java diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/Subtickable.java b/src/main/java/com/minecrafttas/tasmod/virtual/Subtickable.java index c0cd892b..56a0873e 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/Subtickable.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/Subtickable.java @@ -36,7 +36,7 @@ protected Subtickable(List subtickList, boolean ignoreFirstUpdate) { /** * Adds a peripheral to {@link #subtickList} - * + * * @param peripheral The peripheral to add */ protected void addSubtick(T peripheral) { @@ -60,11 +60,11 @@ public boolean isParent() { /** * Gets all peripheral states in an immutable list.
*
- * This list is comprised of {@link #subtickList} and the current peripheral + * This list comprises {@link #subtickList} and the current peripheral * state added after that
* This will result in a list where the first element is the oldest state and * the last being the current state. - * + * * @return An immutable list of keyboard states */ @SuppressWarnings("unchecked") @@ -78,7 +78,7 @@ protected void clear() { /** * Retrieves and sets {@link #ignoreFirstUpdate} to false - * + * * @return If the first update should be ignored */ protected boolean ignoreFirstUpdate() { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index b51a7a87..b59f7a25 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -26,8 +26,9 @@ * Main component for redirecting inputs.
*
* This class mimics the LWJGL classes {@link org.lwjgl.input.Keyboard} and - * {@link org.lwjgl.input.Mouse}.
- *
+ * {@link org.lwjgl.input.Mouse} and redirects the camera angle and player rotation
+ * + * @author Scribble */ public class VirtualInput { private final Logger LOGGER; @@ -46,7 +47,7 @@ public class VirtualInput { /** * Creates a new virtual input with an empty {@link VirtualKeyboardInput}, {@link VirtualMouseInput} and {@link VirtualCameraAngleInput} - * @param logger + * @param logger The logger instance */ public VirtualInput(Logger logger) { this(logger, new VirtualKeyboard(), new VirtualMouse(), new VirtualCameraAngle()); @@ -497,7 +498,7 @@ public boolean willKeyBeDown(int keycode) { * After extensive testing, the decision was made to conform the camera to update every tick,
* instead of every frame. By itself, this meant that moving the camera felt really laggy
*
- * Therefore an interpolation system was created that seperated the camera angle from the player head rotation,
+ * Therefore, an interpolation system was created that seperated the camera angle from the player head rotation,
* which are usually the synced. *
* While the camera is the angle displayed on screen, the player rotation is responsible for the logic,
diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey.java index 2c175166..98e2d273 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKey.java @@ -1,5 +1,10 @@ package com.minecrafttas.tasmod.virtual; +/** + * List of all names and keycodes from the keyboard and the mouse. + * + * @author Scribble + */ public enum VirtualKey { // Keyboard ZERO(0), diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeybindings.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeybindings.java index c2130f56..d79cc738 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeybindings.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeybindings.java @@ -20,7 +20,7 @@ * Applies special rules to vanilla keybindings.
*
* Using {@link #isKeyDown(KeyBinding)}, the registered keybindings will work - * inside of gui screens
+ * inside gui screens
*
* {@link #isKeyDownExceptTextfield(KeyBinding)} does the same, but excludes * textfields, certain guiscreens, and the keybinding options
@@ -32,18 +32,33 @@ * */ public class VirtualKeybindings { - private static Minecraft mc = Minecraft.getMinecraft(); - private static long cooldown = 50*5; - private static HashMap cooldownHashMap = Maps.newHashMap(); - private static List blockedKeys = new ArrayList<>(); + /** + * The Minecraft instance + */ + private static final Minecraft mc = Minecraft.getMinecraft(); + /** + * The standard cooldown for a keybinding in milliseconds + */ + private static final long cooldown = 50*5; + /** + * Stores the start time of a keybinding, used for cooldown calculation + */ + private static final HashMap cooldownHashMap = new HashMap<>(); + /** + * A list of keybindings which will not be recorded or pressed during recording or playback. + */ + private static final List blockedKeys = new ArrayList<>(); + /** + * True when a text field is currently focused in a gui, like the creative search tab + */ public static boolean focused = false; /** * Checks whether the keycode is pressed, regardless of any gui screens * - * @param keybind - * @return + * @param keybind The keybind to check + * @return If the keybind is down */ public static boolean isKeyDown(KeyBinding keybind) { @@ -77,10 +92,12 @@ public static boolean isKeyDown(KeyBinding keybind) { } /** - * Checks whether the key is down, but stops when certain conditions apply + * Checks whether the key is down, but returns false if a text field is focused in a gui.
+ *
+ * Always returns false if GuiChat and GuiEditSign is open. * - * @param keybind - * @return + * @param keybind The keybinding to check + * @return If a keybind is pressed. Returns false if a text field in a gui is focused */ public static boolean isKeyDownExceptTextfield(KeyBinding keybind) { if (mc.currentScreen instanceof GuiChat || mc.currentScreen instanceof GuiEditSign || (focused && mc.currentScreen != null)) { @@ -92,7 +109,7 @@ public static boolean isKeyDownExceptTextfield(KeyBinding keybind) { /** * Registers keybindings that should not be recorded or played back in a TAS * - * @param keybind + * @param keybind The keybinding to block */ public static void registerBlockedKeyBinding(KeyBinding keybind) { blockedKeys.add(keybind); @@ -111,5 +128,4 @@ public static boolean isKeyCodeAlwaysBlocked(int keycode) { } return false; } - } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java index d12bea00..80adab57 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java @@ -52,13 +52,13 @@ * 32, true, d // D is pressed *
*

Subticks

- * Minecraft updates it's keyboard every tick. All the key events that occur inbetween are stored,
+ * Minecraft updates its keyboard every tick. All the key events that occur inbetween are stored,
* then read out when a new tick has started.
We call these "inbetween" ticks subticks.
*

Parent->Subtick

* In a previous version of this keyboard, subticks were bundeled and flattened into one keyboard state.
* After all, Minecraft updates only occur once every tick, storing subticks seemed unnecessary.
*
- * However this posed some usability issues when playing in a low game speed via {@link com.minecrafttas.tasmod.tickratechanger.TickrateChangerClient}.
+ * However, this posed some usability issues when playing in a low game speed via {@link com.minecrafttas.tasmod.tickratechanger.TickrateChangerClient}.
* Now you had to hold the key until the next tick to get it recognised by the game.
*
* To fix this, now every subtick is stored as a keyboard state as well.
diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualCameraAngleEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualCameraAngleEvent.java deleted file mode 100644 index 21e85aa4..00000000 --- a/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualCameraAngleEvent.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.minecrafttas.tasmod.virtual.event; - -public class VirtualCameraAngleEvent extends VirtualEvent { - private float pitchDelta; - private float yawDelta; - - public VirtualCameraAngleEvent(float pitchDelta, float yawDelta) { - this.pitchDelta = pitchDelta; - this.yawDelta = yawDelta; - } - - public float getDeltaPitch() { - return pitchDelta; - } - - public float getDeltaYaw() { - return yawDelta; - } - - @Override - public boolean equals(Object obj) { - if(obj instanceof VirtualCameraAngleEvent) { - return ((VirtualCameraAngleEvent)obj).pitchDelta == pitchDelta && ((VirtualCameraAngleEvent)obj).yawDelta == yawDelta; - } - return super.equals(obj); - } -} diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualEvent.java index ea376bfd..0c2909fd 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualEvent.java @@ -1,33 +1,29 @@ package com.minecrafttas.tasmod.virtual.event; public class VirtualEvent { + protected final int keycode; + protected final boolean keystate; - public static class VirtualButtonEvent extends VirtualEvent{ + public VirtualEvent(int keycode, boolean keystate) { + this.keycode = keycode; + this.keystate = keystate; + } - protected final int keycode; - protected final boolean keystate; - - public VirtualButtonEvent(int keycode, boolean keystate) { - this.keycode = keycode; - this.keystate = keystate; - } + public VirtualEvent(VirtualEvent event) { + this.keycode = event.keycode; + this.keystate = event.keystate; + } - public VirtualButtonEvent(VirtualButtonEvent event) { - this.keycode = event.keycode; - this.keystate = event.keystate; - } + public int getKeyCode() { + return keycode; + } - public int getKeyCode() { - return keycode; - } + public boolean isState() { + return keystate; + } - public boolean isState() { - return keystate; - } - - @Override - public String toString() { - return String.format("%s, %s", keycode, keystate); - } + @Override + public String toString() { + return String.format("%s, %s", keycode, keystate); } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualKeyboardEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualKeyboardEvent.java index 5c0b0cc8..3ad0e7c0 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualKeyboardEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualKeyboardEvent.java @@ -1,8 +1,11 @@ package com.minecrafttas.tasmod.virtual.event; -import com.minecrafttas.tasmod.virtual.event.VirtualEvent.VirtualButtonEvent; - -public class VirtualKeyboardEvent extends VirtualButtonEvent { +/** + * Template for recording {@link org.lwjgl.input.Keyboard#next()} events. + * + * @author Scribble + */ +public class VirtualKeyboardEvent extends VirtualEvent { private final char character; public VirtualKeyboardEvent(){ @@ -14,11 +17,6 @@ public VirtualKeyboardEvent(int keycode, boolean keystate, char character) { this.character = character; } - public VirtualKeyboardEvent(VirtualButtonEvent event, char character) { - super(event); - this.character = character; - } - public char getCharacter() { return character; } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualMouseEvent.java b/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualMouseEvent.java index 251eb865..ba57ec4c 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualMouseEvent.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/event/VirtualMouseEvent.java @@ -1,13 +1,11 @@ package com.minecrafttas.tasmod.virtual.event; -import com.minecrafttas.tasmod.virtual.event.VirtualEvent.VirtualButtonEvent; - /** - * Template for recording Mouse.next() events. + * Template for recording {@link org.lwjgl.input.Mouse#next()} events. * * @author Scribble */ -public class VirtualMouseEvent extends VirtualButtonEvent { +public class VirtualMouseEvent extends VirtualEvent { private final int scrollwheel; private final int cursorX; private final int cursorY;