From c0a7d0c0f116c70c56c5717e4bf1e3ef15ee1907 Mon Sep 17 00:00:00 2001 From: Scribble Date: Fri, 24 Apr 2026 10:27:05 +0200 Subject: [PATCH 01/16] [Savestates] Fix config option PauseOnTempSavestate being reversed --- .../tasmod/savestates/SavestateHandlerServer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java b/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java index c7c9963e..45e055e3 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java @@ -207,7 +207,7 @@ public void saveStateTemp(SavestateCallback cb) { SavestateFlags[] flags = new SavestateFlags[] { SavestateFlags.BLOCK_CLIENT_SAVESTATE }; if (!TASmod.config.getBoolean(TASmodServerConfig.PauseOnTempSavestate)) { - if (ArrayUtils.contains(flags, SavestateFlags.BLOCK_PAUSE_TICKRATE)) + if (!ArrayUtils.contains(flags, SavestateFlags.BLOCK_PAUSE_TICKRATE)) flags = ArrayUtils.add(flags, SavestateFlags.BLOCK_PAUSE_TICKRATE); } @@ -368,7 +368,7 @@ public void loadStateTemp(SavestateCallback cb) { SavestateFlags[] flags = new SavestateFlags[] { SavestateFlags.BLOCK_CLIENT_SAVESTATE }; if (!TASmod.config.getBoolean(TASmodServerConfig.PauseOnTempSavestate)) { - if (ArrayUtils.contains(flags, SavestateFlags.BLOCK_PAUSE_TICKRATE)) + if (!ArrayUtils.contains(flags, SavestateFlags.BLOCK_PAUSE_TICKRATE)) flags = ArrayUtils.add(flags, SavestateFlags.BLOCK_PAUSE_TICKRATE); } From 739ddc7aacace17949c0a2d28f36af957a1b92f1 Mon Sep 17 00:00:00 2001 From: Scribble Date: Fri, 24 Apr 2026 10:33:05 +0200 Subject: [PATCH 02/16] [Savestates] Fix motion being reset on temp savestates --- .../savestates/MixinNetHandlerPlayClient.java | 30 +++++++++++++++++++ .../tasmod/registries/TASmodKeybinds.java | 10 +++---- .../savestates/SavestateHandlerServer.java | 2 +- src/main/resources/tasmod.mixin.json | 1 + 4 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/minecrafttas/tasmod/mixin/savestates/MixinNetHandlerPlayClient.java diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/savestates/MixinNetHandlerPlayClient.java b/src/main/java/com/minecrafttas/tasmod/mixin/savestates/MixinNetHandlerPlayClient.java new file mode 100644 index 00000000..95aac539 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/mixin/savestates/MixinNetHandlerPlayClient.java @@ -0,0 +1,30 @@ +package com.minecrafttas.tasmod.mixin.savestates; + +import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; + +import net.minecraft.client.network.NetHandlerPlayClient; +import net.minecraft.entity.player.EntityPlayer; + +@Mixin(NetHandlerPlayClient.class) +public class MixinNetHandlerPlayClient { + + @WrapOperation(method = "handlePlayerPosLook", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/player/EntityPlayer;motionX:D", opcode = Opcodes.PUTFIELD)) + public void redirect_handlePlayerPosLook1(EntityPlayer player, double motionX, Operation original) { + original.call(player, player.motionX); + } + + @WrapOperation(method = "handlePlayerPosLook", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/player/EntityPlayer;motionY:D", opcode = Opcodes.PUTFIELD)) + public void redirect_handlePlayerPosLook2(EntityPlayer player, double motionY, Operation original) { + original.call(player, player.motionY); + } + + @WrapOperation(method = "handlePlayerPosLook", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/player/EntityPlayer;motionZ:D", opcode = Opcodes.PUTFIELD)) + public void redirect_handlePlayerPosLook3(EntityPlayer player, double motionY, Operation original) { + original.call(player, player.motionZ); + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/registries/TASmodKeybinds.java b/src/main/java/com/minecrafttas/tasmod/registries/TASmodKeybinds.java index de7f8d06..d0a5c4a4 100644 --- a/src/main/java/com/minecrafttas/tasmod/registries/TASmodKeybinds.java +++ b/src/main/java/com/minecrafttas/tasmod/registries/TASmodKeybinds.java @@ -46,11 +46,11 @@ public enum TASmodKeybinds implements KeybindID { TASmodClient.virtual.CAMERA_ANGLE.updateNextCameraAngle(0, 45); }), TEST1("Various Testing", "TASmod", Keyboard.KEY_F12, () -> { - // try { - // TASmodClient.client.send(new TASmodBufferBuilder(PLAYBACK_STATE_TEMP_SAVESTATE).writeEnum(TASstate.RECORDING)); - // } catch (Exception e) { - // e.printStackTrace(); - // } + try { + TASmodClient.client.send(new TASmodBufferBuilder(TASmodPackets.PLAYBACK_STATE_TEMP_SAVESTATE).writeEnum(TASstate.RECORDING)); + } catch (Exception e) { + e.printStackTrace(); + } }, VirtualKeybindings::isKeyDown), TEST2("Various Testing2", "TASmod", Keyboard.KEY_F7, () -> { }, VirtualKeybindings::isKeyDown); diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java b/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java index 45e055e3..76468406 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java @@ -721,7 +721,7 @@ public void onServerPacket(PacketID id, ByteBuffer buf, String username) throws } }; TASmod.gameLoopSchedulerServer.add(loadstateTask); - + break; default: throw new PacketNotImplementedException(packet, this.getClass(), Side.SERVER); } diff --git a/src/main/resources/tasmod.mixin.json b/src/main/resources/tasmod.mixin.json index 1c5e6b97..419755f7 100644 --- a/src/main/resources/tasmod.mixin.json +++ b/src/main/resources/tasmod.mixin.json @@ -38,6 +38,7 @@ // Savestates "savestates.MixinChunkProviderClient", + "savestates.MixinNetHandlerPlayClient", "savestates.MixinWorldClient", "savestates.MixinMinecraft", From 3c7da2b943a13d773cfeb6ab93ae26688b2289ed Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 27 Apr 2026 22:05:42 +0200 Subject: [PATCH 03/16] [KillTheRNG] Add seed display to more entities --- .../tasmod/mixin/killtherng/MixinRender.java | 59 +++++++++++++++++++ src/main/resources/tasmod.mixin.json | 1 + 2 files changed, 60 insertions(+) create mode 100644 src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRender.java diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRender.java b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRender.java new file mode 100644 index 00000000..99b93a74 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRender.java @@ -0,0 +1,59 @@ +package com.minecrafttas.tasmod.mixin.killtherng; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +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.TASmod; +import com.minecrafttas.tasmod.ktrng.RandomBase; + +import net.minecraft.client.renderer.EntityRenderer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.entity.Entity; + +@Mixin(Render.class) +public abstract class MixinRender { + + @Unique + private long previousSeed = 0; + @Shadow + private RenderManager renderManager; + + @Inject(method = "renderName", at = @At(value = "HEAD")) + public void inject_renderName(Entity entity, double d, double e, double f, CallbackInfo ci) { + if (System.getProperty("tasmod.killtherng.entitytrace", "false").equals("true")) { + Entity serverEntity = TASmod.getServerInstance().getEntityFromUuid(entity.getUniqueID()); + if (serverEntity == null) + return; + RandomBase random = (RandomBase) serverEntity.rand; + long seed = random.getSeed(); + long distance = -random.distance(random.getInitialSeed()); + GlStateManager.alphaFunc(516, 0.1F); + this.renderEntityName2(entity, d, e + 0.69D, f, Long.toString(random.getInitialSeed()), 64); + this.renderEntityName2(entity, d, e + 0.46D, f, Long.toString(seed), 64); + this.renderEntityName2(entity, d, e + 0.23D, f, Long.toString(distance), 64); + } + } + + protected void renderEntityName2(Entity entityIn, double x, double y, double z, String name, double distanceSq) { + this.renderLivingLabel2(entityIn, name, x, y, z, 64); + } + + protected void renderLivingLabel2(Entity entityIn, String str, double x, double y, double z, int maxDistance) { + double d = entityIn.getDistanceSq(this.renderManager.renderViewEntity); + if (!(d > maxDistance * maxDistance)) { + boolean bl = entityIn.isSneaking(); + float f = this.renderManager.playerViewY; + float g = this.renderManager.playerViewX; + boolean bl2 = this.renderManager.options.thirdPersonView == 2; + float h = entityIn.height + 0.5F - (bl ? 0.25F : 0.0F); + int i = "deadmau5".equals(str) ? -10 : 0; + EntityRenderer.drawNameplate(this.renderManager.getFontRenderer(), str, (float) x, (float) y + h, (float) z, i, f, g, bl2, bl); + } + } +} diff --git a/src/main/resources/tasmod.mixin.json b/src/main/resources/tasmod.mixin.json index 419755f7..ebe7a53f 100644 --- a/src/main/resources/tasmod.mixin.json +++ b/src/main/resources/tasmod.mixin.json @@ -79,6 +79,7 @@ "fixes.MixinMouseHelper", // KTRNG + "killtherng.MixinRender", "killtherng.MixinRenderLivingBase", // Tickrate Rendering From 7e72395e6ac4669c6d1c19378c066c26d7c59c5f Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 27 Apr 2026 22:05:42 +0200 Subject: [PATCH 04/16] [KillTheRNG] Fix globalTimer not setting the seed properly --- .../tasmod/ktrng/GlobalRandomnessTimer.java | 9 ++++- .../ktrng/GlobalRandomnessTimerClient.java | 2 +- .../minecrafttas/tasmod/ktrng/RandomBase.java | 3 +- .../killtherng/GlobalRandomnessTimerTest.java | 35 ++++++++++++++++++ .../tasmod/killtherng/RandomBaseTest.java | 37 +++++++------------ 5 files changed, 59 insertions(+), 27 deletions(-) create mode 100644 src/test/java/tasmod/killtherng/GlobalRandomnessTimerTest.java diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java b/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java index 50165528..2ec84705 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java @@ -12,7 +12,7 @@ public class GlobalRandomnessTimer implements EventServer.EventServerTick { private long currentSeed = 0L; public GlobalRandomnessTimer() { - globalRandomness = new JRand(0L); + globalRandomness = new JRand(0L, false); } @Override @@ -26,7 +26,12 @@ public long getCurrentSeed() { } public void setSeed(long newSeed) { - globalRandomness.setSeed(newSeed); + globalRandomness.setSeed(newSeed, false); currentSeed = newSeed; } + + @Override + public String toString() { + return Long.toString(globalRandomness.getSeed()); + } } diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimerClient.java b/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimerClient.java index 85bb41d8..a39f26b8 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimerClient.java @@ -32,7 +32,7 @@ public JRand getUUIDRandom() { } public void setSeed(long newSeed) { - globalRandomness.setSeed(newSeed); + globalRandomness.setSeed(newSeed, false); currentSeed = newSeed; } diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java b/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java index dcccf2ee..a3259aa7 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java @@ -18,7 +18,8 @@ public abstract class RandomBase extends Random implements Registerable { public RandomBase() { super(TASmod.globalRandomness.getCurrentSeed()); - jrand = new JRand(TASmod.globalRandomness.getCurrentSeed()); + initialSeed = TASmod.globalRandomness.getCurrentSeed(); + jrand = new JRand(initialSeed); } public RandomBase(long seed) { diff --git a/src/test/java/tasmod/killtherng/GlobalRandomnessTimerTest.java b/src/test/java/tasmod/killtherng/GlobalRandomnessTimerTest.java new file mode 100644 index 00000000..272e65ad --- /dev/null +++ b/src/test/java/tasmod/killtherng/GlobalRandomnessTimerTest.java @@ -0,0 +1,35 @@ +package tasmod.killtherng; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import com.minecrafttas.tasmod.ktrng.GlobalRandomnessTimer; + +class GlobalRandomnessTimerTest { + + @BeforeEach + void setUp() throws Exception { + } + + @Test + void testSetSeed() { + GlobalRandomnessTimer timer = new GlobalRandomnessTimer(); + timer.onServerTick(null); + timer.onServerTick(null); + timer.onServerTick(null); + long start = timer.getCurrentSeed(); + timer.onServerTick(null); + timer.onServerTick(null); + timer.onServerTick(null); + long expected = timer.getCurrentSeed(); + timer.setSeed(start); + timer.onServerTick(null); + timer.onServerTick(null); + timer.onServerTick(null); + long actual = timer.getCurrentSeed(); + assertEquals(expected, actual); + } + +} diff --git a/src/test/java/tasmod/killtherng/RandomBaseTest.java b/src/test/java/tasmod/killtherng/RandomBaseTest.java index 1845241f..92b9ba76 100644 --- a/src/test/java/tasmod/killtherng/RandomBaseTest.java +++ b/src/test/java/tasmod/killtherng/RandomBaseTest.java @@ -2,35 +2,13 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import com.minecrafttas.tasmod.ktrng.RandomBase; import kaptainwutax.seedutils.rand.JRand; -class TestRNGTest { - - class TestRNG extends RandomBase { - - public TestRNG() { - super(); - } - - public TestRNG(long seed) { - super(seed); - } - - @Override - public String getExtensionName() { - return "TestRNG"; - } - - } - - @BeforeEach - void setUp() throws Exception { - } +class RandomBaseTest { @Test void testInitialSeed() { @@ -91,4 +69,17 @@ void testAdvancingDifferentRNGs() { assertEquals(testRandom1.getSeed(), testRandom2.getSeed()); } + + private class TestRNG extends RandomBase { + + public TestRNG(long seed) { + super(seed); + } + + @Override + public String getExtensionName() { + return "TestRNG"; + } + + } } From e73a4db1684584509bd1eea3ead3d1b302d0628f Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 27 Apr 2026 22:05:42 +0200 Subject: [PATCH 05/16] [KillTheRNG] Replace Math.random() with instanced randoms --- .../tasmod/ktrng/builtin/MathRandomness.java | 2 +- .../killtherng/mathrand/MixinEntityItem.java | 11 ++++------- .../mathrand/MixinEntityLivingBase.java | 17 +++++++---------- .../mathrand/MixinEntityTNTPrimed.java | 3 +-- .../killtherng/mathrand/MixinEntityXPOrb.java | 11 ++++------- 5 files changed, 17 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/MathRandomness.java b/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/MathRandomness.java index c2d5a878..59371e35 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/MathRandomness.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/MathRandomness.java @@ -19,7 +19,7 @@ public MathRandomness(long seed) { @Override public void fireRNGEvent(String eventType, long seed, String value, int stackTraceOffset) { -// super.fireEvent(eventType, seed, value, 6); + super.fireRNGEvent(eventType, seed, value, 6); } @Override diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityItem.java b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityItem.java index a94c9bf5..d8acd0dd 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityItem.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityItem.java @@ -3,18 +3,15 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import com.minecrafttas.tasmod.TASmod; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import net.minecraft.entity.item.EntityItem; -import net.minecraft.world.World; @Mixin(EntityItem.class) public class MixinEntityItem { - @WrapOperation(method = "", at = @At(value = "INVOKE", target = "Ljava/lang/Math;random()D")) - private double wrap_entityItemInit(Operation original, World world, double d, double e, double f) { - return TASmod.mathRandomness.nextDouble(); + @ModifyExpressionValue(method = "", at = @At(value = "INVOKE", target = "Ljava/lang/Math;random()D")) + private double wrap_entityItemInit(double original) { + return ((EntityItem) (Object) this).rand.nextDouble(); } } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityLivingBase.java b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityLivingBase.java index 2d882de9..d26fbc3e 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityLivingBase.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityLivingBase.java @@ -3,23 +3,20 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import com.minecrafttas.tasmod.TASmod; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.world.World; @Mixin(EntityLivingBase.class) public class MixinEntityLivingBase { - @WrapOperation(method = "", at = @At(value = "INVOKE", target = "Ljava/lang/Math;random()D")) - private double wrap_entityLivingBase(Operation original, World world) { - return TASmod.mathRandomness.nextDouble(); + @ModifyExpressionValue(method = "", at = @At(value = "INVOKE", target = "Ljava/lang/Math;random()D")) + private double wrap_entityLivingBase(double original) { + return ((EntityLivingBase) (Object) this).rand.nextDouble(); } - @WrapOperation(method = "attackEntityFrom", at = @At(value = "INVOKE", target = "Ljava/lang/Math;random()D")) - private double wrap_attackEntityFrom(Operation original) { - return TASmod.mathRandomness.nextDouble(); + @ModifyExpressionValue(method = "attackEntityFrom", at = @At(value = "INVOKE", target = "Ljava/lang/Math;random()D")) + private double wrap_attackEntityFrom(double original) { + return ((EntityLivingBase) (Object) this).rand.nextDouble(); } } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityTNTPrimed.java b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityTNTPrimed.java index add0e4e1..51f1d959 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityTNTPrimed.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityTNTPrimed.java @@ -5,7 +5,6 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import com.minecrafttas.tasmod.TASmod; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.item.EntityTNTPrimed; @@ -16,6 +15,6 @@ public class MixinEntityTNTPrimed { @WrapOperation(method = "(Lnet/minecraft/world/World;DDDLnet/minecraft/entity/EntityLivingBase;)V", at = @At(value = "INVOKE", target = "Ljava/lang/Math;random()D")) private double wrap_entityTNTPrimedInit(Operation original, World world, double d, double e, double f, EntityLivingBase entityLivingBase) { - return TASmod.mathRandomness.nextDouble(); + return ((EntityTNTPrimed) (Object) this).rand.nextDouble(); } } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityXPOrb.java b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityXPOrb.java index ed776195..3a604e44 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityXPOrb.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityXPOrb.java @@ -3,18 +3,15 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import com.minecrafttas.tasmod.TASmod; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import net.minecraft.entity.item.EntityXPOrb; -import net.minecraft.world.World; @Mixin(EntityXPOrb.class) public class MixinEntityXPOrb { - @WrapOperation(method = "", at = @At(value = "INVOKE", target = "Ljava/lang/Math;random()D")) - private double wrap_entityXPOrb(Operation original, World world, double d, double e, double f, int i) { - return TASmod.mathRandomness.nextDouble(); + @ModifyExpressionValue(method = "", at = @At(value = "INVOKE", target = "Ljava/lang/Math;random()D")) + private double wrap_entityXPOrb(double original) { + return ((EntityXPOrb) (Object) this).rand.nextDouble(); } } From 466cc7dc1afda5c94b58719cfa903f19ab90d9eb Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 28 Apr 2026 17:14:56 +0200 Subject: [PATCH 06/16] [Core] Add FutureTaskQueue Duck --- .../tasmod/mixin/MixinMinecraftServer.java | 25 +++++++++++-------- .../com/minecrafttas/tasmod/util/Ducks.java | 4 +++ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraftServer.java b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraftServer.java index acdca43a..6d22224c 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraftServer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraftServer.java @@ -15,6 +15,7 @@ import com.minecrafttas.tasmod.TASmod; import com.minecrafttas.tasmod.events.EventServer.EventServerTickPost; import com.minecrafttas.tasmod.savestates.SavestateHandlerServer.SavestateState; +import com.minecrafttas.tasmod.util.Ducks.MinecraftServerDuck; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -22,7 +23,7 @@ import net.minecraft.server.MinecraftServer; @Mixin(MinecraftServer.class) -public abstract class MixinMinecraftServer { +public abstract class MixinMinecraftServer implements MinecraftServerDuck { // ===================================================================================================================================== @@ -115,15 +116,7 @@ public void redirectThreadSleep(long msToTick) { boolean stopTaskQueue = TASmod.savestateHandlerServer != null && TASmod.savestateHandlerServer.getState() == SavestateState.LOADING; if (!stopTaskQueue) { - synchronized (this.futureTaskQueue) { - while (!this.futureTaskQueue.isEmpty()) { - try { - ((FutureTask) this.futureTaskQueue.poll()).run(); - } catch (Throwable var9) { - var9.printStackTrace(); - } - } - } + runFutureTaskQueue(); } } @@ -137,4 +130,16 @@ private void runPendingCommands() { // ===================================================================================================================================== + @Override + public void runFutureTaskQueue() { + synchronized (this.futureTaskQueue) { + while (!this.futureTaskQueue.isEmpty()) { + try { + ((FutureTask) this.futureTaskQueue.poll()).run(); + } catch (Throwable var9) { + var9.printStackTrace(); + } + } + } + } } diff --git a/src/main/java/com/minecrafttas/tasmod/util/Ducks.java b/src/main/java/com/minecrafttas/tasmod/util/Ducks.java index 66ef276a..1ac6c3cf 100644 --- a/src/main/java/com/minecrafttas/tasmod/util/Ducks.java +++ b/src/main/java/com/minecrafttas/tasmod/util/Ducks.java @@ -147,4 +147,8 @@ public static interface SoundManagerDuck { public void updatePitch(); } + + public static interface MinecraftServerDuck { + public void runFutureTaskQueue(); + } } From d3b1b68b8cd22eb91dc08728f5e28a82c1c40db0 Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 28 Apr 2026 17:14:56 +0200 Subject: [PATCH 07/16] [Gui] Add blockHitDelay to infohud --- src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java | 6 +++--- src/main/resources/tasmod.accesswidener | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java b/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java index fdef4e00..8d3a1eca 100644 --- a/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java +++ b/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java @@ -329,14 +329,14 @@ public boolean checkInit() { })); y += 14; - title = "ktrng_mathseed"; + title = "ktrng_blockHitDelay"; 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 "MathRNG"; - return "MathRNG: " + TASmod.mathRandomness.getSeed(); + return "BlockHitDelay"; + return "BlockHitDelay: " + Minecraft.getMinecraft().playerController.blockHitDelay; })); title = "facing"; diff --git a/src/main/resources/tasmod.accesswidener b/src/main/resources/tasmod.accesswidener index 18c6cd63..ce57b485 100644 --- a/src/main/resources/tasmod.accesswidener +++ b/src/main/resources/tasmod.accesswidener @@ -4,6 +4,7 @@ accessWidener v1 named accessible field net/minecraft/client/Minecraft timer Lnet/minecraft/util/Timer; accessible method net/minecraft/client/Minecraft runTickKeyboard ()V accessible method net/minecraft/client/Minecraft runTickMouse ()V +accessible field net/minecraft/client/multiplayer/PlayerControllerMP blockHitDelay I # Tickratechanger accessible field net/minecraft/util/Timer tickLength F From 515e566905836cfa42d75941bfce30f4e3d028d7 Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 28 Apr 2026 17:14:56 +0200 Subject: [PATCH 08/16] [Playback] Fix playback being one tick delayed --- .../minecrafttas/tasmod/playback/PlaybackControllerClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java index 0f4a0196..b28b0416 100644 --- a/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/playback/PlaybackControllerClient.java @@ -1063,7 +1063,7 @@ public void onClientPacket(PacketID id, ByteBuffer buf, String username) throws }; - if ((networkState == TASstate.RECORDING || networkState == TASstate.PLAYBACK) && TASmodClient.tickratechanger.ticksPerSecond != 0) { + if (networkState == TASstate.RECORDING && TASmodClient.tickratechanger.ticksPerSecond != 0) { TASmodClient.tickSchedulerClient.add(task); // Starts a recording in the next tick } else { TASmodClient.gameLoopSchedulerClient.add(task); // Starts a recording in the next frame From 8e4cf64178eea028b45d584db34b3ba8375b738f Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 28 Apr 2026 19:03:31 +0200 Subject: [PATCH 09/16] [KillTheRNG] Add mathrng back to MixinWorldEntitySpawner --- .../mixin/killtherng/mathrand/MixinWorldEntitySpawner.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinWorldEntitySpawner.java b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinWorldEntitySpawner.java index 3d9223da..e4c718ca 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinWorldEntitySpawner.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinWorldEntitySpawner.java @@ -5,6 +5,7 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.minecrafttas.tasmod.TASmod; import net.minecraft.world.WorldEntitySpawner; import net.minecraft.world.WorldServer; @@ -14,6 +15,6 @@ public class MixinWorldEntitySpawner { @WrapOperation(method = "findChunksForSpawning", at = @At(value = "INVOKE", target = "Ljava/lang/Math;random()D")) private double wrap_worldEntitySpawnerFindChunks(Operation original, WorldServer worldServer, boolean bl, boolean bl2, boolean bl3) { - return worldServer.rand.nextDouble(); + return TASmod.mathRandomness.nextDouble(); } } From 06363c5c7eb217b5060db4b61cf9155e7b9d79be Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 28 Apr 2026 19:18:35 +0200 Subject: [PATCH 10/16] [Savestates] Remove loadstates disabeling temp savestates --- .../savestates/handlers/SavestateTempHandler.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateTempHandler.java b/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateTempHandler.java index cf211bc4..ff5ce7fd 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateTempHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateTempHandler.java @@ -11,16 +11,13 @@ import com.minecrafttas.tasmod.TASmod; import com.minecrafttas.tasmod.events.EventPlaybackClient.EventRecordClear; import com.minecrafttas.tasmod.events.EventPlaybackServer.EventControllerStateChange; -import com.minecrafttas.tasmod.events.EventSavestate; 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; -import com.minecrafttas.tasmod.savestates.SavestateIndexer.SavestatePaths; import com.minecrafttas.tasmod.savestates.exceptions.SavestateException; import com.minecrafttas.tasmod.util.Component; -import net.minecraft.server.MinecraftServer; import net.minecraft.util.text.TextFormatting; /** @@ -29,7 +26,7 @@ * * @author Scribble */ -public class SavestateTempHandler implements EventControllerStateChange, EventRecordClear, EventSavestate.EventServerLoadstatePre { +public class SavestateTempHandler implements EventControllerStateChange, EventRecordClear { private final Logger logger; private final SavestateHandlerServer handler; @@ -155,9 +152,4 @@ public void onRecordingClear() { public void setActive(boolean active) { this.active = active; } - - @Override - public void onServerLoadstatePre(MinecraftServer server, SavestatePaths paths) { - createState = false; - } } From 7f1af0565b9fc1f2905da80cf6dac198ad1dffdf Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 9 May 2026 11:28:32 +0200 Subject: [PATCH 11/16] [KillTheRNG] Add updateLCG to monitoring --- .../mixin/killtherng/MixinWorldServer.java | 23 +++++++++++++++++++ src/main/resources/tasmod.mixin.json | 1 + 2 files changed, 24 insertions(+) create mode 100644 src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinWorldServer.java diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinWorldServer.java b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinWorldServer.java new file mode 100644 index 00000000..c9b8f19c --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinWorldServer.java @@ -0,0 +1,23 @@ +package com.minecrafttas.tasmod.mixin.killtherng; + +import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.minecrafttas.mctcommon.events.EventListenerRegistry; +import com.minecrafttas.tasmod.events.EventKillTheRNGServer; +import com.minecrafttas.tasmod.ktrng.RandomBase.RNGSide; + +import net.minecraft.world.WorldServer; + +@Mixin(WorldServer.class) +public class MixinWorldServer { + + @WrapOperation(method = "updateBlocks", at = @At(value = "FIELD", target = "Lnet/minecraft/world/WorldServer;updateLCG:I", opcode = Opcodes.PUTFIELD)) + private void modify_updateLCG(WorldServer world, int original, Operation operation) { + EventListenerRegistry.fireEvent(EventKillTheRNGServer.EventRNG.class, RNGSide.Server, "updateLCG", (long) world.updateLCG, Integer.toString(original), "UpdateLCG"); + operation.call(world, original); + } +} diff --git a/src/main/resources/tasmod.mixin.json b/src/main/resources/tasmod.mixin.json index ebe7a53f..c0c4c900 100644 --- a/src/main/resources/tasmod.mixin.json +++ b/src/main/resources/tasmod.mixin.json @@ -25,6 +25,7 @@ "killtherng.MixinEntity", "killtherng.MixinWorld", + "killtherng.MixinWorldServer", "killtherng.mathrand.MixinEntityLivingBase", "killtherng.mathrand.MixinEntityItem", "killtherng.mathrand.MixinEntityXPOrb", From d371213b0f2c759f9dc20201c279c909dd38865f Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 9 May 2026 12:25:04 +0200 Subject: [PATCH 12/16] [KillTheRNG] Add stacktrace offset to rng monitor --- .../tasmod/events/EventKillTheRNGServer.java | 2 +- .../com/minecrafttas/tasmod/ktrng/RandomBase.java | 4 ++-- .../tasmod/ktrng/builtin/MathRandomness.java | 5 ----- .../tasmod/ktrng/builtin/WorldRandomness.java | 2 +- .../tasmod/ktrng/events/KillTheRNGMonitor.java | 4 ++-- .../tasmod/mixin/killtherng/MixinWorldServer.java | 12 +++++++++++- .../com/minecrafttas/tasmod/util/FileThread.java | 2 +- 7 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/events/EventKillTheRNGServer.java b/src/main/java/com/minecrafttas/tasmod/events/EventKillTheRNGServer.java index b463e8b0..2689c5aa 100644 --- a/src/main/java/com/minecrafttas/tasmod/events/EventKillTheRNGServer.java +++ b/src/main/java/com/minecrafttas/tasmod/events/EventKillTheRNGServer.java @@ -7,6 +7,6 @@ public interface EventKillTheRNGServer { @FunctionalInterface public interface EventRNG extends EventBase { - public void onRNGCall(RNGSide side, String eventType, long seed, String value, String rngClass); + public void onRNGCall(RNGSide side, String eventType, long seed, String value, String rngClass, int offset); } } diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java b/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java index a3259aa7..01b0355e 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java @@ -151,7 +151,7 @@ public void fireSetEvent(String eventType, long seed, String value, int stackTra } public void fireGetEvent(String eventType, long seed, String value) { - fireRNGEvent(eventType, seed, value, 3); + fireRNGEvent(eventType, seed, value, 10); } public long getInitialSeed() { @@ -159,7 +159,7 @@ public long getInitialSeed() { } public void fireRNGEvent(String eventType, long seed, String value, int stackTraceOffset) { - EventListenerRegistry.fireEvent(EventKillTheRNGServer.EventRNG.class, side, eventType, seed, value, this.getClass().getSimpleName()); + EventListenerRegistry.fireEvent(EventKillTheRNGServer.EventRNG.class, side, eventType, seed, value, this.getClass().getSimpleName(), stackTraceOffset); } public enum RNGSide { diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/MathRandomness.java b/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/MathRandomness.java index 59371e35..057f06ab 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/MathRandomness.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/MathRandomness.java @@ -17,11 +17,6 @@ public MathRandomness(long seed) { super(seed); } - @Override - public void fireRNGEvent(String eventType, long seed, String value, int stackTraceOffset) { - super.fireRNGEvent(eventType, seed, value, 6); - } - @Override public String getExtensionName() { return "MathRNG"; diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/WorldRandomness.java b/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/WorldRandomness.java index db66efa8..2d00d1ea 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/WorldRandomness.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/WorldRandomness.java @@ -14,7 +14,7 @@ public WorldRandomness(long seed) { @Override public void fireRNGEvent(String val, long seed, String value, int offset) { - super.fireRNGEvent(val, seed, value, 5); + super.fireRNGEvent(val, seed, value, 9); } @Override diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/events/KillTheRNGMonitor.java b/src/main/java/com/minecrafttas/tasmod/ktrng/events/KillTheRNGMonitor.java index 7fce36be..9c08217c 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/events/KillTheRNGMonitor.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/events/KillTheRNGMonitor.java @@ -85,7 +85,7 @@ public void onRecordingClear() { } @Override - public void onRNGCall(RNGSide side, String eventType, long seed, String value, String rngClass) { + public void onRNGCall(RNGSide side, String eventType, long seed, String value, String rngClass, int offset) { if (!isActive() || !isEnabled()) { return; @@ -96,7 +96,7 @@ public void onRNGCall(RNGSide side, String eventType, long seed, String value, S List classOut = new ArrayList<>(); if (stackTraceElements != null && stackTraceElements.length != 0) { - int start = 10; + int start = offset; for (int i = start; i < stackTraceElements.length; i++) { String out = formatStackTraceElement(stackTraceElements[i]); if (out != null) diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinWorldServer.java b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinWorldServer.java index c9b8f19c..116e599f 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinWorldServer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinWorldServer.java @@ -3,21 +3,31 @@ import org.objectweb.asm.Opcodes; 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.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.llamalad7.mixinextras.sugar.Local; import com.minecrafttas.mctcommon.events.EventListenerRegistry; +import com.minecrafttas.tasmod.TASmod; import com.minecrafttas.tasmod.events.EventKillTheRNGServer; import com.minecrafttas.tasmod.ktrng.RandomBase.RNGSide; import net.minecraft.world.WorldServer; +import net.minecraft.world.chunk.Chunk; @Mixin(WorldServer.class) public class MixinWorldServer { + @Inject(method = "updateBlocks", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/Chunk;enqueueRelightChecks()V")) + private void modify_extendedBlockStorage(CallbackInfo ci, @Local Chunk chunk) { + TASmod.debugRand.writeDebug(String.format("(%s, %s)", chunk.x, chunk.z)); + } + @WrapOperation(method = "updateBlocks", at = @At(value = "FIELD", target = "Lnet/minecraft/world/WorldServer;updateLCG:I", opcode = Opcodes.PUTFIELD)) private void modify_updateLCG(WorldServer world, int original, Operation operation) { - EventListenerRegistry.fireEvent(EventKillTheRNGServer.EventRNG.class, RNGSide.Server, "updateLCG", (long) world.updateLCG, Integer.toString(original), "UpdateLCG"); + EventListenerRegistry.fireEvent(EventKillTheRNGServer.EventRNG.class, RNGSide.Server, String.format("updateLCG"), (long) world.updateLCG, Integer.toString(original), "UpdateLCG", 7); operation.call(world, original); } } diff --git a/src/main/java/com/minecrafttas/tasmod/util/FileThread.java b/src/main/java/com/minecrafttas/tasmod/util/FileThread.java index fa3b7cf6..ccdbbf8b 100644 --- a/src/main/java/com/minecrafttas/tasmod/util/FileThread.java +++ b/src/main/java/com/minecrafttas/tasmod/util/FileThread.java @@ -24,7 +24,7 @@ public class FileThread extends Thread { public FileThread(Path fileLocation, boolean append) throws IOException { super("TASmod FileWriter Thread"); - OutputStream outStream = Files.newOutputStream(fileLocation, StandardOpenOption.CREATE, append ? StandardOpenOption.APPEND : StandardOpenOption.TRUNCATE_EXISTING); + OutputStream outStream = Files.newOutputStream(fileLocation, StandardOpenOption.WRITE, StandardOpenOption.CREATE, append ? StandardOpenOption.APPEND : StandardOpenOption.TRUNCATE_EXISTING); stream = new PrintWriter(new OutputStreamWriter(outStream, StandardCharsets.UTF_8), true); } From fc483995d82318ed4c30e94b179dba1e67e63e0d Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 9 May 2026 12:25:04 +0200 Subject: [PATCH 13/16] [Savestates] Add sorting by chunk to PlayerChunkMap.entries --- .../mixin/savestates/MixinPlayerChunkMap.java | 23 ++++++++-- .../handlers/SavestateWorldHandler.java | 44 +++++++++++++++++++ .../com/minecrafttas/tasmod/util/Ducks.java | 2 + .../tasmod/virtual/VirtualInput.java | 2 +- 4 files changed, 66 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/savestates/MixinPlayerChunkMap.java b/src/main/java/com/minecrafttas/tasmod/mixin/savestates/MixinPlayerChunkMap.java index 1a152ac3..fcb67e67 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/savestates/MixinPlayerChunkMap.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/savestates/MixinPlayerChunkMap.java @@ -8,9 +8,13 @@ import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; import com.google.common.collect.ComparisonChain; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.minecrafttas.tasmod.savestates.handlers.SavestateWorldHandler; +import com.minecrafttas.tasmod.savestates.handlers.SavestateWorldHandler.SortedArrayList; import com.minecrafttas.tasmod.util.Ducks.PlayerChunkMapDuck; import net.minecraft.entity.player.EntityPlayerMP; @@ -49,6 +53,11 @@ public List getPlayers() { return players; } + @WrapOperation(method = "", at = @At(value = "FIELD", target = "Lnet/minecraft/server/management/PlayerChunkMap;entries:Ljava/util/List;")) + private void modify_entries(PlayerChunkMap owner, List list, Operation operation) { + operation.call(owner, new SortedArrayList<>()); + } + /** * {@inheritDoc} * @see SavestateWorldHandler#addPlayersToChunkMap() @@ -91,16 +100,12 @@ public int compare(PlayerChunkMapEntry playerChunkMapEntry, PlayerChunkMapEntry * This messes with the RNG, as after a savestate, the chunks where mobs can spawn are * different, hence desyncing the TAS... */ -// int i = 81; Iterator iterator2 = this.pendingSendToPlayers.iterator(); while (iterator2.hasNext()) { PlayerChunkMapEntry playerChunkMapEntry3 = (PlayerChunkMapEntry) iterator2.next(); if (playerChunkMapEntry3.sendToPlayers()) { iterator2.remove(); -// if (--i < 0) { -// break; -// } } } } @@ -113,6 +118,16 @@ public int compare(PlayerChunkMapEntry playerChunkMapEntry, PlayerChunkMapEntry } } + @Override + public void sortChunks() { + Collections.sort(this.pendingSendToPlayers, new Comparator() { + + public int compare(PlayerChunkMapEntry playerChunkMapEntry, PlayerChunkMapEntry playerChunkMapEntry2) { + return ComparisonChain.start().compare(playerChunkMapEntry.getClosestPlayerDistance(), playerChunkMapEntry2.getClosestPlayerDistance()).result(); + } + }); + } + @Shadow protected abstract Iterator getChunkIterator(); } diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateWorldHandler.java b/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateWorldHandler.java index 00a2aa7b..50405cb7 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateWorldHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateWorldHandler.java @@ -2,8 +2,12 @@ import static com.minecrafttas.tasmod.TASmod.LOGGER; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; +import com.google.common.collect.ComparisonChain; import com.minecrafttas.tasmod.mixin.savestates.MixinChunkProviderServer; import com.minecrafttas.tasmod.savestates.SavestateHandlerClient; import com.minecrafttas.tasmod.util.Ducks.ChunkProviderDuck; @@ -15,6 +19,7 @@ import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.server.MinecraftServer; import net.minecraft.server.management.PlayerChunkMap; +import net.minecraft.server.management.PlayerChunkMapEntry; import net.minecraft.util.math.MathHelper; import net.minecraft.world.ServerWorldEventHandler; import net.minecraft.world.WorldServer; @@ -218,6 +223,15 @@ public void sendChunksToClient() { } } + public void sortChunks() { + WorldServer[] worlds = server.worlds; + + for (WorldServer world : worlds) { + PlayerChunkMapDuck chunkMap = (PlayerChunkMapDuck) world.getPlayerChunkMap(); + chunkMap.sortChunks(); + } + } + public void loadAllWorlds(String string) { server.convertMapIfNeeded(string); server.worlds = new WorldServer[3]; @@ -255,4 +269,34 @@ public void loadAllWorlds(String string) { server.setDifficultyForAllWorlds(Minecraft.getMinecraft().gameSettings.difficulty); } } + + public static class SortedArrayList extends ArrayList { + @SuppressWarnings("unchecked") + @Override + public boolean add(E e) { + boolean out = super.add(e); + + Collections.sort((List) this, new Comparator() { + + public int compare(PlayerChunkMapEntry playerChunkMapEntry, PlayerChunkMapEntry playerChunkMapEntry2) { + if (playerChunkMapEntry == null || playerChunkMapEntry == null) + return 0; + + Chunk chunk1 = playerChunkMapEntry.getChunk(); + Chunk chunk2 = playerChunkMapEntry2.getChunk(); + + if (chunk1 == null || chunk2 == null) + return 0; + + //@formatter:off + return ComparisonChain.start() + .compare(playerChunkMapEntry.getChunk().x, playerChunkMapEntry2.getChunk().x) + .compare(playerChunkMapEntry.getChunk().z, playerChunkMapEntry2.getChunk().z) + .result(); + //@formatter:on + } + }); + return out; + } + } } diff --git a/src/main/java/com/minecrafttas/tasmod/util/Ducks.java b/src/main/java/com/minecrafttas/tasmod/util/Ducks.java index 1ac6c3cf..c4401dc1 100644 --- a/src/main/java/com/minecrafttas/tasmod/util/Ducks.java +++ b/src/main/java/com/minecrafttas/tasmod/util/Ducks.java @@ -141,6 +141,8 @@ public static interface PlayerChunkMapDuck { * @see MixinPlayerChunkMap#sendChunksToClient() */ public void sendChunksToClient(); + + public void sortChunks(); } public static interface SoundManagerDuck { diff --git a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java index 7f868932..a6e5c5fa 100644 --- a/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java +++ b/src/main/java/com/minecrafttas/tasmod/virtual/VirtualInput.java @@ -227,7 +227,7 @@ public void preloadInputs(VirtualKeyboard keyboardToPreload, VirtualMouse mouseT MOUSE.nextMouseTick(); // Preload vanilla inputs - if (Minecraft.getMinecraft() == null) { // If running in unit test env + if (Minecraft.getMinecraft() == null || Minecraft.getMinecraft().player == null) { // If running in unit test env return; } Minecraft.getMinecraft().runTickKeyboard(); // Letting mouse and keyboard tick once to load inputs into the "currentKeyboard" From 6d732a5c8898ff1307ae4f174760dddf27d7a28e Mon Sep 17 00:00:00 2001 From: Scribble Date: Sun, 10 May 2026 12:40:12 +0200 Subject: [PATCH 14/16] [KillTheRNG] Rename "Randomness" files to RNG --- .../java/com/minecrafttas/tasmod/TASmod.java | 16 ++++++------- ...balRandomnessTimer.java => GlobalRNG.java} | 16 ++++++------- ...sTimerClient.java => GlobalRNGClient.java} | 12 +++++----- .../tasmod/ktrng/builtin/EntityRNG.java | 19 +++++++++++++++ .../ktrng/builtin/EntityRandomness.java | 24 ------------------- .../{MathRandomness.java => MathRNG.java} | 6 ++--- .../{WorldRandomness.java => WorldRNG.java} | 6 ++--- .../tasmod/ktrng/builtin/WorldSeedRNG.java | 19 +++++++++++++++ .../ktrng/builtin/WorldSeedRandomness.java | 23 ------------------ .../ktrng/handlers/KTRNGEntityHandler.java | 12 +++++----- .../ktrng/handlers/KTRNGWorldHandler.java | 14 +++++------ .../tasmod/mixin/killtherng/MixinEntity.java | 4 ++-- .../tasmod/mixin/killtherng/MixinWorld.java | 4 ++-- .../storage/builtin/KTRNGSeedStorage.java | 20 ++++++++-------- .../killtherng/GlobalRandomnessTimerTest.java | 4 ++-- 15 files changed, 95 insertions(+), 104 deletions(-) rename src/main/java/com/minecrafttas/tasmod/ktrng/{GlobalRandomnessTimer.java => GlobalRNG.java} (55%) rename src/main/java/com/minecrafttas/tasmod/ktrng/{GlobalRandomnessTimerClient.java => GlobalRNGClient.java} (66%) create mode 100644 src/main/java/com/minecrafttas/tasmod/ktrng/builtin/EntityRNG.java delete mode 100644 src/main/java/com/minecrafttas/tasmod/ktrng/builtin/EntityRandomness.java rename src/main/java/com/minecrafttas/tasmod/ktrng/builtin/{MathRandomness.java => MathRNG.java} (72%) rename src/main/java/com/minecrafttas/tasmod/ktrng/builtin/{WorldRandomness.java => WorldRNG.java} (74%) create mode 100644 src/main/java/com/minecrafttas/tasmod/ktrng/builtin/WorldSeedRNG.java delete mode 100644 src/main/java/com/minecrafttas/tasmod/ktrng/builtin/WorldSeedRandomness.java diff --git a/src/main/java/com/minecrafttas/tasmod/TASmod.java b/src/main/java/com/minecrafttas/tasmod/TASmod.java index fbb22827..877af57e 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmod.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmod.java @@ -29,9 +29,9 @@ import com.minecrafttas.tasmod.commands.CommandTickrate; import com.minecrafttas.tasmod.config.TASmodServerConfig; import com.minecrafttas.tasmod.handlers.PlayUntilHandler; -import com.minecrafttas.tasmod.ktrng.GlobalRandomnessTimer; -import com.minecrafttas.tasmod.ktrng.builtin.MathRandomness; -import com.minecrafttas.tasmod.ktrng.builtin.WorldSeedRandomness; +import com.minecrafttas.tasmod.ktrng.GlobalRNG; +import com.minecrafttas.tasmod.ktrng.builtin.MathRNG; +import com.minecrafttas.tasmod.ktrng.builtin.WorldSeedRNG; import com.minecrafttas.tasmod.ktrng.events.KillTheRNGMonitor; import com.minecrafttas.tasmod.playback.PlaybackControllerServer; import com.minecrafttas.tasmod.playback.metadata.builtin.StartpositionMetadataExtension; @@ -95,13 +95,13 @@ public class TASmod implements ModInitializer, EventServerStart, EventServerInit public static ClientMotionStorage motionStorage = new ClientMotionStorage(); - public static GlobalRandomnessTimer globalRandomness; + public static GlobalRNG globalRandomness; public static KTRNGSeedStorage seedStorage = new KTRNGSeedStorage(); - public static MathRandomness mathRandomness = new MathRandomness(0); + public static MathRNG mathRandomness = new MathRNG(0); - public static WorldSeedRandomness worldSeedRandomness = new WorldSeedRandomness(0); + public static WorldSeedRNG worldSeedRandomness = new WorldSeedRNG(0); public static KillTheRNGMonitor debugRand = new KillTheRNGMonitor(); @@ -158,9 +158,9 @@ public void onInitialize() { @Override public void onServerStart(MinecraftServer server) { - globalRandomness = new GlobalRandomnessTimer(); + globalRandomness = new GlobalRNG(); EventListenerRegistry.register(globalRandomness); - mathRandomness = new MathRandomness(0); + mathRandomness = new MathRNG(0); } @Override diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java b/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRNG.java similarity index 55% rename from src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java rename to src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRNG.java index 2ec84705..87ab3b2f 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRNG.java @@ -5,20 +5,20 @@ import kaptainwutax.seedutils.rand.JRand; import net.minecraft.server.MinecraftServer; -public class GlobalRandomnessTimer implements EventServer.EventServerTick { +public class GlobalRNG implements EventServer.EventServerTick { - private final JRand globalRandomness; + private final JRand globalRNG; private long currentSeed = 0L; - public GlobalRandomnessTimer() { - globalRandomness = new JRand(0L, false); + public GlobalRNG() { + globalRNG = new JRand(0L, false); } @Override public void onServerTick(MinecraftServer server) { - globalRandomness.advance(1); - currentSeed = globalRandomness.getSeed(); + globalRNG.advance(1); + currentSeed = globalRNG.getSeed(); } public long getCurrentSeed() { @@ -26,12 +26,12 @@ public long getCurrentSeed() { } public void setSeed(long newSeed) { - globalRandomness.setSeed(newSeed, false); + globalRNG.setSeed(newSeed, false); currentSeed = newSeed; } @Override public String toString() { - return Long.toString(globalRandomness.getSeed()); + return Long.toString(globalRNG.getSeed()); } } diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimerClient.java b/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRNGClient.java similarity index 66% rename from src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimerClient.java rename to src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRNGClient.java index a39f26b8..15449e5e 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRNGClient.java @@ -5,21 +5,21 @@ import kaptainwutax.seedutils.rand.JRand; import net.minecraft.client.Minecraft; -public class GlobalRandomnessTimerClient implements EventClient.EventClientTick { +public class GlobalRNGClient implements EventClient.EventClientTick { - private final JRand globalRandomness; + private final JRand globalRNGClient; private final JRand uuidRandomness; private long currentSeed = 0L; - public GlobalRandomnessTimerClient() { - globalRandomness = new JRand(0L); + public GlobalRNGClient() { + globalRNGClient = new JRand(0L); uuidRandomness = new JRand(0L); } @Override public void onClientTick(Minecraft mc) { - currentSeed = globalRandomness.nextLong(); + currentSeed = globalRNGClient.nextLong(); uuidRandomness.setSeed(currentSeed); } @@ -32,7 +32,7 @@ public JRand getUUIDRandom() { } public void setSeed(long newSeed) { - globalRandomness.setSeed(newSeed, false); + globalRNGClient.setSeed(newSeed, false); currentSeed = newSeed; } diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/EntityRNG.java b/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/EntityRNG.java new file mode 100644 index 00000000..e93db178 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/EntityRNG.java @@ -0,0 +1,19 @@ +package com.minecrafttas.tasmod.ktrng.builtin; + +import com.minecrafttas.tasmod.ktrng.RandomBase; + +public class EntityRNG extends RandomBase { + + public EntityRNG() { + super(); + } + + public EntityRNG(long seed) { + super(seed); + } + + @Override + public String getExtensionName() { + return "EntityRNG"; + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/EntityRandomness.java b/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/EntityRandomness.java deleted file mode 100644 index 81eddf81..00000000 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/EntityRandomness.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.minecrafttas.tasmod.ktrng.builtin; - -import com.minecrafttas.tasmod.ktrng.RandomBase; - -public class EntityRandomness extends RandomBase { - - public EntityRandomness() { - super(); - } - - public EntityRandomness(long seed) { - super(seed); - } - - @Override - public void fireRNGEvent(String eventType, long seed, String value, int stackTraceOffset) { -// super.fireEvent(eventType, seed, value, stackTraceOffset); - } - - @Override - public String getExtensionName() { - return "EntityRNG"; - } -} diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/MathRandomness.java b/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/MathRNG.java similarity index 72% rename from src/main/java/com/minecrafttas/tasmod/ktrng/builtin/MathRandomness.java rename to src/main/java/com/minecrafttas/tasmod/ktrng/builtin/MathRNG.java index 057f06ab..3334f350 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/MathRandomness.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/MathRNG.java @@ -7,13 +7,13 @@ * * @author Scribble */ -public class MathRandomness extends RandomBase { +public class MathRNG extends RandomBase { - public MathRandomness() { + public MathRNG() { super(); } - public MathRandomness(long seed) { + public MathRNG(long seed) { super(seed); } diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/WorldRandomness.java b/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/WorldRNG.java similarity index 74% rename from src/main/java/com/minecrafttas/tasmod/ktrng/builtin/WorldRandomness.java rename to src/main/java/com/minecrafttas/tasmod/ktrng/builtin/WorldRNG.java index 2d00d1ea..d8fab814 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/WorldRandomness.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/WorldRNG.java @@ -2,13 +2,13 @@ import com.minecrafttas.tasmod.ktrng.RandomBase; -public class WorldRandomness extends RandomBase { +public class WorldRNG extends RandomBase { - public WorldRandomness() { + public WorldRNG() { super(); } - public WorldRandomness(long seed) { + public WorldRNG(long seed) { super(seed); } diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/WorldSeedRNG.java b/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/WorldSeedRNG.java new file mode 100644 index 00000000..fc08e241 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/WorldSeedRNG.java @@ -0,0 +1,19 @@ +package com.minecrafttas.tasmod.ktrng.builtin; + +import com.minecrafttas.tasmod.ktrng.RandomBase; + +public class WorldSeedRNG extends RandomBase { + + public WorldSeedRNG() { + super(); + } + + public WorldSeedRNG(long seed) { + super(seed); + } + + @Override + public String getExtensionName() { + return "WorldSeedRNG"; + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/WorldSeedRandomness.java b/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/WorldSeedRandomness.java deleted file mode 100644 index be7a6dcc..00000000 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/builtin/WorldSeedRandomness.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.minecrafttas.tasmod.ktrng.builtin; - -import com.minecrafttas.tasmod.ktrng.RandomBase; - -public class WorldSeedRandomness extends RandomBase { - - public WorldSeedRandomness() { - super(); - } - - public WorldSeedRandomness(long seed) { - super(seed); - } - - @Override - public void fireRNGEvent(String eventType, long seed, String value, int stackTraceOffset) { - } - - @Override - public String getExtensionName() { - return "WorldSeedRNG"; - } -} diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/handlers/KTRNGEntityHandler.java b/src/main/java/com/minecrafttas/tasmod/ktrng/handlers/KTRNGEntityHandler.java index db66af07..58536c1f 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/handlers/KTRNGEntityHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/handlers/KTRNGEntityHandler.java @@ -5,32 +5,32 @@ import java.util.UUID; import com.minecrafttas.tasmod.TASmod; -import com.minecrafttas.tasmod.ktrng.builtin.EntityRandomness; +import com.minecrafttas.tasmod.ktrng.builtin.EntityRNG; import net.minecraft.entity.Entity; import net.minecraft.world.WorldServer; public class KTRNGEntityHandler { - public static Map getRandomnessList() { - Map out = new HashMap<>(); + public static Map getRandomnessList() { + Map out = new HashMap<>(); WorldServer[] worlds = TASmod.getServerInstance().worlds; for (WorldServer worldServer : worlds) { for (Entity entity : worldServer.loadedEntityList) { UUID entityUUID = entity.getUniqueID(); - EntityRandomness entityRandomness = (EntityRandomness) entity.rand; + EntityRNG entityRandomness = (EntityRNG) entity.rand; out.put(entityUUID, entityRandomness); } } return out; } - public static void setRandomnessList(Map randomnessList) { + public static void setRandomnessList(Map randomnessList) { WorldServer[] worlds = TASmod.getServerInstance().worlds; for (WorldServer worldServer : worlds) { for (Entity entity : worldServer.loadedEntityList) { UUID uuid = entity.getUniqueID(); - EntityRandomness rand = randomnessList.get(uuid); + EntityRNG rand = randomnessList.get(uuid); if (rand != null) entity.rand = rand; } diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/handlers/KTRNGWorldHandler.java b/src/main/java/com/minecrafttas/tasmod/ktrng/handlers/KTRNGWorldHandler.java index 0136aeee..42161f3a 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/handlers/KTRNGWorldHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/handlers/KTRNGWorldHandler.java @@ -4,18 +4,18 @@ import java.util.Map; import com.minecrafttas.tasmod.TASmod; -import com.minecrafttas.tasmod.ktrng.builtin.WorldRandomness; +import com.minecrafttas.tasmod.ktrng.builtin.WorldRNG; import net.minecraft.world.WorldServer; public class KTRNGWorldHandler { - public static Map getWorldRandomnessMap() { - Map out = new HashMap<>(); + public static Map getWorldRandomnessMap() { + Map out = new HashMap<>(); WorldServer[] worlds = TASmod.getServerInstance().worlds; int id = 0; for (WorldServer worldServer : worlds) { - WorldRandomness worldRandomness = (WorldRandomness) worldServer.rand; + WorldRNG worldRandomness = (WorldRNG) worldServer.rand; out.put(id, worldRandomness); id++; } @@ -34,11 +34,11 @@ public static Map getWorldLCGMap() { return out; } - public static void setWorldRandomnessMap(Map randomnessList) { + public static void setWorldRandomnessMap(Map randomnessList) { WorldServer[] worlds = TASmod.getServerInstance().worlds; int id = 0; for (WorldServer worldServer : worlds) { - WorldRandomness worldRandomness = randomnessList.get(id); + WorldRNG worldRandomness = randomnessList.get(id); if (worldRandomness != null) worldServer.rand = worldRandomness; id++; @@ -58,7 +58,7 @@ public static void setWorldLCGMap(Map lcgList) { public static String getWorldRandom() { if (TASmod.getServerInstance().worlds[0] != null) - return Long.toString(((WorldRandomness) TASmod.getServerInstance().worlds[0].rand).getSeed()); + return Long.toString(((WorldRNG) TASmod.getServerInstance().worlds[0].rand).getSeed()); else return ""; } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinEntity.java b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinEntity.java index 6db86d40..211b4ee6 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinEntity.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinEntity.java @@ -9,7 +9,7 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import com.minecrafttas.tasmod.ktrng.builtin.EntityRandomness; +import com.minecrafttas.tasmod.ktrng.builtin.EntityRNG; import net.minecraft.entity.Entity; import net.minecraft.world.World; @@ -20,7 +20,7 @@ public class MixinEntity { @ModifyExpressionValue(method = "", at = @At(value = "NEW", target = "Ljava/util/Random;")) public Random modify_entityRandom(Random original, World world) { if (!world.isRemote) { - return new EntityRandomness(); + return new EntityRNG(); } return original; } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinWorld.java b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinWorld.java index 9e50b82c..b2cf9f2b 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinWorld.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinWorld.java @@ -9,7 +9,7 @@ import com.llamalad7.mixinextras.injector.ModifyReceiver; import com.llamalad7.mixinextras.injector.ModifyReturnValue; import com.minecrafttas.tasmod.TASmod; -import com.minecrafttas.tasmod.ktrng.builtin.WorldRandomness; +import com.minecrafttas.tasmod.ktrng.builtin.WorldRNG; import net.minecraft.world.World; import net.minecraft.world.WorldServer; @@ -20,7 +20,7 @@ public class MixinWorld { @ModifyExpressionValue(method = "", at = @At(value = "NEW", target = "Ljava/util/Random;")) public Random modify_worldRandom(Random original) { if (((World) (Object) this) instanceof WorldServer) - return new WorldRandomness(); + return new WorldRNG(); else return original; } diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/storage/builtin/KTRNGSeedStorage.java b/src/main/java/com/minecrafttas/tasmod/savestates/storage/builtin/KTRNGSeedStorage.java index 9bfb068a..3f90834e 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/storage/builtin/KTRNGSeedStorage.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/storage/builtin/KTRNGSeedStorage.java @@ -8,8 +8,8 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.minecrafttas.tasmod.TASmod; -import com.minecrafttas.tasmod.ktrng.builtin.EntityRandomness; -import com.minecrafttas.tasmod.ktrng.builtin.WorldRandomness; +import com.minecrafttas.tasmod.ktrng.builtin.EntityRNG; +import com.minecrafttas.tasmod.ktrng.builtin.WorldRNG; import com.minecrafttas.tasmod.ktrng.handlers.KTRNGEntityHandler; import com.minecrafttas.tasmod.ktrng.handlers.KTRNGWorldHandler; import com.minecrafttas.tasmod.savestates.storage.SavestateStorageExtensionBase; @@ -30,8 +30,8 @@ public JsonObject onSavestate(MinecraftServer server, JsonObject dataToSave) { JsonObject entityRandomDataJson = new JsonObject(); JsonObject entityRandomListJson = new JsonObject(); - Map randomList = KTRNGEntityHandler.getRandomnessList(); - for (Entry entry : randomList.entrySet()) { + Map randomList = KTRNGEntityHandler.getRandomnessList(); + for (Entry entry : randomList.entrySet()) { entityRandomListJson.addProperty(entry.getKey().toString(), entry.getValue().getSeed()); } @@ -42,8 +42,8 @@ public JsonObject onSavestate(MinecraftServer server, JsonObject dataToSave) { JsonObject worldRandomDataJson = new JsonObject(); JsonObject worldListJson = new JsonObject(); - Map worldRandom = KTRNGWorldHandler.getWorldRandomnessMap(); - for (Entry entry : worldRandom.entrySet()) { + Map worldRandom = KTRNGWorldHandler.getWorldRandomnessMap(); + for (Entry entry : worldRandom.entrySet()) { worldListJson.addProperty(entry.getKey().toString(), entry.getValue().getSeed()); } @@ -74,10 +74,10 @@ public void onLoadstatePost(MinecraftServer server, JsonObject loadedData) { JsonObject entityRandomListJson = entityRandomDataJson.get("entityList").getAsJsonObject(); - Map randomList = new HashMap<>(); + Map randomList = new HashMap<>(); for (Entry entry : entityRandomListJson.entrySet()) { UUID uuid = UUID.fromString(entry.getKey().toString()); - EntityRandomness entityRandomness = new EntityRandomness(entry.getValue().getAsLong()); + EntityRNG entityRandomness = new EntityRNG(entry.getValue().getAsLong()); randomList.put(uuid, entityRandomness); } @@ -87,10 +87,10 @@ public void onLoadstatePost(MinecraftServer server, JsonObject loadedData) { JsonObject worldRandomJson = loadedData.get("worldRandom").getAsJsonObject(); JsonObject worldListJson = worldRandomJson.get("worldList").getAsJsonObject(); - Map worldList = new HashMap<>(); + Map worldList = new HashMap<>(); for (Entry entry : worldListJson.entrySet()) { int id = Integer.parseInt(entry.getKey()); - WorldRandomness worldRandomness = new WorldRandomness(entry.getValue().getAsLong()); + WorldRNG worldRandomness = new WorldRNG(entry.getValue().getAsLong()); worldList.put(id, worldRandomness); } diff --git a/src/test/java/tasmod/killtherng/GlobalRandomnessTimerTest.java b/src/test/java/tasmod/killtherng/GlobalRandomnessTimerTest.java index 272e65ad..ee0ea717 100644 --- a/src/test/java/tasmod/killtherng/GlobalRandomnessTimerTest.java +++ b/src/test/java/tasmod/killtherng/GlobalRandomnessTimerTest.java @@ -5,7 +5,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import com.minecrafttas.tasmod.ktrng.GlobalRandomnessTimer; +import com.minecrafttas.tasmod.ktrng.GlobalRNG; class GlobalRandomnessTimerTest { @@ -15,7 +15,7 @@ void setUp() throws Exception { @Test void testSetSeed() { - GlobalRandomnessTimer timer = new GlobalRandomnessTimer(); + GlobalRNG timer = new GlobalRNG(); timer.onServerTick(null); timer.onServerTick(null); timer.onServerTick(null); From 578a1c58eb3088446bea6f23fc4e3dc8302d97f0 Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 12 May 2026 14:48:12 +0200 Subject: [PATCH 15/16] [Savestates] Refactored SortedArrayList --- .../mixin/savestates/MixinPlayerChunkMap.java | 23 ++++++++++-- .../handlers/SavestateWorldHandler.java | 35 ------------------- .../tasmod/util/SortedArrayList.java | 31 ++++++++++++++++ 3 files changed, 52 insertions(+), 37 deletions(-) create mode 100644 src/main/java/com/minecrafttas/tasmod/util/SortedArrayList.java diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/savestates/MixinPlayerChunkMap.java b/src/main/java/com/minecrafttas/tasmod/mixin/savestates/MixinPlayerChunkMap.java index fcb67e67..502d479c 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/savestates/MixinPlayerChunkMap.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/savestates/MixinPlayerChunkMap.java @@ -14,8 +14,8 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.minecrafttas.tasmod.savestates.handlers.SavestateWorldHandler; -import com.minecrafttas.tasmod.savestates.handlers.SavestateWorldHandler.SortedArrayList; import com.minecrafttas.tasmod.util.Ducks.PlayerChunkMapDuck; +import com.minecrafttas.tasmod.util.SortedArrayList; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.server.management.PlayerChunkMap; @@ -53,9 +53,28 @@ public List getPlayers() { return players; } + /** + * Replaces the type of PlayerChunkMap.entries with a {@link SortedArrayList} + */ @WrapOperation(method = "", at = @At(value = "FIELD", target = "Lnet/minecraft/server/management/PlayerChunkMap;entries:Ljava/util/List;")) private void modify_entries(PlayerChunkMap owner, List list, Operation operation) { - operation.call(owner, new SortedArrayList<>()); + operation.call(owner, new SortedArrayList((playerChunkMapEntry, playerChunkMapEntry2) -> { + if (playerChunkMapEntry == null || playerChunkMapEntry == null) + return 0; + + Chunk chunk1 = playerChunkMapEntry.getChunk(); + Chunk chunk2 = playerChunkMapEntry2.getChunk(); + + if (chunk1 == null || chunk2 == null) + return 0; + + //@formatter:off + return ComparisonChain.start() + .compare(playerChunkMapEntry.getChunk().x, playerChunkMapEntry2.getChunk().x) + .compare(playerChunkMapEntry.getChunk().z, playerChunkMapEntry2.getChunk().z) + .result(); + //@formatter:on + })); } /** diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateWorldHandler.java b/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateWorldHandler.java index 50405cb7..959eeb40 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateWorldHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateWorldHandler.java @@ -2,12 +2,8 @@ import static com.minecrafttas.tasmod.TASmod.LOGGER; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.List; -import com.google.common.collect.ComparisonChain; import com.minecrafttas.tasmod.mixin.savestates.MixinChunkProviderServer; import com.minecrafttas.tasmod.savestates.SavestateHandlerClient; import com.minecrafttas.tasmod.util.Ducks.ChunkProviderDuck; @@ -19,7 +15,6 @@ import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.server.MinecraftServer; import net.minecraft.server.management.PlayerChunkMap; -import net.minecraft.server.management.PlayerChunkMapEntry; import net.minecraft.util.math.MathHelper; import net.minecraft.world.ServerWorldEventHandler; import net.minecraft.world.WorldServer; @@ -269,34 +264,4 @@ public void loadAllWorlds(String string) { server.setDifficultyForAllWorlds(Minecraft.getMinecraft().gameSettings.difficulty); } } - - public static class SortedArrayList extends ArrayList { - @SuppressWarnings("unchecked") - @Override - public boolean add(E e) { - boolean out = super.add(e); - - Collections.sort((List) this, new Comparator() { - - public int compare(PlayerChunkMapEntry playerChunkMapEntry, PlayerChunkMapEntry playerChunkMapEntry2) { - if (playerChunkMapEntry == null || playerChunkMapEntry == null) - return 0; - - Chunk chunk1 = playerChunkMapEntry.getChunk(); - Chunk chunk2 = playerChunkMapEntry2.getChunk(); - - if (chunk1 == null || chunk2 == null) - return 0; - - //@formatter:off - return ComparisonChain.start() - .compare(playerChunkMapEntry.getChunk().x, playerChunkMapEntry2.getChunk().x) - .compare(playerChunkMapEntry.getChunk().z, playerChunkMapEntry2.getChunk().z) - .result(); - //@formatter:on - } - }); - return out; - } - } } diff --git a/src/main/java/com/minecrafttas/tasmod/util/SortedArrayList.java b/src/main/java/com/minecrafttas/tasmod/util/SortedArrayList.java new file mode 100644 index 00000000..e08657ed --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/util/SortedArrayList.java @@ -0,0 +1,31 @@ +package com.minecrafttas.tasmod.util; + +import java.util.ArrayList; +import java.util.Comparator; + +/** + * Sorts the ArrayList everytime an element is added/removed. + * @param Type The type of the ArrayList + * @author Scribble + */ +public class SortedArrayList extends ArrayList { + + private final Comparator comparable; + + public SortedArrayList(Comparator comparable) { + this.comparable = comparable; + } + + @Override + public boolean add(E e) { + boolean out = super.add(e); + sort(comparable); + return out; + } + + @Override + public E remove(int index) { + sort(comparable); + return super.remove(index); + } +} From 1b1e9161a3ce8a1201d1b365bb8161014df86dca Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 12 May 2026 19:10:07 +0200 Subject: [PATCH 16/16] [Savestates] Increase performance of SortedArrayList --- .../tasmod/util/SortedArrayList.java | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/util/SortedArrayList.java b/src/main/java/com/minecrafttas/tasmod/util/SortedArrayList.java index e08657ed..845de36e 100644 --- a/src/main/java/com/minecrafttas/tasmod/util/SortedArrayList.java +++ b/src/main/java/com/minecrafttas/tasmod/util/SortedArrayList.java @@ -4,7 +4,7 @@ import java.util.Comparator; /** - * Sorts the ArrayList everytime an element is added/removed. + * Sorts the ArrayList every time an element is added/removed. * @param Type The type of the ArrayList * @author Scribble */ @@ -17,15 +17,14 @@ public SortedArrayList(Comparator comparable) { } @Override - public boolean add(E e) { - boolean out = super.add(e); - sort(comparable); - return out; - } - - @Override - public E remove(int index) { - sort(comparable); - return super.remove(index); + public boolean add(E newElement) { + for (int i = 0; i < this.size(); i++) { + E element = this.get(i); + if (comparable.compare(element, newElement) >= 0) { + super.add(i, newElement); + return true; + } + } + return super.add(newElement); } }