From 6ea0bb30e0ea0e6a3724cf6dd84820c28841ece8 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sun, 22 Nov 2020 07:27:24 -0500 Subject: [PATCH] VANILLA STRUCTURES --- pom.xml | 2 +- .../volmit/iris/generator/IrisComplex.java | 2 +- .../com/volmit/iris/generator/IrisEngine.java | 8 +- .../iris/generator/IrisEngineCompound.java | 27 +- src/main/java/com/volmit/iris/nms/INMS.java | 6 +- .../java/com/volmit/iris/nms/INMSBinding.java | 3 + .../ChunkGeneratorAbstract_16_2_PAPER.java | 591 ++++++++++++++++++ .../volmit/iris/nms/v16_2/NMSBinding16_2.java | 26 + .../volmit/iris/nms/v16_2/NMSCreator16_2.java | 264 ++++++++ .../nms/v16_2/WorldChunkManagerIris16_2.java | 56 ++ .../ChunkGeneratorAbstract_16_3_PAPER.java | 591 ++++++++++++++++++ .../volmit/iris/nms/v16_3/NMSBinding16_3.java | 26 + .../volmit/iris/nms/v16_3/NMSCreator16_3.java | 266 ++++++++ .../nms/v16_3/WorldChunkManagerIris16_3.java | 56 ++ .../com/volmit/iris/nms/v1X/NMSBinding1X.java | 9 +- .../com/volmit/iris/object/IrisDimension.java | 44 +- .../iris/object/IrisDimensionIndex.java | 4 + .../com/volmit/iris/object/IrisRegion.java | 42 +- .../volmit/iris/scaffold/engine/Engine.java | 2 +- .../engine/EngineCompositeGenerator.java | 130 +++- .../iris/scaffold/engine/EngineCompound.java | 29 +- .../com/volmit/iris/scaffold/hunk/Hunk.java | 46 +- .../scaffold/hunk/view/FringedHunkView.java | 50 ++ 23 files changed, 2256 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/volmit/iris/nms/v16_2/ChunkGeneratorAbstract_16_2_PAPER.java create mode 100644 src/main/java/com/volmit/iris/nms/v16_2/NMSBinding16_2.java create mode 100644 src/main/java/com/volmit/iris/nms/v16_2/NMSCreator16_2.java create mode 100644 src/main/java/com/volmit/iris/nms/v16_2/WorldChunkManagerIris16_2.java create mode 100644 src/main/java/com/volmit/iris/nms/v16_3/ChunkGeneratorAbstract_16_3_PAPER.java create mode 100644 src/main/java/com/volmit/iris/nms/v16_3/NMSBinding16_3.java create mode 100644 src/main/java/com/volmit/iris/nms/v16_3/NMSCreator16_3.java create mode 100644 src/main/java/com/volmit/iris/nms/v16_3/WorldChunkManagerIris16_3.java create mode 100644 src/main/java/com/volmit/iris/scaffold/hunk/view/FringedHunkView.java diff --git a/pom.xml b/pom.xml index 56868ec86..5d0fd0215 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.volmit Iris - 1.1 + 1.1.1 Iris false diff --git a/src/main/java/com/volmit/iris/generator/IrisComplex.java b/src/main/java/com/volmit/iris/generator/IrisComplex.java index cb989e771..fc048e540 100644 --- a/src/main/java/com/volmit/iris/generator/IrisComplex.java +++ b/src/main/java/com/volmit/iris/generator/IrisComplex.java @@ -138,7 +138,7 @@ public class IrisComplex implements DataProvider .convertCached((s) -> data.getBiomeLoader().load(s) .setInferredType(InferredType.SHORE)) ).convertAware2D(ProceduralStream::get).cache2D(cacheSize); - bridgeStream = engine.getDimension().getContinentalStyle().create(rng.nextRNG()).stream() + bridgeStream = engine.getDimension().getContinentalStyle().create(rng.nextRNG()).bake().scale(1D / engine.getDimension().getContinentZoom()).bake().stream() .convert((v) -> v >= engine.getDimension().getLandChance() ? InferredType.SEA : InferredType.LAND); baseBiomeStream = bridgeStream.convertAware2D((t, x, z) -> t.equals(InferredType.SEA) ? seaBiomeStream.get(x, z) : landBiomeStream.get(x, z)) diff --git a/src/main/java/com/volmit/iris/generator/IrisEngine.java b/src/main/java/com/volmit/iris/generator/IrisEngine.java index d58fc23a4..a436876d1 100644 --- a/src/main/java/com/volmit/iris/generator/IrisEngine.java +++ b/src/main/java/com/volmit/iris/generator/IrisEngine.java @@ -95,12 +95,14 @@ public class IrisEngine extends BlockPopulator implements Engine } @Override - public void generate(int x, int z, Hunk vblocks, Hunk vbiomes) { + public void generate(int x, int z, Hunk vblocks, Hunk postblocks, Hunk vbiomes) { try { PrecisionStopwatch p = PrecisionStopwatch.start(); Hunk biomes = vbiomes; Hunk blocks = vblocks.synchronize().listen((xx,y,zz,t) -> catchBlockUpdates(x+xx,y+getMinHeight(),z+zz, t)); + Hunk pblocks = postblocks.synchronize().listen((xx,y,zz,t) -> catchBlockUpdates(x+xx,y+getMinHeight(),z+zz, t)); + Hunk fringe = Hunk.fringe(blocks, pblocks); MultiBurst.burst.burst( () -> getFramework().getEngineParallax().generateParallaxArea(x, z), @@ -114,10 +116,10 @@ public class IrisEngine extends BlockPopulator implements Engine MultiBurst.burst.burst( () -> getFramework().getDepositModifier().modify(x, z, blocks), () -> getFramework().getPostModifier().modify(x, z, blocks), - () -> getFramework().getDecorantActuator().actuate(x, z, blocks) + () -> getFramework().getDecorantActuator().actuate(x, z, fringe) ); - getFramework().getEngineParallax().insertParallax(x, z, blocks); + getFramework().getEngineParallax().insertParallax(x, z, fringe); getFramework().recycle(); getMetrics().getTotal().put(p.getMilliseconds()); } diff --git a/src/main/java/com/volmit/iris/generator/IrisEngineCompound.java b/src/main/java/com/volmit/iris/generator/IrisEngineCompound.java index 72023cba9..183474865 100644 --- a/src/main/java/com/volmit/iris/generator/IrisEngineCompound.java +++ b/src/main/java/com/volmit/iris/generator/IrisEngineCompound.java @@ -32,6 +32,8 @@ public class IrisEngineCompound implements EngineCompound { private final AtomicRollingSequence wallClock; + private Engine defaultEngine; + @Getter private final EngineData engineMetadata; @@ -69,6 +71,7 @@ public class IrisEngineCompound implements EngineCompound { { burster = null; engines = new Engine[]{new IrisEngine(new EngineTarget(world, rootDimension, data, 256, maximumThreads), this, 0)}; + defaultEngine = engines[0]; } else @@ -97,6 +100,16 @@ public class IrisEngineCompound implements EngineCompound { engines[i] = new IrisEngine(new EngineTarget(world, dimension, data.copy(), (int)Math.floor(256D * (index.getWeight() / totalWeight)), index.isInverted(), threadDist), this, i); engines[i].setMinHeight(buf); buf += engines[i].getHeight(); + + if(index.isPrimary()) + { + defaultEngine = engines[i]; + } + } + + if(defaultEngine == null) + { + defaultEngine = engines[0]; } } @@ -194,12 +207,12 @@ public class IrisEngineCompound implements EngineCompound { } @Override - public void generate(int x, int z, Hunk blocks, Hunk biomes) + public void generate(int x, int z, Hunk blocks, Hunk postblocks, Hunk biomes) { PrecisionStopwatch p = PrecisionStopwatch.start(); if(engines.length == 1 && !getEngine(0).getTarget().isInverted()) { - engines[0].generate(x, z, blocks, biomes); + engines[0].generate(x, z, blocks, postblocks, biomes); } else @@ -216,15 +229,18 @@ public class IrisEngineCompound implements EngineCompound { int doffset = offset; int height = engine.getTarget().getHeight(); AtomicReference> cblock = new AtomicReference<>(Hunk.newArrayHunk(16, height, 16)); + AtomicReference> cpblock = new AtomicReference<>(Hunk.newArrayHunk(16, height, 16)); AtomicReference> cbiome = new AtomicReference<>(Hunk.newArrayHunk(16, height, 16)); cblock.set(engine.getTarget().isInverted() ? cblock.get().invertY() : cblock.get()); + cpblock.set(engine.getTarget().isInverted() ? cpblock.get().invertY() : cpblock.get()); cbiome.set(engine.getTarget().isInverted() ? cbiome.get().invertY() : cbiome.get()); e.queue(() -> { - engine.generate(x, z, cblock.get(), cbiome.get()); + engine.generate(x, z, cblock.get(), cpblock.get(), cbiome.get()); synchronized (insert) { insert[index.get()] = () -> { blocks.insert(0, doffset, 0, cblock.get()); + postblocks.insert(0, doffset, 0, cpblock.get()); biomes.insert(0, doffset, 0, cbiome.get()); }; } @@ -270,6 +286,11 @@ public class IrisEngineCompound implements EngineCompound { return false; } + @Override + public Engine getDefaultEngine() { + return defaultEngine; + } + @Override public void hotload() { for(int i = 0; i < getSize(); i++) diff --git a/src/main/java/com/volmit/iris/nms/INMS.java b/src/main/java/com/volmit/iris/nms/INMS.java index f436f3e41..d765f0171 100644 --- a/src/main/java/com/volmit/iris/nms/INMS.java +++ b/src/main/java/com/volmit/iris/nms/INMS.java @@ -2,6 +2,8 @@ package com.volmit.iris.nms; import com.volmit.iris.Iris; import com.volmit.iris.IrisSettings; +import com.volmit.iris.nms.v16_2.NMSBinding16_2; +import com.volmit.iris.nms.v16_3.NMSBinding16_3; import com.volmit.iris.nms.v1X.NMSBinding1X; import com.volmit.iris.util.KMap; import org.bukkit.Bukkit; @@ -10,7 +12,9 @@ public class INMS { //@builder private static final KMap> bindings = new KMap>() - ;//.qput("v1_16_R2", NMSBinding16_2.class); + .qput("v1_16_R2", NMSBinding16_2.class) + .qput("v1_16_R3", NMSBinding16_3.class) + ; //@done private static final INMSBinding binding = bind(); diff --git a/src/main/java/com/volmit/iris/nms/INMSBinding.java b/src/main/java/com/volmit/iris/nms/INMSBinding.java index 45746a00d..f40b35225 100644 --- a/src/main/java/com/volmit/iris/nms/INMSBinding.java +++ b/src/main/java/com/volmit/iris/nms/INMSBinding.java @@ -2,11 +2,14 @@ package com.volmit.iris.nms; import org.bukkit.World; import org.bukkit.WorldCreator; +import org.bukkit.block.Biome; public interface INMSBinding { public INMSCreator getCreator(); + public Object getBiomeBase(World world, Biome biome); + default World createWorld(WorldCreator creator) { return getCreator().createWorld(creator); diff --git a/src/main/java/com/volmit/iris/nms/v16_2/ChunkGeneratorAbstract_16_2_PAPER.java b/src/main/java/com/volmit/iris/nms/v16_2/ChunkGeneratorAbstract_16_2_PAPER.java new file mode 100644 index 000000000..05a083783 --- /dev/null +++ b/src/main/java/com/volmit/iris/nms/v16_2/ChunkGeneratorAbstract_16_2_PAPER.java @@ -0,0 +1,591 @@ +// +// Source code recreated from a .class file by IntelliJ IDEA +// (powered by FernFlower decompiler) +// + +package com.volmit.iris.nms.v16_2; + +import com.mojang.serialization.Codec; +import com.volmit.iris.Iris; +import com.volmit.iris.nms.INMS; +import com.volmit.iris.scaffold.cache.Cache; +import com.volmit.iris.scaffold.engine.EngineCompositeGenerator; +import com.volmit.iris.util.KMap; +import com.volmit.iris.util.O; +import com.volmit.iris.util.TerrainChunk; +import com.volmit.iris.util.V; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import it.unimi.dsi.fastutil.objects.ObjectList; +import net.minecraft.server.v1_16_R2.*; +import org.bukkit.WorldCreator; +import org.bukkit.block.Biome; +import org.bukkit.block.data.BlockData; +import org.bukkit.craftbukkit.v1_16_R2.block.CraftBlock; +import org.bukkit.craftbukkit.v1_16_R2.block.data.CraftBlockData; +import org.bukkit.craftbukkit.v1_16_R2.util.CraftMagicNumbers; +import org.bukkit.material.MaterialData; + +import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Supplier; + +public final class ChunkGeneratorAbstract_16_2_PAPER extends ChunkGenerator { + private static final IBlockData k; + private final O ws; + protected final IBlockData f; + protected final IBlockData g; + private final long w; + private final int maxHeight; + private final int xzSize; + protected final Supplier h; + private WorldCreator wc; + private EngineCompositeGenerator gen; + private BlockColumn BC; + private KMap posts = new KMap<>(); + + static { + k = Blocks.AIR.getBlockData(); + } + + public ChunkGeneratorAbstract_16_2_PAPER(O ws, WorldCreator wc, WorldChunkManager worldchunkmanager, long i, Supplier supplier) { + this(ws, wc, worldchunkmanager, worldchunkmanager, i, supplier); + } + + private ChunkGeneratorAbstract_16_2_PAPER(O ws, WorldCreator wc, WorldChunkManager worldchunkmanager, WorldChunkManager worldchunkmanager1, long i, Supplier supplier) { + super(worldchunkmanager, worldchunkmanager1, ((GeneratorSettingBase)supplier.get()).a(), i); + this.wc = wc; + this.ws = ws; + this.gen = (EngineCompositeGenerator) wc.generator(); + this.w = i; + GeneratorSettingBase generatorsettingbase = supplier.get(); + this.h = supplier; + NoiseSettings noisesettings = generatorsettingbase.b(); + this.f = generatorsettingbase.c(); + this.g = generatorsettingbase.d(); + this.maxHeight = noisesettings.f() * 4; + this.xzSize = noisesettings.a() / this.maxHeight; + BC = new BlockColumn(new IBlockData[this.xzSize * this.maxHeight]); + } + + public int getSpawnHeight() + { + return getSeaLevel() + 8; + } + + public WorldChunkManager getWorldChunkManager() + { + return this.c; + } + + public int getGenerationDepth() + { + return 256; + } + + public void doCarving(long i, BiomeManager biomemanager, IChunkAccess ichunkaccess, WorldGenStage.Features worldgenstage_features) + { + if(gen.isVanillaCaves()) + { + super.doCarving(i, biomemanager, ichunkaccess, worldgenstage_features); + } + } + + @Override + protected Codec a() + { + return ChunkGeneratorAbstract.d; + } + + public boolean a(long i, ResourceKey resourcekey) + { + return this.w == i && this.h.get().a(resourcekey); + } + + @Override + public int getBaseHeight(int i, int j, HeightMap.Type heightmap_type) + { + try + { + return 1+gen.getComposite().getDefaultEngine().getMinHeight() + Math.max(gen.getComposite().getDefaultEngine().getHeight(i, j), gen.getComposite().getDefaultEngine().getDimension().getFluidHeight()); + } + catch(Throwable e) + { + return 0; + } + } + + @Override + public IBlockAccess a(int x, int z) + { + return BC; + } + + protected IBlockData a(double d0, int i) + { + IBlockData iblockdata; + + if(d0 > 0.0D) + { + iblockdata = this.f; + } + else if(i < this.getSeaLevel()) + { + iblockdata = this.g; + } + else + { + iblockdata = k; + } + + return iblockdata; + } + + @Override + public void buildBase(RegionLimitedWorldAccess regionlimitedworldaccess, IChunkAccess ichunkaccess) + { + + } + + @Override + public void buildNoise(GeneratorAccess generatoraccess, StructureManager structuremanager, IChunkAccess ichunkaccess) + { + ObjectList objectlist = new ObjectArrayList(10); + ObjectList objectlist1 = new ObjectArrayList(32); + ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos(); + int i = chunkcoordintpair.x; + int j = chunkcoordintpair.z; + + int k = i << 4; + int l = j << 4; + Iterator iterator = StructureGenerator.t.iterator(); + + while(iterator.hasNext()) + { + StructureGenerator structuregenerator = (StructureGenerator) iterator.next(); + + structuremanager.a(SectionPosition.a(chunkcoordintpair, 0), structuregenerator).forEach((structurestart) -> + { + Iterator iterator1 = structurestart.d().iterator(); + + while(iterator1.hasNext()) + { + StructurePiece structurepiece = (StructurePiece) iterator1.next(); + + if(structurepiece.a(chunkcoordintpair, 12)) + { + if(structurepiece instanceof WorldGenFeaturePillagerOutpostPoolPiece) + { + WorldGenFeaturePillagerOutpostPoolPiece worldgenfeaturepillageroutpostpoolpiece = (WorldGenFeaturePillagerOutpostPoolPiece) structurepiece; + WorldGenFeatureDefinedStructurePoolTemplate.Matching worldgenfeaturedefinedstructurepooltemplate_matching = worldgenfeaturepillageroutpostpoolpiece.b().e(); + + if(worldgenfeaturedefinedstructurepooltemplate_matching == WorldGenFeatureDefinedStructurePoolTemplate.Matching.RIGID) + { + objectlist.add(worldgenfeaturepillageroutpostpoolpiece); + } + + Iterator iterator2 = worldgenfeaturepillageroutpostpoolpiece.e().iterator(); + + while(iterator2.hasNext()) + { + WorldGenFeatureDefinedStructureJigsawJunction worldgenfeaturedefinedstructurejigsawjunction = (WorldGenFeatureDefinedStructureJigsawJunction) iterator2.next(); + int i1 = worldgenfeaturedefinedstructurejigsawjunction.a(); + int j1 = worldgenfeaturedefinedstructurejigsawjunction.c(); + + if(i1 > k - 12 && j1 > l - 12 && i1 < k + 15 + 12 && j1 < l + 15 + 12) + { + objectlist1.add(worldgenfeaturedefinedstructurejigsawjunction); + } + } + } + else + { + objectlist.add(structurepiece); + } + } + } + }); + } + ProtoChunk protochunk = (ProtoChunk) ichunkaccess; + HeightMap heightmap = protochunk.a(HeightMap.Type.OCEAN_FLOOR_WG); + HeightMap heightmap1 = protochunk.a(HeightMap.Type.WORLD_SURFACE_WG); + AtomicBoolean allow = new AtomicBoolean(true); + posts.put(Cache.key(i, j), gen.generateChunkRawData(ws.get().getWorld(), i, j, new TerrainChunk() { + @Override + public void setBiome(int x, int y, int z, Biome bio) + { + protochunk.getBiomeIndex().setBiome(x, y, z, CraftBlock.biomeToBiomeBase(ws.get().r().b(IRegistry.ay), bio)); + } + + @Override + public void setBiome(int x, int z, Biome bio) + { + protochunk.getBiomeIndex().setBiome(x, 0, z, CraftBlock.biomeToBiomeBase(ws.get().r().b(IRegistry.ay), bio)); + } + + @Override + public Biome getBiome(int x, int y, int z) + { + return CraftBlock.biomeBaseToBiome(ws.get().r().b(IRegistry.ay), protochunk.getBiomeIndex().getBiome(x&15, y, z&15)); + } + + @Override + public void setRaw(org.bukkit.generator.ChunkGenerator.ChunkData data) { + + } + + @Override + public Biome getBiome(int x, int z) + { + return CraftBlock.biomeBaseToBiome(ws.get().r().b(IRegistry.ay), protochunk.getBiomeIndex().getBiome(x, 0, z)); + } + + public int getMaxHeight() + { + return 256; + } + + public void setBlock(int x, int y, int z, org.bukkit.Material material) + { + this.setBlock(x, y, z, material.createBlockData()); + } + + public void setBlock(int x, int y, int z, MaterialData material) + { + this.setBlock(x, y, z, CraftMagicNumbers.getBlock((MaterialData) material)); + } + + public void setBlock(int x, int y, int z, BlockData blockData) + { + if(allow.get()) + { + heightmap.a(x,y,z,((CraftBlockData) blockData).getState()); + heightmap1.a(x,y,z,((CraftBlockData) blockData).getState()); + } + + this.setBlock(x, y, z, ((CraftBlockData) blockData).getState()); + } + + public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, org.bukkit.Material material) + { + this.setRegion(xMin, yMin, zMin, xMax, yMax, zMax, material.createBlockData()); + } + + public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, MaterialData material) + { + this.setRegion(xMin, yMin, zMin, xMax, yMax, zMax, CraftMagicNumbers.getBlock((MaterialData) material)); + } + + public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, BlockData blockData) + { + this.setRegion(xMin, yMin, zMin, xMax, yMax, zMax, ((CraftBlockData) blockData).getState()); + } + + public org.bukkit.Material getType(int x, int y, int z) + { + return CraftMagicNumbers.getMaterial((Block) this.getTypeId(x, y, z).getBlock()); + } + + public MaterialData getTypeAndData(int x, int y, int z) + { + return CraftMagicNumbers.getMaterial((IBlockData) this.getTypeId(x, y, z)); + } + + public BlockData getBlockData(int x, int y, int z) + { + return CraftBlockData.fromData((IBlockData) this.getTypeId(x, y, z)); + } + + @Override + public org.bukkit.generator.ChunkGenerator.ChunkData getRaw() { + return null; + } + + @Override + public void inject(org.bukkit.generator.ChunkGenerator.BiomeGrid biome) { + + } + + public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, IBlockData type) + { + if(xMin > 15 || yMin >= getMaxHeight() || zMin > 15) + { + return; + } + if(xMin < 0) + { + xMin = 0; + } + if(yMin < 0) + { + yMin = 0; + } + if(zMin < 0) + { + zMin = 0; + } + if(xMax > 16) + { + xMax = 16; + } + if(yMax > getMaxHeight()) + { + yMax = getMaxHeight(); + } + if(zMax > 16) + { + zMax = 16; + } + if(xMin >= xMax || yMin >= yMax || zMin >= zMax) + { + return; + } + int y = yMin; + while(y < yMax) + { + int x = xMin; + while(x < xMax) + { + int z = zMin; + while(z < zMax) + { + protochunk.setType(new BlockPosition(x, y, z), type, false); + ++z; + } + ++x; + } + ++y; + } + } + + public IBlockData getTypeId(int x, int y, int z) + { + if(x != (x & 15) || y < 0 || y >= getMaxHeight() || z != (z & 15)) + { + return Blocks.AIR.getBlockData(); + } + return protochunk.getType(new BlockPosition(x, y, z)); + } + + public byte getData(int x, int y, int z) + { + return CraftMagicNumbers.toLegacyData((IBlockData) this.getTypeId(x, y, z)); + } + + private void setBlock(int x, int y, int z, IBlockData type) + { + if(x != (x & 15) || y < 0 || y >= getMaxHeight() || z != (z & 15)) + { + return; + } + + protochunk.setType(new BlockPosition(x, y, z), type, false); + + if(type.getBlock().isTileEntity()) + { + // if (this.tiles == null) { + // this.tiles = new HashSet(); + // } + // this.tiles.add(new BlockPosition(x, y, z)); + } + } + })); + allow.set(false); + } + + public void addDecorations(RegionLimitedWorldAccess regionlimitedworldaccess, StructureManager structuremanager) + { + int i = regionlimitedworldaccess.a(); + int j = regionlimitedworldaccess.b(); + int k = i * 16; + int l = j * 16; + BlockPosition blockposition = new BlockPosition(k, 0, l); + BiomeBase biomebase = getStructureBiome(k, l); + SeededRandom seededrandom = new SeededRandom(); + long i1 = seededrandom.a(regionlimitedworldaccess.getSeed(), k, l); + try + { + a(biomebase, structuremanager, this, regionlimitedworldaccess, i1, seededrandom, blockposition); + } + catch(Exception exception) + { + + } + + Runnable r = posts.remove(Cache.key(i, j)); + + if(r != null) + { + r.run(); + } + + if(posts.size() > 1000) + { + Iris.warn("POSTS OUT OF CONTROL CLEARING QUEUE!"); + posts.clear(); + } + } + + private BiomeBase getStructureBiome(int k, int l) { + return (BiomeBase) INMS.get().getBiomeBase(ws.get().getWorld(), gen.getComposite().getDefaultEngine().getSurfaceBiome(k, l).getVanillaDerivative()); + } + + public void a(BiomeBase bbase, StructureManager var0, ChunkGenerator var1, RegionLimitedWorldAccess var2, long var3, SeededRandom var5, BlockPosition var6) + { + int stages = WorldGenStage.Decoration.values().length; + for(int stage = 0; stage < stages; ++stage) + { + WorldGenStage.Decoration st = WorldGenStage.Decoration.values()[stage]; + + if(st.equals(WorldGenStage.Decoration.LAKES)) + { + continue; + } + + if(st.equals(WorldGenStage.Decoration.LOCAL_MODIFICATIONS)) + { + continue; + } + + if(st.equals(WorldGenStage.Decoration.RAW_GENERATION)) + { + continue; + } + + if(st.equals(WorldGenStage.Decoration.TOP_LAYER_MODIFICATION)) + { + continue; + } + + if(st.equals(WorldGenStage.Decoration.UNDERGROUND_DECORATION)) + { + continue; + } + + if(st.equals(WorldGenStage.Decoration.UNDERGROUND_ORES)) + { + continue; + } + + if(st.equals(WorldGenStage.Decoration.VEGETAL_DECORATION)) + { + continue; + } + + StructureGenerator var13; + int var10 = 0; + if(var0.a()) + { + @SuppressWarnings("unchecked") + List> structureGenerators = ((Map>>) new V(bbase).get("g")).getOrDefault(stage, Collections.emptyList()); + Iterator> iterator = structureGenerators.iterator(); + while(iterator.hasNext()) + { + var13 = (StructureGenerator) iterator.next(); + + var5.b(var3, var10, stage); + int var14 = var6.getX() >> 4; + int var15 = var6.getZ() >> 4; + int var16 = var14 << 4; + int var17 = var15 << 4; + + try + { + var0.a(SectionPosition.a((BlockPosition) var6), var13).forEach(var8 -> var8.a((GeneratorAccessSeed) var2, var0, var1, (Random) var5, new StructureBoundingBox(var16, var17, var16 + 15, var17 + 15), new ChunkCoordIntPair(var14, var15))); + } + + catch(Exception var18) + { + + } + + ++var10; + } + } + } + } + + @Override + public int getSeaLevel() + { + try + { + return gen.getComposite().getDefaultEngine().getMinHeight() + gen.getComposite().getDefaultEngine().getDimension().getFluidHeight(); + } + + catch(Throwable e) + { + return 0; + } + } + + public void createStructures(IRegistryCustom iregistrycustom, StructureManager structuremanager, IChunkAccess ichunkaccess, DefinedStructureManager definedstructuremanager, long i) + { + ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos(); + BiomeBase biomebase = this.b.getBiome((chunkcoordintpair.x * 16) + 2, 0, (chunkcoordintpair.z * 16) + 2); + this.a(StructureFeatures.k, iregistrycustom, structuremanager, ichunkaccess, definedstructuremanager, i, chunkcoordintpair, biomebase); + for(Supplier> supplier : biomebase.e().a()) + { + StructureFeature structurefeature = (StructureFeature) supplier.get(); + if(StructureFeature.c == StructureGenerator.STRONGHOLD) + { + StructureFeature structureFeature = structurefeature; + synchronized(structureFeature) + { + this.a(structurefeature, iregistrycustom, structuremanager, ichunkaccess, definedstructuremanager, i, chunkcoordintpair, biomebase); + continue; + } + } + this.a(structurefeature, iregistrycustom, structuremanager, ichunkaccess, definedstructuremanager, i, chunkcoordintpair, biomebase); + } + } + + private void a(StructureFeature structurefeature, IRegistryCustom iregistrycustom, StructureManager structuremanager, IChunkAccess ichunkaccess, DefinedStructureManager definedstructuremanager, long i, ChunkCoordIntPair chunkcoordintpair, BiomeBase biomebase) + { + StructureStart structurestart = structuremanager.a(SectionPosition.a((ChunkCoordIntPair) ichunkaccess.getPos(), (int) 0), structurefeature.d, (IStructureAccess) ichunkaccess); + int j = structurestart != null ? structurestart.j() : 0; + StructureSettingsFeature structuresettingsfeature = getSettings().a(structurefeature.d); + if(structuresettingsfeature != null) + { + StructureStart structurestart1 = structurefeature.a(iregistrycustom, this, this.b, definedstructuremanager, i, chunkcoordintpair, biomebase, j, structuresettingsfeature); + structuremanager.a(SectionPosition.a((ChunkCoordIntPair) ichunkaccess.getPos(), (int) 0), structurefeature.d, structurestart1, (IStructureAccess) ichunkaccess); + } + } + + public void storeStructures(GeneratorAccessSeed generatoraccessseed, StructureManager structuremanager, IChunkAccess ichunkaccess) + { + int i = ichunkaccess.getPos().x; + int j = ichunkaccess.getPos().z; + int k = i << 4; + int l = j << 4; + SectionPosition sectionposition = SectionPosition.a((ChunkCoordIntPair) ichunkaccess.getPos(), (int) 0); + int i1 = i - 8; + while(i1 <= i + 8) + { + int j1 = j - 8; + while(j1 <= j + 8) + { + long k1 = ChunkCoordIntPair.pair((int) i1, (int) j1); + for(StructureStart structurestart : generatoraccessseed.getChunkAt(i1, j1).h().values()) + { + try + { + if(structurestart == StructureStart.a || !structurestart.c().a(k, l, k + 15, l + 15)) + continue; + structuremanager.a(sectionposition, structurestart.l(), k1, (IStructureAccess) ichunkaccess); + PacketDebug.a((GeneratorAccessSeed) generatoraccessseed, (StructureStart) structurestart); + } + catch(Exception exception) + { + CrashReport crashreport = CrashReport.a((Throwable) exception, (String) "Generating structure reference"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Structure"); + crashreportsystemdetails.a("Name", () -> structurestart.l().i()); + crashreportsystemdetails.a("Class", () -> structurestart.l().getClass().getCanonicalName()); + throw new ReportedException(crashreport); + } + } + ++j1; + } + ++i1; + } + } +} diff --git a/src/main/java/com/volmit/iris/nms/v16_2/NMSBinding16_2.java b/src/main/java/com/volmit/iris/nms/v16_2/NMSBinding16_2.java new file mode 100644 index 000000000..18d5ac463 --- /dev/null +++ b/src/main/java/com/volmit/iris/nms/v16_2/NMSBinding16_2.java @@ -0,0 +1,26 @@ +package com.volmit.iris.nms.v16_2; + +import com.volmit.iris.nms.INMSBinding; +import com.volmit.iris.nms.INMSCreator; +import com.volmit.iris.scaffold.cache.AtomicCache; +import org.bukkit.World; +import org.bukkit.block.Biome; +import org.bukkit.craftbukkit.v1_16_R2.CraftWorld; +import org.bukkit.craftbukkit.v1_16_R2.block.CraftBlock; + +public class NMSBinding16_2 implements INMSBinding +{ + private final AtomicCache creator = new AtomicCache<>(); + + @Override + public INMSCreator getCreator() + { + return creator.aquire(NMSCreator16_2::new); + } + + @Override + public Object getBiomeBase(World world, Biome biome) + { + return CraftBlock.biomeToBiomeBase(((CraftWorld)world).getHandle().r().b(net.minecraft.server.v1_16_R2.IRegistry.ay), biome); + } +} diff --git a/src/main/java/com/volmit/iris/nms/v16_2/NMSCreator16_2.java b/src/main/java/com/volmit/iris/nms/v16_2/NMSCreator16_2.java new file mode 100644 index 000000000..b7605b560 --- /dev/null +++ b/src/main/java/com/volmit/iris/nms/v16_2/NMSCreator16_2.java @@ -0,0 +1,264 @@ +package com.volmit.iris.nms.v16_2; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.mojang.serialization.DynamicOps; +import com.mojang.serialization.Lifecycle; +import com.volmit.iris.nms.INMSCreator; +import com.volmit.iris.scaffold.IrisWorlds; +import com.volmit.iris.scaffold.engine.EngineCompositeGenerator; +import com.volmit.iris.util.O; +import com.volmit.iris.util.V; +import net.minecraft.server.v1_16_R2.*; +import net.minecraft.server.v1_16_R2.IRegistryCustom.Dimension; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.World.Environment; +import org.bukkit.WorldCreator; +import org.bukkit.craftbukkit.v1_16_R2.CraftServer; +import org.bukkit.event.Event; +import org.bukkit.event.world.WorldInitEvent; +import org.bukkit.event.world.WorldLoadEvent; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.*; + +class NMSCreator16_2 implements INMSCreator +{ + @SuppressWarnings({"unchecked", "rawtypes", "resource"}) + public World createWorld(WorldCreator creator, boolean loadSpawn) + { + if(!creator.environment().equals(Environment.NORMAL)) + { + return creator.createWorld(); + } + + EngineCompositeGenerator pro = (EngineCompositeGenerator) creator.generator(); + CraftServer server = ((CraftServer) Bukkit.getServer()); + Map worlds = new V(server).get("worlds"); + DedicatedServer console = new V(server).get("console"); + Preconditions.checkState(!console.worldServer.isEmpty(), (Object) "Cannot create additional worlds on STARTUP"); + Validate.notNull((Object) creator, "Creator may not be null"); + final String name = creator.name(); + org.bukkit.generator.ChunkGenerator generator = creator.generator(); + final File folder = new File(server.getWorldContainer(), name); + final World world = server.getWorld(name); + + if(world != null) + { + return world; + } + + if(folder.exists() && !folder.isDirectory()) + { + throw new IllegalArgumentException("File exists with the name '" + name + "' and isn't a folder"); + } + + if(generator == null) + { + generator = server.getGenerator(name); + } + + ResourceKey actualDimension = null; + switch(creator.environment()) + { + case NORMAL: + { + actualDimension = (ResourceKey) WorldDimension.OVERWORLD; + break; + } + case NETHER: + { + actualDimension = (ResourceKey) WorldDimension.THE_NETHER; + break; + } + case THE_END: + { + actualDimension = (ResourceKey) WorldDimension.THE_END; + break; + } + default: + { + throw new IllegalArgumentException("Illegal dimension"); + } + } + Convertable.ConversionSession worldSession; + try + { + worldSession = Convertable.a(server.getWorldContainer().toPath()).c(name, (ResourceKey) actualDimension); + } + catch(IOException ex) + { + throw new RuntimeException(ex); + } + MinecraftServer.convertWorld(worldSession); + final boolean hardcore = creator.hardcore(); + final RegistryReadOps registryreadops = (RegistryReadOps) RegistryReadOps.a((DynamicOps) DynamicOpsNBT.a, console.dataPackResources.h(), getConsoleDimension(console)); + WorldDataServer worlddata = (WorldDataServer) worldSession.a((DynamicOps) registryreadops, console.datapackconfiguration); + if(worlddata == null) + { + final Properties properties = new Properties(); + properties.put("generator-settings", Objects.toString(creator.generatorSettings())); + properties.put("level-seed", Objects.toString(creator.seed())); + properties.put("generate-structures", Objects.toString(creator.generateStructures())); + properties.put("level-type", Objects.toString(creator.type().getName())); + final GeneratorSettings generatorsettings = GeneratorSettings.a(getConsoleDimension(console), properties); + @SuppressWarnings("deprecation") + final WorldSettings worldSettings = new WorldSettings(name, EnumGamemode.getById(server.getDefaultGameMode().getValue()), hardcore, EnumDifficulty.EASY, false, new GameRules(), console.datapackconfiguration); + worlddata = new WorldDataServer(worldSettings, generatorsettings, Lifecycle.stable()); + } + worlddata.checkName(name); + worlddata.a(console.getServerModName(), console.getModded().isPresent()); + if(console.options.has("forceUpgrade")) + { + net.minecraft.server.v1_16_R2.Main.convertWorld(worldSession, DataConverterRegistry.a(), console.options.has("eraseCache"), () -> true, (ImmutableSet) worlddata.getGeneratorSettings().d().d().stream().map(entry -> ResourceKey.a(IRegistry.K, entry.getKey().a())).collect(ImmutableSet.toImmutableSet())); + } + final long j = BiomeManager.a(creator.seed()); + final List list = (List) ImmutableList.of((MobSpawner) new MobSpawnerPhantom(), (MobSpawner) new MobSpawnerPatrol(), (MobSpawner) new MobSpawnerCat(), (MobSpawner) new VillageSiege(), (MobSpawner) new MobSpawnerTrader((IWorldDataServer) worlddata)); + DimensionManager dimensionmanager; + net.minecraft.server.v1_16_R2.ChunkGenerator chunkgenerator; + long ll = creator.seed(); + dimensionmanager = (DimensionManager) getConsoleDimension(console).a().d(DimensionManager.OVERWORLD); + O ws = new O(); + chunkgenerator = new ChunkGeneratorAbstract_16_2_PAPER(ws, creator, (WorldChunkManager) new WorldChunkManagerIris16_2(((EngineCompositeGenerator)creator.generator()), creator.name(), ll, false, false, (IRegistry) getConsoleDimension(console).b(IRegistry.ay)), ll, () -> (GeneratorSettingBase) getConsoleDimension(console).b(IRegistry.ar).d(GeneratorSettingBase.c)); + final ResourceKey worldKey = (ResourceKey) ResourceKey.a(IRegistry.L, new MinecraftKey(name.toLowerCase(Locale.ENGLISH))); + //@builder + final WorldServer internal = new WorldServer((MinecraftServer) console, + console.executorService, worldSession, + (IWorldDataServer) worlddata, + (ResourceKey) worldKey, + dimensionmanager, + server.getServer().worldLoadListenerFactory.create(11), + chunkgenerator, + worlddata.getGeneratorSettings().isDebugWorld(), + j, + (List) ((creator.environment() == World.Environment.NORMAL) ? list : ImmutableList.of()), + true, + creator.environment(), + server.getGenerator(name)); + //@done + IrisWorlds.register(internal.getWorld(), pro); + ws.set(internal); + if(!worlds.containsKey(name.toLowerCase(Locale.ENGLISH))) + { + try + { + internal.close(); + } + + catch(IOException e) + { + e.printStackTrace(); + } + + return null; + } + + console.initWorld(internal, (IWorldDataServer) worlddata, (SaveData) worlddata, worlddata.getGeneratorSettings()); + internal.setSpawnFlags(true, true); + console.worldServer.put(internal.getDimensionKey(), internal); + server.getPluginManager().callEvent((Event) new WorldInitEvent((World) internal.getWorld())); + + if(loadSpawn) + { + server.getServer().loadSpawn(internal.getChunkProvider().playerChunkMap.worldLoadListener, internal); + } + + else + { + MinecraftServer.LOGGER.info("Preparing start region for dimens... Oh wait, We don't do that here anymore."); + } + + server.getPluginManager().callEvent((Event) new WorldLoadEvent((World) internal.getWorld())); + return (World) internal.getWorld(); + } + + private Dimension getConsoleDimension(DedicatedServer console) + { + Dimension dim = null; + + try + { + dim = new V((MinecraftServer) console, true).get("customRegistry"); + + if(dim != null) + { + return dim; + } + } + + catch(Throwable e) + { + + } + + try + { + dim = new V((MinecraftServer) console, true).get("f"); + + if(dim != null) + { + return dim; + } + } + + catch(Throwable e) + { + + } + + for(Field i : MinecraftServer.class.getDeclaredFields()) + { + if(i.getType().equals(dim.getClass())) + { + i.setAccessible(true); + + if(Modifier.isStatic(i.getModifiers())) + { + try + { + return (Dimension) i.get(null); + } + + catch(Throwable e) + { + e.printStackTrace(); + } + } + + else + { + try + { + return (Dimension) i.get((MinecraftServer) console); + } + + catch(Throwable e) + { + e.printStackTrace(); + } + } + } + } + + if(dim == null) + { + try + { + throw new RuntimeException("Cannot find dimension field!"); + } + + catch(Throwable e) + { + e.printStackTrace(); + } + } + + return dim; + } +} \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/nms/v16_2/WorldChunkManagerIris16_2.java b/src/main/java/com/volmit/iris/nms/v16_2/WorldChunkManagerIris16_2.java new file mode 100644 index 000000000..dbe92b37a --- /dev/null +++ b/src/main/java/com/volmit/iris/nms/v16_2/WorldChunkManagerIris16_2.java @@ -0,0 +1,56 @@ +package com.volmit.iris.nms.v16_2; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.Lifecycle; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import com.volmit.iris.scaffold.engine.EngineCompositeGenerator; +import net.minecraft.server.v1_16_R2.*; +import org.bukkit.craftbukkit.v1_16_R2.util.CraftNamespacedKey; + +public class WorldChunkManagerIris16_2 extends WorldChunkManager { + public static final Codec e = RecordCodecBuilder.create((var0) -> { + return var0.group(Codec.LONG.fieldOf("seed").stable().forGetter((var0x) -> { + return var0x.h; + }), Codec.BOOL.optionalFieldOf("legacy_biome_init_layer", false, Lifecycle.stable()).forGetter((var0x) -> { + return var0x.i; + }), Codec.BOOL.fieldOf("large_biomes").orElse(false).stable().forGetter((var0x) -> { + return var0x.j; + }), RegistryLookupCodec.a(IRegistry.ay).forGetter((var0x) -> { + return var0x.k; + })).apply(var0, var0.stable((a,b,c,d) -> new WorldChunkManagerIris16_2(null, "", a, b, c, d))); + }); + private final long h; + private final boolean i; + private final boolean j; + private final EngineCompositeGenerator compound; + private final IRegistry k; + + public WorldChunkManagerIris16_2(EngineCompositeGenerator compound, String wn, long var0, boolean var2, boolean var3, IRegistry var4) { + super(compound.getAllBiomes(wn).convert((v)-> v.getDerivative().getKey().getKey()).stream().map((var1) -> { + return () -> { + return (BiomeBase)var4.d(ResourceKey.a(IRegistry.ay, new MinecraftKey(var1))); + }; + })); + this.compound = compound; + this.h = var0; + this.i = var2; + this.j = var3; + this.k = var4; + } + + protected Codec a() { + return e; + } + + public BiomeBase getBiome(int var0, int var1, int var2) { + try + { + return k.get(CraftNamespacedKey.toMinecraft(compound.getComposite().getDefaultEngine().getSurfaceBiome(var0, var2).getVanillaDerivative().getKey())); + } + + catch(Throwable e) + { + return k.get(Biomes.THE_VOID.a()); + } + } +} diff --git a/src/main/java/com/volmit/iris/nms/v16_3/ChunkGeneratorAbstract_16_3_PAPER.java b/src/main/java/com/volmit/iris/nms/v16_3/ChunkGeneratorAbstract_16_3_PAPER.java new file mode 100644 index 000000000..21f11b894 --- /dev/null +++ b/src/main/java/com/volmit/iris/nms/v16_3/ChunkGeneratorAbstract_16_3_PAPER.java @@ -0,0 +1,591 @@ +// +// Source code recreated from a .class file by IntelliJ IDEA +// (powered by FernFlower decompiler) +// + +package com.volmit.iris.nms.v16_3; + +import com.mojang.serialization.Codec; +import com.volmit.iris.Iris; +import com.volmit.iris.nms.INMS; +import com.volmit.iris.scaffold.cache.Cache; +import com.volmit.iris.scaffold.engine.EngineCompositeGenerator; +import com.volmit.iris.util.KMap; +import com.volmit.iris.util.O; +import com.volmit.iris.util.TerrainChunk; +import com.volmit.iris.util.V; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import it.unimi.dsi.fastutil.objects.ObjectList; +import net.minecraft.server.v1_16_R3.*; +import org.bukkit.WorldCreator; +import org.bukkit.block.Biome; +import org.bukkit.block.data.BlockData; +import org.bukkit.craftbukkit.v1_16_R3.block.CraftBlock; +import org.bukkit.craftbukkit.v1_16_R3.block.data.CraftBlockData; +import org.bukkit.craftbukkit.v1_16_R3.util.CraftMagicNumbers; +import org.bukkit.material.MaterialData; + +import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Supplier; + +public final class ChunkGeneratorAbstract_16_3_PAPER extends ChunkGenerator { + private static final IBlockData k; + private final O ws; + protected final IBlockData f; + protected final IBlockData g; + private final long w; + private final int maxHeight; + private final int xzSize; + protected final Supplier h; + private WorldCreator wc; + private EngineCompositeGenerator gen; + private BlockColumn BC; + private KMap posts = new KMap<>(); + + static { + k = Blocks.AIR.getBlockData(); + } + + public ChunkGeneratorAbstract_16_3_PAPER(O ws, WorldCreator wc, WorldChunkManager worldchunkmanager, long i, Supplier supplier) { + this(ws, wc, worldchunkmanager, worldchunkmanager, i, supplier); + } + + private ChunkGeneratorAbstract_16_3_PAPER(O ws, WorldCreator wc, WorldChunkManager worldchunkmanager, WorldChunkManager worldchunkmanager1, long i, Supplier supplier) { + super(worldchunkmanager, worldchunkmanager1, ((GeneratorSettingBase)supplier.get()).a(), i); + this.wc = wc; + this.ws = ws; + this.gen = (EngineCompositeGenerator) wc.generator(); + this.w = i; + GeneratorSettingBase generatorsettingbase = supplier.get(); + this.h = supplier; + NoiseSettings noisesettings = generatorsettingbase.b(); + this.f = generatorsettingbase.c(); + this.g = generatorsettingbase.d(); + this.maxHeight = noisesettings.f() * 4; + this.xzSize = noisesettings.a() / this.maxHeight; + BC = new BlockColumn(new IBlockData[this.xzSize * this.maxHeight]); + } + + public int getSpawnHeight() + { + return getSeaLevel() + 8; + } + + public WorldChunkManager getWorldChunkManager() + { + return this.c; + } + + public int getGenerationDepth() + { + return 256; + } + + public void doCarving(long i, BiomeManager biomemanager, IChunkAccess ichunkaccess, WorldGenStage.Features worldgenstage_features) + { + if(gen.isVanillaCaves()) + { + super.doCarving(i, biomemanager, ichunkaccess, worldgenstage_features); + } + } + + @Override + protected Codec a() + { + return ChunkGeneratorAbstract.d; + } + + public boolean a(long i, ResourceKey resourcekey) + { + return this.w == i && this.h.get().a(resourcekey); + } + + @Override + public int getBaseHeight(int i, int j, HeightMap.Type heightmap_type) + { + try + { + return 1+gen.getComposite().getDefaultEngine().getMinHeight() + Math.max(gen.getComposite().getDefaultEngine().getHeight(i, j), gen.getComposite().getDefaultEngine().getDimension().getFluidHeight()); + } + catch(Throwable e) + { + return 0; + } + } + + @Override + public IBlockAccess a(int x, int z) + { + return BC; + } + + protected IBlockData a(double d0, int i) + { + IBlockData iblockdata; + + if(d0 > 0.0D) + { + iblockdata = this.f; + } + else if(i < this.getSeaLevel()) + { + iblockdata = this.g; + } + else + { + iblockdata = k; + } + + return iblockdata; + } + + @Override + public void buildBase(RegionLimitedWorldAccess regionlimitedworldaccess, IChunkAccess ichunkaccess) + { + + } + + @Override + public void buildNoise(GeneratorAccess generatoraccess, StructureManager structuremanager, IChunkAccess ichunkaccess) + { + ObjectList objectlist = new ObjectArrayList(10); + ObjectList objectlist1 = new ObjectArrayList(32); + ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos(); + int i = chunkcoordintpair.x; + int j = chunkcoordintpair.z; + + int k = i << 4; + int l = j << 4; + Iterator iterator = StructureGenerator.t.iterator(); + + while(iterator.hasNext()) + { + StructureGenerator structuregenerator = (StructureGenerator) iterator.next(); + + structuremanager.a(SectionPosition.a(chunkcoordintpair, 0), structuregenerator).forEach((structurestart) -> + { + Iterator iterator1 = structurestart.d().iterator(); + + while(iterator1.hasNext()) + { + StructurePiece structurepiece = (StructurePiece) iterator1.next(); + + if(structurepiece.a(chunkcoordintpair, 12)) + { + if(structurepiece instanceof WorldGenFeaturePillagerOutpostPoolPiece) + { + WorldGenFeaturePillagerOutpostPoolPiece worldgenfeaturepillageroutpostpoolpiece = (WorldGenFeaturePillagerOutpostPoolPiece) structurepiece; + WorldGenFeatureDefinedStructurePoolTemplate.Matching worldgenfeaturedefinedstructurepooltemplate_matching = worldgenfeaturepillageroutpostpoolpiece.b().e(); + + if(worldgenfeaturedefinedstructurepooltemplate_matching == WorldGenFeatureDefinedStructurePoolTemplate.Matching.RIGID) + { + objectlist.add(worldgenfeaturepillageroutpostpoolpiece); + } + + Iterator iterator2 = worldgenfeaturepillageroutpostpoolpiece.e().iterator(); + + while(iterator2.hasNext()) + { + WorldGenFeatureDefinedStructureJigsawJunction worldgenfeaturedefinedstructurejigsawjunction = (WorldGenFeatureDefinedStructureJigsawJunction) iterator2.next(); + int i1 = worldgenfeaturedefinedstructurejigsawjunction.a(); + int j1 = worldgenfeaturedefinedstructurejigsawjunction.c(); + + if(i1 > k - 12 && j1 > l - 12 && i1 < k + 15 + 12 && j1 < l + 15 + 12) + { + objectlist1.add(worldgenfeaturedefinedstructurejigsawjunction); + } + } + } + else + { + objectlist.add(structurepiece); + } + } + } + }); + } + ProtoChunk protochunk = (ProtoChunk) ichunkaccess; + HeightMap heightmap = protochunk.a(HeightMap.Type.OCEAN_FLOOR_WG); + HeightMap heightmap1 = protochunk.a(HeightMap.Type.WORLD_SURFACE_WG); + AtomicBoolean allow = new AtomicBoolean(true); + posts.put(Cache.key(i, j), gen.generateChunkRawData(ws.get().getWorld(), i, j, new TerrainChunk() { + @Override + public void setBiome(int x, int y, int z, Biome bio) + { + protochunk.getBiomeIndex().setBiome(x, y, z, CraftBlock.biomeToBiomeBase(ws.get().r().b(IRegistry.ay), bio)); + } + + @Override + public void setBiome(int x, int z, Biome bio) + { + protochunk.getBiomeIndex().setBiome(x, 0, z, CraftBlock.biomeToBiomeBase(ws.get().r().b(IRegistry.ay), bio)); + } + + @Override + public Biome getBiome(int x, int y, int z) + { + return CraftBlock.biomeBaseToBiome(ws.get().r().b(IRegistry.ay), protochunk.getBiomeIndex().getBiome(x&15, y, z&15)); + } + + @Override + public void setRaw(org.bukkit.generator.ChunkGenerator.ChunkData data) { + + } + + @Override + public Biome getBiome(int x, int z) + { + return CraftBlock.biomeBaseToBiome(ws.get().r().b(IRegistry.ay), protochunk.getBiomeIndex().getBiome(x, 0, z)); + } + + public int getMaxHeight() + { + return 256; + } + + public void setBlock(int x, int y, int z, org.bukkit.Material material) + { + this.setBlock(x, y, z, material.createBlockData()); + } + + public void setBlock(int x, int y, int z, MaterialData material) + { + this.setBlock(x, y, z, CraftMagicNumbers.getBlock((MaterialData) material)); + } + + public void setBlock(int x, int y, int z, BlockData blockData) + { + if(allow.get()) + { + heightmap.a(x,y,z,((CraftBlockData) blockData).getState()); + heightmap1.a(x,y,z,((CraftBlockData) blockData).getState()); + } + + this.setBlock(x, y, z, ((CraftBlockData) blockData).getState()); + } + + public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, org.bukkit.Material material) + { + this.setRegion(xMin, yMin, zMin, xMax, yMax, zMax, material.createBlockData()); + } + + public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, MaterialData material) + { + this.setRegion(xMin, yMin, zMin, xMax, yMax, zMax, CraftMagicNumbers.getBlock((MaterialData) material)); + } + + public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, BlockData blockData) + { + this.setRegion(xMin, yMin, zMin, xMax, yMax, zMax, ((CraftBlockData) blockData).getState()); + } + + public org.bukkit.Material getType(int x, int y, int z) + { + return CraftMagicNumbers.getMaterial((Block) this.getTypeId(x, y, z).getBlock()); + } + + public MaterialData getTypeAndData(int x, int y, int z) + { + return CraftMagicNumbers.getMaterial((IBlockData) this.getTypeId(x, y, z)); + } + + public BlockData getBlockData(int x, int y, int z) + { + return CraftBlockData.fromData((IBlockData) this.getTypeId(x, y, z)); + } + + @Override + public org.bukkit.generator.ChunkGenerator.ChunkData getRaw() { + return null; + } + + @Override + public void inject(org.bukkit.generator.ChunkGenerator.BiomeGrid biome) { + + } + + public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, IBlockData type) + { + if(xMin > 15 || yMin >= getMaxHeight() || zMin > 15) + { + return; + } + if(xMin < 0) + { + xMin = 0; + } + if(yMin < 0) + { + yMin = 0; + } + if(zMin < 0) + { + zMin = 0; + } + if(xMax > 16) + { + xMax = 16; + } + if(yMax > getMaxHeight()) + { + yMax = getMaxHeight(); + } + if(zMax > 16) + { + zMax = 16; + } + if(xMin >= xMax || yMin >= yMax || zMin >= zMax) + { + return; + } + int y = yMin; + while(y < yMax) + { + int x = xMin; + while(x < xMax) + { + int z = zMin; + while(z < zMax) + { + protochunk.setType(new BlockPosition(x, y, z), type, false); + ++z; + } + ++x; + } + ++y; + } + } + + public IBlockData getTypeId(int x, int y, int z) + { + if(x != (x & 15) || y < 0 || y >= getMaxHeight() || z != (z & 15)) + { + return Blocks.AIR.getBlockData(); + } + return protochunk.getType(new BlockPosition(x, y, z)); + } + + public byte getData(int x, int y, int z) + { + return CraftMagicNumbers.toLegacyData((IBlockData) this.getTypeId(x, y, z)); + } + + private void setBlock(int x, int y, int z, IBlockData type) + { + if(x != (x & 15) || y < 0 || y >= getMaxHeight() || z != (z & 15)) + { + return; + } + + protochunk.setType(new BlockPosition(x, y, z), type, false); + + if(type.getBlock().isTileEntity()) + { + // if (this.tiles == null) { + // this.tiles = new HashSet(); + // } + // this.tiles.add(new BlockPosition(x, y, z)); + } + } + })); + allow.set(false); + } + + public void addDecorations(RegionLimitedWorldAccess regionlimitedworldaccess, StructureManager structuremanager) + { + int i = regionlimitedworldaccess.a(); + int j = regionlimitedworldaccess.b(); + int k = i * 16; + int l = j * 16; + BlockPosition blockposition = new BlockPosition(k, 0, l); + BiomeBase biomebase = getStructureBiome(k, l); + SeededRandom seededrandom = new SeededRandom(); + long i1 = seededrandom.a(regionlimitedworldaccess.getSeed(), k, l); + try + { + a(biomebase, structuremanager, this, regionlimitedworldaccess, i1, seededrandom, blockposition); + } + catch(Exception exception) + { + + } + + Runnable r = posts.remove(Cache.key(i, j)); + + if(r != null) + { + r.run(); + } + + if(posts.size() > 1000) + { + Iris.warn("POSTS OUT OF CONTROL CLEARING QUEUE!"); + posts.clear(); + } + } + + private BiomeBase getStructureBiome(int k, int l) { + return (BiomeBase) INMS.get().getBiomeBase(ws.get().getWorld(), gen.getComposite().getDefaultEngine().getSurfaceBiome(k, l).getVanillaDerivative()); + } + + public void a(BiomeBase bbase, StructureManager var0, ChunkGenerator var1, RegionLimitedWorldAccess var2, long var3, SeededRandom var5, BlockPosition var6) + { + int stages = WorldGenStage.Decoration.values().length; + for(int stage = 0; stage < stages; ++stage) + { + WorldGenStage.Decoration st = WorldGenStage.Decoration.values()[stage]; + + if(st.equals(WorldGenStage.Decoration.LAKES)) + { + continue; + } + + if(st.equals(WorldGenStage.Decoration.LOCAL_MODIFICATIONS)) + { + continue; + } + + if(st.equals(WorldGenStage.Decoration.RAW_GENERATION)) + { + continue; + } + + if(st.equals(WorldGenStage.Decoration.TOP_LAYER_MODIFICATION)) + { + continue; + } + + if(st.equals(WorldGenStage.Decoration.UNDERGROUND_DECORATION)) + { + continue; + } + + if(st.equals(WorldGenStage.Decoration.UNDERGROUND_ORES)) + { + continue; + } + + if(st.equals(WorldGenStage.Decoration.VEGETAL_DECORATION)) + { + continue; + } + + StructureGenerator var13; + int var10 = 0; + if(var0.a()) + { + @SuppressWarnings("unchecked") + List> structureGenerators = ((Map>>) new V(bbase).get("g")).getOrDefault(stage, Collections.emptyList()); + Iterator> iterator = structureGenerators.iterator(); + while(iterator.hasNext()) + { + var13 = (StructureGenerator) iterator.next(); + + var5.b(var3, var10, stage); + int var14 = var6.getX() >> 4; + int var15 = var6.getZ() >> 4; + int var16 = var14 << 4; + int var17 = var15 << 4; + + try + { + var0.a(SectionPosition.a((BlockPosition) var6), var13).forEach(var8 -> var8.a((GeneratorAccessSeed) var2, var0, var1, (Random) var5, new StructureBoundingBox(var16, var17, var16 + 15, var17 + 15), new ChunkCoordIntPair(var14, var15))); + } + + catch(Exception var18) + { + + } + + ++var10; + } + } + } + } + + @Override + public int getSeaLevel() + { + try + { + return gen.getComposite().getDefaultEngine().getMinHeight() + gen.getComposite().getDefaultEngine().getDimension().getFluidHeight(); + } + + catch(Throwable e) + { + return 0; + } + } + + public void createStructures(IRegistryCustom iregistrycustom, StructureManager structuremanager, IChunkAccess ichunkaccess, DefinedStructureManager definedstructuremanager, long i) + { + ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos(); + BiomeBase biomebase = this.b.getBiome((chunkcoordintpair.x * 16) + 2, 0, (chunkcoordintpair.z * 16) + 2); + this.a(StructureFeatures.k, iregistrycustom, structuremanager, ichunkaccess, definedstructuremanager, i, chunkcoordintpair, biomebase); + for(Supplier> supplier : biomebase.e().a()) + { + StructureFeature structurefeature = (StructureFeature) supplier.get(); + if(StructureFeature.c == StructureGenerator.STRONGHOLD) + { + StructureFeature structureFeature = structurefeature; + synchronized(structureFeature) + { + this.a(structurefeature, iregistrycustom, structuremanager, ichunkaccess, definedstructuremanager, i, chunkcoordintpair, biomebase); + continue; + } + } + this.a(structurefeature, iregistrycustom, structuremanager, ichunkaccess, definedstructuremanager, i, chunkcoordintpair, biomebase); + } + } + + private void a(StructureFeature structurefeature, IRegistryCustom iregistrycustom, StructureManager structuremanager, IChunkAccess ichunkaccess, DefinedStructureManager definedstructuremanager, long i, ChunkCoordIntPair chunkcoordintpair, BiomeBase biomebase) + { + StructureStart structurestart = structuremanager.a(SectionPosition.a((ChunkCoordIntPair) ichunkaccess.getPos(), (int) 0), structurefeature.d, (IStructureAccess) ichunkaccess); + int j = structurestart != null ? structurestart.j() : 0; + StructureSettingsFeature structuresettingsfeature = getSettings().a(structurefeature.d); + if(structuresettingsfeature != null) + { + StructureStart structurestart1 = structurefeature.a(iregistrycustom, this, this.b, definedstructuremanager, i, chunkcoordintpair, biomebase, j, structuresettingsfeature); + structuremanager.a(SectionPosition.a((ChunkCoordIntPair) ichunkaccess.getPos(), (int) 0), structurefeature.d, structurestart1, (IStructureAccess) ichunkaccess); + } + } + + public void storeStructures(GeneratorAccessSeed generatoraccessseed, StructureManager structuremanager, IChunkAccess ichunkaccess) + { + int i = ichunkaccess.getPos().x; + int j = ichunkaccess.getPos().z; + int k = i << 4; + int l = j << 4; + SectionPosition sectionposition = SectionPosition.a((ChunkCoordIntPair) ichunkaccess.getPos(), (int) 0); + int i1 = i - 8; + while(i1 <= i + 8) + { + int j1 = j - 8; + while(j1 <= j + 8) + { + long k1 = ChunkCoordIntPair.pair((int) i1, (int) j1); + for(StructureStart structurestart : generatoraccessseed.getChunkAt(i1, j1).h().values()) + { + try + { + if(structurestart == StructureStart.a || !structurestart.c().a(k, l, k + 15, l + 15)) + continue; + structuremanager.a(sectionposition, structurestart.l(), k1, (IStructureAccess) ichunkaccess); + PacketDebug.a((GeneratorAccessSeed) generatoraccessseed, (StructureStart) structurestart); + } + catch(Exception exception) + { + CrashReport crashreport = CrashReport.a((Throwable) exception, (String) "Generating structure reference"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Structure"); + crashreportsystemdetails.a("Name", () -> structurestart.l().i()); + crashreportsystemdetails.a("Class", () -> structurestart.l().getClass().getCanonicalName()); + throw new ReportedException(crashreport); + } + } + ++j1; + } + ++i1; + } + } +} diff --git a/src/main/java/com/volmit/iris/nms/v16_3/NMSBinding16_3.java b/src/main/java/com/volmit/iris/nms/v16_3/NMSBinding16_3.java new file mode 100644 index 000000000..093b596a0 --- /dev/null +++ b/src/main/java/com/volmit/iris/nms/v16_3/NMSBinding16_3.java @@ -0,0 +1,26 @@ +package com.volmit.iris.nms.v16_3; + +import com.volmit.iris.nms.INMSBinding; +import com.volmit.iris.nms.INMSCreator; +import com.volmit.iris.scaffold.cache.AtomicCache; +import org.bukkit.World; +import org.bukkit.block.Biome; +import org.bukkit.craftbukkit.v1_16_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_16_R3.block.CraftBlock; + +public class NMSBinding16_3 implements INMSBinding +{ + private final AtomicCache creator = new AtomicCache<>(); + + @Override + public INMSCreator getCreator() + { + return creator.aquire(NMSCreator16_3::new); + } + + @Override + public Object getBiomeBase(World world, Biome biome) + { + return CraftBlock.biomeToBiomeBase(((CraftWorld)world).getHandle().r().b(net.minecraft.server.v1_16_R3.IRegistry.ay), biome); + } +} diff --git a/src/main/java/com/volmit/iris/nms/v16_3/NMSCreator16_3.java b/src/main/java/com/volmit/iris/nms/v16_3/NMSCreator16_3.java new file mode 100644 index 000000000..d75329dea --- /dev/null +++ b/src/main/java/com/volmit/iris/nms/v16_3/NMSCreator16_3.java @@ -0,0 +1,266 @@ +package com.volmit.iris.nms.v16_3; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.mojang.serialization.DynamicOps; +import com.mojang.serialization.Lifecycle; +import com.volmit.iris.nms.INMSCreator; +import com.volmit.iris.scaffold.IrisWorlds; +import com.volmit.iris.scaffold.engine.EngineCompositeGenerator; +import com.volmit.iris.util.O; +import com.volmit.iris.util.V; +import net.minecraft.server.v1_16_R3.*; +import net.minecraft.server.v1_16_R3.IRegistryCustom.Dimension; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.World.Environment; +import org.bukkit.WorldCreator; +import org.bukkit.craftbukkit.v1_16_R3.CraftServer; +import org.bukkit.event.Event; +import org.bukkit.event.world.WorldInitEvent; +import org.bukkit.event.world.WorldLoadEvent; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.*; + +class NMSCreator16_3 implements INMSCreator +{ + @SuppressWarnings({"unchecked", "rawtypes", "resource"}) + public World createWorld(WorldCreator creator, boolean loadSpawn) + { + if(!creator.environment().equals(Environment.NORMAL)) + { + return creator.createWorld(); + } + + EngineCompositeGenerator pro = (EngineCompositeGenerator) creator.generator(); + CraftServer server = ((CraftServer) Bukkit.getServer()); + Map worlds = new V(server).get("worlds"); + DedicatedServer console = new V(server).get("console"); + Preconditions.checkState(!console.worldServer.isEmpty(), (Object) "Cannot create additional worlds on STARTUP"); + Validate.notNull((Object) creator, "Creator may not be null"); + final String name = creator.name(); + org.bukkit.generator.ChunkGenerator generator = creator.generator(); + final File folder = new File(server.getWorldContainer(), name); + final World world = server.getWorld(name); + + if(world != null) + { + return world; + } + + if(folder.exists() && !folder.isDirectory()) + { + throw new IllegalArgumentException("File exists with the name '" + name + "' and isn't a folder"); + } + + if(generator == null) + { + generator = server.getGenerator(name); + } + + ResourceKey actualDimension = null; + switch(creator.environment()) + { + case NORMAL: + { + actualDimension = (ResourceKey) WorldDimension.OVERWORLD; + break; + } + case NETHER: + { + actualDimension = (ResourceKey) WorldDimension.THE_NETHER; + break; + } + case THE_END: + { + actualDimension = (ResourceKey) WorldDimension.THE_END; + break; + } + default: + { + throw new IllegalArgumentException("Illegal dimension"); + } + } + Convertable.ConversionSession worldSession; + try + { + worldSession = Convertable.a(server.getWorldContainer().toPath()).c(name, (ResourceKey) actualDimension); + } + catch(IOException ex) + { + throw new RuntimeException(ex); + } + MinecraftServer.convertWorld(worldSession); + final boolean hardcore = creator.hardcore(); + final RegistryReadOps registryreadops = (RegistryReadOps) RegistryReadOps.a((DynamicOps) DynamicOpsNBT.a, console.dataPackResources.h(), getConsoleDimension(console)); + WorldDataServer worlddata = (WorldDataServer) worldSession.a((DynamicOps) registryreadops, console.datapackconfiguration); + if(worlddata == null) + { + final Properties properties = new Properties(); + properties.put("generator-settings", Objects.toString(creator.generatorSettings())); + properties.put("level-seed", Objects.toString(creator.seed())); + properties.put("generate-structures", Objects.toString(creator.generateStructures())); + properties.put("level-type", Objects.toString(creator.type().getName())); + final GeneratorSettings generatorsettings = GeneratorSettings.a(getConsoleDimension(console), properties); + @SuppressWarnings("deprecation") + final WorldSettings worldSettings = new WorldSettings(name, EnumGamemode.getById(server.getDefaultGameMode().getValue()), hardcore, EnumDifficulty.EASY, false, new GameRules(), console.datapackconfiguration); + worlddata = new WorldDataServer(worldSettings, generatorsettings, Lifecycle.stable()); + } + worlddata.checkName(name); + worlddata.a(console.getServerModName(), console.getModded().isPresent()); + if(console.options.has("forceUpgrade")) + { + Main.convertWorld(worldSession, DataConverterRegistry.a(), console.options.has("eraseCache"), () -> true, (ImmutableSet) worlddata.getGeneratorSettings().d().d().stream().map(entry -> ResourceKey.a(IRegistry.K, entry.getKey().a())).collect(ImmutableSet.toImmutableSet())); + } + final long j = BiomeManager.a(creator.seed()); + final List list = (List) ImmutableList.of((MobSpawner) new MobSpawnerPhantom(), (MobSpawner) new MobSpawnerPatrol(), (MobSpawner) new MobSpawnerCat(), (MobSpawner) new VillageSiege(), (MobSpawner) new MobSpawnerTrader((IWorldDataServer) worlddata)); + DimensionManager dimensionmanager; + ChunkGenerator chunkgenerator; + long ll = creator.seed(); + dimensionmanager = (DimensionManager) getConsoleDimension(console).a().d(DimensionManager.OVERWORLD); + O ws = new O(); + chunkgenerator = new ChunkGeneratorAbstract_16_3_PAPER(ws, creator, (WorldChunkManager) new WorldChunkManagerIris16_3(((EngineCompositeGenerator)creator.generator()), creator.name(), ll, false, false, (IRegistry) getConsoleDimension(console).b(IRegistry.ay)), ll, + + () -> (GeneratorSettingBase) getConsoleDimension(console).b(IRegistry.ar).d(GeneratorSettingBase.c)); + final ResourceKey worldKey = (ResourceKey) ResourceKey.a(IRegistry.L, new MinecraftKey(name.toLowerCase(Locale.ENGLISH))); + //@builder + final WorldServer internal = new WorldServer((MinecraftServer) console, + console.executorService, worldSession, + (IWorldDataServer) worlddata, + (ResourceKey) worldKey, + dimensionmanager, + server.getServer().worldLoadListenerFactory.create(11), + chunkgenerator, + worlddata.getGeneratorSettings().isDebugWorld(), + j, + (List) ((creator.environment() == Environment.NORMAL) ? list : ImmutableList.of()), + true, + creator.environment(), + server.getGenerator(name)); + //@done + IrisWorlds.register(internal.getWorld(), pro); + ws.set(internal); + if(!worlds.containsKey(name.toLowerCase(Locale.ENGLISH))) + { + try + { + internal.close(); + } + + catch(IOException e) + { + e.printStackTrace(); + } + + return null; + } + + console.initWorld(internal, (IWorldDataServer) worlddata, (SaveData) worlddata, worlddata.getGeneratorSettings()); + internal.setSpawnFlags(true, true); + console.worldServer.put(internal.getDimensionKey(), internal); + server.getPluginManager().callEvent((Event) new WorldInitEvent((World) internal.getWorld())); + + if(loadSpawn) + { + server.getServer().loadSpawn(internal.getChunkProvider().playerChunkMap.worldLoadListener, internal); + } + + else + { + MinecraftServer.LOGGER.info("Preparing start region for dimens... Oh wait, We don't do that here anymore."); + } + + server.getPluginManager().callEvent((Event) new WorldLoadEvent((World) internal.getWorld())); + return (World) internal.getWorld(); + } + + private Dimension getConsoleDimension(DedicatedServer console) + { + Dimension dim = null; + + try + { + dim = new V((MinecraftServer) console, true).get("customRegistry"); + + if(dim != null) + { + return dim; + } + } + + catch(Throwable e) + { + + } + + try + { + dim = new V((MinecraftServer) console, true).get("f"); + + if(dim != null) + { + return dim; + } + } + + catch(Throwable e) + { + + } + + for(Field i : MinecraftServer.class.getDeclaredFields()) + { + if(i.getType().equals(dim.getClass())) + { + i.setAccessible(true); + + if(Modifier.isStatic(i.getModifiers())) + { + try + { + return (Dimension) i.get(null); + } + + catch(Throwable e) + { + e.printStackTrace(); + } + } + + else + { + try + { + return (Dimension) i.get((MinecraftServer) console); + } + + catch(Throwable e) + { + e.printStackTrace(); + } + } + } + } + + if(dim == null) + { + try + { + throw new RuntimeException("Cannot find dimension field!"); + } + + catch(Throwable e) + { + e.printStackTrace(); + } + } + + return dim; + } +} \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/nms/v16_3/WorldChunkManagerIris16_3.java b/src/main/java/com/volmit/iris/nms/v16_3/WorldChunkManagerIris16_3.java new file mode 100644 index 000000000..caf1c6321 --- /dev/null +++ b/src/main/java/com/volmit/iris/nms/v16_3/WorldChunkManagerIris16_3.java @@ -0,0 +1,56 @@ +package com.volmit.iris.nms.v16_3; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.Lifecycle; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import com.volmit.iris.scaffold.engine.EngineCompositeGenerator; +import net.minecraft.server.v1_16_R3.*; +import org.bukkit.craftbukkit.v1_16_R3.util.CraftNamespacedKey; + +public class WorldChunkManagerIris16_3 extends WorldChunkManager { + public static final Codec e = RecordCodecBuilder.create((var0) -> { + return var0.group(Codec.LONG.fieldOf("seed").stable().forGetter((var0x) -> { + return var0x.h; + }), Codec.BOOL.optionalFieldOf("legacy_biome_init_layer", false, Lifecycle.stable()).forGetter((var0x) -> { + return var0x.i; + }), Codec.BOOL.fieldOf("large_biomes").orElse(false).stable().forGetter((var0x) -> { + return var0x.j; + }), RegistryLookupCodec.a(IRegistry.ay).forGetter((var0x) -> { + return var0x.k; + })).apply(var0, var0.stable((a,b,c,d) -> new WorldChunkManagerIris16_3(null, "", a, b, c, d))); + }); + private final long h; + private final boolean i; + private final boolean j; + private final EngineCompositeGenerator compound; + private final IRegistry k; + + public WorldChunkManagerIris16_3(EngineCompositeGenerator compound, String wn, long var0, boolean var2, boolean var3, IRegistry var4) { + super(compound.getAllBiomes(wn).convert((v)-> v.getDerivative().getKey().getKey()).stream().map((var1) -> { + return () -> { + return (BiomeBase)var4.d(ResourceKey.a(IRegistry.ay, new MinecraftKey(var1))); + }; + })); + this.compound = compound; + this.h = var0; + this.i = var2; + this.j = var3; + this.k = var4; + } + + protected Codec a() { + return e; + } + + public BiomeBase getBiome(int var0, int var1, int var2) { + try + { + return k.get(CraftNamespacedKey.toMinecraft(compound.getComposite().getDefaultEngine().getSurfaceBiome(var0, var2).getVanillaDerivative().getKey())); + } + + catch(Throwable e) + { + return k.get(Biomes.THE_VOID.a()); + } + } +} diff --git a/src/main/java/com/volmit/iris/nms/v1X/NMSBinding1X.java b/src/main/java/com/volmit/iris/nms/v1X/NMSBinding1X.java index ec43f758d..eaeb0b763 100644 --- a/src/main/java/com/volmit/iris/nms/v1X/NMSBinding1X.java +++ b/src/main/java/com/volmit/iris/nms/v1X/NMSBinding1X.java @@ -1,8 +1,10 @@ package com.volmit.iris.nms.v1X; -import com.volmit.iris.scaffold.cache.AtomicCache; import com.volmit.iris.nms.INMSBinding; import com.volmit.iris.nms.INMSCreator; +import com.volmit.iris.scaffold.cache.AtomicCache; +import org.bukkit.World; +import org.bukkit.block.Biome; public class NMSBinding1X implements INMSBinding { @@ -13,4 +15,9 @@ public class NMSBinding1X implements INMSBinding { return creator.aquire(NMSCreator1X::new); } + + public Object getBiomeBase(World world, Biome biome) + { + return null; + } } diff --git a/src/main/java/com/volmit/iris/object/IrisDimension.java b/src/main/java/com/volmit/iris/object/IrisDimension.java index 3801cb405..993931efd 100644 --- a/src/main/java/com/volmit/iris/object/IrisDimension.java +++ b/src/main/java/com/volmit/iris/object/IrisDimension.java @@ -1,8 +1,9 @@ package com.volmit.iris.object; -import com.volmit.iris.scaffold.cache.AtomicCache; import com.volmit.iris.generator.noise.CNG; -import com.volmit.iris.scaffold.engine.GeneratorAccess; +import com.volmit.iris.manager.IrisDataManager; +import com.volmit.iris.scaffold.cache.AtomicCache; +import com.volmit.iris.scaffold.data.DataProvider; import com.volmit.iris.util.*; import lombok.AllArgsConstructor; import lombok.Data; @@ -376,7 +377,7 @@ public class IrisDimension extends IrisRegistrant return cosr.aquire(() -> Math.cos(getDimensionAngle())); } - public KList getAllRegions(GeneratorAccess g) + public KList getAllRegions(DataProvider g) { KList r = new KList<>(); @@ -388,18 +389,53 @@ public class IrisDimension extends IrisRegistrant return r; } - public KList getAllBiomes(GeneratorAccess g) + + public KList getAllAnyRegions() + { + KList r = new KList<>(); + + for(String i : getRegions()) + { + r.add(IrisDataManager.loadAnyRegion(i)); + } + + return r; + } + + public KList getAllBiomes(DataProvider g) { KList r = new KList<>(); for(IrisRegion i : getAllRegions(g)) { + if(i == null) + { + continue; + } + r.addAll(i.getAllBiomes(g)); } return r; } + public KList getAllAnyBiomes() + { + KList r = new KList<>(); + + for(IrisRegion i : getAllAnyRegions()) + { + if(i == null) + { + continue; + } + + r.addAll(i.getAllAnyBiomes()); + } + + return r; + } + public IrisGeneratorStyle getBiomeStyle(InferredType type) { switch(type) diff --git a/src/main/java/com/volmit/iris/object/IrisDimensionIndex.java b/src/main/java/com/volmit/iris/object/IrisDimensionIndex.java index 498d07306..2adc2001e 100644 --- a/src/main/java/com/volmit/iris/object/IrisDimensionIndex.java +++ b/src/main/java/com/volmit/iris/object/IrisDimensionIndex.java @@ -29,6 +29,10 @@ public class IrisDimensionIndex @Desc("If inverted is set to true, the dimension will be updide down in the world") private boolean inverted = false; + @DontObfuscate + @Desc("Only one dimension layer should be set to primary. The primary dimension layer is where players spawn, and the biomes that the vanilla structure system uses to figure out what structures to place.") + private boolean primary = false; + @DontObfuscate @Required @RegistryListDimension diff --git a/src/main/java/com/volmit/iris/object/IrisRegion.java b/src/main/java/com/volmit/iris/object/IrisRegion.java index 269a9b336..2ac2a2a6a 100644 --- a/src/main/java/com/volmit/iris/object/IrisRegion.java +++ b/src/main/java/com/volmit/iris/object/IrisRegion.java @@ -1,7 +1,8 @@ package com.volmit.iris.object; -import com.volmit.iris.scaffold.cache.AtomicCache; import com.volmit.iris.generator.noise.CNG; +import com.volmit.iris.manager.IrisDataManager; +import com.volmit.iris.scaffold.cache.AtomicCache; import com.volmit.iris.scaffold.data.DataProvider; import com.volmit.iris.util.*; import lombok.AllArgsConstructor; @@ -531,4 +532,43 @@ public class IrisRegion extends IrisRegistrant implements IRare return realLandBiomes; }); } + + public KList getAllAnyBiomes() { + KMap b = new KMap<>(); + KSet names = new KSet<>(); + names.addAll(landBiomes); + names.addAll(caveBiomes); + names.addAll(seaBiomes); + names.addAll(shoreBiomes); + names.addAll(riverBiomes); + names.addAll(lakeBiomes); + spotBiomes.forEach((i) -> names.add(i.getBiome())); + ridgeBiomes.forEach((i) -> names.add(i.getBiome())); + + while(!names.isEmpty()) + { + for(String i : new KList<>(names)) + { + if(b.containsKey(i)) + { + names.remove(i); + continue; + } + + IrisBiome biome = IrisDataManager.loadAnyBiome(i); + + names.remove(i); + if(biome == null) + { + continue; + } + + names.add(biome.getCarvingBiome()); + b.put(biome.getLoadKey(), biome); + names.addAll(biome.getChildren()); + } + } + + return b.v(); + } } diff --git a/src/main/java/com/volmit/iris/scaffold/engine/Engine.java b/src/main/java/com/volmit/iris/scaffold/engine/Engine.java index 3477d893b..9c943e862 100644 --- a/src/main/java/com/volmit/iris/scaffold/engine/Engine.java +++ b/src/main/java/com/volmit/iris/scaffold/engine/Engine.java @@ -48,7 +48,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro public double modifyZ(double z); - public void generate(int x, int z, Hunk blocks, Hunk biomes); + public void generate(int x, int z, Hunk blocks, Hunk postblocks, Hunk biomes); public EngineMetrics getMetrics(); diff --git a/src/main/java/com/volmit/iris/scaffold/engine/EngineCompositeGenerator.java b/src/main/java/com/volmit/iris/scaffold/engine/EngineCompositeGenerator.java index 8d8a9a4ab..2611cf10e 100644 --- a/src/main/java/com/volmit/iris/scaffold/engine/EngineCompositeGenerator.java +++ b/src/main/java/com/volmit/iris/scaffold/engine/EngineCompositeGenerator.java @@ -163,6 +163,81 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce return dim; } + private synchronized IrisDimension getDimension(String world) { + String hint = dimensionHint; + IrisDimension dim = null; + + if (hint == null) { + File iris = new File(world +"/iris"); + + if(iris.exists() && iris.isDirectory()) + { + searching: + for (File i : iris.listFiles()) { + // Look for v1 location + if (i.isDirectory() && i.getName().equals("dimensions")) { + for (File j : i.listFiles()) { + if (j.isFile() && j.getName().endsWith(".json")) { + hint = j.getName().replaceAll("\\Q.json\\E", ""); + Iris.error("Found v1 install. Please create a new world, this will cause chunks to change in your existing iris worlds!"); + throw new RuntimeException(); + } + } + } + + // Look for v2 location + else if (i.isFile() && i.getName().equals("engine-metadata.json")) { + EngineData metadata = EngineData.load(i); + hint = metadata.getDimension(); + break; + } + } + } + } + + if (hint == null) { + Iris.error("Cannot find iris dimension data for world: " + world + "! Assuming overworld!"); + hint = "overworld"; + } + + dim = IrisDataManager.loadAnyDimension(hint); + + if (dim == null) { + Iris.proj.downloadSearch(new MortarSender(Bukkit.getConsoleSender(), Iris.instance.getTag()), hint, false); + dim = IrisDataManager.loadAnyDimension(hint); + + if(dim == null) + { + throw new RuntimeException("Cannot find dimension: " + hint); + } + + else + { + Iris.info("Download pack: " + hint); + } + } + + if (production) { + IrisDimension od = dim; + dim = new IrisDataManager(getDataFolder(world)).getDimensionLoader().load(od.getLoadKey()); + + if (dim == null) { + Iris.info("Installing Iris pack " + od.getName() + " into world " + world + "..."); + Iris.proj.installIntoWorld(new MortarSender(Bukkit.getConsoleSender(), Iris.instance.getTag()), od.getLoadKey(), new File(world)); + dim = new IrisDataManager(getDataFolder(world)).getDimensionLoader().load(od.getLoadKey()); + + if(dim == null) + { + throw new RuntimeException("Cannot find dimension: " + hint); + } + } + } + + Iris.info(world + " is configured to generate " + dim.getName() + "!"); + + return dim; + } + private synchronized void initialize(World world) { if (initialized.get()) { return; @@ -182,22 +257,28 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce return new File(world.getWorldFolder(), "iris/pack"); } + private File getDataFolder(String world) { + return new File(world + "/iris/pack"); + } + @NotNull @Override public ChunkData generateChunkData(@NotNull World world, @NotNull Random ignored, int x, int z, @NotNull BiomeGrid biome) { TerrainChunk tc = TerrainChunk.create(world, biome); - generateChunkRawData(world, x, z, tc); + generateChunkRawData(world, x, z, tc).run(); return tc.getRaw(); } - public void generateChunkRawData(World world, int x, int z, TerrainChunk tc) + public Runnable generateChunkRawData(World world, int x, int z, TerrainChunk tc) { initialize(world); Hunk blocks = Hunk.view((ChunkData) tc); Hunk biomes = Hunk.view((BiomeGrid) tc); - long m = M.ms(); - compound.generate(x * 16, z * 16, blocks, biomes); + Hunk post = Hunk.newAtomicHunk(biomes.getWidth(), biomes.getHeight(), biomes.getDepth()); + compound.generate(x * 16, z * 16, blocks, post, biomes); generated++; + + return () -> blocks.insertSoftly(0,0,0,post, (b) -> b == null || B.isAir(b)); } @Override @@ -451,7 +532,14 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce @Override public boolean isClosed() { - return getComposite().getEngine(0).isClosed(); + try + { + return getComposite().getEngine(0).isClosed(); + } + catch(Throwable e) + { + return false; + } } @Override @@ -473,4 +561,36 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce public boolean isStudio() { return !production; } + + public boolean isVanillaCaves() { + return false; + } + + public KList getAllBiomes(String worldName) { + if(getComposite() != null) + { + return getComposite().getAllBiomes(); + } + + else + { + KMap v = new KMap<>(); + IrisDimension dim = getDimension(worldName); + dim.getAllAnyBiomes().forEach((i) -> v.put(i.getLoadKey(), i)); + + try + { + dim.getDimensionalComposite().forEach((m) -> IrisDataManager.loadAnyDimension(m.getDimension()).getAllAnyBiomes().forEach((i) -> v.put(i.getLoadKey(), i))); + } + + catch(Throwable e) + { + + } + + Iris.info("Injecting " + v.size() + " biomes into the NMS World Chunk Provider (Iris)"); + + return v.v(); + } + } } \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/scaffold/engine/EngineCompound.java b/src/main/java/com/volmit/iris/scaffold/engine/EngineCompound.java index 44db020c2..07af71059 100644 --- a/src/main/java/com/volmit/iris/scaffold/engine/EngineCompound.java +++ b/src/main/java/com/volmit/iris/scaffold/engine/EngineCompound.java @@ -1,10 +1,13 @@ package com.volmit.iris.scaffold.engine; import com.volmit.iris.manager.IrisDataManager; +import com.volmit.iris.object.IrisBiome; import com.volmit.iris.object.IrisDimension; +import com.volmit.iris.scaffold.data.DataProvider; import com.volmit.iris.scaffold.hunk.Hunk; import com.volmit.iris.scaffold.parallel.MultiBurst; import com.volmit.iris.util.KList; +import com.volmit.iris.util.KMap; import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -12,11 +15,11 @@ import org.bukkit.command.CommandSender; import org.bukkit.event.Listener; import org.bukkit.generator.BlockPopulator; -public interface EngineCompound extends Listener, Hotloadable +public interface EngineCompound extends Listener, Hotloadable, DataProvider { public IrisDimension getRootDimension(); - public void generate(int x, int z, Hunk blocks, Hunk biomes); + public void generate(int x, int z, Hunk blocks, Hunk postblocks, Hunk biomes); public World getWorld(); @@ -105,4 +108,26 @@ public interface EngineCompound extends Listener, Hotloadable getEngine(i).clean(); } } + + public Engine getDefaultEngine(); + + public default KList getAllBiomes() + { + KMap v = new KMap<>(); + + IrisDimension dim = getRootDimension(); + dim.getAllBiomes(this).forEach((i) -> v.put(i.getLoadKey(), i)); + + try + { + dim.getDimensionalComposite().forEach((m) -> getData().getDimensionLoader().load(m.getDimension()).getAllBiomes(this).forEach((i) -> v.put(i.getLoadKey(), i))); + } + + catch(Throwable e) + { + + } + + return v.v(); + } } diff --git a/src/main/java/com/volmit/iris/scaffold/hunk/Hunk.java b/src/main/java/com/volmit/iris/scaffold/hunk/Hunk.java index 6f9b77c72..62532b143 100644 --- a/src/main/java/com/volmit/iris/scaffold/hunk/Hunk.java +++ b/src/main/java/com/volmit/iris/scaffold/hunk/Hunk.java @@ -41,6 +41,11 @@ public interface Hunk return new BiomeGridHunkView(biome); } + public static Hunk fringe(Hunk i, Hunk o) + { + return new FringedHunkView<>(i, o); + } + public static Hunk view(ChunkData src) { return new ChunkDataHunkView(src); @@ -1309,6 +1314,11 @@ public interface Hunk insert(offX, offY, offZ, hunk, false); } + default void insertSoftly(int offX, int offY, int offZ, Hunk hunk, Predicate shouldOverwrite) + { + insertSoftly(offX, offY, offZ, hunk, false, shouldOverwrite); + } + /** * Insert a hunk into this one * @@ -1348,7 +1358,7 @@ public interface Hunk /** * Insert a hunk into this one with an offset and possibly inverting the y of * the inserted hunk - * + * * @param offX * the offset from zero for x * @param offY @@ -1375,4 +1385,38 @@ public interface Hunk } } } + + /** + * Insert a hunk into this one with an offset and possibly inverting the y of. Will never insert a node if its already used + * the inserted hunk + * + * @param offX + * the offset from zero for x + * @param offY + * the offset from zero for y + * @param offZ + * the offset from zero for z + * @param hunk + * the hunk to insert + * @param invertY + * should the inserted hunk be inverted + */ + default void insertSoftly(int offX, int offY, int offZ, Hunk hunk, boolean invertY, Predicate shouldOverwrite) + { + enforceBounds(offX, offY, offZ, hunk.getWidth(), hunk.getHeight(), hunk.getDepth()); + + for(int i = offX; i < offX + hunk.getWidth(); i++) + { + for(int j = offY; j < offY + hunk.getHeight(); j++) + { + for(int k = offZ; k < offZ + hunk.getDepth(); k++) + { + if(shouldOverwrite.test(getRaw(i, j, k))) + { + setRaw(i, j, k, hunk.getRaw(i - offX, j - offY, k - offZ)); + } + } + } + } + } } diff --git a/src/main/java/com/volmit/iris/scaffold/hunk/view/FringedHunkView.java b/src/main/java/com/volmit/iris/scaffold/hunk/view/FringedHunkView.java new file mode 100644 index 000000000..f1628e6b9 --- /dev/null +++ b/src/main/java/com/volmit/iris/scaffold/hunk/view/FringedHunkView.java @@ -0,0 +1,50 @@ +package com.volmit.iris.scaffold.hunk.view; + +import com.volmit.iris.scaffold.hunk.Hunk; + +public class FringedHunkView implements Hunk { + private final Hunk src; + private final Hunk out; + + public FringedHunkView(Hunk src, Hunk out) + { + this.src = src; + this.out = out; + } + + @Override + public void setRaw(int x, int y, int z, T t) + { + out.setRaw(x,y,z,t); + } + + @Override + public T getRaw(int x, int y, int z) + { + return src.getRaw(x, y, z); + } + + @Override + public int getWidth() + { + return src.getWidth(); + } + + @Override + public int getHeight() + { + return src.getHeight(); + } + + @Override + public int getDepth() + { + return src.getDepth(); + } + + @Override + public Hunk getSource() + { + return src; + } +}