diff --git a/src/main/java/com/volmit/iris/core/nms/v18_1/NMSBinding18_1.java b/src/main/java/com/volmit/iris/core/nms/v18_1/NMSBinding18_1.java index 80b065ebc..ecaab0e6b 100644 --- a/src/main/java/com/volmit/iris/core/nms/v18_1/NMSBinding18_1.java +++ b/src/main/java/com/volmit/iris/core/nms/v18_1/NMSBinding18_1.java @@ -24,22 +24,37 @@ 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 it.unimi.dsi.fastutil.objects.Object2IntMap; import net.minecraft.core.Registry; import net.minecraft.nbt.NbtIo; import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; 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_18_R1.CraftChunk; import org.bukkit.craftbukkit.v1_18_R1.CraftServer; import org.bukkit.craftbukkit.v1_18_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_18_R1.block.data.CraftBlockData; +import org.bukkit.craftbukkit.v1_18_R1.generator.CustomChunkGenerator; import org.bukkit.entity.Entity; import org.bukkit.generator.ChunkGenerator; import org.jetbrains.annotations.NotNull; @@ -48,13 +63,20 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; +import java.lang.reflect.Field; +import java.util.IdentityHashMap; import java.util.Iterator; +import java.util.List; import java.util.concurrent.atomic.AtomicInteger; public class NMSBinding18_1 implements INMSBinding { private final KMap baseBiomeCache = new KMap<>(); + private final BlockData AIR = Material.AIR.createBlockData(); private final AtomicCache> biomeMapCache = new AtomicCache<>(); + private final AtomicCache> registryCache = new AtomicCache<>(); + private final AtomicCache> globalCache = new AtomicCache<>(); + private Field biomeStorageCache = null; @Override public boolean hasTile(Location l) { @@ -126,6 +148,10 @@ public class NMSBinding18_1 implements INMSBinding { return ((CraftServer) Bukkit.getServer()).getHandle().getServer().registryHolder.registry(Registry.BIOME_REGISTRY).orElse(null); } + private Registry getBlockRegistry() { + return ((CraftServer) Bukkit.getServer()).getHandle().getServer().registryHolder.registry(Registry.BLOCK_REGISTRY).orElse(null); + } + @Override public Object getBiomeBaseFromId(int id) { return getCustomBiomeRegistry().byId(id); @@ -223,7 +249,7 @@ public class NMSBinding18_1 implements INMSBinding { @Override public net.minecraft.world.level.biome.Biome byId(int paramInt) { - return getCustomBiomeRegistry().fromId(paramInt); + return getCustomBiomeRegistry().byId(paramInt); } }); } @@ -279,17 +305,57 @@ public class NMSBinding18_1 implements INMSBinding { @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); + ChunkAccess s = (ChunkAccess) getFieldForBiomeStorage(chunk).get(chunk); + s.setBiome(x, y, z, (net.minecraft.world.level.biome.Biome) somethingVeryDirty); } catch (IllegalAccessException e) { Iris.reportError(e); e.printStackTrace(); } } - @Override - public MCAPaletteAccess createPalette() { + 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; } + + @Override + public MCAPaletteAccess createPalette() { + MCAIdMapper registry = registryCache.aquireNasty(() -> { + Field cf = net.minecraft.core.IdMapper.class.getDeclaredField("tToId"); + Field df = net.minecraft.core.IdMapper.class.getDeclaredField("idToT"); + Field bf = net.minecraft.core.IdMapper.class.getDeclaredField("nextId"); + cf.setAccessible(true); + df.setAccessible(true); + bf.setAccessible(true); + net.minecraft.core.IdMapper blockData = Block.BLOCK_STATE_REGISTRY; + int b = bf.getInt(blockData); + Object2IntMap c = (Object2IntMap) 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()); + } } diff --git a/src/main/java/com/volmit/iris/util/nbt/mca/palette/MCAIdMapper.java b/src/main/java/com/volmit/iris/util/nbt/mca/palette/MCAIdMapper.java index d12f094f9..b0d78e843 100644 --- a/src/main/java/com/volmit/iris/util/nbt/mca/palette/MCAIdMapper.java +++ b/src/main/java/com/volmit/iris/util/nbt/mca/palette/MCAIdMapper.java @@ -21,6 +21,12 @@ package com.volmit.iris.util.nbt.mca.palette; import com.google.common.base.Predicates; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import it.unimi.dsi.fastutil.Hash; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenCustomHashMap; +import net.kyori.adventure.identity.Identity; +import net.minecraft.Util; import java.util.IdentityHashMap; import java.util.Iterator; @@ -28,11 +34,11 @@ import java.util.List; public class MCAIdMapper implements MCAIdMap { public static final int DEFAULT = -1; - private final IdentityHashMap tToId; + private final Object2IntMap tToId; private final List idToT; private int nextId; - public MCAIdMapper(IdentityHashMap tToId, List idToT, int nextId) { + public MCAIdMapper(Object2IntMap tToId, List idToT, int nextId) { this.tToId = tToId; this.idToT = idToT; this.nextId = nextId; @@ -44,7 +50,7 @@ public class MCAIdMapper implements MCAIdMap { public MCAIdMapper(int var0) { this.idToT = Lists.newArrayListWithExpectedSize(var0); - this.tToId = new IdentityHashMap<>(var0); + this.tToId = new Object2IntOpenCustomHashMap<>(var0, IdentityStrategy.INSTANCE); } public void addMapping(T var0, int var1) { @@ -82,4 +88,19 @@ public class MCAIdMapper implements MCAIdMap { public int size() { return this.tToId.size(); } + + static enum IdentityStrategy implements Hash.Strategy { + INSTANCE; + + private IdentityStrategy() { + } + + public int hashCode(Object var0) { + return System.identityHashCode(var0); + } + + public boolean equals(Object var0, Object var1) { + return var0 == var1; + } + } } \ No newline at end of file