From 9c9c93493ec3fff402ecebe1b069108458be92bc Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Tue, 7 Jun 2022 12:28:16 -0500 Subject: [PATCH] Initial spigot/paper 1.19 port --- bukkit-helper-119/.gitignore | 1 + bukkit-helper-119/bin/.gitignore | 1 + bukkit-helper-119/build.gradle | 15 + .../helper/v119/AsyncChunkProvider119.java | 60 +++ .../v119/BukkitVersionHelperSpigot119.java | 456 ++++++++++++++++++ .../bukkit/helper/v119/MapChunkCache119.java | 103 ++++ .../org/dynmap/bukkit/helper/v119/NBT.java | 126 +++++ .../.settings/org.eclipse.jdt.core.prefs | 2 +- settings.gradle | 2 + spigot/build.gradle | 4 + .../main/java/org/dynmap/bukkit/Helper.java | 4 + 11 files changed, 773 insertions(+), 1 deletion(-) create mode 100644 bukkit-helper-119/.gitignore create mode 100644 bukkit-helper-119/bin/.gitignore create mode 100644 bukkit-helper-119/build.gradle create mode 100644 bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/AsyncChunkProvider119.java create mode 100644 bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/BukkitVersionHelperSpigot119.java create mode 100644 bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/MapChunkCache119.java create mode 100644 bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/NBT.java diff --git a/bukkit-helper-119/.gitignore b/bukkit-helper-119/.gitignore new file mode 100644 index 00000000..84c048a7 --- /dev/null +++ b/bukkit-helper-119/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/bukkit-helper-119/bin/.gitignore b/bukkit-helper-119/bin/.gitignore new file mode 100644 index 00000000..ddf9c656 --- /dev/null +++ b/bukkit-helper-119/bin/.gitignore @@ -0,0 +1 @@ +/main/ diff --git a/bukkit-helper-119/build.gradle b/bukkit-helper-119/build.gradle new file mode 100644 index 00000000..74aa29e4 --- /dev/null +++ b/bukkit-helper-119/build.gradle @@ -0,0 +1,15 @@ +eclipse { + project { + name = "Dynmap(Spigot-1.19)" + } +} + +description = 'bukkit-helper-1.19' + +dependencies { + implementation project(':bukkit-helper') + implementation project(':dynmap-api') + implementation project(path: ':DynmapCore', configuration: 'shadow') + implementation group: 'org.spigotmc', name: 'spigot-api', version:'1.19-R0.1-SNAPSHOT' + implementation group: 'org.spigotmc', name: 'spigot', version:'1.19-R0.1-SNAPSHOT' +} diff --git a/bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/AsyncChunkProvider119.java b/bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/AsyncChunkProvider119.java new file mode 100644 index 00000000..7438575c --- /dev/null +++ b/bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/AsyncChunkProvider119.java @@ -0,0 +1,60 @@ +package org.dynmap.bukkit.helper.v119; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.level.WorldServer; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; +import java.util.function.Predicate; + +/** + * The provider used to work with paper libs + * Because paper libs need java 17 we can't interact with them directly + */ +public class AsyncChunkProvider119 { + private final Thread ioThread; + private final Method getChunk; + private final Predicate ifFailed; + AsyncChunkProvider119 () { + try { + Predicate ifFailed1 = null; + Method getChunk1 = null; + Thread ioThread1 = null; + try { + Class threadClass = Class.forName("com.destroystokyo.paper.io.PaperFileIOThread"); + Class[] classes = threadClass.getClasses(); + Class holder = Arrays.stream(classes).filter(aClass -> aClass.getSimpleName().equals("Holder")).findAny().orElseThrow(RuntimeException::new); + ioThread1 = (Thread) holder.getField("INSTANCE").get(null); + getChunk1 = threadClass.getMethod("loadChunkDataAsync", WorldServer.class, int.class, int.class, int.class, Consumer.class, boolean.class, boolean.class, boolean.class); + NBTTagCompound failure = (NBTTagCompound) threadClass.getField("FAILURE_VALUE").get(null); + ifFailed1 = nbtTagCompound -> nbtTagCompound == failure; + } catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException | NoSuchMethodException e) { + e.printStackTrace(); + } + ifFailed = Objects.requireNonNull(ifFailed1); + getChunk = Objects.requireNonNull(getChunk1); + ioThread = Objects.requireNonNull(ioThread1); + } catch (Throwable e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + public CompletableFuture getChunk(WorldServer world, int x, int y) throws InvocationTargetException, IllegalAccessException { + CompletableFuture future = new CompletableFuture<>(); + getChunk.invoke(ioThread,world,x,y,5,(Consumer) future::complete, false, true, true); + return future.thenApply((resultFuture) -> { + if (resultFuture == null) return null; + try { + NBTTagCompound compound = (NBTTagCompound) resultFuture.getClass().getField("chunkData").get(resultFuture); + return ifFailed.test(compound) ? null : compound; + } catch (IllegalAccessException | NoSuchFieldException e) { + e.printStackTrace(); + } + return null; + }); + } +} diff --git a/bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/BukkitVersionHelperSpigot119.java b/bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/BukkitVersionHelperSpigot119.java new file mode 100644 index 00000000..d4d5daf9 --- /dev/null +++ b/bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/BukkitVersionHelperSpigot119.java @@ -0,0 +1,456 @@ +package org.dynmap.bukkit.helper.v119; + +import org.bukkit.*; +import org.bukkit.craftbukkit.v1_19_R1.CraftChunk; +import org.bukkit.craftbukkit.v1_19_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_19_R1.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.RegistryBlocks; +import net.minecraft.core.BlockPosition; +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.world.level.BlockAccessAir; +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 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; +import java.util.Set; + + +/** + * Helper for isolation of bukkit version specific issues + */ +public class BukkitVersionHelperSpigot119 extends BukkitVersionHelper { + private final boolean unsafeAsync; + + public BukkitVersionHelperSpigot119() { + boolean unsafeAsync1; + try { + Class.forName("com.destroystokyo.paper.io.PaperFileIOThread"); + unsafeAsync1 = false; + } catch (ClassNotFoundException e) { + unsafeAsync1 = true; + } + this.unsafeAsync = unsafeAsync1; + } + + @Override + public boolean isUnsafeAsync() { + return unsafeAsync; + } + + /** + * Get block short name list + */ + @Override + public String[] getBlockNames() { + RegistryBlockID bsids = Block.o; + 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 = RegistryBlocks.V.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().aX().d(IRegistry.aR); + } + 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); + 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.o; + 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 = RegistryBlocks.V.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); + } + net.minecraft.world.level.material.Material mat = bd.d(); + + int lightAtten = b.g(bd, BlockAccessAir.a, BlockPosition.b); // getLightBlock + //Log.info("statename=" + bname + "[" + sb + "], lightAtten=" + lightAtten); + // Fill in base attributes + bld.setBaseState(lastbs).setStateIndex(idx).setBlockName(bname).setStateName(sb).setMaterial(mat.toString()).setAttenuatesLight(lightAtten); + if (mat.b()) { bld.setSolid(); } + if (mat == net.minecraft.world.level.material.Material.a) { bld.setAir(); } + if (mat == net.minecraft.world.level.material.Material.z) { bld.setLog(); } + if (mat == net.minecraft.world.level.material.Material.F) { bld.setLeaves(); } + if ((!bd.p().c()) && ((bd.b() instanceof BlockFluids) == false)) { // Test if fluid type for block is not empty + bld.setWaterlogged(); + } + 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) { + MapChunkCache119 c = new MapChunkCache119(gencache); + c.setChunks(dw, chunks); + return c; + } + + /** + * Get biome base water multiplier + */ + @Override + public int getBiomeBaseWaterMult(Object bb) { + BiomeBase biome = (BiomeBase) bb; + return biome.k(); // waterColor + } + + /** Get temperature from biomebase */ + @Override + public float getBiomeBaseTemperature(Object bb) { + return ((BiomeBase)bb).i(); + } + + /** Get humidity from biomebase */ + @Override + public float getBiomeBaseHumidity(Object bb) { + return ((BiomeBase)bb).h(); + } + + @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().u(); + } + + @Override + public Map getTileEntitiesForChunk(Chunk c) { + return ((CraftChunk)c).getHandle().i; + } + + @Override + public int getTileEntityX(Object te) { + TileEntity tileent = (TileEntity) te; + return tileent.p().u(); + } + + @Override + public int getTileEntityY(Object te) { + TileEntity tileent = (TileEntity) te; + return tileent.p().v(); + } + + @Override + public int getTileEntityZ(Object te) { + TileEntity tileent = (TileEntity) te; + return tileent.p().w(); + } + + @Override + public Object readTileEntityNBT(Object te) { + TileEntity tileent = (TileEntity) te; + NBTTagCompound nbt = tileent.n(); + 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).h(); + } + else if(val instanceof NBTTagShort) { + return ((NBTTagShort)val).g(); + } + else if(val instanceof NBTTagInt) { + return ((NBTTagInt)val).f(); + } + else if(val instanceof NBTTagLong) { + return ((NBTTagLong)val).e(); + } + else if(val instanceof NBTTagFloat) { + return ((NBTTagFloat)val).j(); + } + else if(val instanceof NBTTagDouble) { + return ((NBTTagDouble)val).i(); + } + else if(val instanceof NBTTagByteArray) { + return ((NBTTagByteArray)val).d(); + } + else if(val instanceof NBTTagString) { + return ((NBTTagString)val).e_(); + } + else if(val instanceof NBTTagIntArray) { + return ((NBTTagIntArray)val).f(); + } + 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.getValue(); + 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-119/src/main/java/org/dynmap/bukkit/helper/v119/MapChunkCache119.java b/bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/MapChunkCache119.java new file mode 100644 index 00000000..4743e94f --- /dev/null +++ b/bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/MapChunkCache119.java @@ -0,0 +1,103 @@ +package org.dynmap.bukkit.helper.v119; + +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_19_R1.CraftServer; +import org.bukkit.craftbukkit.v1_19_R1.CraftWorld; +import org.dynmap.DynmapChunk; +import org.dynmap.bukkit.helper.BukkitVersionHelper; +import org.dynmap.bukkit.helper.BukkitWorld; +import org.dynmap.common.chunk.GenericChunk; +import org.dynmap.common.chunk.GenericChunkCache; +import org.dynmap.common.chunk.GenericMapChunkCache; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.level.ChunkCoordIntPair; +import net.minecraft.world.level.chunk.storage.ChunkRegionLoader; +import net.minecraft.world.level.chunk.Chunk; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.concurrent.CancellationException; +import java.util.concurrent.CompletableFuture; +import java.util.function.Supplier; + +/** + * Container for managing chunks - dependent upon using chunk snapshots, since rendering is off server thread + */ +public class MapChunkCache119 extends GenericMapChunkCache { + private static final AsyncChunkProvider119 provider = BukkitVersionHelper.helper.isUnsafeAsync() ? null : new AsyncChunkProvider119(); + private World w; + /** + * Construct empty cache + */ + public MapChunkCache119(GenericChunkCache cc) { + super(cc); + } + + // Load generic chunk from existing and already loaded chunk + protected GenericChunk getLoadedChunk(DynmapChunk chunk) { + return getLoadedChunk(chunk, false).get(); + } + @Override + protected Supplier getLoadedChunkAsync(DynmapChunk ch) { + return getLoadedChunk(ch, true); + } + + @Override + protected Supplier loadChunkAsync(DynmapChunk chunk){ + try { + CompletableFuture nbt = provider.getChunk(((CraftWorld) w).getHandle(), chunk.x, chunk.z); + return () -> { + NBTTagCompound compound = nbt.join(); + return compound == null ? null : parseChunkFromNBT(new NBT.NBTCompound(compound)); + }; + } catch (InvocationTargetException | IllegalAccessException ignored) { + return () -> null; + } + } + + private Supplier getLoadedChunk(DynmapChunk chunk, boolean async) { + CraftWorld cw = (CraftWorld) w; + if (!cw.isChunkLoaded(chunk.x, chunk.z)) return () -> null; + Chunk c = cw.getHandle().getChunkIfLoaded(chunk.x, chunk.z); //already safe async on vanilla + if ((c == null) || c.o) return () -> null; // c.loaded + if (async) { //the data of the chunk may change while we write, better to write it sync + CompletableFuture nbt = CompletableFuture.supplyAsync(() -> ChunkRegionLoader.a(cw.getHandle(), c), ((CraftServer) Bukkit.getServer()).getServer()); + return () -> { + NBTTagCompound compound = nbt.join(); + return compound == null ? null : parseChunkFromNBT(new NBT.NBTCompound(compound)); + }; + } else { + NBTTagCompound nbt = ChunkRegionLoader.a(cw.getHandle(), c); + GenericChunk genericChunk; + if (nbt != null) genericChunk = parseChunkFromNBT(new NBT.NBTCompound(nbt)); + else genericChunk = null; + return () -> genericChunk; + } + + } + // Load generic chunk from unloaded chunk + 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().k().a.f(cc).join().get(); // playerChunkMap + } 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); + } +} diff --git a/bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/NBT.java b/bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/NBT.java new file mode 100644 index 00000000..14503faf --- /dev/null +++ b/bukkit-helper-119/src/main/java/org/dynmap/bukkit/helper/v119/NBT.java @@ -0,0 +1,126 @@ +package org.dynmap.bukkit.helper.v119; + +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.d(); + } + @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).e_(); + } + @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/.settings/org.eclipse.jdt.core.prefs b/bukkit-helper/.settings/org.eclipse.jdt.core.prefs index 34340ad4..68479f99 100644 --- a/bukkit-helper/.settings/org.eclipse.jdt.core.prefs +++ b/bukkit-helper/.settings/org.eclipse.jdt.core.prefs @@ -1,5 +1,5 @@ # -#Tue Mar 29 22:17:34 CDT 2022 +#Tue Jun 07 11:38:11 CDT 2022 org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 diff --git a/settings.gradle b/settings.gradle index b7e91e37..49c06be4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -19,6 +19,7 @@ include ':bukkit-helper-116-4' include ':bukkit-helper-117' include ':bukkit-helper-118' include ':bukkit-helper-118-2' +include ':bukkit-helper-119' include ':bukkit-helper' include ':dynmap-api' include ':DynmapCore' @@ -47,6 +48,7 @@ project(':bukkit-helper-116-4').projectDir = "$rootDir/bukkit-helper-116-4" as F project(':bukkit-helper-117').projectDir = "$rootDir/bukkit-helper-117" as File project(':bukkit-helper-118').projectDir = "$rootDir/bukkit-helper-118" as File project(':bukkit-helper-118-2').projectDir = "$rootDir/bukkit-helper-118-2" as File +project(':bukkit-helper-119').projectDir = "$rootDir/bukkit-helper-119" 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 8f647d09..b84c5169 100644 --- a/spigot/build.gradle +++ b/spigot/build.gradle @@ -63,6 +63,9 @@ dependencies { implementation(project(':bukkit-helper-118-2')) { transitive = false } + implementation(project(':bukkit-helper-119')) { + transitive = false + } } processResources { @@ -96,6 +99,7 @@ shadowJar { include(dependency(':bukkit-helper-117')) include(dependency(':bukkit-helper-118')) include(dependency(':bukkit-helper-118-2')) + include(dependency(':bukkit-helper-119')) } relocate('org.bstats', 'org.dynmap.bstats') destinationDir = 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 de807ecb..3856f595 100644 --- a/spigot/src/main/java/org/dynmap/bukkit/Helper.java +++ b/spigot/src/main/java/org/dynmap/bukkit/Helper.java @@ -15,6 +15,7 @@ import org.dynmap.bukkit.helper.v116_4.BukkitVersionHelperSpigot116_4; import org.dynmap.bukkit.helper.v117.BukkitVersionHelperSpigot117; import org.dynmap.bukkit.helper.v118.BukkitVersionHelperSpigot118; import org.dynmap.bukkit.helper.v118_2.BukkitVersionHelperSpigot118_2; +import org.dynmap.bukkit.helper.v119.BukkitVersionHelperSpigot119; public class Helper { @@ -40,6 +41,9 @@ public class Helper { Log.info("Loading Glowstone support"); BukkitVersionHelper.helper = new BukkitVersionHelperGlowstone(); } + else if (v.contains("(MC: 1.19")) { + BukkitVersionHelper.helper = new BukkitVersionHelperSpigot119(); + } else if (v.contains("(MC: 1.18)") || (v.contains("(MC: 1.18.1)"))) { BukkitVersionHelper.helper = new BukkitVersionHelperSpigot118(); }