diff --git a/DynmapCore/src/main/java/org/dynmap/hdmap/ChunkStatusHDShader.java b/DynmapCore/src/main/java/org/dynmap/hdmap/ChunkStatusHDShader.java index c23b63480..db13fd342 100644 --- a/DynmapCore/src/main/java/org/dynmap/hdmap/ChunkStatusHDShader.java +++ b/DynmapCore/src/main/java/org/dynmap/hdmap/ChunkStatusHDShader.java @@ -43,9 +43,10 @@ private static class ChunkStatusMap { new ChunkStatusMap("carvers", 0xFFEFD5); new ChunkStatusMap("liquid_carvers", 0xF0E68C); new ChunkStatusMap("features", 0xBDB76B); + new ChunkStatusMap("initialize_light", 0xAAA0AA); new ChunkStatusMap("light", 0xDDA0DD); - new ChunkStatusMap("spawn", 0xFF00FF); new ChunkStatusMap("heightmaps", 0x9370DB); + new ChunkStatusMap("spawn", 0xFF00FF); new ChunkStatusMap("full", 0x32CD32); } diff --git a/DynmapCore/src/main/java/org/dynmap/storage/aws_s3/AWSS3MapStorage.java b/DynmapCore/src/main/java/org/dynmap/storage/aws_s3/AWSS3MapStorage.java index 577ed2fc2..d4250eacd 100644 --- a/DynmapCore/src/main/java/org/dynmap/storage/aws_s3/AWSS3MapStorage.java +++ b/DynmapCore/src/main/java/org/dynmap/storage/aws_s3/AWSS3MapStorage.java @@ -138,9 +138,9 @@ public boolean write(long hash, BufferOutputStream encImage, long timestamp) { s3.deleteObject(req); } else { - PutObjectRequest req = PutObjectRequest.builder().bucketName(bucketname).key(baseKey).contentType(map.getImageFormat().getEncoding().getContentType()) + PutObjectRequest req = PutObjectRequest.builder().bucketName(bucketname).key(baseKey).contentType(map.getImageFormat().getEncoding().getContentType()) .addMetadata("x-dynmap-hash", Long.toHexString(hash)).addMetadata("x-dynmap-ts", Long.toString(timestamp)).build(); - s3.putObject(req, RequestBody.fromBytes(encImage.buf)); + s3.putObject(req, RequestBody.fromBytes(Arrays.copyOf(encImage.buf, encImage.len))); } done = true; } catch (S3Exception x) { @@ -407,7 +407,7 @@ private void processEnumMapTiles(DynmapWorld world, MapType map, ImageVariant va } if (result.isTruncated()) { // If more, build continuiation request req = ListObjectsV2Request.builder().bucketName(bucketname) - .prefix(basekey).delimiter("").maxKeys(1000).continuationToken(result.getContinuationToken()).encodingType("url").requestPayer("requester").build(); + .prefix(basekey).delimiter("").maxKeys(1000).continuationToken(result.getNextContinuationToken()).encodingType("url").requestPayer("requester").build(); } else { // Else, we're done done = true; @@ -480,7 +480,7 @@ private void processPurgeMapTiles(DynmapWorld world, MapType map, ImageVariant v } if (result.isTruncated()) { // If more, build continuiation request req = ListObjectsV2Request.builder().bucketName(bucketname) - .prefix(basekey).delimiter("").maxKeys(1000).continuationToken(result.getContinuationToken()).encodingType("url").requestPayer("requester").build(); + .prefix(basekey).delimiter("").maxKeys(1000).continuationToken(result.getNextContinuationToken()).encodingType("url").requestPayer("requester").build(); } else { // Else, we're done done = true; @@ -529,7 +529,7 @@ public boolean setPlayerFaceImage(String playername, FaceType facetype, } else { PutObjectRequest req = PutObjectRequest.builder().bucketName(bucketname).key(baseKey).contentType("image/png").build(); - s3.putObject(req, RequestBody.fromBytes(encImage.buf)); + s3.putObject(req, RequestBody.fromBytes(Arrays.copyOf(encImage.buf, encImage.len))); } done = true; } catch (S3Exception x) { @@ -582,7 +582,7 @@ public boolean setMarkerImage(String markerid, BufferOutputStream encImage) { } else { PutObjectRequest req = PutObjectRequest.builder().bucketName(bucketname).key(baseKey).contentType("image/png").build(); - s3.putObject(req, RequestBody.fromBytes(encImage.buf)); + s3.putObject(req, RequestBody.fromBytes(Arrays.copyOf(encImage.buf, encImage.len))); } done = true; } catch (S3Exception x) { @@ -611,8 +611,8 @@ public boolean setMarkerFile(String world, String content) { s3.deleteObject(delreq); } else { - PutObjectRequest req = PutObjectRequest.builder().bucketName(bucketname).key(baseKey).contentType("application/json").build(); - s3.putObject(req, RequestBody.fromBytes(content.getBytes(StandardCharsets.UTF_8))); + PutObjectRequest req = PutObjectRequest.builder().bucketName(bucketname).key(baseKey).contentType("application/json").build(); + s3.putObject(req, RequestBody.fromString(content)); } done = true; } catch (S3Exception x) { @@ -745,7 +745,7 @@ else if (fileid.endsWith(".js")) { ct = "application/x-javascript"; } PutObjectRequest req = PutObjectRequest.builder().bucketName(bucketname).key(baseKey).contentType(ct).build(); - s3.putObject(req, RequestBody.fromBytes(content.buf)); + s3.putObject(req, RequestBody.fromBytes(Arrays.copyOf(content.buf, content.len))); standalone_cache.put(fileid, digest); } done = true; diff --git a/DynmapCore/src/main/resources/extracted/web/css/dynmap_style.css b/DynmapCore/src/main/resources/extracted/web/css/dynmap_style.css index 489c49185..b679b1d9f 100644 --- a/DynmapCore/src/main/resources/extracted/web/css/dynmap_style.css +++ b/DynmapCore/src/main/resources/extracted/web/css/dynmap_style.css @@ -1,3 +1,22 @@ +:root { + --colour-highlight: oklch(0.56 0.16 142.24); + --smokey-white: oklch(0.99 0 0); + --gunmetal: oklch(0.29 0.02 277.99); + --charcoal-grey: oklch(0.34 0.03 273.24); + --ship-grey: oklch(0.36 0.02 278.37); + --vampire-grey: oklch(0.45 0.02 278.64); + --cool-grey: oklch(0.72 0.02 270.22); + --slate-grey: oklch(0.6 0.02 264.54); + --status-error: oklch(0.51 0.12 22.01); +} + +.montserrat-font { + font-family: "Montserrat", sans-serif; + font-optical-sizing: auto; + font-weight: 400; + font-style: normal; +} + /* TILE DEBUGGING */ /*.leaflet-tile { margin: -1; @@ -1019,46 +1038,227 @@ /* Login/register panel */ .dynmaplogin { - text-align: center; - width: 100%; - font-weight: bold; - color: #FFFFFF; + display: grid; + width: 100%; + height: 100%; + place-items: center; + width: 100%; + font-weight: bold; + color: #FFFFFF; + background: var(--vampire-grey); + font-family: "Montserrat", sans-serif; + font-optical-sizing: auto; + font-weight: 400; + font-style: normal; + box-sizing: border-box; + + & * { + box-sizing: border-box; + } + + .container { + --outer-margin: 2rem; + container-type: inline-size; + container-name: container; + position: relative; + width: calc(100% - var(--outer-margin) * 2); + max-width: 960px; + padding: 3rem; + margin: var(--outer-margin); + padding-block-start: 3rem; + border-radius: 20px; + /*background-image: url("https://wallpapersok.com/images/file/minecraft-landscape-with-cloudy-sky-b9nxzmdukp1j51zq.jpg"); */ + background-color: var(--gunmetal); + box-shadow: 0px 30px 30px -5px var(--ship-grey); + + &::before { + position: absolute; + top: 0; + left: 0; + z-index: 0; + content: ''; + display: flex; + width: 100%; + height: 100%; + background: url("https://cdn.modrinth.com/data/fRQREgAc/2eaa1e6a6fa03e485a319a628d6b29ba382855b4_96.webp"); + background-position: right 1rem; + background-repeat: no-repeat; + background-size: 25%; + pointer-events: none; + opacity: 0.4; + mix-blend-mode: overlay; + } + } + + h2 { + margin: 0; + font-size: 2rem; + font-weight: 700; + color: var(--smokey-white); + + span { + color: var(--colour-highlight); + } + } + h3 { + margin: 0; + margin-block-end: 5rem; + padding-right: 40px; + font-size: 1rem; + font-weight: 700; + color: var(--cool-grey); + text-transform: uppercase; + text-decoration: underline; + text-decoration-thickness: 1px; + text-underline-offset: 5px; + text-decoration-color: var(--colour-highlight); + + &:has(~ .statusmessage > div) { + margin-block-end: 3rem; + } + } + + p { + line-height: 1.4; + } + + a { + color: var(--colour-highlight); + } + + code { + font-family: 'Courier New', Courier, monospace; + font-size: 14px; + padding: 4px 6px; background: #000000; -} + border-radius: 5px; + } -table.loginregister { - color: #ffffff; - border: 1px solid rgba(64,64,64,0.6); - background: #bbb; - font-weight: bold; - margin: auto; -} + .loginregister { + font-size: 1rem; -td.login { - vertical-align: top; - color: #000000; - background-color: #bbb; - border: 1px solid rgba(64,64,64,0.6); - font-weight: bold; - margin: 2em; - width: 40em; -} + &:has(#register-form:target) #login-form { + display: none; + } -td.register { - vertical-align: top; - color: #000000; - background-color: #bbb; - border: 1px solid rgba(64,64,64,0.6); - font-weight: bold; - margin: 2em; - width: 40em; + #login-form { } + + #register-form { + display: none; + &:target { + display: block; + } + } + input { + width: 100%; + padding: 0; + font-size: 1rem; + color: var(--smokey-white); + border: none; + background: transparent; + font-family: inherit; + font-weight: 500; + &::placeholder { + opacity: 0.1; + color: var(--smokey-white); + + } + &:focus-visible { + background: none; + border: none; + outline: none; + } + &:is(:-webkit-autofill, :autofill) { + border: none; + } + + &[type="submit"] { + max-width: 20ch; + padding-block: 1rem; + padding-inline: 2rem; + background-color: var(--colour-highlight); + border-radius: calc(infinity * 1px); + border: 2px solid transparent; + cursor: pointer; + transition: .2s background ease; + &:hover { + background-color: oklch(from var(--colour-highlight) calc(l - 0.04) c h); + } + &:focus-visible { + border: 2px solid var(--smokey-white); + } + } + } + + label { + margin-block-end: .2rem; + color: var(--slate-grey); + font-size: 0.813rem; + font-weight: 400; + } + } + + form { + display: grid; + grid-template-columns: minmax(100px, 1fr); + gap: 2rem; + max-width: 60ch; + + p { + grid-column: 1 / -1; + } + } + .form-item { + position: relative; + grid-column: 1 / -1; + display: flex; + flex-direction: column; + padding-block: 1rem; + padding-inline: 2rem; + background-color: var(--charcoal-grey); + border-radius: 10px; + border: 2px solid transparent; + transition: border .5s ease; + &:focus-within { + border: 2px solid var(--colour-highlight); + color: black; + } + } + + @container (width > 400px) { + form { + grid-template-columns: repeat(2, minmax(100px, 1fr)); + + } + + .form-item.shortened { + grid-column: 1; + + .shortened { + grid-column: 2; + } + } + + h3 { + padding: 0; + } + } } div.statusmessage { - color: #FF0000; - font-weight: bold; - font-size: 24px; - + position: relative; + z-index: 2; + &:empty { + display: none; + } + > div { + margin-block-end: 2rem; + padding: 1rem; + color: var(--smokey-white); + font-weight: bold; + font-size: 16px; + background: linear-gradient(90deg, var(--status-error) 30%, transparent 80%); + font-weight: 300; + border-radius: 5px; } .logincontainer { diff --git a/DynmapCore/src/main/resources/extracted/web/login.html b/DynmapCore/src/main/resources/extracted/web/login.html index 6ddfcff55..6b44d23d7 100644 --- a/DynmapCore/src/main/resources/extracted/web/login.html +++ b/DynmapCore/src/main/resources/extracted/web/login.html @@ -2,14 +2,17 @@ - + Minecraft Dynamic Map - Login/Register + + + @@ -55,48 +58,50 @@
-

Minecraft Dynamic Map - Login/Register

-
- - - - - - - -
Existing User:
Register New User:
-
-

-Run '/dynmap webregister' and enter your username and registration code, and create a password: -
-
- - - - - -
Username
Password
Verify Password
Registration Code
-
-
- -

-
-
+
+

Minecraft Dynamic Map

+
+ +
+ + +
+

Register New User.

+ +

Already have an account? Log in

+
+

Run /dynmap webregister [username] enter your username and password, followed by the registration code

+
+ +
+
+ +
+
+ +
+
+ +
+ +
+
+
+ +
diff --git a/DynmapCore/src/main/resources/extracted/web/standalone/PostgreSQL_register.php b/DynmapCore/src/main/resources/extracted/web/standalone/PostgreSQL_register.php new file mode 100644 index 000000000..1af07600f --- /dev/null +++ b/DynmapCore/src/main/resources/extracted/web/standalone/PostgreSQL_register.php @@ -0,0 +1,88 @@ + bsids = Block.k; + 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); // BuiltInRegistries.BLOCK.getKey(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().bg().f(Registries.aN); // 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.k; + 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(); // BlockBehaviour$BlockStateBase.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.e()) { bld.setSolid(); } // BlockBehaviour$BlockStateBase.isSolid + if (bd.l()) { bld.setAir(); } // BlockBehaviour$BlockStateBase.isAir + if (bd.a(TagsBlock.av)) { bld.setLog(); } // BlockBehaviour$BlockStateBase.is(BlockTags.OVERWORLD_NATURAL_LOGS) + if (bd.a(TagsBlock.M)) { bld.setLeaves(); } // BlockBehaviour$BlockStateBase.is(BlockTags.LEAVES) + // BlockBehaviour$BlockStateBase.getFluidState.isEmpty(), BlockBehaviour$BlockStateBase.getBlock + if (!bd.y().c() && !(bd.b() instanceof BlockFluids)) { // 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_10 c = new MapChunkCache121_10(gencache); + c.setChunks(dw, chunks); + return c; + } + + /** + * Get biome base water multiplier + */ + @Override + public int getBiomeBaseWaterMult(Object bb) { + BiomeBase biome = (BiomeBase) bb; + return biome.j(); // Biome.getWaterColor + } + + /** Get temperature from biomebase */ + @Override + public float getBiomeBaseTemperature(Object bb) { + return ((BiomeBase)bb).h(); // Biome.getBaseTemperature + } + + /** Get humidity from biomebase */ + @Override + public float getBiomeBaseHumidity(Object bb) { + String vals = ((BiomeBase)bb).i.toString(); // Biome.climateSettings + 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, 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(); // MinecraftKey.getPath() + } + @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(); // ChunkStatus.FULL ; IChunkAccess.getInhabitedTime + } + + @Override + public Map getTileEntitiesForChunk(Chunk c) { + return ((CraftChunk)c).getHandle(ChunkStatus.n).j; // ChunkStatus.FULL ; IChunkAccess.blockEntities + } + + @Override + public int getTileEntityX(Object te) { + TileEntity tileent = (TileEntity) te; + return tileent.aD_().u(); // TileEntity.getBlockPos ; Vec3i.getX + } + + @Override + public int getTileEntityY(Object te) { + TileEntity tileent = (TileEntity) te; + return tileent.aD_().v(); // TileEntity.getBlockPos ; Vec3i.getY + } + + @Override + public int getTileEntityZ(Object te) { + TileEntity tileent = (TileEntity) te; + return tileent.aD_().w(); // TileEntity.getBlockPos ; Vec3i.getZ + } + + @Override + public Object readTileEntityNBT(Object te, World w) { + TileEntity tileent = (TileEntity) te; + CraftWorld cw = (CraftWorld) w; + return tileent.d(cw.getHandle().L_()); // TileEntity.saveCustomOnly ; LevelReader.registryAccess + } + + @Override + public Object getFieldValue(Object nbt, String field) { + NBTTagCompound rec = (NBTTagCompound) nbt; + NBTBase val = rec.a(field); // NBTTagCompound.get + if(val == null) return null; + if(val instanceof NBTTagByte) { + return ((NBTTagByte)val).n(); // NBTTagByte.value + } + else if(val instanceof NBTTagShort) { + return ((NBTTagShort)val).n(); // NBTTagShort.value + } + else if(val instanceof NBTTagInt) { + return ((NBTTagInt)val).n(); // NBTTagInt.value + } + else if(val instanceof NBTTagLong) { + return ((NBTTagLong)val).n(); // NBTTagLong.value + } + else if(val instanceof NBTTagFloat) { + return ((NBTTagFloat)val).n(); // NBTTagFloat.value + } + else if(val instanceof NBTTagDouble) { + return ((NBTTagDouble)val).n(); // NBTTagDouble.value + } + else if(val instanceof NBTTagByteArray) { + return ((NBTTagByteArray)val).e(); // NBTTagByteArray.getAsByteArray + } + else if(val instanceof NBTTagString) { + return ((NBTTagString)val).k(); // NBTTagString.value + } + else if(val instanceof NBTTagIntArray) { + return ((NBTTagIntArray)val).g(); // NBTTagIntArray.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.properties(); + 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-10/src/main/java/org/dynmap/bukkit/helper/v121_10/MapChunkCache121_10.java b/bukkit-helper-121-10/src/main/java/org/dynmap/bukkit/helper/v121_10/MapChunkCache121_10.java new file mode 100644 index 000000000..bffc97dae --- /dev/null +++ b/bukkit-helper-121-10/src/main/java/org/dynmap/bukkit/helper/v121_10/MapChunkCache121_10.java @@ -0,0 +1,105 @@ +package org.dynmap.bukkit.helper.v121_10; + +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.Bukkit; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_21_R6.CraftServer; +import org.bukkit.craftbukkit.v1_21_R6.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.Optional; +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 MapChunkCache121_10 extends GenericMapChunkCache { + private World w; + /** + * Construct empty cache + */ + public MapChunkCache121_10(GenericChunkCache cc) { + super(cc); + } + + @Override + protected Supplier getLoadedChunkAsync(DynmapChunk chunk) { + CompletableFuture> chunkData = CompletableFuture.supplyAsync(() -> { + CraftWorld cw = (CraftWorld) w; + Chunk c = cw.getHandle().getChunkIfLoaded(chunk.x, chunk.z); + if (c == null || !c.p) { // !LevelChunk.loaded + return Optional.empty(); + } + return Optional.of(SerializableChunkData.a(cw.getHandle(), c)); // SerializableChunkData.copyOf + }, ((CraftServer) Bukkit.getServer()).getServer()); + return () -> chunkData.join().map(SerializableChunkData::a).map(NBT.NBTCompound::new).map(this::parseChunkFromNBT).orElse(null); // SerializableChunkData::write + } + + 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.p) return null; // LevelChunk.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; + } + + @Override + protected Supplier loadChunkAsync(DynmapChunk chunk) { + CraftWorld cw = (CraftWorld) w; + CompletableFuture> genericChunk = cw.getHandle().n().a.d(new ChunkCoordIntPair(chunk.x, chunk.z)); // WorldServer.getChunkSource().chunkMap.read(new ChunkCoordIntPair(chunk.x, chunk.z)) + return () -> genericChunk.join().map(NBT.NBTCompound::new).map(this::parseChunkFromNBT).orElse(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() + .n() // ServerLevel.getChunkSource + .a // ServerChunkCache.chunkMap + .d(cc) // ChunkStorage.read(ChunkPos) + .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::i).flatMap(BiomeFog::e).orElse(colormap[bm.biomeLookup()]); // BiomeBase::getSpecialEffects ; BiomeFog::getFoliageColorOverride + } + + @Override + public int getGrassColor(BiomeMap bm, int[] colormap, int x, int z) { + BiomeFog fog = bm.getBiomeObject().map(BiomeBase::i).orElse(null); // BiomeBase::getSpecialEffects + if (fog == null) return colormap[bm.biomeLookup()]; + return fog.h().a(x, z, fog.g().orElse(colormap[bm.biomeLookup()])); // BiomeFog.getGrassColorModifier.modifyColor ; BiomeFog.getGrassColorOverride + } +} diff --git a/bukkit-helper-121-10/src/main/java/org/dynmap/bukkit/helper/v121_10/NBT.java b/bukkit-helper-121-10/src/main/java/org/dynmap/bukkit/helper/v121_10/NBT.java new file mode 100644 index 000000000..39cf4ffbe --- /dev/null +++ b/bukkit-helper-121-10/src/main/java/org/dynmap/bukkit/helper/v121_10/NBT.java @@ -0,0 +1,144 @@ +package org.dynmap.bukkit.helper.v121_10; + +import org.dynmap.common.chunk.GenericBitStorage; +import org.dynmap.common.chunk.GenericNBTCompound; +import org.dynmap.common.chunk.GenericNBTList; + +import java.util.Optional; +import java.util.Set; +import net.minecraft.nbt.NBTBase; +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(); // CompoundTag.keySet + } + @Override + public boolean contains(String s) { + return obj.b(s); // CompoundTag.contains + } + @Override + public boolean contains(String s, int i) { + // Like contains, but with an extra constraint on type + NBTBase base = obj.a(s); // CompoundTag.get + if (base == null) + return false; + byte type = base.b(); // CompoundTag.getId + if (type == i) + return true; + else if (i != TAG_ANY_NUMERIC) + return false; + return type == TAG_BYTE || type == TAG_SHORT || type == TAG_INT || type == TAG_LONG || type == TAG_FLOAT + || type == TAG_DOUBLE; + } + @Override + public byte getByte(String s) { + return obj.b(s, (byte)0); // CompoundTag.getByteOr + } + @Override + public short getShort(String s) { + return obj.b(s, (short)0); // CompoundTag.getShortOr + } + @Override + public int getInt(String s) { + return obj.b(s, 0); // CompoundTag.getIntOr + } + @Override + public long getLong(String s) { + return obj.b(s, 0L); // CompoundTag.getLongOr + } + @Override + public float getFloat(String s) { + return obj.b(s, 0.0f); // CompoundTag.getFloatOr + } + @Override + public double getDouble(String s) { + return obj.b(s, 0.0); // CompoundTag.getDoubleOr + } + @Override + public String getString(String s) { + return obj.b(s, ""); // CompoundTag.getDoubleOr + } + @Override + public byte[] getByteArray(String s) { + Optional byteArr = obj.j(s); // CompoundTag.getByteArray + return byteArr.orElseGet(() -> new byte[0]); + } + @Override + public int[] getIntArray(String s) { + Optional intArr = obj.k(s); // CompoundTag.getIntArray + return intArr.orElseGet(() -> new int[0]); + } + @Override + public long[] getLongArray(String s) { + Optional longArr = obj.l(s); // CompoundTag.getLongArray + return longArr.orElseGet(() -> new long[0]); + } + @Override + public GenericNBTCompound getCompound(String s) { + return new NBTCompound(obj.n(s)); // CompoundTag.getCompoundOrEmpty + } + @Override + public GenericNBTList getList(String s, int i) { + // i argument used to be used to constrain list type, but nbt lists no longer have types as of 1.21.5 + return new NBTList(obj.p(s)); // CompoundTag.getListOrEmpty + } + @Override + public boolean getBoolean(String s) { + return getByte(s) != 0; + } + @Override + public String getAsString(String s) { + return obj.a(s).r_().orElseGet(() -> ""); // CompoundTag.get ; Tag.asString + } + @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.a(idx, ""); // ListTag.getStringOr + } + @Override + public GenericNBTCompound getCompound(int idx) { + return new NBTCompound(obj.b(idx)); // ListTag.getCompoundOrEmpty + } + 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/forge-1.21/.gitignore b/bukkit-helper-121-11/.gitignore similarity index 100% rename from forge-1.21/.gitignore rename to bukkit-helper-121-11/.gitignore diff --git a/bukkit-helper-121-11/build.gradle b/bukkit-helper-121-11/build.gradle new file mode 100644 index 000000000..5a8ccc1f0 --- /dev/null +++ b/bukkit-helper-121-11/build.gradle @@ -0,0 +1,19 @@ +eclipse { + project { + name = "Dynmap(Spigot-1.21.11)" + } +} + +description = 'bukkit-helper-1.21.11' + +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.11-R0.1-SNAPSHOT' + compileOnly ('org.spigotmc:spigot:1.21.11-R0.1-SNAPSHOT') { + exclude group: "com.mojang", module: "jtracy" + } +} diff --git a/bukkit-helper-121-11/src/main/java/org/dynmap/bukkit/helper/v121_11/BukkitVersionHelperSpigot121_11.java b/bukkit-helper-121-11/src/main/java/org/dynmap/bukkit/helper/v121_11/BukkitVersionHelperSpigot121_11.java new file mode 100644 index 000000000..8982c57dd --- /dev/null +++ b/bukkit-helper-121-11/src/main/java/org/dynmap/bukkit/helper/v121_11/BukkitVersionHelperSpigot121_11.java @@ -0,0 +1,450 @@ +package org.dynmap.bukkit.helper.v121_11; + +import org.bukkit.*; +import org.bukkit.craftbukkit.v1_21_R7.CraftChunk; +import org.bukkit.craftbukkit.v1_21_R7.CraftWorld; +import org.bukkit.craftbukkit.v1_21_R7.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_11 extends BukkitVersionHelper { + + @Override + public boolean isUnsafeAsync() { + return false; + } + + /** + * Get block short name list + */ + @Override + public String[] getBlockNames() { + RegistryBlockID bsids = Block.k; + 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); // BuiltInRegistries.BLOCK.getKey(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().bc().f(Registries.aS); // 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); // Registry.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.k; + 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(); // BlockBehaviour$BlockStateBase.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.e()) { bld.setSolid(); } // BlockBehaviour$BlockStateBase.isSolid + if (bd.l()) { bld.setAir(); } // BlockBehaviour$BlockStateBase.isAir + if (bd.a(TagsBlock.av)) { bld.setLog(); } // BlockBehaviour$BlockStateBase.is(BlockTags.OVERWORLD_NATURAL_LOGS) + if (bd.a(TagsBlock.M)) { bld.setLeaves(); } // BlockBehaviour$BlockStateBase.is(BlockTags.LEAVES) + // BlockBehaviour$BlockStateBase.getFluidState.isEmpty(), BlockBehaviour$BlockStateBase.getBlock + if (!bd.y().c() && !(bd.b() instanceof BlockFluids)) { // 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_11 c = new MapChunkCache121_11(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(); // Biome.getWaterColor + } + + /** Get temperature from biomebase */ + @Override + public float getBiomeBaseTemperature(Object bb) { + return ((BiomeBase)bb).f(); // Biome.getBaseTemperature + } + + /** Get humidity from biomebase */ + @Override + public float getBiomeBaseHumidity(Object bb) { + String vals = ((BiomeBase)bb).i.toString(); // Biome.climateSettings + 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, 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(); // MinecraftKey.getPath() + } + @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(); // ChunkStatus.FULL ; ChunkAccess.getInhabitedTime + } + + @Override + public Map getTileEntitiesForChunk(Chunk c) { + return ((CraftChunk)c).getHandle(ChunkStatus.n).j; // ChunkStatus.FULL ; ChunkAccess.blockEntities + } + + @Override + public int getTileEntityX(Object te) { + TileEntity tileent = (TileEntity) te; + return tileent.aD_().u(); // BlockEntity.getBlockPos ; Vec3i.getX + } + + @Override + public int getTileEntityY(Object te) { + TileEntity tileent = (TileEntity) te; + return tileent.aD_().v(); // BlockEntity.getBlockPos ; Vec3i.getY + } + + @Override + public int getTileEntityZ(Object te) { + TileEntity tileent = (TileEntity) te; + return tileent.aD_().w(); // BlockEntity.getBlockPos ; Vec3i.getZ + } + + @Override + public Object readTileEntityNBT(Object te, World w) { + TileEntity tileent = (TileEntity) te; + CraftWorld cw = (CraftWorld) w; + return tileent.d(cw.getHandle().J_()); // BlockEntity.saveCustomOnly ; LevelReader.registryAccess + } + + @Override + public Object getFieldValue(Object nbt, String field) { + NBTTagCompound rec = (NBTTagCompound) nbt; + NBTBase val = rec.a(field); // CompoundTag.get + if(val == null) return null; + if(val instanceof NBTTagByte) { + return ((NBTTagByte)val).n(); // ByteTag.value + } + else if(val instanceof NBTTagShort) { + return ((NBTTagShort)val).n(); // ShortTag.value + } + else if(val instanceof NBTTagInt) { + return ((NBTTagInt)val).n(); // IntTag.value + } + else if(val instanceof NBTTagLong) { + return ((NBTTagLong)val).n(); // LongTag.value + } + else if(val instanceof NBTTagFloat) { + return ((NBTTagFloat)val).n(); // FloatTag.value + } + else if(val instanceof NBTTagDouble) { + return ((NBTTagDouble)val).n(); // DoubleTag.value + } + else if(val instanceof NBTTagByteArray) { + return ((NBTTagByteArray)val).e(); // ByteArrayTag.getAsByteArray + } + else if(val instanceof NBTTagString) { + return ((NBTTagString)val).k(); // StringTag.value + } + else if(val instanceof NBTTagIntArray) { + return ((NBTTagIntArray)val).g(); // IntArrayTag.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.properties(); + 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-11/src/main/java/org/dynmap/bukkit/helper/v121_11/MapChunkCache121_11.java b/bukkit-helper-121-11/src/main/java/org/dynmap/bukkit/helper/v121_11/MapChunkCache121_11.java new file mode 100644 index 000000000..707998bf3 --- /dev/null +++ b/bukkit-helper-121-11/src/main/java/org/dynmap/bukkit/helper/v121_11/MapChunkCache121_11.java @@ -0,0 +1,105 @@ +package org.dynmap.bukkit.helper.v121_11; + +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.Bukkit; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_21_R7.CraftServer; +import org.bukkit.craftbukkit.v1_21_R7.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.Optional; +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 MapChunkCache121_11 extends GenericMapChunkCache { + private World w; + /** + * Construct empty cache + */ + public MapChunkCache121_11(GenericChunkCache cc) { + super(cc); + } + + @Override + protected Supplier getLoadedChunkAsync(DynmapChunk chunk) { + CompletableFuture> chunkData = CompletableFuture.supplyAsync(() -> { + CraftWorld cw = (CraftWorld) w; + Chunk c = cw.getHandle().getChunkIfLoaded(chunk.x, chunk.z); + if (c == null || !c.p) { // !LevelChunk.loaded + return Optional.empty(); + } + return Optional.of(SerializableChunkData.a(cw.getHandle(), c)); // SerializableChunkData.copyOf + }, ((CraftServer) Bukkit.getServer()).getServer()); + return () -> chunkData.join().map(SerializableChunkData::a).map(NBT.NBTCompound::new).map(this::parseChunkFromNBT).orElse(null); // SerializableChunkData::write + } + + 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.p) return null; // LevelChunk.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; + } + + @Override + protected Supplier loadChunkAsync(DynmapChunk chunk) { + CraftWorld cw = (CraftWorld) w; + CompletableFuture> genericChunk = cw.getHandle().p().a.d(new ChunkCoordIntPair(chunk.x, chunk.z)); // ServerLevel.getChunkSource().chunkMap.read(new ChunkCoordIntPair(chunk.x, chunk.z)) + return () -> genericChunk.join().map(NBT.NBTCompound::new).map(this::parseChunkFromNBT).orElse(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() + .p() // ServerLevel.getChunkSource + .a // ServerChunkCache.chunkMap + .d(cc) // SimpleRegionStorage.read(ChunkPos) + .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::b).orElse(colormap[bm.biomeLookup()]); // BiomeBase::getSpecialEffects, Biome::foliageColorOverride + } + + @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.e().a(x, z, fog.d().orElse(colormap[bm.biomeLookup()])); // BiomeFog.grassColorModifier.modifyColor ; BiomeFog.grassColorOverride + } +} diff --git a/bukkit-helper-121-11/src/main/java/org/dynmap/bukkit/helper/v121_11/NBT.java b/bukkit-helper-121-11/src/main/java/org/dynmap/bukkit/helper/v121_11/NBT.java new file mode 100644 index 000000000..5cbefe182 --- /dev/null +++ b/bukkit-helper-121-11/src/main/java/org/dynmap/bukkit/helper/v121_11/NBT.java @@ -0,0 +1,144 @@ +package org.dynmap.bukkit.helper.v121_11; + +import org.dynmap.common.chunk.GenericBitStorage; +import org.dynmap.common.chunk.GenericNBTCompound; +import org.dynmap.common.chunk.GenericNBTList; + +import java.util.Optional; +import java.util.Set; +import net.minecraft.nbt.NBTBase; +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(); // CompoundTag.keySet + } + @Override + public boolean contains(String s) { + return obj.b(s); // CompoundTag.contains + } + @Override + public boolean contains(String s, int i) { + // Like contains, but with an extra constraint on type + NBTBase base = obj.a(s); // CompoundTag.get + if (base == null) + return false; + byte type = base.b(); // CompoundTag.getId + if (type == i) + return true; + else if (i != TAG_ANY_NUMERIC) + return false; + return type == TAG_BYTE || type == TAG_SHORT || type == TAG_INT || type == TAG_LONG || type == TAG_FLOAT + || type == TAG_DOUBLE; + } + @Override + public byte getByte(String s) { + return obj.b(s, (byte)0); // CompoundTag.getByteOr + } + @Override + public short getShort(String s) { + return obj.b(s, (short)0); // CompoundTag.getShortOr + } + @Override + public int getInt(String s) { + return obj.b(s, 0); // CompoundTag.getIntOr + } + @Override + public long getLong(String s) { + return obj.b(s, 0L); // CompoundTag.getLongOr + } + @Override + public float getFloat(String s) { + return obj.b(s, 0.0f); // CompoundTag.getFloatOr + } + @Override + public double getDouble(String s) { + return obj.b(s, 0.0); // CompoundTag.getDoubleOr + } + @Override + public String getString(String s) { + return obj.b(s, ""); // CompoundTag.getStringOr + } + @Override + public byte[] getByteArray(String s) { + Optional byteArr = obj.j(s); // CompoundTag.getByteArray + return byteArr.orElseGet(() -> new byte[0]); + } + @Override + public int[] getIntArray(String s) { + Optional intArr = obj.k(s); // CompoundTag.getIntArray + return intArr.orElseGet(() -> new int[0]); + } + @Override + public long[] getLongArray(String s) { + Optional longArr = obj.l(s); // CompoundTag.getLongArray + return longArr.orElseGet(() -> new long[0]); + } + @Override + public GenericNBTCompound getCompound(String s) { + return new NBTCompound(obj.n(s)); // CompoundTag.getCompoundOrEmpty + } + @Override + public GenericNBTList getList(String s, int i) { + // i argument used to be used to constrain list type, but nbt lists no longer have types as of 1.21.5 + return new NBTList(obj.p(s)); // CompoundTag.getListOrEmpty + } + @Override + public boolean getBoolean(String s) { + return getByte(s) != 0; + } + @Override + public String getAsString(String s) { + return obj.a(s).p_().orElseGet(() -> ""); // CompoundTag.get ; Tag.asString + } + @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.a(idx, ""); // ListTag.getStringOr + } + @Override + public GenericNBTCompound getCompound(int idx) { + return new NBTCompound(obj.b(idx)); // ListTag.getCompoundOrEmpty + } + 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-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 index 4527aaeb4..a5a5aaf6c 100644 --- 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 @@ -67,7 +67,7 @@ public class BukkitVersionHelperSpigot121_3 extends BukkitVersionHelper { @Override public boolean isUnsafeAsync() { - return true; + return false; } /** 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 index b3b1b796b..676391f1e 100644 --- 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 @@ -6,7 +6,9 @@ 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.Bukkit; import org.bukkit.World; +import org.bukkit.craftbukkit.v1_21_R2.CraftServer; import org.bukkit.craftbukkit.v1_21_R2.CraftWorld; import org.dynmap.DynmapChunk; import org.dynmap.bukkit.helper.BukkitWorld; @@ -17,7 +19,10 @@ import java.util.List; import java.util.NoSuchElementException; +import java.util.Optional; 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 @@ -31,6 +36,19 @@ public MapChunkCache121_3(GenericChunkCache cc) { super(cc); } + @Override + protected Supplier getLoadedChunkAsync(DynmapChunk chunk) { + CompletableFuture> chunkData = CompletableFuture.supplyAsync(() -> { + CraftWorld cw = (CraftWorld) w; + Chunk c = cw.getHandle().getChunkIfLoaded(chunk.x, chunk.z); + if (c == null || !c.q) { // !c.loaded + return Optional.empty(); + } + return Optional.of(SerializableChunkData.a(cw.getHandle(), c)); // SerializableChunkData.copyOf + }, ((CraftServer) Bukkit.getServer()).getServer()); + return () -> chunkData.join().map(SerializableChunkData::a).map(NBT.NBTCompound::new).map(this::parseChunkFromNBT).orElse(null); // SerializableChunkData::write + } + protected GenericChunk getLoadedChunk(DynmapChunk chunk) { CraftWorld cw = (CraftWorld) w; if (!cw.isChunkLoaded(chunk.x, chunk.z)) return null; @@ -41,6 +59,13 @@ protected GenericChunk getLoadedChunk(DynmapChunk chunk) { return nbt != null ? parseChunkFromNBT(new NBT.NBTCompound(nbt)) : null; } + @Override + protected Supplier loadChunkAsync(DynmapChunk chunk) { + CraftWorld cw = (CraftWorld) w; + CompletableFuture> genericChunk = cw.getHandle().m().a.d(new ChunkCoordIntPair(chunk.x, chunk.z)); // WorldServer.getChunkSource().chunkMap.read(new ChunkCoordIntPair(chunk.x, chunk.z)) + return () -> genericChunk.join().map(NBT.NBTCompound::new).map(this::parseChunkFromNBT).orElse(null); + } + protected GenericChunk loadChunk(DynmapChunk chunk) { CraftWorld cw = (CraftWorld) w; NBTTagCompound nbt = null; @@ -64,7 +89,7 @@ public void setChunks(BukkitWorld dw, List 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 + return bm.getBiomeObject().map(BiomeBase::h).flatMap(BiomeFog::e).orElse(colormap[bm.biomeLookup()]); // BiomeBase::getSpecialEffects, BiomeFog::getFoliageColorOverride } @Override diff --git a/bukkit-helper-121-4/src/main/java/org/dynmap/bukkit/helper/v121_4/BukkitVersionHelperSpigot121_4.java b/bukkit-helper-121-4/src/main/java/org/dynmap/bukkit/helper/v121_4/BukkitVersionHelperSpigot121_4.java index 67dc588e7..9a388d74d 100644 --- a/bukkit-helper-121-4/src/main/java/org/dynmap/bukkit/helper/v121_4/BukkitVersionHelperSpigot121_4.java +++ b/bukkit-helper-121-4/src/main/java/org/dynmap/bukkit/helper/v121_4/BukkitVersionHelperSpigot121_4.java @@ -67,7 +67,7 @@ public class BukkitVersionHelperSpigot121_4 extends BukkitVersionHelper { @Override public boolean isUnsafeAsync() { - return true; + return false; } /** diff --git a/bukkit-helper-121-4/src/main/java/org/dynmap/bukkit/helper/v121_4/MapChunkCache121_4.java b/bukkit-helper-121-4/src/main/java/org/dynmap/bukkit/helper/v121_4/MapChunkCache121_4.java index 9a7320a46..40efaf670 100644 --- a/bukkit-helper-121-4/src/main/java/org/dynmap/bukkit/helper/v121_4/MapChunkCache121_4.java +++ b/bukkit-helper-121-4/src/main/java/org/dynmap/bukkit/helper/v121_4/MapChunkCache121_4.java @@ -6,7 +6,9 @@ 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.Bukkit; import org.bukkit.World; +import org.bukkit.craftbukkit.v1_21_R3.CraftServer; import org.bukkit.craftbukkit.v1_21_R3.CraftWorld; import org.dynmap.DynmapChunk; import org.dynmap.bukkit.helper.BukkitWorld; @@ -17,7 +19,10 @@ import java.util.List; import java.util.NoSuchElementException; +import java.util.Optional; 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 @@ -31,6 +36,19 @@ public MapChunkCache121_4(GenericChunkCache cc) { super(cc); } + @Override + protected Supplier getLoadedChunkAsync(DynmapChunk chunk) { + CompletableFuture> chunkData = CompletableFuture.supplyAsync(() -> { + CraftWorld cw = (CraftWorld) w; + Chunk c = cw.getHandle().getChunkIfLoaded(chunk.x, chunk.z); + if (c == null || !c.q) { // !c.loaded + return Optional.empty(); + } + return Optional.of(SerializableChunkData.a(cw.getHandle(), c)); // SerializableChunkData.copyOf + }, ((CraftServer) Bukkit.getServer()).getServer()); + return () -> chunkData.join().map(SerializableChunkData::a).map(NBT.NBTCompound::new).map(this::parseChunkFromNBT).orElse(null); // SerializableChunkData::write + } + protected GenericChunk getLoadedChunk(DynmapChunk chunk) { CraftWorld cw = (CraftWorld) w; if (!cw.isChunkLoaded(chunk.x, chunk.z)) return null; @@ -41,6 +59,13 @@ protected GenericChunk getLoadedChunk(DynmapChunk chunk) { return nbt != null ? parseChunkFromNBT(new NBT.NBTCompound(nbt)) : null; } + @Override + protected Supplier loadChunkAsync(DynmapChunk chunk) { + CraftWorld cw = (CraftWorld) w; + CompletableFuture> genericChunk = cw.getHandle().m().a.d(new ChunkCoordIntPair(chunk.x, chunk.z)); // WorldServer.getChunkSource().chunkMap.read(new ChunkCoordIntPair(chunk.x, chunk.z)) + return () -> genericChunk.join().map(NBT.NBTCompound::new).map(this::parseChunkFromNBT).orElse(null); + } + protected GenericChunk loadChunk(DynmapChunk chunk) { CraftWorld cw = (CraftWorld) w; NBTTagCompound nbt = null; @@ -64,7 +89,7 @@ public void setChunks(BukkitWorld dw, List 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 + return bm.getBiomeObject().map(BiomeBase::h).flatMap(BiomeFog::e).orElse(colormap[bm.biomeLookup()]); // BiomeBase::getSpecialEffects, BiomeFog::getFoliageColorOverride } @Override diff --git a/bukkit-helper-121-5/.gitignore b/bukkit-helper-121-5/.gitignore new file mode 100644 index 000000000..84c048a73 --- /dev/null +++ b/bukkit-helper-121-5/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/bukkit-helper-121-5/build.gradle b/bukkit-helper-121-5/build.gradle new file mode 100644 index 000000000..0b5680747 --- /dev/null +++ b/bukkit-helper-121-5/build.gradle @@ -0,0 +1,19 @@ +eclipse { + project { + name = "Dynmap(Spigot-1.21.5)" + } +} + +description = 'bukkit-helper-1.21.5' + +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.5-R0.1-SNAPSHOT' + compileOnly ('org.spigotmc:spigot:1.21.5-R0.1-SNAPSHOT') { + exclude group: "com.mojang", module: "jtracy" + } +} diff --git a/bukkit-helper-121-5/src/main/java/org/dynmap/bukkit/helper/v121_5/BukkitVersionHelperSpigot121_5.java b/bukkit-helper-121-5/src/main/java/org/dynmap/bukkit/helper/v121_5/BukkitVersionHelperSpigot121_5.java new file mode 100644 index 000000000..08614de47 --- /dev/null +++ b/bukkit-helper-121-5/src/main/java/org/dynmap/bukkit/helper/v121_5/BukkitVersionHelperSpigot121_5.java @@ -0,0 +1,450 @@ +package org.dynmap.bukkit.helper.v121_5; + +import org.bukkit.*; +import org.bukkit.craftbukkit.v1_21_R4.CraftChunk; +import org.bukkit.craftbukkit.v1_21_R4.CraftWorld; +import org.bukkit.craftbukkit.v1_21_R4.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_5 extends BukkitVersionHelper { + + @Override + public boolean isUnsafeAsync() { + return false; + } + + /** + * Get block short name list + */ + @Override + public String[] getBlockNames() { + RegistryBlockID bsids = Block.k; + 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().f(Registries.aG); // 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.k; + 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(); // BlockBehaviour$BlockStateBase.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.e()) { bld.setSolid(); } // BlockBehaviour$BlockStateBase.isSolid + if (bd.l()) { bld.setAir(); } // BlockBehaviour$BlockStateBase.isAir + if (bd.a(TagsBlock.t)) { bld.setLog(); } // BlockBehaviour$BlockStateBase.is(OVERWORLD_NATURAL_LOGS) + if (bd.a(TagsBlock.Q)) { bld.setLeaves(); } // BlockBehaviour$BlockStateBase.is(LEAVES) + // BlockBehaviour$BlockStateBase.getFluidState.isEmpty(), BlockBehaviour$BlockStateBase.getBlock + if (!bd.y().c() && !(bd.b() instanceof BlockFluids)) { // 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_5 c = new MapChunkCache121_5(gencache); + c.setChunks(dw, chunks); + return c; + } + + /** + * Get biome base water multiplier + */ + @Override + public int getBiomeBaseWaterMult(Object bb) { + BiomeBase biome = (BiomeBase) bb; + return biome.j(); // Biome.getWaterColor + } + + /** Get temperature from biomebase */ + @Override + public float getBiomeBaseTemperature(Object bb) { + return ((BiomeBase)bb).h(); // Biome.getBaseTemperature + } + + /** Get humidity from biomebase */ + @Override + public float getBiomeBaseHumidity(Object bb) { + String vals = ((BiomeBase)bb).i.toString(); // Biome.climateSettings + 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(); // MinecraftKey.getPath() + } + @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(); // ChunkStatus.FULL ; IChunkAccess.getInhabitedTime + } + + @Override + public Map getTileEntitiesForChunk(Chunk c) { + return ((CraftChunk)c).getHandle(ChunkStatus.n).k; // ChunkStatus.FULL ; IChunkAccess.blockEntities + } + + @Override + public int getTileEntityX(Object te) { + TileEntity tileent = (TileEntity) te; + return tileent.ax_().u(); // TileEntity.getBlockPos ; Vec3i.getX + } + + @Override + public int getTileEntityY(Object te) { + TileEntity tileent = (TileEntity) te; + return tileent.ax_().v(); // TileEntity.getBlockPos ; Vec3i.getY + } + + @Override + public int getTileEntityZ(Object te) { + TileEntity tileent = (TileEntity) te; + return tileent.ax_().w(); // TileEntity.getBlockPos ; Vec3i.getZ + } + + @Override + public Object readTileEntityNBT(Object te, org.bukkit.World w) { + TileEntity tileent = (TileEntity) te; + CraftWorld cw = (CraftWorld) w; + return tileent.e(cw.getHandle().J_()); // TileEntity.saveCustomOnly ; LevelReader.registryAccess + } + + @Override + public Object getFieldValue(Object nbt, String field) { + NBTTagCompound rec = (NBTTagCompound) nbt; + NBTBase val = rec.a(field); // NBTTagCompound.get + if(val == null) return null; + if(val instanceof NBTTagByte) { + return ((NBTTagByte)val).n(); // NBTTagByte.value + } + else if(val instanceof NBTTagShort) { + return ((NBTTagShort)val).n(); // NBTTagShort.value + } + else if(val instanceof NBTTagInt) { + return ((NBTTagInt)val).n(); // NBTTagInt.value + } + else if(val instanceof NBTTagLong) { + return ((NBTTagLong)val).n(); // NBTTagLong.value + } + else if(val instanceof NBTTagFloat) { + return ((NBTTagFloat)val).n(); // NBTTagFloat.value + } + else if(val instanceof NBTTagDouble) { + return ((NBTTagDouble)val).n(); // NBTTagDouble.value + } + else if(val instanceof NBTTagByteArray) { + return ((NBTTagByteArray)val).e(); // NBTTagByteArray.getAsByteArray + } + else if(val instanceof NBTTagString) { + return ((NBTTagString)val).k(); // NBTTagString.value + } + else if(val instanceof NBTTagIntArray) { + return ((NBTTagIntArray)val).g(); // NBTTagIntArray.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-5/src/main/java/org/dynmap/bukkit/helper/v121_5/MapChunkCache121_5.java b/bukkit-helper-121-5/src/main/java/org/dynmap/bukkit/helper/v121_5/MapChunkCache121_5.java new file mode 100644 index 000000000..3c5b48d39 --- /dev/null +++ b/bukkit-helper-121-5/src/main/java/org/dynmap/bukkit/helper/v121_5/MapChunkCache121_5.java @@ -0,0 +1,105 @@ +package org.dynmap.bukkit.helper.v121_5; + +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.Bukkit; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_21_R4.CraftServer; +import org.bukkit.craftbukkit.v1_21_R4.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.Optional; +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 MapChunkCache121_5 extends GenericMapChunkCache { + private World w; + /** + * Construct empty cache + */ + public MapChunkCache121_5(GenericChunkCache cc) { + super(cc); + } + + @Override + protected Supplier getLoadedChunkAsync(DynmapChunk chunk) { + CompletableFuture> chunkData = CompletableFuture.supplyAsync(() -> { + CraftWorld cw = (CraftWorld) w; + Chunk c = cw.getHandle().getChunkIfLoaded(chunk.x, chunk.z); + if (c == null || !c.q) { // !c.loaded + return Optional.empty(); + } + return Optional.of(SerializableChunkData.a(cw.getHandle(), c)); // SerializableChunkData.copyOf + }, ((CraftServer) Bukkit.getServer()).getServer()); + return () -> chunkData.join().map(SerializableChunkData::a).map(NBT.NBTCompound::new).map(this::parseChunkFromNBT).orElse(null); // SerializableChunkData::write + } + + 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; // LevelChunk.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; + } + + @Override + protected Supplier loadChunkAsync(DynmapChunk chunk) { + CraftWorld cw = (CraftWorld) w; + CompletableFuture> genericChunk = cw.getHandle().m().a.d(new ChunkCoordIntPair(chunk.x, chunk.z)); // WorldServer.getChunkSource().chunkMap.read(new ChunkCoordIntPair(chunk.x, chunk.z)) + return () -> genericChunk.join().map(NBT.NBTCompound::new).map(this::parseChunkFromNBT).orElse(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() // ServerLevel.getChunkSource + .a // ServerChunkCache.chunkMap + .d(cc) // ChunkStorage.read(ChunkPos) + .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::i).flatMap(BiomeFog::e).orElse(colormap[bm.biomeLookup()]); // BiomeBase::getSpecialEffects ; BiomeFog::getFoliageColorOverride + } + + @Override + public int getGrassColor(BiomeMap bm, int[] colormap, int x, int z) { + BiomeFog fog = bm.getBiomeObject().map(BiomeBase::i).orElse(null); // BiomeBase::getSpecialEffects + if (fog == null) return colormap[bm.biomeLookup()]; + return fog.h().a(x, z, fog.g().orElse(colormap[bm.biomeLookup()])); // BiomeFog.getGrassColorModifier.modifyColor ; BiomeFog.getGrassColorOverride + } +} diff --git a/bukkit-helper-121-5/src/main/java/org/dynmap/bukkit/helper/v121_5/NBT.java b/bukkit-helper-121-5/src/main/java/org/dynmap/bukkit/helper/v121_5/NBT.java new file mode 100644 index 000000000..6df501040 --- /dev/null +++ b/bukkit-helper-121-5/src/main/java/org/dynmap/bukkit/helper/v121_5/NBT.java @@ -0,0 +1,144 @@ +package org.dynmap.bukkit.helper.v121_5; + +import org.dynmap.common.chunk.GenericBitStorage; +import org.dynmap.common.chunk.GenericNBTCompound; +import org.dynmap.common.chunk.GenericNBTList; + +import java.util.Optional; +import java.util.Set; +import net.minecraft.nbt.NBTBase; +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(); // CompoundTag.keySet + } + @Override + public boolean contains(String s) { + return obj.b(s); // CompoundTag.contains + } + @Override + public boolean contains(String s, int i) { + // Like contains, but with an extra constraint on type + NBTBase base = obj.a(s); // CompoundTag.get + if (base == null) + return false; + byte type = base.b(); // CompoundTag.getId + if (type == i) + return true; + else if (i != TAG_ANY_NUMERIC) + return false; + return type == TAG_BYTE || type == TAG_SHORT || type == TAG_INT || type == TAG_LONG || type == TAG_FLOAT + || type == TAG_DOUBLE; + } + @Override + public byte getByte(String s) { + return obj.b(s, (byte)0); // CompoundTag.getByteOr + } + @Override + public short getShort(String s) { + return obj.b(s, (short)0); // CompoundTag.getShortOr + } + @Override + public int getInt(String s) { + return obj.b(s, 0); // CompoundTag.getIntOr + } + @Override + public long getLong(String s) { + return obj.b(s, 0L); // CompoundTag.getLongOr + } + @Override + public float getFloat(String s) { + return obj.b(s, 0.0f); // CompoundTag.getFloatOr + } + @Override + public double getDouble(String s) { + return obj.b(s, 0.0); // CompoundTag.getDoubleOr + } + @Override + public String getString(String s) { + return obj.b(s, ""); // CompoundTag.getDoubleOr + } + @Override + public byte[] getByteArray(String s) { + Optional byteArr = obj.j(s); // CompoundTag.getByteArray + return byteArr.orElseGet(() -> new byte[0]); + } + @Override + public int[] getIntArray(String s) { + Optional intArr = obj.k(s); // CompoundTag.getIntArray + return intArr.orElseGet(() -> new int[0]); + } + @Override + public long[] getLongArray(String s) { + Optional longArr = obj.l(s); // CompoundTag.getLongArray + return longArr.orElseGet(() -> new long[0]); + } + @Override + public GenericNBTCompound getCompound(String s) { + return new NBTCompound(obj.n(s)); // CompoundTag.getCompoundOrEmpty + } + @Override + public GenericNBTList getList(String s, int i) { + // i argument used to be used to constrain list type, but nbt lists no longer have types as of 1.21.5 + return new NBTList(obj.p(s)); // CompoundTag.getListOrEmpty + } + @Override + public boolean getBoolean(String s) { + return getByte(s) != 0; + } + @Override + public String getAsString(String s) { + return obj.a(s).p_().orElseGet(() -> ""); // CompoundTag.get ; Tag.asString + } + @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.a(idx, ""); // ListTag.getStringOr + } + @Override + public GenericNBTCompound getCompound(int idx) { + return new NBTCompound(obj.b(idx)); // ListTag.getCompoundOrEmpty + } + 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-6/.gitignore b/bukkit-helper-121-6/.gitignore new file mode 100644 index 000000000..84c048a73 --- /dev/null +++ b/bukkit-helper-121-6/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/bukkit-helper-121-6/build.gradle b/bukkit-helper-121-6/build.gradle new file mode 100644 index 000000000..e4aa9c39a --- /dev/null +++ b/bukkit-helper-121-6/build.gradle @@ -0,0 +1,19 @@ +eclipse { + project { + name = "Dynmap(Spigot-1.21.7)" + } +} + +description = 'bukkit-helper-1.21.7' + +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.7-R0.1-SNAPSHOT' + compileOnly ('org.spigotmc:spigot:1.21.7-R0.1-SNAPSHOT') { + exclude group: "com.mojang", module: "jtracy" + } +} diff --git a/bukkit-helper-121-6/src/main/java/org/dynmap/bukkit/helper/v121_6/BukkitVersionHelperSpigot121_6.java b/bukkit-helper-121-6/src/main/java/org/dynmap/bukkit/helper/v121_6/BukkitVersionHelperSpigot121_6.java new file mode 100644 index 000000000..7698789de --- /dev/null +++ b/bukkit-helper-121-6/src/main/java/org/dynmap/bukkit/helper/v121_6/BukkitVersionHelperSpigot121_6.java @@ -0,0 +1,450 @@ +package org.dynmap.bukkit.helper.v121_6; + +import org.bukkit.*; +import org.bukkit.craftbukkit.v1_21_R5.CraftChunk; +import org.bukkit.craftbukkit.v1_21_R5.CraftWorld; +import org.bukkit.craftbukkit.v1_21_R5.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_6 extends BukkitVersionHelper { + + @Override + public boolean isUnsafeAsync() { + return false; + } + + /** + * Get block short name list + */ + @Override + public String[] getBlockNames() { + RegistryBlockID bsids = Block.k; + 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().f(Registries.aK); + } + 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.k; + 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(); // BlockBehaviour$BlockStateBase.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.e()) { bld.setSolid(); } // BlockBehaviour$BlockStateBase.isSolid + if (bd.l()) { bld.setAir(); } // BlockBehaviour$BlockStateBase.isAir + if (bd.a(TagsBlock.an)) { bld.setLog(); } // BlockBehaviour$BlockStateBase.is(OVERWORLD_NATURAL_LOGS) + if (bd.a(TagsBlock.L)) { bld.setLeaves(); } // BlockBehaviour$BlockStateBase.is(LEAVES) + // BlockBehaviour$BlockStateBase.getFluidState.isEmpty(), BlockBehaviour$BlockStateBase.getBlock + if (!bd.y().c() && !(bd.b() instanceof BlockFluids)) { // 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_6 c = new MapChunkCache121_6(gencache); + c.setChunks(dw, chunks); + return c; + } + + /** + * Get biome base water multiplier + */ + @Override + public int getBiomeBaseWaterMult(Object bb) { + BiomeBase biome = (BiomeBase) bb; + return biome.j(); // Biome.getWaterColor + } + + /** Get temperature from biomebase */ + @Override + public float getBiomeBaseTemperature(Object bb) { + return ((BiomeBase)bb).h(); // Biome.getBaseTemperature + } + + /** Get humidity from biomebase */ + @Override + public float getBiomeBaseHumidity(Object bb) { + String vals = ((BiomeBase)bb).i.toString(); // Biome.climateSettings + 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, 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(); // MinecraftKey.getPath() + } + @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(); // ChunkStatus.FULL ; IChunkAccess.getInhabitedTime + } + + @Override + public Map getTileEntitiesForChunk(Chunk c) { + return ((CraftChunk)c).getHandle(ChunkStatus.n).k; // ChunkStatus.FULL ; IChunkAccess.blockEntities + } + + @Override + public int getTileEntityX(Object te) { + TileEntity tileent = (TileEntity) te; + return tileent.aA_().u(); // TileEntity.getBlockPos ; Vec3i.getX + } + + @Override + public int getTileEntityY(Object te) { + TileEntity tileent = (TileEntity) te; + return tileent.aA_().v(); // TileEntity.getBlockPos ; Vec3i.getY + } + + @Override + public int getTileEntityZ(Object te) { + TileEntity tileent = (TileEntity) te; + return tileent.aA_().w(); // TileEntity.getBlockPos ; Vec3i.getZ + } + + @Override + public Object readTileEntityNBT(Object te, World w) { + TileEntity tileent = (TileEntity) te; + CraftWorld cw = (CraftWorld) w; + return tileent.d(cw.getHandle().K_()); // TileEntity.saveCustomOnly ; LevelReader.registryAccess + } + + @Override + public Object getFieldValue(Object nbt, String field) { + NBTTagCompound rec = (NBTTagCompound) nbt; + NBTBase val = rec.a(field); // NBTTagCompound.get + if(val == null) return null; + if(val instanceof NBTTagByte) { + return ((NBTTagByte)val).n(); // NBTTagByte.value + } + else if(val instanceof NBTTagShort) { + return ((NBTTagShort)val).n(); // NBTTagShort.value + } + else if(val instanceof NBTTagInt) { + return ((NBTTagInt)val).n(); // NBTTagInt.value + } + else if(val instanceof NBTTagLong) { + return ((NBTTagLong)val).n(); // NBTTagLong.value + } + else if(val instanceof NBTTagFloat) { + return ((NBTTagFloat)val).n(); // NBTTagFloat.value + } + else if(val instanceof NBTTagDouble) { + return ((NBTTagDouble)val).n(); // NBTTagDouble.value + } + else if(val instanceof NBTTagByteArray) { + return ((NBTTagByteArray)val).e(); // NBTTagByteArray.getAsByteArray + } + else if(val instanceof NBTTagString) { + return ((NBTTagString)val).k(); // NBTTagString.value + } + else if(val instanceof NBTTagIntArray) { + return ((NBTTagIntArray)val).g(); // NBTTagIntArray.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-6/src/main/java/org/dynmap/bukkit/helper/v121_6/MapChunkCache121_6.java b/bukkit-helper-121-6/src/main/java/org/dynmap/bukkit/helper/v121_6/MapChunkCache121_6.java new file mode 100644 index 000000000..f49d7277e --- /dev/null +++ b/bukkit-helper-121-6/src/main/java/org/dynmap/bukkit/helper/v121_6/MapChunkCache121_6.java @@ -0,0 +1,105 @@ +package org.dynmap.bukkit.helper.v121_6; + +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.Bukkit; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_21_R5.CraftServer; +import org.bukkit.craftbukkit.v1_21_R5.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.Optional; +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 MapChunkCache121_6 extends GenericMapChunkCache { + private World w; + /** + * Construct empty cache + */ + public MapChunkCache121_6(GenericChunkCache cc) { + super(cc); + } + + @Override + protected Supplier getLoadedChunkAsync(DynmapChunk chunk) { + CompletableFuture> chunkData = CompletableFuture.supplyAsync(() -> { + CraftWorld cw = (CraftWorld) w; + Chunk c = cw.getHandle().getChunkIfLoaded(chunk.x, chunk.z); + if (c == null || !c.q) { // !c.loaded + return Optional.empty(); + } + return Optional.of(SerializableChunkData.a(cw.getHandle(), c)); // SerializableChunkData.copyOf + }, ((CraftServer) Bukkit.getServer()).getServer()); + return () -> chunkData.join().map(SerializableChunkData::a).map(NBT.NBTCompound::new).map(this::parseChunkFromNBT).orElse(null); // SerializableChunkData::write + } + + 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; // LevelChunk.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; + } + + @Override + protected Supplier loadChunkAsync(DynmapChunk chunk) { + CraftWorld cw = (CraftWorld) w; + CompletableFuture> genericChunk = cw.getHandle().n().a.d(new ChunkCoordIntPair(chunk.x, chunk.z)); // WorldServer.getChunkSource().chunkMap.read(new ChunkCoordIntPair(chunk.x, chunk.z)) + return () -> genericChunk.join().map(NBT.NBTCompound::new).map(this::parseChunkFromNBT).orElse(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() + .n() // ServerLevel.getChunkSource + .a // ServerChunkCache.chunkMap + .d(cc) // ChunkStorage.read(ChunkPos) + .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::i).flatMap(BiomeFog::e).orElse(colormap[bm.biomeLookup()]); // BiomeBase::getSpecialEffects ; BiomeFog::getFoliageColorOverride + } + + @Override + public int getGrassColor(BiomeMap bm, int[] colormap, int x, int z) { + BiomeFog fog = bm.getBiomeObject().map(BiomeBase::i).orElse(null); // BiomeBase::getSpecialEffects + if (fog == null) return colormap[bm.biomeLookup()]; + return fog.h().a(x, z, fog.g().orElse(colormap[bm.biomeLookup()])); // BiomeFog.getGrassColorModifier.modifyColor ; BiomeFog.getGrassColorOverride + } +} diff --git a/bukkit-helper-121-6/src/main/java/org/dynmap/bukkit/helper/v121_6/NBT.java b/bukkit-helper-121-6/src/main/java/org/dynmap/bukkit/helper/v121_6/NBT.java new file mode 100644 index 000000000..2c321c5ff --- /dev/null +++ b/bukkit-helper-121-6/src/main/java/org/dynmap/bukkit/helper/v121_6/NBT.java @@ -0,0 +1,144 @@ +package org.dynmap.bukkit.helper.v121_6; + +import org.dynmap.common.chunk.GenericBitStorage; +import org.dynmap.common.chunk.GenericNBTCompound; +import org.dynmap.common.chunk.GenericNBTList; + +import java.util.Optional; +import java.util.Set; +import net.minecraft.nbt.NBTBase; +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(); // CompoundTag.keySet + } + @Override + public boolean contains(String s) { + return obj.b(s); // CompoundTag.contains + } + @Override + public boolean contains(String s, int i) { + // Like contains, but with an extra constraint on type + NBTBase base = obj.a(s); // CompoundTag.get + if (base == null) + return false; + byte type = base.b(); // CompoundTag.getId + if (type == i) + return true; + else if (i != TAG_ANY_NUMERIC) + return false; + return type == TAG_BYTE || type == TAG_SHORT || type == TAG_INT || type == TAG_LONG || type == TAG_FLOAT + || type == TAG_DOUBLE; + } + @Override + public byte getByte(String s) { + return obj.b(s, (byte)0); // CompoundTag.getByteOr + } + @Override + public short getShort(String s) { + return obj.b(s, (short)0); // CompoundTag.getShortOr + } + @Override + public int getInt(String s) { + return obj.b(s, 0); // CompoundTag.getIntOr + } + @Override + public long getLong(String s) { + return obj.b(s, 0L); // CompoundTag.getLongOr + } + @Override + public float getFloat(String s) { + return obj.b(s, 0.0f); // CompoundTag.getFloatOr + } + @Override + public double getDouble(String s) { + return obj.b(s, 0.0); // CompoundTag.getDoubleOr + } + @Override + public String getString(String s) { + return obj.b(s, ""); // CompoundTag.getDoubleOr + } + @Override + public byte[] getByteArray(String s) { + Optional byteArr = obj.j(s); // CompoundTag.getByteArray + return byteArr.orElseGet(() -> new byte[0]); + } + @Override + public int[] getIntArray(String s) { + Optional intArr = obj.k(s); // CompoundTag.getIntArray + return intArr.orElseGet(() -> new int[0]); + } + @Override + public long[] getLongArray(String s) { + Optional longArr = obj.l(s); // CompoundTag.getLongArray + return longArr.orElseGet(() -> new long[0]); + } + @Override + public GenericNBTCompound getCompound(String s) { + return new NBTCompound(obj.n(s)); // CompoundTag.getCompoundOrEmpty + } + @Override + public GenericNBTList getList(String s, int i) { + // i argument used to be used to constrain list type, but nbt lists no longer have types as of 1.21.5 + return new NBTList(obj.p(s)); // CompoundTag.getListOrEmpty + } + @Override + public boolean getBoolean(String s) { + return getByte(s) != 0; + } + @Override + public String getAsString(String s) { + return obj.a(s).p_().orElseGet(() -> ""); // CompoundTag.get ; Tag.asString + } + @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.a(idx, ""); // ListTag.getStringOr + } + @Override + public GenericNBTCompound getCompound(int idx) { + return new NBTCompound(obj.b(idx)); // ListTag.getCompoundOrEmpty + } + 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.buildship.core.prefs b/bukkit-helper/.settings/org.eclipse.buildship.core.prefs index 15b2bc1a2..24ef279fc 100644 --- a/bukkit-helper/.settings/org.eclipse.buildship.core.prefs +++ b/bukkit-helper/.settings/org.eclipse.buildship.core.prefs @@ -2,7 +2,7 @@ arguments= auto.sync=false build.scans.enabled=false connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(6.3)) -connection.project.dir=../forge-1.21 +connection.project.dir=.. eclipse.preferences.version=1 gradle.user.home= java.home=/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home diff --git a/fabric-1.14.4/build.gradle b/fabric-1.14.4/build.gradle index b5bf304ec..d2c9b13e9 100644 --- a/fabric-1.14.4/build.gradle +++ b/fabric-1.14.4/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.9-SNAPSHOT' + id 'fabric-loom' version '1.13.6' } apply plugin: 'eclipse' diff --git a/fabric-1.15.2/build.gradle b/fabric-1.15.2/build.gradle index b3eb8ff72..c3b32a161 100644 --- a/fabric-1.15.2/build.gradle +++ b/fabric-1.15.2/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.9-SNAPSHOT' + id 'fabric-loom' version '1.13.6' } archivesBaseName = "Dynmap" diff --git a/fabric-1.16.4/build.gradle b/fabric-1.16.4/build.gradle index ff98556bc..e3a80ca46 100644 --- a/fabric-1.16.4/build.gradle +++ b/fabric-1.16.4/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.9-SNAPSHOT' + id 'fabric-loom' version '1.13.6' } archivesBaseName = "Dynmap" diff --git a/fabric-1.17.1/build.gradle b/fabric-1.17.1/build.gradle index 868cff37d..db7e77641 100644 --- a/fabric-1.17.1/build.gradle +++ b/fabric-1.17.1/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.9-SNAPSHOT' + id 'fabric-loom' version '1.13.6' } archivesBaseName = "Dynmap" diff --git a/fabric-1.18.2/build.gradle b/fabric-1.18.2/build.gradle index 4576b0ce5..48fada538 100644 --- a/fabric-1.18.2/build.gradle +++ b/fabric-1.18.2/build.gradle @@ -1,6 +1,6 @@ plugins { - id 'fabric-loom' version '1.9-SNAPSHOT' + id 'fabric-loom' version '1.13.6' } archivesBaseName = "Dynmap" @@ -35,7 +35,7 @@ dependencies { shadow project(path: ':DynmapCore', configuration: 'shadow') - modCompileOnly "me.lucko:fabric-permissions-api:0.1-SNAPSHOT" + modCompileOnly "me.lucko:fabric-permissions-api:0.4.0" compileOnly 'net.luckperms:api:5.4' } diff --git a/fabric-1.19.4/build.gradle b/fabric-1.19.4/build.gradle index c3fab0335..b3e71012a 100644 --- a/fabric-1.19.4/build.gradle +++ b/fabric-1.19.4/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.9-SNAPSHOT' + id 'fabric-loom' version '1.13.6' } archivesBaseName = "Dynmap" @@ -34,7 +34,7 @@ dependencies { shadow project(path: ':DynmapCore', configuration: 'shadow') - modCompileOnly "me.lucko:fabric-permissions-api:0.1-SNAPSHOT" + modCompileOnly "me.lucko:fabric-permissions-api:0.4.0" compileOnly 'net.luckperms:api:5.4' } diff --git a/fabric-1.20.6/build.gradle b/fabric-1.20.6/build.gradle index ef8a9b0e3..da0a1d0e2 100644 --- a/fabric-1.20.6/build.gradle +++ b/fabric-1.20.6/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.9-SNAPSHOT' + id 'fabric-loom' version '1.13.6' } archivesBaseName = "Dynmap" @@ -34,7 +34,7 @@ dependencies { shadow project(path: ':DynmapCore', configuration: 'shadow') - modCompileOnly "me.lucko:fabric-permissions-api:0.1-SNAPSHOT" + modCompileOnly "me.lucko:fabric-permissions-api:0.4.0" compileOnly 'net.luckperms:api:5.4' } diff --git a/fabric-1.21.1/gradle.properties b/fabric-1.21.1/gradle.properties deleted file mode 100644 index 5b783a33e..000000000 --- a/fabric-1.21.1/gradle.properties +++ /dev/null @@ -1,4 +0,0 @@ -minecraft_version=1.21.1 -yarn_mappings=1.21.1+build.3 -loader_version=0.15.11 -fabric_version=0.102.1+1.21.1 diff --git a/fabric-1.21.1/.gitignore b/fabric-1.21.11/.gitignore similarity index 100% rename from fabric-1.21.1/.gitignore rename to fabric-1.21.11/.gitignore diff --git a/fabric-1.21/build.gradle b/fabric-1.21.11/build.gradle similarity index 92% rename from fabric-1.21/build.gradle rename to fabric-1.21.11/build.gradle index cd51a9b01..06e02c7a0 100644 --- a/fabric-1.21/build.gradle +++ b/fabric-1.21.11/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.9-SNAPSHOT' + id 'fabric-loom' version '1.13.6' } archivesBaseName = "Dynmap" @@ -8,7 +8,7 @@ group = parent.group eclipse { project { - name = "Dynmap(Fabric-1.21)" + name = "Dynmap(Fabric-1.21.11)" } } @@ -34,7 +34,7 @@ dependencies { shadow project(path: ':DynmapCore', configuration: 'shadow') - modCompileOnly "me.lucko:fabric-permissions-api:0.1-SNAPSHOT" + modCompileOnly "me.lucko:fabric-permissions-api:0.5.0" compileOnly 'net.luckperms:api:5.4' } diff --git a/fabric-1.21.11/gradle.properties b/fabric-1.21.11/gradle.properties new file mode 100644 index 000000000..6e0e43834 --- /dev/null +++ b/fabric-1.21.11/gradle.properties @@ -0,0 +1,6 @@ +minecraft_version=1.21.11 + +# see https://fabricmc.net/develop/ +yarn_mappings=1.21.11+build.3 +loader_version=0.18.4 +fabric_version=0.140.2+1.21.11 diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/DynmapMod.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/DynmapMod.java similarity index 97% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/DynmapMod.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/DynmapMod.java index 8c2e3bef6..d4fbb6f91 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/DynmapMod.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/DynmapMod.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21; +package org.dynmap.fabric_1_21_11; import net.fabricmc.api.ModInitializer; import net.fabricmc.loader.api.FabricLoader; diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/DynmapPlugin.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/DynmapPlugin.java similarity index 96% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/DynmapPlugin.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/DynmapPlugin.java index b6f99fc5c..5e9141be5 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/DynmapPlugin.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/DynmapPlugin.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1; +package org.dynmap.fabric_1_21_11; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.exceptions.CommandSyntaxException; @@ -29,22 +29,22 @@ import net.minecraft.world.biome.Biome; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.ChunkSection; +import net.minecraft.client.color.world.BiomeColors; import org.dynmap.*; import org.dynmap.common.BiomeMap; import org.dynmap.common.DynmapCommandSender; import org.dynmap.common.DynmapListenerManager; import org.dynmap.common.DynmapPlayer; import org.dynmap.common.chunk.GenericChunkCache; -import org.dynmap.fabric_1_21_1.command.DmapCommand; -import org.dynmap.fabric_1_21_1.command.DmarkerCommand; -import org.dynmap.fabric_1_21_1.command.DynmapCommand; -import org.dynmap.fabric_1_21_1.command.DynmapExpCommand; -import org.dynmap.fabric_1_21_1.event.BlockEvents; -import org.dynmap.fabric_1_21_1.event.CustomServerChunkEvents; -import org.dynmap.fabric_1_21_1.event.CustomServerLifecycleEvents; -import org.dynmap.fabric_1_21_1.event.PlayerEvents; -import org.dynmap.fabric_1_21_1.mixin.BiomeEffectsAccessor; -import org.dynmap.fabric_1_21_1.permissions.*; +import org.dynmap.fabric_1_21_11.command.DmapCommand; +import org.dynmap.fabric_1_21_11.command.DmarkerCommand; +import org.dynmap.fabric_1_21_11.command.DynmapCommand; +import org.dynmap.fabric_1_21_11.command.DynmapExpCommand; +import org.dynmap.fabric_1_21_11.event.BlockEvents; +import org.dynmap.fabric_1_21_11.event.CustomServerChunkEvents; +import org.dynmap.fabric_1_21_11.event.CustomServerLifecycleEvents; +import org.dynmap.fabric_1_21_11.event.PlayerEvents; +import org.dynmap.fabric_1_21_11.permissions.*; import org.dynmap.permissions.PermissionsHandler; import org.dynmap.renderer.DynmapBlockState; @@ -163,7 +163,7 @@ public void initializeBlockStates() { } statename += p.getName() + "=" + bs.get(p).toString(); } - int lightAtten = bs.isOpaqueFullCube(EmptyBlockView.INSTANCE, BlockPos.ORIGIN) ? 15 : (bs.isTransparent(EmptyBlockView.INSTANCE, BlockPos.ORIGIN) ? 0 : 1); + int lightAtten = bs.isOpaqueFullCube() ? 15 : (bs.isTransparent() ? 0 : 1); //Log.info("statename=" + bn + "[" + statename + "], lightAtten=" + lightAtten); // Fill in base attributes bld.setBaseState(basebs).setStateIndex(idx - baseidx).setBlockName(bn).setStateName(statename).setLegacyBlockID(idx).setAttenuatesLight(lightAtten); @@ -259,7 +259,7 @@ public boolean isOp(String player) { } // TODO: Consider whether cheats are enabled for integrated server - return server.isSingleplayer() && server.isHost(server.getPlayerManager().getPlayer(player).getGameProfile()); + return server.isSingleplayer() && server.isHost(server.getPlayerManager().getPlayer(player).getPlayerConfigEntry()); } boolean hasPerm(PlayerEntity psender, String permission) { @@ -335,7 +335,7 @@ public void loadExtraBiomes(String mcver) { String id = biomeRegistry.getId(bb).getPath(); String rl = biomeRegistry.getId(bb).toString(); float tmp = bb.getTemperature(), hum = bb.weather.downfall(); - int watermult = ((BiomeEffectsAccessor) bb.getEffects()).getWaterColor(); + int watermult = bb.getWaterColor(); Log.verboseinfo("biome[" + i + "]: hum=" + hum + ", tmp=" + tmp + ", mult=" + Integer.toHexString(watermult)); BiomeMap bmap = BiomeMap.NULL; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricAdapter.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricAdapter.java similarity index 91% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricAdapter.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricAdapter.java index 3560e44d2..8a3ed05cd 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricAdapter.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricAdapter.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21; +package org.dynmap.fabric_1_21_11; import net.minecraft.server.world.ServerWorld; import org.dynmap.DynmapLocation; diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricCommandSender.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricCommandSender.java similarity index 96% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricCommandSender.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricCommandSender.java index c0dfbfa6a..2e590a780 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricCommandSender.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricCommandSender.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1; +package org.dynmap.fabric_1_21_11; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.text.Text; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricLogger.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricLogger.java similarity index 96% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricLogger.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricLogger.java index 1aed4d2c9..aaadead59 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricLogger.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricLogger.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3; +package org.dynmap.fabric_1_21_11; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricMapChunkCache.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricMapChunkCache.java similarity index 75% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricMapChunkCache.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricMapChunkCache.java index 0832c794e..c885f5840 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricMapChunkCache.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricMapChunkCache.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21; +package org.dynmap.fabric_1_21_11; import net.minecraft.nbt.*; import net.minecraft.server.world.ServerChunkLoadingManager; @@ -8,13 +8,14 @@ import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.WordPackedArray; -import net.minecraft.world.ChunkSerializer; import net.minecraft.world.World; import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.BiomeEffects; +import net.minecraft.client.color.world.BiomeColors; import net.minecraft.world.chunk.ChunkManager; import net.minecraft.world.chunk.ChunkStatus; - +import net.minecraft.world.chunk.SerializedChunk; +import org.dynmap.fabric_1_21_11.access.BiomeEffectsExt; import org.dynmap.DynmapChunk; import org.dynmap.DynmapCore; import org.dynmap.DynmapWorld; @@ -66,7 +67,8 @@ protected GenericChunk getLoadedChunk(DynmapChunk chunk) { if (cps.isChunkLoaded(chunk.x, chunk.z)) { NbtCompound nbt = null; try { - nbt = ChunkSerializer.serialize((ServerWorld) w, cps.getWorldChunk(chunk.x, chunk.z, false)); + SerializedChunk sc = SerializedChunk.fromChunk((ServerWorld) w, cps.getWorldChunk(chunk.x, chunk.z, false)); + nbt = sc.serialize(); } catch (NullPointerException e) { // TODO: find out why this is happening and why it only seems to happen since 1.16.2 Log.severe("ChunkSerializer.serialize threw a NullPointerException", e); @@ -104,13 +106,30 @@ protected GenericChunk loadChunk(DynmapChunk chunk) { @Override public int getFoliageColor(BiomeMap bm, int[] colormap, int x, int z) { - return bm.getBiomeObject().map(Biome::getEffects).flatMap(BiomeEffects::getFoliageColor).orElse(colormap[bm.biomeLookup()]); + return bm.getBiomeObject() + .map(Biome::getEffects) + .map(effects -> ((BiomeEffectsExt)(Object)effects) + .dynmap$getFoliageColor() + .orElse(colormap[bm.biomeLookup()])) + .orElse(colormap[bm.biomeLookup()]); } @Override public int getGrassColor(BiomeMap bm, int[] colormap, int x, int z) { - BiomeEffects effects = bm.getBiomeObject().map(Biome::getEffects).orElse(null); + BiomeEffects effects = bm.getBiomeObject() + .map(Biome::getEffects) + .orElse(null); + if (effects == null) return colormap[bm.biomeLookup()]; - return effects.getGrassColorModifier().getModifiedGrassColor(x, z, effects.getGrassColor().orElse(colormap[bm.biomeLookup()])); + + BiomeEffectsExt ext = (BiomeEffectsExt) (Object) effects; + + int baseColor = ext.dynmap$getGrassColor() + .orElse(colormap[bm.biomeLookup()]); + + BiomeEffects.GrassColorModifier modifier = ext.dynmap$getGrassColorModifier(); + if (modifier != null) return modifier.getModifiedGrassColor((double)x, (double)z, baseColor); + + return baseColor; } } diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricPlayer.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricPlayer.java similarity index 96% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricPlayer.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricPlayer.java index a6adce1f7..d1bff9322 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricPlayer.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricPlayer.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3; +package org.dynmap.fabric_1_21_11; import com.google.common.collect.Iterables; import com.google.gson.Gson; @@ -44,7 +44,7 @@ public FabricPlayer(DynmapPlugin plugin, ServerPlayerEntity player) { uuid = this.player.getUuid(); GameProfile prof = this.player.getGameProfile(); if (prof != null) { - Property textureProperty = Iterables.getFirst(prof.getProperties().get("textures"), null); + Property textureProperty = Iterables.getFirst(prof.properties().get("textures"), null); if (textureProperty != null) { DynmapPlugin.TexturesPayload result = null; @@ -99,8 +99,8 @@ public DynmapLocation getLocation() { return null; } - Vec3d pos = player.getPos(); - return FabricAdapter.toDynmapLocation(plugin, player.getServerWorld(), pos.getX(), pos.getY(), pos.getZ()); + // Vec3d pos = player.movement; + return FabricAdapter.toDynmapLocation(plugin, player.getEntityWorld(), player.getX(), player.getY(), player.getZ()); } @Override @@ -109,7 +109,7 @@ public String getWorld() { return null; } - World world = player.getWorld(); + World world = player.getEntityWorld(); if (world != null) { return plugin.getWorld(world).getName(); } diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricServer.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricServer.java similarity index 96% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricServer.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricServer.java index 0c02dbf43..356da962d 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricServer.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricServer.java @@ -1,6 +1,5 @@ -package org.dynmap.fabric_1_21; +package org.dynmap.fabric_1_21_11; -import com.mojang.authlib.GameProfile; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.ModContainer; import net.minecraft.block.AbstractSignBlock; @@ -14,6 +13,7 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.PlayerManager; import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.PlayerConfigEntry; import net.minecraft.text.Text; import net.minecraft.util.UserCache; import net.minecraft.util.Util; @@ -28,8 +28,8 @@ import org.dynmap.common.DynmapListenerManager; import org.dynmap.common.DynmapPlayer; import org.dynmap.common.DynmapServerInterface; -import org.dynmap.fabric_1_21.event.BlockEvents; -import org.dynmap.fabric_1_21.event.ServerChatEvents; +import org.dynmap.fabric_1_21_11.event.BlockEvents; +import org.dynmap.fabric_1_21_11.event.ServerChatEvents; import org.dynmap.utils.MapChunkCache; import org.dynmap.utils.VisibilityLimit; @@ -60,12 +60,11 @@ public class FabricServer extends DynmapServerInterface { public FabricServer(DynmapPlugin plugin, MinecraftServer server) { this.plugin = plugin; this.server = server; - this.biomeRegistry = server.getRegistryManager().get(RegistryKeys.BIOME); + this.biomeRegistry = server.getRegistryManager().getOrThrow(RegistryKeys.BIOME); } - private Optional getProfileByName(String player) { - UserCache cache = server.getUserCache(); - return cache.findByName(player); + private Optional getProfileByName(String playerName) { + return Optional.ofNullable(PlayerConfigEntry.fromNickname(playerName)); } public final Registry getBiomeRegistry() { @@ -202,12 +201,10 @@ public String getServerName() { public boolean isPlayerBanned(String pid) { PlayerManager scm = server.getPlayerManager(); BannedPlayerList bl = scm.getUserBanList(); - try { - return bl.contains(getProfileByName(pid).get()); - } catch (NoSuchElementException e) { - /* If this profile doesn't exist, default to "banned" for good measure. */ - return true; - } + + return getProfileByName(pid) + .map(profile -> bl.get(profile) != null) + .orElse(true); } @Override diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricWorld.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricWorld.java similarity index 98% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricWorld.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricWorld.java index 4f7cfa42c..238c7a711 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricWorld.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/FabricWorld.java @@ -1,7 +1,8 @@ -package org.dynmap.fabric_1_21_1; +package org.dynmap.fabric_1_21_11; import net.minecraft.registry.RegistryKey; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.WorldProperties.SpawnPoint; import net.minecraft.util.math.MathHelper; import net.minecraft.world.Heightmap; import net.minecraft.world.LightType; @@ -96,7 +97,7 @@ public boolean isTheEnd() { @Override public DynmapLocation getSpawnLocation() { if (world != null) { - BlockPos spawnPos = world.getLevelProperties().getSpawnPos(); + BlockPos spawnPos = world.getLevelProperties().getSpawnPoint().getPos().toImmutable(); spawnloc.x = spawnPos.getX(); spawnloc.y = spawnPos.getY(); spawnloc.z = spawnPos.getZ(); diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/NBT.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/NBT.java similarity index 65% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/NBT.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/NBT.java index 49ad8d914..4e236b21e 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/NBT.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/NBT.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21; +package org.dynmap.fabric_1_21_11; import org.dynmap.common.chunk.GenericBitStorage; import org.dynmap.common.chunk.GenericNBTCompound; @@ -6,6 +6,7 @@ import java.util.Set; import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtElement; import net.minecraft.nbt.NbtList; import net.minecraft.util.collection.PackedIntegerArray; @@ -26,63 +27,74 @@ public boolean contains(String s) { } @Override public boolean contains(String s, int i) { - return obj.contains(s, i); + // Like contains, but with an extra constraint on type + NbtElement base = obj.get(s); + if (base == null) + return false; + int type = base.getType(); + if (type == i) + return true; + else if (i != TAG_ANY_NUMERIC) + return false; + return type == TAG_BYTE || type == TAG_SHORT || type == TAG_INT || type == TAG_LONG || type == TAG_FLOAT + || type == TAG_DOUBLE; } @Override public byte getByte(String s) { - return obj.getByte(s); + return obj.getByte(s, (byte)0); } @Override public short getShort(String s) { - return obj.getShort(s); + return obj.getShort(s, (short)0); } @Override public int getInt(String s) { - return obj.getInt(s); + return obj.getInt(s, (int)0); } @Override public long getLong(String s) { - return obj.getLong(s); + return obj.getLong(s, (long)0); } @Override public float getFloat(String s) { - return obj.getFloat(s); + return obj.getFloat(s, (float)0); } @Override public double getDouble(String s) { - return obj.getDouble(s); + return obj.getDouble(s, (double)0); } @Override public String getString(String s) { - return obj.getString(s); + return obj.getString(s, ""); } @Override public byte[] getByteArray(String s) { - return obj.getByteArray(s); + return obj.getByteArray(s).orElseGet(() -> new byte[0]); } @Override public int[] getIntArray(String s) { - return obj.getIntArray(s); + return obj.getIntArray(s).orElseGet(() -> new int[0]); } @Override public long[] getLongArray(String s) { - return obj.getLongArray(s); + return obj.getLongArray(s).orElseGet(() -> new long[0]); } @Override public GenericNBTCompound getCompound(String s) { - return new NBTCompound(obj.getCompound(s)); + return new NBTCompound(obj.getCompoundOrEmpty(s)); } @Override public GenericNBTList getList(String s, int i) { - return new NBTList(obj.getList(s, i)); + // i argument used to be used to constrain list type, but nbt lists no longer have types as of 1.21.5 + return new NBTList(obj.getListOrEmpty(s)); } @Override public boolean getBoolean(String s) { - return obj.getBoolean(s); + return obj.getBoolean(s, false); } @Override public String getAsString(String s) { - return obj.get(s).asString(); + return obj.get(s).asString().orElse(""); } @Override public GenericBitStorage makeBitStorage(int bits, int count, long[] data) { @@ -103,11 +115,11 @@ public int size() { } @Override public String getString(int idx) { - return obj.getString(idx); + return obj.getString(idx, ""); } @Override public GenericNBTCompound getCompound(int idx) { - return new NBTCompound(obj.getCompound(idx)); + return new NBTCompound(obj.getCompoundOrEmpty(idx)); } public String toString() { return obj.toString(); diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/TaskRecord.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/TaskRecord.java similarity index 96% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/TaskRecord.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/TaskRecord.java index dc5c32957..4b179536d 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/TaskRecord.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/TaskRecord.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21; +package org.dynmap.fabric_1_21_11; import java.util.concurrent.FutureTask; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/VersionCheck.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/VersionCheck.java similarity index 99% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/VersionCheck.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/VersionCheck.java index 94a12f7ba..b4d3295ba 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/VersionCheck.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/VersionCheck.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21; +package org.dynmap.fabric_1_21_11; import org.dynmap.DynmapCore; import org.dynmap.Log; diff --git a/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/access/BiomeEffectsExt.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/access/BiomeEffectsExt.java new file mode 100644 index 000000000..b87052993 --- /dev/null +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/access/BiomeEffectsExt.java @@ -0,0 +1,12 @@ +package org.dynmap.fabric_1_21_11.access; +import java.util.Optional; +import net.minecraft.world.biome.BiomeEffects; +import java.util.OptionalInt; + +public interface BiomeEffectsExt { + int dynmap$getWaterColor(); + Optional dynmap$getFoliageColor(); + Optional dynmap$getDryFoliageColor(); + Optional dynmap$getGrassColor(); + BiomeEffects.GrassColorModifier dynmap$getGrassColorModifier(); +} \ No newline at end of file diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/access/ProtoChunkAccessor.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/access/ProtoChunkAccessor.java similarity index 64% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/access/ProtoChunkAccessor.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/access/ProtoChunkAccessor.java index fd2ad5fa9..21d94fced 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/access/ProtoChunkAccessor.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/access/ProtoChunkAccessor.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21.access; +package org.dynmap.fabric_1_21_11.access; public interface ProtoChunkAccessor { boolean getTouchedByWorldGen(); diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/command/DmapCommand.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/command/DmapCommand.java similarity index 59% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/command/DmapCommand.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/command/DmapCommand.java index 8510555ef..b1d9b28ef 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/command/DmapCommand.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/command/DmapCommand.java @@ -1,6 +1,6 @@ -package org.dynmap.fabric_1_21.command; +package org.dynmap.fabric_1_21_11.command; -import org.dynmap.fabric_1_21.DynmapPlugin; +import org.dynmap.fabric_1_21_11.DynmapPlugin; public class DmapCommand extends DynmapCommandExecutor { public DmapCommand(DynmapPlugin p) { diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/command/DmarkerCommand.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/command/DmarkerCommand.java similarity index 61% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/command/DmarkerCommand.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/command/DmarkerCommand.java index a6216335e..f6fe4eb88 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/command/DmarkerCommand.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/command/DmarkerCommand.java @@ -1,6 +1,6 @@ -package org.dynmap.fabric_1_21.command; +package org.dynmap.fabric_1_21_11.command; -import org.dynmap.fabric_1_21.DynmapPlugin; +import org.dynmap.fabric_1_21_11.DynmapPlugin; public class DmarkerCommand extends DynmapCommandExecutor { public DmarkerCommand(DynmapPlugin p) { diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/command/DynmapCommand.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/command/DynmapCommand.java similarity index 60% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/command/DynmapCommand.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/command/DynmapCommand.java index f92db84f2..2f764c2f2 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/command/DynmapCommand.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/command/DynmapCommand.java @@ -1,6 +1,6 @@ -package org.dynmap.fabric_1_21_1.command; +package org.dynmap.fabric_1_21_11.command; -import org.dynmap.fabric_1_21_1.DynmapPlugin; +import org.dynmap.fabric_1_21_11.DynmapPlugin; public class DynmapCommand extends DynmapCommandExecutor { public DynmapCommand(DynmapPlugin p) { diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/command/DynmapCommandExecutor.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/command/DynmapCommandExecutor.java similarity index 96% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/command/DynmapCommandExecutor.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/command/DynmapCommandExecutor.java index 56287a9aa..ec0614ed8 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/command/DynmapCommandExecutor.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/command/DynmapCommandExecutor.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3.command; +package org.dynmap.fabric_1_21_11.command; import com.mojang.brigadier.Command; import com.mojang.brigadier.CommandDispatcher; @@ -11,7 +11,7 @@ import java.util.Arrays; -import org.dynmap.fabric_1_21_3.DynmapPlugin; +import org.dynmap.fabric_1_21_11.DynmapPlugin; import static com.mojang.brigadier.arguments.StringArgumentType.greedyString; import static net.minecraft.server.command.CommandManager.argument; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/command/DynmapExpCommand.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/command/DynmapExpCommand.java similarity index 62% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/command/DynmapExpCommand.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/command/DynmapExpCommand.java index dee66a2c8..4c0276286 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/command/DynmapExpCommand.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/command/DynmapExpCommand.java @@ -1,6 +1,6 @@ -package org.dynmap.fabric_1_21_3.command; +package org.dynmap.fabric_1_21_11.command; -import org.dynmap.fabric_1_21_3.DynmapPlugin; +import org.dynmap.fabric_1_21_11.DynmapPlugin; public class DynmapExpCommand extends DynmapCommandExecutor { public DynmapExpCommand(DynmapPlugin p) { diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/event/BlockEvents.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/event/BlockEvents.java similarity index 97% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/event/BlockEvents.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/event/BlockEvents.java index 6cc117860..3d0193239 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/event/BlockEvents.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/event/BlockEvents.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21.event; +package org.dynmap.fabric_1_21_11.event; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/event/CustomServerChunkEvents.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/event/CustomServerChunkEvents.java similarity index 94% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/event/CustomServerChunkEvents.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/event/CustomServerChunkEvents.java index d9122c25a..7139764a1 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/event/CustomServerChunkEvents.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/event/CustomServerChunkEvents.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1.event; +package org.dynmap.fabric_1_21_11.event; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/event/CustomServerLifecycleEvents.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/event/CustomServerLifecycleEvents.java similarity index 93% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/event/CustomServerLifecycleEvents.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/event/CustomServerLifecycleEvents.java index f84666b29..f91d02aaa 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/event/CustomServerLifecycleEvents.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/event/CustomServerLifecycleEvents.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1.event; +package org.dynmap.fabric_1_21_11.event; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/event/PlayerEvents.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/event/PlayerEvents.java similarity index 98% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/event/PlayerEvents.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/event/PlayerEvents.java index dad913e05..b767be7fb 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/event/PlayerEvents.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/event/PlayerEvents.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21.event; +package org.dynmap.fabric_1_21_11.event; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/event/ServerChatEvents.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/event/ServerChatEvents.java similarity index 94% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/event/ServerChatEvents.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/event/ServerChatEvents.java index 8ab6989e8..9227ba07f 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/event/ServerChatEvents.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/event/ServerChatEvents.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3.event; +package org.dynmap.fabric_1_21_11.event; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; diff --git a/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/BiomeEffectsMixin.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/BiomeEffectsMixin.java new file mode 100644 index 000000000..0f6030dbc --- /dev/null +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/BiomeEffectsMixin.java @@ -0,0 +1,52 @@ +package org.dynmap.fabric_1_21_11.mixin; + +import net.minecraft.world.biome.BiomeEffects; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.dynmap.fabric_1_21_11.access.BiomeEffectsExt; +import java.util.Optional; + +@Mixin(BiomeEffects.class) +public class BiomeEffectsMixin implements BiomeEffectsExt { + + @Shadow private int waterColor; + @Shadow private Optional foliageColor; + @Shadow private Optional dryFoliageColor; + @Shadow private Optional grassColor; + @Shadow private BiomeEffects.GrassColorModifier grassColorModifier; + + private int dynmap$waterColor; + + @Inject(method = "", at = @At("RETURN")) + private void onInit(int waterColor, + Optional foliageColor, + Optional dryFoliageColor, + Optional grassColor, + BiomeEffects.GrassColorModifier grassColorModifier, + CallbackInfo ci) + { + this.dynmap$waterColor = waterColor; + } + + @Override + public int dynmap$getWaterColor() { + return dynmap$waterColor; + } + + @Override + public Optional dynmap$getFoliageColor() { return foliageColor; } + + @Override + public Optional dynmap$getDryFoliageColor() { return dryFoliageColor; } + + @Override + public Optional dynmap$getGrassColor() { return grassColor; } + + @Override + public BiomeEffects.GrassColorModifier dynmap$getGrassColorModifier() { + return grassColorModifier; + } +} diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/ChunkGeneratingMixin.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/ChunkGeneratingMixin.java similarity index 87% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/ChunkGeneratingMixin.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/ChunkGeneratingMixin.java index a48fbcdb2..f3110bfdc 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/ChunkGeneratingMixin.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/ChunkGeneratingMixin.java @@ -1,12 +1,12 @@ -package org.dynmap.fabric_1_21_1.mixin; +package org.dynmap.fabric_1_21_11.mixin; import net.minecraft.world.chunk.ChunkGenerating; import net.minecraft.world.chunk.ChunkGenerationContext; import net.minecraft.world.chunk.AbstractChunkHolder; import net.minecraft.world.chunk.Chunk; -import org.dynmap.fabric_1_21_1.access.ProtoChunkAccessor; -import org.dynmap.fabric_1_21_1.event.CustomServerChunkEvents; +import org.dynmap.fabric_1_21_11.access.ProtoChunkAccessor; +import org.dynmap.fabric_1_21_11.event.CustomServerChunkEvents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/MinecraftServerMixin.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/MinecraftServerMixin.java similarity index 83% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/MinecraftServerMixin.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/MinecraftServerMixin.java index 2b296eef5..3e39a21fd 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/MinecraftServerMixin.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/MinecraftServerMixin.java @@ -1,8 +1,8 @@ -package org.dynmap.fabric_1_21.mixin; +package org.dynmap.fabric_1_21_11.mixin; import net.minecraft.server.MinecraftServer; -import org.dynmap.fabric_1_21.event.CustomServerLifecycleEvents; +import org.dynmap.fabric_1_21_11.event.CustomServerLifecycleEvents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/PlayerManagerMixin.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/PlayerManagerMixin.java similarity index 93% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/PlayerManagerMixin.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/PlayerManagerMixin.java index c00d683f4..2c6bde8db 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/PlayerManagerMixin.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/PlayerManagerMixin.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3.mixin; +package org.dynmap.fabric_1_21_11.mixin; import net.minecraft.entity.Entity; import net.minecraft.network.ClientConnection; @@ -6,7 +6,7 @@ import net.minecraft.server.network.ConnectedClientData; import net.minecraft.server.network.ServerPlayerEntity; -import org.dynmap.fabric_1_21_3.event.PlayerEvents; +import org.dynmap.fabric_1_21_11.event.PlayerEvents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/ProtoChunkMixin.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/ProtoChunkMixin.java similarity index 80% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/ProtoChunkMixin.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/ProtoChunkMixin.java index 74822a58e..06e5ba01c 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/ProtoChunkMixin.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/ProtoChunkMixin.java @@ -1,10 +1,10 @@ -package org.dynmap.fabric_1_21_1.mixin; +package org.dynmap.fabric_1_21_11.mixin; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.world.chunk.ProtoChunk; -import org.dynmap.fabric_1_21_1.access.ProtoChunkAccessor; +import org.dynmap.fabric_1_21_11.access.ProtoChunkAccessor; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -21,7 +21,7 @@ public class ProtoChunkMixin implements ProtoChunkAccessor { target = "Lnet/minecraft/world/chunk/ChunkSection;setBlockState(IIILnet/minecraft/block/BlockState;)Lnet/minecraft/block/BlockState;" ) ) - public void setBlockState(BlockPos pos, BlockState state, boolean moved, CallbackInfoReturnable info) { + public void setBlockState(BlockPos pos, BlockState state, int flags, CallbackInfoReturnable info) { touchedByWorldGen = true; } diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/ServerPlayNetworkHandlerMixin.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/ServerPlayNetworkHandlerMixin.java similarity index 95% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/ServerPlayNetworkHandlerMixin.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/ServerPlayNetworkHandlerMixin.java index 4d9c853e2..08d74df1b 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/ServerPlayNetworkHandlerMixin.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/ServerPlayNetworkHandlerMixin.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3.mixin; +package org.dynmap.fabric_1_21_11.mixin; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; @@ -17,8 +17,8 @@ import java.util.Arrays; import java.util.List; -import org.dynmap.fabric_1_21_3.event.BlockEvents; -import org.dynmap.fabric_1_21_3.event.ServerChatEvents; +import org.dynmap.fabric_1_21_11.event.BlockEvents; +import org.dynmap.fabric_1_21_11.event.ServerChatEvents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/ServerPlayerEntityMixin.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/ServerPlayerEntityMixin.java similarity index 94% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/ServerPlayerEntityMixin.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/ServerPlayerEntityMixin.java index 62aa1d273..0324f1ede 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/ServerPlayerEntityMixin.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/ServerPlayerEntityMixin.java @@ -1,11 +1,11 @@ -package org.dynmap.fabric_1_21_3.mixin; +package org.dynmap.fabric_1_21_11.mixin; import net.minecraft.entity.Entity; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.world.TeleportTarget; -import org.dynmap.fabric_1_21_3.event.PlayerEvents; +import org.dynmap.fabric_1_21_11.event.PlayerEvents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/WorldChunkMixin.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/WorldChunkMixin.java similarity index 77% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/WorldChunkMixin.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/WorldChunkMixin.java index eb36a7987..77770fa28 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/WorldChunkMixin.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/mixin/WorldChunkMixin.java @@ -1,11 +1,11 @@ -package org.dynmap.fabric_1_21_3.mixin; +package org.dynmap.fabric_1_21_11.mixin; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.chunk.WorldChunk; -import org.dynmap.fabric_1_21_3.event.BlockEvents; +import org.dynmap.fabric_1_21_11.event.BlockEvents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -18,7 +18,7 @@ public abstract class WorldChunkMixin { public abstract World getWorld(); @Inject(method = "setBlockState", at = @At("RETURN")) - public void setBlockState(BlockPos pos, BlockState state, boolean moved, CallbackInfoReturnable info) { + public void setBlockState(BlockPos pos, BlockState state, int flags, CallbackInfoReturnable info) { if (info.getReturnValue() != null) { BlockEvents.BLOCK_EVENT.invoker().onBlockEvent(this.getWorld(), pos); } diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/permissions/FabricPermissions.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/permissions/FabricPermissions.java similarity index 93% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/permissions/FabricPermissions.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/permissions/FabricPermissions.java index 6e32ca7e5..77293e4a2 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/permissions/FabricPermissions.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/permissions/FabricPermissions.java @@ -1,9 +1,9 @@ -package org.dynmap.fabric_1_21_3.permissions; +package org.dynmap.fabric_1_21_11.permissions; import me.lucko.fabric.api.permissions.v0.Permissions; import net.minecraft.entity.player.PlayerEntity; import org.dynmap.Log; -import org.dynmap.fabric_1_21_3.DynmapPlugin; +import org.dynmap.fabric_1_21_11.DynmapPlugin; import org.dynmap.json.simple.parser.JSONParser; import java.util.Set; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/permissions/FilePermissions.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/permissions/FilePermissions.java similarity index 96% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/permissions/FilePermissions.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/permissions/FilePermissions.java index 7c2f0fd79..b0eacc083 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/permissions/FilePermissions.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/permissions/FilePermissions.java @@ -1,9 +1,9 @@ -package org.dynmap.fabric_1_21.permissions; +package org.dynmap.fabric_1_21_11.permissions; import net.minecraft.entity.player.PlayerEntity; import org.dynmap.ConfigurationNode; import org.dynmap.Log; -import org.dynmap.fabric_1_21.DynmapPlugin; +import org.dynmap.fabric_1_21_11.DynmapPlugin; import java.io.File; import java.util.HashMap; diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/permissions/LuckPermissions.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/permissions/LuckPermissions.java similarity index 97% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/permissions/LuckPermissions.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/permissions/LuckPermissions.java index 1a90bab2d..7fde17543 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/permissions/LuckPermissions.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/permissions/LuckPermissions.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1.permissions; +package org.dynmap.fabric_1_21_11.permissions; import me.lucko.fabric.api.permissions.v0.Permissions; import net.luckperms.api.LuckPerms; @@ -9,7 +9,7 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.MinecraftServer; import org.dynmap.Log; -import org.dynmap.fabric_1_21_1.DynmapPlugin; +import org.dynmap.fabric_1_21_11.DynmapPlugin; import org.dynmap.json.simple.JSONArray; import org.dynmap.json.simple.JSONObject; import org.dynmap.json.simple.parser.JSONParser; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/permissions/OpPermissions.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/permissions/OpPermissions.java similarity index 93% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/permissions/OpPermissions.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/permissions/OpPermissions.java index 444535613..a4bf39e7e 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/permissions/OpPermissions.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/permissions/OpPermissions.java @@ -1,8 +1,8 @@ -package org.dynmap.fabric_1_21.permissions; +package org.dynmap.fabric_1_21_11.permissions; import net.minecraft.entity.player.PlayerEntity; import org.dynmap.Log; -import org.dynmap.fabric_1_21.DynmapPlugin; +import org.dynmap.fabric_1_21_11.DynmapPlugin; import java.util.HashSet; import java.util.Set; diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/permissions/PermissionProvider.java b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/permissions/PermissionProvider.java similarity index 89% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/permissions/PermissionProvider.java rename to fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/permissions/PermissionProvider.java index fca16005b..4fb7522c5 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/permissions/PermissionProvider.java +++ b/fabric-1.21.11/src/main/java/org/dynmap/fabric_1_21_11/permissions/PermissionProvider.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1.permissions; +package org.dynmap.fabric_1_21_11.permissions; import net.minecraft.entity.player.PlayerEntity; diff --git a/fabric-1.21.1/src/main/resources/assets/dynmap/icon.png b/fabric-1.21.11/src/main/resources/assets/dynmap/icon.png similarity index 100% rename from fabric-1.21.1/src/main/resources/assets/dynmap/icon.png rename to fabric-1.21.11/src/main/resources/assets/dynmap/icon.png diff --git a/fabric-1.21.1/src/main/resources/configuration.txt b/fabric-1.21.11/src/main/resources/configuration.txt similarity index 100% rename from fabric-1.21.1/src/main/resources/configuration.txt rename to fabric-1.21.11/src/main/resources/configuration.txt diff --git a/fabric-1.21.1/src/main/resources/dynmap.accesswidener b/fabric-1.21.11/src/main/resources/dynmap.accesswidener similarity index 100% rename from fabric-1.21.1/src/main/resources/dynmap.accesswidener rename to fabric-1.21.11/src/main/resources/dynmap.accesswidener diff --git a/fabric-1.21/src/main/resources/dynmap.mixins.json b/fabric-1.21.11/src/main/resources/dynmap.mixins.json similarity index 73% rename from fabric-1.21/src/main/resources/dynmap.mixins.json rename to fabric-1.21.11/src/main/resources/dynmap.mixins.json index 36f345b06..6790f8e1b 100644 --- a/fabric-1.21/src/main/resources/dynmap.mixins.json +++ b/fabric-1.21.11/src/main/resources/dynmap.mixins.json @@ -1,10 +1,10 @@ { "required": true, "minVersion": "0.8", - "package": "org.dynmap.fabric_1_21.mixin", - "compatibilityLevel": "JAVA_17", + "package": "org.dynmap.fabric_1_21_11.mixin", + "compatibilityLevel": "JAVA_21", "mixins": [ - "BiomeEffectsAccessor", + "BiomeEffectsMixin", "ChunkGeneratingMixin", "MinecraftServerMixin", "PlayerManagerMixin", diff --git a/fabric-1.21.1/src/main/resources/fabric.mod.json b/fabric-1.21.11/src/main/resources/fabric.mod.json similarity index 78% rename from fabric-1.21.1/src/main/resources/fabric.mod.json rename to fabric-1.21.11/src/main/resources/fabric.mod.json index 8c1cca87d..26cfc2f40 100644 --- a/fabric-1.21.1/src/main/resources/fabric.mod.json +++ b/fabric-1.21.11/src/main/resources/fabric.mod.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "id": "dynmap", - "version": "${version}", + "version": "3.4.0-beta-1", "name": "Dynmap", "description": "Dynamic, Google-maps style rendered maps for your Minecraft server", "authors": [ @@ -18,7 +18,7 @@ "environment": "*", "entrypoints": { "main": [ - "org.dynmap.fabric_1_21_1.DynmapMod" + "org.dynmap.fabric_1_21_11.DynmapMod" ] }, "mixins": [ @@ -27,8 +27,8 @@ "accessWidener" : "dynmap.accesswidener", "depends": { - "fabricloader": ">=0.15.11", - "fabric": ">=0.102.0", - "minecraft": ["1.21.1"] + "fabricloader": ">=0.18.2", + "fabric": ">=0.139.4", + "minecraft": ["1.21.11"] } } diff --git a/fabric-1.21.1/src/main/resources/permissions.yml.example b/fabric-1.21.11/src/main/resources/permissions.yml.example similarity index 100% rename from fabric-1.21.1/src/main/resources/permissions.yml.example rename to fabric-1.21.11/src/main/resources/permissions.yml.example diff --git a/fabric-1.21.3/gradle.properties b/fabric-1.21.3/gradle.properties deleted file mode 100644 index 17faf67f4..000000000 --- a/fabric-1.21.3/gradle.properties +++ /dev/null @@ -1,4 +0,0 @@ -minecraft_version=1.21.3 -yarn_mappings=1.21.3+build.1 -loader_version=0.16.9 -fabric_version=0.108.0+1.21.3 diff --git a/fabric-1.21.3/.gitignore b/fabric-1.21.6/.gitignore similarity index 100% rename from fabric-1.21.3/.gitignore rename to fabric-1.21.6/.gitignore diff --git a/fabric-1.21.1/build.gradle b/fabric-1.21.6/build.gradle similarity index 92% rename from fabric-1.21.1/build.gradle rename to fabric-1.21.6/build.gradle index e54424d89..bce1c28d2 100644 --- a/fabric-1.21.1/build.gradle +++ b/fabric-1.21.6/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.9-SNAPSHOT' + id 'fabric-loom' version '1.13.6' } archivesBaseName = "Dynmap" @@ -8,7 +8,7 @@ group = parent.group eclipse { project { - name = "Dynmap(Fabric-1.21.1)" + name = "Dynmap(Fabric-1.21.6)" } } @@ -34,7 +34,7 @@ dependencies { shadow project(path: ':DynmapCore', configuration: 'shadow') - modCompileOnly "me.lucko:fabric-permissions-api:0.1-SNAPSHOT" + modCompileOnly "me.lucko:fabric-permissions-api:0.4.0" compileOnly 'net.luckperms:api:5.4' } diff --git a/fabric-1.21.6/gradle.properties b/fabric-1.21.6/gradle.properties new file mode 100644 index 000000000..fea2c1bf6 --- /dev/null +++ b/fabric-1.21.6/gradle.properties @@ -0,0 +1,6 @@ +minecraft_version=1.21.6 + +# see https://fabricmc.net/develop/ +yarn_mappings=1.21.6+build.1 +loader_version=0.16.14 +fabric_version=0.128.2+1.21.6 diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/DynmapMod.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/DynmapMod.java similarity index 98% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/DynmapMod.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/DynmapMod.java index 4ce880463..670cb2d60 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/DynmapMod.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/DynmapMod.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3; +package org.dynmap.fabric_1_21_7; import net.fabricmc.api.ModInitializer; import net.fabricmc.loader.api.FabricLoader; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/DynmapPlugin.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/DynmapPlugin.java similarity index 98% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/DynmapPlugin.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/DynmapPlugin.java index 2f1700e67..d95fb9e59 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/DynmapPlugin.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/DynmapPlugin.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3; +package org.dynmap.fabric_1_21_7; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.exceptions.CommandSyntaxException; @@ -35,16 +35,16 @@ import org.dynmap.common.DynmapListenerManager; import org.dynmap.common.DynmapPlayer; import org.dynmap.common.chunk.GenericChunkCache; -import org.dynmap.fabric_1_21_3.command.DmapCommand; -import org.dynmap.fabric_1_21_3.command.DmarkerCommand; -import org.dynmap.fabric_1_21_3.command.DynmapCommand; -import org.dynmap.fabric_1_21_3.command.DynmapExpCommand; -import org.dynmap.fabric_1_21_3.event.BlockEvents; -import org.dynmap.fabric_1_21_3.event.CustomServerChunkEvents; -import org.dynmap.fabric_1_21_3.event.CustomServerLifecycleEvents; -import org.dynmap.fabric_1_21_3.event.PlayerEvents; -import org.dynmap.fabric_1_21_3.mixin.BiomeEffectsAccessor; -import org.dynmap.fabric_1_21_3.permissions.*; +import org.dynmap.fabric_1_21_7.command.DmapCommand; +import org.dynmap.fabric_1_21_7.command.DmarkerCommand; +import org.dynmap.fabric_1_21_7.command.DynmapCommand; +import org.dynmap.fabric_1_21_7.command.DynmapExpCommand; +import org.dynmap.fabric_1_21_7.event.BlockEvents; +import org.dynmap.fabric_1_21_7.event.CustomServerChunkEvents; +import org.dynmap.fabric_1_21_7.event.CustomServerLifecycleEvents; +import org.dynmap.fabric_1_21_7.event.PlayerEvents; +import org.dynmap.fabric_1_21_7.mixin.BiomeEffectsAccessor; +import org.dynmap.fabric_1_21_7.permissions.*; import org.dynmap.permissions.PermissionsHandler; import org.dynmap.renderer.DynmapBlockState; diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricAdapter.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricAdapter.java similarity index 91% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricAdapter.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricAdapter.java index ad444547e..1c32eb5ae 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricAdapter.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricAdapter.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1; +package org.dynmap.fabric_1_21_7; import net.minecraft.server.world.ServerWorld; import org.dynmap.DynmapLocation; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricCommandSender.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricCommandSender.java similarity index 96% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricCommandSender.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricCommandSender.java index 5616d9f69..8ae55cd32 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricCommandSender.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricCommandSender.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21; +package org.dynmap.fabric_1_21_7; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.text.Text; diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricLogger.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricLogger.java similarity index 96% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricLogger.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricLogger.java index 6fab5556a..2d0900cb9 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricLogger.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricLogger.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1; +package org.dynmap.fabric_1_21_7; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricMapChunkCache.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricMapChunkCache.java similarity index 99% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricMapChunkCache.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricMapChunkCache.java index 8847b5be6..62b8d5ccb 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricMapChunkCache.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricMapChunkCache.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3; +package org.dynmap.fabric_1_21_7; import net.minecraft.nbt.*; import net.minecraft.server.world.ServerChunkLoadingManager; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricPlayer.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricPlayer.java similarity index 98% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricPlayer.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricPlayer.java index f026ec674..2551de862 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricPlayer.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricPlayer.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21; +package org.dynmap.fabric_1_21_7; import com.google.common.collect.Iterables; import com.google.gson.Gson; @@ -100,7 +100,7 @@ public DynmapLocation getLocation() { } Vec3d pos = player.getPos(); - return FabricAdapter.toDynmapLocation(plugin, player.getServerWorld(), pos.getX(), pos.getY(), pos.getZ()); + return FabricAdapter.toDynmapLocation(plugin, player.getWorld(), pos.getX(), pos.getY(), pos.getZ()); } @Override diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricServer.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricServer.java similarity index 99% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricServer.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricServer.java index 91316b9ac..ebf4e455a 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricServer.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricServer.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3; +package org.dynmap.fabric_1_21_7; import com.mojang.authlib.GameProfile; import net.fabricmc.loader.api.FabricLoader; @@ -28,8 +28,8 @@ import org.dynmap.common.DynmapListenerManager; import org.dynmap.common.DynmapPlayer; import org.dynmap.common.DynmapServerInterface; -import org.dynmap.fabric_1_21_3.event.BlockEvents; -import org.dynmap.fabric_1_21_3.event.ServerChatEvents; +import org.dynmap.fabric_1_21_7.event.BlockEvents; +import org.dynmap.fabric_1_21_7.event.ServerChatEvents; import org.dynmap.utils.MapChunkCache; import org.dynmap.utils.VisibilityLimit; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricWorld.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricWorld.java similarity index 99% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricWorld.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricWorld.java index e0ded7543..b5378d25f 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricWorld.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/FabricWorld.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21; +package org.dynmap.fabric_1_21_7; import net.minecraft.registry.RegistryKey; import net.minecraft.util.math.BlockPos; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/NBT.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/NBT.java similarity index 65% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/NBT.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/NBT.java index 47b27c8f2..e98109acd 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/NBT.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/NBT.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3; +package org.dynmap.fabric_1_21_7; import org.dynmap.common.chunk.GenericBitStorage; import org.dynmap.common.chunk.GenericNBTCompound; @@ -6,6 +6,7 @@ import java.util.Set; import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtElement; import net.minecraft.nbt.NbtList; import net.minecraft.util.collection.PackedIntegerArray; @@ -26,63 +27,74 @@ public boolean contains(String s) { } @Override public boolean contains(String s, int i) { - return obj.contains(s, i); + // Like contains, but with an extra constraint on type + NbtElement base = obj.get(s); + if (base == null) + return false; + int type = base.getType(); + if (type == i) + return true; + else if (i != TAG_ANY_NUMERIC) + return false; + return type == TAG_BYTE || type == TAG_SHORT || type == TAG_INT || type == TAG_LONG || type == TAG_FLOAT + || type == TAG_DOUBLE; } @Override public byte getByte(String s) { - return obj.getByte(s); + return obj.getByte(s, (byte)0); } @Override public short getShort(String s) { - return obj.getShort(s); + return obj.getShort(s, (short)0); } @Override public int getInt(String s) { - return obj.getInt(s); + return obj.getInt(s, (int)0); } @Override public long getLong(String s) { - return obj.getLong(s); + return obj.getLong(s, (long)0); } @Override public float getFloat(String s) { - return obj.getFloat(s); + return obj.getFloat(s, (float)0); } @Override public double getDouble(String s) { - return obj.getDouble(s); + return obj.getDouble(s, (double)0); } @Override public String getString(String s) { - return obj.getString(s); + return obj.getString(s, ""); } @Override public byte[] getByteArray(String s) { - return obj.getByteArray(s); + return obj.getByteArray(s).orElseGet(() -> new byte[0]); } @Override public int[] getIntArray(String s) { - return obj.getIntArray(s); + return obj.getIntArray(s).orElseGet(() -> new int[0]); } @Override public long[] getLongArray(String s) { - return obj.getLongArray(s); + return obj.getLongArray(s).orElseGet(() -> new long[0]); } @Override public GenericNBTCompound getCompound(String s) { - return new NBTCompound(obj.getCompound(s)); + return new NBTCompound(obj.getCompoundOrEmpty(s)); } @Override public GenericNBTList getList(String s, int i) { - return new NBTList(obj.getList(s, i)); + // i argument used to be used to constrain list type, but nbt lists no longer have types as of 1.21.5 + return new NBTList(obj.getListOrEmpty(s)); } @Override public boolean getBoolean(String s) { - return obj.getBoolean(s); + return obj.getBoolean(s, false); } @Override public String getAsString(String s) { - return obj.get(s).asString(); + return obj.get(s).asString().orElse(""); } @Override public GenericBitStorage makeBitStorage(int bits, int count, long[] data) { @@ -103,11 +115,11 @@ public int size() { } @Override public String getString(int idx) { - return obj.getString(idx); + return obj.getString(idx, ""); } @Override public GenericNBTCompound getCompound(int idx) { - return new NBTCompound(obj.getCompound(idx)); + return new NBTCompound(obj.getCompoundOrEmpty(idx)); } public String toString() { return obj.toString(); diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/TaskRecord.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/TaskRecord.java similarity index 96% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/TaskRecord.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/TaskRecord.java index 7ad620128..30bf611f5 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/TaskRecord.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/TaskRecord.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3; +package org.dynmap.fabric_1_21_7; import java.util.concurrent.FutureTask; diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/VersionCheck.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/VersionCheck.java similarity index 99% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/VersionCheck.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/VersionCheck.java index a029690a3..92c87281d 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/VersionCheck.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/VersionCheck.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1; +package org.dynmap.fabric_1_21_7; import org.dynmap.DynmapCore; import org.dynmap.Log; diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/access/ProtoChunkAccessor.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/access/ProtoChunkAccessor.java similarity index 65% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/access/ProtoChunkAccessor.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/access/ProtoChunkAccessor.java index 6ecb5becf..acad7fb10 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/access/ProtoChunkAccessor.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/access/ProtoChunkAccessor.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1.access; +package org.dynmap.fabric_1_21_7.access; public interface ProtoChunkAccessor { boolean getTouchedByWorldGen(); diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/command/DmapCommand.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/command/DmapCommand.java similarity index 60% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/command/DmapCommand.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/command/DmapCommand.java index 819bad0cf..ecc331983 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/command/DmapCommand.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/command/DmapCommand.java @@ -1,6 +1,6 @@ -package org.dynmap.fabric_1_21_3.command; +package org.dynmap.fabric_1_21_7.command; -import org.dynmap.fabric_1_21_3.DynmapPlugin; +import org.dynmap.fabric_1_21_7.DynmapPlugin; public class DmapCommand extends DynmapCommandExecutor { public DmapCommand(DynmapPlugin p) { diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/command/DmarkerCommand.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/command/DmarkerCommand.java similarity index 61% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/command/DmarkerCommand.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/command/DmarkerCommand.java index 438908458..c571a921b 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/command/DmarkerCommand.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/command/DmarkerCommand.java @@ -1,6 +1,6 @@ -package org.dynmap.fabric_1_21_3.command; +package org.dynmap.fabric_1_21_7.command; -import org.dynmap.fabric_1_21_3.DynmapPlugin; +import org.dynmap.fabric_1_21_7.DynmapPlugin; public class DmarkerCommand extends DynmapCommandExecutor { public DmarkerCommand(DynmapPlugin p) { diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/command/DynmapCommand.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/command/DynmapCommand.java similarity index 61% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/command/DynmapCommand.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/command/DynmapCommand.java index c9180f374..e5ad39ae1 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/command/DynmapCommand.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/command/DynmapCommand.java @@ -1,6 +1,6 @@ -package org.dynmap.fabric_1_21.command; +package org.dynmap.fabric_1_21_7.command; -import org.dynmap.fabric_1_21.DynmapPlugin; +import org.dynmap.fabric_1_21_7.DynmapPlugin; public class DynmapCommand extends DynmapCommandExecutor { public DynmapCommand(DynmapPlugin p) { diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/command/DynmapCommandExecutor.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/command/DynmapCommandExecutor.java similarity index 96% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/command/DynmapCommandExecutor.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/command/DynmapCommandExecutor.java index 702edd8ca..fd1d8c51d 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/command/DynmapCommandExecutor.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/command/DynmapCommandExecutor.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21.command; +package org.dynmap.fabric_1_21_7.command; import com.mojang.brigadier.Command; import com.mojang.brigadier.CommandDispatcher; @@ -11,7 +11,7 @@ import java.util.Arrays; -import org.dynmap.fabric_1_21.DynmapPlugin; +import org.dynmap.fabric_1_21_7.DynmapPlugin; import static com.mojang.brigadier.arguments.StringArgumentType.greedyString; import static net.minecraft.server.command.CommandManager.argument; diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/command/DynmapExpCommand.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/command/DynmapExpCommand.java similarity index 62% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/command/DynmapExpCommand.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/command/DynmapExpCommand.java index 7daaab757..b2210b230 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/command/DynmapExpCommand.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/command/DynmapExpCommand.java @@ -1,6 +1,6 @@ -package org.dynmap.fabric_1_21_1.command; +package org.dynmap.fabric_1_21_7.command; -import org.dynmap.fabric_1_21_1.DynmapPlugin; +import org.dynmap.fabric_1_21_7.DynmapPlugin; public class DynmapExpCommand extends DynmapCommandExecutor { public DynmapExpCommand(DynmapPlugin p) { diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/event/BlockEvents.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/event/BlockEvents.java similarity index 97% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/event/BlockEvents.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/event/BlockEvents.java index 538e8335f..14cb0cbfc 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/event/BlockEvents.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/event/BlockEvents.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1.event; +package org.dynmap.fabric_1_21_7.event; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/event/CustomServerChunkEvents.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/event/CustomServerChunkEvents.java similarity index 94% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/event/CustomServerChunkEvents.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/event/CustomServerChunkEvents.java index bb661c916..02c8efabb 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/event/CustomServerChunkEvents.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/event/CustomServerChunkEvents.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3.event; +package org.dynmap.fabric_1_21_7.event; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/event/CustomServerLifecycleEvents.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/event/CustomServerLifecycleEvents.java similarity index 93% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/event/CustomServerLifecycleEvents.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/event/CustomServerLifecycleEvents.java index 46f028048..f1e49232b 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/event/CustomServerLifecycleEvents.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/event/CustomServerLifecycleEvents.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21.event; +package org.dynmap.fabric_1_21_7.event; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/event/PlayerEvents.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/event/PlayerEvents.java similarity index 98% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/event/PlayerEvents.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/event/PlayerEvents.java index fb4d6976a..91dc059ef 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/event/PlayerEvents.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/event/PlayerEvents.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1.event; +package org.dynmap.fabric_1_21_7.event; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/event/ServerChatEvents.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/event/ServerChatEvents.java similarity index 94% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/event/ServerChatEvents.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/event/ServerChatEvents.java index aff1d72e4..63783ffa5 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/event/ServerChatEvents.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/event/ServerChatEvents.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1.event; +package org.dynmap.fabric_1_21_7.event; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/BiomeEffectsAccessor.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/BiomeEffectsAccessor.java similarity index 86% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/BiomeEffectsAccessor.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/BiomeEffectsAccessor.java index a083db0b7..9fe749792 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/BiomeEffectsAccessor.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/BiomeEffectsAccessor.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1.mixin; +package org.dynmap.fabric_1_21_7.mixin; import net.minecraft.world.biome.BiomeEffects; import org.spongepowered.asm.mixin.Mixin; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/ChunkGeneratingMixin.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/ChunkGeneratingMixin.java similarity index 87% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/ChunkGeneratingMixin.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/ChunkGeneratingMixin.java index 9355f2b91..2449b3d3e 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/ChunkGeneratingMixin.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/ChunkGeneratingMixin.java @@ -1,12 +1,12 @@ -package org.dynmap.fabric_1_21_3.mixin; +package org.dynmap.fabric_1_21_7.mixin; import net.minecraft.world.chunk.ChunkGenerating; import net.minecraft.world.chunk.ChunkGenerationContext; import net.minecraft.world.chunk.AbstractChunkHolder; import net.minecraft.world.chunk.Chunk; -import org.dynmap.fabric_1_21_3.access.ProtoChunkAccessor; -import org.dynmap.fabric_1_21_3.event.CustomServerChunkEvents; +import org.dynmap.fabric_1_21_7.access.ProtoChunkAccessor; +import org.dynmap.fabric_1_21_7.event.CustomServerChunkEvents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/MinecraftServerMixin.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/MinecraftServerMixin.java similarity index 84% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/MinecraftServerMixin.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/MinecraftServerMixin.java index 5059403a2..72a28617c 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/MinecraftServerMixin.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/MinecraftServerMixin.java @@ -1,8 +1,8 @@ -package org.dynmap.fabric_1_21_3.mixin; +package org.dynmap.fabric_1_21_7.mixin; import net.minecraft.server.MinecraftServer; -import org.dynmap.fabric_1_21_3.event.CustomServerLifecycleEvents; +import org.dynmap.fabric_1_21_7.event.CustomServerLifecycleEvents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/PlayerManagerMixin.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/PlayerManagerMixin.java similarity index 93% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/PlayerManagerMixin.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/PlayerManagerMixin.java index aabd196ba..ad59d77af 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/PlayerManagerMixin.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/PlayerManagerMixin.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21.mixin; +package org.dynmap.fabric_1_21_7.mixin; import net.minecraft.entity.Entity; import net.minecraft.network.ClientConnection; @@ -6,7 +6,7 @@ import net.minecraft.server.network.ConnectedClientData; import net.minecraft.server.network.ServerPlayerEntity; -import org.dynmap.fabric_1_21.event.PlayerEvents; +import org.dynmap.fabric_1_21_7.event.PlayerEvents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/ProtoChunkMixin.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/ProtoChunkMixin.java similarity index 80% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/ProtoChunkMixin.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/ProtoChunkMixin.java index d6a22196c..3079a4ece 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/ProtoChunkMixin.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/ProtoChunkMixin.java @@ -1,10 +1,10 @@ -package org.dynmap.fabric_1_21.mixin; +package org.dynmap.fabric_1_21_7.mixin; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.world.chunk.ProtoChunk; -import org.dynmap.fabric_1_21.access.ProtoChunkAccessor; +import org.dynmap.fabric_1_21_7.access.ProtoChunkAccessor; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -21,11 +21,11 @@ public class ProtoChunkMixin implements ProtoChunkAccessor { target = "Lnet/minecraft/world/chunk/ChunkSection;setBlockState(IIILnet/minecraft/block/BlockState;)Lnet/minecraft/block/BlockState;" ) ) - public void setBlockState(BlockPos pos, BlockState state, boolean moved, CallbackInfoReturnable info) { + public void setBlockState(BlockPos pos, BlockState state, int flags, CallbackInfoReturnable info) { touchedByWorldGen = true; } public boolean getTouchedByWorldGen() { return touchedByWorldGen; } -} \ No newline at end of file +} diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/ServerPlayNetworkHandlerMixin.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/ServerPlayNetworkHandlerMixin.java similarity index 95% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/ServerPlayNetworkHandlerMixin.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/ServerPlayNetworkHandlerMixin.java index 7f625df25..2833ef2af 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/ServerPlayNetworkHandlerMixin.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/ServerPlayNetworkHandlerMixin.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1.mixin; +package org.dynmap.fabric_1_21_7.mixin; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; @@ -17,8 +17,8 @@ import java.util.Arrays; import java.util.List; -import org.dynmap.fabric_1_21_1.event.BlockEvents; -import org.dynmap.fabric_1_21_1.event.ServerChatEvents; +import org.dynmap.fabric_1_21_7.event.BlockEvents; +import org.dynmap.fabric_1_21_7.event.ServerChatEvents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/ServerPlayerEntityMixin.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/ServerPlayerEntityMixin.java similarity index 94% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/ServerPlayerEntityMixin.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/ServerPlayerEntityMixin.java index 82fc9b5fa..bd701a0c8 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/ServerPlayerEntityMixin.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/ServerPlayerEntityMixin.java @@ -1,11 +1,11 @@ -package org.dynmap.fabric_1_21.mixin; +package org.dynmap.fabric_1_21_7.mixin; import net.minecraft.entity.Entity; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.world.TeleportTarget; -import org.dynmap.fabric_1_21.event.PlayerEvents; +import org.dynmap.fabric_1_21_7.event.PlayerEvents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/WorldChunkMixin.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/WorldChunkMixin.java similarity index 78% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/WorldChunkMixin.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/WorldChunkMixin.java index af289d7f9..12fd5f9df 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/WorldChunkMixin.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/mixin/WorldChunkMixin.java @@ -1,11 +1,11 @@ -package org.dynmap.fabric_1_21.mixin; +package org.dynmap.fabric_1_21_7.mixin; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.chunk.WorldChunk; -import org.dynmap.fabric_1_21.event.BlockEvents; +import org.dynmap.fabric_1_21_7.event.BlockEvents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -18,7 +18,7 @@ public abstract class WorldChunkMixin { public abstract World getWorld(); @Inject(method = "setBlockState", at = @At("RETURN")) - public void setBlockState(BlockPos pos, BlockState state, boolean moved, CallbackInfoReturnable info) { + public void setBlockState(BlockPos pos, BlockState state, int flags, CallbackInfoReturnable info) { if (info.getReturnValue() != null) { BlockEvents.BLOCK_EVENT.invoker().onBlockEvent(this.getWorld(), pos); } diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/permissions/FabricPermissions.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/permissions/FabricPermissions.java similarity index 93% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/permissions/FabricPermissions.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/permissions/FabricPermissions.java index 6abd57195..133931fd7 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/permissions/FabricPermissions.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/permissions/FabricPermissions.java @@ -1,9 +1,9 @@ -package org.dynmap.fabric_1_21.permissions; +package org.dynmap.fabric_1_21_7.permissions; import me.lucko.fabric.api.permissions.v0.Permissions; import net.minecraft.entity.player.PlayerEntity; import org.dynmap.Log; -import org.dynmap.fabric_1_21.DynmapPlugin; +import org.dynmap.fabric_1_21_7.DynmapPlugin; import org.dynmap.json.simple.parser.JSONParser; import java.util.Set; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/permissions/FilePermissions.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/permissions/FilePermissions.java similarity index 96% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/permissions/FilePermissions.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/permissions/FilePermissions.java index a9d560437..d36b4c474 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/permissions/FilePermissions.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/permissions/FilePermissions.java @@ -1,9 +1,9 @@ -package org.dynmap.fabric_1_21_3.permissions; +package org.dynmap.fabric_1_21_7.permissions; import net.minecraft.entity.player.PlayerEntity; import org.dynmap.ConfigurationNode; import org.dynmap.Log; -import org.dynmap.fabric_1_21_3.DynmapPlugin; +import org.dynmap.fabric_1_21_7.DynmapPlugin; import java.io.File; import java.util.HashMap; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/permissions/LuckPermissions.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/permissions/LuckPermissions.java similarity index 97% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/permissions/LuckPermissions.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/permissions/LuckPermissions.java index 8723aa5f1..81b698a33 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/permissions/LuckPermissions.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/permissions/LuckPermissions.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21.permissions; +package org.dynmap.fabric_1_21_7.permissions; import me.lucko.fabric.api.permissions.v0.Permissions; import net.luckperms.api.LuckPerms; @@ -9,7 +9,7 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.MinecraftServer; import org.dynmap.Log; -import org.dynmap.fabric_1_21.DynmapPlugin; +import org.dynmap.fabric_1_21_7.DynmapPlugin; import org.dynmap.json.simple.JSONArray; import org.dynmap.json.simple.JSONObject; import org.dynmap.json.simple.parser.JSONParser; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/permissions/OpPermissions.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/permissions/OpPermissions.java similarity index 93% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/permissions/OpPermissions.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/permissions/OpPermissions.java index 870b30668..2bc5a9163 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/permissions/OpPermissions.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/permissions/OpPermissions.java @@ -1,8 +1,8 @@ -package org.dynmap.fabric_1_21_3.permissions; +package org.dynmap.fabric_1_21_7.permissions; import net.minecraft.entity.player.PlayerEntity; import org.dynmap.Log; -import org.dynmap.fabric_1_21_3.DynmapPlugin; +import org.dynmap.fabric_1_21_7.DynmapPlugin; import java.util.HashSet; import java.util.Set; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/permissions/PermissionProvider.java b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/permissions/PermissionProvider.java similarity index 89% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/permissions/PermissionProvider.java rename to fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/permissions/PermissionProvider.java index 1e08a7fd6..91c7b52fd 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/permissions/PermissionProvider.java +++ b/fabric-1.21.6/src/main/java/org/dynmap/fabric_1_21_7/permissions/PermissionProvider.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21.permissions; +package org.dynmap.fabric_1_21_7.permissions; import net.minecraft.entity.player.PlayerEntity; diff --git a/fabric-1.21.3/src/main/resources/assets/dynmap/icon.png b/fabric-1.21.6/src/main/resources/assets/dynmap/icon.png similarity index 100% rename from fabric-1.21.3/src/main/resources/assets/dynmap/icon.png rename to fabric-1.21.6/src/main/resources/assets/dynmap/icon.png diff --git a/fabric-1.21.3/src/main/resources/configuration.txt b/fabric-1.21.6/src/main/resources/configuration.txt similarity index 100% rename from fabric-1.21.3/src/main/resources/configuration.txt rename to fabric-1.21.6/src/main/resources/configuration.txt diff --git a/fabric-1.21.3/src/main/resources/dynmap.accesswidener b/fabric-1.21.6/src/main/resources/dynmap.accesswidener similarity index 100% rename from fabric-1.21.3/src/main/resources/dynmap.accesswidener rename to fabric-1.21.6/src/main/resources/dynmap.accesswidener diff --git a/fabric-1.21.1/src/main/resources/dynmap.mixins.json b/fabric-1.21.6/src/main/resources/dynmap.mixins.json similarity index 88% rename from fabric-1.21.1/src/main/resources/dynmap.mixins.json rename to fabric-1.21.6/src/main/resources/dynmap.mixins.json index 28fce76cf..9b1618339 100644 --- a/fabric-1.21.1/src/main/resources/dynmap.mixins.json +++ b/fabric-1.21.6/src/main/resources/dynmap.mixins.json @@ -1,7 +1,7 @@ { "required": true, "minVersion": "0.8", - "package": "org.dynmap.fabric_1_21_1.mixin", + "package": "org.dynmap.fabric_1_21_7.mixin", "compatibilityLevel": "JAVA_17", "mixins": [ "BiomeEffectsAccessor", diff --git a/fabric-1.21.3/src/main/resources/fabric.mod.json b/fabric-1.21.6/src/main/resources/fabric.mod.json similarity index 84% rename from fabric-1.21.3/src/main/resources/fabric.mod.json rename to fabric-1.21.6/src/main/resources/fabric.mod.json index 2e9c78c11..6718f719d 100644 --- a/fabric-1.21.3/src/main/resources/fabric.mod.json +++ b/fabric-1.21.6/src/main/resources/fabric.mod.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "id": "dynmap", - "version": "${version}", + "version": "3.4.0-beta-1", "name": "Dynmap", "description": "Dynamic, Google-maps style rendered maps for your Minecraft server", "authors": [ @@ -18,7 +18,7 @@ "environment": "*", "entrypoints": { "main": [ - "org.dynmap.fabric_1_21_3.DynmapMod" + "org.dynmap.fabric_1_21_7.DynmapMod" ] }, "mixins": [ @@ -29,6 +29,6 @@ "depends": { "fabricloader": ">=0.16.9", "fabric": ">=0.108.0", - "minecraft": ["1.21.3","1.21.4"] + "minecraft": ["1.21.6","1.21.7", "1.21.8"] } } diff --git a/fabric-1.21.3/src/main/resources/permissions.yml.example b/fabric-1.21.6/src/main/resources/permissions.yml.example similarity index 100% rename from fabric-1.21.3/src/main/resources/permissions.yml.example rename to fabric-1.21.6/src/main/resources/permissions.yml.example diff --git a/fabric-1.21/.gitignore b/fabric-1.21.9-10/.gitignore similarity index 100% rename from fabric-1.21/.gitignore rename to fabric-1.21.9-10/.gitignore diff --git a/fabric-1.21.3/build.gradle b/fabric-1.21.9-10/build.gradle similarity index 88% rename from fabric-1.21.3/build.gradle rename to fabric-1.21.9-10/build.gradle index 73492c32e..8a8de3289 100644 --- a/fabric-1.21.3/build.gradle +++ b/fabric-1.21.9-10/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.9-SNAPSHOT' + id 'fabric-loom' version '1.13.6' } archivesBaseName = "Dynmap" @@ -8,7 +8,7 @@ group = parent.group eclipse { project { - name = "Dynmap(Fabric-1.21.3)" + name = "Dynmap(Fabric-1.21.9-10)" } } @@ -34,7 +34,7 @@ dependencies { shadow project(path: ':DynmapCore', configuration: 'shadow') - modCompileOnly "me.lucko:fabric-permissions-api:0.1-SNAPSHOT" + modCompileOnly "me.lucko:fabric-permissions-api:0.5.0" compileOnly 'net.luckperms:api:5.4' } @@ -63,7 +63,7 @@ jar { } remapJar { - archiveFileName = "${archivesBaseName}-${project.version}-fabric-${project.minecraft_version}.jar" + archiveFileName = "${archivesBaseName}-${project.version}-fabric-${project.minecraft_version}-10.jar" // TODO: Remove -10 when updating after 1.21.10 release destinationDirectory = file '../target' } diff --git a/fabric-1.21.9-10/gradle.properties b/fabric-1.21.9-10/gradle.properties new file mode 100644 index 000000000..9e1958d38 --- /dev/null +++ b/fabric-1.21.9-10/gradle.properties @@ -0,0 +1,6 @@ +minecraft_version=1.21.9 + +# see https://fabricmc.net/develop/ +yarn_mappings=1.21.9+build.1 +loader_version=0.17.2 +fabric_version=0.133.14+1.21.9 diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/DynmapMod.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/DynmapMod.java similarity index 97% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/DynmapMod.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/DynmapMod.java index 683c13d05..a7c5f8532 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/DynmapMod.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/DynmapMod.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1; +package org.dynmap.fabric_1_21_9_10; import net.fabricmc.api.ModInitializer; import net.fabricmc.loader.api.FabricLoader; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/DynmapPlugin.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/DynmapPlugin.java similarity index 97% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/DynmapPlugin.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/DynmapPlugin.java index 4962df149..8e7968186 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/DynmapPlugin.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/DynmapPlugin.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21; +package org.dynmap.fabric_1_21_9_10; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.exceptions.CommandSyntaxException; @@ -35,16 +35,16 @@ import org.dynmap.common.DynmapListenerManager; import org.dynmap.common.DynmapPlayer; import org.dynmap.common.chunk.GenericChunkCache; -import org.dynmap.fabric_1_21.command.DmapCommand; -import org.dynmap.fabric_1_21.command.DmarkerCommand; -import org.dynmap.fabric_1_21.command.DynmapCommand; -import org.dynmap.fabric_1_21.command.DynmapExpCommand; -import org.dynmap.fabric_1_21.event.BlockEvents; -import org.dynmap.fabric_1_21.event.CustomServerChunkEvents; -import org.dynmap.fabric_1_21.event.CustomServerLifecycleEvents; -import org.dynmap.fabric_1_21.event.PlayerEvents; -import org.dynmap.fabric_1_21.mixin.BiomeEffectsAccessor; -import org.dynmap.fabric_1_21.permissions.*; +import org.dynmap.fabric_1_21_9_10.command.DmapCommand; +import org.dynmap.fabric_1_21_9_10.command.DmarkerCommand; +import org.dynmap.fabric_1_21_9_10.command.DynmapCommand; +import org.dynmap.fabric_1_21_9_10.command.DynmapExpCommand; +import org.dynmap.fabric_1_21_9_10.event.BlockEvents; +import org.dynmap.fabric_1_21_9_10.event.CustomServerChunkEvents; +import org.dynmap.fabric_1_21_9_10.event.CustomServerLifecycleEvents; +import org.dynmap.fabric_1_21_9_10.event.PlayerEvents; +import org.dynmap.fabric_1_21_9_10.mixin.BiomeEffectsAccessor; +import org.dynmap.fabric_1_21_9_10.permissions.*; import org.dynmap.permissions.PermissionsHandler; import org.dynmap.renderer.DynmapBlockState; @@ -163,7 +163,7 @@ public void initializeBlockStates() { } statename += p.getName() + "=" + bs.get(p).toString(); } - int lightAtten = bs.isOpaqueFullCube(EmptyBlockView.INSTANCE, BlockPos.ORIGIN) ? 15 : (bs.isTransparent(EmptyBlockView.INSTANCE, BlockPos.ORIGIN) ? 0 : 1); + int lightAtten = bs.isOpaqueFullCube() ? 15 : (bs.isTransparent() ? 0 : 1); //Log.info("statename=" + bn + "[" + statename + "], lightAtten=" + lightAtten); // Fill in base attributes bld.setBaseState(basebs).setStateIndex(idx - baseidx).setBlockName(bn).setStateName(statename).setLegacyBlockID(idx).setAttenuatesLight(lightAtten); @@ -259,7 +259,7 @@ public boolean isOp(String player) { } // TODO: Consider whether cheats are enabled for integrated server - return server.isSingleplayer() && server.isHost(server.getPlayerManager().getPlayer(player).getGameProfile()); + return server.isSingleplayer() && server.isHost(server.getPlayerManager().getPlayer(player).getPlayerConfigEntry()); } boolean hasPerm(PlayerEntity psender, String permission) { @@ -793,4 +793,4 @@ private void loadWorlds() { } } } -} \ No newline at end of file +} diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricAdapter.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricAdapter.java similarity index 90% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricAdapter.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricAdapter.java index bb12c7c33..076cda678 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricAdapter.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricAdapter.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3; +package org.dynmap.fabric_1_21_9_10; import net.minecraft.server.world.ServerWorld; import org.dynmap.DynmapLocation; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricCommandSender.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricCommandSender.java similarity index 96% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricCommandSender.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricCommandSender.java index b13956a92..b2c538589 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricCommandSender.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricCommandSender.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3; +package org.dynmap.fabric_1_21_9_10; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.text.Text; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricLogger.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricLogger.java similarity index 95% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricLogger.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricLogger.java index f2046938c..cf70bb801 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/FabricLogger.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricLogger.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21; +package org.dynmap.fabric_1_21_9_10; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -46,4 +46,4 @@ public void warning(String s) { public void warning(String s, Throwable t) { log.warn(DM + s, t); } -} \ No newline at end of file +} diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricMapChunkCache.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricMapChunkCache.java similarity index 94% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricMapChunkCache.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricMapChunkCache.java index bbadf1568..b164a99d2 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricMapChunkCache.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricMapChunkCache.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1; +package org.dynmap.fabric_1_21_9_10; import net.minecraft.nbt.*; import net.minecraft.server.world.ServerChunkLoadingManager; @@ -8,12 +8,12 @@ import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.WordPackedArray; -import net.minecraft.world.ChunkSerializer; import net.minecraft.world.World; import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.BiomeEffects; import net.minecraft.world.chunk.ChunkManager; import net.minecraft.world.chunk.ChunkStatus; +import net.minecraft.world.chunk.SerializedChunk; import org.dynmap.DynmapChunk; import org.dynmap.DynmapCore; @@ -66,7 +66,8 @@ protected GenericChunk getLoadedChunk(DynmapChunk chunk) { if (cps.isChunkLoaded(chunk.x, chunk.z)) { NbtCompound nbt = null; try { - nbt = ChunkSerializer.serialize((ServerWorld) w, cps.getWorldChunk(chunk.x, chunk.z, false)); + SerializedChunk sc = SerializedChunk.fromChunk((ServerWorld) w, cps.getWorldChunk(chunk.x, chunk.z, false)); + nbt = sc.serialize(); } catch (NullPointerException e) { // TODO: find out why this is happening and why it only seems to happen since 1.16.2 Log.severe("ChunkSerializer.serialize threw a NullPointerException", e); diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricPlayer.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricPlayer.java similarity index 96% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricPlayer.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricPlayer.java index 508bfa0ee..9eb7e9d78 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricPlayer.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricPlayer.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1; +package org.dynmap.fabric_1_21_9_10; import com.google.common.collect.Iterables; import com.google.gson.Gson; @@ -44,7 +44,7 @@ public FabricPlayer(DynmapPlugin plugin, ServerPlayerEntity player) { uuid = this.player.getUuid(); GameProfile prof = this.player.getGameProfile(); if (prof != null) { - Property textureProperty = Iterables.getFirst(prof.getProperties().get("textures"), null); + Property textureProperty = Iterables.getFirst(prof.properties().get("textures"), null); if (textureProperty != null) { DynmapPlugin.TexturesPayload result = null; @@ -99,8 +99,8 @@ public DynmapLocation getLocation() { return null; } - Vec3d pos = player.getPos(); - return FabricAdapter.toDynmapLocation(plugin, player.getServerWorld(), pos.getX(), pos.getY(), pos.getZ()); + // Vec3d pos = player.movement; + return FabricAdapter.toDynmapLocation(plugin, player.getEntityWorld(), player.getX(), player.getY(), player.getZ()); } @Override @@ -109,7 +109,7 @@ public String getWorld() { return null; } - World world = player.getWorld(); + World world = player.getEntityWorld(); if (world != null) { return plugin.getWorld(world).getName(); } diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricServer.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricServer.java similarity index 96% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricServer.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricServer.java index 488640e54..4b2400771 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/FabricServer.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricServer.java @@ -1,6 +1,5 @@ -package org.dynmap.fabric_1_21_1; +package org.dynmap.fabric_1_21_9_10; -import com.mojang.authlib.GameProfile; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.ModContainer; import net.minecraft.block.AbstractSignBlock; @@ -14,6 +13,7 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.PlayerManager; import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.PlayerConfigEntry; import net.minecraft.text.Text; import net.minecraft.util.UserCache; import net.minecraft.util.Util; @@ -28,8 +28,8 @@ import org.dynmap.common.DynmapListenerManager; import org.dynmap.common.DynmapPlayer; import org.dynmap.common.DynmapServerInterface; -import org.dynmap.fabric_1_21_1.event.BlockEvents; -import org.dynmap.fabric_1_21_1.event.ServerChatEvents; +import org.dynmap.fabric_1_21_9_10.event.BlockEvents; +import org.dynmap.fabric_1_21_9_10.event.ServerChatEvents; import org.dynmap.utils.MapChunkCache; import org.dynmap.utils.VisibilityLimit; @@ -60,12 +60,11 @@ public class FabricServer extends DynmapServerInterface { public FabricServer(DynmapPlugin plugin, MinecraftServer server) { this.plugin = plugin; this.server = server; - this.biomeRegistry = server.getRegistryManager().get(RegistryKeys.BIOME); + this.biomeRegistry = server.getRegistryManager().getOrThrow(RegistryKeys.BIOME); } - private Optional getProfileByName(String player) { - UserCache cache = server.getUserCache(); - return cache.findByName(player); + private Optional getProfileByName(String playerName) { + return Optional.ofNullable(PlayerConfigEntry.fromNickname(playerName)); } public final Registry getBiomeRegistry() { @@ -202,12 +201,10 @@ public String getServerName() { public boolean isPlayerBanned(String pid) { PlayerManager scm = server.getPlayerManager(); BannedPlayerList bl = scm.getUserBanList(); - try { - return bl.contains(getProfileByName(pid).get()); - } catch (NoSuchElementException e) { - /* If this profile doesn't exist, default to "banned" for good measure. */ - return true; - } + + return getProfileByName(pid) + .map(profile -> bl.get(profile) != null) + .orElse(true); } @Override diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricWorld.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricWorld.java similarity index 98% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricWorld.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricWorld.java index 51f681282..0c35b5bd4 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/FabricWorld.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/FabricWorld.java @@ -1,7 +1,8 @@ -package org.dynmap.fabric_1_21_3; +package org.dynmap.fabric_1_21_9_10; import net.minecraft.registry.RegistryKey; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.WorldProperties.SpawnPoint; import net.minecraft.util.math.MathHelper; import net.minecraft.world.Heightmap; import net.minecraft.world.LightType; @@ -96,7 +97,7 @@ public boolean isTheEnd() { @Override public DynmapLocation getSpawnLocation() { if (world != null) { - BlockPos spawnPos = world.getLevelProperties().getSpawnPos(); + BlockPos spawnPos = world.getLevelProperties().getSpawnPoint().getPos().toImmutable(); spawnloc.x = spawnPos.getX(); spawnloc.y = spawnPos.getY(); spawnloc.z = spawnPos.getZ(); diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/NBT.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/NBT.java similarity index 65% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/NBT.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/NBT.java index 485eeae6c..a9e65d5ba 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/NBT.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/NBT.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1; +package org.dynmap.fabric_1_21_9_10; import org.dynmap.common.chunk.GenericBitStorage; import org.dynmap.common.chunk.GenericNBTCompound; @@ -6,6 +6,7 @@ import java.util.Set; import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtElement; import net.minecraft.nbt.NbtList; import net.minecraft.util.collection.PackedIntegerArray; @@ -26,63 +27,74 @@ public boolean contains(String s) { } @Override public boolean contains(String s, int i) { - return obj.contains(s, i); + // Like contains, but with an extra constraint on type + NbtElement base = obj.get(s); + if (base == null) + return false; + int type = base.getType(); + if (type == i) + return true; + else if (i != TAG_ANY_NUMERIC) + return false; + return type == TAG_BYTE || type == TAG_SHORT || type == TAG_INT || type == TAG_LONG || type == TAG_FLOAT + || type == TAG_DOUBLE; } @Override public byte getByte(String s) { - return obj.getByte(s); + return obj.getByte(s, (byte)0); } @Override public short getShort(String s) { - return obj.getShort(s); + return obj.getShort(s, (short)0); } @Override public int getInt(String s) { - return obj.getInt(s); + return obj.getInt(s, (int)0); } @Override public long getLong(String s) { - return obj.getLong(s); + return obj.getLong(s, (long)0); } @Override public float getFloat(String s) { - return obj.getFloat(s); + return obj.getFloat(s, (float)0); } @Override public double getDouble(String s) { - return obj.getDouble(s); + return obj.getDouble(s, (double)0); } @Override public String getString(String s) { - return obj.getString(s); + return obj.getString(s, ""); } @Override public byte[] getByteArray(String s) { - return obj.getByteArray(s); + return obj.getByteArray(s).orElseGet(() -> new byte[0]); } @Override public int[] getIntArray(String s) { - return obj.getIntArray(s); + return obj.getIntArray(s).orElseGet(() -> new int[0]); } @Override public long[] getLongArray(String s) { - return obj.getLongArray(s); + return obj.getLongArray(s).orElseGet(() -> new long[0]); } @Override public GenericNBTCompound getCompound(String s) { - return new NBTCompound(obj.getCompound(s)); + return new NBTCompound(obj.getCompoundOrEmpty(s)); } @Override public GenericNBTList getList(String s, int i) { - return new NBTList(obj.getList(s, i)); + // i argument used to be used to constrain list type, but nbt lists no longer have types as of 1.21.5 + return new NBTList(obj.getListOrEmpty(s)); } @Override public boolean getBoolean(String s) { - return obj.getBoolean(s); + return obj.getBoolean(s, false); } @Override public String getAsString(String s) { - return obj.get(s).asString(); + return obj.get(s).asString().orElse(""); } @Override public GenericBitStorage makeBitStorage(int bits, int count, long[] data) { @@ -103,11 +115,11 @@ public int size() { } @Override public String getString(int idx) { - return obj.getString(idx); + return obj.getString(idx, ""); } @Override public GenericNBTCompound getCompound(int idx) { - return new NBTCompound(obj.getCompound(idx)); + return new NBTCompound(obj.getCompoundOrEmpty(idx)); } public String toString() { return obj.toString(); diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/TaskRecord.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/TaskRecord.java similarity index 95% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/TaskRecord.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/TaskRecord.java index 3f35e06f3..e439385c1 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/TaskRecord.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/TaskRecord.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1; +package org.dynmap.fabric_1_21_9_10; import java.util.concurrent.FutureTask; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/VersionCheck.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/VersionCheck.java similarity index 99% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/VersionCheck.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/VersionCheck.java index a05bb81b3..dabc37151 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/VersionCheck.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/VersionCheck.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3; +package org.dynmap.fabric_1_21_9_10; import org.dynmap.DynmapCore; import org.dynmap.Log; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/access/ProtoChunkAccessor.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/access/ProtoChunkAccessor.java similarity index 63% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/access/ProtoChunkAccessor.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/access/ProtoChunkAccessor.java index e1208130b..95be663ea 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/access/ProtoChunkAccessor.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/access/ProtoChunkAccessor.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3.access; +package org.dynmap.fabric_1_21_9_10.access; public interface ProtoChunkAccessor { boolean getTouchedByWorldGen(); diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/command/DmapCommand.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/command/DmapCommand.java similarity index 58% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/command/DmapCommand.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/command/DmapCommand.java index e0b460cbc..3e6fe4384 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/command/DmapCommand.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/command/DmapCommand.java @@ -1,6 +1,6 @@ -package org.dynmap.fabric_1_21_1.command; +package org.dynmap.fabric_1_21_9_10.command; -import org.dynmap.fabric_1_21_1.DynmapPlugin; +import org.dynmap.fabric_1_21_9_10.DynmapPlugin; public class DmapCommand extends DynmapCommandExecutor { public DmapCommand(DynmapPlugin p) { diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/command/DmarkerCommand.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/command/DmarkerCommand.java similarity index 60% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/command/DmarkerCommand.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/command/DmarkerCommand.java index de845d34c..18d202856 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/command/DmarkerCommand.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/command/DmarkerCommand.java @@ -1,6 +1,6 @@ -package org.dynmap.fabric_1_21_1.command; +package org.dynmap.fabric_1_21_9_10.command; -import org.dynmap.fabric_1_21_1.DynmapPlugin; +import org.dynmap.fabric_1_21_9_10.DynmapPlugin; public class DmarkerCommand extends DynmapCommandExecutor { public DmarkerCommand(DynmapPlugin p) { diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/command/DynmapCommand.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/command/DynmapCommand.java similarity index 59% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/command/DynmapCommand.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/command/DynmapCommand.java index ea7daec7c..2cf8ec0a2 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/command/DynmapCommand.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/command/DynmapCommand.java @@ -1,6 +1,6 @@ -package org.dynmap.fabric_1_21_3.command; +package org.dynmap.fabric_1_21_9_10.command; -import org.dynmap.fabric_1_21_3.DynmapPlugin; +import org.dynmap.fabric_1_21_9_10.DynmapPlugin; public class DynmapCommand extends DynmapCommandExecutor { public DynmapCommand(DynmapPlugin p) { diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/command/DynmapCommandExecutor.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/command/DynmapCommandExecutor.java similarity index 96% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/command/DynmapCommandExecutor.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/command/DynmapCommandExecutor.java index ab48599af..01cc34fde 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/command/DynmapCommandExecutor.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/command/DynmapCommandExecutor.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1.command; +package org.dynmap.fabric_1_21_9_10.command; import com.mojang.brigadier.Command; import com.mojang.brigadier.CommandDispatcher; @@ -11,7 +11,7 @@ import java.util.Arrays; -import org.dynmap.fabric_1_21_1.DynmapPlugin; +import org.dynmap.fabric_1_21_9_10.DynmapPlugin; import static com.mojang.brigadier.arguments.StringArgumentType.greedyString; import static net.minecraft.server.command.CommandManager.argument; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/command/DynmapExpCommand.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/command/DynmapExpCommand.java similarity index 61% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/command/DynmapExpCommand.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/command/DynmapExpCommand.java index 2fcf9f695..2955e8b85 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/command/DynmapExpCommand.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/command/DynmapExpCommand.java @@ -1,6 +1,6 @@ -package org.dynmap.fabric_1_21.command; +package org.dynmap.fabric_1_21_9_10.command; -import org.dynmap.fabric_1_21.DynmapPlugin; +import org.dynmap.fabric_1_21_9_10.DynmapPlugin; public class DynmapExpCommand extends DynmapCommandExecutor { public DynmapExpCommand(DynmapPlugin p) { diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/event/BlockEvents.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/event/BlockEvents.java similarity index 96% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/event/BlockEvents.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/event/BlockEvents.java index 9fb7b8156..19b4d5f75 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/event/BlockEvents.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/event/BlockEvents.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3.event; +package org.dynmap.fabric_1_21_9_10.event; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/event/CustomServerChunkEvents.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/event/CustomServerChunkEvents.java similarity index 93% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/event/CustomServerChunkEvents.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/event/CustomServerChunkEvents.java index 1b390c34c..6a370dabf 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/event/CustomServerChunkEvents.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/event/CustomServerChunkEvents.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21.event; +package org.dynmap.fabric_1_21_9_10.event; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; @@ -18,4 +18,4 @@ public class CustomServerChunkEvents { public interface ChunkGenerate { void onChunkGenerate(ServerWorld world, Chunk chunk); } -} \ No newline at end of file +} diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/event/CustomServerLifecycleEvents.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/event/CustomServerLifecycleEvents.java similarity index 93% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/event/CustomServerLifecycleEvents.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/event/CustomServerLifecycleEvents.java index 0c95f394c..4387519ed 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/event/CustomServerLifecycleEvents.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/event/CustomServerLifecycleEvents.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3.event; +package org.dynmap.fabric_1_21_9_10.event; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/event/PlayerEvents.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/event/PlayerEvents.java similarity index 97% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/event/PlayerEvents.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/event/PlayerEvents.java index 40114d923..03ed4d194 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/event/PlayerEvents.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/event/PlayerEvents.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3.event; +package org.dynmap.fabric_1_21_9_10.event; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/event/ServerChatEvents.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/event/ServerChatEvents.java similarity index 93% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/event/ServerChatEvents.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/event/ServerChatEvents.java index c0c3ceadf..127bc35bd 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/event/ServerChatEvents.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/event/ServerChatEvents.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21.event; +package org.dynmap.fabric_1_21_9_10.event; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; @@ -20,4 +20,4 @@ private ServerChatEvents() { public interface ServerChatCallback { void onChatMessage(ServerPlayerEntity player, String message); } -} \ No newline at end of file +} diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/BiomeEffectsAccessor.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/BiomeEffectsAccessor.java similarity index 85% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/BiomeEffectsAccessor.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/BiomeEffectsAccessor.java index fef2f5071..d6a3fe67c 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/BiomeEffectsAccessor.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/BiomeEffectsAccessor.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3.mixin; +package org.dynmap.fabric_1_21_9_10.mixin; import net.minecraft.world.biome.BiomeEffects; import org.spongepowered.asm.mixin.Mixin; diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/ChunkGeneratingMixin.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/ChunkGeneratingMixin.java similarity index 87% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/ChunkGeneratingMixin.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/ChunkGeneratingMixin.java index e206a0adf..2e5d75e6d 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/ChunkGeneratingMixin.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/ChunkGeneratingMixin.java @@ -1,12 +1,12 @@ -package org.dynmap.fabric_1_21.mixin; +package org.dynmap.fabric_1_21_9_10.mixin; import net.minecraft.world.chunk.ChunkGenerating; import net.minecraft.world.chunk.ChunkGenerationContext; import net.minecraft.world.chunk.AbstractChunkHolder; import net.minecraft.world.chunk.Chunk; -import org.dynmap.fabric_1_21.access.ProtoChunkAccessor; -import org.dynmap.fabric_1_21.event.CustomServerChunkEvents; +import org.dynmap.fabric_1_21_9_10.access.ProtoChunkAccessor; +import org.dynmap.fabric_1_21_9_10.event.CustomServerChunkEvents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -24,4 +24,4 @@ private static void onChunkGenerate(Chunk chunk, ChunkGenerationContext chunkGen CustomServerChunkEvents.CHUNK_GENERATE.invoker().onChunkGenerate(chunkGenerationContext.world(), callbackInfoReturnable.getReturnValue()); } } -} \ No newline at end of file +} diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/MinecraftServerMixin.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/MinecraftServerMixin.java similarity index 83% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/MinecraftServerMixin.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/MinecraftServerMixin.java index d6ec18cff..689ed0770 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/MinecraftServerMixin.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/MinecraftServerMixin.java @@ -1,8 +1,8 @@ -package org.dynmap.fabric_1_21_1.mixin; +package org.dynmap.fabric_1_21_9_10.mixin; import net.minecraft.server.MinecraftServer; -import org.dynmap.fabric_1_21_1.event.CustomServerLifecycleEvents; +import org.dynmap.fabric_1_21_9_10.event.CustomServerLifecycleEvents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/PlayerManagerMixin.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/PlayerManagerMixin.java similarity index 93% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/PlayerManagerMixin.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/PlayerManagerMixin.java index 9ce9db01b..cd50f37b7 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/PlayerManagerMixin.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/PlayerManagerMixin.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_1.mixin; +package org.dynmap.fabric_1_21_9_10.mixin; import net.minecraft.entity.Entity; import net.minecraft.network.ClientConnection; @@ -6,7 +6,7 @@ import net.minecraft.server.network.ConnectedClientData; import net.minecraft.server.network.ServerPlayerEntity; -import org.dynmap.fabric_1_21_1.event.PlayerEvents; +import org.dynmap.fabric_1_21_9_10.event.PlayerEvents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/ProtoChunkMixin.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/ProtoChunkMixin.java similarity index 80% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/ProtoChunkMixin.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/ProtoChunkMixin.java index 182ac7f36..670abb723 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/mixin/ProtoChunkMixin.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/ProtoChunkMixin.java @@ -1,10 +1,10 @@ -package org.dynmap.fabric_1_21_3.mixin; +package org.dynmap.fabric_1_21_9_10.mixin; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.world.chunk.ProtoChunk; -import org.dynmap.fabric_1_21_3.access.ProtoChunkAccessor; +import org.dynmap.fabric_1_21_9_10.access.ProtoChunkAccessor; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -21,7 +21,7 @@ public class ProtoChunkMixin implements ProtoChunkAccessor { target = "Lnet/minecraft/world/chunk/ChunkSection;setBlockState(IIILnet/minecraft/block/BlockState;)Lnet/minecraft/block/BlockState;" ) ) - public void setBlockState(BlockPos pos, BlockState state, boolean moved, CallbackInfoReturnable info) { + public void setBlockState(BlockPos pos, BlockState state, int flags, CallbackInfoReturnable info) { touchedByWorldGen = true; } diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/ServerPlayNetworkHandlerMixin.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/ServerPlayNetworkHandlerMixin.java similarity index 94% rename from fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/ServerPlayNetworkHandlerMixin.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/ServerPlayNetworkHandlerMixin.java index a273cfd3b..4e142670d 100644 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/ServerPlayNetworkHandlerMixin.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/ServerPlayNetworkHandlerMixin.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21.mixin; +package org.dynmap.fabric_1_21_9_10.mixin; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; @@ -17,8 +17,8 @@ import java.util.Arrays; import java.util.List; -import org.dynmap.fabric_1_21.event.BlockEvents; -import org.dynmap.fabric_1_21.event.ServerChatEvents; +import org.dynmap.fabric_1_21_9_10.event.BlockEvents; +import org.dynmap.fabric_1_21_9_10.event.ServerChatEvents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -71,4 +71,4 @@ public void onSignUpdate(UpdateSignC2SPacket packet, List signT // Cancel the original tryChangeText() since we're calling it ourselves above. ci.cancel(); } -} \ No newline at end of file +} diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/ServerPlayerEntityMixin.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/ServerPlayerEntityMixin.java similarity index 93% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/ServerPlayerEntityMixin.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/ServerPlayerEntityMixin.java index 9749e8675..87ecd5b5e 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/ServerPlayerEntityMixin.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/ServerPlayerEntityMixin.java @@ -1,11 +1,11 @@ -package org.dynmap.fabric_1_21_1.mixin; +package org.dynmap.fabric_1_21_9_10.mixin; import net.minecraft.entity.Entity; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.world.TeleportTarget; -import org.dynmap.fabric_1_21_1.event.PlayerEvents; +import org.dynmap.fabric_1_21_9_10.event.PlayerEvents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/WorldChunkMixin.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/WorldChunkMixin.java similarity index 77% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/WorldChunkMixin.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/WorldChunkMixin.java index 7ecae9606..a998cccb6 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/mixin/WorldChunkMixin.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/mixin/WorldChunkMixin.java @@ -1,11 +1,11 @@ -package org.dynmap.fabric_1_21_1.mixin; +package org.dynmap.fabric_1_21_9_10.mixin; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.chunk.WorldChunk; -import org.dynmap.fabric_1_21_1.event.BlockEvents; +import org.dynmap.fabric_1_21_9_10.event.BlockEvents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -18,7 +18,7 @@ public abstract class WorldChunkMixin { public abstract World getWorld(); @Inject(method = "setBlockState", at = @At("RETURN")) - public void setBlockState(BlockPos pos, BlockState state, boolean moved, CallbackInfoReturnable info) { + public void setBlockState(BlockPos pos, BlockState state, int flags, CallbackInfoReturnable info) { if (info.getReturnValue() != null) { BlockEvents.BLOCK_EVENT.invoker().onBlockEvent(this.getWorld(), pos); } diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/permissions/FabricPermissions.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/permissions/FabricPermissions.java similarity index 93% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/permissions/FabricPermissions.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/permissions/FabricPermissions.java index 5987fa75a..bab41fc20 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/permissions/FabricPermissions.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/permissions/FabricPermissions.java @@ -1,9 +1,9 @@ -package org.dynmap.fabric_1_21_1.permissions; +package org.dynmap.fabric_1_21_9_10.permissions; import me.lucko.fabric.api.permissions.v0.Permissions; import net.minecraft.entity.player.PlayerEntity; import org.dynmap.Log; -import org.dynmap.fabric_1_21_1.DynmapPlugin; +import org.dynmap.fabric_1_21_9_10.DynmapPlugin; import org.dynmap.json.simple.parser.JSONParser; import java.util.Set; diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/permissions/FilePermissions.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/permissions/FilePermissions.java similarity index 96% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/permissions/FilePermissions.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/permissions/FilePermissions.java index aa2a3167e..333bd5865 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/permissions/FilePermissions.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/permissions/FilePermissions.java @@ -1,9 +1,9 @@ -package org.dynmap.fabric_1_21_1.permissions; +package org.dynmap.fabric_1_21_9_10.permissions; import net.minecraft.entity.player.PlayerEntity; import org.dynmap.ConfigurationNode; import org.dynmap.Log; -import org.dynmap.fabric_1_21_1.DynmapPlugin; +import org.dynmap.fabric_1_21_9_10.DynmapPlugin; import java.io.File; import java.util.HashMap; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/permissions/LuckPermissions.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/permissions/LuckPermissions.java similarity index 97% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/permissions/LuckPermissions.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/permissions/LuckPermissions.java index e4b2b50b7..ddd51d763 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/permissions/LuckPermissions.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/permissions/LuckPermissions.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3.permissions; +package org.dynmap.fabric_1_21_9_10.permissions; import me.lucko.fabric.api.permissions.v0.Permissions; import net.luckperms.api.LuckPerms; @@ -9,7 +9,7 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.MinecraftServer; import org.dynmap.Log; -import org.dynmap.fabric_1_21_3.DynmapPlugin; +import org.dynmap.fabric_1_21_9_10.DynmapPlugin; import org.dynmap.json.simple.JSONArray; import org.dynmap.json.simple.JSONObject; import org.dynmap.json.simple.parser.JSONParser; diff --git a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/permissions/OpPermissions.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/permissions/OpPermissions.java similarity index 93% rename from fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/permissions/OpPermissions.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/permissions/OpPermissions.java index 7cb9f61e1..451a6e823 100644 --- a/fabric-1.21.1/src/main/java/org/dynmap/fabric_1_21_1/permissions/OpPermissions.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/permissions/OpPermissions.java @@ -1,8 +1,8 @@ -package org.dynmap.fabric_1_21_1.permissions; +package org.dynmap.fabric_1_21_9_10.permissions; import net.minecraft.entity.player.PlayerEntity; import org.dynmap.Log; -import org.dynmap.fabric_1_21_1.DynmapPlugin; +import org.dynmap.fabric_1_21_9_10.DynmapPlugin; import java.util.HashSet; import java.util.Set; diff --git a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/permissions/PermissionProvider.java b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/permissions/PermissionProvider.java similarity index 88% rename from fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/permissions/PermissionProvider.java rename to fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/permissions/PermissionProvider.java index 6c6e9fe46..1c6dd3879 100644 --- a/fabric-1.21.3/src/main/java/org/dynmap/fabric_1_21_3/permissions/PermissionProvider.java +++ b/fabric-1.21.9-10/src/main/java/org/dynmap/fabric_1_21_9_10/permissions/PermissionProvider.java @@ -1,4 +1,4 @@ -package org.dynmap.fabric_1_21_3.permissions; +package org.dynmap.fabric_1_21_9_10.permissions; import net.minecraft.entity.player.PlayerEntity; diff --git a/fabric-1.21/src/main/resources/assets/dynmap/icon.png b/fabric-1.21.9-10/src/main/resources/assets/dynmap/icon.png similarity index 100% rename from fabric-1.21/src/main/resources/assets/dynmap/icon.png rename to fabric-1.21.9-10/src/main/resources/assets/dynmap/icon.png diff --git a/fabric-1.21/src/main/resources/configuration.txt b/fabric-1.21.9-10/src/main/resources/configuration.txt similarity index 100% rename from fabric-1.21/src/main/resources/configuration.txt rename to fabric-1.21.9-10/src/main/resources/configuration.txt diff --git a/fabric-1.21/src/main/resources/dynmap.accesswidener b/fabric-1.21.9-10/src/main/resources/dynmap.accesswidener similarity index 100% rename from fabric-1.21/src/main/resources/dynmap.accesswidener rename to fabric-1.21.9-10/src/main/resources/dynmap.accesswidener diff --git a/fabric-1.21.3/src/main/resources/dynmap.mixins.json b/fabric-1.21.9-10/src/main/resources/dynmap.mixins.json similarity index 79% rename from fabric-1.21.3/src/main/resources/dynmap.mixins.json rename to fabric-1.21.9-10/src/main/resources/dynmap.mixins.json index d089d0172..ace8e2d34 100644 --- a/fabric-1.21.3/src/main/resources/dynmap.mixins.json +++ b/fabric-1.21.9-10/src/main/resources/dynmap.mixins.json @@ -1,8 +1,8 @@ { "required": true, "minVersion": "0.8", - "package": "org.dynmap.fabric_1_21_3.mixin", - "compatibilityLevel": "JAVA_17", + "package": "org.dynmap.fabric_1_21_9_10.mixin", + "compatibilityLevel": "JAVA_21", "mixins": [ "BiomeEffectsAccessor", "ChunkGeneratingMixin", diff --git a/fabric-1.21/src/main/resources/fabric.mod.json b/fabric-1.21.9-10/src/main/resources/fabric.mod.json similarity index 77% rename from fabric-1.21/src/main/resources/fabric.mod.json rename to fabric-1.21.9-10/src/main/resources/fabric.mod.json index 9051acdee..94996de55 100644 --- a/fabric-1.21/src/main/resources/fabric.mod.json +++ b/fabric-1.21.9-10/src/main/resources/fabric.mod.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "id": "dynmap", - "version": "${version}", + "version": "3.4.0-beta-1", "name": "Dynmap", "description": "Dynamic, Google-maps style rendered maps for your Minecraft server", "authors": [ @@ -18,7 +18,7 @@ "environment": "*", "entrypoints": { "main": [ - "org.dynmap.fabric_1_21.DynmapMod" + "org.dynmap.fabric_1_21_9_10.DynmapMod" ] }, "mixins": [ @@ -27,8 +27,8 @@ "accessWidener" : "dynmap.accesswidener", "depends": { - "fabricloader": ">=0.15.11", - "fabric": ">=0.98.0", - "minecraft": ["1.21-rc.1", "1.21"] + "fabricloader": ">=0.17.2", + "fabric": ">=0.108.0", + "minecraft": ["1.21.9", "1.21.10"] } } diff --git a/fabric-1.21/src/main/resources/permissions.yml.example b/fabric-1.21.9-10/src/main/resources/permissions.yml.example similarity index 100% rename from fabric-1.21/src/main/resources/permissions.yml.example rename to fabric-1.21.9-10/src/main/resources/permissions.yml.example diff --git a/fabric-1.21/gradle.properties b/fabric-1.21/gradle.properties deleted file mode 100644 index 5dfbbcf83..000000000 --- a/fabric-1.21/gradle.properties +++ /dev/null @@ -1,4 +0,0 @@ -minecraft_version=1.21 -yarn_mappings=1.21+build.1 -loader_version=0.15.11 -fabric_version=0.100.1+1.21 diff --git a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/BiomeEffectsAccessor.java b/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/BiomeEffectsAccessor.java deleted file mode 100644 index 7bcf881c5..000000000 --- a/fabric-1.21/src/main/java/org/dynmap/fabric_1_21/mixin/BiomeEffectsAccessor.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.dynmap.fabric_1_21.mixin; - -import net.minecraft.world.biome.BiomeEffects; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(BiomeEffects.class) -public interface BiomeEffectsAccessor { - @Accessor - int getWaterColor(); -} diff --git a/forge-1.20.6/src/main/java/org/dynmap/forge_1_20_6/DynmapPlugin.java b/forge-1.20.6/src/main/java/org/dynmap/forge_1_20_6/DynmapPlugin.java index ca7c49bb0..4c9b20869 100644 --- a/forge-1.20.6/src/main/java/org/dynmap/forge_1_20_6/DynmapPlugin.java +++ b/forge-1.20.6/src/main/java/org/dynmap/forge_1_20_6/DynmapPlugin.java @@ -54,9 +54,7 @@ import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.LeavesBlock; import net.minecraft.world.level.block.LiquidBlock; -import net.minecraft.world.level.block.SoundType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.LevelChunk; @@ -125,7 +123,6 @@ import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.SubscribeEvent; - import net.minecraft.world.level.EmptyBlockGetter; public class DynmapPlugin @@ -1730,7 +1727,35 @@ public void run() { } } - @SubscribeEvent(priority=EventPriority.LOWEST) + private void touchChunk(ForgeWorld fw, ChunkAccess c, String cause) { + int ymax = Integer.MIN_VALUE; + int ymin = Integer.MAX_VALUE; + LevelChunkSection[] sections = c.getSections(); + // If no sections, assume all + if (sections.length == 0) { + ymax = (c.getMaxSection()+1) << 4; + ymin = c.getMinSection() << 4; + } + else { + for(int i = 0; i < sections.length; i++) { + if((sections[i] != null) && (sections[i].hasOnlyAir() == false)) { + int sy = c.getSectionYFromSectionIndex(i) << 4; + if (sy < ymin) ymin = sy; + if ((sy+16) > ymax) ymax = sy + 16; + } + } + } + ChunkPos cp = c.getPos(); + int x = cp.x << 4; + int z = cp.z << 4; + Log.info(String.format("ymin=%d, ymax=%d", ymin, ymax)); + // If not empty AND not initial scan + if (ymax != Integer.MIN_VALUE) { + mapManager.touchVolume(fw.getName(), x, ymin, z, x+15, ymax, z+15, "chunkgenerate"); + } + } + + @SubscribeEvent(priority=EventPriority.MONITOR) public void handleChunkLoad(ChunkEvent.Load event) { if(!onchunkgenerate) return; @@ -1744,7 +1769,7 @@ public void handleChunkLoad(ChunkEvent.Load event) { } } } - @SubscribeEvent(priority=EventPriority.LOWEST) + @SubscribeEvent(priority=EventPriority.MONITOR) public void handleChunkUnload(ChunkEvent.Unload event) { if(!onchunkgenerate) return; @@ -1756,29 +1781,13 @@ public void handleChunkUnload(ChunkEvent.Unload event) { ChunkPos cp = c.getPos(); if (fw != null) { if (!checkIfKnownChunk(fw, cp)) { - int ymax = Integer.MIN_VALUE; - int ymin = Integer.MAX_VALUE; - LevelChunkSection[] sections = c.getSections(); - for(int i = 0; i < sections.length; i++) { - if((sections[i] != null) && (sections[i].hasOnlyAir() == false)) { - int sy = c.getSectionYFromSectionIndex(i); - if (sy < ymin) ymin = sy; - if ((sy+16) > ymax) ymax = sy + 16; - } - } - int x = cp.x << 4; - int z = cp.z << 4; - // If not empty AND not initial scan - if (ymax != Integer.MIN_VALUE) { - //Log.info(String.format("chunkkeyerate(unload)(%s,%d,%d,%d,%d,%d,%s)", fw.getName(), x, ymin, z, x+15, ymax, z+15)); - mapManager.touchVolume(fw.getName(), x, ymin, z, x+15, ymax, z+15, "chunkgenerate"); - } + touchChunk(fw, c, "unload"); } removeKnownChunk(fw, cp); } } } - @SubscribeEvent(priority=EventPriority.LOWEST) + @SubscribeEvent(priority=EventPriority.MONITOR) public void handleChunkDataSave(ChunkDataEvent.Save event) { if(!onchunkgenerate) return; @@ -1789,33 +1798,16 @@ public void handleChunkDataSave(ChunkDataEvent.Save event) { ForgeWorld fw = getWorld((ServerLevel)w, false); ChunkPos cp = c.getPos(); if (fw != null) { - if (!checkIfKnownChunk(fw, cp)) { - int ymax = Integer.MIN_VALUE; - int ymin = Integer.MAX_VALUE; - LevelChunkSection[] sections = c.getSections(); - for(int i = 0; i < sections.length; i++) { - if((sections[i] != null) && (sections[i].hasOnlyAir() == false)) { - int sy = c.getSectionYFromSectionIndex(i); - if (sy < ymin) ymin = sy; - if ((sy+16) > ymax) ymax = sy + 16; - } - } - int x = cp.x << 4; - int z = cp.z << 4; - // If not empty AND not initial scan - if (ymax != Integer.MIN_VALUE) { - //Log.info(String.format("chunkkeyerate(save)(%s,%d,%d,%d,%d,%d,%s)", fw.getName(), x, ymin, z, x+15, ymax, z+15)); - mapManager.touchVolume(fw.getName(), x, ymin, z, x+15, ymax, z+15, "chunkgenerate"); - } - // If cooked, add to known - if ((c.getStatus() == ChunkStatus.FULL) && (c instanceof LevelChunk)) { - addKnownChunk(fw, cp); - } + touchChunk(fw, c, "datasave"); + // If cooked, add to known + if (c.getStatus() == ChunkStatus.FULL) { + addKnownChunk(fw, cp); } } } } - @SubscribeEvent(priority=EventPriority.LOWEST) + + @SubscribeEvent(priority=EventPriority.MONITOR, receiveCanceled=false) public void handleBlockEvent(BlockEvent event) { if(!core_enabled) return; if(!onblockchange) return; diff --git a/forge-1.21.10/.gitignore b/forge-1.21.10/.gitignore new file mode 100644 index 000000000..84c048a73 --- /dev/null +++ b/forge-1.21.10/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/forge-1.21/build.gradle b/forge-1.21.10/build.gradle similarity index 81% rename from forge-1.21/build.gradle rename to forge-1.21.10/build.gradle index 3dff50159..262083a7e 100644 --- a/forge-1.21/build.gradle +++ b/forge-1.21.10/build.gradle @@ -14,7 +14,7 @@ apply plugin: 'eclipse' eclipse { project { - name = "Dynmap(Forge-1.21)" + name = "Dynmap(Forge-1.21.10)" } } @@ -25,24 +25,26 @@ println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getPro ext.buildNumber = System.getenv().BUILD_NUMBER ?: "Dev" minecraft { - mappings channel: 'official', version: '1.21' + mappings channel: 'official', version: '1.21.10' accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') reobf = false copyIdeResources = true runs { server { + property 'eventbus.api.strictRuntimeChecks', 'true' workingDirectory project.file('run').canonicalPath } } } -project.archivesBaseName = "${project.archivesBaseName}-forge-1.21" +project.archivesBaseName = "${project.archivesBaseName}-forge-1.21.10" dependencies { implementation project(path: ":DynmapCore", configuration: "shadow") implementation project(path: ':DynmapCoreAPI') + annotationProcessor 'net.minecraftforge:eventbus-validator:7.0-beta.7' - minecraft 'net.minecraftforge:forge:1.21-51.0.8' + minecraft 'net.minecraftforge:forge:1.21.10-60.1.5' } processResources @@ -51,7 +53,7 @@ processResources // replace version and mcversion expand( version: project.version + '-' + project.ext.buildNumber, - mcversion: "1.21" + mcversion: "1.21.10" ) } } @@ -63,10 +65,10 @@ shadowJar { exclude("META-INF/maven/**") exclude("META-INF/services/**") } - relocate('org.apache.commons.codec', 'org.dynmap.forge_1_21.commons.codec') + relocate('org.apache.commons.codec', 'org.dynmap.forge_1_21_10.commons.codec') archiveBaseName = "Dynmap" - archiveClassifier = "forge-1.21" + archiveClassifier = "forge-1.21.10" destinationDirectory = file '../target' } diff --git a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/ClientProxy.java b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/ClientProxy.java similarity index 67% rename from forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/ClientProxy.java rename to forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/ClientProxy.java index feedf2405..0d4756fb1 100644 --- a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/ClientProxy.java +++ b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/ClientProxy.java @@ -1,4 +1,4 @@ -package org.dynmap.forge_1_21_3; +package org.dynmap.forge_1_21_10; public class ClientProxy extends Proxy { public ClientProxy() { diff --git a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/DynmapMod.java b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/DynmapMod.java similarity index 64% rename from forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/DynmapMod.java rename to forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/DynmapMod.java index 10d5cf96c..5c5d24ef5 100644 --- a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/DynmapMod.java +++ b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/DynmapMod.java @@ -1,4 +1,4 @@ -package org.dynmap.forge_1_21_3; +package org.dynmap.forge_1_21_10; import java.io.File; @@ -6,7 +6,7 @@ import org.dynmap.DynmapCommonAPI; import org.dynmap.DynmapCommonAPIListener; import org.dynmap.Log; -import org.dynmap.forge_1_21_3.DynmapPlugin.OurLog; +import org.dynmap.forge_1_21_10.DynmapPlugin.OurLog; import net.minecraft.server.MinecraftServer; import net.minecraftforge.fml.common.Mod; @@ -15,14 +15,13 @@ import net.minecraftforge.event.server.ServerStartedEvent; import net.minecraftforge.event.server.ServerStartingEvent; import net.minecraftforge.event.server.ServerStoppingEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.eventbus.api.bus.BusGroup; +import net.minecraftforge.eventbus.api.bus.EventBus; +import net.minecraftforge.eventbus.api.listener.SubscribeEvent; import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.IExtensionPoint; import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.StartupMessageManager; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; -import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; @Mod("dynmap") @@ -30,6 +29,7 @@ public class DynmapMod { // The instance of your mod that Forge uses. public static DynmapMod instance; + public static BusGroup modBusGroup; // Says where the client and server 'proxy' code is loaded. public static Proxy proxy = DistExecutor.runForDist(() -> ClientProxy::new, () -> Proxy::new); @@ -51,27 +51,19 @@ public void apiEnabled(DynmapCommonAPI api) { } } - //TODO - //public class LoadingCallback implements net.minecraftforge.common.ForgeChunkManager.LoadingCallback { - // @Override - // public void ticketsLoaded(List tickets, World world) { - // if(tickets.size() > 0) { - // DynmapPlugin.setBusy(world, tickets.get(0)); - // for(int i = 1; i < tickets.size(); i++) { - // ForgeChunkManager.releaseTicket(tickets.get(i)); - // } - // } - // } - //} - - public DynmapMod() { + public DynmapMod(FMLJavaModLoadingContext context) { instance = this; - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::init); + + modBusGroup = context.getModBusGroup(); + + // Register the commonSetup method for modloading + FMLCommonSetupEvent.getBus(modBusGroup).addListener(this::setup); - MinecraftForge.EVENT_BUS.register(this); + ServerStartedEvent.BUS.addListener(this::onServerStarted); + ServerAboutToStartEvent.BUS.addListener(this::onServerStarting); + ServerStoppingEvent.BUS.addListener(this::onServerStopping); - ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, + context.registerExtensionPoint(IExtensionPoint.DisplayTest.class, ()->new IExtensionPoint.DisplayTest(()->IExtensionPoint.DisplayTest.IGNORESERVERONLY, (remote, isServer)-> true)); Log.setLogger(new OurLog()); @@ -98,21 +90,8 @@ public void setup(final FMLCommonSetupEvent event) //} } - public void init(FMLLoadCompleteEvent event) - { - /* Set up for chunk loading notice from chunk manager */ - //TODO - //if(useforcedchunks) { - // ForgeChunkManager.setForcedChunkLoadingCallback(DynmapMod.instance, new LoadingCallback()); - //} - //else { - // Log.info("[Dynmap] World loading using forced chunks is disabled"); - //} - } - private MinecraftServer server; - @SubscribeEvent public void onServerStarting(ServerAboutToStartEvent event) { server = event.getServer(); if(plugin == null) @@ -120,14 +99,12 @@ public void onServerStarting(ServerAboutToStartEvent event) { plugin.onStarting(server.getCommands().getDispatcher()); } - @SubscribeEvent public void onServerStarted(ServerStartedEvent event) { DynmapCommonAPIListener.register(new APICallback()); plugin.serverStarted(); } - @SubscribeEvent - public void serverStopping(ServerStoppingEvent event) + public void onServerStopping(ServerStoppingEvent event) { proxy.stopServer(plugin); plugin = null; diff --git a/forge-1.21/src/main/java/org/dynmap/forge_1_21/DynmapPlugin.java b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/DynmapPlugin.java similarity index 91% rename from forge-1.21/src/main/java/org/dynmap/forge_1_21/DynmapPlugin.java rename to forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/DynmapPlugin.java index 838a4ef7e..0030ff67b 100644 --- a/forge-1.21/src/main/java/org/dynmap/forge_1_21/DynmapPlugin.java +++ b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/DynmapPlugin.java @@ -1,4 +1,4 @@ -package org.dynmap.forge_1_21; +package org.dynmap.forge_1_21_10; import java.io.File; import java.io.InputStream; @@ -46,7 +46,7 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.network.ServerGamePacketListenerImpl; -import net.minecraft.server.players.GameProfileCache; +import net.minecraft.server.players.NameAndId; import net.minecraft.server.players.UserBanList; import net.minecraft.tags.BlockTags; import net.minecraft.world.entity.Pose; @@ -54,9 +54,7 @@ import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.LeavesBlock; import net.minecraft.world.level.block.LiquidBlock; -import net.minecraft.world.level.block.SoundType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.LevelChunk; @@ -65,6 +63,7 @@ import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.ServerChatEvent; import net.minecraftforge.event.TickEvent; +import net.minecraftforge.event.TickEvent.ServerTickEvent; import net.minecraftforge.event.entity.player.PlayerEvent.PlayerChangedDimensionEvent; import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedInEvent; import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedOutEvent; @@ -73,6 +72,8 @@ import net.minecraftforge.event.level.ChunkDataEvent; import net.minecraftforge.event.level.ChunkEvent; import net.minecraftforge.event.level.LevelEvent; +import net.minecraftforge.eventbus.api.listener.Priority; +import net.minecraftforge.eventbus.api.listener.SubscribeEvent; import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.ModContainer; import net.minecraftforge.fml.loading.LoadingModList; @@ -98,12 +99,12 @@ import org.dynmap.common.DynmapServerInterface; import org.dynmap.common.DynmapListenerManager.EventType; import org.dynmap.common.chunk.GenericChunkCache; -import org.dynmap.forge_1_21.DmapCommand; -import org.dynmap.forge_1_21.DmarkerCommand; -import org.dynmap.forge_1_21.DynmapCommand; -import org.dynmap.forge_1_21.permissions.FilePermissions; -import org.dynmap.forge_1_21.permissions.OpPermissions; -import org.dynmap.forge_1_21.permissions.PermissionProvider; +import org.dynmap.forge_1_21_10.DmapCommand; +import org.dynmap.forge_1_21_10.DmarkerCommand; +import org.dynmap.forge_1_21_10.DynmapCommand; +import org.dynmap.forge_1_21_10.permissions.FilePermissions; +import org.dynmap.forge_1_21_10.permissions.OpPermissions; +import org.dynmap.forge_1_21_10.permissions.PermissionProvider; import org.dynmap.permissions.PermissionsHandler; import org.dynmap.renderer.DynmapBlockState; import org.dynmap.utils.DynmapLogger; @@ -123,10 +124,6 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; -import net.minecraftforge.eventbus.api.EventPriority; -import net.minecraftforge.eventbus.api.SubscribeEvent; - -import net.minecraft.world.level.EmptyBlockGetter; public class DynmapPlugin { @@ -138,7 +135,6 @@ public class DynmapPlugin private MapManager mapManager; private static net.minecraft.server.MinecraftServer server; public static DynmapPlugin plugin; - private ChatHandler chathandler; private HashMap sortWeights = new HashMap(); // Drop world load ticket after 30 seconds private long worldIdleTimeoutNS = 30 * 1000000000L; @@ -199,7 +195,7 @@ private boolean checkIfKnownChunk(ForgeWorld fw, ChunkPos pos) { private static Registry getBiomeReg() { if (reg == null) { - reg = server.registryAccess().registryOrThrow(Registries.BIOME); + reg = server.registryAccess().lookup(Registries.BIOME).get(); } return reg; } @@ -251,7 +247,7 @@ public void initializeBlockStates() { } int lightAtten = 15; try { // Workaround for mods with broken block state logic... - lightAtten =bs.isSolidRender(EmptyBlockGetter.INSTANCE, BlockPos.ZERO) ? 15 : (bs.propagatesSkylightDown(EmptyBlockGetter.INSTANCE, BlockPos.ZERO) ? 0 : 1); + lightAtten = bs.isSolidRender() ? 15 : (bs.propagatesSkylightDown() ? 0 : 1); } catch (Exception x) { Log.warning(String.format("Exception while checking lighting data for block state: %s[%s]", bn, statename)); Log.verboseinfo("Exception: " + x.toString()); @@ -355,18 +351,16 @@ private class ChatMessage { } private ConcurrentLinkedQueue msgqueue = new ConcurrentLinkedQueue(); - public class ChatHandler { - @SubscribeEvent - public void handleChat(ServerChatEvent event) { - String msg = event.getMessage().getString(); - if(!msg.startsWith("/")) { - ChatMessage cm = new ChatMessage(); - cm.message = msg; - cm.sender = event.getPlayer(); - msgqueue.add(cm); - } - } - } + private boolean handleChatRegistered = false; + public void handleChat(final ServerChatEvent event) { + String msg = event.getMessage().getString(); + if(!msg.startsWith("/")) { + ChatMessage cm = new ChatMessage(); + cm.message = msg; + cm.sender = event.getPlayer(); + msgqueue.add(cm); + } + } /** TODO: depends on forge chunk manager private static class WorldBusyRecord { @@ -470,7 +464,7 @@ public boolean isOp(String player) { return true; } } - return (server.isSingleplayer() && player.equalsIgnoreCase(server.getSingleplayerProfile().getName())); + return (server.isSingleplayer() && player.equalsIgnoreCase(server.getSingleplayerProfile().name())); } private boolean hasPerm(ServerPlayer psender, String permission) { @@ -531,10 +525,9 @@ public class ForgeServer extends DynmapServerInterface public ForgeServer() { } - private GameProfile getProfileByName(String player) { - GameProfileCache cache = server.getProfileCache(); - Optional val = cache.get(player); - return val.isPresent() ? val.get() : null; + private NameAndId getNameAndIdByName(String player) { + ServerPlayer p = server.getPlayerList().getPlayer(player); + return (p != null) ? new NameAndId(p.getGameProfile()) : null; } @Override @@ -647,7 +640,8 @@ public String getServerName() public boolean isPlayerBanned(String pid) { UserBanList bl = server.getPlayerList().getBans(); - return bl.isBanned(getProfileByName(pid)); + NameAndId nid = getNameAndIdByName(pid); + return (nid != null) ? bl.isBanned(nid) : false; } @Override @@ -701,9 +695,9 @@ public void onPlayerBedLeave(PlayerBedLeaveEvent evt) { break; case PLAYER_CHAT: - if (chathandler == null) { - chathandler = new ChatHandler(); - MinecraftForge.EVENT_BUS.register(chathandler); + if (!handleChatRegistered) { + handleChatRegistered = true; + ServerChatEvent.BUS.addListener(DynmapPlugin.this::handleChat); } break; @@ -811,7 +805,7 @@ public Set checkPlayerPermissions(String player, Set perms) if (scm == null) return Collections.emptySet(); UserBanList bl = scm.getBans(); if (bl == null) return Collections.emptySet(); - if(bl.isBanned(getProfileByName(player))) { + if (isPlayerBanned(player)) { return Collections.emptySet(); } Set rslt = hasOfflinePermissions(player, perms); @@ -830,7 +824,7 @@ public boolean checkPlayerPermission(String player, String perm) if (scm == null) return false; UserBanList bl = scm.getBans(); if (bl == null) return false; - if(bl.isBanned(getProfileByName(player))) { + if (isPlayerBanned(player)) { return false; } return hasOfflinePermission(player, perm); @@ -921,10 +915,7 @@ public int getCurrentPlayers() } @SubscribeEvent - public void tickEvent(TickEvent.ServerTickEvent event) { - if (event.phase == TickEvent.Phase.START) { - return; - } + public void tickEvent(TickEvent.ServerTickEvent.Post event) { cur_tick_starttime = System.nanoTime(); long elapsed = cur_tick_starttime - lasttick; lasttick = cur_tick_starttime; @@ -1139,7 +1130,7 @@ public ForgePlayer(ServerPlayer p) uuid = player.getUUID(); GameProfile prof = player.getGameProfile(); if (prof != null) { - Property textureProperty = Iterables.getFirst(prof.getProperties().get("textures"), null); + Property textureProperty = Iterables.getFirst(prof.properties().get("textures"), null); if (textureProperty != null) { TexturesPayload result = null; @@ -1196,7 +1187,7 @@ public DynmapLocation getLocation() return null; } Vec3 v = player.position(); - return toLoc(player.serverLevel(), v.x, v.y, v.z); + return toLoc(player.level(), v.x, v.y, v.z); } @Override public String getWorld() @@ -1206,9 +1197,9 @@ public String getWorld() return null; } - if (player.serverLevel() != null) + if (player.level() != null) { - return DynmapPlugin.this.getWorld((ServerLevel)player.serverLevel()).getName(); + return DynmapPlugin.this.getWorld((ServerLevel)player.level()).getName(); } return null; @@ -1555,7 +1546,7 @@ public void onStart() { /* Register tick handler */ if(!tickregistered) { - MinecraftForge.EVENT_BUS.register(fserver); + ServerTickEvent.Post.BUS.addListener(fserver::tickEvent); tickregistered = true; } @@ -1694,7 +1685,7 @@ private void registerPlayerLoginListener() } public class WorldTracker { - @SubscribeEvent(priority=EventPriority.LOWEST) + @SubscribeEvent(priority=Priority.MONITOR) public void handleWorldLoad(LevelEvent.Load event) { if(!core_enabled) return; LevelAccessor w = event.getLevel(); @@ -1708,7 +1699,7 @@ public void run() { } }, 0); } - @SubscribeEvent(priority=EventPriority.LOWEST) + @SubscribeEvent(priority=Priority.MONITOR) public void handleWorldUnload(LevelEvent.Unload event) { if(!core_enabled) return; LevelAccessor w = event.getLevel(); @@ -1730,95 +1721,124 @@ public void run() { } } - @SubscribeEvent(priority=EventPriority.LOWEST) + private void touchChunk(ForgeWorld fw, ChunkAccess c, String cause) { + int ymax = Integer.MIN_VALUE; + int ymin = Integer.MAX_VALUE; + LevelChunkSection[] sections = c.getSections(); + // If no sections, assume all + if (sections.length == 0) { + ymax = (c.getMaxSectionY()+1) << 4; + ymin = c.getMinSectionY() << 4; + } + else { + for(int i = 0; i < sections.length; i++) { + if((sections[i] != null) && (sections[i].hasOnlyAir() == false)) { + int sy = c.getSectionYFromSectionIndex(i) << 4; + if (sy < ymin) ymin = sy; + if ((sy+16) > ymax) ymax = sy + 16; + } + } + } + ChunkPos cp = c.getPos(); + int x = cp.x << 4; + int z = cp.z << 4; + // If not empty AND not initial scan + if (ymax != Integer.MIN_VALUE) { + mapManager.touchVolume(fw.getName(), x, ymin, z, x+15, ymax, z+15, "chunkgenerate"); + } + } + + @SubscribeEvent(priority=Priority.MONITOR) public void handleChunkLoad(ChunkEvent.Load event) { - if(!onchunkgenerate) return; - LevelAccessor w = event.getLevel(); - if(!(w instanceof ServerLevel)) return; + if (!(w instanceof ServerLevel)) return; ChunkAccess c = event.getChunk(); - if ((c != null) && (c.getPersistedStatus() == ChunkStatus.FULL) && (c instanceof LevelChunk)) { + if ((c != null) && (c.getPersistedStatus() == ChunkStatus.FULL)) { ForgeWorld fw = getWorld((ServerLevel)w, false); if (fw != null) { addKnownChunk(fw, c.getPos()); } } } - @SubscribeEvent(priority=EventPriority.LOWEST) - public void handleChunkUnload(ChunkEvent.Unload event) { - if(!onchunkgenerate) return; + @SubscribeEvent(priority=Priority.MONITOR) + public void handleChunkLightingCalculated(ChunkEvent.LightingCalculated event) { + LevelAccessor w = event.getLevel(); + if (!(w instanceof ServerLevel)) return; + ChunkAccess c = event.getChunk(); + if (c != null) { + ForgeWorld fw = getWorld((ServerLevel)w, false); + if (fw != null) { + touchChunk(fw, c, "lighting"); + if (c.getPersistedStatus() == ChunkStatus.FULL) { + addKnownChunk(fw, c.getPos()); + } + } + } + } + @SubscribeEvent(priority=Priority.MONITOR) + public void handleChunkUnload(ChunkEvent.Unload event) { LevelAccessor w = event.getLevel(); - if(!(w instanceof ServerLevel)) return; + if (!(w instanceof ServerLevel)) return; ChunkAccess c = event.getChunk(); if (c != null) { ForgeWorld fw = getWorld((ServerLevel)w, false); ChunkPos cp = c.getPos(); if (fw != null) { if (!checkIfKnownChunk(fw, cp)) { - int ymax = Integer.MIN_VALUE; - int ymin = Integer.MAX_VALUE; - LevelChunkSection[] sections = c.getSections(); - for(int i = 0; i < sections.length; i++) { - if((sections[i] != null) && (sections[i].hasOnlyAir() == false)) { - int sy = c.getSectionYFromSectionIndex(i); - if (sy < ymin) ymin = sy; - if ((sy+16) > ymax) ymax = sy + 16; - } - } - int x = cp.x << 4; - int z = cp.z << 4; - // If not empty AND not initial scan - if (ymax != Integer.MIN_VALUE) { - //Log.info(String.format("chunkkeyerate(unload)(%s,%d,%d,%d,%d,%d,%s)", fw.getName(), x, ymin, z, x+15, ymax, z+15)); - mapManager.touchVolume(fw.getName(), x, ymin, z, x+15, ymax, z+15, "chunkgenerate"); - } + touchChunk(fw, c, "unload"); } removeKnownChunk(fw, cp); } } } - @SubscribeEvent(priority=EventPriority.LOWEST) + @SubscribeEvent(priority=Priority.MONITOR) public void handleChunkDataSave(ChunkDataEvent.Save event) { - if(!onchunkgenerate) return; - LevelAccessor w = event.getLevel(); - if(!(w instanceof ServerLevel)) return; + if (!(w instanceof ServerLevel)) return; ChunkAccess c = event.getChunk(); if (c != null) { ForgeWorld fw = getWorld((ServerLevel)w, false); ChunkPos cp = c.getPos(); if (fw != null) { - if (!checkIfKnownChunk(fw, cp)) { - int ymax = Integer.MIN_VALUE; - int ymin = Integer.MAX_VALUE; - LevelChunkSection[] sections = c.getSections(); - for(int i = 0; i < sections.length; i++) { - if((sections[i] != null) && (sections[i].hasOnlyAir() == false)) { - int sy = c.getSectionYFromSectionIndex(i); - if (sy < ymin) ymin = sy; - if ((sy+16) > ymax) ymax = sy + 16; - } - } - int x = cp.x << 4; - int z = cp.z << 4; - // If not empty AND not initial scan - if (ymax != Integer.MIN_VALUE) { - //Log.info(String.format("chunkkeyerate(save)(%s,%d,%d,%d,%d,%d,%s)", fw.getName(), x, ymin, z, x+15, ymax, z+15)); - mapManager.touchVolume(fw.getName(), x, ymin, z, x+15, ymax, z+15, "chunkgenerate"); - } - // If cooked, add to known - if ((c.getPersistedStatus() == ChunkStatus.FULL) && (c instanceof LevelChunk)) { - addKnownChunk(fw, cp); - } - } + touchChunk(fw, c, "datasave"); + // If cooked, add to known + if (c.getPersistedStatus() == ChunkStatus.FULL) { + addKnownChunk(fw, cp); + } } } } - @SubscribeEvent(priority=EventPriority.LOWEST) - public void handleBlockEvent(BlockEvent event) { + @SubscribeEvent(priority=Priority.MONITOR) + public void handleBlockToolModificationEvent(BlockEvent.BlockToolModificationEvent event) { + handleBlockEvent(event); + } + @SubscribeEvent(priority=Priority.MONITOR) + public void handleBreakEvent(BlockEvent.BreakEvent event) { + handleBlockEvent(event); + } + @SubscribeEvent(priority=Priority.MONITOR) + public void handleCropGrowEvent(BlockEvent.CropGrowEvent event) { + handleBlockEvent(event); + } + @SubscribeEvent(priority=Priority.MONITOR) + public void handleEntityPlaceEvent(BlockEvent.EntityPlaceEvent event) { + handleBlockEvent(event); + } + @SubscribeEvent(priority=Priority.MONITOR) + public void handleFluidPlaceBlockEvent(BlockEvent.FluidPlaceBlockEvent event) { + handleBlockEvent(event); + } + @SubscribeEvent(priority=Priority.MONITOR) + public void handleNeighborNotifyEvent(BlockEvent.NeighborNotifyEvent event) { + handleBlockEvent(event); + } + @SubscribeEvent(priority=Priority.MONITOR) + public void handlePortalSpawnEvent(BlockEvent.PortalSpawnEvent event) { + handleBlockEvent(event); + } + private void handleBlockEvent(BlockEvent event) { if(!core_enabled) return; - if(!onblockchange) return; BlockUpdateRec r = new BlockUpdateRec(); r.w = event.getLevel(); if(!(r.w instanceof ServerLevel)) return; // band-aid to prevent errors in unsupported 'running in client' scenario @@ -1849,7 +1869,22 @@ private void registerEvents() onblockchange = true; if ((worldTracker == null) && (onblockchange || onchunkpopulate || onchunkgenerate)) { worldTracker = new WorldTracker(); - MinecraftForge.EVENT_BUS.register(worldTracker); + LevelEvent.Load.BUS.addListener(worldTracker::handleWorldLoad); + LevelEvent.Unload.BUS.addListener(worldTracker::handleWorldUnload); + if (onchunkgenerate) { + ChunkEvent.Load.BUS.addListener(worldTracker::handleChunkLoad); + ChunkDataEvent.Save.BUS.addListener(worldTracker::handleChunkDataSave); + ChunkEvent.LightingCalculated.BUS.addListener(worldTracker::handleChunkLightingCalculated); + } + if (onblockchange) { + BlockEvent.BlockToolModificationEvent.BUS.addListener(worldTracker::handleBlockToolModificationEvent); + BlockEvent.BreakEvent.BUS.addListener(worldTracker::handleBreakEvent); + BlockEvent.CropGrowEvent.BUS.addListener(worldTracker::handleCropGrowEvent); + BlockEvent.EntityPlaceEvent.BUS.addListener(worldTracker::handleEntityPlaceEvent); + BlockEvent.FluidPlaceBlockEvent.BUS.addListener(worldTracker::handleFluidPlaceBlockEvent); + BlockEvent.NeighborNotifyEvent.BUS.addListener(worldTracker::handleNeighborNotifyEvent); + BlockEvent.PortalSpawnEvent.BUS.addListener(worldTracker::handlePortalSpawnEvent); + } } // Prime the known full chunks if (onchunkgenerate && (server.getAllLevels() != null)) { diff --git a/forge-1.21/src/main/java/org/dynmap/forge_1_21/ForgeMapChunkCache.java b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/ForgeMapChunkCache.java similarity index 88% rename from forge-1.21/src/main/java/org/dynmap/forge_1_21/ForgeMapChunkCache.java rename to forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/ForgeMapChunkCache.java index 1018ebfbd..d317fd3d8 100644 --- a/forge-1.21/src/main/java/org/dynmap/forge_1_21/ForgeMapChunkCache.java +++ b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/ForgeMapChunkCache.java @@ -1,4 +1,4 @@ -package org.dynmap.forge_1_21; +package org.dynmap.forge_1_21_10; import java.util.List; import java.util.NoSuchElementException; @@ -17,8 +17,8 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.storage.ChunkSerializer; import net.minecraft.world.level.chunk.status.ChunkStatus; +import net.minecraft.world.level.chunk.storage.SerializableChunkData; /** * Container for managing chunks - dependent upon using chunk snapshots, since @@ -39,7 +39,8 @@ protected GenericChunk getLoadedChunk(DynmapChunk chunk) { GenericChunk gc = null; ChunkAccess ch = cps.getChunk(chunk.x, chunk.z, ChunkStatus.FULL, false); if (ch != null) { - CompoundTag nbt = ChunkSerializer.write(w, ch); + SerializableChunkData sc = SerializableChunkData.copyOf(w, cps.getChunk(chunk.x, chunk.z, false)); + CompoundTag nbt = sc.write(); if (nbt != null) { gc = parseChunkFromNBT(new NBT.NBTCompound(nbt)); } @@ -72,10 +73,10 @@ private CompoundTag readChunk(int x, int z) { if (rslt != null) { CompoundTag lev = rslt; if (lev.contains("Level")) { - lev = lev.getCompound("Level"); + lev = lev.getCompoundOrEmpty("Level"); } // Don't load uncooked chunks - String stat = lev.getString("Status"); + String stat = lev.getStringOr("Status", null); ChunkStatus cs = ChunkStatus.byName(stat); if ((stat == null) || // Needs to be at least lighted @@ -95,8 +96,8 @@ private CompoundTag readChunk(int x, int z) { } @Override public int getFoliageColor(BiomeMap bm, int[] colormap, int x, int z) { - return bm.getBiomeObject().map(Biome::getSpecialEffects) - .flatMap(BiomeSpecialEffects::getFoliageColorOverride) + return bm.getBiomeObject().map(Biome::getSpecialEffects). + flatMap(BiomeSpecialEffects::getFoliageColorOverride) .orElse(colormap[bm.biomeLookup()]); } diff --git a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/ForgeWorld.java b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/ForgeWorld.java similarity index 98% rename from forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/ForgeWorld.java rename to forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/ForgeWorld.java index 81bf1e7bd..fe0d374a3 100644 --- a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/ForgeWorld.java +++ b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/ForgeWorld.java @@ -1,4 +1,4 @@ -package org.dynmap.forge_1_21_3; +package org.dynmap.forge_1_21_10; /** * Forge specific implementation of DynmapWorld */ @@ -106,7 +106,7 @@ public boolean isTheEnd() public DynmapLocation getSpawnLocation() { if(world != null) { - BlockPos p = world.getLevel().getSharedSpawnPos(); + BlockPos p = world.getLevel().getRespawnData().pos(); spawnloc.x = p.getX(); spawnloc.y = p.getY(); spawnloc.z = p.getZ(); diff --git a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/NBT.java b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/NBT.java similarity index 64% rename from forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/NBT.java rename to forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/NBT.java index 685ac88c2..26c64edb3 100644 --- a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/NBT.java +++ b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/NBT.java @@ -1,4 +1,4 @@ -package org.dynmap.forge_1_21_3; +package org.dynmap.forge_1_21_10; import org.dynmap.common.chunk.GenericBitStorage; import org.dynmap.common.chunk.GenericNBTCompound; @@ -7,6 +7,7 @@ import java.util.Set; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.Tag; import net.minecraft.util.SimpleBitStorage; public class NBT { @@ -18,7 +19,7 @@ public NBTCompound(CompoundTag t) { } @Override public Set getAllKeys() { - return obj.getAllKeys(); + return obj.keySet(); } @Override public boolean contains(String s) { @@ -26,63 +27,74 @@ public boolean contains(String s) { } @Override public boolean contains(String s, int i) { - return obj.contains(s, i); + // Like contains, but with an extra constraint on type + Tag base = obj.get(s); + if (base == null) + return false; + byte type = base.getId(); + if (type == (byte) i) + return true; + else if (i != TAG_ANY_NUMERIC) + return false; + return type == TAG_BYTE || type == TAG_SHORT || type == TAG_INT || type == TAG_LONG || type == TAG_FLOAT + || type == TAG_DOUBLE; } @Override public byte getByte(String s) { - return obj.getByte(s); + return obj.getByteOr(s, (byte)0); } @Override public short getShort(String s) { - return obj.getShort(s); + return obj.getShortOr(s, (short)0); } @Override public int getInt(String s) { - return obj.getInt(s); + return obj.getIntOr(s, (int)0); } @Override public long getLong(String s) { - return obj.getLong(s); + return obj.getLongOr(s, (long)0); } @Override public float getFloat(String s) { - return obj.getFloat(s); + return obj.getFloatOr(s, (float)0); } @Override public double getDouble(String s) { - return obj.getDouble(s); + return obj.getDoubleOr(s, (double)0); } @Override public String getString(String s) { - return obj.getString(s); + return obj.getStringOr(s, ""); } @Override public byte[] getByteArray(String s) { - return obj.getByteArray(s); + return obj.getByteArray(s).orElseGet(() -> new byte[0]); } @Override public int[] getIntArray(String s) { - return obj.getIntArray(s); + return obj.getIntArray(s).orElseGet(() -> new int[0]); } @Override public long[] getLongArray(String s) { - return obj.getLongArray(s); + return obj.getLongArray(s).orElseGet(() -> new long[0]); } @Override public GenericNBTCompound getCompound(String s) { - return new NBTCompound(obj.getCompound(s)); + return new NBTCompound(obj.getCompoundOrEmpty(s)); } @Override public GenericNBTList getList(String s, int i) { - return new NBTList(obj.getList(s, i)); + // i argument used to be used to constrain list type, but nbt lists no longer have types as of 1.21.5 + return new NBTList(obj.getListOrEmpty(s)); } @Override public boolean getBoolean(String s) { - return obj.getBoolean(s); + return obj.getBooleanOr(s, false); } @Override public String getAsString(String s) { - return obj.get(s).getAsString(); + return obj.get(s).asString().orElse(""); } @Override public GenericBitStorage makeBitStorage(int bits, int count, long[] data) { @@ -103,11 +115,11 @@ public int size() { } @Override public String getString(int idx) { - return obj.getString(idx); + return obj.getStringOr(idx, ""); } @Override public GenericNBTCompound getCompound(int idx) { - return new NBTCompound(obj.getCompound(idx)); + return new NBTCompound(obj.getCompoundOrEmpty(idx)); } public String toString() { return obj.toString(); diff --git a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/Proxy.java b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/Proxy.java similarity index 93% rename from forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/Proxy.java rename to forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/Proxy.java index 6e945f7d0..1614b58ae 100644 --- a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/Proxy.java +++ b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/Proxy.java @@ -1,4 +1,4 @@ -package org.dynmap.forge_1_21_3; +package org.dynmap.forge_1_21_10; import net.minecraft.server.MinecraftServer; diff --git a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/VersionCheck.java b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/VersionCheck.java similarity index 99% rename from forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/VersionCheck.java rename to forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/VersionCheck.java index b695d9cf6..3843ec4d1 100644 --- a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/VersionCheck.java +++ b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/VersionCheck.java @@ -1,4 +1,4 @@ -package org.dynmap.forge_1_21_3; +package org.dynmap.forge_1_21_10; import java.io.BufferedReader; import java.io.InputStreamReader; diff --git a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/permissions/FilePermissions.java b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/permissions/FilePermissions.java similarity index 96% rename from forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/permissions/FilePermissions.java rename to forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/permissions/FilePermissions.java index 5526e3d1a..c3019edf2 100644 --- a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/permissions/FilePermissions.java +++ b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/permissions/FilePermissions.java @@ -1,4 +1,4 @@ -package org.dynmap.forge_1_21_3.permissions; +package org.dynmap.forge_1_21_10.permissions; import java.io.File; import java.util.HashMap; @@ -8,7 +8,7 @@ import org.dynmap.ConfigurationNode; import org.dynmap.Log; -import org.dynmap.forge_1_21_3.DynmapPlugin; +import org.dynmap.forge_1_21_10.DynmapPlugin; import net.minecraft.server.level.ServerPlayer; diff --git a/forge-1.21/src/main/java/org/dynmap/forge_1_21/permissions/OpPermissions.java b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/permissions/OpPermissions.java similarity index 93% rename from forge-1.21/src/main/java/org/dynmap/forge_1_21/permissions/OpPermissions.java rename to forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/permissions/OpPermissions.java index f4e642e44..66777ddae 100644 --- a/forge-1.21/src/main/java/org/dynmap/forge_1_21/permissions/OpPermissions.java +++ b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/permissions/OpPermissions.java @@ -1,10 +1,10 @@ -package org.dynmap.forge_1_21.permissions; +package org.dynmap.forge_1_21_10.permissions; import java.util.HashSet; import java.util.Set; import org.dynmap.Log; -import org.dynmap.forge_1_21.DynmapPlugin; +import org.dynmap.forge_1_21_10.DynmapPlugin; import net.minecraft.server.level.ServerPlayer; diff --git a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/permissions/PermissionProvider.java b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/permissions/PermissionProvider.java similarity index 89% rename from forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/permissions/PermissionProvider.java rename to forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/permissions/PermissionProvider.java index f3c7f3543..e75281485 100644 --- a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/permissions/PermissionProvider.java +++ b/forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/permissions/PermissionProvider.java @@ -1,4 +1,4 @@ -package org.dynmap.forge_1_21_3.permissions; +package org.dynmap.forge_1_21_10.permissions; import java.util.Set; diff --git a/forge-1.21.3/src/main/resources/META-INF/accesstransformer.cfg b/forge-1.21.10/src/main/resources/META-INF/accesstransformer.cfg similarity index 100% rename from forge-1.21.3/src/main/resources/META-INF/accesstransformer.cfg rename to forge-1.21.10/src/main/resources/META-INF/accesstransformer.cfg diff --git a/forge-1.21.10/src/main/resources/META-INF/mods.toml b/forge-1.21.10/src/main/resources/META-INF/mods.toml new file mode 100644 index 000000000..163811904 --- /dev/null +++ b/forge-1.21.10/src/main/resources/META-INF/mods.toml @@ -0,0 +1,26 @@ +modLoader="javafml" +loaderVersion="[60,)" +issueTrackerURL="https://github.com/webbukkit/dynmap/issues" +license="Apache Public License v2" +[[mods]] +modId="dynmap" +version="${version}" +displayName="Dynmap" +authors="mikeprimm" +description=''' +Dynamic, Google-maps style rendered maps for your Minecraft server +''' + +[[dependencies.dynmap]] + modId="forge" + mandatory=true + versionRange="[60,)" + ordering="NONE" + # Side this dependency is applied on - BOTH, CLIENT or SERVER + side="SERVER" +[[dependencies.dynmap]] + modId="minecraft" + mandatory=true + versionRange="[1.21.10,1.21.11)" + ordering="NONE" + side="SERVER" diff --git a/forge-1.21.3/src/main/resources/configuration.txt b/forge-1.21.10/src/main/resources/configuration.txt similarity index 100% rename from forge-1.21.3/src/main/resources/configuration.txt rename to forge-1.21.10/src/main/resources/configuration.txt diff --git a/forge-1.21.3/src/main/resources/pack.mcmeta b/forge-1.21.10/src/main/resources/pack.mcmeta similarity index 100% rename from forge-1.21.3/src/main/resources/pack.mcmeta rename to forge-1.21.10/src/main/resources/pack.mcmeta diff --git a/forge-1.21.3/src/main/resources/permissions.yml.example b/forge-1.21.10/src/main/resources/permissions.yml.example similarity index 100% rename from forge-1.21.3/src/main/resources/permissions.yml.example rename to forge-1.21.10/src/main/resources/permissions.yml.example diff --git a/forge-1.21.11/.gitignore b/forge-1.21.11/.gitignore new file mode 100644 index 000000000..84c048a73 --- /dev/null +++ b/forge-1.21.11/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/forge-1.21.11/build.gradle b/forge-1.21.11/build.gradle new file mode 100644 index 000000000..854ab09c8 --- /dev/null +++ b/forge-1.21.11/build.gradle @@ -0,0 +1,80 @@ +buildscript { + repositories { + maven { url = 'https://files.minecraftforge.net/maven' } + jcenter() + mavenCentral() + } + dependencies { + classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '[6.0.24,6.2)', changing: true + } +} +apply plugin: 'net.minecraftforge.gradle' +//apply plugin: 'com.github.johnrengelman.shadow' +apply plugin: 'eclipse' + +eclipse { + project { + name = "Dynmap(Forge-1.21.11)" + } +} + +sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(21) // Need this here so eclipse task generates correctly. + +println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) + +ext.buildNumber = System.getenv().BUILD_NUMBER ?: "Dev" + +minecraft { + mappings channel: 'official', version: '1.21.11' + accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') + reobf = false + copyIdeResources = true + runs { + server { + property 'eventbus.api.strictRuntimeChecks', 'true' + workingDirectory project.file('run').canonicalPath + } + } +} + +project.archivesBaseName = "${project.archivesBaseName}-forge-1.21.11" + +dependencies { + implementation project(path: ":DynmapCore", configuration: "shadow") + implementation project(path: ':DynmapCoreAPI') + annotationProcessor 'net.minecraftforge:eventbus-validator:7.0-beta.7' + + minecraft 'net.minecraftforge:forge:1.21.11-61.0.5' +} + +processResources +{ + filesMatching('META-INF/mods.toml') { + // replace version and mcversion + expand( + version: project.version + '-' + project.ext.buildNumber, + mcversion: "1.21.11" + ) + } +} + +shadowJar { + dependencies { + include(dependency(':DynmapCore')) + include(dependency("commons-codec:commons-codec:")) + exclude("META-INF/maven/**") + exclude("META-INF/services/**") + } + relocate('org.apache.commons.codec', 'org.dynmap.forge_1_21_11.commons.codec') + + archiveBaseName = "Dynmap" + archiveClassifier = "forge-1.21.11" + destinationDirectory = file '../target' +} + +shadowJar.doLast { + task -> + ant.checksum file: task.archivePath +} + +build.dependsOn(shadowJar) diff --git a/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/ClientProxy.java b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/ClientProxy.java new file mode 100644 index 000000000..d76cdbc67 --- /dev/null +++ b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/ClientProxy.java @@ -0,0 +1,6 @@ +package org.dynmap.forge_1_21_11; + +public class ClientProxy extends Proxy { + public ClientProxy() { + } +} diff --git a/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/DynmapMod.java b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/DynmapMod.java new file mode 100644 index 000000000..3f5bc5521 --- /dev/null +++ b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/DynmapMod.java @@ -0,0 +1,112 @@ +package org.dynmap.forge_1_21_11; + +import java.io.File; + +import org.apache.commons.lang3.tuple.Pair; +import org.dynmap.DynmapCommonAPI; +import org.dynmap.DynmapCommonAPIListener; +import org.dynmap.Log; +import org.dynmap.forge_1_21_11.DynmapPlugin.OurLog; + +import net.minecraft.server.MinecraftServer; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.server.ServerAboutToStartEvent; +import net.minecraftforge.event.server.ServerStartedEvent; +import net.minecraftforge.event.server.ServerStartingEvent; +import net.minecraftforge.event.server.ServerStoppingEvent; +import net.minecraftforge.eventbus.api.bus.BusGroup; +import net.minecraftforge.eventbus.api.bus.EventBus; +import net.minecraftforge.eventbus.api.listener.SubscribeEvent; +import net.minecraftforge.fml.DistExecutor; +import net.minecraftforge.fml.IExtensionPoint; +import net.minecraftforge.fml.ModList; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; + +@Mod("dynmap") +public class DynmapMod +{ + // The instance of your mod that Forge uses. + public static DynmapMod instance; + public static BusGroup modBusGroup; + + // Says where the client and server 'proxy' code is loaded. + public static Proxy proxy = DistExecutor.runForDist(() -> ClientProxy::new, () -> Proxy::new); + + public static DynmapPlugin plugin; + public static File jarfile; + public static String ver; + public static boolean useforcedchunks; + + public class APICallback extends DynmapCommonAPIListener { + @Override + public void apiListenerAdded() { + if(plugin == null) { + plugin = proxy.startServer(server); + } + } + @Override + public void apiEnabled(DynmapCommonAPI api) { + } + } + + public DynmapMod(FMLJavaModLoadingContext context) { + instance = this; + + modBusGroup = context.getModBusGroup(); + + // Register the commonSetup method for modloading + FMLCommonSetupEvent.getBus(modBusGroup).addListener(this::setup); + + ServerStartedEvent.BUS.addListener(this::onServerStarted); + ServerAboutToStartEvent.BUS.addListener(this::onServerStarting); + ServerStoppingEvent.BUS.addListener(this::onServerStopping); + + context.registerExtensionPoint(IExtensionPoint.DisplayTest.class, + ()->new IExtensionPoint.DisplayTest(()->IExtensionPoint.DisplayTest.IGNORESERVERONLY, (remote, isServer)-> true)); + + Log.setLogger(new OurLog()); + org.dynmap.modsupport.ModSupportImpl.init(); + } + + public void setup(final FMLCommonSetupEvent event) + { + //TOOO + jarfile = ModList.get().getModFileById("dynmap").getFile().getFilePath().toFile(); + + ver = ModList.get().getModContainerById("dynmap").get().getModInfo().getVersion().toString(); + + //// Load configuration file - use suggested (config/WesterosBlocks.cfg) + //Configuration cfg = new Configuration(event.getSuggestedConfigurationFile()); + //try { + // cfg.load(); + // + // useforcedchunks = cfg.get("Settings", "UseForcedChunks", true).getBoolean(true); + //} + //finally + //{ + // cfg.save(); + //} + } + + private MinecraftServer server; + + public void onServerStarting(ServerAboutToStartEvent event) { + server = event.getServer(); + if(plugin == null) + plugin = proxy.startServer(server); + plugin.onStarting(server.getCommands().getDispatcher()); + } + + public void onServerStarted(ServerStartedEvent event) { + DynmapCommonAPIListener.register(new APICallback()); + plugin.serverStarted(); + } + + public void onServerStopping(ServerStoppingEvent event) + { + proxy.stopServer(plugin); + plugin = null; + } +} diff --git a/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/DynmapPlugin.java b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/DynmapPlugin.java new file mode 100644 index 000000000..d02010d88 --- /dev/null +++ b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/DynmapPlugin.java @@ -0,0 +1,2076 @@ +package org.dynmap.forge_1_21_11; + +import java.io.File; +import java.io.InputStream; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Base64; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.PriorityQueue; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.Callable; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; +import java.util.regex.Pattern; + +import net.minecraft.commands.CommandSource; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.core.BlockPos; +import net.minecraft.core.IdMapper; +import net.minecraft.core.Registry; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.Connection; +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket; +import net.minecraft.resources.Identifier; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.server.players.NameAndId; +import net.minecraft.server.players.UserBanList; +import net.minecraft.tags.BlockTags; +import net.minecraft.world.entity.Pose; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.LiquidBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.phys.Vec3; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.ServerChatEvent; +import net.minecraftforge.event.TickEvent; +import net.minecraftforge.event.TickEvent.ServerTickEvent; +import net.minecraftforge.event.entity.player.PlayerEvent.PlayerChangedDimensionEvent; +import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedInEvent; +import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedOutEvent; +import net.minecraftforge.event.entity.player.PlayerEvent.PlayerRespawnEvent; +import net.minecraftforge.event.level.BlockEvent; +import net.minecraftforge.event.level.ChunkDataEvent; +import net.minecraftforge.event.level.ChunkEvent; +import net.minecraftforge.event.level.LevelEvent; +import net.minecraftforge.eventbus.api.listener.Priority; +import net.minecraftforge.eventbus.api.listener.SubscribeEvent; +import net.minecraftforge.fml.ModList; +import net.minecraftforge.fml.ModContainer; +import net.minecraftforge.fml.loading.LoadingModList; +import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo; +import net.minecraftforge.fml.loading.moddiscovery.ModInfo; +import net.minecraft.world.level.chunk.status.ChunkStatus; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.maven.artifact.versioning.ArtifactVersion; +import org.dynmap.ConfigurationNode; +import org.dynmap.DynmapChunk; +import org.dynmap.DynmapCommonAPIListener; +import org.dynmap.DynmapCore; +import org.dynmap.DynmapLocation; +import org.dynmap.DynmapWorld; +import org.dynmap.Log; +import org.dynmap.MapManager; +import org.dynmap.PlayerList; +import org.dynmap.common.BiomeMap; +import org.dynmap.common.DynmapCommandSender; +import org.dynmap.common.DynmapPlayer; +import org.dynmap.common.DynmapServerInterface; +import org.dynmap.common.DynmapListenerManager.EventType; +import org.dynmap.common.chunk.GenericChunkCache; +import org.dynmap.forge_1_21_11.DmapCommand; +import org.dynmap.forge_1_21_11.DmarkerCommand; +import org.dynmap.forge_1_21_11.DynmapCommand; +import org.dynmap.forge_1_21_11.permissions.FilePermissions; +import org.dynmap.forge_1_21_11.permissions.OpPermissions; +import org.dynmap.forge_1_21_11.permissions.PermissionProvider; +import org.dynmap.permissions.PermissionsHandler; +import org.dynmap.renderer.DynmapBlockState; +import org.dynmap.utils.DynmapLogger; +import org.dynmap.utils.MapChunkCache; +import org.dynmap.utils.VisibilityLimit; + +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.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.builder.RequiredArgumentBuilder; +import com.mojang.brigadier.exceptions.CommandSyntaxException; + +import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; +import it.unimi.dsi.fastutil.longs.LongOpenHashSet; + +public class DynmapPlugin +{ + private DynmapCore core; + private PermissionProvider permissions; + private boolean core_enabled; + public GenericChunkCache sscache; + public PlayerList playerList; + private MapManager mapManager; + private static net.minecraft.server.MinecraftServer server; + public static DynmapPlugin plugin; + private HashMap sortWeights = new HashMap(); + // Drop world load ticket after 30 seconds + private long worldIdleTimeoutNS = 30 * 1000000000L; + private HashMap worlds = new HashMap(); + private LevelAccessor last_world; + private ForgeWorld last_fworld; + private Map players = new HashMap(); + //TODO private ForgeMetrics metrics; + private HashSet modsused = new HashSet(); + private ForgeServer fserver = new ForgeServer(); + private boolean tickregistered = false; + // TPS calculator + private double tps; + private long lasttick; + private long avgticklen; + // Per tick limit, in nsec + private long perTickLimit = (50000000); // 50 ms + private boolean useSaveFolder = true; + + private static final String[] TRIGGER_DEFAULTS = { "blockupdate", "chunkpopulate", "chunkgenerate" }; + + private static final Pattern patternControlCode = Pattern.compile("(?i)\\u00A7[0-9A-FK-OR]"); + + public static class BlockUpdateRec { + LevelAccessor w; + String wid; + int x, y, z; + } + ConcurrentLinkedQueue blockupdatequeue = new ConcurrentLinkedQueue(); + + public static DynmapBlockState[] stateByID; + + private Map knownloadedchunks = new HashMap(); + private boolean didInitialKnownChunks = false; + private void addKnownChunk(ForgeWorld fw, ChunkPos pos) { + LongOpenHashSet cset = knownloadedchunks.get(fw.getName()); + if (cset == null) { + cset = new LongOpenHashSet(); + knownloadedchunks.put(fw.getName(), cset); + } + cset.add(pos.toLong()); + } + private void removeKnownChunk(ForgeWorld fw, ChunkPos pos) { + LongOpenHashSet cset = knownloadedchunks.get(fw.getName()); + if (cset != null) { + cset.remove(pos.toLong()); + } + } + private boolean checkIfKnownChunk(ForgeWorld fw, ChunkPos pos) { + LongOpenHashSet cset = knownloadedchunks.get(fw.getName()); + if (cset != null) { + return cset.contains(pos.toLong()); + } + return false; + } + + private static Registry reg = null; + + private static Registry getBiomeReg() { + if (reg == null) { + reg = server.registryAccess().lookup(Registries.BIOME).get(); + } + return reg; + } + + /** + * Initialize block states (org.dynmap.blockstate.DynmapBlockState) + */ + public void initializeBlockStates() { + stateByID = new DynmapBlockState[512*32]; // Simple map - scale as needed + Arrays.fill(stateByID, DynmapBlockState.AIR); // Default to air + + IdMapper bsids = Block.BLOCK_STATE_REGISTRY; + + DynmapBlockState basebs = null; + Block baseb = null; + int baseidx = 0; + + Iterator iter = bsids.iterator(); + DynmapBlockState.Builder bld = new DynmapBlockState.Builder(); + while (iter.hasNext()) { + BlockState bs = iter.next(); + int idx = bsids.getId(bs); + if (idx >= stateByID.length) { + int plen = stateByID.length; + stateByID = Arrays.copyOf(stateByID, idx*11/10); // grow array by 10% + Arrays.fill(stateByID, plen, stateByID.length, DynmapBlockState.AIR); + } + Block b = bs.getBlock(); + // If this is new block vs last, it's the base block state + if (b != baseb) { + basebs = null; + baseidx = idx; + baseb = b; + } + Identifier ui = BuiltInRegistries.BLOCK.getKey(b); + + if (ui == null) { + continue; + } + String bn = ui.getNamespace() + ":" + ui.getPath(); + // Only do defined names, and not "air" + if (!bn.equals(DynmapBlockState.AIR_BLOCK)) { + String statename = ""; + for (net.minecraft.world.level.block.state.properties.Property p : bs.getProperties()) { + if (statename.length() > 0) { + statename += ","; + } + statename += p.getName() + "=" + bs.getValue(p).toString(); + } + int lightAtten = 15; + try { // Workaround for mods with broken block state logic... + lightAtten = bs.isSolidRender() ? 15 : (bs.propagatesSkylightDown() ? 0 : 1); + } catch (Exception x) { + Log.warning(String.format("Exception while checking lighting data for block state: %s[%s]", bn, statename)); + Log.verboseinfo("Exception: " + x.toString()); + } + //Log.info("statename=" + bn + "[" + statename + "], lightAtten=" + lightAtten); + // Fill in base attributes + bld.setBaseState(basebs).setStateIndex(idx - baseidx).setBlockName(bn).setStateName(statename).setLegacyBlockID(idx).setAttenuatesLight(lightAtten); + if (bs.getSoundType() != null) { bld.setMaterial(bs.getSoundType().toString()); } + if (bs.isSolid()) { bld.setSolid(); } + if (bs.isAir()) { bld.setAir(); } + if (bs.is(BlockTags.LOGS)) { bld.setLog(); } + if (bs.is(BlockTags.LEAVES)) { bld.setLeaves(); } + if ((!bs.getFluidState().isEmpty()) && !(bs.getBlock() instanceof LiquidBlock)) { + bld.setWaterlogged(); + } + DynmapBlockState dbs = bld.build(); // Build state + stateByID[idx] = dbs; + if (basebs == null) { basebs = dbs; } + } + } + for (int gidx = 0; gidx < DynmapBlockState.getGlobalIndexMax(); gidx++) { + DynmapBlockState bs = DynmapBlockState.getStateByGlobalIndex(gidx); + //Log.info(gidx + ":" + bs.toString() + ", gidx=" + bs.globalStateIndex + ", sidx=" + bs.stateIndex); + } + } + + //public static final Item getItemByID(int id) { + // return Item.getItemById(id); + //} + + private static Biome[] biomelist = null; + + public static final Biome[] getBiomeList() { + if (biomelist == null) { + biomelist = new Biome[256]; + Iterator iter = getBiomeReg().iterator(); + while (iter.hasNext()) { + Biome b = iter.next(); + int bidx = getBiomeReg().getId(b); + if (bidx >= biomelist.length) { + biomelist = Arrays.copyOf(biomelist, bidx + biomelist.length); + } + biomelist[bidx] = b; + } + } + return biomelist; + } + //public static final NetworkManager getNetworkManager(ServerPlayNetHandler nh) { + // return nh.netManager; + //} + + private ForgePlayer getOrAddPlayer(ServerPlayer p) { + String name = p.getName().getString(); + ForgePlayer fp = players.get(name); + if(fp != null) { + fp.player = p; + } + else { + fp = new ForgePlayer(p); + players.put(name, fp); + } + return fp; + } + + private static class TaskRecord implements Comparable + { + private long ticktorun; + private long id; + private FutureTask future; + @Override + public int compareTo(Object o) + { + TaskRecord tr = (TaskRecord)o; + + if (this.ticktorun < tr.ticktorun) + { + return -1; + } + else if (this.ticktorun > tr.ticktorun) + { + return 1; + } + else if (this.id < tr.id) + { + return -1; + } + else if (this.id > tr.id) + { + return 1; + } + else + { + return 0; + } + } + } + + private class ChatMessage { + String message; + ServerPlayer sender; + } + private ConcurrentLinkedQueue msgqueue = new ConcurrentLinkedQueue(); + + private boolean handleChatRegistered = false; + public void handleChat(final ServerChatEvent event) { + String msg = event.getMessage().getString(); + if(!msg.startsWith("/")) { + ChatMessage cm = new ChatMessage(); + cm.message = msg; + cm.sender = event.getPlayer(); + msgqueue.add(cm); + } + } + + /** TODO: depends on forge chunk manager + private static class WorldBusyRecord { + long last_ts; + Ticket ticket; + } + private static HashMap busy_worlds = new HashMap(); + + private void setBusy(World w) { + setBusy(w, null); + } + static void setBusy(World w, Ticket t) { + if(w == null) return; + if (!DynmapMod.useforcedchunks) return; + WorldBusyRecord wbr = busy_worlds.get(w.provider.getDimension()); + if(wbr == null) { // Not busy, make ticket and keep spawn loaded + Debug.debug("World " + w.getWorldInfo().getWorldName() + "/"+ w.provider.getDimensionType().getName() + " is busy"); + wbr = new WorldBusyRecord(); + if(t != null) + wbr.ticket = t; + else + wbr.ticket = ForgeChunkManager.requestTicket(DynmapMod.instance, w, ForgeChunkManager.Type.NORMAL); + if(wbr.ticket != null) { + BlockPos cc = w.getSpawnPoint(); + ChunkPos ccip = new ChunkPos(cc.getX() >> 4, cc.getZ() >> 4); + ForgeChunkManager.forceChunk(wbr.ticket, ccip); + busy_worlds.put(w.provider.getDimension(), wbr); // Add to busy list + } + } + wbr.last_ts = System.nanoTime(); + } + + private void doIdleOutOfWorlds() { + if (!DynmapMod.useforcedchunks) return; + long ts = System.nanoTime() - worldIdleTimeoutNS; + for(Iterator itr = busy_worlds.values().iterator(); itr.hasNext();) { + WorldBusyRecord wbr = itr.next(); + if(wbr.last_ts < ts) { + World w = wbr.ticket.world; + Debug.debug("World " + w.getWorldInfo().getWorldName() + "/" + wbr.ticket.world.provider.getDimensionType().getName() + " is idle"); + if (wbr.ticket != null) + ForgeChunkManager.releaseTicket(wbr.ticket); // Release hold on world + itr.remove(); + } + } + } + */ + + public static class OurLog implements DynmapLogger { + Logger log; + public static final String DM = "[Dynmap] "; + OurLog() { + log = LogManager.getLogger("Dynmap"); + } + @Override + public void info(String s) { + log.info(DM + s); + } + + @Override + public void severe(Throwable t) { + log.fatal(t); + } + + @Override + public void severe(String s) { + log.fatal(DM + s); + } + + @Override + public void severe(String s, Throwable t) { + log.fatal(DM + s, t); + } + + @Override + public void verboseinfo(String s) { + log.info(DM + s); + } + + @Override + public void warning(String s) { + log.warn(DM + s); + } + + @Override + public void warning(String s, Throwable t) { + log.warn(DM + s, t); + } + } + + public DynmapPlugin(MinecraftServer srv) + { + plugin = this; + this.server = srv; + } + + public boolean isOp(String player) { + String[] ops = server.getPlayerList().getOps().getUserList(); + for (String op : ops) { + if (op.equalsIgnoreCase(player)) { + return true; + } + } + return (server.isSingleplayer() && player.equalsIgnoreCase(server.getSingleplayerProfile().name())); + } + + private boolean hasPerm(ServerPlayer psender, String permission) { + PermissionsHandler ph = PermissionsHandler.getHandler(); + if ((psender != null) && (ph != null) && ph.hasPermission(psender.getName().getString(), permission)) { + return true; + } + return permissions.has(psender, permission); + } + + private boolean hasPermNode(ServerPlayer psender, String permission) { + PermissionsHandler ph = PermissionsHandler.getHandler(); + if ((psender != null) && (ph != null) && ph.hasPermissionNode(psender.getName().getString(), permission)) { + return true; + } + return permissions.hasPermissionNode(psender, permission); + } + + private Set hasOfflinePermissions(String player, Set perms) { + Set rslt = null; + PermissionsHandler ph = PermissionsHandler.getHandler(); + if(ph != null) { + rslt = ph.hasOfflinePermissions(player, perms); + } + Set rslt2 = hasOfflinePermissions(player, perms); + if((rslt != null) && (rslt2 != null)) { + Set newrslt = new HashSet(rslt); + newrslt.addAll(rslt2); + rslt = newrslt; + } + else if(rslt2 != null) { + rslt = rslt2; + } + return rslt; + } + private boolean hasOfflinePermission(String player, String perm) { + PermissionsHandler ph = PermissionsHandler.getHandler(); + if(ph != null) { + if(ph.hasOfflinePermission(player, perm)) { + return true; + } + } + return permissions.hasOfflinePermission(player, perm); + } + + /** + * Server access abstraction class + */ + public class ForgeServer extends DynmapServerInterface + { + /* Server thread scheduler */ + private Object schedlock = new Object(); + private long cur_tick; + private long next_id; + private long cur_tick_starttime; + private PriorityQueue runqueue = new PriorityQueue(); + + public ForgeServer() { + } + + private NameAndId getNameAndIdByName(String player) { + ServerPlayer p = server.getPlayerList().getPlayer(player); + return (p != null) ? new NameAndId(p.getGameProfile()) : null; + } + + @Override + public int getBlockIDAt(String wname, int x, int y, int z) { + return -1; + } + + @Override + public int isSignAt(String wname, int x, int y, int z) { + return -1; + } + + @Override + public void scheduleServerTask(Runnable run, long delay) + { + TaskRecord tr = new TaskRecord(); + tr.future = new FutureTask(run, null); + + /* Add task record to queue */ + synchronized (schedlock) + { + tr.id = next_id++; + tr.ticktorun = cur_tick + delay; + runqueue.add(tr); + } + } + @Override + public DynmapPlayer[] getOnlinePlayers() + { + if(server.getPlayerList() == null) + return new DynmapPlayer[0]; + List playlist = server.getPlayerList().getPlayers(); + int pcnt = playlist.size(); + DynmapPlayer[] dplay = new DynmapPlayer[pcnt]; + + for (int i = 0; i < pcnt; i++) + { + ServerPlayer p = playlist.get(i); + dplay[i] = getOrAddPlayer(p); + } + + return dplay; + } + @Override + public void reload() + { + plugin.onDisable(); + plugin.onEnable(); + plugin.onStart(); + } + @Override + public DynmapPlayer getPlayer(String name) + { + List players = server.getPlayerList().getPlayers(); + + for (ServerPlayer p : players) + { + if (p.getName().getString().equalsIgnoreCase(name)) + { + return getOrAddPlayer(p); + } + } + + return null; + } + @Override + public Set getIPBans() + { + UserBanList bl = server.getPlayerList().getBans(); + Set ips = new HashSet(); + + for (String s : bl.getUserList()) { + ips.add(s); + } + + return ips; + } + @Override + public Future callSyncMethod(Callable task) { + return callSyncMethod(task, 0); + } + public Future callSyncMethod(Callable task, long delay) + { + TaskRecord tr = new TaskRecord(); + FutureTask ft = new FutureTask(task); + tr.future = ft; + + /* Add task record to queue */ + synchronized (schedlock) + { + tr.id = next_id++; + tr.ticktorun = cur_tick + delay; + runqueue.add(tr); + } + + return ft; + } + @Override + public String getServerName() + { + String sn; + if (server.isSingleplayer()) + sn = "Integrated"; + else + sn = server.getLocalIp(); + if(sn == null) sn = "Unknown Server"; + return sn; + } + @Override + public boolean isPlayerBanned(String pid) + { + UserBanList bl = server.getPlayerList().getBans(); + NameAndId nid = getNameAndIdByName(pid); + return (nid != null) ? bl.isBanned(nid) : false; + } + + @Override + public String stripChatColor(String s) + { + return patternControlCode.matcher(s).replaceAll(""); + } + private Set registered = new HashSet(); + @Override + public boolean requestEventNotification(EventType type) + { + if (registered.contains(type)) + { + return true; + } + + switch (type) + { + case WORLD_LOAD: + case WORLD_UNLOAD: + /* Already called for normal world activation/deactivation */ + break; + + case WORLD_SPAWN_CHANGE: + /*TODO + pm.registerEvents(new Listener() { + @EventHandler(priority=EventPriority.MONITOR) + public void onSpawnChange(SpawnChangeEvent evt) { + DynmapWorld w = new BukkitWorld(evt.getWorld()); + core.listenerManager.processWorldEvent(EventType.WORLD_SPAWN_CHANGE, w); + } + }, DynmapPlugin.this); + */ + break; + + case PLAYER_JOIN: + case PLAYER_QUIT: + /* Already handled */ + break; + + case PLAYER_BED_LEAVE: + /*TODO + pm.registerEvents(new Listener() { + @EventHandler(priority=EventPriority.MONITOR) + public void onPlayerBedLeave(PlayerBedLeaveEvent evt) { + DynmapPlayer p = new BukkitPlayer(evt.getPlayer()); + core.listenerManager.processPlayerEvent(EventType.PLAYER_BED_LEAVE, p); + } + }, DynmapPlugin.this); + */ + break; + + case PLAYER_CHAT: + if (!handleChatRegistered) { + handleChatRegistered = true; + ServerChatEvent.BUS.addListener(DynmapPlugin.this::handleChat); + } + break; + + case BLOCK_BREAK: + /*TODO + pm.registerEvents(new Listener() { + @EventHandler(priority=EventPriority.MONITOR) + public void onBlockBreak(BlockBreakEvent evt) { + if(evt.isCancelled()) return; + Block b = evt.getBlock(); + if(b == null) return; + Location l = b.getLocation(); + core.listenerManager.processBlockEvent(EventType.BLOCK_BREAK, b.getType().getId(), + BukkitWorld.normalizeWorldName(l.getWorld().getName()), l.getBlockX(), l.getBlockY(), l.getBlockZ()); + } + }, DynmapPlugin.this); + */ + break; + + case SIGN_CHANGE: + /*TODO + pm.registerEvents(new Listener() { + @EventHandler(priority=EventPriority.MONITOR) + public void onSignChange(SignChangeEvent evt) { + if(evt.isCancelled()) return; + Block b = evt.getBlock(); + Location l = b.getLocation(); + String[] lines = evt.getLines(); + DynmapPlayer dp = null; + Player p = evt.getPlayer(); + if(p != null) dp = new BukkitPlayer(p); + core.listenerManager.processSignChangeEvent(EventType.SIGN_CHANGE, b.getType().getId(), + BukkitWorld.normalizeWorldName(l.getWorld().getName()), l.getBlockX(), l.getBlockY(), l.getBlockZ(), lines, dp); + } + }, DynmapPlugin.this); + */ + break; + + default: + Log.severe("Unhandled event type: " + type); + return false; + } + + registered.add(type); + return true; + } + @Override + public boolean sendWebChatEvent(String source, String name, String msg) + { + return DynmapCommonAPIListener.fireWebChatEvent(source, name, msg); + } + @Override + public void broadcastMessage(String msg) + { + Component component = Component.literal(msg); + server.getPlayerList().broadcastSystemMessage(component, false); + Log.info(stripChatColor(msg)); + } + @Override + public String[] getBiomeIDs() + { + BiomeMap[] b = BiomeMap.values(); + String[] bname = new String[b.length]; + + for (int i = 0; i < bname.length; i++) + { + bname[i] = b[i].toString(); + } + + return bname; + } + @Override + public double getCacheHitRate() + { + if(sscache != null) + return sscache.getHitRate(); + return 0.0; + } + @Override + public void resetCacheStats() + { + if(sscache != null) + sscache.resetStats(); + } + @Override + public DynmapWorld getWorldByName(String wname) + { + return DynmapPlugin.this.getWorldByName(wname); + } + @Override + public DynmapPlayer getOfflinePlayer(String name) + { + /* + OfflinePlayer op = getServer().getOfflinePlayer(name); + if(op != null) { + return new BukkitPlayer(op); + } + */ + return null; + } + @Override + public Set checkPlayerPermissions(String player, Set perms) + { + net.minecraft.server.players.PlayerList scm = server.getPlayerList(); + if (scm == null) return Collections.emptySet(); + UserBanList bl = scm.getBans(); + if (bl == null) return Collections.emptySet(); + if (isPlayerBanned(player)) { + return Collections.emptySet(); + } + Set rslt = hasOfflinePermissions(player, perms); + if (rslt == null) { + rslt = new HashSet(); + if(plugin.isOp(player)) { + rslt.addAll(perms); + } + } + return rslt; + } + @Override + public boolean checkPlayerPermission(String player, String perm) + { + net.minecraft.server.players.PlayerList scm = server.getPlayerList(); + if (scm == null) return false; + UserBanList bl = scm.getBans(); + if (bl == null) return false; + if (isPlayerBanned(player)) { + return false; + } + return hasOfflinePermission(player, perm); + } + /** + * Render processor helper - used by code running on render threads to request chunk snapshot cache from server/sync thread + */ + @Override + public MapChunkCache createMapChunkCache(DynmapWorld w, List chunks, + boolean blockdata, boolean highesty, boolean biome, boolean rawbiome) + { + ForgeMapChunkCache c = (ForgeMapChunkCache) w.getChunkCache(chunks); + if(c == null) { + return null; + } + if (w.visibility_limits != null) + { + for (VisibilityLimit limit: w.visibility_limits) + { + c.setVisibleRange(limit); + } + + c.setHiddenFillStyle(w.hiddenchunkstyle); + } + + if (w.hidden_limits != null) + { + for (VisibilityLimit limit: w.hidden_limits) + { + c.setHiddenRange(limit); + } + + c.setHiddenFillStyle(w.hiddenchunkstyle); + } + + if (chunks.size() == 0) /* No chunks to get? */ + { + c.loadChunks(0); + return c; + } + + //Now handle any chunks in server thread that are already loaded (on server thread) + final ForgeMapChunkCache cc = c; + Future f = this.callSyncMethod(new Callable() { + public Boolean call() throws Exception { + // Update busy state on world + ForgeWorld fw = (ForgeWorld)cc.getWorld(); + //TODO + //setBusy(fw.getWorld()); + cc.getLoadedChunks(); + return true; + } + }, 0); + try { + f.get(); + } + catch (CancellationException cx) { + return null; + } + catch (InterruptedException cx) { + return null; + } + catch (ExecutionException xx) { + Log.severe("Exception while loading chunks", xx.getCause()); + return null; + } + catch (Exception ix) { + Log.severe(ix); + return null; + } + if(w.isLoaded() == false) { + return null; + } + // Now, do rest of chunk reading from calling thread + c.readChunks(chunks.size()); + + return c; + } + @Override + public int getMaxPlayers() + { + return server.getMaxPlayers(); + } + @Override + public int getCurrentPlayers() + { + return server.getPlayerList().getPlayerCount(); + } + + @SubscribeEvent + public void tickEvent(TickEvent.ServerTickEvent.Post event) { + cur_tick_starttime = System.nanoTime(); + long elapsed = cur_tick_starttime - lasttick; + lasttick = cur_tick_starttime; + avgticklen = ((avgticklen * 99) / 100) + (elapsed / 100); + tps = (double)1E9 / (double)avgticklen; + // Tick core + if (core != null) { + core.serverTick(tps); + } + + boolean done = false; + TaskRecord tr = null; + + while(!blockupdatequeue.isEmpty()) { + BlockUpdateRec r = blockupdatequeue.remove(); + BlockState bs = r.w.getBlockState(new BlockPos(r.x, r.y, r.z)); + int idx = Block.BLOCK_STATE_REGISTRY.getId(bs); + if((idx >= 0) && (!org.dynmap.hdmap.HDBlockModels.isChangeIgnoredBlock(stateByID[idx]))) { + if(onblockchange_with_id) + mapManager.touch(r.wid, r.x, r.y, r.z, "blockchange[" + idx + "]"); + else + mapManager.touch(r.wid, r.x, r.y, r.z, "blockchange"); + } + } + + long now; + + synchronized(schedlock) { + cur_tick++; + now = System.nanoTime(); + tr = runqueue.peek(); + /* Nothing due to run */ + if((tr == null) || (tr.ticktorun > cur_tick) || ((now - cur_tick_starttime) > perTickLimit)) { + done = true; + } + else { + tr = runqueue.poll(); + } + } + while (!done) { + tr.future.run(); + + synchronized(schedlock) { + tr = runqueue.peek(); + now = System.nanoTime(); + /* Nothing due to run */ + if((tr == null) || (tr.ticktorun > cur_tick) || ((now - cur_tick_starttime) > perTickLimit)) { + done = true; + } + else { + tr = runqueue.poll(); + } + } + } + while(!msgqueue.isEmpty()) { + ChatMessage cm = msgqueue.poll(); + DynmapPlayer dp = null; + if(cm.sender != null) + dp = getOrAddPlayer(cm.sender); + else + dp = new ForgePlayer(null); + + core.listenerManager.processChatEvent(EventType.PLAYER_CHAT, dp, cm.message); + } + // Check for generated chunks + if((cur_tick % 20) == 0) { + } + } + + @Override + public boolean isModLoaded(String name) { + boolean loaded = ModList.get().isLoaded(name); + if (loaded) { + modsused.add(name); + } + return loaded; + } + @Override + public String getModVersion(String name) { + Optional mod = ModList.get().getModContainerById(name); // Try case sensitive lookup + if (mod.isPresent()) { + ArtifactVersion vi = mod.get().getModInfo().getVersion(); + return vi.getMajorVersion() + "." + vi.getMinorVersion() + "." + vi.getIncrementalVersion(); + } + return null; + } + @Override + public double getServerTPS() { + return tps; + } + + @Override + public String getServerIP() { + if (server.isSingleplayer()) + return "0.0.0.0"; + else + return server.getLocalIp(); + } + @Override + public File getModContainerFile(String name) { + ModFileInfo mfi = LoadingModList.get().getModFileById(name); // Try case sensitive lookup + if (mfi != null) { + try { + File f = mfi.getFile().getFilePath().toFile(); + return f; + } + catch (UnsupportedOperationException ex) { + //TODO Implement proper jar in jar method for fetching data +/* + Log.info("Searching for: " + name); + for (IModInfo e: ModList.get().getMods()) { + Log.info("in: " + e.getModId().toString()); + Log.info("resource: "+ ModList.get().getModFileById(e.getModId()).getFile().findResource(String.valueOf(mfi.getFile().getFilePath()))); + } +*/ + Log.warning("jar in jar method found, skipping: " + ex.getMessage()); + } + } + return null; + } + @Override + public List getModList() { + List mil = LoadingModList.get().getMods(); + List lst = new ArrayList(); + for (ModInfo mi : mil) { + lst.add(mi.getModId()); + } + return lst; + } + + @Override + public Map getBlockIDMap() { + Map map = new HashMap(); + return map; + } + + @Override + public InputStream openResource(String modid, String rname) { + if (modid == null) modid = "minecraft"; + + Optional mc = ModList.get().getModContainerById(modid); + Object mod = (mc.isPresent()) ? mc.get().getMod() : null; + if (mod != null) { + ClassLoader cl = mod.getClass().getClassLoader(); + if (cl == null) cl = ClassLoader.getSystemClassLoader(); + InputStream is = cl.getResourceAsStream(rname); + if (is != null) { + return is; + } + } + List mcl = LoadingModList.get().getMods(); + for (ModInfo mci : mcl) { + mc = ModList.get().getModContainerById(mci.getModId()); + mod = (mc.isPresent()) ? mc.get().getMod() : null; + if (mod == null) continue; + ClassLoader cl = mod.getClass().getClassLoader(); + if (cl == null) cl = ClassLoader.getSystemClassLoader(); + InputStream is = cl.getResourceAsStream(rname); + if (is != null) { + return is; + } + } + return null; + } + /** + * Get block unique ID map (module:blockid) + */ + @Override + public Map getBlockUniqueIDMap() { + HashMap map = new HashMap(); + return map; + } + /** + * Get item unique ID map (module:itemid) + */ + @Override + public Map getItemUniqueIDMap() { + HashMap map = new HashMap(); + return map; + } + + } + private static final Gson gson = new GsonBuilder().create(); + + public class TexturesPayload { + public long timestamp; + public String profileId; + public String profileName; + public boolean isPublic; + public Map textures; + + } + public class ProfileTexture { + public String url; + } + + /** + * Player access abstraction class + */ + public class ForgePlayer extends ForgeCommandSender implements DynmapPlayer + { + private ServerPlayer player; + private final String skinurl; + private final UUID uuid; + + + public ForgePlayer(ServerPlayer p) + { + player = p; + String url = null; + if (player != null) { + uuid = player.getUUID(); + GameProfile prof = player.getGameProfile(); + if (prof != null) { + Property textureProperty = Iterables.getFirst(prof.properties().get("textures"), null); + + if (textureProperty != null) { + TexturesPayload result = null; + try { + String json = new String(Base64.getDecoder().decode(textureProperty.value()), StandardCharsets.UTF_8); + result = gson.fromJson(json, TexturesPayload.class); + } catch (JsonParseException e) { + } + if ((result != null) && (result.textures != null) && (result.textures.containsKey("SKIN"))) { + url = result.textures.get("SKIN").url; + } + } + } + } + else { + uuid = null; + } + skinurl = url; + } + @Override + public boolean isConnected() + { + return true; + } + @Override + public String getName() + { + if(player != null) { + String n = player.getName().getString();; + return n; + } + else + return "[Server]"; + } + @Override + public String getDisplayName() + { + if(player != null) { + String n = player.getDisplayName().getString(); + return n; + } + else + return "[Server]"; + } + @Override + public boolean isOnline() + { + return true; + } + @Override + public DynmapLocation getLocation() + { + if (player == null) { + return null; + } + Vec3 v = player.position(); + return toLoc(player.level(), v.x, v.y, v.z); + } + @Override + public String getWorld() + { + if (player == null) + { + return null; + } + + if (player.level() != null) + { + return DynmapPlugin.this.getWorld((ServerLevel)player.level()).getName(); + } + + return null; + } + public static final Connection getNetworkManager(ServerGamePacketListenerImpl nh) { + return nh.getConnection(); + } + + @Override + public InetSocketAddress getAddress() + { + if((player != null) && (player instanceof ServerPlayer)) { + ServerGamePacketListenerImpl nsh = ((ServerPlayer)player).connection; + if((nsh != null) && (getNetworkManager(nsh) != null)) { + SocketAddress sa = getNetworkManager(nsh).getRemoteAddress(); + if(sa instanceof InetSocketAddress) { + return (InetSocketAddress)sa; + } + } + } + return null; + } + @Override + public boolean isSneaking() + { + if (player != null) + { + return player.getPose() == Pose.CROUCHING; + } + + return false; + } + @Override + public double getHealth() + { + if (player != null) + { + double h = player.getHealth(); + if(h > 20) h = 20; + return h; // Scale to 20 range + } + else + { + return 0; + } + } + @Override + public int getArmorPoints() + { + if (player != null) + { + return player.getArmorValue(); + } + else + { + return 0; + } + } + @Override + public DynmapLocation getBedSpawnLocation() + { + return null; + } + @Override + public long getLastLoginTime() + { + return 0; + } + @Override + public long getFirstLoginTime() + { + return 0; + } + @Override + public boolean hasPrivilege(String privid) + { + if(player != null) + return hasPerm(player, privid); + return false; + } + @Override + public boolean isOp() + { + return DynmapPlugin.this.isOp(player.getName().getString()); + } + @Override + public void sendMessage(String msg) + { + Component ichatcomponent = Component.literal(msg); + player.sendSystemMessage(ichatcomponent); + } + @Override + public boolean isInvisible() { + if(player != null) { + return player.isInvisible(); + } + return false; + } + @Override + public boolean isSpectator() { + if(player != null) { + return player.isSpectator(); + } + return false; + } + @Override + public int getSortWeight() { + Integer wt = sortWeights.get(getName()); + if (wt != null) + return wt; + return 0; + } + @Override + public void setSortWeight(int wt) { + if (wt == 0) { + sortWeights.remove(getName()); + } + else { + sortWeights.put(getName(), wt); + } + } + @Override + public boolean hasPermissionNode(String node) { + if(player != null) + return hasPermNode(player, node); + return false; + } + @Override + public String getSkinURL() { + return skinurl; + } + @Override + public UUID getUUID() { + return uuid; + } + /** + * Send title and subtitle text (called from server thread) + */ + @Override + public void sendTitleText(String title, String subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks) { + if (player instanceof ServerPlayer) { + ServerPlayer mp = (ServerPlayer) player; + ClientboundSetTitlesAnimationPacket times = new ClientboundSetTitlesAnimationPacket(fadeInTicks, stayTicks, fadeOutTicks); + mp.connection.send(times); + if (title != null) { + ClientboundSetTitleTextPacket titlepkt = new ClientboundSetTitleTextPacket(Component.literal(title)); + mp.connection.send(titlepkt); + } + + if (subtitle != null) { + ClientboundSetSubtitleTextPacket subtitlepkt = new ClientboundSetSubtitleTextPacket(Component.literal(subtitle)); + mp.connection.send(subtitlepkt); + } + } + } + } + /* Handler for generic console command sender */ + public class ForgeCommandSender implements DynmapCommandSender + { + private CommandSourceStack sender; + + protected ForgeCommandSender() { + sender = null; + } + + public ForgeCommandSender(CommandSourceStack send) + { + sender = send; + } + + @Override + public boolean hasPrivilege(String privid) + { + return true; + } + + @Override + public void sendMessage(String msg) + { + if(sender != null) { + Component ichatcomponent = Component.literal(msg); + sender.sendSuccess(() -> ichatcomponent, true); + } + } + + @Override + public boolean isConnected() + { + return false; + } + @Override + public boolean isOp() + { + return true; + } + @Override + public boolean hasPermissionNode(String node) { + return true; + } + } + + public void loadExtraBiomes(String mcver) { + int cnt = 0; + BiomeMap.loadWellKnownByVersion(mcver); + + Biome[] list = getBiomeList(); + + for (int i = 0; i < list.length; i++) { + Biome bb = list[i]; + if (bb != null) { + Identifier regid = getBiomeReg().getKey(bb); + String id = regid.getPath(); + String rl = regid.toString(); + float tmp = bb.getBaseTemperature(), hum = bb.getModifiedClimateSettings().downfall(); + int watermult = bb.getWaterColor(); + Log.verboseinfo("biome[" + i + "]: hum=" + hum + ", tmp=" + tmp + ", mult=" + Integer.toHexString(watermult)); + + BiomeMap bmap = BiomeMap.NULL; + if (rl != null) { // If resource location, lookup by this + bmap = BiomeMap.byBiomeResourceLocation(rl); + } + else { + bmap = BiomeMap.byBiomeID(i); + } + if (bmap.isDefault() || (bmap == BiomeMap.NULL)) { + bmap = new BiomeMap((rl != null) ? BiomeMap.NO_INDEX : i, id, tmp, hum, rl); + Log.verboseinfo("Add custom biome [" + bmap.toString() + "] (" + i + ")"); + cnt++; + } + else { + bmap.setTemperature(tmp); + bmap.setRainfall(hum); + } + if (watermult != -1) { + bmap.setWaterColorMultiplier(watermult); + Log.verboseinfo("Set watercolormult for " + bmap.toString() + " (" + i + ") to " + Integer.toHexString(watermult)); + } + bmap.setBiomeObject(bb); + } + } + if(cnt > 0) + Log.info("Added " + cnt + " custom biome mappings"); + } + + private String[] getBiomeNames() { + Biome[] list = getBiomeList(); + String[] lst = new String[list.length]; + for(int i = 0; i < list.length; i++) { + Biome bb = list[i]; + if (bb != null) { + lst[i] = bb.toString(); + } + } + return lst; + } + + public void onEnable() + { + /* Get MC version */ + String mcver = server.getServerVersion(); + /* Load extra biomes */ + loadExtraBiomes(mcver); + /* Set up player login/quit event handler */ + registerPlayerLoginListener(); + + /* Initialize permissions handler */ + permissions = FilePermissions.create(); + if(permissions == null) { + permissions = new OpPermissions(new String[] { "webchat", "marker.icons", "marker.list", "webregister", "stats", "hide.self", "show.self" }); + } + /* Get and initialize data folder */ + File dataDirectory = new File("dynmap"); + + if (dataDirectory.exists() == false) + { + dataDirectory.mkdirs(); + } + + /* Instantiate core */ + if (core == null) + { + core = new DynmapCore(); + } + + /* Inject dependencies */ + core.setPluginJarFile(DynmapMod.jarfile); + core.setPluginVersion(DynmapMod.ver); + core.setMinecraftVersion(mcver); + core.setDataFolder(dataDirectory); + core.setServer(fserver); + core.setTriggerDefault(TRIGGER_DEFAULTS); + core.setBiomeNames(getBiomeNames()); + + if(!core.initConfiguration(null)) + { + return; + } + // Extract default permission example, if needed + File filepermexample = new File(core.getDataFolder(), "permissions.yml.example"); + core.createDefaultFileFromResource("/permissions.yml.example", filepermexample); + + DynmapCommonAPIListener.apiInitialized(core); + } + + private static int test(CommandSource source) throws CommandSyntaxException + { + Log.warning(source.toString()); + return 1; + } + + private DynmapCommand dynmapCmd; + private DmapCommand dmapCmd; + private DmarkerCommand dmarkerCmd; + private DynmapExpCommand dynmapexpCmd; + + public void onStarting(CommandDispatcher cd) { + /* Register command hander */ + dynmapCmd = new DynmapCommand(this); + dmapCmd = new DmapCommand(this); + dmarkerCmd = new DmarkerCommand(this); + dynmapexpCmd = new DynmapExpCommand(this); + dynmapCmd.register(cd); + dmapCmd.register(cd); + dmarkerCmd.register(cd); + dynmapexpCmd.register(cd); + + Log.info("Register commands"); + } + + public void onStart() { + initializeBlockStates(); + /* Enable core */ + if (!core.enableCore(null)) + { + return; + } + core_enabled = true; + VersionCheck.runCheck(core); + // Get per tick time limit + perTickLimit = core.getMaxTickUseMS() * 1000000; + // Prep TPS + lasttick = System.nanoTime(); + tps = 20.0; + + /* Register tick handler */ + if(!tickregistered) { + ServerTickEvent.Post.BUS.addListener(fserver::tickEvent); + tickregistered = true; + } + + playerList = core.playerList; + sscache = new GenericChunkCache(core.getSnapShotCacheSize(), core.useSoftRefInSnapShotCache()); + /* Get map manager from core */ + mapManager = core.getMapManager(); + + /* Load saved world definitions */ + loadWorlds(); + + /* Initialized the currently loaded worlds */ + for (ServerLevel world : server.getAllLevels()) { + ForgeWorld w = this.getWorld(world); + } + for(ForgeWorld w : worlds.values()) { + if (core.processWorldLoad(w)) { /* Have core process load first - fire event listeners if good load after */ + if(w.isLoaded()) { + core.listenerManager.processWorldEvent(EventType.WORLD_LOAD, w); + } + } + } + core.updateConfigHashcode(); + + /* Register our update trigger events */ + registerEvents(); + Log.info("Register events"); + + //DynmapCommonAPIListener.apiInitialized(core); + + Log.info("Enabled"); + } + + public void onDisable() + { + DynmapCommonAPIListener.apiTerminated(); + + //if (metrics != null) { + // metrics.stop(); + // metrics = null; + //} + /* Save worlds */ + saveWorlds(); + + /* Purge tick queue */ + fserver.runqueue.clear(); + + /* Disable core */ + core.disableCore(); + core_enabled = false; + + if (sscache != null) + { + sscache.cleanup(); + sscache = null; + } + + Log.info("Disabled"); + } + + void onCommand(CommandSourceStack commandSourceStack, String cmd, String[] args) + { + DynmapCommandSender dsender; + ServerPlayer psender; + try { + psender = commandSourceStack.getPlayerOrException(); + } catch (com.mojang.brigadier.exceptions.CommandSyntaxException x) { + psender = null; + } + + if (psender != null) + { + dsender = new ForgePlayer(psender); + } + else + { + dsender = new ForgeCommandSender(commandSourceStack); + } + try { + core.processCommand(dsender, cmd, cmd, args); + } catch (Exception x) { + dsender.sendMessage("Command internal error: " + x.getMessage()); + Log.severe("Error with command: " + cmd + Arrays.deepToString(args), x); + } + } + + private DynmapLocation toLoc(ServerLevel level, double x, double y, double z) + { + return new DynmapLocation(DynmapPlugin.this.getWorld(level).getName(), x, y, z); + } + + public class PlayerTracker { + @SubscribeEvent + public void onPlayerLogin(PlayerLoggedInEvent event) { + if(!core_enabled) return; + final DynmapPlayer dp = getOrAddPlayer((ServerPlayer)event.getEntity()); + /* This event can be called from off server thread, so push processing there */ + core.getServer().scheduleServerTask(new Runnable() { + public void run() { + core.listenerManager.processPlayerEvent(EventType.PLAYER_JOIN, dp); + } + }, 2); + } + @SubscribeEvent + public void onPlayerLogout(PlayerLoggedOutEvent event) { + if(!core_enabled) return; + final DynmapPlayer dp = getOrAddPlayer((ServerPlayer)event.getEntity()); + final String name = event.getEntity().getName().getString(); + /* This event can be called from off server thread, so push processing there */ + core.getServer().scheduleServerTask(new Runnable() { + public void run() { + core.listenerManager.processPlayerEvent(EventType.PLAYER_QUIT, dp); + players.remove(name); + } + }, 0); + } + @SubscribeEvent + public void onPlayerChangedDimension(PlayerChangedDimensionEvent event) { + if(!core_enabled) return; + getOrAddPlayer((ServerPlayer)event.getEntity()); // Freshen player object reference + } + @SubscribeEvent + public void onPlayerRespawn(PlayerRespawnEvent event) { + if(!core_enabled) return; + getOrAddPlayer((ServerPlayer)event.getEntity()); // Freshen player object reference + } + } + private PlayerTracker playerTracker = null; + + private void registerPlayerLoginListener() + { + if (playerTracker == null) { + playerTracker = new PlayerTracker(); + MinecraftForge.EVENT_BUS.register(playerTracker); + } + } + + public class WorldTracker { + @SubscribeEvent(priority=Priority.MONITOR) + public void handleWorldLoad(LevelEvent.Load event) { + if(!core_enabled) return; + LevelAccessor w = event.getLevel(); + if(!(w instanceof ServerLevel)) return; + final ForgeWorld fw = getWorld((ServerLevel)w); + // This event can be called from off server thread, so push processing there + core.getServer().scheduleServerTask(new Runnable() { + public void run() { + if(core.processWorldLoad(fw)) // Have core process load first - fire event listeners if good load after + core.listenerManager.processWorldEvent(EventType.WORLD_LOAD, fw); + } + }, 0); + } + @SubscribeEvent(priority=Priority.MONITOR) + public void handleWorldUnload(LevelEvent.Unload event) { + if(!core_enabled) return; + LevelAccessor w = event.getLevel(); + if(!(w instanceof ServerLevel)) return; + final ForgeWorld fw = getWorld((ServerLevel)w); + if(fw != null) { + // This event can be called from off server thread, so push processing there + core.getServer().scheduleServerTask(new Runnable() { + public void run() { + core.listenerManager.processWorldEvent(EventType.WORLD_UNLOAD, fw); + core.processWorldUnload(fw); + } + }, 0); + // Set world unloaded (needs to be immediate, since it may be invalid after event) + fw.setWorldUnloaded(); + // Clean up tracker + //WorldUpdateTracker wut = updateTrackers.remove(fw.getName()); + //if(wut != null) wut.world = null; + } + } + + private void touchChunk(ForgeWorld fw, ChunkAccess c, String cause) { + int ymax = Integer.MIN_VALUE; + int ymin = Integer.MAX_VALUE; + LevelChunkSection[] sections = c.getSections(); + // If no sections, assume all + if (sections.length == 0) { + ymax = (c.getMaxSectionY()+1) << 4; + ymin = c.getMinSectionY() << 4; + } + else { + for(int i = 0; i < sections.length; i++) { + if((sections[i] != null) && (sections[i].hasOnlyAir() == false)) { + int sy = c.getSectionYFromSectionIndex(i) << 4; + if (sy < ymin) ymin = sy; + if ((sy+16) > ymax) ymax = sy + 16; + } + } + } + ChunkPos cp = c.getPos(); + int x = cp.x << 4; + int z = cp.z << 4; + // If not empty AND not initial scan + if (ymax != Integer.MIN_VALUE) { + mapManager.touchVolume(fw.getName(), x, ymin, z, x+15, ymax, z+15, "chunkgenerate"); + } + } + + @SubscribeEvent(priority=Priority.MONITOR) + public void handleChunkLoad(ChunkEvent.Load event) { + LevelAccessor w = event.getLevel(); + if (!(w instanceof ServerLevel)) return; + ChunkAccess c = event.getChunk(); + if ((c != null) && (c.getPersistedStatus() == ChunkStatus.FULL)) { + ForgeWorld fw = getWorld((ServerLevel)w, false); + if (fw != null) { + addKnownChunk(fw, c.getPos()); + } + } + } + @SubscribeEvent(priority=Priority.MONITOR) + public void handleChunkLightingCalculated(ChunkEvent.LightingCalculated event) { + LevelAccessor w = event.getLevel(); + if (!(w instanceof ServerLevel)) return; + ChunkAccess c = event.getChunk(); + if (c != null) { + ForgeWorld fw = getWorld((ServerLevel)w, false); + if (fw != null) { + touchChunk(fw, c, "lighting"); + if (c.getPersistedStatus() == ChunkStatus.FULL) { + addKnownChunk(fw, c.getPos()); + } + } + } + } + + @SubscribeEvent(priority=Priority.MONITOR) + public void handleChunkUnload(ChunkEvent.Unload event) { + LevelAccessor w = event.getLevel(); + if (!(w instanceof ServerLevel)) return; + ChunkAccess c = event.getChunk(); + if (c != null) { + ForgeWorld fw = getWorld((ServerLevel)w, false); + ChunkPos cp = c.getPos(); + if (fw != null) { + if (!checkIfKnownChunk(fw, cp)) { + touchChunk(fw, c, "unload"); + } + removeKnownChunk(fw, cp); + } + } + } + @SubscribeEvent(priority=Priority.MONITOR) + public void handleChunkDataSave(ChunkDataEvent.Save event) { + LevelAccessor w = event.getLevel(); + if (!(w instanceof ServerLevel)) return; + ChunkAccess c = event.getChunk(); + if (c != null) { + ForgeWorld fw = getWorld((ServerLevel)w, false); + ChunkPos cp = c.getPos(); + if (fw != null) { + touchChunk(fw, c, "datasave"); + // If cooked, add to known + if (c.getPersistedStatus() == ChunkStatus.FULL) { + addKnownChunk(fw, cp); + } + } + } + } + @SubscribeEvent(priority=Priority.MONITOR) + public void handleBlockToolModificationEvent(BlockEvent.BlockToolModificationEvent event) { + handleBlockEvent(event); + } + @SubscribeEvent(priority=Priority.MONITOR) + public void handleBreakEvent(BlockEvent.BreakEvent event) { + handleBlockEvent(event); + } + @SubscribeEvent(priority=Priority.MONITOR) + public void handleCropGrowEvent(BlockEvent.CropGrowEvent event) { + handleBlockEvent(event); + } + @SubscribeEvent(priority=Priority.MONITOR) + public void handleEntityPlaceEvent(BlockEvent.EntityPlaceEvent event) { + handleBlockEvent(event); + } + @SubscribeEvent(priority=Priority.MONITOR) + public void handleFluidPlaceBlockEvent(BlockEvent.FluidPlaceBlockEvent event) { + handleBlockEvent(event); + } + @SubscribeEvent(priority=Priority.MONITOR) + public void handleNeighborNotifyEvent(BlockEvent.NeighborNotifyEvent event) { + handleBlockEvent(event); + } + @SubscribeEvent(priority=Priority.MONITOR) + public void handlePortalSpawnEvent(BlockEvent.PortalSpawnEvent event) { + handleBlockEvent(event); + } + private void handleBlockEvent(BlockEvent event) { + if(!core_enabled) return; + BlockUpdateRec r = new BlockUpdateRec(); + r.w = event.getLevel(); + if(!(r.w instanceof ServerLevel)) return; // band-aid to prevent errors in unsupported 'running in client' scenario + ForgeWorld fw = getWorld((ServerLevel)r.w, false); + if (fw == null) return; + r.wid = fw.getName(); + BlockPos p = event.getPos(); + r.x = p.getX(); + r.y = p.getY(); + r.z = p.getZ(); + blockupdatequeue.add(r); + } + } + private WorldTracker worldTracker = null; + private boolean onblockchange = false; + private boolean onchunkpopulate = false; + private boolean onchunkgenerate = false; + private boolean onblockchange_with_id = false; + + private void registerEvents() + { + // To trigger rendering. + onblockchange = core.isTrigger("blockupdate"); + onchunkpopulate = core.isTrigger("chunkpopulate"); + onchunkgenerate = core.isTrigger("chunkgenerate"); + onblockchange_with_id = core.isTrigger("blockupdate-with-id"); + if(onblockchange_with_id) + onblockchange = true; + if ((worldTracker == null) && (onblockchange || onchunkpopulate || onchunkgenerate)) { + worldTracker = new WorldTracker(); + LevelEvent.Load.BUS.addListener(worldTracker::handleWorldLoad); + LevelEvent.Unload.BUS.addListener(worldTracker::handleWorldUnload); + if (onchunkgenerate) { + ChunkEvent.Load.BUS.addListener(worldTracker::handleChunkLoad); + ChunkDataEvent.Save.BUS.addListener(worldTracker::handleChunkDataSave); + ChunkEvent.LightingCalculated.BUS.addListener(worldTracker::handleChunkLightingCalculated); + } + if (onblockchange) { + BlockEvent.BlockToolModificationEvent.BUS.addListener(worldTracker::handleBlockToolModificationEvent); + BlockEvent.BreakEvent.BUS.addListener(worldTracker::handleBreakEvent); + BlockEvent.CropGrowEvent.BUS.addListener(worldTracker::handleCropGrowEvent); + BlockEvent.EntityPlaceEvent.BUS.addListener(worldTracker::handleEntityPlaceEvent); + BlockEvent.FluidPlaceBlockEvent.BUS.addListener(worldTracker::handleFluidPlaceBlockEvent); + BlockEvent.NeighborNotifyEvent.BUS.addListener(worldTracker::handleNeighborNotifyEvent); + BlockEvent.PortalSpawnEvent.BUS.addListener(worldTracker::handlePortalSpawnEvent); + } + } + // Prime the known full chunks + if (onchunkgenerate && (server.getAllLevels() != null)) { + for (ServerLevel world : server.getAllLevels()) { + ForgeWorld fw = getWorld(world); + if (fw == null) continue; + Long2ObjectLinkedOpenHashMap chunks = world.getChunkSource().chunkMap.visibleChunkMap; + for (Entry k : chunks.long2ObjectEntrySet()) { + long key = k.getKey().longValue(); + ChunkHolder ch = k.getValue(); + ChunkAccess c = null; + try { + c = ch.getChunkToSend(); + } catch (Exception x) { } + if (c == null) continue; + ChunkStatus cs = c.getPersistedStatus(); + ChunkPos pos = ch.getPos(); + if (cs == ChunkStatus.FULL) { // Cooked? + // Add it as known + addKnownChunk(fw, pos); + } + } + } + } + } + + private ForgeWorld getWorldByName(String name) { + return worlds.get(name); + } + + private ForgeWorld getWorld(ServerLevel w) { + return getWorld(w, true); + } + + private ForgeWorld getWorld(ServerLevel w, boolean add_if_not_found) { + if(last_world == w) { + return last_fworld; + } + String wname = ForgeWorld.getWorldName(w); + + for(ForgeWorld fw : worlds.values()) { + if(fw.getRawName().equals(wname)) { + last_world = w; + last_fworld = fw; + if(fw.isLoaded() == false) { + fw.setWorldLoaded(w); + } + fw.updateWorld(w); + return fw; + } + } + ForgeWorld fw = null; + if(add_if_not_found) { + /* Add to list if not found */ + fw = new ForgeWorld(w); + worlds.put(fw.getName(), fw); + } + last_world = w; + last_fworld = fw; + return fw; + } + + private void saveWorlds() { + File f = new File(core.getDataFolder(), "forgeworlds.yml"); + ConfigurationNode cn = new ConfigurationNode(f); + ArrayList> lst = new ArrayList>(); + for(DynmapWorld fw : core.mapManager.getWorlds()) { + HashMap vals = new HashMap(); + vals.put("name", fw.getRawName()); + vals.put("height", fw.worldheight); + vals.put("miny", fw.minY); + vals.put("sealevel", fw.sealevel); + vals.put("nether", fw.isNether()); + vals.put("the_end", ((ForgeWorld)fw).isTheEnd()); + vals.put("title", fw.getTitle()); + lst.add(vals); + } + cn.put("worlds", lst); + cn.put("useSaveFolderAsName", useSaveFolder); + cn.put("maxWorldHeight", ForgeWorld.getMaxWorldHeight()); + + cn.save(); + } + private void loadWorlds() { + File f = new File(core.getDataFolder(), "forgeworlds.yml"); + if(f.canRead() == false) { + useSaveFolder = true; + return; + } + ConfigurationNode cn = new ConfigurationNode(f); + cn.load(); + // If defined, use maxWorldHeight + ForgeWorld.setMaxWorldHeight(cn.getInteger("maxWorldHeight", 256)); + + // If setting defined, use it + if (cn.containsKey("useSaveFolderAsName")) { + useSaveFolder = cn.getBoolean("useSaveFolderAsName", useSaveFolder); + } + List> lst = cn.getMapList("worlds"); + if(lst == null) { + Log.warning("Discarding bad forgeworlds.yml"); + return; + } + + for(Map world : lst) { + try { + String name = (String)world.get("name"); + int height = (Integer)world.get("height"); + Integer miny = (Integer) world.get("miny"); + int sealevel = (Integer)world.get("sealevel"); + boolean nether = (Boolean)world.get("nether"); + boolean theend = (Boolean)world.get("the_end"); + String title = (String)world.get("title"); + if(name != null) { + ForgeWorld fw = new ForgeWorld(name, height, sealevel, nether, theend, title, (miny != null) ? miny : 0); + fw.setWorldUnloaded(); + core.processWorldLoad(fw); + worlds.put(fw.getName(), fw); + } + } catch (Exception x) { + Log.warning("Unable to load saved worlds from forgeworlds.yml"); + return; + } + } + } + public void serverStarted() { + this.onStart(); + if (core != null) { + core.serverStarted(); + } + } + public MinecraftServer getMCServer() { + return server; + } +} + +class DynmapCommandHandler +{ + private String cmd; + private DynmapPlugin plugin; + + public DynmapCommandHandler(String cmd, DynmapPlugin p) + { + this.cmd = cmd; + this.plugin = p; + } + + public void register(CommandDispatcher cd) { + cd.register(Commands.literal(cmd). + then(RequiredArgumentBuilder. argument("args", StringArgumentType.greedyString()). + executes((ctx) -> this.execute(plugin.getMCServer(), ctx.getSource(), ctx.getInput()))). + executes((ctx) -> this.execute(plugin.getMCServer(), ctx.getSource(), ctx.getInput()))); + } + +// @Override + public int execute(MinecraftServer server, CommandSourceStack commandSourceStack, + String cmdline) { + String[] args = cmdline.split("\\s+"); + plugin.onCommand(commandSourceStack, cmd, Arrays.copyOfRange(args, 1, args.length)); + return 1; + } + +// @Override + public String getUsage(CommandSource arg0) { + return "Run /" + cmd + " help for details on using command"; + } +} + +class DynmapCommand extends DynmapCommandHandler { + DynmapCommand(DynmapPlugin p) { + super("dynmap", p); + } +} +class DmapCommand extends DynmapCommandHandler { + DmapCommand(DynmapPlugin p) { + super("dmap", p); + } +} +class DmarkerCommand extends DynmapCommandHandler { + DmarkerCommand(DynmapPlugin p) { + super("dmarker", p); + } +} +class DynmapExpCommand extends DynmapCommandHandler { + DynmapExpCommand(DynmapPlugin p) { + super("dynmapexp", p); + } +} + diff --git a/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/ForgeMapChunkCache.java b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/ForgeMapChunkCache.java new file mode 100644 index 000000000..65843cdec --- /dev/null +++ b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/ForgeMapChunkCache.java @@ -0,0 +1,110 @@ +package org.dynmap.forge_1_21_11; + +import java.util.List; +import java.util.NoSuchElementException; + +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeSpecialEffects; +import org.dynmap.DynmapChunk; +import org.dynmap.Log; +import org.dynmap.common.BiomeMap; +import org.dynmap.common.chunk.GenericChunk; +import org.dynmap.common.chunk.GenericChunkCache; +import org.dynmap.common.chunk.GenericMapChunkCache; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerChunkCache; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.status.ChunkStatus; +import net.minecraft.world.level.chunk.storage.SerializableChunkData; + +/** + * Container for managing chunks - dependent upon using chunk snapshots, since + * rendering is off server thread + */ +public class ForgeMapChunkCache extends GenericMapChunkCache { + private ServerLevel w; + private ServerChunkCache cps; + /** + * Construct empty cache + */ + public ForgeMapChunkCache(GenericChunkCache cc) { + super(cc); + } + + // Load generic chunk from existing and already loaded chunk + protected GenericChunk getLoadedChunk(DynmapChunk chunk) { + GenericChunk gc = null; + ChunkAccess ch = cps.getChunk(chunk.x, chunk.z, ChunkStatus.FULL, false); + if (ch != null) { + SerializableChunkData sc = SerializableChunkData.copyOf(w, cps.getChunk(chunk.x, chunk.z, false)); + CompoundTag nbt = sc.write(); + if (nbt != null) { + gc = parseChunkFromNBT(new NBT.NBTCompound(nbt)); + } + } + return gc; + } + // Load generic chunk from unloaded chunk + protected GenericChunk loadChunk(DynmapChunk chunk) { + GenericChunk gc = null; + CompoundTag nbt = readChunk(chunk.x, chunk.z); + // If read was good + if (nbt != null) { + gc = parseChunkFromNBT(new NBT.NBTCompound(nbt)); + } + return gc; + } + + public void setChunks(ForgeWorld dw, List chunks) { + this.w = dw.getWorld(); + if (dw.isLoaded()) { + /* Check if world's provider is ServerChunkProvider */ + cps = this.w.getChunkSource(); + } + super.setChunks(dw, chunks); + } + + private CompoundTag readChunk(int x, int z) { + try { + CompoundTag rslt = cps.chunkMap.read(new ChunkPos(x, z)).join().get(); + if (rslt != null) { + CompoundTag lev = rslt; + if (lev.contains("Level")) { + lev = lev.getCompoundOrEmpty("Level"); + } + // Don't load uncooked chunks + String stat = lev.getStringOr("Status", null); + ChunkStatus cs = ChunkStatus.byName(stat); + if ((stat == null) || + // Needs to be at least lighted + (!cs.isOrAfter(ChunkStatus.LIGHT))) { + rslt = null; + } + } + // Log.info(String.format("loadChunk(%d,%d)=%s", x, z, (rslt != null) ? + // rslt.toString() : "null")); + return rslt; + } catch (NoSuchElementException nsex) { + return null; + } catch (Exception exc) { + Log.severe(String.format("Error reading chunk: %s,%d,%d", dw.getName(), x, z), exc); + return null; + } + } + @Override + public int getFoliageColor(BiomeMap bm, int[] colormap, int x, int z) { + return bm.getBiomeObject().map(Biome::getSpecialEffects). + flatMap(effects -> effects.foliageColorOverride()) + .orElse(colormap[bm.biomeLookup()]); + } + + @Override + public int getGrassColor(BiomeMap bm, int[] colormap, int x, int z) { + BiomeSpecialEffects effects = bm.getBiomeObject().map(Biome::getSpecialEffects).orElse(null); + if (effects == null) return colormap[bm.biomeLookup()]; + return effects.grassColorModifier().modifyColor(x, z, effects.grassColorOverride().orElse(colormap[bm.biomeLookup()])); + } +} diff --git a/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/ForgeWorld.java b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/ForgeWorld.java new file mode 100644 index 000000000..d48f6461a --- /dev/null +++ b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/ForgeWorld.java @@ -0,0 +1,249 @@ +package org.dynmap.forge_1_21_11; +/** + * Forge specific implementation of DynmapWorld + */ +import java.util.List; + +import net.minecraft.world.level.ServerLevelAccessor; +import net.minecraft.world.level.border.WorldBorder; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LightLayer; + +import org.dynmap.DynmapChunk; +import org.dynmap.DynmapLocation; +import org.dynmap.DynmapWorld; +import org.dynmap.utils.MapChunkCache; +import org.dynmap.utils.Polygon; + +public class ForgeWorld extends DynmapWorld +{ + private ServerLevelAccessor world; + private final boolean skylight; + private final boolean isnether; + private final boolean istheend; + private final String env; + private DynmapLocation spawnloc = new DynmapLocation(); + private static int maxWorldHeight = 320; // Maximum allows world height + + public static int getMaxWorldHeight() { + return maxWorldHeight; + } + public static void setMaxWorldHeight(int h) { + maxWorldHeight = h; + } + + public static String getWorldName(ServerLevelAccessor w) { + ResourceKey rk = w.getLevel().dimension(); + String id = rk.identifier().getNamespace() + "_" + rk.identifier().getPath(); + if (id.equals("minecraft_overworld")) { // Overworld? + return w.getLevel().serverLevelData.getLevelName(); + } + else if (id.equals("minecraft_the_end")) { + return "DIM1"; + } + else if (id.equals("minecraft_the_nether")) { + return "DIM-1"; + } + else { + return id; + } + } + + public void updateWorld(ServerLevelAccessor w) { + this.updateWorldHeights(w.getLevel().getHeight(), w.getLevel().dimensionType().minY(), w.getLevel().getSeaLevel()); + } + + public ForgeWorld(ServerLevelAccessor w) + { + this(getWorldName(w), + w.getLevel().getHeight(), + w.getLevel().getSeaLevel(), + w.getLevel().dimension() == Level.NETHER, + w.getLevel().dimension() == Level.END, + getWorldName(w), + w.getLevel().dimensionType().minY()); + setWorldLoaded(w); + } + public ForgeWorld(String name, int height, int sealevel, boolean nether, boolean the_end, String deftitle, int miny) + { + super(name, (height > maxWorldHeight)?maxWorldHeight:height, sealevel, miny); + world = null; + setTitle(deftitle); + isnether = nether; + istheend = the_end; + skylight = !(isnether || istheend); + + if (isnether) + { + env = "nether"; + } + else if (istheend) + { + env = "the_end"; + } + else + { + env = "normal"; + } + //Log.info(getName() + ": skylight=" + skylight + ", height=" + this.worldheight + ", isnether=" + isnether + ", istheend=" + istheend); + } + /* Test if world is nether */ + @Override + public boolean isNether() + { + return isnether; + } + public boolean isTheEnd() + { + return istheend; + } + /* Get world spawn location */ + @Override + public DynmapLocation getSpawnLocation() + { + if(world != null) { + BlockPos p = world.getLevel().getRespawnData().pos(); + spawnloc.x = p.getX(); + spawnloc.y = p.getY(); + spawnloc.z = p.getZ(); + spawnloc.world = this.getName(); + } + return spawnloc; + } + /* Get world time */ + @Override + public long getTime() + { + if(world != null) + return world.getLevel().getDayTime(); + else + return -1; + } + /* World is storming */ + @Override + public boolean hasStorm() + { + if(world != null) + return world.getLevel().isRaining(); + else + return false; + } + /* World is thundering */ + @Override + public boolean isThundering() + { + if(world != null) + return world.getLevel().isThundering(); + else + return false; + } + /* World is loaded */ + @Override + public boolean isLoaded() + { + return (world != null); + } + /* Set world to unloaded */ + @Override + public void setWorldUnloaded() + { + getSpawnLocation(); + world = null; + } + /* Set world to loaded */ + public void setWorldLoaded(ServerLevelAccessor w) { + world = w; + this.sealevel = w.getLevel().getSeaLevel(); // Read actual current sealevel from world + // Update lighting table + for (int i = 0; i < 16; i++) { + // Algorithm based on LightmapTextureManager.getBrightness() + // We can't call that method because it's client-only. + // This means the code below can stop being correct if Mojang ever + // updates the curve; in that case we should reflect the changes. + float value = (float) i / 15.0f; + float brightness = value / (4.0f - 3.0f * value); + this.setBrightnessTableEntry(i, brightness); + //Log.info(getName() + ": light " + i + " = " + light); + } + } + /* Get light level of block */ + @Override + public int getLightLevel(int x, int y, int z) + { + if(world != null) + return world.getLevel().getLightEngine().getRawBrightness(new BlockPos(x, y, z), 0); + else + return -1; + } + /* Get highest Y coord of given location */ + @Override + public int getHighestBlockYAt(int x, int z) + { + if(world != null) { + return world.getLevel().getChunk(x >> 4, z >> 4).getHeight(Heightmap.Types.MOTION_BLOCKING, x & 15, z & 15); + } + else + return -1; + } + /* Test if sky light level is requestable */ + @Override + public boolean canGetSkyLightLevel() + { + return skylight; + } + /* Return sky light level */ + @Override + public int getSkyLightLevel(int x, int y, int z) + { + if(world != null) { + return world.getLevel().getBrightness(LightLayer.SKY, new BlockPos(x, y, z)); + } + else + return -1; + } + /** + * Get world environment ID (lower case - normal, the_end, nether) + */ + @Override + public String getEnvironment() + { + return env; + } + /** + * Get map chunk cache for world + */ + @Override + public MapChunkCache getChunkCache(List chunks) + { + if (world != null) { + ForgeMapChunkCache c = new ForgeMapChunkCache(DynmapPlugin.plugin.sscache); + c.setChunks(this, chunks); + return c; + } + return null; + } + + public ServerLevel getWorld() + { + return world.getLevel(); + } + @Override + public Polygon getWorldBorder() { + if (world != null) { + WorldBorder wb = world.getWorldBorder(); + if ((wb != null) && (wb.getSize() < 5.9E7)) { + Polygon p = new Polygon(); + p.addVertex(wb.getMinX(), wb.getMinZ()); + p.addVertex(wb.getMinX(), wb.getMaxZ()); + p.addVertex(wb.getMaxX(), wb.getMaxZ()); + p.addVertex(wb.getMaxX(), wb.getMinZ()); + return p; + } + } + return null; + } +} diff --git a/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/NBT.java b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/NBT.java new file mode 100644 index 000000000..d2b19ca17 --- /dev/null +++ b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/NBT.java @@ -0,0 +1,138 @@ +package org.dynmap.forge_1_21_11; + +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.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.Tag; +import net.minecraft.util.SimpleBitStorage; + +public class NBT { + + public static class NBTCompound implements GenericNBTCompound { + private final CompoundTag obj; + public NBTCompound(CompoundTag t) { + this.obj = t; + } + @Override + public Set getAllKeys() { + return obj.keySet(); + } + @Override + public boolean contains(String s) { + return obj.contains(s); + } + @Override + public boolean contains(String s, int i) { + // Like contains, but with an extra constraint on type + Tag base = obj.get(s); + if (base == null) + return false; + byte type = base.getId(); + if (type == (byte) i) + return true; + else if (i != TAG_ANY_NUMERIC) + return false; + return type == TAG_BYTE || type == TAG_SHORT || type == TAG_INT || type == TAG_LONG || type == TAG_FLOAT + || type == TAG_DOUBLE; + } + @Override + public byte getByte(String s) { + return obj.getByteOr(s, (byte)0); + } + @Override + public short getShort(String s) { + return obj.getShortOr(s, (short)0); + } + @Override + public int getInt(String s) { + return obj.getIntOr(s, (int)0); + } + @Override + public long getLong(String s) { + return obj.getLongOr(s, (long)0); + } + @Override + public float getFloat(String s) { + return obj.getFloatOr(s, (float)0); + } + @Override + public double getDouble(String s) { + return obj.getDoubleOr(s, (double)0); + } + @Override + public String getString(String s) { + return obj.getStringOr(s, ""); + } + @Override + public byte[] getByteArray(String s) { + return obj.getByteArray(s).orElseGet(() -> new byte[0]); + } + @Override + public int[] getIntArray(String s) { + return obj.getIntArray(s).orElseGet(() -> new int[0]); + } + @Override + public long[] getLongArray(String s) { + return obj.getLongArray(s).orElseGet(() -> new long[0]); + } + @Override + public GenericNBTCompound getCompound(String s) { + return new NBTCompound(obj.getCompoundOrEmpty(s)); + } + @Override + public GenericNBTList getList(String s, int i) { + // i argument used to be used to constrain list type, but nbt lists no longer have types as of 1.21.5 + return new NBTList(obj.getListOrEmpty(s)); + } + @Override + public boolean getBoolean(String s) { + return obj.getBooleanOr(s, false); + } + @Override + public String getAsString(String s) { + return obj.get(s).asString().orElse(""); + } + @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 ListTag obj; + public NBTList(ListTag t) { + obj = t; + } + @Override + public int size() { + return obj.size(); + } + @Override + public String getString(int idx) { + return obj.getStringOr(idx, ""); + } + @Override + public GenericNBTCompound getCompound(int idx) { + return new NBTCompound(obj.getCompoundOrEmpty(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.get(idx); + } + } +} diff --git a/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/Proxy.java b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/Proxy.java new file mode 100644 index 000000000..883f5eac9 --- /dev/null +++ b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/Proxy.java @@ -0,0 +1,24 @@ +package org.dynmap.forge_1_21_11; + +import net.minecraft.server.MinecraftServer; + +/** + * Server side proxy - methods for creating and cleaning up plugin + */ +public class Proxy +{ + public Proxy() + { + } + public DynmapPlugin startServer(MinecraftServer srv) { + DynmapPlugin plugin = DynmapPlugin.plugin; + if (plugin == null) { + plugin = new DynmapPlugin(srv); + plugin.onEnable(); + } + return plugin; + } + public void stopServer(DynmapPlugin plugin) { + plugin.onDisable(); + } +} diff --git a/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/VersionCheck.java b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/VersionCheck.java new file mode 100644 index 000000000..2275fa23d --- /dev/null +++ b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/VersionCheck.java @@ -0,0 +1,97 @@ +package org.dynmap.forge_1_21_11; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +import org.dynmap.DynmapCore; +import org.dynmap.Log; + +public class VersionCheck { + private static final String VERSION_URL = "http://mikeprimm.com/dynmap/releases.php"; + public static void runCheck(final DynmapCore core) { + new Thread(new Runnable() { + public void run() { + doCheck(core); + } + }).start(); + } + + private static int getReleaseVersion(String s) { + int index = s.lastIndexOf('-'); + if(index < 0) + index = s.lastIndexOf('.'); + if(index >= 0) + s = s.substring(0, index); + String[] split = s.split("\\."); + int v = 0; + try { + for(int i = 0; (i < split.length) && (i < 3); i++) { + v += Integer.parseInt(split[i]) << (8 * (2 - i)); + } + } catch (NumberFormatException nfx) {} + return v; + } + + private static int getBuildNumber(String s) { + int index = s.lastIndexOf('-'); + if(index < 0) + index = s.lastIndexOf('.'); + if(index >= 0) + s = s.substring(index+1); + try { + return Integer.parseInt(s); + } catch (NumberFormatException nfx) { + return 99999999; + } + } + + private static void doCheck(DynmapCore core) { + String pluginver = core.getDynmapPluginVersion(); + String platform = core.getDynmapPluginPlatform(); + String platver = core.getDynmapPluginPlatformVersion(); + if((pluginver == null) || (platform == null) || (platver == null)) + return; + HttpURLConnection conn = null; + String loc = VERSION_URL; + int cur_ver = getReleaseVersion(pluginver); + int cur_bn = getBuildNumber(pluginver); + try { + while((loc != null) && (!loc.isEmpty())) { + URL url = new URL(loc); + conn = (HttpURLConnection) url.openConnection(); + conn.setRequestProperty("User-Agent", "Dynmap (" + platform + "/" + platver + "/" + pluginver); + conn.connect(); + loc = conn.getHeaderField("Location"); + } + BufferedReader rdr = new BufferedReader(new InputStreamReader(conn.getInputStream())); + String line = null; + while((line = rdr.readLine()) != null) { + String[] split = line.split(":"); + if(split.length < 4) continue; + /* If our platform and version, or wildcard platform version */ + if(split[0].equals(platform) && (split[1].equals("*") || split[1].equals(platver))) { + int recommended_ver = getReleaseVersion(split[2]); + int recommended_bn = getBuildNumber(split[2]); + if((recommended_ver > cur_ver) || ((recommended_ver == cur_ver) && (recommended_bn > cur_bn))) { /* Newer recommended build */ + Log.info("Version obsolete: new recommended version " + split[2] + " is available."); + } + else if(cur_ver > recommended_ver) { /* Running dev or prerelease? */ + int prerel_ver = getReleaseVersion(split[3]); + int prerel_bn = getBuildNumber(split[3]); + if((prerel_ver > cur_ver) || ((prerel_ver == cur_ver) && (prerel_bn > cur_bn))) { + Log.info("Version obsolete: new prerelease version " + split[3] + " is available."); + } + } + } + } + } catch (Exception x) { + Log.info("Error checking for latest version"); + } finally { + if(conn != null) { + conn.disconnect(); + } + } + } +} diff --git a/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/permissions/FilePermissions.java b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/permissions/FilePermissions.java new file mode 100644 index 000000000..955cefcef --- /dev/null +++ b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/permissions/FilePermissions.java @@ -0,0 +1,103 @@ +package org.dynmap.forge_1_21_11.permissions; + +import java.io.File; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.dynmap.ConfigurationNode; +import org.dynmap.Log; +import org.dynmap.forge_1_21_11.DynmapPlugin; + +import net.minecraft.server.level.ServerPlayer; + +public class FilePermissions implements PermissionProvider { + private HashMap> perms; + private Set defperms; + + public static FilePermissions create() { + File f = new File("dynmap/permissions.yml"); + if(!f.exists()) + return null; + ConfigurationNode cfg = new ConfigurationNode(f); + cfg.load(); + + Log.info("Using permissions.yml for access control"); + + return new FilePermissions(cfg); + } + + private FilePermissions(ConfigurationNode cfg) { + perms = new HashMap>(); + for(String k : cfg.keySet()) { + List p = cfg.getStrings(k, null); + if(p != null) { + k = k.toLowerCase(); + HashSet pset = new HashSet(); + for(String perm : p) { + pset.add(perm.toLowerCase()); + } + perms.put(k, pset); + if(k.equals("defaultuser")) { + defperms = pset; + } + } + } + } + + private boolean hasPerm(String player, String perm) { + Set ps = perms.get(player); + if((ps != null) && (ps.contains(perm))) { + return true; + } + if(defperms.contains(perm)) { + return true; + } + return false; + } + @Override + public Set hasOfflinePermissions(String player, Set perms) { + player = player.toLowerCase(); + HashSet rslt = new HashSet(); + if(DynmapPlugin.plugin.isOp(player)) { + rslt.addAll(perms); + } + else { + for(String p : perms) { + if(hasPerm(player, p)) { + rslt.add(p); + } + } + } + return rslt; + } + @Override + public boolean hasOfflinePermission(String player, String perm) { + player = player.toLowerCase(); + if(DynmapPlugin.plugin.isOp(player)) { + return true; + } + else { + return hasPerm(player, perm); + } + } + + @Override + public boolean has(ServerPlayer psender, String permission) { + if(psender != null) { + String n = psender.getName().getString().toLowerCase(); + return hasPerm(n, permission); + } + return true; + } + @Override + public boolean hasPermissionNode(ServerPlayer psender, String permission) { + if(psender != null) { + String player = psender.getName().getString().toLowerCase(); + return DynmapPlugin.plugin.isOp(player); + } + return false; + } + +} diff --git a/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/permissions/OpPermissions.java b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/permissions/OpPermissions.java new file mode 100644 index 000000000..497b2d883 --- /dev/null +++ b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/permissions/OpPermissions.java @@ -0,0 +1,51 @@ +package org.dynmap.forge_1_21_11.permissions; + +import java.util.HashSet; +import java.util.Set; + +import org.dynmap.Log; +import org.dynmap.forge_1_21_11.DynmapPlugin; + +import net.minecraft.server.level.ServerPlayer; + +public class OpPermissions implements PermissionProvider { + public HashSet usrCommands = new HashSet(); + + public OpPermissions(String[] usrCommands) { + for (String usrCommand : usrCommands) { + this.usrCommands.add(usrCommand); + } + Log.info("Using ops.txt for access control"); + } + + @Override + public Set hasOfflinePermissions(String player, Set perms) { + HashSet rslt = new HashSet(); + if(DynmapPlugin.plugin.isOp(player)) { + rslt.addAll(perms); + } + return rslt; + } + @Override + public boolean hasOfflinePermission(String player, String perm) { + return DynmapPlugin.plugin.isOp(player); + } + + @Override + public boolean has(ServerPlayer psender, String permission) { + if(psender != null) { + if(usrCommands.contains(permission)) { + return true; + } + return DynmapPlugin.plugin.isOp(psender.getName().getString()); + } + return true; + } + @Override + public boolean hasPermissionNode(ServerPlayer psender, String permission) { + if(psender != null) { + return DynmapPlugin.plugin.isOp(psender.getName().getString()); + } + return true; + } +} diff --git a/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/permissions/PermissionProvider.java b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/permissions/PermissionProvider.java new file mode 100644 index 000000000..80709b3ed --- /dev/null +++ b/forge-1.21.11/src/main/java/org/dynmap/forge_1_21_11/permissions/PermissionProvider.java @@ -0,0 +1,15 @@ +package org.dynmap.forge_1_21_11.permissions; + +import java.util.Set; + +import net.minecraft.server.level.ServerPlayer; + +public interface PermissionProvider { + boolean has(ServerPlayer sender, String permission); + boolean hasPermissionNode(ServerPlayer sender, String permission); + + Set hasOfflinePermissions(String player, Set perms); + + boolean hasOfflinePermission(String player, String perm); + +} diff --git a/forge-1.21/src/main/resources/META-INF/accesstransformer.cfg b/forge-1.21.11/src/main/resources/META-INF/accesstransformer.cfg similarity index 100% rename from forge-1.21/src/main/resources/META-INF/accesstransformer.cfg rename to forge-1.21.11/src/main/resources/META-INF/accesstransformer.cfg diff --git a/forge-1.21/src/main/resources/META-INF/mods.toml b/forge-1.21.11/src/main/resources/META-INF/mods.toml similarity index 87% rename from forge-1.21/src/main/resources/META-INF/mods.toml rename to forge-1.21.11/src/main/resources/META-INF/mods.toml index fa074c16c..c0a418ec6 100644 --- a/forge-1.21/src/main/resources/META-INF/mods.toml +++ b/forge-1.21.11/src/main/resources/META-INF/mods.toml @@ -1,5 +1,5 @@ modLoader="javafml" -loaderVersion="[51,)" +loaderVersion="[61,)" issueTrackerURL="https://github.com/webbukkit/dynmap/issues" license="Apache Public License v2" [[mods]] @@ -14,13 +14,13 @@ Dynamic, Google-maps style rendered maps for your Minecraft server [[dependencies.dynmap]] modId="forge" mandatory=true - versionRange="[51,)" + versionRange="[61,)" ordering="NONE" # Side this dependency is applied on - BOTH, CLIENT or SERVER side="SERVER" [[dependencies.dynmap]] modId="minecraft" mandatory=true - versionRange="[1.21,1.21.3)" + versionRange="[1.21.11,1.22)" ordering="NONE" side="SERVER" diff --git a/forge-1.21/src/main/resources/configuration.txt b/forge-1.21.11/src/main/resources/configuration.txt similarity index 100% rename from forge-1.21/src/main/resources/configuration.txt rename to forge-1.21.11/src/main/resources/configuration.txt diff --git a/forge-1.21/src/main/resources/pack.mcmeta b/forge-1.21.11/src/main/resources/pack.mcmeta similarity index 100% rename from forge-1.21/src/main/resources/pack.mcmeta rename to forge-1.21.11/src/main/resources/pack.mcmeta diff --git a/forge-1.21/src/main/resources/permissions.yml.example b/forge-1.21.11/src/main/resources/permissions.yml.example similarity index 100% rename from forge-1.21/src/main/resources/permissions.yml.example rename to forge-1.21.11/src/main/resources/permissions.yml.example diff --git a/forge-1.21.6/.gitignore b/forge-1.21.6/.gitignore new file mode 100644 index 000000000..84c048a73 --- /dev/null +++ b/forge-1.21.6/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/forge-1.21.3/build.gradle b/forge-1.21.6/build.gradle similarity index 87% rename from forge-1.21.3/build.gradle rename to forge-1.21.6/build.gradle index 5164998c9..0e002414a 100644 --- a/forge-1.21.3/build.gradle +++ b/forge-1.21.6/build.gradle @@ -14,7 +14,7 @@ apply plugin: 'eclipse' eclipse { project { - name = "Dynmap(Forge-1.21.3)" + name = "Dynmap(Forge-1.21.6)" } } @@ -25,7 +25,7 @@ println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getPro ext.buildNumber = System.getenv().BUILD_NUMBER ?: "Dev" minecraft { - mappings channel: 'official', version: '1.21.3' + mappings channel: 'official', version: '1.21.6' accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') reobf = false copyIdeResources = true @@ -36,13 +36,13 @@ minecraft { } } -project.archivesBaseName = "${project.archivesBaseName}-forge-1.21.3" +project.archivesBaseName = "${project.archivesBaseName}-forge-1.21.6" dependencies { implementation project(path: ":DynmapCore", configuration: "shadow") implementation project(path: ':DynmapCoreAPI') - minecraft 'net.minecraftforge:forge:1.21.3-53.0.37' + minecraft 'net.minecraftforge:forge:1.21.6-56.0.9' } processResources @@ -51,7 +51,7 @@ processResources // replace version and mcversion expand( version: project.version + '-' + project.ext.buildNumber, - mcversion: "1.21.3" + mcversion: "1.21.6" ) } } @@ -63,10 +63,10 @@ shadowJar { exclude("META-INF/maven/**") exclude("META-INF/services/**") } - relocate('org.apache.commons.codec', 'org.dynmap.forge_1_21_3.commons.codec') + relocate('org.apache.commons.codec', 'org.dynmap.forge_1_21_6.commons.codec') archiveBaseName = "Dynmap" - archiveClassifier = "forge-1.21.3" + archiveClassifier = "forge-1.21.6" destinationDirectory = file '../target' } diff --git a/forge-1.21/src/main/java/org/dynmap/forge_1_21/ClientProxy.java b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/ClientProxy.java similarity index 68% rename from forge-1.21/src/main/java/org/dynmap/forge_1_21/ClientProxy.java rename to forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/ClientProxy.java index abf523e33..31809fb10 100644 --- a/forge-1.21/src/main/java/org/dynmap/forge_1_21/ClientProxy.java +++ b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/ClientProxy.java @@ -1,4 +1,4 @@ -package org.dynmap.forge_1_21; +package org.dynmap.forge_1_21_6; public class ClientProxy extends Proxy { public ClientProxy() { diff --git a/forge-1.21/src/main/java/org/dynmap/forge_1_21/DynmapMod.java b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/DynmapMod.java similarity index 68% rename from forge-1.21/src/main/java/org/dynmap/forge_1_21/DynmapMod.java rename to forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/DynmapMod.java index c3530ca39..d5f4ec619 100644 --- a/forge-1.21/src/main/java/org/dynmap/forge_1_21/DynmapMod.java +++ b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/DynmapMod.java @@ -1,4 +1,4 @@ -package org.dynmap.forge_1_21; +package org.dynmap.forge_1_21_6; import java.io.File; @@ -6,7 +6,7 @@ import org.dynmap.DynmapCommonAPI; import org.dynmap.DynmapCommonAPIListener; import org.dynmap.Log; -import org.dynmap.forge_1_21.DynmapPlugin.OurLog; +import org.dynmap.forge_1_21_6.DynmapPlugin.OurLog; import net.minecraft.server.MinecraftServer; import net.minecraftforge.fml.common.Mod; @@ -15,14 +15,13 @@ import net.minecraftforge.event.server.ServerStartedEvent; import net.minecraftforge.event.server.ServerStartingEvent; import net.minecraftforge.event.server.ServerStoppingEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.eventbus.api.bus.BusGroup; +import net.minecraftforge.eventbus.api.bus.EventBus; +import net.minecraftforge.eventbus.api.listener.SubscribeEvent; import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.IExtensionPoint; import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.StartupMessageManager; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; -import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; @Mod("dynmap") @@ -30,6 +29,7 @@ public class DynmapMod { // The instance of your mod that Forge uses. public static DynmapMod instance; + public static BusGroup modBusGroup; // Says where the client and server 'proxy' code is loaded. public static Proxy proxy = DistExecutor.runForDist(() -> ClientProxy::new, () -> Proxy::new); @@ -51,27 +51,17 @@ public void apiEnabled(DynmapCommonAPI api) { } } - //TODO - //public class LoadingCallback implements net.minecraftforge.common.ForgeChunkManager.LoadingCallback { - // @Override - // public void ticketsLoaded(List tickets, World world) { - // if(tickets.size() > 0) { - // DynmapPlugin.setBusy(world, tickets.get(0)); - // for(int i = 1; i < tickets.size(); i++) { - // ForgeChunkManager.releaseTicket(tickets.get(i)); - // } - // } - // } - //} - - public DynmapMod() { + public DynmapMod(FMLJavaModLoadingContext context) { instance = this; - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::init); + + modBusGroup = context.getModBusGroup(); + + // Register the commonSetup method for modloading + FMLCommonSetupEvent.getBus(modBusGroup).addListener(this::setup); MinecraftForge.EVENT_BUS.register(this); - ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, + context.registerExtensionPoint(IExtensionPoint.DisplayTest.class, ()->new IExtensionPoint.DisplayTest(()->IExtensionPoint.DisplayTest.IGNORESERVERONLY, (remote, isServer)-> true)); Log.setLogger(new OurLog()); @@ -98,18 +88,6 @@ public void setup(final FMLCommonSetupEvent event) //} } - public void init(FMLLoadCompleteEvent event) - { - /* Set up for chunk loading notice from chunk manager */ - //TODO - //if(useforcedchunks) { - // ForgeChunkManager.setForcedChunkLoadingCallback(DynmapMod.instance, new LoadingCallback()); - //} - //else { - // Log.info("[Dynmap] World loading using forced chunks is disabled"); - //} - } - private MinecraftServer server; @SubscribeEvent diff --git a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/DynmapPlugin.java b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/DynmapPlugin.java similarity index 94% rename from forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/DynmapPlugin.java rename to forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/DynmapPlugin.java index a35f08f3d..af0637452 100644 --- a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/DynmapPlugin.java +++ b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/DynmapPlugin.java @@ -1,4 +1,4 @@ -package org.dynmap.forge_1_21_3; +package org.dynmap.forge_1_21_6; import java.io.File; import java.io.InputStream; @@ -54,17 +54,15 @@ import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.LeavesBlock; import net.minecraft.world.level.block.LiquidBlock; -import net.minecraft.world.level.block.SoundType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; import net.minecraft.world.phys.Vec3; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.ServerChatEvent; import net.minecraftforge.event.TickEvent; +import net.minecraftforge.event.TickEvent.ServerTickEvent; import net.minecraftforge.event.entity.player.PlayerEvent.PlayerChangedDimensionEvent; import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedInEvent; import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedOutEvent; @@ -73,6 +71,8 @@ import net.minecraftforge.event.level.ChunkDataEvent; import net.minecraftforge.event.level.ChunkEvent; import net.minecraftforge.event.level.LevelEvent; +import net.minecraftforge.eventbus.api.listener.Priority; +import net.minecraftforge.eventbus.api.listener.SubscribeEvent; import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.ModContainer; import net.minecraftforge.fml.loading.LoadingModList; @@ -98,12 +98,12 @@ import org.dynmap.common.DynmapServerInterface; import org.dynmap.common.DynmapListenerManager.EventType; import org.dynmap.common.chunk.GenericChunkCache; -import org.dynmap.forge_1_21_3.DmapCommand; -import org.dynmap.forge_1_21_3.DmarkerCommand; -import org.dynmap.forge_1_21_3.DynmapCommand; -import org.dynmap.forge_1_21_3.permissions.FilePermissions; -import org.dynmap.forge_1_21_3.permissions.OpPermissions; -import org.dynmap.forge_1_21_3.permissions.PermissionProvider; +import org.dynmap.forge_1_21_6.DmapCommand; +import org.dynmap.forge_1_21_6.DmarkerCommand; +import org.dynmap.forge_1_21_6.DynmapCommand; +import org.dynmap.forge_1_21_6.permissions.FilePermissions; +import org.dynmap.forge_1_21_6.permissions.OpPermissions; +import org.dynmap.forge_1_21_6.permissions.PermissionProvider; import org.dynmap.permissions.PermissionsHandler; import org.dynmap.renderer.DynmapBlockState; import org.dynmap.utils.DynmapLogger; @@ -123,8 +123,6 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; -import net.minecraftforge.eventbus.api.EventPriority; -import net.minecraftforge.eventbus.api.SubscribeEvent; public class DynmapPlugin { @@ -136,7 +134,6 @@ public class DynmapPlugin private MapManager mapManager; private static net.minecraft.server.MinecraftServer server; public static DynmapPlugin plugin; - private ChatHandler chathandler; private HashMap sortWeights = new HashMap(); // Drop world load ticket after 30 seconds private long worldIdleTimeoutNS = 30 * 1000000000L; @@ -353,18 +350,16 @@ private class ChatMessage { } private ConcurrentLinkedQueue msgqueue = new ConcurrentLinkedQueue(); - public class ChatHandler { - @SubscribeEvent - public void handleChat(ServerChatEvent event) { - String msg = event.getMessage().getString(); - if(!msg.startsWith("/")) { - ChatMessage cm = new ChatMessage(); - cm.message = msg; - cm.sender = event.getPlayer(); - msgqueue.add(cm); - } - } - } + private boolean handleChatRegistered = false; + public void handleChat(final ServerChatEvent event) { + String msg = event.getMessage().getString(); + if(!msg.startsWith("/")) { + ChatMessage cm = new ChatMessage(); + cm.message = msg; + cm.sender = event.getPlayer(); + msgqueue.add(cm); + } + } /** TODO: depends on forge chunk manager private static class WorldBusyRecord { @@ -699,9 +694,9 @@ public void onPlayerBedLeave(PlayerBedLeaveEvent evt) { break; case PLAYER_CHAT: - if (chathandler == null) { - chathandler = new ChatHandler(); - MinecraftForge.EVENT_BUS.register(chathandler); + if (!handleChatRegistered) { + handleChatRegistered = true; + ServerChatEvent.BUS.addListener(DynmapPlugin.this::handleChat); } break; @@ -1194,7 +1189,7 @@ public DynmapLocation getLocation() return null; } Vec3 v = player.position(); - return toLoc(player.serverLevel(), v.x, v.y, v.z); + return toLoc(player.level(), v.x, v.y, v.z); } @Override public String getWorld() @@ -1204,9 +1199,9 @@ public String getWorld() return null; } - if (player.serverLevel() != null) + if (player.level() != null) { - return DynmapPlugin.this.getWorld((ServerLevel)player.serverLevel()).getName(); + return DynmapPlugin.this.getWorld((ServerLevel)player.level()).getName(); } return null; @@ -1553,7 +1548,7 @@ public void onStart() { /* Register tick handler */ if(!tickregistered) { - MinecraftForge.EVENT_BUS.register(fserver); + ServerTickEvent.BUS.addListener(fserver::tickEvent); tickregistered = true; } @@ -1692,7 +1687,7 @@ private void registerPlayerLoginListener() } public class WorldTracker { - @SubscribeEvent(priority=EventPriority.LOWEST) + @SubscribeEvent(priority=Priority.LOWEST) public void handleWorldLoad(LevelEvent.Load event) { if(!core_enabled) return; LevelAccessor w = event.getLevel(); @@ -1706,7 +1701,7 @@ public void run() { } }, 0); } - @SubscribeEvent(priority=EventPriority.LOWEST) + @SubscribeEvent(priority=Priority.LOWEST) public void handleWorldUnload(LevelEvent.Unload event) { if(!core_enabled) return; LevelAccessor w = event.getLevel(); @@ -1728,21 +1723,64 @@ public void run() { } } - @SubscribeEvent(priority=EventPriority.LOWEST) + private void touchChunk(ForgeWorld fw, ChunkAccess c, String cause) { + int ymax = Integer.MIN_VALUE; + int ymin = Integer.MAX_VALUE; + LevelChunkSection[] sections = c.getSections(); + // If no sections, assume all + if (sections.length == 0) { + ymax = (c.getMaxSectionY()+1) << 4; + ymin = c.getMinSectionY() << 4; + } + else { + for(int i = 0; i < sections.length; i++) { + if((sections[i] != null) && (sections[i].hasOnlyAir() == false)) { + int sy = c.getSectionYFromSectionIndex(i) << 4; + if (sy < ymin) ymin = sy; + if ((sy+16) > ymax) ymax = sy + 16; + } + } + } + ChunkPos cp = c.getPos(); + int x = cp.x << 4; + int z = cp.z << 4; + // If not empty AND not initial scan + if (ymax != Integer.MIN_VALUE) { + mapManager.touchVolume(fw.getName(), x, ymin, z, x+15, ymax, z+15, "chunkgenerate"); + } + } + + @SubscribeEvent(priority=Priority.LOWEST) public void handleChunkLoad(ChunkEvent.Load event) { if(!onchunkgenerate) return; LevelAccessor w = event.getLevel(); if(!(w instanceof ServerLevel)) return; ChunkAccess c = event.getChunk(); - if ((c != null) && (c.getPersistedStatus() == ChunkStatus.FULL) && (c instanceof LevelChunk)) { + if ((c != null) && (c.getPersistedStatus() == ChunkStatus.FULL)) { ForgeWorld fw = getWorld((ServerLevel)w, false); if (fw != null) { addKnownChunk(fw, c.getPos()); } } } - @SubscribeEvent(priority=EventPriority.LOWEST) + @SubscribeEvent(priority=Priority.MONITOR) + public void handleChunkLightingCalculated(ChunkEvent.LightingCalculated event) { + LevelAccessor w = event.getLevel(); + if (!(w instanceof ServerLevel)) return; + ChunkAccess c = event.getChunk(); + if (c != null) { + ForgeWorld fw = getWorld((ServerLevel)w, false); + if (fw != null) { + touchChunk(fw, c, "lighting"); + if (c.getPersistedStatus() == ChunkStatus.FULL) { + addKnownChunk(fw, c.getPos()); + } + } + } + } + + @SubscribeEvent(priority=Priority.LOWEST) public void handleChunkUnload(ChunkEvent.Unload event) { if(!onchunkgenerate) return; @@ -1754,29 +1792,13 @@ public void handleChunkUnload(ChunkEvent.Unload event) { ChunkPos cp = c.getPos(); if (fw != null) { if (!checkIfKnownChunk(fw, cp)) { - int ymax = Integer.MIN_VALUE; - int ymin = Integer.MAX_VALUE; - LevelChunkSection[] sections = c.getSections(); - for(int i = 0; i < sections.length; i++) { - if((sections[i] != null) && (sections[i].hasOnlyAir() == false)) { - int sy = c.getSectionYFromSectionIndex(i); - if (sy < ymin) ymin = sy; - if ((sy+16) > ymax) ymax = sy + 16; - } - } - int x = cp.x << 4; - int z = cp.z << 4; - // If not empty AND not initial scan - if (ymax != Integer.MIN_VALUE) { - //Log.info(String.format("chunkkeyerate(unload)(%s,%d,%d,%d,%d,%d,%s)", fw.getName(), x, ymin, z, x+15, ymax, z+15)); - mapManager.touchVolume(fw.getName(), x, ymin, z, x+15, ymax, z+15, "chunkgenerate"); - } + touchChunk(fw, c, "unload"); } removeKnownChunk(fw, cp); } } } - @SubscribeEvent(priority=EventPriority.LOWEST) + @SubscribeEvent(priority=Priority.LOWEST) public void handleChunkDataSave(ChunkDataEvent.Save event) { if(!onchunkgenerate) return; @@ -1787,33 +1809,15 @@ public void handleChunkDataSave(ChunkDataEvent.Save event) { ForgeWorld fw = getWorld((ServerLevel)w, false); ChunkPos cp = c.getPos(); if (fw != null) { - if (!checkIfKnownChunk(fw, cp)) { - int ymax = Integer.MIN_VALUE; - int ymin = Integer.MAX_VALUE; - LevelChunkSection[] sections = c.getSections(); - for(int i = 0; i < sections.length; i++) { - if((sections[i] != null) && (sections[i].hasOnlyAir() == false)) { - int sy = c.getSectionYFromSectionIndex(i); - if (sy < ymin) ymin = sy; - if ((sy+16) > ymax) ymax = sy + 16; - } - } - int x = cp.x << 4; - int z = cp.z << 4; - // If not empty AND not initial scan - if (ymax != Integer.MIN_VALUE) { - //Log.info(String.format("chunkkeyerate(save)(%s,%d,%d,%d,%d,%d,%s)", fw.getName(), x, ymin, z, x+15, ymax, z+15)); - mapManager.touchVolume(fw.getName(), x, ymin, z, x+15, ymax, z+15, "chunkgenerate"); - } - // If cooked, add to known - if ((c.getPersistedStatus() == ChunkStatus.FULL) && (c instanceof LevelChunk)) { - addKnownChunk(fw, cp); - } - } + touchChunk(fw, c, "datasave"); + // If cooked, add to known + if (c.getPersistedStatus() == ChunkStatus.FULL) { + addKnownChunk(fw, cp); + } } } } - @SubscribeEvent(priority=EventPriority.LOWEST) + @SubscribeEvent(priority=Priority.LOWEST) public void handleBlockEvent(BlockEvent event) { if(!core_enabled) return; if(!onblockchange) return; diff --git a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/ForgeMapChunkCache.java b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/ForgeMapChunkCache.java similarity index 96% rename from forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/ForgeMapChunkCache.java rename to forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/ForgeMapChunkCache.java index 5ab3a4571..c814e775e 100644 --- a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/ForgeMapChunkCache.java +++ b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/ForgeMapChunkCache.java @@ -1,4 +1,4 @@ -package org.dynmap.forge_1_21_3; +package org.dynmap.forge_1_21_6; import java.util.List; import java.util.NoSuchElementException; @@ -73,10 +73,10 @@ private CompoundTag readChunk(int x, int z) { if (rslt != null) { CompoundTag lev = rslt; if (lev.contains("Level")) { - lev = lev.getCompound("Level"); + lev = lev.getCompoundOrEmpty("Level"); } // Don't load uncooked chunks - String stat = lev.getString("Status"); + String stat = lev.getStringOr("Status", null); ChunkStatus cs = ChunkStatus.byName(stat); if ((stat == null) || // Needs to be at least lighted diff --git a/forge-1.21/src/main/java/org/dynmap/forge_1_21/ForgeWorld.java b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/ForgeWorld.java similarity index 99% rename from forge-1.21/src/main/java/org/dynmap/forge_1_21/ForgeWorld.java rename to forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/ForgeWorld.java index 9e454a0e6..a0a0951b0 100644 --- a/forge-1.21/src/main/java/org/dynmap/forge_1_21/ForgeWorld.java +++ b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/ForgeWorld.java @@ -1,4 +1,4 @@ -package org.dynmap.forge_1_21; +package org.dynmap.forge_1_21_6; /** * Forge specific implementation of DynmapWorld */ diff --git a/forge-1.21/src/main/java/org/dynmap/forge_1_21/NBT.java b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/NBT.java similarity index 64% rename from forge-1.21/src/main/java/org/dynmap/forge_1_21/NBT.java rename to forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/NBT.java index acdf25159..989e46c71 100644 --- a/forge-1.21/src/main/java/org/dynmap/forge_1_21/NBT.java +++ b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/NBT.java @@ -1,4 +1,4 @@ -package org.dynmap.forge_1_21; +package org.dynmap.forge_1_21_6; import org.dynmap.common.chunk.GenericBitStorage; import org.dynmap.common.chunk.GenericNBTCompound; @@ -7,6 +7,7 @@ import java.util.Set; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.Tag; import net.minecraft.util.SimpleBitStorage; public class NBT { @@ -18,7 +19,7 @@ public NBTCompound(CompoundTag t) { } @Override public Set getAllKeys() { - return obj.getAllKeys(); + return obj.keySet(); } @Override public boolean contains(String s) { @@ -26,63 +27,74 @@ public boolean contains(String s) { } @Override public boolean contains(String s, int i) { - return obj.contains(s, i); + // Like contains, but with an extra constraint on type + Tag base = obj.get(s); + if (base == null) + return false; + byte type = base.getId(); + if (type == (byte) i) + return true; + else if (i != TAG_ANY_NUMERIC) + return false; + return type == TAG_BYTE || type == TAG_SHORT || type == TAG_INT || type == TAG_LONG || type == TAG_FLOAT + || type == TAG_DOUBLE; } @Override public byte getByte(String s) { - return obj.getByte(s); + return obj.getByteOr(s, (byte)0); } @Override public short getShort(String s) { - return obj.getShort(s); + return obj.getShortOr(s, (short)0); } @Override public int getInt(String s) { - return obj.getInt(s); + return obj.getIntOr(s, (int)0); } @Override public long getLong(String s) { - return obj.getLong(s); + return obj.getLongOr(s, (long)0); } @Override public float getFloat(String s) { - return obj.getFloat(s); + return obj.getFloatOr(s, (float)0); } @Override public double getDouble(String s) { - return obj.getDouble(s); + return obj.getDoubleOr(s, (double)0); } @Override public String getString(String s) { - return obj.getString(s); + return obj.getStringOr(s, ""); } @Override public byte[] getByteArray(String s) { - return obj.getByteArray(s); + return obj.getByteArray(s).orElseGet(() -> new byte[0]); } @Override public int[] getIntArray(String s) { - return obj.getIntArray(s); + return obj.getIntArray(s).orElseGet(() -> new int[0]); } @Override public long[] getLongArray(String s) { - return obj.getLongArray(s); + return obj.getLongArray(s).orElseGet(() -> new long[0]); } @Override public GenericNBTCompound getCompound(String s) { - return new NBTCompound(obj.getCompound(s)); + return new NBTCompound(obj.getCompoundOrEmpty(s)); } @Override public GenericNBTList getList(String s, int i) { - return new NBTList(obj.getList(s, i)); + // i argument used to be used to constrain list type, but nbt lists no longer have types as of 1.21.5 + return new NBTList(obj.getListOrEmpty(s)); } @Override public boolean getBoolean(String s) { - return obj.getBoolean(s); + return obj.getBooleanOr(s, false); } @Override public String getAsString(String s) { - return obj.get(s).getAsString(); + return obj.get(s).asString().orElse(""); } @Override public GenericBitStorage makeBitStorage(int bits, int count, long[] data) { @@ -103,11 +115,11 @@ public int size() { } @Override public String getString(int idx) { - return obj.getString(idx); + return obj.getStringOr(idx, ""); } @Override public GenericNBTCompound getCompound(int idx) { - return new NBTCompound(obj.getCompound(idx)); + return new NBTCompound(obj.getCompoundOrEmpty(idx)); } public String toString() { return obj.toString(); diff --git a/forge-1.21/src/main/java/org/dynmap/forge_1_21/Proxy.java b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/Proxy.java similarity index 93% rename from forge-1.21/src/main/java/org/dynmap/forge_1_21/Proxy.java rename to forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/Proxy.java index 19ac58c80..7ad05f99b 100644 --- a/forge-1.21/src/main/java/org/dynmap/forge_1_21/Proxy.java +++ b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/Proxy.java @@ -1,4 +1,4 @@ -package org.dynmap.forge_1_21; +package org.dynmap.forge_1_21_6; import net.minecraft.server.MinecraftServer; diff --git a/forge-1.21/src/main/java/org/dynmap/forge_1_21/VersionCheck.java b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/VersionCheck.java similarity index 99% rename from forge-1.21/src/main/java/org/dynmap/forge_1_21/VersionCheck.java rename to forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/VersionCheck.java index fed972d1d..35a998ce4 100644 --- a/forge-1.21/src/main/java/org/dynmap/forge_1_21/VersionCheck.java +++ b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/VersionCheck.java @@ -1,4 +1,4 @@ -package org.dynmap.forge_1_21; +package org.dynmap.forge_1_21_6; import java.io.BufferedReader; import java.io.InputStreamReader; diff --git a/forge-1.21/src/main/java/org/dynmap/forge_1_21/permissions/FilePermissions.java b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/permissions/FilePermissions.java similarity index 97% rename from forge-1.21/src/main/java/org/dynmap/forge_1_21/permissions/FilePermissions.java rename to forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/permissions/FilePermissions.java index bb516577e..ba20c6739 100644 --- a/forge-1.21/src/main/java/org/dynmap/forge_1_21/permissions/FilePermissions.java +++ b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/permissions/FilePermissions.java @@ -1,4 +1,4 @@ -package org.dynmap.forge_1_21.permissions; +package org.dynmap.forge_1_21_6.permissions; import java.io.File; import java.util.HashMap; @@ -8,7 +8,7 @@ import org.dynmap.ConfigurationNode; import org.dynmap.Log; -import org.dynmap.forge_1_21.DynmapPlugin; +import org.dynmap.forge_1_21_6.DynmapPlugin; import net.minecraft.server.level.ServerPlayer; diff --git a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/permissions/OpPermissions.java b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/permissions/OpPermissions.java similarity index 94% rename from forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/permissions/OpPermissions.java rename to forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/permissions/OpPermissions.java index 08995a5a1..105479989 100644 --- a/forge-1.21.3/src/main/java/org/dynmap/forge_1_21_3/permissions/OpPermissions.java +++ b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/permissions/OpPermissions.java @@ -1,10 +1,10 @@ -package org.dynmap.forge_1_21_3.permissions; +package org.dynmap.forge_1_21_6.permissions; import java.util.HashSet; import java.util.Set; import org.dynmap.Log; -import org.dynmap.forge_1_21_3.DynmapPlugin; +import org.dynmap.forge_1_21_6.DynmapPlugin; import net.minecraft.server.level.ServerPlayer; diff --git a/forge-1.21/src/main/java/org/dynmap/forge_1_21/permissions/PermissionProvider.java b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/permissions/PermissionProvider.java similarity index 89% rename from forge-1.21/src/main/java/org/dynmap/forge_1_21/permissions/PermissionProvider.java rename to forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/permissions/PermissionProvider.java index e120a0f77..2ccd6838a 100644 --- a/forge-1.21/src/main/java/org/dynmap/forge_1_21/permissions/PermissionProvider.java +++ b/forge-1.21.6/src/main/java/org/dynmap/forge_1_21_6/permissions/PermissionProvider.java @@ -1,4 +1,4 @@ -package org.dynmap.forge_1_21.permissions; +package org.dynmap.forge_1_21_6.permissions; import java.util.Set; diff --git a/forge-1.21.6/src/main/resources/META-INF/accesstransformer.cfg b/forge-1.21.6/src/main/resources/META-INF/accesstransformer.cfg new file mode 100644 index 000000000..9f6e7211e --- /dev/null +++ b/forge-1.21.6/src/main/resources/META-INF/accesstransformer.cfg @@ -0,0 +1,4 @@ +public net.minecraft.world.level.biome.BiomeSpecialEffects$Builder f_48006_ # waterColor +public net.minecraft.server.level.ServerLevel f_8549_ # serverLevelData +public net.minecraft.server.level.ChunkMap f_140130_ # visibleChunkMap +public net.minecraft.server.level.ChunkMap m_214963_(Lnet/minecraft/world/level/ChunkPos;)Ljava/util/concurrent/CompletableFuture; # readChunk( diff --git a/forge-1.21.3/src/main/resources/META-INF/mods.toml b/forge-1.21.6/src/main/resources/META-INF/mods.toml similarity index 87% rename from forge-1.21.3/src/main/resources/META-INF/mods.toml rename to forge-1.21.6/src/main/resources/META-INF/mods.toml index 014525005..87aaf2305 100644 --- a/forge-1.21.3/src/main/resources/META-INF/mods.toml +++ b/forge-1.21.6/src/main/resources/META-INF/mods.toml @@ -1,5 +1,5 @@ modLoader="javafml" -loaderVersion="[53,)" +loaderVersion="[56,)" issueTrackerURL="https://github.com/webbukkit/dynmap/issues" license="Apache Public License v2" [[mods]] @@ -14,13 +14,13 @@ Dynamic, Google-maps style rendered maps for your Minecraft server [[dependencies.dynmap]] modId="forge" mandatory=true - versionRange="[53,)" + versionRange="[56,)" ordering="NONE" # Side this dependency is applied on - BOTH, CLIENT or SERVER side="SERVER" [[dependencies.dynmap]] modId="minecraft" mandatory=true - versionRange="[1.21.3,1.22)" + versionRange="[1.21.6,1.22)" ordering="NONE" side="SERVER" diff --git a/forge-1.21.6/src/main/resources/configuration.txt b/forge-1.21.6/src/main/resources/configuration.txt new file mode 100644 index 000000000..38174f817 --- /dev/null +++ b/forge-1.21.6/src/main/resources/configuration.txt @@ -0,0 +1,504 @@ +# All paths in this configuration file are relative to Dynmap's data-folder: minecraft_server/dynmap/ + +# All map templates are defined in the templates directory +# To use the HDMap very-low-res (2 ppb) map templates as world defaults, set value to vlowres +# The definitions of these templates are in normal-vlowres.txt, nether-vlowres.txt, and the_end-vlowres.txt +# To use the HDMap low-res (4 ppb) map templates as world defaults, set value to lowres +# The definitions of these templates are in normal-lowres.txt, nether-lowres.txt, and the_end-lowres.txt +# To use the HDMap hi-res (16 ppb) map templates (these can take a VERY long time for initial fullrender), set value to hires +# The definitions of these templates are in normal-hires.txt, nether-hires.txt, and the_end-hires.txt +# To use the HDMap low-res (4 ppb) map templates, with support for boosting resolution selectively to hi-res (16 ppb), set value to low_boost_hi +# The definitions of these templates are in normal-low_boost_hi.txt, nether-low_boost_hi.txt, and the_end-low_boost_hi.txt +# To use the HDMap hi-res (16 ppb) map templates, with support for boosting resolution selectively to vhi-res (32 ppb), set value to hi_boost_vhi +# The definitions of these templates are in normal-hi_boost_vhi.txt, nether-hi_boost_vhi.txt, and the_end-hi_boost_vhi.txt +# To use the HDMap hi-res (16 ppb) map templates, with support for boosting resolution selectively to xhi-res (64 ppb), set value to hi_boost_xhi +# The definitions of these templates are in normal-hi_boost_xhi.txt, nether-hi_boost_xhi.txt, and the_end-hi_boost_xhi.txt +deftemplatesuffix: hires + +# Set default tile scale (0 = 128px x 128x, 1 = 256px x 256px, 2 = 512px x 512px, 3 = 1024px x 1024px, 4 = 2048px x 2048px) - 0 is default +# Note: changing this value will result in all maps that use the default value being required to be fully rendered +#defaulttilescale: 0 + +# Map storage scheme: only uncommoent one 'type' value +# filetree: classic and default scheme: tree of files, with all map data under the directory indicated by 'tilespath' setting +# sqlite: single SQLite database file (this can get VERY BIG), located at 'dbfile' setting (default is file dynmap.db in data directory) +# mysql: MySQL database, at hostname:port in database, accessed via userid with password +# mariadb: MariaDB database, at hostname:port in database, accessed via userid with password +# postgres: PostgreSQL database, at hostname:port in database, accessed via userid with password +storage: + # Filetree storage (standard tree of image files for maps) + type: filetree + # SQLite db for map storage (uses dbfile as storage location) + #type: sqlite + #dbfile: dynmap.db + # MySQL DB for map storage (at 'hostname':'port' in database 'database' using user 'userid' password 'password' and table prefix 'prefix' + #type: mysql + #hostname: localhost + #port: 3306 + #database: dynmap + #userid: dynmap + #password: dynmap + #prefix: "" + # + # AWS S3 backet web site + #type: aws_s3 + #bucketname: "dynmap-bucket-name" + #region: us-east-1 + #aws_access_key_id: "" + #aws_secret_access_key: "" + #prefix: "" + #override_endpoint: "" + +components: + - class: org.dynmap.ClientConfigurationComponent + + # Remember to change the following class to org.dynmap.JsonFileClientUpdateComponent when using an external web server. + - class: org.dynmap.InternalClientUpdateComponent + sendhealth: true + sendposition: true + allowwebchat: true + webchat-interval: 5 + hidewebchatip: false + trustclientname: false + includehiddenplayers: false + # (optional) if true, color codes in player display names are used + use-name-colors: false + # (optional) if true, player login IDs will be used for web chat when their IPs match + use-player-login-ip: true + # (optional) if use-player-login-ip is true, setting this to true will cause chat messages not matching a known player IP to be ignored + require-player-login-ip: false + # (optional) block player login IDs that are banned from chatting + block-banned-player-chat: true + # Require login for web-to-server chat (requires login-enabled: true) + webchat-requires-login: false + # If set to true, users must have dynmap.webchat permission in order to chat + webchat-permissions: false + # Limit length of single chat messages + chatlengthlimit: 256 + # # Optional - make players hidden when they are inside/underground/in shadows (#=light level: 0=full shadow,15=sky) + # hideifshadow: 4 + # # Optional - make player hidden when they are under cover (#=sky light level,0=underground,15=open to sky) + # hideifundercover: 14 + # # (Optional) if true, players that are crouching/sneaking will be hidden + hideifsneaking: false + # optional, if true, players that are in spectator mode will be hidden + hideifspectator: false + # If true, player positions/status is protected (login with ID with dynmap.playermarkers.seeall permission required for info other than self) + protected-player-info: false + # If true, hide players with invisibility potion effects active + hide-if-invisiblity-potion: true + # If true, player names are not shown on map, chat, list + hidenames: false + #- class: org.dynmap.JsonFileClientUpdateComponent + # writeinterval: 1 + # sendhealth: true + # sendposition: true + # allowwebchat: true + # webchat-interval: 5 + # hidewebchatip: false + # includehiddenplayers: false + # use-name-colors: false + # use-player-login-ip: false + # require-player-login-ip: false + # block-banned-player-chat: true + # hideifshadow: 0 + # hideifundercover: 0 + # hideifsneaking: false + # # Require login for web-to-server chat (requires login-enabled: true) + # webchat-requires-login: false + # # If set to true, users must have dynmap.webchat permission in order to chat + # webchat-permissions: false + # # Limit length of single chat messages + # chatlengthlimit: 256 + # hide-if-invisiblity-potion: true + # hidenames: false + + - class: org.dynmap.SimpleWebChatComponent + allowchat: true + # If true, web UI users can supply name for chat using 'playername' URL parameter. 'trustclientname' must also be set true. + allowurlname: false + + # Note: this component is needed for the dmarker commands, and for the Marker API to be available to other plugins + - class: org.dynmap.MarkersComponent + type: markers + showlabel: false + enablesigns: false + # Default marker set for sign markers + default-sign-set: markers + # (optional) add spawn point markers to standard marker layer + showspawn: true + spawnicon: world + spawnlabel: "Spawn" + # (optional) layer for showing offline player's positions (for 'maxofflinetime' minutes after logoff) + showofflineplayers: false + offlinelabel: "Offline" + offlineicon: offlineuser + offlinehidebydefault: true + offlineminzoom: 0 + maxofflinetime: 30 + # (optional) layer for showing player's spawn beds + showspawnbeds: false + spawnbedlabel: "Spawn Beds" + spawnbedicon: bed + spawnbedhidebydefault: true + spawnbedminzoom: 0 + spawnbedformat: "%name%'s bed" + spawnbedremoveonplayerleave: true + # (optional) Show world border (vanilla 1.8+) + showworldborder: true + worldborderlabel: "Border" + + - class: org.dynmap.ClientComponent + type: chat + allowurlname: false + - class: org.dynmap.ClientComponent + type: chatballoon + focuschatballoons: false + - class: org.dynmap.ClientComponent + type: chatbox + showplayerfaces: true + messagettl: 5 + # Optional: set number of lines in scrollable message history: if set, messagettl is not used to age out messages + #scrollback: 100 + # Optional: set maximum number of lines visible for chatbox + #visiblelines: 10 + # Optional: send push button + sendbutton: false + - class: org.dynmap.ClientComponent + type: playermarkers + showplayerfaces: true + showplayerhealth: true + # If true, show player body too (only valid if showplayerfaces=true) + showplayerbody: false + # Option to make player faces small - don't use with showplayerhealth or largeplayerfaces + smallplayerfaces: false + # Option to make player faces larger - don't use with showplayerhealth or smallplayerfaces + largeplayerfaces: false + # Optional - make player faces layer hidden by default + hidebydefault: false + # Optional - ordering priority in layer menu (low goes before high - default is 0) + layerprio: 0 + # Optional - label for player marker layer (default is 'Players') + label: "Players" + + #- class: org.dynmap.ClientComponent + # type: digitalclock + - class: org.dynmap.ClientComponent + type: link + + - class: org.dynmap.ClientComponent + type: timeofdayclock + showdigitalclock: true + #showweather: true + # Mouse pointer world coordinate display + - class: org.dynmap.ClientComponent + type: coord + label: "Location" + hidey: false + show-mcr: false + show-chunk: false + + # Note: more than one logo component can be defined + #- class: org.dynmap.ClientComponent + # type: logo + # text: "Dynmap" + # #logourl: "images/block_surface.png" + # linkurl: "http://forums.bukkit.org/threads/dynmap.489/" + # # Valid positions: top-left, top-right, bottom-left, bottom-right + # position: bottom-right + + #- class: org.dynmap.ClientComponent + # type: inactive + # timeout: 1800 # in seconds (1800 seconds = 30 minutes) + # redirecturl: inactive.html + # #showmessage: 'You were inactive for too long.' + + #- class: org.dynmap.TestComponent + # stuff: "This is some configuration-value" + +# Treat hiddenplayers.txt as a whitelist for players to be shown on the map? (Default false) +display-whitelist: false + +# How often a tile gets rendered (in seconds). +renderinterval: 1 + +# How many tiles on update queue before accelerate render interval +renderacceleratethreshold: 60 + +# How often to render tiles when backlog is above renderacceleratethreshold +renderaccelerateinterval: 0.2 + +# How many update tiles to work on at once (if not defined, default is 1/2 the number of cores) +tiles-rendered-at-once: 2 + +# If true, use normal priority threads for rendering (versus low priority) - this can keep rendering +# from starving on busy Windows boxes (Linux JVMs pretty much ignore thread priority), but may result +# in more competition for CPU resources with other processes +usenormalthreadpriority: true + +# Save and restore pending tile renders - prevents their loss on server shutdown or /reload +saverestorepending: true + +# Save period for pending jobs (in seconds): periodic saving for crash recovery of jobs +save-pending-period: 900 + +# Zoom-out tile update period - how often to scan for and process tile updates into zoom-out tiles (in seconds) +zoomoutperiod: 30 + +# Control whether zoom out tiles are validated on startup (can be needed if zoomout processing is interrupted, but can be expensive on large maps) +initial-zoomout-validate: true + +# Default delay on processing of updated tiles, in seconds. This can reduce potentially expensive re-rendering +# of frequently updated tiles (such as due to machines, pistons, quarries or other automation). Values can +# also be set on individual worlds and individual maps. +tileupdatedelay: 30 + +# Tile hashing is used to minimize tile file updates when no changes have occurred - set to false to disable +enabletilehash: true + +# Optional - hide ores: render as normal stone (so that they aren't revealed by maps) +#hideores: true + +# Optional - enabled BetterGrass style rendering of grass and snow block sides +#better-grass: true + +# Optional - enable smooth lighting by default on all maps supporting it (can be set per map as lighting option) +smooth-lighting: true + +# Optional - use world provider lighting table (good for custom worlds with custom lighting curves, like nether) +# false=classic Dynmap lighting curve +use-brightness-table: true + +# Optional - render specific block names using the textures and models of another block name: can be used to hide/disguise specific +# blocks (e.g. make ores look like stone, hide chests) or to provide simple support for rendering unsupported custom blocks +block-alias: +# "minecraft:quartz_ore": "stone" +# "diamond_ore": "coal_ore" + +# Default image format for HDMaps (png, jpg, jpg-q75, jpg-q80, jpg-q85, jpg-q90, jpg-q95, jpg-q100, webp, webp-q75, webp-q80, webp-q85, webp-q90, webp-q95, webp-q100), +# Note: any webp format requires the presence of the 'webp command line tools' (cwebp, dwebp) (https://developers.google.com/speed/webp/download) +# +# Has no effect on maps with explicit format settings +image-format: jpg-q90 + +# If cwebp or dwebp are not on the PATH, use these settings to provide their full path. Do not use these settings if the tools are on the PATH +# For Windows, include .exe +# +#cwebpPath: /usr/bin/cwebp +#dwebpPath: /usr/bin/dwebp + +# use-generated-textures: if true, use generated textures (same as client); false is static water/lava textures +# correct-water-lighting: if true, use corrected water lighting (same as client); false is legacy water (darker) +# transparent-leaves: if true, leaves are transparent (lighting-wise): false is needed for some Spout versions that break lighting on leaf blocks +use-generated-textures: true +correct-water-lighting: true +transparent-leaves: true + +# ctm-support: if true, Connected Texture Mod (CTM) in texture packs is enabled (default) +ctm-support: true +# custom-colors-support: if true, Custom Colors in texture packs is enabled (default) +custom-colors-support: true + +# Control loading of player faces (if set to false, skins are never fetched) +#fetchskins: false + +# Control updating of player faces, once loaded (if faces are being managed by other apps or manually) +#refreshskins: false + +# Customize URL used for fetching player skins (%player% is macro for name, %uuid% for UUID) +skin-url: "http://skins.minecraft.net/MinecraftSkins/%player%.png" + +# Control behavior for new (1.0+) compass orientation (sunrise moved 90 degrees: east is now what used to be south) +# default is 'newrose' (preserve pre-1.0 maps, rotate rose) +# 'newnorth' is used to rotate maps and rose (requires fullrender of any HDMap map - same as 'newrose' for FlatMap or KzedMap) +compass-mode: newnorth + +# Triggers for automatic updates : blockupdate-with-id is debug for breaking down updates by ID:meta +# To disable, set just 'none' and comment/delete the rest +render-triggers: + - blockupdate + #- blockupdate-with-id + #- lightingupdate + - chunkpopulate + - chunkgenerate + #- none + +# Title for the web page - if not specified, defaults to the server's name (unless it is the default of 'Unknown Server') +#webpage-title: "My Awesome Server Map" + +# The path where the tile-files are placed. +tilespath: web/tiles + +# The path where the web-files are located. +webpath: web + +# If set to false, disable extraction of webpath content (good if using custom web UI or 3rd party web UI) +# Note: web interface is unsupported in this configuration - you're on your own +update-webpath-files: true + +# The path were the /dynmapexp command exports OBJ ZIP files +exportpath: export + +# The path where files can be imported for /dmarker commands +importpath: import + +# The network-interface the webserver will bind to (0.0.0.0 for all interfaces, 127.0.0.1 for only local access). +# If not set, uses same setting as server in server.properties (or 0.0.0.0 if not specified) +#webserver-bindaddress: 0.0.0.0 + +# The TCP-port the webserver will listen on. +webserver-port: 8123 + +# Maximum concurrent session on internal web server - limits resources used in Bukkit server +max-sessions: 30 + +# Disables Webserver portion of Dynmap (Advanced users only) +disable-webserver: false + +# Enable/disable having the web server allow symbolic links (true=compatible with existing code, false=more secure (default)) +allow-symlinks: true + +# Enable login support +login-enabled: false +# Require login to access website (requires login-enabled: true) +login-required: false + +# Period between tile renders for fullrender, in seconds (non-zero to pace fullrenders, lessen CPU load) +timesliceinterval: 0.0 + +# Maximum chunk loads per server tick (1/20th of a second) - reducing this below 90 will impact render performance, but also will reduce server thread load +maxchunkspertick: 200 + +# Progress report interval for fullrender/radiusrender, in tiles. Must be 100 or greater +progressloginterval: 100 + +# Parallel fullrender: if defined, number of concurrent threads used for fullrender or radiusrender +# Note: setting this will result in much more intensive CPU use, some additional memory use. Caution should be used when +# setting this to equal or exceed the number of physical cores on the system. +#parallelrendercnt: 4 + +# Interval the browser should poll for updates. +updaterate: 2000 + +# If nonzero, server will pause fullrender/radiusrender processing when 'fullrenderplayerlimit' or more users are logged in +fullrenderplayerlimit: 0 +# If nonzero, server will pause update render processing when 'updateplayerlimit' or more users are logged in +updateplayerlimit: 0 +# Target limit on server thread use - msec per tick +per-tick-time-limit: 50 +# If TPS of server is below this setting, update renders processing is paused +update-min-tps: 18.0 +# If TPS of server is below this setting, full/radius renders processing is paused +fullrender-min-tps: 18.0 +# If TPS of server is below this setting, zoom out processing is paused +zoomout-min-tps: 18.0 + +showplayerfacesinmenu: true + +# Control whether players that are hidden or not on current map are grayed out (true=yes) +grayplayerswhenhidden: true + +# Set sidebaropened: 'true' to pin menu sidebar opened permanently, 'pinned' to default the sidebar to pinned, but allow it to unpin +#sidebaropened: true + +# Customized HTTP response headers - add 'id: value' pairs to all HTTP response headers (internal web server only) +#http-response-headers: +# Access-Control-Allow-Origin: "my-domain.com" +# X-Custom-Header-Of-Mine: "MyHeaderValue" + +# Trusted proxies for web server - which proxy addresses are trusted to supply valid X-Forwarded-For fields +# This now supports both IP address, and subnet ranges (e.g. 192.168.1.0/24 or 202.24.0.0/14 ) +trusted-proxies: + - "127.0.0.1" + - "0:0:0:0:0:0:0:1" + +joinmessage: "%playername% joined" +quitmessage: "%playername% quit" +spammessage: "You may only chat once every %interval% seconds." +# format for messages from web: %playername% substitutes sender ID (typically IP), %message% includes text +webmsgformat: "&color;2[WEB] %playername%: &color;f%message%" + +# Control whether layer control is presented on the UI (default is true) +showlayercontrol: true + +# Enable checking for banned IPs via banned-ips.txt (internal web server only) +check-banned-ips: true + +# Default selection when map page is loaded +defaultzoom: 0 +defaultworld: world +defaultmap: flat +# (optional) Zoom level and map to switch to when following a player, if possible +#followzoom: 3 +#followmap: surface + +# If true, make persistent record of IP addresses used by player logins, to support web IP to player matching +persist-ids-by-ip: true + +# If true, map text to cyrillic +cyrillic-support: false + +# Messages to customize +msg: + maptypes: "Map Types" + players: "Players" + chatrequireslogin: "Chat Requires Login" + chatnotallowed: "You are not permitted to send chat messages" + hiddennamejoin: "Player joined" + hiddennamequit: "Player quit" + +# URL for client configuration (only need to be tailored for proxies or other non-standard configurations) +url: + # configuration URL + #configuration: "up/configuration" + # update URL + #update: "up/world/{world}/{timestamp}" + # sendmessage URL + #sendmessage: "up/sendmessage" + # login URL + #login: "up/login" + # register URL + #register: "up/register" + # tiles base URL + #tiles: "tiles/" + # markers base URL + #markers: "tiles/" + # Snapshot cache size, in chunks +snapshotcachesize: 500 +# Snapshot cache uses soft references (true), else weak references (false) +soft-ref-cache: true + +# Player enter/exit title messages for map markers +# +# Processing period - how often to check player positions vs markers - default is 1000ms (1 second) +#enterexitperiod: 1000 +# Title message fade in time, in ticks (0.05 second intervals) - default is 10 (1/2 second) +#titleFadeIn: 10 +# Title message stay time, in ticks (0.05 second intervals) - default is 70 (3.5 seconds) +#titleStay: 70 +# Title message fade out time, in ticks (0.05 seocnd intervals) - default is 20 (1 second) +#titleFadeOut: 20 +# Enter/exit messages use on screen titles (true - default), if false chat messages are sent instead +#enterexitUseTitle: true +# Set true if new enter messages should supercede pending exit messages (vs being queued in order), default false +#enterReplacesExits: true + +# Published public URL for Dynmap server (allows users to use 'dynmap url' command to get public URL usable to access server +# If not set, 'dynmap url' will not return anything. URL should be fully qualified (e.g. https://mc.westeroscraft.com/) +#publicURL: http://my.greatserver.com/dynmap + +# Send this message if the player does not have permission to use the command +noPermissionMsg: "You don't have permission to use this command!" + +# Set to true to enable verbose startup messages - can help with debugging map configuration problems +# Set to false for a much quieter startup log +verbose: false + +# Enables debugging. +#debuggers: +# - class: org.dynmap.debug.LogDebugger +# Debug: dump blocks missing render data +dump-missing-blocks: false + +# Log4J defense: string substituted for attempts to use macros in web chat +hackAttemptBlurb: "(IaM5uchA1337Haxr-Ban Me!)" diff --git a/forge-1.21.6/src/main/resources/pack.mcmeta b/forge-1.21.6/src/main/resources/pack.mcmeta new file mode 100644 index 000000000..64ff3854a --- /dev/null +++ b/forge-1.21.6/src/main/resources/pack.mcmeta @@ -0,0 +1,8 @@ +{ + "pack": { + "description": { + "text": "Dynmap resources" + }, + "pack_format": 22 + } +} diff --git a/forge-1.21.6/src/main/resources/permissions.yml.example b/forge-1.21.6/src/main/resources/permissions.yml.example new file mode 100644 index 000000000..a25f9adca --- /dev/null +++ b/forge-1.21.6/src/main/resources/permissions.yml.example @@ -0,0 +1,27 @@ +# +# Sample permissions.yml for dynmap - trivial, flat-file based permissions for dynmap features +# To use, copy this file to dynmap/permissions.yml, and edit appropriate. File is YAML format. +# +# All operators have full permissions to all functions. +# All users receive the permissions under the 'defaultuser' section +# Specific users can be given more permissions by defining a section with their name containing their permisssions +# All permissions correspond to those documented here (https://github.com/webbukkit/dynmap/wiki/Permissions), but +# do NOT have the 'dynmap.' prefix when used here (e.g. 'dynmap.fullrender' permission is just 'fullrender' here). +# +defaultuser: + - render + - show.self + - hide.self + - sendtoweb + - stats + - marker.list + - marker.listsets + - marker.icons + - webregister + - webchat + #- marker.sign + +#playername1: +# - fullrender +# - cancelrender +# - radiusrender diff --git a/gradle.properties b/gradle.properties index 1f4688034..6b6d6983d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,8 @@ org.gradle.jvmargs=-Xmx4G org.gradle.daemon=false org.gradle.parallel=false +# GitHub user and password (workaround for OSSRH beeing sunset - https://central.sonatype.org/pages/ossrh-eol/ +# https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic +# https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-gradle-registry#authenticating-to-github-packages +gpr.user="" +gpr.key="" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 94113f200..ca025c83a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/oldbuilds/build.gradle b/oldbuilds/build.gradle index ea97377e1..fcceaaac9 100644 --- a/oldbuilds/build.gradle +++ b/oldbuilds/build.gradle @@ -26,7 +26,7 @@ allprojects { apply plugin: 'java' group = 'us.dynmap' - version = '3.7-beta-8' + version = '3.9-SNAPSHOT' } diff --git a/settings.gradle b/settings.gradle index 1a5709986..3429534f0 100644 --- a/settings.gradle +++ b/settings.gradle @@ -29,13 +29,17 @@ include ':bukkit-helper-120-5' include ':bukkit-helper-121' include ':bukkit-helper-121-3' include ':bukkit-helper-121-4' +include ':bukkit-helper-121-5' +include ':bukkit-helper-121-6' +include ':bukkit-helper-121-10' +include ':bukkit-helper-121-11' include ':bukkit-helper' include ':dynmap-api' include ':DynmapCore' include ':DynmapCoreAPI' -include ':fabric-1.21.1' -include ':fabric-1.21.3' -include ':fabric-1.21' +include ':fabric-1.21.6' +include ':fabric-1.21.9-10' +include ':fabric-1.21.11' include ':fabric-1.20.6' include ':fabric-1.19.4' include ':fabric-1.18.2' @@ -43,8 +47,9 @@ include ':fabric-1.17.1' include ':fabric-1.16.4' include ':fabric-1.15.2' include ':fabric-1.14.4' -include ':forge-1.21.3' -include ':forge-1.21' +include ':forge-1.21.11' +include ':forge-1.21.10' +include ':forge-1.21.6' include ':forge-1.20.6' include ':forge-1.19.3' include ':forge-1.18.2' @@ -74,13 +79,17 @@ project(':bukkit-helper-120-5').projectDir = "$rootDir/bukkit-helper-120-5" as F 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-121-4').projectDir = "$rootDir/bukkit-helper-121-4" as File +project(':bukkit-helper-121-5').projectDir = "$rootDir/bukkit-helper-121-5" as File +project(':bukkit-helper-121-6').projectDir = "$rootDir/bukkit-helper-121-6" as File +project(':bukkit-helper-121-10').projectDir = "$rootDir/bukkit-helper-121-10" as File +project(':bukkit-helper-121-11').projectDir = "$rootDir/bukkit-helper-121-11" 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 project(':DynmapCoreAPI').projectDir = "$rootDir/DynmapCoreAPI" as File -project(':fabric-1.21.1').projectDir = "$rootDir/fabric-1.21.1" as File -project(':fabric-1.21.3').projectDir = "$rootDir/fabric-1.21.3" as File -project(':fabric-1.21').projectDir = "$rootDir/fabric-1.21" as File +project(':fabric-1.21.6').projectDir = "$rootDir/fabric-1.21.6" as File +project(':fabric-1.21.9-10').projectDir = "$rootDir/fabric-1.21.9-10" as File +project(':fabric-1.21.11').projectDir = "$rootDir/fabric-1.21.11" as File project(':fabric-1.20.6').projectDir = "$rootDir/fabric-1.20.6" as File project(':fabric-1.19.4').projectDir = "$rootDir/fabric-1.19.4" as File project(':fabric-1.18.2').projectDir = "$rootDir/fabric-1.18.2" as File @@ -88,8 +97,9 @@ project(':fabric-1.17.1').projectDir = "$rootDir/fabric-1.17.1" as File project(':fabric-1.16.4').projectDir = "$rootDir/fabric-1.16.4" as File project(':fabric-1.15.2').projectDir = "$rootDir/fabric-1.15.2" as File project(':fabric-1.14.4').projectDir = "$rootDir/fabric-1.14.4" as File -project(':forge-1.21.3').projectDir = "$rootDir/forge-1.21.3" as File -project(':forge-1.21').projectDir = "$rootDir/forge-1.21" as File +project(':forge-1.21.11').projectDir = "$rootDir/forge-1.21.11" as File +project(':forge-1.21.10').projectDir = "$rootDir/forge-1.21.10" as File +project(':forge-1.21.6').projectDir = "$rootDir/forge-1.21.6" as File project(':forge-1.20.6').projectDir = "$rootDir/forge-1.20.6" as File project(':forge-1.19.3').projectDir = "$rootDir/forge-1.19.3" as File project(':forge-1.18.2').projectDir = "$rootDir/forge-1.18.2" as File diff --git a/spigot/build.gradle b/spigot/build.gradle index eea07d833..9fa548e1d 100644 --- a/spigot/build.gradle +++ b/spigot/build.gradle @@ -97,6 +97,18 @@ dependencies { implementation(project(':bukkit-helper-121-4')) { transitive = false } + implementation(project(':bukkit-helper-121-5')) { + transitive = false + } + implementation(project(':bukkit-helper-121-6')) { + transitive = false + } + implementation(project(':bukkit-helper-121-10')) { + transitive = false + } + implementation(project(':bukkit-helper-121-11')) { + transitive = false + } } processResources { @@ -140,6 +152,10 @@ shadowJar { include(dependency(':bukkit-helper-121')) include(dependency(':bukkit-helper-121-3')) include(dependency(':bukkit-helper-121-4')) + include(dependency(':bukkit-helper-121-5')) + include(dependency(':bukkit-helper-121-6')) + include(dependency(':bukkit-helper-121-10')) + include(dependency(':bukkit-helper-121-11')) } relocate('org.bstats', 'org.dynmap.bstats') destinationDirectory = file '../target' diff --git a/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java b/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java index 56662ee95..48c8b4fe1 100644 --- a/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java +++ b/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java @@ -1091,7 +1091,9 @@ public void onDisable() { } /* Disable core */ - core.disableCore(); + if (core != null) { + core.disableCore(); + } if(SnapshotCache.sscache != null) { SnapshotCache.sscache.cleanup(); diff --git a/spigot/src/main/java/org/dynmap/bukkit/Helper.java b/spigot/src/main/java/org/dynmap/bukkit/Helper.java index 3a4b87f2f..26cc72e7f 100644 --- a/spigot/src/main/java/org/dynmap/bukkit/Helper.java +++ b/spigot/src/main/java/org/dynmap/bukkit/Helper.java @@ -40,14 +40,26 @@ else if(Bukkit.getServer().getClass().getName().contains("GlowServer")) { Log.info("Loading Glowstone support"); BukkitVersionHelper.helper = loadVersionHelper("org.dynmap.bukkit.helper.BukkitVersionHelperGlowstone"); } - else if (v.contains("(MC: 1.21.4")) { - BukkitVersionHelper.helper = loadVersionHelper("org.dynmap.bukkit.helper.v121_4.BukkitVersionHelperSpigot121_4"); + 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.21.2") || v.contains("(MC: 1.21.3")) { + 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.21.4)")) { + BukkitVersionHelper.helper = loadVersionHelper("org.dynmap.bukkit.helper.v121_4.BukkitVersionHelperSpigot121_4"); + } + else if (v.contains("(MC: 1.21.5)")) { + BukkitVersionHelper.helper = loadVersionHelper("org.dynmap.bukkit.helper.v121_5.BukkitVersionHelperSpigot121_5"); + } + else if (v.contains("(MC: 1.21.6") || v.contains("(MC: 1.21.7") || v.contains("(MC: 1.21.8")) { + BukkitVersionHelper.helper = loadVersionHelper("org.dynmap.bukkit.helper.v121_6.BukkitVersionHelperSpigot121_6"); + } + else if (v.contains("(MC: 1.21.9)") || v.contains("(MC: 1.21.10)")) { + BukkitVersionHelper.helper = loadVersionHelper("org.dynmap.bukkit.helper.v121_10.BukkitVersionHelperSpigot121_10"); + } + else if (v.contains("(MC: 1.21.")) { // Set up in case 1.21.12 works 'as is' + BukkitVersionHelper.helper = loadVersionHelper("org.dynmap.bukkit.helper.v121_11.BukkitVersionHelperSpigot121_11"); } else if (v.contains("(MC: 1.20)") || v.contains("(MC: 1.20.1)")) { BukkitVersionHelper.helper = loadVersionHelper("org.dynmap.bukkit.helper.v120.BukkitVersionHelperSpigot120");