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 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 diff --git a/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java b/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java index b0d868e7..774ca47f 100644 --- a/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java +++ b/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java @@ -107,6 +107,18 @@ 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); + } + } + /** * Unregisters an object from being an event listener. * @@ -130,6 +142,17 @@ public static void unregister(EventBase 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 * @@ -151,6 +174,7 @@ public static Object fireEvent(Class 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; } @@ -250,12 +274,7 @@ private static boolean checkTypes(Method method, Object... parameters) { for (int i = 0; i < methodParameterTypes.length; i++) { Class paramName = methodParameterTypes[i]; Class eventName = eventParameterTypes[i]; - - if (paramName == null || eventName == null) { - continue; - } - - if (!paramName.equals(eventName) && !paramName.isAssignableFrom(eventName)) { + if (!paramName.equals(eventName) && (paramName != null && eventName != null && !paramName.isAssignableFrom(eventName))) { return false; } } @@ -265,7 +284,11 @@ private static boolean checkTypes(Method method, Object... parameters) { 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(); + if (parameters[i] == null) { + out[i] = null; + continue; + } + out[i] = parameters[i].getClass(); } return out; } diff --git a/src/main/java/com/minecrafttas/mctcommon/server/PacketHandlerRegistry.java b/src/main/java/com/minecrafttas/mctcommon/server/PacketHandlerRegistry.java index 37cb5ca5..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,13 +35,13 @@ 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)) { 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()); } } @@ -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/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 7a40fb75..aab41277 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java @@ -28,7 +28,10 @@ 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.metadata.integrated.StartpositionMetadataExtension; +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 +88,10 @@ public class TASmodClient implements ClientModInitializer, EventClientInit, Even public static SavestateHandlerClient savestateHandlerClient = new SavestateHandlerClient(); 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 @@ -153,6 +160,12 @@ public void onInitializeClient() { } return gui; })); + EventListenerRegistry.register(controller); + PlaybackMetadataRegistry.register(creditsMetadataExtension); + EventListenerRegistry.register(creditsMetadataExtension); + + PlaybackMetadataRegistry.register(startpositionMetadataExtension); + EventListenerRegistry.register(startpositionMetadataExtension); // Register packet handlers LOGGER.info(LoggerMarkers.Networking, "Registering network handlers on client"); @@ -195,14 +208,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/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/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/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/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/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/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/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/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 64247e25..758c7a1b 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -9,10 +9,8 @@ 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.IOException; import java.io.Serializable; import java.nio.ByteBuffer; import java.util.HashMap; @@ -23,6 +21,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; @@ -31,16 +30,24 @@ 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; +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.metadata.PlaybackMetadataRegistry; +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; 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; import net.minecraft.client.Minecraft; @@ -63,12 +70,12 @@ * 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 * */ -public class PlaybackControllerClient implements ClientPacketHandler { +public class PlaybackControllerClient implements ClientPacketHandler, EventVirtualKeyboardTick, EventVirtualMouseTick, EventVirtualCameraAngleTick, EventClientTickPost { /** * The current state of the controller. @@ -76,9 +83,10 @@ public class PlaybackControllerClient implements ClientPacketHandler { 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; + /** * The current index of the inputs */ @@ -88,7 +96,7 @@ public class PlaybackControllerClient implements ClientPacketHandler { 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"); @@ -107,34 +115,20 @@ public class PlaybackControllerClient implements ClientPacketHandler { *

* 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 String title = "Insert TAS category here"; + private Map> comments = new HashMap<>(); // TODO Replace with TASFile extension - private String authors = "Insert author here"; + public DesyncMonitoring desyncMonitor = new DesyncMonitoring(this); // TODO Replace with TASFile extension - private String playtime = "00:00.0"; - - private int rerecords = 0; - - private String startLocation = ""; - - private long startSeed = TASmod.ktrngHandler.getGlobalSeedClient(); + private long startSeed = TASmod.ktrngHandler.getGlobalSeedClient(); // TODO Replace with Metadata extension // ===================================================================================================== - private boolean creditsPrinted = false; - - private Integer playUntil = null; + private Integer playUntil = null; // TODO Replace with event /** * Sets the current {@link TASstate} @@ -152,7 +146,7 @@ public void setTASState(TASstate stateIn) { e.printStackTrace(); } } - + /** * Starts or stops a recording/playback * @@ -171,7 +165,9 @@ public String setTASStateClient(TASstate stateIn) { * @return The message printed in the chat */ public String setTASStateClient(TASstate stateIn, boolean verbose) { - ControlByteHandler.reset(); // FIXME Controlbytes are resetting when loading a world, due to "Paused" state being active during loading... Fix Paused state shenanigans? + 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) { case PLAYBACK: @@ -187,31 +183,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: @@ -231,8 +207,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" : ""; } @@ -249,9 +224,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" : ""; } @@ -280,6 +253,32 @@ public String setTASStateClient(TASstate stateIn, boolean verbose) { return "Something went wrong ._."; } + private void startRecording() { + LOGGER.debug(LoggerMarkers.Playback, "Starting recording"); + 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"); + Minecraft.getMinecraft().gameSettings.chatLinks = false; // #119 + index = 0; + 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 * @@ -340,78 +339,61 @@ 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) { + @Override + public VirtualMouse onVirtualMouseTick(VirtualMouse vmouse) { if (state == TASstate.RECORDING) { - this.keyboard = keyboard.clone(); + this.mouse.deepCopyFrom(vmouse); } else if (state == TASstate.PLAYBACK) { - keyboard = this.keyboard.clone(); + vmouse.deepCopyFrom(this.mouse); } - return keyboard; + return vmouse.clone(); } - /** - * 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) { + @Override + public VirtualKeyboard onVirtualKeyboardTick(VirtualKeyboard vkeyboard) { if (state == TASstate.RECORDING) { - this.mouse = mouse.clone(); + this.keyboard.deepCopyFrom(vkeyboard); } else if (state == TASstate.PLAYBACK) { - mouse = this.mouse.clone(); + vkeyboard.deepCopyFrom(this.keyboard); } - return mouse; + return vkeyboard.clone(); } - /** - * 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) { + @Override + public VirtualCameraAngle onVirtualCameraTick(VirtualCameraAngle vcamera) { if (state == TASstate.RECORDING) { - this.subticks = subticks.clone(); + this.camera.deepCopyFrom(vcamera); } else if (state == TASstate.PLAYBACK) { - subticks = this.subticks.clone(); + vcamera.deepCopyFrom(this.camera); } - return subticks; + return vcamera.clone(); } /** * 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 */ - 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) { setTASState(tempPause); // The recording is paused in LoadWorldEvents#startLaunchServer pause(false); - printCredits(); + EventListenerRegistry.fireEvent(EventPlaybackJoinedWorld.class, state); } } @@ -429,9 +411,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 } @@ -460,7 +442,7 @@ private void playbackNextTick() { } /* Stop condition */ - if (index == inputs.size()) { + if (index == inputs.size() || inputs.isEmpty()) { unpressContainer(); setTASState(TASstate.NONE); } @@ -469,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.subticks = tickcontainer.getSubticks().clone(); + this.camera = tickcontainer.getCameraAngle().clone(); // check for control bytes ControlByteHandler.readCotrolByte(controlBytes.get(index)); } @@ -494,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; } @@ -509,7 +491,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.getCameraAngle(); } } else { throw new IndexOutOfBoundsException("Index is bigger than the container"); @@ -539,16 +521,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(); } /** @@ -566,117 +540,12 @@ public String toString() { return out; } - // ===================================================================================================== - // 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() { + 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; - } - - // ===================================================================================================== - // 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(); - } - } - // ============================================================== /** @@ -690,28 +559,6 @@ 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; } @@ -747,7 +594,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 @@ -763,7 +610,7 @@ public VirtualMouse getMouse() { return mouse; } - public VirtualCameraAngle getSubticks() { + public VirtualCameraAngle getCameraAngle() { return subticks; } @@ -811,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); }); } @@ -831,9 +678,9 @@ public PacketID[] getAcceptedPacketIDs() { PLAYBACK_FULLRECORD, PLAYBACK_RESTARTANDPLAY, PLAYBACK_PLAYUNTIL, - PLAYBACK_TELEPORT, - PLAYBACK_CLEAR_INPUTS, - PLAYBACK_STATE + PLAYBACK_CLEAR_INPUTS, + PLAYBACK_STATE + }; } @@ -932,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/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/PlaybackMetadata.java b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java new file mode 100644 index 00000000..c2a00c47 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadata.java @@ -0,0 +1,95 @@ +package com.minecrafttas.tasmod.playback.metadata; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +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 { + private String extensionName; + private LinkedHashMap metadata; + + private static String SEPERATOR = ":"; + + public PlaybackMetadata(PlaybackMetadataExtension extension) { + this(extension.getExtensionName()); + } + + private PlaybackMetadata(String extensionName) { + this.extensionName = extensionName; + this.metadata = new LinkedHashMap(); + } + + public void setValue(String key, String value) { + if (key.contains(SEPERATOR)) { + throw new IllegalArgumentException(String.format("%sKeyname %s can't contain %s", extensionName != null ? extensionName + ": " : "", key, SEPERATOR)); + } + metadata.put(key, value); + } + + public String getValue(String key) { + return metadata.get(key); + } + + @Override + public String toString() { + String out = ""; + for (String key : metadata.keySet()) { + String value = getValue(key); + out += (String.format("%s%s%s\n", key, SEPERATOR, 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%s\n", key, SEPERATOR, value)); + } + return out; + } + + public String getExtensionName() { + return extensionName; + } + + 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) { + PlaybackMetadata out = new PlaybackMetadata(extensionName); + + final Pattern pattern = Pattern.compile("(\\w+)\\"+SEPERATOR+"(.+)"); + + 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 new file mode 100644 index 00000000..4c604261 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/PlaybackMetadataRegistry.java @@ -0,0 +1,133 @@ +package com.minecrafttas.tasmod.playback.metadata; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import com.minecrafttas.tasmod.TASmod; + +/** + * 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 Map METADATA_EXTENSION = new LinkedHashMap<>(); + + /** + * 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"); + } + + if (containsClass(extension)) { + 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.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.containsKey(extension.getExtensionName())) { + METADATA_EXTENSION.remove(extension.getExtensionName()); + } else { + TASmod.LOGGER.warn("Trying to unregister the playback extension {}, but it was not registered!", extension.getClass().getName()); + } + } + + public static void handleOnCreate() { + + } + + public static List handleOnStore() { + List metadataList = new ArrayList<>(); + for(PlaybackMetadataExtension extension : METADATA_EXTENSION.values()) { + metadataList.add(extension.onStore()); + } + return metadataList; + } + + 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()); + } + } + } + + public static void handleOnClear() { + METADATA_EXTENSION.forEach((key, extension) ->{ + extension.onClear(); + }); + } + + private static boolean containsClass(PlaybackMetadataExtension newExtension) { + for (PlaybackMetadataExtension extension : METADATA_EXTENSION.values()) { + if (extension.getClass().equals(newExtension.getClass())) { + return true; + } + } + return false; + } + + 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); + + /** + * 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 new file mode 100644 index 00000000..ddeb0a9d --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/CreditsMetadataExtension.java @@ -0,0 +1,118 @@ +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 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 { + + /** + * 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 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"); + if (state == TASstate.PLAYBACK && !creditsPrinted) { + creditsPrinted = true; + printMessage(title, TextFormatting.GOLD); + printMessage("", null); + printMessage("by " + authors, TextFormatting.AQUA); + printMessage("", null); + printMessage("in " + playtime, null); + printMessage("", null); + printMessage("Rerecords: " + rerecords, null); + } + } + + private void printMessage(String msg, TextFormatting 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/metadata/integrated/StartpositionMetadataExtension.java b/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/StartpositionMetadataExtension.java new file mode 100644 index 00000000..319588e0 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/playback/metadata/integrated/StartpositionMetadataExtension.java @@ -0,0 +1,158 @@ +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; + +/** + * 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 { + + 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() { + // Unused atm + } + + @Override + public PlaybackMetadata onStore() { + 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) { + 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) { + 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/PlaybackSerialiser.java b/src/main/java/com/minecrafttas/tasmod/playback/tasfile/PlaybackSerialiser.java similarity index 87% rename from src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java rename to src/main/java/com/minecrafttas/tasmod/playback/tasfile/PlaybackSerialiser.java index 0d3c2b98..29b0db5e 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackSerialiser.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/tasfile/PlaybackSerialiser.java @@ -1,13 +1,14 @@ -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; 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; @@ -107,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(); @@ -282,12 +283,12 @@ public PlaybackControllerClient fromEntireFileV1(File file) throws IOException { } } } - controller.setAuthors(author); - controller.setTitle(title); - controller.setPlaytime(playtime); - controller.setRerecords(rerecords); - controller.setStartLocation(startLocation); - controller.setStartSeed(startSeed); +// 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/main/java/com/minecrafttas/tasmod/playback/tasfile/PlaybackSerialiserBase.java b/src/main/java/com/minecrafttas/tasmod/playback/tasfile/PlaybackSerialiserBase.java new file mode 100644 index 00000000..305b3a74 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/playback/tasfile/PlaybackSerialiserBase.java @@ -0,0 +1,42 @@ +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) { + 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) { + + } +} 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); + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualCameraAngle.java index aefb5a50..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,11 +80,21 @@ 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()) { - addSubtick(clone()); + if(isParent() && !ignoreFirstUpdate() && updateSubtick) { + addSubtick(shallowClone()); } this.pitch = MathHelper.clamp(this.pitch + pitchDelta, -90.0F, 90.0F); this.yaw += yawDelta; @@ -113,10 +123,12 @@ 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 + * 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; this.yaw = camera.yaw; this.subtickList.clear(); @@ -124,6 +136,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 || !camera.isParent()) + 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 */ @@ -137,9 +162,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/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index b59f7a25..ea385bf6 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -11,6 +11,10 @@ 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.EventVirtualKeyboardTick; +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; @@ -244,8 +248,9 @@ 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.copyFrom(nextKeyboard); + currentKeyboard.moveFrom(nextKeyboard); } /** @@ -403,8 +408,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.deepCopyFrom((VirtualMouse) EventListenerRegistry.fireEvent(EventVirtualMouseTick.class, nextMouse)); currentMouse.getVirtualEvents(nextMouse, mouseEventQueue); - currentMouse.copyFrom(nextMouse); + currentMouse.moveFrom(nextMouse); } /** @@ -577,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); } /** @@ -588,8 +608,10 @@ public void updateNextCameraAngle(float pitchDelta, float yawDelta) { * @see MixinEntityRenderer#runUpdate(float) */ public void nextCameraTick() { + nextCameraAngle.deepCopyFrom((VirtualCameraAngle) EventListenerRegistry.fireEvent(EventVirtualCameraAngleTick.class, nextCameraAngle)); + cameraAngleInterpolationStates.clear(); nextCameraAngle.getStates(cameraAngleInterpolationStates); - currentCameraAngle.copyFrom(nextCameraAngle); + currentCameraAngle.moveFrom(nextCameraAngle); } /** @@ -634,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 ? yaw : 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(), 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/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..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,21 +289,45 @@ 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 copyFrom(VirtualKeyboard keyboard) { - super.copyFrom(keyboard); + public void moveFrom(VirtualKeyboard keyboard) { + if(keyboard == null) + return; + 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 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 99a65ddf..6b83e7a5 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) { @@ -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(clone()); - } + 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 @@ -220,18 +241,44 @@ 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 + 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.scrollWheel=0; + } + @Override public void copyFrom(VirtualMouse mouse) { + if(mouse==null) + return; super.copyFrom(mouse); this.scrollWheel = mouse.scrollWheel; this.cursorX = mouse.cursorX; this.cursorY = mouse.cursorY; - mouse.clearMouseData(); + } + + @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 diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java index 44130857..e194a4b0 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualPeripheral.java @@ -134,15 +134,44 @@ 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.
+ * Ignores {@link com.minecrafttas.tasmod.virtual.Subtickable.subtickList} * * @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.
+ * Ignores {@link com.minecrafttas.tasmod.virtual.Subtickable.subtickList} + * + * @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(); } + + /** + * 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/mctcommon/event/EventTest.java b/src/test/java/mctcommon/event/EventTest.java index cf1bdd3a..fa0eeec5 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; @@ -164,6 +160,7 @@ void testUnregister() { EventListenerRegistry.unregister(event); - assertNull(EventListenerRegistry.fireEvent(TestEvent.class)); + EventListenerRegistry.fireEvent(TestEvent.class); + return; } } 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..1c3ba61e --- /dev/null +++ b/src/test/java/tasmod/playback/metadata/PlaybackMetadataRegistryTest.java @@ -0,0 +1,105 @@ +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"); + } + + @Override + public void onClear() { + } + + } + + 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 new file mode 100644 index 00000000..fbb21a7c --- /dev/null +++ b/src/test/java/tasmod/playback/metadata/PlaybackMetadataTest.java @@ -0,0 +1,174 @@ +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 java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.Test; + +import com.minecrafttas.tasmod.playback.metadata.PlaybackMetadata; +import com.minecrafttas.tasmod.playback.metadata.PlaybackMetadataRegistry.PlaybackMetadataExtension; + +public class PlaybackMetadataTest { + + 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) { + } + + @Override + public void onClear() { + } + + } + + @Test + void testConstructor() { + MetadataTest test = new MetadataTest(); + PlaybackMetadata metadata = new PlaybackMetadata(test); + assertNotNull(metadata.getMetadata()); + assertEquals("Test", metadata.getExtensionName()); + } + + @Test + void testSettingAndReading() { + MetadataTest test = new MetadataTest(); + PlaybackMetadata metadata = new PlaybackMetadata(test); + metadata.setValue("testProperty", "Test"); + + String actual = metadata.getValue("testProperty"); + + assertEquals("Test", actual); + } + + @Test + void testToString() { + 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"); + + String actual = metadata.toString(); + + String expected = "1:One\n" + + "2:Two\n" + + "3:Three\n" + + "4:Four\n"; + + assertEquals(expected, actual); + } + + @Test + void testToStringList() { + 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"); + + 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() { + 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"); + + MetadataTest test2 = new MetadataTest(); + PlaybackMetadata metadata2 = new PlaybackMetadata(test2); + metadata2.setValue("1", "One"); + metadata2.setValue("2", "Two"); + metadata2.setValue("3", "Three"); + metadata2.setValue("4", "Four"); + + assertEquals(metadata, metadata2); + } + + @Test + void testFailedEquals() { + //Key difference + 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"); + + MetadataTest test2 = new MetadataTest(); + PlaybackMetadata metadata2 = new PlaybackMetadata(test2); + 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 + metadata2 = new PlaybackMetadata(test); + metadata.setValue("1", "One"); + metadata.setValue("2", "Two"); + metadata.setValue("3", "Three"); + metadata.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); + } +} diff --git a/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java b/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java index a6aa974b..d8773e25 100644 --- a/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java +++ b/src/test/java/tasmod/virtual/VirtualCameraAngleTest.java @@ -142,17 +142,17 @@ 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); VirtualCameraAngle actual = new VirtualCameraAngle(0f, 0f, true); - actual.copyFrom(expected); + actual.moveFrom(expected); // Test pitch and yaw assertEquals(expected.getPitch(), actual.getPitch()); @@ -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/VirtualInputTest.java b/src/test/java/tasmod/virtual/VirtualInputTest.java index 060ce206..17fbd63f 100644 --- a/src/test/java/tasmod/virtual/VirtualInputTest.java +++ b/src/test/java/tasmod/virtual/VirtualInputTest.java @@ -8,9 +8,13 @@ import org.apache.commons.lang3.tuple.Triple; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.BeforeAll; 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 +25,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 */ @@ -297,59 +309,36 @@ 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(10f, 10f, 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(20f, 20f, 0f); + expected = Triple.of(10f, 190f, 0f); actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.2f, 0f, 0f, true); assertEquals(expected, actual); - expected = Triple.of(30f, 30f, 0f); + expected = Triple.of(20f, 200f, 0f); actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.3f, 0f, 0f, true); assertEquals(expected, actual); - expected = Triple.of(40f, 40f, 0f); + expected = Triple.of(30f, 210f, 0f); actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.4f, 0f, 0f, true); assertEquals(expected, actual); - expected = Triple.of(50f, 50f, 0f); + expected = Triple.of(40f, 220f, 0f); actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.5f, 0f, 0f, true); assertEquals(expected, actual); - expected = Triple.of(60f, 60f, 0f); + expected = Triple.of(50f, 230f, 0f); actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.6f, 0f, 0f, true); assertEquals(expected, actual); } - - /** - * Test interpolation but with playback running, but there are only 2 values - */ - @Test - @Disabled - void testInterpolationEnabledLegacy(){ - VirtualInput virtual = new VirtualInput(LOGGER); - - virtual.CAMERA_ANGLE.setCamera(0f, 0f); - - virtual.CAMERA_ANGLE.updateNextCameraAngle(10f, 10f); - - virtual.CAMERA_ANGLE.nextCameraTick(); - - Triple expected = Triple.of(0f, 0f, 0f); - Triple actual = virtual.CAMERA_ANGLE.getInterpolatedState(0f, 0f, 0f, true); - assertEquals(expected, actual); - - expected = Triple.of(10f, 10f, 0f); - actual = virtual.CAMERA_ANGLE.getInterpolatedState(0.3f, 0f, 0f, true); - assertEquals(expected, actual); - } } diff --git a/src/test/java/tasmod/virtual/VirtualKeyboardTest.java b/src/test/java/tasmod/virtual/VirtualKeyboardTest.java index 2ce164b7..7432b97a 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()); @@ -213,17 +213,58 @@ void testClone() { testCharList.add('w'); testCharList.add('s'); - VirtualKeyboard actual = new VirtualKeyboard(testKeycodeSet, testCharList); - VirtualKeyboard test2 = actual.clone(); + VirtualKeyboard expected = new VirtualKeyboard(testKeycodeSet, testCharList); + VirtualKeyboard actual = expected.shallowClone(); - assertEquals(actual, test2); + assertEquals(expected, actual); + } + + /** + * 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 + */ + @Test + 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 copy from method + * Test copyFrom method */ @Test - void testCopyFrom(){ + void testCopyFrom() { VirtualKeyboard copyFrom = new VirtualKeyboard(); VirtualKeyboard actual = new VirtualKeyboard(); @@ -235,15 +276,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..90fd0f4c 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); @@ -177,20 +174,66 @@ 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); } + /** + * 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 + */ + @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(10, moveFrom.getCursorX()); + assertEquals(20, moveFrom.getCursorY()); + } + /** * Test copyFrom method */ @@ -204,9 +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()); @@ -214,17 +259,17 @@ 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()); } /** * 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); @@ -235,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); + } }