From 4e409a80c742c743f1a1b78deaf2991234ee1edf Mon Sep 17 00:00:00 2001 From: jacob1 Date: Sat, 9 Nov 2024 20:56:09 -0500 Subject: [PATCH] Spigot / Paper 1.21.3 support --- .../BukkitVersionHelperSpigot119_3.java | 2 +- .../BukkitVersionHelperSpigot119_4.java | 2 +- .../BukkitVersionHelperSpigot120_2.java | 2 +- .../BukkitVersionHelperSpigot120_4.java | 2 +- .../BukkitVersionHelperSpigot120_5.java | 2 +- .../v120/BukkitVersionHelperSpigot120.java | 2 +- bukkit-helper-121-3/build.gradle | 17 + .../BukkitVersionHelperSpigot121_3.java | 452 ++++++++++++++++++ .../helper/v121_3/MapChunkCache121_3.java | 76 +++ .../org/dynmap/bukkit/helper/v121_3/NBT.java | 126 +++++ .../v121/BukkitVersionHelperSpigot121.java | 2 +- settings.gradle | 2 + spigot/build.gradle | 4 + .../main/java/org/dynmap/bukkit/Helper.java | 5 +- 14 files changed, 688 insertions(+), 8 deletions(-) create mode 100644 bukkit-helper-121-3/build.gradle create mode 100644 bukkit-helper-121-3/src/main/java/org/dynmap/bukkit/helper/v121_3/BukkitVersionHelperSpigot121_3.java create mode 100644 bukkit-helper-121-3/src/main/java/org/dynmap/bukkit/helper/v121_3/MapChunkCache121_3.java create mode 100644 bukkit-helper-121-3/src/main/java/org/dynmap/bukkit/helper/v121_3/NBT.java diff --git a/bukkit-helper-119-3/src/main/java/org/dynmap/bukkit/helper/v119_3/BukkitVersionHelperSpigot119_3.java b/bukkit-helper-119-3/src/main/java/org/dynmap/bukkit/helper/v119_3/BukkitVersionHelperSpigot119_3.java index 2cb2ac67..5c7394a7 100644 --- a/bukkit-helper-119-3/src/main/java/org/dynmap/bukkit/helper/v119_3/BukkitVersionHelperSpigot119_3.java +++ b/bukkit-helper-119-3/src/main/java/org/dynmap/bukkit/helper/v119_3/BukkitVersionHelperSpigot119_3.java @@ -368,7 +368,7 @@ public class BukkitVersionHelperSpigot119_3 extends BukkitVersionHelper { NBTBase val = rec.c(field); if(val == null) return null; if(val instanceof NBTTagByte) { - return ((NBTTagByte)val).h(); + return ((NBTTagByte)val).i(); } else if(val instanceof NBTTagShort) { return ((NBTTagShort)val).g(); diff --git a/bukkit-helper-119-4/src/main/java/org/dynmap/bukkit/helper/v119_4/BukkitVersionHelperSpigot119_4.java b/bukkit-helper-119-4/src/main/java/org/dynmap/bukkit/helper/v119_4/BukkitVersionHelperSpigot119_4.java index fb62b90f..0e8368ae 100644 --- a/bukkit-helper-119-4/src/main/java/org/dynmap/bukkit/helper/v119_4/BukkitVersionHelperSpigot119_4.java +++ b/bukkit-helper-119-4/src/main/java/org/dynmap/bukkit/helper/v119_4/BukkitVersionHelperSpigot119_4.java @@ -376,7 +376,7 @@ public class BukkitVersionHelperSpigot119_4 extends BukkitVersionHelper { NBTBase val = rec.c(field); if(val == null) return null; if(val instanceof NBTTagByte) { - return ((NBTTagByte)val).h(); + return ((NBTTagByte)val).i(); } else if(val instanceof NBTTagShort) { return ((NBTTagShort)val).g(); diff --git a/bukkit-helper-120-2/src/main/java/org/dynmap/bukkit/helper/v120_2/BukkitVersionHelperSpigot120_2.java b/bukkit-helper-120-2/src/main/java/org/dynmap/bukkit/helper/v120_2/BukkitVersionHelperSpigot120_2.java index 0ea5d571..a0083e2c 100644 --- a/bukkit-helper-120-2/src/main/java/org/dynmap/bukkit/helper/v120_2/BukkitVersionHelperSpigot120_2.java +++ b/bukkit-helper-120-2/src/main/java/org/dynmap/bukkit/helper/v120_2/BukkitVersionHelperSpigot120_2.java @@ -374,7 +374,7 @@ public class BukkitVersionHelperSpigot120_2 extends BukkitVersionHelper { NBTBase val = rec.c(field); if(val == null) return null; if(val instanceof NBTTagByte) { - return ((NBTTagByte)val).h(); + return ((NBTTagByte)val).i(); } else if(val instanceof NBTTagShort) { return ((NBTTagShort)val).g(); diff --git a/bukkit-helper-120-4/src/main/java/org/dynmap/bukkit/helper/v120_4/BukkitVersionHelperSpigot120_4.java b/bukkit-helper-120-4/src/main/java/org/dynmap/bukkit/helper/v120_4/BukkitVersionHelperSpigot120_4.java index 669c55d1..ee2bb120 100644 --- a/bukkit-helper-120-4/src/main/java/org/dynmap/bukkit/helper/v120_4/BukkitVersionHelperSpigot120_4.java +++ b/bukkit-helper-120-4/src/main/java/org/dynmap/bukkit/helper/v120_4/BukkitVersionHelperSpigot120_4.java @@ -374,7 +374,7 @@ public class BukkitVersionHelperSpigot120_4 extends BukkitVersionHelper { NBTBase val = rec.c(field); if(val == null) return null; if(val instanceof NBTTagByte) { - return ((NBTTagByte)val).h(); + return ((NBTTagByte)val).i(); } else if(val instanceof NBTTagShort) { return ((NBTTagShort)val).g(); diff --git a/bukkit-helper-120-5/src/main/java/org/dynmap/bukkit/helper/v120_5/BukkitVersionHelperSpigot120_5.java b/bukkit-helper-120-5/src/main/java/org/dynmap/bukkit/helper/v120_5/BukkitVersionHelperSpigot120_5.java index 20d4af0f..8c330b0a 100644 --- a/bukkit-helper-120-5/src/main/java/org/dynmap/bukkit/helper/v120_5/BukkitVersionHelperSpigot120_5.java +++ b/bukkit-helper-120-5/src/main/java/org/dynmap/bukkit/helper/v120_5/BukkitVersionHelperSpigot120_5.java @@ -376,7 +376,7 @@ public class BukkitVersionHelperSpigot120_5 extends BukkitVersionHelper { NBTBase val = rec.c(field); if(val == null) return null; if(val instanceof NBTTagByte) { - return ((NBTTagByte)val).h(); + return ((NBTTagByte)val).i(); } else if(val instanceof NBTTagShort) { return ((NBTTagShort)val).g(); diff --git a/bukkit-helper-120/src/main/java/org/dynmap/bukkit/helper/v120/BukkitVersionHelperSpigot120.java b/bukkit-helper-120/src/main/java/org/dynmap/bukkit/helper/v120/BukkitVersionHelperSpigot120.java index d473dfd3..af48be90 100644 --- a/bukkit-helper-120/src/main/java/org/dynmap/bukkit/helper/v120/BukkitVersionHelperSpigot120.java +++ b/bukkit-helper-120/src/main/java/org/dynmap/bukkit/helper/v120/BukkitVersionHelperSpigot120.java @@ -374,7 +374,7 @@ public class BukkitVersionHelperSpigot120 extends BukkitVersionHelper { NBTBase val = rec.c(field); if(val == null) return null; if(val instanceof NBTTagByte) { - return ((NBTTagByte)val).h(); + return ((NBTTagByte)val).i(); } else if(val instanceof NBTTagShort) { return ((NBTTagShort)val).g(); diff --git a/bukkit-helper-121-3/build.gradle b/bukkit-helper-121-3/build.gradle new file mode 100644 index 00000000..4a8ec0c5 --- /dev/null +++ b/bukkit-helper-121-3/build.gradle @@ -0,0 +1,17 @@ +eclipse { + project { + name = "Dynmap(Spigot-1.21.3)" + } +} + +description = 'bukkit-helper-1.21.3' + +sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. + +dependencies { + implementation project(':bukkit-helper') + implementation project(':dynmap-api') + implementation project(path: ':DynmapCore', configuration: 'shadow') + compileOnly group: 'org.spigotmc', name: 'spigot-api', version:'1.21.3-R0.1-SNAPSHOT' + compileOnly group: 'org.spigotmc', name: 'spigot', version:'1.21.3-R0.1-SNAPSHOT' +} diff --git a/bukkit-helper-121-3/src/main/java/org/dynmap/bukkit/helper/v121_3/BukkitVersionHelperSpigot121_3.java b/bukkit-helper-121-3/src/main/java/org/dynmap/bukkit/helper/v121_3/BukkitVersionHelperSpigot121_3.java new file mode 100644 index 00000000..efb0357e --- /dev/null +++ b/bukkit-helper-121-3/src/main/java/org/dynmap/bukkit/helper/v121_3/BukkitVersionHelperSpigot121_3.java @@ -0,0 +1,452 @@ +package org.dynmap.bukkit.helper.v121_3; + +import org.bukkit.*; +import org.bukkit.craftbukkit.v1_21_R2.CraftChunk; +import org.bukkit.craftbukkit.v1_21_R2.CraftWorld; +import org.bukkit.craftbukkit.v1_21_R2.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.dynmap.DynmapChunk; +import org.dynmap.Log; +import org.dynmap.bukkit.helper.BukkitMaterial; +import org.dynmap.bukkit.helper.BukkitVersionHelper; +import org.dynmap.bukkit.helper.BukkitWorld; +import org.dynmap.bukkit.helper.BukkitVersionHelperGeneric.TexturesPayload; +import org.dynmap.renderer.DynmapBlockState; +import org.dynmap.utils.MapChunkCache; +import org.dynmap.utils.Polygon; + +import com.google.common.collect.Iterables; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; + +import net.minecraft.core.RegistryBlockID; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.core.IRegistry; +import net.minecraft.nbt.NBTTagByteArray; +import net.minecraft.nbt.NBTTagByte; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagDouble; +import net.minecraft.nbt.NBTTagFloat; +import net.minecraft.nbt.NBTTagIntArray; +import net.minecraft.nbt.NBTTagInt; +import net.minecraft.nbt.NBTTagLong; +import net.minecraft.nbt.NBTTagShort; +import net.minecraft.nbt.NBTTagString; +import net.minecraft.resources.MinecraftKey; +import net.minecraft.nbt.NBTBase; +import net.minecraft.server.MinecraftServer; +import net.minecraft.tags.TagsBlock; +import net.minecraft.world.level.biome.BiomeBase; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.BlockFluids; +import net.minecraft.world.level.block.entity.TileEntity; +import net.minecraft.world.level.block.state.IBlockData; +import net.minecraft.world.level.chunk.status.ChunkStatus; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Base64; +import java.util.Collection; +import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + + +/** + * Helper for isolation of bukkit version specific issues + */ +public class BukkitVersionHelperSpigot121_3 extends BukkitVersionHelper { + + @Override + public boolean isUnsafeAsync() { + return true; + } + + /** + * Get block short name list + */ + @Override + public String[] getBlockNames() { + RegistryBlockID bsids = Block.q; + Block baseb = null; + Iterator iter = bsids.iterator(); + ArrayList names = new ArrayList(); + while (iter.hasNext()) { + IBlockData bs = iter.next(); + Block b = bs.b(); + // If this is new block vs last, it's the base block state + if (b != baseb) { + baseb = b; + continue; + } + MinecraftKey id = BuiltInRegistries.e.b(b); + String bn = id.toString(); + if (bn != null) { + names.add(bn); + Log.info("block=" + bn); + } + } + return names.toArray(new String[0]); + } + + private static IRegistry reg = null; + + private static IRegistry getBiomeReg() { + if (reg == null) { + reg = MinecraftServer.getServer().ba().e(Registries.aI); // MinecraftServer.registryAccess().lookupOrThrow(Registries.BIOME) + } + return reg; + } + + private Object[] biomelist; + /** + * Get list of defined biomebase objects + */ + @Override + public Object[] getBiomeBaseList() { + if (biomelist == null) { + biomelist = new BiomeBase[256]; + Iterator iter = getBiomeReg().iterator(); + while (iter.hasNext()) { + BiomeBase b = iter.next(); + int bidx = getBiomeReg().a(b); // iRegistry.getId + if (bidx >= biomelist.length) { + biomelist = Arrays.copyOf(biomelist, bidx + biomelist.length); + } + biomelist[bidx] = b; + } + } + return biomelist; + } + + /** Get ID from biomebase */ + @Override + public int getBiomeBaseID(Object bb) { + return getBiomeReg().a((BiomeBase)bb); + } + + public static IdentityHashMap dataToState; + + /** + * Initialize block states (org.dynmap.blockstate.DynmapBlockState) + */ + @Override + public void initializeBlockStates() { + dataToState = new IdentityHashMap(); + HashMap lastBlockState = new HashMap(); + RegistryBlockID bsids = Block.q; + Block baseb = null; + Iterator iter = bsids.iterator(); + ArrayList names = new ArrayList(); + + // Loop through block data states + DynmapBlockState.Builder bld = new DynmapBlockState.Builder(); + while (iter.hasNext()) { + IBlockData bd = iter.next(); + Block b = bd.b(); + MinecraftKey id = BuiltInRegistries.e.b(b); + String bname = id.toString(); + DynmapBlockState lastbs = lastBlockState.get(bname); // See if we have seen this one + int idx = 0; + if (lastbs != null) { // Yes + idx = lastbs.getStateCount(); // Get number of states so far, since this is next + } + // Build state name + String sb = ""; + String fname = bd.toString(); + int off1 = fname.indexOf('['); + if (off1 >= 0) { + int off2 = fname.indexOf(']'); + sb = fname.substring(off1+1, off2); + } + int lightAtten = bd.g(); // getLightBlock + //Log.info("statename=" + bname + "[" + sb + "], lightAtten=" + lightAtten); + // Fill in base attributes + bld.setBaseState(lastbs).setStateIndex(idx).setBlockName(bname).setStateName(sb).setAttenuatesLight(lightAtten); + if (bd.w() != null) { bld.setMaterial(bd.w().toString()); } + if (bd.e()) { bld.setSolid(); } + if (bd.i()) { bld.setAir(); } + if (bd.a(TagsBlock.t)) { bld.setLog(); } + if (bd.a(TagsBlock.O)) { bld.setLeaves(); } + if ((!bd.y().c()) && ((bd.b() instanceof BlockFluids) == false)) { // Test if fluid type for block is not empty + bld.setWaterlogged(); + //Log.info("statename=" + bname + "[" + sb + "] = waterlogged"); + } + DynmapBlockState dbs = bld.build(); // Build state + + dataToState.put(bd, dbs); + lastBlockState.put(bname, (lastbs == null) ? dbs : lastbs); + Log.verboseinfo("blk=" + bname + ", idx=" + idx + ", state=" + sb + ", waterlogged=" + dbs.isWaterlogged()); + } + } + /** + * Create chunk cache for given chunks of given world + * @param dw - world + * @param chunks - chunk list + * @return cache + */ + @Override + public MapChunkCache getChunkCache(BukkitWorld dw, List chunks) { + MapChunkCache121_3 c = new MapChunkCache121_3(gencache); + c.setChunks(dw, chunks); + return c; + } + + /** + * Get biome base water multiplier + */ + @Override + public int getBiomeBaseWaterMult(Object bb) { + BiomeBase biome = (BiomeBase) bb; + return biome.i(); // waterColor + } + + /** Get temperature from biomebase */ + @Override + public float getBiomeBaseTemperature(Object bb) { + return ((BiomeBase)bb).g(); + } + + /** Get humidity from biomebase */ + @Override + public float getBiomeBaseHumidity(Object bb) { + String vals = ((BiomeBase)bb).i.toString(); // Sleazy + float humidity = 0.5F; + int idx = vals.indexOf("downfall="); + if (idx >= 0) { + humidity = Float.parseFloat(vals.substring(idx+9, vals.indexOf(']', idx))); + } + return humidity; + } + + @Override + public Polygon getWorldBorder(World world) { + Polygon p = null; + WorldBorder wb = world.getWorldBorder(); + if (wb != null) { + Location c = wb.getCenter(); + double size = wb.getSize(); + if ((size > 1) && (size < 1E7)) { + size = size / 2; + p = new Polygon(); + p.addVertex(c.getX()-size, c.getZ()-size); + p.addVertex(c.getX()+size, c.getZ()-size); + p.addVertex(c.getX()+size, c.getZ()+size); + p.addVertex(c.getX()-size, c.getZ()+size); + } + } + return p; + } + // Send title/subtitle to user + public void sendTitleText(Player p, String title, String subtitle, int fadeInTicks, int stayTicks, int fadeOutTIcks) { + if (p != null) { + p.sendTitle(title, subtitle, fadeInTicks, stayTicks, fadeOutTIcks); + } + } + + /** + * Get material map by block ID + */ + @Override + public BukkitMaterial[] getMaterialList() { + return new BukkitMaterial[4096]; // Not used + } + + @Override + public void unloadChunkNoSave(World w, org.bukkit.Chunk c, int cx, int cz) { + Log.severe("unloadChunkNoSave not implemented"); + } + + private String[] biomenames; + @Override + public String[] getBiomeNames() { + if (biomenames == null) { + biomenames = new String[256]; + Iterator iter = getBiomeReg().iterator(); + while (iter.hasNext()) { + BiomeBase b = iter.next(); + int bidx = getBiomeReg().a(b); + if (bidx >= biomenames.length) { + biomenames = Arrays.copyOf(biomenames, bidx + biomenames.length); + } + biomenames[bidx] = b.toString(); + } + } + return biomenames; + } + + @Override + public String getStateStringByCombinedId(int blkid, int meta) { + Log.severe("getStateStringByCombinedId not implemented"); + return null; + } + @Override + /** Get ID string from biomebase */ + public String getBiomeBaseIDString(Object bb) { + return getBiomeReg().b((BiomeBase)bb).a(); + } + @Override + public String getBiomeBaseResourceLocsation(Object bb) { + return getBiomeReg().b((BiomeBase)bb).toString(); + } + + @Override + public Object getUnloadQueue(World world) { + Log.warning("getUnloadQueue not implemented yet"); + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isInUnloadQueue(Object unloadqueue, int x, int z) { + Log.warning("isInUnloadQueue not implemented yet"); + // TODO Auto-generated method stub + return false; + } + + @Override + public Object[] getBiomeBaseFromSnapshot(ChunkSnapshot css) { + Log.warning("getBiomeBaseFromSnapshot not implemented yet"); + // TODO Auto-generated method stub + return new Object[256]; + } + + @Override + public long getInhabitedTicks(Chunk c) { + return ((CraftChunk)c).getHandle(ChunkStatus.n).w(); // IChunkAccess.getInhabitedTime + } + + @Override + public Map getTileEntitiesForChunk(Chunk c) { + return ((CraftChunk)c).getHandle(ChunkStatus.n).k; // IChunkAccess.blockEntities + } + + @Override + public int getTileEntityX(Object te) { + TileEntity tileent = (TileEntity) te; + return tileent.aB_().u(); // getBlockPos + } + + @Override + public int getTileEntityY(Object te) { + TileEntity tileent = (TileEntity) te; + return tileent.aB_().v(); // getBlockPos + } + + @Override + public int getTileEntityZ(Object te) { + TileEntity tileent = (TileEntity) te; + return tileent.aB_().w(); // getBlockPos + } + + @Override + public Object readTileEntityNBT(Object te, org.bukkit.World w) { + TileEntity tileent = (TileEntity) te; + CraftWorld cw = (CraftWorld) w; + //NBTTagCompound nbt = tileent.o(world.registryAccess()); + NBTTagCompound nbt = tileent.e(cw.getHandle().K_()); + return nbt; + } + + @Override + public Object getFieldValue(Object nbt, String field) { + NBTTagCompound rec = (NBTTagCompound) nbt; + NBTBase val = rec.c(field); + if(val == null) return null; + if(val instanceof NBTTagByte) { + return ((NBTTagByte)val).i(); // getAsByte + } + else if(val instanceof NBTTagShort) { + return ((NBTTagShort)val).g(); // getAsShort + } + else if(val instanceof NBTTagInt) { + return ((NBTTagInt)val).f(); // getAsInt + } + else if(val instanceof NBTTagLong) { + return ((NBTTagLong)val).e(); // getAsLong + } + else if(val instanceof NBTTagFloat) { + return ((NBTTagFloat)val).j(); // getAsFloat + } + else if(val instanceof NBTTagDouble) { + return ((NBTTagDouble)val).i(); // getAsDouble + } + else if(val instanceof NBTTagByteArray) { + return ((NBTTagByteArray)val).d(); // getAsByteArray + } + else if(val instanceof NBTTagString) { + return ((NBTTagString)val).u_(); // getAsString + } + else if(val instanceof NBTTagIntArray) { + return ((NBTTagIntArray)val).f(); // getAsIntArray + } + return null; + } + + @Override + public Player[] getOnlinePlayers() { + Collection p = Bukkit.getServer().getOnlinePlayers(); + return p.toArray(new Player[0]); + } + + @Override + public double getHealth(Player p) { + return p.getHealth(); + } + + private static final Gson gson = new GsonBuilder().create(); + + /** + * Get skin URL for player + * @param player + */ + @Override + public String getSkinURL(Player player) { + String url = null; + CraftPlayer cp = (CraftPlayer)player; + GameProfile profile = cp.getProfile(); + if (profile != null) { + PropertyMap pm = profile.getProperties(); + if (pm != null) { + Collection txt = pm.get("textures"); + Property textureProperty = Iterables.getFirst(pm.get("textures"), null); + if (textureProperty != null) { + String val = textureProperty.value(); + if (val != null) { + TexturesPayload result = null; + try { + String json = new String(Base64.getDecoder().decode(val), StandardCharsets.UTF_8); + result = gson.fromJson(json, TexturesPayload.class); + } catch (JsonParseException e) { + } catch (IllegalArgumentException x) { + Log.warning("Malformed response from skin URL check: " + val); + } + if ((result != null) && (result.textures != null) && (result.textures.containsKey("SKIN"))) { + url = result.textures.get("SKIN").url; + } + } + } + } + } + return url; + } + // Get minY for world + @Override + public int getWorldMinY(World w) { + CraftWorld cw = (CraftWorld) w; + return cw.getMinHeight(); + } + @Override + public boolean useGenericCache() { + return true; + } + +} diff --git a/bukkit-helper-121-3/src/main/java/org/dynmap/bukkit/helper/v121_3/MapChunkCache121_3.java b/bukkit-helper-121-3/src/main/java/org/dynmap/bukkit/helper/v121_3/MapChunkCache121_3.java new file mode 100644 index 00000000..b3b1b796 --- /dev/null +++ b/bukkit-helper-121-3/src/main/java/org/dynmap/bukkit/helper/v121_3/MapChunkCache121_3.java @@ -0,0 +1,76 @@ +package org.dynmap.bukkit.helper.v121_3; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.level.ChunkCoordIntPair; +import net.minecraft.world.level.biome.BiomeBase; +import net.minecraft.world.level.biome.BiomeFog; +import net.minecraft.world.level.chunk.Chunk; +import net.minecraft.world.level.chunk.storage.SerializableChunkData; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_21_R2.CraftWorld; +import org.dynmap.DynmapChunk; +import org.dynmap.bukkit.helper.BukkitWorld; +import org.dynmap.common.BiomeMap; +import org.dynmap.common.chunk.GenericChunk; +import org.dynmap.common.chunk.GenericChunkCache; +import org.dynmap.common.chunk.GenericMapChunkCache; + +import java.util.List; +import java.util.NoSuchElementException; +import java.util.concurrent.CancellationException; + +/** + * Container for managing chunks - dependent upon using chunk snapshots, since rendering is off server thread + */ +public class MapChunkCache121_3 extends GenericMapChunkCache { + private World w; + /** + * Construct empty cache + */ + public MapChunkCache121_3(GenericChunkCache cc) { + super(cc); + } + + protected GenericChunk getLoadedChunk(DynmapChunk chunk) { + CraftWorld cw = (CraftWorld) w; + if (!cw.isChunkLoaded(chunk.x, chunk.z)) return null; + Chunk c = cw.getHandle().getChunkIfLoaded(chunk.x, chunk.z); + if (c == null || !c.q) return null; // c.loaded + SerializableChunkData chunkData = SerializableChunkData.a(cw.getHandle(), c); //SerializableChunkData.copyOf + NBTTagCompound nbt = chunkData.a(); // SerializableChunkData.write + return nbt != null ? parseChunkFromNBT(new NBT.NBTCompound(nbt)) : null; + } + + protected GenericChunk loadChunk(DynmapChunk chunk) { + CraftWorld cw = (CraftWorld) w; + NBTTagCompound nbt = null; + ChunkCoordIntPair cc = new ChunkCoordIntPair(chunk.x, chunk.z); + GenericChunk gc = null; + try { // BUGBUG - convert this all to asyn properly, since now native async + nbt = cw.getHandle().m().a.d(cc).join().get(); // WorldServer.getChunkSource().chunkMap.read(cc).join().get() + } catch (CancellationException cx) { + } catch (NoSuchElementException snex) { + } + if (nbt != null) { + gc = parseChunkFromNBT(new NBT.NBTCompound(nbt)); + } + return gc; + } + + public void setChunks(BukkitWorld dw, List chunks) { + this.w = dw.getWorld(); + super.setChunks(dw, chunks); + } + + @Override + public int getFoliageColor(BiomeMap bm, int[] colormap, int x, int z) { + return bm.getBiomeObject().map(BiomeBase::h).flatMap(BiomeFog::e).orElse(colormap[bm.biomeLookup()]); // BiomeBase::getSpecialEffects, BiomeFog::skyColor + } + + @Override + public int getGrassColor(BiomeMap bm, int[] colormap, int x, int z) { + BiomeFog fog = bm.getBiomeObject().map(BiomeBase::h).orElse(null); // BiomeBase::getSpecialEffects + if (fog == null) return colormap[bm.biomeLookup()]; + return fog.g().a(x, z, fog.f().orElse(colormap[bm.biomeLookup()])); // BiomeFog.getGrassColorModifier, BiomeFog.getGrassColorOverride + } +} diff --git a/bukkit-helper-121-3/src/main/java/org/dynmap/bukkit/helper/v121_3/NBT.java b/bukkit-helper-121-3/src/main/java/org/dynmap/bukkit/helper/v121_3/NBT.java new file mode 100644 index 00000000..209734a5 --- /dev/null +++ b/bukkit-helper-121-3/src/main/java/org/dynmap/bukkit/helper/v121_3/NBT.java @@ -0,0 +1,126 @@ +package org.dynmap.bukkit.helper.v121_3; + +import org.dynmap.common.chunk.GenericBitStorage; +import org.dynmap.common.chunk.GenericNBTCompound; +import org.dynmap.common.chunk.GenericNBTList; + +import java.util.Set; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.SimpleBitStorage; + +public class NBT { + + public static class NBTCompound implements GenericNBTCompound { + private final NBTTagCompound obj; + public NBTCompound(NBTTagCompound t) { + this.obj = t; + } + @Override + public Set getAllKeys() { + return obj.e(); + } + @Override + public boolean contains(String s) { + return obj.e(s); + } + @Override + public boolean contains(String s, int i) { + return obj.b(s, i); + } + @Override + public byte getByte(String s) { + return obj.f(s); + } + @Override + public short getShort(String s) { + return obj.g(s); + } + @Override + public int getInt(String s) { + return obj.h(s); + } + @Override + public long getLong(String s) { + return obj.i(s); + } + @Override + public float getFloat(String s) { + return obj.j(s); + } + @Override + public double getDouble(String s) { + return obj.k(s); + } + @Override + public String getString(String s) { + return obj.l(s); + } + @Override + public byte[] getByteArray(String s) { + return obj.m(s); + } + @Override + public int[] getIntArray(String s) { + return obj.n(s); + } + @Override + public long[] getLongArray(String s) { + return obj.o(s); + } + @Override + public GenericNBTCompound getCompound(String s) { + return new NBTCompound(obj.p(s)); + } + @Override + public GenericNBTList getList(String s, int i) { + return new NBTList(obj.c(s, i)); + } + @Override + public boolean getBoolean(String s) { + return obj.q(s); + } + @Override + public String getAsString(String s) { + return obj.c(s).u_(); + } + @Override + public GenericBitStorage makeBitStorage(int bits, int count, long[] data) { + return new OurBitStorage(bits, count, data); + } + public String toString() { + return obj.toString(); + } + } + public static class NBTList implements GenericNBTList { + private final NBTTagList obj; + public NBTList(NBTTagList t) { + obj = t; + } + @Override + public int size() { + return obj.size(); + } + @Override + public String getString(int idx) { + return obj.j(idx); + } + @Override + public GenericNBTCompound getCompound(int idx) { + return new NBTCompound(obj.a(idx)); + } + public String toString() { + return obj.toString(); + } + } + public static class OurBitStorage implements GenericBitStorage { + private final SimpleBitStorage bs; + public OurBitStorage(int bits, int count, long[] data) { + bs = new SimpleBitStorage(bits, count, data); + } + @Override + public int get(int idx) { + return bs.a(idx); + } + } +} diff --git a/bukkit-helper-121/src/main/java/org/dynmap/bukkit/helper/v121/BukkitVersionHelperSpigot121.java b/bukkit-helper-121/src/main/java/org/dynmap/bukkit/helper/v121/BukkitVersionHelperSpigot121.java index bff11be8..21ade89f 100644 --- a/bukkit-helper-121/src/main/java/org/dynmap/bukkit/helper/v121/BukkitVersionHelperSpigot121.java +++ b/bukkit-helper-121/src/main/java/org/dynmap/bukkit/helper/v121/BukkitVersionHelperSpigot121.java @@ -376,7 +376,7 @@ public class BukkitVersionHelperSpigot121 extends BukkitVersionHelper { NBTBase val = rec.c(field); if(val == null) return null; if(val instanceof NBTTagByte) { - return ((NBTTagByte)val).h(); + return ((NBTTagByte)val).i(); } else if(val instanceof NBTTagShort) { return ((NBTTagShort)val).g(); diff --git a/settings.gradle b/settings.gradle index d85eb23d..8ae9cda5 100644 --- a/settings.gradle +++ b/settings.gradle @@ -27,6 +27,7 @@ include ':bukkit-helper-120-2' include ':bukkit-helper-120-4' include ':bukkit-helper-120-5' include ':bukkit-helper-121' +include ':bukkit-helper-121-3' include ':bukkit-helper' include ':dynmap-api' include ':DynmapCore' @@ -72,6 +73,7 @@ project(':bukkit-helper-120-2').projectDir = "$rootDir/bukkit-helper-120-2" as F project(':bukkit-helper-120-4').projectDir = "$rootDir/bukkit-helper-120-4" as File project(':bukkit-helper-120-5').projectDir = "$rootDir/bukkit-helper-120-5" as File project(':bukkit-helper-121').projectDir = "$rootDir/bukkit-helper-121" as File +project(':bukkit-helper-121-3').projectDir = "$rootDir/bukkit-helper-121-3" as File project(':bukkit-helper').projectDir = "$rootDir/bukkit-helper" as File project(':dynmap-api').projectDir = "$rootDir/dynmap-api" as File project(':DynmapCore').projectDir = "$rootDir/DynmapCore" as File diff --git a/spigot/build.gradle b/spigot/build.gradle index e918e218..8fa7a1ad 100644 --- a/spigot/build.gradle +++ b/spigot/build.gradle @@ -91,6 +91,9 @@ dependencies { implementation(project(':bukkit-helper-121')) { transitive = false } + implementation(project(':bukkit-helper-121-3')) { + transitive = false + } } processResources { @@ -132,6 +135,7 @@ shadowJar { include(dependency(':bukkit-helper-120-4')) include(dependency(':bukkit-helper-120-5')) include(dependency(':bukkit-helper-121')) + include(dependency(':bukkit-helper-121-3')) } relocate('org.bstats', 'org.dynmap.bstats') destinationDirectory = file '../target' diff --git a/spigot/src/main/java/org/dynmap/bukkit/Helper.java b/spigot/src/main/java/org/dynmap/bukkit/Helper.java index cd1fad52..52db74d2 100644 --- a/spigot/src/main/java/org/dynmap/bukkit/Helper.java +++ b/spigot/src/main/java/org/dynmap/bukkit/Helper.java @@ -40,7 +40,10 @@ public class Helper { Log.info("Loading Glowstone support"); BukkitVersionHelper.helper = loadVersionHelper("org.dynmap.bukkit.helper.BukkitVersionHelperGlowstone"); } - else if (v.contains("(MC: 1.21")) { + else if (v.contains("(MC: 1.21.2") || v.contains("(MC: 1.21.3")) { + BukkitVersionHelper.helper = loadVersionHelper("org.dynmap.bukkit.helper.v121_3.BukkitVersionHelperSpigot121_3"); + } + else if (v.contains("(MC: 1.21)") || v.contains("(MC: 1.21.1)")) { BukkitVersionHelper.helper = loadVersionHelper("org.dynmap.bukkit.helper.v121.BukkitVersionHelperSpigot121"); } else if (v.contains("(MC: 1.20)") || v.contains("(MC: 1.20.1)")) {