diff --git a/src/main/java/kaptainwutax/seedcracker/SeedCracker.java b/src/main/java/kaptainwutax/seedcracker/SeedCracker.java index ec9dc5f..be6062a 100644 --- a/src/main/java/kaptainwutax/seedcracker/SeedCracker.java +++ b/src/main/java/kaptainwutax/seedcracker/SeedCracker.java @@ -6,13 +6,9 @@ import kaptainwutax.seedcracker.cracker.population.DecoratorData; import kaptainwutax.seedcracker.finder.FinderQueue; import kaptainwutax.seedcracker.render.RenderQueue; import kaptainwutax.seedcracker.util.Log; -import kaptainwutax.seedcracker.util.Rand; import net.fabricmc.api.ModInitializer; -import net.minecraft.util.math.BlockBox; -import net.minecraft.util.math.ChunkPos; import net.minecraft.world.gen.ChunkRandom; -import net.minecraft.world.gen.feature.Feature; -import net.minecraft.world.gen.feature.StrongholdFeature; +import net.minecraft.world.level.LevelProperties; import java.util.ArrayList; import java.util.List; @@ -22,6 +18,8 @@ public class SeedCracker implements ModInitializer { private static final SeedCracker INSTANCE = new SeedCracker(); + public long hashedWorldSeed = -1; + public List worldSeeds = null; public Set structureSeeds = null; public List pillarSeeds = null; @@ -31,21 +29,18 @@ public class SeedCracker implements ModInitializer { private List decoratorCache = new ArrayList<>(); private List biomeCache = new ArrayList<>(); - @Override + @Override public void onInitialize() { RenderQueue.get().add("hand", FinderQueue.get()::renderFinders); DecoratorCache.get().initialize(); } - private void checkWorldSeed(long worldSeed, ChunkPos pos) { - StrongholdFeature.Start start = new StrongholdFeature.Start(Feature.STRONGHOLD, pos.x, pos.z, BlockBox.empty(), 0, worldSeed); - } - public static SeedCracker get() { return INSTANCE; } public void clear() { + this.hashedWorldSeed = -1; this.worldSeeds = null; this.structureSeeds = null; this.pillarSeeds = null; @@ -134,6 +129,27 @@ public class SeedCracker implements ModInitializer { if(this.worldSeeds == null && this.structureSeeds != null && this.biomeCache.size() >= 5) { this.worldSeeds = new ArrayList<>(); + + if(this.hashedWorldSeed != -1) { + Log.warn("SHA2 seed was found."); + Log.warn("Looking for world seeds with hash [" + this.hashedWorldSeed + "]."); + + for(long structureSeed: this.structureSeeds) { + for(long j = 0; j < (1L << 16); j++) { + long worldSeed = (j << 48) | structureSeed; + long hash = LevelProperties.sha256Hash(worldSeed); + + if(hash == this.hashedWorldSeed) { + this.worldSeeds.add(worldSeed); + Log.warn("Finished search with " + this.worldSeeds + (this.worldSeeds.size() == 1 ? " seed." : " seeds.")); + return added; + } + } + } + + Log.error("Finished search with no seeds, reverting to biomes."); + } + Log.warn("Looking for world seeds with " + this.biomeCache.size() + " biomes."); this.structureSeeds.forEach(structureSeed -> { @@ -144,7 +160,7 @@ public class SeedCracker implements ModInitializer { FakeBiomeSource fakeBiomeSource = new FakeBiomeSource(worldSeed); for(BiomeData data : this.biomeCache) { - if (!data.test(fakeBiomeSource)) { + if(!data.test(fakeBiomeSource)) { goodSeed = false; break; } @@ -180,119 +196,4 @@ public class SeedCracker implements ModInitializer { return added; } - public static void main(String[] args) throws Exception { - for(int i = 0; i < 10000; i++) { - Rand rand = new Rand(i, false); - if(rand.nextInt(700) == 0)System.out.println(i); - } - - /*Random rand = new Random(1234L); - - IntStream.range(0, 8).mapToObj((int_1x) -> { - int int_2 = rand.nextInt(16); - int int_3 = rand.nextInt(256); - int int_4 = rand.nextInt(16); - System.out.println("Created " + int_2 + ", " + int_3 + ", " + int_4); - return new BlockPos(int_2, int_3, int_4); - }).forEach(pos -> { - System.out.println("Populating " + pos); - });*/ - - /* - System.out.println(validSeed(65867021031296932L)); - - BufferedReader reader = new BufferedReader(new FileReader("run/seeds.txt")); - BufferedWriter writer = new BufferedWriter(new FileWriter("run/kaktoos14.txt")); - - while(reader.ready()) { - long seed = Long.parseLong(reader.readLine().split(Pattern.quote(" "))[0]); - seed ^= Rand.JAVA_LCG.multiplier; - seed -= 60007; - - writer.write(seed + "===========================================\n"); - - for(int i = 0; i < (1 << 16); i++) { - long worldSeed = seed | ((long)i << 48); - - BiomeLayerSampler sampler = BiomeLayers.build(worldSeed, LevelGeneratorType.DEFAULT, - BiomeSourceType.VANILLA_LAYERED.getConfig().getGeneratorSettings())[1]; - - if(sampler.sample(8, 8) == Biomes.DESERT) { - writer.write(worldSeed + "\n"); - } - } - - writer.flush(); - } - - writer.close();*/ - } - - /* - private static List initialize(long worldSeed) { - BiomeLayerSampler sampler = BiomeLayers.build(worldSeed, LevelGeneratorType.DEFAULT, - BiomeSourceType.VANILLA_LAYERED.getConfig().getGeneratorSettings())[0]; - - List startPositions = new ArrayList<>(); - List validBiomes = Lists.newArrayList(); - Iterator biomeIterator = Registry.BIOME.iterator(); - - while(biomeIterator.hasNext()) { - Biome biome = (Biome)biomeIterator.next(); - if(biome != null && biome.hasStructureFeature(Feature.STRONGHOLD)) { - validBiomes.add(biome); - } - } - - Random rand = new Random(worldSeed); - double randomRadian = rand.nextDouble() * Math.PI * 2.0D; - - //Actually 128, but we don't care about all of them. - for(int i = 0; i < 3; ++i) { - double double_2 = 128.0D + (rand.nextDouble() - 0.5D) * 80.0D; - int x = (int)Math.round(Math.cos(randomRadian) * double_2); - int z = (int)Math.round(Math.sin(randomRadian) * double_2); - - BlockPos locatedPos = locateBiome(sampler, (x << 4) + 8, (z << 4) + 8, 112, validBiomes, rand); - - if(locatedPos != null) { - x = locatedPos.getX() >> 4; - z = locatedPos.getZ() >> 4; - } - - startPositions.add(new ChunkPos(x, z)); - randomRadian += (Math.PI * 2.0D) / 3.0d; - } - - return startPositions; - }./ - - //CHECK NEW 1.15 SAMPLER - /* - public static BlockPos locateBiome(BiomeLayerSampler sampler, int x, int z, int size, List validBiomes, Random rand) { - int int_4 = x - size >> 2; - int int_5 = z - size >> 2; - int int_6 = x + size >> 2; - int int_7 = z + size >> 2; - int int_8 = int_6 - int_4 + 1; - int int_9 = int_7 - int_5 + 1; - Biome[] biomeSample = sampler.sample(int_4, int_5, int_8, int_9); - BlockPos pos = null; - int int_10 = 0; - - for(int i = 0; i < int_8 * int_9; ++i) { - int int_12 = int_4 + i % int_8 << 2; - int int_13 = int_5 + i / int_8 << 2; - if (validBiomes.contains(biomeSample[i])) { - if(pos == null || rand.nextInt(int_10 + 1) == 0) { - pos = new BlockPos(int_12, 0, int_13); - } - - ++int_10; - } - } - - return pos; - }*/ - } diff --git a/src/main/java/kaptainwutax/seedcracker/cracker/PillarData.java b/src/main/java/kaptainwutax/seedcracker/cracker/PillarData.java index acba647..ba1c7d9 100644 --- a/src/main/java/kaptainwutax/seedcracker/cracker/PillarData.java +++ b/src/main/java/kaptainwutax/seedcracker/cracker/PillarData.java @@ -7,39 +7,39 @@ import java.util.Random; public class PillarData { - private List heights; + private List heights; - public PillarData(List heights) { - this.heights = heights; - } + public PillarData(List heights) { + this.heights = heights; + } - public List getPillarSeeds() { - List result = new ArrayList<>(); + public List getPillarSeeds() { + List result = new ArrayList<>(); - for(int pillarSeed = 0; pillarSeed < (1 << 16); pillarSeed++) { - List h = this.getPillarHeights(pillarSeed); - if(h.equals(heights))result.add(pillarSeed); - } + for(int pillarSeed = 0; pillarSeed < (1 << 16); pillarSeed++) { + List h = this.getPillarHeights(pillarSeed); + if(h.equals(this.heights)) result.add(pillarSeed); + } - return result; - } + return result; + } - public List getPillarHeights(int spikeSeed) { - List indices = new ArrayList<>(); + public List getPillarHeights(int spikeSeed) { + List indices = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - indices.add(i); - } + for(int i = 0; i < 10; i++) { + indices.add(i); + } - Collections.shuffle(indices, new Random(spikeSeed)); + Collections.shuffle(indices, new Random(spikeSeed)); - List heights = new ArrayList<>(); + List heights = new ArrayList<>(); - for (Integer index: indices) { - heights.add(76 + index * 3); - } + for(Integer index : indices) { + heights.add(76 + index * 3); + } - return heights; - } + return heights; + } } diff --git a/src/main/java/kaptainwutax/seedcracker/feature/decoration/DecorationFeature.java b/src/main/java/kaptainwutax/seedcracker/feature/decoration/DecorationFeature.java deleted file mode 100644 index 811406e..0000000 --- a/src/main/java/kaptainwutax/seedcracker/feature/decoration/DecorationFeature.java +++ /dev/null @@ -1,23 +0,0 @@ -package kaptainwutax.seedcracker.feature.decoration; - -import net.minecraft.block.Block; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; - -public abstract class DecorationFeature { - - protected World world; - protected BlockPos pos; - - public DecorationFeature(World world, BlockPos pos) { - this.world = world; - this.pos = pos; - } - - public abstract void reverseSeed(); - - public Block getBlockAt(BlockPos pos) { - return this.world.getBlockState(pos).getBlock(); - } - -} diff --git a/src/main/java/kaptainwutax/seedcracker/feature/decoration/DungeonFeature.java b/src/main/java/kaptainwutax/seedcracker/feature/decoration/DungeonFeature.java deleted file mode 100644 index 6b33bf6..0000000 --- a/src/main/java/kaptainwutax/seedcracker/feature/decoration/DungeonFeature.java +++ /dev/null @@ -1,91 +0,0 @@ -package kaptainwutax.seedcracker.feature.decoration; - -import kaptainwutax.seedcracker.util.Rand; -import net.minecraft.block.Block; -import net.minecraft.block.Blocks; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3i; -import net.minecraft.world.World; - -import java.util.ArrayList; -import java.util.List; - -public class DungeonFeature extends DecorationFeature { - - private static int MOSSY_COBBLESTONE_CALL = 0; - private static int COBBLESTONE_CALL = 1; - - public DungeonFeature(World world, BlockPos pos) { - super(world, pos); - } - - @Override - public void reverseSeed() { - BlockPos decoratorPos = this.getLocalPos(this.pos); - Vec3i dungeonSize = this.getDungeonSize(this.pos); - - List floorCalls = new ArrayList<>(); - - for(int xo = -dungeonSize.getX(); xo <= dungeonSize.getX(); xo++) { - for(int zo = -dungeonSize.getZ(); zo <= dungeonSize.getZ(); zo++) { - Block block = this.world.getBlockState(this.pos.add(xo, -1, zo)).getBlock(); - - if(block == Blocks.MOSSY_COBBLESTONE) { - floorCalls.add(MOSSY_COBBLESTONE_CALL); - } else if(block == Blocks.COBBLESTONE) { - floorCalls.add(COBBLESTONE_CALL); - } - } - } - - List dungeonSeeds = this.getDungeonSeeds(dungeonSize, floorCalls); - List decoratorSeeds = new ArrayList<>(); - - for(long dungeonSeed: dungeonSeeds) { - long decoratorSeed = Rand.JAVA_LCG.combine(-3).nextSeed(dungeonSeed); - Rand rand = new Rand(decoratorSeed, false); - if(rand.nextInt(16) != decoratorPos.getX())continue; - if(rand.nextInt(256) != decoratorPos.getY())continue; - if(rand.nextInt(16) != decoratorPos.getZ())continue; - decoratorSeeds.add(decoratorSeed); - } - - decoratorSeeds.forEach(System.out::println); - } - - public BlockPos getLocalPos(BlockPos pos) { - return new BlockPos(pos.getX() & 15, pos.getY(), pos.getZ() & 15); - } - - public Vec3i getDungeonSize(BlockPos spawnerPos) { - for(int xo = 4; xo >= 3; xo--) { - for(int zo = 4; zo >= 3; zo--) { - Block block = this.getBlockAt(spawnerPos.add(xo, -1, zo)); - if(block != Blocks.MOSSY_COBBLESTONE)continue; - if(block != Blocks.COBBLESTONE)continue; - return new Vec3i(xo, 0, zo); - } - } - - return Vec3i.ZERO; - } - - public List getDungeonSeeds(Vec3i dungeonSize, List floorCalls) { - List floorSeeds = new ArrayList<>(); - - //TODO: Lattice magic to find floorSeeds from floorCalls. - - List dungeonSeeds = new ArrayList<>(); - - for(long floorSeed: floorSeeds) { - long dungeonSeed = Rand.JAVA_LCG.combine(-2).nextSeed(floorSeed); - Rand rand = new Rand(dungeonSeed, false); - if(rand.nextInt(2) + 3 != dungeonSize.getX())continue; - if(rand.nextInt(2) + 3 != dungeonSize.getZ())continue; - dungeonSeeds.add(dungeonSeed); - } - - return dungeonSeeds; - } - -} diff --git a/src/main/java/kaptainwutax/seedcracker/mixin/ClientPlayNetworkHandlerMixin.java b/src/main/java/kaptainwutax/seedcracker/mixin/ClientPlayNetworkHandlerMixin.java index fc75998..f88eca7 100644 --- a/src/main/java/kaptainwutax/seedcracker/mixin/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/kaptainwutax/seedcracker/mixin/ClientPlayNetworkHandlerMixin.java @@ -2,6 +2,7 @@ package kaptainwutax.seedcracker.mixin; import com.mojang.authlib.GameProfile; import com.mojang.brigadier.CommandDispatcher; +import kaptainwutax.seedcracker.SeedCracker; import kaptainwutax.seedcracker.command.ClientCommands; import kaptainwutax.seedcracker.finder.FinderQueue; import net.minecraft.client.MinecraftClient; @@ -9,6 +10,7 @@ import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.network.packet.ChunkDataS2CPacket; import net.minecraft.client.network.packet.CommandTreeS2CPacket; +import net.minecraft.client.network.packet.PlayerRespawnS2CPacket; import net.minecraft.client.world.ClientWorld; import net.minecraft.network.ClientConnection; import net.minecraft.server.command.CommandSource; @@ -44,4 +46,9 @@ public abstract class ClientPlayNetworkHandlerMixin { ClientCommands.registerCommands((CommandDispatcher)(Object)this.commandDispatcher); } + @Inject(method = "onPlayerRespawn", at = @At("HEAD")) + public void onPlayerRespawn(PlayerRespawnS2CPacket packet, CallbackInfo ci) { + SeedCracker.get().hashedWorldSeed = packet.method_22425(); + } + }