From 9ececd80d6a9e1adb02fa72c1760d9cb3333cf2f Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sat, 7 Nov 2020 11:05:30 -0500 Subject: [PATCH] NMS Support for 1.16.4 (R3) --- pom.xml | 6 + .../java/com/volmit/iris/gen/nms/INMS.java | 7 +- .../iris/gen/nms/v16_2/NMSBinding16_2.java | 2 +- .../iris/gen/nms/v16_3/NMSBinding16_3.java | 16 + .../v16_3/NMSChunkGenerator16_3_PAPER.java | 688 ++++++++++++++++++ .../v16_3/NMSChunkGenerator16_3_SPIGOT.java | 680 +++++++++++++++++ .../iris/gen/nms/v16_3/NMSCreator16_3.java | 270 +++++++ .../volmit/iris/gen/nms/v1X/NMSBinding1X.java | 2 +- 8 files changed, 1666 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/volmit/iris/gen/nms/v16_3/NMSBinding16_3.java create mode 100644 src/main/java/com/volmit/iris/gen/nms/v16_3/NMSChunkGenerator16_3_PAPER.java create mode 100644 src/main/java/com/volmit/iris/gen/nms/v16_3/NMSChunkGenerator16_3_SPIGOT.java create mode 100644 src/main/java/com/volmit/iris/gen/nms/v16_3/NMSCreator16_3.java diff --git a/pom.xml b/pom.xml index 492d49abf..47cfb989b 100644 --- a/pom.xml +++ b/pom.xml @@ -193,6 +193,12 @@ 1.16.2 provided + + org.bukkit.craftbukkit + cb-1.16.4 + 1.16.4 + provided + com.bergerkiller.bukkit diff --git a/src/main/java/com/volmit/iris/gen/nms/INMS.java b/src/main/java/com/volmit/iris/gen/nms/INMS.java index 2f967ace6..a10f3d9f1 100644 --- a/src/main/java/com/volmit/iris/gen/nms/INMS.java +++ b/src/main/java/com/volmit/iris/gen/nms/INMS.java @@ -1,18 +1,19 @@ package com.volmit.iris.gen.nms; -import org.bukkit.Bukkit; - import com.volmit.iris.Iris; import com.volmit.iris.IrisSettings; import com.volmit.iris.gen.nms.v16_2.NMSBinding16_2; +import com.volmit.iris.gen.nms.v16_3.NMSBinding16_3; import com.volmit.iris.gen.nms.v1X.NMSBinding1X; import com.volmit.iris.util.KMap; +import org.bukkit.Bukkit; 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/gen/nms/v16_2/NMSBinding16_2.java b/src/main/java/com/volmit/iris/gen/nms/v16_2/NMSBinding16_2.java index 7045e6101..1c75644fa 100644 --- a/src/main/java/com/volmit/iris/gen/nms/v16_2/NMSBinding16_2.java +++ b/src/main/java/com/volmit/iris/gen/nms/v16_2/NMSBinding16_2.java @@ -11,6 +11,6 @@ public class NMSBinding16_2 implements INMSBinding @Override public INMSCreator getCreator() { - return creator.aquire(() -> new NMSCreator16_2()); + return creator.aquire(NMSCreator16_2::new); } } diff --git a/src/main/java/com/volmit/iris/gen/nms/v16_3/NMSBinding16_3.java b/src/main/java/com/volmit/iris/gen/nms/v16_3/NMSBinding16_3.java new file mode 100644 index 000000000..25c5f8736 --- /dev/null +++ b/src/main/java/com/volmit/iris/gen/nms/v16_3/NMSBinding16_3.java @@ -0,0 +1,16 @@ +package com.volmit.iris.gen.nms.v16_3; + +import com.volmit.iris.gen.atomics.AtomicCache; +import com.volmit.iris.gen.nms.INMSBinding; +import com.volmit.iris.gen.nms.INMSCreator; + +public class NMSBinding16_3 implements INMSBinding +{ + private final AtomicCache creator = new AtomicCache<>(); + + @Override + public INMSCreator getCreator() + { + return creator.aquire(NMSCreator16_3::new); + } +} diff --git a/src/main/java/com/volmit/iris/gen/nms/v16_3/NMSChunkGenerator16_3_PAPER.java b/src/main/java/com/volmit/iris/gen/nms/v16_3/NMSChunkGenerator16_3_PAPER.java new file mode 100644 index 000000000..1ce3e1aab --- /dev/null +++ b/src/main/java/com/volmit/iris/gen/nms/v16_3/NMSChunkGenerator16_3_PAPER.java @@ -0,0 +1,688 @@ +package com.volmit.iris.gen.nms.v16_3; + +import com.mojang.serialization.Codec; +import com.volmit.iris.gen.IrisTerrainProvider; +import com.volmit.iris.gen.provisions.ProvisionBukkit; +import com.volmit.iris.gen.scaffold.GeneratedChunk; +import com.volmit.iris.gen.scaffold.Provisioned; +import com.volmit.iris.gen.scaffold.ProvisionedHolder; +import com.volmit.iris.gen.scaffold.TerrainProvider; +import com.volmit.iris.util.O; +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.Material; +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.generator.ChunkGenerator.BiomeGrid; +import org.bukkit.generator.ChunkGenerator.ChunkData; +import org.bukkit.material.MaterialData; + +import java.util.*; +import java.util.function.Supplier; + +@SuppressWarnings("deprecation") +public class NMSChunkGenerator16_3_PAPER extends ChunkGenerator implements ProvisionedHolder +{ + private static final IBlockData k = Blocks.AIR.getBlockData(); + private final Provisioned provisioned; + private final int maxHeight; + private final int xzSize; + protected final IBlockData f; + protected final IBlockData g; + private final long w; + protected final Supplier h; + private final O ws; + private BlockColumn BC; + + public NMSChunkGenerator16_3_PAPER(Provisioned p, O ws, WorldChunkManager worldchunkmanager, long i, Supplier supplier) + { + this(p, ws, worldchunkmanager, worldchunkmanager, i, supplier); + } + + private NMSChunkGenerator16_3_PAPER(Provisioned p, O ws, WorldChunkManager worldchunkmanager, WorldChunkManager worldchunkmanager1, long i, Supplier supplier) + { + super(worldchunkmanager, worldchunkmanager1, supplier.get().a(), i); + this.provisioned = p; + this.ws = ws; + this.w = i; + GeneratorSettingBase generatorsettingbase = supplier.get(); + + this.h = supplier; + NoiseSettings noisesettings = generatorsettingbase.b(); + + this.maxHeight = noisesettings.f() * 4; + this.f = generatorsettingbase.c(); + this.g = generatorsettingbase.d(); + 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(((IrisTerrainProvider) provisioned.getProvider()).getDimension().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) + { + return 63; + } + + @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 = NMSChunkGenerator16_3_PAPER.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; + + if(((IrisTerrainProvider) provisioned.getProvider()).shouldGenerateVanillaStructures()) + { + 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); + GeneratedChunk gc = ((ProvisionBukkit) provisioned).generateNMSChunkData(ws.get().getWorld(), new Random(i + j), i, j, new ChunkData() + { + public int getMaxHeight() + { + return 256; + } + + public void setBlock(int x, int y, int z, 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) + { + this.setBlock(x, y, z, ((CraftBlockData) blockData).getState()); + } + + public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, 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 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)); + } + + 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)); + } + } + }, new BiomeGrid() + { + @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, y, z)); + } + + @Override + public Biome getBiome(int x, int z) + { + return CraftBlock.biomeBaseToBiome(ws.get().r().b(IRegistry.ay), protochunk.getBiomeIndex().getBiome(x, 0, z)); + } + }); + + for(int xx = 0; xx < 16; xx++) + { + for(int zz = 0; zz < 16; zz++) + { + try + { + int y = gc.getHeight().getHeight(xx, zz); + if(y < getSeaLevel()) + { + heightmap.a(xx, y, zz, Blocks.STONE.getBlockData()); + } + heightmap1.a(xx, Math.max(y, getSeaLevel()), zz, Blocks.STONE.getBlockData()); + } + + catch(Throwable e) + { + + } + } + } + } + + public void addDecorations(RegionLimitedWorldAccess regionlimitedworldaccess, StructureManager structuremanager) + { + if(((IrisTerrainProvider) provisioned.getProvider()).shouldGenerateVanillaStructures()) + { + 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 = this.b.getBiome((i << 2) + 2, 2, (j << 2) + 2); + SeededRandom seededrandom = new SeededRandom(); + long i1 = seededrandom.a(regionlimitedworldaccess.getSeed(), k, l); + try + { + a(biomebase, structuremanager, this, regionlimitedworldaccess, i1, seededrandom, blockposition); + } + catch(Exception exception) + { + + } + } + } + + public void a(BiomeBase bbase, StructureManager var0, ChunkGenerator var1, RegionLimitedWorldAccess var2, long var3, SeededRandom var5, BlockPosition var6) + { + if(!((IrisTerrainProvider) provisioned.getProvider()).shouldGenerateVanillaStructures()) + { + return; + } + + 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(); + + if(var13.equals(StructureGenerator.VILLAGE)) + { + continue; + } + + if(var13.equals(StructureGenerator.JUNGLE_PYRAMID)) + { + continue; + } + + if(var13.equals(StructureGenerator.IGLOO)) + { + continue; + } + + if(var13.equals(StructureGenerator.MINESHAFT)) + { + continue; + } + + if(var13.equals(StructureGenerator.NETHER_FOSSIL)) + { + continue; + } + + if(var13.equals(StructureGenerator.SHIPWRECK)) + { + continue; + } + + if(var13.equals(StructureGenerator.SHIPWRECK)) + { + continue; + } + + if(var13.equals(StructureGenerator.MONUMENT)) + { + continue; + } + + if(var13.equals(StructureGenerator.OCEAN_RUIN)) + { + continue; + } + + if(var13.equals(StructureGenerator.BASTION_REMNANT)) + { + continue; + } + + 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() + { + return ((IrisTerrainProvider) provisioned.getProvider()).getFluidHeight(); + } + + @Override + public List getMobsFor(BiomeBase biomebase, StructureManager structuremanager, EnumCreatureType enumcreaturetype, BlockPosition blockposition) + { + if(structuremanager.a(blockposition, true, StructureGenerator.SWAMP_HUT).e()) + { + if(enumcreaturetype == EnumCreatureType.MONSTER) + { + return StructureGenerator.SWAMP_HUT.c(); + } + + if(enumcreaturetype == EnumCreatureType.CREATURE) + { + return StructureGenerator.SWAMP_HUT.j(); + } + } + + if(enumcreaturetype == EnumCreatureType.MONSTER) + { + if(structuremanager.a(blockposition, false, StructureGenerator.PILLAGER_OUTPOST).e()) + { + return StructureGenerator.PILLAGER_OUTPOST.c(); + } + + if(structuremanager.a(blockposition, false, StructureGenerator.MONUMENT).e()) + { + return StructureGenerator.MONUMENT.c(); + } + + if(structuremanager.a(blockposition, true, StructureGenerator.FORTRESS).e()) + { + return StructureGenerator.FORTRESS.c(); + } + } + + return super.getMobsFor(biomebase, structuremanager, enumcreaturetype, blockposition); + } + + @Override + public void addMobs(RegionLimitedWorldAccess regionlimitedworldaccess) + { + int i = regionlimitedworldaccess.a(); + int j = regionlimitedworldaccess.b(); + BiomeBase biomebase = regionlimitedworldaccess.getBiome((new ChunkCoordIntPair(i, j)).l()); + SeededRandom seededrandom = new SeededRandom(); + seededrandom.a(regionlimitedworldaccess.getSeed(), i << 4, j << 4); + SpawnerCreature.a(regionlimitedworldaccess, biomebase, i, j, seededrandom); + } + + public void createStructures(IRegistryCustom iregistrycustom, StructureManager structuremanager, IChunkAccess ichunkaccess, DefinedStructureManager definedstructuremanager, long i) + { + ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos(); + BiomeBase biomebase = this.b.getBiome((chunkcoordintpair.x << 2) + 2, 0, (chunkcoordintpair.z << 2) + 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; + } + } + + @Override + public Provisioned getProvisioned() + { + return provisioned; + } + + @Override + public void clearRegeneratedLists() + { + getProvisioned().clearRegeneratedLists(); + } + + @Override + public TerrainProvider getProvider() + { + return getProvisioned().getProvider(); + } + + @Override + public void regenerate(int x, int z) + { + getProvisioned().regenerate(x, z); + } +} diff --git a/src/main/java/com/volmit/iris/gen/nms/v16_3/NMSChunkGenerator16_3_SPIGOT.java b/src/main/java/com/volmit/iris/gen/nms/v16_3/NMSChunkGenerator16_3_SPIGOT.java new file mode 100644 index 000000000..22bd8331f --- /dev/null +++ b/src/main/java/com/volmit/iris/gen/nms/v16_3/NMSChunkGenerator16_3_SPIGOT.java @@ -0,0 +1,680 @@ +package com.volmit.iris.gen.nms.v16_3; + +import com.mojang.serialization.Codec; +import com.volmit.iris.gen.IrisTerrainProvider; +import com.volmit.iris.gen.provisions.ProvisionBukkit; +import com.volmit.iris.gen.scaffold.GeneratedChunk; +import com.volmit.iris.gen.scaffold.Provisioned; +import com.volmit.iris.gen.scaffold.ProvisionedHolder; +import com.volmit.iris.gen.scaffold.TerrainProvider; +import com.volmit.iris.util.O; +import com.volmit.iris.util.V; +import net.minecraft.server.v1_16_R3.*; +import org.bukkit.Material; +import org.bukkit.block.Biome; +import org.bukkit.block.data.BlockData; +import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.objects.ObjectList; +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.generator.ChunkGenerator.BiomeGrid; +import org.bukkit.generator.ChunkGenerator.ChunkData; +import org.bukkit.material.MaterialData; + +import java.util.*; +import java.util.function.Supplier; + +@SuppressWarnings("deprecation") +public class NMSChunkGenerator16_3_SPIGOT extends ChunkGenerator implements ProvisionedHolder +{ + private static final IBlockData k = Blocks.AIR.getBlockData(); + private final Provisioned provisioned; + private final int maxHeight; + private final int xzSize; + protected final IBlockData f; + protected final IBlockData g; + private final long w; + protected final Supplier h; + private final O ws; + private BlockColumn BC; + + public NMSChunkGenerator16_3_SPIGOT(Provisioned p, O ws, WorldChunkManager worldchunkmanager, long i, Supplier supplier) + { + this(p, ws, worldchunkmanager, worldchunkmanager, i, supplier); + } + + private NMSChunkGenerator16_3_SPIGOT(Provisioned p, O ws, WorldChunkManager worldchunkmanager, WorldChunkManager worldchunkmanager1, long i, Supplier supplier) + { + super(worldchunkmanager, worldchunkmanager1, supplier.get().a(), i); + this.provisioned = p; + this.ws = ws; + this.w = i; + GeneratorSettingBase generatorsettingbase = supplier.get(); + + this.h = supplier; + NoiseSettings noisesettings = generatorsettingbase.b(); + + this.maxHeight = noisesettings.f() * 4; + this.f = generatorsettingbase.c(); + this.g = generatorsettingbase.d(); + 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(((IrisTerrainProvider) provisioned.getProvider()).getDimension().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) + { + return 63; + } + + @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 = NMSChunkGenerator16_3_SPIGOT.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; + + if(((IrisTerrainProvider) provisioned.getProvider()).shouldGenerateVanillaStructures()) + { + 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); + GeneratedChunk gc = ((ProvisionBukkit) provisioned).generateNMSChunkData(ws.get().getWorld(), new Random(i + j), i, j, new ChunkData() + { + public int getMaxHeight() + { + return 256; + } + + public void setBlock(int x, int y, int z, 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) + { + this.setBlock(x, y, z, ((CraftBlockData) blockData).getState()); + } + + public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, 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 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)); + } + + 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)); + } + } + }, new BiomeGrid() + { + @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, y, z)); + } + + @Override + public Biome getBiome(int x, int z) + { + return CraftBlock.biomeBaseToBiome(ws.get().r().b(IRegistry.ay), protochunk.getBiomeIndex().getBiome(x, 0, z)); + } + }); + + for(int xx = 0; xx < 16; xx++) + { + for(int zz = 0; zz < 16; zz++) + { + int y = gc.getHeight().getHeight(xx, zz); + if(y < getSeaLevel()) + { + heightmap.a(xx, y, zz, Blocks.STONE.getBlockData()); + } + heightmap1.a(xx, Math.max(y, getSeaLevel()), zz, Blocks.STONE.getBlockData()); + } + } + } + + public void addDecorations(RegionLimitedWorldAccess regionlimitedworldaccess, StructureManager structuremanager) + { + if(((IrisTerrainProvider) provisioned.getProvider()).shouldGenerateVanillaStructures()) + { + 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 = this.b.getBiome((i << 2) + 2, 2, (j << 2) + 2); + SeededRandom seededrandom = new SeededRandom(); + long i1 = seededrandom.a(regionlimitedworldaccess.getSeed(), k, l); + try + { + a(biomebase, structuremanager, this, regionlimitedworldaccess, i1, seededrandom, blockposition); + } + catch(Exception exception) + { + + } + } + } + + public void a(BiomeBase bbase, StructureManager var0, ChunkGenerator var1, RegionLimitedWorldAccess var2, long var3, SeededRandom var5, BlockPosition var6) + { + if(!((IrisTerrainProvider) provisioned.getProvider()).shouldGenerateVanillaStructures()) + { + return; + } + + 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(); + + if(var13.equals(StructureGenerator.VILLAGE)) + { + continue; + } + + if(var13.equals(StructureGenerator.JUNGLE_PYRAMID)) + { + continue; + } + + if(var13.equals(StructureGenerator.OCEAN_RUIN)) + { + continue; + } + + if(var13.equals(StructureGenerator.IGLOO)) + { + continue; + } + + if(var13.equals(StructureGenerator.MINESHAFT)) + { + continue; + } + + if(var13.equals(StructureGenerator.NETHER_FOSSIL)) + { + continue; + } + + if(var13.equals(StructureGenerator.SHIPWRECK)) + { + continue; + } + + if(var13.equals(StructureGenerator.SHIPWRECK)) + { + continue; + } + + if(var13.equals(StructureGenerator.MONUMENT)) + { + continue; + } + + if(var13.equals(StructureGenerator.BASTION_REMNANT)) + { + continue; + } + + 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() + { + return ((IrisTerrainProvider) provisioned.getProvider()).getFluidHeight(); + } + + @Override + public List getMobsFor(BiomeBase biomebase, StructureManager structuremanager, EnumCreatureType enumcreaturetype, BlockPosition blockposition) + { + if(structuremanager.a(blockposition, true, StructureGenerator.SWAMP_HUT).e()) + { + if(enumcreaturetype == EnumCreatureType.MONSTER) + { + return StructureGenerator.SWAMP_HUT.c(); + } + + if(enumcreaturetype == EnumCreatureType.CREATURE) + { + return StructureGenerator.SWAMP_HUT.j(); + } + } + + if(enumcreaturetype == EnumCreatureType.MONSTER) + { + if(structuremanager.a(blockposition, false, StructureGenerator.PILLAGER_OUTPOST).e()) + { + return StructureGenerator.PILLAGER_OUTPOST.c(); + } + + if(structuremanager.a(blockposition, false, StructureGenerator.MONUMENT).e()) + { + return StructureGenerator.MONUMENT.c(); + } + + if(structuremanager.a(blockposition, true, StructureGenerator.FORTRESS).e()) + { + return StructureGenerator.FORTRESS.c(); + } + } + + return super.getMobsFor(biomebase, structuremanager, enumcreaturetype, blockposition); + } + + @Override + public void addMobs(RegionLimitedWorldAccess regionlimitedworldaccess) + { + int i = regionlimitedworldaccess.a(); + int j = regionlimitedworldaccess.b(); + BiomeBase biomebase = regionlimitedworldaccess.getBiome((new ChunkCoordIntPair(i, j)).l()); + SeededRandom seededrandom = new SeededRandom(); + seededrandom.a(regionlimitedworldaccess.getSeed(), i << 4, j << 4); + SpawnerCreature.a(regionlimitedworldaccess, biomebase, i, j, seededrandom); + } + + public void createStructures(IRegistryCustom iregistrycustom, StructureManager structuremanager, IChunkAccess ichunkaccess, DefinedStructureManager definedstructuremanager, long i) + { + ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos(); + BiomeBase biomebase = this.b.getBiome((chunkcoordintpair.x << 2) + 2, 0, (chunkcoordintpair.z << 2) + 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; + } + } + + @Override + public Provisioned getProvisioned() + { + return provisioned; + } + + @Override + public void clearRegeneratedLists() + { + getProvisioned().clearRegeneratedLists(); + } + + @Override + public TerrainProvider getProvider() + { + return getProvisioned().getProvider(); + } + + @Override + public void regenerate(int x, int z) + { + getProvisioned().regenerate(x, z); + } +} diff --git a/src/main/java/com/volmit/iris/gen/nms/v16_3/NMSCreator16_3.java b/src/main/java/com/volmit/iris/gen/nms/v16_3/NMSCreator16_3.java new file mode 100644 index 000000000..d91b86205 --- /dev/null +++ b/src/main/java/com/volmit/iris/gen/nms/v16_3/NMSCreator16_3.java @@ -0,0 +1,270 @@ +package com.volmit.iris.gen.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.gen.nms.INMSCreator; +import com.volmit.iris.gen.scaffold.IrisWorlds; +import com.volmit.iris.gen.scaffold.Provisioned; +import com.volmit.iris.util.O; +import com.volmit.iris.util.V; +import io.papermc.lib.PaperLib; +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(); + } + + Provisioned pro = (Provisioned) 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_R3.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_R3.ChunkGenerator chunkgenerator; + long ll = creator.seed(); + dimensionmanager = (DimensionManager) getConsoleDimension(console).a().d(DimensionManager.OVERWORLD); + O ws = new O(); + chunkgenerator = PaperLib.isPaper() ? new NMSChunkGenerator16_3_PAPER(pro, ws, (WorldChunkManager) new WorldChunkManagerOverworld(ll, false, false, (IRegistry) getConsoleDimension(console).b(IRegistry.ay)), ll, + + () -> (GeneratorSettingBase) + getConsoleDimension(console) + .b(IRegistry.ar) + .d(GeneratorSettingBase.c)) : new NMSChunkGenerator16_3_SPIGOT(pro, ws, (WorldChunkManager) new WorldChunkManagerOverworld(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; + } +} diff --git a/src/main/java/com/volmit/iris/gen/nms/v1X/NMSBinding1X.java b/src/main/java/com/volmit/iris/gen/nms/v1X/NMSBinding1X.java index 57eae74a4..ea68120dd 100644 --- a/src/main/java/com/volmit/iris/gen/nms/v1X/NMSBinding1X.java +++ b/src/main/java/com/volmit/iris/gen/nms/v1X/NMSBinding1X.java @@ -11,6 +11,6 @@ public class NMSBinding1X implements INMSBinding @Override public INMSCreator getCreator() { - return creator.aquire(() -> new NMSCreator1X()); + return creator.aquire(NMSCreator1X::new); } }