diff --git a/src/main/java/com/minecrafttas/tasmod/TASmod.java b/src/main/java/com/minecrafttas/tasmod/TASmod.java index 69fb8eb3..6cb78d10 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmod.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmod.java @@ -29,6 +29,7 @@ import com.minecrafttas.tasmod.playback.metadata.builtin.StartpositionMetadataExtension; import com.minecrafttas.tasmod.registries.TASmodPackets; import com.minecrafttas.tasmod.savestates.SavestateHandlerServer; +import com.minecrafttas.tasmod.savestates.handlers.SavestateResourcePackHandler; import com.minecrafttas.tasmod.savestates.storage.builtin.SavestateMotionStorage; import com.minecrafttas.tasmod.tickratechanger.TickrateChangerServer; import com.minecrafttas.tasmod.ticksync.TickSyncServer; @@ -119,6 +120,9 @@ public void onInitialize() { SavestateMotionStorage motionStorage = new SavestateMotionStorage(); PacketHandlerRegistry.register(motionStorage); EventListenerRegistry.register(motionStorage); + SavestateResourcePackHandler resourcepackHandler = new SavestateResourcePackHandler(); + PacketHandlerRegistry.register(resourcepackHandler); + EventListenerRegistry.register(resourcepackHandler); PacketHandlerRegistry.register(playUntil); EventListenerRegistry.register(playUntil); } diff --git a/src/main/java/com/minecrafttas/tasmod/commands/CommandSavestate.java b/src/main/java/com/minecrafttas/tasmod/commands/CommandSavestate.java index 7abd7317..63d66b46 100644 --- a/src/main/java/com/minecrafttas/tasmod/commands/CommandSavestate.java +++ b/src/main/java/com/minecrafttas/tasmod/commands/CommandSavestate.java @@ -42,17 +42,41 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args } else if (args.length >= 1) { if ("save".equals(args[0])) { if (args.length == 1) { - saveLatest(); + TASmod.gameLoopSchedulerServer.add(() -> { + try { + saveLatest(); + } catch (CommandException e) { + e.printStackTrace(); + } + }); } else if (args.length == 2) { - saveWithIndex(args); + TASmod.gameLoopSchedulerServer.add(() -> { + try { + saveWithIndex(args); + } catch (CommandException e) { + e.printStackTrace(); + } + }); } else { throw new CommandException("Too many arguments!", new Object[] {}); } } else if ("load".equals(args[0])) { if (args.length == 1) { - loadLatest(); + TASmod.gameLoopSchedulerServer.add(() -> { + try { + loadLatest(); + } catch (CommandException e) { + e.printStackTrace(); + } + }); } else if (args.length == 2) { - loadLatest(args); + TASmod.gameLoopSchedulerServer.add(() -> { + try { + loadLatest(args); + } catch (CommandException e) { + e.printStackTrace(); + } + }); } else { throw new CommandException("Too many arguments!", new Object[] {}); } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/savestates/MixinMinecraft.java b/src/main/java/com/minecrafttas/tasmod/mixin/savestates/MixinMinecraft.java new file mode 100644 index 00000000..2662e459 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/mixin/savestates/MixinMinecraft.java @@ -0,0 +1,21 @@ +package com.minecrafttas.tasmod.mixin.savestates; + +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.CallbackInfo; + +import com.minecrafttas.tasmod.savestates.handlers.SavestateResourcePackHandler; + +import net.minecraft.client.Minecraft; + +@Mixin(Minecraft.class) +public class MixinMinecraft { + + @Inject(method = "refreshResources", at = @At(value = "RETURN")) + public void inject_refreshResources(CallbackInfo ci) { + if (SavestateResourcePackHandler.clientRPLatch != null && SavestateResourcePackHandler.clientRPLatch.getCount() > 0) { + SavestateResourcePackHandler.clientRPLatch.countDown(); + } + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/registries/TASmodPackets.java b/src/main/java/com/minecrafttas/tasmod/registries/TASmodPackets.java index 7c8b2094..42f4e093 100644 --- a/src/main/java/com/minecrafttas/tasmod/registries/TASmodPackets.java +++ b/src/main/java/com/minecrafttas/tasmod/registries/TASmodPackets.java @@ -104,6 +104,12 @@ public enum TASmodPackets implements PacketID { Minecraft mc = Minecraft.getMinecraft(); ((ScoreboardDuck) mc.world.getScoreboard()).clearScoreboard(); }), + /** + *
Clears the resourcepack on the client side + *
SIDE: Client
+ * ARGS: none
+ */
+ SAVESTATE_CLEAR_RESOURCEPACK,
/**
*
Notifies the client to clear all inputs from the input buffer in {@link PlaybackControllerClient} *
SIDE: Both
diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java b/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java
index 387078c5..05f91369 100644
--- a/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java
+++ b/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java
@@ -40,6 +40,7 @@
import com.minecrafttas.tasmod.savestates.files.SavestateDataFile.DataValues;
import com.minecrafttas.tasmod.savestates.files.SavestateTrackerFile;
import com.minecrafttas.tasmod.savestates.handlers.SavestatePlayerHandler;
+import com.minecrafttas.tasmod.savestates.handlers.SavestateResourcePackHandler;
import com.minecrafttas.tasmod.savestates.handlers.SavestateWorldHandler;
import com.minecrafttas.tasmod.util.LoggerMarkers;
import com.minecrafttas.tasmod.util.Scheduler.Task;
@@ -386,6 +387,9 @@ public void loadState(int savestateIndex, boolean tickrate0, boolean changeIndex
// Reenable level saving
worldHandler.enableLevelSaving();
+ // Refresh server resourcepacks on the client
+ SavestateResourcePackHandler.refreshServerResourcepack(server);
+
// Incrementing info file
SavestateTrackerFile tracker = new SavestateTrackerFile(savestateDirectory.resolve(worldname + "-info.txt"));
tracker.increaseLoadstateCount();
@@ -753,9 +757,9 @@ private int legacyIndexFile(Path savestateDat) {
public PacketID[] getAcceptedPacketIDs() {
return new TASmodPackets[] {
//@formatter:off
- TASmodPackets.SAVESTATE_SAVE,
- TASmodPackets.SAVESTATE_LOAD,
- TASmodPackets.SAVESTATE_SCREEN,
+ TASmodPackets.SAVESTATE_SAVE,
+ TASmodPackets.SAVESTATE_LOAD,
+ TASmodPackets.SAVESTATE_SCREEN,
TASmodPackets.SAVESTATE_UNLOAD_CHUNKS
//@formatter:on
};
@@ -770,7 +774,7 @@ public void onServerPacket(PacketID id, ByteBuffer buf, String username) throws
switch (packet) {
case SAVESTATE_SAVE:
- Integer index = TASmodBufferBuilder.readInt(buf);
+ int index = TASmodBufferBuilder.readInt(buf);
Task savestateTask = () -> {
try {
diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/gui/GuiResourcepackWarn.java b/src/main/java/com/minecrafttas/tasmod/savestates/gui/GuiResourcepackWarn.java
new file mode 100644
index 00000000..bcf3f560
--- /dev/null
+++ b/src/main/java/com/minecrafttas/tasmod/savestates/gui/GuiResourcepackWarn.java
@@ -0,0 +1,43 @@
+package com.minecrafttas.tasmod.savestates.gui;
+
+import com.minecrafttas.tasmod.util.MessageUtils;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.GuiScreen;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.client.resources.I18n;
+
+/**
+ * Screen for warning the player that a "reources.zip" is present in the world folder,
+ * which significantly slows down savestates
+ */
+public class GuiResourcepackWarn extends GuiScreen {
+
+ /**
+ * Screen for warning the player that a "reources.zip" is present in the world folder,
+ * which significantly slows down savestates
+ */
+ public GuiResourcepackWarn() {
+ this.mc = Minecraft.getMinecraft();
+ }
+
+ @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();
+
+ MessageUtils.splitNewline(I18n.format("gui.tasmod.savestate.resourcepack"), 15, (line, y) -> {
+ drawCenteredString(fontRenderer, line, width / 2, height / 4 + 40 + y, 0xFF5555);
+ });
+
+ super.drawScreen(mouseX, mouseY, partialTicks);
+ }
+
+ @Override
+ public boolean doesGuiPauseGame() {
+ return false;
+ }
+}
diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateResourcePackHandler.java b/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateResourcePackHandler.java
new file mode 100644
index 00000000..520280b5
--- /dev/null
+++ b/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateResourcePackHandler.java
@@ -0,0 +1,162 @@
+package com.minecrafttas.tasmod.savestates.handlers;
+
+import java.nio.ByteBuffer;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+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.ClientPacketHandler;
+import com.minecrafttas.mctcommon.networking.interfaces.PacketID;
+import com.minecrafttas.mctcommon.networking.interfaces.ServerPacketHandler;
+import com.minecrafttas.tasmod.TASmod;
+import com.minecrafttas.tasmod.TASmodClient;
+import com.minecrafttas.tasmod.events.EventSavestate;
+import com.minecrafttas.tasmod.networking.TASmodBufferBuilder;
+import com.minecrafttas.tasmod.registries.TASmodPackets;
+import com.minecrafttas.tasmod.savestates.exceptions.SavestateException;
+import com.minecrafttas.tasmod.savestates.gui.GuiResourcepackWarn;
+import com.minecrafttas.tasmod.util.LoggerMarkers;
+
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.client.Minecraft;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.server.MinecraftServer;
+
+/**
+ * Handles reloading server resourcepacks when loadstating.
+ *
+ * @author Scribble
+ */
+public class SavestateResourcePackHandler implements EventSavestate.EventServerLoadstate, ServerPacketHandler, ClientPacketHandler {
+
+ /**
+ * The server future for waiting until the client is done unloading the RP
+ */
+ private CompletableFuture