From 8fcb05072f4a6fe09d159d2601c555755a16b62a Mon Sep 17 00:00:00 2001 From: Scribble Date: Sun, 19 Oct 2025 19:03:52 +0200 Subject: [PATCH 1/2] [PlaybackController] Fix restartandplay not working - Update PlaybackControllerServer to work with packets and not only with commands - [Savestates] Seperate temporary savestates into it's own handler --- .../java/com/minecrafttas/tasmod/TASmod.java | 3 + .../tasmod/commands/CommandFullPlay.java | 37 +---- .../tasmod/commands/CommandFullRecord.java | 32 +--- .../tasmod/commands/CommandPlay.java | 9 +- .../tasmod/commands/CommandRecord.java | 8 +- .../commands/CommandRestartAndPlay.java | 31 +--- .../tasmod/events/EventPlaybackServer.java | 34 ++++ .../playback/PlaybackControllerClient.java | 11 +- .../playback/PlaybackControllerServer.java | 145 ++++++++++++++---- .../tasmod/registries/TASmodPackets.java | 2 +- .../savestates/SavestateHandlerServer.java | 15 +- .../handlers/SavestateTempHandler.java | 79 ++++++++++ 12 files changed, 259 insertions(+), 147 deletions(-) create mode 100644 src/main/java/com/minecrafttas/tasmod/events/EventPlaybackServer.java create mode 100644 src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateTempHandler.java diff --git a/src/main/java/com/minecrafttas/tasmod/TASmod.java b/src/main/java/com/minecrafttas/tasmod/TASmod.java index 06cb1ed1..a82566f4 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmod.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmod.java @@ -157,6 +157,7 @@ public void onServerInit(MinecraftServer server) { savestateHandlerServer = new SavestateHandlerServer(server, LOGGER); PacketHandlerRegistry.register(savestateHandlerServer); PacketHandlerRegistry.register(savestateHandlerServer.getPlayerHandler()); + EventListenerRegistry.register(savestateHandlerServer.getSavestateTemporaryHandler()); if (!server.isDedicatedServer()) { TASmod.tickratechanger.ticksPerSecond = 0F; @@ -187,6 +188,8 @@ public void onServerStop(MinecraftServer mcserver) { if (savestateHandlerServer != null) { PacketHandlerRegistry.unregister(savestateHandlerServer); // Unregistering the savestatehandler, as a new instance is registered in onServerStart() PacketHandlerRegistry.unregister(savestateHandlerServer.getPlayerHandler()); + PacketHandlerRegistry.unregister(savestateHandlerServer); + EventListenerRegistry.unregister(savestateHandlerServer.getSavestateTemporaryHandler()); savestateHandlerServer = null; } diff --git a/src/main/java/com/minecrafttas/tasmod/commands/CommandFullPlay.java b/src/main/java/com/minecrafttas/tasmod/commands/CommandFullPlay.java index b6068335..e45a3352 100644 --- a/src/main/java/com/minecrafttas/tasmod/commands/CommandFullPlay.java +++ b/src/main/java/com/minecrafttas/tasmod/commands/CommandFullPlay.java @@ -1,19 +1,11 @@ package com.minecrafttas.tasmod.commands; import com.minecrafttas.tasmod.TASmod; -import com.minecrafttas.tasmod.networking.TASmodBufferBuilder; -import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate; -import com.minecrafttas.tasmod.registries.TASmodPackets; -import com.minecrafttas.tasmod.savestates.SavestateHandlerServer.SavestateCallback; -import com.minecrafttas.tasmod.savestates.SavestateHandlerServer.SavestateFlags; -import com.minecrafttas.tasmod.savestates.exceptions.LoadstateException; import net.minecraft.command.CommandBase; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; import net.minecraft.server.MinecraftServer; -import net.minecraft.util.text.TextComponentString; -import net.minecraft.util.text.TextFormatting; public class CommandFullPlay extends CommandBase { @@ -29,33 +21,6 @@ public String getUsage(ICommandSender sender) { @Override public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { - - SavestateCallback cb = (paths) -> { - try { - TASmod.server.sendToAll(new TASmodBufferBuilder(TASmodPackets.SAVESTATE_CLEAR_SCREEN)); - } catch (Exception e) { - TASmod.LOGGER.catching(e); - } - }; - - try { - TASmod.savestateHandlerServer.loadState(0, cb, SavestateFlags.BLOCK_CHANGE_INDEX, SavestateFlags.BLOCK_PAUSE_TICKRATE); - } catch (LoadstateException e) { - sender.sendMessage(new TextComponentString(TextFormatting.RED + "Failed to load a savestate: " + e.getMessage())); - return; - } catch (Exception e) { - sender.sendMessage(new TextComponentString(TextFormatting.RED + "Failed to load a savestate: " + e.getCause().toString())); - e.printStackTrace(); - return; - } finally { - TASmod.savestateHandlerServer.resetState(); - } - TASmod.playbackControllerServer.setServerState(TASstate.PLAYBACK); - try { - TASmod.server.sendToAll(new TASmodBufferBuilder(TASmodPackets.PLAYBACK_FULLPLAY)); - } catch (Exception e) { - e.printStackTrace(); - } + TASmod.playbackControllerServer.fullPlay(); } - } diff --git a/src/main/java/com/minecrafttas/tasmod/commands/CommandFullRecord.java b/src/main/java/com/minecrafttas/tasmod/commands/CommandFullRecord.java index 797a2a18..b50d8053 100644 --- a/src/main/java/com/minecrafttas/tasmod/commands/CommandFullRecord.java +++ b/src/main/java/com/minecrafttas/tasmod/commands/CommandFullRecord.java @@ -1,19 +1,11 @@ package com.minecrafttas.tasmod.commands; import com.minecrafttas.tasmod.TASmod; -import com.minecrafttas.tasmod.networking.TASmodBufferBuilder; -import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate; -import com.minecrafttas.tasmod.registries.TASmodPackets; -import com.minecrafttas.tasmod.savestates.SavestateHandlerServer.SavestateCallback; -import com.minecrafttas.tasmod.savestates.SavestateHandlerServer.SavestateFlags; -import com.minecrafttas.tasmod.savestates.exceptions.SavestateException; import net.minecraft.command.CommandBase; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; import net.minecraft.server.MinecraftServer; -import net.minecraft.util.text.TextComponentString; -import net.minecraft.util.text.TextFormatting; public class CommandFullRecord extends CommandBase { @@ -29,28 +21,6 @@ public String getUsage(ICommandSender sender) { @Override public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { - - SavestateCallback cb = (paths) -> { - try { - TASmod.server.sendToAll(new TASmodBufferBuilder(TASmodPackets.SAVESTATE_CLEAR_SCREEN)); - } catch (Exception e) { - TASmod.LOGGER.catching(e); - } - }; - - try { - TASmod.savestateHandlerServer.saveState(0, cb, SavestateFlags.BLOCK_PAUSE_TICKRATE); - } catch (SavestateException e) { - sender.sendMessage(new TextComponentString(TextFormatting.RED + "Failed to create a savestate: " + e.getMessage())); - return; - } finally { - TASmod.savestateHandlerServer.resetState(); - } - TASmod.playbackControllerServer.setServerState(TASstate.RECORDING); - try { - TASmod.server.sendToAll(new TASmodBufferBuilder(TASmodPackets.PLAYBACK_FULLRECORD)); - } catch (Exception e) { - e.printStackTrace(); - } + TASmod.playbackControllerServer.fullRecord(); } } diff --git a/src/main/java/com/minecrafttas/tasmod/commands/CommandPlay.java b/src/main/java/com/minecrafttas/tasmod/commands/CommandPlay.java index 7a236c2f..9b84a8f9 100644 --- a/src/main/java/com/minecrafttas/tasmod/commands/CommandPlay.java +++ b/src/main/java/com/minecrafttas/tasmod/commands/CommandPlay.java @@ -42,11 +42,10 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args return; } if (args.length <= 1) { - boolean loadTempSavestate = true; - if (args.length == 1 && "nosave".equals(args[0])) { - loadTempSavestate = false; - } - TASmod.playbackControllerServer.togglePlayback(loadTempSavestate); + boolean noSave = args.length == 1 && "nosave".equals(args[0]); + TASmod.savestateHandlerServer.getSavestateTemporaryHandler().setNoSave(noSave); + + TASmod.playbackControllerServer.togglePlayback(); } else if (args.length > 2) { sender.sendMessage(new TextComponentString(TextFormatting.RED + "Too many arguments. " + getUsage(sender))); } diff --git a/src/main/java/com/minecrafttas/tasmod/commands/CommandRecord.java b/src/main/java/com/minecrafttas/tasmod/commands/CommandRecord.java index 09f2cf89..e7d40fb8 100644 --- a/src/main/java/com/minecrafttas/tasmod/commands/CommandRecord.java +++ b/src/main/java/com/minecrafttas/tasmod/commands/CommandRecord.java @@ -42,11 +42,9 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args return; } if (args.length <= 1) { - boolean saveTempSavestate = true; - if (args.length == 1 && "nosave".equals(args[0])) { - saveTempSavestate = false; - } - TASmod.playbackControllerServer.toggleRecording(saveTempSavestate); + boolean noSave = args.length == 1 && "nosave".equals(args[0]); + TASmod.savestateHandlerServer.getSavestateTemporaryHandler().setNoSave(noSave); + TASmod.playbackControllerServer.toggleRecording(); } else if (args.length > 1) { sender.sendMessage(new TextComponentString(TextFormatting.RED + "Too many arguments. " + getUsage(sender))); } diff --git a/src/main/java/com/minecrafttas/tasmod/commands/CommandRestartAndPlay.java b/src/main/java/com/minecrafttas/tasmod/commands/CommandRestartAndPlay.java index 97bc4a28..accfd551 100644 --- a/src/main/java/com/minecrafttas/tasmod/commands/CommandRestartAndPlay.java +++ b/src/main/java/com/minecrafttas/tasmod/commands/CommandRestartAndPlay.java @@ -6,11 +6,6 @@ import java.util.List; import com.minecrafttas.tasmod.TASmod; -import com.minecrafttas.tasmod.networking.TASmodBufferBuilder; -import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate; -import com.minecrafttas.tasmod.registries.TASmodPackets; -import com.minecrafttas.tasmod.savestates.SavestateHandlerServer.SavestateFlags; -import com.minecrafttas.tasmod.savestates.exceptions.LoadstateException; import net.minecraft.client.Minecraft; import net.minecraft.command.CommandBase; @@ -39,31 +34,7 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args if (args.length < 1) { sender.sendMessage(new TextComponentString(TextFormatting.RED + "Please add a filename, " + getUsage(sender))); } else { - String name = ""; - String spacer = " "; - for (int i = 0; i < args.length; i++) { - if (i == args.length - 1) { - spacer = ""; - } - name = name.concat(args[i] + spacer); - } - try { - TASmod.savestateHandlerServer.loadState(0, null, SavestateFlags.BLOCK_PAUSE_TICKRATE); - } catch (LoadstateException e) { - TASmod.LOGGER.catching(e); - if (e.getMessage() != null) { - sender.sendMessage(new TextComponentString(TextFormatting.RED + "Could not load the initial savestate: " + e.getMessage())); - } - TASmod.savestateHandlerServer.resetState(); - TASmod.tickratechanger.pauseGame(false); - return; - } - TASmod.playbackControllerServer.setServerState(TASstate.PLAYBACK); - try { - TASmod.server.sendToAll(new TASmodBufferBuilder(TASmodPackets.PLAYBACK_RESTARTANDPLAY).writeString(args[0])); - } catch (Exception e) { - e.printStackTrace(); - } + TASmod.playbackControllerServer.restartAndPlay(String.join(" ", args)); } } else { sender.sendMessage(new TextComponentString(TextFormatting.RED + "You have no permission to use this command")); diff --git a/src/main/java/com/minecrafttas/tasmod/events/EventPlaybackServer.java b/src/main/java/com/minecrafttas/tasmod/events/EventPlaybackServer.java new file mode 100644 index 00000000..66b97c4b --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/events/EventPlaybackServer.java @@ -0,0 +1,34 @@ +package com.minecrafttas.tasmod.events; + +import com.minecrafttas.mctcommon.events.EventListenerRegistry.EventBase; +import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate; +import com.minecrafttas.tasmod.playback.PlaybackControllerServer; + +public interface EventPlaybackServer { + + /** + * Fired when {@link PlaybackControllerServer#setTASStateServer(TASstate)} is called + * + * @author Scribble + */ + public interface EventControllerStateChange extends EventBase { + /** + * Fired when {@link PlaybackControllerServer#setTASStateServer(TASstate)} is called + * @param newstate The new state that the playback controller is about to be set + * @param oldstate The current state that is about to be replaced by newstate + */ + public void onControllerStateChange(TASstate newstate, TASstate oldstate); + } + + /** + * Fired when a recording is cleared + */ + @FunctionalInterface + public interface EventRecordClear extends EventBase { + + /** + * Fired when a recording is cleared + */ + public void onRecordingClear(); + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index 56860605..7155e805 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -9,6 +9,7 @@ import static com.minecrafttas.tasmod.registries.TASmodPackets.PLAYBACK_SAVE; import static com.minecrafttas.tasmod.registries.TASmodPackets.PLAYBACK_STATE; +import java.io.IOException; import java.io.Serializable; import java.nio.ByteBuffer; import java.nio.file.Path; @@ -1014,7 +1015,7 @@ public void onClientPacket(PacketID id, ByteBuffer buf, String username) throws break; case PLAYBACK_RESTARTANDPLAY: - final String finalname = ByteBufferBuilder.readString(buf); + String finalname = ByteBufferBuilder.readString(buf); try { Thread.sleep(100L); @@ -1077,5 +1078,13 @@ public void onClientInit(Minecraft mc) { } else { TASmodClient.config.reset(TASmodConfig.FileToOpen); } + + try { + TASmodClient.controller.setInputs(PlaybackSerialiser.loadFromFile(tasFileDirectory.resolve(fileOnStart + fileEnding))); + } catch (PlaybackLoadException | IOException e) { + logger.catching(e); + } + + setTASState(TASstate.PLAYBACK); } } diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerServer.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerServer.java index 98cb0245..283d4991 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerServer.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerServer.java @@ -1,6 +1,10 @@ package com.minecrafttas.tasmod.playback; import static com.minecrafttas.tasmod.TASmod.LOGGER; +import static com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate.NONE; +import static com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate.PAUSED; +import static com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate.PLAYBACK; +import static com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate.RECORDING; import static com.minecrafttas.tasmod.registries.TASmodPackets.PLAYBACK_CLEAR_INPUTS; import static com.minecrafttas.tasmod.registries.TASmodPackets.PLAYBACK_FULLPLAY; import static com.minecrafttas.tasmod.registries.TASmodPackets.PLAYBACK_FULLRECORD; @@ -8,19 +12,26 @@ import static com.minecrafttas.tasmod.registries.TASmodPackets.PLAYBACK_RESTARTANDPLAY; import static com.minecrafttas.tasmod.registries.TASmodPackets.PLAYBACK_SAVE; import static com.minecrafttas.tasmod.registries.TASmodPackets.PLAYBACK_STATE; +import static com.minecrafttas.tasmod.registries.TASmodPackets.SAVESTATE_CLEAR_SCREEN; import static com.minecrafttas.tasmod.util.LoggerMarkers.Playback; import java.nio.ByteBuffer; +import com.minecrafttas.mctcommon.events.EventListenerRegistry; import com.minecrafttas.mctcommon.networking.Client.Side; import com.minecrafttas.mctcommon.networking.exception.PacketNotImplementedException; import com.minecrafttas.mctcommon.networking.exception.WrongSideException; import com.minecrafttas.mctcommon.networking.interfaces.PacketID; import com.minecrafttas.mctcommon.networking.interfaces.ServerPacketHandler; import com.minecrafttas.tasmod.TASmod; +import com.minecrafttas.tasmod.events.EventPlaybackServer; import com.minecrafttas.tasmod.networking.TASmodBufferBuilder; import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate; import com.minecrafttas.tasmod.registries.TASmodPackets; +import com.minecrafttas.tasmod.savestates.SavestateHandlerServer.SavestateCallback; +import com.minecrafttas.tasmod.savestates.SavestateHandlerServer.SavestateFlags; +import com.minecrafttas.tasmod.savestates.exceptions.LoadstateException; +import com.minecrafttas.tasmod.savestates.exceptions.SavestateException; /** * The playback controller on the server side.
@@ -33,8 +44,6 @@ public class PlaybackControllerServer implements ServerPacketHandler { private TASstate state; - private boolean createState = true; - @Override public PacketID[] getAcceptedPacketIDs() { //@formatter:off @@ -60,15 +69,22 @@ public void onServerPacket(PacketID id, ByteBuffer buf, String username) throws case PLAYBACK_STATE: TASstate networkState = TASmodBufferBuilder.readEnum(TASstate.class, buf); /* TODO Permissions */ - setState(networkState); + setTASState(networkState); break; case PLAYBACK_CLEAR_INPUTS: clearInputs(); break; - case PLAYBACK_FULLPLAY: case PLAYBACK_FULLRECORD: + fullRecord(); + break; + case PLAYBACK_FULLPLAY: + fullPlay(); + break; case PLAYBACK_RESTARTANDPLAY: + String tasFileName = TASmodBufferBuilder.readString(buf); + restartAndPlay(tasFileName); + break; case PLAYBACK_SAVE: case PLAYBACK_LOAD: TASmod.server.sendToAll(new TASmodBufferBuilder(buf)); @@ -79,56 +95,39 @@ public void onServerPacket(PacketID id, ByteBuffer buf, String username) throws } } - public void setState(TASstate stateIn) { - setServerState(stateIn); + public void setTASState(TASstate stateIn) { + setTASStateServer(stateIn); try { - TASmod.server.sendToAll(new TASmodBufferBuilder(TASmodPackets.PLAYBACK_STATE).writeEnum(state).writeBoolean(true)); + TASmod.server.sendToAll(new TASmodBufferBuilder(PLAYBACK_STATE).writeEnum(state).writeBoolean(true)); } catch (Exception e) { e.printStackTrace(); } } - public void setServerState(TASstate stateIn) { + public void setTASStateServer(TASstate stateIn) { if (state != stateIn) { - if (state == TASstate.RECORDING && stateIn == TASstate.PLAYBACK) + if (state == RECORDING && stateIn == PLAYBACK) return; - if (state == TASstate.NONE && state == TASstate.PAUSED) { + if (state == NONE && state == PAUSED) { return; } + EventListenerRegistry.fireEvent(EventPlaybackServer.EventControllerStateChange.class, stateIn, this.state); + this.state = stateIn; LOGGER.info(Playback, "Set the server state to {}", stateIn.toString()); } } - public void toggleRecording(boolean saveSavestate) { - if (state == TASstate.NONE && createState && saveSavestate) { - createState = false; - TASmod.savestateHandlerServer.saveStateTemp((paths) -> { - try { - TASmod.server.sendToAll(new TASmodBufferBuilder(TASmodPackets.SAVESTATE_CLEAR_SCREEN)); - } catch (Exception e) { - TASmod.LOGGER.catching(e); - } - }); - } - setState(state == TASstate.RECORDING ? TASstate.NONE : TASstate.RECORDING); + public void toggleRecording() { + setTASState(state == RECORDING ? NONE : RECORDING); } - public void togglePlayback(boolean loadSavestate) { - if (state == TASstate.NONE && loadSavestate) { - TASmod.savestateHandlerServer.loadStateTemp((paths) -> { - try { - TASmod.server.sendToAll(new TASmodBufferBuilder(TASmodPackets.SAVESTATE_CLEAR_SCREEN)); - } catch (Exception e) { - TASmod.LOGGER.catching(e); - } - }); - } - setState(state == TASstate.PLAYBACK ? TASstate.NONE : TASstate.PLAYBACK); + public void togglePlayback() { + setTASState(state == PLAYBACK ? NONE : PLAYBACK); } public void clearInputs() { - createState = true; + EventListenerRegistry.fireEvent(EventPlaybackServer.EventRecordClear.class); try { TASmod.server.sendToAll(new TASmodBufferBuilder(PLAYBACK_CLEAR_INPUTS)); } catch (Exception e) { @@ -140,4 +139,82 @@ public TASstate getState() { return state; } + public void fullRecord() { + SavestateCallback cb = (paths) -> { + try { + TASmod.server.sendToAll(new TASmodBufferBuilder(SAVESTATE_CLEAR_SCREEN)); + } catch (Exception e) { + LOGGER.catching(e); + } + }; + + TASmod.tickSchedulerServer.add(() -> { + try { + TASmod.savestateHandlerServer.saveState(0, cb, SavestateFlags.BLOCK_PAUSE_TICKRATE); + } catch (SavestateException e) { + LOGGER.catching(e); + return; + } finally { + TASmod.savestateHandlerServer.resetState(); + } + + setTASStateServer(TASstate.RECORDING); + + try { + TASmod.server.sendToAll(new TASmodBufferBuilder(PLAYBACK_FULLRECORD)); + } catch (Exception e) { + LOGGER.catching(e); + } + }); + } + + public void fullPlay() { + SavestateCallback cb = (paths) -> { + try { + TASmod.server.sendToAll(new TASmodBufferBuilder(TASmodPackets.SAVESTATE_CLEAR_SCREEN)); + } catch (Exception e) { + LOGGER.catching(e); + } + }; + + TASmod.tickSchedulerServer.add(() -> { + try { + TASmod.savestateHandlerServer.loadState(0, cb, SavestateFlags.BLOCK_CHANGE_INDEX, SavestateFlags.BLOCK_PAUSE_TICKRATE); + } catch (LoadstateException e) { + LOGGER.catching(e); + return; + } finally { + TASmod.savestateHandlerServer.resetState(); + } + + setTASStateServer(TASstate.PLAYBACK); + + try { + TASmod.server.sendToAll(new TASmodBufferBuilder(PLAYBACK_FULLPLAY)); + } catch (Exception e) { + LOGGER.catching(e); + } + }); + } + + public void restartAndPlay(String tasFileName) { + TASmod.savestateHandlerServer.getSavestateTemporaryHandler().setNoSave(true); + TASmod.playbackControllerServer.setTASStateServer(PLAYBACK); + + TASmod.tickSchedulerServer.add(() -> { + try { + TASmod.savestateHandlerServer.loadState(0, null, SavestateFlags.BLOCK_PAUSE_TICKRATE); + } catch (LoadstateException e) { + LOGGER.catching(e); + TASmod.savestateHandlerServer.resetState(); + TASmod.tickratechanger.pauseGame(false); + return; + } + try { + TASmod.server.sendToAll(new TASmodBufferBuilder(PLAYBACK_RESTARTANDPLAY).writeString(tasFileName)); + } catch (Exception e) { + LOGGER.catching(e); + } + }); + } } diff --git a/src/main/java/com/minecrafttas/tasmod/registries/TASmodPackets.java b/src/main/java/com/minecrafttas/tasmod/registries/TASmodPackets.java index 67ad42f1..fd282b38 100644 --- a/src/main/java/com/minecrafttas/tasmod/registries/TASmodPackets.java +++ b/src/main/java/com/minecrafttas/tasmod/registries/TASmodPackets.java @@ -180,7 +180,7 @@ public enum TASmodPackets implements PacketID { *

Notifies the client to quit the game. Upon restarting the game, the specified tasfile will be loaded and played back in {@link PlaybackControllerClient} *

SIDE: Both
* ARGS:
- * Client->Server None
+ * Client->Server String filename The TASfile name to load on restart
* Server->Client String filename The TASfile name to load on restart */ PLAYBACK_RESTARTANDPLAY, diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java b/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java index a3a20e87..c8c6f5a6 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java @@ -35,6 +35,7 @@ import com.minecrafttas.tasmod.savestates.exceptions.SavestateException; import com.minecrafttas.tasmod.savestates.handlers.SavestatePlayerHandlerServer; import com.minecrafttas.tasmod.savestates.handlers.SavestateResourcePackHandler; +import com.minecrafttas.tasmod.savestates.handlers.SavestateTempHandler; import com.minecrafttas.tasmod.savestates.handlers.SavestateWorldHandler; import com.minecrafttas.tasmod.util.Component; import com.minecrafttas.tasmod.util.LoggerMarkers; @@ -72,6 +73,7 @@ public class SavestateHandlerServer implements ServerPacketHandler { private final SavestatePlayerHandlerServer playerHandler; private final SavestateWorldHandler worldHandler; + private final SavestateTempHandler tempSavestateHandler; private final Logger logger; @@ -87,6 +89,7 @@ public SavestateHandlerServer(MinecraftServer server, Logger logger) { this.playerHandler = new SavestatePlayerHandlerServer(server); this.worldHandler = new SavestateWorldHandler(server); + this.tempSavestateHandler = new SavestateTempHandler(this, logger); createIndexer(server); } @@ -408,10 +411,6 @@ public void deleteSavestate(int from, int to, SavestateCallback cb, ErrorRunnabl indexer.deleteMultipleSavestates(from, to, onDelete, err); } - public SavestatePlayerHandlerServer getPlayerHandler() { - return playerHandler; - } - public int getCurrentIndex() { return indexer.getCurrentSavestate().index; } @@ -667,4 +666,12 @@ public void rename(int index, String name, SavestateCallback cb) throws Savestat public void reload() { indexer.reload(); } + + public SavestatePlayerHandlerServer getPlayerHandler() { + return playerHandler; + } + + public SavestateTempHandler getSavestateTemporaryHandler() { + return tempSavestateHandler; + } } diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateTempHandler.java b/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateTempHandler.java new file mode 100644 index 00000000..77bea8e4 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateTempHandler.java @@ -0,0 +1,79 @@ +package com.minecrafttas.tasmod.savestates.handlers; + +import static com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate.NONE; +import static com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate.PLAYBACK; +import static com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate.RECORDING; +import static com.minecrafttas.tasmod.registries.TASmodPackets.SAVESTATE_CLEAR_SCREEN; + +import org.apache.logging.log4j.Logger; + +import com.minecrafttas.tasmod.TASmod; +import com.minecrafttas.tasmod.events.EventPlaybackClient.EventRecordClear; +import com.minecrafttas.tasmod.events.EventPlaybackServer.EventControllerStateChange; +import com.minecrafttas.tasmod.networking.TASmodBufferBuilder; +import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate; +import com.minecrafttas.tasmod.savestates.SavestateHandlerServer; + +/** + *

Handles the creation of temporary savestates when recording/playing back a TAS + *

Is exclusively run on the server side + * + * @author Scribble + */ +public class SavestateTempHandler implements EventControllerStateChange, EventRecordClear { + + private final Logger logger; + private final SavestateHandlerServer handler; + + private boolean createState = true; + private boolean noSave = false; + + public SavestateTempHandler(SavestateHandlerServer handler, Logger logger) { + this.logger = logger; + this.handler = handler; + } + + @Override + public void onControllerStateChange(TASstate newstate, TASstate oldstate) { + + if (oldstate != NONE) { + return; + } + + if (noSave) { + noSave = false; + return; + } + + if (newstate == RECORDING && createState) { + logger.info("Creating temporary savestate"); + createState = false; + handler.saveStateTemp((paths) -> { + try { + TASmod.server.sendToAll(new TASmodBufferBuilder(SAVESTATE_CLEAR_SCREEN)); + } catch (Exception e) { + logger.catching(e); + } + }); + } else if (newstate == PLAYBACK) { + logger.info("Loading temporary savestate"); + createState = false; + handler.loadStateTemp((paths) -> { + try { + TASmod.server.sendToAll(new TASmodBufferBuilder(SAVESTATE_CLEAR_SCREEN)); + } catch (Exception e) { + logger.catching(e); + } + }); + } + } + + @Override + public void onRecordingClear() { + createState = true; + } + + public void setNoSave(boolean noSave) { + this.noSave = noSave; + } +} From d5ac9ccfdda558d4bd9d2efe5898f86196d93af3 Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 20 Oct 2025 08:27:21 +0200 Subject: [PATCH 2/2] Fix typo and inconsistent documentation --- .../minecrafttas/tasmod/events/EventPlaybackServer.java | 7 +++---- .../tasmod/playback/PlaybackControllerClient.java | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/events/EventPlaybackServer.java b/src/main/java/com/minecrafttas/tasmod/events/EventPlaybackServer.java index 66b97c4b..c179905d 100644 --- a/src/main/java/com/minecrafttas/tasmod/events/EventPlaybackServer.java +++ b/src/main/java/com/minecrafttas/tasmod/events/EventPlaybackServer.java @@ -8,9 +8,8 @@ public interface EventPlaybackServer { /** * Fired when {@link PlaybackControllerServer#setTASStateServer(TASstate)} is called - * - * @author Scribble */ + @FunctionalInterface public interface EventControllerStateChange extends EventBase { /** * Fired when {@link PlaybackControllerServer#setTASStateServer(TASstate)} is called @@ -21,13 +20,13 @@ public interface EventControllerStateChange extends EventBase { } /** - * Fired when a recording is cleared + * Fired when a recording is cleared in {@link PlaybackControllerServer#clearInputs()} */ @FunctionalInterface public interface EventRecordClear extends EventBase { /** - * Fired when a recording is cleared + * Fired when a recording is cleared in {@link PlaybackControllerServer#clearInputs()} */ public void onRecordingClear(); } diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index 7155e805..c4c1943f 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -1015,7 +1015,7 @@ public void onClientPacket(PacketID id, ByteBuffer buf, String username) throws break; case PLAYBACK_RESTARTANDPLAY: - String finalname = ByteBufferBuilder.readString(buf); + String tasFilename = ByteBufferBuilder.readString(buf); try { Thread.sleep(100L); @@ -1023,7 +1023,7 @@ public void onClientPacket(PacketID id, ByteBuffer buf, String username) throws e.printStackTrace(); } Minecraft.getMinecraft().addScheduledTask(() -> { - TASmodClient.config.set(TASmodConfig.FileToOpen, finalname); + TASmodClient.config.set(TASmodConfig.FileToOpen, tasFilename); System.exit(0); }); break;