diff --git a/src/main/java/com/volmit/iris/core/nms/INMS.java b/src/main/java/com/volmit/iris/core/nms/INMS.java index f624fa418..589045e27 100644 --- a/src/main/java/com/volmit/iris/core/nms/INMS.java +++ b/src/main/java/com/volmit/iris/core/nms/INMS.java @@ -20,7 +20,7 @@ package com.volmit.iris.core.nms; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.core.nms.v17_1.NMSBinding17_1; +import com.volmit.iris.core.nms.v18_1.NMSBinding18_1; import com.volmit.iris.core.nms.v1X.NMSBinding1X; import com.volmit.iris.util.collection.KMap; import org.bukkit.Bukkit; @@ -28,7 +28,7 @@ import org.bukkit.Bukkit; public class INMS { //@builder private static final KMap> bindings = new KMap>() - .qput("v1_17_R1", NMSBinding17_1.class); + .qput("v1_18_R1", NMSBinding18_1.class); //@done private static final INMSBinding binding = bind(); diff --git a/src/main/java/com/volmit/iris/core/nms/NMSVersion.java b/src/main/java/com/volmit/iris/core/nms/NMSVersion.java index c6e629039..7389f6909 100644 --- a/src/main/java/com/volmit/iris/core/nms/NMSVersion.java +++ b/src/main/java/com/volmit/iris/core/nms/NMSVersion.java @@ -24,6 +24,8 @@ import java.util.ArrayList; import java.util.List; public enum NMSVersion { + R1_18, + R1_17, R1_16, R1_15, R1_14, @@ -88,6 +90,14 @@ public enum NMSVersion { if (tryVersion("1_16_R1")) { return R1_16; } + + if (tryVersion("1_17_R1")) { + return R1_17; + } + + if (tryVersion("1_18_R1")) { + return R1_18; + } return null; } diff --git a/src/main/java/com/volmit/iris/core/nms/v17_1/NMSBinding17_1.java b/src/main/java/com/volmit/iris/core/nms/v17_1/NMSBinding17_1.java deleted file mode 100644 index eb5ca2d0d..000000000 --- a/src/main/java/com/volmit/iris/core/nms/v17_1/NMSBinding17_1.java +++ /dev/null @@ -1,486 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.core.nms.v17_1; - -import com.volmit.iris.Iris; -import com.volmit.iris.core.nms.INMSBinding; -import com.volmit.iris.engine.data.cache.AtomicCache; -import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.nbt.io.NBTUtil; -import com.volmit.iris.util.nbt.mca.NBTWorld; -import com.volmit.iris.util.nbt.mca.palette.MCABiomeContainer; -import com.volmit.iris.util.nbt.mca.palette.MCAChunkBiomeContainer; -import com.volmit.iris.util.nbt.mca.palette.MCAGlobalPalette; -import com.volmit.iris.util.nbt.mca.palette.MCAIdMap; -import com.volmit.iris.util.nbt.mca.palette.MCAIdMapper; -import com.volmit.iris.util.nbt.mca.palette.MCAPalette; -import com.volmit.iris.util.nbt.mca.palette.MCAPaletteAccess; -import com.volmit.iris.util.nbt.mca.palette.MCAPalettedContainer; -import com.volmit.iris.util.nbt.mca.palette.MCAWrappedPalettedContainer; -import com.volmit.iris.util.nbt.tag.CompoundTag; -import net.minecraft.core.BlockPosition; -import net.minecraft.core.IRegistry; -import net.minecraft.core.IRegistryWritable; -import net.minecraft.nbt.NBTCompressedStreamTools; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagDouble; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.resources.MinecraftKey; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.level.WorldServer; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.biome.BiomeBase; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.TileEntity; -import net.minecraft.world.level.block.state.IBlockData; -import net.minecraft.world.level.chunk.BiomeStorage; -import net.minecraft.world.level.chunk.Chunk; -import net.minecraft.world.level.chunk.ChunkSection; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; -import org.bukkit.craftbukkit.v1_17_R1.CraftServer; -import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_17_R1.block.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEntity; -import org.bukkit.entity.EntityType; -import org.bukkit.generator.ChunkGenerator; -import org.jetbrains.annotations.NotNull; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInput; -import java.io.DataInputStream; -import java.io.DataOutput; -import java.io.DataOutputStream; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -public class NMSBinding17_1 implements INMSBinding { - private final BlockData AIR = Material.AIR.createBlockData(); - private final KMap baseBiomeCache = new KMap<>(); - private final AtomicCache> registryCache = new AtomicCache<>(); - private final AtomicCache> globalCache = new AtomicCache<>(); - private final AtomicCache> biomeMapCache = new AtomicCache<>(); - private Field biomeStorageCache = null; - - public boolean supportsDataPacks() { - return true; - } - - @Override - public MCAPaletteAccess createPalette() { - MCAIdMapper registry = registryCache.aquireNasty(() -> { - Field cf = net.minecraft.core.RegistryBlockID.class.getDeclaredField("c"); - Field df = net.minecraft.core.RegistryBlockID.class.getDeclaredField("d"); - Field bf = net.minecraft.core.RegistryBlockID.class.getDeclaredField("b"); - cf.setAccessible(true); - df.setAccessible(true); - bf.setAccessible(true); - net.minecraft.core.RegistryBlockID blockData = Block.p; - int b = bf.getInt(blockData); - IdentityHashMap c = (IdentityHashMap) cf.get(blockData); - List d = (List) df.get(blockData); - return new MCAIdMapper<>(c, d, b); - }); - MCAPalette global = globalCache.aquireNasty(() -> new MCAGlobalPalette<>(registry, ((CraftBlockData) AIR).getState())); - MCAPalettedContainer container = new MCAPalettedContainer<>(global, registry, - i -> ((CraftBlockData) NBTWorld.getBlockData(i)).getState(), - i -> NBTWorld.getCompound(CraftBlockData.fromData(i)), - ((CraftBlockData) AIR).getState()); - return new MCAWrappedPalettedContainer<>(container, - i -> NBTWorld.getCompound(CraftBlockData.fromData(i)), - i -> ((CraftBlockData) NBTWorld.getBlockData(i)).getState()); - } - - private Object getBiomeStorage(ChunkGenerator.BiomeGrid g) { - try { - return getFieldForBiomeStorage(g).get(g); - } catch (IllegalAccessException e) { - Iris.reportError(e); - e.printStackTrace(); - } - - return null; - } - - @Override - public boolean hasTile(Location l) { - return ((CraftWorld) l.getWorld()).getHandle().getTileEntity(new BlockPosition(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null; - } - - @Override - public CompoundTag serializeTile(Location location) { - TileEntity e = ((CraftWorld) location.getWorld()).getHandle().getTileEntity(new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true); - - if (e == null) { - return null; - } - - NBTTagCompound tag = new NBTTagCompound(); - e.save(tag); - return convert(tag); - } - - @Override - public void deserializeTile(CompoundTag s, Location newPosition) { - NBTTagCompound c = convert(s); - - if (c != null) { - int x = newPosition.getBlockX(); - int y = newPosition.getBlockY(); - int z = newPosition.getBlockZ(); - WorldServer w = ((CraftWorld) newPosition.getWorld()).getHandle(); - Chunk ch = w.getChunkAt(x >> 4, z >> 4); - ChunkSection sect = ch.getSections()[y >> 4]; - IBlockData block = sect.getBlocks().a(x & 15, y & 15, z & 15); - BlockPosition pos = new BlockPosition(x, y, z); - ch.b(TileEntity.create(pos, block, c)); - } - } - - private NBTTagCompound convert(CompoundTag tag) { - try { - ByteArrayOutputStream boas = new ByteArrayOutputStream(); - NBTUtil.write(tag, boas, false); - DataInputStream din = new DataInputStream(new ByteArrayInputStream(boas.toByteArray())); - NBTTagCompound c = NBTCompressedStreamTools.a((DataInput) din); - din.close(); - return c; - } catch (Throwable e) { - e.printStackTrace(); - } - - return null; - } - - private CompoundTag convert(NBTTagCompound tag) { - try { - ByteArrayOutputStream boas = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(boas); - NBTCompressedStreamTools.a(tag, (DataOutput) dos); - dos.close(); - return (CompoundTag) NBTUtil.read(new ByteArrayInputStream(boas.toByteArray()), false).getTag(); - } catch (Throwable ex) { - ex.printStackTrace(); - } - - return null; - } - - @Override - public CompoundTag serializeEntity(org.bukkit.entity.Entity be) { - Entity entity = ((CraftEntity) be).getHandle(); - NBTTagCompound tag = new NBTTagCompound(); - entity.save(tag); - CompoundTag t = convert(tag); - t.putInt("btype", be.getType().ordinal()); - return t; - } - - @Override - public org.bukkit.entity.Entity deserializeEntity(CompoundTag s, Location newPosition) { - - EntityType type = EntityType.values()[s.getInt("btype")]; - s.remove("btype"); - NBTTagCompound tag = convert(s); - NBTTagList pos = tag.getList("Pos", 6); - pos.a(0, NBTTagDouble.a(newPosition.getX())); - pos.a(1, NBTTagDouble.a(newPosition.getY())); - pos.a(2, NBTTagDouble.a(newPosition.getZ())); - tag.set("Pos", pos); - org.bukkit.entity.Entity be = newPosition.getWorld().spawnEntity(newPosition, type); - ((CraftEntity) be).getHandle().load(tag); - - return be; - } - - @Override - public boolean supportsCustomHeight() { - return false; - } - - private Field getFieldForBiomeStorage(Object storage) { - Field f = biomeStorageCache; - - if (f != null) { - return f; - } - try { - - f = storage.getClass().getDeclaredField("biome"); - f.setAccessible(true); - return f; - } catch (Throwable e) { - Iris.reportError(e); - e.printStackTrace(); - Iris.error(storage.getClass().getCanonicalName()); - } - - biomeStorageCache = f; - return null; - } - - private IRegistryWritable getCustomBiomeRegistry() { - return ((CraftServer) Bukkit.getServer()).getHandle().getServer().getCustomRegistry().b(IRegistry.aO); - } - - @Override - public Object getBiomeBaseFromId(int id) { - return getCustomBiomeRegistry().fromId(id); - } - - @Override - public int getTrueBiomeBaseId(Object biomeBase) { - return getCustomBiomeRegistry().getId((BiomeBase) biomeBase); - } - - @Override - public Object getTrueBiomeBase(Location location) { - return ((CraftWorld) location.getWorld()).getHandle().getBiome(location.getBlockX(), location.getBlockY(), location.getBlockZ()); - } - - @Override - public String getTrueBiomeBaseKey(Location location) { - return getKeyForBiomeBase(getTrueBiomeBase(location)); - } - - @Override - public boolean supportsCustomBiomes() { - return true; - } - - @Override - public int getMinHeight(World world) { - return world.getMinHeight(); - } - - @Override - public Object getCustomBiomeBaseFor(String mckey) { - try { - return getCustomBiomeRegistry().d(ResourceKey.a(IRegistry.aO, new MinecraftKey(mckey.toLowerCase()))); - } catch (Throwable e) { - Iris.reportError(e); - } - - return null; - } - - @SuppressWarnings("OptionalGetWithoutIsPresent") - @Override - public String getKeyForBiomeBase(Object biomeBase) { - return getCustomBiomeRegistry().c((BiomeBase) biomeBase).get().a().toString(); - } - - @Override - public Object getBiomeBase(World world, Biome biome) { - return getBiomeBase(((CraftWorld) world).getHandle().t().d(IRegistry.aO), biome); - } - - private Class[] classify(Object... par) { - Class[] g = new Class[par.length]; - for (int i = 0; i < g.length; i++) { - g[i] = par[i].getClass(); - } - - return g; - } - - private T invoke(Object from, String name, Object... par) { - try { - Method f = from.getClass().getDeclaredMethod(name, classify(par)); - f.setAccessible(true); - //noinspection unchecked - return (T) f.invoke(from, par); - } catch (Throwable e) { - Iris.reportError(e); - e.printStackTrace(); - } - - return null; - } - - private T invokeStatic(Class from, String name, Object... par) { - try { - Method f = from.getDeclaredMethod(name, classify(par)); - f.setAccessible(true); - //noinspection unchecked - return (T) f.invoke(null, par); - } catch (Throwable e) { - Iris.reportError(e); - e.printStackTrace(); - } - - return null; - } - - private T getField(Object from, String name) { - try { - Field f = from.getClass().getDeclaredField(name); - f.setAccessible(true); - //noinspection unchecked - return (T) f.get(from); - } catch (Throwable e) { - Iris.reportError(e); - e.printStackTrace(); - } - - return null; - } - - private T getStaticField(Class t, String name) { - try { - Field f = t.getDeclaredField(name); - f.setAccessible(true); - //noinspection unchecked - return (T) f.get(null); - } catch (Throwable e) { - Iris.reportError(e); - e.printStackTrace(); - } - - return null; - } - - @Override - public Object getBiomeBase(Object registry, Biome biome) { - Object v = baseBiomeCache.get(biome); - - if (v != null) { - return v; - } - //noinspection unchecked - v = org.bukkit.craftbukkit.v1_17_R1.block.CraftBlock.biomeToBiomeBase((IRegistry) registry, biome); - if (v == null) { - // Ok so there is this new biome name called "CUSTOM" in Paper's new releases. - // But, this does NOT exist within CraftBukkit which makes it return an error. - // So, we will just return the ID that the plains biome returns instead. - //noinspection unchecked - return org.bukkit.craftbukkit.v1_17_R1.block.CraftBlock.biomeToBiomeBase((IRegistry) registry, Biome.PLAINS); - } - baseBiomeCache.put(biome, v); - return v; - } - - @Override - public int getBiomeId(Biome biome) { - for (World i : Bukkit.getWorlds()) { - if (i.getEnvironment().equals(World.Environment.NORMAL)) { - - IRegistry registry = ((CraftWorld) i).getHandle().t().d(IRegistry.aO); - - return registry.getId((BiomeBase) getBiomeBase(registry, biome)); - } - } - - return biome.ordinal(); - } - - private MCAIdMap getBiomeMapping() { - return biomeMapCache.aquire(() -> new MCAIdMap<>() { - @NotNull - @Override - public Iterator iterator() { - return getCustomBiomeRegistry().iterator(); - } - - @Override - public int getId(BiomeBase paramT) { - return getCustomBiomeRegistry().getId(paramT); - } - - @Override - public BiomeBase byId(int paramInt) { - return getCustomBiomeRegistry().fromId(paramInt); - } - }); - } - - @Override - public MCABiomeContainer newBiomeContainer(int min, int max) { - MCAChunkBiomeContainer base = new MCAChunkBiomeContainer<>(getBiomeMapping(), min, max); - return getBiomeContainerInterface(getBiomeMapping(), base); - } - - @Override - public MCABiomeContainer newBiomeContainer(int min, int max, int[] data) { - MCAChunkBiomeContainer base = new MCAChunkBiomeContainer<>(getBiomeMapping(), min, max, data); - return getBiomeContainerInterface(getBiomeMapping(), base); - } - - @NotNull - private MCABiomeContainer getBiomeContainerInterface(MCAIdMap biomeMapping, MCAChunkBiomeContainer base) { - return new MCABiomeContainer() { - @Override - public int[] getData() { - return base.writeBiomes(); - } - - @Override - public void setBiome(int x, int y, int z, int id) { - base.setBiome(x, y, z, biomeMapping.byId(id)); - } - - @Override - public int getBiome(int x, int y, int z) { - return biomeMapping.getId(base.getBiome(x, y, z)); - } - }; - } - - @Override - public int countCustomBiomes() { - AtomicInteger a = new AtomicInteger(0); - getCustomBiomeRegistry().d().forEach((i) -> { - MinecraftKey k = i.getKey().a(); - - if (k.getNamespace().equals("minecraft")) { - return; - } - - a.incrementAndGet(); - Iris.debug("Custom Biome: " + k); - }); - - return a.get(); - } - - @Override - public void forceBiomeInto(int x, int y, int z, Object somethingVeryDirty, ChunkGenerator.BiomeGrid chunk) { - try { - BiomeStorage s = (BiomeStorage) getFieldForBiomeStorage(chunk).get(chunk); - s.setBiome(x, y, z, (BiomeBase) somethingVeryDirty); - } catch (IllegalAccessException e) { - Iris.reportError(e); - e.printStackTrace(); - } - } - - @Override - public boolean isBukkit() { - return false; - } -}