From 08a134a135c9cf1e473117be66b1c14f3715092e Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 27 Feb 2024 21:25:10 +0100 Subject: [PATCH 01/27] [PlaybackController] Add events that fire when updating VirtualInput - Add null check to copyFrom --- .../tasmod/events/EventClient.java | 78 +++++++++++++++++-- .../playback/PlaybackControllerClient.java | 61 ++++----------- .../tasmod/virtual/VirtualCameraAngle.java | 2 + .../tasmod/virtual/VirtualInput.java | 5 ++ .../tasmod/virtual/VirtualKeybindings.java | 1 - .../tasmod/virtual/VirtualKeyboard.java | 2 + .../tasmod/virtual/VirtualMouse.java | 2 + .../tasmod/virtual/VirtualPeripheral.java | 2 + 8 files changed, 98 insertions(+), 55 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/events/EventClient.java b/src/main/java/com/minecrafttas/tasmod/events/EventClient.java index fe55d3b4..4314ce50 100644 --- a/src/main/java/com/minecrafttas/tasmod/events/EventClient.java +++ b/src/main/java/com/minecrafttas/tasmod/events/EventClient.java @@ -1,6 +1,13 @@ package com.minecrafttas.tasmod.events; import com.minecrafttas.mctcommon.events.EventListenerRegistry.EventBase; +import com.minecrafttas.tasmod.virtual.VirtualCameraAngle; +import com.minecrafttas.tasmod.virtual.VirtualInput.VirtualCameraAngleInput; +import com.minecrafttas.tasmod.virtual.VirtualInput.VirtualKeyboardInput; +import com.minecrafttas.tasmod.virtual.VirtualInput.VirtualMouseInput; +import com.minecrafttas.tasmod.virtual.VirtualKeyboard; +import com.minecrafttas.tasmod.virtual.VirtualMouse; + import net.minecraft.client.Minecraft; /** @@ -9,39 +16,94 @@ * @author Scribble */ public interface EventClient { - + /** * Fired when the hotbar is drawn on screen */ @FunctionalInterface - public static interface EventDrawHotbar extends EventBase{ + public static interface EventDrawHotbar extends EventBase { /** * Fired when the hotbar is drawn on screen */ public void onDrawHotbar(); } - + /** * Fired at the end of a client tick */ @FunctionalInterface - public static interface EventClientTickPost extends EventBase{ - + public static interface EventClientTickPost extends EventBase { + /** * Fired at the end of a client tick */ public void onClientTickPost(Minecraft mc); } - + /** * Fired when the tickrate changes on the client side */ @FunctionalInterface - public static interface EventClientTickrateChange extends EventBase{ - + public static interface EventClientTickrateChange extends EventBase { + /** * Fired at the end of a client tick */ public void onClientTickrateChange(float tickrate); } + + + /** + * Fired when the {@link VirtualKeyboardInput#currentKeyboard} is updated + * + * @see VirtualKeyboardInput#nextKeyboardTick() + */ + @FunctionalInterface + public static interface EventVirtualKeyboardTick extends EventBase { + + /** + * Fired when the {@link VirtualKeyboard} ticks + * + * @param vkeyboard The {@link VirtualKeyboardInput#nextKeyboard} that is supposed to be pressed + * @returns The redirected keyboard + * @see VirtualKeyboardInput#nextKeyboardTick() + */ + public VirtualKeyboard onVirtualKeyboardTick(VirtualKeyboard vkeyboard); + } + + /** + * Fired when the {@link VirtualMouseInput#currentMouse} is updated + * + * @see VirtualMouseInput#nextMouseTick() + */ + @FunctionalInterface + public static interface EventVirtualMouseTick extends EventBase { + + /** + * Fired when the {@link VirtualMouseInput#currentMouse} is updated + * + * @param vmouse The {@link VirtualMouseInput#nextMouse} that is supposed to be pressed + * @returns The redirected mouse + * @see VirtualMouseInput#nextMouseTick() + */ + public VirtualMouse onVirtualMouseTick(VirtualMouse vmouse); + } + + /** + * Fired when the {@link VirtualCameraAngleInput#currentCameraAngle} is updated + * + * @see VirtualCameraAngleInput#nextCameraTick() + */ + @FunctionalInterface + public static interface EventVirtualCameraAngleTick extends EventBase { + + /** + * Fired when the {@link VirtualCameraAngleInput#currentCameraAngle} is updated + * + * @param vcamera The {@link VirtualCameraAngleInput#nextCameraAngle} + * @returns The redirected cameraAngle + * @see VirtualCameraAngleInput#nextCameraTick() + */ + public VirtualCameraAngle onVirtualCameraTick(VirtualCameraAngle vcamera); + } } diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index 64247e25..b0bd2e22 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -12,7 +12,6 @@ import static com.minecrafttas.tasmod.networking.TASmodPackets.PLAYBACK_TELEPORT; import java.io.File; -import java.io.IOException; import java.io.Serializable; import java.nio.ByteBuffer; import java.util.HashMap; @@ -31,15 +30,18 @@ import com.minecrafttas.mctcommon.server.interfaces.PacketID; import com.minecrafttas.tasmod.TASmod; import com.minecrafttas.tasmod.TASmodClient; +import com.minecrafttas.tasmod.events.EventClient.EventVirtualCameraAngleTick; +import com.minecrafttas.tasmod.events.EventClient.EventVirtualKeyboardTick; +import com.minecrafttas.tasmod.events.EventClient.EventVirtualMouseTick; import com.minecrafttas.tasmod.monitoring.DesyncMonitoring; import com.minecrafttas.tasmod.networking.TASmodBufferBuilder; import com.minecrafttas.tasmod.networking.TASmodPackets; import com.minecrafttas.tasmod.util.LoggerMarkers; import com.minecrafttas.tasmod.util.Scheduler.Task; +import com.minecrafttas.tasmod.virtual.VirtualCameraAngle; import com.minecrafttas.tasmod.virtual.VirtualInput; import com.minecrafttas.tasmod.virtual.VirtualKeyboard; import com.minecrafttas.tasmod.virtual.VirtualMouse; -import com.minecrafttas.tasmod.virtual.VirtualCameraAngle; import com.mojang.realmsclient.gui.ChatFormatting; import com.mojang.realmsclient.util.Pair; @@ -68,7 +70,7 @@ * @author Scribble * */ -public class PlaybackControllerClient implements ClientPacketHandler { +public class PlaybackControllerClient implements ClientPacketHandler, EventVirtualKeyboardTick, EventVirtualMouseTick, EventVirtualCameraAngleTick{ /** * The current state of the controller. @@ -340,54 +342,21 @@ public TASstate getState() { // These act as an input and output, depending if a recording or a playback is // running - /** - * Adds or retrives a keyboard to the input container, depends on whether a - * recording or a playback is running - * - * @param keyboard Keyboard to add - * @return Keyboard to retrieve - */ - public VirtualKeyboard addKeyboardToContainer(VirtualKeyboard keyboard) { - if (state == TASstate.RECORDING) { - this.keyboard = keyboard.clone(); - } else if (state == TASstate.PLAYBACK) { - keyboard = this.keyboard.clone(); - } - return keyboard; + @Override + public VirtualCameraAngle onVirtualCameraTick(VirtualCameraAngle vcamera) { + return null; } - /** - * Adds or retrives a mouse to the input container, depends on whether a - * recording or a playback is running - * - * @param mouse Mouse to add - * @return Mouse to retrieve - */ - public VirtualMouse addMouseToContainer(VirtualMouse mouse) { - if (state == TASstate.RECORDING) { - this.mouse = mouse.clone(); - } else if (state == TASstate.PLAYBACK) { - mouse = this.mouse.clone(); - } - return mouse; + @Override + public VirtualMouse onVirtualMouseTick(VirtualMouse vmouse) { + return null; } - /** - * Adds or retrives the angle of the camera to the input container, depends on - * whether a recording or a playback is running - * - * @param subticks Subticks to add - * @return Subticks to retrieve - */ - public VirtualCameraAngle addSubticksToContainer(VirtualCameraAngle subticks) { - if (state == TASstate.RECORDING) { - this.subticks = subticks.clone(); - } else if (state == TASstate.PLAYBACK) { - subticks = this.subticks.clone(); - } - return subticks; + @Override + public VirtualKeyboard onVirtualKeyboardTick(VirtualKeyboard vkeyboard) { + return null; } - + /** * Updates the input container.
*
diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java index aefb5a50..45f036ae 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java @@ -117,6 +117,8 @@ public void getStates(List reference) { * @param camera The camera to move from */ public void copyFrom(VirtualCameraAngle camera) { + if(camera == null) + return; this.pitch = camera.pitch; this.yaw = camera.yaw; this.subtickList.clear(); diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index b59f7a25..db79d2e7 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -11,6 +11,9 @@ import org.lwjgl.input.Mouse; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import com.minecrafttas.mctcommon.events.EventListenerRegistry; +import com.minecrafttas.tasmod.events.EventClient.EventVirtualCameraAngleTick; +import com.minecrafttas.tasmod.events.EventClient.EventVirtualMouseTick; import com.minecrafttas.tasmod.mixin.playbackhooks.MixinEntityRenderer; import com.minecrafttas.tasmod.mixin.playbackhooks.MixinMinecraft; import com.minecrafttas.tasmod.util.Ducks; @@ -403,6 +406,7 @@ public void updateNextMouse(int keycode, boolean keystate, int scrollwheel, int * @see MixinMinecraft#playback_injectRunTickMouse(org.spongepowered.asm.mixin.injection.callback.CallbackInfo) */ public void nextMouseTick() { + nextMouse.copyFrom((VirtualMouse) EventListenerRegistry.fireEvent(EventVirtualMouseTick.class, nextMouse)); currentMouse.getVirtualEvents(nextMouse, mouseEventQueue); currentMouse.copyFrom(nextMouse); } @@ -588,6 +592,7 @@ public void updateNextCameraAngle(float pitchDelta, float yawDelta) { * @see MixinEntityRenderer#runUpdate(float) */ public void nextCameraTick() { + nextCameraAngle.copyFrom((VirtualCameraAngle) EventListenerRegistry.fireEvent(EventVirtualCameraAngleTick.class, nextCameraAngle)); nextCameraAngle.getStates(cameraAngleInterpolationStates); currentCameraAngle.copyFrom(nextCameraAngle); } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeybindings.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeybindings.java index d79cc738..ca930fe8 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeybindings.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeybindings.java @@ -7,7 +7,6 @@ import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; -import com.google.common.collect.Maps; import com.minecrafttas.tasmod.TASmodClient; import net.minecraft.client.Minecraft; diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java index 80adab57..6e248297 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java @@ -290,6 +290,8 @@ public VirtualKeyboard clone() { @Override public void copyFrom(VirtualKeyboard keyboard) { + if(keyboard == null) + return; super.copyFrom(keyboard); charList.clear(); charList.addAll(keyboard.charList); diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java index 99a65ddf..761956ac 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java @@ -227,6 +227,8 @@ public VirtualMouse clone() { @Override public void copyFrom(VirtualMouse mouse) { + if(mouse==null) + return; super.copyFrom(mouse); this.scrollWheel = mouse.scrollWheel; this.cursorX = mouse.cursorX; diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java index 44130857..c0588efb 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java @@ -140,6 +140,8 @@ public boolean equals(Object obj) { * @param peripheral The peripheral to move from */ protected void copyFrom(T peripheral) { + if(peripheral == null) + return; this.pressedKeys.clear(); this.pressedKeys.addAll(peripheral.pressedKeys); peripheral.subtickList.clear(); From bdd6c0eb1c13cba7b3282376b19b76ad01af4cff Mon Sep 17 00:00:00 2001 From: Scribble Date: Wed, 28 Feb 2024 20:09:25 +0100 Subject: [PATCH 02/27] [PlaybackController] Fix tests failing --- .../events/EventListenerRegistry.java | 24 ++++++++++++------- .../playback/PlaybackControllerClient.java | 1 + .../java/tasmod/virtual/VirtualInputTest.java | 13 ++++++++++ 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java b/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java index b0d868e7..d0e21b2a 100644 --- a/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java +++ b/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java @@ -97,15 +97,21 @@ public static void register(EventBase eventListener) { for (Class type : eventListener.getClass().getInterfaces()) { if (EventBase.class.isAssignableFrom(type)) { - // If a new event type is being registered, add a new arraylist - ArrayList registryList = EVENTLISTENER_REGISTRY.putIfAbsent(type, new ArrayList<>()); - if (registryList == null) { - registryList = EVENTLISTENER_REGISTRY.get(type); - } - registryList.add(eventListener); - } - } - } + // If a new event type is being registered, add a new arraylist + ArrayList registryList = EVENTLISTENER_REGISTRY.putIfAbsent(type, new ArrayList<>()); + if (registryList == null) { + registryList = EVENTLISTENER_REGISTRY.get(type); + } + registryList.add(eventListener); + } + } + } + + public static void register(EventBase... eventListeners) { + for(EventBase eventListener : eventListeners) { + register(eventListener); + } + } /** * Unregisters an object from being an event listener. diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index b0bd2e22..cfe83723 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -81,6 +81,7 @@ public class PlaybackControllerClient implements ClientPacketHandler, EventVirtu * The state of the controller when the state is paused */ private TASstate tempPause = TASstate.NONE; + /** * The current index of the inputs */ diff --git a/src/test/java/tasmod/virtual/VirtualInputTest.java b/src/test/java/tasmod/virtual/VirtualInputTest.java index 060ce206..ed8a38b7 100644 --- a/src/test/java/tasmod/virtual/VirtualInputTest.java +++ b/src/test/java/tasmod/virtual/VirtualInputTest.java @@ -8,9 +8,14 @@ import org.apache.commons.lang3.tuple.Triple; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import com.minecrafttas.mctcommon.events.EventListenerRegistry; +import com.minecrafttas.tasmod.events.EventClient.EventVirtualCameraAngleTick; +import com.minecrafttas.tasmod.events.EventClient.EventVirtualKeyboardTick; +import com.minecrafttas.tasmod.events.EventClient.EventVirtualMouseTick; import com.minecrafttas.tasmod.virtual.VirtualCameraAngle; import com.minecrafttas.tasmod.virtual.VirtualInput; import com.minecrafttas.tasmod.virtual.VirtualKey; @@ -21,6 +26,14 @@ class VirtualInputTest { private final Logger LOGGER = LogManager.getLogger("TASmod"); + @BeforeAll + static void beforeAll() { + EventVirtualKeyboardTick kb = (keyboard)->null; + EventVirtualMouseTick ms = (mouse)->null; + EventVirtualCameraAngleTick cmra = (cameraangle)->null; + EventListenerRegistry.register(kb, ms, cmra); + } + /** * Test constructor initializing keyboard, mouse and camera_angle */ From 43f2940a9a9206b886b3658cdc77055cd1c45251 Mon Sep 17 00:00:00 2001 From: Scribble Date: Thu, 29 Feb 2024 19:40:21 +0100 Subject: [PATCH 03/27] [VirtualInput] Renamed copyFrom to moveFrom and added copyFrom --- .../tasmod/virtual/VirtualCameraAngle.java | 2 +- .../tasmod/virtual/VirtualInput.java | 6 +-- .../tasmod/virtual/VirtualKeyboard.java | 13 +++++- .../tasmod/virtual/VirtualMouse.java | 12 +++++- .../tasmod/virtual/VirtualPeripheral.java | 20 +++++++-- src/test/java/mctcommon/event/EventTest.java | 4 -- .../virtual/VirtualCameraAngleTest.java | 4 +- .../tasmod/virtual/VirtualKeyboardTest.java | 37 ++++++++++++++--- .../java/tasmod/virtual/VirtualMouseTest.java | 41 +++++++++++++++++-- 9 files changed, 113 insertions(+), 26 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java index 45f036ae..d934ac25 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java @@ -114,7 +114,7 @@ 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 + * @param camera The camera to copy from */ public void copyFrom(VirtualCameraAngle camera) { if(camera == null) diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index db79d2e7..e2a49bf9 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -248,7 +248,7 @@ public void updateNextKeyboard(int keycode, boolean keystate, char character, bo */ public void nextKeyboardTick() { currentKeyboard.getVirtualEvents(nextKeyboard, keyboardEventQueue); - currentKeyboard.copyFrom(nextKeyboard); + currentKeyboard.moveFrom(nextKeyboard); } /** @@ -406,9 +406,9 @@ public void updateNextMouse(int keycode, boolean keystate, int scrollwheel, int * @see MixinMinecraft#playback_injectRunTickMouse(org.spongepowered.asm.mixin.injection.callback.CallbackInfo) */ public void nextMouseTick() { - nextMouse.copyFrom((VirtualMouse) EventListenerRegistry.fireEvent(EventVirtualMouseTick.class, nextMouse)); + nextMouse.moveFrom((VirtualMouse) EventListenerRegistry.fireEvent(EventVirtualMouseTick.class, nextMouse)); currentMouse.getVirtualEvents(nextMouse, mouseEventQueue); - currentMouse.copyFrom(nextMouse); + currentMouse.moveFrom(nextMouse); } /** diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java index 6e248297..7c15c8e8 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java @@ -289,15 +289,24 @@ public VirtualKeyboard clone() { } @Override - public void copyFrom(VirtualKeyboard keyboard) { + public void moveFrom(VirtualKeyboard keyboard) { if(keyboard == null) return; - super.copyFrom(keyboard); + super.moveFrom(keyboard); charList.clear(); charList.addAll(keyboard.charList); keyboard.charList.clear(); } + @Override + public void copyFrom(VirtualKeyboard keyboard) { + if(keyboard == null) + return; + super.copyFrom(keyboard); + charList.clear(); + charList.addAll(keyboard.charList); + } + @Override public boolean equals(Object obj) { if(obj instanceof VirtualKeyboard) { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java index 761956ac..635a406c 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java @@ -225,6 +225,17 @@ public VirtualMouse clone() { return new VirtualMouse(new HashSet<>(this.pressedKeys), scrollWheel, cursorX, cursorY, null, ignoreFirstUpdate()); } + @Override + public void moveFrom(VirtualMouse mouse) { + if(mouse==null) + return; + super.moveFrom(mouse); + this.scrollWheel = mouse.scrollWheel; + this.cursorX = mouse.cursorX; + this.cursorY = mouse.cursorY; + mouse.clearMouseData(); + } + @Override public void copyFrom(VirtualMouse mouse) { if(mouse==null) @@ -233,7 +244,6 @@ public void copyFrom(VirtualMouse mouse) { this.scrollWheel = mouse.scrollWheel; this.cursorX = mouse.cursorX; this.cursorY = mouse.cursorY; - mouse.clearMouseData(); } @Override diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java index c0588efb..7e216334 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java @@ -134,17 +134,29 @@ public boolean equals(Object obj) { } /** - * Copies the data from another virtual peripheral into this peripheral without - * creating a new object. + * Moves the data from another virtual peripheral into this peripheral without + * creating a new object. Deletes the data in the other peripheral * * @param peripheral The peripheral to move from */ + protected void moveFrom(T peripheral) { + if(peripheral == null) + return; + copyFrom(peripheral); + peripheral.subtickList.clear(); + peripheral.resetFirstUpdate(); + } + + /** + * Copies the data from another virtual peripheral into this peripheral without creating a new object.
+ * Does not delete the data from the other peripehral + * + * @param peripheral The peripheral to copy from + */ protected void copyFrom(T peripheral) { if(peripheral == null) return; this.pressedKeys.clear(); this.pressedKeys.addAll(peripheral.pressedKeys); - peripheral.subtickList.clear(); - peripheral.resetFirstUpdate(); } } diff --git a/src/test/java/mctcommon/event/EventTest.java b/src/test/java/mctcommon/event/EventTest.java index cf1bdd3a..507167fe 100644 --- a/src/test/java/mctcommon/event/EventTest.java +++ b/src/test/java/mctcommon/event/EventTest.java @@ -119,10 +119,6 @@ void testEventMethodwithSameName() { class TestClass implements TestEvent { - public int onTestEvent(int test) { - return test; - } - @Override public int onTestEvent() { return 1; diff --git a/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java b/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java index a6aa974b..c42d8ede 100644 --- a/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java +++ b/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java @@ -142,10 +142,10 @@ void testGetStates() { } /** - * Test copyfrom method + * Test copyFrom method */ @Test - void copyFrom() { + void testCopyFrom() { VirtualCameraAngle expected = new VirtualCameraAngle(0f, 0f, true); expected.update(1f, 2f); expected.update(3f, 4f); diff --git a/src/test/java/tasmod/virtual/VirtualKeyboardTest.java b/src/test/java/tasmod/virtual/VirtualKeyboardTest.java index 2ce164b7..2e57968d 100644 --- a/src/test/java/tasmod/virtual/VirtualKeyboardTest.java +++ b/src/test/java/tasmod/virtual/VirtualKeyboardTest.java @@ -220,10 +220,36 @@ void testClone() { } /** - * Test copy from method + * Test moveFrom method */ @Test - void testCopyFrom(){ + void testMoveFrom(){ + VirtualKeyboard moveFrom = new VirtualKeyboard(); + VirtualKeyboard actual = new VirtualKeyboard(); + + moveFrom.update(VirtualKey.W.getKeycode(), true, 'w'); + moveFrom.update(VirtualKey.A.getKeycode(), true, 'a'); + + VirtualKeyboard expected = moveFrom.clone(); + + actual.update(VirtualKey.S.getKeycode(), true, 's'); + actual.update(VirtualKey.D.getKeycode(), true, 'd'); + + actual.moveFrom(null); + actual.moveFrom(moveFrom); + + assertIterableEquals(expected.getPressedKeys(), actual.getPressedKeys()); + assertIterableEquals(expected.getCharList(), actual.getCharList()); + + assertTrue(moveFrom.getSubticks().isEmpty()); + assertTrue(moveFrom.getCharList().isEmpty()); + } + + /** + * Test copyFrom method + */ + @Test + void testCopyFrom() { VirtualKeyboard copyFrom = new VirtualKeyboard(); VirtualKeyboard actual = new VirtualKeyboard(); @@ -235,15 +261,16 @@ void testCopyFrom(){ actual.update(VirtualKey.S.getKeycode(), true, 's'); actual.update(VirtualKey.D.getKeycode(), true, 'd'); + actual.copyFrom(null); actual.copyFrom(copyFrom); assertIterableEquals(expected.getPressedKeys(), actual.getPressedKeys()); assertIterableEquals(expected.getCharList(), actual.getCharList()); - assertTrue(copyFrom.getSubticks().isEmpty()); - assertTrue(copyFrom.getCharList().isEmpty()); + assertFalse(copyFrom.getSubticks().isEmpty()); + assertFalse(copyFrom.getCharList().isEmpty()); } - + /** * Test subtick list being filled via update */ diff --git a/src/test/java/tasmod/virtual/VirtualMouseTest.java b/src/test/java/tasmod/virtual/VirtualMouseTest.java index dddb52b4..79e3a828 100644 --- a/src/test/java/tasmod/virtual/VirtualMouseTest.java +++ b/src/test/java/tasmod/virtual/VirtualMouseTest.java @@ -191,6 +191,37 @@ void testClone() { assertEquals(actual, test2); } + /** + * Test moveFrom method + */ + @Test + void testMoveFrom() { + VirtualMouse moveFrom = new VirtualMouse(); + VirtualMouse actual = new VirtualMouse(); + + moveFrom.update(VirtualKey.LC.getKeycode(), true, 0, 0, 0); + moveFrom.update(VirtualKey.MOUSEMOVED.getKeycode(), false, 120, 10, 20); + + VirtualMouse expected = moveFrom.clone(); + + actual.update(VirtualKey.MBUTTON12.getKeycode(), true, 0,0,0); + actual.update(VirtualKey.MOUSEMOVED.getKeycode(), true, -120, -10, -10); + + actual.moveFrom(null); + + actual.moveFrom(moveFrom); + + assertIterableEquals(expected.getPressedKeys(), actual.getPressedKeys()); + assertEquals(expected.getScrollWheel(), actual.getScrollWheel()); + assertEquals(expected.getCursorX(), actual.getCursorX()); + assertEquals(expected.getCursorY(), actual.getCursorY()); + + assertTrue(moveFrom.getSubticks().isEmpty()); + assertEquals(0, moveFrom.getScrollWheel()); + assertEquals(0, moveFrom.getCursorX()); + assertEquals(0, moveFrom.getCursorY()); + } + /** * Test copyFrom method */ @@ -207,6 +238,8 @@ void testCopyFrom() { actual.update(VirtualKey.MBUTTON12.getKeycode(), true, 0,0,0); actual.update(VirtualKey.MOUSEMOVED.getKeycode(), true, -120, -10, -10); + actual.copyFrom(null); + actual.copyFrom(copyFrom); assertIterableEquals(expected.getPressedKeys(), actual.getPressedKeys()); @@ -214,10 +247,10 @@ void testCopyFrom() { 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()); + assertFalse(copyFrom.getSubticks().isEmpty()); + assertEquals(120, copyFrom.getScrollWheel()); + assertEquals(10, copyFrom.getCursorX()); + assertEquals(20, copyFrom.getCursorY()); } /** From 2e94dda08372529876e0ac649baa2574f3cdc3c2 Mon Sep 17 00:00:00 2001 From: Scribble Date: Thu, 29 Feb 2024 20:05:20 +0100 Subject: [PATCH 04/27] [PlaybackController] Added playback metadata --- .../tasmod/playback/PlaybackMetadata.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/main/java/com/minecrafttas/tasmod/playback/PlaybackMetadata.java diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackMetadata.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackMetadata.java new file mode 100644 index 00000000..a5a79201 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackMetadata.java @@ -0,0 +1,20 @@ +package com.minecrafttas.tasmod.playback; + +import java.util.LinkedHashMap; +import java.util.Properties; + +/** + * Stores all tasfile specific metadata like author, rerecords and name.
+ *
+ * Each metadata is grouped by a group name.
+ * Made to be easily modifiable so that you can add your own metadata. + */ +public class PlaybackMetadata { + LinkedHashMap metadata; + + public PlaybackMetadata() { + this.metadata = new LinkedHashMap<>(); + } + + +} From 0eaf3b69a07f8879803a01b230ec7eebf3b74e72 Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 25 Mar 2024 20:45:54 +0100 Subject: [PATCH 05/27] [PlaybackController] Added playback metadata registry --- .../events/EventListenerRegistry.java | 28 ++++++--- .../server/PacketHandlerRegistry.java | 2 +- .../com/minecrafttas/tasmod/gui/InfoHud.java | 3 - .../{ => metadata}/PlaybackMetadata.java | 5 +- .../metadata/PlaybackMetadataRegistry.java | 61 +++++++++++++++++++ 5 files changed, 86 insertions(+), 13 deletions(-) rename src/main/java/com/minecrafttas/tasmod/playback/{ => metadata}/PlaybackMetadata.java (78%) create mode 100644 src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java diff --git a/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java b/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java index d0e21b2a..af77dd3f 100644 --- a/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java +++ b/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java @@ -107,6 +107,10 @@ public static void register(EventBase eventListener) { } } + /** + * Registers multiple objects to be an event listener. The objects must implement an event extending {@link EventBase} + * @param eventListeners The event listeners to register + */ public static void register(EventBase... eventListeners) { for(EventBase eventListener : eventListeners) { register(eventListener); @@ -128,13 +132,23 @@ public static void unregister(EventBase eventListener) { if (registryList != null) { registryList.remove(eventListener); - if (registryList.isEmpty()) { - EVENTLISTENER_REGISTRY.remove(type); - } - } - } - } - } + if (registryList.isEmpty()) { + EVENTLISTENER_REGISTRY.remove(type); + } + } + } + } + } + + /** + * Unregisters multiple objects from being an event listener. + * @param eventListener The event listeners to unregister + */ + public static void unregister(EventBase... eventListeners) { + for(EventBase eventListener : eventListeners) { + unregister(eventListener); + } + } /** * Fires an event without parameters diff --git a/src/main/java/com/minecrafttas/mctcommon/server/PacketHandlerRegistry.java b/src/main/java/com/minecrafttas/mctcommon/server/PacketHandlerRegistry.java index 37cb5ca5..6dbac610 100644 --- a/src/main/java/com/minecrafttas/mctcommon/server/PacketHandlerRegistry.java +++ b/src/main/java/com/minecrafttas/mctcommon/server/PacketHandlerRegistry.java @@ -41,7 +41,7 @@ public static void unregister(PacketHandlerBase handler) { if (REGISTRY.contains(handler)) { REGISTRY.remove(handler); } else { - MCTCommon.LOGGER.warn("Trying to unregister packet handler {}, but is was not registered!", handler.getClass().getName()); + MCTCommon.LOGGER.warn("Trying to unregister packet handler {}, but it was not registered!", handler.getClass().getName()); } } diff --git a/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java b/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java index 7cc413c3..13cbda8c 100644 --- a/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java +++ b/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java @@ -17,17 +17,14 @@ import com.minecrafttas.tasmod.TASmod; import com.minecrafttas.tasmod.TASmodClient; import com.minecrafttas.tasmod.events.EventClient.EventDrawHotbar; -import com.minecrafttas.tasmod.handlers.InterpolationHandler; import com.minecrafttas.tasmod.monitoring.DesyncMonitoring; import com.minecrafttas.tasmod.playback.ControlByteHandler; import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate; -import com.minecrafttas.tasmod.util.TrajectoriesCalculator; import com.mojang.realmsclient.gui.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.ScaledResolution; -import net.minecraft.util.math.Vec3d; /** * The info hud is a hud that is always being rendered ontop of the screen, it can show some stuff such as coordinates, etc., diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackMetadata.java b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java similarity index 78% rename from src/main/java/com/minecrafttas/tasmod/playback/PlaybackMetadata.java rename to src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java index a5a79201..d57a61dd 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackMetadata.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java @@ -1,4 +1,4 @@ -package com.minecrafttas.tasmod.playback; +package com.minecrafttas.tasmod.playback.metadata; import java.util.LinkedHashMap; import java.util.Properties; @@ -16,5 +16,6 @@ public PlaybackMetadata() { this.metadata = new LinkedHashMap<>(); } - + public void setValue(String category, String key, String value) { + } } diff --git a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java new file mode 100644 index 00000000..162a91ee --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java @@ -0,0 +1,61 @@ +package com.minecrafttas.tasmod.playback.metadata; + +import java.util.ArrayList; + +import com.minecrafttas.mctcommon.MCTCommon; + +public class PlaybackMetadataRegistry { + + private static final ArrayList METADATA_EXTENSION = new ArrayList<>(); + + public static void register(PlaybackMetadataExtension extension) { + if(extension==null) { + throw new NullPointerException("Tried to register a playback extension with value null"); + } + + if(containsClass(extension)) { + MCTCommon.LOGGER.warn("Trying to register the playback extension {}, but another instance of this class is already registered!", extension.getClass().getName()); + return; + } + + if (!METADATA_EXTENSION.contains(extension)) { + METADATA_EXTENSION.add(extension); + } else { + MCTCommon.LOGGER.warn("Trying to register the playback extension {}, but it is already registered!", extension.getClass().getName()); + } + } + + public static void unregister(PlaybackMetadataExtension extension) { + if(extension==null) { + throw new NullPointerException("Tried to unregister an extension with value null"); + } + if (METADATA_EXTENSION.contains(extension)) { + METADATA_EXTENSION.remove(extension); + } else { + MCTCommon.LOGGER.warn("Trying to unregister the playback extension {}, but it was not registered!", extension.getClass().getName()); + } + } + + public static PlaybackMetadata handleOnLoad() { + return null; //TODO implement + } + + public static void handleOnStore(PlaybackMetadata metadata) { + //TODO + } + + private static boolean containsClass(PlaybackMetadataExtension newExtension) { + for(PlaybackMetadataExtension extension : METADATA_EXTENSION) { + if(extension.getClass().equals(newExtension.getClass())) { + return true; + } + } + return false; + } + + public static interface PlaybackMetadataExtension { + public PlaybackMetadata onStore(); + + public void onLoad(PlaybackMetadata metadata); + } +} From 9a3cc998ad7386f2e37795f0d786c9ad5e2cfc93 Mon Sep 17 00:00:00 2001 From: Scribble Date: Wed, 27 Mar 2024 21:19:54 +0100 Subject: [PATCH 06/27] [PlaybackController] Add onCreate to events - [Common] Fixed indentation in eventlistener --- .../events/EventListenerRegistry.java | 405 +++++++++--------- .../playback/metadata/PlaybackMetadata.java | 75 +++- .../metadata/PlaybackMetadataRegistry.java | 29 +- src/test/java/mctcommon/event/EventTest.java | 5 +- 4 files changed, 287 insertions(+), 227 deletions(-) diff --git a/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java b/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java index af77dd3f..6113e7b6 100644 --- a/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java +++ b/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java @@ -12,90 +12,78 @@ *
* Implement an EventInterface into your class, then implement the function.
*
- * In your initializer method, register the instance of the class with - * {@link EventListenerRegistry#register(EventBase)}
+ * In your initializer method, register the instance of the class with {@link EventListenerRegistry#register(EventBase)} + *
* Example: - * *
- * public class ClassWithListener implements EventInit {
+ *     public class ClassWithListener implements EventInit {
  *
- * 	@Override
- * 	public void onEventInit() {
- * 		// Implement event specific code
- * 	}
- * }
+ *          @ Override
+ *          public void onEventInit() {
+ *              // Implement event specific code
+ *          }
+ *     }
  * 
- * *
* To create and fire your own events, check {@link EventBase}
*/ public class EventListenerRegistry { - /** - * Base interface for events.
- *
- * To create a new event, create an interface and extend EventBase.
- * Only 1 method is accepted in an event, so it's best to add - * {@link FunctionalInterface} to the interface.
- *
- * Example: - * - *
-	 * @FunctionalInterface
-	 * public interface EventInit extends EventBase {
-	 * 	public void onEventInit();
-	 * }
-	 *
-	 * @FunctionalInterface
-	 * public interface EventAdd extends EventBase {
-	 * 	public int onEventAdd(int a, int b); // Accepts parameters and return types
-	 * }
-	 * 
- * - * To fire your event, use {@link EventListenerRegistry#fireEvent(Class)} with - * the parameter being the event class.
- * - *
-	 * EventListenerRegistry.fireEvent(EventInit.class);
-	 * 
- * - * To fire an event with parameters and return types: - * - *
-	 * int eventResult = (int) EventListenerRegistry.fireEvent(EventAdd.class, a, b);
-	 * 
- * - * When using parameters, the type and the amount of parameters has to match! - */ - public interface EventBase { - } + /** + * Base interface for events.
+ *
+ * To create a new event, create an interface and extend EventBase.
+ * Only 1 method is accepted in an event, so it's best to add {@link FunctionalInterface} to the interface.
+ *
+ * Example: + *
+     *     @ FunctionalInterface
+     *     public interface EventInit extends EventBase {
+     *         public void onEventInit();
+     *     }
+     *
+     *     @ FunctionalInterface
+     *     public interface EventAdd extends EventBase {
+     *         public int onEventAdd(int a, int b); // Accepts parameters and return types
+     *     }
+     * 
+ * + * To fire your event, use {@link EventListenerRegistry#fireEvent(Class)} with the parameter being the event class.
+ * + *
+     *     EventListenerRegistry.fireEvent(EventInit.class);
+     * 
+ * + * To fire an event with parameters and return types: + *
+     *     int eventResult = (int) EventListenerRegistry.fireEvent(EventAdd.class, a, b);
+     * 
+ * When using parameters, the type and the amount of parameters has to match! + */ + public interface EventBase { + } - /** - * Stores the event listener objects and calls their event methods during - * {@link EventListenerRegistry#fireEvent(Class, Object...)}
- *
- * Consists of multiple lists seperated by event types.
- * If it were a single ArrayList, firing an event means that you'd have to - * unnecessarily iterate over the entire list,
- * to find the correct events.
- *
- * With multiple lists like this, you iterate only over the objects, that have - * the correct event applied. - */ - private static final HashMap, ArrayList> EVENTLISTENER_REGISTRY = new HashMap<>(); + /** + * Stores the event listener objects and calls their event methods during {@link EventListenerRegistry#fireEvent(Class, Object...)}
+ *
+ * Consists of multiple lists seperated by event types.
+ * If it were a single ArrayList, firing an event means that you'd have to unnecessarily iterate over the entire list,
+ * to find the correct events.
+ *
+ * With multiple lists like this, you iterate only over the objects, that have the correct event applied. + */ + private static final HashMap, ArrayList> EVENTLISTENER_REGISTRY = new HashMap<>(); - /** - * Registers an object to be an event listener. The object must implement an - * event extending {@link EventBase} - * - * @param eventListener The event listener to register - */ - public static void register(EventBase eventListener) { - if (eventListener == null) { - throw new NullPointerException("Tried to register a packethandler with value null"); - } - for (Class type : eventListener.getClass().getInterfaces()) { - if (EventBase.class.isAssignableFrom(type)) { + /** + * Registers an object to be an event listener. The object must implement an event extending {@link EventBase} + * @param eventListener The event listener to register + */ + public static void register(EventBase eventListener) { + if (eventListener == null) { + throw new NullPointerException("Tried to register a packethandler with value null"); + } + for (Class type : eventListener.getClass().getInterfaces()) { + if (EventBase.class.isAssignableFrom(type)) { // If a new event type is being registered, add a new arraylist ArrayList registryList = EVENTLISTENER_REGISTRY.putIfAbsent(type, new ArrayList<>()); @@ -117,20 +105,19 @@ public static void register(EventBase... eventListeners) { } } - /** - * Unregisters an object from being an event listener. - * - * @param eventListener The event listener to unregister - */ - public static void unregister(EventBase eventListener) { - if (eventListener == null) { - throw new NullPointerException("Tried to unregister a packethandler with value null"); - } - for (Class type : eventListener.getClass().getInterfaces()) { - if (EventBase.class.isAssignableFrom(type)) { - ArrayList registryList = EVENTLISTENER_REGISTRY.get(type); - if (registryList != null) { - registryList.remove(eventListener); + /** + * Unregisters an object from being an event listener. + * @param eventListener The event listener to unregister + */ + public static void unregister(EventBase eventListener) { + if (eventListener == null) { + throw new NullPointerException("Tried to unregister a packethandler with value null"); + } + for (Class type : eventListener.getClass().getInterfaces()) { + if (EventBase.class.isAssignableFrom(type)) { + ArrayList registryList = EVENTLISTENER_REGISTRY.get(type); + if (registryList != null) { + registryList.remove(eventListener); if (registryList.isEmpty()) { EVENTLISTENER_REGISTRY.remove(type); @@ -150,150 +137,140 @@ public static void unregister(EventBase... eventListeners) { } } - /** - * Fires an event without parameters - * - * @param eventClass The event class to fire e.g. EventClientInit.class - * @return The result of the event, might be null if the event returns nothing - */ - public static Object fireEvent(Class eventClass) { - return fireEvent(eventClass, new Object[] {}); - } - - /** - * Fires an event with parameters - * - * @param eventClass The event class to fire e.g. EventClientInit.class - * @param eventParams List of parameters for the event. Number of arguments and - * types have to match. - * @return The result of the event, might be null if the event returns nothing - */ - public static Object fireEvent(Class eventClass, Object... eventParams) { - ArrayList listenerList = EVENTLISTENER_REGISTRY.get(eventClass); - if (listenerList == null) { - return null; - } - - // Exception to be thrown at the end of the method. If null then no exception is - // thrown - EventException toThrow = null; + /** + * Fires an event without parameters + * + * @param eventClass The event class to fire e.g. EventClientInit.class + * @return The result of the event, might be null if the event returns nothing + */ + public static Object fireEvent(Class eventClass) { + return fireEvent(eventClass, new Object[]{}); + } - // Get the method from the event that we are looking for in the event listeners - Method methodToFind = getEventMethod(eventClass); + /** + * Fires an event with parameters + * + * @param eventClass The event class to fire e.g. EventClientInit.class + * @param eventParams List of parameters for the event. Number of arguments and types have to match. + * @return The result of the event, might be null if the event returns nothing + */ + public static Object fireEvent(Class eventClass, Object... eventParams) { + ArrayList listenerList = EVENTLISTENER_REGISTRY.get(eventClass); + if (listenerList == null) { + throw new EventException("The event has not been registered yet", eventClass); + } - // Variable for the return value. The last registered listener will return its - // value - Object returnValue = null; + // Exception to be thrown at the end of the method. If null then no exception is thrown + EventException toThrow = null; - // Iterate through the list of eventListeners - for (EventBase eventListener : listenerList) { - // Get all methods in this event listener - Method[] methodsInListener = eventListener.getClass().getDeclaredMethods(); + // Get the method from the event that we are looking for in the event listeners + Method methodToFind = getEventMethod(eventClass); - // Iterate through all methods - for (Method method : methodsInListener) { + // Variable for the return value. The last registered listener will return its value + Object returnValue = null; - // Check if the current method has the same name as the method we are looking - // for - if (!checkName(method, methodToFind.getName())) { - continue; - } + // Iterate through the list of eventListeners + for (EventBase eventListener : listenerList) { + // Get all methods in this event listener + Method[] methodsInListener = eventListener.getClass().getDeclaredMethods(); - // Check if the length is the same before we check for types - if (!checkLength(method, eventParams)) { - toThrow = new EventException(String.format("Event fired with the wrong number of parameters. Expected: %s, Actual: %s", method.getParameterCount(), eventParams.length), eventClass); - continue; - } + // Iterate through all methods + for (Method method : methodsInListener) { - // Check the types of the method - if (checkTypes(method, eventParams)) { - toThrow = null; // Reset toThrow as the correct method was found - method.setAccessible(true); - try { - returnValue = method.invoke(eventListener, eventParams); // Call the method - } catch (IllegalAccessException | InvocationTargetException e) { - throw new EventException(eventClass, e); - } catch (IllegalArgumentException e) { - throw new EventException(String.format("Event fired with the wrong number of parameters. Expected: %s, Actual: %s", method.getParameterCount(), eventParams.length), eventClass, e); - } - } else { - toThrow = new EventException("Event seems to be fired with the wrong parameter types or in the wrong order", eventClass); - } - } - } + // Check if the current method has the same name as the method we are looking for + if (!checkName(method, methodToFind.getName())) { + continue; + } - // Throw the exception - if (toThrow != null) { - throw toThrow; - } + // Check if the length is the same before we check for types + if (!checkLength(method, eventParams)) { + toThrow = new EventException(String.format("Event fired with the wrong number of parameters. Expected: %s, Actual: %s", method.getParameterCount(), eventParams.length), eventClass); + continue; + } - return returnValue; - } + // Check the types of the method + if (checkTypes(method, eventParams)) { + toThrow = null; // Reset toThrow as the correct method was found + method.setAccessible(true); + try { + returnValue = method.invoke(eventListener, eventParams); // Call the method + } catch (IllegalAccessException | InvocationTargetException e) { + throw new EventException(eventClass, e); + } catch (IllegalArgumentException e) { + throw new EventException(String.format("Event fired with the wrong number of parameters. Expected: %s, Actual: %s", method.getParameterCount(), eventParams.length), eventClass, e); + } + } else { + toThrow = new EventException("Event seems to be fired with the wrong parameter types or in the wrong order", eventClass); + } + } + } - private static Method getEventMethod(Class eventClass) { - Method[] test = eventClass.getDeclaredMethods(); - if (test.length != 1) { - throw new EventException("The event method is not properly defined. Only one method is allowed inside of an event", eventClass); - } + // Throw the exception + if (toThrow != null) { + throw toThrow; + } - return test[0]; - } + return returnValue; + } - /** - * @param method The method to check - * @param name The name to check - * @return If method.getName equals name - */ - private static boolean checkName(Method method, String name) { - return method.getName().equals(name); - } + private static Method getEventMethod(Class eventClass) { + Method[] test = eventClass.getDeclaredMethods(); + if (test.length != 1) { + throw new EventException("The event method is not properly defined. Only one method is allowed inside of an event", eventClass); + } - /** - * @param method The method to check - * @param parameters The list of parameters - * @return True, if length of the method parameters is equal to the length of - * the object parameters - */ - private static boolean checkLength(Method method, Object... parameters) { - return method.getParameterCount() == parameters.length; - } + return test[0]; + } - /** - * @param method The method to check - * @param parameters The list of parameters - * @return True, if the types of the parameters equal the object parameters - */ - private static boolean checkTypes(Method method, Object... parameters) { - Class[] methodParameterTypes = ClassUtils.primitivesToWrappers(method.getParameterTypes()); - Class[] eventParameterTypes = getParameterTypes(parameters); + /** + * @param method The method to check + * @param name The name to check + * @return If method.getName equals name + */ + private static boolean checkName(Method method, String name) { + return method.getName().equals(name); + } - for (int i = 0; i < methodParameterTypes.length; i++) { - Class paramName = methodParameterTypes[i]; - Class eventName = eventParameterTypes[i]; + /** + * @param method The method to check + * @param parameters The list of parameters + * @return True, if length of the method parameters is equal to the length of the object parameters + */ + private static boolean checkLength(Method method, Object... parameters) { + return method.getParameterCount() == parameters.length; + } - if (paramName == null || eventName == null) { - continue; - } + /** + * @param method The method to check + * @param parameters The list of parameters + * @return True, if the types of the parameters equal the object parameters + */ + private static boolean checkTypes(Method method, Object... parameters) { + Class[] methodParameterTypes = ClassUtils.primitivesToWrappers(method.getParameterTypes()); + Class[] eventParameterTypes = getParameterTypes(parameters); - if (!paramName.equals(eventName) && !paramName.isAssignableFrom(eventName)) { - return false; - } - } - return true; - } + for (int i = 0; i < methodParameterTypes.length; i++) { + Class paramName = methodParameterTypes[i]; + Class eventName = eventParameterTypes[i]; + if (!paramName.equals(eventName)) { + return false; + } + } + return true; + } - private static Class[] getParameterTypes(Object... parameters) { - Class[] out = new Class[parameters.length]; - for (int i = 0; i < parameters.length; i++) { - out[i] = parameters[i] == null ? null : parameters[i].getClass(); - } - return out; - } + private static Class[] getParameterTypes(Object... parameters) { + Class[] out = new Class[parameters.length]; + for (int i = 0; i < parameters.length; i++) { + out[i] = parameters[i].getClass(); + } + return out; + } - /** - * Removes all registry entries - */ - public static void clear() { - EVENTLISTENER_REGISTRY.clear(); - } + /** + * Removes all registry entries + */ + public static void clear() { + EVENTLISTENER_REGISTRY.clear(); + } } diff --git a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java index d57a61dd..cab3ee0e 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java @@ -1,21 +1,80 @@ package com.minecrafttas.tasmod.playback.metadata; -import java.util.LinkedHashMap; +import java.util.ArrayList; +import java.util.List; import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** - * Stores all tasfile specific metadata like author, rerecords and name.
+ * Stores a section of
*
- * Each metadata is grouped by a group name.
- * Made to be easily modifiable so that you can add your own metadata. */ public class PlaybackMetadata { - LinkedHashMap metadata; - + /** + * Debug extension name + */ + String extensionName; + Properties metadata; + public PlaybackMetadata() { - this.metadata = new LinkedHashMap<>(); + this.metadata = new Properties(); + } + + public PlaybackMetadata(String extensionName) { + this(); + this.extensionName = extensionName; + } + + public void setValue(String key, String value) { + if(key.contains("=")) { + throw new IllegalArgumentException(String.format("%sKeyname %s can't contain =", extensionName!=null?extensionName+": ":"", key)); + } + } + + public String getValue(String key) { + return metadata.getProperty(key); + } + + @Override + public String toString() { + String out = ""; + for (Object keyObj : metadata.keySet()) { + String key = (String) keyObj; + String value = getValue(key); + out += (String.format("%s=%s\n", key, value)); + } + return out; + } + + public List toStringList(){ + List out= new ArrayList<>(); + for (Object keyObj : metadata.keySet()) { + String key = (String) keyObj; + String value = getValue(key); + out.add(String.format("%s=%s\n", key, value)); + } + return out; + } + + public static PlaybackMetadata fromStringList(String extensionName, List list) { + return fromStringList(list); } - public void setValue(String category, String key, String value) { + public static PlaybackMetadata fromStringList(List list) { + PlaybackMetadata out = new PlaybackMetadata(); + + final Pattern pattern = Pattern.compile("(\\w+)=(.+)"); + + for(String data: list) { + Matcher matcher = pattern.matcher(data); + if(matcher.find()) { + String key = matcher.group(1); + String value = matcher.group(2); + out.setValue(key, value); + } + } + + return out; } } diff --git a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java index 162a91ee..4ecfef97 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java @@ -1,13 +1,26 @@ package com.minecrafttas.tasmod.playback.metadata; import java.util.ArrayList; +import java.util.LinkedHashMap; import com.minecrafttas.mctcommon.MCTCommon; +/** + * Registry for registering custom metadata that is stored in the TASFile.
+ *
+ * The default metadata includes general information such as author name, savestate/rerecord count and category.
+ *
+ * Any custom class has to extend PlaybackMetadataExtension + * + */ public class PlaybackMetadataRegistry { private static final ArrayList METADATA_EXTENSION = new ArrayList<>(); + /** + * Registers a new class as a metadata extension + * @param extension + */ public static void register(PlaybackMetadataExtension extension) { if(extension==null) { throw new NullPointerException("Tried to register a playback extension with value null"); @@ -36,12 +49,15 @@ public static void unregister(PlaybackMetadataExtension extension) { } } - public static PlaybackMetadata handleOnLoad() { - return null; //TODO implement + public static void handleOnCreate() { + + } + + public static LinkedHashMap handleOnLoad() { + return null; } - public static void handleOnStore(PlaybackMetadata metadata) { - //TODO + public static void handleOnStore(LinkedHashMap metadata) { } private static boolean containsClass(PlaybackMetadataExtension newExtension) { @@ -54,6 +70,11 @@ private static boolean containsClass(PlaybackMetadataExtension newExtension) { } public static interface PlaybackMetadataExtension { + + public String getExtensionName(); + + public void onCreate(); + public PlaybackMetadata onStore(); public void onLoad(PlaybackMetadata metadata); diff --git a/src/test/java/mctcommon/event/EventTest.java b/src/test/java/mctcommon/event/EventTest.java index 507167fe..23fea348 100644 --- a/src/test/java/mctcommon/event/EventTest.java +++ b/src/test/java/mctcommon/event/EventTest.java @@ -160,6 +160,9 @@ void testUnregister() { EventListenerRegistry.unregister(event); - assertNull(EventListenerRegistry.fireEvent(TestEvent.class)); + Exception exception = assertThrows(EventException.class, () -> EventListenerRegistry.fireEvent(TestEvent.class)); + + String expected = "mctcommon.event.EventTest$TestEvent: The event has not been registered yet"; + assertEquals(expected, exception.getMessage()); } } From 2426356c931bc897b08ee6370fe79c241b315c71 Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 30 Mar 2024 18:04:36 +0100 Subject: [PATCH 07/27] [PLaybackController] Added test for PlaybackMetadata --- .../server/PacketHandlerRegistry.java | 18 ++++---- .../playback/metadata/PlaybackMetadata.java | 43 +++++++++++-------- .../metadata/PlaybackMetadataRegistry.java | 34 ++++++++------- .../metadata/PlaybackMetadataTest.java | 40 +++++++++++++++++ 4 files changed, 93 insertions(+), 42 deletions(-) create mode 100644 src/test/java/tasmod/playback/metadata/PlaybackMetadataTest.java diff --git a/src/main/java/com/minecrafttas/mctcommon/server/PacketHandlerRegistry.java b/src/main/java/com/minecrafttas/mctcommon/server/PacketHandlerRegistry.java index 6dbac610..25b29058 100644 --- a/src/main/java/com/minecrafttas/mctcommon/server/PacketHandlerRegistry.java +++ b/src/main/java/com/minecrafttas/mctcommon/server/PacketHandlerRegistry.java @@ -18,15 +18,15 @@ public class PacketHandlerRegistry { private static final List REGISTRY = new ArrayList<>(); public static void register(PacketHandlerBase handler) { - if(handler==null) { + if (handler == null) { throw new NullPointerException("Tried to register a handler with value null"); } - - if(containsClass(handler)) { + + if (containsClass(handler)) { MCTCommon.LOGGER.warn("Trying to register packet handler {}, but another instance of this class is already registered!", handler.getClass().getName()); return; } - + if (!REGISTRY.contains(handler)) { REGISTRY.add(handler); } else { @@ -35,7 +35,7 @@ public static void register(PacketHandlerBase handler) { } public static void unregister(PacketHandlerBase handler) { - if(handler==null) { + if (handler == null) { throw new NullPointerException("Tried to unregister a handler with value null"); } if (REGISTRY.contains(handler)) { @@ -65,14 +65,14 @@ public static void handle(Side side, PacketID packet, ByteBuffer buf, String use } } } - if(!isImplemented) { + if (!isImplemented) { throw new PacketNotImplementedException(packet, side); } } - + private static boolean containsClass(PacketHandlerBase handler) { - for(PacketHandlerBase packethandler : REGISTRY) { - if(packethandler.getClass().equals(handler.getClass())) { + for (PacketHandlerBase packethandler : REGISTRY) { + if (packethandler.getClass().equals(handler.getClass())) { return true; } } diff --git a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java index cab3ee0e..47a76bbe 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java @@ -14,22 +14,23 @@ public class PlaybackMetadata { /** * Debug extension name */ - String extensionName; - Properties metadata; + private String extensionName; + private Properties metadata; public PlaybackMetadata() { this.metadata = new Properties(); } - + public PlaybackMetadata(String extensionName) { this(); - this.extensionName = extensionName; + this.extensionName = extensionName; } public void setValue(String key, String value) { - if(key.contains("=")) { - throw new IllegalArgumentException(String.format("%sKeyname %s can't contain =", extensionName!=null?extensionName+": ":"", key)); + if (key.contains("=")) { + throw new IllegalArgumentException(String.format("%sKeyname %s can't contain =", extensionName != null ? extensionName + ": " : "", key)); } + metadata.setProperty(key, value); } public String getValue(String key) { @@ -46,9 +47,9 @@ public String toString() { } return out; } - - public List toStringList(){ - List out= new ArrayList<>(); + + public List toStringList() { + List out = new ArrayList<>(); for (Object keyObj : metadata.keySet()) { String key = (String) keyObj; String value = getValue(key); @@ -57,24 +58,32 @@ public List toStringList(){ return out; } + public String getExtensionName() { + return extensionName; + } + + public Properties getMetadata() { + return metadata; + } + public static PlaybackMetadata fromStringList(String extensionName, List list) { return fromStringList(list); } - - public static PlaybackMetadata fromStringList(List list) { + + public static PlaybackMetadata fromStringList(List list) { PlaybackMetadata out = new PlaybackMetadata(); - - final Pattern pattern = Pattern.compile("(\\w+)=(.+)"); - - for(String data: list) { + + final Pattern pattern = Pattern.compile("(\\w+)=(.+)"); + + for (String data : list) { Matcher matcher = pattern.matcher(data); - if(matcher.find()) { + if (matcher.find()) { String key = matcher.group(1); String value = matcher.group(2); out.setValue(key, value); } } - + return out; } } diff --git a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java index 4ecfef97..56a1fa86 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java @@ -8,7 +8,8 @@ /** * Registry for registering custom metadata that is stored in the TASFile.
*
- * The default metadata includes general information such as author name, savestate/rerecord count and category.
+ * The default metadata includes general information such as author name, + * savestate/rerecord count and category.
*
* Any custom class has to extend PlaybackMetadataExtension * @@ -19,18 +20,19 @@ public class PlaybackMetadataRegistry { /** * Registers a new class as a metadata extension + * * @param extension */ public static void register(PlaybackMetadataExtension extension) { - if(extension==null) { + if (extension == null) { throw new NullPointerException("Tried to register a playback extension with value null"); } - - if(containsClass(extension)) { + + if (containsClass(extension)) { MCTCommon.LOGGER.warn("Trying to register the playback extension {}, but another instance of this class is already registered!", extension.getClass().getName()); return; } - + if (!METADATA_EXTENSION.contains(extension)) { METADATA_EXTENSION.add(extension); } else { @@ -39,7 +41,7 @@ public static void register(PlaybackMetadataExtension extension) { } public static void unregister(PlaybackMetadataExtension extension) { - if(extension==null) { + if (extension == null) { throw new NullPointerException("Tried to unregister an extension with value null"); } if (METADATA_EXTENSION.contains(extension)) { @@ -48,21 +50,21 @@ public static void unregister(PlaybackMetadataExtension extension) { MCTCommon.LOGGER.warn("Trying to unregister the playback extension {}, but it was not registered!", extension.getClass().getName()); } } - + public static void handleOnCreate() { - + } - + public static LinkedHashMap handleOnLoad() { return null; } - + public static void handleOnStore(LinkedHashMap metadata) { } - + private static boolean containsClass(PlaybackMetadataExtension newExtension) { - for(PlaybackMetadataExtension extension : METADATA_EXTENSION) { - if(extension.getClass().equals(newExtension.getClass())) { + for (PlaybackMetadataExtension extension : METADATA_EXTENSION) { + if (extension.getClass().equals(newExtension.getClass())) { return true; } } @@ -70,11 +72,11 @@ private static boolean containsClass(PlaybackMetadataExtension newExtension) { } public static interface PlaybackMetadataExtension { - + public String getExtensionName(); - + public void onCreate(); - + public PlaybackMetadata onStore(); public void onLoad(PlaybackMetadata metadata); diff --git a/src/test/java/tasmod/playback/metadata/PlaybackMetadataTest.java b/src/test/java/tasmod/playback/metadata/PlaybackMetadataTest.java new file mode 100644 index 00000000..28e2dae5 --- /dev/null +++ b/src/test/java/tasmod/playback/metadata/PlaybackMetadataTest.java @@ -0,0 +1,40 @@ +package tasmod.playback.metadata; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +import java.util.Properties; + +import org.junit.jupiter.api.Test; + +import com.minecrafttas.tasmod.playback.metadata.PlaybackMetadata; + +public class PlaybackMetadataTest { + + @Test + void testConstructor() { + PlaybackMetadata metadata = new PlaybackMetadata(); + assertNotNull(metadata.getMetadata()); + assertNull(metadata.getExtensionName()); + } + + @Test + void testNameConstructor() { + PlaybackMetadata metadata = new PlaybackMetadata("Test"); + assertNotNull(metadata.getMetadata()); + assertEquals("Test", metadata.getExtensionName()); + } + + @Test + void testSettingAndReading() { + PlaybackMetadata metadata = new PlaybackMetadata("Test"); + metadata.setValue("testProperty", "Test"); + + String actual = metadata.getValue("testProperty"); + + assertEquals("Test", actual); + } + + +} From 69972bd0283cd36e933e62211da7fb075ede4edc Mon Sep 17 00:00:00 2001 From: Scribble Date: Sun, 31 Mar 2024 16:59:14 +0200 Subject: [PATCH 08/27] [PlaybackController] Switch from Properties to Hashmap, add tests --- .../playback/metadata/PlaybackMetadata.java | 29 +++-- .../metadata/PlaybackMetadataTest.java | 105 +++++++++++++++++- 2 files changed, 125 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java index 47a76bbe..1b09f09e 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java @@ -1,8 +1,13 @@ package com.minecrafttas.tasmod.playback.metadata; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Properties; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -15,10 +20,10 @@ public class PlaybackMetadata { * Debug extension name */ private String extensionName; - private Properties metadata; + private LinkedHashMap metadata; public PlaybackMetadata() { - this.metadata = new Properties(); + this.metadata = new LinkedHashMap(); } public PlaybackMetadata(String extensionName) { @@ -30,24 +35,23 @@ public void setValue(String key, String value) { if (key.contains("=")) { throw new IllegalArgumentException(String.format("%sKeyname %s can't contain =", extensionName != null ? extensionName + ": " : "", key)); } - metadata.setProperty(key, value); + metadata.put(key, value); } public String getValue(String key) { - return metadata.getProperty(key); + return metadata.get(key); } @Override public String toString() { String out = ""; - for (Object keyObj : metadata.keySet()) { - String key = (String) keyObj; + for (String key : metadata.keySet()) { String value = getValue(key); out += (String.format("%s=%s\n", key, value)); } return out; } - + public List toStringList() { List out = new ArrayList<>(); for (Object keyObj : metadata.keySet()) { @@ -62,10 +66,19 @@ public String getExtensionName() { return extensionName; } - public Properties getMetadata() { + public HashMap getMetadata() { return metadata; } + @Override + public boolean equals(Object obj) { + if(obj instanceof PlaybackMetadata) { + PlaybackMetadata other = (PlaybackMetadata) obj; + return other.metadata.equals(metadata) && other.extensionName.equals(extensionName); + } + return super.equals(obj); + } + public static PlaybackMetadata fromStringList(String extensionName, List list) { return fromStringList(list); } diff --git a/src/test/java/tasmod/playback/metadata/PlaybackMetadataTest.java b/src/test/java/tasmod/playback/metadata/PlaybackMetadataTest.java index 28e2dae5..beb6f124 100644 --- a/src/test/java/tasmod/playback/metadata/PlaybackMetadataTest.java +++ b/src/test/java/tasmod/playback/metadata/PlaybackMetadataTest.java @@ -1,10 +1,13 @@ package tasmod.playback.metadata; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; -import java.util.Properties; +import java.util.ArrayList; +import java.util.List; import org.junit.jupiter.api.Test; @@ -36,5 +39,105 @@ void testSettingAndReading() { assertEquals("Test", actual); } + @Test + void testToString() { + PlaybackMetadata metadata = new PlaybackMetadata("Test"); + metadata.setValue("1", "One"); + metadata.setValue("2", "Two"); + metadata.setValue("3", "Three"); + metadata.setValue("4", "Four"); + + String actual = metadata.toString(); + + String expected = "1=One\n" + + "2=Two\n" + + "3=Three\n" + + "4=Four\n"; + + assertEquals(expected, actual); + } + + @Test + void testToStringList() { + PlaybackMetadata metadata = new PlaybackMetadata("Test"); + metadata.setValue("1", "One"); + metadata.setValue("2", "Two"); + metadata.setValue("3", "Three"); + metadata.setValue("4", "Four"); + + List actual = metadata.toStringList(); + + List expected = new ArrayList<>(); + expected.add("1=One\n"); + expected.add("2=Two\n"); + expected.add("3=Three\n"); + expected.add("4=Four\n"); + + assertIterableEquals(expected, actual); + } + + @Test + void testEquals() { + PlaybackMetadata metadata = new PlaybackMetadata("Test"); + metadata.setValue("1", "One"); + metadata.setValue("2", "Two"); + metadata.setValue("3", "Three"); + metadata.setValue("4", "Four"); + + PlaybackMetadata metadata2 = new PlaybackMetadata("Test"); + metadata2.setValue("1", "One"); + metadata2.setValue("2", "Two"); + metadata2.setValue("3", "Three"); + metadata2.setValue("4", "Four"); + + assertEquals(metadata, metadata2); + } + @Test + void testFailedEquals() { + //Key difference + PlaybackMetadata metadata = new PlaybackMetadata("Test"); + metadata.setValue("2", "One"); + metadata.setValue("2", "Two"); + metadata.setValue("3", "Three"); + metadata.setValue("4", "Four"); + + PlaybackMetadata metadata2 = new PlaybackMetadata("Test"); + metadata2.setValue("1", "One"); + metadata2.setValue("2", "Two"); + metadata2.setValue("3", "Three"); + metadata2.setValue("4", "Four"); + + assertNotEquals(metadata, metadata2); + + // Value difference + metadata = new PlaybackMetadata("Test"); + metadata.setValue("1", "On"); + metadata.setValue("2", "Two"); + metadata.setValue("3", "Three"); + metadata.setValue("4", "Four"); + + metadata2 = new PlaybackMetadata("Test"); + metadata2.setValue("1", "One"); + metadata2.setValue("2", "Two"); + metadata2.setValue("3", "Three"); + metadata2.setValue("4", "Four"); + + assertNotEquals(metadata, metadata2); + + // Name difference + metadata = new PlaybackMetadata("Tes"); + metadata.setValue("1", "One"); + metadata.setValue("2", "Two"); + metadata.setValue("3", "Three"); + metadata.setValue("4", "Four"); + + metadata2 = new PlaybackMetadata("Test"); + metadata2.setValue("1", "One"); + metadata2.setValue("2", "Two"); + metadata2.setValue("3", "Three"); + metadata2.setValue("4", "Four"); + + assertNotEquals(metadata, metadata2); + } } From 9f0013b23dd7c6d7c845956981c7581363ea1a21 Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 1 Apr 2024 21:48:56 +0200 Subject: [PATCH 09/27] [Common] Added 'isAssignableFrom' to type checking - Added null checks when passing null as a parameter - Disabled Exception when listener list is empty - Reformatted code --- .../events/EventListenerRegistry.java | 480 +++++++++--------- 1 file changed, 253 insertions(+), 227 deletions(-) diff --git a/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java b/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java index 6113e7b6..774ca47f 100644 --- a/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java +++ b/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java @@ -12,265 +12,291 @@ *
* Implement an EventInterface into your class, then implement the function.
*
- * In your initializer method, register the instance of the class with {@link EventListenerRegistry#register(EventBase)} - *
+ * In your initializer method, register the instance of the class with + * {@link EventListenerRegistry#register(EventBase)}
* Example: + * *
- *     public class ClassWithListener implements EventInit {
+ * public class ClassWithListener implements EventInit {
  *
- *          @ Override
- *          public void onEventInit() {
- *              // Implement event specific code
- *          }
- *     }
+ * 	@Override
+ * 	public void onEventInit() {
+ * 		// Implement event specific code
+ * 	}
+ * }
  * 
+ * *
* To create and fire your own events, check {@link EventBase}
*/ public class EventListenerRegistry { - /** - * Base interface for events.
- *
- * To create a new event, create an interface and extend EventBase.
- * Only 1 method is accepted in an event, so it's best to add {@link FunctionalInterface} to the interface.
- *
- * Example: - *
-     *     @ FunctionalInterface
-     *     public interface EventInit extends EventBase {
-     *         public void onEventInit();
-     *     }
-     *
-     *     @ FunctionalInterface
-     *     public interface EventAdd extends EventBase {
-     *         public int onEventAdd(int a, int b); // Accepts parameters and return types
-     *     }
-     * 
- * - * To fire your event, use {@link EventListenerRegistry#fireEvent(Class)} with the parameter being the event class.
- * - *
-     *     EventListenerRegistry.fireEvent(EventInit.class);
-     * 
- * - * To fire an event with parameters and return types: - *
-     *     int eventResult = (int) EventListenerRegistry.fireEvent(EventAdd.class, a, b);
-     * 
- * When using parameters, the type and the amount of parameters has to match! - */ - public interface EventBase { - } + /** + * Base interface for events.
+ *
+ * To create a new event, create an interface and extend EventBase.
+ * Only 1 method is accepted in an event, so it's best to add + * {@link FunctionalInterface} to the interface.
+ *
+ * Example: + * + *
+	 * @FunctionalInterface
+	 * public interface EventInit extends EventBase {
+	 * 	public void onEventInit();
+	 * }
+	 *
+	 * @FunctionalInterface
+	 * public interface EventAdd extends EventBase {
+	 * 	public int onEventAdd(int a, int b); // Accepts parameters and return types
+	 * }
+	 * 
+ * + * To fire your event, use {@link EventListenerRegistry#fireEvent(Class)} with + * the parameter being the event class.
+ * + *
+	 * EventListenerRegistry.fireEvent(EventInit.class);
+	 * 
+ * + * To fire an event with parameters and return types: + * + *
+	 * int eventResult = (int) EventListenerRegistry.fireEvent(EventAdd.class, a, b);
+	 * 
+ * + * When using parameters, the type and the amount of parameters has to match! + */ + public interface EventBase { + } + + /** + * Stores the event listener objects and calls their event methods during + * {@link EventListenerRegistry#fireEvent(Class, Object...)}
+ *
+ * Consists of multiple lists seperated by event types.
+ * If it were a single ArrayList, firing an event means that you'd have to + * unnecessarily iterate over the entire list,
+ * to find the correct events.
+ *
+ * With multiple lists like this, you iterate only over the objects, that have + * the correct event applied. + */ + private static final HashMap, ArrayList> EVENTLISTENER_REGISTRY = new HashMap<>(); + + /** + * Registers an object to be an event listener. The object must implement an + * event extending {@link EventBase} + * + * @param eventListener The event listener to register + */ + public static void register(EventBase eventListener) { + if (eventListener == null) { + throw new NullPointerException("Tried to register a packethandler with value null"); + } + for (Class type : eventListener.getClass().getInterfaces()) { + if (EventBase.class.isAssignableFrom(type)) { - /** - * Stores the event listener objects and calls their event methods during {@link EventListenerRegistry#fireEvent(Class, Object...)}
- *
- * Consists of multiple lists seperated by event types.
- * If it were a single ArrayList, firing an event means that you'd have to unnecessarily iterate over the entire list,
- * to find the correct events.
- *
- * With multiple lists like this, you iterate only over the objects, that have the correct event applied. - */ - private static final HashMap, ArrayList> EVENTLISTENER_REGISTRY = new HashMap<>(); + // If a new event type is being registered, add a new arraylist + ArrayList registryList = EVENTLISTENER_REGISTRY.putIfAbsent(type, new ArrayList<>()); + if (registryList == null) { + registryList = EVENTLISTENER_REGISTRY.get(type); + } + registryList.add(eventListener); + } + } + } - /** - * Registers an object to be an event listener. The object must implement an event extending {@link EventBase} - * @param eventListener The event listener to register - */ - public static void register(EventBase eventListener) { - if (eventListener == null) { - throw new NullPointerException("Tried to register a packethandler with value null"); - } - for (Class type : eventListener.getClass().getInterfaces()) { - if (EventBase.class.isAssignableFrom(type)) { + /** + * Registers multiple objects to be an event listener. The objects must + * implement an event extending {@link EventBase} + * + * @param eventListeners The event listeners to register + */ + public static void register(EventBase... eventListeners) { + for (EventBase eventListener : eventListeners) { + register(eventListener); + } + } - // If a new event type is being registered, add a new arraylist - ArrayList registryList = EVENTLISTENER_REGISTRY.putIfAbsent(type, new ArrayList<>()); - if (registryList == null) { - registryList = EVENTLISTENER_REGISTRY.get(type); - } - registryList.add(eventListener); - } - } - } - - /** - * Registers multiple objects to be an event listener. The objects must implement an event extending {@link EventBase} - * @param eventListeners The event listeners to register - */ - public static void register(EventBase... eventListeners) { - for(EventBase eventListener : eventListeners) { - register(eventListener); - } - } + /** + * Unregisters an object from being an event listener. + * + * @param eventListener The event listener to unregister + */ + public static void unregister(EventBase eventListener) { + if (eventListener == null) { + throw new NullPointerException("Tried to unregister a packethandler with value null"); + } + for (Class type : eventListener.getClass().getInterfaces()) { + if (EventBase.class.isAssignableFrom(type)) { + ArrayList registryList = EVENTLISTENER_REGISTRY.get(type); + if (registryList != null) { + registryList.remove(eventListener); - /** - * Unregisters an object from being an event listener. - * @param eventListener The event listener to unregister - */ - public static void unregister(EventBase eventListener) { - if (eventListener == null) { - throw new NullPointerException("Tried to unregister a packethandler with value null"); - } - for (Class type : eventListener.getClass().getInterfaces()) { - if (EventBase.class.isAssignableFrom(type)) { - ArrayList registryList = EVENTLISTENER_REGISTRY.get(type); - if (registryList != null) { - registryList.remove(eventListener); + if (registryList.isEmpty()) { + EVENTLISTENER_REGISTRY.remove(type); + } + } + } + } + } - if (registryList.isEmpty()) { - EVENTLISTENER_REGISTRY.remove(type); - } - } - } - } - } - - /** - * Unregisters multiple objects from being an event listener. - * @param eventListener The event listeners to unregister - */ - public static void unregister(EventBase... eventListeners) { - for(EventBase eventListener : eventListeners) { - unregister(eventListener); - } - } + /** + * Unregisters multiple objects from being an event listener. + * + * @param eventListener The event listeners to unregister + */ + public static void unregister(EventBase... eventListeners) { + for (EventBase eventListener : eventListeners) { + unregister(eventListener); + } + } - /** - * Fires an event without parameters - * - * @param eventClass The event class to fire e.g. EventClientInit.class - * @return The result of the event, might be null if the event returns nothing - */ - public static Object fireEvent(Class eventClass) { - return fireEvent(eventClass, new Object[]{}); - } + /** + * Fires an event without parameters + * + * @param eventClass The event class to fire e.g. EventClientInit.class + * @return The result of the event, might be null if the event returns nothing + */ + public static Object fireEvent(Class eventClass) { + return fireEvent(eventClass, new Object[] {}); + } - /** - * Fires an event with parameters - * - * @param eventClass The event class to fire e.g. EventClientInit.class - * @param eventParams List of parameters for the event. Number of arguments and types have to match. - * @return The result of the event, might be null if the event returns nothing - */ - public static Object fireEvent(Class eventClass, Object... eventParams) { - ArrayList listenerList = EVENTLISTENER_REGISTRY.get(eventClass); - if (listenerList == null) { - throw new EventException("The event has not been registered yet", eventClass); - } + /** + * Fires an event with parameters + * + * @param eventClass The event class to fire e.g. EventClientInit.class + * @param eventParams List of parameters for the event. Number of arguments and + * types have to match. + * @return The result of the event, might be null if the event returns nothing + */ + public static Object fireEvent(Class eventClass, Object... eventParams) { + ArrayList listenerList = EVENTLISTENER_REGISTRY.get(eventClass); + if (listenerList == null) { +// throw new EventException("The event has not been registered yet", eventClass); + return null; + } - // Exception to be thrown at the end of the method. If null then no exception is thrown - EventException toThrow = null; + // Exception to be thrown at the end of the method. If null then no exception is + // thrown + EventException toThrow = null; - // Get the method from the event that we are looking for in the event listeners - Method methodToFind = getEventMethod(eventClass); + // Get the method from the event that we are looking for in the event listeners + Method methodToFind = getEventMethod(eventClass); - // Variable for the return value. The last registered listener will return its value - Object returnValue = null; + // Variable for the return value. The last registered listener will return its + // value + Object returnValue = null; - // Iterate through the list of eventListeners - for (EventBase eventListener : listenerList) { - // Get all methods in this event listener - Method[] methodsInListener = eventListener.getClass().getDeclaredMethods(); + // Iterate through the list of eventListeners + for (EventBase eventListener : listenerList) { + // Get all methods in this event listener + Method[] methodsInListener = eventListener.getClass().getDeclaredMethods(); - // Iterate through all methods - for (Method method : methodsInListener) { + // Iterate through all methods + for (Method method : methodsInListener) { - // Check if the current method has the same name as the method we are looking for - if (!checkName(method, methodToFind.getName())) { - continue; - } + // Check if the current method has the same name as the method we are looking + // for + if (!checkName(method, methodToFind.getName())) { + continue; + } - // Check if the length is the same before we check for types - if (!checkLength(method, eventParams)) { - toThrow = new EventException(String.format("Event fired with the wrong number of parameters. Expected: %s, Actual: %s", method.getParameterCount(), eventParams.length), eventClass); - continue; - } + // Check if the length is the same before we check for types + if (!checkLength(method, eventParams)) { + toThrow = new EventException(String.format("Event fired with the wrong number of parameters. Expected: %s, Actual: %s", method.getParameterCount(), eventParams.length), eventClass); + continue; + } - // Check the types of the method - if (checkTypes(method, eventParams)) { - toThrow = null; // Reset toThrow as the correct method was found - method.setAccessible(true); - try { - returnValue = method.invoke(eventListener, eventParams); // Call the method - } catch (IllegalAccessException | InvocationTargetException e) { - throw new EventException(eventClass, e); - } catch (IllegalArgumentException e) { - throw new EventException(String.format("Event fired with the wrong number of parameters. Expected: %s, Actual: %s", method.getParameterCount(), eventParams.length), eventClass, e); - } - } else { - toThrow = new EventException("Event seems to be fired with the wrong parameter types or in the wrong order", eventClass); - } - } - } + // Check the types of the method + if (checkTypes(method, eventParams)) { + toThrow = null; // Reset toThrow as the correct method was found + method.setAccessible(true); + try { + returnValue = method.invoke(eventListener, eventParams); // Call the method + } catch (IllegalAccessException | InvocationTargetException e) { + throw new EventException(eventClass, e); + } catch (IllegalArgumentException e) { + throw new EventException(String.format("Event fired with the wrong number of parameters. Expected: %s, Actual: %s", method.getParameterCount(), eventParams.length), eventClass, e); + } + } else { + toThrow = new EventException("Event seems to be fired with the wrong parameter types or in the wrong order", eventClass); + } + } + } - // Throw the exception - if (toThrow != null) { - throw toThrow; - } + // Throw the exception + if (toThrow != null) { + throw toThrow; + } - return returnValue; - } + return returnValue; + } - private static Method getEventMethod(Class eventClass) { - Method[] test = eventClass.getDeclaredMethods(); - if (test.length != 1) { - throw new EventException("The event method is not properly defined. Only one method is allowed inside of an event", eventClass); - } + private static Method getEventMethod(Class eventClass) { + Method[] test = eventClass.getDeclaredMethods(); + if (test.length != 1) { + throw new EventException("The event method is not properly defined. Only one method is allowed inside of an event", eventClass); + } - return test[0]; - } + return test[0]; + } - /** - * @param method The method to check - * @param name The name to check - * @return If method.getName equals name - */ - private static boolean checkName(Method method, String name) { - return method.getName().equals(name); - } + /** + * @param method The method to check + * @param name The name to check + * @return If method.getName equals name + */ + private static boolean checkName(Method method, String name) { + return method.getName().equals(name); + } - /** - * @param method The method to check - * @param parameters The list of parameters - * @return True, if length of the method parameters is equal to the length of the object parameters - */ - private static boolean checkLength(Method method, Object... parameters) { - return method.getParameterCount() == parameters.length; - } + /** + * @param method The method to check + * @param parameters The list of parameters + * @return True, if length of the method parameters is equal to the length of + * the object parameters + */ + private static boolean checkLength(Method method, Object... parameters) { + return method.getParameterCount() == parameters.length; + } - /** - * @param method The method to check - * @param parameters The list of parameters - * @return True, if the types of the parameters equal the object parameters - */ - private static boolean checkTypes(Method method, Object... parameters) { - Class[] methodParameterTypes = ClassUtils.primitivesToWrappers(method.getParameterTypes()); - Class[] eventParameterTypes = getParameterTypes(parameters); + /** + * @param method The method to check + * @param parameters The list of parameters + * @return True, if the types of the parameters equal the object parameters + */ + private static boolean checkTypes(Method method, Object... parameters) { + Class[] methodParameterTypes = ClassUtils.primitivesToWrappers(method.getParameterTypes()); + Class[] eventParameterTypes = getParameterTypes(parameters); - for (int i = 0; i < methodParameterTypes.length; i++) { - Class paramName = methodParameterTypes[i]; - Class eventName = eventParameterTypes[i]; - if (!paramName.equals(eventName)) { - return false; - } - } - return true; - } + for (int i = 0; i < methodParameterTypes.length; i++) { + Class paramName = methodParameterTypes[i]; + Class eventName = eventParameterTypes[i]; + if (!paramName.equals(eventName) && (paramName != null && eventName != null && !paramName.isAssignableFrom(eventName))) { + return false; + } + } + return true; + } - private static Class[] getParameterTypes(Object... parameters) { - Class[] out = new Class[parameters.length]; - for (int i = 0; i < parameters.length; i++) { - out[i] = parameters[i].getClass(); - } - return out; - } + private static Class[] getParameterTypes(Object... parameters) { + Class[] out = new Class[parameters.length]; + for (int i = 0; i < parameters.length; i++) { + if (parameters[i] == null) { + out[i] = null; + continue; + } + out[i] = parameters[i].getClass(); + } + return out; + } - /** - * Removes all registry entries - */ - public static void clear() { - EVENTLISTENER_REGISTRY.clear(); - } + /** + * Removes all registry entries + */ + public static void clear() { + EVENTLISTENER_REGISTRY.clear(); + } } From c7c2178035716544b698564966fa68a14779ddd1 Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 1 Apr 2024 21:55:32 +0200 Subject: [PATCH 10/27] [VirtualInput] Added deepCopy for also copying subticks --- .../tasmod/virtual/VirtualCameraAngle.java | 17 ++++++++++++++-- .../tasmod/virtual/VirtualKeyboard.java | 9 +++++++++ .../tasmod/virtual/VirtualMouse.java | 12 ++++++++++- .../tasmod/virtual/VirtualPeripheral.java | 20 ++++++++++++++++--- .../virtual/VirtualCameraAngleTest.java | 2 +- 5 files changed, 53 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java index d934ac25..79782c24 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java @@ -113,10 +113,10 @@ public void getStates(List reference) { } /** - * Copies the data from another camera angle into this camera without creating a new object. + * Moves the data from another camera angle into this camera without creating a new object. * @param camera The camera to copy from */ - public void copyFrom(VirtualCameraAngle camera) { + public void moveFrom(VirtualCameraAngle camera) { if(camera == null) return; this.pitch = camera.pitch; @@ -126,6 +126,19 @@ public void copyFrom(VirtualCameraAngle camera) { camera.subtickList.clear(); } + /** + * Copies the data from another camera angle into this camera without creating a new object. + * @param camera The camera to copy from + */ + public void deepCopyFrom(VirtualCameraAngle camera) { + if(camera == null) + return; + this.pitch = camera.pitch; + this.yaw = camera.yaw; + this.subtickList.clear(); + this.subtickList.addAll(camera.subtickList); + } + /** * Sets {@link #pitch} and {@link #yaw} to null */ diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java index 7c15c8e8..22e4d793 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java @@ -307,6 +307,15 @@ public void copyFrom(VirtualKeyboard keyboard) { charList.addAll(keyboard.charList); } + @Override + public void deepCopyFrom(VirtualKeyboard keyboard) { + if(keyboard == null) + return; + super.deepCopyFrom(keyboard); + charList.clear(); + charList.addAll(keyboard.charList); + } + @Override public boolean equals(Object obj) { if(obj instanceof VirtualKeyboard) { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java index 635a406c..86f1f513 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java @@ -73,7 +73,7 @@ public VirtualMouse(Set pressedKeys, int scrollWheel, Integer cursorX, * @param scrollWheel The {@link #scrollWheel} * @param cursorX The {@link #cursorX} * @param cursorY The {@link #cursorY} - * @param subtickList 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 subtickList, boolean ignoreFirstUpdate) { @@ -246,6 +246,16 @@ public void copyFrom(VirtualMouse mouse) { this.cursorY = mouse.cursorY; } + @Override + public void deepCopyFrom(VirtualMouse mouse) { + if(mouse==null) + return; + super.deepCopyFrom(mouse); + this.scrollWheel = mouse.scrollWheel; + this.cursorX = mouse.cursorX; + this.cursorY = mouse.cursorY; + } + @Override public boolean equals(Object obj) { if (obj instanceof VirtualMouse) { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java index 7e216334..07a2b4cf 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java @@ -134,8 +134,9 @@ public boolean equals(Object obj) { } /** - * Moves the data from another virtual peripheral into this peripheral without - * creating a new object. Deletes the data in the other peripheral + * Moves the data from another virtual peripheral into this peripheral without creating a new object.
+ * Deletes the data in the other peripheral.
+ * Ignores {@link com.minecrafttas.tasmod.virtual.Subtickable.subtickList} * * @param peripheral The peripheral to move from */ @@ -149,7 +150,8 @@ protected void moveFrom(T peripheral) { /** * Copies the data from another virtual peripheral into this peripheral without creating a new object.
- * Does not delete the data from the other peripehral + * Does not delete the data from the other peripehral.
+ * Ignores {@link com.minecrafttas.tasmod.virtual.Subtickable.subtickList} * * @param peripheral The peripheral to copy from */ @@ -159,4 +161,16 @@ protected void copyFrom(T peripheral) { this.pressedKeys.clear(); this.pressedKeys.addAll(peripheral.pressedKeys); } + + /** + * Copies the data from another virtual peripheral similar to {@link #copyFrom(VirtualPeripheral)}, but including the {@link com.minecrafttas.tasmod.virtual.Subtickable.subtickList} + * @param peripheral + */ + protected void deepCopyFrom(T peripheral) { + if(peripheral == null || !peripheral.isParent()) + return; + copyFrom(peripheral); + this.subtickList.clear(); + this.subtickList.addAll(peripheral.subtickList); + } } diff --git a/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java b/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java index c42d8ede..30fe8e4d 100644 --- a/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java +++ b/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java @@ -152,7 +152,7 @@ void testCopyFrom() { VirtualCameraAngle actual = new VirtualCameraAngle(0f, 0f, true); - actual.copyFrom(expected); + actual.moveFrom(expected); // Test pitch and yaw assertEquals(expected.getPitch(), actual.getPitch()); From d62d38266c5b5fdc1a07e92f7fee34a378b84131 Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 1 Apr 2024 21:58:18 +0200 Subject: [PATCH 11/27] [PlaybackController] Add implement events into controller --- src/main/java/com/minecrafttas/tasmod/TASmodClient.java | 1 + .../com/minecrafttas/tasmod/mixin/MixinMinecraft.java | 5 ----- .../tasmod/playback/PlaybackControllerClient.java | 8 +++++--- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java index 7a40fb75..62bd30c9 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java @@ -153,6 +153,7 @@ public void onInitializeClient() { } return gui; })); + EventListenerRegistry.register(controller); // Register packet handlers LOGGER.info(LoggerMarkers.Networking, "Registering network handlers on client"); diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java index 75a2e914..a4e77c57 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java @@ -91,9 +91,4 @@ public void injectRunTick(CallbackInfo ci) throws IOException { public long fixMouseWheel(long twohundredLong) { return (long) Math.max(4000F / TASmodClient.tickratechanger.ticksPerSecond, 200L); } - - @Inject(method = "runTick", at = @At(value = "RETURN")) - public void injectRunTickReturn(CallbackInfo ci) { - TASmodClient.controller.nextTick(); // TODO Replace with event - } } diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index cfe83723..58ea2051 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -30,6 +30,7 @@ import com.minecrafttas.mctcommon.server.interfaces.PacketID; import com.minecrafttas.tasmod.TASmod; import com.minecrafttas.tasmod.TASmodClient; +import com.minecrafttas.tasmod.events.EventClient.EventClientTickPost; import com.minecrafttas.tasmod.events.EventClient.EventVirtualCameraAngleTick; import com.minecrafttas.tasmod.events.EventClient.EventVirtualKeyboardTick; import com.minecrafttas.tasmod.events.EventClient.EventVirtualMouseTick; @@ -70,7 +71,7 @@ * @author Scribble * */ -public class PlaybackControllerClient implements ClientPacketHandler, EventVirtualKeyboardTick, EventVirtualMouseTick, EventVirtualCameraAngleTick{ +public class PlaybackControllerClient implements ClientPacketHandler, EventVirtualKeyboardTick, EventVirtualMouseTick, EventVirtualCameraAngleTick, EventClientTickPost{ /** * The current state of the controller. @@ -373,9 +374,10 @@ public VirtualKeyboard onVirtualKeyboardTick(VirtualKeyboard vkeyboard) { * {@linkplain #mouse} and {@linkplain #subticks} are retrieved and emulated as * the next inputs */ - public void nextTick() { + @Override + public void onClientTickPost(Minecraft mc) { /* Stop the playback while player is still loading */ - EntityPlayerSP player = Minecraft.getMinecraft().player; + EntityPlayerSP player = mc.player; if (player != null && player.addedToChunk) { if (isPaused() && tempPause != TASstate.NONE) { From 5be5eb18522816a11e491b3d5b4d89d39a0cbf71 Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 1 Apr 2024 21:59:36 +0200 Subject: [PATCH 12/27] [PlaybackController] Connect new VirtualInput with controller --- .../com/minecrafttas/tasmod/TASmodClient.java | 13 +++++---- .../playback/PlaybackControllerClient.java | 29 ++++++++++++++----- .../tasmod/virtual/VirtualInput.java | 6 ++-- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java index 62bd30c9..58139a7f 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java @@ -196,14 +196,15 @@ 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(); + controller.setTASState(TASstate.RECORDING); }, 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(); - } +// try { +// TASmodClient.client = new Client("localhost", TASmod.networkingport-1, TASmodPackets.values(), mc.getSession().getProfile().getName(), true); +// } catch (Exception e) { +// e.printStackTrace(); +// } + controller.setTASState(TASstate.PLAYBACK); }, VirtualKeybindings::isKeyDown))); blockedKeybindings.forEach(VirtualKeybindings::registerBlockedKeyBinding); diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index 58ea2051..0d13618c 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -344,19 +344,34 @@ public TASstate getState() { // These act as an input and output, depending if a recording or a playback is // running - @Override - public VirtualCameraAngle onVirtualCameraTick(VirtualCameraAngle vcamera) { - return null; - } - @Override public VirtualMouse onVirtualMouseTick(VirtualMouse vmouse) { - return null; + if (state == TASstate.RECORDING) { + this.mouse.deepCopyFrom(vmouse); + } else if (state == TASstate.PLAYBACK) { + vmouse.deepCopyFrom(this.mouse); + } + return vmouse; } @Override public VirtualKeyboard onVirtualKeyboardTick(VirtualKeyboard vkeyboard) { - return null; + if (state == TASstate.RECORDING) { + this.keyboard.deepCopyFrom(vkeyboard); + } else if (state == TASstate.PLAYBACK) { + vkeyboard.deepCopyFrom(this.keyboard); + } + return vkeyboard; + } + + @Override + public VirtualCameraAngle onVirtualCameraTick(VirtualCameraAngle vcamera) { + if (state == TASstate.RECORDING) { + this.subticks.deepCopyFrom(vcamera); + } else if (state == TASstate.PLAYBACK) { + vcamera.deepCopyFrom(vcamera); + } + return vcamera; } /** diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index e2a49bf9..99c02aea 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -406,7 +406,7 @@ public void updateNextMouse(int keycode, boolean keystate, int scrollwheel, int * @see MixinMinecraft#playback_injectRunTickMouse(org.spongepowered.asm.mixin.injection.callback.CallbackInfo) */ public void nextMouseTick() { - nextMouse.moveFrom((VirtualMouse) EventListenerRegistry.fireEvent(EventVirtualMouseTick.class, nextMouse)); + EventListenerRegistry.fireEvent(EventVirtualMouseTick.class, nextMouse); currentMouse.getVirtualEvents(nextMouse, mouseEventQueue); currentMouse.moveFrom(nextMouse); } @@ -592,9 +592,9 @@ public void updateNextCameraAngle(float pitchDelta, float yawDelta) { * @see MixinEntityRenderer#runUpdate(float) */ public void nextCameraTick() { - nextCameraAngle.copyFrom((VirtualCameraAngle) EventListenerRegistry.fireEvent(EventVirtualCameraAngleTick.class, nextCameraAngle)); + nextCameraAngle.moveFrom((VirtualCameraAngle) EventListenerRegistry.fireEvent(EventVirtualCameraAngleTick.class, nextCameraAngle)); nextCameraAngle.getStates(cameraAngleInterpolationStates); - currentCameraAngle.copyFrom(nextCameraAngle); + currentCameraAngle.moveFrom(nextCameraAngle); } /** From 08f16ff34cdc9351ac23b5d54a16bbddbaa5156a Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 1 Apr 2024 22:01:21 +0200 Subject: [PATCH 13/27] Fixes crash when no inputs are loaded (#185) - However, things don't seem to be properly reset --- .../minecrafttas/tasmod/playback/PlaybackControllerClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index 0d13618c..92d395cd 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -447,7 +447,7 @@ private void playbackNextTick() { } /* Stop condition */ - if (index == inputs.size()) { + if (index == inputs.size() || inputs.isEmpty()) { unpressContainer(); setTASState(TASstate.NONE); } From 4264c62611107dac7bf79a3cfdd770a36e2e5ebf Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 1 Apr 2024 22:07:54 +0200 Subject: [PATCH 14/27] Fix test --- src/test/java/mctcommon/event/EventTest.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/test/java/mctcommon/event/EventTest.java b/src/test/java/mctcommon/event/EventTest.java index 23fea348..fa0eeec5 100644 --- a/src/test/java/mctcommon/event/EventTest.java +++ b/src/test/java/mctcommon/event/EventTest.java @@ -160,9 +160,7 @@ void testUnregister() { EventListenerRegistry.unregister(event); - Exception exception = assertThrows(EventException.class, () -> EventListenerRegistry.fireEvent(TestEvent.class)); - - String expected = "mctcommon.event.EventTest$TestEvent: The event has not been registered yet"; - assertEquals(expected, exception.getMessage()); + EventListenerRegistry.fireEvent(TestEvent.class); + return; } } From 7f3fab5f44e4f9cde10c4bbc8dd9bc33db0e9af4 Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 2 Apr 2024 21:23:32 +0200 Subject: [PATCH 15/27] Update Loom to 1.6, Update loader to 0.15.9 --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 59afe362..8ff73a8a 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.6 -loom_version=1.5-SNAPSHOT +loader_version=0.15.9 +loom_version=1.6-SNAPSHOT # Mod properties mod_name=Tool-Assisted Speedrun Mod From 6d2594b7d922a076d10eef18a7f8d4b8218e165a Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 2 Apr 2024 21:55:08 +0200 Subject: [PATCH 16/27] [PlaybackController] Extracting start/stop recording/playback from setTASState - Fixed issues with deep copy - Fixed bug in interpolation leading to nullpointer exception --- .../playback/PlaybackControllerClient.java | 76 +++++++++++-------- .../tasmod/virtual/VirtualCameraAngle.java | 2 +- .../tasmod/virtual/VirtualInput.java | 8 +- .../java/tasmod/virtual/VirtualInputTest.java | 12 +-- 4 files changed, 58 insertions(+), 40 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index 92d395cd..a566bd06 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -191,31 +191,11 @@ public String setTASStateClient(TASstate stateIn, boolean verbose) { } else if (state == TASstate.NONE) { // If the container is currently doing nothing switch (stateIn) { case PLAYBACK: - LOGGER.debug(LoggerMarkers.Playback, "Starting playback"); - if (Minecraft.getMinecraft().player != null && !startLocation.isEmpty()) { - try { - tpPlayer(startLocation); - } catch (NumberFormatException e) { - state = TASstate.NONE; - e.printStackTrace(); - return verbose ? TextFormatting.RED + "An error occured while reading the start location of the TAS. The file might be broken" : ""; - } - } - Minecraft.getMinecraft().gameSettings.chatLinks = false; // #119 - index = 0; + startPlayback(); state = TASstate.PLAYBACK; - creditsPrinted = false; - TASmod.ktrngHandler.setInitialSeed(startSeed); return verbose ? TextFormatting.GREEN + "Starting playback" : ""; case RECORDING: - LOGGER.debug(LoggerMarkers.Playback, "Starting recording"); - if (Minecraft.getMinecraft().player != null && startLocation.isEmpty()) { - startLocation = getStartLocation(Minecraft.getMinecraft().player); - } - if (this.inputs.isEmpty()) { - inputs.add(new TickInputContainer(index)); - desyncMonitor.recordNull(index); - } + startRecording(); state = TASstate.RECORDING; return verbose ? TextFormatting.GREEN + "Starting a recording" : ""; case PAUSED: @@ -235,8 +215,7 @@ public String setTASStateClient(TASstate stateIn, boolean verbose) { tempPause = TASstate.RECORDING; return verbose ? TextFormatting.GREEN + "Pausing a recording" : ""; case NONE: - LOGGER.debug(LoggerMarkers.Playback, "Stopping a recording"); - TASmodClient.virtual.clear(); + stopRecording(); state = TASstate.NONE; return verbose ? TextFormatting.GREEN + "Stopping the recording" : ""; } @@ -253,9 +232,7 @@ public String setTASStateClient(TASstate stateIn, boolean verbose) { 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.clear(); + stopPlayback(); state = TASstate.NONE; return verbose ? TextFormatting.GREEN + "Stopping the playback" : ""; } @@ -283,7 +260,46 @@ public String setTASStateClient(TASstate stateIn, boolean verbose) { } return "Something went wrong ._."; } + + private void startRecording() { + LOGGER.debug(LoggerMarkers.Playback, "Starting recording"); + if (Minecraft.getMinecraft().player != null && startLocation.isEmpty()) { + startLocation = getStartLocation(Minecraft.getMinecraft().player); + } + if (this.inputs.isEmpty()) { + inputs.add(new TickInputContainer(index)); + desyncMonitor.recordNull(index); + } + } + + private void stopRecording() { + LOGGER.debug(LoggerMarkers.Playback, "Stopping a recording"); + TASmodClient.virtual.clear(); + } + + private void startPlayback() { + LOGGER.debug(LoggerMarkers.Playback, "Starting playback"); + if (Minecraft.getMinecraft().player != null && !startLocation.isEmpty()) { + try { + tpPlayer(startLocation); + } catch (NumberFormatException e) { + state = TASstate.NONE; + e.printStackTrace(); +// return verbose ? TextFormatting.RED + "An error occured while reading the start location of the TAS. The file might be broken" : ""; + } + } + Minecraft.getMinecraft().gameSettings.chatLinks = false; // #119 + index = 0; + creditsPrinted = false; + TASmod.ktrngHandler.setInitialSeed(startSeed); + } + private void stopPlayback() { + LOGGER.debug(LoggerMarkers.Playback, "Stopping a playback"); + Minecraft.getMinecraft().gameSettings.chatLinks = true; + TASmodClient.virtual.clear(); + } + /** * Switches between the paused state and the state it was in before the pause * @@ -351,7 +367,7 @@ public VirtualMouse onVirtualMouseTick(VirtualMouse vmouse) { } else if (state == TASstate.PLAYBACK) { vmouse.deepCopyFrom(this.mouse); } - return vmouse; + return vmouse.clone(); } @Override @@ -361,7 +377,7 @@ public VirtualKeyboard onVirtualKeyboardTick(VirtualKeyboard vkeyboard) { } else if (state == TASstate.PLAYBACK) { vkeyboard.deepCopyFrom(this.keyboard); } - return vkeyboard; + return vkeyboard.clone(); } @Override @@ -371,7 +387,7 @@ public VirtualCameraAngle onVirtualCameraTick(VirtualCameraAngle vcamera) { } else if (state == TASstate.PLAYBACK) { vcamera.deepCopyFrom(vcamera); } - return vcamera; + return vcamera.clone(); } /** diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java index 79782c24..ddd68e20 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java @@ -131,7 +131,7 @@ public void moveFrom(VirtualCameraAngle camera) { * @param camera The camera to copy from */ public void deepCopyFrom(VirtualCameraAngle camera) { - if(camera == null) + if(camera == null || !camera.isParent()) return; this.pitch = camera.pitch; this.yaw = camera.yaw; diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index 99c02aea..1e07cfa2 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -13,6 +13,7 @@ import com.minecrafttas.mctcommon.events.EventListenerRegistry; import com.minecrafttas.tasmod.events.EventClient.EventVirtualCameraAngleTick; +import com.minecrafttas.tasmod.events.EventClient.EventVirtualKeyboardTick; import com.minecrafttas.tasmod.events.EventClient.EventVirtualMouseTick; import com.minecrafttas.tasmod.mixin.playbackhooks.MixinEntityRenderer; import com.minecrafttas.tasmod.mixin.playbackhooks.MixinMinecraft; @@ -247,6 +248,7 @@ public void updateNextKeyboard(int keycode, boolean keystate, char character, bo * @see MixinMinecraft#playback_injectRunTickKeyboard(org.spongepowered.asm.mixin.injection.callback.CallbackInfo) */ public void nextKeyboardTick() { + nextKeyboard.deepCopyFrom((VirtualKeyboard) EventListenerRegistry.fireEvent(EventVirtualKeyboardTick.class, nextKeyboard)); currentKeyboard.getVirtualEvents(nextKeyboard, keyboardEventQueue); currentKeyboard.moveFrom(nextKeyboard); } @@ -406,7 +408,7 @@ public void updateNextMouse(int keycode, boolean keystate, int scrollwheel, int * @see MixinMinecraft#playback_injectRunTickMouse(org.spongepowered.asm.mixin.injection.callback.CallbackInfo) */ public void nextMouseTick() { - EventListenerRegistry.fireEvent(EventVirtualMouseTick.class, nextMouse); + nextMouse.deepCopyFrom((VirtualMouse) EventListenerRegistry.fireEvent(EventVirtualMouseTick.class, nextMouse)); currentMouse.getVirtualEvents(nextMouse, mouseEventQueue); currentMouse.moveFrom(nextMouse); } @@ -592,7 +594,7 @@ public void updateNextCameraAngle(float pitchDelta, float yawDelta) { * @see MixinEntityRenderer#runUpdate(float) */ public void nextCameraTick() { - nextCameraAngle.moveFrom((VirtualCameraAngle) EventListenerRegistry.fireEvent(EventVirtualCameraAngleTick.class, nextCameraAngle)); + nextCameraAngle.deepCopyFrom((VirtualCameraAngle) EventListenerRegistry.fireEvent(EventVirtualCameraAngleTick.class, nextCameraAngle)); nextCameraAngle.getStates(cameraAngleInterpolationStates); currentCameraAngle.moveFrom(nextCameraAngle); } @@ -651,7 +653,7 @@ public Triple getInterpolatedState(float partialTick, float 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()-1, partialTick); // Get interpolate index interpolatedPitch = cameraAngleInterpolationStates.get(index).getPitch(); interpolatedYaw = cameraAngleInterpolationStates.get(index).getYaw(); diff --git a/src/test/java/tasmod/virtual/VirtualInputTest.java b/src/test/java/tasmod/virtual/VirtualInputTest.java index ed8a38b7..363bb8ec 100644 --- a/src/test/java/tasmod/virtual/VirtualInputTest.java +++ b/src/test/java/tasmod/virtual/VirtualInputTest.java @@ -314,7 +314,7 @@ void testInterpolationEnabled(){ Triple actual = virtual.CAMERA_ANGLE.getInterpolatedState(0f, 0f, 0f, true); assertEquals(expected, actual); - expected = Triple.of(10f, 10f, 0f); + expected = Triple.of(0f, 0f, 0f); actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.1f, 0f, 0f, true); assertEquals(expected, actual); @@ -322,23 +322,23 @@ void testInterpolationEnabled(){ actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.199f, 0f, 0f, true); assertEquals(expected, actual); - expected = Triple.of(20f, 20f, 0f); + expected = Triple.of(10f, 10f, 0f); actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.2f, 0f, 0f, true); assertEquals(expected, actual); - expected = Triple.of(30f, 30f, 0f); + expected = Triple.of(20f, 20f, 0f); actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.3f, 0f, 0f, true); assertEquals(expected, actual); - expected = Triple.of(40f, 40f, 0f); + expected = Triple.of(30f, 30f, 0f); actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.4f, 0f, 0f, true); assertEquals(expected, actual); - expected = Triple.of(50f, 50f, 0f); + expected = Triple.of(40f, 40f, 0f); actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.5f, 0f, 0f, true); assertEquals(expected, actual); - expected = Triple.of(60f, 60f, 0f); + expected = Triple.of(50f, 50f, 0f); actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.6f, 0f, 0f, true); assertEquals(expected, actual); } From 017314d8ee82e29c7df9ac3e6b994cb02f146081 Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 2 Apr 2024 22:04:49 +0200 Subject: [PATCH 17/27] Update gradle version in workflows to 8.6 --- .github/workflows/build.yml | 2 +- .github/workflows/buildandupload.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6845779c..d98a5741 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,7 +19,7 @@ jobs: - name: Setup Gradle uses: gradle/gradle-build-action@v2.4.0 with: - gradle-version: 8.4 + gradle-version: 8.6 - name: Build TASmod with Gradle run: gradle build - name: Upload Test Report diff --git a/.github/workflows/buildandupload.yml b/.github/workflows/buildandupload.yml index f163ffee..16343d43 100644 --- a/.github/workflows/buildandupload.yml +++ b/.github/workflows/buildandupload.yml @@ -20,7 +20,7 @@ jobs: - name: Setup Gradle uses: gradle/gradle-build-action@v2.4.0 with: - gradle-version: 8.4 + gradle-version: 8.6 - name: Build TASmod with Gradle run: gradle build - name: Upload artifact From 87ab153c453cf4f306cbcca9a444ec5cc669bfa8 Mon Sep 17 00:00:00 2001 From: Scribble Date: Wed, 3 Apr 2024 15:13:01 +0200 Subject: [PATCH 18/27] [VirtualInput] Renamed clone to shallowClone and added clone `clone()` used to just clone the object without the associated subticks. This has been renamed to `shallowClone()` and now clone actually does a deep clone of the VirtualPeripherals --- .../tasmod/virtual/VirtualCameraAngle.java | 8 ++- .../tasmod/virtual/VirtualKeyboard.java | 20 ++++-- .../tasmod/virtual/VirtualMouse.java | 8 ++- .../virtual/VirtualCameraAngleTest.java | 8 ++- .../virtual/VirtualInputEventFiring.java | 66 +++++++++++++++++++ .../tasmod/virtual/VirtualKeyboardTest.java | 8 ++- .../java/tasmod/virtual/VirtualMouseTest.java | 8 ++- 7 files changed, 109 insertions(+), 17 deletions(-) create mode 100644 src/test/java/tasmod/virtual/VirtualInputEventFiring.java diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java index ddd68e20..e46a16d2 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java @@ -84,7 +84,7 @@ public void update(float pitchDelta, float yawDelta) { return; } if(isParent() && !ignoreFirstUpdate()) { - addSubtick(clone()); + addSubtick(shallowClone()); } this.pitch = MathHelper.clamp(this.pitch + pitchDelta, -90.0F, 90.0F); this.yaw += yawDelta; @@ -152,9 +152,13 @@ public void clear() { /** * Creates a clone of this object as a subtick */ + public VirtualCameraAngle shallowClone() { + return new VirtualCameraAngle(pitch, yaw); + } + @Override public VirtualCameraAngle clone() { - return new VirtualCameraAngle(pitch, yaw); + return new VirtualCameraAngle(pitch, yaw, new ArrayList<>(subtickList), isIgnoreFirstUpdate()); } @Override diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java index 22e4d793..123bc8d4 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualKeyboard.java @@ -127,7 +127,7 @@ public VirtualKeyboard(Set pressedKeys, List charList, List< */ public void update(int keycode, boolean keystate, char keycharacter, boolean repeatEventsEnabled) { if(isParent() && !ignoreFirstUpdate()) { - addSubtick(clone()); + addSubtick(shallowClone()); } charList.clear(); if (keystate) { @@ -140,6 +140,14 @@ public void update(int keycode, boolean keystate, char keycharacter) { update(keycode, keystate, keycharacter, false); } + public void update(VirtualKey key, boolean keystate, char keycharacter) { + update(key.getKeycode(), keystate, keycharacter); + } + + public void update(VirtualKey key, boolean keystate, char keycharacter, boolean repeatEventsEnabled) { + update(key.getKeycode(), 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 @@ -281,12 +289,16 @@ private String charListToString(List charList) { } /** - * Clones this VirtualKeyboard without subticks + * Clones this VirtualKeyboard without subticks. */ - @Override - public VirtualKeyboard clone() { + public VirtualKeyboard shallowClone() { return new VirtualKeyboard(new HashSet<>(this.pressedKeys), new ArrayList<>(this.charList), isIgnoreFirstUpdate()); } + + @Override + public VirtualKeyboard clone(){ + return new VirtualKeyboard(new HashSet<>(this.pressedKeys), new ArrayList<>(this.charList), new ArrayList<>(subtickList), isIgnoreFirstUpdate()); + } @Override public void moveFrom(VirtualKeyboard keyboard) { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java index 86f1f513..5ec5cc40 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java @@ -85,7 +85,7 @@ public VirtualMouse(Set pressedKeys, int scrollWheel, Integer cursorX, public void update(int keycode, boolean keystate, int scrollwheel, Integer cursorX, Integer cursorY) { if(isParent() && !ignoreFirstUpdate()) { - addSubtick(clone()); + addSubtick(shallowClone()); } setPressed(keycode, keystate); this.scrollWheel = scrollwheel; @@ -220,9 +220,13 @@ private String toString2(){ /** * Clones this VirtualMouse without subticks */ + public VirtualMouse shallowClone() { + return new VirtualMouse(new HashSet<>(this.pressedKeys), scrollWheel, cursorX, cursorY, null, ignoreFirstUpdate()); + } + @Override public VirtualMouse clone() { - return new VirtualMouse(new HashSet<>(this.pressedKeys), scrollWheel, cursorX, cursorY, null, ignoreFirstUpdate()); + return new VirtualMouse(new HashSet<>(this.pressedKeys), scrollWheel, cursorX, cursorY, new ArrayList<>(subtickList), isIgnoreFirstUpdate()); } @Override diff --git a/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java b/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java index 30fe8e4d..d8773e25 100644 --- a/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java +++ b/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java @@ -214,20 +214,22 @@ void testToStringSubticks() { } /** - * Test cloning the camera angle + * Test shallow cloning the camera angle */ @Test - void testClone() { + void testShallowClone() { float x = 1f; float y = 2f; VirtualCameraAngle test = new VirtualCameraAngle(x, y); - VirtualCameraAngle actual = test.clone(); + VirtualCameraAngle actual = test.shallowClone(); assertEquals(1f, actual.getPitch()); assertEquals(2f, actual.getYaw()); } + + // DeepCloning /** * Test equals diff --git a/src/test/java/tasmod/virtual/VirtualInputEventFiring.java b/src/test/java/tasmod/virtual/VirtualInputEventFiring.java new file mode 100644 index 00000000..2dcc7ada --- /dev/null +++ b/src/test/java/tasmod/virtual/VirtualInputEventFiring.java @@ -0,0 +1,66 @@ +package tasmod.virtual; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +import com.minecrafttas.mctcommon.events.EventListenerRegistry; +import com.minecrafttas.mctcommon.events.EventListenerRegistry.EventBase; +import com.minecrafttas.tasmod.virtual.VirtualKey; +import com.minecrafttas.tasmod.virtual.VirtualKeyboard; + +public class VirtualInputEventFiring { + + interface EventTest extends EventBase{ + + void onTest(VirtualKeyboard keyboard); + } + + interface EventCopy extends EventBase{ + + void onCopy(VirtualKeyboard keyboard); + } + + @BeforeAll + static void beforeAll() { + EventTest clear = (keyboard)-> { + keyboard.clear(); + }; + EventCopy copy = (keyboard)-> { + VirtualKeyboard newkeyboard = new VirtualKeyboard(); + newkeyboard.update(VirtualKey.A, true, 'a'); + newkeyboard.update(VirtualKey.D, true, 'd'); + keyboard.deepCopyFrom(newkeyboard); + }; + EventListenerRegistry.register(clear, copy); + } + + @Test + void testClear() { + VirtualKeyboard keyboard = new VirtualKeyboard(); + + keyboard.update(VirtualKey.W, true, 'w'); + keyboard.update(VirtualKey.S, true, 's'); + + EventListenerRegistry.fireEvent(EventTest.class, keyboard); + + assertTrue(keyboard.getPressedKeys().isEmpty()); + } + + @Test + void testCopy() { + + VirtualKeyboard actual = new VirtualKeyboard(); + + actual.update(VirtualKey.W, true, 'w'); + actual.update(VirtualKey.S, true, 's'); + + VirtualKeyboard expected = new VirtualKeyboard(); + expected.update(VirtualKey.A, true, 'a'); + expected.update(VirtualKey.D, true, 'd'); + + EventListenerRegistry.fireEvent(EventCopy.class, actual); + + assertEquals(expected, actual); + } +} diff --git a/src/test/java/tasmod/virtual/VirtualKeyboardTest.java b/src/test/java/tasmod/virtual/VirtualKeyboardTest.java index 2e57968d..cb30b6b5 100644 --- a/src/test/java/tasmod/virtual/VirtualKeyboardTest.java +++ b/src/test/java/tasmod/virtual/VirtualKeyboardTest.java @@ -201,10 +201,10 @@ void testNotEquals() { } /** - * Test cloning the keyboard + * Test shallow cloning the keyboard */ @Test - void testClone() { + void testShallowClone() { Set testKeycodeSet = new HashSet<>(); testKeycodeSet.add(VirtualKey.W.getKeycode()); testKeycodeSet.add(VirtualKey.S.getKeycode()); @@ -214,10 +214,12 @@ void testClone() { testCharList.add('s'); VirtualKeyboard actual = new VirtualKeyboard(testKeycodeSet, testCharList); - VirtualKeyboard test2 = actual.clone(); + VirtualKeyboard test2 = actual.shallowClone(); assertEquals(actual, test2); } + + //TODO DeepClone /** * Test moveFrom method diff --git a/src/test/java/tasmod/virtual/VirtualMouseTest.java b/src/test/java/tasmod/virtual/VirtualMouseTest.java index 79e3a828..c63915b4 100644 --- a/src/test/java/tasmod/virtual/VirtualMouseTest.java +++ b/src/test/java/tasmod/virtual/VirtualMouseTest.java @@ -177,19 +177,21 @@ void testNotEquals() { } /** - * Test cloning the mouse + * Test shallow cloning the mouse */ @Test - void testClone() { + void testShallowClone() { Set testKeycodeSet = new HashSet<>(); testKeycodeSet.add(VirtualKey.LC.getKeycode()); testKeycodeSet.add(VirtualKey.MC.getKeycode()); VirtualMouse actual = new VirtualMouse(testKeycodeSet, 10, 3, 2); - VirtualMouse test2 = actual.clone(); + VirtualMouse test2 = actual.shallowClone(); assertEquals(actual, test2); } + + //TODO DeepClone /** * Test moveFrom method From a818f0838fae3e9375dbc99719d17611143d08ff Mon Sep 17 00:00:00 2001 From: Scribble Date: Thu, 4 Apr 2024 22:32:51 +0200 Subject: [PATCH 19/27] [PlaybackController] Fixed interpolation - [VirtualInput] Removed old interpolation - [VirtualInput] Add a way to disable recording subticks for camera angle --- .../playbackhooks/MixinEntityRenderer.java | 8 ++-- .../playback/PlaybackControllerClient.java | 20 +++++----- .../tasmod/virtual/VirtualCameraAngle.java | 16 ++++++-- .../tasmod/virtual/VirtualInput.java | 38 +++++++++++-------- .../tasmod/virtual/VirtualPeripheral.java | 1 + .../java/tasmod/virtual/VirtualInputTest.java | 16 ++++---- .../tasmod/virtual/VirtualKeyboardTest.java | 23 ++++++++--- 7 files changed, 78 insertions(+), 44 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 ee008ef1..c736c7f0 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/playbackhooks/MixinEntityRenderer.java @@ -81,7 +81,7 @@ public void playback_injectAtStartSection(float partialTicks, long nanoTime, Cal } mc.getTutorial().handleMouse(mc.mouseHelper); - TASmodClient.virtual.CAMERA_ANGLE.updateNextCameraAngle((float) -((double)deltaPitch * 0.15D * invertMouse), (float) ((double)deltaYaw * 0.15D)); + TASmodClient.virtual.CAMERA_ANGLE.updateNextCameraAngle((float) -((double)deltaPitch * 0.15D * invertMouse), (float) ((double)deltaYaw * 0.15D), TASmodClient.tickratechanger.ticksPerSecond != 0); } } @@ -174,11 +174,13 @@ public float redirect_orientCameraYaw(float yaw, @Share("pitch") LocalFloatRef s */ private float redirectCam(float pitch, float yaw) { Triple interpolated = TASmodClient.virtual.CAMERA_ANGLE.getInterpolatedState(Minecraft.getMinecraft().timer.renderPartialTicks, pitch, yaw, TASmodClient.controller.isPlayingback()); + float pitch2 = interpolated.getLeft(); + float yaw2 = interpolated.getMiddle(); // Update pitch - GlStateManager.rotate(interpolated.getLeft(), 1.0f, 0.0f, 0.0f); + GlStateManager.rotate(pitch2, 1.0f, 0.0f, 0.0f); // Update roll GlStateManager.rotate(interpolated.getRight(), 0.0f, 0.0f, 1.0f); // Update yaw - return interpolated.getMiddle(); + return yaw2; } } diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index a566bd06..7941fb73 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -92,7 +92,7 @@ public class PlaybackControllerClient implements ClientPacketHandler, EventVirtu private VirtualMouse mouse = new VirtualMouse(); - private VirtualCameraAngle subticks = new VirtualCameraAngle(); + private VirtualCameraAngle camera = new VirtualCameraAngle(); public final File directory = new File(Minecraft.getMinecraft().mcDataDir.getAbsolutePath() + File.separator + "saves" + File.separator + "tasfiles"); @@ -383,9 +383,9 @@ public VirtualKeyboard onVirtualKeyboardTick(VirtualKeyboard vkeyboard) { @Override public VirtualCameraAngle onVirtualCameraTick(VirtualCameraAngle vcamera) { if (state == TASstate.RECORDING) { - this.subticks.deepCopyFrom(vcamera); + this.camera.deepCopyFrom(vcamera); } else if (state == TASstate.PLAYBACK) { - vcamera.deepCopyFrom(vcamera); + vcamera.deepCopyFrom(this.camera); } return vcamera.clone(); } @@ -394,15 +394,15 @@ public VirtualCameraAngle onVirtualCameraTick(VirtualCameraAngle vcamera) { * Updates the input container.
*
* During a recording this adds the {@linkplain #keyboard}, {@linkplain #mouse} - * and {@linkplain #subticks} to {@linkplain #inputs} and increases the + * and {@linkplain #camera} to {@linkplain #inputs} and increases the * {@linkplain #index}.
*
* During playback the opposite is happening, getting the inputs from * {@linkplain #inputs} and temporarily storing them in {@linkplain #keyboard}, - * {@linkplain #mouse} and {@linkplain #subticks}.
+ * {@linkplain #mouse} and {@linkplain #camera}.
*
* Then in {@linkplain VirtualInput}, {@linkplain #keyboard}, - * {@linkplain #mouse} and {@linkplain #subticks} are retrieved and emulated as + * {@linkplain #mouse} and {@linkplain #camera} are retrieved and emulated as * the next inputs */ @Override @@ -432,9 +432,9 @@ private void recordNextTick() { if (inputs.size() < index) { LOGGER.warn("Index is {} inputs bigger than the container!", index - inputs.size()); } - inputs.add(new TickInputContainer(index, keyboard.clone(), mouse.clone(), subticks.clone())); + inputs.add(new TickInputContainer(index, keyboard.clone(), mouse.clone(), camera.clone())); } else { - inputs.set(index, new TickInputContainer(index, keyboard.clone(), mouse.clone(), subticks.clone())); + inputs.set(index, new TickInputContainer(index, keyboard.clone(), mouse.clone(), camera.clone())); } desyncMonitor.recordMonitor(index); // Capturing monitor values } @@ -472,7 +472,7 @@ private void playbackNextTick() { TickInputContainer tickcontainer = inputs.get(index); // Loads the new inputs from the container this.keyboard = tickcontainer.getKeyboard().clone(); this.mouse = tickcontainer.getMouse().clone(); - this.subticks = tickcontainer.getSubticks().clone(); + this.camera = tickcontainer.getSubticks().clone(); // check for control bytes ControlByteHandler.readCotrolByte(controlBytes.get(index)); } @@ -512,7 +512,7 @@ public void setIndex(int index) throws IndexOutOfBoundsException { TickInputContainer tickcontainer = inputs.get(index); this.keyboard = tickcontainer.getKeyboard(); this.mouse = tickcontainer.getMouse(); - this.subticks = tickcontainer.getSubticks(); + this.camera = tickcontainer.getSubticks(); } } else { throw new IndexOutOfBoundsException("Index is bigger than the container"); diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java index e46a16d2..607e46ef 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java @@ -1,12 +1,12 @@ package com.minecrafttas.tasmod.virtual; -import net.minecraft.util.math.MathHelper; - import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; +import net.minecraft.util.math.MathHelper; + /** * Stores the values of the camera angle of the player in a given timeframe.
*
@@ -80,10 +80,20 @@ public VirtualCameraAngle(Float pitch, Float yaw, List subti * @param yawDelta The difference between absolute coordinates of the yaw, is added to {@link VirtualCameraAngle#yaw} */ public void update(float pitchDelta, float yawDelta) { + update(pitchDelta, yawDelta, true); + } + + /** + * 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} + * @param updateSubtick If the previous camera should be added to {@link Subtickable#subtickList} + */ + public void update(float pitchDelta, float yawDelta, boolean updateSubtick) { if(pitch==null || yaw == null) { return; } - if(isParent() && !ignoreFirstUpdate()) { + if(isParent() && !ignoreFirstUpdate() && updateSubtick) { addSubtick(shallowClone()); } this.pitch = MathHelper.clamp(this.pitch + pitchDelta, -90.0F, 90.0F); diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index 1e07cfa2..3943ff11 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -583,8 +583,22 @@ public VirtualCameraAngleInput(VirtualCameraAngle preloadedCamera) { * @param yawDelta Relative rotationYaw delta from LWJGLs mouse delta. */ public void updateNextCameraAngle(float pitchDelta, float yawDelta) { + updateNextCameraAngle(pitchDelta, yawDelta, true); + } + + /** + * Update the camera angle.
+ *
+ * Runs every frame + * + * @see com.minecrafttas.tasmod.mixin.playbackhooks.MixinEntityRenderer#runUpdate(float); + * @param pitchDelta Relative rotationPitch delta from LWJGLs mouse delta. + * @param yawDelta Relative rotationYaw delta from LWJGLs mouse delta. + * @param updateSubtick Whether to add the previous camera angle to the {@link Subtickable#subtickList} + */ + public void updateNextCameraAngle(float pitchDelta, float yawDelta, boolean updateSubtick) { // LOGGER.debug("Pitch: {}, Yaw: {}", pitch, yaw); - nextCameraAngle.update(pitchDelta, yawDelta); + nextCameraAngle.update(pitchDelta, yawDelta, updateSubtick); } /** @@ -595,6 +609,7 @@ public void updateNextCameraAngle(float pitchDelta, float yawDelta) { */ public void nextCameraTick() { nextCameraAngle.deepCopyFrom((VirtualCameraAngle) EventListenerRegistry.fireEvent(EventVirtualCameraAngleTick.class, nextCameraAngle)); + cameraAngleInterpolationStates.clear(); nextCameraAngle.getStates(cameraAngleInterpolationStates); currentCameraAngle.moveFrom(nextCameraAngle); } @@ -641,24 +656,17 @@ 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 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); - } + + float interpolatedPitch = nextCameraAngle.getPitch() == null ? pitch : nextCameraAngle.getPitch(); + float interpolatedYaw = nextCameraAngle.getYaw() == null ? pitch : nextCameraAngle.getYaw() + 180; - float interpolatedPitch = 0f; - float interpolatedYaw = 0f; - - if (cameraAngleInterpolationStates.size() == 1) { // If no interpolation data was specified, interpolate over 2 values - interpolatedPitch = (float) MathHelper.clampedLerp(cameraAngleInterpolationStates.get(0).getPitch(), currentCameraAngle.getPitch(), partialTick); - interpolatedYaw = (float) MathHelper.clampedLerp(currentCameraAngle.getYaw(), cameraAngleInterpolationStates.get(0).getYaw() + 180, partialTick); - } else { - - int index = (int) MathHelper.clampedLerp(0, cameraAngleInterpolationStates.size()-1, partialTick); // Get interpolate index + if (enable && !cameraAngleInterpolationStates.isEmpty()) { + int index = (int) MathHelper.clampedLerp(0, cameraAngleInterpolationStates.size() - 1, partialTick); // Get interpolate index interpolatedPitch = cameraAngleInterpolationStates.get(index).getPitch(); - interpolatedYaw = cameraAngleInterpolationStates.get(index).getYaw(); - } + interpolatedYaw = cameraAngleInterpolationStates.get(index).getYaw() + 180; + } return Triple.of(interpolatedPitch, interpolatedYaw, 0f); } } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java index 07a2b4cf..e194a4b0 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java @@ -173,4 +173,5 @@ protected void deepCopyFrom(T peripheral) { this.subtickList.clear(); this.subtickList.addAll(peripheral.subtickList); } + } diff --git a/src/test/java/tasmod/virtual/VirtualInputTest.java b/src/test/java/tasmod/virtual/VirtualInputTest.java index 363bb8ec..125621cb 100644 --- a/src/test/java/tasmod/virtual/VirtualInputTest.java +++ b/src/test/java/tasmod/virtual/VirtualInputTest.java @@ -310,35 +310,35 @@ void testInterpolationEnabled(){ virtual.CAMERA_ANGLE.nextCameraTick(); - Triple expected = Triple.of(0f, 0f, 0f); + Triple expected = Triple.of(0f, 180f, 0f); Triple actual = virtual.CAMERA_ANGLE.getInterpolatedState(0f, 0f, 0f, true); assertEquals(expected, actual); - expected = Triple.of(0f, 0f, 0f); + expected = Triple.of(0f, 180f, 0f); actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.1f, 0f, 0f, true); assertEquals(expected, actual); - expected = Triple.of(10f, 10f, 0f); + expected = Triple.of(10f, 190f, 0f); actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.199f, 0f, 0f, true); assertEquals(expected, actual); - expected = Triple.of(10f, 10f, 0f); + expected = Triple.of(10f, 190f, 0f); actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.2f, 0f, 0f, true); assertEquals(expected, actual); - expected = Triple.of(20f, 20f, 0f); + expected = Triple.of(20f, 200f, 0f); actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.3f, 0f, 0f, true); assertEquals(expected, actual); - expected = Triple.of(30f, 30f, 0f); + expected = Triple.of(30f, 210f, 0f); actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.4f, 0f, 0f, true); assertEquals(expected, actual); - expected = Triple.of(40f, 40f, 0f); + expected = Triple.of(40f, 220f, 0f); actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.5f, 0f, 0f, true); assertEquals(expected, actual); - expected = Triple.of(50f, 50f, 0f); + expected = Triple.of(50f, 230f, 0f); actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.6f, 0f, 0f, true); assertEquals(expected, actual); } diff --git a/src/test/java/tasmod/virtual/VirtualKeyboardTest.java b/src/test/java/tasmod/virtual/VirtualKeyboardTest.java index cb30b6b5..7432b97a 100644 --- a/src/test/java/tasmod/virtual/VirtualKeyboardTest.java +++ b/src/test/java/tasmod/virtual/VirtualKeyboardTest.java @@ -213,13 +213,26 @@ void testShallowClone() { testCharList.add('w'); testCharList.add('s'); - VirtualKeyboard actual = new VirtualKeyboard(testKeycodeSet, testCharList); - VirtualKeyboard test2 = actual.shallowClone(); + VirtualKeyboard expected = new VirtualKeyboard(testKeycodeSet, testCharList); + VirtualKeyboard actual = expected.shallowClone(); - assertEquals(actual, test2); + assertEquals(expected, actual); } - - //TODO DeepClone + + /** + * Test deep cloning the keyboard + */ + @Test + void testDeepClone() { + VirtualKeyboard expected = new VirtualKeyboard(); + expected.update(VirtualKey.W, true, 'w'); + expected.update(VirtualKey.S, true, 's'); + + VirtualKeyboard actual = expected.clone(); + + assertEquals(expected, actual); + assertIterableEquals(expected.getSubticks(), actual.getSubticks()); + } /** * Test moveFrom method From f304244f68965e92b39a32fbecb336b2af177f6a Mon Sep 17 00:00:00 2001 From: Scribble Date: Fri, 5 Apr 2024 22:56:59 +0200 Subject: [PATCH 20/27] [VirtualInput] Added tests --- .../tasmod/commands/CommandLoadTAS.java | 1 + .../tasmod/commands/CommandPlay.java | 1 - .../tasmod/commands/CommandRecord.java | 1 - .../tasmod/commands/CommandSaveTAS.java | 1 + .../playback/PlaybackControllerClient.java | 5 +- .../playback/metadata/PlaybackMetadata.java | 16 +- .../tasmod/virtual/VirtualMouse.java | 27 +- .../java/tasmod/virtual/VirtualInputTest.java | 24 -- .../java/tasmod/virtual/VirtualMouseTest.java | 383 +++++++++--------- 9 files changed, 229 insertions(+), 230 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/commands/CommandLoadTAS.java b/src/main/java/com/minecrafttas/tasmod/commands/CommandLoadTAS.java index 858b4de2..0e2ef1d2 100644 --- a/src/main/java/com/minecrafttas/tasmod/commands/CommandLoadTAS.java +++ b/src/main/java/com/minecrafttas/tasmod/commands/CommandLoadTAS.java @@ -33,6 +33,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 does not work at the moment!")); if (sender instanceof EntityPlayer) { if (sender.canUseCommand(2, "load")) { if (args.length < 1) { diff --git a/src/main/java/com/minecrafttas/tasmod/commands/CommandPlay.java b/src/main/java/com/minecrafttas/tasmod/commands/CommandPlay.java index 64b0f027..2f03c713 100644 --- a/src/main/java/com/minecrafttas/tasmod/commands/CommandPlay.java +++ b/src/main/java/com/minecrafttas/tasmod/commands/CommandPlay.java @@ -38,7 +38,6 @@ 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 6373f781..56f58e36 100644 --- a/src/main/java/com/minecrafttas/tasmod/commands/CommandRecord.java +++ b/src/main/java/com/minecrafttas/tasmod/commands/CommandRecord.java @@ -38,7 +38,6 @@ 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/CommandSaveTAS.java b/src/main/java/com/minecrafttas/tasmod/commands/CommandSaveTAS.java index 4eaa6202..93063f98 100644 --- a/src/main/java/com/minecrafttas/tasmod/commands/CommandSaveTAS.java +++ b/src/main/java/com/minecrafttas/tasmod/commands/CommandSaveTAS.java @@ -41,6 +41,7 @@ public List getAliases() { @Override public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { + sender.sendMessage(new TextComponentString(TextFormatting.RED + "This feature does not work at the moment!")); if (sender instanceof EntityPlayer) { if (sender.canUseCommand(2, "save")) { if (args.length < 1) { diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index 7941fb73..120732c9 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -37,6 +37,7 @@ import com.minecrafttas.tasmod.monitoring.DesyncMonitoring; import com.minecrafttas.tasmod.networking.TASmodBufferBuilder; import com.minecrafttas.tasmod.networking.TASmodPackets; +import com.minecrafttas.tasmod.playback.metadata.PlaybackMetadata; import com.minecrafttas.tasmod.util.LoggerMarkers; import com.minecrafttas.tasmod.util.Scheduler.Task; import com.minecrafttas.tasmod.virtual.VirtualCameraAngle; @@ -66,7 +67,7 @@ * Information about the author etc. get stored in the playback controller too * and will be printed out in chat when the player loads into a world
* Inputs are saved and loaded to/from file via the - * {@linkplain PlaybackSerialiser} + * {@linkplain PlaybackSerialiser} TODO Update with new {@link PlaybackMetadata} * * @author Scribble * @@ -750,7 +751,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(); } @Override diff --git a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java index 1b09f09e..82f7c0f0 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java @@ -1,13 +1,9 @@ package com.minecrafttas.tasmod.playback.metadata; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; -import java.util.Properties; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -51,7 +47,7 @@ public String toString() { } return out; } - + public List toStringList() { List out = new ArrayList<>(); for (Object keyObj : metadata.keySet()) { @@ -61,24 +57,24 @@ public List toStringList() { } return out; } - + public String getExtensionName() { return extensionName; } - + public HashMap getMetadata() { return metadata; } - + @Override public boolean equals(Object obj) { - if(obj instanceof PlaybackMetadata) { + if (obj instanceof PlaybackMetadata) { PlaybackMetadata other = (PlaybackMetadata) obj; return other.metadata.equals(metadata) && other.extensionName.equals(extensionName); } return super.equals(obj); } - + public static PlaybackMetadata fromStringList(String extensionName, List list) { return fromStringList(list); } diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java index 5ec5cc40..ebfe0e08 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java @@ -83,16 +83,37 @@ public VirtualMouse(Set pressedKeys, int scrollWheel, Integer cursorX, this.cursorY = cursorY; } + /** + * Updates the mouse, adds a new subtick to this mouse + * @param keycode The keycode of this button + * @param keystate The keystate of this button, true for pressed + * @param scrollwheel The scroll wheel for this mouse + * @oaram cursorX The pointer location in the x axis + * @param cursorY The pointer location in the y axis + */ public void update(int keycode, boolean keystate, int scrollwheel, Integer cursorX, Integer cursorY) { - if(isParent() && !ignoreFirstUpdate()) { - addSubtick(shallowClone()); - } + if (isParent() && !ignoreFirstUpdate()) { + addSubtick(shallowClone()); + } setPressed(keycode, keystate); this.scrollWheel = scrollwheel; this.cursorX = cursorX; this.cursorY = cursorY; } + /** + * Updates the mouse, adds a new subtick to this mouse + * + * @param key The key + * @param keystate The keystate of this button, true for pressed + * @param scrollwheel The scroll wheel for this mouse + * @oaram cursorX The pointer location in the x axis + * @param cursorY The pointer location in the y axis + */ + public void update(VirtualKey key, boolean keystate, int scrollwheel, Integer cursorX, Integer cursorY) { + update(key.getKeycode(), keystate, scrollwheel, cursorX, cursorY); + } + @Override public void setPressed(int keycode, boolean keystate) { if (keycode < 0) { // Mouse buttons always have a keycode smaller than 0 diff --git a/src/test/java/tasmod/virtual/VirtualInputTest.java b/src/test/java/tasmod/virtual/VirtualInputTest.java index 125621cb..17fbd63f 100644 --- a/src/test/java/tasmod/virtual/VirtualInputTest.java +++ b/src/test/java/tasmod/virtual/VirtualInputTest.java @@ -9,7 +9,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import com.minecrafttas.mctcommon.events.EventListenerRegistry; @@ -342,27 +341,4 @@ void testInterpolationEnabled(){ 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); - } } diff --git a/src/test/java/tasmod/virtual/VirtualMouseTest.java b/src/test/java/tasmod/virtual/VirtualMouseTest.java index c63915b4..12a8a34c 100644 --- a/src/test/java/tasmod/virtual/VirtualMouseTest.java +++ b/src/test/java/tasmod/virtual/VirtualMouseTest.java @@ -22,7 +22,7 @@ import com.minecrafttas.tasmod.virtual.event.VirtualMouseEvent; class VirtualMouseTest { - + /** * Test the empty constructor */ @@ -35,42 +35,42 @@ void testEmptyConstructor() { assertEquals(0, actual.getCursorY()); assertTrue(actual.isParent()); } - + /** * Test constructor with premade keycode sets */ @Test void testSubtickConstructor() { - Set expected = new HashSet<>(); - expected.add(VirtualKey.LC.getKeycode()); - expected.add(VirtualKey.RC.getKeycode()); + Set expected = new HashSet<>(); + expected.add(VirtualKey.LC.getKeycode()); + expected.add(VirtualKey.RC.getKeycode()); - VirtualMouse actual = new VirtualMouse(expected, -15, 0, 2); + VirtualMouse actual = new VirtualMouse(expected, -15, 0, 2); - assertIterableEquals(expected, actual.getPressedKeys()); - assertEquals(-15, actual.getScrollWheel()); - assertEquals(0, actual.getCursorX()); - assertEquals(2, actual.getCursorY()); - assertFalse(actual.isParent()); + 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() { + VirtualMouse actual = new VirtualMouse(); + actual.setPressed(VirtualKey.LC.getKeycode(), true); + + assertIterableEquals(Arrays.asList(VirtualKey.LC.getKeycode()), actual.getPressedKeys()); + assertTrue(actual.isParent()); } - - /** - * Test setting the keycodes via setPressed to "pressed" - */ - @Test - void testSetPressedByKeycode(){ - VirtualMouse actual = new VirtualMouse(); - actual.setPressed(VirtualKey.LC.getKeycode(), true); - - assertIterableEquals(Arrays.asList(VirtualKey.LC.getKeycode()), actual.getPressedKeys()); - assertTrue(actual.isParent()); - } /** * Test setting the keynames via setPressed to "pressed" */ @Test - void testSetPressedByKeyname(){ + void testSetPressedByKeyname() { VirtualMouse actual = new VirtualMouse(); actual.setPressed("LC", true); @@ -82,7 +82,7 @@ void testSetPressedByKeyname(){ * Test setting the keycodes via setPressed to "unpressed" */ @Test - void testSetUnPressedByKeycode(){ + void testSetUnPressedByKeycode() { Set testKeycodeSet = new HashSet<>(); testKeycodeSet.add(VirtualKey.LC.getKeycode()); testKeycodeSet.add(VirtualKey.MBUTTON9.getKeycode()); @@ -96,7 +96,7 @@ void testSetUnPressedByKeycode(){ * Test setting the keynames via setPressed to "unpressed" */ @Test - void testSetUnPressedByKeyname(){ + void testSetUnPressedByKeyname() { Set testKeycodeSet = new HashSet<>(); testKeycodeSet.add(VirtualKey.LC.getKeycode()); testKeycodeSet.add(VirtualKey.MBUTTON9.getKeycode()); @@ -110,7 +110,7 @@ void testSetUnPressedByKeyname(){ * Test the toString method without subticks */ @Test - void testToString(){ + void testToString() { Set testKeycodeSet = new LinkedHashSet<>(); testKeycodeSet.add(VirtualKey.LC.getKeycode()); testKeycodeSet.add(VirtualKey.MC.getKeycode()); @@ -124,7 +124,7 @@ void testToString(){ * Test the toString method with subticks */ @Test - void testToStringSubtick(){ + void testToStringSubtick() { VirtualMouse actual = new VirtualMouse(); actual.update(VirtualKey.LC.getKeycode(), true, 10, 100, 120); actual.update(VirtualKey.MC.getKeycode(), true, 0, 12, 3); @@ -141,7 +141,6 @@ void testEquals() { testKeycodeSet.add(VirtualKey.W.getKeycode()); testKeycodeSet.add(VirtualKey.S.getKeycode()); - VirtualMouse actual = new VirtualMouse(testKeycodeSet, -15, 129, 340); VirtualMouse actual2 = new VirtualMouse(testKeycodeSet, -15, 129, 340); @@ -162,8 +161,6 @@ void testNotEquals() { testKeycodeSet.add(VirtualKey.RC.getKeycode()); VirtualMouse test2 = new VirtualMouse(testKeycodeSet2, -15, 1, 1); - - VirtualMouse test3 = new VirtualMouse(testKeycodeSet, -16, 1, 1); VirtualMouse test4 = new VirtualMouse(testKeycodeSet, -15, 2, 1); @@ -190,8 +187,21 @@ void testShallowClone() { assertEquals(actual, test2); } - - //TODO DeepClone + + /** + * Test deep cloning the mouse + */ + @Test + void testDeepClone() { + VirtualMouse expected = new VirtualMouse(); + expected.update(VirtualKey.LC, true, 15, 0, 0); + expected.update(VirtualKey.MOUSEMOVED, true, 0, 0, 0); + + VirtualMouse actual = expected.clone(); + + assertEquals(expected, actual); + assertIterableEquals(expected.getSubticks(), actual.getSubticks()); + } /** * Test moveFrom method @@ -206,11 +216,11 @@ void testMoveFrom() { VirtualMouse expected = moveFrom.clone(); - actual.update(VirtualKey.MBUTTON12.getKeycode(), true, 0,0,0); + actual.update(VirtualKey.MBUTTON12.getKeycode(), true, 0, 0, 0); actual.update(VirtualKey.MOUSEMOVED.getKeycode(), true, -120, -10, -10); actual.moveFrom(null); - + actual.moveFrom(moveFrom); assertIterableEquals(expected.getPressedKeys(), actual.getPressedKeys()); @@ -223,7 +233,7 @@ void testMoveFrom() { assertEquals(0, moveFrom.getCursorX()); assertEquals(0, moveFrom.getCursorY()); } - + /** * Test copyFrom method */ @@ -237,11 +247,11 @@ void testCopyFrom() { VirtualMouse expected = copyFrom.clone(); - actual.update(VirtualKey.MBUTTON12.getKeycode(), true, 0,0,0); + actual.update(VirtualKey.MBUTTON12.getKeycode(), true, 0, 0, 0); actual.update(VirtualKey.MOUSEMOVED.getKeycode(), true, -120, -10, -10); actual.copyFrom(null); - + actual.copyFrom(copyFrom); assertIterableEquals(expected.getPressedKeys(), actual.getPressedKeys()); @@ -259,7 +269,7 @@ void testCopyFrom() { * Test subtick list being filled via update */ @Test - void testUpdate(){ + void testUpdate() { VirtualMouse actual = new VirtualMouse(); actual.update(VirtualKey.LC.getKeycode(), true, -30, 118, 42); actual.update(VirtualKey.MOUSEMOVED.getKeycode(), false, 0, 23, 144); @@ -270,154 +280,149 @@ void testUpdate(){ assertIterableEquals(expected, actual.getAll()); } - - /** - * Tests getDifference - */ - @Test - void testGetDifference(){ - 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(VirtualKey.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() { - VirtualMouse unpressed = new VirtualMouse(); - - 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(VirtualKey.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() { - VirtualMouse unpressed = new VirtualMouse(); - - 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(VirtualKey.LC.getKeycode(), false, 0, 0, 0)); - - assertIterableEquals(expected, actual); - } - - /** - * Tests 2 updates having the same value and the scroll wheel is 0. Should return no additional button events - */ - @Test - void testSameUpdate() { - VirtualMouse unpressed = new VirtualMouse(); - - VirtualMouse pressed = new VirtualMouse(); - pressed.update(VirtualKey.LC.getKeycode(), true, 0, 10, 12); - pressed.update(VirtualKey.LC.getKeycode(), true, 0, 10, 12); - - // Load actual with the events - Queue actual = new ConcurrentLinkedQueue<>(); - unpressed.getVirtualEvents(pressed, actual); - - // Load expected - List expected = Arrays.asList( - new VirtualMouseEvent(VirtualKey.LC.getKeycode(), true, 0, 10, 12) // Should only have one keyboard event - ); - - assertIterableEquals(expected, actual); - } - - - /** - * Tests 2 updates having the same pressed keys, but scrollWheel != 0 - */ - @Test - void testScrollWheelDifferent() { - VirtualMouse unpressed = new VirtualMouse(); - - 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<>(); - unpressed.getVirtualEvents(pressed, actual); - - // Load expected - List expected = Arrays.asList( - new VirtualMouseEvent(VirtualKey.LC.getKeycode(), true, 15, 10, 12), - new VirtualMouseEvent(VirtualKey.MOUSEMOVED.getKeycode(), false, 15, 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() { - VirtualMouse unpressed = new VirtualMouse(); - - VirtualMouse pressed = new VirtualMouse(); - pressed.update(VirtualKey.LC.getKeycode(), true, 0, 10, 12); - pressed.update(VirtualKey.LC.getKeycode(), true, 0, 11, 12); - - // Load actual with the events - Queue actual = new ConcurrentLinkedQueue<>(); - unpressed.getVirtualEvents(pressed, actual); - - // Load expected - List expected = Arrays.asList( - new VirtualMouseEvent(VirtualKey.LC.getKeycode(), true, 0, 10, 12), - new VirtualMouseEvent(VirtualKey.MOUSEMOVED.getKeycode(), false, 0, 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() { - VirtualMouse unpressed = new VirtualMouse(); - - VirtualMouse pressed = new VirtualMouse(); - pressed.update(VirtualKey.LC.getKeycode(), true, 0, 10, 12); - pressed.update(VirtualKey.LC.getKeycode(), true, 0, 10, 120); - - // Load actual with the events - Queue actual = new ConcurrentLinkedQueue<>(); - unpressed.getVirtualEvents(pressed, actual); - - // Load expected - List expected = Arrays.asList( - new VirtualMouseEvent(VirtualKey.LC.getKeycode(), true, 0, 10, 12), - new VirtualMouseEvent(VirtualKey.MOUSEMOVED.getKeycode(), false, 0, 10, 120) // Adds an additional "MOUSEMOVED" event with the cursorY - ); - - assertIterableEquals(expected, actual); - } + + /** + * Tests getDifference + */ + @Test + void testGetDifference() { + 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(VirtualKey.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() { + VirtualMouse unpressed = new VirtualMouse(); + + 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(VirtualKey.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() { + VirtualMouse unpressed = new VirtualMouse(); + + 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(VirtualKey.LC.getKeycode(), false, 0, 0, 0)); + + assertIterableEquals(expected, actual); + } + + /** + * Tests 2 updates having the same value and the scroll wheel is 0. Should + * return no additional button events + */ + @Test + void testSameUpdate() { + VirtualMouse unpressed = new VirtualMouse(); + + VirtualMouse pressed = new VirtualMouse(); + pressed.update(VirtualKey.LC.getKeycode(), true, 0, 10, 12); + pressed.update(VirtualKey.LC.getKeycode(), true, 0, 10, 12); + + // Load actual with the events + Queue actual = new ConcurrentLinkedQueue<>(); + unpressed.getVirtualEvents(pressed, actual); + + // Load expected + List expected = Arrays.asList(new VirtualMouseEvent(VirtualKey.LC.getKeycode(), true, 0, 10, 12) // Should only have one keyboard event + ); + + assertIterableEquals(expected, actual); + } + + /** + * Tests 2 updates having the same pressed keys, but scrollWheel != 0 + */ + @Test + void testScrollWheelDifferent() { + VirtualMouse unpressed = new VirtualMouse(); + + 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<>(); + unpressed.getVirtualEvents(pressed, actual); + + // Load expected + List expected = Arrays.asList(new VirtualMouseEvent(VirtualKey.LC.getKeycode(), true, 15, 10, 12), new VirtualMouseEvent(VirtualKey.MOUSEMOVED.getKeycode(), false, 15, 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() { + VirtualMouse unpressed = new VirtualMouse(); + + VirtualMouse pressed = new VirtualMouse(); + pressed.update(VirtualKey.LC.getKeycode(), true, 0, 10, 12); + pressed.update(VirtualKey.LC.getKeycode(), true, 0, 11, 12); + + // Load actual with the events + Queue actual = new ConcurrentLinkedQueue<>(); + unpressed.getVirtualEvents(pressed, actual); + + // Load expected + List expected = Arrays.asList(new VirtualMouseEvent(VirtualKey.LC.getKeycode(), true, 0, 10, 12), new VirtualMouseEvent(VirtualKey.MOUSEMOVED.getKeycode(), false, 0, 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() { + VirtualMouse unpressed = new VirtualMouse(); + + VirtualMouse pressed = new VirtualMouse(); + pressed.update(VirtualKey.LC.getKeycode(), true, 0, 10, 12); + pressed.update(VirtualKey.LC.getKeycode(), true, 0, 10, 120); + + // Load actual with the events + Queue actual = new ConcurrentLinkedQueue<>(); + unpressed.getVirtualEvents(pressed, actual); + + // Load expected + List expected = Arrays.asList(new VirtualMouseEvent(VirtualKey.LC.getKeycode(), true, 0, 10, 12), new VirtualMouseEvent(VirtualKey.MOUSEMOVED.getKeycode(), false, 0, 10, 120) // Adds an additional "MOUSEMOVED" event with the cursorY + ); + + assertIterableEquals(expected, actual); + } } From f8cf2665deb373908c47fe1f8ba6de3b8a154145 Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 6 Apr 2024 19:37:59 +0200 Subject: [PATCH 21/27] [PlaybackSerialiser] Add base class --- .../playback/PlaybackSerialiserBase.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiserBase.java diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiserBase.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiserBase.java new file mode 100644 index 00000000..a76bf88e --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiserBase.java @@ -0,0 +1,40 @@ +package com.minecrafttas.tasmod.playback; + +import java.util.ArrayList; +import java.util.List; + +public abstract class PlaybackSerialiserBase { + + public PlaybackSerialiserBase(PlaybackControllerClient controller) { + if(controller == null) { + throw new NullPointerException("Parameter controller can't be null"); + } + + + } + + public void onSave() { + + } + + public void onLoad() { + + } + + public List serialize() { + List out = new ArrayList<>(); + return out; + } + + public void deserialize(List in) { + + } + + public List serializeMetadata(){ + return null; + } + + public void deserializeMetadata(List metadataString) { + + } +} From be74f5eabd7ae10d9ab13c3c82e143afb9f989d4 Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 6 Apr 2024 22:16:45 +0200 Subject: [PATCH 22/27] [PlaybackMetadata] Adding handleOnLoad and handleOnSave Changed constructor of PlaybackMetadata to accept PlaybackMetadataExtension. This is to encourage users to write `new PlaybackMetadata(this)` to ensure, that the metadata extension name is also in the PlaybackMetadata. - Added PlaybackMetadata and PlaybackMetadataRegistry tests --- .../playback/PlaybackControllerClient.java | 2 +- .../tasmod/playback/PlaybackSerialiser.java | 1 - .../playback/metadata/PlaybackMetadata.java | 31 +++--- .../metadata/PlaybackMetadataRegistry.java | 44 +++++--- .../PlaybackMetadataRegistryTest.java | 101 ++++++++++++++++++ .../metadata/PlaybackMetadataTest.java | 89 +++++++++------ 6 files changed, 204 insertions(+), 64 deletions(-) create mode 100644 src/test/java/tasmod/playback/metadata/PlaybackMetadataRegistryTest.java diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index 120732c9..b904e1a7 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -80,7 +80,7 @@ public class PlaybackControllerClient implements ClientPacketHandler, EventVirtu private TASstate state = TASstate.NONE; /** - * The state of the controller when the state is paused + * The state of the controller when the {@link #state} is paused */ private TASstate tempPause = TASstate.NONE; diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java index 0d3c2b98..57ef3ecf 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java @@ -7,7 +7,6 @@ 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.mojang.realmsclient.util.Pair; diff --git a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java index 82f7c0f0..c2a00c47 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java @@ -7,29 +7,30 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.minecrafttas.tasmod.playback.metadata.PlaybackMetadataRegistry.PlaybackMetadataExtension; + /** * Stores a section of
*
*/ public class PlaybackMetadata { - /** - * Debug extension name - */ private String extensionName; private LinkedHashMap metadata; + + private static String SEPERATOR = ":"; - public PlaybackMetadata() { - this.metadata = new LinkedHashMap(); + public PlaybackMetadata(PlaybackMetadataExtension extension) { + this(extension.getExtensionName()); } - public PlaybackMetadata(String extensionName) { - this(); + private PlaybackMetadata(String extensionName) { this.extensionName = extensionName; + this.metadata = new LinkedHashMap(); } public void setValue(String key, String value) { - if (key.contains("=")) { - throw new IllegalArgumentException(String.format("%sKeyname %s can't contain =", extensionName != null ? extensionName + ": " : "", key)); + if (key.contains(SEPERATOR)) { + throw new IllegalArgumentException(String.format("%sKeyname %s can't contain %s", extensionName != null ? extensionName + ": " : "", key, SEPERATOR)); } metadata.put(key, value); } @@ -43,7 +44,7 @@ public String toString() { String out = ""; for (String key : metadata.keySet()) { String value = getValue(key); - out += (String.format("%s=%s\n", key, value)); + out += (String.format("%s%s%s\n", key, SEPERATOR, value)); } return out; } @@ -53,7 +54,7 @@ public List toStringList() { for (Object keyObj : metadata.keySet()) { String key = (String) keyObj; String value = getValue(key); - out.add(String.format("%s=%s\n", key, value)); + out.add(String.format("%s%s%s\n", key, SEPERATOR, value)); } return out; } @@ -76,13 +77,9 @@ public boolean equals(Object obj) { } public static PlaybackMetadata fromStringList(String extensionName, List list) { - return fromStringList(list); - } - - public static PlaybackMetadata fromStringList(List list) { - PlaybackMetadata out = new PlaybackMetadata(); + PlaybackMetadata out = new PlaybackMetadata(extensionName); - final Pattern pattern = Pattern.compile("(\\w+)=(.+)"); + final Pattern pattern = Pattern.compile("(\\w+)\\"+SEPERATOR+"(.+)"); for (String data : list) { Matcher matcher = pattern.matcher(data); diff --git a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java index 56a1fa86..b0ca75f8 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java @@ -2,8 +2,10 @@ import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; -import com.minecrafttas.mctcommon.MCTCommon; +import com.minecrafttas.tasmod.TASmod; /** * Registry for registering custom metadata that is stored in the TASFile.
@@ -16,7 +18,7 @@ */ public class PlaybackMetadataRegistry { - private static final ArrayList METADATA_EXTENSION = new ArrayList<>(); + private static final Map METADATA_EXTENSION = new LinkedHashMap<>(); /** * Registers a new class as a metadata extension @@ -29,25 +31,26 @@ public static void register(PlaybackMetadataExtension extension) { } if (containsClass(extension)) { - MCTCommon.LOGGER.warn("Trying to register the playback extension {}, but another instance of this class is already registered!", extension.getClass().getName()); + TASmod.LOGGER.warn("Trying to register the playback extension {}, but another instance of this class is already registered!", extension.getClass().getName()); return; } - if (!METADATA_EXTENSION.contains(extension)) { - METADATA_EXTENSION.add(extension); - } else { - MCTCommon.LOGGER.warn("Trying to register the playback extension {}, but it is already registered!", extension.getClass().getName()); + if(METADATA_EXTENSION.containsKey(extension.getExtensionName())) { + TASmod.LOGGER.warn("Trying to register the playback extension {}, but an extension with the same name is already registered!", extension.getExtensionName()); + return; } + + METADATA_EXTENSION.put(extension.getExtensionName(), extension); } public static void unregister(PlaybackMetadataExtension extension) { if (extension == null) { throw new NullPointerException("Tried to unregister an extension with value null"); } - if (METADATA_EXTENSION.contains(extension)) { - METADATA_EXTENSION.remove(extension); + if (METADATA_EXTENSION.containsKey(extension.getExtensionName())) { + METADATA_EXTENSION.remove(extension.getExtensionName()); } else { - MCTCommon.LOGGER.warn("Trying to unregister the playback extension {}, but it was not registered!", extension.getClass().getName()); + TASmod.LOGGER.warn("Trying to unregister the playback extension {}, but it was not registered!", extension.getClass().getName()); } } @@ -55,15 +58,28 @@ public static void handleOnCreate() { } - public static LinkedHashMap handleOnLoad() { - return null; + public static List handleOnStore() { + List metadataList = new ArrayList<>(); + for(PlaybackMetadataExtension extension : METADATA_EXTENSION.values()) { + metadataList.add(extension.onStore()); + } + return metadataList; } - public static void handleOnStore(LinkedHashMap metadata) { + public static void handleOnLoad(List meta) { + for(PlaybackMetadata metadata : meta) { + if(METADATA_EXTENSION.containsKey(metadata.getExtensionName())) { + PlaybackMetadataExtension extension = METADATA_EXTENSION.get(metadata.getExtensionName()); + + extension.onLoad(metadata); + } else { + TASmod.LOGGER.warn("The metadata extension {} was not found while loading the TASFile. Things might not be correctly loaded!", metadata.getExtensionName()); + } + } } private static boolean containsClass(PlaybackMetadataExtension newExtension) { - for (PlaybackMetadataExtension extension : METADATA_EXTENSION) { + for (PlaybackMetadataExtension extension : METADATA_EXTENSION.values()) { if (extension.getClass().equals(newExtension.getClass())) { return true; } diff --git a/src/test/java/tasmod/playback/metadata/PlaybackMetadataRegistryTest.java b/src/test/java/tasmod/playback/metadata/PlaybackMetadataRegistryTest.java new file mode 100644 index 00000000..f5d673b8 --- /dev/null +++ b/src/test/java/tasmod/playback/metadata/PlaybackMetadataRegistryTest.java @@ -0,0 +1,101 @@ +package tasmod.playback.metadata; + +import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.Test; + +import com.minecrafttas.tasmod.playback.metadata.PlaybackMetadata; +import com.minecrafttas.tasmod.playback.metadata.PlaybackMetadataRegistry; +import com.minecrafttas.tasmod.playback.metadata.PlaybackMetadataRegistry.PlaybackMetadataExtension; + +import static org.junit.jupiter.api.Assertions.*; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + + +public class PlaybackMetadataRegistryTest { + + class Test1 implements PlaybackMetadataExtension{ + + private String actual; + + public String getActual() { + return actual; + } + + @Override + public String getExtensionName() { + return "Test1"; + } + + @Override + public void onCreate() { + } + + @Override + public PlaybackMetadata onStore() { + PlaybackMetadata data = new PlaybackMetadata(this); + data.setValue("Test", "Testing 1"); + return data; + } + + @Override + public void onLoad(PlaybackMetadata metadata) { + actual = metadata.getValue("Test"); + } + + } + + File file = new File("src/test/resources/run/MetadataRegistry.txt"); + + void store() { + List list = PlaybackMetadataRegistry.handleOnStore(); + List out = new ArrayList<>(); + + list.forEach(data -> { + out.addAll(data.toStringList()); + }); + + try { + FileUtils.writeLines(file, out); + } catch (IOException e) { + e.printStackTrace(); + } + } + + void load() { + List loaded = null; + try { + loaded = FileUtils.readLines(file, StandardCharsets.UTF_8); + } catch (IOException e) { + e.printStackTrace(); + } + + + List meta = new ArrayList<>(); + + meta.add(PlaybackMetadata.fromStringList("Test1", loaded)); + + PlaybackMetadataRegistry.handleOnLoad(meta); + } + + /** + * Register, store and read metadata + */ + @Test + void testRegistry() { + Test1 actual = new Test1(); + PlaybackMetadataRegistry.register(actual); + + store(); + load(); + + assertEquals("Testing 1", actual.getActual()); + if(file.exists()) { + file.delete(); + } + } +} diff --git a/src/test/java/tasmod/playback/metadata/PlaybackMetadataTest.java b/src/test/java/tasmod/playback/metadata/PlaybackMetadataTest.java index beb6f124..5339335c 100644 --- a/src/test/java/tasmod/playback/metadata/PlaybackMetadataTest.java +++ b/src/test/java/tasmod/playback/metadata/PlaybackMetadataTest.java @@ -4,7 +4,6 @@ import static org.junit.jupiter.api.Assertions.assertIterableEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; import java.util.ArrayList; import java.util.List; @@ -12,26 +11,45 @@ import org.junit.jupiter.api.Test; import com.minecrafttas.tasmod.playback.metadata.PlaybackMetadata; +import com.minecrafttas.tasmod.playback.metadata.PlaybackMetadataRegistry.PlaybackMetadataExtension; public class PlaybackMetadataTest { - @Test - void testConstructor() { - PlaybackMetadata metadata = new PlaybackMetadata(); - assertNotNull(metadata.getMetadata()); - assertNull(metadata.getExtensionName()); + class MetadataTest implements PlaybackMetadataExtension{ + + @Override + public String getExtensionName() { + return "Test"; + } + + @Override + public void onCreate() { + + } + + @Override + public PlaybackMetadata onStore() { + return null; + } + + @Override + public void onLoad(PlaybackMetadata metadata) { + } + } @Test - void testNameConstructor() { - PlaybackMetadata metadata = new PlaybackMetadata("Test"); + void testConstructor() { + MetadataTest test = new MetadataTest(); + PlaybackMetadata metadata = new PlaybackMetadata(test); assertNotNull(metadata.getMetadata()); assertEquals("Test", metadata.getExtensionName()); } @Test void testSettingAndReading() { - PlaybackMetadata metadata = new PlaybackMetadata("Test"); + MetadataTest test = new MetadataTest(); + PlaybackMetadata metadata = new PlaybackMetadata(test); metadata.setValue("testProperty", "Test"); String actual = metadata.getValue("testProperty"); @@ -41,7 +59,8 @@ void testSettingAndReading() { @Test void testToString() { - PlaybackMetadata metadata = new PlaybackMetadata("Test"); + MetadataTest test = new MetadataTest(); + PlaybackMetadata metadata = new PlaybackMetadata(test); metadata.setValue("1", "One"); metadata.setValue("2", "Two"); metadata.setValue("3", "Three"); @@ -49,17 +68,18 @@ void testToString() { String actual = metadata.toString(); - String expected = "1=One\n" - + "2=Two\n" - + "3=Three\n" - + "4=Four\n"; + String expected = "1:One\n" + + "2:Two\n" + + "3:Three\n" + + "4:Four\n"; assertEquals(expected, actual); } @Test void testToStringList() { - PlaybackMetadata metadata = new PlaybackMetadata("Test"); + MetadataTest test = new MetadataTest(); + PlaybackMetadata metadata = new PlaybackMetadata(test); metadata.setValue("1", "One"); metadata.setValue("2", "Two"); metadata.setValue("3", "Three"); @@ -68,23 +88,25 @@ void testToStringList() { List actual = metadata.toStringList(); List expected = new ArrayList<>(); - expected.add("1=One\n"); - expected.add("2=Two\n"); - expected.add("3=Three\n"); - expected.add("4=Four\n"); + expected.add("1:One\n"); + expected.add("2:Two\n"); + expected.add("3:Three\n"); + expected.add("4:Four\n"); assertIterableEquals(expected, actual); } @Test void testEquals() { - PlaybackMetadata metadata = new PlaybackMetadata("Test"); + MetadataTest test = new MetadataTest(); + PlaybackMetadata metadata = new PlaybackMetadata(test); metadata.setValue("1", "One"); metadata.setValue("2", "Two"); metadata.setValue("3", "Three"); metadata.setValue("4", "Four"); - PlaybackMetadata metadata2 = new PlaybackMetadata("Test"); + MetadataTest test2 = new MetadataTest(); + PlaybackMetadata metadata2 = new PlaybackMetadata(test2); metadata2.setValue("1", "One"); metadata2.setValue("2", "Two"); metadata2.setValue("3", "Three"); @@ -96,13 +118,15 @@ void testEquals() { @Test void testFailedEquals() { //Key difference - PlaybackMetadata metadata = new PlaybackMetadata("Test"); + MetadataTest test = new MetadataTest(); + PlaybackMetadata metadata = new PlaybackMetadata(test); metadata.setValue("2", "One"); metadata.setValue("2", "Two"); metadata.setValue("3", "Three"); metadata.setValue("4", "Four"); - PlaybackMetadata metadata2 = new PlaybackMetadata("Test"); + MetadataTest test2 = new MetadataTest(); + PlaybackMetadata metadata2 = new PlaybackMetadata(test2); metadata2.setValue("1", "One"); metadata2.setValue("2", "Two"); metadata2.setValue("3", "Three"); @@ -111,13 +135,13 @@ void testFailedEquals() { assertNotEquals(metadata, metadata2); // Value difference - metadata = new PlaybackMetadata("Test"); + metadata = new PlaybackMetadata(test); metadata.setValue("1", "On"); metadata.setValue("2", "Two"); metadata.setValue("3", "Three"); metadata.setValue("4", "Four"); - metadata2 = new PlaybackMetadata("Test"); + metadata2 = new PlaybackMetadata(test); metadata2.setValue("1", "One"); metadata2.setValue("2", "Two"); metadata2.setValue("3", "Three"); @@ -126,17 +150,20 @@ void testFailedEquals() { assertNotEquals(metadata, metadata2); // Name difference - metadata = new PlaybackMetadata("Tes"); + metadata2 = new PlaybackMetadata(test); metadata.setValue("1", "One"); metadata.setValue("2", "Two"); metadata.setValue("3", "Three"); metadata.setValue("4", "Four"); - metadata2 = new PlaybackMetadata("Test"); - metadata2.setValue("1", "One"); - metadata2.setValue("2", "Two"); - metadata2.setValue("3", "Three"); - metadata2.setValue("4", "Four"); + + List list = new ArrayList<>(); + list.add("1:One"); + list.add("2:Two"); + list.add("3:Three"); + list.add("4:Four"); + + metadata2 = PlaybackMetadata.fromStringList("Tes", list); assertNotEquals(metadata, metadata2); } From 3287dca041455ea0c0397a06ae25bc76be7006d3 Mon Sep 17 00:00:00 2001 From: Scribble Date: Sun, 7 Apr 2024 21:36:03 +0200 Subject: [PATCH 23/27] [VirtualInput] Fixed mouse pointer not being recorded in GUI screens --- .../java/com/minecrafttas/tasmod/virtual/VirtualMouse.java | 2 +- src/test/java/tasmod/virtual/VirtualMouseTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java index ebfe0e08..6b83e7a5 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualMouse.java @@ -258,7 +258,7 @@ public void moveFrom(VirtualMouse mouse) { this.scrollWheel = mouse.scrollWheel; this.cursorX = mouse.cursorX; this.cursorY = mouse.cursorY; - mouse.clearMouseData(); + mouse.scrollWheel=0; } @Override diff --git a/src/test/java/tasmod/virtual/VirtualMouseTest.java b/src/test/java/tasmod/virtual/VirtualMouseTest.java index 12a8a34c..90fd0f4c 100644 --- a/src/test/java/tasmod/virtual/VirtualMouseTest.java +++ b/src/test/java/tasmod/virtual/VirtualMouseTest.java @@ -230,8 +230,8 @@ void testMoveFrom() { assertTrue(moveFrom.getSubticks().isEmpty()); assertEquals(0, moveFrom.getScrollWheel()); - assertEquals(0, moveFrom.getCursorX()); - assertEquals(0, moveFrom.getCursorY()); + assertEquals(10, moveFrom.getCursorX()); + assertEquals(20, moveFrom.getCursorY()); } /** From b6ee9ee2cb5567759b1d4e44ea280f19a1e7ecb6 Mon Sep 17 00:00:00 2001 From: Scribble Date: Fri, 12 Apr 2024 20:57:18 +0200 Subject: [PATCH 24/27] [VirtualInput] Fixed camera flickering when start/stopping play/rec --- src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index 3943ff11..ea385bf6 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -658,7 +658,7 @@ public Float getCurrentYaw() { public Triple getInterpolatedState(float partialTick, float pitch, float yaw, boolean enable) { float interpolatedPitch = nextCameraAngle.getPitch() == null ? pitch : nextCameraAngle.getPitch(); - float interpolatedYaw = nextCameraAngle.getYaw() == null ? pitch : nextCameraAngle.getYaw() + 180; + float interpolatedYaw = nextCameraAngle.getYaw() == null ? yaw : nextCameraAngle.getYaw() + 180; if (enable && !cameraAngleInterpolationStates.isEmpty()) { int index = (int) MathHelper.clampedLerp(0, cameraAngleInterpolationStates.size() - 1, partialTick); // Get interpolate index From 4d1594eaee1ca8f4ac84ddf23d19b01908e41ff9 Mon Sep 17 00:00:00 2001 From: Scribble Date: Fri, 12 Apr 2024 22:11:21 +0200 Subject: [PATCH 25/27] [PlaybackMetadata] Add credits playback metadata extension - [Events] Added seperate EventPlaybackClient file under events for playback specific events^ - Moved tasfile specific serializers to subpackage tasfile - Added PlaybackLoadException --- .../com/minecrafttas/tasmod/TASmodClient.java | 8 +- .../tasmod/events/EventPlaybackClient.java | 37 +++++++ .../tasmod/networking/TASmodPackets.java | 2 +- .../playback/PlaybackControllerClient.java | 27 +---- .../metadata/PlaybackMetadataRegistry.java | 24 +++- .../integrated/CreditsMetadataExtension.java | 103 ++++++++++++++++++ .../{ => tasfile}/PlaybackSerialiser.java | 4 +- .../{ => tasfile}/PlaybackSerialiserBase.java | 4 +- .../exception/PlaybackLoadException.java | 12 ++ 9 files changed, 195 insertions(+), 26 deletions(-) create mode 100644 src/main/java/com/minecrafttas/tasmod/events/EventPlaybackClient.java create mode 100644 src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/CreditsMetadataExtension.java rename src/main/java/com/minecrafttas/tasmod/playback/{ => tasfile}/PlaybackSerialiser.java (98%) rename src/main/java/com/minecrafttas/tasmod/playback/{ => tasfile}/PlaybackSerialiserBase.java (84%) create mode 100644 src/main/java/com/minecrafttas/tasmod/playback/tasfile/exception/PlaybackLoadException.java diff --git a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java index 58139a7f..c8b131d2 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java @@ -28,7 +28,9 @@ 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.playback.metadata.PlaybackMetadataRegistry; +import com.minecrafttas.tasmod.playback.metadata.integrated.CreditsMetadataExtension; +import com.minecrafttas.tasmod.playback.tasfile.PlaybackSerialiser; import com.minecrafttas.tasmod.savestates.SavestateHandlerClient; import com.minecrafttas.tasmod.tickratechanger.TickrateChangerClient; import com.minecrafttas.tasmod.ticksync.TickSyncClient; @@ -85,6 +87,8 @@ public class TASmodClient implements ClientModInitializer, EventClientInit, Even public static SavestateHandlerClient savestateHandlerClient = new SavestateHandlerClient(); public static Client client; + + public static CreditsMetadataExtension creditsMetadataExtension = new CreditsMetadataExtension(); /** * The container where all inputs get stored during recording or stored and * ready to be played back @@ -154,6 +158,8 @@ public void onInitializeClient() { return gui; })); EventListenerRegistry.register(controller); + PlaybackMetadataRegistry.register(creditsMetadataExtension); + EventListenerRegistry.register(creditsMetadataExtension); // Register packet handlers LOGGER.info(LoggerMarkers.Networking, "Registering network handlers on client"); diff --git a/src/main/java/com/minecrafttas/tasmod/events/EventPlaybackClient.java b/src/main/java/com/minecrafttas/tasmod/events/EventPlaybackClient.java new file mode 100644 index 00000000..df7e3c83 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/events/EventPlaybackClient.java @@ -0,0 +1,37 @@ +package com.minecrafttas.tasmod.events; + +import com.minecrafttas.mctcommon.events.EventListenerRegistry.EventBase; +import com.minecrafttas.tasmod.playback.PlaybackControllerClient; +import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate; + +public interface EventPlaybackClient { + + /** + * Fired when + * {@link PlaybackControllerClient#setTASStateClient(com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate, boolean)} + * is called + */ + @FunctionalInterface + public static interface EventControllerStateChange extends EventBase { + + /** + * Fired when + * {@link PlaybackControllerClient#setTASStateClient(com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate, boolean)} + * is called + * + * @param newstate The new state that the playback controller is about to be set + * to + * @param oldstate The current state that is about to be replaced by newstate + */ + public void onControllerStateChange(TASstate newstate, TASstate oldstate); + } + + /** + * Fired after a player joined the world with a playback/recording running + */ + @FunctionalInterface + public static interface EventPlaybackJoinedWorld extends EventBase { + + public void onPlaybackJoinedWorld(TASstate state); + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/networking/TASmodPackets.java b/src/main/java/com/minecrafttas/tasmod/networking/TASmodPackets.java index bd874206..ac01c975 100644 --- a/src/main/java/com/minecrafttas/tasmod/networking/TASmodPackets.java +++ b/src/main/java/com/minecrafttas/tasmod/networking/TASmodPackets.java @@ -6,7 +6,7 @@ import com.minecrafttas.tasmod.commands.CommandFolder; import com.minecrafttas.tasmod.playback.PlaybackControllerClient; import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate; -import com.minecrafttas.tasmod.playback.PlaybackSerialiser; +import com.minecrafttas.tasmod.playback.tasfile.PlaybackSerialiser; import com.minecrafttas.tasmod.savestates.SavestateHandlerServer.PlayerHandler.MotionData; import com.minecrafttas.tasmod.tickratechanger.TickrateChangerServer.TickratePauseState; diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index b904e1a7..2ebb06df 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -22,6 +22,7 @@ import com.dselent.bigarraylist.BigArrayList; import com.minecrafttas.mctcommon.Configuration.ConfigOptions; +import com.minecrafttas.mctcommon.events.EventListenerRegistry; import com.minecrafttas.mctcommon.server.ByteBufferBuilder; import com.minecrafttas.mctcommon.server.Client.Side; import com.minecrafttas.mctcommon.server.exception.PacketNotImplementedException; @@ -34,10 +35,13 @@ import com.minecrafttas.tasmod.events.EventClient.EventVirtualCameraAngleTick; import com.minecrafttas.tasmod.events.EventClient.EventVirtualKeyboardTick; import com.minecrafttas.tasmod.events.EventClient.EventVirtualMouseTick; +import com.minecrafttas.tasmod.events.EventPlaybackClient.EventControllerStateChange; +import com.minecrafttas.tasmod.events.EventPlaybackClient.EventPlaybackJoinedWorld; import com.minecrafttas.tasmod.monitoring.DesyncMonitoring; import com.minecrafttas.tasmod.networking.TASmodBufferBuilder; import com.minecrafttas.tasmod.networking.TASmodPackets; import com.minecrafttas.tasmod.playback.metadata.PlaybackMetadata; +import com.minecrafttas.tasmod.playback.tasfile.PlaybackSerialiser; import com.minecrafttas.tasmod.util.LoggerMarkers; import com.minecrafttas.tasmod.util.Scheduler.Task; import com.minecrafttas.tasmod.virtual.VirtualCameraAngle; @@ -176,6 +180,7 @@ public String setTASStateClient(TASstate stateIn) { * @return The message printed in the chat */ public String setTASStateClient(TASstate stateIn, boolean verbose) { + EventListenerRegistry.fireEvent(EventControllerStateChange.class, stateIn, state); ControlByteHandler.reset(); // FIXME Controlbytes are resetting when loading a world, due to "Paused" state being active during loading... Fix Paused state shenanigans? if (state == stateIn) { switch (stateIn) { @@ -415,7 +420,7 @@ public void onClientTickPost(Minecraft mc) { if (isPaused() && tempPause != TASstate.NONE) { setTASState(tempPause); // The recording is paused in LoadWorldEvents#startLaunchServer pause(false); - printCredits(); + EventListenerRegistry.fireEvent(EventPlaybackJoinedWorld.class, state); } } @@ -694,27 +699,7 @@ public void unpressContainer() { // ============================================================== - public void printCredits() { - LOGGER.trace(LoggerMarkers.Playback, "Printing credits"); - if (state == TASstate.PLAYBACK && !creditsPrinted) { - creditsPrinted = true; - printMessage(title, ChatFormatting.GOLD); - printMessage("", null); - printMessage("by " + authors, ChatFormatting.AQUA); - printMessage("", null); - printMessage("in " + playtime, null); - printMessage("", null); - printMessage("Rerecords: " + rerecords, null); - } - } - private void printMessage(String msg, ChatFormatting format) { - String formatString = ""; - if (format != null) - formatString = format.toString(); - - Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(new TextComponentString(formatString + msg)); - } public void setPlayUntil(int until) { this.playUntil = until; diff --git a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java index b0ca75f8..c720ede0 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java @@ -88,13 +88,35 @@ private static boolean containsClass(PlaybackMetadataExtension newExtension) { } public static interface PlaybackMetadataExtension { - + + /** + * The name of this playback metadata extension.
+ * The name is printed in the playback file and declares this "section".
+ * It is also used in the {@link PlaybackMetadata} itself to link the metadata to the extension.
+ * @return The name of this playback metadata extension. + */ public String getExtensionName(); + /** + * Currently unused.
+ * Maybe in the future, TASes have to be created with /create, then you can interactively set the values...
+ */ public void onCreate(); + /** + * Runs, when the TASfile is being stored to a file.
+ * Create a new {@link PlaybackMetadata} with PlaybackMetadata metadata = new PlaybackMetadata(this);.
+ * This will ensure, that the metadata is linked to this extension by using the {@link PlaybackMetadataExtension#getExtensionName()}.
+ * + * @return The {@link PlaybackMetadata} to be saved in the TASfile + */ public PlaybackMetadata onStore(); + /** + * Runs when the TASfile is being loaded from a file
+ * + * @param metadata The metadata for this extension to read from + */ public void onLoad(PlaybackMetadata metadata); } } diff --git a/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/CreditsMetadataExtension.java b/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/CreditsMetadataExtension.java new file mode 100644 index 00000000..3ed71334 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/CreditsMetadataExtension.java @@ -0,0 +1,103 @@ +package com.minecrafttas.tasmod.playback.metadata.integrated; + +import static com.minecrafttas.tasmod.TASmod.LOGGER; + +import com.minecrafttas.tasmod.events.EventPlaybackClient.EventControllerStateChange; +import com.minecrafttas.tasmod.events.EventPlaybackClient.EventPlaybackJoinedWorld; +import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate; +import com.minecrafttas.tasmod.playback.metadata.PlaybackMetadata; +import com.minecrafttas.tasmod.playback.metadata.PlaybackMetadataRegistry.PlaybackMetadataExtension; +import com.minecrafttas.tasmod.playback.tasfile.exception.PlaybackLoadException; +import com.minecrafttas.tasmod.util.LoggerMarkers; +import com.mojang.realmsclient.gui.ChatFormatting; + +import net.minecraft.client.Minecraft; +import net.minecraft.util.text.TextComponentString; + +public class CreditsMetadataExtension implements PlaybackMetadataExtension, EventPlaybackJoinedWorld, EventControllerStateChange { + + /** + * The title/category of the TAS (e.g. KillSquid - Any% Glitched) + */ + private String title = "Insert TAS category here"; + /** + * The author(s) of the TAS (e.g. Scribble, Pancake) + */ + private String authors = "Insert author here"; + /** + * How long the TAS is going to take (e.g. 00:01.0 or 20ticks) + */ + private String playtime = "00:00.0"; + /** + * How often a savestate was loaded as a measurement of effort (e.g. 200) + */ + private int rerecords = 0; + + /** + * If the credits where already printed in this instance + */ + private boolean creditsPrinted = false; + + @Override + public String getExtensionName() { + return "Credits"; + } + + @Override + public void onCreate() { + // Unused atm + } + + @Override + public PlaybackMetadata onStore() { + PlaybackMetadata metadata = new PlaybackMetadata(this); + metadata.setValue("Title", title); + metadata.setValue("Author", authors); + metadata.setValue("Playing Time", playtime); + metadata.setValue("Rerecords", Integer.toString(rerecords)); + return metadata; + } + + @Override + public void onLoad(PlaybackMetadata metadata) { + title = metadata.getValue("Title"); + authors = metadata.getValue("Author"); + playtime = metadata.getValue("Playing Time"); + try { + rerecords = Integer.parseInt(metadata.getValue("Rerecords")); + } catch (NumberFormatException e) { + rerecords = 0; + throw new PlaybackLoadException(e); + } + } + + @Override + public void onPlaybackJoinedWorld(TASstate state) { + LOGGER.trace(LoggerMarkers.Playback, "Printing credits"); + if (state == TASstate.PLAYBACK && !creditsPrinted) { + creditsPrinted = true; + printMessage(title, ChatFormatting.GOLD); + printMessage("", null); + printMessage("by " + authors, ChatFormatting.AQUA); + printMessage("", null); + printMessage("in " + playtime, null); + printMessage("", null); + printMessage("Rerecords: " + rerecords, null); + } + } + + private void printMessage(String msg, ChatFormatting format) { + String formatString = ""; + if (format != null) + formatString = format.toString(); + + Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(new TextComponentString(formatString + msg)); + } + + @Override + public void onControllerStateChange(TASstate newstate, TASstate oldstate) { + if(newstate == TASstate.PLAYBACK) { // Reset creditsPrinted when a new playback is started + creditsPrinted = false; + } + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java b/src/main/java/com/minecrafttas/tasmod/playback/tasfile/PlaybackSerialiser.java similarity index 98% rename from src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java rename to src/main/java/com/minecrafttas/tasmod/playback/tasfile/PlaybackSerialiser.java index 57ef3ecf..61c8162d 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/tasfile/PlaybackSerialiser.java @@ -1,8 +1,10 @@ -package com.minecrafttas.tasmod.playback; +package com.minecrafttas.tasmod.playback.tasfile; import com.dselent.bigarraylist.BigArrayList; import com.minecrafttas.tasmod.TASmod; import com.minecrafttas.tasmod.monitoring.DesyncMonitoring; +import com.minecrafttas.tasmod.playback.ControlByteHandler; +import com.minecrafttas.tasmod.playback.PlaybackControllerClient; import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TickInputContainer; import com.minecrafttas.tasmod.util.FileThread; import com.minecrafttas.tasmod.util.LoggerMarkers; diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiserBase.java b/src/main/java/com/minecrafttas/tasmod/playback/tasfile/PlaybackSerialiserBase.java similarity index 84% rename from src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiserBase.java rename to src/main/java/com/minecrafttas/tasmod/playback/tasfile/PlaybackSerialiserBase.java index a76bf88e..305b3a74 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiserBase.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/tasfile/PlaybackSerialiserBase.java @@ -1,8 +1,10 @@ -package com.minecrafttas.tasmod.playback; +package com.minecrafttas.tasmod.playback.tasfile; import java.util.ArrayList; import java.util.List; +import com.minecrafttas.tasmod.playback.PlaybackControllerClient; + public abstract class PlaybackSerialiserBase { public PlaybackSerialiserBase(PlaybackControllerClient controller) { diff --git a/src/main/java/com/minecrafttas/tasmod/playback/tasfile/exception/PlaybackLoadException.java b/src/main/java/com/minecrafttas/tasmod/playback/tasfile/exception/PlaybackLoadException.java new file mode 100644 index 00000000..7ab3f712 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/playback/tasfile/exception/PlaybackLoadException.java @@ -0,0 +1,12 @@ +package com.minecrafttas.tasmod.playback.tasfile.exception; + +public class PlaybackLoadException extends RuntimeException { + + public PlaybackLoadException(String msg) { + super(msg); + } + + public PlaybackLoadException(Throwable cause) { + super(cause); + } +} From 75f34131bd9c985fb302bd5af50c2a586c7876b1 Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 13 Apr 2024 10:37:31 +0200 Subject: [PATCH 26/27] [PlaybackMetadata] Added StartpositionMetadataExtension - Removed credits from PlaybackControllerClient - Removed startposition from PlaybackControllerClient - Added onClear to MetadaExtension for cleaning up. - Moved TeleportPacket handling to from PlaybackControllerServer to StartpositionMetadataExtension --- .../java/com/minecrafttas/tasmod/TASmod.java | 4 + .../com/minecrafttas/tasmod/TASmodClient.java | 6 + .../playback/PlaybackControllerClient.java | 130 +--------------- .../playback/PlaybackControllerServer.java | 20 --- .../metadata/PlaybackMetadataRegistry.java | 11 ++ .../integrated/CreditsMetadataExtension.java | 9 ++ .../StartpositionMetadataExtension.java | 139 ++++++++++++++++++ .../playback/tasfile/PlaybackSerialiser.java | 52 +++---- .../PlaybackMetadataRegistryTest.java | 4 + .../metadata/PlaybackMetadataTest.java | 4 + 10 files changed, 205 insertions(+), 174 deletions(-) create mode 100644 src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/StartpositionMetadataExtension.java diff --git a/src/main/java/com/minecrafttas/tasmod/TASmod.java b/src/main/java/com/minecrafttas/tasmod/TASmod.java index 9e94df5f..cf503604 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmod.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmod.java @@ -27,6 +27,7 @@ import com.minecrafttas.tasmod.ktrng.KillTheRNGHandler; import com.minecrafttas.tasmod.networking.TASmodPackets; import com.minecrafttas.tasmod.playback.PlaybackControllerServer; +import com.minecrafttas.tasmod.playback.metadata.integrated.StartpositionMetadataExtension; import com.minecrafttas.tasmod.savestates.SavestateHandlerServer; import com.minecrafttas.tasmod.savestates.files.SavestateTrackerFile; import com.minecrafttas.tasmod.tickratechanger.TickrateChangerServer; @@ -68,6 +69,8 @@ public class TASmod implements ModInitializer, EventServerInit, EventServerStop{ public static final boolean isDevEnvironment = FabricLoaderImpl.INSTANCE.isDevelopmentEnvironment(); + public static final StartpositionMetadataExtension startPositionMetadataExtension = new StartpositionMetadataExtension(); + @Override public void onInitialize() { @@ -96,6 +99,7 @@ public void onInitialize() { PacketHandlerRegistry.register(tickratechanger); PacketHandlerRegistry.register(ktrngHandler); PacketHandlerRegistry.register(playbackControllerServer); + PacketHandlerRegistry.register(startPositionMetadataExtension); } @Override diff --git a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java index c8b131d2..aab41277 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java @@ -30,6 +30,7 @@ import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate; import com.minecrafttas.tasmod.playback.metadata.PlaybackMetadataRegistry; import com.minecrafttas.tasmod.playback.metadata.integrated.CreditsMetadataExtension; +import com.minecrafttas.tasmod.playback.metadata.integrated.StartpositionMetadataExtension; import com.minecrafttas.tasmod.playback.tasfile.PlaybackSerialiser; import com.minecrafttas.tasmod.savestates.SavestateHandlerClient; import com.minecrafttas.tasmod.tickratechanger.TickrateChangerClient; @@ -89,6 +90,8 @@ public class TASmodClient implements ClientModInitializer, EventClientInit, Even public static Client client; public static CreditsMetadataExtension creditsMetadataExtension = new CreditsMetadataExtension(); + + public static StartpositionMetadataExtension startpositionMetadataExtension = new StartpositionMetadataExtension(); /** * The container where all inputs get stored during recording or stored and * ready to be played back @@ -161,6 +164,9 @@ public void onInitializeClient() { PlaybackMetadataRegistry.register(creditsMetadataExtension); EventListenerRegistry.register(creditsMetadataExtension); + PlaybackMetadataRegistry.register(startpositionMetadataExtension); + EventListenerRegistry.register(startpositionMetadataExtension); + // Register packet handlers LOGGER.info(LoggerMarkers.Networking, "Registering network handlers on client"); PacketHandlerRegistry.register(controller); diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index 2ebb06df..44cce30c 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -41,6 +41,7 @@ import com.minecrafttas.tasmod.networking.TASmodBufferBuilder; import com.minecrafttas.tasmod.networking.TASmodPackets; import com.minecrafttas.tasmod.playback.metadata.PlaybackMetadata; +import com.minecrafttas.tasmod.playback.metadata.PlaybackMetadataRegistry; import com.minecrafttas.tasmod.playback.tasfile.PlaybackSerialiser; import com.minecrafttas.tasmod.util.LoggerMarkers; import com.minecrafttas.tasmod.util.Scheduler.Task; @@ -127,22 +128,10 @@ public class PlaybackControllerClient implements ClientPacketHandler, EventVirtu // ===================================================================================================== - private String title = "Insert TAS category here"; - - private String authors = "Insert author here"; - - private String playtime = "00:00.0"; - - private int rerecords = 0; - - private String startLocation = ""; - private long startSeed = TASmod.ktrngHandler.getGlobalSeedClient(); // ===================================================================================================== - private boolean creditsPrinted = false; - private Integer playUntil = null; /** @@ -269,9 +258,6 @@ public String setTASStateClient(TASstate stateIn, boolean verbose) { private void startRecording() { LOGGER.debug(LoggerMarkers.Playback, "Starting recording"); - if (Minecraft.getMinecraft().player != null && startLocation.isEmpty()) { - startLocation = getStartLocation(Minecraft.getMinecraft().player); - } if (this.inputs.isEmpty()) { inputs.add(new TickInputContainer(index)); desyncMonitor.recordNull(index); @@ -285,18 +271,8 @@ private void stopRecording() { private void startPlayback() { LOGGER.debug(LoggerMarkers.Playback, "Starting playback"); - if (Minecraft.getMinecraft().player != null && !startLocation.isEmpty()) { - try { - tpPlayer(startLocation); - } catch (NumberFormatException e) { - state = TASstate.NONE; - e.printStackTrace(); -// return verbose ? TextFormatting.RED + "An error occured while reading the start location of the TAS. The file might be broken" : ""; - } - } Minecraft.getMinecraft().gameSettings.chatLinks = false; // #119 index = 0; - creditsPrinted = false; TASmod.ktrngHandler.setInitialSeed(startSeed); } @@ -548,16 +524,8 @@ public void clear() { controlBytes.clear(); comments.clear(); index = 0; - startLocation = ""; desyncMonitor.clear(); - clearCredits(); - } - - private void clearCredits() { - title = "Insert Author here"; - authors = "Insert author here"; - playtime = "00:00.0"; - rerecords = 0; + PlaybackMetadataRegistry.handleOnClear(); } /** @@ -578,42 +546,6 @@ public String toString() { // ===================================================================================================== // Methods to set and retrieve author, title etc - public String getAuthors() { - return authors; - } - - public void setAuthors(String authors) { - this.authors = authors; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public int getRerecords() { - return rerecords; - } - - public void setRerecords(int rerecords) { - this.rerecords = rerecords; - } - - public String getPlaytime() { - return playtime; - } - - public void setPlaytime(String playtime) { - this.playtime = playtime; - } - - public void setSavestates(String playtime) { - this.playtime = playtime; - } - public void fixTicks() { for (int i = 0; i < inputs.size(); i++) { inputs.get(i).setTick(i + 1); @@ -628,63 +560,6 @@ public void setStartSeed(long startSeed) { this.startSeed = startSeed; } - // ===================================================================================================== - // Methods and classes related to the start location of a TAS - - /** - * @return The start location of the TAS - */ - public String getStartLocation() { - return startLocation; - } - - /** - * Updates the start location of the input container - * - * @param startLocation The start location of the TAS - */ - public void setStartLocation(String startLocation) { - LOGGER.debug(LoggerMarkers.Playback, "Setting start location"); - this.startLocation = startLocation; - } - - /** - * Generates a start location from the players position and angle - * - * @param player The player of the TAS - * @return The start location from the player - */ - private String getStartLocation(EntityPlayerSP player) { - LOGGER.debug(LoggerMarkers.Playback, "Retrieving player start location"); - String pos = player.posX + "," + player.posY + "," + player.posZ; - String pitch = Float.toString(player.rotationPitch); - String yaw = Float.toString(player.rotationYaw); - return pos + "," + yaw + "," + pitch; - } - - /** - * Teleports the player to the start location - * - * @param startLocation The start location where the player should be teleported - * to - * @throws NumberFormatException If the location can't be parsed - */ - private void tpPlayer(String startLocation) throws NumberFormatException { - LOGGER.debug(LoggerMarkers.Playback, "Teleporting the player to the start location"); - String[] section = startLocation.split(","); - double x = Double.parseDouble(section[0]); - double y = Double.parseDouble(section[1]); - double z = Double.parseDouble(section[2]); - - float angleYaw = Float.parseFloat(section[3]); - float anglePitch = Float.parseFloat(section[4]); - - try { - TASmodClient.client.send(new TASmodBufferBuilder(PLAYBACK_TELEPORT).writeDouble(x).writeDouble(y).writeDouble(z).writeFloat(angleYaw).writeFloat(anglePitch)); - } catch (Exception e) { - e.printStackTrace(); - } - } // ============================================================== @@ -820,7 +695,6 @@ public PacketID[] getAcceptedPacketIDs() { PLAYBACK_FULLRECORD, PLAYBACK_RESTARTANDPLAY, PLAYBACK_PLAYUNTIL, - PLAYBACK_TELEPORT, PLAYBACK_CLEAR_INPUTS, PLAYBACK_STATE }; diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerServer.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerServer.java index fe5b9e28..a834fc40 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerServer.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerServer.java @@ -9,7 +9,6 @@ import static com.minecrafttas.tasmod.networking.TASmodPackets.PLAYBACK_RESTARTANDPLAY; import static com.minecrafttas.tasmod.networking.TASmodPackets.PLAYBACK_SAVE; import static com.minecrafttas.tasmod.networking.TASmodPackets.PLAYBACK_STATE; -import static com.minecrafttas.tasmod.networking.TASmodPackets.PLAYBACK_TELEPORT; import static com.minecrafttas.tasmod.util.LoggerMarkers.Playback; import java.nio.ByteBuffer; @@ -24,8 +23,6 @@ import com.minecrafttas.tasmod.networking.TASmodPackets; import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate; -import net.minecraft.entity.player.EntityPlayerMP; - /** * The playback controller on the server side.
* Currently used sync the {@link TASstate} with all clients @@ -42,7 +39,6 @@ public PacketID[] getAcceptedPacketIDs() { return new TASmodPackets[] { PLAYBACK_STATE, - PLAYBACK_TELEPORT, PLAYBACK_CLEAR_INPUTS, PLAYBACK_FULLPLAY, PLAYBACK_FULLRECORD, @@ -65,22 +61,6 @@ public void onServerPacket(PacketID id, ByteBuffer buf, String username) throws setState(networkState); break; - case PLAYBACK_TELEPORT: - double x = TASmodBufferBuilder.readDouble(buf); - double y = TASmodBufferBuilder.readDouble(buf); - double z = TASmodBufferBuilder.readDouble(buf); - float angleYaw = TASmodBufferBuilder.readFloat(buf); - float anglePitch = TASmodBufferBuilder.readFloat(buf); - - EntityPlayerMP player = TASmod.getServerInstance().getPlayerList().getPlayerByUsername(username); - player.getServerWorld().addScheduledTask(() -> { - player.rotationPitch = anglePitch; - player.rotationYaw = angleYaw; - - player.setPositionAndUpdate(x, y, z); - }); - break; - case PLAYBACK_CLEAR_INPUTS: TASmod.server.sendToAll(new TASmodBufferBuilder(PLAYBACK_CLEAR_INPUTS)); break; diff --git a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java index c720ede0..4c604261 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java @@ -77,6 +77,12 @@ public static void handleOnLoad(List meta) { } } } + + public static void handleOnClear() { + METADATA_EXTENSION.forEach((key, extension) ->{ + extension.onClear(); + }); + } private static boolean containsClass(PlaybackMetadataExtension newExtension) { for (PlaybackMetadataExtension extension : METADATA_EXTENSION.values()) { @@ -118,5 +124,10 @@ public static interface PlaybackMetadataExtension { * @param metadata The metadata for this extension to read from */ public void onLoad(PlaybackMetadata metadata); + + /** + * Runs when the PlaybackController is cleared + */ + public void onClear(); } } diff --git a/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/CreditsMetadataExtension.java b/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/CreditsMetadataExtension.java index 3ed71334..3aabab5e 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/CreditsMetadataExtension.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/CreditsMetadataExtension.java @@ -71,6 +71,15 @@ public void onLoad(PlaybackMetadata metadata) { } } + @Override + public void onClear() { + title = "Insert TAS category here"; + authors = "Insert author here"; + playtime = "00:00.0"; + rerecords = 0; + creditsPrinted = false; + } + @Override public void onPlaybackJoinedWorld(TASstate state) { LOGGER.trace(LoggerMarkers.Playback, "Printing credits"); diff --git a/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/StartpositionMetadataExtension.java b/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/StartpositionMetadataExtension.java new file mode 100644 index 00000000..9fed7e94 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/StartpositionMetadataExtension.java @@ -0,0 +1,139 @@ +package com.minecrafttas.tasmod.playback.metadata.integrated; + +import static com.minecrafttas.tasmod.TASmod.LOGGER; + +import java.nio.ByteBuffer; + +import com.minecrafttas.mctcommon.server.exception.PacketNotImplementedException; +import com.minecrafttas.mctcommon.server.exception.WrongSideException; +import com.minecrafttas.mctcommon.server.interfaces.PacketID; +import com.minecrafttas.mctcommon.server.interfaces.ServerPacketHandler; +import com.minecrafttas.tasmod.TASmod; +import com.minecrafttas.tasmod.TASmodClient; +import com.minecrafttas.tasmod.events.EventPlaybackClient.EventControllerStateChange; +import com.minecrafttas.tasmod.networking.TASmodBufferBuilder; +import com.minecrafttas.tasmod.networking.TASmodPackets; +import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate; +import com.minecrafttas.tasmod.playback.metadata.PlaybackMetadata; +import com.minecrafttas.tasmod.playback.metadata.PlaybackMetadataRegistry.PlaybackMetadataExtension; +import com.minecrafttas.tasmod.util.LoggerMarkers; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.entity.player.EntityPlayerMP; + +public class StartpositionMetadataExtension implements PlaybackMetadataExtension, EventControllerStateChange, ServerPacketHandler { + + StartPosition startPosition = null; + + public static class StartPosition{ + + final double x; + final double y; + final double z; + final float pitch; + final float yaw; + + public StartPosition(double x, double y, double z, float pitch, float yaw) { + this.x = x; + this.y = y; + this.z = z; + this.pitch = pitch; + this.yaw = yaw; + } + + @Override + public String toString() { + return String.format("%e,%e,%e,%e,%e", x, y, z, pitch, yaw); + } + } + + @Override + public String getExtensionName() { + return "Start Position"; + } + + @Override + public void onCreate() { + // TODO Auto-generated method stub + + } + + @Override + public PlaybackMetadata onStore() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void onLoad(PlaybackMetadata metadata) { + // TODO Auto-generated method stub + + } + + @Override + public void onClear() { + startPosition = null; + } + + @Override + public void onControllerStateChange(TASstate newstate, TASstate oldstate) { + Minecraft mc = Minecraft.getMinecraft(); + + if(mc.player!=null) { + EntityPlayerSP player = mc.player; + + if(oldstate == TASstate.NONE && newstate == TASstate.RECORDING && startPosition == null) { // If a recording is started, the player is in a world and startposition is uninitialized + LOGGER.debug(LoggerMarkers.Playback, "Setting start location"); + startPosition = new StartPosition(player.posX, player.posY, player.posZ, player.rotationPitch, player.rotationYaw); + } + + if(oldstate == TASstate.NONE && newstate == TASstate.PLAYBACK && startPosition != null) { + LOGGER.debug(LoggerMarkers.Playback, "Teleporting the player to the start location"); + TASmodBufferBuilder packetBuilder = new TASmodBufferBuilder(TASmodPackets.PLAYBACK_TELEPORT); + + packetBuilder + .writeDouble(startPosition.x) + .writeDouble(startPosition.y) + .writeDouble(startPosition.z) + .writeFloat(startPosition.pitch) + .writeFloat(startPosition.yaw); + + try { + TASmodClient.client.send(packetBuilder); + } catch (Exception e) { + LOGGER.error("Unable to teleport player to start location", e); + } + } + } + + } + + @Override + public PacketID[] getAcceptedPacketIDs() { + return new PacketID[] { + TASmodPackets.PLAYBACK_TELEPORT + }; + } + + @Override + public void onServerPacket(PacketID id, ByteBuffer buf, String username) throws PacketNotImplementedException, WrongSideException, Exception { + TASmodPackets packet = (TASmodPackets) id; + + if (packet == TASmodPackets.PLAYBACK_TELEPORT) { + double x = TASmodBufferBuilder.readDouble(buf); + double y = TASmodBufferBuilder.readDouble(buf); + double z = TASmodBufferBuilder.readDouble(buf); + float angleYaw = TASmodBufferBuilder.readFloat(buf); + float anglePitch = TASmodBufferBuilder.readFloat(buf); + + EntityPlayerMP player = TASmod.getServerInstance().getPlayerList().getPlayerByUsername(username); + player.getServerWorld().addScheduledTask(() -> { + player.rotationPitch = anglePitch; + player.rotationYaw = angleYaw; + + player.setPositionAndUpdate(x, y, z); + }); + } + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/playback/tasfile/PlaybackSerialiser.java b/src/main/java/com/minecrafttas/tasmod/playback/tasfile/PlaybackSerialiser.java index 61c8162d..c98844dd 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/tasfile/PlaybackSerialiser.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/tasfile/PlaybackSerialiser.java @@ -108,27 +108,27 @@ public void saveToFileV1Until(File file, PlaybackControllerClient container, int fileThread.start(); // monitorThread.start(); - fileThread.addLine("################################################# TASFile ###################################################\n" - + "# Version:1 #\n" - + "# This file was generated using the Minecraft TASMod #\n" - + "# #\n" - + "# Any errors while reading this file will be printed out in the console and the chat #\n" - + "# #\n" - + "#------------------------------------------------ Header ---------------------------------------------------#\n" - + "#Author:" + container.getAuthors() + "\n" - + "# #\n" - + "#Title:" + container.getTitle() + "\n" - + "# #\n" - + "#Playing Time:" + container.getPlaytime() + "\n" - + "# #\n" - + "#Rerecords:"+container.getRerecords() + "\n" - + "# #\n" - + "#----------------------------------------------- Settings --------------------------------------------------#\n" - + "#StartPosition:"+container.getStartLocation()+"\n" - + "# #\n" - + "#StartSeed:" + container.getStartSeed() + "\n" - + "#############################################################################################################\n" - + "#Comments start with \"//\" at the start of the line, comments with # will not be saved\n"); +// fileThread.addLine("################################################# TASFile ###################################################\n" +// + "# Version:1 #\n" +// + "# This file was generated using the Minecraft TASMod #\n" +// + "# #\n" +// + "# Any errors while reading this file will be printed out in the console and the chat #\n" +// + "# #\n" +// + "#------------------------------------------------ Header ---------------------------------------------------#\n" +// + "#Author:" + container.getAuthors() + "\n" +// + "# #\n" +// + "#Title:" + container.getTitle() + "\n" +// + "# #\n" +// + "#Playing Time:" + container.getPlaytime() + "\n" +// + "# #\n" +// + "#Rerecords:"+container.getRerecords() + "\n" +// + "# #\n" +// + "#----------------------------------------------- Settings --------------------------------------------------#\n" +// + "#StartPosition:"+container.getStartLocation()+"\n" +// + "# #\n" +// + "#StartSeed:" + container.getStartSeed() + "\n" +// + "#############################################################################################################\n" +// + "#Comments start with \"//\" at the start of the line, comments with # will not be saved\n"); BigArrayList ticks = container.getInputs(); Map>> cbytes= container.getControlBytes(); @@ -283,11 +283,11 @@ public PlaybackControllerClient fromEntireFileV1(File file) throws IOException { } } } - controller.setAuthors(author); - controller.setTitle(title); - controller.setPlaytime(playtime); - controller.setRerecords(rerecords); - controller.setStartLocation(startLocation); +// controller.setAuthors(author); +// controller.setTitle(title); +// controller.setPlaytime(playtime); +// controller.setRerecords(rerecords); +// controller.setStartLocation(startLocation); controller.setStartSeed(startSeed); if(!monitorLines.isEmpty()) { controller.desyncMonitor = new DesyncMonitoring(controller, monitorLines); diff --git a/src/test/java/tasmod/playback/metadata/PlaybackMetadataRegistryTest.java b/src/test/java/tasmod/playback/metadata/PlaybackMetadataRegistryTest.java index f5d673b8..1c3ba61e 100644 --- a/src/test/java/tasmod/playback/metadata/PlaybackMetadataRegistryTest.java +++ b/src/test/java/tasmod/playback/metadata/PlaybackMetadataRegistryTest.java @@ -46,6 +46,10 @@ public PlaybackMetadata onStore() { public void onLoad(PlaybackMetadata metadata) { actual = metadata.getValue("Test"); } + + @Override + public void onClear() { + } } diff --git a/src/test/java/tasmod/playback/metadata/PlaybackMetadataTest.java b/src/test/java/tasmod/playback/metadata/PlaybackMetadataTest.java index 5339335c..fbb21a7c 100644 --- a/src/test/java/tasmod/playback/metadata/PlaybackMetadataTest.java +++ b/src/test/java/tasmod/playback/metadata/PlaybackMetadataTest.java @@ -35,6 +35,10 @@ public PlaybackMetadata onStore() { @Override public void onLoad(PlaybackMetadata metadata) { } + + @Override + public void onClear() { + } } From 12e039b2d98fd1d86810479a179aeb4156eae5dc Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 13 Apr 2024 19:20:23 +0200 Subject: [PATCH 27/27] [PlaybackMetadata] Finish logic for StartpositionMetadataExtension - Add documentation to StartpositionMetadataExtension - Add documentation to CreditsMetadataExtension - Removed credits and metadata related methods from PlaybackControllerClient --- .../tasmod/handlers/InterpolationHandler.java | 4 +- .../tasmod/ktrng/KillTheRNGHandler.java | 2 +- .../playback/PlaybackControllerClient.java | 99 ++++++++----------- .../integrated/CreditsMetadataExtension.java | 20 ++-- .../StartpositionMetadataExtension.java | 65 +++++++----- .../playback/tasfile/PlaybackSerialiser.java | 2 +- 6 files changed, 100 insertions(+), 92 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/handlers/InterpolationHandler.java b/src/main/java/com/minecrafttas/tasmod/handlers/InterpolationHandler.java index 69e4df41..0a904cab 100644 --- a/src/main/java/com/minecrafttas/tasmod/handlers/InterpolationHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/handlers/InterpolationHandler.java @@ -26,8 +26,8 @@ public CameraData onCameraEvent(CameraData dataIn) { TickInputContainer input = TASmodClient.controller.get(); if (input == null) return dataIn; - float nextPitch = input.getSubticks().getPitch(); - float nextYaw = input.getSubticks().getYaw(); + float nextPitch = input.getCameraAngle().getPitch(); + float nextYaw = input.getCameraAngle().getYaw(); dataIn.pitch = (float) MathHelper.clampedLerp(rotationPitch, nextPitch, Minecraft.getMinecraft().timer.renderPartialTicks); dataIn.yaw = (float) MathHelper.clampedLerp(rotationYaw, nextYaw + 180, Minecraft.getMinecraft().timer.renderPartialTicks); } else { diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/KillTheRNGHandler.java b/src/main/java/com/minecrafttas/tasmod/ktrng/KillTheRNGHandler.java index 309644e5..f6643fc8 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/KillTheRNGHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/KillTheRNGHandler.java @@ -209,7 +209,7 @@ public void onClientPacket(PacketID id, ByteBuffer buf, String username) throws break; case KILLTHERNG_STARTSEED: - TASmodClient.controller.setStartSeed(seed); +// TASmodClient.controller.setStartSeed(seed); break; default: diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index 44cce30c..758c7a1b 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -9,7 +9,6 @@ import static com.minecrafttas.tasmod.networking.TASmodPackets.PLAYBACK_RESTARTANDPLAY; import static com.minecrafttas.tasmod.networking.TASmodPackets.PLAYBACK_SAVE; import static com.minecrafttas.tasmod.networking.TASmodPackets.PLAYBACK_STATE; -import static com.minecrafttas.tasmod.networking.TASmodPackets.PLAYBACK_TELEPORT; import java.io.File; import java.io.Serializable; @@ -49,7 +48,6 @@ import com.minecrafttas.tasmod.virtual.VirtualInput; import com.minecrafttas.tasmod.virtual.VirtualKeyboard; import com.minecrafttas.tasmod.virtual.VirtualMouse; -import com.mojang.realmsclient.gui.ChatFormatting; import com.mojang.realmsclient.util.Pair; import net.minecraft.client.Minecraft; @@ -77,7 +75,7 @@ * @author Scribble * */ -public class PlaybackControllerClient implements ClientPacketHandler, EventVirtualKeyboardTick, EventVirtualMouseTick, EventVirtualCameraAngleTick, EventClientTickPost{ +public class PlaybackControllerClient implements ClientPacketHandler, EventVirtualKeyboardTick, EventVirtualMouseTick, EventVirtualCameraAngleTick, EventClientTickPost { /** * The current state of the controller. @@ -88,7 +86,7 @@ public class PlaybackControllerClient implements ClientPacketHandler, EventVirtu * The state of the controller when the {@link #state} is paused */ private TASstate tempPause = TASstate.NONE; - + /** * The current index of the inputs */ @@ -117,22 +115,20 @@ public class PlaybackControllerClient implements ClientPacketHandler, EventVirtu *

* Map(int playbackLine, List(Pair(String controlCommand, String[] arguments))" */ - private Map>> controlBytes = new HashMap>>(); + private Map>> controlBytes = new HashMap>>(); // TODO Replace with TASFile extension /** * The comments in the file, used to store them again later */ - private Map> comments = new HashMap<>(); - - public DesyncMonitoring desyncMonitor = new DesyncMonitoring(this); + private Map> comments = new HashMap<>(); // TODO Replace with TASFile extension - // ===================================================================================================== + public DesyncMonitoring desyncMonitor = new DesyncMonitoring(this); // TODO Replace with TASFile extension - private long startSeed = TASmod.ktrngHandler.getGlobalSeedClient(); + private long startSeed = TASmod.ktrngHandler.getGlobalSeedClient(); // TODO Replace with Metadata extension // ===================================================================================================== - private Integer playUntil = null; + private Integer playUntil = null; // TODO Replace with event /** * Sets the current {@link TASstate} @@ -150,7 +146,7 @@ public void setTASState(TASstate stateIn) { e.printStackTrace(); } } - + /** * Starts or stops a recording/playback * @@ -170,7 +166,8 @@ public String setTASStateClient(TASstate stateIn) { */ public String setTASStateClient(TASstate stateIn, boolean verbose) { EventListenerRegistry.fireEvent(EventControllerStateChange.class, stateIn, state); - ControlByteHandler.reset(); // FIXME Controlbytes are resetting when loading a world, due to "Paused" state being active during loading... Fix Paused state shenanigans? + ControlByteHandler.reset(); // FIXME Controlbytes are resetting when loading a world, due to "Paused" state + // being active during loading... Fix Paused state shenanigans? if (state == stateIn) { switch (stateIn) { case PLAYBACK: @@ -255,7 +252,7 @@ public String setTASStateClient(TASstate stateIn, boolean verbose) { } return "Something went wrong ._."; } - + private void startRecording() { LOGGER.debug(LoggerMarkers.Playback, "Starting recording"); if (this.inputs.isEmpty()) { @@ -263,12 +260,12 @@ private void startRecording() { desyncMonitor.recordNull(index); } } - + private void stopRecording() { LOGGER.debug(LoggerMarkers.Playback, "Stopping a recording"); TASmodClient.virtual.clear(); } - + private void startPlayback() { LOGGER.debug(LoggerMarkers.Playback, "Starting playback"); Minecraft.getMinecraft().gameSettings.chatLinks = false; // #119 @@ -281,7 +278,7 @@ private void stopPlayback() { Minecraft.getMinecraft().gameSettings.chatLinks = true; TASmodClient.virtual.clear(); } - + /** * Switches between the paused state and the state it was in before the pause * @@ -361,7 +358,7 @@ public VirtualKeyboard onVirtualKeyboardTick(VirtualKeyboard vkeyboard) { } return vkeyboard.clone(); } - + @Override public VirtualCameraAngle onVirtualCameraTick(VirtualCameraAngle vcamera) { if (state == TASstate.RECORDING) { @@ -371,7 +368,7 @@ public VirtualCameraAngle onVirtualCameraTick(VirtualCameraAngle vcamera) { } return vcamera.clone(); } - + /** * Updates the input container.
*
@@ -454,7 +451,7 @@ private void playbackNextTick() { TickInputContainer tickcontainer = inputs.get(index); // Loads the new inputs from the container this.keyboard = tickcontainer.getKeyboard().clone(); this.mouse = tickcontainer.getMouse().clone(); - this.camera = tickcontainer.getSubticks().clone(); + this.camera = tickcontainer.getCameraAngle().clone(); // check for control bytes ControlByteHandler.readCotrolByte(controlBytes.get(index)); } @@ -479,11 +476,11 @@ public BigArrayList getInputs() { return inputs; } - public Map>> getControlBytes() { + public Map>> getControlBytes() { // TODO Replace with TASFile extension return controlBytes; } - public Map> getComments() { + public Map> getComments() { // TODO Replace with TASFile extension return comments; } @@ -494,7 +491,7 @@ public void setIndex(int index) throws IndexOutOfBoundsException { TickInputContainer tickcontainer = inputs.get(index); this.keyboard = tickcontainer.getKeyboard(); this.mouse = tickcontainer.getMouse(); - this.camera = tickcontainer.getSubticks(); + this.camera = tickcontainer.getCameraAngle(); } } else { throw new IndexOutOfBoundsException("Index is bigger than the container"); @@ -543,24 +540,12 @@ public String toString() { return out; } - // ===================================================================================================== - // Methods to set and retrieve author, title etc - - public void fixTicks() { + public void fixTicks() { // TODO Remove and use Serializer to list ticks for (int i = 0; i < inputs.size(); i++) { inputs.get(i).setTick(i + 1); } } - public long getStartSeed() { - return startSeed; - } - - public void setStartSeed(long startSeed) { - this.startSeed = startSeed; - } - - // ============================================================== /** @@ -574,8 +559,6 @@ public void unpressContainer() { // ============================================================== - - public void setPlayUntil(int until) { this.playUntil = until; } @@ -627,7 +610,7 @@ public VirtualMouse getMouse() { return mouse; } - public VirtualCameraAngle getSubticks() { + public VirtualCameraAngle getCameraAngle() { return subticks; } @@ -675,11 +658,11 @@ public static enum TASstate { public void setStateWhenOpened(TASstate state) { TASmodClient.openMainMenuScheduler.add(() -> { - PlaybackControllerClient container = TASmodClient.controller; - if (state == TASstate.RECORDING) { - long seed = TASmod.ktrngHandler.getGlobalSeedClient(); - container.setStartSeed(seed); - } +// PlaybackControllerClient container = TASmodClient.controller; // Replace with event +// if (state == TASstate.RECORDING) { +// long seed = TASmod.ktrngHandler.getGlobalSeedClient(); +// container.setStartSeed(seed); +// } setTASState(state); }); } @@ -695,8 +678,9 @@ public PacketID[] getAcceptedPacketIDs() { PLAYBACK_FULLRECORD, PLAYBACK_RESTARTANDPLAY, PLAYBACK_PLAYUNTIL, - PLAYBACK_CLEAR_INPUTS, - PLAYBACK_STATE + PLAYBACK_CLEAR_INPUTS, + PLAYBACK_STATE + }; } @@ -795,31 +779,30 @@ public void onClientPacket(PacketID id, ByteBuffer buf, String username) throws case PLAYBACK_TELEPORT: throw new WrongSideException(packet, Side.CLIENT); - + case PLAYBACK_STATE: TASstate networkState = TASmodBufferBuilder.readTASState(buf); boolean verbose = TASmodBufferBuilder.readBoolean(buf); - Task task = ()->{ + Task task = () -> { PlaybackControllerClient container = TASmodClient.controller; if (networkState != container.getState()) { - + String message = container.setTASStateClient(networkState, verbose); - + if (!message.isEmpty()) { - if(Minecraft.getMinecraft().world != null) + if (Minecraft.getMinecraft().world != null) Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(new TextComponentString(message)); else LOGGER.debug(LoggerMarkers.Playback, message); - } + } } - + }; - - - if((networkState == TASstate.RECORDING || networkState == TASstate.PLAYBACK) && TASmodClient.tickratechanger.ticksPerSecond != 0) { - TASmodClient.tickSchedulerClient.add(task); // Starts a recording in the next tick + + if ((networkState == TASstate.RECORDING || networkState == TASstate.PLAYBACK) && TASmodClient.tickratechanger.ticksPerSecond != 0) { + TASmodClient.tickSchedulerClient.add(task); // Starts a recording in the next tick } else { - TASmodClient.gameLoopSchedulerClient.add(task); // Starts a recording in the next frame + TASmodClient.gameLoopSchedulerClient.add(task); // Starts a recording in the next frame } break; diff --git a/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/CreditsMetadataExtension.java b/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/CreditsMetadataExtension.java index 3aabab5e..ddeb0a9d 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/CreditsMetadataExtension.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/CreditsMetadataExtension.java @@ -9,11 +9,17 @@ import com.minecrafttas.tasmod.playback.metadata.PlaybackMetadataRegistry.PlaybackMetadataExtension; import com.minecrafttas.tasmod.playback.tasfile.exception.PlaybackLoadException; import com.minecrafttas.tasmod.util.LoggerMarkers; -import com.mojang.realmsclient.gui.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.util.text.TextComponentString; +import net.minecraft.util.text.TextFormatting; +/** + * Adds credits to the playback metadata
+ *
+ * Credits can be changed in the file and will be printed in chat, when the + * player joins a world after /fullplay + */ public class CreditsMetadataExtension implements PlaybackMetadataExtension, EventPlaybackJoinedWorld, EventControllerStateChange { /** @@ -32,7 +38,7 @@ public class CreditsMetadataExtension implements PlaybackMetadataExtension, Even * How often a savestate was loaded as a measurement of effort (e.g. 200) */ private int rerecords = 0; - + /** * If the credits where already printed in this instance */ @@ -79,15 +85,15 @@ public void onClear() { rerecords = 0; creditsPrinted = false; } - + @Override public void onPlaybackJoinedWorld(TASstate state) { LOGGER.trace(LoggerMarkers.Playback, "Printing credits"); if (state == TASstate.PLAYBACK && !creditsPrinted) { creditsPrinted = true; - printMessage(title, ChatFormatting.GOLD); + printMessage(title, TextFormatting.GOLD); printMessage("", null); - printMessage("by " + authors, ChatFormatting.AQUA); + printMessage("by " + authors, TextFormatting.AQUA); printMessage("", null); printMessage("in " + playtime, null); printMessage("", null); @@ -95,7 +101,7 @@ public void onPlaybackJoinedWorld(TASstate state) { } } - private void printMessage(String msg, ChatFormatting format) { + private void printMessage(String msg, TextFormatting format) { String formatString = ""; if (format != null) formatString = format.toString(); @@ -105,7 +111,7 @@ private void printMessage(String msg, ChatFormatting format) { @Override public void onControllerStateChange(TASstate newstate, TASstate oldstate) { - if(newstate == TASstate.PLAYBACK) { // Reset creditsPrinted when a new playback is started + if (newstate == TASstate.PLAYBACK) { // Reset creditsPrinted when a new playback is started creditsPrinted = false; } } diff --git a/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/StartpositionMetadataExtension.java b/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/StartpositionMetadataExtension.java index 9fed7e94..319588e0 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/StartpositionMetadataExtension.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/StartpositionMetadataExtension.java @@ -22,18 +22,29 @@ import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.entity.player.EntityPlayerMP; +/** + * Adds a "start position" entry in the playback metadata.
+ *
+ * Records the position of the player when starting a recording,
+ * and teleports the player, at the start of the playback. + * + * @author Scribble + */ public class StartpositionMetadataExtension implements PlaybackMetadataExtension, EventControllerStateChange, ServerPacketHandler { + /** + * The startposition of the playback + */ StartPosition startPosition = null; - public static class StartPosition{ - + public static class StartPosition { + final double x; final double y; final double z; final float pitch; final float yaw; - + public StartPosition(double x, double y, double z, float pitch, float yaw) { this.x = x; this.y = y; @@ -41,13 +52,13 @@ public StartPosition(double x, double y, double z, float pitch, float yaw) { this.pitch = pitch; this.yaw = yaw; } - + @Override public String toString() { return String.format("%e,%e,%e,%e,%e", x, y, z, pitch, yaw); } } - + @Override public String getExtensionName() { return "Start Position"; @@ -55,50 +66,60 @@ public String getExtensionName() { @Override public void onCreate() { - // TODO Auto-generated method stub - + // Unused atm } @Override public PlaybackMetadata onStore() { - // TODO Auto-generated method stub - return null; + PlaybackMetadata metadata = new PlaybackMetadata(this); + metadata.setValue("x", Double.toString(startPosition.x)); + metadata.setValue("y", Double.toString(startPosition.y)); + metadata.setValue("z", Double.toString(startPosition.z)); + metadata.setValue("pitch", Double.toString(startPosition.pitch)); + metadata.setValue("yaw", Double.toString(startPosition.yaw)); + return metadata; } @Override public void onLoad(PlaybackMetadata metadata) { - // TODO Auto-generated method stub + double x = Double.parseDouble(metadata.getValue("x")); + double y = Double.parseDouble(metadata.getValue("y")); + double z = Double.parseDouble(metadata.getValue("z")); + float pitch = Float.parseFloat(metadata.getValue("pitch")); + float yaw = Float.parseFloat(metadata.getValue("yaw")); + this.startPosition = new StartPosition(x, y, z, pitch, yaw); } @Override public void onClear() { startPosition = null; } - + @Override public void onControllerStateChange(TASstate newstate, TASstate oldstate) { Minecraft mc = Minecraft.getMinecraft(); - - if(mc.player!=null) { + + if (mc.player != null) { EntityPlayerSP player = mc.player; - - if(oldstate == TASstate.NONE && newstate == TASstate.RECORDING && startPosition == null) { // If a recording is started, the player is in a world and startposition is uninitialized + + if (oldstate == TASstate.NONE && newstate == TASstate.RECORDING && startPosition == null) { // If a recording is started, the player is in a world and startposition is + // uninitialized LOGGER.debug(LoggerMarkers.Playback, "Setting start location"); startPosition = new StartPosition(player.posX, player.posY, player.posZ, player.rotationPitch, player.rotationYaw); } - - if(oldstate == TASstate.NONE && newstate == TASstate.PLAYBACK && startPosition != null) { + + if (oldstate == TASstate.NONE && newstate == TASstate.PLAYBACK && startPosition != null) { LOGGER.debug(LoggerMarkers.Playback, "Teleporting the player to the start location"); TASmodBufferBuilder packetBuilder = new TASmodBufferBuilder(TASmodPackets.PLAYBACK_TELEPORT); - + packetBuilder .writeDouble(startPosition.x) .writeDouble(startPosition.y) .writeDouble(startPosition.z) .writeFloat(startPosition.pitch) .writeFloat(startPosition.yaw); - + try { TASmodClient.client.send(packetBuilder); } catch (Exception e) { @@ -106,14 +127,12 @@ public void onControllerStateChange(TASstate newstate, TASstate oldstate) { } } } - + } @Override public PacketID[] getAcceptedPacketIDs() { - return new PacketID[] { - TASmodPackets.PLAYBACK_TELEPORT - }; + return new PacketID[] { TASmodPackets.PLAYBACK_TELEPORT }; } @Override diff --git a/src/main/java/com/minecrafttas/tasmod/playback/tasfile/PlaybackSerialiser.java b/src/main/java/com/minecrafttas/tasmod/playback/tasfile/PlaybackSerialiser.java index c98844dd..29b0db5e 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/tasfile/PlaybackSerialiser.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/tasfile/PlaybackSerialiser.java @@ -288,7 +288,7 @@ public PlaybackControllerClient fromEntireFileV1(File file) throws IOException { // controller.setPlaytime(playtime); // controller.setRerecords(rerecords); // controller.setStartLocation(startLocation); - controller.setStartSeed(startSeed); +// controller.setStartSeed(startSeed); if(!monitorLines.isEmpty()) { controller.desyncMonitor = new DesyncMonitoring(controller, monitorLines); }