From 4a979f1fe37244e965d41d45aa09462996a96648 Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 7 May 2022 13:15:48 +0200 Subject: [PATCH 01/12] Fixed a crash when making a savestate --- .../tasmod/savestates/client/gui/GuiSavestateSavingScreen.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/scribble/lp/tasmod/savestates/client/gui/GuiSavestateSavingScreen.java b/src/main/java/de/scribble/lp/tasmod/savestates/client/gui/GuiSavestateSavingScreen.java index 75648edf..92a1614c 100644 --- a/src/main/java/de/scribble/lp/tasmod/savestates/client/gui/GuiSavestateSavingScreen.java +++ b/src/main/java/de/scribble/lp/tasmod/savestates/client/gui/GuiSavestateSavingScreen.java @@ -15,7 +15,7 @@ public void initGui() { @Override public void drawScreen(int mouseX, int mouseY, float partialTicks) { - this.drawDefaultBackground(); + this.drawWorldBackground(0); ScaledResolution scaled = new ScaledResolution(Minecraft.getMinecraft()); int width = scaled.getScaledWidth(); From 5a5989b12e617100531b54ea91117630c9db0a48 Mon Sep 17 00:00:00 2001 From: MCPfannkuchenYT Date: Sat, 7 May 2022 19:37:17 +0200 Subject: [PATCH 02/12] Adding control bytes --- .../de/pfannekuchen/infogui/gui/InfoHud.java | 7 +++ .../controlbytes/ControlByteHandler.java | 62 +++++++++++++++++++ .../events/CameraInterpolationEvents.java | 19 +++++- .../java/de/scribble/lp/tasmod/InfoGui.java | 4 ++ .../tasmod/inputcontainer/InputContainer.java | 19 ++++++ .../lp/tasmod/util/ContainerSerialiser.java | 10 +++ 6 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 src/main/java/de/pfannekuchen/tasmod/controlbytes/ControlByteHandler.java diff --git a/src/main/java/de/pfannekuchen/infogui/gui/InfoHud.java b/src/main/java/de/pfannekuchen/infogui/gui/InfoHud.java index 9e5a5dd1..7ba6e797 100644 --- a/src/main/java/de/pfannekuchen/infogui/gui/InfoHud.java +++ b/src/main/java/de/pfannekuchen/infogui/gui/InfoHud.java @@ -13,6 +13,7 @@ import com.mojang.realmsclient.gui.ChatFormatting; +import de.pfannekuchen.tasmod.controlbytes.ControlByteHandler; import de.pfannekuchen.tasmod.utils.PlayerPositionCalculator; import de.pfannekuchen.tasmod.utils.TrajectoriesCalculator; import de.scribble.lp.killtherng.KillTheRNG; @@ -386,6 +387,12 @@ public boolean checkInit() { * Render the Info Hud only */ public void drawHud() { + // render custom info box if control byte is set + if (!ControlByteHandler.hideInfoBox && ClientProxy.virtual.getContainer().isPlayingback()) + drawRectWithText(ControlByteHandler.text, 10, 10, true); + // skip rendering of control byte is set + if (!ControlByteHandler.shouldRenderHud && ClientProxy.virtual.getContainer().isPlayingback()) + return; int xpos=40; int ypos=190; for (InfoLabel label : lists) { diff --git a/src/main/java/de/pfannekuchen/tasmod/controlbytes/ControlByteHandler.java b/src/main/java/de/pfannekuchen/tasmod/controlbytes/ControlByteHandler.java new file mode 100644 index 00000000..7713ace3 --- /dev/null +++ b/src/main/java/de/pfannekuchen/tasmod/controlbytes/ControlByteHandler.java @@ -0,0 +1,62 @@ +package de.pfannekuchen.tasmod.controlbytes; + +/** + * Handles playback control bytes + * @author Pancake + */ +public class ControlByteHandler { + + /** + * Resets all control-byte-controlled settings + */ + public static void reset() { + ControlByteHandler.shouldInterpolate = false; + ControlByteHandler.shouldRenderHud = true; + ControlByteHandler.text = ""; + ControlByteHandler.hideInfoBox = true; + } + + /** + * Reacts to control bytes + * @param command Control Command + * @param args Arguments + */ + public static void onControlByte(String command, String[] args) { + switch (command.toLowerCase()) { + case "interpolation": + interpolation(args); + break; + case "hud": + hud(args); + break; + case "info": + info(args); + default: + break; + } + } + + private static void info(String[] args) { + ControlByteHandler.hideInfoBox = "off".equals(args[0].trim()) || "false".equals(args[0].trim()) || "no".equals(args[0].trim()) || "0".equals(args[0].trim()); + // Parse array as text + ControlByteHandler.text = ""; + for (String string : args) { + ControlByteHandler.text += " " + string; + } + ControlByteHandler.text = ControlByteHandler.text.trim(); + } + + public static void interpolation(String[] args) { + ControlByteHandler.shouldInterpolate = "on".equals(args[0].trim()) || "true".equals(args[0].trim()) || "yes".equals(args[0].trim()) || "1".equals(args[0].trim()); + } + + public static void hud(String[] args) { + ControlByteHandler.shouldRenderHud = "on".equals(args[0].trim()) || "true".equals(args[0].trim()) || "yes".equals(args[0].trim()) || "1".equals(args[0].trim()); + } + + public static boolean hideInfoBox = true; + public static String text = ""; + public static boolean shouldInterpolate = false; + public static boolean shouldRenderHud = true; + +} diff --git a/src/main/java/de/pfannekuchen/tasmod/events/CameraInterpolationEvents.java b/src/main/java/de/pfannekuchen/tasmod/events/CameraInterpolationEvents.java index 98e66cb9..abd6ecea 100644 --- a/src/main/java/de/pfannekuchen/tasmod/events/CameraInterpolationEvents.java +++ b/src/main/java/de/pfannekuchen/tasmod/events/CameraInterpolationEvents.java @@ -1,5 +1,10 @@ package de.pfannekuchen.tasmod.events; +import de.pfannekuchen.tasmod.controlbytes.ControlByteHandler; +import de.scribble.lp.tasmod.ClientProxy; +import de.scribble.lp.tasmod.inputcontainer.TickInputContainer; +import net.minecraft.client.Minecraft; +import net.minecraft.util.math.MathHelper; import net.minecraftforge.client.event.EntityViewRenderEvent.CameraSetup; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -7,11 +12,19 @@ public class CameraInterpolationEvents { public static float rotationPitch = 0f; public static float rotationYaw = 0f; - @SubscribeEvent public void inter(CameraSetup ev) { - ev.setPitch(rotationPitch); - ev.setYaw(rotationYaw); + if (ClientProxy.virtual.getContainer().isPlayingback() && ControlByteHandler.shouldInterpolate) { + TickInputContainer input = ClientProxy.virtual.getContainer().get(ClientProxy.virtual.getContainer().index()); + if (input == null) return; + float nextPitch = input.getSubticks().getPitch(); + float nextYaw = input.getSubticks().getYaw(); + ev.setPitch((float) MathHelper.clampedLerp(rotationPitch, nextPitch, Minecraft.getMinecraft().timer.renderPartialTicks)); + ev.setYaw((float) MathHelper.clampedLerp(rotationYaw, nextYaw+180, Minecraft.getMinecraft().timer.renderPartialTicks)); + } else { + ev.setPitch(rotationPitch); + ev.setYaw(rotationYaw); + } } } diff --git a/src/main/java/de/scribble/lp/tasmod/InfoGui.java b/src/main/java/de/scribble/lp/tasmod/InfoGui.java index 84e7fec1..d59c122c 100644 --- a/src/main/java/de/scribble/lp/tasmod/InfoGui.java +++ b/src/main/java/de/scribble/lp/tasmod/InfoGui.java @@ -4,6 +4,7 @@ import com.mojang.realmsclient.gui.ChatFormatting; +import de.pfannekuchen.tasmod.controlbytes.ControlByteHandler; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.ScaledResolution; @@ -26,6 +27,9 @@ public void drawStuff(RenderGameOverlayEvent.Post event) { if (event.isCancelable() || event.getType() != ElementType.HOTBAR) { return; } + // skip rendering control byte hide hud is set + if (!ControlByteHandler.shouldRenderHud && ClientProxy.virtual.getContainer().isPlayingback()) + return; ScaledResolution scaled = new ScaledResolution(mc); int width = scaled.getScaledWidth(); int height = scaled.getScaledHeight(); diff --git a/src/main/java/de/scribble/lp/tasmod/inputcontainer/InputContainer.java b/src/main/java/de/scribble/lp/tasmod/inputcontainer/InputContainer.java index 6693b23a..427811db 100644 --- a/src/main/java/de/scribble/lp/tasmod/inputcontainer/InputContainer.java +++ b/src/main/java/de/scribble/lp/tasmod/inputcontainer/InputContainer.java @@ -1,12 +1,17 @@ package de.scribble.lp.tasmod.inputcontainer; import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.lwjgl.opengl.Display; import com.dselent.bigarraylist.BigArrayList; import com.mojang.realmsclient.gui.ChatFormatting; +import com.mojang.realmsclient.util.Pair; +import de.pfannekuchen.tasmod.controlbytes.ControlByteHandler; import de.scribble.lp.tasmod.ClientProxy; import de.scribble.lp.tasmod.CommonProxy; import de.scribble.lp.tasmod.monitoring.DesyncMonitoring; @@ -69,6 +74,9 @@ public class InputContainer { */ private BigArrayList inputs = new BigArrayList(directory + File.separator + "temp"); + // All control characters + private Map>> controls = new HashMap>>(); + public DesyncMonitoring dMonitor = new DesyncMonitoring(); // ===================================================================================================== @@ -105,6 +113,7 @@ public String setTASState(TASstate stateIn) { * @return The message printed in the chat */ public String setTASState(TASstate stateIn, boolean verbose) { + ControlByteHandler.reset(); if (state == stateIn) { switch (stateIn) { case PLAYBACK: @@ -360,6 +369,11 @@ private void playbackNextTick() { this.keyboard = tickcontainer.getKeyboard().clone(); this.mouse = tickcontainer.getMouse().clone(); this.subticks = tickcontainer.getSubticks().clone(); + // check for control bytes + List> controlbyte = controls.get(index); + if (controlbyte != null) + for (Pair pair : controlbyte) + ControlByteHandler.onControlByte(pair.first(), pair.second()); } } // ===================================================================================================== @@ -381,6 +395,10 @@ public BigArrayList getInputs() { return inputs; } + public Map>> getControlBytes() { + return controls; + } + public void setIndex(int index) { this.index = index; if (state == TASstate.PLAYBACK) { @@ -403,6 +421,7 @@ public TickInputContainer get(int index) { public void clear() { inputs = new BigArrayList(directory + File.separator + "temp"); + controls.clear(); index = 0; dMonitor.getPos().clear(); clearCredits(); diff --git a/src/main/java/de/scribble/lp/tasmod/util/ContainerSerialiser.java b/src/main/java/de/scribble/lp/tasmod/util/ContainerSerialiser.java index bedd0129..48802a68 100644 --- a/src/main/java/de/scribble/lp/tasmod/util/ContainerSerialiser.java +++ b/src/main/java/de/scribble/lp/tasmod/util/ContainerSerialiser.java @@ -10,6 +10,7 @@ import org.apache.commons.io.FileUtils; import com.dselent.bigarraylist.BigArrayList; +import com.mojang.realmsclient.util.Pair; import de.scribble.lp.tasmod.inputcontainer.InputContainer; import de.scribble.lp.tasmod.inputcontainer.TickInputContainer; @@ -152,6 +153,15 @@ public InputContainer fromEntireFileV1(File file) throws IOException { } else if (line.startsWith("#StartPosition:")) { startLocation = line.replace("#StartPosition:", ""); } + } else if (line.startsWith("$") && line.replace('$', ' ').trim().contains(" ")) { + String[] sections = line.replace('$', ' ').trim().split(" ", 2); + if (sections.length == 0) + continue; + String control = sections[0]; + String[] params = sections[1].split(" "); + List> cbytes = container.getControlBytes().getOrDefault((int) container.getInputs().size(), new ArrayList<>()); + cbytes.add(Pair.of(control, params)); + container.getControlBytes().put((int) container.getInputs().size(), cbytes); } else { String[] sections = line.split("\\|"); From 3ac9dc9cece5e534c7655927e2593ed0d9cf585a Mon Sep 17 00:00:00 2001 From: MCPfannkuchenYT Date: Sat, 7 May 2022 19:40:55 +0200 Subject: [PATCH 03/12] Use accessor for accessing timer field --- .../tasmod/events/CameraInterpolationEvents.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/de/pfannekuchen/tasmod/events/CameraInterpolationEvents.java b/src/main/java/de/pfannekuchen/tasmod/events/CameraInterpolationEvents.java index abd6ecea..6defb5b1 100644 --- a/src/main/java/de/pfannekuchen/tasmod/events/CameraInterpolationEvents.java +++ b/src/main/java/de/pfannekuchen/tasmod/events/CameraInterpolationEvents.java @@ -3,6 +3,7 @@ import de.pfannekuchen.tasmod.controlbytes.ControlByteHandler; import de.scribble.lp.tasmod.ClientProxy; import de.scribble.lp.tasmod.inputcontainer.TickInputContainer; +import de.scribble.lp.tasmod.mixin.accessors.AccessorRunStuff; import net.minecraft.client.Minecraft; import net.minecraft.util.math.MathHelper; import net.minecraftforge.client.event.EntityViewRenderEvent.CameraSetup; @@ -19,8 +20,8 @@ public void inter(CameraSetup ev) { if (input == null) return; float nextPitch = input.getSubticks().getPitch(); float nextYaw = input.getSubticks().getYaw(); - ev.setPitch((float) MathHelper.clampedLerp(rotationPitch, nextPitch, Minecraft.getMinecraft().timer.renderPartialTicks)); - ev.setYaw((float) MathHelper.clampedLerp(rotationYaw, nextYaw+180, Minecraft.getMinecraft().timer.renderPartialTicks)); + ev.setPitch((float) MathHelper.clampedLerp(rotationPitch, nextPitch, ((AccessorRunStuff) Minecraft.getMinecraft()).timer().renderPartialTicks)); + ev.setYaw((float) MathHelper.clampedLerp(rotationYaw, nextYaw+180, ((AccessorRunStuff) Minecraft.getMinecraft()).timer().renderPartialTicks)); } else { ev.setPitch(rotationPitch); ev.setYaw(rotationYaw); From 1e217e6d969091e5f97a28a00ad37f62400abb0b Mon Sep 17 00:00:00 2001 From: MCPfannkuchenYT Date: Sat, 7 May 2022 19:46:43 +0200 Subject: [PATCH 04/12] Update player angle every frame --- src/main/java/de/pfannekuchen/infogui/gui/InfoHud.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/de/pfannekuchen/infogui/gui/InfoHud.java b/src/main/java/de/pfannekuchen/infogui/gui/InfoHud.java index 7ba6e797..55c4b1d9 100644 --- a/src/main/java/de/pfannekuchen/infogui/gui/InfoHud.java +++ b/src/main/java/de/pfannekuchen/infogui/gui/InfoHud.java @@ -14,6 +14,7 @@ import com.mojang.realmsclient.gui.ChatFormatting; import de.pfannekuchen.tasmod.controlbytes.ControlByteHandler; +import de.pfannekuchen.tasmod.events.CameraInterpolationEvents; import de.pfannekuchen.tasmod.utils.PlayerPositionCalculator; import de.pfannekuchen.tasmod.utils.TrajectoriesCalculator; import de.scribble.lp.killtherng.KillTheRNG; @@ -198,7 +199,6 @@ private void saveConfig() { */ public void tick() { if (checkInit()) return; - for (InfoLabel label : lists) label.tick(); } public boolean checkInit() { @@ -269,7 +269,7 @@ public boolean checkInit() { if (configuration.getProperty(title + "_x", "err").equals("err")) setDefaults(title, y); lists.add(new InfoLabel(title, Integer.parseInt(configuration.getProperty(title + "_x")), Integer.parseInt(configuration.getProperty(title + "_y")), Boolean.parseBoolean(configuration.getProperty(title + "_visible")), Boolean.parseBoolean(configuration.getProperty(title + "_rect")), () -> { if (Minecraft.getMinecraft().currentScreen == this) return "Facing"; - return String.format("%.2f %.2f", Minecraft.getMinecraft().player.rotationYaw, Minecraft.getMinecraft().player.rotationPitch); + return String.format("%.2f %.2f", CameraInterpolationEvents.rotationYaw, CameraInterpolationEvents.rotationPitch); })); title = "cticks"; @@ -396,6 +396,7 @@ public void drawHud() { int xpos=40; int ypos=190; for (InfoLabel label : lists) { + label.tick(); if (label.visible) { drawRectWithText(label.renderText, label.x, label.y, label.renderRect); } else if (Minecraft.getMinecraft().currentScreen != null) { From 94afbb6619a0de7b30f64f7d9d5ac500a7888df8 Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 7 May 2022 16:45:03 +0200 Subject: [PATCH 05/12] Fixes #135, Bump version - General code improvements --- build.gradle | 2 +- .../lp/tasmod/events/LoadWorldEvents.java | 31 +++++++++++-------- .../mixin/events/MixinIntegratedServer.java | 18 +++++++++++ .../mixin/events/MixinMinecraftServer.java | 1 - .../TickrateChangerServer.java | 2 +- src/main/resources/mixins.tasmod.json | 1 + 6 files changed, 39 insertions(+), 16 deletions(-) create mode 100644 src/main/java/de/scribble/lp/tasmod/mixin/events/MixinIntegratedServer.java diff --git a/build.gradle b/build.gradle index 0ecfaf04..4c15c78a 100644 --- a/build.gradle +++ b/build.gradle @@ -19,7 +19,7 @@ apply plugin: 'org.spongepowered.mixin' //Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. -version = "Alpha8" +version = "Alpha8.1-WIP" group = "de.scribble.lp.tastools" // http://maven.apache.org/guides/mini/guide-naming-conventions.html archivesBaseName = "TASmod-1.12.2" diff --git a/src/main/java/de/scribble/lp/tasmod/events/LoadWorldEvents.java b/src/main/java/de/scribble/lp/tasmod/events/LoadWorldEvents.java index 46b1519c..b2df94e5 100644 --- a/src/main/java/de/scribble/lp/tasmod/events/LoadWorldEvents.java +++ b/src/main/java/de/scribble/lp/tasmod/events/LoadWorldEvents.java @@ -8,7 +8,11 @@ public class LoadWorldEvents { public static boolean waszero = false; - public static int cd = -1; + + /** + * Delay after the loading screen is finished before firing "doneWithLoadingScreen" + */ + private static int loadingScreenDelay = -1; /** * Executed when an integrated server is launched @@ -26,14 +30,12 @@ public static void startLaunchServer() { * Executed when the server is initialising * Side: Integrated Server * - * @see de.scribble.lp.tasmod.mixin.events.MixinMinecraftServer#inject_run(org.spongepowered.asm.mixin.injection.callback.CallbackInfo) + * @see de.scribble.lp.tasmod.mixin.events.MixinIntegratedServer#inject_init(org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable) */ public static void initServer() { - if (!TASmod.getServerInstance().isDedicatedServer()) { - TASmod.logger.info("Integrated server initialised"); - TickrateChangerClient.pauseClientGame(true); - TickrateChangerServer.pauseServerGame(true); - } + TASmod.logger.info("Integrated server initialised"); + TickrateChangerClient.pauseClientGame(true); + TickrateChangerServer.pauseServerGame(true); } /* The following code is for integrated and dedicated server! */ @@ -63,8 +65,8 @@ public static void doneShuttingDown() { */ public static void doneLoadingClientWorld() { TASmod.logger.info("Finished loading the world on the client"); - if(TASmod.getServerInstance()!=null) { - cd = 1; + if(TASmod.getServerInstance()!=null) { //Check if a server is running and if it's an integrated server + loadingScreenDelay = 1; } } @@ -72,16 +74,19 @@ public static void doneLoadingClientWorld() { * Executed a frame after the world is done loading */ public static void doneWithLoadingScreen() { - if (cd > -1) { - if (cd == 0) { + if (loadingScreenDelay > -1) { + if (loadingScreenDelay == 0) { TASmod.logger.info("Finished loading screen on the client"); if (!waszero) { - TickrateChangerClient.pauseGame(false); + if(TASmod.getServerInstance()!=null) { //Check if a server is running and if it's an integrated server + TickrateChangerClient.pauseClientGame(false); + TickrateChangerServer.pauseServerGame(false); + } } else { waszero = false; } } - cd--; + loadingScreenDelay--; } } diff --git a/src/main/java/de/scribble/lp/tasmod/mixin/events/MixinIntegratedServer.java b/src/main/java/de/scribble/lp/tasmod/mixin/events/MixinIntegratedServer.java new file mode 100644 index 00000000..95de4f5a --- /dev/null +++ b/src/main/java/de/scribble/lp/tasmod/mixin/events/MixinIntegratedServer.java @@ -0,0 +1,18 @@ +package de.scribble.lp.tasmod.mixin.events; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import de.scribble.lp.tasmod.events.LoadWorldEvents; +import net.minecraft.server.integrated.IntegratedServer; + +@Mixin(IntegratedServer.class) +public class MixinIntegratedServer { + + @Inject(method = "init", at = @At("HEAD")) + public void inject_init(CallbackInfoReturnable ci) { + LoadWorldEvents.initServer(); + } +} diff --git a/src/main/java/de/scribble/lp/tasmod/mixin/events/MixinMinecraftServer.java b/src/main/java/de/scribble/lp/tasmod/mixin/events/MixinMinecraftServer.java index 0e546944..5a65922d 100644 --- a/src/main/java/de/scribble/lp/tasmod/mixin/events/MixinMinecraftServer.java +++ b/src/main/java/de/scribble/lp/tasmod/mixin/events/MixinMinecraftServer.java @@ -14,7 +14,6 @@ public class MixinMinecraftServer { @Inject(method = "run", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;init()Z", shift = Shift.AFTER)) public void inject_run(CallbackInfo ci) { - LoadWorldEvents.initServer(); } @Inject(method = "initiateShutdown", at = @At("HEAD")) diff --git a/src/main/java/de/scribble/lp/tasmod/tickratechanger/TickrateChangerServer.java b/src/main/java/de/scribble/lp/tasmod/tickratechanger/TickrateChangerServer.java index 0ea2a2b6..1885d5fe 100644 --- a/src/main/java/de/scribble/lp/tasmod/tickratechanger/TickrateChangerServer.java +++ b/src/main/java/de/scribble/lp/tasmod/tickratechanger/TickrateChangerServer.java @@ -144,6 +144,6 @@ public static void joinServer(EntityPlayerMP player) { } private static void log(String msg) { - TASmod.logger.debug(msg); + TASmod.logger.info(msg); } } diff --git a/src/main/resources/mixins.tasmod.json b/src/main/resources/mixins.tasmod.json index 74b86c6c..29cb7759 100644 --- a/src/main/resources/mixins.tasmod.json +++ b/src/main/resources/mixins.tasmod.json @@ -54,6 +54,7 @@ "events.MixinGuiIngameMenu", "events.MixinGuiControls", "events.MixinMinecraft", + "events.MixinIntegratedServer", //Playbackhooks "playbackhooks.MixinGameSettings", From e1798c6776d729b9c2283ed2da5fae94d47900b9 Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 7 May 2022 21:46:30 +0200 Subject: [PATCH 06/12] Trying to fix savestate crashes... again --- .../client/gui/GuiSavestateLoadingScreen.java | 10 +++++----- .../client/gui/GuiSavestateSavingScreen.java | 18 ++++++------------ 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/src/main/java/de/scribble/lp/tasmod/savestates/client/gui/GuiSavestateLoadingScreen.java b/src/main/java/de/scribble/lp/tasmod/savestates/client/gui/GuiSavestateLoadingScreen.java index 0c27aae0..437f0432 100644 --- a/src/main/java/de/scribble/lp/tasmod/savestates/client/gui/GuiSavestateLoadingScreen.java +++ b/src/main/java/de/scribble/lp/tasmod/savestates/client/gui/GuiSavestateLoadingScreen.java @@ -5,7 +5,7 @@ import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.resources.I18n; -public class GuiSavestateLoadingScreen extends GuiScreen{ +public class GuiSavestateLoadingScreen extends GuiScreen { // private static boolean copying; // private static boolean deleting; @@ -13,16 +13,16 @@ public class GuiSavestateLoadingScreen extends GuiScreen{ @Override public void drawScreen(int mouseX, int mouseY, float partialTicks) { this.drawDefaultBackground(); - + ScaledResolution scaled = new ScaledResolution(Minecraft.getMinecraft()); int width = scaled.getScaledWidth(); int height = scaled.getScaledHeight(); - - drawCenteredString(fontRenderer,I18n.format("Loading a savestate!"), width / 2, height / 4 + 50 + -16, 0xFFFFFF); //Loading a savestate! + + drawCenteredString(fontRenderer, I18n.format("Loading a savestate!"), width / 2, height / 4 + 50 + -16, 0xFFFFFF); // Loading a savestate! super.drawScreen(mouseX, mouseY, partialTicks); } - + @Override public boolean doesGuiPauseGame() { return true; diff --git a/src/main/java/de/scribble/lp/tasmod/savestates/client/gui/GuiSavestateSavingScreen.java b/src/main/java/de/scribble/lp/tasmod/savestates/client/gui/GuiSavestateSavingScreen.java index 92a1614c..2554ac72 100644 --- a/src/main/java/de/scribble/lp/tasmod/savestates/client/gui/GuiSavestateSavingScreen.java +++ b/src/main/java/de/scribble/lp/tasmod/savestates/client/gui/GuiSavestateSavingScreen.java @@ -5,26 +5,20 @@ import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.resources.I18n; -public class GuiSavestateSavingScreen extends GuiScreen{ +public class GuiSavestateSavingScreen extends GuiScreen { - @Override - public void initGui() { - this.mc=Minecraft.getMinecraft(); - super.initGui(); - } - @Override public void drawScreen(int mouseX, int mouseY, float partialTicks) { - this.drawWorldBackground(0); - + this.drawDefaultBackground(); + ScaledResolution scaled = new ScaledResolution(Minecraft.getMinecraft()); int width = scaled.getScaledWidth(); int height = scaled.getScaledHeight(); - - drawCenteredString(fontRenderer,I18n.format("Making a savestate, please wait!"),width / 2,height / 4 + 34 + -16, 0xFFFFFF); //Making a savestate, please wait! + + drawCenteredString(fontRenderer, I18n.format("Making a savestate, please wait!"), width / 2, height / 4 + 34 + -16, 0xFFFFFF); // Making a savestate, please wait! super.drawScreen(mouseX, mouseY, partialTicks); } - + @Override public boolean doesGuiPauseGame() { return true; From d2e3049828b911d6e7e568fca56ad80309f6f29b Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 7 May 2022 21:49:54 +0200 Subject: [PATCH 07/12] Changing "info" arg in SavestateCommand to list --- .../tasmod/savestates/server/SavestateCommand.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/de/scribble/lp/tasmod/savestates/server/SavestateCommand.java b/src/main/java/de/scribble/lp/tasmod/savestates/server/SavestateCommand.java index 12e79eea..8cb2e2db 100644 --- a/src/main/java/de/scribble/lp/tasmod/savestates/server/SavestateCommand.java +++ b/src/main/java/de/scribble/lp/tasmod/savestates/server/SavestateCommand.java @@ -25,7 +25,7 @@ public String getName() { @Override public String getUsage(ICommandSender sender) { - return "/savestate [index]"; + return "/savestate [index]"; } @Override @@ -71,9 +71,9 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args if (args.length == 3) { deleteMultiple(args); } - } else if ("info".equals(args[0])) { + } else if ("list".equals(args[0])) { sender.sendMessage(new TextComponentString(String.format("The current savestate index is %s%s", TextFormatting.AQUA, TASmod.savestateHandler.getCurrentIndex()))); - sender.sendMessage(new TextComponentString(String.format("Available indexes are %s%s", TextFormatting.AQUA, TASmod.savestateHandler.getIndexesAsString()))); + sender.sendMessage(new TextComponentString(String.format("Available indexes are %s%s", TextFormatting.AQUA, TASmod.savestateHandler.getIndexesAsString().isEmpty() ? "None" : TASmod.savestateHandler.getIndexesAsString()))); } else if ("help".equals(args[0])) { if (args.length == 1) { sendHelp(sender); @@ -125,7 +125,7 @@ private void sendHelp(ICommandSender sender, int i) throws CommandException { + "%3$s/savestate %4$sload%5$s %2$s - Load the savestate at the specified index\n" + "%3$s/savestate %4$sdelete%5$s %2$s - Delete the savestate at the specified index\n" + "%3$s/savestate %4$sdelete%5$s %2$s - Delete the savestates from the fromIndex to the toIndex\n" - + "%3$s/savestate %4$sinfo%2$s - Shows the current index as well as the available indexes\n" + + "%3$s/savestate %4$slist%2$s - Shows the current index as well as the available indexes\n" + "\nInstead of %4$s %2$syou can use ~ to specify an index relative to the current index e.g. %3$s~-1%2$s will currently load %6$s\n", /*1*/TextFormatting.GOLD, /*2*/TextFormatting.RESET, /*3*/TextFormatting.AQUA, /*4*/TextFormatting.GREEN, /*5*/TextFormatting.YELLOW, /*6*/(currentIndex - 1)))); return; @@ -138,8 +138,8 @@ private void sendHelp(ICommandSender sender, int i) throws CommandException { @Override public List getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, BlockPos targetPos) { if (args.length == 1) { - return getListOfStringsMatchingLastWord(args, new String[] { "save", "load", "delete", "info", "help"}); - } else if (args.length == 2 && !"info".equals(args[0])) { + return getListOfStringsMatchingLastWord(args, new String[] { "save", "load", "delete", "list", "help"}); + } else if (args.length == 2 && !"list".equals(args[0])) { sender.sendMessage(new TextComponentString("Available indexes: " + TextFormatting.AQUA + TASmod.savestateHandler.getIndexesAsString())); } return super.getTabCompletions(server, sender, args, targetPos); From 054f6cb6833a9a4282806517f2d2c29f0bcf4b7a Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 7 May 2022 21:58:15 +0200 Subject: [PATCH 08/12] Loading savestate 0 won't change savestate index anymore --- .../commands/fullplay/CommandFullPlay.java | 2 +- .../commands/fullrecord/FullRecordPacket.java | 2 + .../tasmod/inputcontainer/InputContainer.java | 18 +++-- .../savestates/server/SavestateHandler.java | 68 ++++++++++++------- .../lp/tasmod/virtual/VirtualInput.java | 67 +++++++++++++----- 5 files changed, 109 insertions(+), 48 deletions(-) diff --git a/src/main/java/de/scribble/lp/tasmod/commands/fullplay/CommandFullPlay.java b/src/main/java/de/scribble/lp/tasmod/commands/fullplay/CommandFullPlay.java index 9a5b1b25..149b384f 100644 --- a/src/main/java/de/scribble/lp/tasmod/commands/fullplay/CommandFullPlay.java +++ b/src/main/java/de/scribble/lp/tasmod/commands/fullplay/CommandFullPlay.java @@ -27,7 +27,7 @@ public String getUsage(ICommandSender sender) { @Override public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { try { - TASmod.savestateHandler.loadState(0, false); + TASmod.savestateHandler.loadState(0, false, false); } catch (LoadstateException e) { sender.sendMessage(new TextComponentString(TextFormatting.RED+"Failed to load a savestate: "+e.getMessage())); return; diff --git a/src/main/java/de/scribble/lp/tasmod/commands/fullrecord/FullRecordPacket.java b/src/main/java/de/scribble/lp/tasmod/commands/fullrecord/FullRecordPacket.java index 75e81212..876840eb 100644 --- a/src/main/java/de/scribble/lp/tasmod/commands/fullrecord/FullRecordPacket.java +++ b/src/main/java/de/scribble/lp/tasmod/commands/fullrecord/FullRecordPacket.java @@ -1,5 +1,6 @@ package de.scribble.lp.tasmod.commands.fullrecord; +import de.scribble.lp.tasmod.ClientProxy; import de.scribble.lp.tasmod.events.OpenGuiEvents; import de.scribble.lp.tasmod.util.TASstate; import io.netty.buffer.ByteBuf; @@ -43,6 +44,7 @@ public IMessage onMessage(FullRecordPacket message, MessageContext ctx) { @SideOnly(Side.CLIENT) private void workaround(Minecraft mc) { OpenGuiEvents.stateWhenOpened = TASstate.RECORDING; + ClientProxy.virtual.getContainer().clear(); mc.world.sendQuittingDisconnectingPacket(); mc.loadWorld((WorldClient) null); mc.displayGuiScreen(new net.minecraft.client.gui.GuiMainMenu()); diff --git a/src/main/java/de/scribble/lp/tasmod/inputcontainer/InputContainer.java b/src/main/java/de/scribble/lp/tasmod/inputcontainer/InputContainer.java index 427811db..caf732b8 100644 --- a/src/main/java/de/scribble/lp/tasmod/inputcontainer/InputContainer.java +++ b/src/main/java/de/scribble/lp/tasmod/inputcontainer/InputContainer.java @@ -399,13 +399,17 @@ public Map>> getControlBytes() { return controls; } - public void setIndex(int index) { - this.index = index; - if (state == TASstate.PLAYBACK) { - TickInputContainer tickcontainer = inputs.get(index); - this.keyboard = tickcontainer.getKeyboard(); - this.mouse = tickcontainer.getMouse(); - this.subticks = tickcontainer.getSubticks(); + public void setIndex(int index) throws IndexOutOfBoundsException{ + if(index<=size()) { + this.index = index; + if (state == TASstate.PLAYBACK) { + TickInputContainer tickcontainer = inputs.get(index); + this.keyboard = tickcontainer.getKeyboard(); + this.mouse = tickcontainer.getMouse(); + this.subticks = tickcontainer.getSubticks(); + } + }else { + throw new IndexOutOfBoundsException("Index is bigger than the container"); } } diff --git a/src/main/java/de/scribble/lp/tasmod/savestates/server/SavestateHandler.java b/src/main/java/de/scribble/lp/tasmod/savestates/server/SavestateHandler.java index f23116c5..1f1a505d 100644 --- a/src/main/java/de/scribble/lp/tasmod/savestates/server/SavestateHandler.java +++ b/src/main/java/de/scribble/lp/tasmod/savestates/server/SavestateHandler.java @@ -83,6 +83,10 @@ public SavestateHandler(MinecraftServer server) { public void saveState() throws SavestateException, IOException { saveState(-1, true); } + + public void saveState(int savestateIndex, boolean tickrate0) throws SavestateException, IOException { + saveState(savestateIndex, tickrate0, true); + } /** * Creates a copy of the world that is currently being played and saves it in @@ -94,10 +98,11 @@ public void saveState() throws SavestateException, IOException { * index<0 if it should save it in the next index from * the currentindex * @param tickrate0 When true: Set's the game to tickrate 0 after creating a savestate + * @param changeIndex When true: Changes the index to the savestateIndex * @throws SavestateException * @throws IOException */ - public void saveState(int savestateIndex, boolean tickrate0) throws SavestateException, IOException { + public void saveState(int savestateIndex, boolean tickrate0, boolean changeIndex) throws SavestateException, IOException { if (state == SavestateState.SAVING) { throw new SavestateException("A savestating operation is already being carried out"); } @@ -127,19 +132,19 @@ public void saveState(int savestateIndex, boolean tickrate0) throws SavestateExc refresh(); // Setting the current index depending on the savestateIndex. + int indexToSave=savestateIndex; if (savestateIndex < 0) { - setCurrentIndex(currentIndex + 1); // If the savestateIndex <= 0, create a savestate at currentIndex+1 - } else { - setCurrentIndex(savestateIndex); - } + indexToSave=currentIndex + 1; // If the savestateIndex <= 0, create a savestate at currentIndex+1 + } + setCurrentIndex(indexToSave, changeIndex); // Get the current and target directory for copying String worldname = server.getFolderName(); File currentfolder = new File(savestateDirectory, ".." + File.separator + worldname); - File targetfolder = getSavestateFile(currentIndex); + File targetfolder = getSavestateFile(indexToSave); if (targetfolder.exists()) { - TASmod.logger.warn("WARNING! Overwriting the savestate with the index {}", currentIndex); + TASmod.logger.warn("WARNING! Overwriting the savestate with the index {}", indexToSave); FileUtils.deleteDirectory(targetfolder); } @@ -152,7 +157,7 @@ public void saveState(int savestateIndex, boolean tickrate0) throws SavestateExc * Send the name of the world to all players. This will make a savestate of the * recording on the client with that name */ - CommonProxy.NETWORK.sendToAll(new InputSavestatesPacket(true, getSavestateName(currentIndex))); + CommonProxy.NETWORK.sendToAll(new InputSavestatesPacket(true, getSavestateName(indexToSave))); } // Wait for the chunkloader to save the game @@ -173,7 +178,7 @@ public void saveState(int savestateIndex, boolean tickrate0) throws SavestateExc saveCurrentIndexToFile(); // Send a notification that the savestate has been loaded - server.getPlayerList().sendMessage(new TextComponentString(TextFormatting.GREEN + "Savestate " + currentIndex + " saved")); + server.getPlayerList().sendMessage(new TextComponentString(TextFormatting.GREEN + "Savestate " + indexToSave + " saved")); // Close the GuiSavestateScreen on the client CommonProxy.NETWORK.sendToAll(new SavestatePacket()); @@ -198,6 +203,18 @@ public void saveState(int savestateIndex, boolean tickrate0) throws SavestateExc public void loadState() throws LoadstateException, IOException { loadState(-1, true); } + + /** + * + * @param savestateIndex + * @param tickrate0 + * + * @throws LoadstateException + * @throws IOException + */ + public void loadState(int savestateIndex, boolean tickrate0) throws LoadstateException, IOException { + loadState(savestateIndex, tickrate0, true); + } /** * Loads the latest savestate it can find in @@ -208,10 +225,11 @@ public void loadState() throws LoadstateException, IOException { * @param savestateIndex The index where the mod will load the savestate. * index<0 if it should load the currentindex * @param tickrate0 When true: Set's the game to tickrate 0 after creating a savestate + * @param changeIndex When true: Changes the index to the savestateIndex * @throws LoadstateException * @throws IOException */ - public void loadState(int savestateIndex, boolean tickrate0) throws LoadstateException, IOException { + public void loadState(int savestateIndex, boolean tickrate0, boolean changeIndex) throws LoadstateException, IOException { if (state == SavestateState.SAVING) { throw new LoadstateException("A savestating operation is already being carried out"); } @@ -234,16 +252,16 @@ public void loadState(int savestateIndex, boolean tickrate0) throws LoadstateExc int indexToLoad = savestateIndex < 0 ? currentIndex : savestateIndex; - if (!getSavestateFile(indexToLoad).exists()) { - throw new LoadstateException("Savestate " + indexToLoad + " doesn't exist"); + if (getSavestateFile(indexToLoad).exists()) { + setCurrentIndex(indexToLoad, changeIndex); } else { - setCurrentIndex(indexToLoad); + throw new LoadstateException("Savestate " + indexToLoad + " doesn't exist"); } // Get the current and target directory for copying String worldname = server.getFolderName(); File currentfolder = new File(savestateDirectory, ".." + File.separator + worldname); - File targetfolder = getSavestateFile(currentIndex); + File targetfolder = getSavestateFile(indexToLoad); /* * Prevents loading an InputSavestate when loading index 0 (Index 0 is the @@ -252,7 +270,7 @@ public void loadState(int savestateIndex, boolean tickrate0) throws LoadstateExc */ if (savestateIndex != 0) { // Load savestate on the client - CommonProxy.NETWORK.sendToAll(new InputSavestatesPacket(false, getSavestateName(currentIndex))); + CommonProxy.NETWORK.sendToAll(new InputSavestatesPacket(false, getSavestateName(indexToLoad))); } // Disabeling level saving for all worlds in case the auto save kicks in during @@ -293,7 +311,7 @@ public void loadState(int savestateIndex, boolean tickrate0) throws LoadstateExc saveCurrentIndexToFile(); // Send a notification that the savestate has been loaded - server.getPlayerList().sendMessage(new TextComponentString(TextFormatting.GREEN + "Savestate " + currentIndex + " loaded")); + server.getPlayerList().sendMessage(new TextComponentString(TextFormatting.GREEN + "Savestate " + indexToLoad + " loaded")); WorldServer[] worlds = DimensionManager.getWorlds(); @@ -404,7 +422,7 @@ public void deleteSavestate(int index) throws SavestateDeleteException { } refresh(); if (!indexList.contains(currentIndex)) { - setCurrentIndex(latestIndex); + setCurrentIndex(latestIndex, true); } // Send a notification that the savestate has been deleted server.getPlayerList().sendMessage(new TextComponentString(TextFormatting.GREEN + "Savestate " + index + " deleted")); @@ -496,16 +514,20 @@ public void loadCurrentIndexFromFile() { } } } - setCurrentIndex(index); + setCurrentIndex(index, true); } - private void setCurrentIndex(int index) { - if (index < 0) { - currentIndex = latestIndex; + private void setCurrentIndex(int index, boolean changeIndex) { + if(changeIndex) { + if (index < 0) { + currentIndex = latestIndex; + } else { + currentIndex = index; + } + TASmod.logger.info("Setting the savestate index to {}", currentIndex); } else { - currentIndex = index; + TASmod.logger.warn("Keeping the savestate index at {}", currentIndex); } - TASmod.logger.info("Setting the savestate index to {}", currentIndex); } public int getCurrentIndex() { diff --git a/src/main/java/de/scribble/lp/tasmod/virtual/VirtualInput.java b/src/main/java/de/scribble/lp/tasmod/virtual/VirtualInput.java index da333f81..c1b2fafa 100644 --- a/src/main/java/de/scribble/lp/tasmod/virtual/VirtualInput.java +++ b/src/main/java/de/scribble/lp/tasmod/virtual/VirtualInput.java @@ -6,7 +6,6 @@ import java.util.Iterator; import java.util.List; -import de.scribble.lp.killtherng.repack.org.msgpack.core.annotations.Nullable; import de.scribble.lp.tasmod.ClientProxy; import de.scribble.lp.tasmod.TASmod; import de.scribble.lp.tasmod.events.OpenGuiEvents; @@ -125,7 +124,7 @@ public VirtualKeyboard getNextKeyboard() { * Loads the inputs and starts a TAS on initialize * @param fileToLoad (Nullable) Loads this filename and starts playing back the TAS */ - public VirtualInput(@Nullable String fileToLoad) { + public VirtualInput(String fileToLoad) { if (fileToLoad != null) { try { loadInputs(fileToLoad); @@ -447,21 +446,50 @@ public void setContainer(InputContainer container) { * Loads and preloads the inputs from the new InputContainer to * {@link #container} * + * Saving a savestate is done via {@linkplain de.scribble.lp.tasmod.util.ContainerSerialiser#saveToFileV1(File, InputContainer)} in {@linkplain de.scribble.lp.tasmod.savestates.client.InputSavestatesHandler#savestate(String)} + * * @param savestatecontainer The container that should be loaded. */ - public void loadSavestate(InputContainer savestatecontainer) { - - if (this.container.isPlayingback()) { - preloadInput(this.container, savestatecontainer.size() - 1); // Preloading from the current container and from the second to last index of - // the savestatecontainer. Since this is executed during playback, - // we will only load the position of the savestate container and not replace the - // container itself - - this.container.setIndex(savestatecontainer.size()); // Set the "playback" index of the current container to the latest index of the - // savestatecontainer. Meaning this index will be played next + public void loadClientSavestate(InputContainer savestatecontainer) { + + if (container.isPlayingback()) { + preloadInput(container, savestatecontainer.size() - 1); // Preloading from the current container and + // from the second to last index of + // the savestatecontainer. Since this is + // executed during playback, + // we will only load the position of the + // savestate container and not replace the + // container itself. This is due to the fact + // that the playback would immediately end + // when you replace the container. + + if (container.size() >= savestatecontainer.size()) { // Check if the current container is bigger than the + // savestated one. + + try { + container.setIndex(savestatecontainer.size()); // Set the "playback" index of the current + // container to the latest index of the + // savestatecontainer. Meaning this index will + // be played next + } catch (IndexOutOfBoundsException e) { + e.printStackTrace(); + } + } else { + String start = savestatecontainer.getStartLocation(); + savestatecontainer.setStartLocation(""); + + try { + savestatecontainer.setIndex(savestatecontainer.size() - 1); + } catch (IndexOutOfBoundsException e) { + e.printStackTrace(); + } + savestatecontainer.setTASState(TASstate.PLAYBACK); + savestatecontainer.setStartLocation(start); + container = savestatecontainer; + } - } else if (this.container.isRecording()) { - String start = savestatecontainer.getStartLocation(); // TODO Another start location thing to keep in mind + } else if (container.isRecording()) { + String start = savestatecontainer.getStartLocation(); preloadInput(savestatecontainer, savestatecontainer.size() - 1); // Preload the input of the savestate nextKeyboard = new VirtualKeyboard(); // Unpress the nextKeyboard and mouse to get rid of the preloaded inputs in the @@ -469,10 +497,15 @@ public void loadSavestate(InputContainer savestatecontainer) { // keyboard nextMouse = new VirtualMouse(); - savestatecontainer.setIndex(savestatecontainer.size()); + try { + savestatecontainer.setIndex(savestatecontainer.size()); + } catch(IndexOutOfBoundsException e) { + e.printStackTrace(); + } + savestatecontainer.setTASState(TASstate.RECORDING); - savestatecontainer.setStartLocation(start); // TODO Another one - this.container = savestatecontainer; // Replace the current container with the savestated container + savestatecontainer.setStartLocation(start); + container = savestatecontainer; // Replace the current container with the savestated container } } From 9cb5f670026db98b762298aad3c1fa592f8666b5 Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 7 May 2022 22:19:42 +0200 Subject: [PATCH 09/12] Changes to input loading in ClientSavestates - Loading a Client Savestate that doesn't exist prompted the container to clear all inputs. This is now removed. - If nothing is playing, inputs won't be overriden by the client savestates anmore, only when recording or playing back --- .../client/InputSavestatesHandler.java | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/main/java/de/scribble/lp/tasmod/savestates/client/InputSavestatesHandler.java b/src/main/java/de/scribble/lp/tasmod/savestates/client/InputSavestatesHandler.java index 14266b5b..44b3ea23 100644 --- a/src/main/java/de/scribble/lp/tasmod/savestates/client/InputSavestatesHandler.java +++ b/src/main/java/de/scribble/lp/tasmod/savestates/client/InputSavestatesHandler.java @@ -3,10 +3,16 @@ import java.io.File; import java.io.IOException; +import com.mojang.realmsclient.gui.ChatFormatting; + import de.scribble.lp.tasmod.ClientProxy; import de.scribble.lp.tasmod.CommonProxy; +import de.scribble.lp.tasmod.TASmod; import de.scribble.lp.tasmod.inputcontainer.InputContainer; import de.scribble.lp.tasmod.savestates.server.exceptions.SavestateException; +import de.scribble.lp.tasmod.util.TASstate; +import net.minecraft.client.Minecraft; +import net.minecraft.util.text.TextComponentString; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -43,9 +49,9 @@ public static void savestate(String nameOfSavestate) throws SavestateException, InputContainer container = ClientProxy.virtual.getContainer(); if (container.isRecording()) { - ClientProxy.serialiser.saveToFileV1(targetfile, container); + ClientProxy.serialiser.saveToFileV1(targetfile, container); //If the container is recording, store it entirely } else if(container.isPlayingback()){ - ClientProxy.serialiser.saveToFileV1Until(targetfile, container, container.index()); + ClientProxy.serialiser.saveToFileV1Until(targetfile, container, container.index()); //If the container is playing, store it until the current index } } @@ -68,10 +74,16 @@ public static void loadstate(String nameOfSavestate) throws IOException { File targetfile = new File(savestateDirectory, nameOfSavestate + ".tas"); - if (!targetfile.exists()) { - ClientProxy.virtual.getContainer().clear(); - } else { - ClientProxy.virtual.loadSavestate(ClientProxy.serialiser.fromEntireFileV1(targetfile)); + InputContainer container = ClientProxy.virtual.getContainer(); + if (!container.isNothingPlaying()) { // If the file exists and the container is recording or playing, load the clientSavestate + if (targetfile.exists()) { + ClientProxy.virtual.loadClientSavestate(ClientProxy.serialiser.fromEntireFileV1(targetfile)); + } else { + ClientProxy.virtual.getContainer().setTASState(TASstate.NONE, false); + Minecraft.getMinecraft().player.sendMessage(new TextComponentString(ChatFormatting.YELLOW + + "Inputs could not be loaded for this savestate, since the file doesn't exist. Stopping!")); + TASmod.logger.warn("Inputs could not be loaded for this savestate, since the file doesn't exist."); + } } } } From b55b27da7efe25ef79ae51db62137e13efa1b19d Mon Sep 17 00:00:00 2001 From: Scribble Date: Sun, 8 May 2022 00:15:53 +0200 Subject: [PATCH 10/12] Working on #137 --- .../lp/tasmod/events/LoadWorldEvents.java | 6 ++++ .../lp/tasmod/mixin/MixinMinecraftServer.java | 20 +++++------ .../mixin/fixes/MixinNetworkManager.java | 35 +++++++++++++++++++ src/main/resources/mixins.tasmod.json | 1 + 4 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 src/main/java/de/scribble/lp/tasmod/mixin/fixes/MixinNetworkManager.java diff --git a/src/main/java/de/scribble/lp/tasmod/events/LoadWorldEvents.java b/src/main/java/de/scribble/lp/tasmod/events/LoadWorldEvents.java index b2df94e5..7fbbf820 100644 --- a/src/main/java/de/scribble/lp/tasmod/events/LoadWorldEvents.java +++ b/src/main/java/de/scribble/lp/tasmod/events/LoadWorldEvents.java @@ -8,6 +8,7 @@ public class LoadWorldEvents { public static boolean waszero = false; + private static boolean isLoading =false; /** * Delay after the loading screen is finished before firing "doneWithLoadingScreen" @@ -24,6 +25,7 @@ public static void startLaunchServer() { if (TickrateChangerClient.ticksPerSecond == 0 || TickrateChangerClient.advanceTick) { waszero = true; } + isLoading = true; } /** @@ -85,9 +87,13 @@ public static void doneWithLoadingScreen() { } else { waszero = false; } + isLoading=false; } loadingScreenDelay--; } } + public static boolean isLoading() { + return isLoading; + } } diff --git a/src/main/java/de/scribble/lp/tasmod/mixin/MixinMinecraftServer.java b/src/main/java/de/scribble/lp/tasmod/mixin/MixinMinecraftServer.java index 001aef9b..7bbe9b63 100644 --- a/src/main/java/de/scribble/lp/tasmod/mixin/MixinMinecraftServer.java +++ b/src/main/java/de/scribble/lp/tasmod/mixin/MixinMinecraftServer.java @@ -96,12 +96,21 @@ public void redirectThreadSleep(long msToTick) { if (TickrateChangerServer.ticksPerSecond == 0) { currentTime = System.currentTimeMillis(); faketick++; - if (faketick >= 20) { + if (faketick >= 50) { faketick = 0; networkSystem.networkTick(); if (((MinecraftServer) (Object) this).isDedicatedServer()) { runPendingCommands(); } + synchronized (this.futureTaskQueue) { + while (!this.futureTaskQueue.isEmpty()) { + try { + ((FutureTask) this.futureTaskQueue.poll()).run(); + } catch (Throwable var9) { + var9.printStackTrace(); + } + } + } } } if (TickrateChangerServer.interrupt) { @@ -109,15 +118,6 @@ public void redirectThreadSleep(long msToTick) { msToTick = 1L; TickrateChangerServer.interrupt = false; } - synchronized (this.futureTaskQueue) { - while (!this.futureTaskQueue.isEmpty()) { - try { - ((FutureTask) this.futureTaskQueue.poll()).run(); - } catch (Throwable var9) { - var9.printStackTrace(); - } - } - } try { Thread.sleep(1L); diff --git a/src/main/java/de/scribble/lp/tasmod/mixin/fixes/MixinNetworkManager.java b/src/main/java/de/scribble/lp/tasmod/mixin/fixes/MixinNetworkManager.java new file mode 100644 index 00000000..35b1e741 --- /dev/null +++ b/src/main/java/de/scribble/lp/tasmod/mixin/fixes/MixinNetworkManager.java @@ -0,0 +1,35 @@ +package de.scribble.lp.tasmod.mixin.fixes; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import de.scribble.lp.tasmod.events.LoadWorldEvents; +import de.scribble.lp.tasmod.tickratechanger.TickrateChangerServer; +import net.minecraft.network.INetHandler; +import net.minecraft.network.NetHandlerPlayServer; +import net.minecraft.network.NetworkManager; +import net.minecraft.util.ITickable; + +@Mixin(NetworkManager.class) +public class MixinNetworkManager { + @Shadow + private INetHandler packetListener; + + /** + * Fixes #137 + * + * @param manager + */ + @Redirect(method = "processReceivedPackets", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/ITickable;update()V")) + public void redirect_processReceivedPackets(ITickable manager) { + if (TickrateChangerServer.ticksPerSecond == 0) { + if (!(packetListener instanceof NetHandlerPlayServer) || LoadWorldEvents.isLoading()) { + manager.update(); + } + } else { + manager.update(); + } + } +} diff --git a/src/main/resources/mixins.tasmod.json b/src/main/resources/mixins.tasmod.json index 29cb7759..f4316f49 100644 --- a/src/main/resources/mixins.tasmod.json +++ b/src/main/resources/mixins.tasmod.json @@ -20,6 +20,7 @@ //Fixing forge and vanilla stuff "fixes.MixinDragonFightManager", + "fixes.MixinNetworkManager", //Accessors "accessors.AccessorEntity", From c757fd3f695d00c71adc3d62dcb7a6ec1c72bcb6 Mon Sep 17 00:00:00 2001 From: Scribble Date: Sun, 8 May 2022 16:46:29 +0200 Subject: [PATCH 11/12] Fixes #136 Fixing #58 again ._. --- .../mixin/accessors/AccessorWorldServer.java | 15 +++++ .../savestates/server/SavestateHandler.java | 10 +++- .../chunkloading/SavestatesChunkControl.java | 56 +++++++++++++++---- src/main/resources/mixins.tasmod.json | 4 +- 4 files changed, 72 insertions(+), 13 deletions(-) create mode 100644 src/main/java/de/scribble/lp/tasmod/mixin/accessors/AccessorWorldServer.java diff --git a/src/main/java/de/scribble/lp/tasmod/mixin/accessors/AccessorWorldServer.java b/src/main/java/de/scribble/lp/tasmod/mixin/accessors/AccessorWorldServer.java new file mode 100644 index 00000000..0976d5cc --- /dev/null +++ b/src/main/java/de/scribble/lp/tasmod/mixin/accessors/AccessorWorldServer.java @@ -0,0 +1,15 @@ +package de.scribble.lp.tasmod.mixin.accessors; + +import java.util.Set; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import net.minecraft.world.NextTickListEntry; +import net.minecraft.world.WorldServer; + +@Mixin(WorldServer.class) +public interface AccessorWorldServer { + @Accessor("pendingTickListEntriesHashSet") + public Set getTickListEntries(); +} diff --git a/src/main/java/de/scribble/lp/tasmod/savestates/server/SavestateHandler.java b/src/main/java/de/scribble/lp/tasmod/savestates/server/SavestateHandler.java index 1f1a505d..5e84930c 100644 --- a/src/main/java/de/scribble/lp/tasmod/savestates/server/SavestateHandler.java +++ b/src/main/java/de/scribble/lp/tasmod/savestates/server/SavestateHandler.java @@ -313,6 +313,14 @@ public void loadState(int savestateIndex, boolean tickrate0, boolean changeIndex // Send a notification that the savestate has been loaded server.getPlayerList().sendMessage(new TextComponentString(TextFormatting.GREEN + "Savestate " + indexToLoad + " loaded")); + // Add players to the chunk + server.getPlayerList().getPlayers().forEach(player->{ + SavestatesChunkControl.addPlayerToServerChunk(player); + }); + + // Updating redstone component timers to the new world time (#136) + SavestatesChunkControl.updateWorldServerTickListEntries(); + WorldServer[] worlds = DimensionManager.getWorlds(); for (WorldServer world : worlds) { @@ -548,6 +556,6 @@ public static void playerLoadSavestateEventServer() { @SideOnly(Side.CLIENT) public static void playerLoadSavestateEventClient() { - SavestatesChunkControl.addPlayerToChunk(Minecraft.getMinecraft().player); + SavestatesChunkControl.addPlayerToClientChunk(Minecraft.getMinecraft().player); } } \ No newline at end of file diff --git a/src/main/java/de/scribble/lp/tasmod/savestates/server/chunkloading/SavestatesChunkControl.java b/src/main/java/de/scribble/lp/tasmod/savestates/server/chunkloading/SavestatesChunkControl.java index 5394e87f..aea6e9ca 100644 --- a/src/main/java/de/scribble/lp/tasmod/savestates/server/chunkloading/SavestatesChunkControl.java +++ b/src/main/java/de/scribble/lp/tasmod/savestates/server/chunkloading/SavestatesChunkControl.java @@ -2,9 +2,11 @@ import java.util.List; +import de.scribble.lp.tasmod.TASmod; import de.scribble.lp.tasmod.duck.ChunkProviderDuck; import de.scribble.lp.tasmod.mixin.accessors.AccessorSaveHandler; import de.scribble.lp.tasmod.mixin.accessors.AccessorWorld; +import de.scribble.lp.tasmod.mixin.accessors.AccessorWorldServer; import de.scribble.lp.tasmod.mixin.savestates.MixinChunkProviderClient; import de.scribble.lp.tasmod.mixin.savestates.MixinChunkProviderServer; import net.minecraft.client.Minecraft; @@ -13,6 +15,7 @@ import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.server.MinecraftServer; import net.minecraft.util.math.MathHelper; +import net.minecraft.world.NextTickListEntry; import net.minecraft.world.WorldServer; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.gen.ChunkProviderServer; @@ -177,26 +180,59 @@ public static void keepPlayerInLoadedEntityList(net.minecraft.entity.player.Enti *
* Even after adding the player to the world, the chunks may not load the player correctly.
*
- * Without this, no model is shown in third person and the player is able to place blocks inside of him.
+ * Without this, no model is shown in third person
* This state is fixed, once the player moves into a different chunk, since the new chunk adds the player to it's list.
*
* * TLDR:
- * Adds the player to the chunk so he can't place any blocks inside himself
+ * Adds the player to the chunk so the player is shown in third person
*
* Side: Client */ @SideOnly(Side.CLIENT) - public static void addPlayerToChunk(net.minecraft.entity.player.EntityPlayer player) { + public static void addPlayerToClientChunk(net.minecraft.entity.player.EntityPlayer player) { int i = MathHelper.floor(player.posX / 16.0D); - int j = MathHelper.floor(player.posZ / 16.0D); - Chunk chunk=Minecraft.getMinecraft().world.getChunkFromChunkCoords(i, j); - for (int k = 0; k < chunk.getEntityLists().length; k++) { - if(chunk.getEntityLists()[k].contains(player)) { - return; - } + int j = MathHelper.floor(player.posZ / 16.0D); + Chunk chunk = Minecraft.getMinecraft().world.getChunkFromChunkCoords(i, j); + for (int k = 0; k < chunk.getEntityLists().length; k++) { + if (chunk.getEntityLists()[k].contains(player)) { + return; + } } - chunk.addEntity(player); + chunk.addEntity(player); } + /** + * Just like {@link #addPlayerToClientChunk(EntityPlayer)}, adds the player to the chunk on the server. + * This prevents the player from being able to place block inside of him + * + * Side: Server + */ + public static void addPlayerToServerChunk(net.minecraft.entity.player.EntityPlayerMP player) { + int i = MathHelper.floor(player.posX / 16.0D); + int j = MathHelper.floor(player.posZ / 16.0D); + WorldServer world = player.getServerWorld(); + Chunk chunk = world.getChunkFromChunkCoords(i, j); + for (int k = 0; k < chunk.getEntityLists().length; k++) { + if (chunk.getEntityLists()[k].contains(player)) { + return; + } + } + chunk.addEntity(player); + } + + /** + * Updates ticklist entries to the current world time, allowing them to not be stuck in a pressed state #136 + */ + public static void updateWorldServerTickListEntries() { + MinecraftServer server=TASmod.getServerInstance(); + for (WorldServer world : server.worlds) { + AccessorWorldServer acworld=(AccessorWorldServer) world; + + for (NextTickListEntry nextticklistentry : acworld.getTickListEntries()) + { + nextticklistentry.setScheduledTime(world.getTotalWorldTime()); + } + } + } } diff --git a/src/main/resources/mixins.tasmod.json b/src/main/resources/mixins.tasmod.json index f4316f49..d03109f0 100644 --- a/src/main/resources/mixins.tasmod.json +++ b/src/main/resources/mixins.tasmod.json @@ -26,8 +26,8 @@ "accessors.AccessorEntity", "accessors.AccessorMinecraftServer", "accessors.AccessorSaveHandler", - "accessors.AccessorWorld" - + "accessors.AccessorWorld", + "accessors.AccessorWorldServer" ], "client": [ From c1d747e66169acbae5bd1db698185e2f47e35610 Mon Sep 17 00:00:00 2001 From: Scribble Date: Sun, 8 May 2022 16:51:00 +0200 Subject: [PATCH 12/12] Bump version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 4c15c78a..126e7f01 100644 --- a/build.gradle +++ b/build.gradle @@ -19,7 +19,7 @@ apply plugin: 'org.spongepowered.mixin' //Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. -version = "Alpha8.1-WIP" +version = "Alpha8.1" group = "de.scribble.lp.tastools" // http://maven.apache.org/guides/mini/guide-naming-conventions.html archivesBaseName = "TASmod-1.12.2"