From cbcb09871de3a6cfe7c268c23f6c24477f49428a Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 6 Jan 2024 13:42:33 +0100 Subject: [PATCH 01/20] [KillTheRNG] Added random seed display above entities --- .../killtherng/mixin/MixinRender.java | 35 +++++++++++++++++++ .../tasmod/ktrng/KillTheRNGHandler.java | 1 - src/main/resources/fabric.mod.json | 3 +- src/main/resources/killtherng.mixin.json | 13 +++++++ src/main/resources/tasmod.accesswidener | 5 ++- 5 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/minecrafttas/killtherng/mixin/MixinRender.java create mode 100644 src/main/resources/killtherng.mixin.json diff --git a/src/main/java/com/minecrafttas/killtherng/mixin/MixinRender.java b/src/main/java/com/minecrafttas/killtherng/mixin/MixinRender.java new file mode 100644 index 00000000..c5992bc8 --- /dev/null +++ b/src/main/java/com/minecrafttas/killtherng/mixin/MixinRender.java @@ -0,0 +1,35 @@ +package com.minecrafttas.killtherng.mixin; + +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderLivingBase; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.entity.EntityLivingBase; +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 java.util.Random; + +@Mixin(RenderLivingBase.class) +public abstract class MixinRender extends Render { + protected MixinRender(RenderManager renderManager) { + super(renderManager); + } + + @Inject(method = "renderName", at = @At(value = "HEAD")) + public void inject_renderName(EntityLivingBase entity, double d, double e, double f, CallbackInfo ci){ + long seed = getSeed(entity.rand); + GlStateManager.alphaFunc(516, 0.1F); + this.renderEntityName(entity, d, e+0.23D, f, Long.toString(seed), 64); + } + + private long getSeed(Random rand) { + long in = rand.nextLong(); + long seed = (((7847617*((24667315*(in >>> 32) + 18218081*(in & 0xffffffffL) + 67552711) >> 32) - 18218081*((-4824621*(in >>> 32) + 7847617*(in & 0xffffffffL) + 7847617) >> 32)) - 11) * 246154705703781L) & 0xffffffffffffL; + seed = seed ^ 0x5deece66dL; + rand.setSeed(seed); + return seed; + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/KillTheRNGHandler.java b/src/main/java/com/minecrafttas/tasmod/ktrng/KillTheRNGHandler.java index d071cd81..18926f41 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/KillTheRNGHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/KillTheRNGHandler.java @@ -40,7 +40,6 @@ public class KillTheRNGHandler implements EventServerTick, EventPlayerJoinedClie * @param isLoaded If the KillTheRNG mod is loaded */ public KillTheRNGHandler(boolean isLoaded) { - this.isLoaded = isLoaded; if (isLoaded) { diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index dec8d114..1f27ac8b 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -26,8 +26,9 @@ ] }, "mixins": [ + "mctcommon.mixin.json", "tasmod.mixin.json", - "mctcommon.mixin.json" + "killtherng.mixin.json" ], "depends": { "fabricloader": ">=0.14.19", diff --git a/src/main/resources/killtherng.mixin.json b/src/main/resources/killtherng.mixin.json new file mode 100644 index 00000000..6ac449d1 --- /dev/null +++ b/src/main/resources/killtherng.mixin.json @@ -0,0 +1,13 @@ +{ + "required": true, + "minVersion": "0.8.5", + "package": "com.minecrafttas.killtherng.mixin", + "refmap": "tasmod.refmap.json", + "compatibilityLevel": "JAVA_8", + "mixins": [ + + ], + "client": [ + "MixinRender" + ] +} \ No newline at end of file diff --git a/src/main/resources/tasmod.accesswidener b/src/main/resources/tasmod.accesswidener index 0029bc11..7d539c92 100644 --- a/src/main/resources/tasmod.accesswidener +++ b/src/main/resources/tasmod.accesswidener @@ -11,4 +11,7 @@ accessible field net/minecraft/world/World worldInfo Lnet/minecraft/world/storag accessible method net/minecraft/world/storage/SaveHandler setSessionLock ()V -accessible field net/minecraft/client/settings/KeyBinding CATEGORY_ORDER Ljava/util/Map; \ No newline at end of file +accessible field net/minecraft/client/settings/KeyBinding CATEGORY_ORDER Ljava/util/Map; + +#KillTheRNG +accessible field net/minecraft/entity/Entity rand Ljava/util/Random; \ No newline at end of file From eae6886ee03ae400c5f5942e9e9f4185272ebc7a Mon Sep 17 00:00:00 2001 From: Scribble Date: Wed, 6 Aug 2025 20:59:11 +0200 Subject: [PATCH 02/20] [KillTheRNG] Cleanup files - Add CustomRandom from old mod - Update MixinRender - Remove seperate mixin.json --- .../killtherng/mixin/MixinRender.java | 35 ---- .../tasmod/ktrng/KTRNGRandom.java | 180 ++++++++++++++++++ .../killtherng/MixinRenderLivingBase.java | 40 ++++ src/main/resources/fabric.mod.json | 3 +- src/main/resources/killtherng.mixin.json | 13 -- src/main/resources/tasmod.mixin.json | 5 +- 6 files changed, 225 insertions(+), 51 deletions(-) delete mode 100644 src/main/java/com/minecrafttas/killtherng/mixin/MixinRender.java create mode 100644 src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGRandom.java create mode 100644 src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRenderLivingBase.java delete mode 100644 src/main/resources/killtherng.mixin.json diff --git a/src/main/java/com/minecrafttas/killtherng/mixin/MixinRender.java b/src/main/java/com/minecrafttas/killtherng/mixin/MixinRender.java deleted file mode 100644 index c5992bc8..00000000 --- a/src/main/java/com/minecrafttas/killtherng/mixin/MixinRender.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.minecrafttas.killtherng.mixin; - -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.entity.Render; -import net.minecraft.client.renderer.entity.RenderLivingBase; -import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.entity.EntityLivingBase; -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 java.util.Random; - -@Mixin(RenderLivingBase.class) -public abstract class MixinRender extends Render { - protected MixinRender(RenderManager renderManager) { - super(renderManager); - } - - @Inject(method = "renderName", at = @At(value = "HEAD")) - public void inject_renderName(EntityLivingBase entity, double d, double e, double f, CallbackInfo ci){ - long seed = getSeed(entity.rand); - GlStateManager.alphaFunc(516, 0.1F); - this.renderEntityName(entity, d, e+0.23D, f, Long.toString(seed), 64); - } - - private long getSeed(Random rand) { - long in = rand.nextLong(); - long seed = (((7847617*((24667315*(in >>> 32) + 18218081*(in & 0xffffffffL) + 67552711) >> 32) - 18218081*((-4824621*(in >>> 32) + 7847617*(in & 0xffffffffL) + 7847617) >> 32)) - 11) * 246154705703781L) & 0xffffffffffffL; - seed = seed ^ 0x5deece66dL; - rand.setSeed(seed); - return seed; - } -} diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGRandom.java b/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGRandom.java new file mode 100644 index 00000000..f065bf92 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGRandom.java @@ -0,0 +1,180 @@ +package com.minecrafttas.tasmod.ktrng; + +import java.util.Random; + +import kaptainwutax.seedutils.lcg.LCG; +import kaptainwutax.seedutils.rand.JRand; + +public class KTRNGRandom extends Random { + + private String name; + private String description; + + private long timesCalled = 0; + + private boolean enabled; + private boolean client; + + public KTRNGRandom(String name, String description, boolean enabled, boolean client) { + super(0L); + this.name = name; + this.description = description; + this.enabled = enabled; + this.client = client; + } + + public void setSeed(long seedIn) { + timesCalled = 0; + super.setSeed(seedIn ^ 0x5deece66dL); + } + + public void setSeed(long seedIn, boolean shouldIncrease) { + timesCalled++; + super.setSeed(seedIn ^ 0x5deece66dL); + } + + public long getSeed() { + long saved = timesCalled; + long seed = reverse(super.nextLong()) ^ 0x5deece66dL; + super.setSeed(seed); + timesCalled = saved; + return seed ^ 0x5deece66dL; + } + + public static long reverse(long in) { + return (((7847617 * ((24667315 * (in >>> 32) + 18218081 * (in & 0xffffffffL) + 67552711) >> 32) - 18218081 * ((-4824621 * (in >>> 32) + 7847617 * (in & 0xffffffffL) + 7847617) >> 32)) - 11) * 246154705703781L) & 0xffffffffffffL; + } + + public String getName() { + return this.name; + } + + public String getDescription() { + return description; + } + + public long getTimesCalled() { + return timesCalled; + } + + public boolean isEnabled() { + return enabled; + } + + public boolean isClient() { + return client; + } + + @Override + public long nextLong() { + timesCalled++; + long seedstored = getSeed(); + long value = super.nextLong(); + fireEvent(seedstored, Long.toString(value)); + return value; + } + + @Override + public double nextDouble() { + timesCalled++; + long seedstored = getSeed(); + double value = super.nextDouble(); + fireEvent(seedstored, Double.toString(value)); + return value; + } + + @Override + public boolean nextBoolean() { + timesCalled++; + long seedstored = getSeed(); + boolean value = super.nextBoolean(); + fireEvent(seedstored, Boolean.toString(value)); + return value; + } + + @Override + public int nextInt() { + timesCalled++; + long seedstored = getSeed(); + int value = super.nextInt(); + fireEvent(seedstored, Integer.toString(value)); + return value; + } + + @Override + public int nextInt(int bound) { + timesCalled++; + long seedstored = getSeed(); + int value = super.nextInt(bound); + fireEvent(seedstored, Integer.toString(value)); + return value; + } + + @Override + public float nextFloat() { + return super.nextFloat(); + } + + @Override + public void nextBytes(byte[] bytes) { + super.nextBytes(bytes); + } + + @Override + public double nextGaussian() { + timesCalled++; + double value = 0; + value = super.nextGaussian(); + return value; + } + + public void advance() { + advance(1); + } + + public void advance(long i) { + JRand thing = JRand.ofInternalSeed(getSeed()); + thing.advance(i); + setSeed(thing.getSeed()); + } + + public long getSeedAt(int steps) { + JRand thing = new JRand(getSeed()).combine(steps); + return thing.getSeed(); + } + + public long distance(KTRNGRandom random) { + return KTRNGRandom.distance(this.getSeed(), random.getSeed()); + } + + public long distance(long seed) { + return KTRNGRandom.distance(this.getSeed(), seed); + } + + public static long distance(KTRNGRandom random1, KTRNGRandom random2) { + return KTRNGRandom.distance(random1.getSeed(), random2.getSeed()); + } + + public static long distance(long seed, long seed2) { + return LCG.JAVA.distance(seed, seed2); + } + + @Override + public String toString() { + return name + ": " + enabled; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof KTRNGRandom) { + KTRNGRandom custom = (KTRNGRandom) obj; + return custom.name.equals(name); + } else { + return super.equals(obj); + } + } + + public void fireEvent(long seed, String value) { + // TODO Implement + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRenderLivingBase.java b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRenderLivingBase.java new file mode 100644 index 00000000..25f2ea2c --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRenderLivingBase.java @@ -0,0 +1,40 @@ +package com.minecrafttas.tasmod.mixin.killtherng; + +import java.util.Random; + +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 net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderLivingBase; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.entity.EntityLivingBase; + +@SuppressWarnings("rawtypes") +@Mixin(RenderLivingBase.class) +public abstract class MixinRenderLivingBase extends Render { + + protected MixinRenderLivingBase(RenderManager renderManager) { + super(renderManager); + } + + @SuppressWarnings("unchecked") + @Inject(method = "renderName", at = @At(value = "HEAD")) + public void inject_renderName(EntityLivingBase entity, double d, double e, double f, CallbackInfo ci) { + long seed = getSeed(entity.rand); + GlStateManager.alphaFunc(516, 0.1F); + this.renderEntityName(entity, d, e + 0.23D, f, Long.toString(seed), 64); + } + + private long getSeed(Random rand) { + long in = rand.nextLong(); + long seed = (((7847617 * ((24667315 * (in >>> 32) + 18218081 * (in & 0xffffffffL) + 67552711) >> 32) - 18218081 * ((-4824621 * (in >>> 32) + 7847617 * (in & 0xffffffffL) + 7847617) >> 32)) - 11) * 246154705703781L) + & 0xffffffffffffL; + seed = seed ^ 0x5deece66dL; + rand.setSeed(seed); + return seed; + } +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 1f27ac8b..67c0563a 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -27,8 +27,7 @@ }, "mixins": [ "mctcommon.mixin.json", - "tasmod.mixin.json", - "killtherng.mixin.json" + "tasmod.mixin.json" ], "depends": { "fabricloader": ">=0.14.19", diff --git a/src/main/resources/killtherng.mixin.json b/src/main/resources/killtherng.mixin.json deleted file mode 100644 index 6ac449d1..00000000 --- a/src/main/resources/killtherng.mixin.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "required": true, - "minVersion": "0.8.5", - "package": "com.minecrafttas.killtherng.mixin", - "refmap": "tasmod.refmap.json", - "compatibilityLevel": "JAVA_8", - "mixins": [ - - ], - "client": [ - "MixinRender" - ] -} \ No newline at end of file diff --git a/src/main/resources/tasmod.mixin.json b/src/main/resources/tasmod.mixin.json index b500e7d6..362c340c 100644 --- a/src/main/resources/tasmod.mixin.json +++ b/src/main/resources/tasmod.mixin.json @@ -68,6 +68,9 @@ // Fixes "fixes.MixinMinecraftFullscreen", "fixes.MixinNetworkManager", - "fixes.MixinMouseHelper" + "fixes.MixinMouseHelper", + + // KTRNG + "killtherng.MixinRenderLivingBase" ] } \ No newline at end of file From 8e489b30e673d5acfc25a32dd771b258a6dbdc37 Mon Sep 17 00:00:00 2001 From: Scribble Date: Thu, 11 Sep 2025 15:11:05 +0200 Subject: [PATCH 03/20] [KillTheRNG] Add testing code --- .../tasmod/mixin/killtherng/MixinEntity.java | 20 +++++++++++++++ .../killtherng/MixinRenderLivingBase.java | 25 ++++++++++--------- .../tasmod/registries/TASmodKeybinds.java | 7 +++++- src/main/resources/tasmod.mixin.json | 4 ++- 4 files changed, 42 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinEntity.java diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinEntity.java b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinEntity.java new file mode 100644 index 00000000..0bb36b44 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinEntity.java @@ -0,0 +1,20 @@ +package com.minecrafttas.tasmod.mixin.killtherng; + +import java.util.Random; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.minecrafttas.tasmod.ktrng.KTRNGRandom; + +import net.minecraft.entity.Entity; + +@Mixin(Entity.class) +public class MixinEntity { + + @ModifyExpressionValue(method = "", at = @At(value = "NEW", target = "Ljava/util/Random;")) + public Random modify_entityRandom(Random original) { + return new KTRNGRandom("What", "What", true, false); + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRenderLivingBase.java b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRenderLivingBase.java index 25f2ea2c..4af2d282 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRenderLivingBase.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRenderLivingBase.java @@ -1,22 +1,28 @@ package com.minecrafttas.tasmod.mixin.killtherng; -import java.util.Random; - import org.spongepowered.asm.mixin.Mixin; +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.KTRNGRandom; + import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.RenderLivingBase; import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; @SuppressWarnings("rawtypes") @Mixin(RenderLivingBase.class) public abstract class MixinRenderLivingBase extends Render { + @Unique + private long previousSeed = 0; + protected MixinRenderLivingBase(RenderManager renderManager) { super(renderManager); } @@ -24,17 +30,12 @@ protected MixinRenderLivingBase(RenderManager renderManager) { @SuppressWarnings("unchecked") @Inject(method = "renderName", at = @At(value = "HEAD")) public void inject_renderName(EntityLivingBase entity, double d, double e, double f, CallbackInfo ci) { - long seed = getSeed(entity.rand); + Entity serverEntity = TASmod.getServerInstance().getEntityFromUuid(entity.getUniqueID()); + KTRNGRandom random = (KTRNGRandom) serverEntity.rand; + long seed = random.getSeed(); + long distance = -random.distance(previousSeed); GlStateManager.alphaFunc(516, 0.1F); this.renderEntityName(entity, d, e + 0.23D, f, Long.toString(seed), 64); - } - - private long getSeed(Random rand) { - long in = rand.nextLong(); - long seed = (((7847617 * ((24667315 * (in >>> 32) + 18218081 * (in & 0xffffffffL) + 67552711) >> 32) - 18218081 * ((-4824621 * (in >>> 32) + 7847617 * (in & 0xffffffffL) + 7847617) >> 32)) - 11) * 246154705703781L) - & 0xffffffffffffL; - seed = seed ^ 0x5deece66dL; - rand.setSeed(seed); - return seed; + this.renderEntityName(entity, d, e + 0D, f, Long.toString(distance), 64); } } diff --git a/src/main/java/com/minecrafttas/tasmod/registries/TASmodKeybinds.java b/src/main/java/com/minecrafttas/tasmod/registries/TASmodKeybinds.java index 7c486dbf..fd85aaf1 100644 --- a/src/main/java/com/minecrafttas/tasmod/registries/TASmodKeybinds.java +++ b/src/main/java/com/minecrafttas/tasmod/registries/TASmodKeybinds.java @@ -5,7 +5,9 @@ import com.minecrafttas.mctcommon.KeybindManager.IsKeyDownFunc; import com.minecrafttas.mctcommon.KeybindManager.Keybind; import com.minecrafttas.mctcommon.KeybindManager.KeybindID; +import com.minecrafttas.tasmod.TASmod; import com.minecrafttas.tasmod.TASmodClient; +import com.minecrafttas.tasmod.ktrng.KTRNGRandom; import com.minecrafttas.tasmod.networking.TASmodBufferBuilder; import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate; import com.minecrafttas.tasmod.virtual.VirtualKeybindings; @@ -46,7 +48,10 @@ public enum TASmodKeybinds implements KeybindID { TASmodClient.virtual.CAMERA_ANGLE.updateNextCameraAngle(0, 45); }), TEST1("Various Testing", "TASmod", Keyboard.KEY_F12, () -> { - Minecraft.getMinecraft().displayGuiScreen(null); + TASmod.getServerInstance().getEntityWorld().loadedEntityList.forEach(entity -> { + KTRNGRandom rand = (KTRNGRandom) entity.rand; + rand.setSeed(0); + }); }, VirtualKeybindings::isKeyDown), TEST2("Various Testing2", "TASmod", Keyboard.KEY_F7, () -> { }, VirtualKeybindings::isKeyDown); diff --git a/src/main/resources/tasmod.mixin.json b/src/main/resources/tasmod.mixin.json index 362c340c..f648916f 100644 --- a/src/main/resources/tasmod.mixin.json +++ b/src/main/resources/tasmod.mixin.json @@ -21,7 +21,9 @@ "events.MixinEntityPlayerMP", // Fixing forge and vanilla stuff - "fixes.MixinDragonFightManager" + "fixes.MixinDragonFightManager", + + "killtherng.MixinEntity" ], "client": [ From 21da0bfcc5c8c1a5b96d5ab32eaebc93d215d914 Mon Sep 17 00:00:00 2001 From: Scribble Date: Thu, 11 Sep 2025 20:26:50 +0200 Subject: [PATCH 04/20] [KillTheRNG] Adding global randomness timer --- .../events/EventListenerRegistry.java | 4 +-- .../java/com/minecrafttas/tasmod/TASmod.java | 6 ++++ .../tasmod/ktrng/EntityRandomness.java | 12 +++++++ .../tasmod/ktrng/GlobalRandomnessTimer.java | 25 +++++++++++++++ .../{KTRNGRandom.java => RandomBase.java} | 31 ++++++++++--------- .../tasmod/mixin/killtherng/MixinEntity.java | 4 +-- .../killtherng/MixinRenderLivingBase.java | 10 +++--- .../tasmod/registries/TASmodKeybinds.java | 4 +-- 8 files changed, 71 insertions(+), 25 deletions(-) create mode 100644 src/main/java/com/minecrafttas/tasmod/ktrng/EntityRandomness.java create mode 100644 src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java rename src/main/java/com/minecrafttas/tasmod/ktrng/{KTRNGRandom.java => RandomBase.java} (83%) diff --git a/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java b/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java index 1170342e..03d5c1f4 100644 --- a/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java +++ b/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java @@ -94,7 +94,7 @@ public interface EventBase { */ public static void register(EventBase eventListener) { if (eventListener == null) { - throw new NullPointerException("Tried to register a packethandler with value null"); + throw new NullPointerException("Tried to register an eventListener with value null"); } for (Class type : searchForInterfaces(eventListener.getClass())) { @@ -153,7 +153,7 @@ public static void register(List eventListeners) { */ public static void unregister(EventBase eventListener) { if (eventListener == null) { - throw new NullPointerException("Tried to unregister a packethandler with value null"); + throw new NullPointerException("Tried to unregister an eventListener with value null"); } for (Class type : searchForInterfaces(eventListener.getClass())) { if (EventBase.class.isAssignableFrom(type)) { diff --git a/src/main/java/com/minecrafttas/tasmod/TASmod.java b/src/main/java/com/minecrafttas/tasmod/TASmod.java index 51700db5..41daeb4f 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmod.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmod.java @@ -24,6 +24,7 @@ import com.minecrafttas.tasmod.commands.CommandSavestate; import com.minecrafttas.tasmod.commands.CommandTickrate; import com.minecrafttas.tasmod.handlers.PlayUntilHandler; +import com.minecrafttas.tasmod.ktrng.GlobalRandomnessTimer; import com.minecrafttas.tasmod.playback.PlaybackControllerServer; import com.minecrafttas.tasmod.playback.metadata.builtin.StartpositionMetadataExtension; import com.minecrafttas.tasmod.registries.TASmodAPIRegistry; @@ -85,6 +86,8 @@ public class TASmod implements ModInitializer, EventServerInit, EventServerStop public static ClientMotionStorage motionStorage = new ClientMotionStorage(); + public static GlobalRandomnessTimer globalRandomness; + @Override public void onInitialize() { @@ -159,6 +162,9 @@ public void onServerInit(MinecraftServer server) { PacketHandlerRegistry.register(savestateHandlerServer.getPlayerHandler()); EventListenerRegistry.register(savestateHandlerServer.getSavestateTemporaryHandler()); + globalRandomness = new GlobalRandomnessTimer(); + EventListenerRegistry.register(globalRandomness); + if (!server.isDedicatedServer()) { TASmod.tickratechanger.ticksPerSecond = 0F; TASmod.tickratechanger.tickrateSaved = 20F; diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/EntityRandomness.java b/src/main/java/com/minecrafttas/tasmod/ktrng/EntityRandomness.java new file mode 100644 index 00000000..a84cf77e --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/EntityRandomness.java @@ -0,0 +1,12 @@ +package com.minecrafttas.tasmod.ktrng; + +import com.minecrafttas.tasmod.TASmod; + +public class EntityRandomness extends RandomBase { + + private static long entityCounter = 0L; + + public EntityRandomness() { + super(TASmod.globalRandomness.getCurrentSeed() + (entityCounter++)); + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java b/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java new file mode 100644 index 00000000..48faff67 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java @@ -0,0 +1,25 @@ +package com.minecrafttas.tasmod.ktrng; + +import com.minecrafttas.mctcommon.events.EventServer; + +import net.minecraft.server.MinecraftServer; + +public class GlobalRandomnessTimer implements EventServer.EventServerTick { + + private RandomBase globalRandomness; + + private long currentSeed = 0L; + + public GlobalRandomnessTimer() { + globalRandomness = new RandomBase(0L); + } + + @Override + public void onServerTick(MinecraftServer server) { + currentSeed = globalRandomness.nextLong(); + } + + public long getCurrentSeed() { + return currentSeed; + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGRandom.java b/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java similarity index 83% rename from src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGRandom.java rename to src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java index f065bf92..6e609100 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGRandom.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java @@ -5,7 +5,7 @@ import kaptainwutax.seedutils.lcg.LCG; import kaptainwutax.seedutils.rand.JRand; -public class KTRNGRandom extends Random { +public class RandomBase extends Random { private String name; private String description; @@ -15,12 +15,11 @@ public class KTRNGRandom extends Random { private boolean enabled; private boolean client; - public KTRNGRandom(String name, String description, boolean enabled, boolean client) { - super(0L); - this.name = name; - this.description = description; - this.enabled = enabled; - this.client = client; + private long initialSeed; + + public RandomBase(long seed) { + super(seed); + this.initialSeed = seed; } public void setSeed(long seedIn) { @@ -143,16 +142,16 @@ public long getSeedAt(int steps) { return thing.getSeed(); } - public long distance(KTRNGRandom random) { - return KTRNGRandom.distance(this.getSeed(), random.getSeed()); + public long distance(RandomBase random) { + return RandomBase.distance(this.getSeed(), random.getSeed()); } public long distance(long seed) { - return KTRNGRandom.distance(this.getSeed(), seed); + return RandomBase.distance(this.getSeed(), seed); } - public static long distance(KTRNGRandom random1, KTRNGRandom random2) { - return KTRNGRandom.distance(random1.getSeed(), random2.getSeed()); + public static long distance(RandomBase random1, RandomBase random2) { + return RandomBase.distance(random1.getSeed(), random2.getSeed()); } public static long distance(long seed, long seed2) { @@ -166,8 +165,8 @@ public String toString() { @Override public boolean equals(Object obj) { - if (obj instanceof KTRNGRandom) { - KTRNGRandom custom = (KTRNGRandom) obj; + if (obj instanceof RandomBase) { + RandomBase custom = (RandomBase) obj; return custom.name.equals(name); } else { return super.equals(obj); @@ -177,4 +176,8 @@ public boolean equals(Object obj) { public void fireEvent(long seed, String value) { // TODO Implement } + + public long getInitialSeed() { + return initialSeed; + } } 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 0bb36b44..89b3f9ce 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinEntity.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinEntity.java @@ -6,7 +6,7 @@ import org.spongepowered.asm.mixin.injection.At; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import com.minecrafttas.tasmod.ktrng.KTRNGRandom; +import com.minecrafttas.tasmod.ktrng.EntityRandomness; import net.minecraft.entity.Entity; @@ -15,6 +15,6 @@ public class MixinEntity { @ModifyExpressionValue(method = "", at = @At(value = "NEW", target = "Ljava/util/Random;")) public Random modify_entityRandom(Random original) { - return new KTRNGRandom("What", "What", true, false); + return new EntityRandomness(); } } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRenderLivingBase.java b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRenderLivingBase.java index 4af2d282..49b07a4f 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRenderLivingBase.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRenderLivingBase.java @@ -7,7 +7,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.minecrafttas.tasmod.TASmod; -import com.minecrafttas.tasmod.ktrng.KTRNGRandom; +import com.minecrafttas.tasmod.ktrng.RandomBase; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.Render; @@ -31,11 +31,11 @@ protected MixinRenderLivingBase(RenderManager renderManager) { @Inject(method = "renderName", at = @At(value = "HEAD")) public void inject_renderName(EntityLivingBase entity, double d, double e, double f, CallbackInfo ci) { Entity serverEntity = TASmod.getServerInstance().getEntityFromUuid(entity.getUniqueID()); - KTRNGRandom random = (KTRNGRandom) serverEntity.rand; + RandomBase random = (RandomBase) serverEntity.rand; long seed = random.getSeed(); - long distance = -random.distance(previousSeed); + long distance = -random.distance(random.getInitialSeed()); GlStateManager.alphaFunc(516, 0.1F); - this.renderEntityName(entity, d, e + 0.23D, f, Long.toString(seed), 64); - this.renderEntityName(entity, d, e + 0D, f, Long.toString(distance), 64); + this.renderEntityName(entity, d, e + 0.46D, f, Long.toString(seed), 64); + this.renderEntityName(entity, d, e + 0.23D, f, Long.toString(distance), 64); } } diff --git a/src/main/java/com/minecrafttas/tasmod/registries/TASmodKeybinds.java b/src/main/java/com/minecrafttas/tasmod/registries/TASmodKeybinds.java index fd85aaf1..c60347da 100644 --- a/src/main/java/com/minecrafttas/tasmod/registries/TASmodKeybinds.java +++ b/src/main/java/com/minecrafttas/tasmod/registries/TASmodKeybinds.java @@ -7,7 +7,7 @@ import com.minecrafttas.mctcommon.KeybindManager.KeybindID; import com.minecrafttas.tasmod.TASmod; import com.minecrafttas.tasmod.TASmodClient; -import com.minecrafttas.tasmod.ktrng.KTRNGRandom; +import com.minecrafttas.tasmod.ktrng.RandomBase; import com.minecrafttas.tasmod.networking.TASmodBufferBuilder; import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate; import com.minecrafttas.tasmod.virtual.VirtualKeybindings; @@ -49,7 +49,7 @@ public enum TASmodKeybinds implements KeybindID { }), TEST1("Various Testing", "TASmod", Keyboard.KEY_F12, () -> { TASmod.getServerInstance().getEntityWorld().loadedEntityList.forEach(entity -> { - KTRNGRandom rand = (KTRNGRandom) entity.rand; + RandomBase rand = (RandomBase) entity.rand; rand.setSeed(0); }); }, VirtualKeybindings::isKeyDown), From a8aa2d353c85197cbb90e203cb88d3dedf1ee591 Mon Sep 17 00:00:00 2001 From: Scribble Date: Fri, 12 Sep 2025 11:39:21 +0200 Subject: [PATCH 05/20] [KillTheRNG] Add global seed to savestate storage --- .../java/com/minecrafttas/tasmod/TASmod.java | 5 ++ .../tasmod/ktrng/GlobalRandomnessTimer.java | 5 ++ .../storage/builtin/KTRNGSeedStorage.java | 67 +++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 src/main/java/com/minecrafttas/tasmod/savestates/storage/builtin/KTRNGSeedStorage.java diff --git a/src/main/java/com/minecrafttas/tasmod/TASmod.java b/src/main/java/com/minecrafttas/tasmod/TASmod.java index 41daeb4f..805a557e 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmod.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmod.java @@ -33,6 +33,8 @@ import com.minecrafttas.tasmod.savestates.handlers.SavestateGuiHandlerServer; import com.minecrafttas.tasmod.savestates.handlers.SavestateResourcePackHandler; import com.minecrafttas.tasmod.savestates.storage.builtin.ClientMotionStorage; +import com.minecrafttas.tasmod.savestates.storage.builtin.KTRNGSeedStorage; +import com.minecrafttas.tasmod.savestates.storage.builtin.SavestateMotionStorage; import com.minecrafttas.tasmod.tickratechanger.TickrateChangerServer; import com.minecrafttas.tasmod.ticksync.TickSyncServer; import com.minecrafttas.tasmod.util.LoggerMarkers; @@ -88,6 +90,8 @@ public class TASmod implements ModInitializer, EventServerInit, EventServerStop public static GlobalRandomnessTimer globalRandomness; + public static KTRNGSeedStorage seedStorage = new KTRNGSeedStorage(); + @Override public void onInitialize() { @@ -202,6 +206,7 @@ public void onServerStop(MinecraftServer mcserver) { private void registerSavestateStorage() { TASmodAPIRegistry.SAVESTATE_STORAGE.register(motionStorage); + TASmodAPIRegistry.SAVESTATE_STORAGE.register(seedStorage); } public static MinecraftServer getServerInstance() { diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java b/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java index 48faff67..c298e7ec 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java @@ -22,4 +22,9 @@ public void onServerTick(MinecraftServer server) { public long getCurrentSeed() { return currentSeed; } + + public void setSeed(long newSeed) { + globalRandomness.setSeed(newSeed); + currentSeed = newSeed; + } } 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 new file mode 100644 index 00000000..99640cae --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/savestates/storage/builtin/KTRNGSeedStorage.java @@ -0,0 +1,67 @@ +package com.minecrafttas.tasmod.savestates.storage.builtin; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import com.minecrafttas.tasmod.TASmod; +import com.minecrafttas.tasmod.savestates.SavestateHandlerServer; +import com.minecrafttas.tasmod.savestates.exceptions.LoadstateException; +import com.minecrafttas.tasmod.savestates.exceptions.SavestateException; +import com.minecrafttas.tasmod.savestates.storage.AbstractExtendStorage; + +import net.minecraft.server.MinecraftServer; + +public class KTRNGSeedStorage extends AbstractExtendStorage { + + private static final Path fileName = Paths.get("globalSeed.json"); + private final Gson json = new GsonBuilder().setPrettyPrinting().create(); + + @Override + public void onServerSavestate(MinecraftServer server, int index, Path target, Path current) { + long currentSeed = TASmod.globalRandomness.getCurrentSeed(); + JsonObject seedObject = new JsonObject(); + seedObject.addProperty("globalSeed", currentSeed); + saveJson(current, seedObject); + } + + private void saveJson(Path current, JsonObject data) { + Path saveFile = current.resolve(SavestateHandlerServer.storageDir).resolve(fileName); + + String out = json.toJson(data); + + try { + Files.write(saveFile, out.getBytes()); + } catch (IOException e) { + throw new SavestateException(e, "Could not write to the file system"); + } + } + + @Override + public void onServerLoadstate(MinecraftServer server, int index, Path target, Path current) { + JsonObject seedObject = loadJson(target); + if (!seedObject.has("globalSeed")) + return; + long newSeed = seedObject.get("globalSeed").getAsLong(); + TASmod.globalRandomness.setSeed(newSeed); + } + + private JsonObject loadJson(Path target) { + Path saveFile = target.resolve(SavestateHandlerServer.storageDir).resolve(fileName); + + if (!Files.exists(saveFile)) + return new JsonObject(); + + String in; + try { + in = new String(Files.readAllBytes(saveFile)); + } catch (IOException e) { + throw new LoadstateException(e, "Could not read from the file system"); + } + return json.fromJson(in, JsonObject.class); + } +} From a40e54fde2e45fb97f546c085040535e112c6ed8 Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 13 Sep 2025 19:40:34 +0200 Subject: [PATCH 06/20] Update KTRNGSeedStorage to new format --- .../storage/builtin/KTRNGSeedStorage.java | 61 ++++--------------- 1 file changed, 13 insertions(+), 48 deletions(-) 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 99640cae..709563d7 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 @@ -1,67 +1,32 @@ package com.minecrafttas.tasmod.savestates.storage.builtin; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import com.minecrafttas.tasmod.TASmod; -import com.minecrafttas.tasmod.savestates.SavestateHandlerServer; -import com.minecrafttas.tasmod.savestates.exceptions.LoadstateException; -import com.minecrafttas.tasmod.savestates.exceptions.SavestateException; -import com.minecrafttas.tasmod.savestates.storage.AbstractExtendStorage; +import com.minecrafttas.tasmod.savestates.storage.SavestateStorageExtensionBase; import net.minecraft.server.MinecraftServer; -public class KTRNGSeedStorage extends AbstractExtendStorage { +public class KTRNGSeedStorage extends SavestateStorageExtensionBase { - private static final Path fileName = Paths.get("globalSeed.json"); - private final Gson json = new GsonBuilder().setPrettyPrinting().create(); + public KTRNGSeedStorage() { + super("killtherngSeeds.json"); + } @Override - public void onServerSavestate(MinecraftServer server, int index, Path target, Path current) { + public JsonObject onSavestate(MinecraftServer server, JsonObject dataToSave) { long currentSeed = TASmod.globalRandomness.getCurrentSeed(); - JsonObject seedObject = new JsonObject(); - seedObject.addProperty("globalSeed", currentSeed); - saveJson(current, seedObject); - } - - private void saveJson(Path current, JsonObject data) { - Path saveFile = current.resolve(SavestateHandlerServer.storageDir).resolve(fileName); - - String out = json.toJson(data); - - try { - Files.write(saveFile, out.getBytes()); - } catch (IOException e) { - throw new SavestateException(e, "Could not write to the file system"); - } + dataToSave.addProperty("globalSeed", currentSeed); + return dataToSave; } @Override - public void onServerLoadstate(MinecraftServer server, int index, Path target, Path current) { - JsonObject seedObject = loadJson(target); - if (!seedObject.has("globalSeed")) - return; - long newSeed = seedObject.get("globalSeed").getAsLong(); + public void onLoadstate(MinecraftServer server, JsonObject loadedData) { + long newSeed = loadedData.get("globalSeed").getAsLong(); TASmod.globalRandomness.setSeed(newSeed); } - private JsonObject loadJson(Path target) { - Path saveFile = target.resolve(SavestateHandlerServer.storageDir).resolve(fileName); - - if (!Files.exists(saveFile)) - return new JsonObject(); - - String in; - try { - in = new String(Files.readAllBytes(saveFile)); - } catch (IOException e) { - throw new LoadstateException(e, "Could not read from the file system"); - } - return json.fromJson(in, JsonObject.class); + @Override + public String getExtensionName() { + return "KTRNGSeedStorage"; } } From c5927c950df3079d163e0441721968a0c83e4646 Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 13 Sep 2025 20:49:53 +0200 Subject: [PATCH 07/20] [Events] Add ServerStart Event This event is fired before ServerInit when worlds are alredy loaded --- .../minecrafttas/mctcommon/events/EventServer.java | 13 +++++++++++++ .../mctcommon/mixin/MixinMinecraftServer.java | 6 ++++++ src/main/java/com/minecrafttas/tasmod/TASmod.java | 14 ++++++++------ .../tasmod/registries/TASmodAPIRegistry.java | 5 ++++- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/minecrafttas/mctcommon/events/EventServer.java b/src/main/java/com/minecrafttas/mctcommon/events/EventServer.java index ea26c691..6973b2ab 100644 --- a/src/main/java/com/minecrafttas/mctcommon/events/EventServer.java +++ b/src/main/java/com/minecrafttas/mctcommon/events/EventServer.java @@ -13,6 +13,19 @@ */ public interface EventServer { + /** + * Fired, just before the server initialised, for both integrated and dedicated server. + */ + @FunctionalInterface + public static interface EventServerStart extends EventBase { + + /** + * Fired, when the server is initialised, for both integrated and dedicated server. + * @param server The server + */ + public void onServerStart(MinecraftServer server); + } + /** * Fired, when the server is initialised, for both integrated and dedicated server. */ diff --git a/src/main/java/com/minecrafttas/mctcommon/mixin/MixinMinecraftServer.java b/src/main/java/com/minecrafttas/mctcommon/mixin/MixinMinecraftServer.java index 4ea7d14f..b921efc9 100644 --- a/src/main/java/com/minecrafttas/mctcommon/mixin/MixinMinecraftServer.java +++ b/src/main/java/com/minecrafttas/mctcommon/mixin/MixinMinecraftServer.java @@ -9,6 +9,7 @@ import com.minecrafttas.mctcommon.events.EventListenerRegistry; import com.minecrafttas.mctcommon.events.EventServer.EventServerGameLoop; import com.minecrafttas.mctcommon.events.EventServer.EventServerInit; +import com.minecrafttas.mctcommon.events.EventServer.EventServerStart; import com.minecrafttas.mctcommon.events.EventServer.EventServerStop; import com.minecrafttas.mctcommon.events.EventServer.EventServerTick; @@ -17,6 +18,11 @@ @Mixin(MinecraftServer.class) public class MixinMinecraftServer { + @Inject(method = "run", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;init()Z")) + public void inject_initStart(CallbackInfo ci) { + EventListenerRegistry.fireEvent(EventServerStart.class, (MinecraftServer) (Object) this); + } + @Inject(method = "run", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;init()Z", shift = Shift.AFTER)) public void inject_init(CallbackInfo ci) { EventListenerRegistry.fireEvent(EventServerInit.class, (MinecraftServer) (Object) this); diff --git a/src/main/java/com/minecrafttas/tasmod/TASmod.java b/src/main/java/com/minecrafttas/tasmod/TASmod.java index 805a557e..53a386de 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmod.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmod.java @@ -8,6 +8,7 @@ import com.minecrafttas.mctcommon.CommandRegistry; import com.minecrafttas.mctcommon.events.EventListenerRegistry; import com.minecrafttas.mctcommon.events.EventServer.EventServerInit; +import com.minecrafttas.mctcommon.events.EventServer.EventServerStart; import com.minecrafttas.mctcommon.events.EventServer.EventServerStop; import com.minecrafttas.mctcommon.networking.PacketHandlerRegistry; import com.minecrafttas.mctcommon.networking.Server; @@ -34,7 +35,6 @@ import com.minecrafttas.tasmod.savestates.handlers.SavestateResourcePackHandler; import com.minecrafttas.tasmod.savestates.storage.builtin.ClientMotionStorage; import com.minecrafttas.tasmod.savestates.storage.builtin.KTRNGSeedStorage; -import com.minecrafttas.tasmod.savestates.storage.builtin.SavestateMotionStorage; import com.minecrafttas.tasmod.tickratechanger.TickrateChangerServer; import com.minecrafttas.tasmod.ticksync.TickSyncServer; import com.minecrafttas.tasmod.util.LoggerMarkers; @@ -51,7 +51,7 @@ * * @author Scribble */ -public class TASmod implements ModInitializer, EventServerInit, EventServerStop { +public class TASmod implements ModInitializer, EventServerStart, EventServerInit, EventServerStop { public static final Logger LOGGER = LogManager.getLogger("TASmod"); @@ -135,12 +135,17 @@ public void onInitialize() { EventListenerRegistry.register(resourcepackHandler); PacketHandlerRegistry.register(playUntil); EventListenerRegistry.register(playUntil); - EventListenerRegistry.register(TASmodAPIRegistry.SAVESTATE_STORAGE); registerSavestateStorage(); } + @Override + public void onServerStart(MinecraftServer server) { + globalRandomness = new GlobalRandomnessTimer(); + EventListenerRegistry.register(globalRandomness); + } + @Override public void onServerInit(MinecraftServer server) { LOGGER.info("Initializing server"); @@ -166,9 +171,6 @@ public void onServerInit(MinecraftServer server) { PacketHandlerRegistry.register(savestateHandlerServer.getPlayerHandler()); EventListenerRegistry.register(savestateHandlerServer.getSavestateTemporaryHandler()); - globalRandomness = new GlobalRandomnessTimer(); - EventListenerRegistry.register(globalRandomness); - if (!server.isDedicatedServer()) { TASmod.tickratechanger.ticksPerSecond = 0F; TASmod.tickratechanger.tickrateSaved = 20F; diff --git a/src/main/java/com/minecrafttas/tasmod/registries/TASmodAPIRegistry.java b/src/main/java/com/minecrafttas/tasmod/registries/TASmodAPIRegistry.java index 33816e55..23b27d45 100644 --- a/src/main/java/com/minecrafttas/tasmod/registries/TASmodAPIRegistry.java +++ b/src/main/java/com/minecrafttas/tasmod/registries/TASmodAPIRegistry.java @@ -20,6 +20,7 @@ public class TASmodAPIRegistry { * savestate/rerecord count and category. * *

Any custom class has to implement PlaybackMetadataExtension + *

Side: Client

*/ public static final PlaybackMetadataRegistry PLAYBACK_METADATA = new PlaybackMetadataRegistry(); @@ -28,7 +29,7 @@ public class TASmodAPIRegistry { * *

File commands give the opportunity to run commands on each recorded tick and each played back tick.
* File commands also have access to the TASfile so that data can be stored and read in/from the TASfile. - * + *

Side: Client

*/ public static final PlaybackFileCommandsRegistry PLAYBACK_FILE_COMMAND = new PlaybackFileCommandsRegistry(); @@ -39,6 +40,7 @@ public class TASmodAPIRegistry { * or extend an existing flavor (like {@link Beta1Flavor}) and overwrite parts of the methods. * *

The resulting flavor can be registered here and can be found as a saving option with /saveTAS + *

Side: Client

*/ public static final SerialiserFlavorRegistry SERIALISER_FLAVOR = new SerialiserFlavorRegistry(); @@ -47,6 +49,7 @@ public class TASmodAPIRegistry { * *

Create a new ClientCommand by extending {@link ClientCommandBase},
* then create a command like normal, as it extends from the vanilla {@link CommandBase} + *

Side: Client

*/ public static final ClientCommandRegistry CLIENT_COMMANDS = new ClientCommandRegistry(); From 436ced4c6d440a51a65314a8d43035ef2fb20495 Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 25 Oct 2025 22:30:54 +0200 Subject: [PATCH 08/20] Bump version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 9129b224..b0387ad9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,5 +16,5 @@ mod_email=scribble@minecrafttas.com # TASmod properties group=com.minecrafttas artifact=TASmod-1.12.2 -version=Beta2.1 +version=Beta3 release=false From 0bc8d7b151d0f87ba9968aac026b9126f2532b22 Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 3 Nov 2025 20:51:24 +0100 Subject: [PATCH 09/20] [Savestate] Fix gross workaround when applying motion - [Event] Add EventLoadstatePost --- .../tasmod/events/EventSavestate.java | 19 +++++++++- .../savestates/SavestateHandlerServer.java | 4 +- .../SavestatePlayerHandlerClient.java | 37 ------------------- .../SavestateResourcePackHandler.java | 4 +- .../SavestateStorageExtensionBase.java | 1 + .../SavestateStorageExtensionRegistry.java | 6 +-- .../storage/builtin/ClientMotionStorage.java | 7 ++-- 7 files changed, 29 insertions(+), 49 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/events/EventSavestate.java b/src/main/java/com/minecrafttas/tasmod/events/EventSavestate.java index 51ac126b..0add8095 100644 --- a/src/main/java/com/minecrafttas/tasmod/events/EventSavestate.java +++ b/src/main/java/com/minecrafttas/tasmod/events/EventSavestate.java @@ -27,7 +27,7 @@ interface EventServerSavestate extends EventBase { * Fired when loading a savestate, before the savestate folder is copied */ @FunctionalInterface - interface EventServerLoadstate extends EventBase { + interface EventServerLoadstatePre extends EventBase { /** * Fired when loading a savestate, before the savestate folder is copied @@ -35,7 +35,22 @@ interface EventServerLoadstate extends EventBase { * @param server The server instance * @param paths The {@link SavestatePaths} object */ - public void onServerLoadstate(MinecraftServer server, SavestatePaths paths); + public void onServerLoadstatePre(MinecraftServer server, SavestatePaths paths); + } + + /** + * Fired when loading a savestate, after the savestate folder is copied + */ + @FunctionalInterface + interface EventServerLoadstatePost extends EventBase { + + /** + * Fired when loading a savestate, after the savestate folder is copied + * + * @param server The server instance + * @param paths The {@link SavestatePaths} object + */ + public void onServerLoadstatePost(MinecraftServer server, SavestatePaths paths); } /** diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java b/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java index 150b67d5..ea672e62 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java @@ -384,7 +384,7 @@ private void loadStateInner(SavestatePaths paths, SavestateCallback cb, Savestat Path sourcefolder = paths.getSourceFolder(); Path targetfolder = paths.getTargetFolder(); - EventListenerRegistry.fireEvent(EventSavestate.EventServerLoadstate.class, server, paths); + EventListenerRegistry.fireEvent(EventSavestate.EventServerLoadstatePre.class, server, paths); /* * Prevents loading an InputSavestate when loading index 0 (Index 0 is the @@ -445,6 +445,8 @@ private void loadStateInner(SavestatePaths paths, SavestateCallback cb, Savestat worldHandler.sendChunksToClient(); + EventListenerRegistry.fireEvent(EventSavestate.EventServerLoadstatePost.class, server, paths); + if (SavestateFlags.BLOCK_PAUSE_TICKRATE.isBlocked(flags)) { TASmod.tickratechanger.pauseGame(false); } else { diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestatePlayerHandlerClient.java b/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestatePlayerHandlerClient.java index 878ec01f..a1bc64b7 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestatePlayerHandlerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestatePlayerHandlerClient.java @@ -36,45 +36,8 @@ public void loadPlayer(NBTTagCompound compound) { // Clear any accidental applied potion particles on the client ((AccessorEntityLivingBase) player).clearPotionEffects(); - /* - * TODO - * The following 20 lines are all one - * gross workaround for correctly applying the player motion - * to the client... - * - * The motion is applied - * to the player in a previous step and unfortunately - * player.readFromNBT(compound) overwrites the - * previously applied motion... - * - * So this workaround makes sure that the motion is not overwritten - * Fixing this, requires restructuring the steps for loadstating - * and since I plan to do this anyway at some point, I will - * leave this here and be done for today*/ - double x = player.motionX; - double y = player.motionY; - double z = player.motionZ; - - float rx = player.moveForward; - float ry = player.moveVertical; - float rz = player.moveStrafing; - - boolean sprinting = player.isSprinting(); - float jumpVector = player.jumpMovementFactor; - player.readFromNBT(compound); - player.motionX = x; - player.motionY = y; - player.motionZ = z; - - player.moveForward = rx; - player.moveVertical = ry; - player.moveStrafing = rz; - - player.setSprinting(sprinting); - player.jumpMovementFactor = jumpVector; - LOGGER.trace(LoggerMarkers.Savestate, "Setting client gamemode"); // #86 int gamemode = compound.getInteger("playerGameType"); diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateResourcePackHandler.java b/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateResourcePackHandler.java index dcd76051..54c23313 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateResourcePackHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateResourcePackHandler.java @@ -35,7 +35,7 @@ * * @author Scribble */ -public class SavestateResourcePackHandler implements EventSavestate.EventServerLoadstate, ServerPacketHandler, ClientPacketHandler { +public class SavestateResourcePackHandler implements EventSavestate.EventServerLoadstatePre, ServerPacketHandler, ClientPacketHandler { /** * The server future for waiting until the client is done unloading the RP @@ -48,7 +48,7 @@ public class SavestateResourcePackHandler implements EventSavestate.EventServerL public static CountDownLatch clientRPLatch; @Override - public void onServerLoadstate(MinecraftServer server, SavestatePaths paths) { + public void onServerLoadstatePre(MinecraftServer server, SavestatePaths paths) { if (server.getResourcePackUrl().isEmpty() || server.isDedicatedServer()) return; diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/storage/SavestateStorageExtensionBase.java b/src/main/java/com/minecrafttas/tasmod/savestates/storage/SavestateStorageExtensionBase.java index 1f911302..3e78574c 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/storage/SavestateStorageExtensionBase.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/storage/SavestateStorageExtensionBase.java @@ -26,4 +26,5 @@ public SavestateStorageExtensionBase(String fileName) { public abstract JsonObject onSavestate(MinecraftServer server, JsonObject dataToSave); public abstract void onLoadstate(MinecraftServer server, JsonObject loadedData); + } diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/storage/SavestateStorageExtensionRegistry.java b/src/main/java/com/minecrafttas/tasmod/savestates/storage/SavestateStorageExtensionRegistry.java index 8ab26bec..be0e0176 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/storage/SavestateStorageExtensionRegistry.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/storage/SavestateStorageExtensionRegistry.java @@ -8,7 +8,7 @@ import com.google.gson.JsonObject; import com.minecrafttas.mctcommon.registry.AbstractRegistry; import com.minecrafttas.tasmod.TASmod; -import com.minecrafttas.tasmod.events.EventSavestate.EventServerLoadstate; +import com.minecrafttas.tasmod.events.EventSavestate.EventServerLoadstatePost; import com.minecrafttas.tasmod.events.EventSavestate.EventServerSavestate; import com.minecrafttas.tasmod.savestates.SavestateIndexer; import com.minecrafttas.tasmod.savestates.SavestateIndexer.SavestatePaths; @@ -18,7 +18,7 @@ import net.minecraft.server.MinecraftServer; -public class SavestateStorageExtensionRegistry extends AbstractRegistry implements EventServerSavestate, EventServerLoadstate { +public class SavestateStorageExtensionRegistry extends AbstractRegistry implements EventServerSavestate, EventServerLoadstatePost { public SavestateStorageExtensionRegistry() { super("SAVESTATESTORAGE_REGISTRY", new LinkedHashMap<>()); @@ -48,7 +48,7 @@ public void onServerSavestate(MinecraftServer server, SavestatePaths paths) { } @Override - public void onServerLoadstate(MinecraftServer server, SavestatePaths paths) { + public void onServerLoadstatePost(MinecraftServer server, SavestatePaths paths) { Path storageDir = paths.getTargetFolder().resolve(SavestateIndexer.savestateDataDir); if (!Files.exists(storageDir)) { try { diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/storage/builtin/ClientMotionStorage.java b/src/main/java/com/minecrafttas/tasmod/savestates/storage/builtin/ClientMotionStorage.java index 26b7151b..142616c8 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/storage/builtin/ClientMotionStorage.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/storage/builtin/ClientMotionStorage.java @@ -97,17 +97,16 @@ public void onLoadstate(MinecraftServer server, JsonObject loadedData) { EntityPlayerMP player; if (playerUUID.equals("singleplayer")) { String ownerName = server.getServerOwner(); - if (ownerName == null) { + if (ownerName == null) continue; - } + player = list.getPlayerByUsername(ownerName); } else { player = list.getPlayerByUUID(UUID.fromString(playerUUID)); } - if (player == null) { + if (player == null) continue; - } try { TASmod.server.sendTo(player, new TASmodBufferBuilder(SAVESTATE_SET_MOTION).writeMotionData(motionData)); From 605b674a1ace29150e374803c8ed9be976c96978 Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 3 Nov 2025 22:26:51 +0100 Subject: [PATCH 10/20] [KillTheRNG] Add entity randomness saving and loading --- .../com/minecrafttas/tasmod/gui/InfoHud.java | 18 ++++----- .../tasmod/ktrng/EntityRandomness.java | 6 ++- .../tasmod/ktrng/KTRNGEntityHandler.java | 38 +++++++++++++++++++ .../minecrafttas/tasmod/ktrng/RandomBase.java | 2 +- .../storage/builtin/KTRNGSeedStorage.java | 37 ++++++++++++++++++ 5 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGEntityHandler.java diff --git a/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java b/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java index 0269a886..17a02bfa 100644 --- a/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java +++ b/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java @@ -297,15 +297,15 @@ public boolean checkInit() { y += 14; // if (TASmod.ktrngHandler.isLoaded()) { -// title = "ktrng_randomseed"; -// 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 "KTRNG"; -// return "RandomSeed: " + TASmod.ktrngHandler.getGlobalSeedClient(); -// })); + title = "ktrng_randomseed"; + 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 "KTRNG"; + return "Global RandomSeed: " + TASmod.globalRandomness.getCurrentSeed(); + })); // } title = "facing"; diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/EntityRandomness.java b/src/main/java/com/minecrafttas/tasmod/ktrng/EntityRandomness.java index a84cf77e..810fd15a 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/EntityRandomness.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/EntityRandomness.java @@ -4,9 +4,13 @@ public class EntityRandomness extends RandomBase { - private static long entityCounter = 0L; + public static long entityCounter = 0L; public EntityRandomness() { super(TASmod.globalRandomness.getCurrentSeed() + (entityCounter++)); } + + public EntityRandomness(long seed) { + super(seed); + } } diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGEntityHandler.java b/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGEntityHandler.java new file mode 100644 index 00000000..62da4da6 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGEntityHandler.java @@ -0,0 +1,38 @@ +package com.minecrafttas.tasmod.ktrng; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import com.minecrafttas.tasmod.TASmod; + +import net.minecraft.entity.Entity; +import net.minecraft.world.WorldServer; + +public class KTRNGEntityHandler { + + 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; + out.put(entityUUID, entityRandomness); + } + } + return out; + } + + 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); + if (rand != null) + entity.rand = rand; + } + } + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java b/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java index 6e609100..0cfb223e 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java @@ -160,7 +160,7 @@ public static long distance(long seed, long seed2) { @Override public String toString() { - return name + ": " + enabled; + return Long.toString(getSeed()); } @Override 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 709563d7..a0833f22 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 @@ -1,7 +1,15 @@ package com.minecrafttas.tasmod.savestates.storage.builtin; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; + +import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.minecrafttas.tasmod.TASmod; +import com.minecrafttas.tasmod.ktrng.EntityRandomness; +import com.minecrafttas.tasmod.ktrng.KTRNGEntityHandler; import com.minecrafttas.tasmod.savestates.storage.SavestateStorageExtensionBase; import net.minecraft.server.MinecraftServer; @@ -16,6 +24,20 @@ public KTRNGSeedStorage() { public JsonObject onSavestate(MinecraftServer server, JsonObject dataToSave) { long currentSeed = TASmod.globalRandomness.getCurrentSeed(); dataToSave.addProperty("globalSeed", currentSeed); + + JsonObject entityRandomDataJson = new JsonObject(); + entityRandomDataJson.addProperty("entityCount", EntityRandomness.entityCounter); + + JsonObject entityRandomListJson = new JsonObject(); + Map randomList = KTRNGEntityHandler.getRandomnessList(); + for (Entry entry : randomList.entrySet()) { + entityRandomListJson.addProperty(entry.getKey().toString(), entry.getValue().getSeed()); + } + + entityRandomDataJson.add("entityList", entityRandomListJson); + + dataToSave.add("entityRandom", entityRandomDataJson); + return dataToSave; } @@ -23,6 +45,21 @@ public JsonObject onSavestate(MinecraftServer server, JsonObject dataToSave) { public void onLoadstate(MinecraftServer server, JsonObject loadedData) { long newSeed = loadedData.get("globalSeed").getAsLong(); TASmod.globalRandomness.setSeed(newSeed); + + JsonObject entityRandomDataJson = loadedData.get("entityRandom").getAsJsonObject(); + EntityRandomness.entityCounter = entityRandomDataJson.get("entityCount").getAsLong(); + + JsonObject entityRandomListJson = entityRandomDataJson.get("entityList").getAsJsonObject(); + + Map randomList = new HashMap<>(); + for (Entry entry : entityRandomListJson.entrySet()) { + UUID uuid = UUID.fromString(entry.getKey().toString()); + EntityRandomness entityRandomness = new EntityRandomness(entry.getValue().getAsLong()); + + randomList.put(uuid, entityRandomness); + } + + KTRNGEntityHandler.setRandomnessList(randomList); } @Override From 8f220eddeff97ffa2559f9d8644b2acc581457ed Mon Sep 17 00:00:00 2001 From: Scribble Date: Sat, 8 Nov 2025 21:52:57 +0100 Subject: [PATCH 11/20] [KillTheRNG] Add world randomness saving and loading --- .../com/minecrafttas/tasmod/gui/InfoHud.java | 26 ++++++++++++- .../tasmod/ktrng/KTRNGWorldHandler.java | 38 +++++++++++++++++++ .../tasmod/ktrng/WorldRandomness.java | 14 +++++++ .../killtherng/MixinRenderLivingBase.java | 2 + .../tasmod/mixin/killtherng/MixinWorld.java | 20 ++++++++++ .../storage/builtin/KTRNGSeedStorage.java | 21 ++++++++++ src/main/resources/tasmod.accesswidener | 3 +- src/main/resources/tasmod.mixin.json | 3 +- 8 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGWorldHandler.java create mode 100644 src/main/java/com/minecrafttas/tasmod/ktrng/WorldRandomness.java create mode 100644 src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinWorld.java diff --git a/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java b/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java index 17a02bfa..4d28d9c3 100644 --- a/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java +++ b/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java @@ -18,6 +18,8 @@ import com.minecrafttas.tasmod.TASmod; import com.minecrafttas.tasmod.TASmodClient; import com.minecrafttas.tasmod.events.EventClient.EventDrawHotbar; +import com.minecrafttas.tasmod.ktrng.EntityRandomness; +import com.minecrafttas.tasmod.ktrng.KTRNGWorldHandler; import com.minecrafttas.tasmod.playback.PlaybackControllerClient; import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate; import com.minecrafttas.tasmod.playback.filecommands.builtin.DesyncMonitorFileCommandExtension; @@ -296,7 +298,6 @@ public boolean checkInit() { y += 14; -// if (TASmod.ktrngHandler.isLoaded()) { title = "ktrng_randomseed"; if (configuration.getProperty(title + "_x", "err").equals("err")) setDefaults(title, y); @@ -306,7 +307,28 @@ public boolean checkInit() { return "KTRNG"; return "Global RandomSeed: " + TASmod.globalRandomness.getCurrentSeed(); })); -// } + + y += 14; + title = "ktrng_entitycount"; + 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 "EntityCount"; + return "EntityCount: " + EntityRandomness.entityCounter; + })); + + y += 14; + title = "ktrng_worldseed"; + 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 "WorldRNG"; + return "WorldRNG: " + KTRNGWorldHandler.getWorldRandom(); + })); title = "facing"; y += 14; diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGWorldHandler.java b/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGWorldHandler.java new file mode 100644 index 00000000..afc65b57 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGWorldHandler.java @@ -0,0 +1,38 @@ +package com.minecrafttas.tasmod.ktrng; + +import java.util.HashMap; +import java.util.Map; + +import com.minecrafttas.tasmod.TASmod; + +import net.minecraft.world.WorldServer; + +public class KTRNGWorldHandler { + + 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; + out.put(id, worldRandomness); + id++; + } + return out; + } + + public static void setWorldRandomnessMap(Map randomnessList) { + WorldServer[] worlds = TASmod.getServerInstance().worlds; + int id = 0; + for (WorldServer worldServer : worlds) { + WorldRandomness worldRandomness = randomnessList.get(id); + if (worldRandomness != null) + worldServer.rand = worldRandomness; + id++; + } + } + + public static String getWorldRandom() { + return Long.toString(((WorldRandomness) TASmod.getServerInstance().worlds[0].rand).getSeed()); + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/WorldRandomness.java b/src/main/java/com/minecrafttas/tasmod/ktrng/WorldRandomness.java new file mode 100644 index 00000000..ee4316f0 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/WorldRandomness.java @@ -0,0 +1,14 @@ +package com.minecrafttas.tasmod.ktrng; + +import com.minecrafttas.tasmod.TASmod; + +public class WorldRandomness extends RandomBase { + + public WorldRandomness(long seed) { + super(seed); + } + + public WorldRandomness() { + super(TASmod.globalRandomness.getCurrentSeed()); + } +} diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRenderLivingBase.java b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRenderLivingBase.java index 49b07a4f..8c81d1a8 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRenderLivingBase.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRenderLivingBase.java @@ -31,6 +31,8 @@ protected MixinRenderLivingBase(RenderManager renderManager) { @Inject(method = "renderName", at = @At(value = "HEAD")) public void inject_renderName(EntityLivingBase entity, double d, double e, double f, CallbackInfo ci) { 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()); diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinWorld.java b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinWorld.java new file mode 100644 index 00000000..8a710c49 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinWorld.java @@ -0,0 +1,20 @@ +package com.minecrafttas.tasmod.mixin.killtherng; + +import java.util.Random; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.minecrafttas.tasmod.ktrng.WorldRandomness; + +import net.minecraft.world.World; + +@Mixin(World.class) +public class MixinWorld { + + @ModifyExpressionValue(method = "", at = @At(value = "NEW", target = "Ljava/util/Random;")) + public Random modify_worldRandom(Random original) { + return new WorldRandomness(); + } +} 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 a0833f22..2ef352b5 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 @@ -10,6 +10,8 @@ import com.minecrafttas.tasmod.TASmod; import com.minecrafttas.tasmod.ktrng.EntityRandomness; import com.minecrafttas.tasmod.ktrng.KTRNGEntityHandler; +import com.minecrafttas.tasmod.ktrng.KTRNGWorldHandler; +import com.minecrafttas.tasmod.ktrng.WorldRandomness; import com.minecrafttas.tasmod.savestates.storage.SavestateStorageExtensionBase; import net.minecraft.server.MinecraftServer; @@ -38,6 +40,14 @@ public JsonObject onSavestate(MinecraftServer server, JsonObject dataToSave) { dataToSave.add("entityRandom", entityRandomDataJson); + JsonObject worldRandomDataJson = new JsonObject(); + Map worldRandom = KTRNGWorldHandler.getWorldRandomnessMap(); + for (Entry entry : worldRandom.entrySet()) { + worldRandomDataJson.addProperty(entry.getKey().toString(), entry.getValue().getSeed()); + } + + dataToSave.add("worldRandom", worldRandomDataJson); + return dataToSave; } @@ -60,6 +70,17 @@ public void onLoadstate(MinecraftServer server, JsonObject loadedData) { } KTRNGEntityHandler.setRandomnessList(randomList); + + JsonObject worldRandomListJson = loadedData.get("worldRandom").getAsJsonObject(); + + Map worldList = new HashMap<>(); + for (Entry entry : worldRandomListJson.entrySet()) { + int id = Integer.parseInt(entry.getKey()); + WorldRandomness worldRandomness = new WorldRandomness(entry.getValue().getAsLong()); + + worldList.put(id, worldRandomness); + } + KTRNGWorldHandler.setWorldRandomnessMap(worldList); } @Override diff --git a/src/main/resources/tasmod.accesswidener b/src/main/resources/tasmod.accesswidener index 7d539c92..7766c35b 100644 --- a/src/main/resources/tasmod.accesswidener +++ b/src/main/resources/tasmod.accesswidener @@ -14,4 +14,5 @@ accessible method net/minecraft/world/storage/SaveHandler setSessionLock ()V accessible field net/minecraft/client/settings/KeyBinding CATEGORY_ORDER Ljava/util/Map; #KillTheRNG -accessible field net/minecraft/entity/Entity rand Ljava/util/Random; \ No newline at end of file +accessible field net/minecraft/entity/Entity rand Ljava/util/Random; +mutable field net/minecraft/world/World rand Ljava/util/Random; \ No newline at end of file diff --git a/src/main/resources/tasmod.mixin.json b/src/main/resources/tasmod.mixin.json index f648916f..f7c7ec7b 100644 --- a/src/main/resources/tasmod.mixin.json +++ b/src/main/resources/tasmod.mixin.json @@ -23,7 +23,8 @@ // Fixing forge and vanilla stuff "fixes.MixinDragonFightManager", - "killtherng.MixinEntity" + "killtherng.MixinEntity", + "killtherng.MixinWorld" ], "client": [ From dc2d2ffaa3b531cdc10b83ad3d30212f1b05ac1d Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 10 Nov 2025 19:46:23 +0100 Subject: [PATCH 12/20] [KillTheRNG] Add RNG logging --- .../com/minecrafttas/tasmod/ktrng/RandomBase.java | 14 +++++++++++++- .../minecrafttas/tasmod/ktrng/WorldRandomness.java | 5 +++++ .../minecrafttas/tasmod/util/LoggerMarkers.java | 2 ++ src/main/resources/log4j.xml | 2 ++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java b/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java index 0cfb223e..7242c5d0 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java @@ -2,6 +2,9 @@ import java.util.Random; +import com.minecrafttas.tasmod.TASmod; +import com.minecrafttas.tasmod.util.LoggerMarkers; + import kaptainwutax.seedutils.lcg.LCG; import kaptainwutax.seedutils.rand.JRand; @@ -174,7 +177,16 @@ public boolean equals(Object obj) { } public void fireEvent(long seed, String value) { - // TODO Implement + StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[3]; + String methodName = stackTraceElement.getMethodName(); + String[] classNames = stackTraceElement.getClassName().split("\\."); + String className = classNames[classNames.length - 1]; + if (methodName.equals("showBarrierParticles")) + return; + String out = className + "." + methodName + + (stackTraceElement.isNativeMethod() ? "(Native Method)" : (stackTraceElement.getFileName() != null && stackTraceElement.getLineNumber() >= 0 ? "(" + stackTraceElement.getFileName() + ":" + stackTraceElement.getLineNumber() + + ")" : (stackTraceElement.getFileName() != null ? "(" + stackTraceElement.getFileName() + ")" : "(Unknown Source)"))); + TASmod.LOGGER.debug(LoggerMarkers.KillTheRNG, "{}\t{}\t{}", seed, value, out); } public long getInitialSeed() { diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/WorldRandomness.java b/src/main/java/com/minecrafttas/tasmod/ktrng/WorldRandomness.java index ee4316f0..eca1ea45 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/WorldRandomness.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/WorldRandomness.java @@ -11,4 +11,9 @@ public WorldRandomness(long seed) { public WorldRandomness() { super(TASmod.globalRandomness.getCurrentSeed()); } + + @Override + public void fireEvent(long seed, String value) { +// super.fireEvent(seed, value); + } } diff --git a/src/main/java/com/minecrafttas/tasmod/util/LoggerMarkers.java b/src/main/java/com/minecrafttas/tasmod/util/LoggerMarkers.java index 1d2951ed..1a08fe30 100644 --- a/src/main/java/com/minecrafttas/tasmod/util/LoggerMarkers.java +++ b/src/main/java/com/minecrafttas/tasmod/util/LoggerMarkers.java @@ -47,6 +47,8 @@ public class LoggerMarkers implements EventDrawHotbarAlways { public static final Marker Mouse = MarkerManager.getMarker("Mouse"); + public static final Marker KillTheRNG = MarkerManager.getMarker("KillTheRNG"); + @Override public void onDrawHotbarAlways() { ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft()); diff --git a/src/main/resources/log4j.xml b/src/main/resources/log4j.xml index 88fd9007..d2826b99 100644 --- a/src/main/resources/log4j.xml +++ b/src/main/resources/log4j.xml @@ -15,6 +15,8 @@ onMatch="${sys:tasmod.marker.keyboard:-DENY}" onMismatch="NEUTRAL" /> + From 5827f1f335a45820bcce45f381c0d87b0f1b4d58 Mon Sep 17 00:00:00 2001 From: Scribble Date: Wed, 12 Nov 2025 21:32:33 +0100 Subject: [PATCH 13/20] [KillTheRNG] Only redirect server EntityRNG, add initial seed to EntityDisplay --- .../tasmod/ktrng/GlobalRandomnessTimer.java | 2 +- .../ktrng/GlobalRandomnessTimerClient.java | 38 +++++++++++++++++++ .../minecrafttas/tasmod/ktrng/RandomBase.java | 4 ++ .../tasmod/mixin/killtherng/MixinEntity.java | 9 ++++- .../killtherng/MixinRenderLivingBase.java | 1 + 5 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimerClient.java diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java b/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java index c298e7ec..ccfc3911 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java @@ -6,7 +6,7 @@ public class GlobalRandomnessTimer implements EventServer.EventServerTick { - private RandomBase globalRandomness; + private final RandomBase globalRandomness; private long currentSeed = 0L; diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimerClient.java b/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimerClient.java new file mode 100644 index 00000000..ea94251c --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimerClient.java @@ -0,0 +1,38 @@ +package com.minecrafttas.tasmod.ktrng; + +import com.minecrafttas.mctcommon.events.EventClient; + +import net.minecraft.client.Minecraft; + +public class GlobalRandomnessTimerClient implements EventClient.EventClientTick { + + private final RandomBase globalRandomness; + private final RandomBase uuidRandomness; + + private long currentSeed = 0L; + + public GlobalRandomnessTimerClient() { + globalRandomness = new RandomBase(0L); + uuidRandomness = new RandomBase(0L); + } + + @Override + public void onClientTick(Minecraft mc) { + currentSeed = globalRandomness.nextLong(); + uuidRandomness.setSeed(currentSeed); + } + + public long getCurrentSeed() { + return currentSeed; + } + + public RandomBase getUUIDRandom() { + return uuidRandomness; + } + + public void setSeed(long newSeed) { + globalRandomness.setSeed(newSeed); + 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 7242c5d0..5972a36c 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java @@ -20,6 +20,10 @@ public class RandomBase extends Random { private long initialSeed; + public RandomBase() { + super(); + } + public RandomBase(long seed) { super(seed); this.initialSeed = seed; 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 89b3f9ce..a0d5c930 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinEntity.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinEntity.java @@ -9,12 +9,17 @@ import com.minecrafttas.tasmod.ktrng.EntityRandomness; import net.minecraft.entity.Entity; +import net.minecraft.world.World; @Mixin(Entity.class) public class MixinEntity { @ModifyExpressionValue(method = "", at = @At(value = "NEW", target = "Ljava/util/Random;")) - public Random modify_entityRandom(Random original) { - return new EntityRandomness(); + public Random modify_entityRandom(Random original, World world) { + if (!world.isRemote) { + return new EntityRandomness(); + } else { + return new EntityRandomness(0L); + } } } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRenderLivingBase.java b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRenderLivingBase.java index 8c81d1a8..f7953eb3 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRenderLivingBase.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinRenderLivingBase.java @@ -37,6 +37,7 @@ public void inject_renderName(EntityLivingBase entity, double d, double e, doubl long seed = random.getSeed(); long distance = -random.distance(random.getInitialSeed()); GlStateManager.alphaFunc(516, 0.1F); + this.renderEntityName(entity, d, e + 0.69D, f, Long.toString(random.getInitialSeed()), 64); this.renderEntityName(entity, d, e + 0.46D, f, Long.toString(seed), 64); this.renderEntityName(entity, d, e + 0.23D, f, Long.toString(distance), 64); } From a3a1436994575d8966b9bd7a12b161788554a7ca Mon Sep 17 00:00:00 2001 From: Scribble Date: Wed, 12 Nov 2025 21:32:33 +0100 Subject: [PATCH 14/20] [Savestates] Add more loadstate events to SavestateStorage - [KillTheRNG] Remove entitycount --- .../tasmod/events/EventSavestate.java | 2 +- .../com/minecrafttas/tasmod/gui/InfoHud.java | 21 ++++++----- .../tasmod/ktrng/EntityRandomness.java | 4 +-- .../tasmod/mixin/killtherng/MixinEntity.java | 8 +++++ .../savestates/SavestateHandlerServer.java | 2 +- .../SavestateStorageExtensionBase.java | 8 ++++- .../SavestateStorageExtensionRegistry.java | 36 +++++++++++++++---- .../storage/builtin/ClientMotionStorage.java | 2 +- .../storage/builtin/KTRNGSeedStorage.java | 4 +-- 9 files changed, 60 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/events/EventSavestate.java b/src/main/java/com/minecrafttas/tasmod/events/EventSavestate.java index 0add8095..dda3601f 100644 --- a/src/main/java/com/minecrafttas/tasmod/events/EventSavestate.java +++ b/src/main/java/com/minecrafttas/tasmod/events/EventSavestate.java @@ -62,7 +62,7 @@ interface EventServerCompleteLoadstate extends EventBase { /** * Fired one tick after a loadstate was carried out */ - public void onServerLoadstateComplete(); + public void onServerLoadstateComplete(MinecraftServer server, SavestatePaths paths); } /** diff --git a/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java b/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java index 4d28d9c3..37758dd3 100644 --- a/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java +++ b/src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java @@ -18,7 +18,6 @@ import com.minecrafttas.tasmod.TASmod; import com.minecrafttas.tasmod.TASmodClient; import com.minecrafttas.tasmod.events.EventClient.EventDrawHotbar; -import com.minecrafttas.tasmod.ktrng.EntityRandomness; import com.minecrafttas.tasmod.ktrng.KTRNGWorldHandler; import com.minecrafttas.tasmod.playback.PlaybackControllerClient; import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate; @@ -308,16 +307,16 @@ public boolean checkInit() { return "Global RandomSeed: " + TASmod.globalRandomness.getCurrentSeed(); })); - y += 14; - title = "ktrng_entitycount"; - 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 "EntityCount"; - return "EntityCount: " + EntityRandomness.entityCounter; - })); +// y += 14; +// title = "ktrng_entitycount"; +// 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 "EntityCount"; +// return "EntityCount: " + EntityRandomness.entityCounter; +// })); y += 14; title = "ktrng_worldseed"; diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/EntityRandomness.java b/src/main/java/com/minecrafttas/tasmod/ktrng/EntityRandomness.java index 810fd15a..f920d916 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/EntityRandomness.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/EntityRandomness.java @@ -4,10 +4,8 @@ public class EntityRandomness extends RandomBase { - public static long entityCounter = 0L; - public EntityRandomness() { - super(TASmod.globalRandomness.getCurrentSeed() + (entityCounter++)); + super(TASmod.globalRandomness.getCurrentSeed()); } public EntityRandomness(long seed) { 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 a0d5c930..3bef0312 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinEntity.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/MixinEntity.java @@ -1,11 +1,14 @@ package com.minecrafttas.tasmod.mixin.killtherng; import java.util.Random; +import java.util.UUID; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; 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.EntityRandomness; import net.minecraft.entity.Entity; @@ -22,4 +25,9 @@ public Random modify_entityRandom(Random original, World world) { return new EntityRandomness(0L); } } + + @WrapOperation(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/MathHelper;getRandomUUID(Ljava/util/Random;)Ljava/util/UUID;")) + private UUID wrap_getRandomUUID(Random rand, Operation original) { + return original.call(new Random()); + } } diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java b/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java index ea672e62..ea4d0745 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java @@ -469,7 +469,7 @@ private void loadStateInner(SavestatePaths paths, SavestateCallback cb, Savestat * Rn it's not a problem, but this should be looked at... */ TASmod.tickSchedulerServer.add(() -> { - EventListenerRegistry.fireEvent(EventSavestate.EventServerCompleteLoadstate.class); + EventListenerRegistry.fireEvent(EventSavestate.EventServerCompleteLoadstate.class, server, paths); onLoadstateComplete(); }); } diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/storage/SavestateStorageExtensionBase.java b/src/main/java/com/minecrafttas/tasmod/savestates/storage/SavestateStorageExtensionBase.java index 3e78574c..3e1b5b3a 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/storage/SavestateStorageExtensionBase.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/storage/SavestateStorageExtensionBase.java @@ -25,6 +25,12 @@ public SavestateStorageExtensionBase(String fileName) { public abstract JsonObject onSavestate(MinecraftServer server, JsonObject dataToSave); - public abstract void onLoadstate(MinecraftServer server, JsonObject loadedData); + public void onLoadstatePre(MinecraftServer server, JsonObject loadedData) { + } + + public void onLoadstatePost(MinecraftServer server, JsonObject loadedData) { + } + public void onLoadstateComplete(MinecraftServer server, JsonObject loadedData) { + } } diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/storage/SavestateStorageExtensionRegistry.java b/src/main/java/com/minecrafttas/tasmod/savestates/storage/SavestateStorageExtensionRegistry.java index be0e0176..086e74cd 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/storage/SavestateStorageExtensionRegistry.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/storage/SavestateStorageExtensionRegistry.java @@ -3,13 +3,14 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.Map; import com.google.gson.JsonObject; import com.minecrafttas.mctcommon.registry.AbstractRegistry; import com.minecrafttas.tasmod.TASmod; -import com.minecrafttas.tasmod.events.EventSavestate.EventServerLoadstatePost; -import com.minecrafttas.tasmod.events.EventSavestate.EventServerSavestate; +import com.minecrafttas.tasmod.events.EventSavestate; import com.minecrafttas.tasmod.savestates.SavestateIndexer; import com.minecrafttas.tasmod.savestates.SavestateIndexer.SavestatePaths; import com.minecrafttas.tasmod.savestates.exceptions.LoadstateException; @@ -18,7 +19,9 @@ import net.minecraft.server.MinecraftServer; -public class SavestateStorageExtensionRegistry extends AbstractRegistry implements EventServerSavestate, EventServerLoadstatePost { +public class SavestateStorageExtensionRegistry extends AbstractRegistry implements EventSavestate.EventServerSavestate, EventSavestate.EventServerLoadstatePre, EventSavestate.EventServerLoadstatePost, EventSavestate.EventServerCompleteLoadstate { + + Map jsonMap = new HashMap<>(); public SavestateStorageExtensionRegistry() { super("SAVESTATESTORAGE_REGISTRY", new LinkedHashMap<>()); @@ -47,8 +50,8 @@ public void onServerSavestate(MinecraftServer server, SavestatePaths paths) { } } - @Override - public void onServerLoadstatePost(MinecraftServer server, SavestatePaths paths) { + private void load(SavestatePaths paths) { + jsonMap.clear(); Path storageDir = paths.getTargetFolder().resolve(SavestateIndexer.savestateDataDir); if (!Files.exists(storageDir)) { try { @@ -72,8 +75,29 @@ public void onServerLoadstatePost(MinecraftServer server, SavestatePaths paths) } catch (IOException e) { throw new LoadstateException(e, "Can't load %s in %s extension", storage.fileName, storage.getExtensionName()); } + jsonMap.put(storage, loadedData); + } + } + + @Override + public void onServerLoadstatePre(MinecraftServer server, SavestatePaths paths) { + load(paths); + for (SavestateStorageExtensionBase storage : REGISTRY.values()) { + storage.onLoadstatePre(server, jsonMap.get(storage)); + } + } - storage.onLoadstate(server, loadedData); + @Override + public void onServerLoadstatePost(MinecraftServer server, SavestatePaths paths) { + for (SavestateStorageExtensionBase storage : REGISTRY.values()) { + storage.onLoadstatePost(server, jsonMap.get(storage)); + } + } + + @Override + public void onServerLoadstateComplete(MinecraftServer server, SavestatePaths paths) { + for (SavestateStorageExtensionBase storage : REGISTRY.values()) { + storage.onLoadstateComplete(TASmod.getServerInstance(), jsonMap.get(storage)); } } } diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/storage/builtin/ClientMotionStorage.java b/src/main/java/com/minecrafttas/tasmod/savestates/storage/builtin/ClientMotionStorage.java index 142616c8..81f89e55 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/storage/builtin/ClientMotionStorage.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/storage/builtin/ClientMotionStorage.java @@ -87,7 +87,7 @@ public JsonObject onSavestate(MinecraftServer server, JsonObject dataToSave) { } @Override - public void onLoadstate(MinecraftServer server, JsonObject loadedData) { + public void onLoadstatePost(MinecraftServer server, JsonObject loadedData) { PlayerList list = server.getPlayerList(); for (Entry motionDataJsonElement : loadedData.entrySet()) { 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 2ef352b5..2ba78b01 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 @@ -28,7 +28,6 @@ public JsonObject onSavestate(MinecraftServer server, JsonObject dataToSave) { dataToSave.addProperty("globalSeed", currentSeed); JsonObject entityRandomDataJson = new JsonObject(); - entityRandomDataJson.addProperty("entityCount", EntityRandomness.entityCounter); JsonObject entityRandomListJson = new JsonObject(); Map randomList = KTRNGEntityHandler.getRandomnessList(); @@ -52,12 +51,11 @@ public JsonObject onSavestate(MinecraftServer server, JsonObject dataToSave) { } @Override - public void onLoadstate(MinecraftServer server, JsonObject loadedData) { + public void onLoadstateComplete(MinecraftServer server, JsonObject loadedData) { long newSeed = loadedData.get("globalSeed").getAsLong(); TASmod.globalRandomness.setSeed(newSeed); JsonObject entityRandomDataJson = loadedData.get("entityRandom").getAsJsonObject(); - EntityRandomness.entityCounter = entityRandomDataJson.get("entityCount").getAsLong(); JsonObject entityRandomListJson = entityRandomDataJson.get("entityList").getAsJsonObject(); From 80beee52354aa53671c8691e58b68ec4ed027ec6 Mon Sep 17 00:00:00 2001 From: Scribble Date: Sun, 16 Nov 2025 15:19:10 +0100 Subject: [PATCH 15/20] [KillTheRNG] Fix GlobalRandomness not advancing correctly --- .../com/minecrafttas/tasmod/ktrng/EntityRandomness.java | 2 ++ .../minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java | 3 ++- .../com/minecrafttas/tasmod/ktrng/KTRNGWorldHandler.java | 5 ++++- .../com/minecrafttas/tasmod/registries/TASmodKeybinds.java | 6 ------ 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/EntityRandomness.java b/src/main/java/com/minecrafttas/tasmod/ktrng/EntityRandomness.java index f920d916..a5de00bf 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/EntityRandomness.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/EntityRandomness.java @@ -4,6 +4,8 @@ public class EntityRandomness extends RandomBase { + public static long entityCount = 0; + public EntityRandomness() { super(TASmod.globalRandomness.getCurrentSeed()); } diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java b/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java index ccfc3911..6d64417b 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/GlobalRandomnessTimer.java @@ -16,7 +16,8 @@ public GlobalRandomnessTimer() { @Override public void onServerTick(MinecraftServer server) { - currentSeed = globalRandomness.nextLong(); + globalRandomness.advance(); + currentSeed = globalRandomness.getSeed(); } public long getCurrentSeed() { diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGWorldHandler.java b/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGWorldHandler.java index afc65b57..3ba1e10b 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGWorldHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGWorldHandler.java @@ -33,6 +33,9 @@ public static void setWorldRandomnessMap(Map randomnes } public static String getWorldRandom() { - return Long.toString(((WorldRandomness) TASmod.getServerInstance().worlds[0].rand).getSeed()); + if (TASmod.getServerInstance().worlds[0] != null) + return Long.toString(((WorldRandomness) TASmod.getServerInstance().worlds[0].rand).getSeed()); + else + return ""; } } diff --git a/src/main/java/com/minecrafttas/tasmod/registries/TASmodKeybinds.java b/src/main/java/com/minecrafttas/tasmod/registries/TASmodKeybinds.java index c60347da..bbd88526 100644 --- a/src/main/java/com/minecrafttas/tasmod/registries/TASmodKeybinds.java +++ b/src/main/java/com/minecrafttas/tasmod/registries/TASmodKeybinds.java @@ -5,9 +5,7 @@ import com.minecrafttas.mctcommon.KeybindManager.IsKeyDownFunc; import com.minecrafttas.mctcommon.KeybindManager.Keybind; import com.minecrafttas.mctcommon.KeybindManager.KeybindID; -import com.minecrafttas.tasmod.TASmod; import com.minecrafttas.tasmod.TASmodClient; -import com.minecrafttas.tasmod.ktrng.RandomBase; import com.minecrafttas.tasmod.networking.TASmodBufferBuilder; import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate; import com.minecrafttas.tasmod.virtual.VirtualKeybindings; @@ -48,10 +46,6 @@ public enum TASmodKeybinds implements KeybindID { TASmodClient.virtual.CAMERA_ANGLE.updateNextCameraAngle(0, 45); }), TEST1("Various Testing", "TASmod", Keyboard.KEY_F12, () -> { - TASmod.getServerInstance().getEntityWorld().loadedEntityList.forEach(entity -> { - RandomBase rand = (RandomBase) entity.rand; - rand.setSeed(0); - }); }, VirtualKeybindings::isKeyDown), TEST2("Various Testing2", "TASmod", Keyboard.KEY_F7, () -> { }, VirtualKeybindings::isKeyDown); From ff69c8ffc15196b1a1a9ef6a48068675901aef42 Mon Sep 17 00:00:00 2001 From: Scribble Date: Wed, 19 Nov 2025 20:20:08 +0100 Subject: [PATCH 16/20] [KillTheRNG] Add world.updateLCG to randomness pool --- .../tasmod/ktrng/KTRNGWorldHandler.java | 23 +++++++++++ .../minecrafttas/tasmod/ktrng/RandomBase.java | 6 ++- .../tasmod/ktrng/WorldRandomness.java | 4 +- .../storage/builtin/KTRNGSeedStorage.java | 29 ++++++++++++-- src/main/resources/tasmod.accesswidener | 1 + src/test/java/tasmod/killtherng/RNGTest.java | 39 +++++++++++++++++++ 6 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 src/test/java/tasmod/killtherng/RNGTest.java diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGWorldHandler.java b/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGWorldHandler.java index 3ba1e10b..d1c66971 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGWorldHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/KTRNGWorldHandler.java @@ -21,6 +21,18 @@ public static Map getWorldRandomnessMap() { return out; } + public static Map getWorldLCGMap() { + Map out = new HashMap<>(); + WorldServer[] worlds = TASmod.getServerInstance().worlds; + int id = 0; + for (WorldServer worldServer : worlds) { + int updateLCG = worldServer.updateLCG; + out.put(id, updateLCG); + id++; + } + return out; + } + public static void setWorldRandomnessMap(Map randomnessList) { WorldServer[] worlds = TASmod.getServerInstance().worlds; int id = 0; @@ -32,6 +44,17 @@ public static void setWorldRandomnessMap(Map randomnes } } + public static void setWorldLCGMap(Map lcgList) { + WorldServer[] worlds = TASmod.getServerInstance().worlds; + int id = 0; + for (WorldServer worldServer : worlds) { + Integer updateLCG = lcgList.get(id); + if (updateLCG != null) + worldServer.updateLCG = updateLCG; + id++; + } + } + public static String getWorldRandom() { if (TASmod.getServerInstance().worlds[0] != null) return Long.toString(((WorldRandomness) TASmod.getServerInstance().worlds[0].rand).getSeed()); diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java b/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java index 5972a36c..19f636db 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java @@ -181,7 +181,11 @@ public boolean equals(Object obj) { } public void fireEvent(long seed, String value) { - StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[3]; + fireEvent(seed, value, 3); + } + + public void fireEvent(long seed, String value, int stackTraceOffset) { + StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[stackTraceOffset]; String methodName = stackTraceElement.getMethodName(); String[] classNames = stackTraceElement.getClassName().split("\\."); String className = classNames[classNames.length - 1]; diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/WorldRandomness.java b/src/main/java/com/minecrafttas/tasmod/ktrng/WorldRandomness.java index eca1ea45..858fed59 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/WorldRandomness.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/WorldRandomness.java @@ -13,7 +13,7 @@ public WorldRandomness() { } @Override - public void fireEvent(long seed, String value) { -// super.fireEvent(seed, value); + public void fireEvent(long seed, String value, int offset) { + //super.fireEvent(seed, value, 5); } } 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 2ba78b01..0c0848b6 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 @@ -40,11 +40,23 @@ public JsonObject onSavestate(MinecraftServer server, JsonObject dataToSave) { dataToSave.add("entityRandom", entityRandomDataJson); JsonObject worldRandomDataJson = new JsonObject(); + + JsonObject worldListJson = new JsonObject(); Map worldRandom = KTRNGWorldHandler.getWorldRandomnessMap(); for (Entry entry : worldRandom.entrySet()) { - worldRandomDataJson.addProperty(entry.getKey().toString(), entry.getValue().getSeed()); + worldListJson.addProperty(entry.getKey().toString(), entry.getValue().getSeed()); } + worldRandomDataJson.add("worldList", worldListJson); + + JsonObject lcgListJson = new JsonObject(); + Map lcgMap = KTRNGWorldHandler.getWorldLCGMap(); + for (Entry entry : lcgMap.entrySet()) { + lcgListJson.addProperty(entry.getKey().toString(), entry.getValue()); + } + + worldRandomDataJson.add("lcgList", lcgListJson); + dataToSave.add("worldRandom", worldRandomDataJson); return dataToSave; @@ -69,15 +81,26 @@ public void onLoadstateComplete(MinecraftServer server, JsonObject loadedData) { KTRNGEntityHandler.setRandomnessList(randomList); - JsonObject worldRandomListJson = loadedData.get("worldRandom").getAsJsonObject(); + JsonObject worldRandomJson = loadedData.get("worldRandom").getAsJsonObject(); + JsonObject worldListJson = worldRandomJson.get("worldList").getAsJsonObject(); Map worldList = new HashMap<>(); - for (Entry entry : worldRandomListJson.entrySet()) { + for (Entry entry : worldListJson.entrySet()) { int id = Integer.parseInt(entry.getKey()); WorldRandomness worldRandomness = new WorldRandomness(entry.getValue().getAsLong()); worldList.put(id, worldRandomness); } + + JsonObject worldLCGList = worldRandomJson.get("lcgList").getAsJsonObject(); + Map lcgList = new HashMap<>(); + for (Entry entry : worldLCGList.entrySet()) { + int id = Integer.parseInt(entry.getKey()); + int lcg = entry.getValue().getAsInt(); + + lcgList.put(id, lcg); + } + KTRNGWorldHandler.setWorldRandomnessMap(worldList); } diff --git a/src/main/resources/tasmod.accesswidener b/src/main/resources/tasmod.accesswidener index 7766c35b..1f287702 100644 --- a/src/main/resources/tasmod.accesswidener +++ b/src/main/resources/tasmod.accesswidener @@ -15,4 +15,5 @@ accessible field net/minecraft/client/settings/KeyBinding CATEGORY_ORDER Ljava/u #KillTheRNG accessible field net/minecraft/entity/Entity rand Ljava/util/Random; +accessible field net/minecraft/world/World updateLCG I mutable field net/minecraft/world/World rand Ljava/util/Random; \ No newline at end of file diff --git a/src/test/java/tasmod/killtherng/RNGTest.java b/src/test/java/tasmod/killtherng/RNGTest.java new file mode 100644 index 00000000..b969345e --- /dev/null +++ b/src/test/java/tasmod/killtherng/RNGTest.java @@ -0,0 +1,39 @@ +package tasmod.killtherng; + +import com.minecrafttas.tasmod.ktrng.RandomBase; + +public class RNGTest { + + public static void main(String[] args) { + long[] longlist = new long[] { + //@formatter:off + 113621727298730L, + 161845404674820L + //@formatter:on + }; + + printDistance(longlist); + + longlist = new long[] { + //@formatter:off + 161845404674820L, + 107865211428631L, + 252587169991970L, + 223075662074294L, + 66246869218509L, + 81210955942352L, + 183553865074233L, + 11371681017552L + //@formatter:on + }; +// printDistance(longlist); + } + + private static void printDistance(long[] list) { + long prev = list[0]; + for (long l : list) { + System.out.println(RandomBase.distance(prev, l)); + } + System.out.println(""); + } +} From 1e3e3e2d518f4b982ac89d0325d7317232c74765 Mon Sep 17 00:00:00 2001 From: Scribble Date: Wed, 19 Nov 2025 20:41:06 +0100 Subject: [PATCH 17/20] [KillTheRNG] Improve logging in RandomBase --- .../minecrafttas/tasmod/ktrng/RandomBase.java | 33 +++++++++++-------- .../tasmod/ktrng/WorldRandomness.java | 4 +-- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java b/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java index 19f636db..8f2be415 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/RandomBase.java @@ -29,13 +29,14 @@ public RandomBase(long seed) { this.initialSeed = seed; } + @Override public void setSeed(long seedIn) { - timesCalled = 0; - super.setSeed(seedIn ^ 0x5deece66dL); + setSeed(seedIn, true); } - public void setSeed(long seedIn, boolean shouldIncrease) { - timesCalled++; + public void setSeed(long seedIn, boolean shouldLog) { + if (shouldLog) + fireSetEvent("setSeed()", seedIn, "", 8); super.setSeed(seedIn ^ 0x5deece66dL); } @@ -76,7 +77,7 @@ public long nextLong() { timesCalled++; long seedstored = getSeed(); long value = super.nextLong(); - fireEvent(seedstored, Long.toString(value)); + fireGetEvent("nextLong()", seedstored, Long.toString(value)); return value; } @@ -85,7 +86,7 @@ public double nextDouble() { timesCalled++; long seedstored = getSeed(); double value = super.nextDouble(); - fireEvent(seedstored, Double.toString(value)); + fireGetEvent("nextDouble()", seedstored, Double.toString(value)); return value; } @@ -94,7 +95,7 @@ public boolean nextBoolean() { timesCalled++; long seedstored = getSeed(); boolean value = super.nextBoolean(); - fireEvent(seedstored, Boolean.toString(value)); + fireGetEvent("nextBoolean()", seedstored, Boolean.toString(value)); return value; } @@ -103,7 +104,7 @@ public int nextInt() { timesCalled++; long seedstored = getSeed(); int value = super.nextInt(); - fireEvent(seedstored, Integer.toString(value)); + fireGetEvent("nextInt()", seedstored, Integer.toString(value)); return value; } @@ -112,7 +113,7 @@ public int nextInt(int bound) { timesCalled++; long seedstored = getSeed(); int value = super.nextInt(bound); - fireEvent(seedstored, Integer.toString(value)); + fireGetEvent(String.format("nextInt(%s)", bound), seedstored, Integer.toString(value)); return value; } @@ -141,7 +142,7 @@ public void advance() { public void advance(long i) { JRand thing = JRand.ofInternalSeed(getSeed()); thing.advance(i); - setSeed(thing.getSeed()); + setSeed(thing.getSeed(), false); } public long getSeedAt(int steps) { @@ -180,11 +181,15 @@ public boolean equals(Object obj) { } } - public void fireEvent(long seed, String value) { - fireEvent(seed, value, 3); + public void fireSetEvent(String eventType, long seed, String value, int stackTraceOffset) { + fireEvent(eventType, seed, value, stackTraceOffset); + } + + public void fireGetEvent(String eventType, long seed, String value) { + //fireEvent(eventType, seed, value, 3); } - public void fireEvent(long seed, String value, int stackTraceOffset) { + public void fireEvent(String eventType, long seed, String value, int stackTraceOffset) { StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[stackTraceOffset]; String methodName = stackTraceElement.getMethodName(); String[] classNames = stackTraceElement.getClassName().split("\\."); @@ -194,7 +199,7 @@ public void fireEvent(long seed, String value, int stackTraceOffset) { String out = className + "." + methodName + (stackTraceElement.isNativeMethod() ? "(Native Method)" : (stackTraceElement.getFileName() != null && stackTraceElement.getLineNumber() >= 0 ? "(" + stackTraceElement.getFileName() + ":" + stackTraceElement.getLineNumber() + ")" : (stackTraceElement.getFileName() != null ? "(" + stackTraceElement.getFileName() + ")" : "(Unknown Source)"))); - TASmod.LOGGER.debug(LoggerMarkers.KillTheRNG, "{}\t{}\t{}", seed, value, out); + TASmod.LOGGER.debug(LoggerMarkers.KillTheRNG, "{} {}\t{}\t{}", eventType, seed, value, out); } public long getInitialSeed() { diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/WorldRandomness.java b/src/main/java/com/minecrafttas/tasmod/ktrng/WorldRandomness.java index 858fed59..01a51b7c 100644 --- a/src/main/java/com/minecrafttas/tasmod/ktrng/WorldRandomness.java +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/WorldRandomness.java @@ -13,7 +13,7 @@ public WorldRandomness() { } @Override - public void fireEvent(long seed, String value, int offset) { - //super.fireEvent(seed, value, 5); + public void fireEvent(String val, long seed, String value, int offset) { + //super.fireEvent(val, seed, value, 5); } } From d833ed9feddcc649f0167b19d5b7db0f6ef80b4c Mon Sep 17 00:00:00 2001 From: Scribble Date: Thu, 27 Nov 2025 21:20:47 +0100 Subject: [PATCH 18/20] [Tickrate] Remove processing the server task queue in Tickrate 0 --- .../tasmod/mixin/MixinMinecraftServer.java | 25 +++++++++---------- .../handlers/SavestateTempHandler.java | 4 +-- .../storage/builtin/KTRNGSeedStorage.java | 1 + 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraftServer.java b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraftServer.java index 5a57d75d..09876ee0 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraftServer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraftServer.java @@ -13,7 +13,6 @@ import com.minecrafttas.mctcommon.events.EventListenerRegistry; import com.minecrafttas.tasmod.TASmod; import com.minecrafttas.tasmod.events.EventServer.EventServerTickPost; -import com.minecrafttas.tasmod.savestates.SavestateHandlerServer.SavestateState; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -110,18 +109,18 @@ public void redirectThreadSleep(long msToTick) { TASmod.gameLoopSchedulerServer.runAllTasks(); - 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(); - } - } - } - } +// 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(); +// } +// } +// } +// } } @Environment(EnvType.SERVER) 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 619985e8..0474b760 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateTempHandler.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/handlers/SavestateTempHandler.java @@ -29,7 +29,7 @@ * * @author Scribble */ -public class SavestateTempHandler implements EventControllerStateChange, EventRecordClear, EventSavestate.EventServerLoadstate { +public class SavestateTempHandler implements EventControllerStateChange, EventRecordClear, EventSavestate.EventServerLoadstatePre { private final Logger logger; private final SavestateHandlerServer handler; @@ -149,7 +149,7 @@ public void setNoSave(boolean noSave) { } @Override - public void onServerLoadstate(MinecraftServer server, SavestatePaths paths) { + public void onServerLoadstatePre(MinecraftServer server, SavestatePaths paths) { createState = false; } } 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 0c0848b6..b1ee3dd6 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 @@ -64,6 +64,7 @@ public JsonObject onSavestate(MinecraftServer server, JsonObject dataToSave) { @Override public void onLoadstateComplete(MinecraftServer server, JsonObject loadedData) { + TASmod.LOGGER.debug("Loading KTRNG seeds"); long newSeed = loadedData.get("globalSeed").getAsLong(); TASmod.globalRandomness.setSeed(newSeed); From 813d919b8e8dcae6be5a638109b6bfd26459d7d1 Mon Sep 17 00:00:00 2001 From: Scribble Date: Mon, 1 Dec 2025 21:57:35 +0100 Subject: [PATCH 19/20] [KillTheRNG] Started adding MathRandomness --- .../java/com/minecrafttas/tasmod/TASmod.java | 4 ++++ .../tasmod/ktrng/MathRandomness.java | 19 +++++++++++++++++ .../killtherng/mathrand/MixinEntityItem.java | 21 +++++++++++++++++++ .../mathrand/MixinEntityLivingBase.java | 19 +++++++++++++++++ .../storage/builtin/KTRNGSeedStorage.java | 4 ++++ src/main/resources/tasmod.mixin.json | 4 +++- 6 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/minecrafttas/tasmod/ktrng/MathRandomness.java create mode 100644 src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityItem.java create mode 100644 src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityLivingBase.java diff --git a/src/main/java/com/minecrafttas/tasmod/TASmod.java b/src/main/java/com/minecrafttas/tasmod/TASmod.java index 53a386de..302f0860 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmod.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmod.java @@ -26,6 +26,7 @@ import com.minecrafttas.tasmod.commands.CommandTickrate; import com.minecrafttas.tasmod.handlers.PlayUntilHandler; import com.minecrafttas.tasmod.ktrng.GlobalRandomnessTimer; +import com.minecrafttas.tasmod.ktrng.MathRandomness; import com.minecrafttas.tasmod.playback.PlaybackControllerServer; import com.minecrafttas.tasmod.playback.metadata.builtin.StartpositionMetadataExtension; import com.minecrafttas.tasmod.registries.TASmodAPIRegistry; @@ -92,6 +93,8 @@ public class TASmod implements ModInitializer, EventServerStart, EventServerInit public static KTRNGSeedStorage seedStorage = new KTRNGSeedStorage(); + public static MathRandomness mathRandomness = new MathRandomness(0); + @Override public void onInitialize() { @@ -144,6 +147,7 @@ public void onInitialize() { public void onServerStart(MinecraftServer server) { globalRandomness = new GlobalRandomnessTimer(); EventListenerRegistry.register(globalRandomness); + mathRandomness = new MathRandomness(); } @Override diff --git a/src/main/java/com/minecrafttas/tasmod/ktrng/MathRandomness.java b/src/main/java/com/minecrafttas/tasmod/ktrng/MathRandomness.java new file mode 100644 index 00000000..686b5f91 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/ktrng/MathRandomness.java @@ -0,0 +1,19 @@ +package com.minecrafttas.tasmod.ktrng; + +import com.minecrafttas.tasmod.TASmod; + +/** + *

Randomness instance for hooking into {@link Math#random()} + * + * @author Scribble + */ +public class MathRandomness extends RandomBase { + + public MathRandomness() { + super(TASmod.globalRandomness.getCurrentSeed()); + } + + public MathRandomness(long seed) { + super(seed); + } +} 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 new file mode 100644 index 00000000..c863101c --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityItem.java @@ -0,0 +1,21 @@ +package com.minecrafttas.tasmod.mixin.killtherng.mathrand; + +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 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) { + System.out.println("Test"); + return TASmod.mathRandomness.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 new file mode 100644 index 00000000..95f705a1 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityLivingBase.java @@ -0,0 +1,19 @@ +package com.minecrafttas.tasmod.mixin.killtherng.mathrand; + +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 net.minecraft.entity.EntityLivingBase; + +@Mixin(EntityLivingBase.class) +public class MixinEntityLivingBase { + + @WrapOperation(method = "attackEntityFrom", at = @At(value = "INVOKE", target = "Ljava/lang/Math;random()D")) + private double wrap_attackEntityFrom(Operation original) { + return TASmod.mathRandomness.nextDouble(); + } +} 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 b1ee3dd6..4a2324a5 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 @@ -59,6 +59,8 @@ public JsonObject onSavestate(MinecraftServer server, JsonObject dataToSave) { dataToSave.add("worldRandom", worldRandomDataJson); + dataToSave.addProperty("mathRandom", Long.toString(TASmod.mathRandomness.getSeed())); + return dataToSave; } @@ -103,6 +105,8 @@ public void onLoadstateComplete(MinecraftServer server, JsonObject loadedData) { } KTRNGWorldHandler.setWorldRandomnessMap(worldList); + + TASmod.mathRandomness.setSeed(loadedData.get("mathRandom").getAsLong()); } @Override diff --git a/src/main/resources/tasmod.mixin.json b/src/main/resources/tasmod.mixin.json index f7c7ec7b..59d2f410 100644 --- a/src/main/resources/tasmod.mixin.json +++ b/src/main/resources/tasmod.mixin.json @@ -24,7 +24,9 @@ "fixes.MixinDragonFightManager", "killtherng.MixinEntity", - "killtherng.MixinWorld" + "killtherng.MixinWorld", + "killtherng.mathrand.MixinEntityLivingBase", + "killtherng.mathrand.MixinEntityItem" ], "client": [ From b1bbf87066161ec1fa04f61f96bbdc209a713da5 Mon Sep 17 00:00:00 2001 From: Scribble Date: Tue, 2 Dec 2025 19:25:54 +0100 Subject: [PATCH 20/20] [KillTheRNG] Finish MathRandomness --- .../tasmod/mixin/MixinMinecraftServer.java | 25 ++++++++++--------- .../killtherng/mathrand/MixinEntityItem.java | 1 - .../mathrand/MixinEntityLivingBase.java | 6 +++++ .../mathrand/MixinEntityTNTPrimed.java | 21 ++++++++++++++++ .../killtherng/mathrand/MixinEntityXPOrb.java | 20 +++++++++++++++ .../mathrand/MixinWorldEntitySpawner.java | 20 +++++++++++++++ src/main/resources/tasmod.mixin.json | 5 +++- 7 files changed, 84 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityTNTPrimed.java create mode 100644 src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityXPOrb.java create mode 100644 src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinWorldEntitySpawner.java diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraftServer.java b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraftServer.java index 09876ee0..5a57d75d 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraftServer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraftServer.java @@ -13,6 +13,7 @@ import com.minecrafttas.mctcommon.events.EventListenerRegistry; import com.minecrafttas.tasmod.TASmod; import com.minecrafttas.tasmod.events.EventServer.EventServerTickPost; +import com.minecrafttas.tasmod.savestates.SavestateHandlerServer.SavestateState; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -109,18 +110,18 @@ public void redirectThreadSleep(long msToTick) { TASmod.gameLoopSchedulerServer.runAllTasks(); -// 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(); -// } -// } -// } -// } + 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(); + } + } + } + } } @Environment(EnvType.SERVER) 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 c863101c..a94c9bf5 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 @@ -15,7 +15,6 @@ 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) { - System.out.println("Test"); return TASmod.mathRandomness.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 95f705a1..2d882de9 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 @@ -8,10 +8,16 @@ import com.minecrafttas.tasmod.TASmod; 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(); + } + @WrapOperation(method = "attackEntityFrom", at = @At(value = "INVOKE", target = "Ljava/lang/Math;random()D")) private double wrap_attackEntityFrom(Operation original) { return TASmod.mathRandomness.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 new file mode 100644 index 00000000..bd8fec2d --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityTNTPrimed.java @@ -0,0 +1,21 @@ +package com.minecrafttas.tasmod.mixin.killtherng.mathrand; + +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 net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.item.EntityTNTPrimed; +import net.minecraft.world.World; + +@Mixin(EntityTNTPrimed.class) +public class MixinEntityTNTPrimed { + + @WrapOperation(method = "", 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(); + } +} 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 new file mode 100644 index 00000000..ed776195 --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinEntityXPOrb.java @@ -0,0 +1,20 @@ +package com.minecrafttas.tasmod.mixin.killtherng.mathrand; + +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 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(); + } +} 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 new file mode 100644 index 00000000..e4c718ca --- /dev/null +++ b/src/main/java/com/minecrafttas/tasmod/mixin/killtherng/mathrand/MixinWorldEntitySpawner.java @@ -0,0 +1,20 @@ +package com.minecrafttas.tasmod.mixin.killtherng.mathrand; + +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 net.minecraft.world.WorldEntitySpawner; +import net.minecraft.world.WorldServer; + +@Mixin(WorldEntitySpawner.class) +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 TASmod.mathRandomness.nextDouble(); + } +} diff --git a/src/main/resources/tasmod.mixin.json b/src/main/resources/tasmod.mixin.json index 59d2f410..2daed941 100644 --- a/src/main/resources/tasmod.mixin.json +++ b/src/main/resources/tasmod.mixin.json @@ -26,7 +26,10 @@ "killtherng.MixinEntity", "killtherng.MixinWorld", "killtherng.mathrand.MixinEntityLivingBase", - "killtherng.mathrand.MixinEntityItem" + "killtherng.mathrand.MixinEntityItem", + "killtherng.mathrand.MixinEntityXPOrb", + "killtherng.mathrand.MixinEntityTNTPrimed", + "killtherng.mathrand.MixinWorldEntitySpawner" ], "client": [