package ru.dbotthepony.mc.prng; import it.unimi.dsi.fastutil.HashCommon; import net.minecraft.util.Mth; import net.minecraft.util.RandomSource; import net.minecraft.world.level.levelgen.PositionalRandomFactory; import net.minecraft.world.level.levelgen.RandomSupport; import org.jetbrains.annotations.NotNull; import java.util.concurrent.locks.ReentrantLock; public class SynchronizedGJRAND64RandomSource extends GJRAND64RandomSource { private final ReentrantLock lock = new ReentrantLock(); public SynchronizedGJRAND64RandomSource() { super(); } public SynchronizedGJRAND64RandomSource(long seed) { super(seed); } public SynchronizedGJRAND64RandomSource(long seed0, long seed1) { super(seed0, seed1); } public SynchronizedGJRAND64RandomSource(RandomSupport.Seed128bit seed) { super(seed); } @Override public long nextLong() { lock.lock(); long result = super.nextLong(); lock.unlock(); return result; } @Override public void setSeed(long l) { lock.lock(); super.setSeed(l); lock.unlock(); } @Override public double nextGaussian() { lock.lock(); double value = super.nextGaussian(); lock.unlock(); return value; } @Override public @NotNull RandomSource fork() { return new SynchronizedGJRAND64RandomSource(nextLong(), nextLong()); } @Override public @NotNull PositionalRandomFactory forkPositional() { return new Positional(nextLong(), nextLong()); } public static class Positional implements PositionalRandomFactory { private final long seed0; private final long seed1; public Positional(long seed0, long seed1) { this.seed0 = seed0; this.seed1 = seed1; } @Override public @NotNull RandomSource fromHashOf(@NotNull String s) { long seed = HashCommon.murmurHash3((long) s.hashCode() & 0xFFFFFFFFL); return new SynchronizedGJRAND64RandomSource(seed0 ^ Long.rotateLeft(seed, 32), seed1 ^ seed); } @Override public @NotNull RandomSource fromSeed(long l) { return new SynchronizedGJRAND64RandomSource(l); } @Override public @NotNull RandomSource at(int x, int y, int z) { long seed = Mth.getSeed(x, y, z); return new SynchronizedGJRAND64RandomSource(seed0 ^ Long.rotateLeft(seed, 32), seed1 ^ seed); } @Override public void parityConfigString(@NotNull StringBuilder stringBuilder) { throw new UnsupportedOperationException(); } } }