From 9d5c151f798ca7df45dea25a887f95044f8a5fa7 Mon Sep 17 00:00:00 2001 From: kyngs Date: Sun, 11 Aug 2024 22:52:34 +0200 Subject: [PATCH 001/133] Update to 1.21.1 --- gradle.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index 4aed08c01..c812bb2fa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,8 @@ group=com.infernalsuite.aswm -version=1.21-R0.1-SNAPSHOT +version=1.21.1-R0.1-SNAPSHOT -mcVersion=1.21 -paperRef=b1b5d4c1e4b7c95afd5c932ca392bee66533a60c +mcVersion=1.21.1 +paperRef=1187544fb0946e1480acdd52213c2ecb3f321a74 org.gradle.caching=true org.gradle.parallel=true From c337bad3678c1e99ace6c3171e3dcdbfad4a4520 Mon Sep 17 00:00:00 2001 From: IS_Bot Date: Mon, 12 Aug 2024 00:16:58 +0200 Subject: [PATCH 002/133] Update Upstream Automatically updated to Paper commit: a8cb8e6745dab32139d954d732a3423a454545ab [ci skip] Fix JavaDocs for HeightMap#MOTION_BLOCKING_NO_LEAVES (#11291) Automatically updated to Paper commit: ba1b0162faaa7bf78d33162f6976586bb3049275 Allow server administrators to disable book size checks (#10457) Automatically updated to Paper commit: dae906ba452e4a17779aa6438ccd6deb42d7f0df Add getWorld method that uses adventure Key (#11199) Automatically updated to Paper commit: 8fd3a67138b5d7a3a21e059eb3c3b766ffdfc281 [ci skip] Clean up book limits patch (#11297) Automatically updated to Paper commit: be1078f5f2e28c1a1de99e9c96e4003c3f96f6e8 Use player file, not directory, when checking for offline player data When trying to fall back to offline player data in onlide mode, we need to use the player file. This fixes a mistake during update where 'file' was used, but the new code uses 'file1' for the player file. Automatically updated to Paper commit: b4bc512cac4d75f9e366479c5d8fdcf4275c85ce Fix entity limit patch deleting unnecessary entities We need to continue the save loop, not break from it when a limit is reached. Automatically updated to Paper commit: 64c9ee6584ce15e5b486bdc7183fe902e22fddf3 Allow getting/setting the sign's editor uuid (#10637) * Allow getting/setting the sign's editor uuid * rebased --------- Co-authored-by: Jake Potrebic Automatically updated to Paper commit: 44017487a81534067fd17e2d5e8669e61e19d719 Fix CraftBukkit drag system (#10703) Automatically updated to Paper commit: 8c3018a4b177aa0f7658d510bf7d19c5fa8e5b65 Fix Selector Arguments not working with permission (#11286) Automatically updated to Paper commit: 57dd822393df78a4cb47f7a2c2d037dc2a77d5bd Leashable API (#10961) Automatically updated to Paper commit: 2e82fd2d2c1881665e27654977390fa48f5ec346 Add even more Enchantment API (#11115) Automatically updated to Paper commit: 66a97cc929740475bc8dd192382c4ae59fdeace9 Update item data sanitization (#11227) Automatically updated to Paper commit: 0e7361704a16c8386d829c26603f3e5c0bf72b39 Updated Upstream (Bukkit/CraftBukkit/Spigot) (#11284) Updated Upstream (Bukkit/CraftBukkit/Spigot) Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 4068c6aa PR-1053: Change docs for max power in FireworkMeta 6b3c241b SPIGOT-7783, SPIGOT-7784, PR-1051: Add Trial Vault & Spawner event API 5fe300ec PR-1052: Fix broken links and minor improvement for checkstyle.xml CraftBukkit Changes: 7548afcf2 SPIGOT-7872: Fix crash with event-modified teleports 93480d5d6 SPIGOT-7868, PR-1463: Fix default and max power in FireworkMeta 5060d1a84 SPIGOT-7783, SPIGOT-7784, PR-1460: Add Trial Vault & Spawner event API 11dfcae71 PR-1462: Fix broken links and minor improvement for checkstyle.xml Spigot Changes: ca581228 Rebuild patches Automatically updated to Paper commit: 75655ec1d34f344c7b0ba9f31f2ada87951d277d Add Configuration for vertical Despawn Ranges (#11279) Automatically updated to Paper commit: 52ae4ad4666b34d637f2de573ed03c02b0fc6a24 Migrate ArmorStand meta to using entity tag (#11107) Automatically updated to Paper commit: d5ffc573dc17092ea2cfdd4ce14dac3e70b932f5 Implement more methods for horse inventories (#11147) Automatically updated to Paper commit: 4829fbf6bd51e2dc86e2f190971c081aac76a201 Handle custom registry elements properly (#11230) * Handle custom registry elements properly * update error message Datapack made painting variant support is added in https://github.com/PaperMC/Paper/pull/11244 * change msg for art conversion --------- Co-authored-by: Jake Potrebic Automatically updated to Paper commit: 78216fef26e454c78dff5e495f6ebe673be56900 Re-implement portalCreateRadius world config (#11267) Automatically updated to Paper commit: e619744fbdc4963eed0b04c1e44bd1089ce50285 Allow skipping of world symlink validation (#11250) Automatically updated to Paper commit: 534ab86010330ce3afa732910227585d0dc02d1e [ci-skip] Revert "Add Configuration for vertical Despawn Ranges (#10440)" (#11278) This reverts commit 1b8ab116edd5da15791de96aa462db90756848dc. Automatically updated to Paper commit: 1b8ab116edd5da15791de96aa462db90756848dc Add Configuration for vertical Despawn Ranges (#10440) Automatically updated to Paper commit: ec55c11fc074929e4aa1a1ecdaef51da69dbf0be Fix indestructable light blocks (#11275) Co-authored-by: Bjarne Koll Automatically updated to Paper commit: 95719832bf57ae523982d681cd219e8387c39955 Fix scanForLegacyEnderDragon world config (#11262) Automatically updated to Paper commit: 81bfda87103e1a47ea184c5da119e79218a8dc1e [ci skip] Specify rebase location in CONTRIBUTING (#11255) * [ci skip] Specify rebase location in CONTRIBUTING * Improve * remove Paper-MojangAPI mention --------- Co-authored-by: Bjarne Koll Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Automatically updated to Paper commit: fb530743e5c71cb4faba06339bdeb14a33e06a6a Apply optimise collision checking in move packet handling patch Automatically updated to Paper commit: bf5852a6151aa643b87bd0e0f9e3940f867064a3 Fix NPE for PlayerPostRespawnEvent#getRespawnedLocation (#11268) Automatically updated to Paper commit: 11b4ac7c659ffb7e4790b0856b14117b6d532200 Fix disableEndCredits world config (#11261) Automatically updated to Paper commit: 9ab644ed290542a9e537d8f529bc6898a3da2e7d Fix `TooltipContext.create` being wrong(#11254) Co-authored-by: Jake Potrebic Automatically updated to Paper commit: 7c9240f4a63b13be1fdcedbfb0270f9b49b75518 Improve standard messenger logging Automatically updated to Paper commit: 1798e949e5727f376ccaee51873f21dcdedc9a5f Fix BasicCommand suggestion arg count (#11241) Automatically updated to Paper commit: 4a97ba3ea8cb449fe76ed1aef0b572e7cc01d542 Fix `setSendViewDistance`'s return (#11247) Automatically updated to Paper commit: f97aff74b6f7fd4940c0c0b6cca3f8ac6e1afdef [ci skip] Fix Effect javadocs (#11182) Automatically updated to Paper commit: 098bd39092f50cb97a604c2f228f2af29666ca41 Remove arbitrary book page limit (#11228) Automatically updated to Paper commit: ab0d24aa6f22308352eb363b09c992fc70de4143 Configuration for horizontal-only item merging (#11219) --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index c812bb2fa..f2a77fe13 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ group=com.infernalsuite.aswm version=1.21.1-R0.1-SNAPSHOT mcVersion=1.21.1 -paperRef=1187544fb0946e1480acdd52213c2ecb3f321a74 +paperRef=a8cb8e6745dab32139d954d732a3423a454545ab org.gradle.caching=true org.gradle.parallel=true From cbb8fb2cb7e7b0ea819bd8c797810e6b18d9c80d Mon Sep 17 00:00:00 2001 From: kyngs Date: Wed, 21 Aug 2024 18:46:16 +0200 Subject: [PATCH 003/133] Re-add null-check in FastChunkPruner.java --- patches/server/0015-1.21-compatibility.patch | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/patches/server/0015-1.21-compatibility.patch b/patches/server/0015-1.21-compatibility.patch index 4e34ce355..4fae989ff 100644 --- a/patches/server/0015-1.21-compatibility.patch +++ b/patches/server/0015-1.21-compatibility.patch @@ -38,7 +38,7 @@ index f9ac1efca06d8debbb7894160c3e67fd23440ebb..b5a1f75314aac73fb77e139398017b16 import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.ChunkPos; diff --git a/src/main/java/com/infernalsuite/aswm/level/FastChunkPruner.java b/src/main/java/com/infernalsuite/aswm/level/FastChunkPruner.java -index c0e47f25e9be33da374dc737c96d8d3c2bb1cd0f..0f4de8602c3b897e4eb7246951a1a1db646c59fa 100644 +index c0e47f25e9be33da374dc737c96d8d3c2bb1cd0f..4e5eb92e0aa40ca02e58f988ec39a6461f63ac2f 100644 --- a/src/main/java/com/infernalsuite/aswm/level/FastChunkPruner.java +++ b/src/main/java/com/infernalsuite/aswm/level/FastChunkPruner.java @@ -1,9 +1,9 @@ @@ -52,15 +52,6 @@ index c0e47f25e9be33da374dc737c96d8d3c2bb1cd0f..0f4de8602c3b897e4eb7246951a1a1db import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; -@@ -13,7 +13,7 @@ public class FastChunkPruner { - // Kenox - // It's not safe to assume that the chunk can be pruned - // if there isn't a loaded chunk there -- if (chunk == null || chunk.getChunkHolder() == null) { -+ if (chunk == null) { - return false; - } - diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java index 6ef45be4a76c00be5fbfcdb543882fcf41ea6271..9b4b18758d52d66e4abf9e40e49a32428de68b9a 100644 --- a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java @@ -257,7 +248,7 @@ index 2265f83768c4dc29f67d29730c4be45a194727da..187336ecaa4262e3f081a88702031b17 @Override public void setDefaultSpawnPos(BlockPos pos, float angle) { diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index 5453b7051337908ac1c8201827c1b5eec9e1608b..ca011a8803f7a35cc8e24a0b3be15c2347806709 100644 +index 7c11853c5090fbc4fa5b3e73a69acf166158fdec..8e1c3e50f0bc46245488ffa23056120e4500c4f1 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -1,5 +1,7 @@ From ee1a536f3b058b639b233937fed0019146534e1c Mon Sep 17 00:00:00 2001 From: NotStevy Date: Mon, 19 Aug 2024 10:33:37 +0200 Subject: [PATCH 004/133] Migrate back to the gradleup shadow plugin and upgrade version to 8.3.0 --- build.gradle.kts | 2 +- patches/server/0001-Build-Changes.patch | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 91aabfcf0..55bab9135 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,7 @@ plugins { java `maven-publish` - id("io.github.goooler.shadow") version "8.1.7" apply false + id("com.gradleup.shadow") version "8.3.0" apply false id("io.papermc.paperweight.patcher") version "1.7.1" id("org.kordamp.gradle.profiles") version "0.47.0" } diff --git a/patches/server/0001-Build-Changes.patch b/patches/server/0001-Build-Changes.patch index 8ae0f0580..6e234ed4f 100644 --- a/patches/server/0001-Build-Changes.patch +++ b/patches/server/0001-Build-Changes.patch @@ -3,17 +3,17 @@ From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> Date: Mon, 26 Dec 2022 11:25:35 -0500 Subject: [PATCH] Build Changes -Change shadow plugin +Update shadow plugin diff --git a/build.gradle.kts b/build.gradle.kts -index 421f6b3dc8890d63d2e7aa774d0bf8f7e15890ab..ef23b818c58015cd4be77962ea257d4cb4a2a7ac 100644 +index 421f6b3dc8890d63d2e7aa774d0bf8f7e15890ab..51752096a568fd55b0ae09e778f1e0851d839e40 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,6 +4,7 @@ import java.time.Instant plugins { java `maven-publish` -+ id("io.github.goooler.shadow") ++ id("com.gradleup.shadow") } val log4jPlugins = sourceSets.create("log4jPlugins") From 80e3297521cd74691194e4db683d025a2d769013 Mon Sep 17 00:00:00 2001 From: jepudev <71714253+jepu2x@users.noreply.github.com> Date: Sun, 25 Aug 2024 01:53:47 +0800 Subject: [PATCH 005/133] Fix typo: worldData.name() was added twice to WorldsInUse instead of being removed. --- .../infernalsuite/aswm/plugin/commands/sub/LoadWorldCmd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/LoadWorldCmd.java b/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/LoadWorldCmd.java index 3581354ca..c8500506d 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/LoadWorldCmd.java +++ b/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/LoadWorldCmd.java @@ -111,7 +111,7 @@ public CompletableFuture onCommand(CommandSender sender, @Argument(value = Component.text("Failed to load world " + worldData.name() + ". Take a look at the server console for more information.").color(NamedTextColor.RED) )); } finally { - commandManager.getWorldsInUse().add(worldData.name()); + commandManager.getWorldsInUse().remove(worldData.name()); } }); } From 3e348125785263e53d1884ea286b8e1ad06ecaaa Mon Sep 17 00:00:00 2001 From: TechStreet Date: Sat, 31 Aug 2024 20:44:16 +0100 Subject: [PATCH 006/133] fix: issue with chunks not saving sometimes when unloading the world --- 0016-Fix-chunk-saving-when-unloading.patch | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 0016-Fix-chunk-saving-when-unloading.patch diff --git a/0016-Fix-chunk-saving-when-unloading.patch b/0016-Fix-chunk-saving-when-unloading.patch new file mode 100644 index 000000000..565b37cbb --- /dev/null +++ b/0016-Fix-chunk-saving-when-unloading.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: TechStreet <80351782+TechStreetDev@users.noreply.github.com> +Date: Mon, 26 Aug 2024 21:27:08 +0100 +Subject: [PATCH] Fix chunk saving when unloading + + +diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java +index 187336ecaa4262e3f081a88702031b17c6037091..6a5a8fbd8ee013828685495267283d9518d32d20 100644 +--- a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java ++++ b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java +@@ -25,6 +25,7 @@ import net.minecraft.world.Difficulty; + import net.minecraft.world.level.biome.Biome; + import net.minecraft.world.level.chunk.ChunkAccess; + import net.minecraft.world.level.chunk.ChunkGenerator; ++import net.minecraft.world.level.chunk.LevelChunk; + import net.minecraft.world.level.dimension.LevelStem; + import net.minecraft.world.level.storage.LevelStorageSource; + import net.minecraft.world.level.storage.PrimaryLevelData; +@@ -200,9 +201,9 @@ public class SlimeLevelInstance extends ServerLevel { + propertyMap.setValue(SlimeProperties.SPAWN_YAW, angle); + } + +- // @Override +- // public void unload(LevelChunk chunk) { +- // this.slimeInstance.unload(chunk); +- // super.unload(chunk); +- // } ++ @Override ++ public void unload(LevelChunk chunk) { ++ this.slimeInstance.unload(chunk); ++ super.unload(chunk); ++ } + } + From 17eb817a4734b9bc493a5976bf0e8130c16b7a5b Mon Sep 17 00:00:00 2001 From: evlad Date: Mon, 9 Sep 2024 21:40:52 +0300 Subject: [PATCH 007/133] fix disable dragon fights --- .../0017-fix-disable-dragon-fights.patch | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 patches/server/0017-fix-disable-dragon-fights.patch diff --git a/patches/server/0017-fix-disable-dragon-fights.patch b/patches/server/0017-fix-disable-dragon-fights.patch new file mode 100644 index 000000000..135214451 --- /dev/null +++ b/patches/server/0017-fix-disable-dragon-fights.patch @@ -0,0 +1,39 @@ +From d3f1ea79f13a10c567902d8679230de5b2ae8413 Mon Sep 17 00:00:00 2001 +From: evlad +Date: Mon, 9 Sep 2024 21:33:11 +0300 +Subject: [PATCH] fix disable dragon fights + +--- + .../java/net/minecraft/server/level/ServerLevel.java | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java +index 5aae3c769..a0bd2e0e3 100644 +--- a/src/main/java/net/minecraft/server/level/ServerLevel.java ++++ b/src/main/java/net/minecraft/server/level/ServerLevel.java +@@ -3,6 +3,7 @@ package net.minecraft.server.level; + import com.google.common.annotations.VisibleForTesting; + import co.aikar.timings.TimingHistory; // Paper + import com.google.common.collect.Lists; ++import com.infernalsuite.aswm.api.world.properties.SlimeProperties; // ASP + import com.mojang.datafixers.DataFixer; + import com.mojang.datafixers.util.Pair; + import com.mojang.logging.LogUtils; +@@ -580,7 +581,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. + this.structureCheck = new StructureCheck(this.chunkSource.chunkScanner(), this.registryAccess(), minecraftserver.getStructureManager(), this.getTypeKey(), chunkgenerator, this.chunkSource.randomState(), this, chunkgenerator.getBiomeSource(), l, datafixer); // Paper - Fix missing CB diff + this.structureManager = new StructureManager(this, this.serverLevelData.worldGenOptions(), this.structureCheck); // CraftBukkit + if ((this.dimension() == Level.END && this.dimensionTypeRegistration().is(BuiltinDimensionTypes.END)) || env == org.bukkit.World.Environment.THE_END) { // CraftBukkit - Allow to create EnderDragonBattle in default and custom END +- this.dragonFight = new EndDragonFight(this, this.serverLevelData.worldGenOptions().seed(), this.serverLevelData.endDragonFightData()); // CraftBukkit ++ // ASP START ++ if (bootstrap == null || bootstrap.initial().getPropertyMap().getValue(SlimeProperties.DRAGON_BATTLE)) { ++ this.dragonFight = new EndDragonFight(this, this.serverLevelData.worldGenOptions().seed(), this.serverLevelData.endDragonFightData()); // CraftBukkit ++ } else { ++ this.dragonFight = new EndDragonFight(this, this.serverLevelData.worldGenOptions().seed(), new EndDragonFight.Data(false, true, true, false,Optional.empty(),Optional.empty(),Optional.empty())); // ASP - disable dragon ++ } ++ // ASP END + } else { + this.dragonFight = null; + } +-- +2.46.0 + From e36d5ae2d238db2497fad65a43b57d7bb7c3fc4a Mon Sep 17 00:00:00 2001 From: evlad Date: Thu, 19 Sep 2024 20:48:35 +0300 Subject: [PATCH 008/133] fix chunk pdc getting wiped on chunk unload --- ...nk-pdc-getting-wiped-on-chunk-unload.patch | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch diff --git a/patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch b/patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch new file mode 100644 index 000000000..ed3abb287 --- /dev/null +++ b/patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch @@ -0,0 +1,27 @@ +From 1aa484ebd84203862ec7abe41c9e30a01e5ac90c Mon Sep 17 00:00:00 2001 +From: evlad +Date: Thu, 19 Sep 2024 20:47:32 +0300 +Subject: [PATCH] fix chunk pdc getting wiped on chunk unload + +--- + src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java +index 9b4b18758..f0d773977 100644 +--- a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java ++++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java +@@ -68,7 +68,9 @@ public class NMSSlimeChunk implements SlimeChunk { + + public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference) { + this.chunk = chunk; +- this.extra = reference == null ? new CompoundTag("", new CompoundMap()) : reference.getExtraData(); ++ this.extra = new CompoundTag("", new CompoundMap()); ++ extra.getValue().put(Converter.convertTag("ChunkBukkitValues", chunk.persistentDataContainer.toTagCompound())); ++ + this.upgradeData = reference == null ? null : reference.getUpgradeData(); + } + +-- +2.46.0 + From 3fd836f239e38e3389905aee3aa21114fe79ce26 Mon Sep 17 00:00:00 2001 From: kyngs <38181667+kyngs@users.noreply.github.com> Date: Fri, 20 Sep 2024 21:20:59 +0200 Subject: [PATCH 009/133] Move patch 0016 to the correct folder --- .../server/0016-Fix-chunk-saving-when-unloading.patch | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename 0016-Fix-chunk-saving-when-unloading.patch => patches/server/0016-Fix-chunk-saving-when-unloading.patch (100%) diff --git a/0016-Fix-chunk-saving-when-unloading.patch b/patches/server/0016-Fix-chunk-saving-when-unloading.patch similarity index 100% rename from 0016-Fix-chunk-saving-when-unloading.patch rename to patches/server/0016-Fix-chunk-saving-when-unloading.patch From 6ba9ed9bc80611e0e92fa8fd802ec65f74a40f40 Mon Sep 17 00:00:00 2001 From: AverageGithub Date: Sun, 10 Nov 2024 13:09:53 +0100 Subject: [PATCH 010/133] 1.21.3 work maybe donegit add .! --- build.gradle.kts | 2 +- gradle.properties | 6 +- patches/api/0001-Slime-World-Manager.patch | 6 +- patches/server/0001-Build-Changes.patch | 106 +++---- patches/server/0002-poi-data-loader.patch | 30 +- patches/server/0004-Fix-entity-loading.patch | 4 +- ...e-plugin-and-server-rework-API-to-v3.patch | 6 +- patches/server/0015-1.21-compatibility.patch | 22 +- ...0016-Fix-chunk-saving-when-unloading.patch | 2 +- .../0017-fix-disable-dragon-fights.patch | 16 +- ...nk-pdc-getting-wiped-on-chunk-unload.patch | 10 +- patches/server/0019-1.21.3-fixes.patch | 278 ++++++++++++++++++ 12 files changed, 372 insertions(+), 116 deletions(-) create mode 100644 patches/server/0019-1.21.3-fixes.patch diff --git a/build.gradle.kts b/build.gradle.kts index 55bab9135..805afe106 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,7 +2,7 @@ plugins { java `maven-publish` id("com.gradleup.shadow") version "8.3.0" apply false - id("io.papermc.paperweight.patcher") version "1.7.1" + id("io.papermc.paperweight.patcher") version "1.7.4" id("org.kordamp.gradle.profiles") version "0.47.0" } diff --git a/gradle.properties b/gradle.properties index f2a77fe13..826ea81b6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,8 @@ group=com.infernalsuite.aswm -version=1.21.1-R0.1-SNAPSHOT +version=1.21.3-R0.1-SNAPSHOT -mcVersion=1.21.1 -paperRef=a8cb8e6745dab32139d954d732a3423a454545ab +mcVersion=1.21.3 +paperRef=92131adaf2687f350b2f8dc7cd1213ab833d1831 org.gradle.caching=true org.gradle.parallel=true diff --git a/patches/api/0001-Slime-World-Manager.patch b/patches/api/0001-Slime-World-Manager.patch index bc6fec6c8..ba10451f5 100644 --- a/patches/api/0001-Slime-World-Manager.patch +++ b/patches/api/0001-Slime-World-Manager.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Slime World Manager diff --git a/build.gradle.kts b/build.gradle.kts -index fd39ed209b20c927054b8482c400beeeeab460a3..9e413e83f422bba611adb8855b8700be68097006 100644 +index 254fd96d3950b4494c7e43547b00b5175ee53c93..911879d193907e65e0e0e50b8292d2394b934d42 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,5 @@ @@ -23,10 +23,10 @@ index fd39ed209b20c927054b8482c400beeeeab460a3..9e413e83f422bba611adb8855b8700be api("com.google.code.gson:gson:2.10.1") // Paper start - adventure diff --git a/src/main/java/io/papermc/paper/ServerBuildInfo.java b/src/main/java/io/papermc/paper/ServerBuildInfo.java -index 9df9d09aa477d4cd3c496ba0933c816df1ef0964..316d5e4478dfc3ae5ce11b20de7baeab016a11f4 100644 +index 652ff54e7c50412503725d628bfe72ed03059790..9c5118e6193b0e9852ef6b52cb4ae92ded1ba464 100644 --- a/src/main/java/io/papermc/paper/ServerBuildInfo.java +++ b/src/main/java/io/papermc/paper/ServerBuildInfo.java -@@ -18,6 +18,11 @@ public interface ServerBuildInfo { +@@ -19,6 +19,11 @@ public interface ServerBuildInfo { */ Key BRAND_PAPER_ID = Key.key("papermc", "paper"); diff --git a/patches/server/0001-Build-Changes.patch b/patches/server/0001-Build-Changes.patch index 6e234ed4f..ea873b3e5 100644 --- a/patches/server/0001-Build-Changes.patch +++ b/patches/server/0001-Build-Changes.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Build Changes Update shadow plugin diff --git a/build.gradle.kts b/build.gradle.kts -index 421f6b3dc8890d63d2e7aa774d0bf8f7e15890ab..51752096a568fd55b0ae09e778f1e0851d839e40 100644 +index 9b3a6b336cb1344d4e74e0e4f7c50ffd1e1b8955..a615e8dc49bbe84b4baf2fc3cfcce7372210310a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,6 +4,7 @@ import java.time.Instant @@ -32,7 +32,7 @@ index 421f6b3dc8890d63d2e7aa774d0bf8f7e15890ab..51752096a568fd55b0ae09e778f1e085 // Paper start implementation("org.jline:jline-terminal-jansi:3.21.0") implementation("net.minecrell:terminalconsoleappender:1.3.0") -@@ -84,14 +91,14 @@ tasks.jar { +@@ -85,14 +92,14 @@ tasks.jar { val gitBranch = git("rev-parse", "--abbrev-ref", "HEAD").getText().trim() // Paper attributes( "Main-Class" to "org.bukkit.craftbukkit.Main", @@ -52,7 +52,7 @@ index 421f6b3dc8890d63d2e7aa774d0bf8f7e15890ab..51752096a568fd55b0ae09e778f1e085 "Build-Number" to (build ?: ""), "Build-Time" to Instant.now().toString(), "Git-Branch" to gitBranch, // Paper -@@ -148,7 +155,7 @@ fun TaskContainer.registerRunTask( +@@ -153,7 +160,7 @@ fun TaskContainer.registerRunTask( name: String, block: JavaExec.() -> Unit ): TaskProvider = register(name) { @@ -62,10 +62,10 @@ index 421f6b3dc8890d63d2e7aa774d0bf8f7e15890ab..51752096a568fd55b0ae09e778f1e085 standardInput = System.`in` workingDir = rootProject.layout.projectDirectory diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java -index 87d2b3ec165e2e9e4bdbedd7adddaa2130ed507b..286d63e017b8bfabbbecee0c4f994d9e5fbd072b 100644 +index b3c993a790fc3fab6a408c731deb297f74c959ce..0bbd557602932b67212b8951ef769bbce70c5477 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java -@@ -40,7 +40,7 @@ public final class ChunkEntitySlices { +@@ -42,7 +42,7 @@ public final class ChunkEntitySlices { private final EntityCollectionBySection hardCollidingEntities; private final Reference2ObjectOpenHashMap, EntityCollectionBySection> entitiesByClass; private final Reference2ObjectOpenHashMap, EntityCollectionBySection> entitiesByType; @@ -73,12 +73,12 @@ index 87d2b3ec165e2e9e4bdbedd7adddaa2130ed507b..286d63e017b8bfabbbecee0c4f994d9e + public final EntityList entities = new EntityList(); //ASWM public FullChunkStatus status; - + public final ChunkData chunkData; diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java -index 58d3d1a47e9f2423c467bb329c2d5f4b58a8b5ef..19a590bd5b08dc7377fc17262bb343753a482c68 100644 +index a0e5fc2eff605e17704f0726d20e79cbb3d88d6d..e47b0f145d132fb43c0d6a4e165c3a6782b3ed09 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java -@@ -184,7 +184,8 @@ public final class ChunkHolderManager { +@@ -185,7 +185,8 @@ public final class ChunkHolderManager { }; } @@ -89,18 +89,18 @@ index 58d3d1a47e9f2423c467bb329c2d5f4b58a8b5ef..19a590bd5b08dc7377fc17262bb34375 if (halt) { LOGGER.info("Waiting 60s for chunk system to halt for world '" + WorldUtil.getWorldName(this.world) + "'"); diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java -index 1ab93f219246d0b4dcdfd0f685f47c13091425f8..3f5fbc7a1394972e55ac5b345e81b40cefa7d246 100644 +index 1440c9e2b106616884edcb20201113320817ed9f..158dee86d783c4a0a0479b07c4159184479b2a65 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java -@@ -4,6 +4,7 @@ import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue; - import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; - import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; +@@ -6,6 +6,7 @@ import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; + import ca.spottedleaf.concurrentutil.util.Priority; + import ca.spottedleaf.moonrise.common.PlatformHooks; +import com.infernalsuite.aswm.level.CommonLoadTask; import ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystemConverters; - import ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystemFeatures; - import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread; -@@ -31,8 +32,8 @@ public final class ChunkLoadTask extends ChunkProgressionTask { + import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; + import ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk; +@@ -32,8 +33,8 @@ public final class ChunkLoadTask extends ChunkProgressionTask { private static final Logger LOGGER = LoggerFactory.getLogger(ChunkLoadTask.class); @@ -111,8 +111,8 @@ index 1ab93f219246d0b4dcdfd0f685f47c13091425f8..3f5fbc7a1394972e55ac5b345e81b40c private volatile boolean cancelled; private NewChunkHolder.GenericDataLoadTaskCallback entityLoadTask; -@@ -44,11 +45,20 @@ public final class ChunkLoadTask extends ChunkProgressionTask { - final NewChunkHolder chunkHolder, final PrioritisedExecutor.Priority priority) { +@@ -45,11 +46,20 @@ public final class ChunkLoadTask extends ChunkProgressionTask { + final NewChunkHolder chunkHolder, final Priority priority) { super(scheduler, world, chunkX, chunkZ); this.chunkHolder = chunkHolder; - this.loadTask = new ChunkDataLoadTask(scheduler, world, chunkX, chunkZ, priority); @@ -137,15 +137,15 @@ index 1ab93f219246d0b4dcdfd0f685f47c13091425f8..3f5fbc7a1394972e55ac5b345e81b40c } private void tryCompleteLoad() { -@@ -272,7 +282,7 @@ public final class ChunkLoadTask extends ChunkProgressionTask { - } - } +@@ -276,7 +286,7 @@ public final class ChunkLoadTask extends ChunkProgressionTask { + + private static record ReadChunk(ProtoChunk protoChunk, SerializableChunkData chunkData) {} -- private static final class ChunkDataLoadTask extends CallbackDataLoadTask { -+ private static final class ChunkDataLoadTask extends CallbackDataLoadTask implements CommonLoadTask { // ASWM +- private static final class ChunkDataLoadTask extends CallbackDataLoadTask { ++ private static final class ChunkDataLoadTask extends CallbackDataLoadTask implements CommonLoadTask { // ASWM private ChunkDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, - final int chunkZ, final PrioritisedExecutor.Priority priority) { - super(scheduler, world, chunkX, chunkZ, RegionFileIOThread.RegionFileType.CHUNK_DATA, priority); + final int chunkZ, final Priority priority) { + super(scheduler, world, chunkX, chunkZ, MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, priority); diff --git a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java index 532306cacd52579cdf37e4aca25887b1ed3ba6a1..55864e5f9ba2ccca0160760e90d8f77819688b8e 100644 --- a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java @@ -2073,10 +2073,10 @@ index 790bad0494454ca12ee152e3de6da3da634d9b20..2d6b062c4a3cf682d8e4cdbb7b7c84a7 @Override diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 23ddd26af762c1cd7fb3920669abb96b3213ab37..4434022a6235db9cb453596df7d2aef7bf011363 100644 +index 64b56abf8900d0424100da460fc68ac964394793..52c6fd303e150377d0864139065219bda6a4f97f 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -282,7 +282,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop persistentStateManagerFactory) { + // ASWM START @@ -2192,25 +2192,26 @@ index dcb5651d1d9b10b40430fb2f713beedf68336704..025a968d6081d13903396d087a582ff9 this.mainThreadProcessor = new ServerChunkCache.MainThreadExecutor(world); this.mainThread = Thread.currentThread(); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 2fe9d9b38c01d04416843fdd48d3e33899b7de63..5aae3c7692a6e4bc04b843878da063f6d2a5c7f2 100644 +index 5964d601c05176f48167cc92057a59e52a4da92b..56eb45b2df21acb4461e1d800280b39084ccd143 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -499,6 +499,14 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -588,8 +588,14 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + } + // Paper end - lag compensation - // Add env and gen to constructor, IWorldDataServer -> WorldDataServer +- // Add env and gen to constructor, IWorldDataServer -> WorldDataServer public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { -+ // ASWM START -+ this(null, minecraftserver, executor, convertable_conversionsession, iworlddataserver, resourcekey, worlddimension, worldloadlistener, flag, randomsequences, i, list, flag1, env, gen, biomeProvider); ++ this(null, minecraftserver, executor, convertable_conversionsession, iworlddataserver, resourcekey, worlddimension, worldloadlistener, flag, i, list, flag1, randomsequences, env, gen, biomeProvider); + } + -+ public com.infernalsuite.aswm.level.SlimeInMemoryWorld slimeInstance; ++ public com.infernalsuite.aswm.level.SlimeInMemoryWorld slimeInstance; // ASWM + -+ public ServerLevel(com.infernalsuite.aswm.level.SlimeBootstrap bootstrap, MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, @Nullable RandomSequences randomsequences, long i, List list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { -+ // ASWM END - // IRegistryCustom.Dimension iregistrycustom_dimension = minecraftserver.registryAccess(); // CraftBukkit - decompile error - // Holder holder = worlddimension.type(); // CraftBukkit - decompile error - -@@ -538,6 +546,12 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. ++ // Add env and gen to constructor, IWorldDataServer -> WorldDataServer ++ public ServerLevel(com.infernalsuite.aswm.level.SlimeBootstrap bootstrap, MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { + super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess(), iworlddataserver.getGameRules())), executor); // Paper - create paper world configs; Async-Anti-Xray: Pass executor + this.pvpMode = minecraftserver.isPvpAllowed(); + this.convertable = convertable_conversionsession; +@@ -616,6 +622,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe chunkgenerator = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, chunkgenerator, gen); } // CraftBukkit end @@ -2223,7 +2224,7 @@ index 2fe9d9b38c01d04416843fdd48d3e33899b7de63..5aae3c7692a6e4bc04b843878da063f6 boolean flag2 = minecraftserver.forceSynchronousWrites(); DataFixer datafixer = minecraftserver.getFixerUpper(); EntityPersistentStorage entitypersistentstorage = new EntityStorage(new SimpleRegionStorage(new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, DataFixTypes.ENTITY_CHUNK), this, minecraftserver); -@@ -548,7 +562,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -626,7 +638,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe int k = this.spigotConfig.simulationDistance; // Spigot // Paper - rewrite chunk system @@ -2232,7 +2233,7 @@ index 2fe9d9b38c01d04416843fdd48d3e33899b7de63..5aae3c7692a6e4bc04b843878da063f6 return minecraftserver.overworld().getDataStorage(); }); this.chunkSource.getGeneratorState().ensureStructuresGenerated(); -@@ -606,6 +620,12 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -685,6 +697,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.dragonFight = enderDragonFight; } @@ -2246,15 +2247,14 @@ index 2fe9d9b38c01d04416843fdd48d3e33899b7de63..5aae3c7692a6e4bc04b843878da063f6 this.serverLevelData.setClearWeatherTime(clearDuration); this.serverLevelData.setRainTime(rainDuration); diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -index 13d3c877b006a4975e7370713e3919c661e7890f..de9bd38cd09de67028c3218c27afc81e9eb3479b 100644 +index 8b84bf2272556ac3321cbf16361d7f48a1cc6873..c8f018ec8c142f0e05fcf346f4b1a31cd887aec6 100644 --- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java +++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -@@ -386,7 +386,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - void accept(T object, int count); - } - -- static record Data(PalettedContainer.Configuration configuration, BitStorage storage, Palette palette) { -+ public static record Data(PalettedContainer.Configuration configuration, BitStorage storage, Palette palette) { // ASWM +@@ -468,7 +468,6 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + this.moonrise$palette = palette; + } + // Paper end - optimise palette reads +- public void copyFrom(Palette palette, BitStorage storage) { for (int i = 0; i < storage.getSize(); i++) { T object = palette.valueFor(storage.get(i)); diff --git a/patches/server/0002-poi-data-loader.patch b/patches/server/0002-poi-data-loader.patch index b4e8ebee0..e1ac01435 100644 --- a/patches/server/0002-poi-data-loader.patch +++ b/patches/server/0002-poi-data-loader.patch @@ -5,10 +5,10 @@ Subject: [PATCH] poi data loader diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java -index fd35e4db0c8fec8f86b8743bcc2b15ed2e7433f1..212595f0533f152384e010089660ebdd8d6fc395 100644 +index bbf9d6c1c9525d97160806819a57be03eca290f1..38ca7bd039bc1b60a63ff68c53e3ec315545a175 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java -@@ -17,7 +17,7 @@ import org.slf4j.Logger; +@@ -16,7 +16,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Optional; @@ -43,26 +43,16 @@ index 41e652b568598926e838e81fdc338e51f8e97ef8..c32d52c68188dc1eb7feeac364cdc4ad // have tasks to run (at this point, it's just the POI consistency checking) try { // if (data.tasks != null) { -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -index 4bd048387651250135f963303c78c17f8473cfee..cba780ab2eb3d37d7f54a71e248ca688f5d4179b 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -@@ -1,6 +1,9 @@ - package net.minecraft.world.level.chunk.storage; - - import com.google.common.collect.Maps; -+import com.infernalsuite.aswm.api.world.SlimeWorld; -+import com.infernalsuite.aswm.level.NMSSlimeWorld; -+import com.infernalsuite.aswm.level.SlimeLevelInstance; - import com.mojang.logging.LogUtils; - import com.mojang.serialization.Codec; - import com.mojang.serialization.DataResult; -@@ -200,6 +203,10 @@ public class ChunkSerializer { - if (flag4) { - levellightengine.queueSectionData(LightLayer.SKY, SectionPos.of(chunkPos, b0), new DataLayer(nbttagcompound1.getByteArray("SkyLight"))); +diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +index 057c92d182e643cebb1f27e296e0fc4b0e688bea..d558e53b91e38c55fe25273b468b1e8a480ecced 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java ++++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +@@ -357,6 +357,10 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + if (flag3) { + levellightengine.queueSectionData(LightLayer.SKY, sectionposition, serializablechunkdata_b.skyLight); } + -+ if(world instanceof SlimeLevelInstance) { ++ if (world instanceof com.infernalsuite.aswm.level.SlimeLevelInstance) { + poiStorage.checkConsistencyWithBlocks(SectionPos.of(chunkPos.getWorldPosition()), achunksection[j]); + } } diff --git a/patches/server/0004-Fix-entity-loading.patch b/patches/server/0004-Fix-entity-loading.patch index a731901b9..56691b851 100644 --- a/patches/server/0004-Fix-entity-loading.patch +++ b/patches/server/0004-Fix-entity-loading.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix entity loading diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -index 9fcd1b6eef82cd0bbcddab26cf5aaf880d236969..c3afb4a4a8ecb92a85615b176cb04ff2097f4b59 100644 +index eafa4e6d55cd0f9314ac0f2b96a7f48fbb5e1a4c..bc0990458df745c92e5bc0530ff35ab992365b3a 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -@@ -112,7 +112,7 @@ public final class NewChunkHolder { +@@ -117,7 +117,7 @@ public final class NewChunkHolder { } if (!transientChunk) { diff --git a/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch b/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch index 2805c93a4..1e8a6c104 100644 --- a/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch +++ b/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Separate plugin and server, rework API (to v3) diff --git a/build.gradle.kts b/build.gradle.kts -index 61cf2ec3d053f15b69dbc7865755b7a820f369c0..e361a0b6964908a21ebcd6f09a5accf91307b66a 100644 +index b9f1df889cf7d87f988aecf04b75c77da1152eb0..c323b9a523593dcfa4a5ec012c9c65887fcf3dce 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -17,6 +17,7 @@ dependencies { @@ -706,7 +706,7 @@ index 26422904751647a061397ce978bba752149003cd..4940083475948eac4fc06446f7ee7e1e } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index c8b82bc41f2042bb4b067f06265a3a22e51f7629..de34afd3ad9858ea0d1ff9f03ff376e22852b953 100644 +index b185a9b474121b8a4067816b3c3c39270c2a202e..81ca05a02652c610a8a3c5054b0af82fe2a2bbdc 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -8,6 +8,7 @@ import com.google.common.collect.ImmutableList; @@ -717,7 +717,7 @@ index c8b82bc41f2042bb4b067f06265a3a22e51f7629..de34afd3ad9858ea0d1ff9f03ff376e2 import com.mojang.authlib.GameProfile; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; -@@ -1471,6 +1472,8 @@ public final class CraftServer implements Server { +@@ -1475,6 +1476,8 @@ public final class CraftServer implements Server { return false; } diff --git a/patches/server/0015-1.21-compatibility.patch b/patches/server/0015-1.21-compatibility.patch index 4fae989ff..f64f9f6e7 100644 --- a/patches/server/0015-1.21-compatibility.patch +++ b/patches/server/0015-1.21-compatibility.patch @@ -248,7 +248,7 @@ index 2265f83768c4dc29f67d29730c4be45a194727da..187336ecaa4262e3f081a88702031b17 @Override public void setDefaultSpawnPos(BlockPos pos, float angle) { diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index 7c11853c5090fbc4fa5b3e73a69acf166158fdec..8e1c3e50f0bc46245488ffa23056120e4500c4f1 100644 +index 4640baec5bed6c2d53cc0f8ca1d273cc115abe9b..589cb65f79bb05ee8c44b526c707e81dc02a4761 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -1,5 +1,7 @@ @@ -266,8 +266,8 @@ index 7c11853c5090fbc4fa5b3e73a69acf166158fdec..8e1c3e50f0bc46245488ffa23056120e +import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.FullChunkStatus; import net.minecraft.server.level.ServerLevel; - import net.minecraft.util.profiling.ProfilerFiller; -@@ -299,6 +302,12 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p + import net.minecraft.util.profiling.Profiler; +@@ -322,6 +325,12 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p } } @@ -280,16 +280,16 @@ index 7c11853c5090fbc4fa5b3e73a69acf166158fdec..8e1c3e50f0bc46245488ffa23056120e // Paper start - If loaded util @Override public final FluidState getFluidIfLoaded(BlockPos blockposition) { -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -index cba780ab2eb3d37d7f54a71e248ca688f5d4179b..cd467759bc00772be411b7763d66d5451e4a72a3 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -@@ -356,7 +356,7 @@ public class ChunkSerializer { - ChunkSerializer.LOGGER.error("Recoverable errors when loading section [{}, {}, {}]: {}", new Object[]{chunkPos.x, y, chunkPos.z, message}); +diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +index d558e53b91e38c55fe25273b468b1e8a480ecced..c1e5a630d6cafca91398f55203994879bcac6fe4 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java ++++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +@@ -457,7 +457,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + SerializableChunkData.LOGGER.error("Recoverable errors when loading section [{}, {}, {}]: {}", new Object[]{chunkPos.x, y, chunkPos.z, message}); } - private static Codec>> makeBiomeCodec(Registry biomeRegistry) { -+ public static Codec>> makeBiomeCodec(Registry biomeRegistry) { // ASWM - Make public - return PalettedContainer.codecRO(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getHolderOrThrow(Biomes.PLAINS)); ++ public static Codec>> makeBiomeCodec(Registry biomeRegistry) { + return PalettedContainer.codecRO(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getOrThrow(Biomes.PLAINS)); } diff --git a/patches/server/0016-Fix-chunk-saving-when-unloading.patch b/patches/server/0016-Fix-chunk-saving-when-unloading.patch index 565b37cbb..af7d7c6d6 100644 --- a/patches/server/0016-Fix-chunk-saving-when-unloading.patch +++ b/patches/server/0016-Fix-chunk-saving-when-unloading.patch @@ -31,4 +31,4 @@ index 187336ecaa4262e3f081a88702031b17c6037091..6a5a8fbd8ee013828685495267283d95 + super.unload(chunk); + } } - +\ No newline at end of file diff --git a/patches/server/0017-fix-disable-dragon-fights.patch b/patches/server/0017-fix-disable-dragon-fights.patch index 135214451..af602f847 100644 --- a/patches/server/0017-fix-disable-dragon-fights.patch +++ b/patches/server/0017-fix-disable-dragon-fights.patch @@ -1,25 +1,22 @@ -From d3f1ea79f13a10c567902d8679230de5b2ae8413 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: evlad Date: Mon, 9 Sep 2024 21:33:11 +0300 Subject: [PATCH] fix disable dragon fights ---- - .../java/net/minecraft/server/level/ServerLevel.java | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 5aae3c769..a0bd2e0e3 100644 +index 56eb45b2df21acb4461e1d800280b39084ccd143..18d6aa9b37947b5eac7511da5d2e33b79be5be0c 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -3,6 +3,7 @@ package net.minecraft.server.level; +@@ -2,6 +2,7 @@ package net.minecraft.server.level; + import com.google.common.annotations.VisibleForTesting; - import co.aikar.timings.TimingHistory; // Paper import com.google.common.collect.Lists; +import com.infernalsuite.aswm.api.world.properties.SlimeProperties; // ASP import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.util.Pair; import com.mojang.logging.LogUtils; -@@ -580,7 +581,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -656,7 +657,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.structureCheck = new StructureCheck(this.chunkSource.chunkScanner(), this.registryAccess(), minecraftserver.getStructureManager(), this.getTypeKey(), chunkgenerator, this.chunkSource.randomState(), this, chunkgenerator.getBiomeSource(), l, datafixer); // Paper - Fix missing CB diff this.structureManager = new StructureManager(this, this.serverLevelData.worldGenOptions(), this.structureCheck); // CraftBukkit if ((this.dimension() == Level.END && this.dimensionTypeRegistration().is(BuiltinDimensionTypes.END)) || env == org.bukkit.World.Environment.THE_END) { // CraftBukkit - Allow to create EnderDragonBattle in default and custom END @@ -34,6 +31,3 @@ index 5aae3c769..a0bd2e0e3 100644 } else { this.dragonFight = null; } --- -2.46.0 - diff --git a/patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch b/patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch index ed3abb287..93f9d7cf2 100644 --- a/patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch +++ b/patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch @@ -1,14 +1,11 @@ -From 1aa484ebd84203862ec7abe41c9e30a01e5ac90c Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: evlad Date: Thu, 19 Sep 2024 20:47:32 +0300 Subject: [PATCH] fix chunk pdc getting wiped on chunk unload ---- - src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java -index 9b4b18758..f0d773977 100644 +index 9b4b18758d52d66e4abf9e40e49a32428de68b9a..f0d773977609597f2da7bf691d8f4cb983743981 100644 --- a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java +++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java @@ -68,7 +68,9 @@ public class NMSSlimeChunk implements SlimeChunk { @@ -22,6 +19,3 @@ index 9b4b18758..f0d773977 100644 this.upgradeData = reference == null ? null : reference.getUpgradeData(); } --- -2.46.0 - diff --git a/patches/server/0019-1.21.3-fixes.patch b/patches/server/0019-1.21.3-fixes.patch new file mode 100644 index 000000000..4dbf5e1ac --- /dev/null +++ b/patches/server/0019-1.21.3-fixes.patch @@ -0,0 +1,278 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: AverageGithub +Date: Sun, 10 Nov 2024 13:06:42 +0100 +Subject: [PATCH] 1.21.3 fixes + + +diff --git a/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java +index 87b6ee19fd165bde2db3a57545c58251dc6bad22..7b65a8d9137cd160b1c69dfafe70c693e9cfd508 100644 +--- a/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java ++++ b/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java +@@ -213,7 +213,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { + }; + + ResourceKey worldKey = dimensionOverride == null ? ResourceKey.create(Registries.DIMENSION, ResourceLocation.parse(worldName.toLowerCase(Locale.ENGLISH))) : dimensionOverride; +- LevelStem stem = MinecraftServer.getServer().registries().compositeAccess().registryOrThrow(Registries.LEVEL_STEM).get(dimension); ++ LevelStem stem = MinecraftServer.getServer().registries().compositeAccess().lookupOrThrow(Registries.LEVEL_STEM).get(dimension).orElseThrow().value(); + + SlimeLevelInstance level; + +@@ -224,7 +224,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { + } + + // level.setReady(true); +- level.setSpawnSettings(world.getPropertyMap().getValue(SlimeProperties.ALLOW_MONSTERS), world.getPropertyMap().getValue(SlimeProperties.ALLOW_ANIMALS)); ++ level.setSpawnSettings(world.getPropertyMap().getValue(SlimeProperties.ALLOW_MONSTERS)); + + var nmsExtraData = (CompoundTag) Converter.convertTag(world.getExtraData()); + +@@ -244,7 +244,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { + String worldName = world.getName(); + + LevelSettings worldsettings = new LevelSettings(worldName, serverProps.gamemode, false, serverProps.difficulty, +- true, new GameRules(), mcServer.worldLoader.dataConfiguration()); ++ true, new GameRules(net.minecraft.world.flag.FeatureFlagSet.of()), mcServer.worldLoader.dataConfiguration()); + + WorldOptions worldoptions = new WorldOptions(0, false, false); + +diff --git a/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java b/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java +index b5a1f75314aac73fb77e139398017b16acbb8efb..547e8e8824795a601b2028a6007057808eddbb65 100644 +--- a/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java ++++ b/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java +@@ -1,6 +1,7 @@ + package com.infernalsuite.aswm.level; + +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.util.Priority; + import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; + import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkLoadTask; + import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.GenericDataLoadTask; +@@ -36,7 +37,7 @@ public final class ChunkDataLoadTask implements CommonLoadTask { + private final ChunkLoadTask chunkLoadTask; + + protected ChunkDataLoadTask(ChunkLoadTask chunkLoadTask, final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, +- final int chunkZ, final PrioritisedExecutor.Priority priority, final Consumer> onRun) { ++ final int chunkZ, final Priority priority, final Consumer> onRun) { + this.chunkLoadTask = chunkLoadTask; + this.scheduler = scheduler; + this.world = world; +@@ -86,22 +87,22 @@ public final class ChunkDataLoadTask implements CommonLoadTask { + } + + @Override +- public PrioritisedExecutor.Priority getPriority() { ++ public Priority getPriority() { + return this.task.getPriority(); + } + + @Override +- public void setPriority(PrioritisedExecutor.Priority priority) { ++ public void setPriority(Priority priority) { + this.task.setPriority(priority); + } + + @Override +- public void raisePriority(PrioritisedExecutor.Priority priority) { ++ public void raisePriority(Priority priority) { + this.task.raisePriority(priority); + } + + @Override +- public void lowerPriority(PrioritisedExecutor.Priority priority) { ++ public void lowerPriority(Priority priority) { + this.task.lowerPriority(priority); + } + +diff --git a/src/main/java/com/infernalsuite/aswm/level/CommonLoadTask.java b/src/main/java/com/infernalsuite/aswm/level/CommonLoadTask.java +index fc6e46972bcc77134ed718c8c157ec3893d4bcdf..ceaa09deabf53f061185639660a7706c3ff27801 100644 +--- a/src/main/java/com/infernalsuite/aswm/level/CommonLoadTask.java ++++ b/src/main/java/com/infernalsuite/aswm/level/CommonLoadTask.java +@@ -1,18 +1,19 @@ + package com.infernalsuite.aswm.level; + +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.util.Priority; + + public interface CommonLoadTask { + + boolean schedule(boolean schedule); + +- PrioritisedExecutor.Priority getPriority(); ++ Priority getPriority(); + + boolean cancel(); + +- void lowerPriority(PrioritisedExecutor.Priority priority); ++ void lowerPriority(Priority priority); + +- void raisePriority(PrioritisedExecutor.Priority priority); ++ void raisePriority(Priority priority); + +- void setPriority(PrioritisedExecutor.Priority priority); ++ void setPriority(Priority priority); + } +\ No newline at end of file +diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java +index f0d773977609597f2da7bf691d8f4cb983743981..cbcbbc8410b24daf685d74791ad80989d4830d7b 100644 +--- a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java ++++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java +@@ -29,7 +29,7 @@ import net.minecraft.world.level.chunk.LevelChunk; + import net.minecraft.world.level.chunk.LevelChunkSection; + import net.minecraft.world.level.chunk.PalettedContainer; + import net.minecraft.world.level.chunk.PalettedContainerRO; +-import net.minecraft.world.level.chunk.storage.ChunkSerializer; ++import net.minecraft.world.level.chunk.storage.SerializableChunkData; + import net.minecraft.world.level.levelgen.Heightmap; + import net.minecraft.world.level.lighting.LevelLightEngine; + import org.slf4j.Logger; +@@ -49,14 +49,14 @@ public class NMSSlimeChunk implements SlimeChunk { + static { + { + PalettedContainer empty = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, null); +- Tag tag = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); ++ Tag tag = SerializableChunkData.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); + + EMPTY_BLOCK_STATE_PALETTE = (CompoundTag) Converter.convertTag("", tag); + } + { +- Registry biomes = net.minecraft.server.MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME); +- PalettedContainer> empty = new PalettedContainer<>(biomes.asHolderIdMap(), biomes.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); +- Tag tag = ChunkSerializer.makeBiomeCodec(biomes).encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); ++ Registry biomes = net.minecraft.server.MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BIOME); ++ PalettedContainer> empty = new PalettedContainer<>(biomes.asHolderIdMap(), biomes.get(Biomes.PLAINS).orElseThrow(), PalettedContainer.Strategy.SECTION_BIOMES, null); ++ Tag tag = SerializableChunkData.makeBiomeCodec(biomes).encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); + + EMPTY_BIOME_PALETTE = (CompoundTag) Converter.convertTag("", tag); + } +@@ -89,10 +89,10 @@ public class NMSSlimeChunk implements SlimeChunk { + SlimeChunkSection[] sections = new SlimeChunkSection[this.chunk.getSectionsCount()]; + LevelLightEngine lightEngine = chunk.getLevel().getChunkSource().getLightEngine(); + +- Registry biomeRegistry = chunk.getLevel().registryAccess().registryOrThrow(Registries.BIOME); ++ Registry biomeRegistry = chunk.getLevel().registryAccess().lookupOrThrow(Registries.BIOME); + + // Ignore deprecation, spigot only method +- Codec>> codec = PalettedContainer.codecRO(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getHolderOrThrow(Biomes.PLAINS)); ++ Codec>> codec = PalettedContainer.codecRO(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.get(Biomes.PLAINS).orElseThrow()); + + for (int sectionId = 0; sectionId < chunk.getSections().length; sectionId++) { + LevelChunkSection section = chunk.getSections()[sectionId]; +@@ -111,7 +111,7 @@ public class NMSSlimeChunk implements SlimeChunk { + if (section.hasOnlyAir()) { + blockStateTag = EMPTY_BLOCK_STATE_PALETTE; + } else { +- Tag data = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, section.getStates()).getOrThrow(); // todo error handling ++ Tag data = SerializableChunkData.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, section.getStates()).getOrThrow(); // todo error handling + blockStateTag = (CompoundTag) Converter.convertTag("", data); + } + +diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java +index 86a5b457bdca63713769d2b708be905d72ff76a3..7623584e60dddd5558f22eed4403944fafee0696 100644 +--- a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java ++++ b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java +@@ -28,7 +28,7 @@ import net.minecraft.world.level.chunk.LevelChunkSection; + import net.minecraft.world.level.chunk.PalettedContainer; + import net.minecraft.world.level.chunk.UpgradeData; + import net.minecraft.world.level.chunk.status.ChunkStatusTasks; +-import net.minecraft.world.level.chunk.storage.ChunkSerializer; ++import net.minecraft.world.level.chunk.storage.SerializableChunkData; + import net.minecraft.world.level.levelgen.Heightmap; + import net.minecraft.world.level.material.Fluid; + import net.minecraft.world.ticks.LevelChunkTicks; +@@ -54,10 +54,10 @@ public class SlimeChunkConverter { + instance.getLightEngine().retainData(pos, true); + }); + +- Registry biomeRegistry = instance.registryAccess().registryOrThrow(Registries.BIOME); ++ Registry biomeRegistry = instance.registryAccess().lookupOrThrow(Registries.BIOME); + // Ignore deprecated method + +- Codec>> codec = PalettedContainer.codecRW(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getHolderOrThrow(Biomes.PLAINS), null); ++ Codec>> codec = PalettedContainer.codecRW(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.get(Biomes.PLAINS).orElseThrow(), null); + + for (int sectionId = 0; sectionId < chunk.getSections().length; sectionId++) { + SlimeChunkSection slimeSection = chunk.getSections()[sectionId]; +@@ -75,7 +75,7 @@ public class SlimeChunkConverter { + + PalettedContainer blockPalette; + if (slimeSection.getBlockStatesTag() != null) { +- DataResult> dataresult = ChunkSerializer.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, Converter.convertTag(slimeSection.getBlockStatesTag())).promotePartial((s) -> { ++ DataResult> dataresult = SerializableChunkData.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, Converter.convertTag(slimeSection.getBlockStatesTag())).promotePartial((s) -> { + System.out.println("Recoverable error when parsing section " + x + "," + z + ": " + s); // todo proper logging + }); + blockPalette = dataresult.getOrThrow(); // todo proper logging +@@ -91,7 +91,7 @@ public class SlimeChunkConverter { + }); + biomePalette = dataresult.getOrThrow(); // todo proper logging + } else { +- biomePalette = new PalettedContainer<>(biomeRegistry.asHolderIdMap(), biomeRegistry.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); ++ biomePalette = new PalettedContainer<>(biomeRegistry.asHolderIdMap(), biomeRegistry.get(Biomes.PLAINS).orElseThrow(), PalettedContainer.Strategy.SECTION_BIOMES, null); + } + + if (sectionId < sections.length) { +diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java +index 6a5a8fbd8ee013828685495267283d9518d32d20..acb6ea84fbc40a6907edb237b834feeb66075af8 100644 +--- a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java ++++ b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java +@@ -1,6 +1,7 @@ + package com.infernalsuite.aswm.level; + +-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; ++import ca.spottedleaf.concurrentutil.util.Priority; + import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; + import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkLoadTask; + import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.GenericDataLoadTask; +@@ -80,8 +81,8 @@ public class SlimeLevelInstance extends ServerLevel { + super(slimeBootstrap, MinecraftServer.getServer(), MinecraftServer.getServer().executor, + CUSTOM_LEVEL_STORAGE.createAccess(slimeBootstrap.initial().getName() + UUID.randomUUID(), dimensionKey), + primaryLevelData, worldKey, worldDimension, +- MinecraftServer.getServer().progressListenerFactory.create(11), false, null, 0, +- Collections.emptyList(), true, environment, null, null); ++ MinecraftServer.getServer().progressListenerFactory.create(11), false, 0, ++ Collections.emptyList(), true, null, environment, null, null); + this.slimeInstance = new SlimeInMemoryWorld(slimeBootstrap, this); + + +@@ -93,7 +94,7 @@ public class SlimeLevelInstance extends ServerLevel { + propertyMap.getValue(SlimeProperties.SPAWN_Y), + propertyMap.getValue(SlimeProperties.SPAWN_Z)), + propertyMap.getValue(SlimeProperties.SPAWN_YAW)); +- super.setSpawnSettings(propertyMap.getValue(SlimeProperties.ALLOW_MONSTERS), propertyMap.getValue(SlimeProperties.ALLOW_ANIMALS)); ++ super.setSpawnSettings(propertyMap.getValue(SlimeProperties.ALLOW_MONSTERS)); + + this.pvpMode = propertyMap.getValue(SlimeProperties.PVP); + } +@@ -102,7 +103,7 @@ public class SlimeLevelInstance extends ServerLevel { + public ChunkGenerator getGenerator(SlimeBootstrap slimeBootstrap) { + String biomeStr = slimeBootstrap.initial().getPropertyMap().getValue(SlimeProperties.DEFAULT_BIOME); + ResourceKey biomeKey = ResourceKey.create(Registries.BIOME, ResourceLocation.parse(biomeStr)); +- Holder defaultBiome = MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME).getHolder(biomeKey).orElseThrow(); ++ Holder defaultBiome = MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BIOME).get(biomeKey).orElseThrow(); + return new SlimeLevelGenerator(defaultBiome); + } + +@@ -172,7 +173,7 @@ public class SlimeLevelInstance extends ServerLevel { + return this.slimeInstance; + } + +- public ChunkDataLoadTask getLoadTask(ChunkLoadTask task, ChunkTaskScheduler scheduler, ServerLevel world, int chunkX, int chunkZ, PrioritisedExecutor.Priority priority, Consumer> onRun) { ++ public ChunkDataLoadTask getLoadTask(ChunkLoadTask task, ChunkTaskScheduler scheduler, ServerLevel world, int chunkX, int chunkZ, Priority priority, Consumer> onRun) { + return new ChunkDataLoadTask(task, scheduler, world, chunkX, chunkZ, priority, onRun); + } + +diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +index c1e5a630d6cafca91398f55203994879bcac6fe4..07808162fbd38dcfab0c298750323de318baa486 100644 +--- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java ++++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +@@ -359,7 +359,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun + } + + if (world instanceof com.infernalsuite.aswm.level.SlimeLevelInstance) { +- poiStorage.checkConsistencyWithBlocks(SectionPos.of(chunkPos.getWorldPosition()), achunksection[j]); ++ poiStorage.checkConsistencyWithBlocks(sectionposition, serializablechunkdata_b.chunkSection); + } + } + } From 4ef64199a6e283cbdaa787f66bb3cd3580f44aa6 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Tue, 3 Dec 2024 23:33:34 +0100 Subject: [PATCH 011/133] feat: update to da7138233f6392e791d790d1c3407414c855f9c2 Please enter the commit message for your changes. Lines starting --- gradle.properties | 2 +- patches/api/0001-Slime-World-Manager.patch | 4 +-- patches/server/0001-Build-Changes.patch | 36 +++++++++---------- patches/server/0002-poi-data-loader.patch | 4 +-- patches/server/0012-Compile-fixes.patch | 6 ++-- ...e-plugin-and-server-rework-API-to-v3.patch | 10 +++--- patches/server/0015-1.21-compatibility.patch | 4 +-- .../0017-fix-disable-dragon-fights.patch | 4 +-- patches/server/0019-1.21.3-fixes.patch | 4 +-- 9 files changed, 37 insertions(+), 37 deletions(-) diff --git a/gradle.properties b/gradle.properties index 826ea81b6..d002d3f01 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ group=com.infernalsuite.aswm version=1.21.3-R0.1-SNAPSHOT mcVersion=1.21.3 -paperRef=92131adaf2687f350b2f8dc7cd1213ab833d1831 +paperRef=da7138233f6392e791d790d1c3407414c855f9c2 org.gradle.caching=true org.gradle.parallel=true diff --git a/patches/api/0001-Slime-World-Manager.patch b/patches/api/0001-Slime-World-Manager.patch index ba10451f5..059d62e51 100644 --- a/patches/api/0001-Slime-World-Manager.patch +++ b/patches/api/0001-Slime-World-Manager.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Slime World Manager diff --git a/build.gradle.kts b/build.gradle.kts -index 254fd96d3950b4494c7e43547b00b5175ee53c93..911879d193907e65e0e0e50b8292d2394b934d42 100644 +index e29e5024fa693baae469d47fe77b57118f14627c..4da167f928789c1b5d55da2749a94e44912492ad 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,5 @@ @@ -14,7 +14,7 @@ index 254fd96d3950b4494c7e43547b00b5175ee53c93..911879d193907e65e0e0e50b8292d239 plugins { `java-library` `maven-publish` -@@ -29,6 +31,7 @@ configurations.api { +@@ -41,6 +43,7 @@ abstract class MockitoAgentProvider : CommandLineArgumentProvider { dependencies { api("com.mojang:brigadier:1.2.9") // Paper - Brigadier command api // api dependencies are listed transitively to API consumers diff --git a/patches/server/0001-Build-Changes.patch b/patches/server/0001-Build-Changes.patch index ea873b3e5..f075685c5 100644 --- a/patches/server/0001-Build-Changes.patch +++ b/patches/server/0001-Build-Changes.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Build Changes Update shadow plugin diff --git a/build.gradle.kts b/build.gradle.kts -index 9b3a6b336cb1344d4e74e0e4f7c50ffd1e1b8955..a615e8dc49bbe84b4baf2fc3cfcce7372210310a 100644 +index faf3e3fd72e8c915e7a4803dacbe1bb576c6663e..e90c79790c40afb67364fed615be2384c30d73d0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,6 +4,7 @@ import java.time.Instant @@ -17,8 +17,8 @@ index 9b3a6b336cb1344d4e74e0e4f7c50ffd1e1b8955..a615e8dc49bbe84b4baf2fc3cfcce737 } val log4jPlugins = sourceSets.create("log4jPlugins") -@@ -13,7 +14,13 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) { - val alsoShade: Configuration by configurations.creating +@@ -25,7 +26,13 @@ abstract class MockitoAgentProvider : CommandLineArgumentProvider { + // Paper end - configure mockito agent that is needed in newer java versions dependencies { - implementation(project(":paper-api")) @@ -30,9 +30,9 @@ index 9b3a6b336cb1344d4e74e0e4f7c50ffd1e1b8955..a615e8dc49bbe84b4baf2fc3cfcce737 + } + // ASWM end // Paper start - implementation("org.jline:jline-terminal-jansi:3.21.0") - implementation("net.minecrell:terminalconsoleappender:1.3.0") -@@ -85,14 +92,14 @@ tasks.jar { + implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ + implementation("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21 +@@ -99,14 +106,14 @@ tasks.jar { val gitBranch = git("rev-parse", "--abbrev-ref", "HEAD").getText().trim() // Paper attributes( "Main-Class" to "org.bukkit.craftbukkit.Main", @@ -52,7 +52,7 @@ index 9b3a6b336cb1344d4e74e0e4f7c50ffd1e1b8955..a615e8dc49bbe84b4baf2fc3cfcce737 "Build-Number" to (build ?: ""), "Build-Time" to Instant.now().toString(), "Git-Branch" to gitBranch, // Paper -@@ -153,7 +160,7 @@ fun TaskContainer.registerRunTask( +@@ -172,7 +179,7 @@ fun TaskContainer.registerRunTask( name: String, block: JavaExec.() -> Unit ): TaskProvider = register(name) { @@ -75,7 +75,7 @@ index b3c993a790fc3fab6a408c731deb297f74c959ce..0bbd557602932b67212b8951ef769bbc public FullChunkStatus status; public final ChunkData chunkData; diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java -index a0e5fc2eff605e17704f0726d20e79cbb3d88d6d..e47b0f145d132fb43c0d6a4e165c3a6782b3ed09 100644 +index 91a6f57f35fc1553159cca138a0619e703b2b014..07fee642805ac3ec6fce489a0b9050ddf941d932 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java @@ -185,7 +185,8 @@ public final class ChunkHolderManager { @@ -2073,7 +2073,7 @@ index 790bad0494454ca12ee152e3de6da3da634d9b20..2d6b062c4a3cf682d8e4cdbb7b7c84a7 @Override diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 64b56abf8900d0424100da460fc68ac964394793..52c6fd303e150377d0864139065219bda6a4f97f 100644 +index 663b4ecd520e82aa108d44f2d5c2a20cfc7bc01f..4d9b240534372103268a53712a13027ddd434071 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -288,7 +288,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess(), iworlddataserver.getGameRules())), executor); // Paper - create paper world configs; Async-Anti-Xray: Pass executor this.pvpMode = minecraftserver.isPvpAllowed(); this.convertable = convertable_conversionsession; -@@ -616,6 +622,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -623,6 +629,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe chunkgenerator = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, chunkgenerator, gen); } // CraftBukkit end @@ -2224,7 +2224,7 @@ index 5964d601c05176f48167cc92057a59e52a4da92b..56eb45b2df21acb4461e1d800280b390 boolean flag2 = minecraftserver.forceSynchronousWrites(); DataFixer datafixer = minecraftserver.getFixerUpper(); EntityPersistentStorage entitypersistentstorage = new EntityStorage(new SimpleRegionStorage(new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, DataFixTypes.ENTITY_CHUNK), this, minecraftserver); -@@ -626,7 +638,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -633,7 +645,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe int k = this.spigotConfig.simulationDistance; // Spigot // Paper - rewrite chunk system @@ -2233,7 +2233,7 @@ index 5964d601c05176f48167cc92057a59e52a4da92b..56eb45b2df21acb4461e1d800280b390 return minecraftserver.overworld().getDataStorage(); }); this.chunkSource.getGeneratorState().ensureStructuresGenerated(); -@@ -685,6 +697,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -692,6 +704,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.dragonFight = enderDragonFight; } diff --git a/patches/server/0002-poi-data-loader.patch b/patches/server/0002-poi-data-loader.patch index e1ac01435..347cd642c 100644 --- a/patches/server/0002-poi-data-loader.patch +++ b/patches/server/0002-poi-data-loader.patch @@ -44,10 +44,10 @@ index 41e652b568598926e838e81fdc338e51f8e97ef8..c32d52c68188dc1eb7feeac364cdc4ad try { // if (data.tasks != null) { diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index 057c92d182e643cebb1f27e296e0fc4b0e688bea..d558e53b91e38c55fe25273b468b1e8a480ecced 100644 +index 018b24d7611c3fd11536441431abf8f125850129..faf7f4f3bd1fbc91a40e5549a7a5520ea3eaec37 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -@@ -357,6 +357,10 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -369,6 +369,10 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun if (flag3) { levellightengine.queueSectionData(LightLayer.SKY, sectionposition, serializablechunkdata_b.skyLight); } diff --git a/patches/server/0012-Compile-fixes.patch b/patches/server/0012-Compile-fixes.patch index 253ffccae..75cb8942a 100644 --- a/patches/server/0012-Compile-fixes.patch +++ b/patches/server/0012-Compile-fixes.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Compile fixes diff --git a/build.gradle.kts b/build.gradle.kts -index f947b82537e5858dd0020a7a6fff48c54f3b49a3..316d03791a97af50f882c0271cbacf3d2a7af5b3 100644 +index 41ed3865710e9732f7662e1d3bf287ad9cf80c74..bb915dc69af63cab992a5b7f8654b5390340c89e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -17,9 +17,6 @@ dependencies { +@@ -29,9 +29,6 @@ dependencies { // ASWM start implementation(project(":slimeworldmanager-api")) implementation(project(":core")) @@ -17,7 +17,7 @@ index f947b82537e5858dd0020a7a6fff48c54f3b49a3..316d03791a97af50f882c0271cbacf3d - } // ASWM end // Paper start - implementation("org.jline:jline-terminal-jansi:3.21.0") + implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java index e183ca25bf67a0519de7a91615fbcfc6ff45a56e..b295d159200e3bf0e48f851ac206b2e09b756bb2 100644 --- a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java diff --git a/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch b/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch index 1e8a6c104..1e5e946cc 100644 --- a/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch +++ b/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch @@ -5,17 +5,17 @@ Subject: [PATCH] Separate plugin and server, rework API (to v3) diff --git a/build.gradle.kts b/build.gradle.kts -index b9f1df889cf7d87f988aecf04b75c77da1152eb0..c323b9a523593dcfa4a5ec012c9c65887fcf3dce 100644 +index 22931927ac8c1fcdc45d44f8d4a898a44831039c..e10d95ce805d03fa43f526dc0a1a1123a67b4f0c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -17,6 +17,7 @@ dependencies { +@@ -29,6 +29,7 @@ dependencies { // ASWM start implementation(project(":slimeworldmanager-api")) implementation(project(":core")) + implementation("commons-io:commons-io:2.11.0") // ASWM end // Paper start - implementation("org.jline:jline-terminal-jansi:3.21.0") + implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ diff --git a/src/main/java/com/infernalsuite/aswm/AdvancedSlimePaper.java b/src/main/java/com/infernalsuite/aswm/AdvancedSlimePaper.java new file mode 100644 index 0000000000000000000000000000000000000000..719bfb548cfe69cbb726d95b68527bdf45f1eb52 @@ -706,7 +706,7 @@ index 26422904751647a061397ce978bba752149003cd..4940083475948eac4fc06446f7ee7e1e } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index b185a9b474121b8a4067816b3c3c39270c2a202e..81ca05a02652c610a8a3c5054b0af82fe2a2bbdc 100644 +index ac8af406180bc680d46e8edc3da0fc2e5211345a..4936c074ad73d92f3b5ed6463126abb5017e221c 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -8,6 +8,7 @@ import com.google.common.collect.ImmutableList; @@ -717,7 +717,7 @@ index b185a9b474121b8a4067816b3c3c39270c2a202e..81ca05a02652c610a8a3c5054b0af82f import com.mojang.authlib.GameProfile; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; -@@ -1475,6 +1476,8 @@ public final class CraftServer implements Server { +@@ -1487,6 +1488,8 @@ public final class CraftServer implements Server { return false; } diff --git a/patches/server/0015-1.21-compatibility.patch b/patches/server/0015-1.21-compatibility.patch index f64f9f6e7..87cf21f1e 100644 --- a/patches/server/0015-1.21-compatibility.patch +++ b/patches/server/0015-1.21-compatibility.patch @@ -281,10 +281,10 @@ index 4640baec5bed6c2d53cc0f8ca1d273cc115abe9b..589cb65f79bb05ee8c44b526c707e81d @Override public final FluidState getFluidIfLoaded(BlockPos blockposition) { diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index d558e53b91e38c55fe25273b468b1e8a480ecced..c1e5a630d6cafca91398f55203994879bcac6fe4 100644 +index faf7f4f3bd1fbc91a40e5549a7a5520ea3eaec37..8832efbf9f68fb0466fdc9d6eb0d0acf5d5930dd 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -@@ -457,7 +457,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -469,7 +469,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun SerializableChunkData.LOGGER.error("Recoverable errors when loading section [{}, {}, {}]: {}", new Object[]{chunkPos.x, y, chunkPos.z, message}); } diff --git a/patches/server/0017-fix-disable-dragon-fights.patch b/patches/server/0017-fix-disable-dragon-fights.patch index af602f847..55111785f 100644 --- a/patches/server/0017-fix-disable-dragon-fights.patch +++ b/patches/server/0017-fix-disable-dragon-fights.patch @@ -5,7 +5,7 @@ Subject: [PATCH] fix disable dragon fights diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 56eb45b2df21acb4461e1d800280b39084ccd143..18d6aa9b37947b5eac7511da5d2e33b79be5be0c 100644 +index d414a0056ab27558440086ab373867bd7e28cdd2..36d0ce70ab1eaddf3354a9e2f8c86269cb319342 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -2,6 +2,7 @@ package net.minecraft.server.level; @@ -16,7 +16,7 @@ index 56eb45b2df21acb4461e1d800280b39084ccd143..18d6aa9b37947b5eac7511da5d2e33b7 import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.util.Pair; import com.mojang.logging.LogUtils; -@@ -656,7 +657,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -663,7 +664,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.structureCheck = new StructureCheck(this.chunkSource.chunkScanner(), this.registryAccess(), minecraftserver.getStructureManager(), this.getTypeKey(), chunkgenerator, this.chunkSource.randomState(), this, chunkgenerator.getBiomeSource(), l, datafixer); // Paper - Fix missing CB diff this.structureManager = new StructureManager(this, this.serverLevelData.worldGenOptions(), this.structureCheck); // CraftBukkit if ((this.dimension() == Level.END && this.dimensionTypeRegistration().is(BuiltinDimensionTypes.END)) || env == org.bukkit.World.Environment.THE_END) { // CraftBukkit - Allow to create EnderDragonBattle in default and custom END diff --git a/patches/server/0019-1.21.3-fixes.patch b/patches/server/0019-1.21.3-fixes.patch index 4dbf5e1ac..39daf6648 100644 --- a/patches/server/0019-1.21.3-fixes.patch +++ b/patches/server/0019-1.21.3-fixes.patch @@ -264,10 +264,10 @@ index 6a5a8fbd8ee013828685495267283d9518d32d20..acb6ea84fbc40a6907edb237b834feeb } diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index c1e5a630d6cafca91398f55203994879bcac6fe4..07808162fbd38dcfab0c298750323de318baa486 100644 +index 8832efbf9f68fb0466fdc9d6eb0d0acf5d5930dd..d03db9b8e78c795408b336beb53d6940a75ed759 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -@@ -359,7 +359,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun +@@ -371,7 +371,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun } if (world instanceof com.infernalsuite.aswm.level.SlimeLevelInstance) { From 05876d7eecafe7cd8ef0ecd926beb26d7817e049 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Thu, 5 Dec 2024 01:43:51 +0100 Subject: [PATCH 012/133] fix: missing chunks & entities when chunk saving --- ...ng-chunks-entities-when-chunk-saving.patch | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch diff --git a/patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch b/patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch new file mode 100644 index 000000000..066785af6 --- /dev/null +++ b/patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch @@ -0,0 +1,131 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: David Mayr +Date: Thu, 5 Dec 2024 01:41:21 +0100 +Subject: [PATCH] Fix missing chunks & entities when chunk saving + + +diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java +index bc0990458df745c92e5bc0530ff35ab992365b3a..ea8bd11050bb2811fff1a930bfb055fee55a274d 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java ++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java +@@ -914,6 +914,12 @@ public final class NewChunkHolder { + this.world.unload(levelChunk); + } + } ++ // ASP start - Chunk unloading ++ if (world instanceof com.infernalsuite.aswm.level.SlimeLevelInstance slime && chunk instanceof LevelChunk levelChunk) { ++ //The custom entity slices need to be passed on for entities to be saved ++ slime.onChunkUnloaded(levelChunk, entityChunk); ++ } ++ // ASP end - Chunk unloading + + // unload entity data + if (entityChunk != null) { +diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java +index cbcbbc8410b24daf685d74791ad80989d4830d7b..cdc4fd3a8767a3cb168ceb3088f4ae237fd9a11e 100644 +--- a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java ++++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java +@@ -66,12 +66,19 @@ public class NMSSlimeChunk implements SlimeChunk { + private final CompoundTag extra; + private final CompoundTag upgradeData; + ++ private final ChunkEntitySlices entitySlices; ++ + public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference) { ++ this(chunk, reference, null); ++ } ++ ++ public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference, ChunkEntitySlices slices) { + this.chunk = chunk; + this.extra = new CompoundTag("", new CompoundMap()); + extra.getValue().put(Converter.convertTag("ChunkBukkitValues", chunk.persistentDataContainer.toTagCompound())); + + this.upgradeData = reference == null ? null : reference.getUpgradeData(); ++ this.entitySlices = slices; + } + + @Override +@@ -168,11 +175,7 @@ public class NMSSlimeChunk implements SlimeChunk { + public List getEntities() { + List entities = new ArrayList<>(); + +- if(this.chunk == null || this.chunk.getChunkHolder() == null) { +- return new ArrayList<>(); +- } +- +- ChunkEntitySlices slices = this.chunk.getChunkHolder().getEntityChunk(); ++ ChunkEntitySlices slices = getEntitySlices(); + if (slices == null) { + return new ArrayList<>(); + } +@@ -194,6 +197,18 @@ public class NMSSlimeChunk implements SlimeChunk { + }); + } + ++ private ChunkEntitySlices getEntitySlices() { ++ if (this.entitySlices != null) { ++ return entitySlices; ++ } ++ ++ if (this.chunk == null || this.chunk.getChunkHolder() == null) { ++ return null; ++ } ++ ++ return this.chunk.getChunkHolder().getEntityChunk(); ++ } ++ + @Override + public CompoundTag getExtraData() { + return extra; +diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkLevel.java b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkLevel.java +index 2ebabf20c37d2b5c479de5bb241aa334f92a1104..866246838b6d6f23eacb1d9bad1c31cb2c1e76b0 100644 +--- a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkLevel.java ++++ b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkLevel.java +@@ -19,12 +19,6 @@ public class SlimeChunkLevel extends LevelChunk { + this.inMemoryWorld = world.slimeInstance; + } + +- @Override +- public void unloadCallback() { +- super.unloadCallback(); +- this.inMemoryWorld.unload(this); +- } +- + @Override + public void loadCallback() { + super.loadCallback(); +diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java +index 770679851baba2ddb9f8f427f4cd80ea8b32122b..619ccbab1a5582af1d1ad69fb0c54e52ca84847d 100644 +--- a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java ++++ b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java +@@ -104,11 +104,11 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { + + // Authored by: Kenox + // Don't use the NMS live chunk in the chunk map +- public void unload(LevelChunk providedChunk) { ++ public void unload(LevelChunk providedChunk, ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices entitySlices) { + final int x = providedChunk.locX; + final int z = providedChunk.locZ; + +- SlimeChunk chunk = new NMSSlimeChunk(providedChunk, getChunk(x, z)); ++ SlimeChunk chunk = new NMSSlimeChunk(providedChunk, getChunk(x, z), entitySlices); + + if (FastChunkPruner.canBePruned(this.liveWorld, providedChunk)) { + this.chunkStorage.remove(Util.chunkPosition(x, z)); +diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java +index acb6ea84fbc40a6907edb237b834feeb66075af8..2821d953e8b01cadf171508ac0b8e1eda6201970 100644 +--- a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java ++++ b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java +@@ -202,9 +202,7 @@ public class SlimeLevelInstance extends ServerLevel { + propertyMap.setValue(SlimeProperties.SPAWN_YAW, angle); + } + +- @Override +- public void unload(LevelChunk chunk) { +- this.slimeInstance.unload(chunk); +- super.unload(chunk); ++ public void onChunkUnloaded(LevelChunk chunk, ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices entityChunk) { ++ this.slimeInstance.unload(chunk, entityChunk); + } + } +\ No newline at end of file From 32f26406b98ac225d51a44c8e3926c62cf6b049f Mon Sep 17 00:00:00 2001 From: David Mayr Date: Thu, 5 Dec 2024 01:49:11 +0100 Subject: [PATCH 013/133] fix: pdc not saving when chunks are unloaded --- ...-not-saving-when-chunks-are-unloaded.patch | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 patches/server/0021-fix-pdc-not-saving-when-chunks-are-unloaded.patch diff --git a/patches/server/0021-fix-pdc-not-saving-when-chunks-are-unloaded.patch b/patches/server/0021-fix-pdc-not-saving-when-chunks-are-unloaded.patch new file mode 100644 index 000000000..e220d4ca3 --- /dev/null +++ b/patches/server/0021-fix-pdc-not-saving-when-chunks-are-unloaded.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: David Mayr +Date: Thu, 5 Dec 2024 01:46:03 +0100 +Subject: [PATCH] fix pdc not saving when chunks are unloaded + + +diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java +index 619ccbab1a5582af1d1ad69fb0c54e52ca84847d..8c71a932d49d55d861910712d3f482d39b62ad65 100644 +--- a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java ++++ b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java +@@ -114,6 +114,8 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { + this.chunkStorage.remove(Util.chunkPosition(x, z)); + return; + } ++ Tag pdcTag = Converter.convertTag("ChunkBukkitValues", providedChunk.persistentDataContainer.toTagCompound()); ++ chunk.getExtraData().getValue().put(pdcTag); + + this.chunkStorage.put(Util.chunkPosition(x, z), + new SlimeChunkSkeleton(chunk.getX(), chunk.getZ(), chunk.getSections(), From 138ee8b8e7009d1091adce536d0501d2b09be318 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Tue, 10 Dec 2024 02:32:34 +0100 Subject: [PATCH 014/133] fix: move saving up so block entities can get saved --- ...sing-chunks-entities-when-chunk-saving.patch | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch b/patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch index 066785af6..cacb07135 100644 --- a/patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch +++ b/patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch @@ -5,22 +5,23 @@ Subject: [PATCH] Fix missing chunks & entities when chunk saving diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -index bc0990458df745c92e5bc0530ff35ab992365b3a..ea8bd11050bb2811fff1a930bfb055fee55a274d 100644 +index bc0990458df745c92e5bc0530ff35ab992365b3a..682f293396ef34fdc6a61314827dc34f504c7777 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -@@ -914,6 +914,12 @@ public final class NewChunkHolder { - this.world.unload(levelChunk); - } - } +@@ -897,6 +897,13 @@ public final class NewChunkHolder { + + final boolean shouldLevelChunkNotSave = PlatformHooks.get().forceNoSave(chunk); + + // ASP start - Chunk unloading + if (world instanceof com.infernalsuite.aswm.level.SlimeLevelInstance slime && chunk instanceof LevelChunk levelChunk) { + //The custom entity slices need to be passed on for entities to be saved + slime.onChunkUnloaded(levelChunk, entityChunk); + } + // ASP end - Chunk unloading - - // unload entity data - if (entityChunk != null) { ++ + // unload chunk data + if (chunk != null) { + if (chunk instanceof LevelChunk levelChunk) { diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java index cbcbbc8410b24daf685d74791ad80989d4830d7b..cdc4fd3a8767a3cb168ceb3088f4ae237fd9a11e 100644 --- a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java From 991eae1f068def0f78ca713f87d30b1def7caafe Mon Sep 17 00:00:00 2001 From: kyngs Date: Fri, 13 Dec 2024 16:58:28 +0100 Subject: [PATCH 015/133] Attempt to fix #142 --- gradlew.bat | 184 +++++++++--------- .../aswm/loaders/mongo/MongoLoader.java | 2 +- 2 files changed, 93 insertions(+), 93 deletions(-) diff --git a/gradlew.bat b/gradlew.bat index 7101f8e46..25da30dbd 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,92 +1,92 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/loaders/src/main/java/com/infernalsuite/aswm/loaders/mongo/MongoLoader.java b/loaders/src/main/java/com/infernalsuite/aswm/loaders/mongo/MongoLoader.java index b82e92f2f..4da311db6 100644 --- a/loaders/src/main/java/com/infernalsuite/aswm/loaders/mongo/MongoLoader.java +++ b/loaders/src/main/java/com/infernalsuite/aswm/loaders/mongo/MongoLoader.java @@ -36,7 +36,7 @@ public MongoLoader(String database, String collection, @Nullable String username String authParams = username != null && password != null ? username + ":" + password + "@" : ""; String parsedAuthSource = authSource != null ? "/?authSource=" + authSource : ""; - String parsedUri = uri != null ? uri : "mongodb://" + authParams + host + ":" + port + parsedAuthSource; + String parsedUri = uri != null && !uri.isBlank() ? uri : "mongodb://" + authParams + host + ":" + port + parsedAuthSource; this.client = MongoClients.create(parsedUri); From c394d0f0cf47dd182a170804ae5bd850bde1fb5f Mon Sep 17 00:00:00 2001 From: Philip Kelley Date: Sun, 15 Dec 2024 17:15:11 +0000 Subject: [PATCH 016/133] Update deps --- build.gradle.kts | 6 +++--- importer/build.gradle.kts | 2 +- plugin/build.gradle.kts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 805afe106..9ec6949da 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,9 +1,9 @@ plugins { java `maven-publish` - id("com.gradleup.shadow") version "8.3.0" apply false - id("io.papermc.paperweight.patcher") version "1.7.4" - id("org.kordamp.gradle.profiles") version "0.47.0" + id("com.gradleup.shadow") version "8.3.5" apply false + id("io.papermc.paperweight.patcher") version "1.7.7" + id("org.kordamp.gradle.profiles") version "0.54.0" } val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/" diff --git a/importer/build.gradle.kts b/importer/build.gradle.kts index c4ca14198..66047469f 100644 --- a/importer/build.gradle.kts +++ b/importer/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("com.github.johnrengelman.shadow") version "8.1.1" + id("com.gradleup.shadow") version "8.3.5" } dependencies { diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts index 54357579e..818ff7f56 100644 --- a/plugin/build.gradle.kts +++ b/plugin/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("com.github.johnrengelman.shadow") version "8.1.1" + id("com.gradleup.shadow") version "8.3.5" id("net.kyori.blossom") version "2.1.0" } From 6c01d44fe2c75e17905bacc9f9c9db314d0cf8da Mon Sep 17 00:00:00 2001 From: Philip Kelley Date: Sun, 15 Dec 2024 17:45:25 +0000 Subject: [PATCH 017/133] Update gradlew to 8.11.1 --- gradle/wrapper/gradle-wrapper.jar | Bin 43462 -> 43583 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 7 +++++-- gradlew.bat | 2 ++ 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd4917707c1f8861d8cb53dd15194d4248596..a4b76b9530d66f5e68d973ea569d8e19de379189 100644 GIT binary patch delta 34592 zcmY(qRX`kF)3u#IAjsf0xCD212@LM;?(PINyAue(f;$XO2=4Cg1P$=#e%|lo zKk1`B>Q#GH)wNd-&cJog!qw7YfYndTeo)CyX{fOHsQjGa<{e=jamMNwjdatD={CN3>GNchOE9OGPIqr)3v>RcKWR3Z zF-guIMjE2UF0Wqk1)21791y#}ciBI*bAenY*BMW_)AeSuM5}vz_~`+1i!Lo?XAEq{TlK5-efNFgHr6o zD>^vB&%3ZGEWMS>`?tu!@66|uiDvS5`?bF=gIq3rkK(j<_TybyoaDHg8;Y#`;>tXI z=tXo~e9{U!*hqTe#nZjW4z0mP8A9UUv1}C#R*@yu9G3k;`Me0-BA2&Aw6f`{Ozan2 z8c8Cs#dA-7V)ZwcGKH}jW!Ja&VaUc@mu5a@CObzNot?b{f+~+212lwF;!QKI16FDS zodx>XN$sk9;t;)maB^s6sr^L32EbMV(uvW%or=|0@U6cUkE`_!<=LHLlRGJx@gQI=B(nn z-GEjDE}*8>3U$n(t^(b^C$qSTI;}6q&ypp?-2rGpqg7b}pyT zOARu2x>0HB{&D(d3sp`+}ka+Pca5glh|c=M)Ujn_$ly^X6&u z%Q4Y*LtB_>i6(YR!?{Os-(^J`(70lZ&Hp1I^?t@~SFL1!m0x6j|NM!-JTDk)%Q^R< z@e?23FD&9_W{Bgtr&CG&*Oer3Z(Bu2EbV3T9FeQ|-vo5pwzwQ%g&=zFS7b{n6T2ZQ z*!H(=z<{D9@c`KmHO&DbUIzpg`+r5207}4D=_P$ONIc5lsFgn)UB-oUE#{r+|uHc^hzv_df zV`n8&qry%jXQ33}Bjqcim~BY1?KZ}x453Oh7G@fA(}+m(f$)TY%7n=MeLi{jJ7LMB zt(mE*vFnep?YpkT_&WPV9*f>uSi#n#@STJmV&SLZnlLsWYI@y+Bs=gzcqche=&cBH2WL)dkR!a95*Ri)JH_4c*- zl4pPLl^as5_y&6RDE@@7342DNyF&GLJez#eMJjI}#pZN{Y8io{l*D+|f_Y&RQPia@ zNDL;SBERA|B#cjlNC@VU{2csOvB8$HzU$01Q?y)KEfos>W46VMh>P~oQC8k=26-Ku)@C|n^zDP!hO}Y z_tF}0@*Ds!JMt>?4y|l3?`v#5*oV-=vL7}zehMON^=s1%q+n=^^Z{^mTs7}*->#YL z)x-~SWE{e?YCarwU$=cS>VzmUh?Q&7?#Xrcce+jeZ|%0!l|H_=D_`77hBfd4Zqk&! zq-Dnt_?5*$Wsw8zGd@?woEtfYZ2|9L8b>TO6>oMh%`B7iBb)-aCefM~q|S2Cc0t9T zlu-ZXmM0wd$!gd-dTtik{bqyx32%f;`XUvbUWWJmpHfk8^PQIEsByJm+@+-aj4J#D z4#Br3pO6z1eIC>X^yKk|PeVwX_4B+IYJyJyc3B`4 zPrM#raacGIzVOexcVB;fcsxS=s1e&V;Xe$tw&KQ`YaCkHTKe*Al#velxV{3wxx}`7@isG zp6{+s)CG%HF#JBAQ_jM%zCX5X;J%-*%&jVI?6KpYyzGbq7qf;&hFprh?E5Wyo=bZ) z8YNycvMNGp1836!-?nihm6jI`^C`EeGryoNZO1AFTQhzFJOA%Q{X(sMYlzABt!&f{ zoDENSuoJQIg5Q#@BUsNJX2h>jkdx4<+ipUymWKFr;w+s>$laIIkfP6nU}r+?J9bZg zUIxz>RX$kX=C4m(zh-Eg$BsJ4OL&_J38PbHW&7JmR27%efAkqqdvf)Am)VF$+U3WR z-E#I9H6^)zHLKCs7|Zs<7Bo9VCS3@CDQ;{UTczoEprCKL3ZZW!ffmZFkcWU-V|_M2 zUA9~8tE9<5`59W-UgUmDFp11YlORl3mS3*2#ZHjv{*-1#uMV_oVTy{PY(}AqZv#wF zJVks)%N6LaHF$$<6p8S8Lqn+5&t}DmLKiC~lE{jPZ39oj{wR&fe*LX-z0m}9ZnZ{U z>3-5Bh{KKN^n5i!M79Aw5eY=`6fG#aW1_ZG;fw7JM69qk^*(rmO{|Z6rXy?l=K=#_ zE-zd*P|(sskasO(cZ5L~_{Mz&Y@@@Q)5_8l<6vB$@226O+pDvkFaK8b>%2 zfMtgJ@+cN@w>3)(_uR;s8$sGONbYvoEZ3-)zZk4!`tNzd<0lwt{RAgplo*f@Z)uO` zzd`ljSqKfHJOLxya4_}T`k5Ok1Mpo#MSqf~&ia3uIy{zyuaF}pV6 z)@$ZG5LYh8Gge*LqM_|GiT1*J*uKes=Oku_gMj&;FS`*sfpM+ygN&yOla-^WtIU#$ zuw(_-?DS?6DY7IbON7J)p^IM?N>7x^3)(7wR4PZJu(teex%l>zKAUSNL@~{czc}bR z)I{XzXqZBU3a;7UQ~PvAx8g-3q-9AEd}1JrlfS8NdPc+!=HJ6Bs( zCG!0;e0z-22(Uzw>hkEmC&xj?{0p|kc zM}MMXCF%RLLa#5jG`+}{pDL3M&|%3BlwOi?dq!)KUdv5__zR>u^o|QkYiqr(m3HxF z6J*DyN#Jpooc$ok=b7{UAVM@nwGsr6kozSddwulf5g1{B=0#2)zv!zLXQup^BZ4sv*sEsn)+MA?t zEL)}3*R?4(J~CpeSJPM!oZ~8;8s_=@6o`IA%{aEA9!GELRvOuncE`s7sH91 zmF=+T!Q6%){?lJn3`5}oW31(^Of|$r%`~gT{eimT7R~*Mg@x+tWM3KE>=Q>nkMG$U za7r>Yz2LEaA|PsMafvJ(Y>Xzha?=>#B!sYfVob4k5Orb$INFdL@U0(J8Hj&kgWUlO zPm+R07E+oq^4f4#HvEPANGWLL_!uF{nkHYE&BCH%l1FL_r(Nj@M)*VOD5S42Gk-yT z^23oAMvpA57H(fkDGMx86Z}rtQhR^L!T2iS!788E z+^${W1V}J_NwdwdxpXAW8}#6o1(Uu|vhJvubFvQIH1bDl4J4iDJ+181KuDuHwvM?` z%1@Tnq+7>p{O&p=@QT}4wT;HCb@i)&7int<0#bj8j0sfN3s6|a(l7Bj#7$hxX@~iP z1HF8RFH}irky&eCN4T94VyKqGywEGY{Gt0Xl-`|dOU&{Q;Ao;sL>C6N zXx1y^RZSaL-pG|JN;j9ADjo^XR}gce#seM4QB1?S`L*aB&QlbBIRegMnTkTCks7JU z<0(b+^Q?HN1&$M1l&I@>HMS;!&bb()a}hhJzsmB?I`poqTrSoO>m_JE5U4=?o;OV6 zBZjt;*%1P>%2{UL=;a4(aI>PRk|mr&F^=v6Fr&xMj8fRCXE5Z2qdre&;$_RNid5!S zm^XiLK25G6_j4dWkFqjtU7#s;b8h?BYFxV?OE?c~&ME`n`$ix_`mb^AWr+{M9{^^Rl;~KREplwy2q;&xe zUR0SjHzKVYzuqQ84w$NKVPGVHL_4I)Uw<$uL2-Ml#+5r2X{LLqc*p13{;w#E*Kwb*1D|v?e;(<>vl@VjnFB^^Y;;b3 z=R@(uRj6D}-h6CCOxAdqn~_SG=bN%^9(Ac?zfRkO5x2VM0+@_qk?MDXvf=@q_* z3IM@)er6-OXyE1Z4sU3{8$Y$>8NcnU-nkyWD&2ZaqX1JF_JYL8y}>@V8A5%lX#U3E zet5PJM`z79q9u5v(OE~{by|Jzlw2<0h`hKpOefhw=fgLTY9M8h+?37k@TWpzAb2Fc zQMf^aVf!yXlK?@5d-re}!fuAWu0t57ZKSSacwRGJ$0uC}ZgxCTw>cjRk*xCt%w&hh zoeiIgdz__&u~8s|_TZsGvJ7sjvBW<(C@}Y%#l_ID2&C`0;Eg2Z+pk;IK}4T@W6X5H z`s?ayU-iF+aNr5--T-^~K~p;}D(*GWOAYDV9JEw!w8ZYzS3;W6*_`#aZw&9J ziXhBKU3~zd$kKzCAP-=t&cFDeQR*_e*(excIUxKuD@;-twSlP6>wWQU)$|H3Cy+`= z-#7OW!ZlYzZxkdQpfqVDFU3V2B_-eJS)Fi{fLtRz!K{~7TR~XilNCu=Z;{GIf9KYz zf3h=Jo+1#_s>z$lc~e)l93h&RqW1VHYN;Yjwg#Qi0yzjN^M4cuL>Ew`_-_wRhi*!f zLK6vTpgo^Bz?8AsU%#n}^EGigkG3FXen3M;hm#C38P@Zs4{!QZPAU=m7ZV&xKI_HWNt90Ef zxClm)ZY?S|n**2cNYy-xBlLAVZ=~+!|7y`(fh+M$#4zl&T^gV8ZaG(RBD!`3?9xcK zp2+aD(T%QIgrLx5au&TjG1AazI;`8m{K7^!@m>uGCSR;Ut{&?t%3AsF{>0Cm(Kf)2 z?4?|J+!BUg*P~C{?mwPQ#)gDMmro20YVNsVx5oWQMkzQ? zsQ%Y>%7_wkJqnSMuZjB9lBM(o zWut|B7w48cn}4buUBbdPBW_J@H7g=szrKEpb|aE>!4rLm+sO9K%iI75y~2HkUo^iw zJ3se$8$|W>3}?JU@3h@M^HEFNmvCp|+$-0M?RQ8SMoZ@38%!tz8f8-Ptb@106heiJ z^Bx!`0=Im z1!NUhO=9ICM*+||b3a7w*Y#5*Q}K^ar+oMMtekF0JnO>hzHqZKH0&PZ^^M(j;vwf_ z@^|VMBpcw8;4E-9J{(u7sHSyZpQbS&N{VQ%ZCh{c1UA5;?R} z+52*X_tkDQ(s~#-6`z4|Y}3N#a&dgP4S_^tsV=oZr4A1 zaSoPN1czE(UIBrC_r$0HM?RyBGe#lTBL4~JW#A`P^#0wuK)C-2$B6TvMi@@%K@JAT_IB^T7Zfqc8?{wHcSVG_?{(wUG%zhCm=%qP~EqeqKI$9UivF zv+5IUOs|%@ypo6b+i=xsZ=^G1yeWe)z6IX-EC`F=(|_GCNbHbNp(CZ*lpSu5n`FRA zhnrc4w+Vh?r>her@Ba_jv0Omp#-H7avZb=j_A~B%V0&FNi#!S8cwn0(Gg-Gi_LMI{ zCg=g@m{W@u?GQ|yp^yENd;M=W2s-k7Gw2Z(tsD5fTGF{iZ%Ccgjy6O!AB4x z%&=6jB7^}pyftW2YQpOY1w@%wZy%}-l0qJlOSKZXnN2wo3|hujU+-U~blRF!^;Tan z0w;Srh0|Q~6*tXf!5-rCD)OYE(%S|^WTpa1KHtpHZ{!;KdcM^#g8Z^+LkbiBHt85m z;2xv#83lWB(kplfgqv@ZNDcHizwi4-8+WHA$U-HBNqsZ`hKcUI3zV3d1ngJP-AMRET*A{> zb2A>Fk|L|WYV;Eu4>{a6ESi2r3aZL7x}eRc?cf|~bP)6b7%BnsR{Sa>K^0obn?yiJ zCVvaZ&;d_6WEk${F1SN0{_`(#TuOOH1as&#&xN~+JDzX(D-WU_nLEI}T_VaeLA=bc zl_UZS$nu#C1yH}YV>N2^9^zye{rDrn(rS99>Fh&jtNY7PP15q%g=RGnxACdCov47= zwf^9zfJaL{y`R#~tvVL#*<`=`Qe zj_@Me$6sIK=LMFbBrJps7vdaf_HeX?eC+P^{AgSvbEn?n<}NDWiQGQG4^ZOc|GskK z$Ve2_n8gQ-KZ=s(f`_X!+vM5)4+QmOP()2Fe#IL2toZBf+)8gTVgDSTN1CkP<}!j7 z0SEl>PBg{MnPHkj4wj$mZ?m5x!1ePVEYI(L_sb0OZ*=M%yQb?L{UL(2_*CTVbRxBe z@{)COwTK1}!*CK0Vi4~AB;HF(MmQf|dsoy(eiQ>WTKcEQlnKOri5xYsqi61Y=I4kzAjn5~{IWrz_l))|Ls zvq7xgQs?Xx@`N?f7+3XKLyD~6DRJw*uj*j?yvT3}a;(j_?YOe%hUFcPGWRVBXzpMJ zM43g6DLFqS9tcTLSg=^&N-y0dXL816v&-nqC0iXdg7kV|PY+js`F8dm z2PuHw&k+8*&9SPQ6f!^5q0&AH(i+z3I7a?8O+S5`g)>}fG|BM&ZnmL;rk)|u{1!aZ zEZHpAMmK_v$GbrrWNP|^2^s*!0waLW=-h5PZa-4jWYUt(Hr@EA(m3Mc3^uDxwt-me^55FMA9^>hpp26MhqjLg#^Y7OIJ5%ZLdNx&uDgIIqc zZRZl|n6TyV)0^DDyVtw*jlWkDY&Gw4q;k!UwqSL6&sW$B*5Rc?&)dt29bDB*b6IBY z6SY6Unsf6AOQdEf=P1inu6(6hVZ0~v-<>;LAlcQ2u?wRWj5VczBT$Op#8IhppP-1t zfz5H59Aa~yh7EN;BXJsLyjkjqARS5iIhDVPj<=4AJb}m6M@n{xYj3qsR*Q8;hVxDyC4vLI;;?^eENOb5QARj#nII5l$MtBCI@5u~(ylFi$ zw6-+$$XQ}Ca>FWT>q{k)g{Ml(Yv=6aDfe?m|5|kbGtWS}fKWI+})F6`x@||0oJ^(g|+xi zqlPdy5;`g*i*C=Q(aGeDw!eQg&w>UUj^{o?PrlFI=34qAU2u@BgwrBiaM8zoDTFJ< zh7nWpv>dr?q;4ZA?}V}|7qWz4W?6#S&m>hs4IwvCBe@-C>+oohsQZ^JC*RfDRm!?y zS4$7oxcI|##ga*y5hV>J4a%HHl^t$pjY%caL%-FlRb<$A$E!ws?8hf0@(4HdgQ!@> zds{&g$ocr9W4I84TMa9-(&^_B*&R%^=@?Ntxi|Ejnh;z=!|uVj&3fiTngDPg=0=P2 zB)3#%HetD84ayj??qrxsd9nqrBem(8^_u_UY{1@R_vK-0H9N7lBX5K(^O2=0#TtUUGSz{ z%g>qU8#a$DyZ~EMa|8*@`GOhCW3%DN%xuS91T7~iXRr)SG`%=Lfu%U~Z_`1b=lSi?qpD4$vLh$?HU6t0MydaowUpb zQr{>_${AMesCEffZo`}K0^~x>RY_ZIG{(r39MP>@=aiM@C;K)jUcfQV8#?SDvq>9D zI{XeKM%$$XP5`7p3K0T}x;qn)VMo>2t}Ib(6zui;k}<<~KibAb%p)**e>ln<=qyWU zrRDy|UXFi9y~PdEFIAXejLA{K)6<)Q`?;Q5!KsuEw({!#Rl8*5_F{TP?u|5(Hijv( ztAA^I5+$A*+*e0V0R~fc{ET-RAS3suZ}TRk3r)xqj~g_hxB`qIK5z(5wxYboz%46G zq{izIz^5xW1Vq#%lhXaZL&)FJWp0VZNO%2&ADd?+J%K$fM#T_Eke1{dQsx48dUPUY zLS+DWMJeUSjYL453f@HpRGU6Dv)rw+-c6xB>(=p4U%}_p>z^I@Ow9`nkUG21?cMIh9}hN?R-d)*6%pr6d@mcb*ixr7 z)>Lo<&2F}~>WT1ybm^9UO{6P9;m+fU^06_$o9gBWL9_}EMZFD=rLJ~&e?fhDnJNBI zKM=-WR6g7HY5tHf=V~6~QIQ~rakNvcsamU8m28YE=z8+G7K=h%)l6k zmCpiDInKL6*e#)#Pt;ANmjf`8h-nEt&d}(SBZMI_A{BI#ck-_V7nx)K9_D9K-p@?Zh81#b@{wS?wCcJ%og)8RF*-0z+~)6f#T` zWqF7_CBcnn=S-1QykC*F0YTsKMVG49BuKQBH%WuDkEy%E?*x&tt%0m>>5^HCOq|ux zuvFB)JPR-W|%$24eEC^AtG3Gp4qdK%pjRijF5Sg3X}uaKEE z-L5p5aVR!NTM8T`4|2QA@hXiLXRcJveWZ%YeFfV%mO5q#($TJ`*U>hicS+CMj%Ip# zivoL;dd*araeJK9EA<(tihD50FHWbITBgF9E<33A+eMr2;cgI3Gg6<-2o|_g9|> zv5}i932( zYfTE9?4#nQhP@a|zm#9FST2 z!y+p3B;p>KkUzH!K;GkBW}bWssz)9b>Ulg^)EDca;jDl+q=243BddS$hY^fC6lbpM z(q_bo4V8~eVeA?0LFD6ZtKcmOH^75#q$Eo%a&qvE8Zsqg=$p}u^|>DSWUP5i{6)LAYF4E2DfGZuMJ zMwxxmkxQf}Q$V3&2w|$`9_SQS^2NVbTHh;atB>=A%!}k-f4*i$X8m}Ni^ppZXk5_oYF>Gq(& z0wy{LjJOu}69}~#UFPc;$7ka+=gl(FZCy4xEsk);+he>Nnl>hb5Ud-lj!CNicgd^2 z_Qgr_-&S7*#nLAI7r()P$`x~fy)+y=W~6aNh_humoZr7MWGSWJPLk}$#w_1n%(@? z3FnHf1lbxKJbQ9c&i<$(wd{tUTX6DAKs@cXIOBv~!9i{wD@*|kwfX~sjKASrNFGvN zrFc=!0Bb^OhR2f`%hrp2ibv#KUxl)Np1aixD9{^o=)*U%n%rTHX?FSWL^UGpHpY@7 z74U}KoIRwxI#>)Pn4($A`nw1%-D}`sGRZD8Z#lF$6 zOeA5)+W2qvA%m^|$WluUU-O+KtMqd;Pd58?qZj})MbxYGO<{z9U&t4D{S2G>e+J9K ztFZ?}ya>SVOLp9hpW)}G%kTrg*KXXXsLkGdgHb+R-ZXqdkdQC0_)`?6mqo8(EU#d( zy;u&aVPe6C=YgCRPV!mJ6R6kdY*`e+VGM~`VtC>{k27!9vAZT)x2~AiX5|m1Rq}_= z;A9LX^nd$l-9&2%4s~p5r6ad-siV`HtxKF}l&xGSYJmP=z!?Mlwmwef$EQq~7;#OE z)U5eS6dB~~1pkj#9(}T3j!((8Uf%!W49FfUAozijoxInUE7z`~U3Y^}xc3xp){#9D z<^Tz2xw}@o@fdUZ@hnW#dX6gDOj4R8dV}Dw`u!h@*K)-NrxT8%2`T}EvOImNF_N1S zy?uo6_ZS>Qga4Xme3j#aX+1qdFFE{NT0Wfusa$^;eL5xGE_66!5_N8!Z~jCAH2=${ z*goHjl|z|kbmIE{cl-PloSTtD+2=CDm~ZHRgXJ8~1(g4W=1c3=2eF#3tah7ho`zm4 z05P&?nyqq$nC?iJ-nK_iBo=u5l#|Ka3H7{UZ&O`~t-=triw=SE7ynzMAE{Mv-{7E_ zViZtA(0^wD{iCCcg@c{54Ro@U5p1QZq_XlEGtdBAQ9@nT?(zLO0#)q55G8_Ug~Xnu zR-^1~hp|cy&52iogG@o?-^AD8Jb^;@&Ea5jEicDlze6%>?u$-eE};bQ`T6@(bED0J zKYtdc?%9*<<$2LCBzVx9CA4YV|q-qg*-{yQ;|0=KIgI6~z0DKTtajw2Oms3L zn{C%{P`duw!(F@*P)lFy11|Z&x`E2<=$Ln38>UR~z6~za(3r;45kQK_^QTX%!s zNzoIFFH8|Y>YVrUL5#mgA-Jh>j7)n)5}iVM4%_@^GSwEIBA2g-;43* z*)i7u*xc8jo2z8&=8t7qo|B-rsGw)b8UXnu`RgE4u!(J8yIJi(5m3~aYsADcfZ!GG zzqa7p=sg`V_KjiqI*LA-=T;uiNRB;BZZ)~88 z`C%p8%hIev2rxS12@doqsrjgMg3{A&N8A?%Ui5vSHh7!iC^ltF&HqG~;=16=h0{ygy^@HxixUb1XYcR36SB}}o3nxu z_IpEmGh_CK<+sUh@2zbK9MqO!S5cao=8LSQg0Zv4?ju%ww^mvc0WU$q@!oo#2bv24 z+?c}14L2vlDn%Y0!t*z=$*a!`*|uAVu&NO!z_arim$=btpUPR5XGCG0U3YU`v>yMr z^zmTdcEa!APX zYF>^Q-TP11;{VgtMqC}7>B^2gN-3KYl33gS-p%f!X<_Hr?`rG8{jb9jmuQA9U;BeG zHj6Pk(UB5c6zwX%SNi*Py*)gk^?+729$bAN-EUd*RKN7{CM4`Q65a1qF*-QWACA&m zrT)B(M}yih{2r!Tiv5Y&O&=H_OtaHUz96Npo_k0eN|!*s2mLe!Zkuv>^E8Xa43ZwH zOI058AZznYGrRJ+`*GmZzMi6yliFmGMge6^j?|PN%ARns!Eg$ufpcLc#1Ns!1@1 zvC7N8M$mRgnixwEtX{ypBS^n`k@t2cCh#_6L6WtQb8E~*Vu+Rr)YsKZRX~hzLG*BE zaeU#LPo?RLm(Wzltk79Jd1Y$|6aWz1)wf1K1RtqS;qyQMy@H@B805vQ%wfSJB?m&&=^m4i* zYVH`zTTFbFtNFkAI`Khe4e^CdGZw;O0 zqkQe2|NG_y6D%h(|EZNf&77_!NU%0y={^E=*gKGQ=)LdKPM3zUlM@otH2X07Awv8o zY8Y7a1^&Yy%b%m{mNQ5sWNMTIq96Wtr>a(hL>Qi&F(ckgKkyvM0IH<_}v~Fv-GqDapig=3*ZMOx!%cYY)SKzo7ECyem z9Mj3C)tCYM?C9YIlt1?zTJXNOo&oVxu&uXKJs7i+j8p*Qvu2PAnY}b`KStdpi`trk ztAO}T8eOC%x)mu+4ps8sYZ=vYJp16SVWEEgQyFKSfWQ@O5id6GfL`|2<}hMXLPszS zgK>NWOoR zBRyKeUPevpqKKShD|MZ`R;~#PdNMB3LWjqFKNvH9k+;(`;-pyXM55?qaji#nl~K8m z_MifoM*W*X9CQiXAOH{cZcP0;Bn10E1)T@62Um>et2ci!J2$5-_HPy(AGif+BJpJ^ ziHWynC_%-NlrFY+(f7HyVvbDIM$5ci_i3?22ZkF>Y8RPBhgx-7k3M2>6m5R24C|~I z&RPh9xpMGzhN4bii*ryWaN^d(`0 zTOADlU)g`1p+SVMNLztd)c+;XjXox(VHQwqzu>FROvf0`s&|NEv26}(TAe;@=FpZq zaVs6mp>W0rM3Qg*6x5f_bPJd!6dQGmh?&v0rpBNfS$DW-{4L7#_~-eA@7<2BsZV=X zow){3aATmLZOQrs>uzDkXOD=IiX;Ue*B(^4RF%H zeaZ^*MWn4tBDj(wj114r(`)P96EHq4th-;tWiHhkp2rDlrklX}I@ib-nel0slFoQO zOeTc;Rh7sMIebO`1%u)=GlEj+7HU;c|Nj>2j)J-kpR)s3#+9AiB zd$hAk6;3pu9(GCR#)#>aCGPYq%r&i02$0L9=7AlIGYdlUO5%eH&M!ZWD&6^NBAj0Y9ZDcPg@r@8Y&-}e!aq0S(`}NuQ({;aigCPnq75U9cBH&Y7 ze)W0aD>muAepOKgm7uPg3Dz7G%)nEqTUm_&^^3(>+eEI;$ia`m>m0QHEkTt^=cx^JsBC68#H(3zc~Z$E9I)oSrF$3 zUClHXhMBZ|^1ikm3nL$Z@v|JRhud*IhOvx!6X<(YSX(9LG#yYuZeB{=7-MyPF;?_8 zy2i3iVKG2q!=JHN>~!#Bl{cwa6-yB@b<;8LSj}`f9pw7#x3yTD>C=>1S@H)~(n_K4 z2-yr{2?|1b#lS`qG@+823j;&UE5|2+EdU4nVw5=m>o_gj#K>>(*t=xI7{R)lJhLU{ z4IO6!x@1f$aDVIE@1a0lraN9!(j~_uGlks)!&davUFRNYHflp<|ENwAxsp~4Hun$Q z$w>@YzXp#VX~)ZP8`_b_sTg(Gt7?oXJW%^Pf0UW%YM+OGjKS}X`yO~{7WH6nX8S6Z ztl!5AnM2Lo*_}ZLvo%?iV;D2z>#qdpMx*xY2*GGlRzmHCom`VedAoR=(A1nO)Y>;5 zCK-~a;#g5yDgf7_phlkM@)C8s!xOu)N2UnQhif-v5kL$*t=X}L9EyBRq$V(sI{90> z=ghTPGswRVbTW@dS2H|)QYTY&I$ljbpNPTc_T|FEJkSW7MV!JM4I(ksRqQ8)V5>}v z2Sf^Z9_v;dKSp_orZm09jb8;C(vzFFJgoYuWRc|Tt_&3k({wPKiD|*m!+za$(l*!gNRo{xtmqjy1=kGzFkTH=Nc>EL@1Um0BiN1)wBO$i z6rG={bRcT|%A3s3xh!Bw?=L&_-X+6}L9i~xRj2}-)7fsoq0|;;PS%mcn%_#oV#kAp zGw^23c8_0~ ze}v9(p};6HM0+qF5^^>BBEI3d=2DW&O#|(;wg}?3?uO=w+{*)+^l_-gE zSw8GV=4_%U4*OU^hibDV38{Qb7P#Y8zh@BM9pEM_o2FuFc2LWrW2jRRB<+IE)G=Vx zuu?cp2-`hgqlsn|$nx@I%TC!`>bX^G00_oKboOGGXLgyLKXoo$^@L7v;GWqfUFw3< zekKMWo0LR;TaFY}Tt4!O$3MU@pqcw!0w0 zA}SnJ6Lb597|P5W8$OsEHTku2Kw9y4V=hx*K%iSn!#LW9W#~OiWf^dXEP$^2 zaok=UyGwy3GRp)bm6Gqr>8-4h@3=2`Eto2|JE6Sufh?%U6;ut1v1d@#EfcQP2chCt z+mB{Bk5~()7G>wM3KYf7Xh?LGbwg1uWLotmc_}Z_o;XOUDyfU?{9atAT$={v82^w9 z(MW$gINHt4xB3{bdbhRR%T}L?McK?!zkLK3(e>zKyei(yq%Nsijm~LV|9mll-XHavFcc$teX7v);H>=oN-+E_Q{c|! zp
    JV~-9AH}jxf6IF!PxrB9is{_9s@PYth^`pb%DkwghLdAyDREz(csf9)HcVRq z+2Vn~>{(S&_;bq_qA{v7XbU?yR7;~JrLfo;g$Lkm#ufO1P`QW_`zWW+4+7xzQZnO$ z5&GyJs4-VGb5MEDBc5=zxZh9xEVoY(|2yRv&!T7LAlIs@tw+4n?v1T8M>;hBv}2n) zcqi+>M*U@uY>4N3eDSAH2Rg@dsl!1py>kO39GMP#qOHipL~*cCac2_vH^6x@xmO|E zkWeyvl@P$2Iy*mCgVF+b{&|FY*5Ygi8237i)9YW#Fp& z?TJTQW+7U)xCE*`Nsx^yaiJ0KSW}}jc-ub)8Z8x(|K7G>`&l{Y&~W=q#^4Gf{}aJ%6kLXsmv6cr=Hi*uB`V26;dr4C$WrPnHO>g zg1@A%DvIWPDtXzll39kY6#%j;aN7grYJP9AlJgs3FnC?crv$wC7S4_Z?<_s0j;MmE z75yQGul2=bY%`l__1X3jxju2$Ws%hNv75ywfAqjgFO7wFsFDOW^)q2%VIF~WhwEW0 z45z^+r+}sJ{q+>X-w(}OiD(!*&cy4X&yM`!L0Fe+_RUfs@=J{AH#K~gArqT=#DcGE z!FwY(h&+&811rVCVoOuK)Z<-$EX zp`TzcUQC256@YWZ*GkE@P_et4D@qpM92fWA6c$MV=^qTu7&g)U?O~-fUR&xFqNiY1 zRd=|zUs_rmFZhKI|H}dcKhy%Okl(#y#QuMi81zsY56Y@757xBQqDNkd+XhLQhp2BB zBF^aJ__D676wLu|yYo6jNJNw^B+Ce;DYK!f$!dNs1*?D^97u^jKS++7S z5qE%zG#HY-SMUn^_yru=T6v`)CM%K<>_Z>tPe|js`c<|y7?qol&)C=>uLWkg5 zmzNcSAG_sL)E9or;i+O}tY^70@h7+=bG1;YDlX{<4zF_?{)K5B&?^tKZ6<$SD%@>F zY0cl2H7)%zKeDX%Eo7`ky^mzS)s;842cP{_;dzFuyd~Npb4u!bwkkhf8-^C2e3`q8>MuPhgiv0VxHxvrN9_`rJv&GX0fWz-L-Jg^B zrTsm>)-~j0F1sV=^V?UUi{L2cp%YwpvHwwLaSsCIrGI#({{QfbgDxMqR1Z0TcrO*~ z;`z(A$}o+TN+QHHSvsC2`@?YICZ>s8&hY;SmOyF0PKaZIauCMS*cOpAMn@6@g@rZ+ z+GT--(uT6#mL8^*mMf7BE`(AVj?zLY-2$aI%TjtREu}5AWdGlcWLvfz(%wn72tGczwUOgGD3RXpWs%onuMxs9!*D^698AupW z9qTDQu4`!>n|)e35b4t+d(+uOx+>VC#nXCiRex_Fq4fu1f`;C`>g;IuS%6KgEa3NK z<8dsc`?SDP0g~*EC3QU&OZH-QpPowNEUd4rJF9MGAgb@H`mjRGq;?wFRDVQY7mMpm z3yoB7eQ!#O#`XIBDXqU>Pt~tCe{Q#awQI4YOm?Q3muUO6`nZ4^zi5|(wb9R)oyarG?mI|I@A0U!+**&lW7_bYKF2biJ4BDbi~*$h?kQ`rCC(LG-oO(nPxMU zfo#Z#n8t)+3Ph87roL-y2!!U4SEWNCIM16i~-&+f55;kxC2bL$FE@jH{5p$Z8gxOiP%Y`hTTa_!v{AKQz&- ztE+dosg?pN)leO5WpNTS>IKdEEn21zMm&?r28Q52{$e2tGL44^Ys=^?m6p=kOy!gJ zWm*oFGKS@mqj~{|SONA*T2)3XC|J--en+NrnPlNhAmXMqmiXs^*154{EVE{Uc%xqF zrbcQ~sezg;wQkW;dVezGrdC0qf!0|>JG6xErVZ8_?B(25cZrr-sL&=jKwW>zKyYMY zdRn1&@Rid0oIhoRl)+X4)b&e?HUVlOtk^(xldhvgf^7r+@TXa!2`LC9AsB@wEO&eU2mN) z(2^JsyA6qfeOf%LSJx?Y8BU1m=}0P;*H3vVXSjksEcm>#5Xa`}jj5D2fEfH2Xje-M zUYHgYX}1u_p<|fIC+pI5g6KGn%JeZPZ-0!!1})tOab>y=S>3W~x@o{- z6^;@rhHTgRaoor06T(UUbrK4+@5bO?r=!vckDD+nwK+>2{{|{u4N@g}r(r z#3beB`G2`XrO(iR6q2H8yS9v;(z-=*`%fk%CVpj%l#pt?g4*)yP|xS-&NBKOeW5_5 zXkVr;A)BGS=+F;j%O|69F0Lne?{U*t=^g?1HKy7R)R*<>%xD>K zelPqrp$&BF_?^mZ&U<*tWDIuhrw3HJj~--_0)GL8jxYs2@VLev2$;`DG7X6UI9Z)P zq|z`w46OtLJ1=V3U8B%9@FSsRP+Ze)dQ@;zLq|~>(%J5G-n}dRZ6&kyH|cQ!{Vil( zBUvQvj*~0_A1JCtaGZW|?6>KdP}!4A%l>(MnVv>A%d;!|qA>*t&-9-JFU4GZhn`jG z8GrgNsQJ%JSLgNFP`5;(=b+M9GO8cg+ygIz^4i?=eR@IY>IcG?+on?I4+Y47p-DB8 zjrlar)KtoI{#kBcqL&4?ub@Df+zMt*USCD_T8O$J$~oMrC6*TP7j@H5trGV$r0P6I zV7EZ{MWH`5`DrX*wx&`d;C`jjYoc_PMSqNB290QXlRn_4*F{5hBmEE4DHBC$%EsbR zQGb7p;)4MAjY@Bd*2F3L?<8typrrUykb$JXr#}c1|BL*QF|18D{ZTYBZ_=M&Ec6IS ziv{(%>CbeR(9Aog)}hA!xSm1p@K?*ce*-6R%odqGGk?I4@6q3dmHq)4jbw+B?|%#2 zbX;ioJ_tcGO*#d0v?il&mPAi+AKQvsQnPf*?8tX6qfOPsf-ttT+RZX6Dm&RF6beP3 zdotcJDI1Kn7wkq=;Au=BIyoGfXCNVjCKTj+fxU@mxp*d*7aHec0GTUPt`xbN8x%fe zikv87g)u~0cpQaf zd<7Mi9GR0B@*S&l&9pCl-HEaNX?ZY8MoXaYHGDf}733;(88<{E%)< z^k)X#To3=_O2$lKPsc9P-MkDAhJ~{x<=xTJw2aRY5SSZIA6Gij5cFzsGk@S)4@C65 zwN^6CwOI9`5c(3?cqRrH_gSq+ox(wtSBZc-Jr5N%^t3N&WB|TT_i4!i3lxwI=*p)Y zn7fb%HlXhf8OGjhzswj!=Crh~YwQYb+p~UaV@s%YPgiH_);$|Gx3{{v5v?7s<)+cb zxlT0Bb!OwtE!K>gx6c4v^M9mL0F=It*NfQL0J0O$RCpt746=H1pPNG#AZC|Y`SZt( zG`yKMBPV_0I|S?}?$t7GU%;*_39bCGO*x3+R|<=9WNe!8jH- zw5ZJS(k@wws?6w1rejjyZ>08aizReJBo%IRb3b3|VuR6Uo&sL?L5j(isqs%CYe@@b zIID7kF*hyqmy+7D(SPa^xNVm54hVF3{;4I9+mh)F22+_YFP>ux`{F)8l;uRX>1-cH zXqPnGsFRr|UZwJtjG=1x2^l_tF-mS0@sdC38kMi$kDw8W#zceJowZuV=@agQ_#l5w znB`g+sb1mhkrXh$X4y(<-CntwmVwah5#oA_p-U<_5$ zGDc%(b6Z=!QQ%w6YZS&HWovIaN8wMw1B-9N+Vyl=>(yIgy}BrAhpc2}8YL-i*_KY7 ztV+`WKcC?{RKA@t3pu*BtqZJFSd2d)+cc07-Z#4x&7Dnd{yg6)lz@`z%=Sl-`9Z~*io zck_Lshk9JRJs=t>1jmKB~>`6+(J z@(S}J2Q{Q{a-ASTnIViecW(FIagWQ%G41y?zS)gpooM z@c<2$7TykMs4LH*UUYfts(!Ncn`?eZl}f zg)wx@0N0J(X(OJ^=$2()HLn)=Cn~=zx(_9(B@L04%{F_Zn}5!~5Ec5D4ibN6G_AD} zzxY^T_JF##qM8~B%aZ1OC}X^kQu`JDwaRaZnt!YcRrP7fq>eIihJW1UY{Xhkn>NdX zKy|<6-wD*;GtE08sLYryW<-e)?7k;;B>e$u?v!QhU9jPK6*Y$o8{Tl`N`+QvG ze}71rVC)fis9TZ<>EJ2JR`80F^2rkB7dihm$1Ta2bR?&wz>e`)w<4)1{3SfS$uKfV z3R=JT!eY+i7+IIfl3SIgiR|KvBWH*s;OEuF5tq~wLOB^xP_Dc7-BbNjpC|dHYJrZCWj-ucmv4;YS~eN!LvwER`NCd`R4Xh5%zP$V^nU>j zdOkNvbyB_117;mhiTiL_TBcy&Grvl->zO_SlCCX5dFLd`q7x-lBj*&ykj^ zR3@z`y0<8XlBHEhlCk7IV=ofWsuF|d)ECS}qnWf?I#-o~5=JFQM8u+7I!^>dg|wEb zbu4wp#rHGayeYTT>MN+(x3O`nFMpOSERQdpzQv2ui|Z5#Qd zB(+GbXda|>CW55ky@mG13K0wfXAm8yoek3MJG!Hujn$5)Q(6wWb-l4ogu?jj2Q|srw?r z-TG0$OfmDx%(qcX`Fc`D!WS{3dN*V%SZas3$vFXQy98^y3oT~8Yv>$EX0!uiRae?m z_}pvK=rBy5Z_#_!8QEmix_@_*w8E8(2{R5kf^056;GzbLOPr2uqFYaG6Fkrv($n_51%7~QN<>9$WdjE=H}>(a41KM%d2x#e@K3{W|+=-h*mR&2C01e z2sMP;YjU)9h+1kxOKJ+g*W=&D@=$q4jF%@HyRtCwOmEmpS|Rr9V_2br*NOd^ z4LN#oxd5yL=#MPWN{9Vo^X-Wo{a7IF2hvYWB%eUCkAZq+=NQ=iLI9?~@ zr+|ky4Rgm7yEDuc2dIe941~qc8V_$7;?7|XLk6+nbrh}e&Tt20EWZ@dRFDoYbwhkn zjJ$th974Z0F${3wtVLk_Ty;*J-Pi zP0IwrAT!Lj34GcoSB8g?IKPt%!iLD-$s+f_eZg@9q!2Si?`F#fUqY`!{bM0O7V^G%VB|A zyMM>SKNg|KKP}+>>?n6|5MlPK3Vto&;nxppD;yk@z4DXPm0z9hxb+U&Fv4$y&G>q= z799L0$A2&#>CfSgCuu$+9W>s<-&yq3!C{F9N!{d?I|g|+Qd9@*d;GplgY5Fk$LOV+ zoMealKns!!80PWsJ%(}L61B!7l?j1_5P#LRrVv%NBhs{R`;aufHYb&b+mF%A+DGl5 zBemAHtbLFi++KT(wv9*?;awp>ROX~P?e<4#Uf5RKIV{c3NxmUz!LYO#Cxdz*CoRQp zSvX|#NN06=q_eTU5-T!RmUJ?Ht=XQF8t)f+GnY5nY5>-}WLR1+R5pou?l@Y|F@KEX zk=jh-yq=Rn9;riE*;Slo}PfNKhXO#;FrZCf%VZ9h7W z<63YWE^s_SlAVQh6B(En9i<9%4AT|2bTQ4Ph2)pI?f2S`$j?bp`>_3(`Fz&?ig-FJ zoO7KAh@4BDOU>sBXV84Eajr9;>wlbW&OSUt&dug?oAV;`+3oBzpI18%%1wA4blzmb z-{QPYJmn_2-F$A5JI!a8+-p8Bk*^U?^f5j7uZ}jEz0E3;XbahB2iZwS&l4jj4WRS6 z3O&!w=ymQSl~7LUE99noXd2y1)9E>yK`+ouR%sTOQ@Qjt@<;lErGLk1wrw7r zV)M})+amJXs_9hQa++&vrqgU&Xr8T)=G&5Vy6vOnvt37L*nU7&ws&ZO-9`)TGA**t zpby#0X|df;etRud+s~#Y_7zlPZ=_oLg%q&wraF6s>g@;VO#2sUseO=^+3%&Z?61(- z_IKzU`+Kw;Blil&LR#qv&{rzQnG|%i(Q3zLI@gh)2FE^H;~1dx9G|AOj(e%mSwT(C z71Zp!jar*i3S|_ik_3{n0L4KavYWWZ2x3MhyU!66E$h=L+A&-s$9X_w9Q_e;+`-{ZW# z^Zn2H_I~`}!vGeFRRY^DyKK#pORBr{&?X}ut`1a(x__(dt3y_-*Np0pX~q39D{Rns z!iXBWZO~+oZu>($Mrf0rjM>$JZar!n_0_!*e@yT7n=HfVT6#jbYZ0wYEXnTgPDZ0N zVE5?$1-v94G2@1jFyj##-E1Um(naG-8WuGy@rRAg)t9Oe0$RJ3OoWV8X4DXvW+ftx zk%S(O8h?#_3B9-1NHn&@ZAXtr=PXcAATV*GzFBXK>hVb9*`iMM-zvA6RwMH#2^901uxUFh&4fT% zmP?pjNsiRIMD)<6xZyOeThl_DN_ZJ*?KUIHgnx{vz`WKxj&!7HbM8{w?{Rued(M1v zKHsK{_q=YI88@Bf0*RW@cIV@=<{eGsG21xrTrWycT7*KBd!eD2zb1R(O@H~k7>Duv zHPwp=n8;t#1>7~fuM9IaD5w%BpwLtNCe_Sq9eal4oj2DB1#<+(MGR-P&Ig%3t%=!< zS$|KxI1a~an2Q>L$s;1$9nQJal4dk)Box$YsAKgCiEGni##jr|%So6Y4J@pYBF!;~ zhXwpKhc7&QZ$=e~Sb&ABZ4o)&U~N*dSU`2G^eQh-WCe9tA}~Ae369btLlB{GjOKB@yEDH!C7Q&df^#X zi~?{rCuAE|kAjKzt+r#t6s)1h840@A<%i5(O;$Q&tD(opg0)yzgm#=ucf4CSqkqYS zaTdivk5I~#=1Z9K5M*uV6H??6s9*ynT`vzr2@%Tkr4k+Tr_ib40$fPP7$yLA$cwJ@ zF@`94=op)$x^0t+QAsNY$pi!4e7hp~gO=|yD=^8JTvTiC(HAamYEQ}t z+hR~QoKTOz%)IHEg&6iC4vP=3mw&u4wvcSwi$vNBGQE5RoSUs^l+u{A+6s~aMMkXG z+1g4wD8^Y27Oe4f``K{+tm76n(*d6BUA4;pLa26`6RD6?Rq?2K1yMXVAk`&xbks*~{+``Mhg4cQEuw+aM zaI9{}9en8DCh*S9CojIk)qh|k?#iNiCQ}rAmr&iYRJiND ztt+j*c+}Fv&6x&7U~!(Sb1eAz1N@Nf`w?YxGJdhy+seiNNZEYIG1_<^?&pm^P8W?d ze(p@$nWC`Pxqpf8d&AIGNJn#Ty)j z1NbA^Y}pNQ>OfTdiAp+WR>C6390IrFj;YZglitGH8r7(GvVRpWjZd7|r24M{u66B) zs#VS$?R*!1FT&sO-ssvW8s5jh$-O=^9=7^y z75||~QA6zLW}Lu!YOZh1J$j46m zNH|;^a$U_RKgla5h>5(igl^ek(~2nL5a_0}ipvA_Xf0k*E-ExJNld0{LZ;F^DzqAL+IZGJ7<3i1szf zxMRkQ(|@;wj9%I7h{c*{;?g%giylU}Dz{iwb(1vGK<-vlnKs!|Mb9}iTt)Rl&NZka zkkugrMiY(ng3QseY!npaOf1jo3|r35nK+eTYh*`DHabuv@IFy zG7@V!LWE0&)bvqgQ8=-L-(vt#Z-&xaOj3G@Nqw1FfbNQ`!bFEl@z)0)+#Z5e#_hQ|Rd!KrEoRn^aFz zkzYzz%hher>ixcg6fW`=rr>Nx@enQ!sQqYR{<2^|eUfw?e8;B_`T)Kxkp8${U>g?k*VhCd zp^yYLvi}<#5TDjrx@{0U$jx*tQn+mhcXsq2e46a@44^-Sd;C6S2=}sK1LQ_OUhgO` z^4yN+e9Dv9TQ64y1Bw)0i4u)98(^+@R~eUUsG!Ye84 zFa7-?x3cqUXX)$G<2MgYiGWhjq?Q-CE(|sm-68_z>h_O2vME5nX;RodIf)=No(={I z_<&3QJcPg8kAI}_Vd+OH4z{NsFMmjv3;kunMSh94VNnqD?85uOps%nq=q?kU_JT5@ zwih;eQlhxr)7d^K#-~InWlc&<*#?{A(8f^+C_WmRR{B&Yh3pxhLU9-toLz%rCPi}} zE!cw^pQlXB3aACUpacU&ZlBUl(Jo4fxpbDVwDn^m{VG||ar9B)9}@K`(SJxmAWro& z_3yzfUqLoXg`H($!I;FTudPdo6FTJm2@^S|&42H(XbSRW7!)V&=I`{;mWicu@BT7z zQs!)F9t-K|aFaMsoJ_6z-ICrzjW5#yJRs>~)bugki)ST$8T%!D4F@EBliCNSA5!fl zN;OuKbR3m0rj=rrq}5`nq<<%iHIl|euXt6QA}$hFNqV)oR?_Rm4oPnoLy|ru_DQ-= zJTDFa;zjY2p{sg zWqz0I5y>-U{xR1Rl4r{NQ?6Ge&y@N7t~Vsll=-(^?@FF2^Y6JnkbgW==09{7N}eh4 z?h`%x-LM8D}+*41ZA#EG0D9KQjc2#z59Pq zO9u!y^MeiK3jhHB6_epc9Fs0q7m}w4lLmSnf6Gb(F%*XXShZTmYQ1gTje=G?4qg`Z zf*U~;6hT37na-R}qnQiIv@S#+#J6xEf(swOhZ4_JMMMtdob%^9e?s#9@%jc}19Jk8 z4-eKFdIEVQN4T|=j2t&EtMI{9_E$cx)DHN2-1mG28IEdMq557#dRO3U?22M($g zlriC81f!!ELd`)1V?{MBFnGYPgmrGp{4)cn6%<#sg5fMU9E|fi%iTOm9KgiN)zu3o zSD!J}c*e{V&__#si_#}hO9u$51d|3zY5@QM=aUgu9h0?tFMkPm8^?8iLjVN0f)0|R zWazNhlxTrCNF5d_LAD%TwkbkKL>+-8TV4VSawTAw*fNnD^2giQT{goNRR~OwAH5%vorH%=FNNm``;VB z_N`CeB%?_hv?RK-S(>S)VQBau{&NwD>j_ zF-Hwk*KNZb#pqexc5oKPcXjOO*cH#{XIq~NkPxH{TYm*Rtv_hwbV2JZd$e=Z)-pN0 z^PH`XkLz~lpy{|;F6Sq&pjD@}vs!0PGe z6v$ZT%$%iV1Z}J(*k7K8=sNv;I#+Ovvr?~~bXs?u{hF!CQ|_-`Y?!WYn_8|j3&GBu zl|F+DcYh8nxg49<-)ESHyI0Vo;oInYTMcVX9@5;g9>>x1BRMQ@KPJc%Za)^J6|_nr zKQ#*4^Z(G>Pt6Lgrp6!zX?X+rXibm;)WBbN1WBP~{Iw45)a0toTeof%G+Oh5Wryxb zN@p5YCm&YsN!Jd$jG8^|w^_Wo-1ad{*|(#*+kcnS97j-dxV>sGIk+cCchX&K1yxY6 z`dB};!Xf&3!*LyHut$Qlnc5WEME3}4k)j3H$aVHvxg78Y3_E@b3u@5wjX7b zPLz^7h65uMRj8d}5Y1tP55ozK;r0{r?;WHL>g4laujaX3dTd*h+xuy|LOa-f%M7RA zuz#V1WlscYXGzO0Xsu-c>6UPEVQ}o>+w7v~meKw6 zfS|`8k|tL(5VDPt0$*C)(&lVYGnVeCrsb+>%XBrvR5fz~VkMmn-RV#V&X1#`XH?fx zvxb>b_48WV%}uD=X5}V20@O1vluQ2hQ-2>^k+tl+2Al20(<||vxfpIJ~|9`dJ zVH^pxv&RS97h5DqN9ZW4!UT{rMgsH>#tHOouVIW{%W|QnHohN<4ZE5RR@l7FPk$#A zI?0%8pKlXW%QH2&OfWTY{1~5fO3=QyMi3vb*?iSmEU7hC;l7%nHAo*ucA`RmedXLF zXlD(SytNYn`{9Rs;@fw21qcpYFGUH*Xmdk{4fK z0AKh-FGJC#f0Ik!{d{T7B7elr2J8>e z4=VKi^h2D=Q8&0_LHc1j$T9pQ7-FcHxZj3w-{RF}MXBm@?_X&zG?V%-Bet=g# zgEZn=6W?w3jeoQ(!&ECWHqJ zs;lJ@+Tf9MhC9~LX7*WT*0A%cJEpn#(bX;0i-*TF1j2A3zeOFlEi7~=R7B$hpH(7@ zc$q9Z%JU#Am8%BTa1gvUGZPX)hL@#()Y8UP?D?tiCHan51waKUtqypCE-ALn&``k4jkeO@}6ROkhI5oJaRd?*oW z5XmD5>YOZAT4pPd`M`dOKE|;8c#wXMeqKQ__X$u$!F<91^W0T4GtRNpyh;fxIv+8{ zOV!mig|0Jq`E}FfEGH;5uUHx|3whm^-h~cRG|loa&)cs`#D7mW5K(xZ?6+)vAgAZC zD+2J-T)KRUZh~%1{k&VASQx^y`SF+OS6KX4kyjRJJpeT){PgS47=e2L=`KjGaKL_s zUIno%SwM4WAF(xl=4hpof(h_9QEfU}Rt7%rCFq{-h?=0}Z_#HJdX0XYPezSbpFe{d z0C)YJ60>{(bbnZJLT@3P<#<0>aI5md?+Lo2+D-Fke_x?5v0p-So~;%rL+cL|`Xc=y zDo2?BXJ-XJpB{>GjhRUa08Q0fc~|Te5H?$jM>&XZG_?d?@$c3DX04&{U<}^Kj^=z zll8%>K>i=dqr$~=S9jB6O9hsxyPZc556Zw=j_nVDRZX|_LS7YaUr=}9egcpXb&Lyu z)YmbNGJh^0d;nj66%_}BAGOYHUX^~)0N68LkJ^TyJHrdKncoeHWg@5uMJ!*CaF?vi zs}inQ2`7nFmB(0lPrqn_`mS~KaI)&6rO6}?TrFA@(Ja=?UzYTXI{;CnCeCzb>5&FP zU9f&`4m+(A>lG0a8$bbgJoRdhk?tvg@Ikz#RDUy9`Bv_`)Mkhjai_S8ErG{n6Y!ZX zjPs#^rE8v{eXb(WZW}1zS0~dl)qaDzZc6#Eb{ck_GRA z#30&5L=j;Tg=w(=Im_LHt$@}KL1QA*~192~ak5Zap zUm99S=A}`1@@=9=5f6x7EHE6dJZ-x$j_M#N`oWZ#8SoMRTSbJEkaI_E1S`LPb#u`l za~4L#=6*e^6>@H+e`vvSoIfb`u^orz|9^Gmf4h-i>_^V46i#@Dxdo?h3>Vd9UB7Q1 zd*h%uq=*CJ?O?Lm(&(J#sK(r_I|5=@p*QJ8=tPJL3W(!iGFv{}j#xpF;@rMTpd4td z<_1}s1;k09u3T^?RJY`6H5?F+aq(TFbgz!+$2p?$R`cYY_JBwWirgNmvn*Q5HGe{f z-XaT1oDGR#3t6;+$vF}g;7xCzl>r&9Od6(sppYNY?IXMuZ9`V@!`mKeeSE_wM4Gd+URu(#jex(s}ep9w1GC3 z7Kw+jq#o_EXrxGYA1~6D%cM+Ge1B+?9*7ocTWaW4s-L{|jmQn!kxEX{y*KxIy1Xsk zjnC7@NQ-xSD&Z?q_a#!IA$;sPe$gu?Z@nHJio8s36Lg7G@2AP18uG-3n|dSD^zhIP z+Lua-$Q13Lqz^#~2=HF178_n9HXiZ3Ovmd`>ukdKrc^2!X-ZAeBT)7dg@2>+{JWz! z=p-xnDEg15lCRLp=uPi))DZP-pCqq%wfcyWMMo@`orpju`U#jwh%@+&z~1$+@gb_i z)6qj`VXXJU%FkkS64rkme)%TMc?)t4l%`DCsP&j<&wVcTDtWIqWv3~3;0Bqggf}`x z?`&K}p9&;=Aun6(T&k=7S$}GZhkTxv`XW6!32V~_TI%bru-U&74|$7pp-A6@^%t>z zik|j#`C5GOo6l26yv4Vpk#1d>ruU>0Sp1{7@3N40)z%`t|2VeC&_KN}@=GU4?^hP}~YUu?KOKHT)vA#ce-FMp(9pP!wPTFk%# zEwqky;$|C=p1Ezu@6K6!t$>6N_Ie-e^%}k#xcn}ovllZSv|SPDuQ-}tU^i{{+`l1; z+iYOZMxq` zyNmevH37(cCUt;!hJWefMf#0t`kVyL=P%JpzSQp?pS<i{A@amJ0F;?aT#H3gGL(m+ zMd2x(2y7PxEPwgIW>H_-O1kRG@$x~jQ_UiPlcvRrqG+t>u>Js>8_Xp<>`syJiiA&! ztVK|;R}+4AD**Ck_Nds%Xh&S}{}jiCxVtDeH;a2t6-Dft*jg0#%HQsyNF;oXVK{$( zQQY6LPpMO5t9niY*so`U_cqrfS%ttA> zMrrXr{mf-r8(+hNdUxQONMdM>QWS?n{+OpF2q5te-AZ?0^44=hA%DU`#Rc;$`A425WvPKyy?$o4V#Hc#hepIh#q zrzgc`^ts)D{=4V}+2@w~FVe?kpIh#KoUY0~x7_FGtMoP5=a&0# zq5$MRx9AIxXym?ZxgQhVvd=B|)8ZMaXDKe4fFb_31FMfwok)^Lq|q0WrRvD@ZBR=G z2pQ0I&-V@h0C*ge;YJ*jtBNjvYflqF6o%gs=t3z%xd|2&*IQdyR=^LH8WYpRgrrep z4Mx6Aw}fxhSE$jN_`x6Gk20R2MM&C)-R$h{nfE#GnVgwFe}DZ3unAM( z^yK7C>62cU)*<-~eOtHo^)=lJyq4q2*a>{Y3mU}nkX(`x@nlm*hSem0>o7{ZNZ;O< zZbWN(%QigOG8~nI>Q5dw>RYT0OXvK4;<_A&n$p-%65n=wqR{bejviAOu@}cn>s#w3 zqd~{|=TQiObS+3ii(WV`2`mPoZQ7x1xMY3^WvfM@Sq*HPLJh+LQwQ=`ny&P1^Hu$T ztXM-zVD=*VoC&`n>n>@37!?>fN*sy>#GXLvspC8GGlAj!USU^YC|}skAcN~^Xqe0( zjqx#zAj>muU<=IUs~34|v06u2ahGbSeT-uAG|Vv*Bw$#pf8#qXFt zMfw|VuC{UeT)2WpJ6&O+E6jF;;~n9>cf~Ip6j-_@&PGFD0%Vu*QJ@Ht`C7Og!xt#L> zmqlJGEh<%*ATJUmZc(FfNSB##fy_`Y-70r{Iv3jEfR|~Ii!xC44vZ(KNj#>kjsE86 zE3FB*OayD~$|}3Y&(h6^X|1 z(TcJ}8{Ua3yL1loSfg!2gTekntVO7WNyFQCfwF2ti$UvL8C6{{IPBg01XK~$ThIQx z{)~aw>(9F2L#G36*kRDPqA$P*nq=!@bbQ#RzDpVIfYc*x9=}2N^*2z1E%3epP)i30 z>M4^xlbnuWe_MAGRTTb?O*?TCw6v5$6bS)qZqo=w4J~*9i;eVx4NwO!crrOjhE8U( z&P-ZZU9$We^ubqNd73QDTJqqV55D;u{1?`JQre~$mu9WZ%=z|x?{A;q|NiAy0GH5U z*nIM2xww(4aBEe#)zoy#s-^NN%WJl5hX=Oj8cnY%e+ZYt5!@FfY;fPO8p2xj+f6?; zUE_`~@~KwcX!4d}D<7hA<#M$$MY^)MV_$1K4gr3H8yA&|Ten>yr0v!TT@%u$ScDfR zrzVR=Rjj3cjDj)fWv?wQanp7LL)Me^LS6EzBMR%1w^~9L%8&g(G;d3f4uLKFIqs5J zYKSlle?R1Fyx?%RURbI;6jq>Nh+(uYf`e8J=hO2&ZQCoTU^AKRV>_^&!W{P-3%oVM zaQqOcL1!4cYP)vuF~dMQb1#lKj_HWu4TgBXPYuJQYWv&8km~(7Mlh=5I8HE}*mJ#? zmxhx%#+9e>eorO0)eg#m6uhb7G^KSg`Cbxlf9XizZH9>B@hZcqJ*7VTp6)w1tHLB1 z1}(?)MI0$rLIUS0;Z^atECLmzzb6FE#PKdBl;L{}$M%UdWEi4$AS4ew$#8O?ZRr(G z4syuHkcGi8a#*gRz@QP|7R93=j*A$L;eA}9id+JyWjkK`Mod00;{&DlA!QJFR3&lj zf1vI*O1ec{(V=0QA?ELLVls-W``ELsu7M`3`vI4MzhVcpJ!9#^KGjq|#b-J`!F7h$ z{dUEFmBLuMbYu>nV^(S3q+UC;7s@e_qZG#+N=oo0o$G1>6Y0a{9@&9;EU2+8k|7P6 zp?HMh|8#X5UnwpxGbHw;%WXHXn_~8nedvw09V+G$(lhoq7L}=qb+OaPSD&;$TuUtG(4;py( zh)8|Nord(*d1ZH-Dmw1MqU&RKiI)26r-hE(pqnmo4uixe^`qea7(_HA_R2KjdJ4$g!)7ve&Q^b1Tf+{(Vd6vInCd>i725IomG^(Ez(D8L!4qlUAX=)EV9!3JfWLB4n1z)!ums&0UuuVLUH zP)i30*5f6tnvk?lbhL{|8I78X7|_cA3p(L9<~X5y1L3{K8Sf*xL|5gToDT;aYig?m8z^z zQ`XdEMJqC#*O|ho!7x~+MzT<5g$turF~pS;RSY&GR;6TxR)3Q+&%yG`3&ngIwR*qK&t{TERu@0|fDrKKw3=RE&t-)Xh-$i& zl5|>BSn5)z)hg3d?<~8msU=ye>CHWR!9yT;PU|$KP*qADf(V?zj^n^g~nykv^I)Uz3{78Ty81{n~ zZsS&7WH)#Ach3%UyVD1s=Ahvw9*%Wt z<42vTt%|niux3Zww13+oK)-d~G>VKHM0ov>KXKaUH(Cc)#9GFVSc4EoUbnRudxi}T z8J!VNY=4g*Y7C*Ho7#^wUVt&67&ea4^1oBw%@h^ z+YZ+eK^VI5573*KZosq?pMj(u5257?^lBu&LF9`ao`sYf9&zx;uK2iv&$;8{ z4nFUSFF5$3JHFuHORo5YgFkV{CmcNEicdQDvO7NM;484|f=_+6!)x%g1CL;L9DE%% zT=1xaKZ8v-+-@x1OZ;|0_a9J82MFd71j+6K002-1li@}jlN6Rde_awnSQ^R>8l%uQ zO&WF!6qOdxN;eu7Q-nHAUeckHnK(0P3kdECiu+2%6$MdLP?%OK@`LB_gMXCA`(~0R zX;Tm9uJ&d7>n z%9A~GP*{Z zrpyh7B^|a-)|8b<&(!>OhWQ08$LV}WQ`RD4Od8d3O-;%vhK7#W<7u;XvbxQo0JX@f zY(C0RS6^zcd>jo287k@<4tg;k3q5e5hLHE@&4ooC)S|`w7N|jm>3tns$G}U4o!(2g=!}xLHp?+qF zvj$ztd<%96=4tCKGG@ADSX{=mNZ@ho6rr?EOQ1(G2i@2;GXb&S#U3YtCuVwc*4rJc zPm$kZf2+|!X~X6%(QMj{4u)mZOi!(P(dF3hX4ra9l=RKQ$v(kJFS#;ib+z9K^#Gle z6LKa>&4oMFJ4C&NBJ7hhPSIjcOno$M6iq+l;ExpH9rF68@D3-EgCCf}JJSgVPbI1$ z?JjPPX!_88InA}KX&=#cFH#s3Ix<6LeY==wf5DK*jP`hqF%u+|sI)3HfyywfAj=0O zMNUX2pLR;T(8c+$g&}Z#q9L>(D~t~l&X^VFXp@&w92f8tq+KXMZ&o!an%$#uo^hJh z^9-RjEvqE_s%H8{qw(juo4?SC{YhO*`|H*ibxm%ZF6r=2QC)bE`d3oZ(~?;a-(mX)b!|i%p!VVP>DN6tg*Ry97gUPUJj<}OxaYL1nXE}h zxs-O{twImUw z43Eo6nJ4_RTDIQALB8H!3nq37cE6>oNG;jZZhXh!vORPsMKfzJ8_*?O7DfGmcrL8A z(_NAhSH+JE?u?`xR1|ZThDb;2Dt`9hC;UQ%94^20-MA*;<$KO0{3b&9y(ENIe@&xj z6>X23)Ftc?ax=4pL5FZ06CPOjgG%2*lbx;+sVm6EHifaku2RZ6dm2zO1s^4+O| zX?^Rl!e{47y>uJGVh+yEaNe$4U2tTYyJ3nqt9nkQP8+X`9>;yxHT1=;SB4=QU*?nq zndTZfT|OzWa_zE$8FPQtuK2+Z>H-NyCcc=wWX>wq$q7{vij#xqCQBclE;KU_SpRHh zW?)cb0G=uW2QHH@&UKOjUxp5p-v+$&z!*iIUwCrEeC5gh!qSr;%oC7--UiJO%g(@H zgQD=VC|Kd1c_uQ*S7+LyC@PW!E7G5DDhEzd%(QbXn4J;PQoYKo1+C zI4^v%{X#z$(3LimCoU9YO4kMJJG0PS25}<7q9LXMM{Esm6)13%7{fk7Wdx5wm$C1R5emYB+b4!_g{ zCYC2a7ogf;<2t!#hh+G05lGD55CT^#LlBoxIEo9C9q6 zV^AjZEfZsU6$%s=ojiXT+hlLxY4o6EhgiZ7JP-%P5cLSCVgnh(`W^-bB@{)=b3uwG zE!U6%u3dpFT>%EaE{d8bl@K+c6+w`+ju^dTU{F9&yQvzYmVNS(GoZm{D-R;bE=#wApMmV(yJpr(t7y*s2{B8_zE)_ yL|YQw3&NAZiu6_*%Ye#&V4x{Sc^DWpP)tgl235p9dFD!GE+Jk92JyL|;s5}0b2K*q delta 34555 zcmX7vV`H6d(}mmEwr$(CZQE$vU^m*aZQE(=WXEZ2+l}qF_w)XN>&rEBu9;)4>0JOD zo(HR^Mh47P)@z^^pH!4#b(O8!;$>N+S+v5K5f8RrQ+Qv0_oH#e!pI2>yt4ij>fI9l zW&-hsVAQg%dpn3NRy$kb_vbM2sr`>bZ48b35m{D=OqX;p8A${^Dp|W&J5mXvUl#_I zN!~GCBUzj~C%K?<7+UZ_q|L)EGG#_*2Zzko-&Kck)Qd2%CpS3{P1co1?$|Sj1?E;PO z7alI9$X(MDly9AIEZ-vDLhpAKd1x4U#w$OvBtaA{fW9)iD#|AkMrsSaNz(69;h1iM1#_ z?u?O_aKa>vk=j;AR&*V-p3SY`CI}Uo%eRO(Dr-Te<99WQhi>y&l%UiS%W2m(d#woD zW?alFl75!1NiUzVqgqY98fSQNjhX3uZ&orB08Y*DFD;sjIddWoJF;S_@{Lx#SQk+9 zvSQ-620z0D7cy8-u_7u?PqYt?R0m2k%PWj%V(L|MCO(@3%l&pzEy7ijNv(VXU9byn z@6=4zL|qk*7!@QWd9imT9i%y}1#6+%w=s%WmsHbw@{UVc^?nL*GsnACaLnTbr9A>B zK)H-$tB`>jt9LSwaY+4!F1q(YO!E7@?SX3X-Ug4r($QrmJnM8m#;#LN`kE>?<{vbCZbhKOrMpux zTU=02hy${;n&ikcP8PqufhT9nJU>s;dyl;&~|Cs+o{9pCu{cRF+0{iyuH~6=tIZXVd zR~pJBC3Hf-g%Y|bhTuGyd~3-sm}kaX5=T?p$V?48h4{h2;_u{b}8s~Jar{39PnL7DsXpxcX#3zx@f9K zkkrw9s2*>)&=fLY{=xeIYVICff2Id5cc*~l7ztSsU@xuXYdV1(lLGZ5)?mXyIDf1- zA7j3P{C5s?$Y-kg60&XML*y93zrir8CNq*EMx)Kw)XA(N({9t-XAdX;rjxk`OF%4-0x?ne@LlBQMJe5+$Ir{Oj`@#qe+_-z!g5qQ2SxKQy1ex_x^Huj%u+S@EfEPP-70KeL@7@PBfadCUBt%`huTknOCj{ z;v?wZ2&wsL@-iBa(iFd)7duJTY8z-q5^HR-R9d*ex2m^A-~uCvz9B-1C$2xXL#>ow z!O<5&jhbM&@m=l_aW3F>vjJyy27gY}!9PSU3kITbrbs#Gm0gD?~Tub8ZFFK$X?pdv-%EeopaGB#$rDQHELW!8bVt`%?&>0 zrZUQ0!yP(uzVK?jWJ8^n915hO$v1SLV_&$-2y(iDIg}GDFRo!JzQF#gJoWu^UW0#? z*OC-SPMEY!LYYLJM*(Qov{#-t!3Z!CfomqgzFJld>~CTFKGcr^sUai5s-y^vI5K={ z)cmQthQuKS07e8nLfaIYQ5f}PJQqcmokx?%yzFH*`%k}RyXCt1Chfv5KAeMWbq^2MNft;@`hMyhWg50(!jdAn;Jyx4Yt)^^DVCSu?xRu^$*&&=O6#JVShU_N3?D)|$5pyP8A!f)`| z>t0k&S66T*es5(_cs>0F=twYJUrQMqYa2HQvy)d+XW&rai?m;8nW9tL9Ivp9qi2-` zOQM<}D*g`28wJ54H~1U!+)vQh)(cpuf^&8uteU$G{9BUhOL| zBX{5E1**;hlc0ZAi(r@)IK{Y*ro_UL8Ztf8n{Xnwn=s=qH;fxkK+uL zY)0pvf6-iHfX+{F8&6LzG;&d%^5g`_&GEEx0GU=cJM*}RecV-AqHSK@{TMir1jaFf&R{@?|ieOUnmb?lQxCN!GnAqcii9$ z{a!Y{Vfz)xD!m2VfPH=`bk5m6dG{LfgtA4ITT?Sckn<92rt@pG+sk>3UhTQx9ywF3 z=%B0LZN<=6-B4+UbYWxfQUOe8cmEDY3QL$;mOw&X2;q9x9qNz3J97)3^jb zdlzkDYLKm^5?3IV>t3fdWwNpq3qY;hsj=pk9;P!wVmjP|6Dw^ez7_&DH9X33$T=Q{>Nl zv*a*QMM1-2XQ)O=3n@X+RO~S`N13QM81^ZzljPJIFBh%x<~No?@z_&LAl)ap!AflS zb{yFXU(Uw(dw%NR_l7%eN2VVX;^Ln{I1G+yPQr1AY+0MapBnJ3k1>Zdrw^3aUig*! z?xQe8C0LW;EDY(qe_P!Z#Q^jP3u$Z3hQpy^w7?jI;~XTz0ju$DQNc4LUyX}+S5zh> zGkB%~XU+L?3pw&j!i|x6C+RyP+_XYNm9`rtHpqxvoCdV_MXg847oHhYJqO+{t!xxdbsw4Ugn($Cwkm^+36&goy$vkaFs zrH6F29eMPXyoBha7X^b+N*a!>VZ<&Gf3eeE+Bgz7PB-6X7 z_%2M~{sTwC^iQVjH9#fVa3IO6E4b*S%M;#WhHa^L+=DP%arD_`eW5G0<9Tk=Ci?P@ z6tJXhej{ZWF=idj32x7dp{zmQY;;D2*11&-(~wifGXLmD6C-XR=K3c>S^_+x!3OuB z%D&!EOk;V4Sq6eQcE{UEDsPMtED*;qgcJU^UwLwjE-Ww54d73fQ`9Sv%^H>juEKmxN+*aD=0Q+ZFH1_J(*$~9&JyUJ6!>(Nj zi3Z6zWC%Yz0ZjX>thi~rH+lqv<9nkI3?Ghn7@!u3Ef){G(0Pvwnxc&(YeC=Kg2-7z zr>a^@b_QClXs?Obplq@Lq-l5>W);Y^JbCYk^n8G`8PzCH^rnY5Zk-AN6|7Pn=oF(H zxE#8LkI;;}K7I^UK55Z)c=zn7OX_XVgFlEGSO}~H^y|wd7piw*b1$kA!0*X*DQ~O` z*vFvc5Jy7(fFMRq>XA8Tq`E>EF35{?(_;yAdbO8rrmrlb&LceV%;U3haVV}Koh9C| zTZnR0a(*yN^Hp9u*h+eAdn)d}vPCo3k?GCz1w>OOeme(Mbo*A7)*nEmmUt?eN_vA; z=~2}K_}BtDXJM-y5fn^v>QQo+%*FdZQFNz^j&rYhmZHgDA-TH47#Wjn_@iH4?6R{J z%+C8LYIy>{3~A@|y4kN8YZZp72F8F@dOZWp>N0-DyVb4UQd_t^`P)zsCoygL_>>x| z2Hyu7;n(4G&?wCB4YVUIVg0K!CALjRsb}&4aLS|}0t`C}orYqhFe7N~h9XQ_bIW*f zGlDCIE`&wwyFX1U>}g#P0xRRn2q9%FPRfm{-M7;}6cS(V6;kn@6!$y06lO>8AE_!O z{|W{HEAbI0eD$z9tQvWth7y>qpTKQ0$EDsJkQxAaV2+gE28Al8W%t`Pbh zPl#%_S@a^6Y;lH6BfUfZNRKwS#x_keQ`;Rjg@qj zZRwQXZd-rWngbYC}r6X)VCJ-=D54A+81%(L*8?+&r7(wOxDSNn!t(U}!;5|sjq zc5yF5$V!;%C#T+T3*AD+A({T)#p$H_<$nDd#M)KOLbd*KoW~9E19BBd-UwBX1<0h9 z8lNI&7Z_r4bx;`%5&;ky+y7PD9F^;Qk{`J@z!jJKyJ|s@lY^y!r9p^75D)_TJ6S*T zLA7AA*m}Y|5~)-`cyB+lUE9CS_`iB;MM&0fX**f;$n($fQ1_Zo=u>|n~r$HvkOUK(gv_L&@DE0b4#ya{HN)8bNQMl9hCva zi~j0v&plRsp?_zR zA}uI4n;^_Ko5`N-HCw_1BMLd#OAmmIY#ol4M^UjLL-UAat+xA+zxrFqKc@V5Zqan_ z+LoVX-Ub2mT7Dk_ z<+_3?XWBEM84@J_F}FDe-hl@}x@v-s1AR{_YD!_fMgagH6s9uyi6pW3gdhauG>+H? zi<5^{dp*5-9v`|m*ceT&`Hqv77oBQ+Da!=?dDO&9jo;=JkzrQKx^o$RqAgzL{ zjK@n)JW~lzxB>(o(21ibI}i|r3e;17zTjdEl5c`Cn-KAlR7EPp84M@!8~CywES-`mxKJ@Dsf6B18_!XMIq$Q3rTDeIgJ3X zB1)voa#V{iY^ju>*Cdg&UCbx?d3UMArPRHZauE}c@Fdk;z85OcA&Th>ZN%}=VU%3b9={Q(@M4QaeuGE(BbZ{U z?WPDG+sjJSz1OYFpdImKYHUa@ELn%n&PR9&I7B$<-c3e|{tPH*u@hs)Ci>Z@5$M?lP(#d#QIz}~()P7mt`<2PT4oHH}R&#dIx4uq943D8gVbaa2&FygrSk3*whGr~Jn zR4QnS@83UZ_BUGw;?@T zo5jA#potERcBv+dd8V$xTh)COur`TQ^^Yb&cdBcesjHlA3O8SBeKrVj!-D3+_p6%P zP@e{|^-G-C(}g+=bAuAy8)wcS{$XB?I=|r=&=TvbqeyXiuG43RR>R72Ry7d6RS;n^ zO5J-QIc@)sz_l6%Lg5zA8cgNK^GK_b-Z+M{RLYk5=O|6c%!1u6YMm3jJg{TfS*L%2 zA<*7$@wgJ(M*gyTzz8+7{iRP_e~(CCbGB}FN-#`&1ntct@`5gB-u6oUp3#QDxyF8v zOjxr}pS{5RpK1l7+l(bC)0>M;%7L?@6t}S&a zx0gP8^sXi(g2_g8+8-1~hKO;9Nn%_S%9djd*;nCLadHpVx(S0tixw2{Q}vOPCWvZg zjYc6LQ~nIZ*b0m_uN~l{&2df2*ZmBU8dv`#o+^5p>D5l%9@(Y-g%`|$%nQ|SSRm0c zLZV)45DS8d#v(z6gj&6|ay@MP23leodS8-GWIMH8_YCScX#Xr)mbuvXqSHo*)cY9g z#Ea+NvHIA)@`L+)T|f$Etx;-vrE3;Gk^O@IN@1{lpg&XzU5Eh3!w;6l=Q$k|%7nj^ z|HGu}c59-Ilzu^w<93il$cRf@C(4Cr2S!!E&7#)GgUH@py?O;Vl&joXrep=2A|3Vn zH+e$Ctmdy3B^fh%12D$nQk^j|v=>_3JAdKPt2YVusbNW&CL?M*?`K1mK*!&-9Ecp~>V1w{EK(429OT>DJAV21fG z=XP=%m+0vV4LdIi#(~XpaUY$~fQ=xA#5?V%xGRr_|5WWV=uoG_Z&{fae)`2~u{6-p zG>E>8j({w7njU-5Lai|2HhDPntQ(X@yB z9l?NGoKB5N98fWrkdN3g8ox7Vic|gfTF~jIfXkm|9Yuu-p>v3d{5&hC+ZD%mh|_=* zD5v*u(SuLxzX~owH!mJQi%Z=ALvdjyt9U6baVY<88B>{HApAJ~>`buHVGQd%KUu(d z5#{NEKk6Vy08_8*E(?hqZe2L?P2$>!0~26N(rVzB9KbF&JQOIaU{SumX!TsYzR%wB z<5EgJXDJ=1L_SNCNZcBWBNeN+Y`)B%R(wEA?}Wi@mp(jcw9&^1EMSM58?68gwnXF` zzT0_7>)ep%6hid-*DZ42eU)tFcFz7@bo=<~CrLXpNDM}tv*-B(ZF`(9^RiM9W4xC%@ZHv=>w(&~$Wta%)Z;d!{J;e@z zX1Gkw^XrHOfYHR#hAU=G`v43E$Iq}*gwqm@-mPac0HOZ0 zVtfu7>CQYS_F@n6n#CGcC5R%4{+P4m7uVlg3axX}B(_kf((>W?EhIO&rQ{iUO$16X zv{Abj3ZApUrcar7Ck}B1%RvnR%uocMlKsRxV9Qqe^Y_5C$xQW@9QdCcF%W#!zj;!xWc+0#VQ*}u&rJ7)zc+{vpw+nV?{tdd&Xs`NV zKUp|dV98WbWl*_MoyzM0xv8tTNJChwifP!9WM^GD|Mkc75$F;j$K%Y8K@7?uJjq-w zz*|>EH5jH&oTKlIzueAN2926Uo1OryC|CmkyoQZABt#FtHz)QmQvSX35o`f z<^*5XXxexj+Q-a#2h4(?_*|!5Pjph@?Na8Z>K%AAjNr3T!7RN;7c)1SqAJfHY|xAV z1f;p%lSdE8I}E4~tRH(l*rK?OZ>mB4C{3e%E-bUng2ymerg8?M$rXC!D?3O}_mka? zm*Y~JMu+_F7O4T;#nFv)?Ru6 z92r|old*4ZB$*6M40B;V&2w->#>4DEu0;#vHSgXdEzm{+VS48 z7U1tVn#AnQ3z#gP26$!dmS5&JsXsrR>~rWA}%qd{92+j zu+wYAqrJYOA%WC9nZ>BKH&;9vMSW_59z5LtzS4Q@o5vcrWjg+28#&$*8SMYP z!l5=|p@x6YnmNq>23sQ(^du5K)TB&K8t{P`@T4J5cEFL@qwtsCmn~p>>*b=37y!kB zn6x{#KjM{S9O_otGQub*K)iIjtE2NfiV~zD2x{4r)IUD(Y8%r`n;#)ujIrl8Sa+L{ z>ixGoZJ1K@;wTUbRRFgnltN_U*^EOJS zRo4Y+S`cP}e-zNtdl^S5#%oN#HLjmq$W^(Y6=5tM#RBK-M14RO7X(8Gliy3+&9fO; zXn{60%0sWh1_g1Z2r0MuGwSGUE;l4TI*M!$5dm&v9pO7@KlW@j_QboeDd1k9!7S)jIwBza-V#1)(7ht|sjY}a19sO!T z2VEW7nB0!zP=Sx17-6S$r=A)MZikCjlQHE)%_Ka|OY4+jgGOw=I3CM`3ui^=o0p7u z?xujpg#dRVZCg|{%!^DvoR*~;QBH8ia6%4pOh<#t+e_u!8gjuk_Aic=|*H24Yq~Wup1dTRQs0nlZOy+30f16;f7EYh*^*i9hTZ`h`015%{i|4 z?$7qC3&kt#(jI#<76Biz=bl=k=&qyaH>foM#zA7}N`Ji~)-f-t&tR4^do)-5t?Hz_Q+X~S2bZx{t+MEjwy3kGfbv(ij^@;=?H_^FIIu*HP_7mpV)NS{MY-Rr7&rvWo@Wd~{Lt!8|66rq`GdGu% z@<(<7bYcZKCt%_RmTpAjx=TNvdh+ZiLkMN+hT;=tC?%vQQGc7WrCPIYZwYTW`;x|N zrlEz1yf95FiloUU^(onr3A3>+96;;6aL?($@!JwiQ2hO|^i)b4pCJ7-y&a~B#J`#FO!3uBp{5GG*Cni@K85&o0q~6#LtppE&cVY z3Bv{xQ-;i}LN-60B2*1suMd=Fi%Y|7@52axZ|b=Wiwk^5eg{9X4}(q%4D5N5_Gm)` zg~VyFCwfkIKW(@@ZGAlTra6CO$RA_b*yz#){B82N7AYpQ9)sLQfhOAOMUV7$0|d$=_y&jl>va$3u-H z_+H*|UXBPLe%N2Ukwu1*)kt!$Y>(IH3`YbEt; znb1uB*{UgwG{pQnh>h@vyCE!6B~!k}NxEai#iY{$!_w54s5!6jG9%pr=S~3Km^EEA z)sCnnau+ZY)(}IK#(3jGGADw8V7#v~<&y5cF=5_Ypkrs3&7{}%(4KM7) zuSHVqo~g#1kzNwXc39%hL8atpa1Wd#V^uL=W^&E)fvGivt)B!M)?)Y#Ze&zU6O_I?1wj)*M;b*dE zqlcwgX#eVuZj2GKgBu@QB(#LHMd`qk<08i$hG1@g1;zD*#(9PHjVWl*5!;ER{Q#A9 zyQ%fu<$U?dOW=&_#~{nrq{RRyD8upRi}c-m!n)DZw9P>WGs>o1vefI}ujt_`O@l#Z z%xnOt4&e}LlM1-0*dd?|EvrAO-$fX8i{aTP^2wsmSDd!Xc9DxJB=x1}6|yM~QQPbl z0xrJcQNtWHgt*MdGmtj%x6SWYd?uGnrx4{m{6A9bYx`m z$*UAs@9?3s;@Jl19%$!3TxPlCkawEk12FADYJClt0N@O@Pxxhj+Kk(1jK~laR0*KGAc7%C4nI^v2NShTc4#?!p{0@p0T#HSIRndH;#Ts0YECtlSR}~{Uck+keoJq6iH)(Zc~C!fBe2~4(Wd> zR<4I1zMeW$<0xww(@09!l?;oDiq zk8qjS9Lxv$<5m#j(?4VLDgLz;8b$B%XO|9i7^1M;V{aGC#JT)c+L=BgCfO5k>CTlI zOlf~DzcopV29Dajzt*OcYvaUH{UJPaD$;spv%>{y8goE+bDD$~HQbON>W*~JD`;`- zZEcCPSdlCvANe z=?|+e{6AW$f(H;BND>uy1MvQ`pri>SafK5bK!YAE>0URAW9RS8#LWUHBOc&BNQ9T+ zJpg~Eky!u!9WBk)!$Z?!^3M~o_VPERYnk1NmzVYaGH;1h+;st==-;jzF~2LTn+x*k zvywHZg7~=aiJe=OhS@U>1fYGvT1+jsAaiaM;) zay2xsMKhO+FIeK?|K{G4SJOEt*eX?!>K8jpsZWW8c!X|JR#v(1+Ey5NM^TB1n|_40 z@Db2gH}PNT+3YEyqXP8U@)`E|Xat<{K5K;eK7O0yV72m|b!o43!e-!P>iW>7-9HN7 zmmc7)JX0^lPzF#>$#D~nU^3f!~Q zQWly&oZEb1847&czU;dg?=dS>z3lJkADL1innNtE(f?~OxM`%A_PBp?Lj;zDDomdg zn+lVJBnzA5DamDVIk!-AoSMv~QchAOt&5fk#G=s!$FD}9rL0yDjwDkw<9>|UUuyVm z&o7y|6Ut5WI0!G$M?NiMUy%;s3ugPKJU_+B!Z$eMFm}A**6Z8jHg)_qVmzG-uG7bj zfb6twRQ2wVgd)WY00}ux=jqy@YH4ldI*;T^2iAk+@0u`r_Fu(hmc3}!u-Pb>BDIf{ zCNDDv_Ko`U@})TZvuE=#74~E4SUh)<>8kxZ=7`E?#|c zdDKEoHxbEq;VVpkk^b&~>-y`uO~mX=X0bmP!=F1G1YiluyeEg!D*8Fq-h=NyE-2S;^F6j=QMtUzN4oPedvc*q(BCpbg~*As!D@U z3(sz|;Pe1hn08P_cDQ(klZ6 z;P`q(5_V?*kJYBBrA1^yDgJD|)X1FV_*~sO>?8Sy~I9WdK5K8bc7aeNC zDb{Fe>y3N^{mrD1+GyH{F?@9}YQ2Om3t`nt zQ(}MS8M?6Vk>B=*j*yibz6QCdR=ALgTUcKx61){O@1WkPp-v$$4}e#KgK`HG~2@#A?`BF8em`ah6+8hH-DNA2>@02WWk9(fzhL_iz|~H~qEViQ(*{ zV;3tjb<%&r!whm6B`XtWmmrMWi=#ZO&`{h9`->HVxQ)^_oOS{W z!BzVRjdx5@pCXl#87ovlp<^QU;s<*d$)+|vI;Ai(!8Tjll^mi6!o~CpnlgZAK>6=V zm38^kT`D$_$v@UYeFyVhnsMZI1m`E&8<{V07>bBEI1=fg3cji*N?7pBzuamD`X|^^ zm!)2v?s|6T&H-_^y`KM&$!0!9tai9x&)5<(&sY6B`3D{$$KMAX3@&`SW;X0 zB-}obt^I;|#o_bR>eOv?P>=UC6CGTXIM+lSu?Uy+R9~O;q|c2+FafBP;E)B5M9HJgRIpF|GvRi*E+JTBI~T?T*X}r) zefUd*(+3n_YHZZS(g8)+7=pNV9QR^>Qs8t+iEpbJS!9;wio&9rn=19C0G#Ax zM-tWHp_YlJvXWsUqJUr^`OYFA4wkgL`cSOV;w4?tp>GT1jq}-qPoN zp&G}*;+#+Zh&vqDOp>gRL#^O7;s2yWqs+U4_+R4`{l9rEt-ud(kZ*JZm#0M{4K(OH zb<7kgkgbakPE=G&!#cNkvSgpU{KLkc6)dNU$}BQelv+t+gemD5;)F-0(%cjYUFcm{ zxaUt??ycI({X5Gkk@KIR$WCqy4!wkeO_j)?O7=lFL@zJDfz zrJJRDePaPzCAB)hPOL%05T5D*hq|L5-GG&s5sB97pCT23toUrTxRB{!lejfX_xg(y z;VQ+X91I;EUOB;=mTkswkW0~F$ zS%M}ATlKkIg??F?I|%gdYBhU(h$LqkhE!Xx$7kPS{2U4wLujF_4O+d8^ej{ zgSo(;vA)|(KT8R_n_aQ$YqDQaI9Stqi7u=+l~~*u^3-WsfA$=w=VX6H%gf!6X|O#X z*U6Wg#naq%yrf&|`*$O!?cS94GD zk}Gx%{UU!kx|HFb+{f(RA2h+t#A!32`fxL}QlXUM{QF3m&{=7+hz@aXMq*FirZk?W zoQ~ZCOx>S?o>3`+tC&N0x4R`%m)%O$b@BkW;6zE+aBzeYi47~78w$d~uypaV*p$kQ zJf34Q+pp~vg6)yeTT&qWbnR2|SifwK2gA7fzy#W(DyM^bdCjnee42Ws>5mM9W6_`j zC(|n5Fa&=MT$$@?p~)!IlLezYa}=Uw21^Fz-I#?_AOk(7Ttxm;#>RDD_9EloqhvrS z&7fpbd$q_e21Al+bcz|o{(^p}AG>jX0B}ZZRfzk$WLbNLC{y|lZ|&a(=bOE6Mxum{ zM=Nd+-I2A-N&2giWM2oAH`O&QecJn6%uYl0GWlpx&2*)BIfl3h&2E(>#ODt4oG}Dq z__73?sw2-TOWq@d&gmYKdh`a}-_6YQ5```}bEBEmWLj))O z?*eUM4tw0Cwrr+4Ml^9JkKW9e4|_^oal0*sS-u_Xovjo8RJ18x_m7v!j$eR@-{2(Y z?&K4ZR8^T{MGHL#C(+ZAs6&k}r07Xqo1WzaMLo9V;I<9a6jx2wH2qeU?kv25MJxoj zJKzX`Un|;_e&KY%R2jU~<5lm-`$EjIJLDP~11_5?&W#t3I{~+0Ze++pOh2B4c1Mde zSgj$ODQQm7gk&w{wwfE1_@V(g!C=2Hd%Gwj{{-_K4S|nZu+vk}@k(?&13iccsLkQo z_t8#Ah$HVB-MRyzpab*OHOp zl`$tEcUcF9_=3*qh8KTaW$znGztA7Obzb`QW5IQN+8XC=l%+$FVgZ|*XCU?G4w)}! zmEY+2!(!%R5;h`>W(ACqB|7`GTSp4{d)eEC8O)Mhsr$dQG}WVBk$aN1->sTSV7E)K zBqr;^#^bZJJX4E_{9gdPo8e?Ry>ZrE&qM)zF5z20DP0`)IIm_!vm&s2mzl z2;EPI{HgFH-Mp&fIL^6f74>19^>o^AOj`uyL0+Nb##Slvi9K4LQSs>f+$j?cn9Z__C zAkyZ9C;#uRi3cDYoTA>AT<|*pt{K70oZKG*S1F$r?KE=$4~W3!u53yUvh~(kMrClS zXC?Dmgv4iS`>~wBPJJFL_C8x2tEg*PCDX2=rHQ@z+Zs)Kkr;FYG`GnbUXqdipzvHE z1aZ>G6|e`}Q#)Kru0)(SZnUCN#dN2H zd1}r&xGsaAeEed9#?|0HzMGA7pl2=aehy_zsRV8RKV6+^I8woDd%4J8v9hs$x{ zl*V61wSumovRVWtetd1eJ%i^#z`_~~^B;aeuD`6LgHL66F0b^G5@om^&_3REtGmhz z%j^9{U`BH7-~P_>c_yu9sE+kk)|2`C)-ygYhR?g~gH`OK@JFAGg0O)ng-JzSZMjw< z2f&vA7@qAhrVyoz64A!JaTVa>jb5=I0cbRuTv;gMF@4bX3DVV#!VWZEo>PWHeMQtU!!7ptMzb{H ze`E4ZG!rr4A8>j2AK(A0Vh6mNY0|*1BbLhs4?>jmi6fRaQwed-Z?0d=eT@Hg zLS(%af5#q%h@txY2KaYmJBu>}ZESUv-G02~cJ-(ADz6u8rLVECbAR7+KV~a!DI83H zd!Z(Ekz%vjA-|%4-YpgfymMzxm_RjZg%ruo zT4^x)f*%Ufvg_n`&55cK;~QChP6~Fy_Z67HA`UtdW)@$Xk-2+|opk6A@y0~3Qb;V% z%+B@ArKl|Q^DJW&xuBZD#~SurH7XXf*uE0@|ccNd&MA%Ts*1 zg7TU!xY}~*AOY+tAnFR(Fu)e@^9V!Rm65$;G$-?6e%7w7p9WT098%-R?u#J+zLot@ z4H7R>G8;q~_^uxC_Z=-548YRA`r`CsPDL!^$v0Yy<^M=Jryxz5ZVR_<+qP}nwrxzi z-)Y;nZQHhO+db{>IrD$#DkHP%swyKhV(qn`H9~3h0Bd33H*DAP0S!ypZqPF^1^tZJ z{z;HN?$WJ5{0jQNzYOc|KbJ(Pr42~YhW5ohNdY*rEk=({8q+F}hy)&ziN(@q1;>jL zBN<9(k1N!p2D%uHF0NxFut`XwEMc@ZH-|95>U)PY@}C=bmV_*dakL}J5DUpNZi-y& z+{i0>H@c-g|DBO)HJ>7$VVtn)z3X}H`FuN-t>gcqLas?Lk@MJb5?u@BTn0Q}E(}S~ zXrNX`ysRv*iOn1v@fBDeSDvvR>+;o>kj ztRqEZOWN!fqp(`XQ3ppvC)c{AeyS6b_8pN1M*~0=$U;P31!~Px`Obrz;GNs(8RrJvONy<{Dk1x0z zJJzhQBt{J@&DP6cHugB!q?xi~O`yJYHUsTI zmgulx%I<*?vPSl(!tj;LL$K*k zH(*d31iyB9aYAzw49W&qDi0>f;b5kA31nz(%2W`QFJqaX0&hM`KP1gfdRw?7@}$XB z!^cUI%C!?X!QVQxbqEFSbuP0>_3MTCof6!e4LMAfGRd0;Lt+w0WK@b4EkGHRqX!h{ zrYxwwH&-fM67X7zP&Qpup&vAOaKH|S*pcbI{ksFg@tfw)paaK)5khkys0GSTnAtfC z{mVJkCXt|G-SYwt0O4dM8Hf{L*&^nOeQ271ECyc5Y&z5R0%hCq6~} z$XW$kcz!nnCTAl}NyB0#ikwyg_M};inG%*x38`EYJ%FXdj&A`g)-wJ(R=C`O^r{W` z8$1r{G0X4g`uD+}vw4`H5!*B8TTsmeaYGk3x0{&aar7ocO6?dlGbyV480<#{%^93y zF(ei<%{OYi?n?L9#HL_R-00#zRzbbwVnJ0zt}4f|KNBkT6&=Kb=$E(@aC03vU~p)7$XA@ zq5*`*4Y&u*=Ju>+x}q&Xxsjn;Dd)6Otudner9zi z<*LpeG}*vJ58#P4|qXF-ul1|u*;=-@oGPtmBnQW6VY9(s`5GMsO@!;s_PKo_? z3HbGokZ|vaAA-guf5W0JDwpV}1u8;7XJ=wD;NgcLIJW8S5w!c%O*zU0%~)0M)`!Al-+OFsmPW1zniB%fqF;klqxz`Y z2@srWa3e?B3ot|nhE|Q7VIjr+$D7F^n?wm5g8w?Ro0i72K3u^g)&&F^9~@eHd33YY z9LR!!orc0vq$sd~eR~hW{4?R3Di;~mz{^G1X?#-!|Cli(#0-sm|GHYpcab`ZA=zi3 z5*m>sJyOij{!PgIJa?A0%wL*Ur1fLJdJW$a>&Xj5p_IO=SwyTp@nn&@6L4vIfT79aPyo{LQ4DhIz1 z5g*+hII!(cLGHc5ROH&^^o=02r*x>MxMPx{JFMmNvzJ?AI8p!u_H8L1a`{6~bF@L* zxszth=`>%Vi`=E{jJKd-+6pf^vo93EzqFfTcr)A&V{rERu__UAQVyE1imol78AFmB z7T;pNFxW^M+O3#;Tz^e*`AqsD?M*wPT6pnBFPA^kOTnZYHr@O(JUQ^#6bD&CC*?HG zRAKSXYv9DU)L{V(wM=te@V@Db3}97Sn9r2nroOz06!qV=)+%EKB^MR_K}p$zM5OD1 zzhYv+?%A`7dBrU(#&1hXF;7lzH`nENZKP2I{qp^NxBA8~N>?1H@uZ~Do{d+|KYx9I z_z)J7O(;xu0%0n3o4y7LnJKRPK?RV@_v_YLogYPH;}`>cZmDVyO#%-IMQVq6z9r>@ z?*AQC$=?|aqrY8xGx%vfk0ZeByTz18IrP0XTVlJyRx5!NALYPyjcn|)U5jl^<)_KZ z2C?1|dkBZ;h8e#)3gUPfdf80xu^8evspE%Xf~x zs%phX&YuB{y}>%PuOG>s&EW}5Y0`dyseV)!C|`1(U{Nd4c4>07ZFmdTJS2T3+dEw8 zK%f_x!O?H8+_Qd>$DsYNY!?tC^H;N+!fQS{!4-9c^;uXx)D3|joo_FlBTTdDM4nx{ zPve})D_u{PG>&^G=>$2N-dZ!eMx?9X7FmPNo)7|>Z|A-mNZ0{+884L6=f-{Q4bN3y zAWL{oJIh(js2$bDTaV&bh4Fn=4^M?@N~+$IXxytdnI4{RkYA$8j(}sb2TO$~49JHz z0$K$WB@axSqKsyG>m7&3IVR+?xXLfs7ytuJHH8{`ewhkH;?H7#an)*hPiBLi22jAI z{|tZ;dU=nDUVyfIurEm0VoB6kiaK#ju6RV?{3qaV`NQ4&$)fc4AAVKiXu_1$86nxh zX)Mif*|y>N;S~7UCXQhs3-%nqNuTu>=8wqtp$-#tC?bwc-{&k&0>0nRBku-b5X931zqll&%fn$1$->@El+EIA;L zfEYJY)kaTI%H z{A%hpZ?Xt=;#(++B0e)B>4_a3E7h#8upWz!G;VQBX0rjzKvy9N2LECS2@wrBoS;4G z1PgI50DD!wtwsZ&JoAGuum9s&+0NI&_n}!kUTvpD{tyG9jlSXyQ)m9H8VXoDY$j!w zo;imjJKl;E5u|n4Q?HQsy`*&=VY`SG+YFUqG*+;A9(wKfm_|6^SWh_6>1u63)H3zEGm5Uk)#z>J0XC1L+&pzieqnAo+7zlr$M4kl;-h zjo^h7U5Y3tbY@(_{#h1et^{nbOP9Nw*tJOD;WejSG-4d{(2X$tDM@-rK8SbUqMe}%IPqxOV}m#%mq0)auvNwT2R9)$1-o(2o zpIS;qwy8m^tEBC99O}bYKd7ALbB~$d<=eGd>WML+U0aAl>{Uc8CB|oVWMt zbPe9+6&V{l2Th1)Jx`K64?gUC_<>x#Wk*SOSA<&A=j2q zo_M`Lznpsg1h-W546hm(q@Rf=xL@w5QJ;HxIp?O`;sOMovgc4n%D5`kiDO6%Rhe2^ zzPa=8pd(2&HN-=5JzsiJ^(ZlLVpZD^5!$(rt0PVLQCzh7s#6_N1dRKtQv_vTgSQT5 z63+e@K`67zjbb@QdwMNF8G29tcxAl36SZAGxolCj9aS%>(Tl*6a0eW@3j4!&d!12v z%+~Xc=>VJqBcW!D#JX3#yk4O^;#|O3!ol;J%t8>wc!*6`+`~%?-QE_M{wa&vg14R~ z(M1VT-&l-M(N1>3pNjVfvCIk}d|H4&*7{*8!W-;^tFgD31O%~NtUaK_*-m7CSEt}T zm^Z02X#cQ$Mcw}TG{>1I`vmvNoxujnPra4aSwP55x37=0VvyV<)68QB-b$o-h7p*V z#QQ8?A7`=m`*+dTfYdm=;i1ptR|In}rUF^r&{bKbI@5DT$JEo;?-N}Z13}n16v?G2 z{?@ny^7|!rg(on8b97#GupiPA<(g=o;@P`4 zEx06)SiGKkIKFHzK1M`ctf?vQV#b-{ws=+0U^*LYoTK*pu;A#NB$$I=Tv{LLVQin~ z@aGTp?J<(c_1M!Jr8MK;XA8fcB+*DkFF@oAhQ=B1o*$<@;ZdGs_5O!BKi8XjF2L4n zA&(?SaRDWm+p0UTFXj1prs!*v$(q+s=8S1h(*H8pd5*8%HGN0mgw3yvfsxr4QYT)o zzdjal^6zA56|Z@csYH^3Qr2~ZR#p|Huuh0Yt|$~>oQZJDF75aeH%UlQv)fQ=3P{i1 zRt99gL`$b61Q`pdos?W6yd&%2IWK#}$wWOa9wJW&($J4h0M|9sFtQu9k)ZtYEQ#vu zS+uD(3`7T~t?I;f%z8N~nG&FVwxGXrTL!k9s#LB}FSo;a+V-j}H^myGwQq@jTIycD zP5A{w+a;^kOQW^C%9W{j^&o@)3!v~U(?wx42E5G*bd82&a1p6ax|pk)#8nG9risCw zOERH8;tq?Q4ymxf*9_aF-sTpLvETwD#sB#ID1D+WohEt0s557Ij5)ldexY+diQJ*l ziBo;1v*vx(F|lI8udAo450QIQTmPqf(7oULr5*0dE9i>i#D&k%WyfM*4{*?_%9k>g zg1_1%x?#`Xm7M@YZ?!zJs$AxS&8sBLI@c|-vSiG<*OZyw>CL*p6#N~p z#VywqpWdZ;{ylc5d7W8E7Jx_H+5e#N$h#{ni@#TlGqz`yah-qCC_;P8?N*>CPJ03b ze(YVDvbIR$#lJEkuf}L7F8q$fKCWz&>{uFg9JgTOmA*Rux-{|#+pO`!s!!4;PlE%9ys+;|)oK%&V$*FH!G2%|y(zz>X zUwdXer0HIIJkelANg_W!ofsyiN{zi2=}G1UL{`V81}1D1Sz zviLV^w-$RE9fE4@H+ys>u;OY!sgqe&V-oFE9Fn$P9HbpOI{}esLIvc zV5S-9(XjFzn1qzo2owwg_d%7_)cR*!d&%@S&D($cFFMXXd!GdUxw5tZ_W@zRbjVfU zzx13(Hc!$teqA2WOYo^+SHpRz16DOcYqaXHSMZl2Ax$)f^WC??al8lfX9)O_p9#Ml}LB(N8yJ! zj&_UD9K54Rt#yqvhklEMZ3bRC&)(^h`#kzq-#_QN?J6eLT$ zMWG-mP;HkB@5;2*lAP&1*4C)HWEs{gtp15Y%y|*%(3UOMu*v4kTi0@pWvg2Y%7yI* z%XNlZa$@AZ(Z#Elv`5MUei~VFCjF8El)@g&>(v;E; z;laavf&ANfk9*0LA@oP4QmbCBF-lB^Mj~wo)eGG57gqAKC>Hd80Eb+7b;iJzV5RsL z8>ddQH8PnC;l{M(t4c$M=q78GW6=*d#c`-jK$q#-{9c)UNO4eLm9c!DWcCth4O-FU zboSKPhL-lq3q<)m8Xw7+l=Z)H=rGgMI0H?KrPjc;iDzY5g|Ve$8?SE`8*sb1u*>dm zD~f9~j2H~6Oo2`_1 zq@_mmUbFQV25E7XJ)zBRQktT12@qHHy-@aCdAFWv4iZVN0B3}E;k(jg>X|eqOrqgM z4yBUuA*BHdnN9v;5>3#L$NFREyHW&Q*rWYa_q zhC~>M&bMFgXC6AeQ`P-s<}Ot_x^cb51r7ArPbRRs&Dd_TEeugnjR(O#V5i6OYjzRF zw1@Rvo;_wEfQA@P%I^9ljrhxxuqf9g^cWSKq~+kiVxa`&EBDqmB=C1G+XB7`TQeiV zR_k?`$&W&+ntIPeEtM9hqcj|yfW>x7&1Ht1@;!d#Wo%1hO+^Q{E?VD|`-OvV9G?tp;6{sI%L-u)Hw z;|`uN6~VqZ!g~K#B@W7?wDcbO?XS4hnW9kS1Hbi=U_m*~7`N~3oK;qFTX$$LQ#CkL z6I?a(HkF8SKJU8mT{K35ekfP3`05!M{gmrV0E-=IyqP=N;K<&jOnPcjdXrbk$%)z9cUe|#I0unK5^+qGx8#2 zz_!bmzVG*Uat*&f4P>&sV2RswlITV}wPz?_;(S;19}e}54fP|K5l_c2kU5(-Zh!7t zz=B2HktD~ap{s%*CDEl?x6o+91T-xH895-S1}M=*KhFM7Nm&1$OB++Robv0T`OBcJ zXNX%Xio0_ryjr)!Osc7au35UM`B}Ru4zN_o+C!+s&e7|}Zc;5?whP$@J@DE`>w-XH zlVmbrI4|-Z^2^I^EzuYKD+JA@8lx%>aLFZq7KT1~lAu}8cj$<-JJ4ljkcSA;{PNr)d-6P5Z!6Q=t!t*8%X)a|;_92=XXN=WMV))*gWR-wHzU(G6FPTfSjd9) zm8e1mfj4qFmlXO*a3};$&jgc$nfG>NR&iao(jYk`%E75h=K~dJ{Jqs%UH|aGHL8)-1MOyS2B?OJsyeA_YbGMDpE+>=NFcyoI;N z>1>3G4QR2~EP{L{x2e@E1U0jGGV5H$aeigDq&Dr zQ3FwJ+& zndX7VK+XD)t06uUY=)Cfo!ke%uDpOmq^bpEB`iv6(CKTGgEZUi4ddfNXJi_z4;)ob z?R+qj2SYX*zi8z=DXChEEDW+Cy>w-0agE|A7MoRJ4}-(|go-rP#sr%a(5k%wV z&Jllj+6XuSoIfZX9|mK!bbd)7TuaHBvoa(`9C$*XUh}hH1;Q7cTJQR)c>h}Hfr$aS z64c7#D^f{mN3s#2=SEf1$(*Vj{vZjF6Qc{a=VbTske7L^EY&A1I1sgXaYSH7(lF1V zZ<7`Rq33WZuu`!HK$wRr1=uE}#&JMftnZ&(P17gWF;>$TA&$ZQnIz>blTrW@49Z&H9yhgLBpFw(57K1dbIQW4fn1X(IiFWEKmPzV8gAa|ak)HAsmcQ7stP|q0hEzBNL=4YdXEkyfS zF+K+CVB#~(qd7eeZqR-VKIYJVmK2ePk``4I^PfQ*C7NUR z`w9lb?iHv2$4_p-+a+O}Fq6SnPiz>aV!~d=l3VdgDuwAPMR9eR`)b_`lg~{oX0lf1(zbBrnj4+-q zOl^#`)XKn=`()B-jExviKVTYrAKa27KAg3cboG+}D6*R;<`GC-b?i=e;aV7n(}XDS zK5xAEV=T^r#eThV+3C<^H>SuvAP&fw;Yn67eY%4=Y(p$~!`~h12 zQHM|f0#pQP_s$Q+TtMMvBdjQbLWw9cW?gl_+P z)2T94UJaYG2!yXITYjYl-@#5_47g{N|5=P~m|e}-F)*^L+{7O$#wv2e##5Y=A{>jN z6NhQSor9ulwP3gfxTF?V`P7AJ#E)ij$I`gc2fnmp&9w6qS2-Ct}6 z$#O%mKtP>I2VUBMt^Xm3LjP*D=xEyV?|8Psb91ZEj=gM(C3^Kcfvbx*$NK+MhP>W;OneZ{Q>eFEmxv}%ZCJ32=zr_OZd>6~v@ z6+3JzX%9qOvKS393r&R9O+te&#?{Q9nLkOV-eLg9!{WK}WyUWLZ7bQ5u26*u9c*T1 z_s1)j1k5&b8&5@YnmtS{tsmQaLW2%8D*8G-9w#PcVQh6sQY`!tBpU=8EZR!zfB{f{ za<+Err#ZNM4JEx5n9!zuC#KmeI*%tRXP}jpswzymT7J{YpXdzA{J7K)j1tBF8B3DL zZXkec{`rT_{__t_`!E7veO1rg1tFzVeUTBjut*3ZOq}A$r%sWXn4v4|rA+7uMvy9n zL~2WHKLg$BeD2Wq%?frTUM^c}?K?3#L+Q2-?PR+e1Fn-XUThl8^}8JOyDZz-wcFh5 zYJCJ%J_Pf~bX(0A?Z4hGw(mY?J$j#Vo&@9O>in*f)*`H6&(Z-5xx5}$V@dR)-lxgN z=DMA_EJO4+^w_+D7N>4=%{6AbvpDG<(b)xE5Ezo~oEg~cEM?mwyY?3ZtFE;RyDS`u z(^sa_s%B<)vktqh=1|?Uv6DXsA`D^B9%_mXqx1C=a#KurOE?49)P_ixiHAA)D)oqEjQ6_v0UC9mTtMu&kf8&7uRiiigPD{$Cf(&DuOj0 zr*5{zPyO@Kq(|Ttu@wxKanV=^OPOjh-_$MbNz})ou6*9nq_XQo86WJ@JN~-b=Ln_8>Nz_ZS#QpRGt+bzH*-;{#x7PFqie+ z7p5e})fcDq)J2z=z~%nrFGFjbVu~0ICDHW3=HgtCW)?Z(%Cx$z!QuszcOCe&3!Al2 z`793RnB{Jj4QpQ2N#oKT>aY~aNxz_6B2&vPdJadbC4qp#H^<@o50}m>7WR?NO0$ZI z9OKTM+jxMFWX9mi7(@j)1Ji6~?HLU!KT0Y5a^-?|XH^B?R@T zn&a_U_XFAsGrNX@S~g1<=uz@~dCcZO=1??VC@PML{g}lbuN?j|_1S=dJgbT~o}}hs zP_uYZ&0+mWY1fupe(+6nn6<9-)Xluk97yX-!!lqSXq~!kL-=+4$Dy>O$sKO7M^1QY zhZGZfiNQu+?sef?E>5sqj$kHmf;kMv<>Gu)!^4!#7T009vBzq(m2aoHu#+93HBq7T z;Fs8IHvUlmxCB2hkDbm&xwFQcXUD_&sdeu|EYhFpf7v5_LCcVua9aunVe)qoGmyg# zIGlj&IrLKg=id@t7s916d&Gf(%X7^FFR9^bz-;*o1~Sa=`cKfJ0i}X+pBKN=?}!dP zg`ZMtP6xSuvHb=5HYH%ELaGxwqH{ zpY>Ic^}J!OwM!VmNM!$nUg$qN9DLtKuBvn1(x-P+tA*UHoOc727>5?^J;JFo_ac@) zU57%w^U2ME z@z^ZsB!AhyOscE8;~Ft$)NL)GcLteq4d32fw??L0QuWt_M9IJMgZ71Jm%2khx|QN+ zkm4zQ@OjyM+l=Rv(!k?%cYwnf7HWs^M+P^zo5o?7;E)V0v*zf}(;?ms0oUK)wKmZY)mSTGN4X@2=ZU!Gy73M(ftmHJHLFKQDcu`d% zeqiW{G`?}AtEP zKCnHuWzXZ_Hc>{cP@h~M$#q}kG{52%zmhATR3AbNGR~*6(%^Gs@UZ3i%7%PJ1mB^S zcdcrFDbD6lEJGZ4k6JT;eB_JbgIkkOqkz0I{q`d^kWl6a!%w4V?Y!;8%uU(-UA4Ti z{pv2+5CN^ba{ALpu1&qm`sMP@_L=-a)@-zC1*`f)uV5MU$xJj51%?S^ zoo@;kqY@4Zw0B!+hIvTT8KK*~9H@u54r>s{MX_|#z`Z$55bDJo#=hz~k)7CTbf>Gn z=!u;@JViT~(>P7UDdIOL;6kPDzOZNl16jLo5tHS4a%~T&AlicnCwZ5pZ;+WIB3tJE zv|J^!X0Kb|8njISx#zoB(Pv#!6=D}Uq(6Dg*ll##3kfDxdHdBXN*8dZOM0I{eLTO4 z=L}zF35GJX4Wee`#h=aCB+ZV0xcaZiLCH3bOFYTmEn0qf?uC#lOPC7>+nVeO1KQ@S zcZ5Z0gfk8hH03QrC@NnEKNi15bWP;FEKsGi0iUHN4L&2_auv%tIM}UFfgRyp5HWt()pn#0P9+xF2H!8zMqf`WJ*9YB zq~m+%xLtVjza4>CO4*%thB2k;Gv1Ani%8)IP6Pm^BAigXgOUHWcQDEgB??AtdsOx5 z+pXKfU4>+8ViRUJ;h()e88jRLEzSN7%O|=MovCW3@VxK@Z*xS$WLG=u_Nenb0wP@Y z6zs##uQ7oFvcSdh5?6kZ!%8l$Xuz^Rc!lv4q?e$mv(=#@x)s_VFF50vGuE_Nr{4zXB>y?7FOMC5^sBZr`mS*t_@%LYN9wl z+lsqD#V5JR63GEr9^&9*f)kFs zJ-A(>>!h~d0%9*wd+AY+&oryzurfV{QP{&-AtDs}#iq;dal?A9jE;huq2gExb3z+- zVQB@UHlVfsy1$)dF`dcZuc(GLnim09jrI9nJ6<#=03FVrkuINg2`RTPloS^^@KYD6 z1-C-Oj2OI0y9Tdx>=dNHhOYVvx!J#4EMhold-PGClLuLA~k2VDl6cPuV4lI5c(w9@7sllth~H@)0+v~XYqqC6&*fSX~S4Bii^0& z=M)D(5FoZsKxB&M$J_7lbS>$kF=@B|Z$#D|LHJQIr$aO51ta6s96Ug*Jk;|>9Yd$! zoF2W+)lFzY)J<>U$PHwbe9>BKLAeo~e%=Qy#qhvK&`)b2 z(U9#8bba`eGr9tr$SvM4`y`lLavOzPm`l<%-(R<1urb(AX0RE=R=#&QI)klkwrJ5%D5YHZ!~s zGwK?zKZeX|uO*Y|xLjO#6uzO%iXWsSE8#zLOWc! z&2L8sdT;bhUW495)_fGCcOLM-@DfGcb1xjf(ezYJxYOv<7YE$lBCrkbfBA{`I(GH- z(yHy1h=bg~fE$aIbB_3l`|p$R_p0b(+aL(~b<-Am9H@?s!T2*7{+*Vj?pCpV5&WJO z*GbW%PLj|(hbd!fQK5Y-kgDHV!-I$y6G>Y|&uo9+79v}}$s=l$>#F-_F{TjUn~-!M zBN>n)@(LkzI0Sg?f1s}uBZi`wRB}ywU7wqq-PwaS%3nitaXb{&Q=x!xvOPfiQmmkd zWpe2@y7?wbI;hF|hlqf@x+3@a4$wLdJ1PZBoRc9oRGgdM+vm*;5XBZcMZ+@4_{aPUS|`NsD4YP2JUM zZEvA&!QLB$K*%gHy~y-RVs-C zkN^usP)S1pZXjj)nugy#?&vpiE^DS|QlhiBOc?nC$9CK}Ze)ihI{p-m$pgYV^5L~B zQTU>)x*fvKCNK*9j$@Gyt@@I2LF8c7YvDJDCf%1h0zVyNg7E~R$`6JE1EQk~-c1xG zE@xT)TesWHs}ny!5_7F_AyGL9K?Q~mP?>Vs!(oWZR42kf?*iTV*h5>tnzpljZL8IR zb7}l8q%Ckfh{^e3k^3pQMk=gLu60`Ja8HdkzVbeAU*exs*ajmRVp}O}l)TqX!?G7e z{4-~g?Gq%~)IJJ7p1k*WSnL3jqECe1OU}5nirS66_-$3FzMT5t3X zg{jgP^5?%zb(vMa!S|1cOYk4W!vG2KKd{YFIbPCk3_74HL`fWJASs{fxpzY@$(}Q- zK5I4TKS~`mfiDoDOm;XycF6mi|K|+d=lh=@U?9_V)BDDaZAnEw43`Ls1677I-+uFi zG?^$Fbc*pPun65{D!fH=3Oyp$WZAY!{JhzaUtIgYCWXf@)AkTa@x4xGjp0c zs7@JB012~&;z=SMbCp8d=Ga{l0(iwx<@o(f!OwmyH-gBN6wewq7A_h)oKg)koFPft zNfdie%F63S?rGDQR(N=bPuK>G0t^ax$0P8`N_cvR8rOf(O9T7$9#5!B;#!XUpLZXu z5C(OESAmE*2+hV}!bg$4K%`cQHBk!>##tW>1RbC%am`*|5IbvoLh!BqpAi2OmdXqf zHp%|!N;d!LN_26809n^14YVJJBe7aL87U~>HZ)VK%d|rZp(~zwNH#VGuX!vfal&Vv z-c)h33DOB@xl*~m5ZZ22sVRK>8I9+)QMVtsAB>r~SMkGMZaQ;Xi|?~Xxnmx;cYwYx z^nNxRxGcq7I!sO#b%$!0vQ(OqXm6T4mTilvMlYj|*i|=MK%kT2df;bZGW@NrgeX>( zf7eBsjJv}pNuEuHPEs42>}a`ut-O9lZDNh)_CsBpeHKvPKnpcWh^bC2QtnB5a4qy) zSrZhafuAkk5{yiM|zdiecKh zuc2R;6^;@i07fmepeofAJdX*knDzBA{3tyVYu6z#z;Lsi&x_bzzLEpfXtH*NrY_G`= z^X!;eI#hV*mmjjEOlo{TxQwSdUv0P$!Qvijpv9plBI@FUU#RJ)8Vn1ZGA$ATqF&s= zvcTS>Z8pepd>k=sjPY^3fpCB@aW8$Oq%fW;R?GpYoT@ki@N#2LxgTk1dYZHNrk@lx z7=yYr0FT$I>z~I0nXpPp$t3)}D?2^<@KWH#E{irFy2`)5r{AyvWHYzn`5@h;GVj0@ zJ@1fbD9gX=vQNR7PG5i}jFE}9#!;ote)FHdW?VVe6v4dWEz(R?!HC4KeVde*DGr=F zRotamm=!I~=_{|m;mCI4#5{C3_gBXan1<>!K!8O|)&K?O_L`}=uKCJ-s&+!XTk?wi z%Bwa_&k>4}`a` zFCG!c^Cdj#Bc2z2PXBCW$G)<%9X6;oZiigwvMLXQ$0f+2bKDCKCGR*cG>+;UTQ2bj z(2r#Od&Ulv*{?U~hq`j8W&8aggxHo<6*$&cDG#k;GS?mLx0^7mda35tz zHTnFA6vB^rczV1Ai8I&XyJX?jiEcQ}n;PYCl~EUPIxF@V%#c7LW`44<>ezAiG>1ff zeOSeCd#PW2z5z+<4Y?Qc#tb&+uH++5^G@!BaaDeVN8x=3ZB{R=Z5e+zf&13+nz{l% z{{#>B^OaIK}1Xh z;}?)W)sfwuf~?Ov1!oiQ-@WVG>D#(JL4Ob-h*l`y&hBY*!EkULKFdt9+VGJ?E=r85 zl*~dE)e4&l8Fdq`I@T2BAme(u7_)}y$TNu^lWWK-M8UQ(ZuBcA(qHG3; z&7bO_w9Cp!REZ3VB`&kfYOCmrNQxu7pbLoFkf)9Jkas&36ZnTBL?~cDug+T3bw?o! z$U-GUnOTkujjaB8vxcenWsZ4UrH*vMmACDj!95aG?gE5-g<6v8X9%kXThF|rP(0eu za*9aK6%^Qu4oyr(1t4hqmPX~~L7tB(;C{DH&MWDzUG+6I(;TGeM)jR#hK~O13LRwk zRc2;#m|qsRADyxC<6XC8u+lvVXoH+-HNTQXImy0_oM&D=ngI3OP?c>&k8&P2iV%hg zq{#n%P=0$dYJ2o$clJWqpVH&Q;S5Hv`T0-)mU2aa$XL#RH`0~|_g zmmfHkP7#d=iuiU1lL&5T+egS~-01WrWiiA=({_yWBnY@x5eX}`?y?3Xdic;`1dn5T zxTwLw{;Qt1MSWowZ}r+U?8Q+R46Avz>o>^}4zhvZaa_*Jd(2A!dP8ah=_*lh!W#a~ zNUm{^sD#HbDq!m*EK}(GzVn4N2GeNpEp8Z<_tctC_id9X=Irqhb_{b^H;~}qwZI&F z3t^MPXp4BuDv9@1Kr3*u zZ|&i`IKW!_Rv5(CaTJBndmX9B{YL8HJ2}u)`_>#J_-m{T-xpj%|2|{xmnVF#+X3=* zY*5{hDkk6M{+!Ved>d}mD@q^#{3qo9ZYb-+75cj*gH%I+d=}E+qSCK>vj4p z81UxB7>Gz}5QU^Pv-AJ*EHMW3g`EwB^^}ps>1E2$#r*H_{O{u)J@@1m$?Pu=va`3n z?so1N_WbU8U+4Nb|AN$Gv|%%33+!xpvv3iSLv&=qIUrD|3^*|rn7cNTWHgpaH0mTS zbXS-J>ZVOG~>BOwxVSa1sk6ivguYJD`$YgKkB!awl#vZ1NenaIidf zIo;H>3%L>R^l(kGI`c9&1a9H-s~68yw>3t6~N-Bv<9hyv4@0XlT|13}n_wh4#^(`bgWSiUFD z?SO{pz~eEqAvU|UZ-MPN$ZoAzAm@B5l}5B&MB(X&#FQ{BiwixOTe9@pn>F;%(9zOZ zly7ELHP0wS+Ikfr4P>I383O6E%8Ps6HYh5VLs3+bL1$J`TkTm6$wnI&{gh;r(^g9_ zB1RO-zhYoFDSl^oIQ*3Sm`H4%TTjHtuLbN&=j+P%iuVlxfEi zjsZUV9XdHY8m9muB8q5Vz z(`L%J6y+JTwbc>-nW(k@1!b!V8X7{S8M4^jErN(9CY}WtZ%l(hygPSA0+WuRy2zYP z{I1rh;dEB2eq9TUxCz{Gyr5B`eQAc=V{W%c+@W5W-mHRf!`2j21`y@SR^7Oz6_2Pt zkOomwUO=FaWS0^zE_8fOUJ%bwuxpLG@_{*8@bC&b7t2Op`l< z@kNX+GMUc*Zm2{Mv|>~c3<+pti9iF4V#K8sFm1soxJDi@ z0hJgP6;T1hrbc}rAns8Ko;#S9v5&XknRCva_O>&b{J*(Da_#Ad?20`5$%Xl&Puge2 zx?l9eH%e}NIwyYKT%Sue)L;7I7JYB)tpVNP7pm4j0n6@>Y|3y<8rov)IM#WzE@P_p zpPF3p<9y7UBK}GHof5CwW07klGghQ%{IeT#5013G-@n^&IFHZTJJ6g~ zCL1d0jcUJO-+8y)#+Wl0=`qCJo^!~ia8$-;rOBE~#*_zRZ*s~5n>IEYEtin@n6TMCEC;3v*irJ77~dTlkH+Ea~ni&gW~z zEBWCpC22aJfc1md!}q~j@)~H{%|IZpVtGYMh}wWjmPAVGFG{e*)g0Ukf*24y3)BXV zL{F7d(CXNXPzVFQlu~e}UL~fsmSnqLDoUS5FIMR1VZnVc3TinGDcHznFA6zTs<73? z4WUqG_@f*^v&jR_Q>a63^$bI30RuiF&nnl+1=px4kSzi_XB+AxOARqt@H;ZXlCce# zxlDYVFRiA{;DaYx(}XclB2S^eT1Q#1;p=9y6{`}J_sm<1Th)5PG zzzBlA<6+TFhl2c=Jl_@yJ}518aXJd2YFCAVu-7TMwT$KZefT7 zs5NxjtWvoM1u)bqHBp$PBs0RBf))u;m?bp>hDT6vTw&Lr!dBTtgj5XtcKJWphk_H; zeH09+T|vQZQ8Efz6lS0!cG`T`QE*MzYzhh@C0zhrg|>NSMAtY9%Huc+TF>Ppkl@@zX1imQDFMlS23i7E;Qs+kyyrF{7O&UZxN+ z-QgiSOj1$l30gw2$s1etFkp1{tI8Eq=&i{Q(-jkZqNBkxHjo*)Mn|Eg=J}ZZ*M!@$ m8X&e#V;O~v<{(@8u;?|riGH1;*CyBcIM_}B>Hc%VBjPV`^lBFX diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a80b22ce5..e2847c820 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.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1aa94a426..f5feea6d6 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 25da30dbd..9d21a2183 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## From b4d01cda7c1849d8c3dd4467af0faf11f1be2b5f Mon Sep 17 00:00:00 2001 From: Philip Kelley Date: Sun, 15 Dec 2024 18:18:31 +0000 Subject: [PATCH 018/133] Downgrade some versions slightly Paperweight 1.7.7 -> 1.7.5 gradlew 8.11.1 -> 8.10.1 --- build.gradle.kts | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9ec6949da..3f4b9bfb8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,7 +2,7 @@ plugins { java `maven-publish` id("com.gradleup.shadow") version "8.3.5" apply false - id("io.papermc.paperweight.patcher") version "1.7.7" + id("io.papermc.paperweight.patcher") version "1.7.5" id("org.kordamp.gradle.profiles") version "0.54.0" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e2847c820..df97d72b8 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.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From e70bcdd02c7fa0ab5d6db4bb525e58420fa69c6e Mon Sep 17 00:00:00 2001 From: Philip Kelley Date: Mon, 16 Dec 2024 15:04:19 +0000 Subject: [PATCH 019/133] chore(*): restructuring round 1 --- api/build.gradle.kts | 95 +----- .../api/AdvancedSlimePaperAPI.java | 17 +- .../{aswm => asp}/api/SlimeNMSBridge.java | 6 +- .../AsyncPostCreateEmptyWorldEvent.java | 9 +- .../api/events/AsyncPostGetWorldEvent.java | 9 +- .../api/events/AsyncPostImportWorldEvent.java | 4 +- .../api/events/AsyncPostLoadWorldEvent.java | 9 +- .../events/AsyncPostMigrateWorldEvent.java | 4 +- .../events/AsyncPreCreateEmptyWorldEvent.java | 13 +- .../api/events/AsyncPreGetWorldEvent.java | 2 +- .../api/events/AsyncPreImportWorldEvent.java | 4 +- .../api/events/AsyncPreLoadWorldEvent.java | 13 +- .../api/events/LoadSlimeWorldEvent.java | 9 +- .../api/events/PreGenerateWorldEvent.java | 11 +- .../exceptions/CorruptedWorldException.java | 2 +- .../exceptions/InvalidVersionException.java | 2 +- .../api/exceptions/InvalidWorldException.java | 2 +- .../api/exceptions/NewerFormatException.java | 2 +- .../api/exceptions/SlimeException.java | 2 +- .../api/exceptions/UnknownWorldException.java | 2 +- .../WorldAlreadyExistsException.java | 2 +- .../api/exceptions/WorldLoadedException.java | 2 +- .../api/exceptions/WorldTooBigException.java | 2 +- .../api/loaders/SlimeLoader.java | 4 +- .../{aswm => asp}/api/utils/NibbleArray.java | 2 +- .../{aswm => asp}/api/utils/SlimeFormat.java | 2 +- .../{aswm => asp}/api/world/SlimeChunk.java | 2 +- .../api/world/SlimeChunkSection.java | 4 +- .../{aswm => asp}/api/world/SlimeWorld.java | 8 +- .../api/world/SlimeWorldInstance.java | 7 +- .../api/world/properties/SlimeProperties.java | 10 +- .../api/world/properties/SlimeProperty.java | 2 +- .../world/properties/SlimePropertyMap.java | 2 +- .../properties/type/SlimePropertyBoolean.java | 5 +- .../properties/type/SlimePropertyFloat.java | 5 +- .../properties/type/SlimePropertyInt.java | 4 +- .../properties/type/SlimePropertyString.java | 5 +- build.gradle.kts | 74 +---- core/build.gradle.kts | 11 +- .../{aswm => asp}/SlimeLogger.java | 2 +- .../com/infernalsuite/{aswm => asp}/Util.java | 2 +- .../pdc/FlowDataTypeRegistry.java | 4 +- .../pdc/FlowPersistentDataContainer.java | 2 +- .../asp/serialization/SlimeWorldReader.java | 8 + .../serialization/anvil/AnvilImportData.java | 4 +- .../serialization/anvil/AnvilWorldReader.java | 32 +- .../serialization/slime/ChunkPruner.java | 12 +- .../serialization/slime/SlimeSerializer.java | 12 +- .../reader/SlimeWorldReaderRegistry.java | 24 +- .../reader/VersionedByteSlimeWorldReader.java | 10 +- .../slime/reader/impl/SimpleWorldFormat.java | 19 +- .../impl/v10/v10SlimeWorldDeSerializer.java | 33 +- .../slime/reader/impl/v10/v10WorldFormat.java | 8 + .../impl/v11/v11SlimeWorldDeSerializer.java | 36 +- .../slime/reader/impl/v11/v11WorldFormat.java | 7 + .../impl/v12/v12SlimeWorldDeSerializer.java | 36 +- .../slime/reader/impl/v12/v12WorldFormat.java | 7 + .../slime/reader/impl/v1_9/Upgrade.java | 2 +- .../impl/v1_9/upgrade/v1_11WorldUpgrade.java | 11 +- .../impl/v1_9/upgrade/v1_13WorldUpgrade.java | 26 +- .../impl/v1_9/upgrade/v1_14WorldUpgrade.java | 14 +- .../impl/v1_9/upgrade/v1_16WorldUpgrade.java | 12 +- .../impl/v1_9/upgrade/v1_17WorldUpgrade.java | 14 +- .../impl/v1_9/upgrade/v1_18WorldUpgrade.java | 24 +- .../impl/v1_9/upgrade/v1_9WorldUpgrade.java | 10 +- .../reader/impl/v1_9/v1_9SlimeChunk.java | 2 +- .../impl/v1_9/v1_9SlimeChunkSection.java | 4 +- .../reader/impl/v1_9/v1_9SlimeWorld.java | 6 +- .../impl/v1_9/v1_9SlimeWorldDeserializer.java | 17 +- .../reader/impl/v1_9/v1_9WorldFormat.java | 7 + .../reader/impl/v1_9/v1_v9SlimeConverter.java | 38 +-- .../skeleton/SkeletonCloning.java | 14 +- .../skeleton/SkeletonSlimeWorld.java | 19 +- .../skeleton/SlimeChunkSectionSkeleton.java | 6 +- .../skeleton/SlimeChunkSkeleton.java | 6 +- .../aswm/serialization/SlimeWorldReader.java | 8 - .../slime/reader/impl/v10/v10WorldFormat.java | 11 - .../slime/reader/impl/v11/v11WorldFormat.java | 10 - .../slime/reader/impl/v12/v12WorldFormat.java | 10 - .../reader/impl/v1_9/v1_9WorldFormat.java | 9 - gradle.properties | 3 +- gradle/build-logic/build.gradle.kts | 28 ++ gradle/build-logic/settings.gradle.kts | 17 + .../kotlin/asp.base-conventions.gradle.kts | 58 ++++ .../asp.paperweight-conventions.gradle.kts | 42 +++ .../asp.publishing-conventions.gradle.kts | 86 +++++ .../asp/conventions/PublishConfiguration.kt | 19 ++ .../build-logic/src/main/kotlin/constants.kt | 2 + .../build-logic/src/main/kotlin/extensions.kt | 24 ++ gradle/libs.versions.toml | 53 +++ gradle/platform/build.gradle.kts | 26 ++ importer/build.gradle.kts | 9 +- .../{aswm => asp}/importer/SWMImporter.java | 9 +- loaders/build.gradle.kts | 102 +----- .../loaders/UpdatableLoader.java | 4 +- .../{aswm => asp}/loaders/api/APILoader.java | 6 +- .../loaders/api/MapStructure.java | 2 +- .../loaders/file/FileLoader.java | 6 +- .../loaders/mongo/MongoLoader.java | 7 +- .../loaders/mysql/MysqlLoader.java | 7 +- .../loaders/redis/RedisLoader.java | 9 +- .../loaders/redis/util/StringByteCodec.java | 2 +- patches/api/0001-Slime-World-Manager.patch | 10 +- patches/server/0001-Build-Changes.patch | 312 +++++++++--------- patches/server/0002-poi-data-loader.patch | 12 +- ...rt-for-serializing-deserializing-PDC.patch | 28 +- patches/server/0004-Fix-entity-loading.patch | 26 +- .../server/0005-Remove-catch-throwable.patch | 8 +- .../0006-Handle-null-data-properly.patch | 8 +- ...ke-SlimeWorld-a-PersistentDataHolder.patch | 50 +-- ...c-and-extra-nbt.-Fix-double-compress.patch | 64 ++-- .../0009-Add-migration-from-SRF-1-8.patch | 64 ++-- ...n-yaw-propagate-CraftWorld-setSpawnL.patch | 8 +- ...not-getting-serialized-when-reloaded.patch | 16 +- patches/server/0012-Compile-fixes.patch | 38 +-- ...e-plugin-and-server-rework-API-to-v3.patch | 108 +++--- .../0014-replace-ChunkPos-with-long.patch | 64 ++-- patches/server/0015-1.21-compatibility.patch | 98 +++--- ...0016-Fix-chunk-saving-when-unloading.patch | 8 +- .../0017-fix-disable-dragon-fights.patch | 6 +- ...nk-pdc-getting-wiped-on-chunk-unload.patch | 8 +- patches/server/0019-1.21.3-fixes.patch | 58 ++-- ...ng-chunks-entities-when-chunk-saving.patch | 36 +- ...-not-saving-when-chunks-are-unloaded.patch | 8 +- plugin/build.gradle.kts | 57 ++-- .../{aswm => asp}/plugin/SWPlugin.java | 33 +- .../plugin/commands/CommandManager.java | 65 ++-- .../plugin/commands/SlimeCommand.java | 19 +- .../exception/MessageCommandException.java | 2 +- .../commands/parser/BukkitWorldParser.java | 7 +- .../commands/parser/NamedSlimeLoader.java | 4 +- .../parser/NamedSlimeLoaderParser.java | 11 +- .../commands/parser/NamedWorldData.java | 6 + .../commands/parser/NamedWorldDataParser.java | 12 +- .../commands/parser/SlimeWorldParser.java | 10 +- .../KnownSlimeWorldSuggestionProvider.java | 4 +- .../plugin/commands/sub/CloneWorldCmd.java | 62 ++-- .../plugin/commands/sub/CreateWorldCmd.java | 44 +-- .../plugin/commands/sub/DSListCmd.java | 28 +- .../plugin/commands/sub/DeleteWorldCmd.java | 37 +-- .../plugin/commands/sub/GotoCmd.java | 17 +- .../plugin/commands/sub/HelpCmd.java | 8 +- .../plugin/commands/sub/ImportWorldCmd.java | 48 ++- .../commands/sub/LoadTemplateWorldCmd.java | 33 +- .../plugin/commands/sub/LoadWorldCmd.java | 26 +- .../plugin/commands/sub/MigrateWorldCmd.java | 20 +- .../plugin/commands/sub/ReloadConfigCmd.java | 12 +- .../plugin/commands/sub/SaveWorldCmd.java | 13 +- .../plugin/commands/sub/SetSpawnCmd.java | 18 +- .../plugin/commands/sub/UnloadWorldCmd.java | 10 +- .../plugin/commands/sub/VersionCmd.java | 10 +- .../plugin/commands/sub/WorldListCmd.java | 12 +- .../plugin/config/ConfigManager.java | 4 +- .../plugin/config/DatasourcesConfig.java | 2 +- .../plugin/config/WorldData.java | 6 +- .../plugin/config/WorldsConfig.java | 2 +- .../plugin/loader/LoaderManager.java | 32 +- .../plugin/util/ExecutorUtil.java | 2 +- .../commands/parser/NamedWorldData.java | 6 - settings.gradle.kts | 15 +- 160 files changed, 1581 insertions(+), 1583 deletions(-) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/AdvancedSlimePaperAPI.java (90%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/SlimeNMSBridge.java (89%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/events/AsyncPostCreateEmptyWorldEvent.java (66%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/events/AsyncPostGetWorldEvent.java (67%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/events/AsyncPostImportWorldEvent.java (91%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/events/AsyncPostLoadWorldEvent.java (67%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/events/AsyncPostMigrateWorldEvent.java (92%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/events/AsyncPreCreateEmptyWorldEvent.java (78%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/events/AsyncPreGetWorldEvent.java (96%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/events/AsyncPreImportWorldEvent.java (94%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/events/AsyncPreLoadWorldEvent.java (79%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/events/LoadSlimeWorldEvent.java (67%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/events/PreGenerateWorldEvent.java (72%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/exceptions/CorruptedWorldException.java (88%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/exceptions/InvalidVersionException.java (85%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/exceptions/InvalidWorldException.java (91%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/exceptions/NewerFormatException.java (84%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/exceptions/SlimeException.java (84%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/exceptions/UnknownWorldException.java (82%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/exceptions/WorldAlreadyExistsException.java (84%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/exceptions/WorldLoadedException.java (85%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/exceptions/WorldTooBigException.java (86%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/loaders/SlimeLoader.java (94%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/utils/NibbleArray.java (96%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/utils/SlimeFormat.java (87%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/world/SlimeChunk.java (97%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/world/SlimeChunkSection.java (86%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/world/SlimeWorld.java (92%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/world/SlimeWorldInstance.java (58%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/world/properties/SlimeProperties.java (91%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/world/properties/SlimeProperty.java (96%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/world/properties/SlimePropertyMap.java (97%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/world/properties/type/SlimePropertyBoolean.java (80%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/world/properties/type/SlimePropertyFloat.java (81%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/world/properties/type/SlimePropertyInt.java (86%) rename api/src/main/java/com/infernalsuite/{aswm => asp}/api/world/properties/type/SlimePropertyString.java (79%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/SlimeLogger.java (91%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/Util.java (86%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/pdc/FlowDataTypeRegistry.java (99%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/pdc/FlowPersistentDataContainer.java (99%) create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/SlimeWorldReader.java rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/anvil/AnvilImportData.java (60%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/anvil/AnvilWorldReader.java (92%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/ChunkPruner.java (86%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/SlimeSerializer.java (95%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/reader/SlimeWorldReaderRegistry.java (69%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/reader/VersionedByteSlimeWorldReader.java (54%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/reader/impl/SimpleWorldFormat.java (51%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java (86%) create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10WorldFormat.java rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java (80%) create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11WorldFormat.java rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/reader/impl/v12/v12SlimeWorldDeSerializer.java (80%) create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12WorldFormat.java rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/reader/impl/v1_9/Upgrade.java (50%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java (83%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java (76%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java (93%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java (88%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java (70%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java (93%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java (76%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java (94%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java (89%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java (83%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java (97%) create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9WorldFormat.java rename core/src/main/java/com/infernalsuite/{aswm => asp}/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java (71%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/skeleton/SkeletonCloning.java (90%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/skeleton/SkeletonSlimeWorld.java (90%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/skeleton/SlimeChunkSectionSkeleton.java (79%) rename core/src/main/java/com/infernalsuite/{aswm => asp}/skeleton/SlimeChunkSkeleton.java (88%) delete mode 100644 core/src/main/java/com/infernalsuite/aswm/serialization/SlimeWorldReader.java delete mode 100644 core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v10/v10WorldFormat.java delete mode 100644 core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v11/v11WorldFormat.java delete mode 100644 core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v12/v12WorldFormat.java delete mode 100644 core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9WorldFormat.java create mode 100644 gradle/build-logic/build.gradle.kts create mode 100644 gradle/build-logic/settings.gradle.kts create mode 100644 gradle/build-logic/src/main/kotlin/asp.base-conventions.gradle.kts create mode 100644 gradle/build-logic/src/main/kotlin/asp.paperweight-conventions.gradle.kts create mode 100644 gradle/build-logic/src/main/kotlin/asp.publishing-conventions.gradle.kts create mode 100644 gradle/build-logic/src/main/kotlin/com/infernalsuite/asp/conventions/PublishConfiguration.kt create mode 100644 gradle/build-logic/src/main/kotlin/constants.kt create mode 100644 gradle/build-logic/src/main/kotlin/extensions.kt create mode 100644 gradle/libs.versions.toml create mode 100644 gradle/platform/build.gradle.kts rename importer/src/main/java/com/infernalsuite/{aswm => asp}/importer/SWMImporter.java (90%) rename loaders/src/main/java/com/infernalsuite/{aswm => asp}/loaders/UpdatableLoader.java (88%) rename loaders/src/main/java/com/infernalsuite/{aswm => asp}/loaders/api/APILoader.java (97%) rename loaders/src/main/java/com/infernalsuite/{aswm => asp}/loaders/api/MapStructure.java (97%) rename loaders/src/main/java/com/infernalsuite/{aswm => asp}/loaders/file/FileLoader.java (93%) rename loaders/src/main/java/com/infernalsuite/{aswm => asp}/loaders/mongo/MongoLoader.java (97%) rename loaders/src/main/java/com/infernalsuite/{aswm => asp}/loaders/mysql/MysqlLoader.java (97%) rename loaders/src/main/java/com/infernalsuite/{aswm => asp}/loaders/redis/RedisLoader.java (88%) rename loaders/src/main/java/com/infernalsuite/{aswm => asp}/loaders/redis/util/StringByteCodec.java (95%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/SWPlugin.java (85%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/CommandManager.java (66%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/SlimeCommand.java (63%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/exception/MessageCommandException.java (84%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/parser/BukkitWorldParser.java (83%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/parser/NamedSlimeLoader.java (57%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/parser/NamedSlimeLoaderParser.java (81%) create mode 100644 plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/NamedWorldData.java rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/parser/NamedWorldDataParser.java (77%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/parser/SlimeWorldParser.java (85%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/parser/suggestion/KnownSlimeWorldSuggestionProvider.java (88%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/sub/CloneWorldCmd.java (69%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/sub/CreateWorldCmd.java (74%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/sub/DSListCmd.java (79%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/sub/DeleteWorldCmd.java (79%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/sub/GotoCmd.java (78%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/sub/HelpCmd.java (73%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/sub/ImportWorldCmd.java (80%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/sub/LoadTemplateWorldCmd.java (82%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/sub/LoadWorldCmd.java (89%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/sub/MigrateWorldCmd.java (87%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/sub/ReloadConfigCmd.java (81%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/sub/SaveWorldCmd.java (79%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/sub/SetSpawnCmd.java (81%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/sub/UnloadWorldCmd.java (92%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/sub/VersionCmd.java (80%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/commands/sub/WorldListCmd.java (92%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/config/ConfigManager.java (96%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/config/DatasourcesConfig.java (99%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/config/WorldData.java (96%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/config/WorldsConfig.java (95%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/loader/LoaderManager.java (75%) rename plugin/src/main/java/com/infernalsuite/{aswm => asp}/plugin/util/ExecutorUtil.java (96%) delete mode 100644 plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/NamedWorldData.java diff --git a/api/build.gradle.kts b/api/build.gradle.kts index 6b52c8aea..30ab1e918 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -1,96 +1,17 @@ plugins { - `java-library` - `maven-publish` - signing + id("asp.base-conventions") + id("asp.publishing-conventions") } dependencies { + api(libs.annotations) + api(libs.adventure.nbt) api("com.flowpowered:flow-nbt:2.0.2") - api("org.jetbrains:annotations:23.0.0") - compileOnly("io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT") + compileOnly(paperApi()) } -version = "3.0.0-SNAPSHOT" - -java { - withSourcesJar() - withJavadocJar() -} - -profiles { - profile("publish") { - activation { - property { - setKey("publish") - setValue("true") - } - } - action { - publishing { - publications { - create("maven") { - groupId = "${project.group}" - artifactId = project.name - version = "${project.version}" - - from(components["java"]) - - pom { - name.set("Advanced Slime Paper API") - description.set("API for ASP") - url.set("https://github.com/InfernalSuite/AdvancedSlimePaper") - licenses { - license { - name.set("GNU General Public License, Version 3.0") - url.set("https://www.gnu.org/licenses/gpl-3.0.txt") - } - } - developers { - developer { - id.set("InfernalSuite") - name.set("The InfernalSuite Team") - url.set("https://github.com/InfernalSuite") - email.set("infernalsuite@gmail.com") - } - } - scm { - connection.set("scm:git:https://github.com:InfernalSuite/AdvancedSlimePaper.git") - developerConnection.set("scm:git:ssh://github.com:InfernalSuite/AdvancedSlimePaper.git") - url.set("https://github.com/InfernalSuite/AdvancedSlimePaper/") - } - issueManagement { - system.set("Github") - url.set("https://github.com/InfernalSuite/AdvancedSlimePaper/issues") - } - } - - versionMapping { - usage("java-api") { - fromResolutionOf("runtimeClasspath") - } - usage("java-runtime") { - fromResolutionResult() - } - } - } - } - repositories { - maven { - name = "infernalsuite" - url = uri("https://repo.infernalsuite.com/repository/maven-snapshots/") - credentials { - username = project.property("ISUsername") as String? - password = project.property("ISPassword") as String? - } - } - } - } - - signing { - useGpgCmd() - sign(publishing.publications["maven"]) - } - } - } +publishConfiguration { + name = "Advanced Slime Paper API" + description = "API for Advanced Slime Paper" } diff --git a/api/src/main/java/com/infernalsuite/aswm/api/AdvancedSlimePaperAPI.java b/api/src/main/java/com/infernalsuite/asp/api/AdvancedSlimePaperAPI.java similarity index 90% rename from api/src/main/java/com/infernalsuite/aswm/api/AdvancedSlimePaperAPI.java rename to api/src/main/java/com/infernalsuite/asp/api/AdvancedSlimePaperAPI.java index 88d36977c..527b9d863 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/AdvancedSlimePaperAPI.java +++ b/api/src/main/java/com/infernalsuite/asp/api/AdvancedSlimePaperAPI.java @@ -1,9 +1,16 @@ -package com.infernalsuite.aswm.api; +package com.infernalsuite.asp.api; -import com.infernalsuite.aswm.api.exceptions.*; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; +import com.infernalsuite.asp.api.exceptions.InvalidWorldException; +import com.infernalsuite.asp.api.exceptions.NewerFormatException; +import com.infernalsuite.asp.api.exceptions.UnknownWorldException; +import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; +import com.infernalsuite.asp.api.exceptions.WorldLoadedException; +import com.infernalsuite.asp.api.exceptions.WorldTooBigException; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.api.exceptions.*; +import com.infernalsuite.asp.api.loaders.SlimeLoader; import net.kyori.adventure.util.Services; import org.bukkit.World; import org.jetbrains.annotations.ApiStatus; diff --git a/api/src/main/java/com/infernalsuite/aswm/api/SlimeNMSBridge.java b/api/src/main/java/com/infernalsuite/asp/api/SlimeNMSBridge.java similarity index 89% rename from api/src/main/java/com/infernalsuite/aswm/api/SlimeNMSBridge.java rename to api/src/main/java/com/infernalsuite/asp/api/SlimeNMSBridge.java index 9aef6612d..febdcf72e 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/SlimeNMSBridge.java +++ b/api/src/main/java/com/infernalsuite/asp/api/SlimeNMSBridge.java @@ -1,9 +1,9 @@ -package com.infernalsuite.aswm.api; +package com.infernalsuite.asp.api; import com.flowpowered.nbt.CompoundMap; import com.flowpowered.nbt.CompoundTag; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.api.world.SlimeWorldInstance; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.SlimeWorldInstance; import net.kyori.adventure.util.Services; import org.bukkit.World; import org.bukkit.persistence.PersistentDataContainer; diff --git a/api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPostCreateEmptyWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostCreateEmptyWorldEvent.java similarity index 66% rename from api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPostCreateEmptyWorldEvent.java rename to api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostCreateEmptyWorldEvent.java index 654896236..ebf10f1dd 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPostCreateEmptyWorldEvent.java +++ b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostCreateEmptyWorldEvent.java @@ -1,6 +1,5 @@ -package com.infernalsuite.aswm.api.events; +package com.infernalsuite.asp.api.events; -import com.infernalsuite.aswm.api.world.SlimeWorld; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; @@ -10,9 +9,9 @@ public class AsyncPostCreateEmptyWorldEvent extends Event { private static final HandlerList handlers = new HandlerList(); - private final SlimeWorld slimeWorld; + private final com.infernalsuite.asp.api.world.SlimeWorld slimeWorld; - public AsyncPostCreateEmptyWorldEvent(SlimeWorld slimeWorld) { + public AsyncPostCreateEmptyWorldEvent(com.infernalsuite.asp.api.world.SlimeWorld slimeWorld) { super(true); this.slimeWorld = Objects.requireNonNull(slimeWorld, "slimeWorld cannot be null"); } @@ -26,7 +25,7 @@ public static HandlerList getHandlerList() { return handlers; } - public SlimeWorld getSlimeWorld() { + public com.infernalsuite.asp.api.world.SlimeWorld getSlimeWorld() { return slimeWorld; } } diff --git a/api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPostGetWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostGetWorldEvent.java similarity index 67% rename from api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPostGetWorldEvent.java rename to api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostGetWorldEvent.java index 0a0552062..69bbbea5d 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPostGetWorldEvent.java +++ b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostGetWorldEvent.java @@ -1,6 +1,5 @@ -package com.infernalsuite.aswm.api.events; +package com.infernalsuite.asp.api.events; -import com.infernalsuite.aswm.api.world.SlimeWorld; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; @@ -10,9 +9,9 @@ public class AsyncPostGetWorldEvent extends Event { private static final HandlerList handlers = new HandlerList(); - private final SlimeWorld slimeWorld; + private final com.infernalsuite.asp.api.world.SlimeWorld slimeWorld; - public AsyncPostGetWorldEvent(SlimeWorld slimeWorld) { + public AsyncPostGetWorldEvent(com.infernalsuite.asp.api.world.SlimeWorld slimeWorld) { super(true); this.slimeWorld = Objects.requireNonNull(slimeWorld, "slimeWorld cannot be null"); } @@ -26,7 +25,7 @@ public static HandlerList getHandlerList() { return handlers; } - public SlimeWorld getSlimeWorld() { + public com.infernalsuite.asp.api.world.SlimeWorld getSlimeWorld() { return slimeWorld; } } diff --git a/api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPostImportWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostImportWorldEvent.java similarity index 91% rename from api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPostImportWorldEvent.java rename to api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostImportWorldEvent.java index 08fe02616..3bf078393 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPostImportWorldEvent.java +++ b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostImportWorldEvent.java @@ -1,6 +1,6 @@ -package com.infernalsuite.aswm.api.events; +package com.infernalsuite.asp.api.events; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.loaders.SlimeLoader; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; diff --git a/api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPostLoadWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostLoadWorldEvent.java similarity index 67% rename from api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPostLoadWorldEvent.java rename to api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostLoadWorldEvent.java index 3c9374f63..ae9e2eb3d 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPostLoadWorldEvent.java +++ b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostLoadWorldEvent.java @@ -1,6 +1,5 @@ -package com.infernalsuite.aswm.api.events; +package com.infernalsuite.asp.api.events; -import com.infernalsuite.aswm.api.world.SlimeWorld; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; @@ -10,9 +9,9 @@ public class AsyncPostLoadWorldEvent extends Event { private static final HandlerList handlers = new HandlerList(); - private final SlimeWorld slimeWorld; + private final com.infernalsuite.asp.api.world.SlimeWorld slimeWorld; - public AsyncPostLoadWorldEvent(SlimeWorld slimeWorld) { + public AsyncPostLoadWorldEvent(com.infernalsuite.asp.api.world.SlimeWorld slimeWorld) { super(true); this.slimeWorld = Objects.requireNonNull(slimeWorld, "slimeWorld cannot be null"); } @@ -26,7 +25,7 @@ public static HandlerList getHandlerList() { return handlers; } - public SlimeWorld getSlimeWorld() { + public com.infernalsuite.asp.api.world.SlimeWorld getSlimeWorld() { return this.slimeWorld; } } diff --git a/api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPostMigrateWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostMigrateWorldEvent.java similarity index 92% rename from api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPostMigrateWorldEvent.java rename to api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostMigrateWorldEvent.java index d9a8fa2b0..be1e257a6 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPostMigrateWorldEvent.java +++ b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostMigrateWorldEvent.java @@ -1,6 +1,6 @@ -package com.infernalsuite.aswm.api.events; +package com.infernalsuite.asp.api.events; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.loaders.SlimeLoader; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; diff --git a/api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPreCreateEmptyWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreCreateEmptyWorldEvent.java similarity index 78% rename from api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPreCreateEmptyWorldEvent.java rename to api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreCreateEmptyWorldEvent.java index 4bc35a5f2..a7468fff6 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPreCreateEmptyWorldEvent.java +++ b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreCreateEmptyWorldEvent.java @@ -1,7 +1,6 @@ -package com.infernalsuite.aswm.api.events; +package com.infernalsuite.asp.api.events; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.api.loaders.SlimeLoader; import org.bukkit.event.Cancellable; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; @@ -16,9 +15,9 @@ public class AsyncPreCreateEmptyWorldEvent extends Event implements Cancellable private SlimeLoader slimeLoader; private String worldName; private boolean readOnly; - private SlimePropertyMap slimePropertyMap; + private com.infernalsuite.asp.api.world.properties.SlimePropertyMap slimePropertyMap; - public AsyncPreCreateEmptyWorldEvent(SlimeLoader slimeLoader, String worldName, boolean readOnly, SlimePropertyMap slimePropertyMap) { + public AsyncPreCreateEmptyWorldEvent(SlimeLoader slimeLoader, String worldName, boolean readOnly, com.infernalsuite.asp.api.world.properties.SlimePropertyMap slimePropertyMap) { super(true); this.slimeLoader = Objects.requireNonNull(slimeLoader, "slimeLoader cannot be null"); this.worldName = Objects.requireNonNull(worldName, "worldName cannot be null"); @@ -69,11 +68,11 @@ public void setReadOnly(boolean readOnly) { this.readOnly = readOnly; } - public SlimePropertyMap getSlimePropertyMap() { + public com.infernalsuite.asp.api.world.properties.SlimePropertyMap getSlimePropertyMap() { return this.slimePropertyMap; } - public void setSlimePropertyMap(SlimePropertyMap slimePropertyMap) { + public void setSlimePropertyMap(com.infernalsuite.asp.api.world.properties.SlimePropertyMap slimePropertyMap) { this.slimePropertyMap = Objects.requireNonNull(slimePropertyMap, "slimePropertyMap cannot be null"); } } diff --git a/api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPreGetWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreGetWorldEvent.java similarity index 96% rename from api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPreGetWorldEvent.java rename to api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreGetWorldEvent.java index a73796e92..6d6fc28c7 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPreGetWorldEvent.java +++ b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreGetWorldEvent.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.api.events; +package com.infernalsuite.asp.api.events; import org.bukkit.event.Cancellable; import org.bukkit.event.Event; diff --git a/api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPreImportWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreImportWorldEvent.java similarity index 94% rename from api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPreImportWorldEvent.java rename to api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreImportWorldEvent.java index a42df4b3a..ec4eb6a61 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPreImportWorldEvent.java +++ b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreImportWorldEvent.java @@ -1,6 +1,6 @@ -package com.infernalsuite.aswm.api.events; +package com.infernalsuite.asp.api.events; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.loaders.SlimeLoader; import org.bukkit.event.Cancellable; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; diff --git a/api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPreLoadWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreLoadWorldEvent.java similarity index 79% rename from api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPreLoadWorldEvent.java rename to api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreLoadWorldEvent.java index 716bc4315..c241e3a94 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/events/AsyncPreLoadWorldEvent.java +++ b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreLoadWorldEvent.java @@ -1,7 +1,6 @@ -package com.infernalsuite.aswm.api.events; +package com.infernalsuite.asp.api.events; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.api.loaders.SlimeLoader; import org.bukkit.event.Cancellable; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; @@ -16,9 +15,9 @@ public class AsyncPreLoadWorldEvent extends Event implements Cancellable { private SlimeLoader slimeLoader; private String worldName; private boolean readOnly; - private SlimePropertyMap slimePropertyMap; + private com.infernalsuite.asp.api.world.properties.SlimePropertyMap slimePropertyMap; - public AsyncPreLoadWorldEvent(SlimeLoader slimeLoader, String worldName, boolean readOnly, SlimePropertyMap slimePropertyMap) { + public AsyncPreLoadWorldEvent(SlimeLoader slimeLoader, String worldName, boolean readOnly, com.infernalsuite.asp.api.world.properties.SlimePropertyMap slimePropertyMap) { super(true); this.slimeLoader = Objects.requireNonNull(slimeLoader, "slimeLoader cannot be null"); this.worldName = Objects.requireNonNull(worldName, "worldName cannot be null"); @@ -69,11 +68,11 @@ public void setReadOnly(boolean readOnly) { this.readOnly = readOnly; } - public SlimePropertyMap getSlimePropertyMap() { + public com.infernalsuite.asp.api.world.properties.SlimePropertyMap getSlimePropertyMap() { return this.slimePropertyMap; } - public void setSlimePropertyMap(SlimePropertyMap slimePropertyMap) { + public void setSlimePropertyMap(com.infernalsuite.asp.api.world.properties.SlimePropertyMap slimePropertyMap) { this.slimePropertyMap = Objects.requireNonNull(slimePropertyMap, "slimePropertyMap cannot be null"); } } diff --git a/api/src/main/java/com/infernalsuite/aswm/api/events/LoadSlimeWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/LoadSlimeWorldEvent.java similarity index 67% rename from api/src/main/java/com/infernalsuite/aswm/api/events/LoadSlimeWorldEvent.java rename to api/src/main/java/com/infernalsuite/asp/api/events/LoadSlimeWorldEvent.java index 7f8f144a2..490021fed 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/events/LoadSlimeWorldEvent.java +++ b/api/src/main/java/com/infernalsuite/asp/api/events/LoadSlimeWorldEvent.java @@ -1,6 +1,5 @@ -package com.infernalsuite.aswm.api.events; +package com.infernalsuite.asp.api.events; -import com.infernalsuite.aswm.api.world.SlimeWorld; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; @@ -10,9 +9,9 @@ public class LoadSlimeWorldEvent extends Event { private static final HandlerList handlers = new HandlerList(); - private final SlimeWorld slimeWorld; + private final com.infernalsuite.asp.api.world.SlimeWorld slimeWorld; - public LoadSlimeWorldEvent(SlimeWorld slimeWorld) { + public LoadSlimeWorldEvent(com.infernalsuite.asp.api.world.SlimeWorld slimeWorld) { super(false); this.slimeWorld = Objects.requireNonNull(slimeWorld, "slimeWorld cannot be null"); } @@ -26,7 +25,7 @@ public static HandlerList getHandlerList() { return handlers; } - public SlimeWorld getSlimeWorld() { + public com.infernalsuite.asp.api.world.SlimeWorld getSlimeWorld() { return slimeWorld; } } diff --git a/api/src/main/java/com/infernalsuite/aswm/api/events/PreGenerateWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/PreGenerateWorldEvent.java similarity index 72% rename from api/src/main/java/com/infernalsuite/aswm/api/events/PreGenerateWorldEvent.java rename to api/src/main/java/com/infernalsuite/asp/api/events/PreGenerateWorldEvent.java index a0401d689..739a88906 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/events/PreGenerateWorldEvent.java +++ b/api/src/main/java/com/infernalsuite/asp/api/events/PreGenerateWorldEvent.java @@ -1,6 +1,5 @@ -package com.infernalsuite.aswm.api.events; +package com.infernalsuite.asp.api.events; -import com.infernalsuite.aswm.api.world.SlimeWorld; import org.bukkit.event.Cancellable; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; @@ -12,9 +11,9 @@ public class PreGenerateWorldEvent extends Event implements Cancellable { private static final HandlerList handlers = new HandlerList(); private boolean isCancelled; - private SlimeWorld slimeWorld; + private com.infernalsuite.asp.api.world.SlimeWorld slimeWorld; - public PreGenerateWorldEvent(SlimeWorld slimeWorld) { + public PreGenerateWorldEvent(com.infernalsuite.asp.api.world.SlimeWorld slimeWorld) { super(false); this.slimeWorld = Objects.requireNonNull(slimeWorld, "slimeWorld cannot be null"); } @@ -38,11 +37,11 @@ public void setCancelled(boolean cancelled) { this.isCancelled = cancelled; } - public SlimeWorld getSlimeWorld() { + public com.infernalsuite.asp.api.world.SlimeWorld getSlimeWorld() { return this.slimeWorld; } - public void setSlimeWorld(SlimeWorld slimeWorld) { + public void setSlimeWorld(com.infernalsuite.asp.api.world.SlimeWorld slimeWorld) { this.slimeWorld = Objects.requireNonNull(slimeWorld, "slimeWorld cannot be null"); } } diff --git a/api/src/main/java/com/infernalsuite/aswm/api/exceptions/CorruptedWorldException.java b/api/src/main/java/com/infernalsuite/asp/api/exceptions/CorruptedWorldException.java similarity index 88% rename from api/src/main/java/com/infernalsuite/aswm/api/exceptions/CorruptedWorldException.java rename to api/src/main/java/com/infernalsuite/asp/api/exceptions/CorruptedWorldException.java index 7b29bf585..2d5f491f3 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/exceptions/CorruptedWorldException.java +++ b/api/src/main/java/com/infernalsuite/asp/api/exceptions/CorruptedWorldException.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.api.exceptions; +package com.infernalsuite.asp.api.exceptions; /** * Exception thrown when a world could not diff --git a/api/src/main/java/com/infernalsuite/aswm/api/exceptions/InvalidVersionException.java b/api/src/main/java/com/infernalsuite/asp/api/exceptions/InvalidVersionException.java similarity index 85% rename from api/src/main/java/com/infernalsuite/aswm/api/exceptions/InvalidVersionException.java rename to api/src/main/java/com/infernalsuite/asp/api/exceptions/InvalidVersionException.java index eb25d0af6..c02c46e0f 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/exceptions/InvalidVersionException.java +++ b/api/src/main/java/com/infernalsuite/asp/api/exceptions/InvalidVersionException.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.api.exceptions; +package com.infernalsuite.asp.api.exceptions; /** * Exception thrown when SWM is loaded diff --git a/api/src/main/java/com/infernalsuite/aswm/api/exceptions/InvalidWorldException.java b/api/src/main/java/com/infernalsuite/asp/api/exceptions/InvalidWorldException.java similarity index 91% rename from api/src/main/java/com/infernalsuite/aswm/api/exceptions/InvalidWorldException.java rename to api/src/main/java/com/infernalsuite/asp/api/exceptions/InvalidWorldException.java index 0ad2d751d..bac590354 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/exceptions/InvalidWorldException.java +++ b/api/src/main/java/com/infernalsuite/asp/api/exceptions/InvalidWorldException.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.api.exceptions; +package com.infernalsuite.asp.api.exceptions; import java.io.File; diff --git a/api/src/main/java/com/infernalsuite/aswm/api/exceptions/NewerFormatException.java b/api/src/main/java/com/infernalsuite/asp/api/exceptions/NewerFormatException.java similarity index 84% rename from api/src/main/java/com/infernalsuite/aswm/api/exceptions/NewerFormatException.java rename to api/src/main/java/com/infernalsuite/asp/api/exceptions/NewerFormatException.java index dd54386ee..e29eb5521 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/exceptions/NewerFormatException.java +++ b/api/src/main/java/com/infernalsuite/asp/api/exceptions/NewerFormatException.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.api.exceptions; +package com.infernalsuite.asp.api.exceptions; /** * Exception thrown when a world is encoded diff --git a/api/src/main/java/com/infernalsuite/aswm/api/exceptions/SlimeException.java b/api/src/main/java/com/infernalsuite/asp/api/exceptions/SlimeException.java similarity index 84% rename from api/src/main/java/com/infernalsuite/aswm/api/exceptions/SlimeException.java rename to api/src/main/java/com/infernalsuite/asp/api/exceptions/SlimeException.java index 545fcff0a..a7a4d976a 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/exceptions/SlimeException.java +++ b/api/src/main/java/com/infernalsuite/asp/api/exceptions/SlimeException.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.api.exceptions; +package com.infernalsuite.asp.api.exceptions; /** * Generic SWM exception. diff --git a/api/src/main/java/com/infernalsuite/aswm/api/exceptions/UnknownWorldException.java b/api/src/main/java/com/infernalsuite/asp/api/exceptions/UnknownWorldException.java similarity index 82% rename from api/src/main/java/com/infernalsuite/aswm/api/exceptions/UnknownWorldException.java rename to api/src/main/java/com/infernalsuite/asp/api/exceptions/UnknownWorldException.java index 89499cdf2..e50ce81c4 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/exceptions/UnknownWorldException.java +++ b/api/src/main/java/com/infernalsuite/asp/api/exceptions/UnknownWorldException.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.api.exceptions; +package com.infernalsuite.asp.api.exceptions; /** * Exception thrown when a diff --git a/api/src/main/java/com/infernalsuite/aswm/api/exceptions/WorldAlreadyExistsException.java b/api/src/main/java/com/infernalsuite/asp/api/exceptions/WorldAlreadyExistsException.java similarity index 84% rename from api/src/main/java/com/infernalsuite/aswm/api/exceptions/WorldAlreadyExistsException.java rename to api/src/main/java/com/infernalsuite/asp/api/exceptions/WorldAlreadyExistsException.java index 425eeab45..22c366573 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/exceptions/WorldAlreadyExistsException.java +++ b/api/src/main/java/com/infernalsuite/asp/api/exceptions/WorldAlreadyExistsException.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.api.exceptions; +package com.infernalsuite.asp.api.exceptions; /** * Exception thrown when a world diff --git a/api/src/main/java/com/infernalsuite/aswm/api/exceptions/WorldLoadedException.java b/api/src/main/java/com/infernalsuite/asp/api/exceptions/WorldLoadedException.java similarity index 85% rename from api/src/main/java/com/infernalsuite/aswm/api/exceptions/WorldLoadedException.java rename to api/src/main/java/com/infernalsuite/asp/api/exceptions/WorldLoadedException.java index 30a014458..646e9d355 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/exceptions/WorldLoadedException.java +++ b/api/src/main/java/com/infernalsuite/asp/api/exceptions/WorldLoadedException.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.api.exceptions; +package com.infernalsuite.asp.api.exceptions; /** * Exception thrown when a world is loaded diff --git a/api/src/main/java/com/infernalsuite/aswm/api/exceptions/WorldTooBigException.java b/api/src/main/java/com/infernalsuite/asp/api/exceptions/WorldTooBigException.java similarity index 86% rename from api/src/main/java/com/infernalsuite/aswm/api/exceptions/WorldTooBigException.java rename to api/src/main/java/com/infernalsuite/asp/api/exceptions/WorldTooBigException.java index 913b74864..a35c42553 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/exceptions/WorldTooBigException.java +++ b/api/src/main/java/com/infernalsuite/asp/api/exceptions/WorldTooBigException.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.api.exceptions; +package com.infernalsuite.asp.api.exceptions; /** * Exception thrown when a MC world is diff --git a/api/src/main/java/com/infernalsuite/aswm/api/loaders/SlimeLoader.java b/api/src/main/java/com/infernalsuite/asp/api/loaders/SlimeLoader.java similarity index 94% rename from api/src/main/java/com/infernalsuite/aswm/api/loaders/SlimeLoader.java rename to api/src/main/java/com/infernalsuite/asp/api/loaders/SlimeLoader.java index 722a63f41..6cc1ff276 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/loaders/SlimeLoader.java +++ b/api/src/main/java/com/infernalsuite/asp/api/loaders/SlimeLoader.java @@ -1,6 +1,6 @@ -package com.infernalsuite.aswm.api.loaders; +package com.infernalsuite.asp.api.loaders; -import com.infernalsuite.aswm.api.exceptions.UnknownWorldException; +import com.infernalsuite.asp.api.exceptions.UnknownWorldException; import java.io.IOException; import java.util.List; diff --git a/api/src/main/java/com/infernalsuite/aswm/api/utils/NibbleArray.java b/api/src/main/java/com/infernalsuite/asp/api/utils/NibbleArray.java similarity index 96% rename from api/src/main/java/com/infernalsuite/aswm/api/utils/NibbleArray.java rename to api/src/main/java/com/infernalsuite/asp/api/utils/NibbleArray.java index 89419ce79..23318a82b 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/utils/NibbleArray.java +++ b/api/src/main/java/com/infernalsuite/asp/api/utils/NibbleArray.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.api.utils; +package com.infernalsuite.asp.api.utils; /** * Credits to Minikloon for this class. diff --git a/api/src/main/java/com/infernalsuite/aswm/api/utils/SlimeFormat.java b/api/src/main/java/com/infernalsuite/asp/api/utils/SlimeFormat.java similarity index 87% rename from api/src/main/java/com/infernalsuite/aswm/api/utils/SlimeFormat.java rename to api/src/main/java/com/infernalsuite/asp/api/utils/SlimeFormat.java index d41e44779..4ada699f3 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/utils/SlimeFormat.java +++ b/api/src/main/java/com/infernalsuite/asp/api/utils/SlimeFormat.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.api.utils; +package com.infernalsuite.asp.api.utils; /** * Class containing some standards of the SRF. diff --git a/api/src/main/java/com/infernalsuite/aswm/api/world/SlimeChunk.java b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunk.java similarity index 97% rename from api/src/main/java/com/infernalsuite/aswm/api/world/SlimeChunk.java rename to api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunk.java index 770f79e8e..253c7cd97 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/world/SlimeChunk.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunk.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.api.world; +package com.infernalsuite.asp.api.world; import com.flowpowered.nbt.CompoundTag; diff --git a/api/src/main/java/com/infernalsuite/aswm/api/world/SlimeChunkSection.java b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunkSection.java similarity index 86% rename from api/src/main/java/com/infernalsuite/aswm/api/world/SlimeChunkSection.java rename to api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunkSection.java index 53b445086..312bd2645 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/world/SlimeChunkSection.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunkSection.java @@ -1,6 +1,6 @@ -package com.infernalsuite.aswm.api.world; +package com.infernalsuite.asp.api.world; -import com.infernalsuite.aswm.api.utils.NibbleArray; +import com.infernalsuite.asp.api.utils.NibbleArray; import com.flowpowered.nbt.CompoundTag; import org.jetbrains.annotations.Nullable; diff --git a/api/src/main/java/com/infernalsuite/aswm/api/world/SlimeWorld.java b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorld.java similarity index 92% rename from api/src/main/java/com/infernalsuite/aswm/api/world/SlimeWorld.java rename to api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorld.java index c86fd9dde..041dec9a9 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/world/SlimeWorld.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorld.java @@ -1,9 +1,9 @@ -package com.infernalsuite.aswm.api.world; +package com.infernalsuite.asp.api.world; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import com.flowpowered.nbt.CompoundTag; -import com.infernalsuite.aswm.api.exceptions.WorldAlreadyExistsException; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; import org.bukkit.persistence.PersistentDataHolder; import java.io.IOException; diff --git a/api/src/main/java/com/infernalsuite/aswm/api/world/SlimeWorldInstance.java b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java similarity index 58% rename from api/src/main/java/com/infernalsuite/aswm/api/world/SlimeWorldInstance.java rename to api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java index d8fc5c2cd..9b86a1265 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/world/SlimeWorldInstance.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java @@ -1,8 +1,7 @@ -package com.infernalsuite.aswm.api.world; +package com.infernalsuite.asp.api.world; import com.flowpowered.nbt.CompoundTag; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.loaders.SlimeLoader; import org.bukkit.World; public interface SlimeWorldInstance { @@ -13,7 +12,7 @@ public interface SlimeWorldInstance { SlimeWorld getSlimeWorldMirror(); - SlimePropertyMap getPropertyMap(); + com.infernalsuite.asp.api.world.properties.SlimePropertyMap getPropertyMap(); boolean isReadOnly(); diff --git a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/SlimeProperties.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperties.java similarity index 91% rename from api/src/main/java/com/infernalsuite/aswm/api/world/properties/SlimeProperties.java rename to api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperties.java index fb4f35e65..f5ef78955 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/SlimeProperties.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperties.java @@ -1,9 +1,9 @@ -package com.infernalsuite.aswm.api.world.properties; +package com.infernalsuite.asp.api.world.properties; -import com.infernalsuite.aswm.api.world.properties.type.SlimePropertyBoolean; -import com.infernalsuite.aswm.api.world.properties.type.SlimePropertyFloat; -import com.infernalsuite.aswm.api.world.properties.type.SlimePropertyInt; -import com.infernalsuite.aswm.api.world.properties.type.SlimePropertyString; +import com.infernalsuite.asp.api.world.properties.type.SlimePropertyBoolean; +import com.infernalsuite.asp.api.world.properties.type.SlimePropertyFloat; +import com.infernalsuite.asp.api.world.properties.type.SlimePropertyInt; +import com.infernalsuite.asp.api.world.properties.type.SlimePropertyString; import org.jetbrains.annotations.ApiStatus; /** diff --git a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/SlimeProperty.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperty.java similarity index 96% rename from api/src/main/java/com/infernalsuite/aswm/api/world/properties/SlimeProperty.java rename to api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperty.java index 9023fa1f8..58f576470 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/SlimeProperty.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperty.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.api.world.properties; +package com.infernalsuite.asp.api.world.properties; import com.flowpowered.nbt.CompoundMap; import com.flowpowered.nbt.Tag; diff --git a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/SlimePropertyMap.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimePropertyMap.java similarity index 97% rename from api/src/main/java/com/infernalsuite/aswm/api/world/properties/SlimePropertyMap.java rename to api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimePropertyMap.java index a537a4f74..706ec33e2 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/SlimePropertyMap.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimePropertyMap.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.api.world.properties; +package com.infernalsuite.asp.api.world.properties; import com.flowpowered.nbt.CompoundMap; import com.flowpowered.nbt.CompoundTag; diff --git a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyBoolean.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyBoolean.java similarity index 80% rename from api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyBoolean.java rename to api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyBoolean.java index 6b43ec4e8..aae436462 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyBoolean.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyBoolean.java @@ -1,6 +1,5 @@ -package com.infernalsuite.aswm.api.world.properties.type; +package com.infernalsuite.asp.api.world.properties.type; -import com.infernalsuite.aswm.api.world.properties.SlimeProperty; import com.flowpowered.nbt.ByteTag; import com.flowpowered.nbt.CompoundMap; import com.flowpowered.nbt.Tag; @@ -10,7 +9,7 @@ /** * A slime property of type boolean */ -public class SlimePropertyBoolean extends SlimeProperty { +public class SlimePropertyBoolean extends com.infernalsuite.asp.api.world.properties.SlimeProperty { public SlimePropertyBoolean(String nbtName, Boolean defaultValue) { super(nbtName, defaultValue); diff --git a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyFloat.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyFloat.java similarity index 81% rename from api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyFloat.java rename to api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyFloat.java index 5c0bfc00c..ff47a20ac 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyFloat.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyFloat.java @@ -1,16 +1,15 @@ -package com.infernalsuite.aswm.api.world.properties.type; +package com.infernalsuite.asp.api.world.properties.type; import com.flowpowered.nbt.CompoundMap; import com.flowpowered.nbt.FloatTag; import com.flowpowered.nbt.Tag; -import com.infernalsuite.aswm.api.world.properties.SlimeProperty; import java.util.function.Function; /** * A slime property of type float */ -public class SlimePropertyFloat extends SlimeProperty { +public class SlimePropertyFloat extends com.infernalsuite.asp.api.world.properties.SlimeProperty { public SlimePropertyFloat(String nbtName, Float defaultValue, Function validator) { super(nbtName, defaultValue, validator); diff --git a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyInt.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyInt.java similarity index 86% rename from api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyInt.java rename to api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyInt.java index 2a51125c6..2bb497b03 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyInt.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyInt.java @@ -1,6 +1,6 @@ -package com.infernalsuite.aswm.api.world.properties.type; +package com.infernalsuite.asp.api.world.properties.type; -import com.infernalsuite.aswm.api.world.properties.SlimeProperty; +import com.infernalsuite.asp.api.world.properties.SlimeProperty; import com.flowpowered.nbt.CompoundMap; import com.flowpowered.nbt.IntTag; import com.flowpowered.nbt.Tag; diff --git a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyString.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyString.java similarity index 79% rename from api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyString.java rename to api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyString.java index 02eeb058f..a446ea67d 100644 --- a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyString.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyString.java @@ -1,6 +1,5 @@ -package com.infernalsuite.aswm.api.world.properties.type; +package com.infernalsuite.asp.api.world.properties.type; -import com.infernalsuite.aswm.api.world.properties.SlimeProperty; import com.flowpowered.nbt.CompoundMap; import com.flowpowered.nbt.StringTag; import com.flowpowered.nbt.Tag; @@ -10,7 +9,7 @@ /** * A slime property of type integer */ -public class SlimePropertyString extends SlimeProperty { +public class SlimePropertyString extends com.infernalsuite.asp.api.world.properties.SlimeProperty { public SlimePropertyString(String nbtName, String defaultValue) { super(nbtName, defaultValue); diff --git a/build.gradle.kts b/build.gradle.kts index 3f4b9bfb8..8dce44724 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,30 +1,10 @@ plugins { - java - `maven-publish` + id("asp.paperweight-conventions") id("com.gradleup.shadow") version "8.3.5" apply false - id("io.papermc.paperweight.patcher") version "1.7.5" - id("org.kordamp.gradle.profiles") version "0.54.0" -} - -val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/" - -repositories { - mavenCentral() - maven(paperMavenPublicUrl) { - content { onlyForConfigurations(configurations.paperclip.name) } - } + java } allprojects { - apply(plugin = "java") - apply(plugin = "maven-publish") - - java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(21)) - } - } - repositories { mavenLocal() mavenCentral() @@ -37,53 +17,3 @@ allprojects { maven("https://oss.sonatype.org/content/repositories/snapshots/") } } - -dependencies { - remapper("net.fabricmc:tiny-remapper:0.10.3:fat") - decompiler("org.vineflower:vineflower:1.10.1") - paperclip("io.papermc:paperclip:3.0.3") -} - -subprojects { - tasks.withType { - options.encoding = Charsets.UTF_8.name() - options.release.set(21) - } - tasks.withType { - options.encoding = Charsets.UTF_8.name() - } - tasks.withType { - filteringCharset = Charsets.UTF_8.name() - } - - repositories { - mavenCentral() - maven(paperMavenPublicUrl) - } -} - -paperweight { - serverProject.set(project(":slimeworldmanager-server")) - - remapRepo.set(paperMavenPublicUrl) - decompileRepo.set(paperMavenPublicUrl) - - usePaperUpstream(providers.gradleProperty("paperRef")) { - withPaperPatcher { - apiPatchDir.set(layout.projectDirectory.dir("patches/api")) - apiOutputDir.set(layout.projectDirectory.dir("slimeworldmanager-api")) - - serverPatchDir.set(layout.projectDirectory.dir("patches/server")) - serverOutputDir.set(layout.projectDirectory.dir("slimeworldmanager-server")) - - patchTasks { - register("generatedApi") { - isBareDirectory.set(true) - upstreamDirPath.set("paper-api-generator/generated") - patchDir.set(layout.projectDirectory.dir("patches/generatedApi")) - outputDir.set(layout.projectDirectory.dir("paper-api-generator/generated")) - } - } - } - } -} diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 3a1cad604..d981c5b8d 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -1,8 +1,15 @@ plugins { + id("asp.base-conventions") + id("asp.publishing-conventions") } dependencies { compileOnly(project(":api")) - compileOnly(project(":slimeworldmanager-api")) - implementation("com.github.luben:zstd-jni:1.5.2-2") + compileOnly(project(":aspaper-api")) + implementation(libs.zstd) +} + +publishConfiguration { + name = "Advanced Slime Paper Core" + description = "Core logic for Advanced Slime Paper" } diff --git a/core/src/main/java/com/infernalsuite/aswm/SlimeLogger.java b/core/src/main/java/com/infernalsuite/asp/SlimeLogger.java similarity index 91% rename from core/src/main/java/com/infernalsuite/aswm/SlimeLogger.java rename to core/src/main/java/com/infernalsuite/asp/SlimeLogger.java index 02e6d6826..f71da1ed9 100644 --- a/core/src/main/java/com/infernalsuite/aswm/SlimeLogger.java +++ b/core/src/main/java/com/infernalsuite/asp/SlimeLogger.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm; +package com.infernalsuite.asp; import java.util.logging.Level; import java.util.logging.Logger; diff --git a/core/src/main/java/com/infernalsuite/aswm/Util.java b/core/src/main/java/com/infernalsuite/asp/Util.java similarity index 86% rename from core/src/main/java/com/infernalsuite/aswm/Util.java rename to core/src/main/java/com/infernalsuite/asp/Util.java index 643a5098c..1a3652ffe 100644 --- a/core/src/main/java/com/infernalsuite/aswm/Util.java +++ b/core/src/main/java/com/infernalsuite/asp/Util.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm; +package com.infernalsuite.asp; public final class Util { diff --git a/core/src/main/java/com/infernalsuite/aswm/pdc/FlowDataTypeRegistry.java b/core/src/main/java/com/infernalsuite/asp/pdc/FlowDataTypeRegistry.java similarity index 99% rename from core/src/main/java/com/infernalsuite/aswm/pdc/FlowDataTypeRegistry.java rename to core/src/main/java/com/infernalsuite/asp/pdc/FlowDataTypeRegistry.java index 2fb42c8e3..f70ab0a8a 100644 --- a/core/src/main/java/com/infernalsuite/aswm/pdc/FlowDataTypeRegistry.java +++ b/core/src/main/java/com/infernalsuite/asp/pdc/FlowDataTypeRegistry.java @@ -1,9 +1,9 @@ -package com.infernalsuite.aswm.pdc; +package com.infernalsuite.asp.pdc; import com.flowpowered.nbt.*; import com.google.common.base.Preconditions; import com.google.common.primitives.Primitives; -import com.infernalsuite.aswm.api.SlimeNMSBridge; +import com.infernalsuite.asp.api.SlimeNMSBridge; import net.kyori.adventure.util.Services; import org.bukkit.persistence.PersistentDataContainer; diff --git a/core/src/main/java/com/infernalsuite/aswm/pdc/FlowPersistentDataContainer.java b/core/src/main/java/com/infernalsuite/asp/pdc/FlowPersistentDataContainer.java similarity index 99% rename from core/src/main/java/com/infernalsuite/aswm/pdc/FlowPersistentDataContainer.java rename to core/src/main/java/com/infernalsuite/asp/pdc/FlowPersistentDataContainer.java index deb69bfb1..5712bc1b6 100644 --- a/core/src/main/java/com/infernalsuite/aswm/pdc/FlowPersistentDataContainer.java +++ b/core/src/main/java/com/infernalsuite/asp/pdc/FlowPersistentDataContainer.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.pdc; +package com.infernalsuite.asp.pdc; import com.flowpowered.nbt.CompoundMap; import com.flowpowered.nbt.CompoundTag; diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/SlimeWorldReader.java b/core/src/main/java/com/infernalsuite/asp/serialization/SlimeWorldReader.java new file mode 100644 index 000000000..a6e166cac --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/SlimeWorldReader.java @@ -0,0 +1,8 @@ +package com.infernalsuite.asp.serialization; + +import com.infernalsuite.asp.api.world.SlimeWorld; + +public interface SlimeWorldReader { + + SlimeWorld readFromData(T data); +} diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/anvil/AnvilImportData.java b/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilImportData.java similarity index 60% rename from core/src/main/java/com/infernalsuite/aswm/serialization/anvil/AnvilImportData.java rename to core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilImportData.java index cb05608f4..51d6c6512 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/anvil/AnvilImportData.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilImportData.java @@ -1,6 +1,6 @@ -package com.infernalsuite.aswm.serialization.anvil; +package com.infernalsuite.asp.serialization.anvil; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.loaders.SlimeLoader; import org.jetbrains.annotations.Nullable; import java.io.File; diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/anvil/AnvilWorldReader.java b/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java similarity index 92% rename from core/src/main/java/com/infernalsuite/aswm/serialization/anvil/AnvilWorldReader.java rename to core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java index af0119613..4bf356bb5 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/anvil/AnvilWorldReader.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.serialization.anvil; +package com.infernalsuite.asp.serialization.anvil; import com.flowpowered.nbt.CompoundMap; import com.flowpowered.nbt.CompoundTag; @@ -6,18 +6,14 @@ import com.flowpowered.nbt.ListTag; import com.flowpowered.nbt.TagType; import com.flowpowered.nbt.stream.NBTInputStream; -import com.infernalsuite.aswm.Util; -import com.infernalsuite.aswm.api.exceptions.InvalidWorldException; -import com.infernalsuite.aswm.api.utils.NibbleArray; -import com.infernalsuite.aswm.api.world.SlimeChunk; -import com.infernalsuite.aswm.api.world.SlimeChunkSection; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.api.world.properties.SlimeProperties; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; -import com.infernalsuite.aswm.serialization.SlimeWorldReader; -import com.infernalsuite.aswm.skeleton.SkeletonSlimeWorld; -import com.infernalsuite.aswm.skeleton.SlimeChunkSectionSkeleton; -import com.infernalsuite.aswm.skeleton.SlimeChunkSkeleton; +import com.infernalsuite.asp.Util; +import com.infernalsuite.asp.api.exceptions.InvalidWorldException; +import com.infernalsuite.asp.api.utils.NibbleArray; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeChunkSection; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.properties.SlimeProperties; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; @@ -26,9 +22,7 @@ import java.nio.ByteOrder; import java.nio.file.Files; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.regex.Pattern; @@ -36,7 +30,7 @@ import java.util.zip.GZIPInputStream; import java.util.zip.InflaterInputStream; -public class AnvilWorldReader implements SlimeWorldReader { +public class AnvilWorldReader implements com.infernalsuite.asp.serialization.SlimeWorldReader { public static final int V1_16 = 2566; public static final int V1_16_5 = 2586; @@ -131,7 +125,7 @@ public SlimeWorld readFromData(AnvilImportData importData) { propertyMap.setValue(SlimeProperties.SPAWN_Y, data.y); propertyMap.setValue(SlimeProperties.SPAWN_Z, data.z); - return new SkeletonSlimeWorld(importData.newName(), importData.loader(), true, chunks, new CompoundTag("", extraData), propertyMap, worldVersion); + return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld(importData.newName(), importData.loader(), true, chunks, new CompoundTag("", extraData), propertyMap, worldVersion); } catch (IOException | InvalidWorldException e) { throw new RuntimeException(e); @@ -379,7 +373,7 @@ private static SlimeChunk readChunk(CompoundTag compound, int worldVersion) { NibbleArray skyLightArray = sectionTag.getValue().containsKey("SkyLight") ? new NibbleArray(sectionTag.getByteArrayValue("SkyLight").get()) : null; // There is no need to do any custom processing here. - sectionArray[index - minSectionY] = new SlimeChunkSectionSkeleton(/*paletteTag, blockStatesArray,*/ blockStatesTag, biomeTag, blockLightArray, skyLightArray); + sectionArray[index - minSectionY] = new com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton(/*paletteTag, blockStatesArray,*/ blockStatesTag, biomeTag, blockLightArray, skyLightArray); } CompoundTag extraTag = new CompoundTag("", new CompoundMap()); @@ -387,7 +381,7 @@ private static SlimeChunk readChunk(CompoundTag compound, int worldVersion) { for (SlimeChunkSection section : sectionArray) { if (section != null) { // Chunk isn't empty - return new SlimeChunkSkeleton(chunkX, chunkZ, sectionArray, heightMapsCompound, tileEntities, entities, extraTag, null); + return new com.infernalsuite.asp.skeleton.SlimeChunkSkeleton(chunkX, chunkZ, sectionArray, heightMapsCompound, tileEntities, entities, extraTag, null); } } diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/ChunkPruner.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/ChunkPruner.java similarity index 86% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/ChunkPruner.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/ChunkPruner.java index 389c6f6e5..abf90f095 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/ChunkPruner.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/ChunkPruner.java @@ -1,12 +1,12 @@ -package com.infernalsuite.aswm.serialization.slime; +package com.infernalsuite.asp.serialization.slime; import com.flowpowered.nbt.CompoundTag; import com.flowpowered.nbt.ListTag; -import com.infernalsuite.aswm.api.world.SlimeChunk; -import com.infernalsuite.aswm.api.world.SlimeChunkSection; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.api.world.properties.SlimeProperties; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeChunkSection; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.properties.SlimeProperties; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import java.util.List; diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/SlimeSerializer.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/SlimeSerializer.java similarity index 95% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/SlimeSerializer.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/SlimeSerializer.java index b2ed62c08..5e0ccd2e3 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/SlimeSerializer.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/SlimeSerializer.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.serialization.slime; +package com.infernalsuite.asp.serialization.slime; import com.flowpowered.nbt.CompoundMap; import com.flowpowered.nbt.CompoundTag; @@ -7,11 +7,11 @@ import com.flowpowered.nbt.stream.NBTInputStream; import com.flowpowered.nbt.stream.NBTOutputStream; import com.github.luben.zstd.Zstd; -import com.infernalsuite.aswm.api.utils.SlimeFormat; -import com.infernalsuite.aswm.api.world.SlimeChunk; -import com.infernalsuite.aswm.api.world.SlimeChunkSection; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.api.utils.SlimeFormat; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeChunkSection; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/SlimeWorldReaderRegistry.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java similarity index 69% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/SlimeWorldReaderRegistry.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java index b0d734e81..f8f19e057 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/SlimeWorldReaderRegistry.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java @@ -1,15 +1,15 @@ -package com.infernalsuite.aswm.serialization.slime.reader; - -import com.infernalsuite.aswm.api.exceptions.CorruptedWorldException; -import com.infernalsuite.aswm.api.exceptions.NewerFormatException; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.api.utils.SlimeFormat; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v11.v11WorldFormat; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v12.v12WorldFormat; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.v1_9WorldFormat; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v10.v10WorldFormat; +package com.infernalsuite.asp.serialization.slime.reader; + +import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; +import com.infernalsuite.asp.api.exceptions.NewerFormatException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.utils.SlimeFormat; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.serialization.slime.reader.impl.v11.v11WorldFormat; +import com.infernalsuite.asp.serialization.slime.reader.impl.v12.v12WorldFormat; +import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9WorldFormat; +import com.infernalsuite.asp.serialization.slime.reader.impl.v10.v10WorldFormat; import java.io.ByteArrayInputStream; import java.io.DataInputStream; diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/VersionedByteSlimeWorldReader.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/VersionedByteSlimeWorldReader.java similarity index 54% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/VersionedByteSlimeWorldReader.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/VersionedByteSlimeWorldReader.java index e6507f019..4c1d95357 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/VersionedByteSlimeWorldReader.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/VersionedByteSlimeWorldReader.java @@ -1,9 +1,9 @@ -package com.infernalsuite.aswm.serialization.slime.reader; +package com.infernalsuite.asp.serialization.slime.reader; -import com.infernalsuite.aswm.api.exceptions.CorruptedWorldException; -import com.infernalsuite.aswm.api.exceptions.NewerFormatException; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; +import com.infernalsuite.asp.api.exceptions.NewerFormatException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import org.jetbrains.annotations.Nullable; import java.io.DataInputStream; diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/SimpleWorldFormat.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/SimpleWorldFormat.java similarity index 51% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/SimpleWorldFormat.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/SimpleWorldFormat.java index 4069f0dfa..8d4c60dc8 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/SimpleWorldFormat.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/SimpleWorldFormat.java @@ -1,12 +1,11 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl; +package com.infernalsuite.asp.serialization.slime.reader.impl; -import com.infernalsuite.aswm.api.exceptions.CorruptedWorldException; -import com.infernalsuite.aswm.api.exceptions.NewerFormatException; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.serialization.SlimeWorldReader; -import com.infernalsuite.aswm.serialization.slime.reader.VersionedByteSlimeWorldReader; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; +import com.infernalsuite.asp.api.exceptions.NewerFormatException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.serialization.slime.reader.VersionedByteSlimeWorldReader; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import org.jetbrains.annotations.Nullable; import java.io.DataInputStream; @@ -14,10 +13,10 @@ public class SimpleWorldFormat implements VersionedByteSlimeWorldReader { - private final SlimeWorldReader data; + private final com.infernalsuite.asp.serialization.SlimeWorldReader data; private final VersionedByteSlimeWorldReader reader; - public SimpleWorldFormat(SlimeWorldReader data, VersionedByteSlimeWorldReader reader) { + public SimpleWorldFormat(com.infernalsuite.asp.serialization.SlimeWorldReader data, VersionedByteSlimeWorldReader reader) { this.data = data; this.reader = reader; } diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java similarity index 86% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java index 8ece7660e..3baf1fb1b 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v10; +package com.infernalsuite.asp.serialization.slime.reader.impl.v10; import com.flowpowered.nbt.CompoundMap; import com.flowpowered.nbt.CompoundTag; @@ -7,19 +7,16 @@ import com.flowpowered.nbt.ListTag; import com.flowpowered.nbt.stream.NBTInputStream; import com.github.luben.zstd.Zstd; -import com.infernalsuite.aswm.Util; -import com.infernalsuite.aswm.api.exceptions.CorruptedWorldException; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.serialization.slime.reader.VersionedByteSlimeWorldReader; -import com.infernalsuite.aswm.skeleton.SkeletonSlimeWorld; -import com.infernalsuite.aswm.skeleton.SlimeChunkSectionSkeleton; -import com.infernalsuite.aswm.skeleton.SlimeChunkSkeleton; -import com.infernalsuite.aswm.api.utils.NibbleArray; -import com.infernalsuite.aswm.api.world.SlimeChunk; -import com.infernalsuite.aswm.api.world.SlimeChunkSection; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.api.world.properties.SlimeProperties; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.Util; +import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.serialization.slime.reader.VersionedByteSlimeWorldReader; +import com.infernalsuite.asp.api.utils.NibbleArray; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeChunkSection; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.properties.SlimeProperties; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; @@ -29,9 +26,7 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Optional; @@ -101,7 +96,7 @@ public SlimeWorld deserializeWorld(byte version, SlimeLoader loader, String worl worldPropertyMap.merge(propertyMap); // Override world properties } - return new SkeletonSlimeWorld(worldName, loader, readOnly, chunks, + return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld(worldName, loader, readOnly, chunks, extraCompound, worldPropertyMap, worldVersion @@ -161,7 +156,7 @@ private static Long2ObjectMap readChunks(SlimePropertyMap slimePrope chunkData.read(biomeData); com.flowpowered.nbt.CompoundTag biomeTag = readCompound(biomeData); - chunkSectionArray[sectionId] = new SlimeChunkSectionSkeleton( + chunkSectionArray[sectionId] = new com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton( blockStateTag, biomeTag, blockLightArray, @@ -169,7 +164,7 @@ private static Long2ObjectMap readChunks(SlimePropertyMap slimePrope } chunkMap.put(Util.chunkPosition(x, z), - new SlimeChunkSkeleton(x, z, chunkSectionArray, heightMaps, new ArrayList<>(), new ArrayList<>(), new CompoundTag("", new CompoundMap()), null) + new com.infernalsuite.asp.skeleton.SlimeChunkSkeleton(x, z, chunkSectionArray, heightMaps, new ArrayList<>(), new ArrayList<>(), new CompoundTag("", new CompoundMap()), null) ); } } diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10WorldFormat.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10WorldFormat.java new file mode 100644 index 000000000..033377a17 --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10WorldFormat.java @@ -0,0 +1,8 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v10; + +public interface v10WorldFormat { + + // Latest, returns same + com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat FORMAT = new com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat<>(data -> data, new v10SlimeWorldDeSerializer()); + +} diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java similarity index 80% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java index 0cc8bb099..5e664d1d2 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java @@ -1,24 +1,20 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v11; +package com.infernalsuite.asp.serialization.slime.reader.impl.v11; import com.flowpowered.nbt.CompoundMap; import com.flowpowered.nbt.CompoundTag; import com.flowpowered.nbt.ListTag; import com.flowpowered.nbt.stream.NBTInputStream; import com.github.luben.zstd.Zstd; -import com.infernalsuite.aswm.Util; -import com.infernalsuite.aswm.api.exceptions.CorruptedWorldException; -import com.infernalsuite.aswm.api.exceptions.NewerFormatException; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.api.utils.NibbleArray; -import com.infernalsuite.aswm.api.world.SlimeChunk; -import com.infernalsuite.aswm.api.world.SlimeChunkSection; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.api.world.properties.SlimeProperties; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; -import com.infernalsuite.aswm.serialization.slime.reader.VersionedByteSlimeWorldReader; -import com.infernalsuite.aswm.skeleton.SkeletonSlimeWorld; -import com.infernalsuite.aswm.skeleton.SlimeChunkSectionSkeleton; -import com.infernalsuite.aswm.skeleton.SlimeChunkSkeleton; +import com.infernalsuite.asp.Util; +import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; +import com.infernalsuite.asp.api.exceptions.NewerFormatException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.utils.NibbleArray; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeChunkSection; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.properties.SlimeProperties; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import org.jetbrains.annotations.Nullable; @@ -27,12 +23,10 @@ import java.io.DataInputStream; import java.io.IOException; import java.nio.ByteOrder; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Optional; -public class v11SlimeWorldDeSerializer implements VersionedByteSlimeWorldReader { +public class v11SlimeWorldDeSerializer implements com.infernalsuite.asp.serialization.slime.reader.VersionedByteSlimeWorldReader { public static final int ARRAY_SIZE = 16 * 16 * 16 / (8 / 4); @@ -56,7 +50,7 @@ public SlimeWorld deserializeWorld(byte version, @Nullable SlimeLoader loader, S worldPropertyMap.merge(propertyMap); } - return new SkeletonSlimeWorld(worldName, loader, readOnly, chunks, extraTag, worldPropertyMap, worldVersion); + return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld(worldName, loader, readOnly, chunks, extraTag, worldPropertyMap, worldVersion); } private static Long2ObjectMap readChunks(SlimePropertyMap slimePropertyMap, byte[] chunkBytes) throws IOException { @@ -106,7 +100,7 @@ private static Long2ObjectMap readChunks(SlimePropertyMap slimePrope chunkData.read(biomeData); CompoundTag biomeTag = readCompound(biomeData); - chunkSections[sectionId] = new SlimeChunkSectionSkeleton(blockStateTag, biomeTag, blockLightArray, skyLightArray); + chunkSections[sectionId] = new com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton(blockStateTag, biomeTag, blockLightArray, skyLightArray); } // HeightMaps @@ -141,7 +135,7 @@ private static Long2ObjectMap readChunks(SlimePropertyMap slimePrope List serializedEntities = ((ListTag) entitiesCompound.getValue().get("entities")).getValue(); chunkMap.put(Util.chunkPosition(x, z), - new SlimeChunkSkeleton(x, z, chunkSections, heightMaps, serializedTileEntities, serializedEntities, new CompoundTag("", new CompoundMap()), null)); + new com.infernalsuite.asp.skeleton.SlimeChunkSkeleton(x, z, chunkSections, heightMaps, serializedTileEntities, serializedEntities, new CompoundTag("", new CompoundMap()), null)); } return chunkMap; } diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11WorldFormat.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11WorldFormat.java new file mode 100644 index 000000000..779eeb28b --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11WorldFormat.java @@ -0,0 +1,7 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v11; + +public interface v11WorldFormat { + + com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat FORMAT = new com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat<>(data -> data, new v11SlimeWorldDeSerializer()); + +} diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v12/v12SlimeWorldDeSerializer.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12SlimeWorldDeSerializer.java similarity index 80% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v12/v12SlimeWorldDeSerializer.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12SlimeWorldDeSerializer.java index cb57b94a4..3672cdcb4 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v12/v12SlimeWorldDeSerializer.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12SlimeWorldDeSerializer.java @@ -1,24 +1,20 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v12; +package com.infernalsuite.asp.serialization.slime.reader.impl.v12; import com.flowpowered.nbt.CompoundMap; import com.flowpowered.nbt.CompoundTag; import com.flowpowered.nbt.ListTag; import com.flowpowered.nbt.stream.NBTInputStream; import com.github.luben.zstd.Zstd; -import com.infernalsuite.aswm.Util; -import com.infernalsuite.aswm.api.exceptions.CorruptedWorldException; -import com.infernalsuite.aswm.api.exceptions.NewerFormatException; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.api.utils.NibbleArray; -import com.infernalsuite.aswm.api.world.SlimeChunk; -import com.infernalsuite.aswm.api.world.SlimeChunkSection; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.api.world.properties.SlimeProperties; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; -import com.infernalsuite.aswm.serialization.slime.reader.VersionedByteSlimeWorldReader; -import com.infernalsuite.aswm.skeleton.SkeletonSlimeWorld; -import com.infernalsuite.aswm.skeleton.SlimeChunkSectionSkeleton; -import com.infernalsuite.aswm.skeleton.SlimeChunkSkeleton; +import com.infernalsuite.asp.Util; +import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; +import com.infernalsuite.asp.api.exceptions.NewerFormatException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.utils.NibbleArray; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeChunkSection; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.properties.SlimeProperties; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import org.jetbrains.annotations.Nullable; @@ -27,12 +23,10 @@ import java.io.DataInputStream; import java.io.IOException; import java.nio.ByteOrder; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Optional; -public class v12SlimeWorldDeSerializer implements VersionedByteSlimeWorldReader { +public class v12SlimeWorldDeSerializer implements com.infernalsuite.asp.serialization.slime.reader.VersionedByteSlimeWorldReader { public static final int ARRAY_SIZE = 16 * 16 * 16 / (8 / 4); @@ -56,7 +50,7 @@ public SlimeWorld deserializeWorld(byte version, @Nullable SlimeLoader loader, S worldPropertyMap.merge(propertyMap); } - return new SkeletonSlimeWorld(worldName, loader, readOnly, chunks, extraTag, worldPropertyMap, worldVersion); + return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld(worldName, loader, readOnly, chunks, extraTag, worldPropertyMap, worldVersion); } private static Long2ObjectMap readChunks(SlimePropertyMap slimePropertyMap, byte[] chunkBytes) throws IOException { @@ -106,7 +100,7 @@ private static Long2ObjectMap readChunks(SlimePropertyMap slimePrope chunkData.read(biomeData); CompoundTag biomeTag = readCompound(biomeData); - chunkSections[sectionId] = new SlimeChunkSectionSkeleton(blockStateTag, biomeTag, blockLightArray, skyLightArray); + chunkSections[sectionId] = new com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton(blockStateTag, biomeTag, blockLightArray, skyLightArray); } // HeightMaps @@ -141,7 +135,7 @@ private static Long2ObjectMap readChunks(SlimePropertyMap slimePrope } chunkMap.put(Util.chunkPosition(x, z), - new SlimeChunkSkeleton(x, z, chunkSections, heightMaps, serializedTileEntities, serializedEntities, extra, null)); + new com.infernalsuite.asp.skeleton.SlimeChunkSkeleton(x, z, chunkSections, heightMaps, serializedTileEntities, serializedEntities, extra, null)); } return chunkMap; } diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12WorldFormat.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12WorldFormat.java new file mode 100644 index 000000000..c4a7a0ad8 --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12WorldFormat.java @@ -0,0 +1,7 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v12; + +public interface v12WorldFormat { + + com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat FORMAT = new com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat<>(data -> data, new v12SlimeWorldDeSerializer()); + +} diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/Upgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/Upgrade.java similarity index 50% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/Upgrade.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/Upgrade.java index fecd95b54..62f4254e6 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/Upgrade.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/Upgrade.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9; +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; public interface Upgrade { diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java similarity index 83% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java index e1ee0b209..4e35d3ddd 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java @@ -1,15 +1,12 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.upgrade; +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; import com.flowpowered.nbt.CompoundTag; import com.flowpowered.nbt.StringTag; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.Upgrade; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld; import java.util.HashMap; import java.util.Map; -public class v1_11WorldUpgrade implements Upgrade { +public class v1_11WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { private static Map oldToNewMap = new HashMap<>(); private static Map newToOldMap = new HashMap<>(); @@ -50,9 +47,9 @@ private static void rename(String oldName, String newName) { } @Override - public void upgrade(v1_9SlimeWorld world) { + public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld world) { // 1.11 changed the way Tile Entities are named - for (v1_9SlimeChunk chunk : world.chunks.values()) { + for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : world.chunks.values()) { for (CompoundTag entityTag : chunk.tileEntities) { String oldType = entityTag.getAsStringTag("id").get().getValue(); String newType = oldToNewMap.get(oldType); diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java similarity index 76% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java index afc9238ee..14d613582 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java @@ -1,29 +1,25 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.upgrade; +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; import com.flowpowered.nbt.*; -import com.infernalsuite.aswm.api.SlimeNMSBridge; -import com.infernalsuite.aswm.api.utils.NibbleArray; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.Upgrade; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld; +import com.infernalsuite.asp.api.SlimeNMSBridge; +import com.infernalsuite.asp.api.utils.NibbleArray; import org.bukkit.ChatColor; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; -public class v1_13WorldUpgrade implements Upgrade { +public class v1_13WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { @Override - public void upgrade(v1_9SlimeWorld world) { + public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld world) { Logger.getLogger("v1_13WorldUpgrade").warning("Updating world to the 1.13 format. This may take a while."); - List chunks = new ArrayList<>(world.chunks.values()); + List chunks = new ArrayList<>(world.chunks.values()); long lastMessage = -1; for (int i = 0; i < chunks.size(); i++) { - v1_9SlimeChunk chunk = chunks.get(i); + com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk = chunks.get(i); // The world upgrade process is a very complex task, and there's already a // built-in upgrade tool inside the server, so we can simply use it @@ -47,7 +43,7 @@ public void upgrade(v1_9SlimeWorld world) { chunkTag = globalTag.getAsCompoundTag("Level").get(); // Chunk sections - v1_9SlimeChunkSection[] newSections = new v1_9SlimeChunkSection[16]; + com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[] newSections = new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[16]; ListTag serializedSections = (ListTag) chunkTag.getAsListTag("Sections").get(); for (CompoundTag sectionTag : serializedSections.getValue()) { @@ -59,7 +55,7 @@ public void upgrade(v1_9SlimeWorld world) { int index = sectionTag.getIntValue("Y").get(); - v1_9SlimeChunkSection section = new v1_9SlimeChunkSection(null, null, palette, blockStates, null, null, blockLight, skyLight); + com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection section = new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection(null, null, palette, blockStates, null, null, blockLight, skyLight); newSections[index] = section; } @@ -87,11 +83,11 @@ public void upgrade(v1_9SlimeWorld world) { } } - private ListTag serializeSections(v1_9SlimeChunkSection[] sections) { + private ListTag serializeSections(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[] sections) { ListTag sectionList = new ListTag<>("Sections", TagType.TAG_COMPOUND, new ArrayList<>()); for (int i = 0; i < sections.length; i++) { - v1_9SlimeChunkSection section = sections[i]; + com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection section = sections[i]; if (section != null) { CompoundTag sectionTag = new CompoundTag(i + "", new CompoundMap()); diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java similarity index 93% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java index be0d1d931..edd60c393 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java @@ -1,14 +1,12 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.upgrade; +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; import com.flowpowered.nbt.*; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.Upgrade; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld; +import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection; +import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld; import java.util.*; -public class v1_14WorldUpgrade implements Upgrade { +public class v1_14WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { private static final int[] VILLAGER_XP = { 0, 10, 50, 100, 150 }; @@ -33,7 +31,7 @@ private static void rename(String oldName, String newName) { @Override public void upgrade(v1_9SlimeWorld world) { - for (v1_9SlimeChunk chunk : new ArrayList<>(world.chunks.values())) { + for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : new ArrayList<>(world.chunks.values())) { // Update renamed blocks for (int sectionIndex = 0; sectionIndex < chunk.sections.length; sectionIndex++) { v1_9SlimeChunkSection section = chunk.sections[sectionIndex]; @@ -144,7 +142,7 @@ private String getVillagerProfession(int profession, int career) { (profession == 4 ? (career == 2 ? "minecraft:leatherworker" : "minecraft:butcher") : (profession == 5 ? "minecraft:nitwit" : "minecraft:none"))))); } - private void updateBlockEntities(v1_9SlimeChunk chunk, int sectionIndex, int paletteIndex, String oldName, String newName) { + private void updateBlockEntities(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk, int sectionIndex, int paletteIndex, String oldName, String newName) { if (chunk.tileEntities != null) { v1_9SlimeChunkSection section = chunk.sections[sectionIndex]; long[] blockData = section.blockStates; diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java similarity index 88% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java index e83bfe63b..520f88142 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java @@ -1,16 +1,14 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.upgrade; +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; import com.flowpowered.nbt.CompoundTag; import com.flowpowered.nbt.LongArrayTag; import com.flowpowered.nbt.Tag; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.Upgrade; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld; +import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection; +import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld; import java.util.Arrays; -public class v1_16WorldUpgrade implements Upgrade { +public class v1_16WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { private static final int[] MULTIPLY_DE_BRUIJN_BIT_POSITION = new int[]{ 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 @@ -18,7 +16,7 @@ public class v1_16WorldUpgrade implements Upgrade { @Override public void upgrade(v1_9SlimeWorld world) { - for (v1_9SlimeChunk chunk : world.chunks.values()) { + for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : world.chunks.values()) { // Add padding to height maps and block states CompoundTag heightMaps = chunk.heightMap; diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java similarity index 70% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java index 0149f6dc0..0455b9c33 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java @@ -1,22 +1,18 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.upgrade; +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; import com.flowpowered.nbt.CompoundMap; import com.flowpowered.nbt.CompoundTag; import com.flowpowered.nbt.StringTag; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.Upgrade; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld; import java.util.List; import java.util.Optional; -public class v1_17WorldUpgrade implements Upgrade { +public class v1_17WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { @Override - public void upgrade(v1_9SlimeWorld world) { - for (v1_9SlimeChunk chunk : world.chunks.values()) { - for (v1_9SlimeChunkSection section : chunk.sections) { + public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld world) { + for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : world.chunks.values()) { + for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection section : chunk.sections) { if (section == null) { continue; } diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java similarity index 93% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java index 009a79cd0..c1e0bc799 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java @@ -1,14 +1,10 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.upgrade; +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; import com.flowpowered.nbt.*; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.Upgrade; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld; import java.util.*; -public class v1_18WorldUpgrade implements Upgrade { +public class v1_18WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { private static final String[] BIOMES_BY_ID = new String[256]; // rip datapacks @@ -146,8 +142,8 @@ public class v1_18WorldUpgrade implements Upgrade { } @Override - public void upgrade(v1_9SlimeWorld world) { - for (v1_9SlimeChunk chunk : world.chunks.values()) { + public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld world) { + for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : world.chunks.values()) { // SpawnerSpawnDataFix for (CompoundTag tileEntity : chunk.tileEntities) { @@ -205,9 +201,9 @@ public void upgrade(v1_9SlimeWorld world) { CompoundTag[] tags = createBiomeSections(chunk.biomes, false, 0); - v1_9SlimeChunkSection[] sections = chunk.sections; + com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[] sections = chunk.sections; for (int i = 0; i < sections.length; i++) { - v1_9SlimeChunkSection section = sections[i]; + com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection section = sections[i]; if (section == null) { continue; } @@ -217,13 +213,13 @@ public void upgrade(v1_9SlimeWorld world) { section.biomeTag = tags[i]; } - v1_9SlimeChunkSection[] shiftedSections = new v1_9SlimeChunkSection[sections.length + 4]; + com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[] shiftedSections = new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[sections.length + 4]; System.arraycopy(sections, 0, shiftedSections, 4, sections.length); chunk.sections = shiftedSections; // Shift all sections up 4 - v1_9SlimeChunkSection[] sectionArray = chunk.sections; + com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[] sectionArray = chunk.sections; CompoundMap emptyBiomes = new CompoundMap(); emptyBiomes.put("palette", new ListTag<>("palette", TagType.TAG_STRING, List.of(new StringTag("", "minecraft:plains")))); @@ -234,9 +230,9 @@ public void upgrade(v1_9SlimeWorld world) { CompoundTag blockTag = new CompoundTag("", blocks); CompoundTag emptyBiomesTag = new CompoundTag("", emptyBiomes); for (int i = 0; i < sectionArray.length; i++) { - v1_9SlimeChunkSection section = sectionArray[i]; + com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection section = sectionArray[i]; if (section == null) { - sectionArray[i] = new v1_9SlimeChunkSection( + sectionArray[i] = new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection( null, null, null, diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java similarity index 76% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java index b5b48ca2d..bc1a5c6b2 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.upgrade; +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; import com.flowpowered.nbt.CompoundMap; import com.flowpowered.nbt.CompoundTag; @@ -6,18 +6,16 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonSyntaxException; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.Upgrade; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld; +import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld; -public class v1_9WorldUpgrade implements Upgrade { +public class v1_9WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { private static final JsonParser PARSER = new JsonParser(); @Override public void upgrade(v1_9SlimeWorld world) { // In 1.9, all signs must be formatted using JSON - for (v1_9SlimeChunk chunk : world.chunks.values()) { + for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : world.chunks.values()) { for (CompoundTag entityTag : chunk.tileEntities) { String type = entityTag.getAsStringTag("id").get().getValue(); diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java similarity index 94% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java index 92fe6bbfb..306f54fdd 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9; +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; import com.flowpowered.nbt.CompoundTag; diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java similarity index 89% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java index 80f8fbb65..5379c3dbf 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java @@ -1,8 +1,8 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9; +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; import com.flowpowered.nbt.CompoundTag; import com.flowpowered.nbt.ListTag; -import com.infernalsuite.aswm.api.utils.NibbleArray; +import com.infernalsuite.asp.api.utils.NibbleArray; public class v1_9SlimeChunkSection { diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java similarity index 83% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java index cc59043a0..0864c6b92 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java @@ -1,8 +1,8 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9; +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; import com.flowpowered.nbt.CompoundTag; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; public class v1_9SlimeWorld { diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java similarity index 97% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java index 8401801fc..07b7e24d3 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9; +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; import com.flowpowered.nbt.CompoundMap; import com.flowpowered.nbt.CompoundTag; @@ -9,13 +9,12 @@ import com.flowpowered.nbt.TagType; import com.flowpowered.nbt.stream.NBTInputStream; import com.github.luben.zstd.Zstd; -import com.infernalsuite.aswm.SlimeLogger; -import com.infernalsuite.aswm.Util; -import com.infernalsuite.aswm.api.exceptions.CorruptedWorldException; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.serialization.slime.reader.VersionedByteSlimeWorldReader; -import com.infernalsuite.aswm.api.utils.NibbleArray; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.SlimeLogger; +import com.infernalsuite.asp.Util; +import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.utils.NibbleArray; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; @@ -30,7 +29,7 @@ import java.util.List; import java.util.Optional; -class v1_9SlimeWorldDeserializer implements VersionedByteSlimeWorldReader { +class v1_9SlimeWorldDeserializer implements com.infernalsuite.asp.serialization.slime.reader.VersionedByteSlimeWorldReader { @Override public v1_9SlimeWorld deserializeWorld(byte version, SlimeLoader loader, String worldName, DataInputStream dataStream, SlimePropertyMap propertyMap, boolean readOnly) diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9WorldFormat.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9WorldFormat.java new file mode 100644 index 000000000..62bf97f07 --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9WorldFormat.java @@ -0,0 +1,7 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; + +public interface v1_9WorldFormat { + + com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat FORMAT = new com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat<>(new v1_v9SlimeConverter(), new v1_9SlimeWorldDeserializer()); + +} diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java similarity index 71% rename from core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java rename to core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java index 5316bb507..f5a06898e 100644 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java @@ -1,14 +1,10 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9; +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; import com.flowpowered.nbt.*; -import com.infernalsuite.aswm.serialization.SlimeWorldReader; -import com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9.upgrade.*; -import com.infernalsuite.aswm.skeleton.SkeletonSlimeWorld; -import com.infernalsuite.aswm.skeleton.SlimeChunkSectionSkeleton; -import com.infernalsuite.aswm.skeleton.SlimeChunkSkeleton; -import com.infernalsuite.aswm.api.world.SlimeChunk; -import com.infernalsuite.aswm.api.world.SlimeChunkSection; -import com.infernalsuite.aswm.api.world.SlimeWorld; +import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.*; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeChunkSection; +import com.infernalsuite.asp.api.world.SlimeWorld; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; @@ -17,18 +13,18 @@ import java.util.Map; import java.util.logging.Logger; -class v1_v9SlimeConverter implements SlimeWorldReader { +class v1_v9SlimeConverter implements com.infernalsuite.asp.serialization.SlimeWorldReader { public static final Map UPGRADES = new HashMap<>(); static { - UPGRADES.put((byte) 0x02, new v1_9WorldUpgrade()); - UPGRADES.put((byte) 0x03, new v1_11WorldUpgrade()); - UPGRADES.put((byte) 0x04, new v1_13WorldUpgrade()); - UPGRADES.put((byte) 0x05, new v1_14WorldUpgrade()); - UPGRADES.put((byte) 0x06, new v1_16WorldUpgrade()); - UPGRADES.put((byte) 0x07, new v1_17WorldUpgrade()); - UPGRADES.put((byte) 0x08, new v1_18WorldUpgrade()); + UPGRADES.put((byte) 0x02, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_9WorldUpgrade()); + UPGRADES.put((byte) 0x03, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_11WorldUpgrade()); + UPGRADES.put((byte) 0x04, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_13WorldUpgrade()); + UPGRADES.put((byte) 0x05, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_14WorldUpgrade()); + UPGRADES.put((byte) 0x06, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_16WorldUpgrade()); + UPGRADES.put((byte) 0x07, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_17WorldUpgrade()); + UPGRADES.put((byte) 0x08, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_18WorldUpgrade()); } @Override @@ -64,7 +60,7 @@ public SlimeWorld readFromData(v1_9SlimeWorld data) { dataSection.biomeTag.getValue().put("palette", new ListTag<>("palette", TagType.TAG_STRING, newPalette)); } - sections[i] = new SlimeChunkSectionSkeleton( + sections[i] = new com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton( // SlimeChunkConverter can handle null blockState, but cannot handle empty blockState dataSection.blockStatesTag.getValue().isEmpty() ? null : dataSection.blockStatesTag, dataSection.biomeTag, @@ -72,7 +68,7 @@ public SlimeWorld readFromData(v1_9SlimeWorld data) { dataSection.skyLight ); } else { - sections[i] = new SlimeChunkSectionSkeleton( + sections[i] = new com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton( null, null, null, @@ -85,7 +81,7 @@ public SlimeWorld readFromData(v1_9SlimeWorld data) { // slimeChunk.minY, // slimeChunk.maxY, - chunks.put(entry.getLongKey(), new SlimeChunkSkeleton( + chunks.put(entry.getLongKey(), new com.infernalsuite.asp.skeleton.SlimeChunkSkeleton( slimeChunk.x, slimeChunk.z, sections, @@ -98,7 +94,7 @@ public SlimeWorld readFromData(v1_9SlimeWorld data) { } - return new SkeletonSlimeWorld( + return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld( data.worldName, data.loader, data.readOnly, diff --git a/core/src/main/java/com/infernalsuite/aswm/skeleton/SkeletonCloning.java b/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java similarity index 90% rename from core/src/main/java/com/infernalsuite/aswm/skeleton/SkeletonCloning.java rename to core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java index c6d42db7a..c373a2abe 100644 --- a/core/src/main/java/com/infernalsuite/aswm/skeleton/SkeletonCloning.java +++ b/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java @@ -1,12 +1,12 @@ -package com.infernalsuite.aswm.skeleton; +package com.infernalsuite.asp.skeleton; import com.flowpowered.nbt.CompoundTag; -import com.infernalsuite.aswm.Util; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.api.utils.NibbleArray; -import com.infernalsuite.aswm.api.world.SlimeChunk; -import com.infernalsuite.aswm.api.world.SlimeChunkSection; -import com.infernalsuite.aswm.api.world.SlimeWorld; +import com.infernalsuite.asp.Util; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.utils.NibbleArray; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeChunkSection; +import com.infernalsuite.asp.api.world.SlimeWorld; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; diff --git a/core/src/main/java/com/infernalsuite/aswm/skeleton/SkeletonSlimeWorld.java b/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonSlimeWorld.java similarity index 90% rename from core/src/main/java/com/infernalsuite/aswm/skeleton/SkeletonSlimeWorld.java rename to core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonSlimeWorld.java index 2ae1d623b..147d4885e 100644 --- a/core/src/main/java/com/infernalsuite/aswm/skeleton/SkeletonSlimeWorld.java +++ b/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonSlimeWorld.java @@ -1,14 +1,14 @@ -package com.infernalsuite.aswm.skeleton; +package com.infernalsuite.asp.skeleton; import com.flowpowered.nbt.CompoundTag; -import com.infernalsuite.aswm.Util; -import com.infernalsuite.aswm.api.exceptions.WorldAlreadyExistsException; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.api.world.SlimeChunk; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; -import com.infernalsuite.aswm.pdc.FlowPersistentDataContainer; -import com.infernalsuite.aswm.serialization.slime.SlimeSerializer; +import com.infernalsuite.asp.Util; +import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.pdc.FlowPersistentDataContainer; +import com.infernalsuite.asp.serialization.slime.SlimeSerializer; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import org.bukkit.persistence.PersistentDataContainer; import org.jetbrains.annotations.NotNull; @@ -17,7 +17,6 @@ import java.io.IOException; import java.util.Collection; import java.util.List; -import java.util.Map; import java.util.Objects; public final class SkeletonSlimeWorld implements SlimeWorld { diff --git a/core/src/main/java/com/infernalsuite/aswm/skeleton/SlimeChunkSectionSkeleton.java b/core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSectionSkeleton.java similarity index 79% rename from core/src/main/java/com/infernalsuite/aswm/skeleton/SlimeChunkSectionSkeleton.java rename to core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSectionSkeleton.java index afa22963a..a1b83f2d2 100644 --- a/core/src/main/java/com/infernalsuite/aswm/skeleton/SlimeChunkSectionSkeleton.java +++ b/core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSectionSkeleton.java @@ -1,8 +1,8 @@ -package com.infernalsuite.aswm.skeleton; +package com.infernalsuite.asp.skeleton; import com.flowpowered.nbt.CompoundTag; -import com.infernalsuite.aswm.api.utils.NibbleArray; -import com.infernalsuite.aswm.api.world.SlimeChunkSection; +import com.infernalsuite.asp.api.utils.NibbleArray; +import com.infernalsuite.asp.api.world.SlimeChunkSection; import org.jetbrains.annotations.Nullable; public record SlimeChunkSectionSkeleton(CompoundTag blockStates, CompoundTag biome, NibbleArray block, NibbleArray light) implements SlimeChunkSection { diff --git a/core/src/main/java/com/infernalsuite/aswm/skeleton/SlimeChunkSkeleton.java b/core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSkeleton.java similarity index 88% rename from core/src/main/java/com/infernalsuite/aswm/skeleton/SlimeChunkSkeleton.java rename to core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSkeleton.java index 2aba39fb8..bac46961c 100644 --- a/core/src/main/java/com/infernalsuite/aswm/skeleton/SlimeChunkSkeleton.java +++ b/core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSkeleton.java @@ -1,8 +1,8 @@ -package com.infernalsuite.aswm.skeleton; +package com.infernalsuite.asp.skeleton; import com.flowpowered.nbt.CompoundTag; -import com.infernalsuite.aswm.api.world.SlimeChunk; -import com.infernalsuite.aswm.api.world.SlimeChunkSection; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeChunkSection; import java.util.List; diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/SlimeWorldReader.java b/core/src/main/java/com/infernalsuite/aswm/serialization/SlimeWorldReader.java deleted file mode 100644 index c90854f95..000000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/SlimeWorldReader.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.infernalsuite.aswm.serialization; - -import com.infernalsuite.aswm.api.world.SlimeWorld; - -public interface SlimeWorldReader { - - SlimeWorld readFromData(T data); -} diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v10/v10WorldFormat.java b/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v10/v10WorldFormat.java deleted file mode 100644 index d56ecbf78..000000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v10/v10WorldFormat.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v10; - -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.serialization.slime.reader.impl.SimpleWorldFormat; - -public interface v10WorldFormat { - - // Latest, returns same - SimpleWorldFormat FORMAT = new SimpleWorldFormat<>(data -> data, new v10SlimeWorldDeSerializer()); - -} diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v11/v11WorldFormat.java b/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v11/v11WorldFormat.java deleted file mode 100644 index aea58ec5a..000000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v11/v11WorldFormat.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v11; - -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.serialization.slime.reader.impl.SimpleWorldFormat; - -public interface v11WorldFormat { - - SimpleWorldFormat FORMAT = new SimpleWorldFormat<>(data -> data, new v11SlimeWorldDeSerializer()); - -} diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v12/v12WorldFormat.java b/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v12/v12WorldFormat.java deleted file mode 100644 index 8fdef8408..000000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v12/v12WorldFormat.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v12; - -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.serialization.slime.reader.impl.SimpleWorldFormat; - -public interface v12WorldFormat { - - SimpleWorldFormat FORMAT = new SimpleWorldFormat<>(data -> data, new v12SlimeWorldDeSerializer()); - -} diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9WorldFormat.java b/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9WorldFormat.java deleted file mode 100644 index 8316cf534..000000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9WorldFormat.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9; - -import com.infernalsuite.aswm.serialization.slime.reader.impl.SimpleWorldFormat; - -public interface v1_9WorldFormat { - - SimpleWorldFormat FORMAT = new SimpleWorldFormat<>(new v1_v9SlimeConverter(), new v1_9SlimeWorldDeserializer()); - -} diff --git a/gradle.properties b/gradle.properties index d002d3f01..e51685592 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,5 @@ -group=com.infernalsuite.aswm +group=com.infernalsuite.asp +apiVersion=4.0.0-SNAPSHOT version=1.21.3-R0.1-SNAPSHOT mcVersion=1.21.3 diff --git a/gradle/build-logic/build.gradle.kts b/gradle/build-logic/build.gradle.kts new file mode 100644 index 000000000..a47ba2a45 --- /dev/null +++ b/gradle/build-logic/build.gradle.kts @@ -0,0 +1,28 @@ +plugins { + `kotlin-dsl` +} + +group = "com.infernalsuite" + +repositories { + mavenLocal() + mavenCentral() + gradlePluginPortal() +} + +fun convertPlugin(plugin: Provider): String { + val id = plugin.get().pluginId + return "$id:$id.gradle.plugin:${plugin.get().version}" +} + +dependencies { + implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location)) + implementation(convertPlugin(libs.plugins.blossom)) + implementation(convertPlugin(libs.plugins.gitprops)) + implementation(convertPlugin(libs.plugins.profiles)) + implementation(convertPlugin(libs.plugins.kotlin.jvm)) + implementation(convertPlugin(libs.plugins.lombok)) + implementation(convertPlugin(libs.plugins.paperweight.patcher)) + implementation(convertPlugin(libs.plugins.plugin.yml.paper)) + implementation(convertPlugin(libs.plugins.shadow)) +} diff --git a/gradle/build-logic/settings.gradle.kts b/gradle/build-logic/settings.gradle.kts new file mode 100644 index 000000000..ab6c4736e --- /dev/null +++ b/gradle/build-logic/settings.gradle.kts @@ -0,0 +1,17 @@ +rootProject.name = "build-logic" + +pluginManagement { + repositories { + mavenLocal() + mavenCentral() + gradlePluginPortal() + } +} + +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("../libs.versions.toml")) + } + } +} diff --git a/gradle/build-logic/src/main/kotlin/asp.base-conventions.gradle.kts b/gradle/build-logic/src/main/kotlin/asp.base-conventions.gradle.kts new file mode 100644 index 000000000..8f211a934 --- /dev/null +++ b/gradle/build-logic/src/main/kotlin/asp.base-conventions.gradle.kts @@ -0,0 +1,58 @@ +plugins { + `java-library` + id("com.gorylenko.gradle-git-properties") +} + +group = rootProject.providers.gradleProperty("group") +version = rootProject.providers.gradleProperty("apiVersion") + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(JAVA_VERSION)) + } + withJavadocJar() + withSourcesJar() +} + +repositories { + mavenLocal() + mavenCentral() + + maven(PAPER_MAVEN_PUBLIC_URL) + + maven("https://repo.codemc.io/repository/nms/") + maven("https://repo.rapture.pw/repository/maven-releases/") + maven("https://repo.glaremasters.me/repository/concuncan/") + maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") + maven("https://oss.sonatype.org/content/repositories/snapshots/") +} + +dependencies { + api(platform(project(":gradle:platform"))) +} + +tasks { + compileJava { + options.encoding = Charsets.UTF_8.name() + options.release.set(JAVA_VERSION) + } + + javadoc { + options.encoding = Charsets.UTF_8.name() + (options as StandardJavadocDocletOptions) + .tags("apiNote:a:API Note", "implSpec:a:Implementation Requirements", "implNote:a:Implementation Note") + } + + val git = withType { + outputs.upToDateWhen { false } + gitProperties.extProperty = "git" + }.first() + + processResources { + filteringCharset = Charsets.UTF_8.name() + dependsOn(git) + filesMatching(listOf("paper-plugin.yml", "version.txt")) { + expand("gitCommitId" to git.generatedProperties["git.commit.id"]) + } + } +} diff --git a/gradle/build-logic/src/main/kotlin/asp.paperweight-conventions.gradle.kts b/gradle/build-logic/src/main/kotlin/asp.paperweight-conventions.gradle.kts new file mode 100644 index 000000000..6aa2ebe35 --- /dev/null +++ b/gradle/build-logic/src/main/kotlin/asp.paperweight-conventions.gradle.kts @@ -0,0 +1,42 @@ +plugins { + id("io.papermc.paperweight.patcher") +} + +repositories { + mavenCentral() + maven(PAPER_MAVEN_PUBLIC_URL) { + content { onlyForConfigurations(configurations.paperclip.name) } + } +} + +dependencies { + remapper("net.fabricmc:tiny-remapper:0.10.3:fat") + decompiler("org.vineflower:vineflower:1.10.1") + paperclip("io.papermc:paperclip:3.0.3") +} + +paperweight { + serverProject.set(project(":aspaper-server")) + + remapRepo.set(PAPER_MAVEN_PUBLIC_URL) + decompileRepo.set(PAPER_MAVEN_PUBLIC_URL) + + usePaperUpstream(providers.gradleProperty("paperRef")) { + withPaperPatcher { + apiPatchDir.set(layout.projectDirectory.dir("patches/api")) + apiOutputDir.set(layout.projectDirectory.dir("aspaper-api")) + + serverPatchDir.set(layout.projectDirectory.dir("patches/server")) + serverOutputDir.set(layout.projectDirectory.dir("aspaper-server")) + + patchTasks { + register("generatedApi") { + isBareDirectory.set(true) + upstreamDirPath.set("paper-api-generator/generated") + patchDir.set(layout.projectDirectory.dir("patches/generatedApi")) + outputDir.set(layout.projectDirectory.dir("paper-api-generator/generated")) + } + } + } + } +} diff --git a/gradle/build-logic/src/main/kotlin/asp.publishing-conventions.gradle.kts b/gradle/build-logic/src/main/kotlin/asp.publishing-conventions.gradle.kts new file mode 100644 index 000000000..c0ea0d6c5 --- /dev/null +++ b/gradle/build-logic/src/main/kotlin/asp.publishing-conventions.gradle.kts @@ -0,0 +1,86 @@ +import com.infernalsuite.asp.conventions.PublishConfiguration.Companion.publishConfiguration +import org.kordamp.gradle.plugin.profiles.ProfilesExtension + +plugins { + `maven-publish` + signing + id("org.kordamp.gradle.profiles") +} + +val publishConfiguration = publishConfiguration() + +extensions.configure("profiles") { + profile("publish") { + activation { + property { + setKey("publish") + setValue("true") + } + } + action { + extensions.configure("publishing") { + publications { + create("maven") { + groupId = "${project.group}" + artifactId = project.name + version = "${project.version}" + + from(components["java"]) + + pom { + name.set(publishConfiguration.name) + description.set(publishConfiguration.description) + url.set("https://github.com/InfernalSuite/AdvancedSlimePaper") + licenses { + license { + name.set("GNU General Public License, Version 3.0") + url.set("https://www.gnu.org/licenses/gpl-3.0.txt") + } + } + developers { + developer { + id.set("InfernalSuite") + name.set("The InfernalSuite Team") + url.set("https://github.com/InfernalSuite") + email.set("infernalsuite@gmail.com") + } + } + scm { + connection.set("scm:git:https://github.com:InfernalSuite/AdvancedSlimePaper.git") + developerConnection.set("scm:git:ssh://github.com:InfernalSuite/AdvancedSlimePaper.git") + url.set("https://github.com/InfernalSuite/AdvancedSlimePaper/") + } + issueManagement { + system.set("Github") + url.set("https://github.com/InfernalSuite/AdvancedSlimePaper/issues") + } + } + + versionMapping { + usage("java-api") { + fromResolutionOf("runtimeClasspath") + } + usage("java-runtime") { + fromResolutionResult() + } + } + } + } + repositories { + maven { + name = "infernalsuite" + url = uri("https://repo.infernalsuite.com/repository/maven-snapshots/") + credentials { + username = project.property("ISUsername") as String? + password = project.property("ISPassword") as String? + } + } + } + } + extensions.configure("signing") { + useGpgCmd() + sign(extensions.getByName("publishing").publications["maven"]) + } + } + } +} \ No newline at end of file diff --git a/gradle/build-logic/src/main/kotlin/com/infernalsuite/asp/conventions/PublishConfiguration.kt b/gradle/build-logic/src/main/kotlin/com/infernalsuite/asp/conventions/PublishConfiguration.kt new file mode 100644 index 000000000..65841170d --- /dev/null +++ b/gradle/build-logic/src/main/kotlin/com/infernalsuite/asp/conventions/PublishConfiguration.kt @@ -0,0 +1,19 @@ +package com.infernalsuite.asp.conventions + +import org.gradle.api.Project +import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.Property +import javax.inject.Inject + +open class PublishConfiguration @Inject constructor(objects: ObjectFactory) { + + companion object { + internal fun Project.publishConfiguration(): PublishConfiguration { + return extensions.create("publishConfiguration", PublishConfiguration::class.java) + } + } + + val name: Property = objects.property(String::class.java) + val description: Property = objects.property(String::class.java) + +} diff --git a/gradle/build-logic/src/main/kotlin/constants.kt b/gradle/build-logic/src/main/kotlin/constants.kt new file mode 100644 index 000000000..6f6fe73c9 --- /dev/null +++ b/gradle/build-logic/src/main/kotlin/constants.kt @@ -0,0 +1,2 @@ +const val JAVA_VERSION = 21 +const val PAPER_MAVEN_PUBLIC_URL = "https://repo.papermc.io/repository/maven-public/" \ No newline at end of file diff --git a/gradle/build-logic/src/main/kotlin/extensions.kt b/gradle/build-logic/src/main/kotlin/extensions.kt new file mode 100644 index 000000000..2b7913f9d --- /dev/null +++ b/gradle/build-logic/src/main/kotlin/extensions.kt @@ -0,0 +1,24 @@ +import org.gradle.accessors.dm.LibrariesForLibs +import org.gradle.api.Project +import org.gradle.api.artifacts.Dependency +import org.gradle.api.file.FileSystemLocation +import org.gradle.api.provider.Provider +import org.gradle.kotlin.dsl.the +import java.nio.file.Path + +val Project.libs: LibrariesForLibs + get() = the() + +// Utils for working with java.nio.file.Path from a FileSystemLocation +// Courtesy of PaperMC (io.papermc.paperweight.util/file.kt) <3 +val FileSystemLocation.path: Path + get() = asFile.toPath() + +val Provider.path: Path + get() = get().path + +val Provider.pathOrNull: Path? + get() = orNull?.path + +fun Project.paperApi(): Dependency = + dependencies.create("io.papermc.paper:paper-api:${rootProject.providers.gradleProperty("version").get()}") diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 000000000..fe8780ecb --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,53 @@ +[versions] +adventure = "4.17.0" +annotations = "26.0.1" +autoservice = "1.1.1" +blossom = "2.1.0" +bstats = "3.1.0" +cloud-core = "2.0.0" +cloud-minecraft = "2.0.0-beta.10" +configurate = "4.1.2" +gradle-git-properties = "2.4.2" +gradle-profiles = "0.54.0" +hikari = "6.2.1" +kotlin = "1.9.25" +lettuce = "6.5.1.RELEASE" +lombok = "1.18.36" +lombok-plugin = "8.11" +mongo = "5.2.1" +paperweight = "1.7.7" +plugin-yml-paper = "0.6.0" +shadow = "8.3.5" +slf4j = "2.0.16" +zstd = "1.5.6-8" + +[plugins] +blossom = { id = "net.kyori.blossom", version.ref = "blossom" } +gitprops = { id = "com.gorylenko.gradle-git-properties", version.ref = "gradle-git-properties" } +profiles = { id = "org.kordamp.gradle.profiles", version.ref = "gradle-profiles" } +kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } +lombok = { id = "io.freefair.lombok", version.ref = "lombok-plugin" } +paperweight-patcher = { id = "io.papermc.paperweight.patcher", version.ref = "paperweight" } +plugin-yml-paper = { id = "net.minecrell.plugin-yml.paper", version.ref = "plugin-yml-paper" } +shadow = { id = "com.gradleup.shadow", version.ref = "shadow" } + +[libraries] +adventure-nbt = { module = "net.kyori:adventure-nbt", version.ref = "adventure" } +annotations = { module = "org.jetbrains:annotations", version.ref = "annotations" } +auto-service = { module = "com.google.auto.service:auto-service", version.ref = "autoservice" } +auto-service-annotations = { module = "com.google.auto.service:auto-service-annotations", version.ref = "autoservice" } +bstats = { module = "org.bstats:bstats-bukkit", version.ref = "bstats" } +cloud-annotations = { module = "org.incendo:cloud-annotations", version.ref = "cloud-core" } +cloud-bom = { module = "org.incendo:cloud-bom", version.ref = "cloud-core" } +cloud-core = { module = "org.incendo:cloud-core", version.ref = "cloud-core" } +cloud-minecraft-bom = { module = "org.incendo:cloud-minecraft-bom", version.ref = "cloud-minecraft" } +cloud-minecraft-extras = { module = "org.incendo:cloud-minecraft-extras", version.ref = "cloud-minecraft" } +cloud-paper = { module = "org.incendo:cloud-paper", version.ref = "cloud-minecraft" } +configurate-core = { module = "org.spongepowered:configurate-core", version.ref = "configurate" } +configurate-yaml = { module = "org.spongepowered:configurate-yaml", version.ref = "configurate" } +hikari = { module = "com.zaxxer:HikariCP", version.ref = "hikari" } +lettuce = { module = "io.lettuce:lettuce-core", version.ref = "lettuce" } +lombok = { module = "org.projectlombok:lombok", version.ref = "lombok" } +mongo = { module = "org.mongodb:mongodb-driver-sync", version.ref = "mongo" } +slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" } +zstd = { module = "com.github.luben:zstd-jni", version.ref = "zstd" } \ No newline at end of file diff --git a/gradle/platform/build.gradle.kts b/gradle/platform/build.gradle.kts new file mode 100644 index 000000000..e0f923aa7 --- /dev/null +++ b/gradle/platform/build.gradle.kts @@ -0,0 +1,26 @@ +plugins { + `java-platform` +} + +javaPlatform { + allowDependencies() +} + +dependencies { + constraints { + api(libs.adventure.nbt) + api(libs.auto.service) + api(libs.auto.service.annotations) + api(libs.bstats) + api(platform(libs.cloud.bom)) + api(platform(libs.cloud.minecraft.bom)) + api(libs.configurate.core) + api(libs.configurate.yaml) + api(libs.hikari) + api(libs.lettuce) + api(libs.lombok) + api(libs.mongo) + api(libs.slf4j.api) + api(libs.zstd) + } +} diff --git a/importer/build.gradle.kts b/importer/build.gradle.kts index 66047469f..f55f9d48a 100644 --- a/importer/build.gradle.kts +++ b/importer/build.gradle.kts @@ -1,17 +1,18 @@ plugins { - id("com.gradleup.shadow") version "8.3.5" + id("asp.base-conventions") + id("com.gradleup.shadow") } dependencies { implementation(project(":api")) implementation(project(":core")) - implementation(project(":slimeworldmanager-api")) + implementation(project(":aspaper-api")) } tasks { jar { manifest { - attributes["Main-Class"] = "com.infernalsuite.aswm.importer.SWMImporter" + attributes["Main-Class"] = "com.infernalsuite.asp.importer.ASPImporter" } } shadowJar { @@ -19,4 +20,4 @@ tasks { } } -description = "slimeworldmanager-importer" +description = "asp-importer" diff --git a/importer/src/main/java/com/infernalsuite/aswm/importer/SWMImporter.java b/importer/src/main/java/com/infernalsuite/asp/importer/SWMImporter.java similarity index 90% rename from importer/src/main/java/com/infernalsuite/aswm/importer/SWMImporter.java rename to importer/src/main/java/com/infernalsuite/asp/importer/SWMImporter.java index 4f02aa0ba..29751e9c8 100644 --- a/importer/src/main/java/com/infernalsuite/aswm/importer/SWMImporter.java +++ b/importer/src/main/java/com/infernalsuite/asp/importer/SWMImporter.java @@ -1,9 +1,8 @@ -package com.infernalsuite.aswm.importer; +package com.infernalsuite.asp.importer; -import com.infernalsuite.aswm.api.exceptions.InvalidWorldException; -import com.infernalsuite.aswm.serialization.anvil.AnvilImportData; -import com.infernalsuite.aswm.serialization.anvil.AnvilWorldReader; -import com.infernalsuite.aswm.serialization.slime.SlimeSerializer; +import com.infernalsuite.asp.serialization.anvil.AnvilImportData; +import com.infernalsuite.asp.serialization.anvil.AnvilWorldReader; +import com.infernalsuite.asp.serialization.slime.SlimeSerializer; import java.io.File; import java.io.IOException; diff --git a/loaders/build.gradle.kts b/loaders/build.gradle.kts index 79cfc7a9a..134bd46f6 100644 --- a/loaders/build.gradle.kts +++ b/loaders/build.gradle.kts @@ -1,101 +1,19 @@ plugins { - id("java") - `java-library` - `maven-publish` - signing -} - -group = "com.infernalsuite.aswm" -version = "3.0.0-SNAPSHOT" - -repositories { - mavenCentral() + id("asp.base-conventions") + id("asp.publishing-conventions") } dependencies { compileOnly(project(":api")) - api("com.zaxxer:HikariCP:5.1.0") - api("org.mongodb:mongodb-driver-sync:5.1.0") - api("io.lettuce:lettuce-core:6.3.2.RELEASE") + api(libs.hikari) + api(libs.mongo) + api(libs.lettuce) - compileOnly("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT") - compileOnly("commons-io:commons-io:2.11.0") + compileOnly(paperApi()) } -profiles { - profile("publish") { - activation { - property { - setKey("publish") - setValue("true") - } - } - action { - publishing { - publications { - create("maven") { - groupId = "${project.group}" - artifactId = project.name - version = "${project.version}" - - from(components["java"]) - - pom { - name.set("Advanced Slime Paper Reference Loaders") - description.set("Reference loader implementations for ASP") - url.set("https://github.com/InfernalSuite/AdvancedSlimePaper") - licenses { - license { - name.set("GNU General Public License, Version 3.0") - url.set("https://www.gnu.org/licenses/gpl-3.0.txt") - } - } - developers { - developer { - id.set("InfernalSuite") - name.set("The InfernalSuite Team") - url.set("https://github.com/InfernalSuite") - email.set("infernalsuite@gmail.com") - } - } - scm { - connection.set("scm:git:https://github.com:InfernalSuite/AdvancedSlimePaper.git") - developerConnection.set("scm:git:ssh://github.com:InfernalSuite/AdvancedSlimePaper.git") - url.set("https://github.com/InfernalSuite/AdvancedSlimePaper/") - } - issueManagement { - system.set("Github") - url.set("https://github.com/InfernalSuite/AdvancedSlimePaper/issues") - } - } - - versionMapping { - usage("java-api") { - fromResolutionOf("runtimeClasspath") - } - usage("java-runtime") { - fromResolutionResult() - } - } - } - } - repositories { - maven { - name = "infernalsuite" - url = uri("https://repo.infernalsuite.com/repository/maven-snapshots/") - credentials { - username = project.property("ISUsername") as String? - password = project.property("ISPassword") as String? - } - } - } - } - - signing { - useGpgCmd() - sign(publishing.publications["maven"]) - } - } - } -} \ No newline at end of file +publishConfiguration { + name = "Advanced Slime Paper Loaders" + description = "Default loaders for Advanced Slime Paper" +} diff --git a/loaders/src/main/java/com/infernalsuite/aswm/loaders/UpdatableLoader.java b/loaders/src/main/java/com/infernalsuite/asp/loaders/UpdatableLoader.java similarity index 88% rename from loaders/src/main/java/com/infernalsuite/aswm/loaders/UpdatableLoader.java rename to loaders/src/main/java/com/infernalsuite/asp/loaders/UpdatableLoader.java index 23c0f5296..ca0415efa 100644 --- a/loaders/src/main/java/com/infernalsuite/aswm/loaders/UpdatableLoader.java +++ b/loaders/src/main/java/com/infernalsuite/asp/loaders/UpdatableLoader.java @@ -1,6 +1,6 @@ -package com.infernalsuite.aswm.loaders; +package com.infernalsuite.asp.loaders; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.loaders.SlimeLoader; import java.io.IOException; diff --git a/loaders/src/main/java/com/infernalsuite/aswm/loaders/api/APILoader.java b/loaders/src/main/java/com/infernalsuite/asp/loaders/api/APILoader.java similarity index 97% rename from loaders/src/main/java/com/infernalsuite/aswm/loaders/api/APILoader.java rename to loaders/src/main/java/com/infernalsuite/asp/loaders/api/APILoader.java index 93bc69a0a..10e7b6ec4 100644 --- a/loaders/src/main/java/com/infernalsuite/aswm/loaders/api/APILoader.java +++ b/loaders/src/main/java/com/infernalsuite/asp/loaders/api/APILoader.java @@ -1,9 +1,9 @@ -package com.infernalsuite.aswm.loaders.api; +package com.infernalsuite.asp.loaders.api; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; -import com.infernalsuite.aswm.api.exceptions.UnknownWorldException; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.exceptions.UnknownWorldException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/loaders/src/main/java/com/infernalsuite/aswm/loaders/api/MapStructure.java b/loaders/src/main/java/com/infernalsuite/asp/loaders/api/MapStructure.java similarity index 97% rename from loaders/src/main/java/com/infernalsuite/aswm/loaders/api/MapStructure.java rename to loaders/src/main/java/com/infernalsuite/asp/loaders/api/MapStructure.java index be56adb46..95bf1a783 100644 --- a/loaders/src/main/java/com/infernalsuite/aswm/loaders/api/MapStructure.java +++ b/loaders/src/main/java/com/infernalsuite/asp/loaders/api/MapStructure.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.loaders.api; +package com.infernalsuite.asp.loaders.api; import java.util.List; import java.util.Map; diff --git a/loaders/src/main/java/com/infernalsuite/aswm/loaders/file/FileLoader.java b/loaders/src/main/java/com/infernalsuite/asp/loaders/file/FileLoader.java similarity index 93% rename from loaders/src/main/java/com/infernalsuite/aswm/loaders/file/FileLoader.java rename to loaders/src/main/java/com/infernalsuite/asp/loaders/file/FileLoader.java index 0366a7b27..3fa872922 100644 --- a/loaders/src/main/java/com/infernalsuite/aswm/loaders/file/FileLoader.java +++ b/loaders/src/main/java/com/infernalsuite/asp/loaders/file/FileLoader.java @@ -1,7 +1,7 @@ -package com.infernalsuite.aswm.loaders.file; +package com.infernalsuite.asp.loaders.file; -import com.infernalsuite.aswm.api.exceptions.UnknownWorldException; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.exceptions.UnknownWorldException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/loaders/src/main/java/com/infernalsuite/aswm/loaders/mongo/MongoLoader.java b/loaders/src/main/java/com/infernalsuite/asp/loaders/mongo/MongoLoader.java similarity index 97% rename from loaders/src/main/java/com/infernalsuite/aswm/loaders/mongo/MongoLoader.java rename to loaders/src/main/java/com/infernalsuite/asp/loaders/mongo/MongoLoader.java index 4da311db6..0cb15e42c 100644 --- a/loaders/src/main/java/com/infernalsuite/aswm/loaders/mongo/MongoLoader.java +++ b/loaders/src/main/java/com/infernalsuite/asp/loaders/mongo/MongoLoader.java @@ -1,7 +1,6 @@ -package com.infernalsuite.aswm.loaders.mongo; +package com.infernalsuite.asp.loaders.mongo; -import com.infernalsuite.aswm.api.exceptions.UnknownWorldException; -import com.infernalsuite.aswm.loaders.UpdatableLoader; +import com.infernalsuite.asp.api.exceptions.UnknownWorldException; import com.mongodb.MongoException; import com.mongodb.MongoNamespace; import com.mongodb.client.*; @@ -21,7 +20,7 @@ import java.util.ArrayList; import java.util.List; -public class MongoLoader extends UpdatableLoader { +public class MongoLoader extends com.infernalsuite.asp.loaders.UpdatableLoader { private static final Logger LOGGER = LoggerFactory.getLogger(MongoLoader.class); diff --git a/loaders/src/main/java/com/infernalsuite/aswm/loaders/mysql/MysqlLoader.java b/loaders/src/main/java/com/infernalsuite/asp/loaders/mysql/MysqlLoader.java similarity index 97% rename from loaders/src/main/java/com/infernalsuite/aswm/loaders/mysql/MysqlLoader.java rename to loaders/src/main/java/com/infernalsuite/asp/loaders/mysql/MysqlLoader.java index 1a05d7c15..756ab7605 100644 --- a/loaders/src/main/java/com/infernalsuite/aswm/loaders/mysql/MysqlLoader.java +++ b/loaders/src/main/java/com/infernalsuite/asp/loaders/mysql/MysqlLoader.java @@ -1,7 +1,6 @@ -package com.infernalsuite.aswm.loaders.mysql; +package com.infernalsuite.asp.loaders.mysql; -import com.infernalsuite.aswm.api.exceptions.UnknownWorldException; -import com.infernalsuite.aswm.loaders.UpdatableLoader; +import com.infernalsuite.asp.api.exceptions.UnknownWorldException; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import org.slf4j.Logger; @@ -15,7 +14,7 @@ import java.util.ArrayList; import java.util.List; -public class MysqlLoader extends UpdatableLoader { +public class MysqlLoader extends com.infernalsuite.asp.loaders.UpdatableLoader { private static final Logger LOGGER = LoggerFactory.getLogger(MysqlLoader.class); diff --git a/loaders/src/main/java/com/infernalsuite/aswm/loaders/redis/RedisLoader.java b/loaders/src/main/java/com/infernalsuite/asp/loaders/redis/RedisLoader.java similarity index 88% rename from loaders/src/main/java/com/infernalsuite/aswm/loaders/redis/RedisLoader.java rename to loaders/src/main/java/com/infernalsuite/asp/loaders/redis/RedisLoader.java index f0f757662..e4b873147 100644 --- a/loaders/src/main/java/com/infernalsuite/aswm/loaders/redis/RedisLoader.java +++ b/loaders/src/main/java/com/infernalsuite/asp/loaders/redis/RedisLoader.java @@ -1,8 +1,7 @@ -package com.infernalsuite.aswm.loaders.redis; +package com.infernalsuite.asp.loaders.redis; -import com.infernalsuite.aswm.api.exceptions.UnknownWorldException; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.loaders.redis.util.StringByteCodec; +import com.infernalsuite.asp.api.exceptions.UnknownWorldException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; import io.lettuce.core.RedisClient; import io.lettuce.core.api.sync.RedisCommands; @@ -21,7 +20,7 @@ public class RedisLoader implements SlimeLoader { public RedisLoader(String uri) { this.connection = RedisClient .create(uri) - .connect(StringByteCodec.INSTANCE) + .connect(com.infernalsuite.asp.loaders.redis.util.StringByteCodec.INSTANCE) .sync(); } diff --git a/loaders/src/main/java/com/infernalsuite/aswm/loaders/redis/util/StringByteCodec.java b/loaders/src/main/java/com/infernalsuite/asp/loaders/redis/util/StringByteCodec.java similarity index 95% rename from loaders/src/main/java/com/infernalsuite/aswm/loaders/redis/util/StringByteCodec.java rename to loaders/src/main/java/com/infernalsuite/asp/loaders/redis/util/StringByteCodec.java index d9d4fadbf..6203b5a88 100644 --- a/loaders/src/main/java/com/infernalsuite/aswm/loaders/redis/util/StringByteCodec.java +++ b/loaders/src/main/java/com/infernalsuite/asp/loaders/redis/util/StringByteCodec.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.loaders.redis.util; +package com.infernalsuite.asp.loaders.redis.util; import io.lettuce.core.codec.RedisCodec; diff --git a/patches/api/0001-Slime-World-Manager.patch b/patches/api/0001-Slime-World-Manager.patch index 059d62e51..ca201dbe1 100644 --- a/patches/api/0001-Slime-World-Manager.patch +++ b/patches/api/0001-Slime-World-Manager.patch @@ -5,16 +5,10 @@ Subject: [PATCH] Slime World Manager diff --git a/build.gradle.kts b/build.gradle.kts -index e29e5024fa693baae469d47fe77b57118f14627c..4da167f928789c1b5d55da2749a94e44912492ad 100644 +index e29e5024fa693baae469d47fe77b57118f14627c..a1ab3bc4f7853c83e79de52d2549586655ca569e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -1,3 +1,5 @@ -+ -+ - plugins { - `java-library` - `maven-publish` -@@ -41,6 +43,7 @@ abstract class MockitoAgentProvider : CommandLineArgumentProvider { +@@ -41,6 +41,7 @@ abstract class MockitoAgentProvider : CommandLineArgumentProvider { dependencies { api("com.mojang:brigadier:1.2.9") // Paper - Brigadier command api // api dependencies are listed transitively to API consumers diff --git a/patches/server/0001-Build-Changes.patch b/patches/server/0001-Build-Changes.patch index f075685c5..73ce36b19 100644 --- a/patches/server/0001-Build-Changes.patch +++ b/patches/server/0001-Build-Changes.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Build Changes Update shadow plugin diff --git a/build.gradle.kts b/build.gradle.kts -index faf3e3fd72e8c915e7a4803dacbe1bb576c6663e..e90c79790c40afb67364fed615be2384c30d73d0 100644 +index faf3e3fd72e8c915e7a4803dacbe1bb576c6663e..b5b5c099e61f828edbcd18aba9d379a6e45fb8b4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,6 +4,7 @@ import java.time.Instant @@ -23,7 +23,7 @@ index faf3e3fd72e8c915e7a4803dacbe1bb576c6663e..e90c79790c40afb67364fed615be2384 dependencies { - implementation(project(":paper-api")) + // ASWM start -+ implementation(project(":slimeworldmanager-api")) ++ implementation(project(":aspaper-api")) + implementation(project(":core")) + implementation("io.papermc.paper:paper-mojangapi:1.20.4-R0.1-SNAPSHOT") { + exclude("io.papermc.paper", "paper-api") @@ -75,7 +75,7 @@ index b3c993a790fc3fab6a408c731deb297f74c959ce..0bbd557602932b67212b8951ef769bbc public FullChunkStatus status; public final ChunkData chunkData; diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java -index 91a6f57f35fc1553159cca138a0619e703b2b014..07fee642805ac3ec6fce489a0b9050ddf941d932 100644 +index 91a6f57f35fc1553159cca138a0619e703b2b014..0474325958293ea36bae0e44849e95a2fde819b8 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java @@ -185,7 +185,8 @@ public final class ChunkHolderManager { @@ -84,19 +84,19 @@ index 91a6f57f35fc1553159cca138a0619e703b2b014..07fee642805ac3ec6fce489a0b9050dd - public void close(final boolean save, final boolean halt) { + public void close(boolean save, final boolean halt) { // ASWM -+ if (this.world instanceof com.infernalsuite.aswm.level.SlimeLevelInstance) save = false; // ASWM ++ if (this.world instanceof com.infernalsuite.asp.level.SlimeLevelInstance) save = false; // ASWM TickThread.ensureTickThread("Closing world off-main"); if (halt) { LOGGER.info("Waiting 60s for chunk system to halt for world '" + WorldUtil.getWorldName(this.world) + "'"); diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java -index 1440c9e2b106616884edcb20201113320817ed9f..158dee86d783c4a0a0479b07c4159184479b2a65 100644 +index 1440c9e2b106616884edcb20201113320817ed9f..ae8b6fd79dd556499acb96114dfd38c85eca67f6 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java @@ -6,6 +6,7 @@ import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; import ca.spottedleaf.concurrentutil.util.Priority; import ca.spottedleaf.moonrise.common.PlatformHooks; -+import com.infernalsuite.aswm.level.CommonLoadTask; ++import com.infernalsuite.asp.level.CommonLoadTask; import ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystemConverters; import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; import ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk; @@ -121,7 +121,7 @@ index 1440c9e2b106616884edcb20201113320817ed9f..158dee86d783c4a0a0479b07c4159184 - ChunkLoadTask.this.tryCompleteLoad(); - }); + // ASWM start -+ if (world instanceof com.infernalsuite.aswm.level.SlimeLevelInstance levelInstance) { ++ if (world instanceof com.infernalsuite.asp.level.SlimeLevelInstance levelInstance) { + + this.loadTask = levelInstance.getLoadTask(this, scheduler, world, chunkX, chunkZ, priority, result -> { + ChunkLoadTask.this.complete(result == null ? null : result.left(), result == null ? null : result.right()); @@ -198,17 +198,17 @@ index 532306cacd52579cdf37e4aca25887b1ed3ba6a1..55864e5f9ba2ccca0160760e90d8f778 .append(text(DOWNLOAD_PAGE, NamedTextColor.GOLD) .hoverEvent(text("Click to open", NamedTextColor.WHITE)) .clickEvent(ClickEvent.openUrl(DOWNLOAD_PAGE)))); -diff --git a/src/main/java/com/infernalsuite/aswm/Converter.java b/src/main/java/com/infernalsuite/aswm/Converter.java +diff --git a/src/main/java/com/infernalsuite/asp/Converter.java b/src/main/java/com/infernalsuite/asp/Converter.java new file mode 100644 -index 0000000000000000000000000000000000000000..7d1753c0b7e89bbf0c245a0231b62773eca2779e +index 0000000000000000000000000000000000000000..4ce96aae099f7ac941e7e7665693b5ba04802a8c --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/Converter.java ++++ b/src/main/java/com/infernalsuite/asp/Converter.java @@ -0,0 +1,118 @@ -+package com.infernalsuite.aswm; ++package com.infernalsuite.asp; + +import com.flowpowered.nbt.CompoundMap; +import com.flowpowered.nbt.TagType; -+import com.infernalsuite.aswm.api.utils.NibbleArray; ++import com.infernalsuite.asp.api.utils.NibbleArray; +import net.minecraft.nbt.*; +import net.minecraft.world.level.chunk.DataLayer; +import org.apache.logging.log4j.LogManager; @@ -323,13 +323,13 @@ index 0000000000000000000000000000000000000000..7d1753c0b7e89bbf0c245a0231b62773 + } +} \ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/aswm/InternalPlugin.java b/src/main/java/com/infernalsuite/aswm/InternalPlugin.java +diff --git a/src/main/java/com/infernalsuite/asp/InternalPlugin.java b/src/main/java/com/infernalsuite/asp/InternalPlugin.java new file mode 100644 -index 0000000000000000000000000000000000000000..61518ab2b68e7a41500f3c8c8a5ec1230597f0e5 +index 0000000000000000000000000000000000000000..4c7938c07e06810f475eac0bb4400c11154b56ba --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/InternalPlugin.java ++++ b/src/main/java/com/infernalsuite/asp/InternalPlugin.java @@ -0,0 +1,28 @@ -+package com.infernalsuite.aswm; ++package com.infernalsuite.asp; + +import net.minecraft.server.MinecraftServer; +import org.bukkit.Server; @@ -358,25 +358,25 @@ index 0000000000000000000000000000000000000000..61518ab2b68e7a41500f3c8c8a5ec123 + +} \ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java +diff --git a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java new file mode 100644 -index 0000000000000000000000000000000000000000..1affe4c94b490a05184deccc9eb80530f67fd5ea +index 0000000000000000000000000000000000000000..2f5b79632226f5d0112a4c0ddfc903d6b2b93549 --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java ++++ b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java @@ -0,0 +1,101 @@ -+package com.infernalsuite.aswm; ++package com.infernalsuite.asp; + +import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; +import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; +import ca.spottedleaf.dataconverter.types.nbt.NBTMapType; +import com.flowpowered.nbt.CompoundTag; -+import com.infernalsuite.aswm.serialization.SlimeWorldReader; -+import com.infernalsuite.aswm.skeleton.SkeletonSlimeWorld; -+import com.infernalsuite.aswm.skeleton.SlimeChunkSectionSkeleton; -+import com.infernalsuite.aswm.skeleton.SlimeChunkSkeleton; -+import com.infernalsuite.aswm.api.world.SlimeChunk; -+import com.infernalsuite.aswm.api.world.SlimeChunkSection; -+import com.infernalsuite.aswm.api.world.SlimeWorld; ++import com.infernalsuite.asp.serialization.SlimeWorldReader; ++import com.infernalsuite.asp.skeleton.SkeletonSlimeWorld; ++import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; ++import com.infernalsuite.asp.skeleton.SlimeChunkSkeleton; ++import com.infernalsuite.asp.api.world.SlimeChunk; ++import com.infernalsuite.asp.api.world.SlimeChunkSection; ++import com.infernalsuite.asp.api.world.SlimeWorld; +import net.minecraft.SharedConstants; + +import java.util.ArrayList; @@ -396,7 +396,7 @@ index 0000000000000000000000000000000000000000..1affe4c94b490a05184deccc9eb80530 + return data; + } + -+ Map chunks = new HashMap<>(); ++ Map chunks = new HashMap<>(); + for (SlimeChunk chunk : data.getChunkStorage()) { + List entities = new ArrayList<>(); + List blockEntities = new ArrayList<>(); @@ -466,21 +466,21 @@ index 0000000000000000000000000000000000000000..1affe4c94b490a05184deccc9eb80530 + } +} \ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java +diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java new file mode 100644 -index 0000000000000000000000000000000000000000..20f16757ba8b8da525ff17d51d4f7eb660c4d22b +index 0000000000000000000000000000000000000000..d1ab18a2a2793807118ae1fc23d21248aa7e09a3 --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java ++++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java @@ -0,0 +1,206 @@ -+package com.infernalsuite.aswm; -+ -+import com.infernalsuite.aswm.api.SlimeNMSBridge; -+import com.infernalsuite.aswm.api.world.SlimeWorld; -+import com.infernalsuite.aswm.api.world.SlimeWorldInstance; -+import com.infernalsuite.aswm.api.world.properties.SlimeProperties; -+import com.infernalsuite.aswm.level.SlimeBootstrap; -+import com.infernalsuite.aswm.level.SlimeInMemoryWorld; -+import com.infernalsuite.aswm.level.SlimeLevelInstance; ++package com.infernalsuite.asp; ++ ++import com.infernalsuite.asp.api.SlimeNMSBridge; ++import com.infernalsuite.asp.api.world.SlimeWorld; ++import com.infernalsuite.asp.api.world.SlimeWorldInstance; ++import com.infernalsuite.asp.api.world.properties.SlimeProperties; ++import com.infernalsuite.asp.level.SlimeBootstrap; ++import com.infernalsuite.asp.level.SlimeInMemoryWorld; ++import com.infernalsuite.asp.level.SlimeLevelInstance; +import com.mojang.serialization.Lifecycle; +import net.kyori.adventure.util.Services; +import net.minecraft.SharedConstants; @@ -679,16 +679,16 @@ index 0000000000000000000000000000000000000000..20f16757ba8b8da525ff17d51d4f7eb6 + +} \ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java b/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java +diff --git a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java new file mode 100644 -index 0000000000000000000000000000000000000000..41e652b568598926e838e81fdc338e51f8e97ef8 +index 0000000000000000000000000000000000000000..bb954b74739e22525f9a45648d3ecf54f5a9e61c --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java ++++ b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java @@ -0,0 +1,121 @@ -+package com.infernalsuite.aswm.level; ++package com.infernalsuite.asp.level; + +import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import com.infernalsuite.aswm.api.world.SlimeChunk; ++import com.infernalsuite.asp.api.world.SlimeChunk; +import com.mojang.logging.LogUtils; +import io.papermc.paper.chunk.system.poi.PoiChunk; +import io.papermc.paper.chunk.system.scheduling.ChunkLoadTask; @@ -807,13 +807,13 @@ index 0000000000000000000000000000000000000000..41e652b568598926e838e81fdc338e51 + } +} \ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/aswm/level/CommonLoadTask.java b/src/main/java/com/infernalsuite/aswm/level/CommonLoadTask.java +diff --git a/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java b/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java new file mode 100644 -index 0000000000000000000000000000000000000000..fc6e46972bcc77134ed718c8c157ec3893d4bcdf +index 0000000000000000000000000000000000000000..9954db3eabd60ac0600af1efc6f8a1650ef4d85b --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/level/CommonLoadTask.java ++++ b/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java @@ -0,0 +1,18 @@ -+package com.infernalsuite.aswm.level; ++package com.infernalsuite.asp.level; + +import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; + @@ -832,17 +832,17 @@ index 0000000000000000000000000000000000000000..fc6e46972bcc77134ed718c8c157ec38 + void setPriority(PrioritisedExecutor.Priority priority); +} \ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/aswm/level/FastChunkPruner.java b/src/main/java/com/infernalsuite/aswm/level/FastChunkPruner.java +diff --git a/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java b/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java new file mode 100644 -index 0000000000000000000000000000000000000000..c0e47f25e9be33da374dc737c96d8d3c2bb1cd0f +index 0000000000000000000000000000000000000000..10bfcb7250c01c8361375c4d9b34d2b0ae17257d --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/level/FastChunkPruner.java ++++ b/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java @@ -0,0 +1,59 @@ -+package com.infernalsuite.aswm.level; ++package com.infernalsuite.asp.level; + -+import com.infernalsuite.aswm.api.world.SlimeWorld; -+import com.infernalsuite.aswm.api.world.properties.SlimeProperties; -+import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; ++import com.infernalsuite.asp.api.world.SlimeWorld; ++import com.infernalsuite.asp.api.world.properties.SlimeProperties; ++import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import io.papermc.paper.world.ChunkEntitySlices; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.LevelChunkSection; @@ -898,23 +898,23 @@ index 0000000000000000000000000000000000000000..c0e47f25e9be33da374dc737c96d8d3c + } +} \ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java +diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java new file mode 100644 -index 0000000000000000000000000000000000000000..f1db2fe121bb3aabfad727a8133b645524b8f19a +index 0000000000000000000000000000000000000000..9a6e901b394d1e7740e616a33e6c251ae1d7e0e0 --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java ++++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -0,0 +1,203 @@ -+package com.infernalsuite.aswm.level; ++package com.infernalsuite.asp.level; + +import com.flowpowered.nbt.CompoundMap; +import com.flowpowered.nbt.CompoundTag; +import com.flowpowered.nbt.LongArrayTag; +import com.google.common.collect.Lists; -+import com.infernalsuite.aswm.Converter; -+import com.infernalsuite.aswm.skeleton.SlimeChunkSectionSkeleton; -+import com.infernalsuite.aswm.api.utils.NibbleArray; -+import com.infernalsuite.aswm.api.world.SlimeChunk; -+import com.infernalsuite.aswm.api.world.SlimeChunkSection; ++import com.infernalsuite.asp.Converter; ++import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; ++import com.infernalsuite.asp.api.utils.NibbleArray; ++import com.infernalsuite.asp.api.world.SlimeChunk; ++import com.infernalsuite.asp.api.world.SlimeChunkSection; +import com.mojang.logging.LogUtils; +import com.mojang.serialization.Codec; +import io.papermc.paper.world.ChunkEntitySlices; @@ -1108,20 +1108,20 @@ index 0000000000000000000000000000000000000000..f1db2fe121bb3aabfad727a8133b6455 + +} \ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeWorld.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeWorld.java +diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java new file mode 100644 -index 0000000000000000000000000000000000000000..9a27369c00345bbb94aa19f77687269dc94c0b0a +index 0000000000000000000000000000000000000000..3dc776b5387b4e2f1b669f754b5b064fc0142006 --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeWorld.java ++++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java @@ -0,0 +1,91 @@ -+package com.infernalsuite.aswm.level; ++package com.infernalsuite.asp.level; + +import com.flowpowered.nbt.CompoundTag; -+import com.infernalsuite.aswm.api.exceptions.WorldAlreadyExistsException; -+import com.infernalsuite.aswm.api.loaders.SlimeLoader; -+import com.infernalsuite.aswm.api.world.SlimeChunk; -+import com.infernalsuite.aswm.api.world.SlimeWorld; -+import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; ++import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; ++import com.infernalsuite.asp.api.loaders.SlimeLoader; ++import com.infernalsuite.asp.api.world.SlimeChunk; ++import com.infernalsuite.asp.api.world.SlimeWorld; ++import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import net.minecraft.SharedConstants; +import net.minecraft.server.level.ChunkHolder; +import net.minecraft.world.level.chunk.LevelChunk; @@ -1206,17 +1206,17 @@ index 0000000000000000000000000000000000000000..9a27369c00345bbb94aa19f77687269d + } +} \ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/aswm/level/SafeNmsChunkWrapper.java b/src/main/java/com/infernalsuite/aswm/level/SafeNmsChunkWrapper.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java b/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java new file mode 100644 -index 0000000000000000000000000000000000000000..b20a037679182e3c4a8bf31f084078f6d7e4ff46 +index 0000000000000000000000000000000000000000..025da4dd831f9b8b35000be7de493d44caa41003 --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/level/SafeNmsChunkWrapper.java ++++ b/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java @@ -0,0 +1,83 @@ -+package com.infernalsuite.aswm.level; ++package com.infernalsuite.asp.level; + +import com.flowpowered.nbt.CompoundTag; -+import com.infernalsuite.aswm.api.world.SlimeChunk; -+import com.infernalsuite.aswm.api.world.SlimeChunkSection; ++import com.infernalsuite.asp.api.world.SlimeChunk; ++import com.infernalsuite.asp.api.world.SlimeChunkSection; + +import java.util.List; + @@ -1296,37 +1296,37 @@ index 0000000000000000000000000000000000000000..b20a037679182e3c4a8bf31f084078f6 + } +} \ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeBootstrap.java b/src/main/java/com/infernalsuite/aswm/level/SlimeBootstrap.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeBootstrap.java b/src/main/java/com/infernalsuite/asp/level/SlimeBootstrap.java new file mode 100644 -index 0000000000000000000000000000000000000000..8853088c5c6306511716bbffac9bf73c633b61bb +index 0000000000000000000000000000000000000000..b1dde643ae719fa539c6986e86e12aecdd86957f --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeBootstrap.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeBootstrap.java @@ -0,0 +1,8 @@ -+package com.infernalsuite.aswm.level; ++package com.infernalsuite.asp.level; + -+import com.infernalsuite.aswm.api.world.SlimeWorld; ++import com.infernalsuite.asp.api.world.SlimeWorld; + +public record SlimeBootstrap( + SlimeWorld initial +) { +} \ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java new file mode 100644 -index 0000000000000000000000000000000000000000..91a7f41db47c7df3ecc301e0827a1d07305f604e +index 0000000000000000000000000000000000000000..ba0b401e0b39605303e90720f7c8dc48fcb0bc29 --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java @@ -0,0 +1,164 @@ -+package com.infernalsuite.aswm.level; ++package com.infernalsuite.asp.level; + +import ca.spottedleaf.starlight.common.light.SWMRNibbleArray; +import com.flowpowered.nbt.CompoundMap; +import com.flowpowered.nbt.CompoundTag; +import com.flowpowered.nbt.LongArrayTag; -+import com.infernalsuite.aswm.Converter; -+import com.infernalsuite.aswm.api.utils.NibbleArray; -+import com.infernalsuite.aswm.api.world.SlimeChunk; -+import com.infernalsuite.aswm.api.world.SlimeChunkSection; ++import com.infernalsuite.asp.Converter; ++import com.infernalsuite.asp.api.utils.NibbleArray; ++import com.infernalsuite.asp.api.world.SlimeChunk; ++import com.infernalsuite.asp.api.world.SlimeChunkSection; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import net.minecraft.core.BlockPos; @@ -1482,13 +1482,13 @@ index 0000000000000000000000000000000000000000..91a7f41db47c7df3ecc301e0827a1d07 + } +} \ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkLevel.java b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkLevel.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java new file mode 100644 -index 0000000000000000000000000000000000000000..b159fc8751e9840b311cc1eda01e496e2dbc5f2e +index 0000000000000000000000000000000000000000..0d218911fb8be1bc5272b6e291ec60404306c831 --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkLevel.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java @@ -0,0 +1,27 @@ -+package com.infernalsuite.aswm.level; ++package com.infernalsuite.asp.level; + +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.block.Block; @@ -1516,26 +1516,26 @@ index 0000000000000000000000000000000000000000..b159fc8751e9840b311cc1eda01e496e + } +} \ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java new file mode 100644 -index 0000000000000000000000000000000000000000..fd4cfb9cceb4f23265cb3cce7f1f251051bfba92 +index 0000000000000000000000000000000000000000..ba337466525971885247c269c23aac7df96d2782 --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -0,0 +1,251 @@ -+package com.infernalsuite.aswm.level; ++package com.infernalsuite.asp.level; + +import com.flowpowered.nbt.CompoundTag; -+import com.infernalsuite.aswm.ChunkPos; -+import com.infernalsuite.aswm.api.exceptions.WorldAlreadyExistsException; -+import com.infernalsuite.aswm.api.loaders.SlimeLoader; -+import com.infernalsuite.aswm.serialization.slime.SlimeSerializer; -+import com.infernalsuite.aswm.skeleton.SkeletonCloning; -+import com.infernalsuite.aswm.skeleton.SkeletonSlimeWorld; -+import com.infernalsuite.aswm.skeleton.SlimeChunkSkeleton; -+import com.infernalsuite.aswm.api.world.SlimeChunk; -+import com.infernalsuite.aswm.api.world.SlimeWorld; -+import com.infernalsuite.aswm.api.world.SlimeWorldInstance; -+import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; ++import com.infernalsuite.asp.ChunkPos; ++import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; ++import com.infernalsuite.asp.api.loaders.SlimeLoader; ++import com.infernalsuite.asp.serialization.slime.SlimeSerializer; ++import com.infernalsuite.asp.skeleton.SkeletonCloning; ++import com.infernalsuite.asp.skeleton.SkeletonSlimeWorld; ++import com.infernalsuite.asp.skeleton.SlimeChunkSkeleton; ++import com.infernalsuite.asp.api.world.SlimeChunk; ++import com.infernalsuite.asp.api.world.SlimeWorld; ++import com.infernalsuite.asp.api.world.SlimeWorldInstance; ++import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.UpgradeData; @@ -1773,13 +1773,13 @@ index 0000000000000000000000000000000000000000..fd4cfb9cceb4f23265cb3cce7f1f2510 + return instance; + } +} -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelGenerator.java b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelGenerator.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java new file mode 100644 -index 0000000000000000000000000000000000000000..4f48b7a1a41aabc78cc9276fbf9f372cb117003f +index 0000000000000000000000000000000000000000..b74ccd2b6b526f7b7955ce601a37185d3b6a2f59 --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelGenerator.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java @@ -0,0 +1,39 @@ -+package com.infernalsuite.aswm.level; ++package com.infernalsuite.asp.level; + +import com.mojang.serialization.Codec; +import net.minecraft.core.Holder; @@ -1819,23 +1819,23 @@ index 0000000000000000000000000000000000000000..4f48b7a1a41aabc78cc9276fbf9f372c + } +} \ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java new file mode 100644 -index 0000000000000000000000000000000000000000..65b475b1292e01c918c1f8144599b5fa78688e97 +index 0000000000000000000000000000000000000000..b8d789c93f7fef253d6ab0c35dcee37460f275eb --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -0,0 +1,197 @@ -+package com.infernalsuite.aswm.level; ++package com.infernalsuite.asp.level; + +import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; +import com.google.common.util.concurrent.ThreadFactoryBuilder; -+import com.infernalsuite.aswm.Converter; -+import com.infernalsuite.aswm.serialization.slime.SlimeSerializer; -+import com.infernalsuite.aswm.api.world.SlimeChunk; -+import com.infernalsuite.aswm.api.world.SlimeWorld; -+import com.infernalsuite.aswm.api.world.SlimeWorldInstance; -+import com.infernalsuite.aswm.api.world.properties.SlimeProperties; -+import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; ++import com.infernalsuite.asp.Converter; ++import com.infernalsuite.asp.serialization.slime.SlimeSerializer; ++import com.infernalsuite.asp.api.world.SlimeChunk; ++import com.infernalsuite.asp.api.world.SlimeWorld; ++import com.infernalsuite.asp.api.world.SlimeWorldInstance; ++import com.infernalsuite.asp.api.world.properties.SlimeProperties; ++import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import io.papermc.paper.chunk.system.scheduling.ChunkLoadTask; +import io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler; +import io.papermc.paper.chunk.system.scheduling.GenericDataLoadTask; @@ -2023,13 +2023,13 @@ index 0000000000000000000000000000000000000000..65b475b1292e01c918c1f8144599b5fa + // } +} \ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/aswm/util/NmsUtil.java b/src/main/java/com/infernalsuite/aswm/util/NmsUtil.java +diff --git a/src/main/java/com/infernalsuite/asp/util/NmsUtil.java b/src/main/java/com/infernalsuite/asp/util/NmsUtil.java new file mode 100644 -index 0000000000000000000000000000000000000000..3500005bb09dc484bc333f1e0799613d097a37d3 +index 0000000000000000000000000000000000000000..04e43a22c1932dce66abb54337cdce802110a7af --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/util/NmsUtil.java ++++ b/src/main/java/com/infernalsuite/asp/util/NmsUtil.java @@ -0,0 +1,9 @@ -+package com.infernalsuite.aswm.util; ++package com.infernalsuite.asp.util; + +public class NmsUtil { + @@ -2073,7 +2073,7 @@ index 790bad0494454ca12ee152e3de6da3da634d9b20..2d6b062c4a3cf682d8e4cdbb7b7c84a7 @Override diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 663b4ecd520e82aa108d44f2d5c2a20cfc7bc01f..4d9b240534372103268a53712a13027ddd434071 100644 +index 4158473fd553a16fec23bcbcf9a278d413120600..e49e329b4713fefb153b64aee35f5e2c9eaa51a4 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -288,7 +288,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop persistentStateManagerFactory) { + // ASWM START -+ public final com.infernalsuite.aswm.level.SlimeBootstrap bootstrap; -+ public ServerChunkCache(com.infernalsuite.aswm.level.SlimeBootstrap bootstrap, ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor workerExecutor, ChunkGenerator chunkGenerator, int viewDistance, int simulationDistance, boolean dsync, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory) { // ASWM ++ public final com.infernalsuite.asp.level.SlimeBootstrap bootstrap; ++ public ServerChunkCache(com.infernalsuite.asp.level.SlimeBootstrap bootstrap, ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor workerExecutor, ChunkGenerator chunkGenerator, int viewDistance, int simulationDistance, boolean dsync, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory) { // ASWM + this.bootstrap = bootstrap; + // ASWM end this.level = world; this.mainThreadProcessor = new ServerChunkCache.MainThreadExecutor(world); this.mainThread = Thread.currentThread(); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 957cae6ddeba9efe3b55588567ae51e8b86b6a42..d414a0056ab27558440086ab373867bd7e28cdd2 100644 +index 585e2b43a0326f0b81597fa1234d3c67c76af550..7eb21e0c8fc4103a4eb656bd1d81ae10e7ee9dc4 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -595,8 +595,14 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -144,7 +144,6 @@ import net.minecraft.world.level.entity.EntityTickList; + import net.minecraft.world.level.entity.EntityTypeTest; + import net.minecraft.world.level.entity.LevelCallback; + import net.minecraft.world.level.entity.LevelEntityGetter; +-import net.minecraft.world.level.entity.PersistentEntitySectionManager; + import net.minecraft.world.level.gameevent.DynamicGameEventListener; + import net.minecraft.world.level.gameevent.GameEvent; + import net.minecraft.world.level.gameevent.GameEventDispatcher; +@@ -595,8 +594,14 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } // Paper end - lag compensation @@ -2204,14 +2212,14 @@ index 957cae6ddeba9efe3b55588567ae51e8b86b6a42..d414a0056ab27558440086ab373867bd + this(null, minecraftserver, executor, convertable_conversionsession, iworlddataserver, resourcekey, worlddimension, worldloadlistener, flag, i, list, flag1, randomsequences, env, gen, biomeProvider); + } + -+ public com.infernalsuite.aswm.level.SlimeInMemoryWorld slimeInstance; // ASWM ++ public com.infernalsuite.asp.level.SlimeInMemoryWorld slimeInstance; // ASWM + + // Add env and gen to constructor, IWorldDataServer -> WorldDataServer -+ public ServerLevel(com.infernalsuite.aswm.level.SlimeBootstrap bootstrap, MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { ++ public ServerLevel(com.infernalsuite.asp.level.SlimeBootstrap bootstrap, MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess(), iworlddataserver.getGameRules())), executor); // Paper - create paper world configs; Async-Anti-Xray: Pass executor this.pvpMode = minecraftserver.isPvpAllowed(); this.convertable = convertable_conversionsession; -@@ -623,6 +629,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -623,6 +628,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe chunkgenerator = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, chunkgenerator, gen); } // CraftBukkit end @@ -2224,7 +2232,7 @@ index 957cae6ddeba9efe3b55588567ae51e8b86b6a42..d414a0056ab27558440086ab373867bd boolean flag2 = minecraftserver.forceSynchronousWrites(); DataFixer datafixer = minecraftserver.getFixerUpper(); EntityPersistentStorage entitypersistentstorage = new EntityStorage(new SimpleRegionStorage(new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, DataFixTypes.ENTITY_CHUNK), this, minecraftserver); -@@ -633,7 +645,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -633,7 +644,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe int k = this.spigotConfig.simulationDistance; // Spigot // Paper - rewrite chunk system @@ -2233,12 +2241,12 @@ index 957cae6ddeba9efe3b55588567ae51e8b86b6a42..d414a0056ab27558440086ab373867bd return minecraftserver.overworld().getDataStorage(); }); this.chunkSource.getGeneratorState().ensureStructuresGenerated(); -@@ -692,6 +704,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -692,6 +703,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.dragonFight = enderDragonFight; } + // ASWM START -+ public ChunkGenerator getGenerator(com.infernalsuite.aswm.level.SlimeBootstrap bootstrap) { ++ public ChunkGenerator getGenerator(com.infernalsuite.asp.level.SlimeBootstrap bootstrap) { + return null; + } + // ASWM END @@ -2259,7 +2267,7 @@ index 8b84bf2272556ac3321cbf16361d7f48a1cc6873..c8f018ec8c142f0e05fcf346f4b1a31c for (int i = 0; i < storage.getSize(); i++) { T object = palette.valueFor(storage.get(i)); diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java -index 774556a62eb240da42e84db4502e2ed43495be17..29e29fb2228f08dff3edd8bf651220b83b16ed7b 100644 +index 774556a62eb240da42e84db4502e2ed43495be17..f3ff4b5f15959a3fc52c000f7636bc3f23dd7598 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java +++ b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java @@ -11,7 +11,7 @@ public final class Versioning { @@ -2267,15 +2275,15 @@ index 774556a62eb240da42e84db4502e2ed43495be17..29e29fb2228f08dff3edd8bf651220b8 String result = "Unknown-Version"; - InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/io.papermc.paper/paper-api/pom.properties"); -+ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/com.infernalsuite.aswm/slimeworldmanager-api/pom.properties"); // ASWM ++ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/com.infernalsuite.asp/slimeworldmanager-api/pom.properties"); // ASWM Properties properties = new Properties(); if (stream != null) { -diff --git a/src/main/resources/META-INF/services/com.infernalsuite.aswm.api.SlimeNMSBridge b/src/main/resources/META-INF/services/com.infernalsuite.aswm.api.SlimeNMSBridge +diff --git a/src/main/resources/META-INF/services/com.infernalsuite.asp.api.SlimeNMSBridge b/src/main/resources/META-INF/services/com.infernalsuite.asp.api.SlimeNMSBridge new file mode 100644 -index 0000000000000000000000000000000000000000..d07947f0b42fe491617151e2aa7b0f02ff3ce610 +index 0000000000000000000000000000000000000000..973f2f48d75f1912c12bb89a106379557747296d --- /dev/null -+++ b/src/main/resources/META-INF/services/com.infernalsuite.aswm.api.SlimeNMSBridge ++++ b/src/main/resources/META-INF/services/com.infernalsuite.asp.api.SlimeNMSBridge @@ -0,0 +1 @@ -+com.infernalsuite.aswm.SlimeNMSBridgeImpl ++com.infernalsuite.asp.SlimeNMSBridgeImpl \ No newline at end of file diff --git a/patches/server/0002-poi-data-loader.patch b/patches/server/0002-poi-data-loader.patch index 347cd642c..0b9b2cd54 100644 --- a/patches/server/0002-poi-data-loader.patch +++ b/patches/server/0002-poi-data-loader.patch @@ -17,10 +17,10 @@ index bbf9d6c1c9525d97160806819a57be03eca290f1..38ca7bd039bc1b60a63ff68c53e3ec31 private static final Logger LOGGER = LoggerFactory.getLogger(PoiChunk.class); -diff --git a/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java b/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java -index 41e652b568598926e838e81fdc338e51f8e97ef8..c32d52c68188dc1eb7feeac364cdc4aded1c4574 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java -+++ b/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java +diff --git a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java +index bb954b74739e22525f9a45648d3ecf54f5a9e61c..7e7c560b89c45e8ff003813f3c7a141c2b0b7a1d 100644 +--- a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java ++++ b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java @@ -14,6 +14,7 @@ import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ImposterProtoChunk; import net.minecraft.world.level.chunk.LevelChunk; @@ -44,7 +44,7 @@ index 41e652b568598926e838e81fdc338e51f8e97ef8..c32d52c68188dc1eb7feeac364cdc4ad try { // if (data.tasks != null) { diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index 018b24d7611c3fd11536441431abf8f125850129..faf7f4f3bd1fbc91a40e5549a7a5520ea3eaec37 100644 +index 018b24d7611c3fd11536441431abf8f125850129..6f482bf045cf7a14dceb5673d9d19ee87b7c03a8 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java @@ -369,6 +369,10 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun @@ -52,7 +52,7 @@ index 018b24d7611c3fd11536441431abf8f125850129..faf7f4f3bd1fbc91a40e5549a7a5520e levellightengine.queueSectionData(LightLayer.SKY, sectionposition, serializablechunkdata_b.skyLight); } + -+ if (world instanceof com.infernalsuite.aswm.level.SlimeLevelInstance) { ++ if (world instanceof com.infernalsuite.asp.level.SlimeLevelInstance) { + poiStorage.checkConsistencyWithBlocks(SectionPos.of(chunkPos.getWorldPosition()), achunksection[j]); + } } diff --git a/patches/server/0003-Add-support-for-serializing-deserializing-PDC.patch b/patches/server/0003-Add-support-for-serializing-deserializing-PDC.patch index 93cc19152..391cb5dbe 100644 --- a/patches/server/0003-Add-support-for-serializing-deserializing-PDC.patch +++ b/patches/server/0003-Add-support-for-serializing-deserializing-PDC.patch @@ -4,10 +4,10 @@ Date: Sat, 21 Oct 2023 18:11:15 +0200 Subject: [PATCH] Add support for serializing/deserializing PDC -diff --git a/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java -index 20f16757ba8b8da525ff17d51d4f7eb660c4d22b..97a3c0401d1bcf34d8022da5163b8169a66fd5b3 100644 ---- a/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java -+++ b/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java +diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java +index d1ab18a2a2793807118ae1fc23d21248aa7e09a3..0c1e599aa7d148c40ece1957c89991e1d761162a 100644 +--- a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java ++++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java @@ -11,6 +11,7 @@ import com.mojang.serialization.Lifecycle; import net.kyori.adventure.util.Services; import net.minecraft.SharedConstants; @@ -28,18 +28,18 @@ index 20f16757ba8b8da525ff17d51d4f7eb660c4d22b..97a3c0401d1bcf34d8022da5163b8169 return level; } -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -index fd4cfb9cceb4f23265cb3cce7f1f251051bfba92..03f0a5c88a6b2d28a5a69649fc1295b51aaf879f 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -@@ -2,6 +2,7 @@ package com.infernalsuite.aswm.level; +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +index ba337466525971885247c269c23aac7df96d2782..5d325e85a4634c21ab0bec12b493ea9b857d8ff3 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +@@ -2,6 +2,7 @@ package com.infernalsuite.asp.level; import com.flowpowered.nbt.CompoundTag; - import com.infernalsuite.aswm.ChunkPos; -+import com.infernalsuite.aswm.Converter; - import com.infernalsuite.aswm.api.exceptions.WorldAlreadyExistsException; - import com.infernalsuite.aswm.api.loaders.SlimeLoader; - import com.infernalsuite.aswm.serialization.slime.SlimeSerializer; + import com.infernalsuite.asp.ChunkPos; ++import com.infernalsuite.asp.Converter; + import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; + import com.infernalsuite.asp.api.loaders.SlimeLoader; + import com.infernalsuite.asp.serialization.slime.SlimeSerializer; @@ -235,6 +236,17 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { cloned.put(entry.getKey(), clonedChunk); } diff --git a/patches/server/0004-Fix-entity-loading.patch b/patches/server/0004-Fix-entity-loading.patch index 56691b851..3ae83cdf2 100644 --- a/patches/server/0004-Fix-entity-loading.patch +++ b/patches/server/0004-Fix-entity-loading.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix entity loading diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -index eafa4e6d55cd0f9314ac0f2b96a7f48fbb5e1a4c..bc0990458df745c92e5bc0530ff35ab992365b3a 100644 +index eafa4e6d55cd0f9314ac0f2b96a7f48fbb5e1a4c..62b526f7e147586977615ec8cec191d0aaf0bcdc 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java @@ -117,7 +117,7 @@ public final class NewChunkHolder { @@ -13,20 +13,20 @@ index eafa4e6d55cd0f9314ac0f2b96a7f48fbb5e1a4c..bc0990458df745c92e5bc0530ff35ab9 if (!transientChunk) { - if (entityChunk != null) { -+ if (!(this.world instanceof com.infernalsuite.aswm.level.SlimeLevelInstance) && entityChunk != null) { ++ if (!(this.world instanceof com.infernalsuite.asp.level.SlimeLevelInstance) && entityChunk != null) { final List entities = ChunkEntitySlices.readEntities(this.world, entityChunk); ((ChunkSystemServerLevel)this.world).moonrise$getEntityLookup().addEntityChunkEntities(entities, new ChunkPos(this.chunkX, this.chunkZ)); -diff --git a/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java b/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java -index c32d52c68188dc1eb7feeac364cdc4aded1c4574..8485296594c01edcaef271fc37bf2c70932f4986 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java -+++ b/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java +diff --git a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java +index 7e7c560b89c45e8ff003813f3c7a141c2b0b7a1d..e2c67548ff6341c1c981af83f6df7711c78330a9 100644 +--- a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java ++++ b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java @@ -1,12 +1,13 @@ - package com.infernalsuite.aswm.level; + package com.infernalsuite.asp.level; import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import com.infernalsuite.aswm.Converter; - import com.infernalsuite.aswm.api.world.SlimeChunk; ++import com.infernalsuite.asp.Converter; + import com.infernalsuite.asp.api.world.SlimeChunk; import com.mojang.logging.LogUtils; -import io.papermc.paper.chunk.system.poi.PoiChunk; import io.papermc.paper.chunk.system.scheduling.ChunkLoadTask; @@ -67,10 +67,10 @@ index c32d52c68188dc1eb7feeac364cdc4aded1c4574..8485296594c01edcaef271fc37bf2c70 } catch (final ThreadDeath death) { throw death; } catch (final Throwable thr2) { -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java -index 91a7f41db47c7df3ecc301e0827a1d07305f604e..27af3aa6ba8ffb100a6b1b50ba584e65c4aee86a 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +index ba0b401e0b39605303e90720f7c8dc48fcb0bc29..6b38f707b43e1e584c79a6c8d9ec1232ed2901b9 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java @@ -15,6 +15,8 @@ import net.minecraft.core.Holder; import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; diff --git a/patches/server/0005-Remove-catch-throwable.patch b/patches/server/0005-Remove-catch-throwable.patch index 89b3cf28a..d89ef86ee 100644 --- a/patches/server/0005-Remove-catch-throwable.patch +++ b/patches/server/0005-Remove-catch-throwable.patch @@ -4,10 +4,10 @@ Date: Thu, 2 Nov 2023 23:01:26 +0000 Subject: [PATCH] Remove catch throwable -diff --git a/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java b/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java -index 8485296594c01edcaef271fc37bf2c70932f4986..f9ac1efca06d8debbb7894160c3e67fd23440ebb 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java -+++ b/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java +diff --git a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java +index e2c67548ff6341c1c981af83f6df7711c78330a9..bf44132f7614832119f798a2418e2014ec378cf9 100644 +--- a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java ++++ b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java @@ -48,7 +48,7 @@ public final class ChunkDataLoadTask implements CommonLoadTask { try { SlimeChunk chunk = ((SlimeLevelInstance) this.world).slimeInstance.getChunk(this.chunkX, this.chunkZ); diff --git a/patches/server/0006-Handle-null-data-properly.patch b/patches/server/0006-Handle-null-data-properly.patch index 3f30631e6..ebad5140d 100644 --- a/patches/server/0006-Handle-null-data-properly.patch +++ b/patches/server/0006-Handle-null-data-properly.patch @@ -4,10 +4,10 @@ Date: Sat, 4 Nov 2023 20:36:26 +0000 Subject: [PATCH] Handle null data properly -diff --git a/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java -index 1affe4c94b490a05184deccc9eb80530f67fd5ea..1a4be97069f01a82deadd26a94e86dbebe0e47a0 100644 ---- a/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java -+++ b/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java +diff --git a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java +index 2f5b79632226f5d0112a4c0ddfc903d6b2b93549..eb426271140d9e36b09ef96e4c59c21d265a5edc 100644 +--- a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java ++++ b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java @@ -45,9 +45,12 @@ class SimpleDataFixerConverter implements SlimeWorldReader { ); } diff --git a/patches/server/0007-Make-SlimeWorld-a-PersistentDataHolder.patch b/patches/server/0007-Make-SlimeWorld-a-PersistentDataHolder.patch index 8db8760b9..de4933554 100644 --- a/patches/server/0007-Make-SlimeWorld-a-PersistentDataHolder.patch +++ b/patches/server/0007-Make-SlimeWorld-a-PersistentDataHolder.patch @@ -4,17 +4,17 @@ Date: Thu, 26 Oct 2023 14:55:39 +0200 Subject: [PATCH] Make SlimeWorld a PersistentDataHolder -diff --git a/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java -index 97a3c0401d1bcf34d8022da5163b8169a66fd5b3..21c3ea3596a1f954618348afae2b2f7f058393d1 100644 ---- a/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java -+++ b/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java +diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java +index 0c1e599aa7d148c40ece1957c89991e1d761162a..4c503e5a31ba38c5a52e9b6738a6ade4fab94b49 100644 +--- a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java ++++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java @@ -1,5 +1,6 @@ - package com.infernalsuite.aswm; + package com.infernalsuite.asp; +import com.flowpowered.nbt.CompoundMap; - import com.infernalsuite.aswm.api.SlimeNMSBridge; - import com.infernalsuite.aswm.api.world.SlimeWorld; - import com.infernalsuite.aswm.api.world.SlimeWorldInstance; + import com.infernalsuite.asp.api.SlimeNMSBridge; + import com.infernalsuite.asp.api.world.SlimeWorld; + import com.infernalsuite.asp.api.world.SlimeWorldInstance; @@ -12,6 +13,7 @@ import net.kyori.adventure.util.Services; import net.minecraft.SharedConstants; import net.minecraft.core.registries.Registries; @@ -69,11 +69,11 @@ index 97a3c0401d1bcf34d8022da5163b8169a66fd5b3..21c3ea3596a1f954618348afae2b2f7f @Override public boolean loadOverworldOverride() { if (defaultWorld == null) { -diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeWorld.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeWorld.java -index 9a27369c00345bbb94aa19f77687269dc94c0b0a..07e542e3f75bf272f53345dc040d90358e7d7b2d 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeWorld.java -+++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeWorld.java -@@ -9,6 +9,8 @@ import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; +diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java +index 3dc776b5387b4e2f1b669f754b5b064fc0142006..76ee216925d9ced3c9bf1e7e8e1d8b80ca9f8e50 100644 +--- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java ++++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java +@@ -9,6 +9,8 @@ import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import net.minecraft.SharedConstants; import net.minecraft.server.level.ChunkHolder; import net.minecraft.world.level.chunk.LevelChunk; @@ -93,18 +93,18 @@ index 9a27369c00345bbb94aa19f77687269dc94c0b0a..07e542e3f75bf272f53345dc040d9035 + } } \ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -index 03f0a5c88a6b2d28a5a69649fc1295b51aaf879f..092dae1f9e68f1c395cd0f8151cd696c0bcdceb0 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -@@ -5,6 +5,7 @@ import com.infernalsuite.aswm.ChunkPos; - import com.infernalsuite.aswm.Converter; - import com.infernalsuite.aswm.api.exceptions.WorldAlreadyExistsException; - import com.infernalsuite.aswm.api.loaders.SlimeLoader; -+import com.infernalsuite.aswm.pdc.FlowPersistentDataContainer; - import com.infernalsuite.aswm.serialization.slime.SlimeSerializer; - import com.infernalsuite.aswm.skeleton.SkeletonCloning; - import com.infernalsuite.aswm.skeleton.SkeletonSlimeWorld; +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +index 5d325e85a4634c21ab0bec12b493ea9b857d8ff3..35d0dd30b3c91b423c03a8f1682a422bf5eb8bc1 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +@@ -5,6 +5,7 @@ import com.infernalsuite.asp.ChunkPos; + import com.infernalsuite.asp.Converter; + import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; + import com.infernalsuite.asp.api.loaders.SlimeLoader; ++import com.infernalsuite.asp.pdc.FlowPersistentDataContainer; + import com.infernalsuite.asp.serialization.slime.SlimeSerializer; + import com.infernalsuite.asp.skeleton.SkeletonCloning; + import com.infernalsuite.asp.skeleton.SkeletonSlimeWorld; @@ -19,6 +20,8 @@ import net.minecraft.world.level.chunk.UpgradeData; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.ticks.LevelChunkTicks; diff --git a/patches/server/0008-Add-v12-chunk-pdc-and-extra-nbt.-Fix-double-compress.patch b/patches/server/0008-Add-v12-chunk-pdc-and-extra-nbt.-Fix-double-compress.patch index f047a3204..445aa874e 100644 --- a/patches/server/0008-Add-v12-chunk-pdc-and-extra-nbt.-Fix-double-compress.patch +++ b/patches/server/0008-Add-v12-chunk-pdc-and-extra-nbt.-Fix-double-compress.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add v12, chunk pdc and extra nbt. Fix double compression on tile entities and entities. Fix horrible bug which made chunks go poof. -diff --git a/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java -index 1a4be97069f01a82deadd26a94e86dbebe0e47a0..ca4a80e7b5c73f9669a717adc46b2e9b8c1f48b6 100644 ---- a/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java -+++ b/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java +diff --git a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java +index eb426271140d9e36b09ef96e4c59c21d265a5edc..36d13632916b8e93d5f28c29ea80ef4ac87e6c89 100644 +--- a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java ++++ b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java @@ -70,11 +70,12 @@ class SimpleDataFixerConverter implements SlimeWorldReader { chunks.put(chunkPos, new SlimeChunkSkeleton( @@ -24,10 +24,10 @@ index 1a4be97069f01a82deadd26a94e86dbebe0e47a0..ca4a80e7b5c73f9669a717adc46b2e9b )); } -diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java -index f1db2fe121bb3aabfad727a8133b645524b8f19a..ad30e83670ca88f09fa7625fc52c224247410623 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java -+++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java +diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +index 9a6e901b394d1e7740e616a33e6c251ae1d7e0e0..dc34469712bdd84d4b17dfd5e9657c3a12420241 100644 +--- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java ++++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -67,9 +67,11 @@ public class NMSSlimeChunk implements SlimeChunk { } @@ -53,10 +53,10 @@ index f1db2fe121bb3aabfad727a8133b645524b8f19a..ad30e83670ca88f09fa7625fc52c2242 public LevelChunk getChunk() { return chunk; } -diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeWorld.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeWorld.java -index 07e542e3f75bf272f53345dc040d90358e7d7b2d..004d7bcc5b35c76855787dcf32fe460e73cab38f 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeWorld.java -+++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeWorld.java +diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java +index 76ee216925d9ced3c9bf1e7e8e1d8b80ca9f8e50..bd2f8da46d4a04f2777086a416015563f3b06cdf 100644 +--- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java ++++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java @@ -45,14 +45,14 @@ public class NMSSlimeWorld implements SlimeWorld { return null; } @@ -74,10 +74,10 @@ index 07e542e3f75bf272f53345dc040d90358e7d7b2d..004d7bcc5b35c76855787dcf32fe460e .collect(Collectors.toList()); } -diff --git a/src/main/java/com/infernalsuite/aswm/level/SafeNmsChunkWrapper.java b/src/main/java/com/infernalsuite/aswm/level/SafeNmsChunkWrapper.java -index b20a037679182e3c4a8bf31f084078f6d7e4ff46..e449b3eebe0d245a2107a6d0018930d32dfc4976 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SafeNmsChunkWrapper.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SafeNmsChunkWrapper.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java b/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java +index 025da4dd831f9b8b35000be7de493d44caa41003..7dd1c52f718866f8918c30de9cc71d151eddc958 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java ++++ b/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java @@ -62,6 +62,15 @@ public class SafeNmsChunkWrapper implements SlimeChunk { return this.wrapper.getEntities(); } @@ -94,10 +94,10 @@ index b20a037679182e3c4a8bf31f084078f6d7e4ff46..e449b3eebe0d245a2107a6d0018930d3 /* Slime chunks can still be requested but not actually loaded, this caused some things to not properly save because they are not "loaded" into the chunk. -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java -index 27af3aa6ba8ffb100a6b1b50ba584e65c4aee86a..a03c59d2800885e90467812f0088787a85d8cd88 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +index 6b38f707b43e1e584c79a6c8d9ec1232ed2901b9..d3289cb71f9ff71d5122ed43e9a0ab40f93c774a 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java @@ -165,6 +165,13 @@ public class SlimeChunkConverter { Heightmap.primeHeightmaps(nmsChunk, unsetHeightMaps); } @@ -113,18 +113,18 @@ index 27af3aa6ba8ffb100a6b1b50ba584e65c4aee86a..a03c59d2800885e90467812f0088787a } } \ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -index 092dae1f9e68f1c395cd0f8151cd696c0bcdceb0..72a74f0c2cf21c32fa4ffd600cf95eaee003aec6 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +index 35d0dd30b3c91b423c03a8f1682a422bf5eb8bc1..15340aecc97a30767340f7837a21decc74afbe9c 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -1,6 +1,7 @@ - package com.infernalsuite.aswm.level; + package com.infernalsuite.asp.level; import com.flowpowered.nbt.CompoundTag; +import com.flowpowered.nbt.Tag; - import com.infernalsuite.aswm.ChunkPos; - import com.infernalsuite.aswm.Converter; - import com.infernalsuite.aswm.api.exceptions.WorldAlreadyExistsException; + import com.infernalsuite.asp.ChunkPos; + import com.infernalsuite.asp.Converter; + import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; @@ -88,11 +89,11 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { levelChunk = new SlimeChunkLevel(this.instance, pos, UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks, 0L, null, null, null); @@ -179,10 +179,10 @@ index 092dae1f9e68f1c395cd0f8151cd696c0bcdceb0..72a74f0c2cf21c32fa4ffd600cf95eae ); } } -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java -index 65b475b1292e01c918c1f8144599b5fa78688e97..a525fa1781535d458c5ecb67e261520692c858ac 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +index b8d789c93f7fef253d6ab0c35dcee37460f275eb..5e3426a632d471aff38de29645fdee291c4931ae 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -151,9 +151,7 @@ public class SlimeLevelInstance extends ServerLevel { Bukkit.getLogger().log(Level.INFO, "Saving world " + this.slimeInstance.getName() + "..."); long start = System.currentTimeMillis(); diff --git a/patches/server/0009-Add-migration-from-SRF-1-8.patch b/patches/server/0009-Add-migration-from-SRF-1-8.patch index 800ce1c81..edfd8cd53 100644 --- a/patches/server/0009-Add-migration-from-SRF-1-8.patch +++ b/patches/server/0009-Add-migration-from-SRF-1-8.patch @@ -4,12 +4,12 @@ Date: Sat, 6 Jan 2024 22:23:55 +0100 Subject: [PATCH] Add migration from SRF 1-8 -diff --git a/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java -index ca4a80e7b5c73f9669a717adc46b2e9b8c1f48b6..ba203e3dc9f6b0be5a92c30808daa0c284616f09 100644 ---- a/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java -+++ b/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java +diff --git a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java +index 36d13632916b8e93d5f28c29ea80ef4ac87e6c89..b2a0913290694d27151779aac5fb6be57f01da8b 100644 +--- a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java ++++ b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java @@ -1,5 +1,6 @@ - package com.infernalsuite.aswm; + package com.infernalsuite.asp; +import ca.spottedleaf.dataconverter.converters.DataConverter; import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; @@ -22,7 +22,7 @@ index ca4a80e7b5c73f9669a717adc46b2e9b8c1f48b6..ba203e3dc9f6b0be5a92c30808daa0c2 + long encodedNewVersion = DataConverter.encodeVersions(newVersion, Integer.MAX_VALUE); + long encodedCurrentVersion = DataConverter.encodeVersions(currentVersion, Integer.MAX_VALUE); + - Map chunks = new HashMap<>(); + Map chunks = new HashMap<>(); for (SlimeChunk chunk : data.getChunkStorage()) { List entities = new ArrayList<>(); List blockEntities = new ArrayList<>(); @@ -63,22 +63,22 @@ index ca4a80e7b5c73f9669a717adc46b2e9b8c1f48b6..ba203e3dc9f6b0be5a92c30808daa0c2 )); } -diff --git a/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java -index 21c3ea3596a1f954618348afae2b2f7f058393d1..18f0f7933c42a7609a3d7bd775b24c372baae175 100644 ---- a/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java -+++ b/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java +diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java +index 4c503e5a31ba38c5a52e9b6738a6ade4fab94b49..bfcd4fc5e0ce187c79491fc720bb4bebde51f8e1 100644 +--- a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java ++++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java @@ -1,5 +1,8 @@ - package com.infernalsuite.aswm; + package com.infernalsuite.asp; +import ca.spottedleaf.dataconverter.converters.DataConverter; +import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; +import ca.spottedleaf.dataconverter.types.nbt.NBTMapType; import com.flowpowered.nbt.CompoundMap; - import com.infernalsuite.aswm.api.SlimeNMSBridge; - import com.infernalsuite.aswm.api.world.SlimeWorld; -@@ -9,7 +12,6 @@ import com.infernalsuite.aswm.level.SlimeBootstrap; - import com.infernalsuite.aswm.level.SlimeInMemoryWorld; - import com.infernalsuite.aswm.level.SlimeLevelInstance; + import com.infernalsuite.asp.api.SlimeNMSBridge; + import com.infernalsuite.asp.api.world.SlimeWorld; +@@ -9,7 +12,6 @@ import com.infernalsuite.asp.level.SlimeBootstrap; + import com.infernalsuite.asp.level.SlimeInMemoryWorld; + import com.infernalsuite.asp.level.SlimeLevelInstance; import com.mojang.serialization.Lifecycle; -import net.kyori.adventure.util.Services; import net.minecraft.SharedConstants; @@ -113,10 +113,10 @@ index 21c3ea3596a1f954618348afae2b2f7f058393d1..18f0f7933c42a7609a3d7bd775b24c37 @Override public int getCurrentVersion() { return SharedConstants.getCurrentVersion().getDataVersion().getVersion(); -diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java -index ad30e83670ca88f09fa7625fc52c224247410623..e183ca25bf67a0519de7a91615fbcfc6ff45a56e 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java -+++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java +diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +index dc34469712bdd84d4b17dfd5e9657c3a12420241..419c3c12177bc7b85c6643fb114b4d0ad8f80c46 100644 +--- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java ++++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -26,10 +26,7 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BlockEntity; @@ -156,10 +156,10 @@ index ad30e83670ca88f09fa7625fc52c224247410623..e183ca25bf67a0519de7a91615fbcfc6 public LevelChunk getChunk() { return chunk; } -diff --git a/src/main/java/com/infernalsuite/aswm/level/SafeNmsChunkWrapper.java b/src/main/java/com/infernalsuite/aswm/level/SafeNmsChunkWrapper.java -index e449b3eebe0d245a2107a6d0018930d32dfc4976..f5da649f4914319229fdba014e1042abca62f835 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SafeNmsChunkWrapper.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SafeNmsChunkWrapper.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java b/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java +index 7dd1c52f718866f8918c30de9cc71d151eddc958..4df75c87f235ca5c55982c0b836f433eec9c9e9f 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java ++++ b/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java @@ -71,6 +71,15 @@ public class SafeNmsChunkWrapper implements SlimeChunk { return this.wrapper.getExtraData(); } @@ -176,10 +176,10 @@ index e449b3eebe0d245a2107a6d0018930d32dfc4976..f5da649f4914319229fdba014e1042ab /* Slime chunks can still be requested but not actually loaded, this caused some things to not properly save because they are not "loaded" into the chunk. -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java -index a03c59d2800885e90467812f0088787a85d8cd88..75bb1e9355141215c4850f1b57db9434d8212637 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +index d3289cb71f9ff71d5122ed43e9a0ab40f93c774a..ace4d6272560783fd7903495b5a3c84550b1b4d8 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java @@ -118,7 +118,14 @@ public class SlimeChunkConverter { LevelChunkTicks blockLevelChunkTicks = new LevelChunkTicks<>(); @@ -196,10 +196,10 @@ index a03c59d2800885e90467812f0088787a85d8cd88..75bb1e9355141215c4850f1b57db9434 List tileEntities = chunk.getTileEntities(); -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -index 72a74f0c2cf21c32fa4ffd600cf95eaee003aec6..95133e0ff8a8bdfc84c1dd7ff6b2c7ed7ae9a2f9 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +index 15340aecc97a30767340f7837a21decc74afbe9c..619075ededa0443cf8f888f04d863bf7b936a4b0 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -115,7 +115,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { this.chunkStorage.put(new ChunkPos(x, z), diff --git a/patches/server/0010-Add-default-spawn-yaw-propagate-CraftWorld-setSpawnL.patch b/patches/server/0010-Add-default-spawn-yaw-propagate-CraftWorld-setSpawnL.patch index d2dd3d0b2..4798b9012 100644 --- a/patches/server/0010-Add-default-spawn-yaw-propagate-CraftWorld-setSpawnL.patch +++ b/patches/server/0010-Add-default-spawn-yaw-propagate-CraftWorld-setSpawnL.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add default spawn yaw, propagate CraftWorld#setSpawnLocation to the SlimeProperties. -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java -index a525fa1781535d458c5ecb67e261520692c858ac..1d5547a74042743e388f77f70b9ebbd37be3f1bc 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +index 5e3426a632d471aff38de29645fdee291c4931ae..eddae8fc510d6e263df55a725148d96f677bcb0b 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -95,7 +95,11 @@ public class SlimeLevelInstance extends ServerLevel { SlimePropertyMap propertyMap = slimeBootstrap.initial().getPropertyMap(); diff --git a/patches/server/0011-Fix-chunks-not-getting-serialized-when-reloaded.patch b/patches/server/0011-Fix-chunks-not-getting-serialized-when-reloaded.patch index 8684f2c0d..6e13e13db 100644 --- a/patches/server/0011-Fix-chunks-not-getting-serialized-when-reloaded.patch +++ b/patches/server/0011-Fix-chunks-not-getting-serialized-when-reloaded.patch @@ -4,10 +4,10 @@ Date: Sun, 19 May 2024 19:17:07 +0200 Subject: [PATCH] Fix chunks not getting serialized when reloaded. -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkLevel.java b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkLevel.java -index b159fc8751e9840b311cc1eda01e496e2dbc5f2e..2ebabf20c37d2b5c479de5bb241aa334f92a1104 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkLevel.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkLevel.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java +index 0d218911fb8be1bc5272b6e291ec60404306c831..a92d17b5c6a7c8427ecbdf56a9c2a0c1b66978e4 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java @@ -24,4 +24,10 @@ public class SlimeChunkLevel extends LevelChunk { super.unloadCallback(); this.inMemoryWorld.unload(this); @@ -20,10 +20,10 @@ index b159fc8751e9840b311cc1eda01e496e2dbc5f2e..2ebabf20c37d2b5c479de5bb241aa334 + } } \ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -index 95133e0ff8a8bdfc84c1dd7ff6b2c7ed7ae9a2f9..b54b231e22967eb0b34e6ba9b7ec9cdf64bad87e 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +index 619075ededa0443cf8f888f04d863bf7b936a4b0..70eb8b95740b46579ad3520ca1d3395a920a8a6a 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -219,7 +219,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { } else { chunk = safeNmsChunkWrapper.getWrapper().getChunk(); diff --git a/patches/server/0012-Compile-fixes.patch b/patches/server/0012-Compile-fixes.patch index 75cb8942a..070b28a17 100644 --- a/patches/server/0012-Compile-fixes.patch +++ b/patches/server/0012-Compile-fixes.patch @@ -5,12 +5,12 @@ Subject: [PATCH] Compile fixes diff --git a/build.gradle.kts b/build.gradle.kts -index 41ed3865710e9732f7662e1d3bf287ad9cf80c74..bb915dc69af63cab992a5b7f8654b5390340c89e 100644 +index b5b5c099e61f828edbcd18aba9d379a6e45fb8b4..838639a8bbeb59700037c3e101714f68f8b79671 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -29,9 +29,6 @@ dependencies { // ASWM start - implementation(project(":slimeworldmanager-api")) + implementation(project(":aspaper-api")) implementation(project(":core")) - implementation("io.papermc.paper:paper-mojangapi:1.20.4-R0.1-SNAPSHOT") { - exclude("io.papermc.paper", "paper-api") @@ -18,10 +18,10 @@ index 41ed3865710e9732f7662e1d3bf287ad9cf80c74..bb915dc69af63cab992a5b7f8654b539 // ASWM end // Paper start implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ -diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java -index e183ca25bf67a0519de7a91615fbcfc6ff45a56e..b295d159200e3bf0e48f851ac206b2e09b756bb2 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java -+++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java +diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +index 419c3c12177bc7b85c6643fb114b4d0ad8f80c46..b6c0ba9325b06e1d76609aa4de564af11f231a74 100644 +--- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java ++++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -46,18 +46,14 @@ public class NMSSlimeChunk implements SlimeChunk { static { { @@ -70,10 +70,10 @@ index e183ca25bf67a0519de7a91615fbcfc6ff45a56e..b295d159200e3bf0e48f851ac206b2e0 tileEntities.add(entityNbt); } -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java -index 75bb1e9355141215c4850f1b57db9434d8212637..003778f3ba9db1f52d7746d3b4b1132e373dd365 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +index ace4d6272560783fd7903495b5a3c84550b1b4d8..6807767a2067b62558f749da0c25f184082d0769 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java @@ -78,7 +78,7 @@ public class SlimeChunkConverter { DataResult> dataresult = ChunkSerializer.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, Converter.convertTag(slimeSection.getBlockStatesTag())).promotePartial((s) -> { System.out.println("Recoverable error when parsing section " + x + "," + z + ": " + s); // todo proper logging @@ -101,12 +101,12 @@ index 75bb1e9355141215c4850f1b57db9434d8212637..003778f3ba9db1f52d7746d3b4b1132e if (entity != null) { nmsChunk.setBlockEntity(entity); -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelGenerator.java b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelGenerator.java -index 4f48b7a1a41aabc78cc9276fbf9f372cb117003f..aa3ed7005ddfda74b2c3ca1e1dde810c62aa1ce7 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelGenerator.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelGenerator.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java +index b74ccd2b6b526f7b7955ce601a37185d3b6a2f59..18053d099145bd9351902ff062139c731eafc5d3 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java @@ -1,6 +1,7 @@ - package com.infernalsuite.aswm.level; + package com.infernalsuite.asp.level; import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; @@ -122,10 +122,10 @@ index 4f48b7a1a41aabc78cc9276fbf9f372cb117003f..aa3ed7005ddfda74b2c3ca1e1dde810c return null; } -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java -index 1d5547a74042743e388f77f70b9ebbd37be3f1bc..b28c2b917accc0249e5df19a65db8820336b7279 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +index eddae8fc510d6e263df55a725148d96f677bcb0b..a8c103d435ac9473b1c5dd404e5c69ebf4353490 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -103,8 +103,6 @@ public class SlimeLevelInstance extends ServerLevel { super.setSpawnSettings(propertyMap.getValue(SlimeProperties.ALLOW_MONSTERS), propertyMap.getValue(SlimeProperties.ALLOW_ANIMALS)); diff --git a/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch b/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch index 1e5e946cc..8293c5747 100644 --- a/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch +++ b/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch @@ -5,42 +5,42 @@ Subject: [PATCH] Separate plugin and server, rework API (to v3) diff --git a/build.gradle.kts b/build.gradle.kts -index 22931927ac8c1fcdc45d44f8d4a898a44831039c..e10d95ce805d03fa43f526dc0a1a1123a67b4f0c 100644 +index 838639a8bbeb59700037c3e101714f68f8b79671..26be7ff48f2eb50a140e71372cfef54d4ff570f1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -29,6 +29,7 @@ dependencies { // ASWM start - implementation(project(":slimeworldmanager-api")) + implementation(project(":aspaper-api")) implementation(project(":core")) + implementation("commons-io:commons-io:2.11.0") // ASWM end // Paper start implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ -diff --git a/src/main/java/com/infernalsuite/aswm/AdvancedSlimePaper.java b/src/main/java/com/infernalsuite/aswm/AdvancedSlimePaper.java +diff --git a/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java b/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java new file mode 100644 -index 0000000000000000000000000000000000000000..719bfb548cfe69cbb726d95b68527bdf45f1eb52 +index 0000000000000000000000000000000000000000..704cf0fa3d3c6114923d5b9b9594a4ba9d7ab0a6 --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/AdvancedSlimePaper.java ++++ b/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java @@ -0,0 +1,243 @@ -+package com.infernalsuite.aswm; ++package com.infernalsuite.asp; + +import com.flowpowered.nbt.CompoundMap; +import com.flowpowered.nbt.CompoundTag; -+import com.infernalsuite.aswm.api.SlimeNMSBridge; -+import com.infernalsuite.aswm.api.AdvancedSlimePaperAPI; -+import com.infernalsuite.aswm.api.events.LoadSlimeWorldEvent; -+import com.infernalsuite.aswm.api.exceptions.*; -+import com.infernalsuite.aswm.api.loaders.SlimeLoader; -+import com.infernalsuite.aswm.api.world.SlimeWorld; -+import com.infernalsuite.aswm.api.world.SlimeWorldInstance; -+import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; -+import com.infernalsuite.aswm.level.SlimeLevelInstance; -+import com.infernalsuite.aswm.serialization.anvil.AnvilImportData; -+import com.infernalsuite.aswm.serialization.anvil.AnvilWorldReader; -+import com.infernalsuite.aswm.serialization.slime.SlimeSerializer; -+import com.infernalsuite.aswm.serialization.slime.reader.SlimeWorldReaderRegistry; -+import com.infernalsuite.aswm.skeleton.SkeletonSlimeWorld; -+import com.infernalsuite.aswm.util.NmsUtil; ++import com.infernalsuite.asp.api.SlimeNMSBridge; ++import com.infernalsuite.asp.api.AdvancedSlimePaperAPI; ++import com.infernalsuite.asp.api.events.LoadSlimeWorldEvent; ++import com.infernalsuite.asp.api.exceptions.*; ++import com.infernalsuite.asp.api.loaders.SlimeLoader; ++import com.infernalsuite.asp.api.world.SlimeWorld; ++import com.infernalsuite.asp.api.world.SlimeWorldInstance; ++import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; ++import com.infernalsuite.asp.level.SlimeLevelInstance; ++import com.infernalsuite.asp.serialization.anvil.AnvilImportData; ++import com.infernalsuite.asp.serialization.anvil.AnvilWorldReader; ++import com.infernalsuite.asp.serialization.slime.SlimeSerializer; ++import com.infernalsuite.asp.serialization.slime.reader.SlimeWorldReaderRegistry; ++import com.infernalsuite.asp.skeleton.SkeletonSlimeWorld; ++import com.infernalsuite.asp.util.NmsUtil; +import net.minecraft.server.level.ServerLevel; +import org.bukkit.Bukkit; +import org.bukkit.World; @@ -265,12 +265,12 @@ index 0000000000000000000000000000000000000000..719bfb548cfe69cbb726d95b68527bdf + this.loadedWorlds.remove(name); + } +} -diff --git a/src/main/java/com/infernalsuite/aswm/InternalPlugin.java b/src/main/java/com/infernalsuite/aswm/InternalPlugin.java -index 61518ab2b68e7a41500f3c8c8a5ec1230597f0e5..875960d0c9fdcbcb3250abc05cfbde48eec0f15a 100644 ---- a/src/main/java/com/infernalsuite/aswm/InternalPlugin.java -+++ b/src/main/java/com/infernalsuite/aswm/InternalPlugin.java +diff --git a/src/main/java/com/infernalsuite/asp/InternalPlugin.java b/src/main/java/com/infernalsuite/asp/InternalPlugin.java +index 4c7938c07e06810f475eac0bb4400c11154b56ba..cb8720e3961b897ae87a59c2c91d1502be3e62cf 100644 +--- a/src/main/java/com/infernalsuite/asp/InternalPlugin.java ++++ b/src/main/java/com/infernalsuite/asp/InternalPlugin.java @@ -1,14 +1,36 @@ - package com.infernalsuite.aswm; + package com.infernalsuite.asp; +import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager; import net.minecraft.server.MinecraftServer; @@ -423,10 +423,10 @@ index 61518ab2b68e7a41500f3c8c8a5ec1230597f0e5..875960d0c9fdcbcb3250abc05cfbde48 + } } \ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java -index 18f0f7933c42a7609a3d7bd775b24c372baae175..962c5ebf73261d0ba19b781d9269ef7ffee8b97d 100644 ---- a/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java -+++ b/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java +diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java +index bfcd4fc5e0ce187c79491fc720bb4bebde51f8e1..5d7afcb8e90bde6fd5aa3c1a10917f4fdb78ee3a 100644 +--- a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java ++++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java @@ -48,8 +48,6 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { private static final CraftPersistentDataTypeRegistry REGISTRY = new CraftPersistentDataTypeRegistry(); private static final SimpleDataFixerConverter DATA_FIXER_CONVERTER = new SimpleDataFixerConverter(); @@ -450,10 +450,10 @@ index 18f0f7933c42a7609a3d7bd775b24c372baae175..962c5ebf73261d0ba19b781d9269ef7f @Override public void setDefaultWorlds(SlimeWorld normalWorld, SlimeWorld netherWorld, SlimeWorld endWorld) { if (normalWorld != null) { -diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java -index b295d159200e3bf0e48f851ac206b2e09b756bb2..6ef45be4a76c00be5fbfcdb543882fcf41ea6271 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java -+++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java +diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +index b6c0ba9325b06e1d76609aa4de564af11f231a74..7b31aba65e30fdef7a3eeb96cd899e6be6839aa9 100644 +--- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java ++++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -31,13 +31,14 @@ import net.minecraft.world.level.chunk.storage.ChunkSerializer; import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.lighting.LevelLightEngine; @@ -470,10 +470,10 @@ index b295d159200e3bf0e48f851ac206b2e09b756bb2..6ef45be4a76c00be5fbfcdb543882fcf private static final CompoundTag EMPTY_BLOCK_STATE_PALETTE; private static final CompoundTag EMPTY_BIOME_PALETTE; -diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeWorld.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeWorld.java -index 004d7bcc5b35c76855787dcf32fe460e73cab38f..56c5db9a22af8ddd1d459bcf1f5b3fc7ca809b72 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeWorld.java -+++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeWorld.java +diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java +index bd2f8da46d4a04f2777086a416015563f3b06cdf..8c63ddf62415d0c88080fbe9a2ff9df4ffdd7a36 100644 +--- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java ++++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java @@ -35,7 +35,7 @@ public class NMSSlimeWorld implements SlimeWorld { @Override @@ -492,10 +492,10 @@ index 004d7bcc5b35c76855787dcf32fe460e73cab38f..56c5db9a22af8ddd1d459bcf1f5b3fc7 return chunks.stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull) .map((chunkLevel) -> new NMSSlimeChunk(chunkLevel, memoryWorld.getChunk(chunkLevel.getPos().x, chunkLevel.getPos().z))) // This sucks, is there a better way? .collect(Collectors.toList()); -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -index b54b231e22967eb0b34e6ba9b7ec9cdf64bad87e..114da62698c2897b16042327a4171f785bc58cec 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +index 70eb8b95740b46579ad3520ca1d3395a920a8a6a..e9b6114e1a799217b44001d66592bbae52b03e13 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -145,7 +145,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { @Override @@ -517,10 +517,10 @@ index b54b231e22967eb0b34e6ba9b7ec9cdf64bad87e..114da62698c2897b16042327a4171f78 @Override public CompoundTag getExtraData() { return this.extra; -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java -index b28c2b917accc0249e5df19a65db8820336b7279..2265f83768c4dc29f67d29730c4be45a194727da 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +index a8c103d435ac9473b1c5dd404e5c69ebf4353490..d6e5eac7732f32cabd6ed5ac6b10af20074a39b8 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -24,7 +24,6 @@ import net.minecraft.util.ProgressListener; import net.minecraft.util.Unit; import net.minecraft.util.datafix.DataFixers; @@ -613,14 +613,14 @@ index b28c2b917accc0249e5df19a65db8820336b7279..2265f83768c4dc29f67d29730c4be45a Bukkit.getLogger().log(Level.INFO, "World " + slimeWorld.getName() + " serialized in " + (saveStart - start) + "ms and saved in " + (System.currentTimeMillis() - saveStart) + "ms."); } catch (IOException | IllegalStateException ex) { ex.printStackTrace(); -diff --git a/src/main/java/com/infernalsuite/aswm/util/NmsUtil.java b/src/main/java/com/infernalsuite/aswm/util/NmsUtil.java -index 3500005bb09dc484bc333f1e0799613d097a37d3..4a5a6f208ad91fd861bd6f2b2c008ef14a547d6e 100644 ---- a/src/main/java/com/infernalsuite/aswm/util/NmsUtil.java -+++ b/src/main/java/com/infernalsuite/aswm/util/NmsUtil.java +diff --git a/src/main/java/com/infernalsuite/asp/util/NmsUtil.java b/src/main/java/com/infernalsuite/asp/util/NmsUtil.java +index 04e43a22c1932dce66abb54337cdce802110a7af..c8e8d61b9b9f5f0ce639aae95ddacb16442ba73f 100644 +--- a/src/main/java/com/infernalsuite/asp/util/NmsUtil.java ++++ b/src/main/java/com/infernalsuite/asp/util/NmsUtil.java @@ -1,9 +1,46 @@ - package com.infernalsuite.aswm.util; + package com.infernalsuite.asp.util; -+import com.infernalsuite.aswm.InternalPlugin; ++import com.infernalsuite.asp.InternalPlugin; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.scheduler.CraftScheduler; +import org.bukkit.plugin.Plugin; @@ -706,14 +706,14 @@ index 26422904751647a061397ce978bba752149003cd..4940083475948eac4fc06446f7ee7e1e } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index ac8af406180bc680d46e8edc3da0fc2e5211345a..4936c074ad73d92f3b5ed6463126abb5017e221c 100644 +index ac8af406180bc680d46e8edc3da0fc2e5211345a..2bd2aa53b656012f49f3c4692a092b9f9d4a4d9a 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -8,6 +8,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; import com.google.common.collect.MapMaker; -+import com.infernalsuite.aswm.AdvancedSlimePaper; ++import com.infernalsuite.asp.AdvancedSlimePaper; import com.mojang.authlib.GameProfile; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; diff --git a/patches/server/0014-replace-ChunkPos-with-long.patch b/patches/server/0014-replace-ChunkPos-with-long.patch index 755f44a7c..1abdfd2e3 100644 --- a/patches/server/0014-replace-ChunkPos-with-long.patch +++ b/patches/server/0014-replace-ChunkPos-with-long.patch @@ -4,14 +4,14 @@ Date: Sun, 16 Jun 2024 03:06:08 +0200 Subject: [PATCH] replace ChunkPos with long -diff --git a/src/main/java/com/infernalsuite/aswm/AdvancedSlimePaper.java b/src/main/java/com/infernalsuite/aswm/AdvancedSlimePaper.java -index 50350820d228e3656c569176aafd2cc534c17c15..280750cd9872210cc9043deea71f76758c2925fd 100644 ---- a/src/main/java/com/infernalsuite/aswm/AdvancedSlimePaper.java -+++ b/src/main/java/com/infernalsuite/aswm/AdvancedSlimePaper.java -@@ -17,6 +17,7 @@ import com.infernalsuite.aswm.serialization.slime.SlimeSerializer; - import com.infernalsuite.aswm.serialization.slime.reader.SlimeWorldReaderRegistry; - import com.infernalsuite.aswm.skeleton.SkeletonSlimeWorld; - import com.infernalsuite.aswm.util.NmsUtil; +diff --git a/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java b/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java +index 704cf0fa3d3c6114923d5b9b9594a4ba9d7ab0a6..efa3639457e89870fc0a7dac8aa632579d74800f 100644 +--- a/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java ++++ b/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java +@@ -17,6 +17,7 @@ import com.infernalsuite.asp.serialization.slime.SlimeSerializer; + import com.infernalsuite.asp.serialization.slime.reader.SlimeWorldReaderRegistry; + import com.infernalsuite.asp.skeleton.SkeletonSlimeWorld; + import com.infernalsuite.asp.util.NmsUtil; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minecraft.server.level.ServerLevel; import org.bukkit.Bukkit; @@ -25,14 +25,14 @@ index 50350820d228e3656c569176aafd2cc534c17c15..280750cd9872210cc9043deea71f7675 } @Override -diff --git a/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java -index ba203e3dc9f6b0be5a92c30808daa0c284616f09..eb441905b43c0f2f7edc104a34f78a18d8f3bedf 100644 ---- a/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java -+++ b/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java -@@ -12,6 +12,8 @@ import com.infernalsuite.aswm.skeleton.SlimeChunkSkeleton; - import com.infernalsuite.aswm.api.world.SlimeChunk; - import com.infernalsuite.aswm.api.world.SlimeChunkSection; - import com.infernalsuite.aswm.api.world.SlimeWorld; +diff --git a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java +index b2a0913290694d27151779aac5fb6be57f01da8b..f72953db6c79b62929244c56f1e76ce4ad72c0ee 100644 +--- a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java ++++ b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java +@@ -12,6 +12,8 @@ import com.infernalsuite.asp.skeleton.SlimeChunkSkeleton; + import com.infernalsuite.asp.api.world.SlimeChunk; + import com.infernalsuite.asp.api.world.SlimeChunkSection; + import com.infernalsuite.asp.api.world.SlimeWorld; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minecraft.SharedConstants; @@ -42,7 +42,7 @@ index ba203e3dc9f6b0be5a92c30808daa0c284616f09..eb441905b43c0f2f7edc104a34f78a18 long encodedNewVersion = DataConverter.encodeVersions(newVersion, Integer.MAX_VALUE); long encodedCurrentVersion = DataConverter.encodeVersions(currentVersion, Integer.MAX_VALUE); -- Map chunks = new HashMap<>(); +- Map chunks = new HashMap<>(); + Long2ObjectMap chunks = new Long2ObjectOpenHashMap<>(); for (SlimeChunk chunk : data.getChunkStorage()) { List entities = new ArrayList<>(); @@ -56,24 +56,24 @@ index ba203e3dc9f6b0be5a92c30808daa0c284616f09..eb441905b43c0f2f7edc104a34f78a18 SlimeChunkSection[] sections = new SlimeChunkSection[chunk.getSections().length]; for (int i = 0; i < sections.length; i++) { -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -index 114da62698c2897b16042327a4171f785bc58cec..770679851baba2ddb9f8f427f4cd80ea8b32122b 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -@@ -2,8 +2,8 @@ package com.infernalsuite.aswm.level; +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +index e9b6114e1a799217b44001d66592bbae52b03e13..a150c5ebb1fa48542550d905a675a86444f8f22d 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +@@ -2,8 +2,8 @@ package com.infernalsuite.asp.level; import com.flowpowered.nbt.CompoundTag; import com.flowpowered.nbt.Tag; --import com.infernalsuite.aswm.ChunkPos; - import com.infernalsuite.aswm.Converter; -+import com.infernalsuite.aswm.Util; - import com.infernalsuite.aswm.api.exceptions.WorldAlreadyExistsException; - import com.infernalsuite.aswm.api.loaders.SlimeLoader; - import com.infernalsuite.aswm.pdc.FlowPersistentDataContainer; -@@ -15,6 +15,8 @@ import com.infernalsuite.aswm.api.world.SlimeChunk; - import com.infernalsuite.aswm.api.world.SlimeWorld; - import com.infernalsuite.aswm.api.world.SlimeWorldInstance; - import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; +-import com.infernalsuite.asp.ChunkPos; + import com.infernalsuite.asp.Converter; ++import com.infernalsuite.asp.Util; + import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; + import com.infernalsuite.asp.api.loaders.SlimeLoader; + import com.infernalsuite.asp.pdc.FlowPersistentDataContainer; +@@ -15,6 +15,8 @@ import com.infernalsuite.asp.api.world.SlimeChunk; + import com.infernalsuite.asp.api.world.SlimeWorld; + import com.infernalsuite.asp.api.world.SlimeWorldInstance; + import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minecraft.world.level.block.Block; diff --git a/patches/server/0015-1.21-compatibility.patch b/patches/server/0015-1.21-compatibility.patch index 87cf21f1e..0b13e743b 100644 --- a/patches/server/0015-1.21-compatibility.patch +++ b/patches/server/0015-1.21-compatibility.patch @@ -4,10 +4,10 @@ Date: Tue, 9 Jul 2024 02:00:22 +0200 Subject: [PATCH] 1.21 compatibility -diff --git a/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java -index 962c5ebf73261d0ba19b781d9269ef7ffee8b97d..87b6ee19fd165bde2db3a57545c58251dc6bad22 100644 ---- a/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java -+++ b/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java +diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java +index 5d7afcb8e90bde6fd5aa3c1a10917f4fdb78ee3a..8c80b611c00ac09d9d45db5a712435c6534f937a 100644 +--- a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java ++++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java @@ -212,7 +212,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { default -> throw new IllegalArgumentException("Unknown dimension supplied"); }; @@ -17,19 +17,19 @@ index 962c5ebf73261d0ba19b781d9269ef7ffee8b97d..87b6ee19fd165bde2db3a57545c58251 LevelStem stem = MinecraftServer.getServer().registries().compositeAccess().registryOrThrow(Registries.LEVEL_STEM).get(dimension); SlimeLevelInstance level; -diff --git a/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java b/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java -index f9ac1efca06d8debbb7894160c3e67fd23440ebb..b5a1f75314aac73fb77e139398017b16acbb8efb 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java -+++ b/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java +diff --git a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java +index bf44132f7614832119f798a2418e2014ec378cf9..2f0e34e105a27b12eb28dfc2b3c3b6590d76cbb2 100644 +--- a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java ++++ b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java @@ -1,12 +1,12 @@ - package com.infernalsuite.aswm.level; + package com.infernalsuite.asp.level; import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkLoadTask; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.GenericDataLoadTask; - import com.infernalsuite.aswm.Converter; - import com.infernalsuite.aswm.api.world.SlimeChunk; + import com.infernalsuite.asp.Converter; + import com.infernalsuite.asp.api.world.SlimeChunk; import com.mojang.logging.LogUtils; -import io.papermc.paper.chunk.system.scheduling.ChunkLoadTask; -import io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler; @@ -37,40 +37,40 @@ index f9ac1efca06d8debbb7894160c3e67fd23440ebb..b5a1f75314aac73fb77e139398017b16 import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.ChunkPos; -diff --git a/src/main/java/com/infernalsuite/aswm/level/FastChunkPruner.java b/src/main/java/com/infernalsuite/aswm/level/FastChunkPruner.java -index c0e47f25e9be33da374dc737c96d8d3c2bb1cd0f..4e5eb92e0aa40ca02e58f988ec39a6461f63ac2f 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/FastChunkPruner.java -+++ b/src/main/java/com/infernalsuite/aswm/level/FastChunkPruner.java +diff --git a/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java b/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java +index 10bfcb7250c01c8361375c4d9b34d2b0ae17257d..7f86b1922f179a3ff9b4238ab2da5aea5dde5564 100644 +--- a/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java ++++ b/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java @@ -1,9 +1,9 @@ - package com.infernalsuite.aswm.level; + package com.infernalsuite.asp.level; +import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; - import com.infernalsuite.aswm.api.world.SlimeWorld; - import com.infernalsuite.aswm.api.world.properties.SlimeProperties; - import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; + import com.infernalsuite.asp.api.world.SlimeWorld; + import com.infernalsuite.asp.api.world.properties.SlimeProperties; + import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; -import io.papermc.paper.world.ChunkEntitySlices; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; -diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java -index 6ef45be4a76c00be5fbfcdb543882fcf41ea6271..9b4b18758d52d66e4abf9e40e49a32428de68b9a 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java -+++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java +diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +index 7b31aba65e30fdef7a3eeb96cd899e6be6839aa9..844d23310b2b38cc9f6e2ae1636ba8a485c07999 100644 +--- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java ++++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -1,17 +1,16 @@ - package com.infernalsuite.aswm.level; + package com.infernalsuite.asp.level; +import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; import com.flowpowered.nbt.CompoundMap; import com.flowpowered.nbt.CompoundTag; import com.flowpowered.nbt.LongArrayTag; import com.google.common.collect.Lists; - import com.infernalsuite.aswm.Converter; --import com.infernalsuite.aswm.skeleton.SlimeChunkSectionSkeleton; - import com.infernalsuite.aswm.api.utils.NibbleArray; - import com.infernalsuite.aswm.api.world.SlimeChunk; - import com.infernalsuite.aswm.api.world.SlimeChunkSection; + import com.infernalsuite.asp.Converter; +-import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; + import com.infernalsuite.asp.api.utils.NibbleArray; + import com.infernalsuite.asp.api.world.SlimeChunk; + import com.infernalsuite.asp.api.world.SlimeChunkSection; -import com.mojang.logging.LogUtils; -+import com.infernalsuite.aswm.skeleton.SlimeChunkSectionSkeleton; ++import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; import com.mojang.serialization.Codec; -import io.papermc.paper.world.ChunkEntitySlices; import net.minecraft.core.Holder; @@ -88,12 +88,12 @@ index 6ef45be4a76c00be5fbfcdb543882fcf41ea6271..9b4b18758d52d66e4abf9e40e49a3242 import net.minecraft.world.level.chunk.storage.ChunkSerializer; import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.lighting.LevelLightEngine; -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java -index 003778f3ba9db1f52d7746d3b4b1132e373dd365..86a5b457bdca63713769d2b708be905d72ff76a3 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +index 6807767a2067b62558f749da0c25f184082d0769..d04ad95b65f764560aa1ca8c7137f951ed474003 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java @@ -1,6 +1,7 @@ - package com.infernalsuite.aswm.level; + package com.infernalsuite.asp.level; -import ca.spottedleaf.starlight.common.light.SWMRNibbleArray; +import ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray; @@ -155,29 +155,29 @@ index 003778f3ba9db1f52d7746d3b4b1132e373dd365..86a5b457bdca63713769d2b708be905d for (Heightmap.Types type : heightMapTypes) { String name = type.getSerializedName(); -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java -index 2265f83768c4dc29f67d29730c4be45a194727da..187336ecaa4262e3f081a88702031b17c6037091 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +index d6e5eac7732f32cabd6ed5ac6b10af20074a39b8..33af1d7e671c5aeb06482038e205efc831641ec0 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -1,17 +1,15 @@ - package com.infernalsuite.aswm.level; + package com.infernalsuite.asp.level; import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkLoadTask; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.GenericDataLoadTask; import com.google.common.util.concurrent.ThreadFactoryBuilder; --import com.infernalsuite.aswm.Converter; --import com.infernalsuite.aswm.serialization.slime.SlimeSerializer; --import com.infernalsuite.aswm.api.world.SlimeChunk; - import com.infernalsuite.aswm.api.world.SlimeWorld; - import com.infernalsuite.aswm.api.world.SlimeWorldInstance; - import com.infernalsuite.aswm.api.world.properties.SlimeProperties; - import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; +-import com.infernalsuite.asp.Converter; +-import com.infernalsuite.asp.serialization.slime.SlimeSerializer; +-import com.infernalsuite.asp.api.world.SlimeChunk; + import com.infernalsuite.asp.api.world.SlimeWorld; + import com.infernalsuite.asp.api.world.SlimeWorldInstance; + import com.infernalsuite.asp.api.world.properties.SlimeProperties; + import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; -import io.papermc.paper.chunk.system.scheduling.ChunkLoadTask; -import io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler; -import io.papermc.paper.chunk.system.scheduling.GenericDataLoadTask; -+import com.infernalsuite.aswm.serialization.slime.SlimeSerializer; ++import com.infernalsuite.asp.serialization.slime.SlimeSerializer; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; import net.minecraft.core.registries.Registries; @@ -281,7 +281,7 @@ index 4640baec5bed6c2d53cc0f8ca1d273cc115abe9b..589cb65f79bb05ee8c44b526c707e81d @Override public final FluidState getFluidIfLoaded(BlockPos blockposition) { diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index faf7f4f3bd1fbc91a40e5549a7a5520ea3eaec37..8832efbf9f68fb0466fdc9d6eb0d0acf5d5930dd 100644 +index 6f482bf045cf7a14dceb5673d9d19ee87b7c03a8..cb0c551bb3899201e2ca55a72babc76b3704501b 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java @@ -469,7 +469,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun diff --git a/patches/server/0016-Fix-chunk-saving-when-unloading.patch b/patches/server/0016-Fix-chunk-saving-when-unloading.patch index af7d7c6d6..5eb3342be 100644 --- a/patches/server/0016-Fix-chunk-saving-when-unloading.patch +++ b/patches/server/0016-Fix-chunk-saving-when-unloading.patch @@ -4,10 +4,10 @@ Date: Mon, 26 Aug 2024 21:27:08 +0100 Subject: [PATCH] Fix chunk saving when unloading -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java -index 187336ecaa4262e3f081a88702031b17c6037091..6a5a8fbd8ee013828685495267283d9518d32d20 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +index 33af1d7e671c5aeb06482038e205efc831641ec0..dbc4620fea0b1b5aa130aaaa2af06fcaad93ed29 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -25,6 +25,7 @@ import net.minecraft.world.Difficulty; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.chunk.ChunkAccess; diff --git a/patches/server/0017-fix-disable-dragon-fights.patch b/patches/server/0017-fix-disable-dragon-fights.patch index 55111785f..09a8543b1 100644 --- a/patches/server/0017-fix-disable-dragon-fights.patch +++ b/patches/server/0017-fix-disable-dragon-fights.patch @@ -5,18 +5,18 @@ Subject: [PATCH] fix disable dragon fights diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index d414a0056ab27558440086ab373867bd7e28cdd2..36d0ce70ab1eaddf3354a9e2f8c86269cb319342 100644 +index 7eb21e0c8fc4103a4eb656bd1d81ae10e7ee9dc4..fecee66cf0ab3fe820273a6850c9d2f6c51501b6 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -2,6 +2,7 @@ package net.minecraft.server.level; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Lists; -+import com.infernalsuite.aswm.api.world.properties.SlimeProperties; // ASP ++import com.infernalsuite.asp.api.world.properties.SlimeProperties; // ASP import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.util.Pair; import com.mojang.logging.LogUtils; -@@ -663,7 +664,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -662,7 +663,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.structureCheck = new StructureCheck(this.chunkSource.chunkScanner(), this.registryAccess(), minecraftserver.getStructureManager(), this.getTypeKey(), chunkgenerator, this.chunkSource.randomState(), this, chunkgenerator.getBiomeSource(), l, datafixer); // Paper - Fix missing CB diff this.structureManager = new StructureManager(this, this.serverLevelData.worldGenOptions(), this.structureCheck); // CraftBukkit if ((this.dimension() == Level.END && this.dimensionTypeRegistration().is(BuiltinDimensionTypes.END)) || env == org.bukkit.World.Environment.THE_END) { // CraftBukkit - Allow to create EnderDragonBattle in default and custom END diff --git a/patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch b/patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch index 93f9d7cf2..7c6b44701 100644 --- a/patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch +++ b/patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch @@ -4,10 +4,10 @@ Date: Thu, 19 Sep 2024 20:47:32 +0300 Subject: [PATCH] fix chunk pdc getting wiped on chunk unload -diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java -index 9b4b18758d52d66e4abf9e40e49a32428de68b9a..f0d773977609597f2da7bf691d8f4cb983743981 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java -+++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java +diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +index 844d23310b2b38cc9f6e2ae1636ba8a485c07999..c2dd10e46bd4c73b0db641b0a057e6e599033521 100644 +--- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java ++++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -68,7 +68,9 @@ public class NMSSlimeChunk implements SlimeChunk { public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference) { diff --git a/patches/server/0019-1.21.3-fixes.patch b/patches/server/0019-1.21.3-fixes.patch index 39daf6648..87b76633c 100644 --- a/patches/server/0019-1.21.3-fixes.patch +++ b/patches/server/0019-1.21.3-fixes.patch @@ -4,10 +4,10 @@ Date: Sun, 10 Nov 2024 13:06:42 +0100 Subject: [PATCH] 1.21.3 fixes -diff --git a/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java -index 87b6ee19fd165bde2db3a57545c58251dc6bad22..7b65a8d9137cd160b1c69dfafe70c693e9cfd508 100644 ---- a/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java -+++ b/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java +diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java +index 8c80b611c00ac09d9d45db5a712435c6534f937a..28d49e4e23b300b3b53de9cc4c276d5c40f43a0c 100644 +--- a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java ++++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java @@ -213,7 +213,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { }; @@ -35,12 +35,12 @@ index 87b6ee19fd165bde2db3a57545c58251dc6bad22..7b65a8d9137cd160b1c69dfafe70c693 WorldOptions worldoptions = new WorldOptions(0, false, false); -diff --git a/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java b/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java -index b5a1f75314aac73fb77e139398017b16acbb8efb..547e8e8824795a601b2028a6007057808eddbb65 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java -+++ b/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java +diff --git a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java +index 2f0e34e105a27b12eb28dfc2b3c3b6590d76cbb2..2b700ec76e0eca7441676d48cf842cb944261668 100644 +--- a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java ++++ b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java @@ -1,6 +1,7 @@ - package com.infernalsuite.aswm.level; + package com.infernalsuite.asp.level; -import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; @@ -84,12 +84,12 @@ index b5a1f75314aac73fb77e139398017b16acbb8efb..547e8e8824795a601b2028a600705780 this.task.lowerPriority(priority); } -diff --git a/src/main/java/com/infernalsuite/aswm/level/CommonLoadTask.java b/src/main/java/com/infernalsuite/aswm/level/CommonLoadTask.java -index fc6e46972bcc77134ed718c8c157ec3893d4bcdf..ceaa09deabf53f061185639660a7706c3ff27801 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/CommonLoadTask.java -+++ b/src/main/java/com/infernalsuite/aswm/level/CommonLoadTask.java +diff --git a/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java b/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java +index 9954db3eabd60ac0600af1efc6f8a1650ef4d85b..b8d82510cf66700abf0c1820c561b5cc78c7d318 100644 +--- a/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java ++++ b/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java @@ -1,18 +1,19 @@ - package com.infernalsuite.aswm.level; + package com.infernalsuite.asp.level; -import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; @@ -114,10 +114,10 @@ index fc6e46972bcc77134ed718c8c157ec3893d4bcdf..ceaa09deabf53f061185639660a7706c + void setPriority(Priority priority); } \ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java -index f0d773977609597f2da7bf691d8f4cb983743981..cbcbbc8410b24daf685d74791ad80989d4830d7b 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java -+++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java +diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +index c2dd10e46bd4c73b0db641b0a057e6e599033521..43790021bdc50a37d4bda7a89586eb56eb032791 100644 +--- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java ++++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -29,7 +29,7 @@ import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; import net.minecraft.world.level.chunk.PalettedContainer; @@ -168,10 +168,10 @@ index f0d773977609597f2da7bf691d8f4cb983743981..cbcbbc8410b24daf685d74791ad80989 blockStateTag = (CompoundTag) Converter.convertTag("", data); } -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java -index 86a5b457bdca63713769d2b708be905d72ff76a3..7623584e60dddd5558f22eed4403944fafee0696 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +index d04ad95b65f764560aa1ca8c7137f951ed474003..30d16c759e269ce0bffa5d5a4f7d90bc09e03eaa 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java @@ -28,7 +28,7 @@ import net.minecraft.world.level.chunk.LevelChunkSection; import net.minecraft.world.level.chunk.PalettedContainer; import net.minecraft.world.level.chunk.UpgradeData; @@ -212,12 +212,12 @@ index 86a5b457bdca63713769d2b708be905d72ff76a3..7623584e60dddd5558f22eed4403944f } if (sectionId < sections.length) { -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java -index 6a5a8fbd8ee013828685495267283d9518d32d20..acb6ea84fbc40a6907edb237b834feeb66075af8 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +index dbc4620fea0b1b5aa130aaaa2af06fcaad93ed29..d672504eee439d96a9054b3308ba3a5d18cca867 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -1,6 +1,7 @@ - package com.infernalsuite.aswm.level; + package com.infernalsuite.asp.level; -import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; @@ -264,13 +264,13 @@ index 6a5a8fbd8ee013828685495267283d9518d32d20..acb6ea84fbc40a6907edb237b834feeb } diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index 8832efbf9f68fb0466fdc9d6eb0d0acf5d5930dd..d03db9b8e78c795408b336beb53d6940a75ed759 100644 +index cb0c551bb3899201e2ca55a72babc76b3704501b..def0ae9a3a3e7a884d24275bb5f0f9b8e87f7d64 100644 --- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java @@ -371,7 +371,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun } - if (world instanceof com.infernalsuite.aswm.level.SlimeLevelInstance) { + if (world instanceof com.infernalsuite.asp.level.SlimeLevelInstance) { - poiStorage.checkConsistencyWithBlocks(SectionPos.of(chunkPos.getWorldPosition()), achunksection[j]); + poiStorage.checkConsistencyWithBlocks(sectionposition, serializablechunkdata_b.chunkSection); } diff --git a/patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch b/patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch index cacb07135..ea821e8d6 100644 --- a/patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch +++ b/patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix missing chunks & entities when chunk saving diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -index bc0990458df745c92e5bc0530ff35ab992365b3a..682f293396ef34fdc6a61314827dc34f504c7777 100644 +index 62b526f7e147586977615ec8cec191d0aaf0bcdc..ad7c19ceb42da90bd995421be7fb764aa7ee48e0 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java @@ -897,6 +897,13 @@ public final class NewChunkHolder { @@ -13,7 +13,7 @@ index bc0990458df745c92e5bc0530ff35ab992365b3a..682f293396ef34fdc6a61314827dc34f final boolean shouldLevelChunkNotSave = PlatformHooks.get().forceNoSave(chunk); + // ASP start - Chunk unloading -+ if (world instanceof com.infernalsuite.aswm.level.SlimeLevelInstance slime && chunk instanceof LevelChunk levelChunk) { ++ if (world instanceof com.infernalsuite.asp.level.SlimeLevelInstance slime && chunk instanceof LevelChunk levelChunk) { + //The custom entity slices need to be passed on for entities to be saved + slime.onChunkUnloaded(levelChunk, entityChunk); + } @@ -22,10 +22,10 @@ index bc0990458df745c92e5bc0530ff35ab992365b3a..682f293396ef34fdc6a61314827dc34f // unload chunk data if (chunk != null) { if (chunk instanceof LevelChunk levelChunk) { -diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java -index cbcbbc8410b24daf685d74791ad80989d4830d7b..cdc4fd3a8767a3cb168ceb3088f4ae237fd9a11e 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java -+++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java +diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +index 43790021bdc50a37d4bda7a89586eb56eb032791..4f99fbafda6cd4500005a793bba73eee5a2061b9 100644 +--- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java ++++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -66,12 +66,19 @@ public class NMSSlimeChunk implements SlimeChunk { private final CompoundTag extra; private final CompoundTag upgradeData; @@ -78,10 +78,10 @@ index cbcbbc8410b24daf685d74791ad80989d4830d7b..cdc4fd3a8767a3cb168ceb3088f4ae23 @Override public CompoundTag getExtraData() { return extra; -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkLevel.java b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkLevel.java -index 2ebabf20c37d2b5c479de5bb241aa334f92a1104..866246838b6d6f23eacb1d9bad1c31cb2c1e76b0 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkLevel.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkLevel.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java +index a92d17b5c6a7c8427ecbdf56a9c2a0c1b66978e4..6313b235eb8ccbd63b57159964ba33d36db51933 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java @@ -19,12 +19,6 @@ public class SlimeChunkLevel extends LevelChunk { this.inMemoryWorld = world.slimeInstance; } @@ -95,10 +95,10 @@ index 2ebabf20c37d2b5c479de5bb241aa334f92a1104..866246838b6d6f23eacb1d9bad1c31cb @Override public void loadCallback() { super.loadCallback(); -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -index 770679851baba2ddb9f8f427f4cd80ea8b32122b..619ccbab1a5582af1d1ad69fb0c54e52ca84847d 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +index a150c5ebb1fa48542550d905a675a86444f8f22d..5daabf7d2c31972082fc618142643592535fb13f 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -104,11 +104,11 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { // Authored by: Kenox @@ -113,10 +113,10 @@ index 770679851baba2ddb9f8f427f4cd80ea8b32122b..619ccbab1a5582af1d1ad69fb0c54e52 if (FastChunkPruner.canBePruned(this.liveWorld, providedChunk)) { this.chunkStorage.remove(Util.chunkPosition(x, z)); -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java -index acb6ea84fbc40a6907edb237b834feeb66075af8..2821d953e8b01cadf171508ac0b8e1eda6201970 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelInstance.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +index d672504eee439d96a9054b3308ba3a5d18cca867..1b0d36854c190efefc7421f445a70b92f82a4fe5 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -202,9 +202,7 @@ public class SlimeLevelInstance extends ServerLevel { propertyMap.setValue(SlimeProperties.SPAWN_YAW, angle); } diff --git a/patches/server/0021-fix-pdc-not-saving-when-chunks-are-unloaded.patch b/patches/server/0021-fix-pdc-not-saving-when-chunks-are-unloaded.patch index e220d4ca3..324797989 100644 --- a/patches/server/0021-fix-pdc-not-saving-when-chunks-are-unloaded.patch +++ b/patches/server/0021-fix-pdc-not-saving-when-chunks-are-unloaded.patch @@ -4,10 +4,10 @@ Date: Thu, 5 Dec 2024 01:46:03 +0100 Subject: [PATCH] fix pdc not saving when chunks are unloaded -diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -index 619ccbab1a5582af1d1ad69fb0c54e52ca84847d..8c71a932d49d55d861910712d3f482d39b62ad65 100644 ---- a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +index 5daabf7d2c31972082fc618142643592535fb13f..cdf0534ff6516eb631a200a5159461b99236c808 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -114,6 +114,8 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { this.chunkStorage.remove(Util.chunkPosition(x, z)); return; diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts index 818ff7f56..fff5d7195 100644 --- a/plugin/build.gradle.kts +++ b/plugin/build.gradle.kts @@ -1,43 +1,31 @@ plugins { - id("com.gradleup.shadow") version "8.3.5" - id("net.kyori.blossom") version "2.1.0" -} - -version = "3.0.0" - -sourceSets { - main { - blossom { - resources { - property("version", version.toString()) - } - } - } + id("asp.base-conventions") + id("asp.publishing-conventions") + id("net.minecrell.plugin-yml.paper") + id("com.gradleup.shadow") } dependencies { compileOnly(project(":api")) - implementation(project(":loaders")) - implementation("org.spongepowered:configurate-yaml:4.1.2") - implementation("org.bstats:bstats-bukkit:3.0.0") - implementation("org.incendo:cloud-paper:2.0.0-beta.9") - implementation("org.incendo:cloud-minecraft-extras:2.0.0-beta.9") - implementation("org.incendo:cloud-annotations:2.0.0-rc.1") - compileOnly("io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT") + + implementation(libs.configurate.yaml) + implementation(libs.bstats) + implementation(libs.cloud.paper) + implementation(libs.cloud.minecraft.extras) + implementation(libs.cloud.annotations) + + compileOnly(paperApi()) } tasks { shadowJar { - archiveClassifier.set("") - - relocate("org.bstats", "com.grinderwolf.swm.internal.bstats") - relocate("ninja.leaping.configurate", "com.grinderwolf.swm.internal.configurate") - //relocate("com.flowpowered.nbt", "com.grinderwolf.swm.internal.nbt") - relocate("com.zaxxer.hikari", "com.grinderwolf.swm.internal.hikari") - relocate("com.mongodb", "com.grinderwolf.swm.internal.mongodb") - relocate("io.lettuce", "com.grinderwolf.swm.internal.lettuce") - relocate("org.bson", "com.grinderwolf.swm.internal.bson") + relocate("org.bstats", "com.infernalsuite.asp.libs.bstats") + relocate("org.spongepowered.configurate", "com.infernalsuite.asp.libs.configurate") + relocate("com.zaxxer.hikari", "com.infernalsuite.asp.libs.hikari") + relocate("com.mongodb", "com.infernalsuite.asp.libs.mongo") + relocate("io.lettuce", "com.infernalsuite.asp.libs.lettuce") + relocate("org.bson", "com.infernalsuite.asp.libs.bson") } assemble { @@ -45,4 +33,11 @@ tasks { } } -description = "slimeworldplugin" +paper { + name = "ASPaperPlugin" + description = "ASP plugin for Paper, providing utilities for the ASP platform" + version = "\${gitCommitId}" + apiVersion = "1.21" + main = "com.infernalsuite.asp.plugin.SWPlugin" + authors = listOf("InfernalSuite") +} diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/SWPlugin.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/SWPlugin.java similarity index 85% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/SWPlugin.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/SWPlugin.java index a32f83a24..9443ad209 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/SWPlugin.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/SWPlugin.java @@ -1,18 +1,17 @@ -package com.infernalsuite.aswm.plugin; - -import com.infernalsuite.aswm.plugin.commands.CommandManager; -import com.infernalsuite.aswm.plugin.config.ConfigManager; -import com.infernalsuite.aswm.plugin.config.WorldData; -import com.infernalsuite.aswm.plugin.config.WorldsConfig; -import com.infernalsuite.aswm.plugin.loader.LoaderManager; -import com.infernalsuite.aswm.api.AdvancedSlimePaperAPI; -import com.infernalsuite.aswm.api.SlimeNMSBridge; -import com.infernalsuite.aswm.api.exceptions.CorruptedWorldException; -import com.infernalsuite.aswm.api.exceptions.NewerFormatException; -import com.infernalsuite.aswm.api.exceptions.UnknownWorldException; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; +package com.infernalsuite.asp.plugin; + +import com.infernalsuite.asp.plugin.commands.CommandManager; +import com.infernalsuite.asp.plugin.config.WorldData; +import com.infernalsuite.asp.plugin.config.WorldsConfig; +import com.infernalsuite.asp.plugin.loader.LoaderManager; +import com.infernalsuite.asp.api.AdvancedSlimePaperAPI; +import com.infernalsuite.asp.api.SlimeNMSBridge; +import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; +import com.infernalsuite.asp.api.exceptions.NewerFormatException; +import com.infernalsuite.asp.api.exceptions.UnknownWorldException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; @@ -40,7 +39,7 @@ public LoaderManager getLoaderManager() { @Override public void onLoad() { try { - ConfigManager.initialize(); + com.infernalsuite.asp.plugin.config.ConfigManager.initialize(); } catch (NullPointerException | IOException ex) { getSLF4JLogger().error("Failed to load config files", ex); return; @@ -99,7 +98,7 @@ public void onEnable() { private List loadWorlds() { List erroredWorlds = new ArrayList<>(); - WorldsConfig config = ConfigManager.getWorldConfig(); + WorldsConfig config = com.infernalsuite.asp.plugin.config.ConfigManager.getWorldConfig(); for (Map.Entry entry : config.getWorlds().entrySet()) { String worldName = entry.getKey(); diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/CommandManager.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/CommandManager.java similarity index 66% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/CommandManager.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/CommandManager.java index ee801836e..6f7c85aab 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/CommandManager.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/CommandManager.java @@ -1,11 +1,8 @@ -package com.infernalsuite.aswm.plugin.commands; - -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.plugin.SWPlugin; -import com.infernalsuite.aswm.plugin.commands.exception.MessageCommandException; -import com.infernalsuite.aswm.plugin.commands.parser.*; -import com.infernalsuite.aswm.plugin.commands.parser.suggestion.KnownSlimeWorldSuggestionProvider; -import com.infernalsuite.aswm.plugin.commands.sub.*; +package com.infernalsuite.asp.plugin.commands; + +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.plugin.commands.parser.*; +import com.infernalsuite.asp.plugin.commands.sub.*; import io.leangen.geantyref.TypeToken; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -39,9 +36,9 @@ public class CommandManager { // A list containing all the worlds that are being performed operations on, so two commands cannot be run at the same time private final Set worldsInUse = new HashSet<>(); - private final SWPlugin plugin; + private final com.infernalsuite.asp.plugin.SWPlugin plugin; - public CommandManager(SWPlugin plugin) { + public CommandManager(com.infernalsuite.asp.plugin.SWPlugin plugin) { LegacyPaperCommandManager commandManager = LegacyPaperCommandManager.createNative( plugin, @@ -57,17 +54,17 @@ public CommandManager(SWPlugin plugin) { ParserRegistry parserRegistry = commandManager.parserRegistry(); - parserRegistry.registerSuggestionProvider("known-slime-worlds", new KnownSlimeWorldSuggestionProvider()); + parserRegistry.registerSuggestionProvider("known-slime-worlds", new com.infernalsuite.asp.plugin.commands.parser.suggestion.KnownSlimeWorldSuggestionProvider()); - parserRegistry.registerParserSupplier(TypeToken.get(NamedWorldData.class), parserParameters -> new NamedWorldDataParser()); - parserRegistry.registerParserSupplier(TypeToken.get(SlimeWorld.class), parserParameters -> new SlimeWorldParser()); - parserRegistry.registerParserSupplier(TypeToken.get(NamedSlimeLoader.class), parserParameters -> new NamedSlimeLoaderParser(plugin.getLoaderManager())); - parserRegistry.registerParserSupplier(TypeToken.get(World.class), parserParameters -> new BukkitWorldParser()); + parserRegistry.registerParserSupplier(TypeToken.get(com.infernalsuite.asp.plugin.commands.parser.NamedWorldData.class), parserParameters -> new com.infernalsuite.asp.plugin.commands.parser.NamedWorldDataParser()); + parserRegistry.registerParserSupplier(TypeToken.get(SlimeWorld.class), parserParameters -> new com.infernalsuite.asp.plugin.commands.parser.SlimeWorldParser()); + parserRegistry.registerParserSupplier(TypeToken.get(com.infernalsuite.asp.plugin.commands.parser.NamedSlimeLoader.class), parserParameters -> new com.infernalsuite.asp.plugin.commands.parser.NamedSlimeLoaderParser(plugin.getLoaderManager())); + parserRegistry.registerParserSupplier(TypeToken.get(World.class), parserParameters -> new com.infernalsuite.asp.plugin.commands.parser.BukkitWorldParser()); commandManager.exceptionController().registerHandler(TypeToken.get(CommandExecutionException.class), ExceptionHandler.unwrappingHandler()); // Unwrap the exception commandManager.exceptionController().registerHandler(TypeToken.get(ArgumentParseException.class), context -> { Throwable cause = context.exception().getCause(); - if (cause instanceof MessageCommandException message) { + if (cause instanceof com.infernalsuite.asp.plugin.commands.exception.MessageCommandException message) { context.context().sender().sendMessage(message.getComponent()); } else { String message = cause.getMessage(); @@ -101,29 +98,29 @@ public CommandManager(SWPlugin plugin) { )); }); - commandManager.exceptionController().registerHandler(TypeToken.get(MessageCommandException.class), context -> { + commandManager.exceptionController().registerHandler(TypeToken.get(com.infernalsuite.asp.plugin.commands.exception.MessageCommandException.class), context -> { context.context().sender().sendMessage(context.exception().getComponent()); }); AnnotationParser ap = new AnnotationParser<>(commandManager, CommandSender.class); ap.parse(this, - new CloneWorldCmd(this), - new CreateWorldCmd(this), - new DeleteWorldCmd(this), - new DSListCmd(this), - new GotoCmd(this), - new ImportWorldCmd(this), - new LoadTemplateWorldCmd(this), - new LoadWorldCmd(this), - new MigrateWorldCmd(this), - new ReloadConfigCmd(this), - new SaveWorldCmd(this), - new SetSpawnCmd(this), - new UnloadWorldCmd(this), - new VersionCmd(this), - new WorldListCmd(this), - new HelpCmd(this, commandManager) + new com.infernalsuite.asp.plugin.commands.sub.CloneWorldCmd(this), + new com.infernalsuite.asp.plugin.commands.sub.CreateWorldCmd(this), + new com.infernalsuite.asp.plugin.commands.sub.DeleteWorldCmd(this), + new com.infernalsuite.asp.plugin.commands.sub.DSListCmd(this), + new com.infernalsuite.asp.plugin.commands.sub.GotoCmd(this), + new com.infernalsuite.asp.plugin.commands.sub.ImportWorldCmd(this), + new com.infernalsuite.asp.plugin.commands.sub.LoadTemplateWorldCmd(this), + new com.infernalsuite.asp.plugin.commands.sub.LoadWorldCmd(this), + new com.infernalsuite.asp.plugin.commands.sub.MigrateWorldCmd(this), + new com.infernalsuite.asp.plugin.commands.sub.ReloadConfigCmd(this), + new com.infernalsuite.asp.plugin.commands.sub.SaveWorldCmd(this), + new com.infernalsuite.asp.plugin.commands.sub.SetSpawnCmd(this), + new com.infernalsuite.asp.plugin.commands.sub.UnloadWorldCmd(this), + new com.infernalsuite.asp.plugin.commands.sub.VersionCmd(this), + new com.infernalsuite.asp.plugin.commands.sub.WorldListCmd(this), + new com.infernalsuite.asp.plugin.commands.sub.HelpCmd(this, commandManager) ); } @@ -141,7 +138,7 @@ public void onCommand(CommandSender sender) { )); } - SWPlugin getPlugin() { + com.infernalsuite.asp.plugin.SWPlugin getPlugin() { return plugin; } diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/SlimeCommand.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/SlimeCommand.java similarity index 63% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/SlimeCommand.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/SlimeCommand.java index 9496fcd46..34b6499ad 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/SlimeCommand.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/SlimeCommand.java @@ -1,13 +1,12 @@ -package com.infernalsuite.aswm.plugin.commands; +package com.infernalsuite.asp.plugin.commands; -import com.infernalsuite.aswm.api.AdvancedSlimePaperAPI; -import com.infernalsuite.aswm.api.exceptions.CorruptedWorldException; -import com.infernalsuite.aswm.api.exceptions.NewerFormatException; -import com.infernalsuite.aswm.api.exceptions.UnknownWorldException; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; -import com.infernalsuite.aswm.plugin.SWPlugin; +import com.infernalsuite.asp.api.AdvancedSlimePaperAPI; +import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; +import com.infernalsuite.asp.api.exceptions.NewerFormatException; +import com.infernalsuite.asp.api.exceptions.UnknownWorldException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; @@ -19,7 +18,7 @@ public class SlimeCommand { ); protected final CommandManager commandManager; - protected final SWPlugin plugin; + protected final com.infernalsuite.asp.plugin.SWPlugin plugin; protected final AdvancedSlimePaperAPI asp = AdvancedSlimePaperAPI.instance(); public SlimeCommand(CommandManager commandManager) { diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/exception/MessageCommandException.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/exception/MessageCommandException.java similarity index 84% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/exception/MessageCommandException.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/exception/MessageCommandException.java index e6eab23d5..385fb9398 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/exception/MessageCommandException.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/exception/MessageCommandException.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.plugin.commands.exception; +package com.infernalsuite.asp.plugin.commands.exception; import net.kyori.adventure.text.Component; diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/BukkitWorldParser.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/BukkitWorldParser.java similarity index 83% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/BukkitWorldParser.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/BukkitWorldParser.java index 3adcb4db9..be78f128f 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/BukkitWorldParser.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/BukkitWorldParser.java @@ -1,7 +1,6 @@ -package com.infernalsuite.aswm.plugin.commands.parser; +package com.infernalsuite.asp.plugin.commands.parser; -import com.infernalsuite.aswm.plugin.commands.SlimeCommand; -import com.infernalsuite.aswm.plugin.commands.exception.MessageCommandException; +import com.infernalsuite.asp.plugin.commands.SlimeCommand; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; @@ -24,7 +23,7 @@ public class BukkitWorldParser implements ArgumentParser { World loaded = Bukkit.getWorld(input); if (loaded == null) { - return ArgumentParseResult.failure(new MessageCommandException(SlimeCommand.COMMAND_PREFIX.append( + return ArgumentParseResult.failure(new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(SlimeCommand.COMMAND_PREFIX.append( Component.text("World " + input + " is not loaded!").color(NamedTextColor.RED) ))); } diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/NamedSlimeLoader.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/NamedSlimeLoader.java similarity index 57% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/NamedSlimeLoader.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/NamedSlimeLoader.java index e27aef7d1..5a7ed2a7b 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/NamedSlimeLoader.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/NamedSlimeLoader.java @@ -1,6 +1,6 @@ -package com.infernalsuite.aswm.plugin.commands.parser; +package com.infernalsuite.asp.plugin.commands.parser; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.loaders.SlimeLoader; public record NamedSlimeLoader(String name, SlimeLoader slimeLoader) { @Override diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/NamedSlimeLoaderParser.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/NamedSlimeLoaderParser.java similarity index 81% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/NamedSlimeLoaderParser.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/NamedSlimeLoaderParser.java index c9df2af8f..9b5efea97 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/NamedSlimeLoaderParser.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/NamedSlimeLoaderParser.java @@ -1,9 +1,8 @@ -package com.infernalsuite.aswm.plugin.commands.parser; +package com.infernalsuite.asp.plugin.commands.parser; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.plugin.commands.SlimeCommand; -import com.infernalsuite.aswm.plugin.commands.exception.MessageCommandException; -import com.infernalsuite.aswm.plugin.loader.LoaderManager; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.plugin.commands.SlimeCommand; +import com.infernalsuite.asp.plugin.loader.LoaderManager; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.command.CommandSender; @@ -31,7 +30,7 @@ public NamedSlimeLoaderParser(LoaderManager loaderManager) { SlimeLoader loader = loaderManager.getLoader(input); if (loader == null) { - return ArgumentParseResult.failure(new MessageCommandException(SlimeCommand.COMMAND_PREFIX.append( + return ArgumentParseResult.failure(new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(SlimeCommand.COMMAND_PREFIX.append( Component.text("Unknown data source " + input + "!").color(NamedTextColor.RED) ))); } diff --git a/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/NamedWorldData.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/NamedWorldData.java new file mode 100644 index 000000000..b15ab60bc --- /dev/null +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/NamedWorldData.java @@ -0,0 +1,6 @@ +package com.infernalsuite.asp.plugin.commands.parser; + +import com.infernalsuite.asp.plugin.config.WorldData; + +public record NamedWorldData(String name, WorldData worldData) { +} diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/NamedWorldDataParser.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/NamedWorldDataParser.java similarity index 77% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/NamedWorldDataParser.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/NamedWorldDataParser.java index 51f5743f5..036e7045b 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/NamedWorldDataParser.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/NamedWorldDataParser.java @@ -1,10 +1,10 @@ -package com.infernalsuite.aswm.plugin.commands.parser; +package com.infernalsuite.asp.plugin.commands.parser; -import com.infernalsuite.aswm.plugin.commands.SlimeCommand; -import com.infernalsuite.aswm.plugin.commands.exception.MessageCommandException; -import com.infernalsuite.aswm.plugin.commands.parser.suggestion.KnownSlimeWorldSuggestionProvider; -import com.infernalsuite.aswm.plugin.config.ConfigManager; -import com.infernalsuite.aswm.plugin.config.WorldData; +import com.infernalsuite.asp.plugin.commands.SlimeCommand; +import com.infernalsuite.asp.plugin.commands.exception.MessageCommandException; +import com.infernalsuite.asp.plugin.commands.parser.suggestion.KnownSlimeWorldSuggestionProvider; +import com.infernalsuite.asp.plugin.config.ConfigManager; +import com.infernalsuite.asp.plugin.config.WorldData; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.command.CommandSender; diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/SlimeWorldParser.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/SlimeWorldParser.java similarity index 85% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/SlimeWorldParser.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/SlimeWorldParser.java index efe1e178b..ed6ddea8e 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/SlimeWorldParser.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/SlimeWorldParser.java @@ -1,9 +1,9 @@ -package com.infernalsuite.aswm.plugin.commands.parser; +package com.infernalsuite.asp.plugin.commands.parser; -import com.infernalsuite.aswm.api.AdvancedSlimePaperAPI; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.plugin.commands.SlimeCommand; -import com.infernalsuite.aswm.plugin.commands.exception.MessageCommandException; +import com.infernalsuite.asp.api.AdvancedSlimePaperAPI; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.plugin.commands.SlimeCommand; +import com.infernalsuite.asp.plugin.commands.exception.MessageCommandException; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.command.CommandSender; diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/suggestion/KnownSlimeWorldSuggestionProvider.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/suggestion/KnownSlimeWorldSuggestionProvider.java similarity index 88% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/suggestion/KnownSlimeWorldSuggestionProvider.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/suggestion/KnownSlimeWorldSuggestionProvider.java index 25e36ae5b..4a57928d8 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/suggestion/KnownSlimeWorldSuggestionProvider.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/parser/suggestion/KnownSlimeWorldSuggestionProvider.java @@ -1,6 +1,6 @@ -package com.infernalsuite.aswm.plugin.commands.parser.suggestion; +package com.infernalsuite.asp.plugin.commands.parser.suggestion; -import com.infernalsuite.aswm.plugin.config.ConfigManager; +import com.infernalsuite.asp.plugin.config.ConfigManager; import org.bukkit.command.CommandSender; import org.checkerframework.checker.nullness.qual.NonNull; import org.incendo.cloud.context.CommandContext; diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/CloneWorldCmd.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/CloneWorldCmd.java similarity index 69% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/CloneWorldCmd.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/CloneWorldCmd.java index 78a128396..fd4e17e7d 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/CloneWorldCmd.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/CloneWorldCmd.java @@ -1,18 +1,8 @@ -package com.infernalsuite.aswm.plugin.commands.sub; - - -import com.infernalsuite.aswm.api.exceptions.*; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.plugin.commands.SlimeCommand; -import com.infernalsuite.aswm.plugin.commands.CommandManager; -import com.infernalsuite.aswm.plugin.commands.exception.MessageCommandException; -import com.infernalsuite.aswm.plugin.commands.parser.NamedSlimeLoader; -import com.infernalsuite.aswm.plugin.commands.parser.NamedWorldData; -import com.infernalsuite.aswm.plugin.config.ConfigManager; -import com.infernalsuite.aswm.plugin.config.WorldData; -import com.infernalsuite.aswm.plugin.config.WorldsConfig; -import com.infernalsuite.aswm.plugin.util.ExecutorUtil; +package com.infernalsuite.asp.plugin.commands.sub; + + +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.world.SlimeWorld; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; @@ -29,39 +19,39 @@ import java.io.IOException; import java.util.concurrent.CompletableFuture; -public class CloneWorldCmd extends SlimeCommand { +public class CloneWorldCmd extends com.infernalsuite.asp.plugin.commands.SlimeCommand { private static final Logger LOGGER = LoggerFactory.getLogger(CloneWorldCmd.class); - public CloneWorldCmd(CommandManager commandManager) { + public CloneWorldCmd(com.infernalsuite.asp.plugin.commands.CommandManager commandManager) { super(commandManager); } @Command("swp|aswm|swm clone-world [new-data-source]") @CommandDescription("Clones a world") @Permission("swm.cloneworld") - public CompletableFuture cloneWorld(CommandSender sender, @Argument(value = "template-world") NamedWorldData templateWorld, + public CompletableFuture cloneWorld(CommandSender sender, @Argument(value = "template-world") com.infernalsuite.asp.plugin.commands.parser.NamedWorldData templateWorld, @Argument(value = "world-name") String worldName, - @Argument(value = "new-data-source") @Nullable NamedSlimeLoader slimeLoader) { + @Argument(value = "new-data-source") @Nullable com.infernalsuite.asp.plugin.commands.parser.NamedSlimeLoader slimeLoader) { World world = Bukkit.getWorld(worldName); if (world != null) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("World " + worldName + " is already loaded!")).color(NamedTextColor.RED) ); } - WorldsConfig config = ConfigManager.getWorldConfig(); - WorldData worldData = templateWorld.worldData(); + com.infernalsuite.asp.plugin.config.WorldsConfig config = com.infernalsuite.asp.plugin.config.ConfigManager.getWorldConfig(); + com.infernalsuite.asp.plugin.config.WorldData worldData = templateWorld.worldData(); if (templateWorld.name().equals(worldName)) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("The template world name cannot be the same as the cloned world one!")).color(NamedTextColor.RED) ); } if (commandManager.getWorldsInUse().contains(worldName)) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("World " + worldName + " is already being used on another command! Wait some time and try again.")).color(NamedTextColor.RED) ); } @@ -86,13 +76,13 @@ public CompletableFuture cloneWorld(CommandSender sender, @Argument(value SlimeWorld slimeWorld = getWorldReadyForCloning(templateWorld.name(), initLoader, templateWorld.worldData().toPropertyMap()); SlimeWorld finalSlimeWorld = slimeWorld.clone(worldName, dataSource); - ExecutorUtil.runSyncAndWait(plugin, () -> { + com.infernalsuite.asp.plugin.util.ExecutorUtil.runSyncAndWait(plugin, () -> { try { asp.loadWorld(finalSlimeWorld, true); config.getWorlds().put(worldName, worldData); } catch (IllegalArgumentException ex) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Failed to generate world " + worldName + ": " + ex.getMessage() + ".").color(NamedTextColor.RED) )); } @@ -103,30 +93,30 @@ public CompletableFuture cloneWorld(CommandSender sender, @Argument(value )); }); config.save(); - } catch (WorldAlreadyExistsException ex) { - throw new MessageCommandException(COMMAND_PREFIX.append( + } catch (com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException ex) { + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("There is already a world called " + worldName + " stored in " + dataSource + ".").color(NamedTextColor.RED) )); - } catch (CorruptedWorldException ex) { + } catch (com.infernalsuite.asp.api.exceptions.CorruptedWorldException ex) { LOGGER.error("Failed to load world {}: world seems to be corrupted.", templateWorld.name(), ex); - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Failed to load world " + templateWorld.name() + ": world seems to be corrupted.").color(NamedTextColor.RED) )); - } catch (NewerFormatException ex) { - throw new MessageCommandException(COMMAND_PREFIX.append( + } catch (com.infernalsuite.asp.api.exceptions.NewerFormatException ex) { + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Failed to load world " + templateWorld.name() + ": this world was serialized with a newer version of the Slime Format (" + ex.getMessage() + ") that SWM cannot understand.").color(NamedTextColor.RED) )); - } catch (UnknownWorldException ex) { - throw new MessageCommandException(COMMAND_PREFIX.append( + } catch (com.infernalsuite.asp.api.exceptions.UnknownWorldException ex) { + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Failed to load world " + templateWorld.name() + ": world could not be found (using data source '" + worldData.getDataSource() + "').").color(NamedTextColor.RED) )); } catch (IllegalArgumentException ex) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Failed to load world " + templateWorld.name() + ": " + ex.getMessage()).color(NamedTextColor.RED) )); } catch (IOException ex) { LOGGER.error("Failed to load world {}.", templateWorld.name(), ex); - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Failed to load world " + templateWorld.name() + ". Take a look at the server console for more information.").color(NamedTextColor.RED) )); } finally { diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/CreateWorldCmd.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/CreateWorldCmd.java similarity index 74% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/CreateWorldCmd.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/CreateWorldCmd.java index 6685df336..b1634d86e 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/CreateWorldCmd.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/CreateWorldCmd.java @@ -1,17 +1,9 @@ -package com.infernalsuite.aswm.plugin.commands.sub; - - -import com.infernalsuite.aswm.plugin.commands.SlimeCommand; -import com.infernalsuite.aswm.plugin.commands.CommandManager; -import com.infernalsuite.aswm.plugin.commands.exception.MessageCommandException; -import com.infernalsuite.aswm.plugin.commands.parser.NamedSlimeLoader; -import com.infernalsuite.aswm.plugin.config.ConfigManager; -import com.infernalsuite.aswm.plugin.config.WorldData; -import com.infernalsuite.aswm.plugin.config.WorldsConfig; -import com.infernalsuite.aswm.api.exceptions.WorldAlreadyExistsException; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; -import com.infernalsuite.aswm.plugin.util.ExecutorUtil; +package com.infernalsuite.asp.plugin.commands.sub; + + +import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; @@ -29,10 +21,10 @@ import java.io.IOException; import java.util.concurrent.CompletableFuture; -public class CreateWorldCmd extends SlimeCommand { +public class CreateWorldCmd extends com.infernalsuite.asp.plugin.commands.SlimeCommand { private static final Logger LOGGER = LoggerFactory.getLogger(CreateWorldCmd.class); - public CreateWorldCmd(CommandManager commandManager) { + public CreateWorldCmd(com.infernalsuite.asp.plugin.commands.CommandManager commandManager) { super(commandManager); } @@ -40,10 +32,10 @@ public CreateWorldCmd(CommandManager commandManager) { @CommandDescription("Create an empty world") @Permission("swm.createworld") public CompletableFuture createWorld(CommandSender sender, @Argument(value = "world") String worldName, - @Argument(value = "data-source") NamedSlimeLoader loader) { + @Argument(value = "data-source") com.infernalsuite.asp.plugin.commands.parser.NamedSlimeLoader loader) { if (commandManager.getWorldsInUse().contains(worldName)) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("World " + worldName + " is already being used on another command! Wait some time and try again.")).color(NamedTextColor.RED) ); } @@ -51,15 +43,15 @@ public CompletableFuture createWorld(CommandSender sender, @Argument(value World world = Bukkit.getWorld(worldName); if (world != null) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("World " + worldName + " already exists!")).color(NamedTextColor.RED) ); } - WorldsConfig config = ConfigManager.getWorldConfig(); + com.infernalsuite.asp.plugin.config.WorldsConfig config = com.infernalsuite.asp.plugin.config.ConfigManager.getWorldConfig(); if (config.getWorlds().containsKey(worldName)) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("There is already a world called " + worldName + " inside the worlds config file.")).color(NamedTextColor.RED) ); } @@ -81,7 +73,7 @@ public CompletableFuture createWorld(CommandSender sender, @Argument(value throw new WorldAlreadyExistsException("World already exists"); } - WorldData worldData = new WorldData(); + com.infernalsuite.asp.plugin.config.WorldData worldData = new com.infernalsuite.asp.plugin.config.WorldData(); worldData.setSpawn("0, 64, 0"); worldData.setDataSource(loader.name()); @@ -89,7 +81,7 @@ public CompletableFuture createWorld(CommandSender sender, @Argument(value SlimeWorld slimeWorld = asp.createEmptyWorld(worldName, false, propertyMap, loader.slimeLoader()); asp.saveWorld(slimeWorld); - ExecutorUtil.runSyncAndWait(plugin, () -> { + com.infernalsuite.asp.plugin.util.ExecutorUtil.runSyncAndWait(plugin, () -> { try { asp.loadWorld(slimeWorld, true); @@ -100,7 +92,7 @@ public CompletableFuture createWorld(CommandSender sender, @Argument(value // Config config.getWorlds().put(worldName, worldData); } catch (IllegalArgumentException ex) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Failed to create world " + worldName + ": " + ex.getMessage() + ".").color(NamedTextColor.RED) )); } @@ -113,12 +105,12 @@ public CompletableFuture createWorld(CommandSender sender, @Argument(value .append(Component.text(" created in " + (System.currentTimeMillis() - start) + "ms!").color(NamedTextColor.GREEN)) )); } catch (WorldAlreadyExistsException ex) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Failed to create world " + worldName + ": world already exists (using data source '" + loader.name() + "').").color(NamedTextColor.RED) )); } catch (IOException ex) { LOGGER.error("Failed to create world {}:", worldName, ex); - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Failed to create world " + worldName + ". Take a look at the server console for more information.").color(NamedTextColor.RED) )); } finally { diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/DSListCmd.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/DSListCmd.java similarity index 79% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/DSListCmd.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/DSListCmd.java index 4c7dbf5a3..9bbf12c0c 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/DSListCmd.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/DSListCmd.java @@ -1,12 +1,8 @@ -package com.infernalsuite.aswm.plugin.commands.sub; - -import com.infernalsuite.aswm.api.SlimeNMSBridge; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.plugin.commands.SlimeCommand; -import com.infernalsuite.aswm.plugin.commands.CommandManager; -import com.infernalsuite.aswm.plugin.commands.exception.MessageCommandException; -import com.infernalsuite.aswm.plugin.commands.parser.NamedSlimeLoader; +package com.infernalsuite.asp.plugin.commands.sub; + +import com.infernalsuite.asp.api.SlimeNMSBridge; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.world.SlimeWorld; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; @@ -20,24 +16,24 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -public class DSListCmd extends SlimeCommand { +public class DSListCmd extends com.infernalsuite.asp.plugin.commands.SlimeCommand { private static final int MAX_ITEMS_PER_PAGE = 5; private static final Logger LOGGER = LoggerFactory.getLogger(DSListCmd.class); - public DSListCmd(CommandManager commandManager) { + public DSListCmd(com.infernalsuite.asp.plugin.commands.CommandManager commandManager) { super(commandManager); } @Command("swp|aswm|swm dslist [page]") @CommandDescription("List all worlds inside a data source.") @Permission("swm.dslist") - public CompletableFuture listWorlds(CommandSender sender, @Argument(value = "data-source") NamedSlimeLoader namedLoader, + public CompletableFuture listWorlds(CommandSender sender, @Argument(value = "data-source") com.infernalsuite.asp.plugin.commands.parser.NamedSlimeLoader namedLoader, @Default("1") @Argument(value = "page") int page) { SlimeLoader loader = namedLoader.slimeLoader(); if (page < 1) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Page number must be greater than 0!").color(NamedTextColor.RED) )); } @@ -50,13 +46,13 @@ public CompletableFuture listWorlds(CommandSender sender, @Argument(value worldList = loader.listWorlds(); } catch (IOException ex) { LOGGER.error("Failed to load world list:", ex); - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Failed to load world list. Take a look at the server console for more information.").color(NamedTextColor.RED) )); } if (worldList.isEmpty()) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("There are no worlds stored in data source " + namedLoader.name() + ".").color(NamedTextColor.RED) )); } @@ -66,7 +62,7 @@ public CompletableFuture listWorlds(CommandSender sender, @Argument(value int maxPages = ((int) d) + ((d > (int) d) ? 1 : 0); if (offset >= worldList.size()) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("There " + (maxPages == 1 ? "is" : "are") + " only " + maxPages + " page" + (maxPages == 1 ? "" : "s") + "!").color(NamedTextColor.RED) )); diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/DeleteWorldCmd.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/DeleteWorldCmd.java similarity index 79% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/DeleteWorldCmd.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/DeleteWorldCmd.java index a94a75494..12c9359ef 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/DeleteWorldCmd.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/DeleteWorldCmd.java @@ -1,16 +1,9 @@ -package com.infernalsuite.aswm.plugin.commands.sub; +package com.infernalsuite.asp.plugin.commands.sub; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; -import com.infernalsuite.aswm.api.exceptions.UnknownWorldException; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.plugin.commands.SlimeCommand; -import com.infernalsuite.aswm.plugin.commands.CommandManager; -import com.infernalsuite.aswm.plugin.commands.exception.MessageCommandException; -import com.infernalsuite.aswm.plugin.commands.parser.NamedSlimeLoader; -import com.infernalsuite.aswm.plugin.config.ConfigManager; -import com.infernalsuite.aswm.plugin.config.WorldData; -import com.infernalsuite.aswm.plugin.config.WorldsConfig; +import com.infernalsuite.asp.api.exceptions.UnknownWorldException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; @@ -30,11 +23,11 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; -public class DeleteWorldCmd extends SlimeCommand { +public class DeleteWorldCmd extends com.infernalsuite.asp.plugin.commands.SlimeCommand { private static final Logger LOGGER = LoggerFactory.getLogger(DeleteWorldCmd.class); - public DeleteWorldCmd(CommandManager commandManager) { + public DeleteWorldCmd(com.infernalsuite.asp.plugin.commands.CommandManager commandManager) { super(commandManager); } @@ -46,11 +39,11 @@ public DeleteWorldCmd(CommandManager commandManager) { @RawArgs public CompletableFuture deleteWorld(CommandSender sender, String[] args, @Argument(value = "world", suggestions = "known-slime-worlds") String worldName, - @Argument(value = "data-source") @Nullable NamedSlimeLoader dataSource) { + @Argument(value = "data-source") @Nullable com.infernalsuite.asp.plugin.commands.parser.NamedSlimeLoader dataSource) { World world = Bukkit.getWorld(worldName); if (world != null) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("World " + worldName + " is loaded on this server! Unload it by running the command ").color(NamedTextColor.RED) .append(Component.text("/swm unload " + worldName).color(NamedTextColor.GRAY)) .append(Component.text(".")).color(NamedTextColor.RED) @@ -62,11 +55,11 @@ public CompletableFuture deleteWorld(CommandSender sender, String[] args, if (dataSource != null) { loader = dataSource.slimeLoader(); } else { - WorldsConfig config = ConfigManager.getWorldConfig(); - WorldData worldData = config.getWorlds().get(worldName); + com.infernalsuite.asp.plugin.config.WorldsConfig config = com.infernalsuite.asp.plugin.config.ConfigManager.getWorldConfig(); + com.infernalsuite.asp.plugin.config.WorldData worldData = config.getWorlds().get(worldName); if (worldData == null) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Failed to find world " + worldName + " inside the worlds config file!").color(NamedTextColor.RED) )); } @@ -76,13 +69,13 @@ public CompletableFuture deleteWorld(CommandSender sender, String[] args, if (loader == null) { // This could happen if the loader inside WorldData is invalid - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Unknown data source! Are you sure you typed it correctly?").color(NamedTextColor.RED) )); } if (commandManager.getWorldsInUse().contains(worldName)) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("World " + worldName + " is already being used on another command! Wait some time and try again.").color(NamedTextColor.RED) )); } @@ -107,7 +100,7 @@ public CompletableFuture deleteWorld(CommandSender sender, String[] args, loader.deleteWorld(worldName); // Now let's delete it from the config file - WorldsConfig config = ConfigManager.getWorldConfig(); + com.infernalsuite.asp.plugin.config.WorldsConfig config = com.infernalsuite.asp.plugin.config.ConfigManager.getWorldConfig(); config.getWorlds().remove(worldName); config.save(); @@ -120,11 +113,11 @@ public CompletableFuture deleteWorld(CommandSender sender, String[] args, } catch (IOException ex) { LOGGER.error("Failed to delete world {}", worldName, ex); - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Failed to delete world " + worldName + ". Take a look at the server console for more information.").color(NamedTextColor.RED) )); } catch (UnknownWorldException ex) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Data source " + loader + " does not contain any world called " + worldName + ".").color(NamedTextColor.RED) )); } finally { diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/GotoCmd.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/GotoCmd.java similarity index 78% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/GotoCmd.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/GotoCmd.java index 5dad6ccc7..d6dd7f967 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/GotoCmd.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/GotoCmd.java @@ -1,10 +1,5 @@ -package com.infernalsuite.aswm.plugin.commands.sub; +package com.infernalsuite.asp.plugin.commands.sub; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.plugin.commands.SlimeCommand; -import com.infernalsuite.aswm.plugin.commands.CommandManager; -import com.infernalsuite.aswm.plugin.commands.exception.MessageCommandException; -import com.infernalsuite.aswm.plugin.config.ConfigManager; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; @@ -18,9 +13,9 @@ import org.incendo.cloud.annotations.Permission; import org.jetbrains.annotations.Nullable; -public class GotoCmd extends SlimeCommand { +public class GotoCmd extends com.infernalsuite.asp.plugin.commands.SlimeCommand { - public GotoCmd(CommandManager commandManager) { + public GotoCmd(com.infernalsuite.asp.plugin.commands.CommandManager commandManager) { super(commandManager); } @@ -33,7 +28,7 @@ public void onCommand(CommandSender sender, @Argument(value = "world") World wor if (target == null) { if (!(sender instanceof Player)) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("The console cannot be teleported to a world! Please specify a player.").color(NamedTextColor.RED) )); } @@ -60,8 +55,8 @@ public void onCommand(CommandSender sender, @Argument(value = "world") World wor } Location spawnLocation; - if (ConfigManager.getWorldConfig().getWorlds().containsKey(world.getName())) { - String spawn = ConfigManager.getWorldConfig().getWorlds().get(world.getName()).getSpawn(); + if (com.infernalsuite.asp.plugin.config.ConfigManager.getWorldConfig().getWorlds().containsKey(world.getName())) { + String spawn = com.infernalsuite.asp.plugin.config.ConfigManager.getWorldConfig().getWorlds().get(world.getName()).getSpawn(); String[] coords = spawn.split(", "); double x = Double.parseDouble(coords[0]); double y = Double.parseDouble(coords[1]); diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/HelpCmd.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/HelpCmd.java similarity index 73% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/HelpCmd.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/HelpCmd.java index 89c72d011..f60c2f11f 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/HelpCmd.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/HelpCmd.java @@ -1,7 +1,5 @@ -package com.infernalsuite.aswm.plugin.commands.sub; +package com.infernalsuite.asp.plugin.commands.sub; -import com.infernalsuite.aswm.plugin.commands.CommandManager; -import com.infernalsuite.aswm.plugin.commands.SlimeCommand; import org.bukkit.command.CommandSender; import org.incendo.cloud.annotations.Argument; import org.incendo.cloud.annotations.Command; @@ -11,11 +9,11 @@ import org.incendo.cloud.paper.PaperCommandManager; import org.jetbrains.annotations.Nullable; -public class HelpCmd extends SlimeCommand { +public class HelpCmd extends com.infernalsuite.asp.plugin.commands.SlimeCommand { private final MinecraftHelp help; - public HelpCmd(CommandManager commandManager, LegacyPaperCommandManager cloudCommandManager) { + public HelpCmd(com.infernalsuite.asp.plugin.commands.CommandManager commandManager, LegacyPaperCommandManager cloudCommandManager) { super(commandManager); this.help = MinecraftHelp.createNative("/swp help", cloudCommandManager); } diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/ImportWorldCmd.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/ImportWorldCmd.java similarity index 80% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/ImportWorldCmd.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/ImportWorldCmd.java index e3d3ef012..1a269d73a 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/ImportWorldCmd.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/ImportWorldCmd.java @@ -1,21 +1,13 @@ -package com.infernalsuite.aswm.plugin.commands.sub; +package com.infernalsuite.asp.plugin.commands.sub; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; -import com.infernalsuite.aswm.api.exceptions.InvalidWorldException; -import com.infernalsuite.aswm.api.exceptions.WorldAlreadyExistsException; -import com.infernalsuite.aswm.api.exceptions.WorldLoadedException; -import com.infernalsuite.aswm.api.exceptions.WorldTooBigException; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.api.world.properties.SlimeProperties; -import com.infernalsuite.aswm.plugin.commands.CommandManager; -import com.infernalsuite.aswm.plugin.commands.SlimeCommand; -import com.infernalsuite.aswm.plugin.commands.exception.MessageCommandException; -import com.infernalsuite.aswm.plugin.commands.parser.NamedSlimeLoader; -import com.infernalsuite.aswm.plugin.config.ConfigManager; -import com.infernalsuite.aswm.plugin.config.WorldData; -import com.infernalsuite.aswm.plugin.config.WorldsConfig; -import com.infernalsuite.aswm.plugin.util.ExecutorUtil; +import com.infernalsuite.asp.api.exceptions.InvalidWorldException; +import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; +import com.infernalsuite.asp.api.exceptions.WorldLoadedException; +import com.infernalsuite.asp.api.exceptions.WorldTooBigException; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.properties.SlimeProperties; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.command.CommandSender; @@ -33,11 +25,11 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; -public class ImportWorldCmd extends SlimeCommand { +public class ImportWorldCmd extends com.infernalsuite.asp.plugin.commands.SlimeCommand { private static final Logger LOGGER = LoggerFactory.getLogger(ImportWorldCmd.class); - public ImportWorldCmd(CommandManager commandManager) { + public ImportWorldCmd(com.infernalsuite.asp.plugin.commands.CommandManager commandManager) { super(commandManager); } @@ -49,12 +41,12 @@ public ImportWorldCmd(CommandManager commandManager) { @RawArgs public CompletableFuture importWorld(CommandSender sender, String[] args, @Argument(value = "path-to-world") String pathToWorld, - @Argument(value = "data-source") NamedSlimeLoader loader, + @Argument(value = "data-source") com.infernalsuite.asp.plugin.commands.parser.NamedSlimeLoader loader, @Argument(value = "new-world-name") String newWorldName) { File worldDir = new File(pathToWorld); if (!worldDir.exists() || !worldDir.isDirectory()) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Path " + worldDir.getPath() + " does not point out to a valid world directory.")).color(NamedTextColor.RED) ); } @@ -70,10 +62,10 @@ public CompletableFuture importWorld(CommandSender sender, String[] args, Component.text("Importing world " + worldDir.getName() + " into data source " + loader.slimeLoader() + "...")) ); - WorldsConfig config = ConfigManager.getWorldConfig(); + com.infernalsuite.asp.plugin.config.WorldsConfig config = com.infernalsuite.asp.plugin.config.ConfigManager.getWorldConfig(); if (config.getWorlds().containsKey(worldName)) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("There is already a world called " + worldName + " inside the worlds config file.")).color(NamedTextColor.RED) ); } @@ -84,7 +76,7 @@ public CompletableFuture importWorld(CommandSender sender, String[] args, SlimeWorld world = asp.readVanillaWorld(worldDir, worldName, loader.slimeLoader()); asp.saveWorld(world); - ExecutorUtil.runSyncAndWait(plugin, () -> { + com.infernalsuite.asp.plugin.util.ExecutorUtil.runSyncAndWait(plugin, () -> { asp.loadWorld(world, true); }); @@ -94,7 +86,7 @@ public CompletableFuture importWorld(CommandSender sender, String[] args, .append(Component.text(" imported successfully in " + (System.currentTimeMillis() - start) + "ms.")).color(NamedTextColor.GREEN) )); - WorldData worldData = new WorldData(); + com.infernalsuite.asp.plugin.config.WorldData worldData = new com.infernalsuite.asp.plugin.config.WorldData(); StringBuilder spawn = new StringBuilder(); for (String key : world.getPropertyMap().getProperties().keySet()) { switch (key.toLowerCase()) { @@ -125,25 +117,25 @@ public CompletableFuture importWorld(CommandSender sender, String[] args, config.save(); } catch (WorldAlreadyExistsException ex) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Data source " + loader + " already contains a world called " + worldName + ".")).color(NamedTextColor.RED) ); } catch (InvalidWorldException ex) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Directory " + worldDir.getName() + " does not contain a valid Minecraft world.")).color(NamedTextColor.RED) ); } catch (WorldLoadedException ex) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("World " + worldDir.getName() + " is loaded on this server. Please unload it before importing it.")).color(NamedTextColor.RED) ); } catch (WorldTooBigException ex) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Hey! Didn't you just read the warning? The Slime Format isn't meant for big worlds." + " The world you provided just breaks everything. Please, trim it by using the MCEdit tool and try again.")).color(NamedTextColor.RED) ); } catch (IOException ex) { LOGGER.error("Failed to import world {}:", worldDir.getName(), ex); - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Failed to import world " + worldName + ". Take a look at the server console for more information.")).color(NamedTextColor.RED) ); } diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/LoadTemplateWorldCmd.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/LoadTemplateWorldCmd.java similarity index 82% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/LoadTemplateWorldCmd.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/LoadTemplateWorldCmd.java index 66a57fbd4..5cb1f3cff 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/LoadTemplateWorldCmd.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/LoadTemplateWorldCmd.java @@ -1,16 +1,11 @@ -package com.infernalsuite.aswm.plugin.commands.sub; +package com.infernalsuite.asp.plugin.commands.sub; -import com.infernalsuite.aswm.api.exceptions.CorruptedWorldException; -import com.infernalsuite.aswm.api.exceptions.NewerFormatException; -import com.infernalsuite.aswm.api.exceptions.UnknownWorldException; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.plugin.commands.CommandManager; -import com.infernalsuite.aswm.plugin.commands.SlimeCommand; -import com.infernalsuite.aswm.plugin.commands.exception.MessageCommandException; -import com.infernalsuite.aswm.plugin.commands.parser.NamedWorldData; -import com.infernalsuite.aswm.plugin.util.ExecutorUtil; +import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; +import com.infernalsuite.asp.api.exceptions.NewerFormatException; +import com.infernalsuite.asp.api.exceptions.UnknownWorldException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.world.SlimeWorld; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; @@ -26,35 +21,35 @@ import java.io.IOException; import java.util.concurrent.CompletableFuture; -public class LoadTemplateWorldCmd extends SlimeCommand { +public class LoadTemplateWorldCmd extends com.infernalsuite.asp.plugin.commands.SlimeCommand { private static final Logger LOGGER = LoggerFactory.getLogger(LoadTemplateWorldCmd.class); - public LoadTemplateWorldCmd(CommandManager commandManager) { + public LoadTemplateWorldCmd(com.infernalsuite.asp.plugin.commands.CommandManager commandManager) { super(commandManager); } @Command("swp|aswm|swm load-template ") @CommandDescription("Creates a temporary world using another as a template. This world will never be stored.") @Permission("swm.loadworld.template") - public CompletableFuture onCommand(CommandSender sender, @Argument(value = "template-world") NamedWorldData templateWorldData, + public CompletableFuture onCommand(CommandSender sender, @Argument(value = "template-world") com.infernalsuite.asp.plugin.commands.parser.NamedWorldData templateWorldData, @Argument(value = "world-name") String worldName) { World world = Bukkit.getWorld(worldName); if (world != null) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("World " + worldName + " is already loaded!").color(NamedTextColor.RED) )); } if (templateWorldData.name().equals(worldName)) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("The template world name cannot be the same as the cloned world one!").color(NamedTextColor.RED) )); } if (commandManager.getWorldsInUse().contains(worldName)) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("World " + worldName + " is already being used on another command! Wait some time and try again.").color(NamedTextColor.RED) )); } @@ -81,11 +76,11 @@ public CompletableFuture onCommand(CommandSender sender, @Argument(value = SlimeWorld templateWorld = getWorldReadyForCloning(templateWorldData.name(), loader, templateWorldData.worldData().toPropertyMap()); SlimeWorld slimeWorld = templateWorld.clone(worldName); - ExecutorUtil.runSyncAndWait(plugin, () -> { + com.infernalsuite.asp.plugin.util.ExecutorUtil.runSyncAndWait(plugin, () -> { try { asp.loadWorld(slimeWorld, true); } catch (IllegalArgumentException ex) { - throw new MessageCommandException(COMMAND_PREFIX.append( + throw new com.infernalsuite.asp.plugin.commands.exception.MessageCommandException(COMMAND_PREFIX.append( Component.text("Failed to generate world " + worldName + ": " + ex.getMessage() + ".").color(NamedTextColor.RED) )); } diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/LoadWorldCmd.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/LoadWorldCmd.java similarity index 89% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/LoadWorldCmd.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/LoadWorldCmd.java index c8500506d..12f29e123 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/LoadWorldCmd.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/LoadWorldCmd.java @@ -1,16 +1,16 @@ -package com.infernalsuite.aswm.plugin.commands.sub; - - -import com.infernalsuite.aswm.api.exceptions.CorruptedWorldException; -import com.infernalsuite.aswm.api.exceptions.NewerFormatException; -import com.infernalsuite.aswm.api.exceptions.UnknownWorldException; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.plugin.commands.CommandManager; -import com.infernalsuite.aswm.plugin.commands.SlimeCommand; -import com.infernalsuite.aswm.plugin.commands.exception.MessageCommandException; -import com.infernalsuite.aswm.plugin.commands.parser.NamedWorldData; -import com.infernalsuite.aswm.plugin.util.ExecutorUtil; +package com.infernalsuite.asp.plugin.commands.sub; + + +import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; +import com.infernalsuite.asp.api.exceptions.NewerFormatException; +import com.infernalsuite.asp.api.exceptions.UnknownWorldException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.plugin.commands.CommandManager; +import com.infernalsuite.asp.plugin.commands.SlimeCommand; +import com.infernalsuite.asp.plugin.commands.exception.MessageCommandException; +import com.infernalsuite.asp.plugin.commands.parser.NamedWorldData; +import com.infernalsuite.asp.plugin.util.ExecutorUtil; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/MigrateWorldCmd.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/MigrateWorldCmd.java similarity index 87% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/MigrateWorldCmd.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/MigrateWorldCmd.java index 06a99cd38..f76c56bc7 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/MigrateWorldCmd.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/MigrateWorldCmd.java @@ -1,14 +1,14 @@ -package com.infernalsuite.aswm.plugin.commands.sub; +package com.infernalsuite.asp.plugin.commands.sub; -import com.infernalsuite.aswm.api.exceptions.UnknownWorldException; -import com.infernalsuite.aswm.api.exceptions.WorldAlreadyExistsException; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.plugin.commands.CommandManager; -import com.infernalsuite.aswm.plugin.commands.SlimeCommand; -import com.infernalsuite.aswm.plugin.commands.exception.MessageCommandException; -import com.infernalsuite.aswm.plugin.commands.parser.NamedSlimeLoader; -import com.infernalsuite.aswm.plugin.commands.parser.NamedWorldData; -import com.infernalsuite.aswm.plugin.config.ConfigManager; +import com.infernalsuite.asp.api.exceptions.UnknownWorldException; +import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.plugin.commands.CommandManager; +import com.infernalsuite.asp.plugin.commands.SlimeCommand; +import com.infernalsuite.asp.plugin.commands.exception.MessageCommandException; +import com.infernalsuite.asp.plugin.commands.parser.NamedSlimeLoader; +import com.infernalsuite.asp.plugin.commands.parser.NamedWorldData; +import com.infernalsuite.asp.plugin.config.ConfigManager; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.command.CommandSender; diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/ReloadConfigCmd.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/ReloadConfigCmd.java similarity index 81% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/ReloadConfigCmd.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/ReloadConfigCmd.java index 261bf16fe..1ebd8d7ec 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/ReloadConfigCmd.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/ReloadConfigCmd.java @@ -1,9 +1,9 @@ -package com.infernalsuite.aswm.plugin.commands.sub; +package com.infernalsuite.asp.plugin.commands.sub; -import com.infernalsuite.aswm.plugin.commands.CommandManager; -import com.infernalsuite.aswm.plugin.commands.SlimeCommand; -import com.infernalsuite.aswm.plugin.commands.exception.MessageCommandException; -import com.infernalsuite.aswm.plugin.config.ConfigManager; +import com.infernalsuite.asp.plugin.commands.CommandManager; +import com.infernalsuite.asp.plugin.commands.SlimeCommand; +import com.infernalsuite.asp.plugin.commands.exception.MessageCommandException; +import com.infernalsuite.asp.plugin.config.ConfigManager; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.ChatColor; @@ -16,8 +16,6 @@ import org.slf4j.LoggerFactory; import java.io.IOException; -import java.util.Collections; -import java.util.List; import java.util.concurrent.CompletableFuture; public class ReloadConfigCmd extends SlimeCommand { diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/SaveWorldCmd.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/SaveWorldCmd.java similarity index 79% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/SaveWorldCmd.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/SaveWorldCmd.java index 38b82ab1a..5f55c5e72 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/SaveWorldCmd.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/SaveWorldCmd.java @@ -1,10 +1,10 @@ -package com.infernalsuite.aswm.plugin.commands.sub; +package com.infernalsuite.asp.plugin.commands.sub; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.plugin.commands.CommandManager; -import com.infernalsuite.aswm.plugin.commands.SlimeCommand; -import com.infernalsuite.aswm.plugin.commands.exception.MessageCommandException; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.plugin.commands.CommandManager; +import com.infernalsuite.asp.plugin.commands.SlimeCommand; +import com.infernalsuite.asp.plugin.commands.exception.MessageCommandException; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; @@ -19,9 +19,6 @@ import org.slf4j.LoggerFactory; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; public class SaveWorldCmd extends SlimeCommand { private static final Logger LOGGER = LoggerFactory.getLogger(SaveWorldCmd.class); diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/SetSpawnCmd.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/SetSpawnCmd.java similarity index 81% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/SetSpawnCmd.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/SetSpawnCmd.java index 38b0f5fe1..98b2f1023 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/SetSpawnCmd.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/SetSpawnCmd.java @@ -1,13 +1,11 @@ -package com.infernalsuite.aswm.plugin.commands.sub; +package com.infernalsuite.asp.plugin.commands.sub; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.plugin.commands.CommandManager; -import com.infernalsuite.aswm.plugin.commands.SlimeCommand; -import com.infernalsuite.aswm.plugin.commands.exception.MessageCommandException; -import com.infernalsuite.aswm.plugin.config.ConfigManager; -import com.infernalsuite.aswm.plugin.config.WorldData; -import com.infernalsuite.aswm.plugin.config.WorldsConfig; +import com.infernalsuite.asp.plugin.commands.CommandManager; +import com.infernalsuite.asp.plugin.commands.SlimeCommand; +import com.infernalsuite.asp.plugin.commands.exception.MessageCommandException; +import com.infernalsuite.asp.plugin.config.ConfigManager; +import com.infernalsuite.asp.plugin.config.WorldData; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; @@ -20,10 +18,6 @@ import org.incendo.cloud.annotations.CommandDescription; import org.incendo.cloud.annotations.Permission; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - public class SetSpawnCmd extends SlimeCommand { public SetSpawnCmd(CommandManager commandManager) { diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/UnloadWorldCmd.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/UnloadWorldCmd.java similarity index 92% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/UnloadWorldCmd.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/UnloadWorldCmd.java index f7717bd41..dfd1d2703 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/UnloadWorldCmd.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/UnloadWorldCmd.java @@ -1,9 +1,9 @@ -package com.infernalsuite.aswm.plugin.commands.sub; +package com.infernalsuite.asp.plugin.commands.sub; -import com.infernalsuite.aswm.api.world.SlimeWorld; -import com.infernalsuite.aswm.plugin.SWPlugin; -import com.infernalsuite.aswm.plugin.commands.CommandManager; -import com.infernalsuite.aswm.plugin.commands.SlimeCommand; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.plugin.SWPlugin; +import com.infernalsuite.asp.plugin.commands.CommandManager; +import com.infernalsuite.asp.plugin.commands.SlimeCommand; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/VersionCmd.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/VersionCmd.java similarity index 80% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/VersionCmd.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/VersionCmd.java index 69e7bfdb0..83e40b455 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/VersionCmd.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/VersionCmd.java @@ -1,9 +1,9 @@ -package com.infernalsuite.aswm.plugin.commands.sub; +package com.infernalsuite.asp.plugin.commands.sub; -import com.infernalsuite.aswm.plugin.SWPlugin; -import com.infernalsuite.aswm.api.utils.SlimeFormat; -import com.infernalsuite.aswm.plugin.commands.CommandManager; -import com.infernalsuite.aswm.plugin.commands.SlimeCommand; +import com.infernalsuite.asp.plugin.SWPlugin; +import com.infernalsuite.asp.api.utils.SlimeFormat; +import com.infernalsuite.asp.plugin.commands.CommandManager; +import com.infernalsuite.asp.plugin.commands.SlimeCommand; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.command.CommandSender; diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/WorldListCmd.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/WorldListCmd.java similarity index 92% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/WorldListCmd.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/WorldListCmd.java index 49d70a48d..2896dbfc0 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/sub/WorldListCmd.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/WorldListCmd.java @@ -1,10 +1,10 @@ -package com.infernalsuite.aswm.plugin.commands.sub; +package com.infernalsuite.asp.plugin.commands.sub; -import com.infernalsuite.aswm.plugin.commands.SlimeCommand; -import com.infernalsuite.aswm.plugin.commands.CommandManager; -import com.infernalsuite.aswm.plugin.commands.exception.MessageCommandException; -import com.infernalsuite.aswm.plugin.config.ConfigManager; -import com.infernalsuite.aswm.api.SlimeNMSBridge; +import com.infernalsuite.asp.plugin.commands.SlimeCommand; +import com.infernalsuite.asp.plugin.commands.CommandManager; +import com.infernalsuite.asp.plugin.commands.exception.MessageCommandException; +import com.infernalsuite.asp.plugin.config.ConfigManager; +import com.infernalsuite.asp.api.SlimeNMSBridge; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/config/ConfigManager.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/config/ConfigManager.java similarity index 96% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/config/ConfigManager.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/config/ConfigManager.java index f90dd35c2..6dba89baa 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/config/ConfigManager.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/config/ConfigManager.java @@ -1,6 +1,6 @@ -package com.infernalsuite.aswm.plugin.config; +package com.infernalsuite.asp.plugin.config; -import com.infernalsuite.aswm.plugin.SWPlugin; +import com.infernalsuite.asp.plugin.SWPlugin; import io.leangen.geantyref.TypeToken; import org.spongepowered.configurate.loader.HeaderMode; import org.spongepowered.configurate.yaml.NodeStyle; diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/config/DatasourcesConfig.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/config/DatasourcesConfig.java similarity index 99% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/config/DatasourcesConfig.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/config/DatasourcesConfig.java index f28a6f8b4..1b8e06777 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/config/DatasourcesConfig.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/config/DatasourcesConfig.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.plugin.config; +package com.infernalsuite.asp.plugin.config; import org.spongepowered.configurate.objectmapping.ConfigSerializable; import org.spongepowered.configurate.objectmapping.meta.Setting; diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/config/WorldData.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/config/WorldData.java similarity index 96% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/config/WorldData.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/config/WorldData.java index 30dd9feb5..6ce08da9f 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/config/WorldData.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/config/WorldData.java @@ -1,12 +1,12 @@ -package com.infernalsuite.aswm.plugin.config; +package com.infernalsuite.asp.plugin.config; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import org.bukkit.Difficulty; import org.bukkit.World; import org.spongepowered.configurate.objectmapping.ConfigSerializable; import org.spongepowered.configurate.objectmapping.meta.Setting; -import static com.infernalsuite.aswm.api.world.properties.SlimeProperties.*; +import static com.infernalsuite.asp.api.world.properties.SlimeProperties.*; @ConfigSerializable public class WorldData { diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/config/WorldsConfig.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/config/WorldsConfig.java similarity index 95% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/config/WorldsConfig.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/config/WorldsConfig.java index 8d65ab38f..1b429741b 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/config/WorldsConfig.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/config/WorldsConfig.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.plugin.config; +package com.infernalsuite.asp.plugin.config; import io.leangen.geantyref.TypeToken; import org.slf4j.Logger; diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/loader/LoaderManager.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/loader/LoaderManager.java similarity index 75% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/loader/LoaderManager.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/loader/LoaderManager.java index 73b35b25d..7d73e01a2 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/loader/LoaderManager.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/loader/LoaderManager.java @@ -1,14 +1,12 @@ -package com.infernalsuite.aswm.plugin.loader; - -import com.infernalsuite.aswm.plugin.config.ConfigManager; -import com.infernalsuite.aswm.plugin.config.DatasourcesConfig; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import com.infernalsuite.aswm.loaders.UpdatableLoader; -import com.infernalsuite.aswm.loaders.api.APILoader; -import com.infernalsuite.aswm.loaders.file.FileLoader; -import com.infernalsuite.aswm.loaders.mongo.MongoLoader; -import com.infernalsuite.aswm.loaders.mysql.MysqlLoader; -import com.infernalsuite.aswm.loaders.redis.RedisLoader; +package com.infernalsuite.asp.plugin.loader; + +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.loaders.UpdatableLoader; +import com.infernalsuite.asp.loaders.api.APILoader; +import com.infernalsuite.asp.loaders.file.FileLoader; +import com.infernalsuite.asp.loaders.mongo.MongoLoader; +import com.infernalsuite.asp.loaders.mysql.MysqlLoader; +import com.infernalsuite.asp.loaders.redis.RedisLoader; import com.mongodb.MongoException; import io.lettuce.core.RedisException; import org.slf4j.Logger; @@ -27,14 +25,14 @@ public class LoaderManager { private final Map loaders = new HashMap<>(); public LoaderManager() { - DatasourcesConfig config = ConfigManager.getDatasourcesConfig(); + com.infernalsuite.asp.plugin.config.DatasourcesConfig config = com.infernalsuite.asp.plugin.config.ConfigManager.getDatasourcesConfig(); // File loader - DatasourcesConfig.FileConfig fileConfig = config.getFileConfig(); + com.infernalsuite.asp.plugin.config.DatasourcesConfig.FileConfig fileConfig = config.getFileConfig(); registerLoader("file", new FileLoader(new File(fileConfig.getPath()))); // Mysql loader - DatasourcesConfig.MysqlConfig mysqlConfig = config.getMysqlConfig(); + com.infernalsuite.asp.plugin.config.DatasourcesConfig.MysqlConfig mysqlConfig = config.getMysqlConfig(); if (mysqlConfig.isEnabled()) { try { registerLoader("mysql", new MysqlLoader( @@ -49,7 +47,7 @@ public LoaderManager() { } // MongoDB loader - DatasourcesConfig.MongoDBConfig mongoConfig = config.getMongoDbConfig(); + com.infernalsuite.asp.plugin.config.DatasourcesConfig.MongoDBConfig mongoConfig = config.getMongoDbConfig(); if (mongoConfig.isEnabled()) { try { @@ -68,7 +66,7 @@ public LoaderManager() { } } - DatasourcesConfig.RedisConfig redisConfig = config.getRedisConfig(); + com.infernalsuite.asp.plugin.config.DatasourcesConfig.RedisConfig redisConfig = config.getRedisConfig(); if (redisConfig.isEnabled()){ try { registerLoader("redis", new RedisLoader(redisConfig.getUri())); @@ -77,7 +75,7 @@ public LoaderManager() { } } - DatasourcesConfig.APIConfig apiConfig = config.getApiConfig(); + com.infernalsuite.asp.plugin.config.DatasourcesConfig.APIConfig apiConfig = config.getApiConfig(); if(apiConfig.isEnabled()){ registerLoader("api", new APILoader( apiConfig.getUrl(), diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/util/ExecutorUtil.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/util/ExecutorUtil.java similarity index 96% rename from plugin/src/main/java/com/infernalsuite/aswm/plugin/util/ExecutorUtil.java rename to plugin/src/main/java/com/infernalsuite/asp/plugin/util/ExecutorUtil.java index 95fe092b3..7e4fea235 100644 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/util/ExecutorUtil.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/util/ExecutorUtil.java @@ -1,4 +1,4 @@ -package com.infernalsuite.aswm.plugin.util; +package com.infernalsuite.asp.plugin.util; import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; diff --git a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/NamedWorldData.java b/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/NamedWorldData.java deleted file mode 100644 index 35d03d2f9..000000000 --- a/plugin/src/main/java/com/infernalsuite/aswm/plugin/commands/parser/NamedWorldData.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.infernalsuite.aswm.plugin.commands.parser; - -import com.infernalsuite.aswm.plugin.config.WorldData; - -public record NamedWorldData(String name, WorldData worldData) { -} diff --git a/settings.gradle.kts b/settings.gradle.kts index 2fe280a22..78e57a832 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,13 +1,20 @@ pluginManagement { repositories { mavenLocal() + mavenCentral() gradlePluginPortal() maven("https://repo.papermc.io/repository/maven-public/") } + includeBuild("gradle/build-logic") } -rootProject.name = "slimeworldmanager" +rootProject.name = "ASPaper" -include("plugin", "core", "api", "importer") -include("slimeworldmanager-api", "slimeworldmanager-server") -include("loaders") +include(":gradle:platform") +include(":api") +include(":core") +include(":importer") +include(":loaders") +include(":plugin") +include(":aspaper-api") +include(":aspaper-server") From 83bb203f260eee10b1b1a0429bfff10b58d1a06f Mon Sep 17 00:00:00 2001 From: Philip Kelley Date: Mon, 16 Dec 2024 20:39:44 +0000 Subject: [PATCH 020/133] fix(conventions): call get on gradle property --- .../src/main/kotlin/asp.base-conventions.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/build-logic/src/main/kotlin/asp.base-conventions.gradle.kts b/gradle/build-logic/src/main/kotlin/asp.base-conventions.gradle.kts index 8f211a934..6eecf8740 100644 --- a/gradle/build-logic/src/main/kotlin/asp.base-conventions.gradle.kts +++ b/gradle/build-logic/src/main/kotlin/asp.base-conventions.gradle.kts @@ -3,8 +3,8 @@ plugins { id("com.gorylenko.gradle-git-properties") } -group = rootProject.providers.gradleProperty("group") -version = rootProject.providers.gradleProperty("apiVersion") +group = rootProject.providers.gradleProperty("group").get() +version = rootProject.providers.gradleProperty("apiVersion").get() java { toolchain { From c62213a89cd19f2ae51405d91e0d6fcff4d2f2b4 Mon Sep 17 00:00:00 2001 From: Philip Kelley Date: Mon, 16 Dec 2024 20:40:10 +0000 Subject: [PATCH 021/133] chore(plugin): rename to ASP --- plugin/src/main/resources/sources.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/src/main/resources/sources.yml b/plugin/src/main/resources/sources.yml index 0a9499065..c15b59514 100644 --- a/plugin/src/main/resources/sources.yml +++ b/plugin/src/main/resources/sources.yml @@ -1,5 +1,5 @@ # Inside this file is the configuration options -# for the data sources that SWM supports +# for the data sources that ASP supports mysql: enabled: false host: 127.0.0.1 From 49f2351d98d72316e8007cdd98b703545040ea79 Mon Sep 17 00:00:00 2001 From: Philip Kelley Date: Mon, 16 Dec 2024 20:48:09 +0000 Subject: [PATCH 022/133] chore(plugin): update plugin jar output name --- plugin/build.gradle.kts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts index fff5d7195..31e30b316 100644 --- a/plugin/build.gradle.kts +++ b/plugin/build.gradle.kts @@ -19,6 +19,10 @@ dependencies { } tasks { + withType { + archiveBaseName.set("asp-plugin") + } + shadowJar { relocate("org.bstats", "com.infernalsuite.asp.libs.bstats") relocate("org.spongepowered.configurate", "com.infernalsuite.asp.libs.configurate") From b7fd593a04f05f0e597bbf3c95751a32d74d9377 Mon Sep 17 00:00:00 2001 From: Philip Kelley Date: Fri, 20 Dec 2024 00:16:34 +0000 Subject: [PATCH 023/133] chore(*): restructuring round 2 - API/Core: FlowNBT -> AdventureNBT - Add slime property support for all NBT types - Start switch to java.nio, legacy support for java.io - Refactoring for future deprecation and cleanup --- api/build.gradle.kts | 1 - .../asp/api/AdvancedSlimePaperAPI.java | 1 - .../infernalsuite/asp/api/SlimeNMSBridge.java | 9 +- .../api/exceptions/InvalidWorldException.java | 18 +- .../asp/api/world/SlimeChunk.java | 24 +- .../asp/api/world/SlimeChunkSection.java | 6 +- .../asp/api/world/SlimeWorld.java | 23 +- .../asp/api/world/SlimeWorldInstance.java | 4 +- .../api/world/properties/SlimeProperties.java | 40 +- .../api/world/properties/SlimeProperty.java | 44 ++- .../world/properties/SlimePropertyMap.java | 62 +-- .../properties/type/SlimePropertyBoolean.java | 52 ++- .../properties/type/SlimePropertyByte.java | 47 +++ .../type/SlimePropertyByteArray.java | 48 +++ .../properties/type/SlimePropertyDouble.java | 46 +++ .../properties/type/SlimePropertyFloat.java | 53 ++- .../properties/type/SlimePropertyInt.java | 52 ++- .../type/SlimePropertyIntArray.java | 47 +++ .../properties/type/SlimePropertyList.java | 88 +++++ .../properties/type/SlimePropertyLong.java | 47 +++ .../type/SlimePropertyLongArray.java | 47 +++ .../properties/type/SlimePropertyShort.java | 47 +++ .../properties/type/SlimePropertyString.java | 53 ++- .../asp/pdc/AdventureDataTypeRegistry.java | 181 +++++++++ .../pdc/AdventurePersistentDataContainer.java | 188 +++++++++ .../asp/pdc/FlowDataTypeRegistry.java | 239 ------------ .../asp/pdc/FlowPersistentDataContainer.java | 174 --------- .../serialization/anvil/AnvilImportData.java | 8 +- .../serialization/anvil/AnvilWorldReader.java | 361 +++++++----------- .../asp/serialization/slime/ChunkPruner.java | 23 +- .../serialization/slime/SlimeSerializer.java | 76 ++-- .../impl/v12/v12SlimeWorldDeSerializer.java | 83 ++-- .../slime/reader/impl/v12/v12WorldFormat.java | 4 +- .../asp/skeleton/SkeletonCloning.java | 29 +- .../asp/skeleton/SkeletonSlimeWorld.java | 20 +- .../skeleton/SlimeChunkSectionSkeleton.java | 8 +- .../asp/skeleton/SlimeChunkSkeleton.java | 22 +- .../asp/importer/SWMImporter.java | 2 +- 38 files changed, 1347 insertions(+), 930 deletions(-) create mode 100644 api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyByte.java create mode 100644 api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyByteArray.java create mode 100644 api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyDouble.java create mode 100644 api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyIntArray.java create mode 100644 api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyList.java create mode 100644 api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyLong.java create mode 100644 api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyLongArray.java create mode 100644 api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyShort.java create mode 100644 core/src/main/java/com/infernalsuite/asp/pdc/AdventureDataTypeRegistry.java create mode 100644 core/src/main/java/com/infernalsuite/asp/pdc/AdventurePersistentDataContainer.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/pdc/FlowDataTypeRegistry.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/pdc/FlowPersistentDataContainer.java diff --git a/api/build.gradle.kts b/api/build.gradle.kts index 30ab1e918..0da106cd7 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -6,7 +6,6 @@ plugins { dependencies { api(libs.annotations) api(libs.adventure.nbt) - api("com.flowpowered:flow-nbt:2.0.2") compileOnly(paperApi()) } diff --git a/api/src/main/java/com/infernalsuite/asp/api/AdvancedSlimePaperAPI.java b/api/src/main/java/com/infernalsuite/asp/api/AdvancedSlimePaperAPI.java index 527b9d863..50441d0e7 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/AdvancedSlimePaperAPI.java +++ b/api/src/main/java/com/infernalsuite/asp/api/AdvancedSlimePaperAPI.java @@ -9,7 +9,6 @@ import com.infernalsuite.asp.api.exceptions.WorldTooBigException; import com.infernalsuite.asp.api.world.SlimeWorld; import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; -import com.infernalsuite.asp.api.exceptions.*; import com.infernalsuite.asp.api.loaders.SlimeLoader; import net.kyori.adventure.util.Services; import org.bukkit.World; diff --git a/api/src/main/java/com/infernalsuite/asp/api/SlimeNMSBridge.java b/api/src/main/java/com/infernalsuite/asp/api/SlimeNMSBridge.java index febdcf72e..e4f31574e 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/SlimeNMSBridge.java +++ b/api/src/main/java/com/infernalsuite/asp/api/SlimeNMSBridge.java @@ -1,9 +1,8 @@ package com.infernalsuite.asp.api; -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.CompoundTag; import com.infernalsuite.asp.api.world.SlimeWorld; import com.infernalsuite.asp.api.world.SlimeWorldInstance; +import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.util.Services; import org.bukkit.World; import org.bukkit.persistence.PersistentDataContainer; @@ -36,15 +35,15 @@ static SlimeNMSBridge instance() { return Holder.INSTANCE; } - void extractCraftPDC(PersistentDataContainer source, CompoundMap target); + void extractCraftPDC(PersistentDataContainer source, CompoundBinaryTag.Builder builder); - PersistentDataContainer extractCompoundMapIntoCraftPDC(CompoundMap source); + PersistentDataContainer extractCompoundMapIntoCraftPDC(CompoundBinaryTag source); @ApiStatus.Internal class Holder { private static final SlimeNMSBridge INSTANCE = Services.service(SlimeNMSBridge.class).orElseThrow(); } - CompoundTag convertChunkTo1_13(CompoundTag tag); + CompoundBinaryTag convertChunkTo1_13(CompoundBinaryTag tag); } diff --git a/api/src/main/java/com/infernalsuite/asp/api/exceptions/InvalidWorldException.java b/api/src/main/java/com/infernalsuite/asp/api/exceptions/InvalidWorldException.java index bac590354..a9d40f190 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/exceptions/InvalidWorldException.java +++ b/api/src/main/java/com/infernalsuite/asp/api/exceptions/InvalidWorldException.java @@ -1,6 +1,7 @@ package com.infernalsuite.asp.api.exceptions; import java.io.File; +import java.nio.file.Path; /** * Exception thrown when a folder does @@ -8,11 +9,20 @@ */ public class InvalidWorldException extends SlimeException { - public InvalidWorldException(File worldDir, String reason) { - super("Directory " + worldDir.getPath() + " does not contain a valid MC world! " + reason); + public InvalidWorldException(Path worldDir, String reason) { + super("Directory " + worldDir.toString() + " does not contain a valid MC world! " + reason); } - public InvalidWorldException(File worldDir) { - super("Directory " + worldDir.getPath() + " does not contain a valid MC world!"); + public InvalidWorldException(Path worldDir) { + super("Directory " + worldDir.toString() + " does not contain a valid MC world!"); } + + public static InvalidWorldException legacy(File worldDir, String reason) { + return new InvalidWorldException(worldDir.toPath(), reason); + } + + public static InvalidWorldException legacy(File worldDir) { + return new InvalidWorldException(worldDir.toPath()); + } + } diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunk.java b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunk.java index 253c7cd97..c422241f5 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunk.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunk.java @@ -1,6 +1,6 @@ package com.infernalsuite.asp.api.world; -import com.flowpowered.nbt.CompoundTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; import java.util.List; import javax.annotation.Nullable; @@ -36,42 +36,42 @@ public interface SlimeChunk { * a {@link com.flowpowered.nbt.IntArrayTag} containing the height * map will be stored inside here by the name of 'heightMap'. * - * @return A {@link CompoundTag} containing all the height maps of the chunk. + * @return A {@link CompoundBinaryTag} containing all the height maps of the chunk. */ - CompoundTag getHeightMaps(); + CompoundBinaryTag getHeightMaps(); /** * Returns all the tile entities of the chunk. * - * @return A {@link CompoundTag} containing all the tile entities of the chunk. + * @return A {@link CompoundBinaryTag} containing all the tile entities of the chunk. */ - List getTileEntities(); + List getTileEntities(); /** * Returns all the entities of the chunk. * - * @return A {@link CompoundTag} containing all the entities + * @return A {@link CompoundBinaryTag} containing all the entities */ - List getEntities(); + List getEntities(); /** * Returns the extra data of the chunk. - * Inside this {@link CompoundTag} + * Inside this {@link CompoundBinaryTag} * can be stored any information to then be retrieved later, as it's * saved alongside the chunk data. *
    * Beware, a compound tag under the key "ChunkBukkitValues" will be stored here. * It is used for storing chunk-based Bukkit PDC. Do not overwrite it. * - * @return A {@link CompoundTag} containing the extra data of the chunk, + * @return A {@link CompoundBinaryTag} containing the extra data of the chunk, */ - CompoundTag getExtraData(); + CompoundBinaryTag getExtraData(); /** * Upgrade data used to fix the chunks. * Not intended to be serialized. - * @return A {@link CompoundTag} containing the upgrade data of the chunk, + * @return A {@link CompoundBinaryTag} containing the upgrade data of the chunk, */ @Nullable - CompoundTag getUpgradeData(); + CompoundBinaryTag getUpgradeData(); } diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunkSection.java b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunkSection.java index 312bd2645..12dc93413 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunkSection.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunkSection.java @@ -1,7 +1,7 @@ package com.infernalsuite.asp.api.world; import com.infernalsuite.asp.api.utils.NibbleArray; -import com.flowpowered.nbt.CompoundTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; import org.jetbrains.annotations.Nullable; /** @@ -9,9 +9,9 @@ */ public interface SlimeChunkSection { - CompoundTag getBlockStatesTag(); + CompoundBinaryTag getBlockStatesTag(); - CompoundTag getBiomeTag(); + CompoundBinaryTag getBiomeTag(); /** * Returns the block light data. diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorld.java b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorld.java index 041dec9a9..0fce84fae 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorld.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorld.java @@ -1,13 +1,16 @@ package com.infernalsuite.asp.api.world; import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; -import com.flowpowered.nbt.CompoundTag; import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; import com.infernalsuite.asp.api.loaders.SlimeLoader; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; import org.bukkit.persistence.PersistentDataHolder; import java.io.IOException; import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentMap; /** * In-memory representation of a SRF world. @@ -42,21 +45,25 @@ public interface SlimeWorld extends PersistentDataHolder { Collection getChunkStorage(); /** - * Returns the extra data of the world. Inside this {@link CompoundTag} - * can be stored any information to then be retrieved later, as it's - * saved alongside the world data. + * Extra data to be stored alongside the world. * - * @return A {@link CompoundTag} containing the extra data of the world. + *

    Any information can be stored inside this map, it will be serialized into a {@link CompoundBinaryTag} + * and stored alongside the world data so it can then be retrieved later.

    + * + * @apiNote There is a maximum limit of 512 nested tags + * @implSpec The returned map must be an implementation of {@link ConcurrentMap} to avoid CMEs, etc. + * + * @return A Map containing the extra data of the world. */ - CompoundTag getExtraData(); + ConcurrentMap getExtraData(); /** * Returns a {@link Collection} with every world map, serialized - * in a {@link CompoundTag} object. + * in a {@link CompoundBinaryTag} object. * * @return A {@link Collection} containing every world map. */ - Collection getWorldMaps(); + Collection getWorldMaps(); /** * Returns the property map. diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java index 9b86a1265..123949599 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java @@ -1,7 +1,7 @@ package com.infernalsuite.asp.api.world; -import com.flowpowered.nbt.CompoundTag; import com.infernalsuite.asp.api.loaders.SlimeLoader; +import net.kyori.adventure.nbt.CompoundBinaryTag; import org.bukkit.World; public interface SlimeWorldInstance { @@ -18,6 +18,6 @@ public interface SlimeWorldInstance { SlimeLoader getLoader(); - CompoundTag getExtraData(); + CompoundBinaryTag getExtraData(); } diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperties.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperties.java index f5ef78955..d338f939f 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperties.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperties.java @@ -14,27 +14,27 @@ public class SlimeProperties { /** * The X coordinate of the world spawn */ - public static final SlimeProperty SPAWN_X = new SlimePropertyInt("spawnX", 0); + public static final SlimePropertyInt SPAWN_X = SlimePropertyInt.create("spawnX", 0); /** * The Y coordinate of the world spawn */ - public static final SlimeProperty SPAWN_Y = new SlimePropertyInt("spawnY", 255); + public static final SlimePropertyInt SPAWN_Y = SlimePropertyInt.create("spawnY", 255); /** * The Z coordinate of the world spawn */ - public static final SlimeProperty SPAWN_Z = new SlimePropertyInt("spawnZ", 0); + public static final SlimePropertyInt SPAWN_Z = SlimePropertyInt.create("spawnZ", 0); /** * The yaw of the world spawn */ - public static final SlimeProperty SPAWN_YAW = new SlimePropertyFloat("spawnYaw", 0.0f); + public static final SlimePropertyFloat SPAWN_YAW = SlimePropertyFloat.create("spawnYaw", 0.0f); /** * The difficulty set for the world */ - public static final SlimeProperty DIFFICULTY = new SlimePropertyString("difficulty", "peaceful", (value) -> + public static final SlimePropertyString DIFFICULTY = SlimePropertyString.create("difficulty", "peaceful", (value) -> value.equalsIgnoreCase("peaceful") || value.equalsIgnoreCase("easy") || value.equalsIgnoreCase("normal") || value.equalsIgnoreCase("hard") ); @@ -42,34 +42,34 @@ public class SlimeProperties { /** * Whether monsters are allowed to spawn at night or in the dark */ - public static final SlimeProperty ALLOW_MONSTERS = new SlimePropertyBoolean("allowMonsters", true); + public static final SlimePropertyBoolean ALLOW_MONSTERS = SlimePropertyBoolean.create("allowMonsters", true); /** * Whether peaceful animals are allowed to spawn */ - public static final SlimeProperty ALLOW_ANIMALS = new SlimePropertyBoolean("allowAnimals", true); + public static final SlimePropertyBoolean ALLOW_ANIMALS = SlimePropertyBoolean.create("allowAnimals", true); /** * Whether the dragon battle should be enabled in end worlds */ - public static final SlimeProperty DRAGON_BATTLE = new SlimePropertyBoolean("dragonBattle", false); + public static final SlimePropertyBoolean DRAGON_BATTLE = SlimePropertyBoolean.create("dragonBattle", false); /** * Whether PVP combat is allowed */ - public static final SlimeProperty PVP = new SlimePropertyBoolean("pvp", true); + public static final SlimePropertyBoolean PVP = SlimePropertyBoolean.create("pvp", true); /** * The environment of the world */ - public static final SlimeProperty ENVIRONMENT = new SlimePropertyString("environment", "normal", (value) -> + public static final SlimePropertyString ENVIRONMENT = SlimePropertyString.create("environment", "normal", (value) -> value.equalsIgnoreCase("normal") || value.equalsIgnoreCase("nether") || value.equalsIgnoreCase("the_end") ); /** * The type of world */ - public static final SlimeProperty WORLD_TYPE = new SlimePropertyString("worldtype", "default", (value) -> + public static final SlimePropertyString WORLD_TYPE = SlimePropertyString.create("worldtype", "default", (value) -> value.equalsIgnoreCase("default") || value.equalsIgnoreCase("flat") || value.equalsIgnoreCase("large_biomes") || value.equalsIgnoreCase("amplified") || value.equalsIgnoreCase("customized") || value.equalsIgnoreCase("debug_all_block_states") || value.equalsIgnoreCase("default_1_1") @@ -78,32 +78,32 @@ public class SlimeProperties { /** * The default biome generated in empty chunks */ - public static final SlimeProperty DEFAULT_BIOME = new SlimePropertyString("defaultBiome", "minecraft:plains"); + public static final SlimePropertyString DEFAULT_BIOME = SlimePropertyString.create("defaultBiome", "minecraft:plains"); @ApiStatus.Experimental - public static final SlimeProperty SHOULD_LIMIT_SAVE = new SlimePropertyBoolean("hasSaveBounds", false); + public static final SlimePropertyBoolean SHOULD_LIMIT_SAVE = SlimePropertyBoolean.create("hasSaveBounds", false); @ApiStatus.Experimental - public static final SlimeProperty SAVE_MIN_X = new SlimePropertyInt("saveMinX", 0); + public static final SlimePropertyInt SAVE_MIN_X = SlimePropertyInt.create("saveMinX", 0); @ApiStatus.Experimental - public static final SlimeProperty SAVE_MIN_Z = new SlimePropertyInt("saveMinZ", 0); + public static final SlimePropertyInt SAVE_MIN_Z = SlimePropertyInt.create("saveMinZ", 0); @ApiStatus.Experimental - public static final SlimeProperty SAVE_MAX_X = new SlimePropertyInt("saveMaxX", 0); + public static final SlimePropertyInt SAVE_MAX_X = SlimePropertyInt.create("saveMaxX", 0); @ApiStatus.Experimental - public static final SlimeProperty SAVE_MAX_Z = new SlimePropertyInt("saveMaxZ", 0); + public static final SlimePropertyInt SAVE_MAX_Z = SlimePropertyInt.create("saveMaxZ", 0); @ApiStatus.Experimental - public static final SlimeProperty CHUNK_PRUNING = new SlimePropertyString("pruning", "aggressive", (value) -> + public static final SlimePropertyString CHUNK_PRUNING = SlimePropertyString.create("pruning", "aggressive", (value) -> value.equalsIgnoreCase("aggressive") || value.equalsIgnoreCase("never") ); @ApiStatus.Experimental - public static final SlimeProperty CHUNK_SECTION_MIN = new SlimePropertyInt("chunkSectionMin", -4); + public static final SlimePropertyInt CHUNK_SECTION_MIN = SlimePropertyInt.create("chunkSectionMin", -4); @ApiStatus.Experimental - public static final SlimeProperty CHUNK_SECTION_MAX = new SlimePropertyInt("chunkSectionMin", 19); + public static final SlimePropertyInt CHUNK_SECTION_MAX = SlimePropertyInt.create("chunkSectionMin", 19); } diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperty.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperty.java index 58f576470..e3c47b5c1 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperty.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperty.java @@ -1,55 +1,61 @@ package com.infernalsuite.asp.api.world.properties; -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.Tag; +import net.kyori.adventure.nbt.BinaryTag; import java.util.function.Function; /** * A property describing behavior of a slime world. */ -public abstract class SlimeProperty { +public abstract class SlimeProperty { - private final String nbtName; + private final String key; private final T defaultValue; private final Function validator; - protected SlimeProperty(String nbtName, T defaultValue) { - this(nbtName, defaultValue, null); + protected SlimeProperty(String key, T defaultValue) { + this(key, defaultValue, null); } - protected SlimeProperty(String nbtName, T defaultValue, Function validator) { - this.nbtName = nbtName; + protected SlimeProperty(String key, T defaultValue, Function validator) { + this.key = key; if (defaultValue != null && validator != null && !validator.apply(defaultValue)) { - throw new IllegalArgumentException("Invalid default value for property " + nbtName + "! " + defaultValue); + throw new IllegalArgumentException("Invalid default value for property " + key + "! " + defaultValue); } this.defaultValue = defaultValue; this.validator = validator; } - protected abstract void writeValue(CompoundMap compound, T value); + protected abstract Z createTag(T value); - protected abstract T readValue(Tag compoundTag); + protected abstract T readValue(Z tag); - public String getNbtName() { - return nbtName; + protected abstract Z cast(BinaryTag rawTag); + + public final boolean applyValidator(T value) { + return this.validator != null && this.validator.apply(value); + } + + public final String getKey() { + return this.key; } - public T getDefaultValue() { - return defaultValue; + public final T getDefaultValue() { + return this.defaultValue; } - public Function getValidator() { - return validator; + public final Function getValidator() { + return this.validator; } @Override - public String toString() { + public final String toString() { return "SlimeProperty{" + - "nbtName='" + nbtName + '\'' + + "key='" + key + '\'' + ", defaultValue=" + defaultValue + '}'; } + } diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimePropertyMap.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimePropertyMap.java index 706ec33e2..1c687ee3f 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimePropertyMap.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimePropertyMap.java @@ -1,21 +1,24 @@ package com.infernalsuite.asp.api.world.properties; -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.CompoundTag; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; + +import java.util.HashMap; +import java.util.Map; /** * A Property Map object. */ public class SlimePropertyMap { - private final CompoundMap properties; + private final Map properties; - public SlimePropertyMap(CompoundMap compoundMap) { - this.properties = compoundMap; + public SlimePropertyMap() { + this(new HashMap<>()); } - public SlimePropertyMap() { - this(new CompoundMap()); + public SlimePropertyMap(final Map properties) { + this.properties = properties; } /** @@ -24,9 +27,9 @@ public SlimePropertyMap() { * @param property The slime property * @return The current value */ - public T getValue(SlimeProperty property) { - if (properties.containsKey(property.getNbtName())) { - return property.readValue(properties.get(property.getNbtName())); + public T getValue(final SlimeProperty property) { + if (this.properties.containsKey(property.getKey())) { + return property.readValue(property.cast(this.properties.get(property.getKey()))); } else { return property.getDefaultValue(); } @@ -37,7 +40,7 @@ public T getValue(SlimeProperty property) { * * @return The properties */ - public CompoundMap getProperties() { + public Map getProperties() { return this.properties; } @@ -48,44 +51,45 @@ public CompoundMap getProperties() { * @param value The new value * @throws IllegalArgumentException if the value fails validation. */ - public void setValue(SlimeProperty property, T value) { - if (property.getValidator() != null && !property.getValidator().apply(value)) { - throw new IllegalArgumentException("'" + value + "' is not a valid property value."); - } - - property.writeValue(properties, value); + public void setValue(final SlimeProperty property, final T value) { + if (!property.applyValidator(value)) throw new IllegalArgumentException("'%s' is not a valid property value.".formatted(value)); + this.properties.put(property.getKey(), property.createTag(value)); } /** * Copies all values from the specified {@link SlimePropertyMap}. * If the same property has different values on both maps, the one - * on the providen map will be used. + * on the provided map will be used. * - * @param propertyMap A {@link SlimePropertyMap}. + * @param other A {@link SlimePropertyMap}. */ - public void merge(SlimePropertyMap propertyMap) { - properties.putAll(propertyMap.properties); + public void merge(final SlimePropertyMap other) { + this.properties.putAll(other.properties); } /** - * Returns a {@link CompoundTag} containing every property set in this map. + * Returns a {@link CompoundBinaryTag} containing every property set in this map. * - * @return A {@link CompoundTag} with all the properties stored in this map. + * @return A {@link CompoundBinaryTag} with all the properties stored in this map. */ - public CompoundTag toCompound() { - return new CompoundTag("properties", properties); + public CompoundBinaryTag toCompound() { + return CompoundBinaryTag.builder().put(this.properties).build(); } - public static SlimePropertyMap fromCompound(CompoundTag compound) { - return new SlimePropertyMap(compound.getValue()); + public static SlimePropertyMap fromCompound(final CompoundBinaryTag tag) { + final Map tags = new HashMap<>(tag.size()); + tag.forEach(entry -> tags.put(entry.getKey(), entry.getValue())); + return new SlimePropertyMap(tags); } + @SuppressWarnings("MethodDoesntCallSuperMethod") public SlimePropertyMap clone() { - return new SlimePropertyMap(new CompoundMap(this.properties)); + return new SlimePropertyMap(new HashMap<>(this.properties)); } @Override public String toString() { - return "SlimePropertyMap" + properties; + return "SlimePropertyMap{" + properties + '}'; } + } diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyBoolean.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyBoolean.java index aae436462..c32f5af3e 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyBoolean.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyBoolean.java @@ -1,33 +1,57 @@ package com.infernalsuite.asp.api.world.properties.type; -import com.flowpowered.nbt.ByteTag; -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.Tag; +import com.google.common.base.Preconditions; +import com.infernalsuite.asp.api.world.properties.SlimeProperty; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.ByteBinaryTag; +import org.jetbrains.annotations.NotNull; import java.util.function.Function; /** * A slime property of type boolean */ -public class SlimePropertyBoolean extends com.infernalsuite.asp.api.world.properties.SlimeProperty { +public class SlimePropertyBoolean extends SlimeProperty { - public SlimePropertyBoolean(String nbtName, Boolean defaultValue) { - super(nbtName, defaultValue); + public static SlimePropertyBoolean create(final @NotNull String key, final boolean defaultValue) { + Preconditions.checkNotNull(key, "Key cannot be null"); + return new SlimePropertyBoolean(key, defaultValue); } - public SlimePropertyBoolean(String nbtName, Boolean defaultValue, Function validator) { - super(nbtName, defaultValue, validator); + public static SlimePropertyBoolean create(final @NotNull String key, final boolean defaultValue, final @NotNull Function validator) { + Preconditions.checkNotNull(key, "Key cannot be null"); + Preconditions.checkNotNull(validator, "Use SlimePropertyBoolean#create(String, boolean) instead"); + return new SlimePropertyBoolean(key, defaultValue, validator); + } + + /** + * @deprecated Use {@link #create(String, boolean)} instead + */ + @Deprecated(forRemoval = true) + public SlimePropertyBoolean(String key, Boolean defaultValue) { + super(key, defaultValue); + } + + /** + * @deprecated Use {@link #create(String, boolean, Function)} instead + */ + @Deprecated(forRemoval = true) + public SlimePropertyBoolean(String key, Boolean defaultValue, Function validator) { + super(key, defaultValue, validator); + } + + @Override + protected ByteBinaryTag createTag(final Boolean value) { + return value ? ByteBinaryTag.ONE : ByteBinaryTag.ZERO; } @Override - protected void writeValue(CompoundMap compound, Boolean value) { - compound.put(getNbtName(), new ByteTag(getNbtName(), (byte) (value ? 1 : 0))); + protected Boolean readValue(final ByteBinaryTag tag) { + return tag.value() == 1; } @Override - protected Boolean readValue(Tag compoundTag) { - return compoundTag.getAsByteTag() - .map((value) -> value.getValue() == 1) - .orElse(getDefaultValue()); + protected ByteBinaryTag cast(BinaryTag rawTag) { + return (ByteBinaryTag) rawTag; } } diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyByte.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyByte.java new file mode 100644 index 000000000..3640ee00e --- /dev/null +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyByte.java @@ -0,0 +1,47 @@ +package com.infernalsuite.asp.api.world.properties.type; + +import com.google.common.base.Preconditions; +import com.infernalsuite.asp.api.world.properties.SlimeProperty; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.ByteBinaryTag; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Function; + +public class SlimePropertyByte extends SlimeProperty { + + public static SlimePropertyByte create(final @NotNull String key, final byte defaultValue) { + Preconditions.checkNotNull(key, "Key cannot be null"); + return new SlimePropertyByte(key, defaultValue); + } + + public static SlimePropertyByte create(final @NotNull String key, final byte defaultValue, final @NotNull Function validator) { + Preconditions.checkNotNull(key, "Key cannot be null"); + Preconditions.checkNotNull(validator, "Use SlimePropertyByte#create(String, byte) instead"); + return new SlimePropertyByte(key, defaultValue, validator); + } + + private SlimePropertyByte(String key, Byte defaultValue) { + super(key, defaultValue); + } + + private SlimePropertyByte(String key, Byte defaultValue, Function validator) { + super(key, defaultValue, validator); + } + + @Override + protected ByteBinaryTag createTag(final Byte value) { + return ByteBinaryTag.byteBinaryTag(value); + } + + @Override + protected Byte readValue(final ByteBinaryTag tag) { + return tag.value(); + } + + @Override + protected ByteBinaryTag cast(BinaryTag rawTag) { + return (ByteBinaryTag) rawTag; + } + +} diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyByteArray.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyByteArray.java new file mode 100644 index 000000000..1f71d53f4 --- /dev/null +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyByteArray.java @@ -0,0 +1,48 @@ +package com.infernalsuite.asp.api.world.properties.type; + +import com.google.common.base.Preconditions; +import com.infernalsuite.asp.api.world.properties.SlimeProperty; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.ByteArrayBinaryTag; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Function; + +public class SlimePropertyByteArray extends SlimeProperty { + + public static SlimePropertyByteArray create(final @NotNull String key, final byte[] defaultValue) { + Preconditions.checkNotNull(key, "Key cannot be null"); + return new SlimePropertyByteArray(key, defaultValue); + } + + public static SlimePropertyByteArray create(final @NotNull String key, final byte[] defaultValue, final @NotNull Function validator) { + Preconditions.checkNotNull(key, "Key cannot be null"); + Preconditions.checkNotNull(validator, "Use SlimePropertyByteArray#create(String, byte[]) instead"); + return new SlimePropertyByteArray(key, defaultValue, validator); + } + + private SlimePropertyByteArray(String key, byte[] defaultValue) { + super(key, defaultValue); + } + + private SlimePropertyByteArray(String key, byte[] defaultValue, Function validator) { + super(key, defaultValue, validator); + } + + @Override + protected ByteArrayBinaryTag createTag(final byte[] value) { + return ByteArrayBinaryTag.byteArrayBinaryTag(value); + } + + @Override + protected byte[] readValue(final ByteArrayBinaryTag tag) { + return tag.value(); + } + + @Override + protected ByteArrayBinaryTag cast(BinaryTag rawTag) { + return (ByteArrayBinaryTag) rawTag; + } + +} + diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyDouble.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyDouble.java new file mode 100644 index 000000000..ade361759 --- /dev/null +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyDouble.java @@ -0,0 +1,46 @@ +package com.infernalsuite.asp.api.world.properties.type; + +import com.google.common.base.Preconditions; +import com.infernalsuite.asp.api.world.properties.SlimeProperty; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.DoubleBinaryTag; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Function; + +public class SlimePropertyDouble extends SlimeProperty { + + public static SlimePropertyDouble create(final @NotNull String key, final double defaultValue) { + Preconditions.checkNotNull(key, "Key cannot be null"); + return new SlimePropertyDouble(key, defaultValue); + } + + public static SlimePropertyDouble create(final @NotNull String key, final double defaultValue, final @NotNull Function validator) { + Preconditions.checkNotNull(key, "Key cannot be null"); + Preconditions.checkNotNull(validator, "Use SlimePropertyDouble#create(String, double) instead"); + return new SlimePropertyDouble(key, defaultValue, validator); + } + + private SlimePropertyDouble(String key, Double defaultValue) { + super(key, defaultValue); + } + + private SlimePropertyDouble(String key, Double defaultValue, Function validator) { + super(key, defaultValue, validator); + } + + @Override + protected DoubleBinaryTag createTag(final Double value) { + return DoubleBinaryTag.doubleBinaryTag(value); + } + + @Override + protected Double readValue(final DoubleBinaryTag tag) { + return tag.value(); + } + + @Override + protected DoubleBinaryTag cast(BinaryTag rawTag) { + return (DoubleBinaryTag) rawTag; + } +} diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyFloat.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyFloat.java index ff47a20ac..239ff0c5e 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyFloat.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyFloat.java @@ -1,33 +1,58 @@ package com.infernalsuite.asp.api.world.properties.type; -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.FloatTag; -import com.flowpowered.nbt.Tag; +import com.google.common.base.Preconditions; +import com.infernalsuite.asp.api.world.properties.SlimeProperty; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.FloatBinaryTag; +import org.jetbrains.annotations.NotNull; import java.util.function.Function; /** * A slime property of type float */ -public class SlimePropertyFloat extends com.infernalsuite.asp.api.world.properties.SlimeProperty { +public class SlimePropertyFloat extends SlimeProperty { - public SlimePropertyFloat(String nbtName, Float defaultValue, Function validator) { - super(nbtName, defaultValue, validator); + public static SlimePropertyFloat create(final @NotNull String key, final float defaultValue) { + Preconditions.checkNotNull(key, "Key cannot be null"); + return new SlimePropertyFloat(key, defaultValue); } - public SlimePropertyFloat(String nbtName, Float defaultValue) { - super(nbtName, defaultValue); + public static SlimePropertyFloat create(final @NotNull String key, final float defaultValue, final @NotNull Function validator) { + Preconditions.checkNotNull(key, "Key cannot be null"); + Preconditions.checkNotNull(validator, "Use SlimePropertyFloat#create(String, float) instead"); + return new SlimePropertyFloat(key, defaultValue, validator); + } + + /** + * @deprecated use {@link #create(String, float)} instead + */ + @Deprecated(forRemoval = true) + public SlimePropertyFloat(String key, Float defaultValue) { + super(key, defaultValue); + } + + /** + * @deprecated use {@link #create(String, float, Function)} instead + */ + @Deprecated(forRemoval = true) + public SlimePropertyFloat(String key, Float defaultValue, Function validator) { + super(key, defaultValue, validator); } @Override - protected void writeValue(CompoundMap compound, Float value) { - compound.put(getNbtName(), new FloatTag(getNbtName(), value)); + protected FloatBinaryTag createTag(final Float value) { + return FloatBinaryTag.floatBinaryTag(value); } @Override - protected Float readValue(Tag compoundTag) { - return compoundTag.getAsFloatTag() - .map(Tag::getValue) - .orElse(getDefaultValue()); + protected Float readValue(final FloatBinaryTag tag) { + return tag.value(); } + + @Override + protected FloatBinaryTag cast(BinaryTag rawTag) { + return (FloatBinaryTag) rawTag; + } + } diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyInt.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyInt.java index 2bb497b03..4d13026f4 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyInt.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyInt.java @@ -1,34 +1,58 @@ package com.infernalsuite.asp.api.world.properties.type; +import com.google.common.base.Preconditions; import com.infernalsuite.asp.api.world.properties.SlimeProperty; -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.IntTag; -import com.flowpowered.nbt.Tag; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.IntBinaryTag; +import org.jetbrains.annotations.NotNull; import java.util.function.Function; /** * A slime property of type integer */ -public class SlimePropertyInt extends SlimeProperty { +public class SlimePropertyInt extends SlimeProperty { - public SlimePropertyInt(String nbtName, Integer defaultValue) { - super(nbtName, defaultValue); + public static SlimePropertyInt create(final @NotNull String key, final int defaultValue) { + Preconditions.checkNotNull(key, "Key cannot be null"); + return new SlimePropertyInt(key, defaultValue); } - public SlimePropertyInt(String nbtName, Integer defaultValue, Function validator) { - super(nbtName, defaultValue, validator); + public static SlimePropertyInt create(final @NotNull String key, final int defaultValue, final @NotNull Function validator) { + Preconditions.checkNotNull(key, "Key cannot be null"); + Preconditions.checkNotNull(validator, "Use SlimePropertyInt#create(String, int) instead"); + return new SlimePropertyInt(key, defaultValue, validator); + } + + /** + * @deprecated Use {@link #create(String, int)} instead + */ + @Deprecated(forRemoval = true) + public SlimePropertyInt(String key, Integer defaultValue) { + super(key, defaultValue); + } + + /** + * @deprecated Use {@link #create(String, int, Function)} instead + */ + @Deprecated(forRemoval = true) + public SlimePropertyInt(String key, Integer defaultValue, Function validator) { + super(key, defaultValue, validator); } @Override - protected void writeValue(CompoundMap compound, Integer value) { - compound.put(getNbtName(), new IntTag(getNbtName(), value)); + protected IntBinaryTag createTag(final Integer value) { + return IntBinaryTag.intBinaryTag(value); } @Override - protected Integer readValue(Tag compoundTag) { - return compoundTag.getAsIntTag() - .map(Tag::getValue) - .orElse(getDefaultValue()); + protected Integer readValue(final IntBinaryTag tag) { + return tag.value(); } + + @Override + protected IntBinaryTag cast(BinaryTag rawTag) { + return (IntBinaryTag) rawTag; + } + } diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyIntArray.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyIntArray.java new file mode 100644 index 000000000..e74cb6aa3 --- /dev/null +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyIntArray.java @@ -0,0 +1,47 @@ +package com.infernalsuite.asp.api.world.properties.type; + +import com.google.common.base.Preconditions; +import com.infernalsuite.asp.api.world.properties.SlimeProperty; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.IntArrayBinaryTag; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Function; + +public class SlimePropertyIntArray extends SlimeProperty { + + public static SlimePropertyIntArray create(final @NotNull String key, final int[] defaultValue) { + Preconditions.checkNotNull(key, "Key cannot be null"); + return new SlimePropertyIntArray(key, defaultValue); + } + + public static SlimePropertyIntArray create(final @NotNull String key, final int[] defaultValue, final @NotNull Function validator) { + Preconditions.checkNotNull(key, "Key cannot be null"); + Preconditions.checkNotNull(validator, "Use SlimePropertyIntArray#create(String, int[]) instead"); + return new SlimePropertyIntArray(key, defaultValue, validator); + } + + private SlimePropertyIntArray(String key, int[] defaultValue) { + super(key, defaultValue); + } + + private SlimePropertyIntArray(String key, int[] defaultValue, Function validator) { + super(key, defaultValue, validator); + } + + @Override + protected IntArrayBinaryTag createTag(final int[] value) { + return IntArrayBinaryTag.intArrayBinaryTag(value); + } + + @Override + protected int[] readValue(final IntArrayBinaryTag tag) { + return tag.value(); + } + + @Override + protected IntArrayBinaryTag cast(BinaryTag rawTag) { + return (IntArrayBinaryTag) rawTag; + } + +} diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyList.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyList.java new file mode 100644 index 000000000..02931bf4b --- /dev/null +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyList.java @@ -0,0 +1,88 @@ +package com.infernalsuite.asp.api.world.properties.type; + +import com.google.common.base.Preconditions; +import com.infernalsuite.asp.api.world.properties.SlimeProperty; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.BinaryTagType; +import net.kyori.adventure.nbt.ListBinaryTag; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.function.Function; + +public class SlimePropertyList extends SlimeProperty, ListBinaryTag> { + + public static SlimePropertyList create( + final @NotNull String key, + final @NotNull List defaultValue, + final @NotNull BinaryTagType listTagElementType, + final @NotNull Function elementTagConverter, + final @NotNull Function elementTagExtractor + ) { + Preconditions.checkNotNull(key, "Key cannot be null"); + Preconditions.checkNotNull(defaultValue, "Default value cannot be null"); + Preconditions.checkNotNull(listTagElementType, "List tag element type cannot be null"); + Preconditions.checkNotNull(elementTagConverter, "Element tag converter cannot be null"); + Preconditions.checkNotNull(elementTagExtractor, "Element tag extractor cannot be null"); + return new SlimePropertyList<>(key, defaultValue, listTagElementType, elementTagConverter, elementTagExtractor); + } + + public static SlimePropertyList create( + final @NotNull String key, + final @NotNull List defaultValue, + final @NotNull Function, Boolean> validator, + final @NotNull BinaryTagType listTagElementType, + final @NotNull Function elementTagConverter, + final @NotNull Function elementTagExtractor + ) { + Preconditions.checkNotNull(key, "Key cannot be null"); + Preconditions.checkNotNull(defaultValue, "Default value cannot be null"); + Preconditions.checkNotNull(validator, "Use SlimePropertyList#create(String, List) instead"); + Preconditions.checkNotNull(listTagElementType, "List tag element type cannot be null"); + Preconditions.checkNotNull(elementTagConverter, "Element tag converter cannot be null"); + Preconditions.checkNotNull(elementTagExtractor, "Element tag extractor cannot be null"); + return new SlimePropertyList<>(key, defaultValue, validator, listTagElementType, elementTagConverter, elementTagExtractor); + } + + private final BinaryTagType listTagElementType; + private final Function elementTagConverter; + private final Function elementTagExtractor; + + private SlimePropertyList(String key, List defaultValue, BinaryTagType listTagElementType, Function elementTagConverter, Function elementTagExtractor) { + super(key, defaultValue); + this.listTagElementType = listTagElementType; + this.elementTagConverter = elementTagConverter; + this.elementTagExtractor = elementTagExtractor; + } + + private SlimePropertyList(String key, List defaultValue, Function, Boolean> validator, BinaryTagType listTagElementType, Function elementTagConverter, Function elementTagExtractor) { + super(key, defaultValue, validator); + this.listTagElementType = listTagElementType; + this.elementTagConverter = elementTagConverter; + this.elementTagExtractor = elementTagExtractor; + } + + @SuppressWarnings("unchecked") + @Override + protected ListBinaryTag createTag(final List value) { + return ListBinaryTag.listBinaryTag(this.listTagElementType, (List) value.stream() + .map(this.elementTagConverter) + .toList() + ); + } + + @SuppressWarnings("unchecked") + @Override + protected List readValue(final ListBinaryTag tag) { + return tag.stream() + .map(rawTag -> (Z) rawTag) + .map(this.elementTagExtractor) + .toList(); + } + + @Override + protected ListBinaryTag cast(final BinaryTag rawTag) { + return (ListBinaryTag) rawTag; + } + +} diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyLong.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyLong.java new file mode 100644 index 000000000..31e0a1502 --- /dev/null +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyLong.java @@ -0,0 +1,47 @@ +package com.infernalsuite.asp.api.world.properties.type; + +import com.google.common.base.Preconditions; +import com.infernalsuite.asp.api.world.properties.SlimeProperty; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.LongBinaryTag; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Function; + +public class SlimePropertyLong extends SlimeProperty { + + public static SlimePropertyLong create(final @NotNull String key, final long defaultValue) { + Preconditions.checkNotNull(key, "Key cannot be null"); + return new SlimePropertyLong(key, defaultValue); + } + + public static SlimePropertyLong create(final @NotNull String key, final long defaultValue, final @NotNull Function validator) { + Preconditions.checkNotNull(key, "Key cannot be null"); + Preconditions.checkNotNull(validator, "Use SlimePropertyLong#create(String, long) instead"); + return new SlimePropertyLong(key, defaultValue, validator); + } + + private SlimePropertyLong(String key, Long defaultValue) { + super(key, defaultValue); + } + + private SlimePropertyLong(String key, Long defaultValue, Function validator) { + super(key, defaultValue, validator); + } + + @Override + protected LongBinaryTag createTag(final Long value) { + return LongBinaryTag.longBinaryTag(value); + } + + @Override + protected Long readValue(final LongBinaryTag tag) { + return tag.value(); + } + + @Override + protected LongBinaryTag cast(BinaryTag rawTag) { + return (LongBinaryTag) rawTag; + } + +} diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyLongArray.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyLongArray.java new file mode 100644 index 000000000..46a9be665 --- /dev/null +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyLongArray.java @@ -0,0 +1,47 @@ +package com.infernalsuite.asp.api.world.properties.type; + +import com.google.common.base.Preconditions; +import com.infernalsuite.asp.api.world.properties.SlimeProperty; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.LongArrayBinaryTag; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Function; + +public class SlimePropertyLongArray extends SlimeProperty { + + public static SlimePropertyLongArray create(final @NotNull String key, final long[] defaultValue) { + Preconditions.checkNotNull(key, "Key cannot be null"); + return new SlimePropertyLongArray(key, defaultValue); + } + + public static SlimePropertyLongArray create(final @NotNull String key, final long[] defaultValue, final @NotNull Function validator) { + Preconditions.checkNotNull(key, "Key cannot be null"); + Preconditions.checkNotNull(validator, "Use SlimePropertyLongArray#create(String, long[]) instead"); + return new SlimePropertyLongArray(key, defaultValue, validator); + } + + private SlimePropertyLongArray(String key, long[] defaultValue) { + super(key, defaultValue); + } + + private SlimePropertyLongArray(String key, long[] defaultValue, Function validator) { + super(key, defaultValue, validator); + } + + @Override + protected LongArrayBinaryTag createTag(final long[] value) { + return LongArrayBinaryTag.longArrayBinaryTag(value); + } + + @Override + protected long[] readValue(final LongArrayBinaryTag tag) { + return tag.value(); + } + + @Override + protected LongArrayBinaryTag cast(BinaryTag rawTag) { + return (LongArrayBinaryTag) rawTag; + } + +} diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyShort.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyShort.java new file mode 100644 index 000000000..f34184488 --- /dev/null +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyShort.java @@ -0,0 +1,47 @@ +package com.infernalsuite.asp.api.world.properties.type; + +import com.google.common.base.Preconditions; +import com.infernalsuite.asp.api.world.properties.SlimeProperty; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.ShortBinaryTag; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Function; + +public class SlimePropertyShort extends SlimeProperty { + + public static SlimePropertyShort create(final @NotNull String key, final short defaultValue) { + Preconditions.checkNotNull(key, "Key cannot be null"); + return new SlimePropertyShort(key, defaultValue); + } + + public static SlimePropertyShort create(final @NotNull String key, final short defaultValue, final @NotNull Function validator) { + Preconditions.checkNotNull(key, "Key cannot be null"); + Preconditions.checkNotNull(validator, "Use SlimePropertyShort#create(String, short) instead"); + return new SlimePropertyShort(key, defaultValue, validator); + } + + private SlimePropertyShort(String key, Short defaultValue) { + super(key, defaultValue); + } + + private SlimePropertyShort(String key, Short defaultValue, Function validator) { + super(key, defaultValue, validator); + } + + @Override + protected ShortBinaryTag createTag(final Short value) { + return ShortBinaryTag.shortBinaryTag(value); + } + + @Override + protected Short readValue(final ShortBinaryTag tag) { + return tag.value(); + } + + @Override + protected ShortBinaryTag cast(BinaryTag rawTag) { + return (ShortBinaryTag) rawTag; + } + +} diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyString.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyString.java index a446ea67d..fccfeae9d 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyString.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyString.java @@ -1,33 +1,58 @@ package com.infernalsuite.asp.api.world.properties.type; -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.StringTag; -import com.flowpowered.nbt.Tag; +import com.google.common.base.Preconditions; +import com.infernalsuite.asp.api.world.properties.SlimeProperty; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.StringBinaryTag; +import org.jetbrains.annotations.NotNull; import java.util.function.Function; /** * A slime property of type integer */ -public class SlimePropertyString extends com.infernalsuite.asp.api.world.properties.SlimeProperty { +public class SlimePropertyString extends SlimeProperty { - public SlimePropertyString(String nbtName, String defaultValue) { - super(nbtName, defaultValue); + public static SlimePropertyString create(final @NotNull String key, final String defaultValue) { + Preconditions.checkNotNull(key, "Key cannot be null"); + return new SlimePropertyString(key, defaultValue); } - public SlimePropertyString(String nbtName, String defaultValue, Function validator) { - super(nbtName, defaultValue, validator); + public static SlimePropertyString create(final @NotNull String key, final String defaultValue, final @NotNull Function validator) { + Preconditions.checkNotNull(key, "Key cannot be null"); + Preconditions.checkNotNull(validator, "Use SlimePropertyString#create(String, String) instead"); + return new SlimePropertyString(key, defaultValue, validator); + } + + /** + * @deprecated Use {@link #create(String, String)} instead + */ + @Deprecated(forRemoval = true) + public SlimePropertyString(String key, String defaultValue) { + super(key, defaultValue); + } + + /** + * @deprecated Use {@link #create(String, String, Function)} instead + */ + @Deprecated(forRemoval = true) + public SlimePropertyString(String key, String defaultValue, Function validator) { + super(key, defaultValue, validator); } @Override - protected void writeValue(CompoundMap compound, String value) { - compound.put(getNbtName(), new StringTag(getNbtName(), value)); + protected StringBinaryTag createTag(final String value) { + return StringBinaryTag.stringBinaryTag(value); } @Override - protected String readValue(Tag compoundTag) { - return compoundTag.getAsStringTag() - .map(Tag::getValue) - .orElse(getDefaultValue()); + protected String readValue(final StringBinaryTag tag) { + return tag.value(); } + + @Override + protected StringBinaryTag cast(BinaryTag rawTag) { + return (StringBinaryTag) rawTag; + } + } diff --git a/core/src/main/java/com/infernalsuite/asp/pdc/AdventureDataTypeRegistry.java b/core/src/main/java/com/infernalsuite/asp/pdc/AdventureDataTypeRegistry.java new file mode 100644 index 000000000..fa1622199 --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/pdc/AdventureDataTypeRegistry.java @@ -0,0 +1,181 @@ +package com.infernalsuite.asp.pdc; + +import com.google.common.base.Preconditions; +import com.infernalsuite.asp.api.SlimeNMSBridge; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.BinaryTagType; +import net.kyori.adventure.nbt.BinaryTagTypes; +import net.kyori.adventure.nbt.ByteArrayBinaryTag; +import net.kyori.adventure.nbt.ByteBinaryTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.DoubleBinaryTag; +import net.kyori.adventure.nbt.FloatBinaryTag; +import net.kyori.adventure.nbt.IntArrayBinaryTag; +import net.kyori.adventure.nbt.IntBinaryTag; +import net.kyori.adventure.nbt.ListBinaryTag; +import net.kyori.adventure.nbt.LongArrayBinaryTag; +import net.kyori.adventure.nbt.LongBinaryTag; +import net.kyori.adventure.nbt.ShortBinaryTag; +import net.kyori.adventure.nbt.StringBinaryTag; +import org.bukkit.persistence.ListPersistentDataType; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.function.BiFunction; +import java.util.function.BiPredicate; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class AdventureDataTypeRegistry { + + public static final AdventureDataTypeRegistry DEFAULT = new AdventureDataTypeRegistry(); + private final ConcurrentMap, TagAdapter> adapters = new ConcurrentHashMap<>(); + + @SuppressWarnings("unchecked") + private TagAdapter obtainAdapter(final PersistentDataType dataType) { + return (TagAdapter) this.adapters.computeIfAbsent(dataType.getPrimitiveType(), this::createAdapter); + } + + @SuppressWarnings("unchecked") + private TagAdapter createAdapter(final Class

    primitiveType) { + if (TagAdapter.PRIMITIVE_ADAPTERS.containsKey(primitiveType)) { + return (TagAdapter) TagAdapter.PRIMITIVE_ADAPTERS.get(primitiveType); + } else if (PersistentDataContainer.class.isAssignableFrom(primitiveType)) { + return (TagAdapter) TagAdapter.of(PersistentDataContainer.class, CompoundBinaryTag.class, BinaryTagTypes.COMPOUND, this::extractPDC, this::buildPDC); + } else if (primitiveType.isArray() && PersistentDataContainer.class.isAssignableFrom(primitiveType.componentType())) { + return (TagAdapter) TagAdapter.of(PersistentDataContainer[].class, ListBinaryTag.class, BinaryTagTypes.LIST, containers -> { + ListBinaryTag.Builder builder = ListBinaryTag.builder(BinaryTagTypes.COMPOUND); + for (PersistentDataContainer container : containers) { + builder.add(this.extractPDC(container)); + } + return builder.build(); + }, tag -> { + PersistentDataContainer[] containers = new PersistentDataContainer[tag.size()]; + for (int i = 0; i < tag.size(); i++) { + containers[i] = this.buildPDC(tag.getCompound(i)); + } + return containers; + }); + } else if (List.class.isAssignableFrom(primitiveType)) { + return (TagAdapter) TagAdapter.of(List.class, ListBinaryTag.class, BinaryTagTypes.LIST, this::constructList, this::extractList, this::matchesListTag); + } else { + throw new IllegalArgumentException("Could not find a valid TagAdapter implementation for the requested type " + primitiveType.getSimpleName()); + } + } + + private CompoundBinaryTag extractPDC(PersistentDataContainer pdc) { + CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder(); + + if (pdc instanceof AdventurePersistentDataContainer container) { + builder.put(container.getRaw()); + } else { + SlimeNMSBridge.instance().extractCraftPDC(pdc, builder); + } + + return builder.build(); + } + + private PersistentDataContainer buildPDC(CompoundBinaryTag tag) { + return new AdventurePersistentDataContainer(tag, this); + } + + public

    BinaryTag wrap(final PersistentDataType dataType, final P value) throws IllegalArgumentException { + return this.obtainAdapter(dataType).build(dataType, value); + } + + public

    boolean isInstanceOf(final PersistentDataType dataType, final BinaryTag tag) throws IllegalArgumentException{ + return this.obtainAdapter(dataType).isInstance(dataType, tag); + } + + public P extract(final PersistentDataType dataType, final BinaryTag tag) throws ClassCastException, IllegalArgumentException { + final Class

    primitiveType = dataType.getPrimitiveType(); + final TagAdapter adapter = this.obtainAdapter(dataType); + Preconditions.checkArgument(adapter.isInstance(dataType, tag), "The found tag instance (%s) cannot store %s", tag.getClass().getSimpleName(), primitiveType.getSimpleName()); + + final P foundValue = adapter.extract(dataType, tag); + Preconditions.checkArgument(primitiveType.isInstance(foundValue), "The found object is type %s, expected type %s", foundValue.getClass().getSimpleName(), primitiveType.getSimpleName()); + return foundValue; + } + + private > ListBinaryTag constructList(final PersistentDataType dataType, final List

    list) { + Preconditions.checkArgument(dataType instanceof ListPersistentDataType, "The passed list cannot be written to the PDC with a %s (expected a list data type", dataType.getClass().getSimpleName()); + @SuppressWarnings("unchecked") final ListPersistentDataType listDataType = (ListPersistentDataType) dataType; + + final ListBinaryTag.Builder builder = ListBinaryTag.builder(); + list.forEach(primitive -> builder.add(this.wrap(listDataType.elementType(), primitive))); + + return builder.build(); + } + + private

    List

    extractList(final PersistentDataType dataType, final ListBinaryTag listTag) { + Preconditions.checkArgument(dataType instanceof ListPersistentDataType, "The found list tag cannot be read with a %s (expected a list data type)", dataType.getClass().getSimpleName()); + @SuppressWarnings("unchecked") final ListPersistentDataType listDataType = (ListPersistentDataType) dataType; + + return listTag.stream().map(tag -> this.extract(listDataType.elementType(), tag)).collect(Collectors.toList()); + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + private boolean matchesListTag(final PersistentDataType dataType, final BinaryTag tag) { + if (!(dataType instanceof final ListPersistentDataType listDataType)) return false; + if (!(tag instanceof final ListBinaryTag listTag)) return false; + + final TagAdapter adapter = this.obtainAdapter(listDataType.elementType()); + + return adapter.nbtType().id() == listTag.elementType().id(); + } + + private record TagAdapter( + Class

    primitiveType, + Class tagType, + BinaryTagType nbtType, + BiFunction, P, T> builder, + BiFunction, T, P> extractor, + BiPredicate, BinaryTag> matcher + ) { + private static final Map, TagAdapter> PRIMITIVE_ADAPTERS = initPrimitiveAdapters(); + + private static TagAdapter of(Class

    primitiveType, Class tagType, BinaryTagType nbtType, Function builder, Function extractor) { + return of(primitiveType, tagType, nbtType, (type, p) -> builder.apply(p), (type, t) -> extractor.apply(t), (type, tag) -> tagType.isInstance(tag)); + } + + private static TagAdapter of(Class

    primitiveType, Class tagType, BinaryTagType nbtType, BiFunction, P, T> builder, BiFunction, T, P> extractor, BiPredicate, BinaryTag> matcher) { + return new TagAdapter<>(primitiveType, tagType, nbtType, builder, extractor, matcher); + } + + private P extract(final PersistentDataType dataType, final BinaryTag tag) { + Preconditions.checkArgument(this.tagType.isInstance(tag), "The provided tag was type %s, expected %s", tag.getClass().getSimpleName(), this.tagType.getSimpleName()); + return this.extractor.apply(dataType, this.tagType.cast(tag)); + } + + T build(final PersistentDataType dataType, final P value) { + Preconditions.checkArgument(this.primitiveType.isInstance(value), "The provided value was type %s, expected %s", value.getClass().getSimpleName(), this.primitiveType.getSimpleName()); + return this.builder.apply(dataType, value); + } + + boolean isInstance(final PersistentDataType dataType, final BinaryTag tag) { + return this.matcher.test(dataType, tag); + } + + private static Map, TagAdapter> initPrimitiveAdapters() { + final Map, TagAdapter> adapters = new IdentityHashMap<>(); + adapters.put(Byte.class, TagAdapter.of(Byte.class, ByteBinaryTag.class, BinaryTagTypes.BYTE, ByteBinaryTag::byteBinaryTag, ByteBinaryTag::value)); + adapters.put(Short.class, TagAdapter.of(Short.class, ShortBinaryTag.class, BinaryTagTypes.SHORT, ShortBinaryTag::shortBinaryTag, ShortBinaryTag::value)); + adapters.put(Integer.class, TagAdapter.of(Integer.class, IntBinaryTag.class, BinaryTagTypes.INT, IntBinaryTag::intBinaryTag, IntBinaryTag::value)); + adapters.put(Long.class, TagAdapter.of(Long.class, LongBinaryTag.class, BinaryTagTypes.LONG, LongBinaryTag::longBinaryTag, LongBinaryTag::value)); + adapters.put(Float.class, TagAdapter.of(Float.class, FloatBinaryTag.class, BinaryTagTypes.FLOAT, FloatBinaryTag::floatBinaryTag, FloatBinaryTag::value)); + adapters.put(Double.class, TagAdapter.of(Double.class, DoubleBinaryTag.class, BinaryTagTypes.DOUBLE, DoubleBinaryTag::doubleBinaryTag, DoubleBinaryTag::value)); + adapters.put(String.class, TagAdapter.of(String.class, StringBinaryTag.class, BinaryTagTypes.STRING, StringBinaryTag::stringBinaryTag, StringBinaryTag::value)); + adapters.put(byte[].class, TagAdapter.of(byte[].class, ByteArrayBinaryTag.class, BinaryTagTypes.BYTE_ARRAY, ByteArrayBinaryTag::byteArrayBinaryTag, ByteArrayBinaryTag::value)); + adapters.put(int[].class, TagAdapter.of(int[].class, IntArrayBinaryTag.class, BinaryTagTypes.INT_ARRAY, IntArrayBinaryTag::intArrayBinaryTag, IntArrayBinaryTag::value)); + adapters.put(long[].class, TagAdapter.of(long[].class, LongArrayBinaryTag.class, BinaryTagTypes.LONG_ARRAY, LongArrayBinaryTag::longArrayBinaryTag, LongArrayBinaryTag::value)); + return adapters; + } + + } + +} diff --git a/core/src/main/java/com/infernalsuite/asp/pdc/AdventurePersistentDataContainer.java b/core/src/main/java/com/infernalsuite/asp/pdc/AdventurePersistentDataContainer.java new file mode 100644 index 000000000..07ec82950 --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/pdc/AdventurePersistentDataContainer.java @@ -0,0 +1,188 @@ +package com.infernalsuite.asp.pdc; + +import com.google.common.base.Preconditions; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.BinaryTagIO; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import org.bukkit.NamespacedKey; +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; +import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public class AdventurePersistentDataContainer implements PersistentDataContainer, PersistentDataAdapterContext { + + private static final Pattern NS_KEY_PATTERN = Pattern.compile(":"); + + private final ConcurrentMap tags = new ConcurrentHashMap<>(); + private final AdventureDataTypeRegistry registry; + + public AdventurePersistentDataContainer() { + this(AdventureDataTypeRegistry.DEFAULT); + } + + public AdventurePersistentDataContainer(final AdventureDataTypeRegistry registry) { + this.registry = registry; + } + + public AdventurePersistentDataContainer(final Map tags, final AdventureDataTypeRegistry registry) { + this(registry); + this.tags.putAll(tags); + } + + public AdventurePersistentDataContainer(final CompoundBinaryTag root, final AdventureDataTypeRegistry registry) { + this(registry); + root.forEach(entry -> this.tags.put(entry.getKey(), entry.getValue())); + } + + public AdventurePersistentDataContainer(final CompoundBinaryTag root) { + this(root, AdventureDataTypeRegistry.DEFAULT); + } + + public AdventurePersistentDataContainer(final Map tags) { + this(tags, AdventureDataTypeRegistry.DEFAULT); + } + + Map getRaw() { + return this.tags; + } + + public Map getTags() { + return Collections.unmodifiableMap(this.tags); + } + + public CompoundBinaryTag toCompound() { + return CompoundBinaryTag.builder().put(this.tags).build(); + } + + @Override + public void set(@NotNull NamespacedKey key, @NotNull PersistentDataType type, @NotNull C value) { + Preconditions.checkNotNull(key, "The key cannot be null"); + Preconditions.checkNotNull(type, "The provided type cannot be null"); + Preconditions.checkNotNull(value, "The provided value cannot be null"); + this.tags.put(key.toString(), this.registry.wrap(type, type.toPrimitive(value, getAdapterContext()))); + } + + @Override + public boolean has(@NotNull NamespacedKey key, @NotNull PersistentDataType type) { + Preconditions.checkNotNull(key, "The key cannot be null"); + Preconditions.checkNotNull(type, "The provided type cannot be null"); + + BinaryTag tag = this.tags.get(key.toString()); + + return tag != null && this.registry.isInstanceOf(type, tag); + } + + @Override + public boolean has(@NotNull NamespacedKey key) { + Preconditions.checkNotNull(key, "The key cannot be null"); + return this.tags.containsKey(key.toString()); + } + + @Override + public @Nullable C get(@NotNull NamespacedKey key, @NotNull PersistentDataType type) { + Preconditions.checkNotNull(key, "The key cannot be null"); + Preconditions.checkNotNull(type, "The provided type cannot be null"); + + final BinaryTag tag = this.tags.get(key.toString()); + + return tag == null ? null : type.fromPrimitive(this.registry.extract(type, tag), getAdapterContext()); + } + + @Override + public @NotNull C getOrDefault(@NotNull NamespacedKey key, @NotNull PersistentDataType type, @NotNull C defaultValue) { + final C value = this.get(key, type); + return value == null ? defaultValue : value; + } + + @Override + public @NotNull Set getKeys() { + return this.tags.keySet().stream() + .map(key -> NS_KEY_PATTERN.split(key, 2)) + .filter(keyData -> keyData.length == 2) + .map(keyData -> new NamespacedKey(keyData[0], keyData[1])) + .collect(Collectors.toUnmodifiableSet()); + } + + @Override + public void remove(@NotNull NamespacedKey key) { + Preconditions.checkNotNull(key, "The key cannot be null"); + this.tags.remove(key.toString()); + } + + @Override + public boolean isEmpty() { + return this.tags.isEmpty(); + } + + @Override + public void copyTo(@NotNull PersistentDataContainer other, boolean replace) { + Preconditions.checkNotNull(other, "The provided container cannot be null"); + + if (other instanceof AdventurePersistentDataContainer container) { + if (replace) { + container.tags.putAll(this.tags); + } else { + this.tags.forEach(container.tags::putIfAbsent); + } + } else { + throw new IllegalArgumentException("Cannot copy to a container that isn't an AdventurePersistentDataContainer (got " + other.getClass().getName() + ")"); + } + } + + @Override + public @NotNull PersistentDataAdapterContext getAdapterContext() { + return this; + } + + @Override + public byte @NotNull [] serializeToBytes() throws IOException { + if (this.tags.isEmpty()) return new byte[0]; + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + BinaryTagIO.writer().write(CompoundBinaryTag.builder().put(this.tags).build(), outputStream); + + return outputStream.toByteArray(); + } + + @Override + public void readFromBytes(byte @NotNull [] bytes, boolean clear) throws IOException { + if (clear) this.tags.clear(); + if (bytes.length == 0) return; + + BinaryTagIO.unlimitedReader().read(new ByteArrayInputStream(bytes)).forEach(entry -> this.tags.put(entry.getKey(), entry.getValue())); + } + + @Override + public @NotNull PersistentDataContainer newPersistentDataContainer() { + return new AdventurePersistentDataContainer(this.registry); + } + + @Override + public int hashCode() { + int hashCode = 3; + hashCode =+ this.tags.hashCode(); + return hashCode; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + + AdventurePersistentDataContainer other = (AdventurePersistentDataContainer) obj; + return this.tags.equals(other.tags); + } +} diff --git a/core/src/main/java/com/infernalsuite/asp/pdc/FlowDataTypeRegistry.java b/core/src/main/java/com/infernalsuite/asp/pdc/FlowDataTypeRegistry.java deleted file mode 100644 index f70ab0a8a..000000000 --- a/core/src/main/java/com/infernalsuite/asp/pdc/FlowDataTypeRegistry.java +++ /dev/null @@ -1,239 +0,0 @@ -package com.infernalsuite.asp.pdc; - -import com.flowpowered.nbt.*; -import com.google.common.base.Preconditions; -import com.google.common.primitives.Primitives; -import com.infernalsuite.asp.api.SlimeNMSBridge; -import net.kyori.adventure.util.Services; -import org.bukkit.persistence.PersistentDataContainer; - -import java.util.ArrayList; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.BiFunction; -import java.util.function.Function; - -public class FlowDataTypeRegistry { - - public static final FlowDataTypeRegistry DEFAULT = new FlowDataTypeRegistry(); - private final Map, TagAdapter> adapters = new ConcurrentHashMap<>(); - - private > TagAdapter createAdapter(Class primitiveType, Class nbtBaseType, BiFunction builder, Function extractor) { - return new TagAdapter<>(primitiveType, nbtBaseType, builder, extractor); - } - - private > TagAdapter obtainAdapter(Class type) { - // Should be safe - //noinspection unchecked - return (TagAdapter) adapters.computeIfAbsent(type, this::createAdapter); - } - - /** - * Creates a TagAdapter object based on the given type. - *
    - * Unlike CraftBukkit, this implementation does not allow complex tags, as it would require to cast them to CraftPersistentDataContainer which is not available from this context. - * - * @param type The class representing the type to be converted. - * @return A TagAdapter object that can convert the given type to the corresponding Tag implementation. - * @throws IllegalArgumentException if a valid TagAdapter implementation cannot be found for the requested type. - */ - private TagAdapter createAdapter(Class type) throws IllegalArgumentException { - if (!Primitives.isWrapperType(type)) { - type = Primitives.wrap(type); //Make sure we will always "switch" over the wrapper types - } - // This would really make use of pattern matching in JDK 21 :( - - // Convert Byte to ByteTag - if (Objects.equals(Byte.class, type)) { - return createAdapter(Byte.class, ByteTag.class, ByteTag::new, ByteTag::getValue); - } - // Convert Short to ShortTag - if (Objects.equals(Short.class, type)) { - return createAdapter(Short.class, ShortTag.class, ShortTag::new, ShortTag::getValue); - } - // Convert Integer to IntTag - if (Objects.equals(Integer.class, type)) { - return createAdapter(Integer.class, IntTag.class, IntTag::new, IntTag::getValue); - } - // Convert Long to LongTag - if (Objects.equals(Long.class, type)) { - return createAdapter(Long.class, LongTag.class, LongTag::new, LongTag::getValue); - } - // Convert Float to FloatTag - if (Objects.equals(Float.class, type)) { - return createAdapter(Float.class, FloatTag.class, FloatTag::new, FloatTag::getValue); - } - // Convert Double to DoubleTag - if (Objects.equals(Double.class, type)) { - return createAdapter(Double.class, DoubleTag.class, DoubleTag::new, DoubleTag::getValue); - } - - // Convert String to StringTag - if (Objects.equals(String.class, type)) { - return createAdapter(String.class, StringTag.class, StringTag::new, StringTag::getValue); - } - - // Convert byte[] to ByteArrayTag - if (Objects.equals(byte[].class, type)) { - return createAdapter(byte[].class, ByteArrayTag.class, ByteArrayTag::new, ByteArrayTag::getValue); - } - // Convert int[] to IntArrayTag - if (Objects.equals(int[].class, type)) { - return createAdapter(int[].class, IntArrayTag.class, IntArrayTag::new, IntArrayTag::getValue); - } - // Convert long[] to LongArrayTag - if (Objects.equals(long[].class, type)) { - return createAdapter(long[].class, LongArrayTag.class, LongArrayTag::new, LongArrayTag::getValue); - } - // Convert short[] to ShortArrayTag - if (Objects.equals(short[].class, type)) { - return createAdapter(short[].class, ShortArrayTag.class, ShortArrayTag::new, ShortArrayTag::getValue); - } - - if (Objects.equals(PersistentDataContainer.class, type)) { - return createAdapter(PersistentDataContainer.class, CompoundTag.class, this::extractPDCIntoFlowNBT, this::extractFlowNBTIntoPDC); - } - - if (Objects.equals(PersistentDataContainer[].class, type)) { - return createAdapter(PersistentDataContainer[].class, ListTag.class, (key, value) -> { - var list = new ArrayList(); - - for (PersistentDataContainer pdc : value) { - list.add(extractPDCIntoFlowNBT(key, pdc)); - } - - return new ListTag<>(key, TagType.TAG_COMPOUND, list); - }, tag -> { - @SuppressWarnings("unchecked") var casted = (ListTag) tag; - var list = casted.getValue(); - var resArr = new PersistentDataContainer[list.size()]; - - for (int i = 0; i < list.size(); i++) { - resArr[i] = extractFlowNBTIntoPDC(list.get(i)); - } - - return resArr; - }); - } - - throw new IllegalArgumentException("Could not find a valid TagAdapter implementation for the requested type " + type.getSimpleName()); - } - - private PersistentDataContainer extractFlowNBTIntoPDC(CompoundTag compound) { - var optBridge = Services.service(SlimeNMSBridge.class); - if (optBridge.isPresent()) { - var bridge = optBridge.get(); - return bridge.extractCompoundMapIntoCraftPDC(compound.getValue()); - } else { - // Fall back to FlowPersistentDataContainer - var container = new FlowPersistentDataContainer(new CompoundTag("root", new CompoundMap()), this); - container.getRoot().getValue().putAll(compound.getValue()); - return container; - } - } - - private CompoundTag extractPDCIntoFlowNBT(String key, PersistentDataContainer pdc) { - var map = new CompoundMap(); - - if (pdc instanceof FlowPersistentDataContainer container) { - map.putAll(container.getRoot().getValue()); - } else { - Services.service(SlimeNMSBridge.class).orElseThrow().extractCraftPDC(pdc, map); - } - - return new CompoundTag(key, map); - } - - /** - * Wraps the passed value into a tag instance. - * - * @param type the type of the passed value - * @param value the value to be stored in the tag - * @param key the key to store the value under - * @param the generic type of the value - * @return the created tag instance - * @throws IllegalArgumentException if no suitable tag type adapter for this type was found - */ - public Tag wrap(String key, Class type, T value) throws IllegalArgumentException { - return obtainAdapter(type) - .build(key, value); - } - - /** - * Returns if the tag instance matches the provided primitive type. - * - * @param type the type of the primitive value - * @param base the base instance to check - * @param the generic type of the type - * @return if the base stores values of the primitive type passed - * @throws IllegalArgumentException if no suitable tag type adapter for this - * type was found - */ - public boolean isInstanceOf(Class type, Tag base) { - return obtainAdapter(type) - .isInstance(base); - } - - /** - * Extracts the value out of the provided tag. - * - * @param type the type of the value to extract - * @param tag the tag to extract the value from - * @param the generic type of the value stored inside the tag - * @return the extracted value - * @throws IllegalArgumentException if the passed base is not an instanced of the defined base type and therefore is not applicable to the extractor function - * @throws IllegalArgumentException if the found object is not of type passed - * @throws IllegalArgumentException if no suitable tag type adapter for this type was found - */ - public T extract(Class type, Tag tag) throws ClassCastException, IllegalArgumentException { - var adapter = obtainAdapter(type); - Preconditions.checkArgument(adapter.isInstance(tag), "The found tag instance (%s) cannot store %s", tag.getClass().getSimpleName(), type.getSimpleName()); - - Object foundValue = adapter.extract(tag); - Preconditions.checkArgument(type.isInstance(foundValue), "The found object is of the type %s. Expected type %s", foundValue.getClass().getSimpleName(), type.getSimpleName()); - return type.cast(foundValue); - } - - private record TagAdapter>(Class primitiveType, Class nbtBaseType, - BiFunction builder, Function extractor) { - /** - * This method will extract the value stored in the tag, according to - * the expected primitive type. - * - * @param base the base to extract from - * @return the value stored inside of the tag - * @throws ClassCastException if the passed base is not an instanced of - * the defined base type and therefore is not applicable to the - * extractor function - */ - T extract(Tag base) { - Preconditions.checkArgument(this.nbtBaseType.isInstance(base), "The provided NBTBase was of the type %s. Expected type %s", base.getClass().getSimpleName(), this.nbtBaseType.getSimpleName()); - return this.extractor.apply(this.nbtBaseType.cast(base)); - } - - /** - * Builds a tag instance wrapping around the provided value object. - * - * @param value the value to store inside the created tag - * @return the new tag instance - * @throws ClassCastException if the passed value object is not of the - * defined primitive type and therefore is not applicable to the builder - * function - */ - Z build(String key, Object value) { - Preconditions.checkArgument(this.primitiveType.isInstance(value), "The provided value was of the type %s. Expected type %s", value.getClass().getSimpleName(), this.primitiveType.getSimpleName()); - return this.builder.apply(key, this.primitiveType.cast(value)); - } - - /** - * Returns if the tag instance matches the adapters one. - * - * @param base the base to check - * @return if the tag was an instance of the set type - */ - boolean isInstance(Tag base) { - return this.nbtBaseType.isInstance(base); - } - } -} diff --git a/core/src/main/java/com/infernalsuite/asp/pdc/FlowPersistentDataContainer.java b/core/src/main/java/com/infernalsuite/asp/pdc/FlowPersistentDataContainer.java deleted file mode 100644 index 5712bc1b6..000000000 --- a/core/src/main/java/com/infernalsuite/asp/pdc/FlowPersistentDataContainer.java +++ /dev/null @@ -1,174 +0,0 @@ -package com.infernalsuite.asp.pdc; - -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.Tag; -import com.flowpowered.nbt.stream.NBTInputStream; -import com.flowpowered.nbt.stream.NBTOutputStream; -import com.google.common.base.Preconditions; -import org.bukkit.NamespacedKey; -import org.bukkit.persistence.PersistentDataAdapterContext; -import org.bukkit.persistence.PersistentDataContainer; -import org.bukkit.persistence.PersistentDataType; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.ByteOrder; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; - -public class FlowPersistentDataContainer implements PersistentDataContainer, PersistentDataAdapterContext { - - private final CompoundTag root; - private final FlowDataTypeRegistry registry; - - public FlowPersistentDataContainer(CompoundTag root, FlowDataTypeRegistry typeRegistry) { - this.root = root; - this.registry = typeRegistry; - } - - public FlowPersistentDataContainer(CompoundTag root) { - this.root = root; - this.registry = FlowDataTypeRegistry.DEFAULT; - } - - protected CompoundTag getRoot() { - return root; - } - - @Override - public void set(@NotNull NamespacedKey key, @NotNull PersistentDataType type, @NotNull Z value) { - var name = key.toString(); - root.getValue().put(name, registry.wrap(name, type.getPrimitiveType(), type.toPrimitive(value, getAdapterContext()))); - } - - @Override - public boolean has(@NotNull NamespacedKey key, @NotNull PersistentDataType type) { - var value = root.getValue().get(key.toString()); - - if (value == null) { - return false; - } - - return registry.isInstanceOf(type.getPrimitiveType(), value); - } - - @Override - public @Nullable Z get(@NotNull NamespacedKey key, @NotNull PersistentDataType type) { - var value = root.getValue().get(key.toString()); - - if (value == null) { - return null; - } - - return type.fromPrimitive(registry.extract(type.getPrimitiveType(), (Tag) value), getAdapterContext()); - } - - @Override - public @NotNull Z getOrDefault(@NotNull NamespacedKey key, @NotNull PersistentDataType type, @NotNull Z defaultValue) { - var value = get(key, type); - return value == null ? defaultValue : value; - } - - @Override - public @NotNull Set getKeys() { - var keys = new HashSet(); - - for (String key : root.getValue().keySet()) { - String[] keyData = key.split(":", 2); - if (keyData.length == 2) { - keys.add(new NamespacedKey(keyData[0], keyData[1])); - } - } - - return keys; - } - - @Override - public void remove(@NotNull NamespacedKey key) { - root.getValue().remove(key.toString()); - } - - @Override - public boolean isEmpty() { - return root.getValue().isEmpty(); - } - - @Override - public void copyTo(@NotNull PersistentDataContainer other, boolean replace) { - Preconditions.checkNotNull(other, "The target container cannot be null"); - - if (other instanceof FlowPersistentDataContainer otherFlow) { - if (replace) { - otherFlow.root.setValue(this.root.getValue()); - } else { - otherFlow.root.getValue().forEach((k, v) -> otherFlow.root.getValue().putIfAbsent(k, v)); - } - } else { - throw new IllegalStateException("Cannot copy to a container that isn't a FlowPersistentDataContainer"); - } - } - - @Override - public @NotNull PersistentDataAdapterContext getAdapterContext() { - return this; - } - - @Override - public boolean has(@NotNull NamespacedKey key) { - return root.getValue().containsKey(key.toString()); - } - - @Override - public byte @NotNull [] serializeToBytes() throws IOException { - if (root == null || root.getValue().isEmpty()) { - return new byte[0]; - } - ByteArrayOutputStream outByteStream = new ByteArrayOutputStream(); - NBTOutputStream outStream = new NBTOutputStream(outByteStream, NBTInputStream.NO_COMPRESSION, ByteOrder.BIG_ENDIAN); - outStream.writeTag(root); - - return outByteStream.toByteArray(); - } - - @Override - public void readFromBytes(byte @NotNull [] bytes, boolean clear) throws IOException { - if (bytes.length == 0) { - return; - } - - NBTInputStream stream = new NBTInputStream(new ByteArrayInputStream(bytes), NBTInputStream.NO_COMPRESSION, ByteOrder.BIG_ENDIAN); - var compound = (com.flowpowered.nbt.CompoundTag) stream.readTag(); - - if (clear) { - root.getValue().clear(); - } - - root.getValue().putAll(compound.getValue()); - } - - @Override - public @NotNull PersistentDataContainer newPersistentDataContainer() { - return new FlowPersistentDataContainer(new CompoundTag("root", new CompoundMap()), registry); - } - - @Override - public int hashCode() { - int hashCode = 3; - hashCode += root.hashCode(); // We will simply add the tag hashcode - return hashCode; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof FlowPersistentDataContainer flow)) { - return false; - } - - return Objects.equals(root, flow.root); - } -} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilImportData.java b/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilImportData.java index 51d6c6512..bf8c4eb47 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilImportData.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilImportData.java @@ -4,6 +4,12 @@ import org.jetbrains.annotations.Nullable; import java.io.File; +import java.nio.file.Path; + +public record AnvilImportData(Path worldDir, String newName, @Nullable SlimeLoader loader) { + + public static AnvilImportData legacy(File worldDir, String newName, @Nullable SlimeLoader loader) { + return new AnvilImportData(worldDir.toPath(), newName, loader); + } -public record AnvilImportData(File worldDir, String newName, @Nullable SlimeLoader loader) { } diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java b/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java index 4bf356bb5..c446b8fe1 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java @@ -1,11 +1,5 @@ package com.infernalsuite.asp.serialization.anvil; -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.IntTag; -import com.flowpowered.nbt.ListTag; -import com.flowpowered.nbt.TagType; -import com.flowpowered.nbt.stream.NBTInputStream; import com.infernalsuite.asp.Util; import com.infernalsuite.asp.api.exceptions.InvalidWorldException; import com.infernalsuite.asp.api.utils.NibbleArray; @@ -14,89 +8,101 @@ import com.infernalsuite.asp.api.world.SlimeWorld; import com.infernalsuite.asp.api.world.properties.SlimeProperties; import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; - +import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; +import com.infernalsuite.asp.skeleton.SlimeChunkSkeleton; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import java.io.*; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.BinaryTagIO; +import net.kyori.adventure.nbt.BinaryTagTypes; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.IntBinaryTag; +import net.kyori.adventure.nbt.ListBinaryTag; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Objects; -import java.util.Optional; -import java.util.regex.Pattern; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.zip.GZIPInputStream; import java.util.zip.InflaterInputStream; public class AnvilWorldReader implements com.infernalsuite.asp.serialization.SlimeWorldReader { - public static final int V1_16 = 2566; - public static final int V1_16_5 = 2586; - public static final int V1_17_1 = 2730; - public static final int V1_19_2 = 3120; - - private static final Pattern MAP_FILE_PATTERN = Pattern.compile("^(?:map_([0-9]*).dat)$"); private static final int SECTOR_SIZE = 4096; + private static final Logger LOGGER = LoggerFactory.getLogger(AnvilWorldReader.class); + public static final AnvilWorldReader INSTANCE = new AnvilWorldReader(); @Override public SlimeWorld readFromData(AnvilImportData importData) { - File worldDir = importData.worldDir(); - try { - File levelFile = new File(worldDir, "level.dat"); + Path worldDir = importData.worldDir(); - if (!levelFile.exists() || !levelFile.isFile()) { + try { + Path levelFile = worldDir.resolve("level.dat"); + if (!Files.exists(levelFile) || !Files.isRegularFile(levelFile)) { throw new RuntimeException(new InvalidWorldException(worldDir)); } LevelData data = readLevelData(levelFile); - // World version int worldVersion = data.version; SlimePropertyMap propertyMap = new SlimePropertyMap(); - File environmentDir = new File(worldDir, "DIM-1"); + // TODO - Really? There has to be a better way... + Path environmentDir = worldDir.resolve("DIM-1"); propertyMap.setValue(SlimeProperties.ENVIRONMENT, "nether"); - if (!environmentDir.isDirectory()) { - environmentDir = new File(worldDir, "DIM1"); + if (!Files.isDirectory(environmentDir)) { + environmentDir = worldDir.resolve("DIM1"); propertyMap.setValue(SlimeProperties.ENVIRONMENT, "the_end"); - if (!environmentDir.isDirectory()) { + if (!Files.isDirectory(environmentDir)) { environmentDir = worldDir; propertyMap.setValue(SlimeProperties.ENVIRONMENT, "normal"); } } // Chunks - File regionDir = new File(environmentDir, "region"); + Path regionDir = environmentDir.resolve("region"); - if (!regionDir.exists() || !regionDir.isDirectory()) { + if (!Files.exists(regionDir) || !Files.isDirectory(regionDir)) { throw new InvalidWorldException(environmentDir); } Long2ObjectMap chunks = new Long2ObjectOpenHashMap<>(); - for (File file : Objects.requireNonNull(regionDir.listFiles((dir, name) -> name.endsWith(".mca")))) { - System.out.println("Loading region file: " + file.getName() + "..."); - if (file.exists()) { - chunks.putAll( - loadChunks(file, worldVersion).stream().collect(Collectors.toMap((chunk) -> Util.chunkPosition(chunk.getX(), chunk.getZ()), (chunk) -> chunk)) - ); + try (var stream = Files.newDirectoryStream(regionDir, path -> path.toString().endsWith(".mca"))) { + for (final Path path : stream) { + LOGGER.info("Loading region file {}...", path.getFileName()); + chunks.putAll(loadChunks(path, worldVersion).stream() + .collect(Collectors.toMap(chunk -> Util.chunkPosition(chunk.getX(), chunk.getZ()), Function.identity()))); } } // Entity serialization - { - File entityRegion = new File(environmentDir, "entities"); - if (entityRegion.exists()) { - for (File file : entityRegion.listFiles((dir, name) -> name.endsWith(".mca"))) { - if (file != null && file.exists()) { - loadEntities(file, worldVersion, chunks); - } - } + Path entityDir = environmentDir.resolve("entities"); + if (Files.exists(entityDir)) { + if (!Files.isDirectory(entityDir)) throw new InvalidWorldException(environmentDir, "'entities' is not a directory!"); + } + + try (var stream = Files.newDirectoryStream(entityDir, path -> path.toString().endsWith(".mca"))) { + for (final Path path : stream) { + LOGGER.info("Loading entity region file {}...", path.getFileName()); + loadEntities(path, worldVersion, chunks); } } @@ -118,62 +124,52 @@ public SlimeWorld readFromData(AnvilImportData importData) { // } // } - // Extra Data - CompoundMap extraData = new CompoundMap(); - propertyMap.setValue(SlimeProperties.SPAWN_X, data.x); propertyMap.setValue(SlimeProperties.SPAWN_Y, data.y); propertyMap.setValue(SlimeProperties.SPAWN_Z, data.z); - return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld(importData.newName(), importData.loader(), true, chunks, new CompoundTag("", extraData), propertyMap, worldVersion); + return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld(importData.newName(), importData.loader(), true, chunks, new ConcurrentHashMap<>(), propertyMap, worldVersion); } catch (IOException | InvalidWorldException e) { throw new RuntimeException(e); } } - private static CompoundTag loadMap(File mapFile) throws IOException { + private static CompoundBinaryTag loadMap(File mapFile) throws IOException { String fileName = mapFile.getName(); int mapId = Integer.parseInt(fileName.substring(4, fileName.length() - 4)); - CompoundTag tag; - - try (NBTInputStream nbtStream = new NBTInputStream(new FileInputStream(mapFile), - NBTInputStream.GZIP_COMPRESSION, ByteOrder.BIG_ENDIAN)) { - tag = nbtStream.readTag().getAsCompoundTag().get().getAsCompoundTag("data").get(); - } - - tag.getValue().put("id", new IntTag("id", mapId)); - + CompoundBinaryTag tag = BinaryTagIO.unlimitedReader().read(new BufferedInputStream(new FileInputStream(mapFile))).getCompound("data"); + tag.put("id", IntBinaryTag.intBinaryTag(mapId)); return tag; } - private static LevelData readLevelData(File file) throws IOException, InvalidWorldException { - Optional tag; - - try (NBTInputStream nbtStream = new NBTInputStream(new FileInputStream(file))) { - tag = nbtStream.readTag().getAsCompoundTag(); - } - - if (tag.isPresent()) { - Optional dataTag = tag.get().getAsCompoundTag("Data"); + private static CompoundBinaryTag loadMap(Path mapFile) throws IOException { + String fileName = mapFile.getFileName().toString(); + int mapId = Integer.parseInt(fileName.substring(4, fileName.length() - 4)); + CompoundBinaryTag tag = BinaryTagIO.unlimitedReader().read(mapFile).getCompound("data"); + tag.put("id", IntBinaryTag.intBinaryTag(mapId)); + return tag; + } - if (dataTag.isPresent()) { - // Data version - int dataVersion = dataTag.get().getIntValue("DataVersion").orElse(-1); + private static LevelData readLevelData(Path file) throws IOException, InvalidWorldException { + CompoundBinaryTag tag; - int spawnX = dataTag.get().getIntValue("SpawnX").orElse(0); - int spawnY = dataTag.get().getIntValue("SpawnY").orElse(255); - int spawnZ = dataTag.get().getIntValue("SpawnZ").orElse(0); + tag = BinaryTagIO.unlimitedReader().read(file); - return new LevelData(dataVersion, spawnX, spawnY, spawnZ); - } + CompoundBinaryTag dataTag = tag.getCompound("Data"); + if (dataTag.size() != 0) { + int dataVersion = dataTag.getInt("DataVersion", -1); + int spawnX = dataTag.getInt("SpawnX", 0); + int spawnY = dataTag.getInt("SpawnY", 255); + int spawnZ = dataTag.getInt("SpawnZ", 0); + return new LevelData(dataVersion, spawnX, spawnY, spawnZ); } - throw new InvalidWorldException(file.getParentFile()); + throw new InvalidWorldException(file.getParent()); } - private static void loadEntities(File file, int version, Long2ObjectMap chunkMap) throws IOException { - byte[] regionByteArray = Files.readAllBytes(file.toPath()); + private static void loadEntities(Path path, int version, Long2ObjectMap chunkMap) throws IOException { + byte[] regionByteArray = Files.readAllBytes(path); DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(regionByteArray)); List chunks = new ArrayList<>(1024); @@ -198,12 +194,9 @@ private static void loadEntities(File file, int version, Long2ObjectMap loadChunks(File file, int worldVersion) throws IOException { - byte[] regionByteArray = Files.readAllBytes(file.toPath()); + private static List loadChunks(Path path, int worldVersion) throws IOException { + byte[] regionByteArray = Files.readAllBytes(path); DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(regionByteArray)); List chunks = new ArrayList<>(1024); @@ -238,16 +231,8 @@ private static List loadChunks(File file, int worldVersion) throws I DataInputStream chunkStream = new DataInputStream(new ByteArrayInputStream(regionByteArray, entry.offset() + 5, chunkSize)); InputStream decompressorStream = compressionScheme == 1 ? new GZIPInputStream(chunkStream) : new InflaterInputStream(chunkStream); - NBTInputStream nbtStream = new NBTInputStream(decompressorStream, NBTInputStream.NO_COMPRESSION, ByteOrder.BIG_ENDIAN); - CompoundTag globalCompound = (CompoundTag) nbtStream.readTag(); - CompoundMap globalMap = globalCompound.getValue(); - - CompoundTag levelDataTag = new CompoundTag("Level", globalMap); - if (globalMap.containsKey("Level")) { - levelDataTag = (CompoundTag) globalMap.get("Level"); - } - - return readChunk(levelDataTag, worldVersion); + CompoundBinaryTag tag = BinaryTagIO.unlimitedReader().read(decompressorStream); + return readChunk(tag, worldVersion); } catch (IOException ex) { throw new RuntimeException(ex); } @@ -255,174 +240,94 @@ private static List loadChunks(File file, int worldVersion) throws I }).filter(Objects::nonNull).collect(Collectors.toList()); } - private static void readEntityChunk(CompoundTag compound, int worldVersion, Long2ObjectMap slimeChunkMap) { - int[] position = compound.getAsIntArrayTag("Position").orElseThrow().getValue(); + private static void readEntityChunk(CompoundBinaryTag compound, int worldVersion, Long2ObjectMap slimeChunkMap) { + int[] position = compound.getIntArray("Position"); + if (position.length == 0) throw new IllegalStateException("Entity chunk is missing position data"); int chunkX = position[0]; int chunkZ = position[1]; - int dataVersion = compound.getAsIntTag("DataVersion").map(IntTag::getValue).orElse(-1); + int dataVersion = compound.getInt("DataVersion", -1); if (dataVersion != worldVersion) { - System.err.println("Cannot load entity chunk at " + chunkX + "," + chunkZ + ": data version " + dataVersion + " does not match world version " + worldVersion); + LOGGER.error("Cannot load entity chunk at {},{}: data version {} does not match world version {}", chunkX, chunkZ, dataVersion, worldVersion); return; } SlimeChunk chunk = slimeChunkMap.get(Util.chunkPosition(chunkX, chunkZ)); if (chunk == null) { - System.out.println("Lost entity chunk data at: " + chunkX + " " + chunkZ); + LOGGER.warn("Lost entity chunk data at: {},{}", chunkX, chunkZ); } else { - chunk.getEntities().addAll((List) compound.getAsListTag("Entities").get().getValue()); + compound.getList("Entities", BinaryTagTypes.COMPOUND).forEach(entityTag -> chunk.getEntities().add((CompoundBinaryTag) entityTag)); } } - private static SlimeChunk readChunk(CompoundTag compound, int worldVersion) { - int chunkX = compound.getAsIntTag("xPos").get().getValue(); - int chunkZ = compound.getAsIntTag("zPos").get().getValue(); + private static SlimeChunk readChunk(CompoundBinaryTag compound, int worldVersion) { + int chunkX = compound.getInt("xPos"); + int chunkZ = compound.getInt("zPos"); - if (worldVersion >= V1_19_2) { // 1.18 chunks should have a DataVersion tag, we can check if the chunk has been converted to match the world - int dataVersion = compound.getAsIntTag("DataVersion").map(IntTag::getValue).orElse(-1); - if (dataVersion != worldVersion) { - System.err.println("Cannot load chunk at " + chunkX + "," + chunkZ + ": data version " + dataVersion + " does not match world version " + worldVersion); - return null; - } - } - - Optional status = compound.getStringValue("Status"); - - if (status.isPresent() && !status.get().equals("postprocessed") && !status.get().startsWith("full") && !status.get().startsWith("minecraft:full")) { - // It's a protochunk + int dataVersion = compound.getInt("DataVersion", -1); + if (dataVersion != worldVersion) { + LOGGER.error("Cannot load chunk at {},{}: data version {} does not match world version {}", chunkX, chunkZ, dataVersion, worldVersion); return null; } -// int[] biomes; -// Tag biomesTag = compound.getValue().get("Biomes"); -// -// if (biomesTag instanceof IntArrayTag) { -// biomes = ((IntArrayTag) biomesTag).getValue(); -// } else if (biomesTag instanceof ByteArrayTag) { -// byte[] byteBiomes = ((ByteArrayTag) biomesTag).getValue(); -// biomes = toIntArray(byteBiomes); -// } else { -// biomes = null; -// } - - Optional optionalHeightMaps = compound.getAsCompoundTag("Heightmaps"); - CompoundTag heightMapsCompound = optionalHeightMaps.orElse(new CompoundTag("", new CompoundMap())); - - List tileEntities; - List entities; - ListTag sectionsTag; - - int minSectionY = 0; - int maxSectionY = 16; - - if (worldVersion < V1_19_2) { - tileEntities = ((ListTag) compound.getAsListTag("TileEntities") - .orElse(new ListTag<>("TileEntities", TagType.TAG_COMPOUND, new ArrayList<>()))).getValue(); - entities = ((ListTag) compound.getAsListTag("Entities") - .orElse(new ListTag<>("Entities", TagType.TAG_COMPOUND, new ArrayList<>()))).getValue(); - sectionsTag = (ListTag) compound.getAsListTag("Sections").get(); - } else { - tileEntities = ((ListTag) compound.getAsListTag("block_entities") - .orElse(new ListTag<>("block_entities", TagType.TAG_COMPOUND, new ArrayList<>()))).getValue(); - entities = ((ListTag) compound.getAsListTag("entities") - .orElse(new ListTag<>("entities", TagType.TAG_COMPOUND, new ArrayList<>()))).getValue(); - sectionsTag = (ListTag) compound.getAsListTag("sections").get(); - - Class type = compound.getValue().get("yPos").getValue().getClass(); - - if (type == Byte.class) { - minSectionY = compound.getByteValue("yPos").orElseThrow(); - } else { - minSectionY = compound.getIntValue("yPos").orElseThrow(); + String status = compound.getString("Status", ""); + if (!status.isEmpty()) { + // TODO - Check if this is correct, looks like the status string format may have changed... + if (!status.equals("postprocessed") && !status.startsWith("full") && !status.startsWith("minecraft:full")) { + // It's a protochunk + return null; } - - maxSectionY = sectionsTag.getValue().stream().map(c -> c.getByteValue("Y").orElseThrow()).max(Byte::compareTo).orElse((byte) 0) + 1; // Add 1 to the section, as we serialize it with the 1 added. } - SlimeChunkSection[] sectionArray = new SlimeChunkSection[maxSectionY - minSectionY]; - - for (CompoundTag sectionTag : sectionsTag.getValue()) { - int index = sectionTag.getByteValue("Y").get(); - - if (worldVersion < V1_17_1 && index < 0) { - // For some reason MC 1.14 worlds contain an empty section with Y = -1, however 1.17+ worlds can use these sections - continue; - } - - ListTag paletteTag = null; - long[] blockStatesArray = null; + CompoundBinaryTag heightMaps = compound.getCompound("Heightmaps"); - CompoundTag blockStatesTag = null; - CompoundTag biomeTag = null; - if (worldVersion < V1_19_2) { - paletteTag = (ListTag) sectionTag.getAsListTag("Palette").orElse(null); - blockStatesArray = sectionTag.getLongArrayValue("BlockStates").orElse(null); - - if (paletteTag == null || blockStatesArray == null || isEmpty(blockStatesArray)) { // Skip it - continue; - } - } else { - if (!sectionTag.getAsCompoundTag("block_states").isPresent() && !sectionTag.getAsCompoundTag("biomes").isPresent()) { - continue; // empty section - } - blockStatesTag = sectionTag.getAsCompoundTag("block_states").orElseThrow(); - biomeTag = sectionTag.getAsCompoundTag("biomes").orElseThrow(); - } + List tileEntities = compound.getList("block_entities", BinaryTagTypes.COMPOUND).stream().map(t -> (CompoundBinaryTag) t).toList(); + List entities = compound.getList("entities", BinaryTagTypes.COMPOUND).stream().map(t -> (CompoundBinaryTag) t).toList(); + ListBinaryTag sectionsTag = compound.getList("sections", BinaryTagTypes.COMPOUND); - NibbleArray blockLightArray = sectionTag.getValue().containsKey("BlockLight") ? new NibbleArray(sectionTag.getByteArrayValue("BlockLight").get()) : null; - NibbleArray skyLightArray = sectionTag.getValue().containsKey("SkyLight") ? new NibbleArray(sectionTag.getByteArrayValue("SkyLight").get()) : null; + int minSectionY = compound.getInt("yPos"); + // TODO - look into this +1 below + int maxSectionY = sectionsTag.stream().map(tag -> ((CompoundBinaryTag) tag).getByte("Y")).max(Byte::compareTo).orElse((byte) 0) + 1; // Add 1 to the section, as we serialize it with the 1 added. - // There is no need to do any custom processing here. - sectionArray[index - minSectionY] = new com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton(/*paletteTag, blockStatesArray,*/ blockStatesTag, biomeTag, blockLightArray, skyLightArray); - } - - CompoundTag extraTag = new CompoundTag("", new CompoundMap()); - compound.getAsCompoundTag("ChunkBukkitValues").ifPresent(chunkBukkitValues -> extraTag.getValue().put(chunkBukkitValues)); - - for (SlimeChunkSection section : sectionArray) { - if (section != null) { // Chunk isn't empty - return new com.infernalsuite.asp.skeleton.SlimeChunkSkeleton(chunkX, chunkZ, sectionArray, heightMapsCompound, tileEntities, entities, extraTag, null); - } - } + SlimeChunkSection[] sectionArray = new SlimeChunkSection[maxSectionY - minSectionY]; - // Chunk is empty - return null; - } + for (final BinaryTag rawRag : sectionsTag) { + final CompoundBinaryTag sectionTag = (CompoundBinaryTag) rawRag; + int index = sectionTag.getByte("Y"); - private static int[] toIntArray(byte[] buf) { - ByteBuffer buffer = ByteBuffer.wrap(buf).order(ByteOrder.BIG_ENDIAN); - int[] ret = new int[buf.length / 4]; + CompoundBinaryTag blockStatesTag = sectionTag.getCompound("block_states"); + CompoundBinaryTag biomesTag = sectionTag.getCompound("biomes"); - buffer.asIntBuffer().get(ret); + // TODO - actually, the section is empty if the block_states palette only contains air so uh... yeah xD fix this :P + // NB - maybe consider an import flag to respect the original biome even if its an empty section, or just strip and replace with the world default + if (blockStatesTag.size() == 0 && biomesTag.size() == 0) continue; // Empty section - return ret; - } + NibbleArray blockLightArray = applyByteArrayOrNull(sectionTag, "BlockLight", NibbleArray::new); + NibbleArray skyLightArray = applyByteArrayOrNull(sectionTag, "SkyLight", NibbleArray::new); - private static boolean isEmpty(byte[] array) { - for (byte b : array) { - if (b != 0) { - return false; - } + sectionArray[index - minSectionY] = new SlimeChunkSectionSkeleton(blockStatesTag, biomesTag, blockLightArray, skyLightArray); } - return true; + CompoundBinaryTag.Builder extraTagBuilder = CompoundBinaryTag.builder(); + CompoundBinaryTag chunkBukkitValues = compound.getCompound("ChunkBukkitValues"); + if (chunkBukkitValues.size() > 0) extraTagBuilder.put("ChunkBukkitValues", chunkBukkitValues); + CompoundBinaryTag extraTag = extraTagBuilder.build(); + + // Find first non-null chunk section. If all sections are null, chunk is empty so return null + return Arrays.stream(sectionArray) + .filter(Objects::nonNull) + .findFirst() + .map(x -> new SlimeChunkSkeleton(chunkX, chunkZ, sectionArray, heightMaps, tileEntities, entities, extraTag, null)) + .orElse(null); } - private static boolean isEmpty(long[] array) { - for (long b : array) { - if (b != 0L) { - return false; - } - } - - return true; + private static T applyByteArrayOrNull(final CompoundBinaryTag tag, final String key, final Function transform) { + byte[] res = tag.getByteArray(key); + return res.length == 0 ? null : transform.apply(res); } + private record ChunkEntry(int offset, int paddedSize) {} - private record ChunkEntry(int offset, int paddedSize) { + private record LevelData(int version, int x, int y, int z) {} - } - - private record LevelData(int version, int x, int y, int z) { - } } diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/ChunkPruner.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/ChunkPruner.java index abf90f095..1d9d96dea 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/ChunkPruner.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/ChunkPruner.java @@ -1,12 +1,13 @@ package com.infernalsuite.asp.serialization.slime; -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.ListTag; import com.infernalsuite.asp.api.world.SlimeChunk; import com.infernalsuite.asp.api.world.SlimeChunkSection; import com.infernalsuite.asp.api.world.SlimeWorld; import com.infernalsuite.asp.api.world.properties.SlimeProperties; import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import net.kyori.adventure.nbt.BinaryTagTypes; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.ListBinaryTag; import java.util.List; @@ -50,22 +51,20 @@ public static boolean canBePruned(SlimeWorld world, SlimeChunk chunk) { private static boolean areSectionsEmpty(SlimeChunkSection[] sections) { for (SlimeChunkSection chunkSection : sections) { try { - List palettes = chunkSection.getBlockStatesTag().getAsListTag("palette") - .get().getAsCompoundTagList() - .get().getValue(); - - if (palettes.size() > 1) return false; // If there is more than one palette, the section is not empty - if (!palettes.get(0).getStringValue("Name").get().equals("minecraft:air")) { - return false; + ListBinaryTag paletteTag = chunkSection.getBlockStatesTag().getList("palette"); + if (paletteTag.elementType() != BinaryTagTypes.COMPOUND) { + continue; // If the element type isn't a compound tag, consider the section empty } - } catch (Exception e) { + List palette = paletteTag.stream().map(tag -> (CompoundBinaryTag) tag).toList(); + if (palette.size() > 1) return false; // If there is more than one palette, the section is not empty + if (palette.getFirst().getString("Name").equals("minecraft:air")) return false; // If the only palette entry is not air, the section is not empty + } catch (final Exception e) { return false; } - // The section is empty, continue to the next one } - // All sections are empty, we can omit this chunk return true; } + } diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/SlimeSerializer.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/SlimeSerializer.java index 5e0ccd2e3..5352359be 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/SlimeSerializer.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/SlimeSerializer.java @@ -1,39 +1,41 @@ package com.infernalsuite.asp.serialization.slime; -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.ListTag; -import com.flowpowered.nbt.TagType; -import com.flowpowered.nbt.stream.NBTInputStream; -import com.flowpowered.nbt.stream.NBTOutputStream; import com.github.luben.zstd.Zstd; import com.infernalsuite.asp.api.utils.SlimeFormat; import com.infernalsuite.asp.api.world.SlimeChunk; import com.infernalsuite.asp.api.world.SlimeChunkSection; import com.infernalsuite.asp.api.world.SlimeWorld; import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.BinaryTagIO; +import net.kyori.adventure.nbt.BinaryTagTypes; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.ListBinaryTag; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; -import java.nio.ByteOrder; -import java.util.*; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Objects; public class SlimeSerializer { private static final Logger LOGGER = LoggerFactory.getLogger(SlimeSerializer.class); public static byte[] serialize(SlimeWorld world) { - CompoundTag extraData = world.getExtraData(); + Map extraData = world.getExtraData(); SlimePropertyMap propertyMap = world.getPropertyMap(); // Store world properties - if (!extraData.getValue().containsKey("properties")) { - extraData.getValue().putIfAbsent("properties", propertyMap.toCompound()); + if (!extraData.containsKey("properties")) { + extraData.putIfAbsent("properties", propertyMap.toCompound()); } else { - extraData.getValue().replace("properties", propertyMap.toCompound()); + extraData.replace("properties", propertyMap.toCompound()); } ByteArrayOutputStream outByteStream = new ByteArrayOutputStream(); @@ -56,20 +58,17 @@ public static byte[] serialize(SlimeWorld world) { outStream.write(compressedChunkData); // Extra Tag - { - byte[] extra = serializeCompoundTag(extraData); - byte[] compressedExtra = Zstd.compress(extra); + byte[] extra = serializeCompoundTag(CompoundBinaryTag.builder().put(extraData).build()); + byte[] compressedExtra = Zstd.compress(extra); - outStream.writeInt(compressedExtra.length); - outStream.writeInt(extra.length); - outStream.write(compressedExtra); - } + outStream.writeInt(compressedExtra.length); + outStream.writeInt(extra.length); + outStream.write(compressedExtra); } catch (Exception e) { throw new RuntimeException(e); } - return outByteStream.toByteArray(); } @@ -124,45 +123,46 @@ static byte[] serializeChunks(SlimeWorld world, Collection chunks) t outStream.write(heightMaps); // Tile entities - ListTag tileEntitiesNbtList = new ListTag<>("tileEntities", TagType.TAG_COMPOUND, chunk.getTileEntities()); - CompoundTag tileEntitiesCompound = new CompoundTag("", new CompoundMap(Collections.singletonList(tileEntitiesNbtList))); + ListBinaryTag tileEntitiesNbtList = ListBinaryTag.listBinaryTag(BinaryTagTypes.COMPOUND, yayGenerics(chunk.getTileEntities())); + CompoundBinaryTag tileEntitiesCompound = CompoundBinaryTag.builder().put("tileEntities", tileEntitiesNbtList).build(); byte[] tileEntitiesData = serializeCompoundTag(tileEntitiesCompound); outStream.writeInt(tileEntitiesData.length); outStream.write(tileEntitiesData); // Entities - ListTag entitiesNbtList = new ListTag<>("entities", TagType.TAG_COMPOUND, chunk.getEntities()); - CompoundTag entitiesCompound = new CompoundTag("", new CompoundMap(Collections.singletonList(entitiesNbtList))); + ListBinaryTag entitiesNbtList = ListBinaryTag.listBinaryTag(BinaryTagTypes.COMPOUND, yayGenerics(chunk.getEntities())); + CompoundBinaryTag entitiesCompound = CompoundBinaryTag.builder().put("entities", entitiesNbtList).build(); byte[] entitiesData = serializeCompoundTag(entitiesCompound); outStream.writeInt(entitiesData.length); outStream.write(entitiesData); // Extra Tag - { - if (chunk.getExtraData() == null) { - LOGGER.warn("Chunk at " + chunk.getX() + ", " + chunk.getZ() + " from world " + world.getName() + " has no extra data! When deserialized, this chunk will have an empty extra data tag!"); - } - byte[] extra = serializeCompoundTag(chunk.getExtraData()); - - outStream.writeInt(extra.length); - outStream.write(extra); + if (chunk.getExtraData() == null) { + LOGGER.warn("Chunk at " + chunk.getX() + ", " + chunk.getZ() + " from world " + world.getName() + " has no extra data! When deserialized, this chunk will have an empty extra data tag!"); } + byte[] extra = serializeCompoundTag(chunk.getExtraData()); + + outStream.writeInt(extra.length); + outStream.write(extra); } return outByteStream.toByteArray(); } - protected static byte[] serializeCompoundTag(CompoundTag tag) throws IOException { - if (tag == null || tag.getValue().isEmpty()) { - return new byte[0]; - } + protected static byte[] serializeCompoundTag(CompoundBinaryTag tag) throws IOException { + if (tag == null || tag.size() == 0) return new byte[0]; + ByteArrayOutputStream outByteStream = new ByteArrayOutputStream(); - NBTOutputStream outStream = new NBTOutputStream(outByteStream, NBTInputStream.NO_COMPRESSION, ByteOrder.BIG_ENDIAN); - outStream.writeTag(tag); + BinaryTagIO.writer().write(tag, outByteStream); return outByteStream.toByteArray(); } + @SuppressWarnings("unchecked") + private static List yayGenerics(final List tags) { + return (List) tags; + } + } diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12SlimeWorldDeSerializer.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12SlimeWorldDeSerializer.java index 3672cdcb4..0ab7bbb8d 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12SlimeWorldDeSerializer.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12SlimeWorldDeSerializer.java @@ -1,9 +1,5 @@ package com.infernalsuite.asp.serialization.slime.reader.impl.v12; -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.ListTag; -import com.flowpowered.nbt.stream.NBTInputStream; import com.github.luben.zstd.Zstd; import com.infernalsuite.asp.Util; import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; @@ -17,14 +13,19 @@ import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.BinaryTagIO; +import net.kyori.adventure.nbt.BinaryTagTypes; +import net.kyori.adventure.nbt.CompoundBinaryTag; import org.jetbrains.annotations.Nullable; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; -import java.nio.ByteOrder; +import java.util.Collections; import java.util.List; -import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; public class v12SlimeWorldDeSerializer implements com.infernalsuite.asp.serialization.slime.reader.VersionedByteSlimeWorldReader { @@ -38,19 +39,19 @@ public SlimeWorld deserializeWorld(byte version, @Nullable SlimeLoader loader, S Long2ObjectMap chunks = readChunks(propertyMap, chunkBytes); byte[] extraTagBytes = readCompressed(dataStream); - CompoundTag extraTag = readCompound(extraTagBytes); + CompoundBinaryTag extraTag = readCompound(extraTagBytes); - SlimePropertyMap worldPropertyMap = propertyMap; - Optional propertiesMap = extraTag - .getAsCompoundTag("properties") - .map(CompoundTag::getValue); + ConcurrentMap extraData = new ConcurrentHashMap<>(); + if (extraTag != null) extraTag.forEach(entry -> extraData.put(entry.getKey(), entry.getValue())); - if (propertiesMap.isPresent()) { - worldPropertyMap = new SlimePropertyMap(propertiesMap.get()); + SlimePropertyMap worldPropertyMap = propertyMap; + if (extraData.containsKey("properties")) { + CompoundBinaryTag serializedSlimeProperties = (CompoundBinaryTag) extraData.get("properties"); + worldPropertyMap = SlimePropertyMap.fromCompound(serializedSlimeProperties); worldPropertyMap.merge(propertyMap); } - return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld(worldName, loader, readOnly, chunks, extraTag, worldPropertyMap, worldVersion); + return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld(worldName, loader, readOnly, chunks, extraData, worldPropertyMap, worldVersion); } private static Long2ObjectMap readChunks(SlimePropertyMap slimePropertyMap, byte[] chunkBytes) throws IOException { @@ -93,12 +94,12 @@ private static Long2ObjectMap readChunks(SlimePropertyMap slimePrope // Block Data byte[] blockStateData = new byte[chunkData.readInt()]; chunkData.read(blockStateData); - CompoundTag blockStateTag = readCompound(blockStateData); + CompoundBinaryTag blockStateTag = readCompound(blockStateData); // Biome Data byte[] biomeData = new byte[chunkData.readInt()]; chunkData.read(biomeData); - CompoundTag biomeTag = readCompound(biomeData); + CompoundBinaryTag biomeTag = readCompound(biomeData); chunkSections[sectionId] = new com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton(blockStateTag, biomeTag, blockLightArray, skyLightArray); } @@ -106,36 +107,43 @@ private static Long2ObjectMap readChunks(SlimePropertyMap slimePrope // HeightMaps byte[] heightMapData = new byte[chunkData.readInt()]; chunkData.read(heightMapData); - CompoundTag heightMaps = readCompound(heightMapData); + CompoundBinaryTag heightMaps = readCompound(heightMapData); // Tile Entities - byte[] tileEntities = read(chunkData); - - CompoundTag tileEntitiesCompound = readCompound(tileEntities); - @SuppressWarnings("unchecked") - List serializedTileEntities = ((ListTag) tileEntitiesCompound.getValue().get("tileEntities")).getValue(); + byte[] tileEntitiesRaw = read(chunkData); + List tileEntities; + CompoundBinaryTag tileEntitiesCompound = readCompound(tileEntitiesRaw); + if (tileEntitiesCompound == null) { + tileEntities = Collections.emptyList(); + } else { + tileEntities = tileEntitiesCompound.getList("tileEntities", BinaryTagTypes.COMPOUND).stream() + .map(tag -> (CompoundBinaryTag) tag) + .toList(); + } // Entities - byte[] entities = read(chunkData); - - CompoundTag entitiesCompound = readCompound(entities); - @SuppressWarnings("unchecked") - List serializedEntities = ((ListTag) entitiesCompound.getValue().get("entities")).getValue(); - + byte[] entitiesRaw = read(chunkData); + List entities; + CompoundBinaryTag entitiesCompound = readCompound(entitiesRaw); + if (entitiesCompound == null) { + entities = Collections.emptyList(); + } else { + entities = entitiesCompound.getList("entities", BinaryTagTypes.COMPOUND).stream() + .map(tag -> (CompoundBinaryTag) tag) + .toList(); + } // Extra Tag byte[] rawExtra = read(chunkData); - CompoundTag extra = readCompound(rawExtra); + CompoundBinaryTag extra = readCompound(rawExtra); // If the extra tag is empty, the serializer will save it as null. // So if we deserialize a null extra tag, we will assume it was empty. - if (extra == null) { - extra = new CompoundTag("", new CompoundMap()); - } + if (extra == null) extra = CompoundBinaryTag.empty(); chunkMap.put(Util.chunkPosition(x, z), - new com.infernalsuite.asp.skeleton.SlimeChunkSkeleton(x, z, chunkSections, heightMaps, serializedTileEntities, serializedEntities, extra, null)); + new com.infernalsuite.asp.skeleton.SlimeChunkSkeleton(x, z, chunkSections, heightMaps, tileEntities, entities, extra, null)); } return chunkMap; } @@ -157,12 +165,9 @@ private static byte[] read(DataInputStream stream) throws IOException { return data; } - private static CompoundTag readCompound(byte[] tagBytes) throws IOException { - if (tagBytes.length == 0) { - return null; - } + private static CompoundBinaryTag readCompound(byte[] tagBytes) throws IOException { + if (tagBytes.length == 0) return null; - NBTInputStream nbtStream = new NBTInputStream(new ByteArrayInputStream(tagBytes), NBTInputStream.NO_COMPRESSION, ByteOrder.BIG_ENDIAN); - return (CompoundTag) nbtStream.readTag(); + return BinaryTagIO.unlimitedReader().read(new ByteArrayInputStream(tagBytes)); } } diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12WorldFormat.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12WorldFormat.java index c4a7a0ad8..bb8057fba 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12WorldFormat.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12WorldFormat.java @@ -1,7 +1,9 @@ package com.infernalsuite.asp.serialization.slime.reader.impl.v12; +import com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat; + public interface v12WorldFormat { - com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat FORMAT = new com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat<>(data -> data, new v12SlimeWorldDeSerializer()); + SimpleWorldFormat FORMAT = new SimpleWorldFormat<>(data -> data, new v12SlimeWorldDeSerializer()); } diff --git a/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java b/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java index c373a2abe..a08f9f262 100644 --- a/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java +++ b/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java @@ -1,16 +1,19 @@ package com.infernalsuite.asp.skeleton; -import com.flowpowered.nbt.CompoundTag; import com.infernalsuite.asp.Util; import com.infernalsuite.asp.api.loaders.SlimeLoader; import com.infernalsuite.asp.api.utils.NibbleArray; import com.infernalsuite.asp.api.world.SlimeChunk; import com.infernalsuite.asp.api.world.SlimeChunkSection; import com.infernalsuite.asp.api.world.SlimeWorld; - import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import java.util.*; +import net.kyori.adventure.nbt.CompoundBinaryTag; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; public class SkeletonCloning { @@ -19,7 +22,7 @@ public static SkeletonSlimeWorld fullClone(String worldName, SlimeWorld world, S loader == null ? world.getLoader() : loader, loader == null || world.isReadOnly(), cloneChunkStorage(world.getChunkStorage()), - world.getExtraData().clone(), + new ConcurrentHashMap<>(world.getExtraData()), world.getPropertyMap().clone(), world.getDataVersion()); } @@ -36,7 +39,7 @@ public static SkeletonSlimeWorld weakCopy(SlimeWorld world) { world.getLoader(), world.isReadOnly(), cloned, - world.getExtraData().clone(), + new ConcurrentHashMap<>(world.getExtraData()), world.getPropertyMap().clone(), world.getDataVersion()); } @@ -56,8 +59,8 @@ private static Long2ObjectMap cloneChunkStorage(Collection cloneChunkStorage(Collection cloneChunkStorage(Collection deepClone(List tags) { - List cloned = new ArrayList<>(tags.size()); - for (CompoundTag tag : tags) { - cloned.add(tag.clone()); + private static List deepClone(List tags) { + List cloned = new ArrayList<>(tags.size()); + for (CompoundBinaryTag tag : tags) { + cloned.add(CompoundBinaryTag.builder().put(tag).build()); } return cloned; diff --git a/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonSlimeWorld.java b/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonSlimeWorld.java index 147d4885e..d20fffca5 100644 --- a/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonSlimeWorld.java +++ b/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonSlimeWorld.java @@ -1,15 +1,16 @@ package com.infernalsuite.asp.skeleton; -import com.flowpowered.nbt.CompoundTag; import com.infernalsuite.asp.Util; import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; import com.infernalsuite.asp.api.loaders.SlimeLoader; import com.infernalsuite.asp.api.world.SlimeChunk; import com.infernalsuite.asp.api.world.SlimeWorld; import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; -import com.infernalsuite.asp.pdc.FlowPersistentDataContainer; +import com.infernalsuite.asp.pdc.AdventurePersistentDataContainer; import com.infernalsuite.asp.serialization.slime.SlimeSerializer; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; import org.bukkit.persistence.PersistentDataContainer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -18,23 +19,24 @@ import java.util.Collection; import java.util.List; import java.util.Objects; +import java.util.concurrent.ConcurrentMap; public final class SkeletonSlimeWorld implements SlimeWorld { private final String name; private final @Nullable SlimeLoader loader; private final boolean readOnly; private final Long2ObjectMap chunkStorage; - private final CompoundTag extraSerialized; + private final ConcurrentMap extraSerialized; private final SlimePropertyMap slimePropertyMap; private final int dataVersion; - private final FlowPersistentDataContainer pdc; + private final AdventurePersistentDataContainer pdc; public SkeletonSlimeWorld( String name, @Nullable SlimeLoader loader, boolean readOnly, Long2ObjectMap chunkStorage, - CompoundTag extraSerialized, + ConcurrentMap extraSerialized, SlimePropertyMap slimePropertyMap, int dataVersion ) { @@ -45,7 +47,7 @@ public SkeletonSlimeWorld( this.extraSerialized = extraSerialized; this.slimePropertyMap = slimePropertyMap; this.dataVersion = dataVersion; - this.pdc = new FlowPersistentDataContainer(extraSerialized); + this.pdc = new AdventurePersistentDataContainer(extraSerialized); } @Override @@ -69,12 +71,12 @@ public Collection getChunkStorage() { } @Override - public CompoundTag getExtraData() { + public ConcurrentMap getExtraData() { return this.extraSerialized; } @Override - public Collection getWorldMaps() { + public Collection getWorldMaps() { return List.of(); } @@ -146,7 +148,7 @@ public Long2ObjectMap chunkStorage() { return chunkStorage; } - public CompoundTag extraSerialized() { + public ConcurrentMap extraSerialized() { return extraSerialized; } diff --git a/core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSectionSkeleton.java b/core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSectionSkeleton.java index a1b83f2d2..662937e29 100644 --- a/core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSectionSkeleton.java +++ b/core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSectionSkeleton.java @@ -1,18 +1,18 @@ package com.infernalsuite.asp.skeleton; -import com.flowpowered.nbt.CompoundTag; import com.infernalsuite.asp.api.utils.NibbleArray; import com.infernalsuite.asp.api.world.SlimeChunkSection; +import net.kyori.adventure.nbt.CompoundBinaryTag; import org.jetbrains.annotations.Nullable; -public record SlimeChunkSectionSkeleton(CompoundTag blockStates, CompoundTag biome, NibbleArray block, NibbleArray light) implements SlimeChunkSection { +public record SlimeChunkSectionSkeleton(CompoundBinaryTag blockStates, CompoundBinaryTag biome, NibbleArray block, NibbleArray light) implements SlimeChunkSection { @Override - public CompoundTag getBlockStatesTag() { + public CompoundBinaryTag getBlockStatesTag() { return this.blockStates; } @Override - public CompoundTag getBiomeTag() { + public CompoundBinaryTag getBiomeTag() { return this.biome; } diff --git a/core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSkeleton.java b/core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSkeleton.java index bac46961c..f4cf2a9ef 100644 --- a/core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSkeleton.java +++ b/core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSkeleton.java @@ -1,17 +1,17 @@ package com.infernalsuite.asp.skeleton; -import com.flowpowered.nbt.CompoundTag; import com.infernalsuite.asp.api.world.SlimeChunk; import com.infernalsuite.asp.api.world.SlimeChunkSection; +import net.kyori.adventure.nbt.CompoundBinaryTag; import java.util.List; public record SlimeChunkSkeleton(int x, int z, SlimeChunkSection[] sections, - CompoundTag heightMap, - List blockEntities, - List entities, - CompoundTag extra, - CompoundTag upgradeData) implements SlimeChunk { + CompoundBinaryTag heightMap, + List blockEntities, + List entities, + CompoundBinaryTag extra, + CompoundBinaryTag upgradeData) implements SlimeChunk { @Override public int getX() { @@ -29,27 +29,27 @@ public SlimeChunkSection[] getSections() { } @Override - public CompoundTag getHeightMaps() { + public CompoundBinaryTag getHeightMaps() { return this.heightMap; } @Override - public List getTileEntities() { + public List getTileEntities() { return this.blockEntities; } @Override - public List getEntities() { + public List getEntities() { return this.entities; } @Override - public CompoundTag getExtraData() { + public CompoundBinaryTag getExtraData() { return this.extra; } @Override - public CompoundTag getUpgradeData() { + public CompoundBinaryTag getUpgradeData() { return this.upgradeData; } } diff --git a/importer/src/main/java/com/infernalsuite/asp/importer/SWMImporter.java b/importer/src/main/java/com/infernalsuite/asp/importer/SWMImporter.java index 29751e9c8..97911f96d 100644 --- a/importer/src/main/java/com/infernalsuite/asp/importer/SWMImporter.java +++ b/importer/src/main/java/com/infernalsuite/asp/importer/SWMImporter.java @@ -49,7 +49,7 @@ public static void main(String[] args) { public static void importWorld(File worldDir, File outputFile, boolean shouldPrintDebug) { try { outputFile.createNewFile(); - Files.write(outputFile.toPath(), SlimeSerializer.serialize(AnvilWorldReader.INSTANCE.readFromData(new AnvilImportData(worldDir, outputFile.getName(), null)))); + Files.write(outputFile.toPath(), SlimeSerializer.serialize(AnvilWorldReader.INSTANCE.readFromData(AnvilImportData.legacy(worldDir, outputFile.getName(), null)))); } catch (IndexOutOfBoundsException ex) { System.err.println("Oops, it looks like the world provided is too big to be imported. " + "Please trim it by using the MCEdit tool and try again."); From 699f99a53716b9eccd47af98a163edfbf61b1fc1 Mon Sep 17 00:00:00 2001 From: Philip Kelley Date: Fri, 20 Dec 2024 00:17:49 +0000 Subject: [PATCH 024/133] chore(core): remove legacy SRF support Removes SRF < v12 support This is to be re-added later once cleaned up and restructured --- .../reader/SlimeWorldReaderRegistry.java | 6 - .../impl/v10/v10SlimeWorldDeSerializer.java | 205 -------- .../slime/reader/impl/v10/v10WorldFormat.java | 8 - .../impl/v11/v11SlimeWorldDeSerializer.java | 159 ------ .../slime/reader/impl/v11/v11WorldFormat.java | 7 - .../slime/reader/impl/v1_9/Upgrade.java | 7 - .../impl/v1_9/upgrade/v1_11WorldUpgrade.java | 69 --- .../impl/v1_9/upgrade/v1_13WorldUpgrade.java | 107 ---- .../impl/v1_9/upgrade/v1_14WorldUpgrade.java | 199 -------- .../impl/v1_9/upgrade/v1_16WorldUpgrade.java | 131 ----- .../impl/v1_9/upgrade/v1_17WorldUpgrade.java | 48 -- .../impl/v1_9/upgrade/v1_18WorldUpgrade.java | 360 ------------- .../impl/v1_9/upgrade/v1_9WorldUpgrade.java | 51 -- .../reader/impl/v1_9/v1_9SlimeChunk.java | 45 -- .../impl/v1_9/v1_9SlimeChunkSection.java | 35 -- .../reader/impl/v1_9/v1_9SlimeWorld.java | 35 -- .../impl/v1_9/v1_9SlimeWorldDeserializer.java | 480 ------------------ .../reader/impl/v1_9/v1_9WorldFormat.java | 7 - .../reader/impl/v1_9/v1_v9SlimeConverter.java | 131 ----- 19 files changed, 2090 deletions(-) delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10WorldFormat.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11WorldFormat.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/Upgrade.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9WorldFormat.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java index f8f19e057..67ecd8a7c 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java @@ -6,10 +6,7 @@ import com.infernalsuite.asp.api.utils.SlimeFormat; import com.infernalsuite.asp.api.world.SlimeWorld; import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; -import com.infernalsuite.asp.serialization.slime.reader.impl.v11.v11WorldFormat; import com.infernalsuite.asp.serialization.slime.reader.impl.v12.v12WorldFormat; -import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9WorldFormat; -import com.infernalsuite.asp.serialization.slime.reader.impl.v10.v10WorldFormat; import java.io.ByteArrayInputStream; import java.io.DataInputStream; @@ -23,9 +20,6 @@ public class SlimeWorldReaderRegistry { private static final Map> FORMATS = new HashMap<>(); static { - register(v1_9WorldFormat.FORMAT, 1, 2, 3, 4, 5, 6, 7, 8, 9); - register(v10WorldFormat.FORMAT, 10); - register(v11WorldFormat.FORMAT, 11); register(v12WorldFormat.FORMAT, 12); } diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java deleted file mode 100644 index 3baf1fb1b..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java +++ /dev/null @@ -1,205 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v10; - -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.DoubleTag; -import com.flowpowered.nbt.IntTag; -import com.flowpowered.nbt.ListTag; -import com.flowpowered.nbt.stream.NBTInputStream; -import com.github.luben.zstd.Zstd; -import com.infernalsuite.asp.Util; -import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; -import com.infernalsuite.asp.api.loaders.SlimeLoader; -import com.infernalsuite.asp.serialization.slime.reader.VersionedByteSlimeWorldReader; -import com.infernalsuite.asp.api.utils.NibbleArray; -import com.infernalsuite.asp.api.world.SlimeChunk; -import com.infernalsuite.asp.api.world.SlimeChunkSection; -import com.infernalsuite.asp.api.world.SlimeWorld; -import com.infernalsuite.asp.api.world.properties.SlimeProperties; -import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; - -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - - -class v10SlimeWorldDeSerializer implements VersionedByteSlimeWorldReader { - - public static final int ARRAY_SIZE = 16 * 16 * 16 / (8 / 4); // blocks / bytes per block - - @SuppressWarnings("unchecked") - @Override - public SlimeWorld deserializeWorld(byte version, SlimeLoader loader, String worldName, DataInputStream dataStream, SlimePropertyMap propertyMap, boolean readOnly) - throws IOException, CorruptedWorldException { - - // World version - int worldVersion = dataStream.readInt(); - // Chunk Data - - byte[] chunkBytes = readCompressed(dataStream); - Long2ObjectMap chunks = readChunks(propertyMap, chunkBytes); - - byte[] tileEntities = readCompressed(dataStream); - byte[] entities = readCompressed(dataStream); - byte[] extra = readCompressed(dataStream); - - // Entity deserialization - com.flowpowered.nbt.CompoundTag entitiesCompound = readCompound(entities); - { - List serializedEntities = ((ListTag) entitiesCompound.getValue().get("entities")).getValue(); - for (CompoundTag entityCompound : serializedEntities) { - ListTag listTag = (ListTag) entityCompound.getAsListTag("Pos").get(); - - int chunkX = listTag.getValue().get(0).getValue().intValue() >> 4; - int chunkZ = listTag.getValue().get(2).getValue().intValue() >> 4; - long chunkKey = Util.chunkPosition(chunkX, chunkZ); - SlimeChunk chunk = chunks.get(chunkKey); - if (chunk != null) { - chunk.getEntities().add(entityCompound); - } - } - } - - // Tile Entity deserialization - com.flowpowered.nbt.CompoundTag tileEntitiesCompound = readCompound(tileEntities); - for (CompoundTag tileEntityCompound : ((com.flowpowered.nbt.ListTag) tileEntitiesCompound.getValue().get("tiles")).getValue()) { - int chunkX = ((IntTag) tileEntityCompound.getValue().get("x")).getValue() >> 4; - int chunkZ = ((IntTag) tileEntityCompound.getValue().get("z")).getValue() >> 4; - long pos = Util.chunkPosition(chunkX, chunkZ); - SlimeChunk chunk = chunks.get(pos); - - if (chunk == null) { - throw new CorruptedWorldException(worldName); - } - - chunk.getTileEntities().add(tileEntityCompound); - } - - // Extra Data - com.flowpowered.nbt.CompoundTag extraCompound = readCompound(extra); - - // World properties - SlimePropertyMap worldPropertyMap = propertyMap; - Optional propertiesMap = extraCompound - .getAsCompoundTag("properties") - .map(com.flowpowered.nbt.CompoundTag::getValue); - - if (propertiesMap.isPresent()) { - worldPropertyMap = new SlimePropertyMap(propertiesMap.get()); - worldPropertyMap.merge(propertyMap); // Override world properties - } - - return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld(worldName, loader, readOnly, chunks, - extraCompound, - worldPropertyMap, - worldVersion - ); - } - - private static Long2ObjectMap readChunks(SlimePropertyMap slimePropertyMap, byte[] bytes) throws IOException { - Long2ObjectMap chunkMap = new Long2ObjectOpenHashMap<>(); - DataInputStream chunkData = new DataInputStream(new ByteArrayInputStream(bytes)); - - int chunks = chunkData.readInt(); - for (int i = 0; i < chunks; i++) { - // coords - int x = chunkData.readInt(); - int z = chunkData.readInt(); - - // Height Maps - byte[] heightMapData = new byte[chunkData.readInt()]; - chunkData.read(heightMapData); - com.flowpowered.nbt.CompoundTag heightMaps = readCompound(heightMapData); - - // Chunk Sections - { - // See WorldUtils - int sectionAmount = slimePropertyMap.getValue(SlimeProperties.CHUNK_SECTION_MAX) - slimePropertyMap.getValue(SlimeProperties.CHUNK_SECTION_MIN) + 1; - SlimeChunkSection[] chunkSectionArray = new SlimeChunkSection[sectionAmount]; - - int sectionCount = chunkData.readInt(); - for (int sectionId = 0; sectionId < sectionCount; sectionId++) { - // Block Light Nibble Array - NibbleArray blockLightArray; - if (chunkData.readBoolean()) { - byte[] blockLightByteArray = new byte[ARRAY_SIZE]; - chunkData.read(blockLightByteArray); - blockLightArray = new NibbleArray(blockLightByteArray); - } else { - blockLightArray = null; - } - - // Sky Light Nibble Array - NibbleArray skyLightArray; - if (chunkData.readBoolean()) { - byte[] skyLightByteArray = new byte[ARRAY_SIZE]; - chunkData.read(skyLightByteArray); - skyLightArray = new NibbleArray(skyLightByteArray); - } else { - skyLightArray = null; - } - - // Block data - byte[] blockStateData = new byte[chunkData.readInt()]; - chunkData.read(blockStateData); - com.flowpowered.nbt.CompoundTag blockStateTag = readCompound(blockStateData); - - // Biome Data - byte[] biomeData = new byte[chunkData.readInt()]; - chunkData.read(biomeData); - com.flowpowered.nbt.CompoundTag biomeTag = readCompound(biomeData); - - chunkSectionArray[sectionId] = new com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton( - blockStateTag, - biomeTag, - blockLightArray, - skyLightArray); - } - - chunkMap.put(Util.chunkPosition(x, z), - new com.infernalsuite.asp.skeleton.SlimeChunkSkeleton(x, z, chunkSectionArray, heightMaps, new ArrayList<>(), new ArrayList<>(), new CompoundTag("", new CompoundMap()), null) - ); - } - } - - return chunkMap; - } - - private static int[] toIntArray(byte[] buf) { - ByteBuffer buffer = ByteBuffer.wrap(buf).order(ByteOrder.BIG_ENDIAN); - int[] ret = new int[buf.length / 4]; - - buffer.asIntBuffer().get(ret); - - return ret; - } - - private static byte[] readCompressed(DataInputStream stream) throws IOException { - int compressedLength = stream.readInt(); - int normalLength = stream.readInt(); - byte[] compressed = new byte[compressedLength]; - byte[] normal = new byte[normalLength]; - - stream.read(compressed); - Zstd.decompress(normal, compressed); - return normal; - } - - private static com.flowpowered.nbt.CompoundTag readCompound(byte[] bytes) throws IOException { - if (bytes.length == 0) { - return null; - } - - NBTInputStream stream = new NBTInputStream(new ByteArrayInputStream(bytes), NBTInputStream.NO_COMPRESSION, ByteOrder.BIG_ENDIAN); - return (com.flowpowered.nbt.CompoundTag) stream.readTag(); - } - - -} \ No newline at end of file diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10WorldFormat.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10WorldFormat.java deleted file mode 100644 index 033377a17..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10WorldFormat.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v10; - -public interface v10WorldFormat { - - // Latest, returns same - com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat FORMAT = new com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat<>(data -> data, new v10SlimeWorldDeSerializer()); - -} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java deleted file mode 100644 index 5e664d1d2..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java +++ /dev/null @@ -1,159 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v11; - -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.ListTag; -import com.flowpowered.nbt.stream.NBTInputStream; -import com.github.luben.zstd.Zstd; -import com.infernalsuite.asp.Util; -import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; -import com.infernalsuite.asp.api.exceptions.NewerFormatException; -import com.infernalsuite.asp.api.loaders.SlimeLoader; -import com.infernalsuite.asp.api.utils.NibbleArray; -import com.infernalsuite.asp.api.world.SlimeChunk; -import com.infernalsuite.asp.api.world.SlimeChunkSection; -import com.infernalsuite.asp.api.world.SlimeWorld; -import com.infernalsuite.asp.api.world.properties.SlimeProperties; -import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import org.jetbrains.annotations.Nullable; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; -import java.nio.ByteOrder; -import java.util.List; -import java.util.Optional; - -public class v11SlimeWorldDeSerializer implements com.infernalsuite.asp.serialization.slime.reader.VersionedByteSlimeWorldReader { - - public static final int ARRAY_SIZE = 16 * 16 * 16 / (8 / 4); - - @Override - public SlimeWorld deserializeWorld(byte version, @Nullable SlimeLoader loader, String worldName, DataInputStream dataStream, SlimePropertyMap propertyMap, boolean readOnly) throws IOException, CorruptedWorldException, NewerFormatException { - int worldVersion = dataStream.readInt(); - - byte[] chunkBytes = readCompressed(dataStream); - Long2ObjectMap chunks = readChunks(propertyMap, chunkBytes); - - byte[] extraTagBytes = readCompressed(dataStream); - CompoundTag extraTag = readCompound(extraTagBytes); - - SlimePropertyMap worldPropertyMap = propertyMap; - Optional propertiesMap = extraTag - .getAsCompoundTag("properties") - .map(CompoundTag::getValue); - - if (propertiesMap.isPresent()) { - worldPropertyMap = new SlimePropertyMap(propertiesMap.get()); - worldPropertyMap.merge(propertyMap); - } - - return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld(worldName, loader, readOnly, chunks, extraTag, worldPropertyMap, worldVersion); - } - - private static Long2ObjectMap readChunks(SlimePropertyMap slimePropertyMap, byte[] chunkBytes) throws IOException { - Long2ObjectMap chunkMap = new Long2ObjectOpenHashMap<>(); - DataInputStream chunkData = new DataInputStream(new ByteArrayInputStream(chunkBytes)); - - int chunks = chunkData.readInt(); - for (int i = 0; i < chunks; i++) { - // ChunkPos - int x = chunkData.readInt(); - int z = chunkData.readInt(); - - // Sections - int sectionAmount = slimePropertyMap.getValue(SlimeProperties.CHUNK_SECTION_MAX) - slimePropertyMap.getValue(SlimeProperties.CHUNK_SECTION_MIN) + 1; - SlimeChunkSection[] chunkSections = new SlimeChunkSection[sectionAmount]; - - int sectionCount = chunkData.readInt(); - for (int sectionId = 0; sectionId < sectionCount; sectionId++) { - - // Block Light Nibble Array - NibbleArray blockLightArray; - if (chunkData.readBoolean()) { - byte[] blockLightByteArray = new byte[ARRAY_SIZE]; - chunkData.read(blockLightByteArray); - blockLightArray = new NibbleArray(blockLightByteArray); - } else { - blockLightArray = null; - } - - // Sky Light Nibble Array - NibbleArray skyLightArray; - if (chunkData.readBoolean()) { - byte[] skyLightByteArray = new byte[ARRAY_SIZE]; - chunkData.read(skyLightByteArray); - skyLightArray = new NibbleArray(skyLightByteArray); - } else { - skyLightArray = null; - } - - // Block Data - byte[] blockStateData = new byte[chunkData.readInt()]; - chunkData.read(blockStateData); - CompoundTag blockStateTag = readCompound(blockStateData); - - // Biome Data - byte[] biomeData = new byte[chunkData.readInt()]; - chunkData.read(biomeData); - CompoundTag biomeTag = readCompound(biomeData); - - chunkSections[sectionId] = new com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton(blockStateTag, biomeTag, blockLightArray, skyLightArray); - } - - // HeightMaps - byte[] heightMapData = new byte[chunkData.readInt()]; - chunkData.read(heightMapData); - CompoundTag heightMaps = readCompound(heightMapData); - - // Tile Entities - - int compressedTileEntitiesLength = chunkData.readInt(); - int decompressedTileEntitiesLength = chunkData.readInt(); - byte[] compressedTileEntitiesData = new byte[compressedTileEntitiesLength]; - byte[] decompressedTileEntitiesData = new byte[decompressedTileEntitiesLength]; - chunkData.read(compressedTileEntitiesData); - Zstd.decompress(decompressedTileEntitiesData, compressedTileEntitiesData); - - CompoundTag tileEntitiesCompound = readCompound(decompressedTileEntitiesData); - @SuppressWarnings("unchecked") - List serializedTileEntities = ((ListTag) tileEntitiesCompound.getValue().get("tileEntities")).getValue(); - - // Entities - - int compressedEntitiesLength = chunkData.readInt(); - int decompressedEntitiesLength = chunkData.readInt(); - byte[] compressedEntitiesData = new byte[compressedEntitiesLength]; - byte[] decompressedEntitiesData = new byte[decompressedEntitiesLength]; - chunkData.read(compressedEntitiesData); - Zstd.decompress(decompressedEntitiesData, compressedEntitiesData); - - CompoundTag entitiesCompound = readCompound(decompressedEntitiesData); - @SuppressWarnings("unchecked") - List serializedEntities = ((ListTag) entitiesCompound.getValue().get("entities")).getValue(); - - chunkMap.put(Util.chunkPosition(x, z), - new com.infernalsuite.asp.skeleton.SlimeChunkSkeleton(x, z, chunkSections, heightMaps, serializedTileEntities, serializedEntities, new CompoundTag("", new CompoundMap()), null)); - } - return chunkMap; - } - - private static byte[] readCompressed(DataInputStream stream) throws IOException { - int compressedLength = stream.readInt(); - int decompressedLength = stream.readInt(); - byte[] compressedData = new byte[compressedLength]; - byte[] decompressedData = new byte[decompressedLength]; - stream.read(compressedData); - Zstd.decompress(decompressedData, compressedData); - return decompressedData; - } - - private static CompoundTag readCompound(byte[] tagBytes) throws IOException { - if (tagBytes.length == 0) return null; - - NBTInputStream nbtStream = new NBTInputStream(new ByteArrayInputStream(tagBytes), NBTInputStream.NO_COMPRESSION, ByteOrder.BIG_ENDIAN); - return (CompoundTag) nbtStream.readTag(); - } -} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11WorldFormat.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11WorldFormat.java deleted file mode 100644 index 779eeb28b..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11WorldFormat.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v11; - -public interface v11WorldFormat { - - com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat FORMAT = new com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat<>(data -> data, new v11SlimeWorldDeSerializer()); - -} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/Upgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/Upgrade.java deleted file mode 100644 index 62f4254e6..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/Upgrade.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; - -public interface Upgrade { - - void upgrade(v1_9SlimeWorld world); - -} \ No newline at end of file diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java deleted file mode 100644 index 4e35d3ddd..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; - -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.StringTag; - -import java.util.HashMap; -import java.util.Map; - -public class v1_11WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { - - private static Map oldToNewMap = new HashMap<>(); - private static Map newToOldMap = new HashMap<>(); - - static { - rename("Furnace", "minecraft:furnace"); - rename("Chest", "minecraft:chest"); - rename("EnderChest", "minecraft:ender_chest"); - rename("RecordPlayer", "minecraft:jukebox"); - rename("Trap", "minecraft:dispenser"); - rename("Dropper", "minecraft:dropper"); - rename("Sign", "minecraft:sign"); - rename("MobSpawner", "minecraft:mob_spawner"); - rename("Music", "minecraft:noteblock"); - rename("Piston", "minecraft:piston"); - rename("Cauldron", "minecraft:brewing_stand"); - rename("EnchantTable", "minecraft:enchanting_table"); - rename("Airportal", "minecraft:end_portal"); - rename("Beacon", "minecraft:beacon"); - rename("Skull", "minecraft:skull"); - rename("DLDetector", "minecraft:daylight_detector"); - rename("Hopper", "minecraft:hopper"); - rename("Comparator", "minecraft:comparator"); - rename("FlowerPot", "minecraft:flower_pot"); - rename("Banner", "minecraft:banner"); - rename("Structure", "minecraft:structure_block"); - rename("EndGateway", "minecraft:end_gateway"); - rename("Control", "minecraft:command_block"); - rename(null, "minecraft:bed"); // Patch for issue s#62 - } - - private static void rename(String oldName, String newName) { - if (oldName != null) { - oldToNewMap.put(oldName, newName); - } - - newToOldMap.put(newName, oldName); - } - - @Override - public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld world) { - // 1.11 changed the way Tile Entities are named - for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : world.chunks.values()) { - for (CompoundTag entityTag : chunk.tileEntities) { - String oldType = entityTag.getAsStringTag("id").get().getValue(); - String newType = oldToNewMap.get(oldType); - - if (newType == null) { - if (newToOldMap.containsKey(oldType)) { // Maybe it's in the new format for some reason? - continue; - } - - throw new IllegalStateException("Failed to find 1.11 upgrade for tile entity " + oldType); - } - - entityTag.getValue().put("id", new StringTag("id", newType)); - } - } - } -} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java deleted file mode 100644 index 14d613582..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; - -import com.flowpowered.nbt.*; -import com.infernalsuite.asp.api.SlimeNMSBridge; -import com.infernalsuite.asp.api.utils.NibbleArray; -import org.bukkit.ChatColor; - -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Logger; - -public class v1_13WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { - - @Override - public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld world) { - Logger.getLogger("v1_13WorldUpgrade").warning("Updating world to the 1.13 format. This may take a while."); - - List chunks = new ArrayList<>(world.chunks.values()); - long lastMessage = -1; - - for (int i = 0; i < chunks.size(); i++) { - com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk = chunks.get(i); - - // The world upgrade process is a very complex task, and there's already a - // built-in upgrade tool inside the server, so we can simply use it - CompoundTag globalTag = new CompoundTag("", new CompoundMap()); - globalTag.getValue().put("DataVersion", new IntTag("DataVersion", 1343)); - - CompoundTag chunkTag = new CompoundTag("Level", new CompoundMap()); - - chunkTag.getValue().put("xPos", new IntTag("xPos", chunk.x)); - chunkTag.getValue().put("zPos", new IntTag("zPos", chunk.z)); - chunkTag.getValue().put("Sections", serializeSections(chunk.sections)); - chunkTag.getValue().put("Entities", new ListTag<>("Entities", TagType.TAG_COMPOUND, chunk.entities)); - chunkTag.getValue().put("TileEntities", new ListTag<>("TileEntities", TagType.TAG_COMPOUND, chunk.tileEntities)); - chunkTag.getValue().put("TileTicks", new ListTag<>("TileTicks", TagType.TAG_COMPOUND, new ArrayList<>())); - chunkTag.getValue().put("TerrainPopulated", new ByteTag("TerrainPopulated", (byte) 1)); - chunkTag.getValue().put("LightPopulated", new ByteTag("LightPopulated", (byte) 1)); - - globalTag.getValue().put("Level", chunkTag); - - globalTag = SlimeNMSBridge.instance().convertChunkTo1_13(globalTag); - chunkTag = globalTag.getAsCompoundTag("Level").get(); - - // Chunk sections - com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[] newSections = new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[16]; - ListTag serializedSections = (ListTag) chunkTag.getAsListTag("Sections").get(); - - for (CompoundTag sectionTag : serializedSections.getValue()) { - ListTag palette = (ListTag) sectionTag.getAsListTag("Palette").get(); - long[] blockStates = sectionTag.getLongArrayValue("BlockStates").get(); - - NibbleArray blockLight = new NibbleArray(sectionTag.getByteArrayValue("BlockLight").get()); - NibbleArray skyLight = new NibbleArray(sectionTag.getByteArrayValue("SkyLight").get()); - - int index = sectionTag.getIntValue("Y").get(); - - com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection section = new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection(null, null, palette, blockStates, null, null, blockLight, skyLight); - newSections[index] = section; - } - - // Biomes - int[] newBiomes = new int[256]; - - for (int index = 0; index < chunk.biomes.length; index++) { - newBiomes[index] = chunk.biomes[index] & 255; - } - - chunk.sections = newSections; - chunk.biomes = newBiomes; - - // Upgrade data - chunk.upgradeData = chunkTag.getAsCompoundTag("UpgradeData").orElse(null); - - int done = i + 1; - if (done == chunks.size()) { - Logger.getLogger("v1_13WorldUpgrade").info("World successfully converted to the 1.13 format!"); - } else if (System.currentTimeMillis() - lastMessage > 1000) { - int percentage = (done * 100) / chunks.size(); - Logger.getLogger("v1_13WorldUpgrade").info("Converting world... " + percentage + "%"); - lastMessage = System.currentTimeMillis(); - } - } - } - - private ListTag serializeSections(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[] sections) { - ListTag sectionList = new ListTag<>("Sections", TagType.TAG_COMPOUND, new ArrayList<>()); - - for (int i = 0; i < sections.length; i++) { - com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection section = sections[i]; - - if (section != null) { - CompoundTag sectionTag = new CompoundTag(i + "", new CompoundMap()); - - sectionTag.getValue().put("Y", new IntTag("Y", i)); - sectionTag.getValue().put("Blocks", new ByteArrayTag("Blocks", section.blocks)); - sectionTag.getValue().put("Data", new ByteArrayTag("Data", section.data.getBacking())); - sectionTag.getValue().put("BlockLight", new ByteArrayTag("Data", section.blockLight.getBacking())); - sectionTag.getValue().put("SkyLight", new ByteArrayTag("Data", section.skyLight.getBacking())); - - sectionList.getValue().add(sectionTag); - } - } - - return sectionList; - } -} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java deleted file mode 100644 index edd60c393..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java +++ /dev/null @@ -1,199 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; - -import com.flowpowered.nbt.*; -import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection; -import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld; - -import java.util.*; - -public class v1_14WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { - - private static final int[] VILLAGER_XP = { 0, 10, 50, 100, 150 }; - - private static Map oldToNewMap = new HashMap<>(); - private static Map newToOldMap = new HashMap<>(); - - static { - rename("minecraft:tube_coral_fan", "minecraft:tube_coral_wall_fan"); - rename("minecraft:brain_coral_fan", "minecraft:brain_coral_wall_fan"); - rename("minecraft:bubble_coral_fan", "minecraft:bubble_coral_wall_fan"); - rename("minecraft:fire_coral_fan", "minecraft:fire_coral_wall_fan"); - rename("minecraft:horn_coral_fan", "minecraft:horn_coral_wall_fan"); - rename("minecraft:stone_slab", "minecraft:smooth_stone_slab"); - rename("minecraft:sign", "minecraft:oak_sign"); - rename("minecraft:wall_sign", "minecraft:oak_wall_sign"); - } - - private static void rename(String oldName, String newName) { - oldToNewMap.put(oldName, newName); - newToOldMap.put(newName, oldName); - } - - @Override - public void upgrade(v1_9SlimeWorld world) { - for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : new ArrayList<>(world.chunks.values())) { - // Update renamed blocks - for (int sectionIndex = 0; sectionIndex < chunk.sections.length; sectionIndex++) { - v1_9SlimeChunkSection section = chunk.sections[sectionIndex]; - - if (section != null) { - List palette = section.palette.getValue(); - - for (int paletteIndex = 0; paletteIndex < palette.size(); paletteIndex++) { - CompoundTag blockTag = palette.get(paletteIndex); - String name = blockTag.getStringValue("Name").get(); - - // Trapped chests have now a different tile entity, - // so we have to update every block entity type - if (name.equals("minecraft:trapped_chest")) { - updateBlockEntities(chunk, sectionIndex, paletteIndex, "minecraft:chest", "minecraft:trapped_chest"); - } - - String newName = oldToNewMap.get(name); - - if (newName != null) { - blockTag.getValue().put("Name", new StringTag("Name", newName)); - } - } - } - } - - if (chunk.entities != null) { - for (CompoundTag entityTag : chunk.entities) { - String type = entityTag.getStringValue("id").get(); - - switch (type) { - case "minecraft:ocelot": - // Cats are no longer ocelots - int catType = entityTag.getIntValue("CatType").orElse(0); - - if (catType == 0) { - Optional owner = entityTag.getStringValue("Owner"); - Optional ownerId = entityTag.getStringValue("OwnerUUID"); - - if (owner.isPresent() || ownerId.isPresent()) { - entityTag.getValue().put("Trusting", new ByteTag("Trusting", (byte) 1)); - } - - entityTag.getValue().remove("CatType"); - } else if (catType > 0 && catType < 4) { - entityTag.getValue().put("id", new StringTag("id", "minecraft:cat")); - } - break; - case "minecraft:villager": - case "minecraft:zombie_villager": - // Villager data has changed - int profession = entityTag.getIntValue("Profession").orElse(0); - int career = entityTag.getIntValue("Career").orElse(0); - int careerLevel = entityTag.getIntValue("CareerLevel").orElse(1); - - // Villager level and xp has to be rebuilt - Optional offersOpt = entityTag.getAsCompoundTag("Offers"); - - if (offersOpt.isPresent()) { - if (careerLevel == 0 || careerLevel == 1) { - int amount = offersOpt.flatMap((offers) -> offers.getAsCompoundTag("Recipes")).map((recipes) -> recipes.getValue().size()).orElse(0); - careerLevel = clamp(amount / 2, 1, 5); - } - } - - Optional xp = entityTag.getAsCompoundTag("Xp"); - - if (!xp.isPresent()) { - entityTag.getValue().put("Xp", new IntTag("Xp", VILLAGER_XP[clamp(careerLevel - 1, 0, VILLAGER_XP.length - 1)])); - } - - entityTag.getValue().remove("Profession"); - entityTag.getValue().remove("Career"); - entityTag.getValue().remove("CareerLevel"); - - CompoundMap dataMap = new CompoundMap(); - dataMap.put("type", new StringTag("type", "minecraft:plains")); - dataMap.put("profession", new StringTag("profession", getVillagerProfession(profession, career))); - dataMap.put("level", new IntTag("level", careerLevel)); - - entityTag.getValue().put("VillagerData", new CompoundTag("VillagerData", dataMap)); - break; - case "minecraft:banner": - // The illager banners changed the translation message - Optional customName = entityTag.getStringValue("CustomName"); - - if (customName.isPresent()) { - String newName = customName.get().replace("\"translate\":\"block.minecraft.illager_banner\"", - "\"translate\":\"block.minecraft.ominous_banner\""); - - entityTag.getValue().put("CustomName", new StringTag("CustomName", newName)); - } - break; - } - } - } - } - } - - private int clamp(int i, int i1, int i2) { - return i < i1 ? i1 : (i > i2 ? i2 : i); - } - - private String getVillagerProfession(int profession, int career) { - return profession == 0 ? (career == 2 ? "minecraft:fisherman" : (career == 3 ? "minecraft:shepherd" : (career == 4 ? "minecraft:fletcher" : "minecraft:farmer"))) - : (profession == 1 ? (career == 2 ? "minecraft:cartographer" : "minecraft:librarian") : (profession == 2 ? "minecraft:cleric" : - (profession == 3 ? (career == 2 ? "minecraft:weaponsmith" : (career == 3 ? "minecraft:toolsmith" : "minecraft:armorer")) : - (profession == 4 ? (career == 2 ? "minecraft:leatherworker" : "minecraft:butcher") : (profession == 5 ? "minecraft:nitwit" : "minecraft:none"))))); - } - - private void updateBlockEntities(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk, int sectionIndex, int paletteIndex, String oldName, String newName) { - if (chunk.tileEntities != null) { - v1_9SlimeChunkSection section = chunk.sections[sectionIndex]; - long[] blockData = section.blockStates; - - int bitsPerBlock = Math.max(4, blockData.length * 64 / 4096); - long maxEntryValue = (1L << bitsPerBlock) - 1; - - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++) { - int arrayIndex = y << 8 | z << 4 | x; - int bitIndex = arrayIndex * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((arrayIndex + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - - int val; - - if (startIndex == endIndex) { - val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue); - } else { - int endBitSubIndex = 64 - startBitSubIndex; - val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); - } - - // It's the right block type - if (val == paletteIndex) { - int blockX = x + chunk.x * 16; - int blockY = y + sectionIndex * 16; - int blockZ = z + chunk.z * 16; - - for (CompoundTag tileEntityTag : chunk.tileEntities) { - int tileX = tileEntityTag.getIntValue("x").get(); - int tileY = tileEntityTag.getIntValue("y").get(); - int tileZ = tileEntityTag.getIntValue("z").get(); - - if (tileX == blockX && tileY == blockY && tileZ == blockZ) { - String type = tileEntityTag.getStringValue("id").get(); - - if (!type.equals(oldName)) { - throw new IllegalStateException("Expected block entity to be " + oldName + ", not " + type); - } - - tileEntityTag.getValue().put("id", new StringTag("id", newName)); - break; - } - } - } - } - } - } - } - } -} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java deleted file mode 100644 index 520f88142..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java +++ /dev/null @@ -1,131 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; - -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.LongArrayTag; -import com.flowpowered.nbt.Tag; -import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection; -import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld; - -import java.util.Arrays; - -public class v1_16WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { - - private static final int[] MULTIPLY_DE_BRUIJN_BIT_POSITION = new int[]{ - 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 - }; - - @Override - public void upgrade(v1_9SlimeWorld world) { - for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : world.chunks.values()) { - // Add padding to height maps and block states - CompoundTag heightMaps = chunk.heightMap; - - for (Tag map : heightMaps.getValue().values()) { - if (map instanceof LongArrayTag arrayTag) { - arrayTag.setValue(addPadding(256, 9, arrayTag.getValue())); - } - } - - for (int sectionIndex = 0; sectionIndex < chunk.sections.length; sectionIndex++) { - v1_9SlimeChunkSection section = chunk.sections[sectionIndex]; - - if (section != null) { - int bitsPerBlock = Math.max(4, ceillog2(section.palette.getValue().size())); - - if (!isPowerOfTwo(bitsPerBlock)) { - section = new v1_9SlimeChunkSection(null, null, section.palette, - addPadding(4096, bitsPerBlock, section.blockStates), null, null, - section.blockLight, section.skyLight); - chunk.sections[sectionIndex] = section; - } - } - } - - // Update biome array size - int[] newBiomes = new int[1024]; - Arrays.fill(newBiomes, -1); - int[] biomes = chunk.biomes; - System.arraycopy(biomes, 0, newBiomes, 0, biomes.length); - - chunk.biomes = newBiomes; - } - } - - private static int ceillog2(int input) { - input = isPowerOfTwo(input) ? input : smallestEncompassingPowerOfTwo(input); - return MULTIPLY_DE_BRUIJN_BIT_POSITION[(int) ((long) input * 125613361L >> 27) & 31]; - } - - private static int smallestEncompassingPowerOfTwo(int input) { - int result = input - 1; - result |= result >> 1; - result |= result >> 2; - result |= result >> 4; - result |= result >> 8; - result |= result >> 16; - return result + 1; - } - - private static boolean isPowerOfTwo(int input) { - return input != 0 && (input & input - 1) == 0; - } - - // Taken from DataConverterBitStorageAlign.java - private static long[] addPadding(int indices, int bitsPerIndex, long[] originalArray) { - int k = originalArray.length; - - if (k == 0) { - return originalArray; - } - - long l = (1L << bitsPerIndex) - 1L; - int i1 = 64 / bitsPerIndex; - int j1 = (indices + i1 - 1) / i1; - long[] along1 = new long[j1]; - int k1 = 0; - int l1 = 0; - long i2 = 0L; - int j2 = 0; - long k2 = originalArray[0]; - long l2 = k > 1 ? originalArray[1] : 0L; - - for (int i3 = 0; i3 < indices; ++i3) { - int j3 = i3 * bitsPerIndex; - int k3 = j3 >> 6; - int l3 = (i3 + 1) * bitsPerIndex - 1 >> 6; - int i4 = j3 ^ k3 << 6; - - if (k3 != j2) { - k2 = l2; - l2 = k3 + 1 < k ? originalArray[k3 + 1] : 0L; - j2 = k3; - } - - long j4; - int k4; - - if (k3 == l3) { - j4 = k2 >>> i4 & l; - } else { - k4 = 64 - i4; - j4 = (k2 >>> i4 | l2 << k4) & l; - } - - k4 = l1 + bitsPerIndex; - if (k4 >= 64) { - along1[k1++] = i2; - i2 = j4; - l1 = bitsPerIndex; - } else { - i2 |= j4 << l1; - l1 = k4; - } - } - - if (i2 != 0L) { - along1[k1] = i2; - } - - return along1; - } -} \ No newline at end of file diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java deleted file mode 100644 index 0455b9c33..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; - -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.StringTag; - -import java.util.List; -import java.util.Optional; - -public class v1_17WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { - - @Override - public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld world) { - for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : world.chunks.values()) { - for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection section : chunk.sections) { - if (section == null) { - continue; - } - - List palette = section.palette.getValue(); - - for (CompoundTag blockTag : palette) { - Optional name = blockTag.getStringValue("Name"); - CompoundMap map = blockTag.getValue(); - - // CauldronRenameFix - if (name.equals(Optional.of("minecraft:cauldron"))) { - Optional properties = blockTag.getAsCompoundTag("Properties"); - if (properties.isPresent()) { - String waterLevel = blockTag.getStringValue("level").orElse("0"); - if (waterLevel.equals("0")) { - map.remove("Properties"); - } else { - map.put("Name", new StringTag("Name", "minecraft:water_cauldron")); - } - } - } - - // Renamed grass path item to dirt path - if (name.equals(Optional.of("minecraft:grass_path"))) { - map.put("Name", new StringTag("Name", "minecraft:dirt_path")); - } - } - } - } - } - -} \ No newline at end of file diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java deleted file mode 100644 index c1e0bc799..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java +++ /dev/null @@ -1,360 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; - -import com.flowpowered.nbt.*; - -import java.util.*; - -public class v1_18WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { - - private static final String[] BIOMES_BY_ID = new String[256]; // rip datapacks - - static { - BIOMES_BY_ID[0] = "minecraft:ocean"; - BIOMES_BY_ID[1] = "minecraft:plains"; - BIOMES_BY_ID[2] = "minecraft:desert"; - BIOMES_BY_ID[3] = "minecraft:mountains"; - BIOMES_BY_ID[4] = "minecraft:forest"; - BIOMES_BY_ID[5] = "minecraft:taiga"; - BIOMES_BY_ID[6] = "minecraft:swamp"; - BIOMES_BY_ID[7] = "minecraft:river"; - BIOMES_BY_ID[8] = "minecraft:nether_wastes"; - BIOMES_BY_ID[9] = "minecraft:the_end"; - BIOMES_BY_ID[10] = "minecraft:frozen_ocean"; - BIOMES_BY_ID[11] = "minecraft:frozen_river"; - BIOMES_BY_ID[12] = "minecraft:snowy_tundra"; - BIOMES_BY_ID[13] = "minecraft:snowy_mountains"; - BIOMES_BY_ID[14] = "minecraft:mushroom_fields"; - BIOMES_BY_ID[15] = "minecraft:mushroom_field_shore"; - BIOMES_BY_ID[16] = "minecraft:beach"; - BIOMES_BY_ID[17] = "minecraft:desert_hills"; - BIOMES_BY_ID[18] = "minecraft:wooded_hills"; - BIOMES_BY_ID[19] = "minecraft:taiga_hills"; - BIOMES_BY_ID[20] = "minecraft:mountain_edge"; - BIOMES_BY_ID[21] = "minecraft:jungle"; - BIOMES_BY_ID[22] = "minecraft:jungle_hills"; - BIOMES_BY_ID[23] = "minecraft:jungle_edge"; - BIOMES_BY_ID[24] = "minecraft:deep_ocean"; - BIOMES_BY_ID[25] = "minecraft:stone_shore"; - BIOMES_BY_ID[26] = "minecraft:snowy_beach"; - BIOMES_BY_ID[27] = "minecraft:birch_forest"; - BIOMES_BY_ID[28] = "minecraft:birch_forest_hills"; - BIOMES_BY_ID[29] = "minecraft:dark_forest"; - BIOMES_BY_ID[30] = "minecraft:snowy_taiga"; - BIOMES_BY_ID[31] = "minecraft:snowy_taiga_hills"; - BIOMES_BY_ID[32] = "minecraft:giant_tree_taiga"; - BIOMES_BY_ID[33] = "minecraft:giant_tree_taiga_hills"; - BIOMES_BY_ID[34] = "minecraft:wooded_mountains"; - BIOMES_BY_ID[35] = "minecraft:savanna"; - BIOMES_BY_ID[36] = "minecraft:savanna_plateau"; - BIOMES_BY_ID[37] = "minecraft:badlands"; - BIOMES_BY_ID[38] = "minecraft:wooded_badlands_plateau"; - BIOMES_BY_ID[39] = "minecraft:badlands_plateau"; - BIOMES_BY_ID[40] = "minecraft:small_end_islands"; - BIOMES_BY_ID[41] = "minecraft:end_midlands"; - BIOMES_BY_ID[42] = "minecraft:end_highlands"; - BIOMES_BY_ID[43] = "minecraft:end_barrens"; - BIOMES_BY_ID[44] = "minecraft:warm_ocean"; - BIOMES_BY_ID[45] = "minecraft:lukewarm_ocean"; - BIOMES_BY_ID[46] = "minecraft:cold_ocean"; - BIOMES_BY_ID[47] = "minecraft:deep_warm_ocean"; - BIOMES_BY_ID[48] = "minecraft:deep_lukewarm_ocean"; - BIOMES_BY_ID[49] = "minecraft:deep_cold_ocean"; - BIOMES_BY_ID[50] = "minecraft:deep_frozen_ocean"; - BIOMES_BY_ID[127] = "minecraft:the_void"; - BIOMES_BY_ID[129] = "minecraft:sunflower_plains"; - BIOMES_BY_ID[130] = "minecraft:desert_lakes"; - BIOMES_BY_ID[131] = "minecraft:gravelly_mountains"; - BIOMES_BY_ID[132] = "minecraft:flower_forest"; - BIOMES_BY_ID[133] = "minecraft:taiga_mountains"; - BIOMES_BY_ID[134] = "minecraft:swamp_hills"; - BIOMES_BY_ID[140] = "minecraft:ice_spikes"; - BIOMES_BY_ID[149] = "minecraft:modified_jungle"; - BIOMES_BY_ID[151] = "minecraft:modified_jungle_edge"; - BIOMES_BY_ID[155] = "minecraft:tall_birch_forest"; - BIOMES_BY_ID[156] = "minecraft:tall_birch_hills"; - BIOMES_BY_ID[157] = "minecraft:dark_forest_hills"; - BIOMES_BY_ID[158] = "minecraft:snowy_taiga_mountains"; - BIOMES_BY_ID[160] = "minecraft:giant_spruce_taiga"; - BIOMES_BY_ID[161] = "minecraft:giant_spruce_taiga_hills"; - BIOMES_BY_ID[162] = "minecraft:modified_gravelly_mountains"; - BIOMES_BY_ID[163] = "minecraft:shattered_savanna"; - BIOMES_BY_ID[164] = "minecraft:shattered_savanna_plateau"; - BIOMES_BY_ID[165] = "minecraft:eroded_badlands"; - BIOMES_BY_ID[166] = "minecraft:modified_wooded_badlands_plateau"; - BIOMES_BY_ID[167] = "minecraft:modified_badlands_plateau"; - BIOMES_BY_ID[168] = "minecraft:bamboo_jungle"; - BIOMES_BY_ID[169] = "minecraft:bamboo_jungle_hills"; - BIOMES_BY_ID[170] = "minecraft:soul_sand_valley"; - BIOMES_BY_ID[171] = "minecraft:crimson_forest"; - BIOMES_BY_ID[172] = "minecraft:warped_forest"; - BIOMES_BY_ID[173] = "minecraft:basalt_deltas"; - BIOMES_BY_ID[174] = "minecraft:dripstone_caves"; - BIOMES_BY_ID[175] = "minecraft:lush_caves"; - BIOMES_BY_ID[177] = "minecraft:meadow"; - BIOMES_BY_ID[178] = "minecraft:grove"; - BIOMES_BY_ID[179] = "minecraft:snowy_slopes"; - BIOMES_BY_ID[180] = "minecraft:snowcapped_peaks"; - BIOMES_BY_ID[181] = "minecraft:lofty_peaks"; - BIOMES_BY_ID[182] = "minecraft:stony_peaks"; - } - - public static final Map BIOME_UPDATE = new HashMap<>(); - - static { - BIOME_UPDATE.put("minecraft:badlands_plateau", "minecraft:badlands"); - BIOME_UPDATE.put("minecraft:bamboo_jungle_hills", "minecraft:bamboo_jungle"); - BIOME_UPDATE.put("minecraft:birch_forest_hills", "minecraft:birch_forest"); - BIOME_UPDATE.put("minecraft:dark_forest_hills", "minecraft:dark_forest"); - BIOME_UPDATE.put("minecraft:desert_hills", "minecraft:desert"); - BIOME_UPDATE.put("minecraft:desert_lakes", "minecraft:desert"); - BIOME_UPDATE.put("minecraft:giant_spruce_taiga_hills", "minecraft:old_growth_spruce_taiga"); - BIOME_UPDATE.put("minecraft:giant_spruce_taiga", "minecraft:old_growth_spruce_taiga"); - BIOME_UPDATE.put("minecraft:giant_tree_taiga_hills", "minecraft:old_growth_pine_taiga"); - BIOME_UPDATE.put("minecraft:giant_tree_taiga", "minecraft:old_growth_pine_taiga"); - BIOME_UPDATE.put("minecraft:gravelly_mountains", "minecraft:windswept_gravelly_hills"); - BIOME_UPDATE.put("minecraft:jungle_edge", "minecraft:sparse_jungle"); - BIOME_UPDATE.put("minecraft:jungle_hills", "minecraft:jungle"); - BIOME_UPDATE.put("minecraft:modified_badlands_plateau", "minecraft:badlands"); - BIOME_UPDATE.put("minecraft:modified_gravelly_mountains", "minecraft:windswept_gravelly_hills"); - BIOME_UPDATE.put("minecraft:modified_jungle_edge", "minecraft:sparse_jungle"); - BIOME_UPDATE.put("minecraft:modified_jungle", "minecraft:jungle"); - BIOME_UPDATE.put("minecraft:modified_wooded_badlands_plateau", "minecraft:wooded_badlands"); - BIOME_UPDATE.put("minecraft:mountain_edge", "minecraft:windswept_hills"); - BIOME_UPDATE.put("minecraft:mountains", "minecraft:windswept_hills"); - BIOME_UPDATE.put("minecraft:mushroom_field_shore", "minecraft:mushroom_fields"); - BIOME_UPDATE.put("minecraft:shattered_savanna", "minecraft:windswept_savanna"); - BIOME_UPDATE.put("minecraft:shattered_savanna_plateau", "minecraft:windswept_savanna"); - BIOME_UPDATE.put("minecraft:snowy_mountains", "minecraft:snowy_plains"); - BIOME_UPDATE.put("minecraft:snowy_taiga_hills", "minecraft:snowy_taiga"); - BIOME_UPDATE.put("minecraft:snowy_taiga_mountains", "minecraft:snowy_taiga"); - BIOME_UPDATE.put("minecraft:snowy_tundra", "minecraft:snowy_plains"); - BIOME_UPDATE.put("minecraft:stone_shore", "minecraft:stony_shore"); - BIOME_UPDATE.put("minecraft:swamp_hills", "minecraft:swamp"); - BIOME_UPDATE.put("minecraft:taiga_hills", "minecraft:taiga"); - BIOME_UPDATE.put("minecraft:taiga_mountains", "minecraft:taiga"); - BIOME_UPDATE.put("minecraft:tall_birch_forest", "minecraft:old_growth_birch_forest"); - BIOME_UPDATE.put("minecraft:tall_birch_hills", "minecraft:old_growth_birch_forest"); - BIOME_UPDATE.put("minecraft:wooded_badlands_plateau", "minecraft:wooded_badlands"); - BIOME_UPDATE.put("minecraft:wooded_hills", "minecraft:forest"); - BIOME_UPDATE.put("minecraft:wooded_mountains", "minecraft:windswept_forest"); - BIOME_UPDATE.put("minecraft:lofty_peaks", "minecraft:jagged_peaks"); - BIOME_UPDATE.put("minecraft:snowcapped_peaks", "minecraft:frozen_peaks"); - } - - @Override - public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld world) { - for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : world.chunks.values()) { - - // SpawnerSpawnDataFix - for (CompoundTag tileEntity : chunk.tileEntities) { - CompoundMap value = tileEntity.getValue(); - Optional id = tileEntity.getStringValue("id"); - if (id.equals(Optional.of("minecraft:mob_spawner"))) { - Optional> spawnPotentials = tileEntity.getAsListTag("SpawnPotentials"); - Optional spawnData = tileEntity.getAsCompoundTag("SpawnData"); - if (spawnPotentials.isPresent()) { - ListTag spawnPotentialsList = (ListTag) spawnPotentials.get(); - List spawnPotentialsListValue = spawnPotentialsList.getValue(); - for (CompoundTag spawnPotentialsTag : spawnPotentialsListValue) { - CompoundMap spawnPotentialsValue = spawnPotentialsTag.getValue(); - Optional weight = spawnPotentialsTag.getIntValue("Weight"); - if (weight.isPresent()) { - int weightVal = weight.get(); - spawnPotentialsValue.remove("Weight"); - spawnPotentialsValue.put("weight", new IntTag("weight", weightVal)); - } - Optional entity = spawnPotentialsTag.getAsCompoundTag("Entity"); - if (entity.isPresent()) { - CompoundTag entityTag = entity.get(); - spawnPotentialsValue.remove("Entity"); - entityTag.getValue(); - CompoundMap dataMap = new CompoundMap(); - dataMap.put(new CompoundTag("entity", entityTag.getValue())); - spawnPotentialsValue.put("data", new CompoundTag("data", dataMap)); - } - } - value.put("SpawnPotentials", spawnPotentialsList); - if (!spawnPotentialsListValue.isEmpty()) { - CompoundTag compoundTag = spawnPotentialsListValue.get(0); - CompoundTag entityTag = compoundTag.getAsCompoundTag("data"). - get().getAsCompoundTag("entity").get(); - CompoundMap spawnDataMap = new CompoundMap(); - spawnDataMap.put(entityTag.clone()); - value.put("SpawnData", new CompoundTag("SpawnData", spawnDataMap)); - } - } else if (spawnData.isPresent()) { - CompoundTag spawnDataTag = spawnData.get(); - CompoundMap spawnDataValue = spawnDataTag.getValue(); - Optional entityTag = spawnDataTag.getAsCompoundTag("entity"); - Optional idTag = spawnDataTag.getAsStringTag("id"); - if (entityTag.isEmpty() && idTag.isPresent()) { - StringTag entityTypeTag = idTag.get(); - spawnDataValue.remove("id"); - CompoundMap entityMap = new CompoundMap(); - entityMap.put(entityTypeTag); - spawnDataValue.put("entity", new CompoundTag("entity", entityMap)); - value.put("SpawnData", spawnDataTag); - } - } - } - } - - CompoundTag[] tags = createBiomeSections(chunk.biomes, false, 0); - - com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[] sections = chunk.sections; - for (int i = 0; i < sections.length; i++) { - com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection section = sections[i]; - if (section == null) { - continue; - } - - - section.blockStatesTag = wrapPalette(section.palette, section.blockStates); - section.biomeTag = tags[i]; - } - - com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[] shiftedSections = new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[sections.length + 4]; - System.arraycopy(sections, 0, shiftedSections, 4, sections.length); - - chunk.sections = shiftedSections; // Shift all sections up 4 - - - com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[] sectionArray = chunk.sections; - - CompoundMap emptyBiomes = new CompoundMap(); - emptyBiomes.put("palette", new ListTag<>("palette", TagType.TAG_STRING, List.of(new StringTag("", "minecraft:plains")))); - - CompoundMap blocks = new CompoundMap(); - emptyBiomes.put("palette", new ListTag<>("palette", TagType.TAG_STRING, List.of(new StringTag("", "minecraft:air")))); - - CompoundTag blockTag = new CompoundTag("", blocks); - CompoundTag emptyBiomesTag = new CompoundTag("", emptyBiomes); - for (int i = 0; i < sectionArray.length; i++) { - com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection section = sectionArray[i]; - if (section == null) { - sectionArray[i] = new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection( - null, - null, - null, - null, - blockTag, - emptyBiomesTag, - null, - null - ); - } - } - } - } - - private static CompoundTag[] createBiomeSections(int[] biomes, final boolean wantExtendedHeight, final int minSection) { - final CompoundTag[] ret = new CompoundTag[wantExtendedHeight ? 24 : 16]; - - if (biomes != null && biomes.length == 1536) { // magic value for 24 sections of biomes (24 * 4^3) - //isAlreadyExtended.setValue(true); - for (int sectionIndex = 0; sectionIndex < 24; ++sectionIndex) { - ret[sectionIndex] = createBiomeSection(biomes, sectionIndex * 64, -1); // -1 is all 1s - } - } else if (biomes != null && biomes.length == 1024) { // magic value for 24 sections of biomes (16 * 4^3) - for (int sectionY = 0; sectionY < 16; ++sectionY) { - ret[sectionY - minSection] = createBiomeSection(biomes, sectionY * 64, -1); // -1 is all 1s - } - -// if (wantExtendedHeight) { -// // must set the new sections at top and bottom -// final MapType bottomCopy = createBiomeSection(biomes, 0, 15); // just want the biomes at y = 0 -// final MapType topCopy = createBiomeSection(biomes, 1008, 15); // just want the biomes at y = 252 -// -// for (int sectionIndex = 0; sectionIndex < 4; ++sectionIndex) { -// ret[sectionIndex] = bottomCopy.copy(); // copy palette so that later possible modifications don't trash all sections -// } -// -// for (int sectionIndex = 20; sectionIndex < 24; ++sectionIndex) { -// ret[sectionIndex] = topCopy.copy(); // copy palette so that later possible modifications don't trash all sections -// } -// } - } else { - ArrayList palette = new ArrayList<>(); - palette.add(new StringTag("", "minecraft:plains")); - - for (int i = 0; i < ret.length; ++i) { - ret[i] = wrapPalette(new ListTag<>("", TagType.TAG_STRING, palette).clone(), null); // copy palette so that later possible modifications don't trash all sections - } - } - - return ret; - } - - public static int ceilLog2(final int value) { - return value == 0 ? 0 : Integer.SIZE - Integer.numberOfLeadingZeros(value - 1); // see doc of numberOfLeadingZeros - } - - private static CompoundTag createBiomeSection(final int[] biomes, final int offset, final int mask) { - final Map paletteId = new HashMap<>(); - - for (int idx = 0; idx < 64; ++idx) { - final int biome = biomes[offset + (idx & mask)]; - paletteId.putIfAbsent(biome, paletteId.size()); - } - - List paletteString = new ArrayList<>(); - for (final Iterator iterator = paletteId.keySet().iterator(); iterator.hasNext(); ) { - final int biomeId = iterator.next(); - String biome = biomeId >= 0 && biomeId < BIOMES_BY_ID.length ? BIOMES_BY_ID[biomeId] : null; - String update = BIOME_UPDATE.get(biome); - if (update != null) { - biome = update; - } - - paletteString.add(new StringTag("", biome == null ? "minecraft:plains" : biome)); - } - - final int bitsPerObject = ceilLog2(paletteString.size()); - if (bitsPerObject == 0) { - return wrapPalette(new ListTag<>("", TagType.TAG_STRING, paletteString), null); - } - - // manually create packed integer data - final int objectsPerValue = 64 / bitsPerObject; - final long[] packed = new long[(64 + objectsPerValue - 1) / objectsPerValue]; - - int shift = 0; - int idx = 0; - long curr = 0; - - for (int biome_idx = 0; biome_idx < 64; ++biome_idx) { - final int biome = biomes[offset + (biome_idx & mask)]; - - curr |= ((long) paletteId.get(biome)) << shift; - - shift += bitsPerObject; - - if (shift + bitsPerObject > 64) { // will next write overflow? - // must move to next idx - packed[idx++] = curr; - shift = 0; - curr = 0L; - } - } - - // don't forget to write the last one - if (shift != 0) { - packed[idx] = curr; - } - - return wrapPalette(new ListTag<>("", TagType.TAG_STRING, paletteString), packed); - } - - private static CompoundTag wrapPalette(ListTag palette, final long[] blockStates) { - CompoundMap map = new CompoundMap(); - CompoundTag tag = new CompoundTag("", map); - - map.put(new ListTag<>("palette", palette.getElementType(), palette.getValue())); - if (blockStates != null) { - map.put(new LongArrayTag("data", blockStates)); - } - - return tag; - } - -} \ No newline at end of file diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java deleted file mode 100644 index bc1a5c6b2..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; - -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.StringTag; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.JsonSyntaxException; -import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld; - -public class v1_9WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { - - private static final JsonParser PARSER = new JsonParser(); - - @Override - public void upgrade(v1_9SlimeWorld world) { - // In 1.9, all signs must be formatted using JSON - for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : world.chunks.values()) { - for (CompoundTag entityTag : chunk.tileEntities) { - String type = entityTag.getAsStringTag("id").get().getValue(); - - if (type.equals("Sign")) { - CompoundMap map = entityTag.getValue(); - - for (int i = 1; i < 5; i++) { - String id = "Text" + i; - - map.put(id, new StringTag(id, fixJson(entityTag.getAsStringTag(id).map(StringTag::getValue).orElse(null)))); - } - } - } - } - } - - private static String fixJson(String value) { - if (value == null || value.equalsIgnoreCase("null") || value.isEmpty()) { - return "{\"text\":\"\"}"; - } - - try { - PARSER.parse(value); - } catch (JsonSyntaxException ex) { - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("text", value); - - return jsonObject.toString(); - } - - return value; - } -} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java deleted file mode 100644 index 306f54fdd..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; - -import com.flowpowered.nbt.CompoundTag; - -import java.util.List; - -public final class v1_9SlimeChunk { - public final String worldName; - public final int x; - public final int z; - public v1_9SlimeChunkSection[] sections; - public final int minY; - public final int maxY; - public final CompoundTag heightMap; - public int[] biomes; - public final List tileEntities; - public final List entities; - // Used for 1.13 world upgrading - public CompoundTag upgradeData; - - v1_9SlimeChunk(String worldName, - int x, - int z, - v1_9SlimeChunkSection[] sections, - int minY, - int maxY, - CompoundTag heightMap, - int[] biomes, - List tileEntities, - List entities) { - this.worldName = worldName; - this.x = x; - this.z = z; - this.sections = sections; - this.minY = minY; - this.maxY = maxY; - this.heightMap = heightMap; - this.biomes = biomes; - this.tileEntities = tileEntities; - this.entities = entities; - } - -} - - diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java deleted file mode 100644 index 5379c3dbf..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; - -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.ListTag; -import com.infernalsuite.asp.api.utils.NibbleArray; - -public class v1_9SlimeChunkSection { - - // Pre 1.13 block data - public final byte[] blocks; - public final NibbleArray data; - - // Post 1.13 block data - public final ListTag palette; - public final long[] blockStates; - - // Post 1.17 block data - public CompoundTag blockStatesTag; - public CompoundTag biomeTag; - - public final NibbleArray blockLight; - public final NibbleArray skyLight; - - public v1_9SlimeChunkSection(byte[] blocks, NibbleArray data, ListTag palette, long[] blockStates, CompoundTag blockStatesTag, CompoundTag biomeTag, NibbleArray blockLight, NibbleArray skyLight) { - this.blocks = blocks; - this.data = data; - this.palette = palette; - this.blockStates = blockStates; - this.blockStatesTag = blockStatesTag; - this.biomeTag = biomeTag; - this.blockLight = blockLight; - this.skyLight = skyLight; - } - -} \ No newline at end of file diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java deleted file mode 100644 index 0864c6b92..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; - -import com.flowpowered.nbt.CompoundTag; -import com.infernalsuite.asp.api.loaders.SlimeLoader; -import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; - -public class v1_9SlimeWorld { - - public byte version; - public final String worldName; - public final SlimeLoader loader; - public final Long2ObjectMap chunks; - public final CompoundTag extraCompound; - public final SlimePropertyMap propertyMap; - public final boolean readOnly; - - public v1_9SlimeWorld(byte version, - String worldName, - SlimeLoader loader, - Long2ObjectMap chunks, - CompoundTag extraCompound, - SlimePropertyMap propertyMap, - boolean readOnly) { - this.version = version; - this.worldName = worldName; - this.loader = loader; - this.chunks = chunks; - this.extraCompound = extraCompound; - this.propertyMap = propertyMap; - this.readOnly = readOnly; - } - - -} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java deleted file mode 100644 index 07b7e24d3..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java +++ /dev/null @@ -1,480 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; - -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.DoubleTag; -import com.flowpowered.nbt.IntArrayTag; -import com.flowpowered.nbt.IntTag; -import com.flowpowered.nbt.ListTag; -import com.flowpowered.nbt.TagType; -import com.flowpowered.nbt.stream.NBTInputStream; -import com.github.luben.zstd.Zstd; -import com.infernalsuite.asp.SlimeLogger; -import com.infernalsuite.asp.Util; -import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; -import com.infernalsuite.asp.api.loaders.SlimeLoader; -import com.infernalsuite.asp.api.utils.NibbleArray; -import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; - -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.EOFException; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.List; -import java.util.Optional; - -class v1_9SlimeWorldDeserializer implements com.infernalsuite.asp.serialization.slime.reader.VersionedByteSlimeWorldReader { - - @Override - public v1_9SlimeWorld deserializeWorld(byte version, SlimeLoader loader, String worldName, DataInputStream dataStream, SlimePropertyMap propertyMap, boolean readOnly) - throws IOException, CorruptedWorldException { - - try { - - // World version - byte worldVersion; - - if (version >= 6) { - worldVersion = dataStream.readByte(); - } else if (version >= 4) { // In v4 there's just a boolean indicating whether the world is pre-1.13 or post-1.13 - worldVersion = (byte) (dataStream.readBoolean() ? 0x04 : 0x01); - } else { - worldVersion = 0; // We'll try to automatically detect it later - } - - // Chunk - short minX = dataStream.readShort(); - short minZ = dataStream.readShort(); - int width = dataStream.readShort(); - int depth = dataStream.readShort(); - - if (width <= 0 || depth <= 0) { - throw new CorruptedWorldException(worldName); - } - - int bitmaskSize = (int) Math.ceil((width * depth) / 8.0D); - byte[] chunkBitmask = new byte[bitmaskSize]; - dataStream.read(chunkBitmask); - BitSet chunkBitset = BitSet.valueOf(chunkBitmask); - - int compressedChunkDataLength = dataStream.readInt(); - int chunkDataLength = dataStream.readInt(); - byte[] compressedChunkData = new byte[compressedChunkDataLength]; - byte[] chunkData = new byte[chunkDataLength]; - - dataStream.read(compressedChunkData); - - // Tile Entities - int compressedTileEntitiesLength = dataStream.readInt(); - int tileEntitiesLength = dataStream.readInt(); - byte[] compressedTileEntities = new byte[compressedTileEntitiesLength]; - byte[] tileEntities = new byte[tileEntitiesLength]; - - dataStream.read(compressedTileEntities); - - // Entities - byte[] compressedEntities = new byte[0]; - byte[] entities = new byte[0]; - - if (version >= 3) { - boolean hasEntities = dataStream.readBoolean(); - - if (hasEntities) { - int compressedEntitiesLength = dataStream.readInt(); - int entitiesLength = dataStream.readInt(); - compressedEntities = new byte[compressedEntitiesLength]; - entities = new byte[entitiesLength]; - - dataStream.read(compressedEntities); - } - } - - // Extra NBT tag - byte[] compressedExtraTag = new byte[0]; - byte[] extraTag = new byte[0]; - - if (version >= 2) { - int compressedExtraTagLength = dataStream.readInt(); - int extraTagLength = dataStream.readInt(); - compressedExtraTag = new byte[compressedExtraTagLength]; - extraTag = new byte[extraTagLength]; - - dataStream.read(compressedExtraTag); - } - - // World Map NBT tag - byte[] compressedMapsTag = new byte[0]; - byte[] mapsTag = new byte[0]; - - if (version >= 7) { - int compressedMapsTagLength = dataStream.readInt(); - int mapsTagLength = dataStream.readInt(); - compressedMapsTag = new byte[compressedMapsTagLength]; - mapsTag = new byte[mapsTagLength]; - - dataStream.read(compressedMapsTag); - } - - if (dataStream.read() != -1) { - throw new CorruptedWorldException(worldName); - } - - // Data decompression - Zstd.decompress(chunkData, compressedChunkData); - Zstd.decompress(tileEntities, compressedTileEntities); - Zstd.decompress(entities, compressedEntities); - Zstd.decompress(extraTag, compressedExtraTag); - Zstd.decompress(mapsTag, compressedMapsTag); - - // Chunk deserialization - Long2ObjectMap chunks = readChunks(worldVersion, version, worldName, minX, minZ, width, depth, chunkBitset, chunkData); - - // Entity deserialization - CompoundTag entitiesCompound = readCompoundTag(entities); - - Long2ObjectMap> entityStorage = new Long2ObjectOpenHashMap<>(); - if (entitiesCompound != null) { - List serializedEntities = ((ListTag) entitiesCompound.getValue().get("entities")).getValue(); - - SlimeLogger.debug("Serialized entities: " + serializedEntities); - for (CompoundTag entityCompound : serializedEntities) { - ListTag listTag = (ListTag) entityCompound.getAsListTag("Pos").get(); - - int chunkX = floor(listTag.getValue().get(0).getValue()) >> 4; - int chunkZ = floor(listTag.getValue().get(2).getValue()) >> 4; - long chunkKey = Util.chunkPosition(chunkX, chunkZ); - v1_9SlimeChunk chunk = chunks.get(chunkKey); - if (chunk != null) { - chunk.entities.add(entityCompound); - } - if (entityStorage.containsKey(chunkKey)) { - entityStorage.get(chunkKey).add(entityCompound); - } else { - List entityStorageList = new ArrayList<>(); - entityStorageList.add(entityCompound); - entityStorage.put(chunkKey, entityStorageList); - } - } - } - - // Tile Entity deserialization - CompoundTag tileEntitiesCompound = readCompoundTag(tileEntities); - - if (tileEntitiesCompound != null) { - ListTag tileEntitiesList = (ListTag) tileEntitiesCompound.getValue().get("tiles"); - for (CompoundTag tileEntityCompound : tileEntitiesList.getValue()) { - int chunkX = ((IntTag) tileEntityCompound.getValue().get("x")).getValue() >> 4; - int chunkZ = ((IntTag) tileEntityCompound.getValue().get("z")).getValue() >> 4; - v1_9SlimeChunk chunk = chunks.get(Util.chunkPosition(chunkX, chunkZ)); - - if (chunk == null) { - throw new CorruptedWorldException(worldName); - } - - chunk.tileEntities.add(tileEntityCompound); - } - } - - // Extra Data - CompoundTag extraCompound = readCompoundTag(extraTag); - - if (extraCompound == null) { - extraCompound = new CompoundTag("", new CompoundMap()); - } - - if (version <= 0x05) {} - - // World Maps -// CompoundTag mapsCompound = readCompoundTag(mapsTag); -// List mapList; -// -// if (mapsCompound != null) { -// mapList = (List) mapsCompound.getAsListTag("maps").map(ListTag::getValue).orElse(new ArrayList<>()); -// } else { -// mapList = new ArrayList<>(); -// } - - - // World properties - SlimePropertyMap worldPropertyMap = propertyMap; - Optional propertiesMap = extraCompound - .getAsCompoundTag("properties") - .map(CompoundTag::getValue); - - if (propertiesMap.isPresent()) { - worldPropertyMap = new SlimePropertyMap(propertiesMap.get()); - worldPropertyMap.merge(propertyMap); // Override world properties - } else if (propertyMap == null) { // Make sure the property map is never null - worldPropertyMap = new SlimePropertyMap(); - } - - return new v1_9SlimeWorld( - worldVersion, - worldName, - loader, - chunks, - extraCompound, - propertyMap, - readOnly - ); - } catch (EOFException ex) { - throw new CorruptedWorldException(worldName, ex); - } - } - - private static int floor(double num) { - final int floor = (int) num; - return floor == num ? floor : floor - (int) (Double.doubleToRawLongBits(num) >>> 63); - } - - private static Long2ObjectMap readChunks(byte worldVersion, int version, String worldName, int minX, int minZ, int width, int depth, BitSet chunkBitset, byte[] chunkData) throws IOException { - DataInputStream dataStream = new DataInputStream(new ByteArrayInputStream(chunkData)); - Long2ObjectMap chunkMap = new Long2ObjectOpenHashMap<>(); - - for (int z = 0; z < depth; z++) { - for (int x = 0; x < width; x++) { - int bitsetIndex = z * width + x; - - if (chunkBitset.get(bitsetIndex)) { - // Height Maps - CompoundTag heightMaps; - - if (worldVersion >= 0x04) { - int heightMapsLength = dataStream.readInt(); - byte[] heightMapsArray = new byte[heightMapsLength]; - dataStream.read(heightMapsArray); - heightMaps = readCompoundTag(heightMapsArray); - - // Height Maps might be null if empty - if (heightMaps == null) { - heightMaps = new CompoundTag("", new CompoundMap()); - } - } else { - int[] heightMap = new int[256]; - - for (int i = 0; i < 256; i++) { - heightMap[i] = dataStream.readInt(); - } - - CompoundMap map = new CompoundMap(); - map.put("heightMap", new IntArrayTag("heightMap", heightMap)); - - heightMaps = new CompoundTag("", map); - } - - // Biome array - int[] biomes = null; - - if (version == 8 && worldVersion < 0x04) { - // Patch the v8 bug: biome array size is wrong for old worlds - dataStream.readInt(); - } - - if (worldVersion < 0x04) { - byte[] byteBiomes = new byte[256]; - dataStream.read(byteBiomes); - biomes = toIntArray(byteBiomes); - } else if (worldVersion < 0x08) { - int biomesArrayLength = version >= 8 ? dataStream.readInt() : 256; - biomes = new int[biomesArrayLength]; - - for (int i = 0; i < biomes.length; i++) { - biomes[i] = dataStream.readInt(); - } - } - - // Chunk Sections - ChunkSectionData data = worldVersion < 0x08 ? readChunkSections(dataStream, worldVersion, version) : readChunkSectionsNew(dataStream, worldVersion, version); - - int chunkX = minX + x; - int chunkZ = minZ + z; - - chunkMap.put(Util.chunkPosition(chunkX, chunkZ), new v1_9SlimeChunk( - worldName, - chunkX, - chunkZ, - data.sections, - data.minSectionY, - data.maxSectionY, - heightMaps, - biomes, - new ArrayList<>(), - new ArrayList<>() - )); - } - } - } - - return chunkMap; - } - - private static int[] toIntArray(byte[] buf) { - ByteBuffer buffer = ByteBuffer.wrap(buf).order(ByteOrder.BIG_ENDIAN); - int[] ret = new int[buf.length / 4]; - - buffer.asIntBuffer().get(ret); - - return ret; - } - - private record ChunkSectionData(v1_9SlimeChunkSection[] sections, int minSectionY, int maxSectionY) { - } - - private static ChunkSectionData readChunkSectionsNew(DataInputStream dataStream, int worldVersion, int version) throws IOException { - int minSectionY = dataStream.readInt(); - int maxSectionY = dataStream.readInt(); - int sectionCount = dataStream.readInt(); - v1_9SlimeChunkSection[] chunkSectionArray = new v1_9SlimeChunkSection[maxSectionY - minSectionY]; - - for (int i = 0; i < sectionCount; i++) { - int y = dataStream.readInt(); - - // Block Light Nibble Array - NibbleArray blockLightArray; - - if (version < 5 || dataStream.readBoolean()) { - byte[] blockLightByteArray = new byte[2048]; - dataStream.read(blockLightByteArray); - blockLightArray = new NibbleArray((blockLightByteArray)); - } else { - blockLightArray = null; - } - - // Block data - byte[] blockStateData = new byte[dataStream.readInt()]; - dataStream.read(blockStateData); - CompoundTag blockStateTag = readCompoundTag(blockStateData); - - byte[] biomeData = new byte[dataStream.readInt()]; - dataStream.read(biomeData); - CompoundTag biomeTag = readCompoundTag(biomeData); - - // Sky Light Nibble Array - NibbleArray skyLightArray; - - if (version < 5 || dataStream.readBoolean()) { - byte[] skyLightByteArray = new byte[2048]; - dataStream.read(skyLightByteArray); - skyLightArray = new NibbleArray((skyLightByteArray)); - } else { - skyLightArray = null; - } - - // HypixelBlocks 3 - if (version < 4) { - short hypixelBlocksLength = dataStream.readShort(); - dataStream.skip(hypixelBlocksLength); - } - - chunkSectionArray[y] = new v1_9SlimeChunkSection(null, null, null, null, blockStateTag, biomeTag, blockLightArray, skyLightArray); - } - - return new ChunkSectionData(chunkSectionArray, minSectionY, maxSectionY); - } - - private static ChunkSectionData readChunkSections(DataInputStream dataStream, byte worldVersion, int version) throws IOException { - v1_9SlimeChunkSection[] chunkSectionArray = new v1_9SlimeChunkSection[16]; - byte[] sectionBitmask = new byte[2]; - dataStream.read(sectionBitmask); - BitSet sectionBitset = BitSet.valueOf(sectionBitmask); - - for (int i = 0; i < 16; i++) { - if (sectionBitset.get(i)) { - // Block Light Nibble Array - NibbleArray blockLightArray; - - if (version < 5 || dataStream.readBoolean()) { - byte[] blockLightByteArray = new byte[2048]; - dataStream.read(blockLightByteArray); - blockLightArray = new NibbleArray((blockLightByteArray)); - } else { - blockLightArray = null; - } - - // Block data - byte[] blockArray; - NibbleArray dataArray; - - ListTag paletteTag; - long[] blockStatesArray; - - if (worldVersion >= 0x04) { - // Post 1.13 - // Palette - int paletteLength = dataStream.readInt(); - List paletteList = new ArrayList<>(paletteLength); - for (int index = 0; index < paletteLength; index++) { - int tagLength = dataStream.readInt(); - byte[] serializedTag = new byte[tagLength]; - dataStream.read(serializedTag); - - CompoundTag tag = readCompoundTag(serializedTag); - paletteList.add(tag); - } - - paletteTag = new ListTag<>("", TagType.TAG_COMPOUND, paletteList); - - // Block states - int blockStatesArrayLength = dataStream.readInt(); - blockStatesArray = new long[blockStatesArrayLength]; - - for (int index = 0; index < blockStatesArrayLength; index++) { - blockStatesArray[index] = dataStream.readLong(); - } - - blockArray = null; - dataArray = null; - } else { - // Pre 1.13 - blockArray = new byte[4096]; - dataStream.read(blockArray); - - // Block Data Nibble Array - byte[] dataByteArray = new byte[2048]; - dataStream.read(dataByteArray); - dataArray = new NibbleArray((dataByteArray)); - - paletteTag = null; - blockStatesArray = null; - } - - // Sky Light Nibble Array - NibbleArray skyLightArray; - - if (version < 5 || dataStream.readBoolean()) { - byte[] skyLightByteArray = new byte[2048]; - dataStream.read(skyLightByteArray); - skyLightArray = new NibbleArray((skyLightByteArray)); - } else { - skyLightArray = null; - } - - // HypixelBlocks 3 - if (version < 4) { - short hypixelBlocksLength = dataStream.readShort(); - dataStream.skip(hypixelBlocksLength); - } - - chunkSectionArray[i] = new v1_9SlimeChunkSection(blockArray, dataArray, paletteTag, blockStatesArray, null, null, blockLightArray, skyLightArray); - } - } - - return new ChunkSectionData(chunkSectionArray, 0, 16); - } - - private static CompoundTag readCompoundTag(byte[] serializedCompound) throws IOException { - if (serializedCompound.length == 0) { - return null; - } - - NBTInputStream stream = new NBTInputStream(new ByteArrayInputStream(serializedCompound), NBTInputStream.NO_COMPRESSION, ByteOrder.BIG_ENDIAN); - - return (CompoundTag) stream.readTag(); - } -} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9WorldFormat.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9WorldFormat.java deleted file mode 100644 index 62bf97f07..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9WorldFormat.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; - -public interface v1_9WorldFormat { - - com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat FORMAT = new com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat<>(new v1_v9SlimeConverter(), new v1_9SlimeWorldDeserializer()); - -} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java deleted file mode 100644 index f5a06898e..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java +++ /dev/null @@ -1,131 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; - -import com.flowpowered.nbt.*; -import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.*; -import com.infernalsuite.asp.api.world.SlimeChunk; -import com.infernalsuite.asp.api.world.SlimeChunkSection; -import com.infernalsuite.asp.api.world.SlimeWorld; - -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Logger; - -class v1_v9SlimeConverter implements com.infernalsuite.asp.serialization.SlimeWorldReader { - - public static final Map UPGRADES = new HashMap<>(); - - static { - UPGRADES.put((byte) 0x02, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_9WorldUpgrade()); - UPGRADES.put((byte) 0x03, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_11WorldUpgrade()); - UPGRADES.put((byte) 0x04, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_13WorldUpgrade()); - UPGRADES.put((byte) 0x05, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_14WorldUpgrade()); - UPGRADES.put((byte) 0x06, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_16WorldUpgrade()); - UPGRADES.put((byte) 0x07, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_17WorldUpgrade()); - UPGRADES.put((byte) 0x08, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_18WorldUpgrade()); - } - - @Override - public SlimeWorld readFromData(v1_9SlimeWorld data) { - int dataVersion = upgradeWorld(data); - - Long2ObjectMap chunks = new Long2ObjectOpenHashMap<>(); - for (Long2ObjectMap.Entry entry : data.chunks.long2ObjectEntrySet()) { - v1_9SlimeChunk slimeChunk = entry.getValue(); - - SlimeChunkSection[] sections = new SlimeChunkSection[slimeChunk.sections.length]; - for (int i = 0; i < sections.length; i++) { - v1_9SlimeChunkSection dataSection = slimeChunk.sections[i]; - if (dataSection != null) { - // I'm not sure which upgrader should handle this, so I'm leaving it here - if (dataSection.biomeTag != null) { - ListTag palette = (ListTag) dataSection.biomeTag.getValue().get("palette"); - - ArrayList newPalette = new ArrayList(); - if (palette != null) { - for (StringTag stringTag : palette.getValue()) { - // air is no longer a valid biome, I'm not sure when this changed, - // so I cannot pick the proper upgrader to place it in. - if (stringTag.getValue().equals("minecraft:air")) continue; - newPalette.add(stringTag); - } - } - - if (palette == null || palette.getValue().isEmpty()) { - newPalette.add(new StringTag(null, "minecraft:plains")); - } - - dataSection.biomeTag.getValue().put("palette", new ListTag<>("palette", TagType.TAG_STRING, newPalette)); - } - - sections[i] = new com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton( - // SlimeChunkConverter can handle null blockState, but cannot handle empty blockState - dataSection.blockStatesTag.getValue().isEmpty() ? null : dataSection.blockStatesTag, - dataSection.biomeTag, - dataSection.blockLight, - dataSection.skyLight - ); - } else { - sections[i] = new com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton( - null, - null, - null, - null - ); - } - - } - // TODO: - // slimeChunk.minY, - // slimeChunk.maxY, - - chunks.put(entry.getLongKey(), new com.infernalsuite.asp.skeleton.SlimeChunkSkeleton( - slimeChunk.x, - slimeChunk.z, - sections, - slimeChunk.heightMap, - slimeChunk.tileEntities, - slimeChunk.entities, - new CompoundTag("", new CompoundMap()), - slimeChunk.upgradeData - )); - } - - - return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld( - data.worldName, - data.loader, - data.readOnly, - chunks, - data.extraCompound, - data.propertyMap, - dataVersion - ); - } - - - public static int upgradeWorld(v1_9SlimeWorld world) { - byte upgradeTo = 0x08; // Last version - int dataVersion = 3120; // MCVersions.V1_19_2 - - for (byte ver = (byte) (world.version + 1); ver <= upgradeTo; ver++) { - Upgrade upgrade = UPGRADES.get(ver); - - if (upgrade == null) { - Logger.getLogger("v1_9WorldUpgrader").warning("Missing world upgrader for version " + ver + ". World will not be upgraded."); - continue; - } - - upgrade.upgrade(world); - - if (ver == 0x08) { - dataVersion = 2975; - } - } - - world.version = 0x09; - return dataVersion; - } -} From bc2d52dec433e3367f4bbb1a269cbd46c8490b8d Mon Sep 17 00:00:00 2001 From: Philip Kelley Date: Fri, 20 Dec 2024 11:32:29 +0000 Subject: [PATCH 025/133] chore(api): fix javadoc --- .../main/java/com/infernalsuite/asp/api/world/SlimeChunk.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunk.java b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunk.java index c422241f5..cbd31f7d6 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunk.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunk.java @@ -32,9 +32,7 @@ public interface SlimeChunk { SlimeChunkSection[] getSections(); /** - * Returns the height maps of the chunk. If it's a pre 1.13 world, - * a {@link com.flowpowered.nbt.IntArrayTag} containing the height - * map will be stored inside here by the name of 'heightMap'. + * Returns the height maps of the chunk. * * @return A {@link CompoundBinaryTag} containing all the height maps of the chunk. */ From 3e9e99cc4eded8bab56793d6cad8831c5cd6c0a9 Mon Sep 17 00:00:00 2001 From: Philip Kelley Date: Fri, 20 Dec 2024 11:33:18 +0000 Subject: [PATCH 026/133] chore(api): Change SWI extra data to Map --- .../com/infernalsuite/asp/api/world/SlimeWorldInstance.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java index 123949599..ed93b4b6b 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java @@ -1,9 +1,11 @@ package com.infernalsuite.asp.api.world; import com.infernalsuite.asp.api.loaders.SlimeLoader; -import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.BinaryTag; import org.bukkit.World; +import java.util.concurrent.ConcurrentMap; + public interface SlimeWorldInstance { String getName(); @@ -18,6 +20,6 @@ public interface SlimeWorldInstance { SlimeLoader getLoader(); - CompoundBinaryTag getExtraData(); + ConcurrentMap getExtraData(); } From 167c3277c7177a1fe47f1d91be6499067b7539a9 Mon Sep 17 00:00:00 2001 From: Philip Kelley Date: Fri, 20 Dec 2024 11:33:49 +0000 Subject: [PATCH 027/133] chore(impl): Replace FlowNBT with AdventureNBT in all patches --- patches/server/0001-Build-Changes.patch | 361 +++++++++--------- ...rt-for-serializing-deserializing-PDC.patch | 10 +- patches/server/0004-Fix-entity-loading.patch | 36 +- .../0006-Handle-null-data-properly.patch | 8 +- ...ke-SlimeWorld-a-PersistentDataHolder.patch | 102 ++--- ...c-and-extra-nbt.-Fix-double-compress.patch | 59 ++- .../0009-Add-migration-from-SRF-1-8.patch | 74 ++-- ...not-getting-serialized-when-reloaded.patch | 6 +- patches/server/0012-Compile-fixes.patch | 40 +- ...e-plugin-and-server-rework-API-to-v3.patch | 50 +-- .../0014-replace-ChunkPos-with-long.patch | 69 ++-- patches/server/0015-1.21-compatibility.patch | 47 +-- ...nk-pdc-getting-wiped-on-chunk-unload.patch | 11 +- patches/server/0019-1.21.3-fixes.patch | 64 ++-- ...ng-chunks-entities-when-chunk-saving.patch | 47 +-- ...-not-saving-when-chunks-are-unloaded.patch | 4 +- .../0022-Remove-leftover-FlowNBT-usage.patch | 21 + 17 files changed, 520 insertions(+), 489 deletions(-) create mode 100644 patches/server/0022-Remove-leftover-FlowNBT-usage.patch diff --git a/patches/server/0001-Build-Changes.patch b/patches/server/0001-Build-Changes.patch index 73ce36b19..59c6e6b15 100644 --- a/patches/server/0001-Build-Changes.patch +++ b/patches/server/0001-Build-Changes.patch @@ -200,26 +200,54 @@ index 532306cacd52579cdf37e4aca25887b1ed3ba6a1..55864e5f9ba2ccca0160760e90d8f778 .clickEvent(ClickEvent.openUrl(DOWNLOAD_PAGE)))); diff --git a/src/main/java/com/infernalsuite/asp/Converter.java b/src/main/java/com/infernalsuite/asp/Converter.java new file mode 100644 -index 0000000000000000000000000000000000000000..4ce96aae099f7ac941e7e7665693b5ba04802a8c +index 0000000000000000000000000000000000000000..22acbf7d0f7b8ac9eb41efc05d6050d0871c90a9 --- /dev/null +++ b/src/main/java/com/infernalsuite/asp/Converter.java -@@ -0,0 +1,118 @@ +@@ -0,0 +1,128 @@ +package com.infernalsuite.asp; -+ -+import com.flowpowered.nbt.CompoundMap; -+import com.flowpowered.nbt.TagType; ++ +import com.infernalsuite.asp.api.utils.NibbleArray; -+import net.minecraft.nbt.*; ++import net.kyori.adventure.nbt.BinaryTag; ++import net.kyori.adventure.nbt.ByteArrayBinaryTag; ++import net.kyori.adventure.nbt.ByteBinaryTag; ++import net.kyori.adventure.nbt.CompoundBinaryTag; ++import net.kyori.adventure.nbt.DoubleBinaryTag; ++import net.kyori.adventure.nbt.EndBinaryTag; ++import net.kyori.adventure.nbt.FloatBinaryTag; ++import net.kyori.adventure.nbt.IntArrayBinaryTag; ++import net.kyori.adventure.nbt.IntBinaryTag; ++import net.kyori.adventure.nbt.ListBinaryTag; ++import net.kyori.adventure.nbt.LongArrayBinaryTag; ++import net.kyori.adventure.nbt.LongBinaryTag; ++import net.kyori.adventure.nbt.ShortBinaryTag; ++import net.kyori.adventure.nbt.StringBinaryTag; ++import net.kyori.adventure.nbt.TagStringIO; ++import net.minecraft.nbt.ByteArrayTag; ++import net.minecraft.nbt.ByteTag; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.nbt.DoubleTag; ++import net.minecraft.nbt.EndTag; ++import net.minecraft.nbt.FloatTag; ++import net.minecraft.nbt.IntArrayTag; ++import net.minecraft.nbt.IntTag; ++import net.minecraft.nbt.ListTag; ++import net.minecraft.nbt.LongArrayTag; ++import net.minecraft.nbt.LongTag; ++import net.minecraft.nbt.ShortTag; ++import net.minecraft.nbt.StringTag; ++import net.minecraft.nbt.Tag; +import net.minecraft.world.level.chunk.DataLayer; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + ++import java.io.IOException; +import java.util.ArrayList; +import java.util.List; ++import java.util.Objects; + +public class Converter { + -+ private static final Logger LOGGER = LogManager.getLogger("SWM Converter"); ++ private static final Logger LOGGER = LogManager.getLogger("ASP NBT Converter"); + + static DataLayer convertArray(NibbleArray array) { + return new DataLayer(array.getBacking()); @@ -233,96 +261,77 @@ index 0000000000000000000000000000000000000000..4ce96aae099f7ac941e7e7665693b5ba + return new NibbleArray(array.getData()); + } + -+ public static Tag convertTag(com.flowpowered.nbt.Tag tag) { ++ public static Tag convertTag(T tag) { + try { -+ switch(tag.getType()) { -+ case TAG_BYTE: -+ return ByteTag.valueOf(((com.flowpowered.nbt.ByteTag) tag).getValue()); -+ case TAG_SHORT: -+ return ShortTag.valueOf(((com.flowpowered.nbt.ShortTag) tag).getValue()); -+ case TAG_INT: -+ return IntTag.valueOf(((com.flowpowered.nbt.IntTag) tag).getValue()); -+ case TAG_LONG: -+ return LongTag.valueOf(((com.flowpowered.nbt.LongTag) tag).getValue()); -+ case TAG_FLOAT: -+ return FloatTag.valueOf(((com.flowpowered.nbt.FloatTag) tag).getValue()); -+ case TAG_DOUBLE: -+ return DoubleTag.valueOf(((com.flowpowered.nbt.DoubleTag) tag).getValue()); -+ case TAG_BYTE_ARRAY: -+ return new ByteArrayTag(((com.flowpowered.nbt.ByteArrayTag) tag).getValue()); -+ case TAG_STRING: -+ return StringTag.valueOf(((com.flowpowered.nbt.StringTag) tag).getValue()); -+ case TAG_LIST: ++ return switch (tag.type().id()) { ++ case Tag.TAG_END -> EndTag.INSTANCE; ++ case Tag.TAG_BYTE -> ByteTag.valueOf(((ByteBinaryTag) tag).value()); ++ case Tag.TAG_SHORT -> ShortTag.valueOf(((ShortBinaryTag) tag).value()); ++ case Tag.TAG_INT -> IntTag.valueOf(((IntBinaryTag) tag).value()); ++ case Tag.TAG_LONG -> LongTag.valueOf(((LongBinaryTag) tag).value()); ++ case Tag.TAG_FLOAT -> FloatTag.valueOf(((FloatBinaryTag) tag).value()); ++ case Tag.TAG_DOUBLE -> DoubleTag.valueOf(((DoubleBinaryTag) tag).value()); ++ case Tag.TAG_BYTE_ARRAY -> new ByteArrayTag(((ByteArrayBinaryTag) tag).value()); ++ case Tag.TAG_STRING -> StringTag.valueOf(((StringBinaryTag) tag).value()); ++ case Tag.TAG_LIST -> { + ListTag list = new ListTag(); -+ ((com.flowpowered.nbt.ListTag) tag).getValue().stream().map(Converter::convertTag).forEach(list::add); -+ -+ return list; -+ case TAG_COMPOUND: ++ for (BinaryTag entry : ((ListBinaryTag) tag)) list.add(convertTag(entry)); ++ yield list; ++ } ++ case Tag.TAG_COMPOUND -> { + CompoundTag compound = new CompoundTag(); -+ -+ ((com.flowpowered.nbt.CompoundTag) tag).getValue().forEach((key, value) -> compound.put(key, convertTag(value))); -+ return compound; -+ case TAG_INT_ARRAY: -+ return new IntArrayTag(((com.flowpowered.nbt.IntArrayTag) tag).getValue()); -+ case TAG_LONG_ARRAY: -+ return new LongArrayTag(((com.flowpowered.nbt.LongArrayTag) tag).getValue()); -+ default: -+ throw new IllegalArgumentException("Invalid tag type " + tag.getType().name()); ++ ((CompoundBinaryTag) tag).forEach(entry -> compound.put(entry.getKey(), convertTag(entry.getValue()))); ++ yield compound; ++ } ++ case Tag.TAG_INT_ARRAY -> new IntArrayTag(((IntArrayBinaryTag) tag).value()); ++ case Tag.TAG_LONG_ARRAY -> new LongArrayTag(((LongArrayBinaryTag) tag).value()); ++ default -> throw new IllegalArgumentException("Invalid tag type " + tag.type().id()); ++ }; ++ } catch (final Exception e) { ++ CompoundBinaryTag exceptionTag = CompoundBinaryTag.builder().put("failing_tag", tag).build(); ++ String tagString; ++ try { ++ tagString = TagStringIO.get().asString(exceptionTag); ++ } catch (final IOException ioEx) { ++ LOGGER.error("Error while trying to convert exception tag to string", ioEx); ++ tagString = "UNAVAILABLE"; + } -+ } catch(Exception ex) { -+ LOGGER.error("Failed to convert NBT object:"); -+ LOGGER.error(tag.toString()); -+ -+ throw ex; ++ LOGGER.error("Failed to convert NBT object: {}", tagString); ++ throw e; + } + } + -+ public static com.flowpowered.nbt.Tag convertTag(String name, Tag base) { -+ switch(base.getId()) { -+ case Tag.TAG_BYTE: -+ return new com.flowpowered.nbt.ByteTag(name, ((ByteTag) base).getAsByte()); -+ case Tag.TAG_SHORT: -+ return new com.flowpowered.nbt.ShortTag(name, ((ShortTag) base).getAsShort()); -+ case Tag.TAG_INT: -+ return new com.flowpowered.nbt.IntTag(name, ((IntTag) base).getAsInt()); -+ case Tag.TAG_LONG: -+ return new com.flowpowered.nbt.LongTag(name, ((LongTag) base).getAsLong()); -+ case Tag.TAG_FLOAT: -+ return new com.flowpowered.nbt.FloatTag(name, ((FloatTag) base).getAsFloat()); -+ case Tag.TAG_DOUBLE: -+ return new com.flowpowered.nbt.DoubleTag(name, ((DoubleTag) base).getAsDouble()); -+ case Tag.TAG_BYTE_ARRAY: -+ return new com.flowpowered.nbt.ByteArrayTag(name, ((ByteArrayTag) base).getAsByteArray()); -+ case Tag.TAG_STRING: -+ return new com.flowpowered.nbt.StringTag(name, ((StringTag) base).getAsString()); -+ case Tag.TAG_LIST: -+ List list = new ArrayList<>(); ++ @SuppressWarnings("unchecked") ++ public static T convertTag(Tag base) { ++ return switch (base.getId()) { ++ case Tag.TAG_END -> (T) EndBinaryTag.endBinaryTag(); ++ case Tag.TAG_BYTE -> (T) ByteBinaryTag.byteBinaryTag(((ByteTag) base).getAsByte()); ++ case Tag.TAG_SHORT -> (T) ShortBinaryTag.shortBinaryTag(((ShortTag) base).getAsShort()); ++ case Tag.TAG_INT -> (T) IntBinaryTag.intBinaryTag(((IntTag) base).getAsInt()); ++ case Tag.TAG_LONG -> (T) LongBinaryTag.longBinaryTag(((LongTag) base).getAsLong()); ++ case Tag.TAG_FLOAT -> (T) FloatBinaryTag.floatBinaryTag(((FloatTag) base).getAsFloat()); ++ case Tag.TAG_DOUBLE -> (T) DoubleBinaryTag.doubleBinaryTag(((DoubleTag) base).getAsDouble()); ++ case Tag.TAG_BYTE_ARRAY -> (T) ByteArrayBinaryTag.byteArrayBinaryTag(((ByteArrayTag) base).getAsByteArray()); ++ case Tag.TAG_STRING -> (T) StringBinaryTag.stringBinaryTag(((StringTag) base).getAsString()); ++ case Tag.TAG_LIST -> { ++ List list = new ArrayList<>(); + ListTag originalList = ((ListTag) base); -+ -+ for(Tag entry : originalList) { -+ list.add(convertTag("", entry)); -+ } -+ -+ return new com.flowpowered.nbt.ListTag(name, TagType.getById(originalList.getElementType()), list); -+ case Tag.TAG_COMPOUND: ++ for (Tag entry : originalList) list.add(convertTag(entry)); ++ yield (T) ListBinaryTag.listBinaryTag(list.getFirst().type(), list); ++ } ++ case Tag.TAG_COMPOUND -> { ++ CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder(); + CompoundTag originalCompound = ((CompoundTag) base); -+ com.flowpowered.nbt.CompoundTag compound = new com.flowpowered.nbt.CompoundTag(name, new CompoundMap()); -+ -+ for(String key : originalCompound.getAllKeys()) { -+ compound.getValue().put(key, convertTag(key, originalCompound.get(key))); -+ } -+ -+ return compound; -+ case Tag.TAG_INT_ARRAY: -+ return new com.flowpowered.nbt.IntArrayTag(name, ((IntArrayTag) base).getAsIntArray()); -+ case Tag.TAG_LONG_ARRAY: -+ return new com.flowpowered.nbt.LongArrayTag(name, ((LongArrayTag) base).getAsLongArray()); -+ default: -+ throw new IllegalArgumentException("Invalid tag type " + base.getId()); -+ } ++ for (String key : originalCompound.getAllKeys()) builder.put(key, convertTag(Objects.requireNonNull(originalCompound.get(key)))); ++ yield (T) builder.build(); ++ } ++ case Tag.TAG_INT_ARRAY -> (T) IntArrayBinaryTag.intArrayBinaryTag(((IntArrayTag) base).getAsIntArray()); ++ case Tag.TAG_LONG_ARRAY -> (T) LongArrayBinaryTag.longArrayBinaryTag(((LongArrayTag) base).getAsLongArray()); ++ default -> throw new IllegalArgumentException("Invalid tag type " + base.getId()); ++ }; + } ++ +} -\ No newline at end of file diff --git a/src/main/java/com/infernalsuite/asp/InternalPlugin.java b/src/main/java/com/infernalsuite/asp/InternalPlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..4c7938c07e06810f475eac0bb4400c11154b56ba @@ -360,16 +369,15 @@ index 0000000000000000000000000000000000000000..4c7938c07e06810f475eac0bb4400c11 \ No newline at end of file diff --git a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java new file mode 100644 -index 0000000000000000000000000000000000000000..2f5b79632226f5d0112a4c0ddfc903d6b2b93549 +index 0000000000000000000000000000000000000000..694bd135fd4398ecf02940e638fae1047e217a29 --- /dev/null +++ b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -@@ -0,0 +1,101 @@ +@@ -0,0 +1,98 @@ +package com.infernalsuite.asp; + +import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; +import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; +import ca.spottedleaf.dataconverter.types.nbt.NBTMapType; -+import com.flowpowered.nbt.CompoundTag; +import com.infernalsuite.asp.serialization.SlimeWorldReader; +import com.infernalsuite.asp.skeleton.SkeletonSlimeWorld; +import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; @@ -377,12 +385,12 @@ index 0000000000000000000000000000000000000000..2f5b79632226f5d0112a4c0ddfc903d6 +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeChunkSection; +import com.infernalsuite.asp.api.world.SlimeWorld; ++import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.minecraft.SharedConstants; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; -+import java.util.Map; +import java.util.function.Consumer; + +class SimpleDataFixerConverter implements SlimeWorldReader { @@ -398,14 +406,14 @@ index 0000000000000000000000000000000000000000..2f5b79632226f5d0112a4c0ddfc903d6 + + Map chunks = new HashMap<>(); + for (SlimeChunk chunk : data.getChunkStorage()) { -+ List entities = new ArrayList<>(); -+ List blockEntities = new ArrayList<>(); -+ for (CompoundTag upgradeEntity : chunk.getTileEntities()) { ++ List entities = new ArrayList<>(); ++ List blockEntities = new ArrayList<>(); ++ for (CompoundBinaryTag upgradeEntity : chunk.getTileEntities()) { + blockEntities.add( + convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.TILE_ENTITY.convert(new NBTMapType(tag), currentVersion, newVersion)) + ); + } -+ for (CompoundTag upgradeEntity : chunk.getEntities()) { ++ for (CompoundBinaryTag upgradeEntity : chunk.getEntities()) { + entities.add( + convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.ENTITY.convert(new NBTMapType(tag), currentVersion, newVersion)) + ); @@ -415,11 +423,11 @@ index 0000000000000000000000000000000000000000..2f5b79632226f5d0112a4c0ddfc903d6 + for (int i = 0; i < sections.length; i++) { + SlimeChunkSection dataSection = chunk.getSections()[i]; + -+ com.flowpowered.nbt.CompoundTag blockStateTag = blockStateTag = convertAndBack(dataSection.getBlockStatesTag(), (tag) -> { ++ CompoundBinaryTag blockStateTag = blockStateTag = convertAndBack(dataSection.getBlockStatesTag(), (tag) -> { + WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, new NBTMapType(tag), "palette", currentVersion, newVersion); + }); + -+ com.flowpowered.nbt.CompoundTag biomeTag = convertAndBack(dataSection.getBiomeTag(), (tag) -> { ++ CompoundBinaryTag biomeTag = convertAndBack(dataSection.getBiomeTag(), (tag) -> { + WalkerUtils.convertList(MCTypeRegistry.BIOME, new NBTMapType(tag), "palette", currentVersion, newVersion); + }); + @@ -454,21 +462,18 @@ index 0000000000000000000000000000000000000000..2f5b79632226f5d0112a4c0ddfc903d6 + } + + -+ private static com.flowpowered.nbt.CompoundTag convertAndBack(com.flowpowered.nbt.CompoundTag value, Consumer acceptor) { -+ if (value == null) { -+ return null; -+ } ++ private static CompoundBinaryTag convertAndBack(CompoundBinaryTag value, Consumer acceptor) { ++ if (value == null) return null; + + net.minecraft.nbt.CompoundTag converted = (net.minecraft.nbt.CompoundTag) Converter.convertTag(value); + acceptor.accept(converted); + -+ return (com.flowpowered.nbt.CompoundTag) Converter.convertTag(value.getName(), converted); ++ return Converter.convertTag(converted); + } +} -\ No newline at end of file diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java new file mode 100644 -index 0000000000000000000000000000000000000000..d1ab18a2a2793807118ae1fc23d21248aa7e09a3 +index 0000000000000000000000000000000000000000..98043b30614cc0ace252919367662a5e535fa1e1 --- /dev/null +++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java @@ -0,0 +1,206 @@ @@ -512,7 +517,7 @@ index 0000000000000000000000000000000000000000..d1ab18a2a2793807118ae1fc23d21248 + + private static final SimpleDataFixerConverter DATA_FIXER_CONVERTER = new SimpleDataFixerConverter(); + -+ private static final Logger LOGGER = LogManager.getLogger("SWM"); ++ private static final Logger LOGGER = LogManager.getLogger("ASP"); + + private SlimeWorld defaultWorld; + private SlimeWorld defaultNetherWorld; @@ -900,15 +905,12 @@ index 0000000000000000000000000000000000000000..10bfcb7250c01c8361375c4d9b34d2b0 \ No newline at end of file diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java new file mode 100644 -index 0000000000000000000000000000000000000000..9a6e901b394d1e7740e616a33e6c251ae1d7e0e0 +index 0000000000000000000000000000000000000000..beb56b2495a52e1fac815de664677d73ce2bbcc3 --- /dev/null +++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -@@ -0,0 +1,203 @@ +@@ -0,0 +1,187 @@ +package com.infernalsuite.asp.level; + -+import com.flowpowered.nbt.CompoundMap; -+import com.flowpowered.nbt.CompoundTag; -+import com.flowpowered.nbt.LongArrayTag; +import com.google.common.collect.Lists; +import com.infernalsuite.asp.Converter; +import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; @@ -918,10 +920,13 @@ index 0000000000000000000000000000000000000000..9a6e901b394d1e7740e616a33e6c251a +import com.mojang.logging.LogUtils; +import com.mojang.serialization.Codec; +import io.papermc.paper.world.ChunkEntitySlices; ++import net.kyori.adventure.nbt.CompoundBinaryTag; ++import net.kyori.adventure.nbt.LongArrayBinaryTag; +import net.minecraft.core.Holder; +import net.minecraft.core.Registry; +import net.minecraft.core.SectionPos; +import net.minecraft.core.registries.Registries; ++import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; +import net.minecraft.nbt.Tag; +import net.minecraft.world.entity.Entity; @@ -948,8 +953,8 @@ index 0000000000000000000000000000000000000000..9a6e901b394d1e7740e616a33e6c251a +public class NMSSlimeChunk implements SlimeChunk { + private static final Logger LOGGER = LogUtils.getClassLogger(); + -+ private static final CompoundTag EMPTY_BLOCK_STATE_PALETTE; -+ private static final CompoundTag EMPTY_BIOME_PALETTE; ++ private static final CompoundBinaryTag EMPTY_BLOCK_STATE_PALETTE; ++ private static final CompoundBinaryTag EMPTY_BIOME_PALETTE; + + // Optimized empty section serialization + static { @@ -959,7 +964,7 @@ index 0000000000000000000000000000000000000000..9a6e901b394d1e7740e616a33e6c251a + throw new AssertionError(error); + }); + -+ EMPTY_BLOCK_STATE_PALETTE = (CompoundTag) Converter.convertTag("", tag); ++ EMPTY_BLOCK_STATE_PALETTE = Converter.convertTag(tag); + } + { + Registry biomes = net.minecraft.server.MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME); @@ -968,7 +973,7 @@ index 0000000000000000000000000000000000000000..9a6e901b394d1e7740e616a33e6c251a + throw new AssertionError(error); + }); + -+ EMPTY_BIOME_PALETTE = (CompoundTag) Converter.convertTag("", tag); ++ EMPTY_BIOME_PALETTE = Converter.convertTag(tag); + } + } + @@ -1011,22 +1016,22 @@ index 0000000000000000000000000000000000000000..9a6e901b394d1e7740e616a33e6c251a + // Tile/Entity Data + + // Block Data -+ CompoundTag blockStateTag; ++ CompoundBinaryTag blockStateTag; + if (section.hasOnlyAir()) { + blockStateTag = EMPTY_BLOCK_STATE_PALETTE; + } else { + Tag data = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, section.getStates()).getOrThrow(false, System.err::println); // todo error handling -+ blockStateTag = (CompoundTag) Converter.convertTag("", data); ++ blockStateTag = Converter.convertTag(data); + } + + -+ CompoundTag biomeTag; ++ CompoundBinaryTag biomeTag; + PalettedContainer> biomes = (PalettedContainer>) section.getBiomes(); + if (biomes.data.palette().getSize() == 1 && biomes.data.palette().maybeHas((h) -> h.is(Biomes.PLAINS))) { + biomeTag = EMPTY_BIOME_PALETTE; + } else { + Tag biomeData = codec.encodeStart(NbtOps.INSTANCE, section.getBiomes()).getOrThrow(false, System.err::println); // todo error handling -+ biomeTag = (CompoundTag) Converter.convertTag("", biomeData); ++ biomeTag = Converter.convertTag(biomeData); + } + + sections[sectionId] = new SlimeChunkSectionSkeleton(blockStateTag, biomeTag, blockLightArray, skyLightArray); @@ -1036,66 +1041,50 @@ index 0000000000000000000000000000000000000000..9a6e901b394d1e7740e616a33e6c251a + } + + @Override -+ public CompoundTag getHeightMaps() { -+ // HeightMap -+ CompoundMap heightMaps = new CompoundMap(); ++ public CompoundBinaryTag getHeightMaps() { ++ CompoundBinaryTag.Builder heightMapsTagBuilder = CompoundBinaryTag.builder(); + -+ for (Map.Entry entry : chunk.heightmaps.entrySet()) { -+ if (!entry.getKey().keepAfterWorldgen()) { -+ continue; ++ this.chunk.heightmaps.forEach((type, map) -> { ++ if (type.keepAfterWorldgen()) { ++ heightMapsTagBuilder.put(type.name(), LongArrayBinaryTag.longArrayBinaryTag(map.getRawData())); + } ++ }); + -+ Heightmap.Types type = entry.getKey(); -+ Heightmap map = entry.getValue(); -+ -+ heightMaps.put(type.name(), new LongArrayTag(type.name(), map.getRawData())); -+ } -+ -+ return new CompoundTag("", heightMaps); ++ return heightMapsTagBuilder.build(); + } + + @Override -+ public List getTileEntities() { -+ List tileEntities = new ArrayList<>(); ++ public List getTileEntities() { ++ List tileEntities = new ArrayList<>(); + -+ for (BlockEntity entity : chunk.blockEntities.values()) { -+ net.minecraft.nbt.CompoundTag entityNbt = entity.saveWithFullMetadata(); ++ for (BlockEntity entity : this.chunk.blockEntities.values()) { ++ CompoundTag entityNbt = entity.saveWithFullMetadata(); + tileEntities.add(entityNbt); + } + -+ return Lists.transform(tileEntities, (compound) -> { -+ return (CompoundTag) Converter.convertTag("", compound); -+ }); ++ return Lists.transform(tileEntities, Converter::convertTag); + } + + @Override -+ public List getEntities() { -+ List entities = new ArrayList<>(); ++ public List getEntities() { ++ List entities = new ArrayList<>(); + -+ if(this.chunk == null || this.chunk.getChunkHolder() == null) { -+ return new ArrayList<>(); -+ } ++ if (this.chunk == null || this.chunk.getChunkHolder() == null) return new ArrayList<>(); + + ChunkEntitySlices slices = this.chunk.getChunkHolder().getEntityChunk(); -+ if (slices == null) { -+ return new ArrayList<>(); -+ } ++ if (slices == null) return new ArrayList<>(); + + // Work by + for (Entity entity : slices.entities) { -+ net.minecraft.nbt.CompoundTag entityNbt = new net.minecraft.nbt.CompoundTag(); ++ CompoundTag entityNbt = new CompoundTag(); + try { -+ if (entity.save(entityNbt)) { -+ entities.add(entityNbt); -+ } -+ } catch (Exception e) { ++ if (entity.save(entityNbt)) entities.add(entityNbt); ++ } catch (final Exception e) { + LOGGER.error("Could not save the entity = {}, exception = {}", entity, e); + } + } + -+ return Lists.transform(entities, (compound) -> { -+ return (CompoundTag) Converter.convertTag("", compound); -+ }); ++ return Lists.transform(entities, Converter::convertTag); + } + + public LevelChunk getChunk() { @@ -1110,18 +1099,19 @@ index 0000000000000000000000000000000000000000..9a6e901b394d1e7740e616a33e6c251a \ No newline at end of file diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java new file mode 100644 -index 0000000000000000000000000000000000000000..3dc776b5387b4e2f1b669f754b5b064fc0142006 +index 0000000000000000000000000000000000000000..41119f2b0d208718c294076dc3c51f55680b0257 --- /dev/null +++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java -@@ -0,0 +1,91 @@ +@@ -0,0 +1,93 @@ +package com.infernalsuite.asp.level; + -+import com.flowpowered.nbt.CompoundTag; +import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; ++import net.kyori.adventure.nbt.BinaryTag; ++import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.minecraft.SharedConstants; +import net.minecraft.server.level.ChunkHolder; +import net.minecraft.world.level.chunk.LevelChunk; @@ -1130,6 +1120,7 @@ index 0000000000000000000000000000000000000000..3dc776b5387b4e2f1b669f754b5b064f +import java.util.Collection; +import java.util.List; +import java.util.Objects; ++import java.util.concurrent.ConcurrentMap; +import java.util.stream.Collectors; + +public class NMSSlimeWorld implements SlimeWorld { @@ -1171,12 +1162,12 @@ index 0000000000000000000000000000000000000000..3dc776b5387b4e2f1b669f754b5b064f + } + + @Override -+ public CompoundTag getExtraData() { ++ public ConcurrentMap getExtraData() { + return this.instance.slimeInstance.getExtraData(); + } + + @Override -+ public Collection getWorldMaps() { ++ public Collection getWorldMaps() { + return List.of(); + } + @@ -1208,15 +1199,15 @@ index 0000000000000000000000000000000000000000..3dc776b5387b4e2f1b669f754b5b064f \ No newline at end of file diff --git a/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java b/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java new file mode 100644 -index 0000000000000000000000000000000000000000..025da4dd831f9b8b35000be7de493d44caa41003 +index 0000000000000000000000000000000000000000..fa8254ca4b2eafa4e5669c3e0467ed1f7d4dc159 --- /dev/null +++ b/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java @@ -0,0 +1,83 @@ +package com.infernalsuite.asp.level; + -+import com.flowpowered.nbt.CompoundTag; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeChunkSection; ++import net.kyori.adventure.nbt.CompoundBinaryTag; + +import java.util.List; + @@ -1250,7 +1241,7 @@ index 0000000000000000000000000000000000000000..025da4dd831f9b8b35000be7de493d44 + } + + @Override -+ public CompoundTag getHeightMaps() { ++ public CompoundBinaryTag getHeightMaps() { + if (shouldDefaultBackToSlimeChunk()) { + return this.safety.getHeightMaps(); + } @@ -1259,7 +1250,7 @@ index 0000000000000000000000000000000000000000..025da4dd831f9b8b35000be7de493d44 + } + + @Override -+ public List getTileEntities() { ++ public List getTileEntities() { + if (shouldDefaultBackToSlimeChunk()) { + return this.safety.getTileEntities(); + } @@ -1268,7 +1259,7 @@ index 0000000000000000000000000000000000000000..025da4dd831f9b8b35000be7de493d44 + } + + @Override -+ public List getEntities() { ++ public List getEntities() { + if (shouldDefaultBackToSlimeChunk()) { + return this.safety.getEntities(); + } @@ -1313,22 +1304,20 @@ index 0000000000000000000000000000000000000000..b1dde643ae719fa539c6986e86e12aec \ No newline at end of file diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java new file mode 100644 -index 0000000000000000000000000000000000000000..ba0b401e0b39605303e90720f7c8dc48fcb0bc29 +index 0000000000000000000000000000000000000000..b0d45837e918ef720b49a3f4968d7781ecf6436d --- /dev/null +++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -@@ -0,0 +1,164 @@ +@@ -0,0 +1,161 @@ +package com.infernalsuite.asp.level; + +import ca.spottedleaf.starlight.common.light.SWMRNibbleArray; -+import com.flowpowered.nbt.CompoundMap; -+import com.flowpowered.nbt.CompoundTag; -+import com.flowpowered.nbt.LongArrayTag; +import com.infernalsuite.asp.Converter; +import com.infernalsuite.asp.api.utils.NibbleArray; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeChunkSection; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; ++import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.core.Registry; @@ -1428,15 +1417,14 @@ index 0000000000000000000000000000000000000000..ba0b401e0b39605303e90720f7c8dc48 + + // TODO + // Load tile entities -+ List tileEntities = chunk.getTileEntities(); ++ List tileEntities = chunk.getTileEntities(); + + if (tileEntities != null) { -+ for (CompoundTag tag : tileEntities) { -+ Optional type = tag.getStringValue("id"); ++ for (CompoundBinaryTag tag : tileEntities) { ++ String type = tag.getString("id"); + -+ // Sometimes null tile entities are saved -+ if (type.isPresent()) { -+ BlockPos blockPosition = new BlockPos(tag.getIntValue("x").get(), tag.getIntValue("y").get(), tag.getIntValue("z").get()); ++ if (!type.isEmpty()) { ++ BlockPos blockPosition = new BlockPos(tag.getInt("x"), tag.getInt("y"), tag.getInt("z")); + BlockState blockData = nmsChunk.getBlockState(blockPosition); + BlockEntity entity = BlockEntity.loadStatic(blockPosition, blockData, (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)); + @@ -1454,7 +1442,7 @@ index 0000000000000000000000000000000000000000..ba0b401e0b39605303e90720f7c8dc48 + + // Height Maps + EnumSet heightMapTypes = nmsChunk.getStatus().heightmapsAfter(); -+ CompoundMap heightMaps = chunk.getHeightMaps().getValue(); ++ CompoundBinaryTag heightMaps = chunk.getHeightMaps(); + EnumSet unsetHeightMaps = EnumSet.noneOf(Heightmap.Types.class); + + // Light @@ -1464,9 +1452,9 @@ index 0000000000000000000000000000000000000000..ba0b401e0b39605303e90720f7c8dc48 + for (Heightmap.Types type : heightMapTypes) { + String name = type.getSerializedName(); + -+ if (heightMaps.containsKey(name)) { -+ LongArrayTag heightMap = (LongArrayTag) heightMaps.get(name); -+ nmsChunk.setHeightmap(type, heightMap.getValue()); ++ long[] heightMap = heightMaps.getLongArray(name); ++ if (heightMap.length > 0) { ++ nmsChunk.setHeightmap(type, heightMap); + } else { + unsetHeightMaps.add(type); + } @@ -1481,7 +1469,6 @@ index 0000000000000000000000000000000000000000..ba0b401e0b39605303e90720f7c8dc48 + return nmsChunk; + } +} -\ No newline at end of file diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java new file mode 100644 index 0000000000000000000000000000000000000000..0d218911fb8be1bc5272b6e291ec60404306c831 @@ -1518,13 +1505,12 @@ index 0000000000000000000000000000000000000000..0d218911fb8be1bc5272b6e291ec6040 \ No newline at end of file diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java new file mode 100644 -index 0000000000000000000000000000000000000000..ba337466525971885247c269c23aac7df96d2782 +index 0000000000000000000000000000000000000000..636c553f4407f19b3435d487250b041532b8f229 --- /dev/null +++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -0,0 +1,251 @@ +@@ -0,0 +1,253 @@ +package com.infernalsuite.asp.level; + -+import com.flowpowered.nbt.CompoundTag; +import com.infernalsuite.asp.ChunkPos; +import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; @@ -1536,6 +1522,8 @@ index 0000000000000000000000000000000000000000..ba337466525971885247c269c23aac7d +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.SlimeWorldInstance; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; ++import net.kyori.adventure.nbt.BinaryTag; ++import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.UpgradeData; @@ -1549,6 +1537,7 @@ index 0000000000000000000000000000000000000000..ba337466525971885247c269c23aac7d +import java.util.HashMap; +import java.util.List; +import java.util.Map; ++import java.util.concurrent.ConcurrentMap; + +/* +The concept of this is a bit flawed, since ideally this should be a 1:1 representation of the MC world. @@ -1560,7 +1549,7 @@ index 0000000000000000000000000000000000000000..ba337466525971885247c269c23aac7d + private final SlimeLevelInstance instance; + private final SlimeWorld liveWorld; + -+ private final CompoundTag extra; ++ private final ConcurrentMap extra; + private final SlimePropertyMap propertyMap; + private final SlimeLoader loader; + @@ -1577,7 +1566,7 @@ index 0000000000000000000000000000000000000000..ba337466525971885247c269c23aac7d + + for (SlimeChunk initial : bootstrap.initial().getChunkStorage()) { + ChunkPos pos = new ChunkPos(initial.getX(), initial.getZ()); -+ List tags = new ArrayList<>(initial.getEntities()); ++ List tags = new ArrayList<>(initial.getEntities()); + + // this.entityStorage.put(pos, tags); + this.chunkStorage.put(pos, initial); @@ -1708,12 +1697,12 @@ index 0000000000000000000000000000000000000000..ba337466525971885247c269c23aac7d + } + + @Override -+ public CompoundTag getExtraData() { ++ public ConcurrentMap getExtraData() { + return this.extra; + } + + @Override -+ public Collection getWorldMaps() { ++ public Collection getWorldMaps() { + return List.of(); + } + diff --git a/patches/server/0003-Add-support-for-serializing-deserializing-PDC.patch b/patches/server/0003-Add-support-for-serializing-deserializing-PDC.patch index 391cb5dbe..9ab91a0f4 100644 --- a/patches/server/0003-Add-support-for-serializing-deserializing-PDC.patch +++ b/patches/server/0003-Add-support-for-serializing-deserializing-PDC.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add support for serializing/deserializing PDC diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -index d1ab18a2a2793807118ae1fc23d21248aa7e09a3..0c1e599aa7d148c40ece1957c89991e1d761162a 100644 +index 98043b30614cc0ace252919367662a5e535fa1e1..68240b46ce911674ed288fe559737572fa44de6a 100644 --- a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java +++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java @@ -11,6 +11,7 @@ import com.mojang.serialization.Lifecycle; @@ -29,18 +29,18 @@ index d1ab18a2a2793807118ae1fc23d21248aa7e09a3..0c1e599aa7d148c40ece1957c89991e1 } diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -index ba337466525971885247c269c23aac7df96d2782..5d325e85a4634c21ab0bec12b493ea9b857d8ff3 100644 +index 636c553f4407f19b3435d487250b041532b8f229..387954aae7ef1a39025a474ab1fe81b7216d8d6c 100644 --- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -2,6 +2,7 @@ package com.infernalsuite.asp.level; +@@ -1,6 +1,7 @@ + package com.infernalsuite.asp.level; - import com.flowpowered.nbt.CompoundTag; import com.infernalsuite.asp.ChunkPos; +import com.infernalsuite.asp.Converter; import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; import com.infernalsuite.asp.api.loaders.SlimeLoader; import com.infernalsuite.asp.serialization.slime.SlimeSerializer; -@@ -235,6 +236,17 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -237,6 +238,17 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { cloned.put(entry.getKey(), clonedChunk); } diff --git a/patches/server/0004-Fix-entity-loading.patch b/patches/server/0004-Fix-entity-loading.patch index 3ae83cdf2..e2a9a2672 100644 --- a/patches/server/0004-Fix-entity-loading.patch +++ b/patches/server/0004-Fix-entity-loading.patch @@ -68,10 +68,10 @@ index 7e7c560b89c45e8ff003813f3c7a141c2b0b7a1d..e2c67548ff6341c1c981af83f6df7711 throw death; } catch (final Throwable thr2) { diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -index ba0b401e0b39605303e90720f7c8dc48fcb0bc29..6b38f707b43e1e584c79a6c8d9ec1232ed2901b9 100644 +index b0d45837e918ef720b49a3f4968d7781ecf6436d..b705b3133634c3696dee766cbfc95380293ccda3 100644 --- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -@@ -15,6 +15,8 @@ import net.minecraft.core.Holder; +@@ -13,6 +13,8 @@ import net.minecraft.core.Holder; import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.NbtOps; @@ -80,23 +80,22 @@ index ba0b401e0b39605303e90720f7c8dc48fcb0bc29..6b38f707b43e1e584c79a6c8d9ec1232 import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biomes; -@@ -106,26 +108,11 @@ public class SlimeChunkConverter { +@@ -104,25 +106,11 @@ public class SlimeChunkConverter { LevelChunk.PostLoadProcessor loadEntities = (nmsChunk) -> { -+ List entities = chunk.getEntities(); ++ List entities = chunk.getEntities(); - // TODO - // Load tile entities -- List tileEntities = chunk.getTileEntities(); +- List tileEntities = chunk.getTileEntities(); - - if (tileEntities != null) { -- for (CompoundTag tag : tileEntities) { -- Optional type = tag.getStringValue("id"); +- for (CompoundBinaryTag tag : tileEntities) { +- String type = tag.getString("id"); - -- // Sometimes null tile entities are saved -- if (type.isPresent()) { -- BlockPos blockPosition = new BlockPos(tag.getIntValue("x").get(), tag.getIntValue("y").get(), tag.getIntValue("z").get()); +- if (!type.isEmpty()) { +- BlockPos blockPosition = new BlockPos(tag.getInt("x"), tag.getInt("y"), tag.getInt("z")); - BlockState blockData = nmsChunk.getBlockState(blockPosition); - BlockEntity entity = BlockEntity.loadStatic(blockPosition, blockData, (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)); - @@ -107,23 +106,22 @@ index ba0b401e0b39605303e90720f7c8dc48fcb0bc29..6b38f707b43e1e584c79a6c8d9ec1232 - } + if (entities != null) { + net.minecraft.server.level.ChunkMap.postLoadProtoChunk(instance, entities.stream() -+ .map(flowTag -> (net.minecraft.nbt.CompoundTag) Converter.convertTag(flowTag)).toList(), nmsChunk.getPos()); ++ .map(tag -> (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)).toList(), nmsChunk.getPos()); } }; -@@ -133,6 +120,25 @@ public class SlimeChunkConverter { +@@ -130,6 +118,24 @@ public class SlimeChunkConverter { LevelChunkTicks fluidLevelChunkTicks = new LevelChunkTicks<>(); SlimeChunkLevel nmsChunk = new SlimeChunkLevel(instance, pos, UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks, 0L, sections, loadEntities, null); -+ List tileEntities = chunk.getTileEntities(); ++ List tileEntities = chunk.getTileEntities(); + + if (tileEntities != null) { -+ for (CompoundTag tag : tileEntities) { -+ Optional type = tag.getStringValue("id"); ++ for (CompoundBinaryTag tag : tileEntities) { ++ String type = tag.getString("id"); + -+ // Sometimes null tile entities are saved -+ if (type.isPresent()) { -+ BlockPos blockPosition = new BlockPos(tag.getIntValue("x").get(), tag.getIntValue("y").get(), tag.getIntValue("z").get()); ++ if (!type.isEmpty()) { ++ BlockPos blockPosition = new BlockPos(tag.getInt("x"), tag.getInt("y"), tag.getInt("z")); + BlockState blockData = nmsChunk.getBlockState(blockPosition); + BlockEntity entity = BlockEntity.loadStatic(blockPosition, blockData, (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)); + @@ -136,4 +134,4 @@ index ba0b401e0b39605303e90720f7c8dc48fcb0bc29..6b38f707b43e1e584c79a6c8d9ec1232 + // Height Maps EnumSet heightMapTypes = nmsChunk.getStatus().heightmapsAfter(); - CompoundMap heightMaps = chunk.getHeightMaps().getValue(); + CompoundBinaryTag heightMaps = chunk.getHeightMaps(); diff --git a/patches/server/0006-Handle-null-data-properly.patch b/patches/server/0006-Handle-null-data-properly.patch index ebad5140d..512b843e6 100644 --- a/patches/server/0006-Handle-null-data-properly.patch +++ b/patches/server/0006-Handle-null-data-properly.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Handle null data properly diff --git a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -index 2f5b79632226f5d0112a4c0ddfc903d6b2b93549..eb426271140d9e36b09ef96e4c59c21d265a5edc 100644 +index 694bd135fd4398ecf02940e638fae1047e217a29..6856a7254685b2d005bcb2a91841f53d8743e38d 100644 --- a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java +++ b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -@@ -45,9 +45,12 @@ class SimpleDataFixerConverter implements SlimeWorldReader { +@@ -44,9 +44,12 @@ class SimpleDataFixerConverter implements SlimeWorldReader { ); } @@ -19,9 +19,9 @@ index 2f5b79632226f5d0112a4c0ddfc903d6b2b93549..eb426271140d9e36b09ef96e4c59c21d SlimeChunkSection dataSection = chunk.getSections()[i]; + if (dataSection == null) continue; - com.flowpowered.nbt.CompoundTag blockStateTag = blockStateTag = convertAndBack(dataSection.getBlockStatesTag(), (tag) -> { + CompoundBinaryTag blockStateTag = blockStateTag = convertAndBack(dataSection.getBlockStatesTag(), (tag) -> { WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, new NBTMapType(tag), "palette", currentVersion, newVersion); -@@ -63,17 +66,17 @@ class SimpleDataFixerConverter implements SlimeWorldReader { +@@ -62,17 +65,17 @@ class SimpleDataFixerConverter implements SlimeWorldReader { dataSection.getBlockLight(), dataSection.getSkyLight() ); diff --git a/patches/server/0007-Make-SlimeWorld-a-PersistentDataHolder.patch b/patches/server/0007-Make-SlimeWorld-a-PersistentDataHolder.patch index de4933554..fc9588079 100644 --- a/patches/server/0007-Make-SlimeWorld-a-PersistentDataHolder.patch +++ b/patches/server/0007-Make-SlimeWorld-a-PersistentDataHolder.patch @@ -5,25 +5,19 @@ Subject: [PATCH] Make SlimeWorld a PersistentDataHolder diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -index 0c1e599aa7d148c40ece1957c89991e1d761162a..4c503e5a31ba38c5a52e9b6738a6ade4fab94b49 100644 +index 68240b46ce911674ed288fe559737572fa44de6a..7b702b41a1bc589bf405ea280b8fc1c744012081 100644 --- a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java +++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -@@ -1,5 +1,6 @@ - package com.infernalsuite.asp; - -+import com.flowpowered.nbt.CompoundMap; - import com.infernalsuite.asp.api.SlimeNMSBridge; - import com.infernalsuite.asp.api.world.SlimeWorld; - import com.infernalsuite.asp.api.world.SlimeWorldInstance; -@@ -12,6 +13,7 @@ import net.kyori.adventure.util.Services; +@@ -8,7 +8,7 @@ import com.infernalsuite.asp.level.SlimeBootstrap; + import com.infernalsuite.asp.level.SlimeInMemoryWorld; + import com.infernalsuite.asp.level.SlimeLevelInstance; + import com.mojang.serialization.Lifecycle; +-import net.kyori.adventure.util.Services; ++import net.kyori.adventure.nbt.CompoundBinaryTag; import net.minecraft.SharedConstants; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; -+import net.minecraft.nbt.Tag; - import net.minecraft.resources.ResourceKey; - import net.minecraft.resources.ResourceLocation; - import net.minecraft.server.MinecraftServer; -@@ -30,13 +32,18 @@ import org.apache.logging.log4j.Logger; +@@ -30,6 +30,9 @@ import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.craftbukkit.CraftWorld; @@ -33,47 +27,51 @@ index 0c1e599aa7d148c40ece1957c89991e1d761162a..4c503e5a31ba38c5a52e9b6738a6ade4 import org.jetbrains.annotations.Nullable; import java.io.IOException; - import java.util.Locale; -+import java.util.Map; +@@ -37,6 +40,7 @@ import java.util.Locale; public class SlimeNMSBridgeImpl implements SlimeNMSBridge { + private static final CraftPersistentDataTypeRegistry REGISTRY = new CraftPersistentDataTypeRegistry(); private static final SimpleDataFixerConverter DATA_FIXER_CONVERTER = new SimpleDataFixerConverter(); - private static final Logger LOGGER = LogManager.getLogger("SWM"); -@@ -49,6 +56,26 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { + private static final Logger LOGGER = LogManager.getLogger("ASP"); +@@ -49,6 +53,22 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { return (SlimeNMSBridgeImpl) SlimeNMSBridge.instance(); } + @Override -+ public void extractCraftPDC(PersistentDataContainer source, CompoundMap target) { ++ public void extractCraftPDC(PersistentDataContainer source, CompoundBinaryTag.Builder builder) { + if (source instanceof CraftPersistentDataContainer craftPDC) { -+ for (Map.Entry entry : craftPDC.getRaw().entrySet()) { -+ target.put(Converter.convertTag(entry.getKey(), entry.getValue())); -+ } ++ craftPDC.getRaw().forEach((key, nmsTag) -> builder.put(key, Converter.convertTag(nmsTag))); + } else { + throw new IllegalArgumentException("PersistentDataContainer is not a CraftPersistentDataContainer"); + } + } + + @Override -+ public PersistentDataContainer extractCompoundMapIntoCraftPDC(CompoundMap source) { -+ var container = new CraftPersistentDataContainer(REGISTRY); -+ for (Map.Entry> entry : source.entrySet()) { -+ container.put(entry.getKey(), Converter.convertTag(entry.getValue())); -+ } ++ public PersistentDataContainer extractCompoundMapIntoCraftPDC(CompoundBinaryTag source) { ++ CraftPersistentDataContainer container = new CraftPersistentDataContainer(REGISTRY); ++ source.forEach(entry -> container.put(entry.getKey(), Converter.convertTag(entry.getValue()))); + return container; + } + @Override public boolean loadOverworldOverride() { if (defaultWorld == null) { +@@ -179,7 +199,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { + // level.setReady(true); + level.setSpawnSettings(world.getPropertyMap().getValue(SlimeProperties.ALLOW_MONSTERS), world.getPropertyMap().getValue(SlimeProperties.ALLOW_ANIMALS)); + +- var nmsExtraData = (CompoundTag) Converter.convertTag(world.getExtraData()); ++ CompoundTag nmsExtraData = (CompoundTag) Converter.convertTag(CompoundBinaryTag.from(world.getExtraData())); + + //Attempt to read PDC + if (nmsExtraData.get("BukkitValues") != null) level.getWorld().readBukkitValues(nmsExtraData.get("BukkitValues")); diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java -index 3dc776b5387b4e2f1b669f754b5b064fc0142006..76ee216925d9ced3c9bf1e7e8e1d8b80ca9f8e50 100644 +index 41119f2b0d208718c294076dc3c51f55680b0257..25249743caca6f354005d7f9e4498fdf413df629 100644 --- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java +++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java -@@ -9,6 +9,8 @@ import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +@@ -10,6 +10,8 @@ import net.kyori.adventure.nbt.CompoundBinaryTag; import net.minecraft.SharedConstants; import net.minecraft.server.level.ChunkHolder; import net.minecraft.world.level.chunk.LevelChunk; @@ -82,30 +80,31 @@ index 3dc776b5387b4e2f1b669f754b5b064fc0142006..76ee216925d9ced3c9bf1e7e8e1d8b80 import java.io.IOException; import java.util.Collection; -@@ -88,4 +90,9 @@ public class NMSSlimeWorld implements SlimeWorld { +@@ -90,4 +92,9 @@ public class NMSSlimeWorld implements SlimeWorld { public int getDataVersion() { return SharedConstants.getCurrentVersion().getDataVersion().getVersion(); } +-} +\ No newline at end of file + + @Override + public @NotNull PersistentDataContainer getPersistentDataContainer() { -+ return memoryWorld.getPersistentDataContainer(); ++ return this.memoryWorld.getPersistentDataContainer(); + } - } -\ No newline at end of file ++} diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -index 5d325e85a4634c21ab0bec12b493ea9b857d8ff3..35d0dd30b3c91b423c03a8f1682a422bf5eb8bc1 100644 +index 387954aae7ef1a39025a474ab1fe81b7216d8d6c..70787a7b87a0ebb4d47de7d110fadc8952708c58 100644 --- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -5,6 +5,7 @@ import com.infernalsuite.asp.ChunkPos; +@@ -4,6 +4,7 @@ import com.infernalsuite.asp.ChunkPos; import com.infernalsuite.asp.Converter; import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; import com.infernalsuite.asp.api.loaders.SlimeLoader; -+import com.infernalsuite.asp.pdc.FlowPersistentDataContainer; ++import com.infernalsuite.asp.pdc.AdventurePersistentDataContainer; import com.infernalsuite.asp.serialization.slime.SlimeSerializer; import com.infernalsuite.asp.skeleton.SkeletonCloning; import com.infernalsuite.asp.skeleton.SkeletonSlimeWorld; -@@ -19,6 +20,8 @@ import net.minecraft.world.level.chunk.UpgradeData; +@@ -20,6 +21,8 @@ import net.minecraft.world.level.chunk.UpgradeData; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.ticks.LevelChunkTicks; import org.bukkit.World; @@ -114,23 +113,40 @@ index 5d325e85a4634c21ab0bec12b493ea9b857d8ff3..35d0dd30b3c91b423c03a8f1682a422b import java.io.IOException; import java.util.ArrayList; -@@ -38,6 +41,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -40,6 +43,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { private final SlimeWorld liveWorld; - private final CompoundTag extra; -+ private final FlowPersistentDataContainer extraPDC; + private final ConcurrentMap extra; ++ private final AdventurePersistentDataContainer extraPDC; private final SlimePropertyMap propertyMap; private final SlimeLoader loader; -@@ -60,6 +64,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -62,6 +66,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { this.chunkStorage.put(pos, initial); } -+ this.extraPDC = new FlowPersistentDataContainer(extra); ++ this.extraPDC = new AdventurePersistentDataContainer(this.extra); this.liveWorld = new NMSSlimeWorld(this); } -@@ -260,4 +265,9 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -241,13 +246,12 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { + // Serialize Bukkit Values (PDC) + + var nmsTag = new net.minecraft.nbt.CompoundTag(); +- +- instance.getWorld().storeBukkitValues(nmsTag); ++ this.instance.getWorld().storeBukkitValues(nmsTag); + + // Bukkit stores the relevant tag as a tag with the key "BukkitValues" in the tag we supply to it +- var flowTag = Converter.convertTag("BukkitValues", nmsTag.getCompound("BukkitValues")); ++ var adventureTag = Converter.convertTag(nmsTag.getCompound("BukkitValues")); + +- world.getExtraData().getValue().put(flowTag); ++ world.getExtraData().put("BukkitValues", adventureTag); + + return new SkeletonSlimeWorld(world.getName(), + world.getLoader(), +@@ -262,4 +266,9 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { public SlimeLevelInstance getInstance() { return instance; } diff --git a/patches/server/0008-Add-v12-chunk-pdc-and-extra-nbt.-Fix-double-compress.patch b/patches/server/0008-Add-v12-chunk-pdc-and-extra-nbt.-Fix-double-compress.patch index 445aa874e..e06b417b2 100644 --- a/patches/server/0008-Add-v12-chunk-pdc-and-extra-nbt.-Fix-double-compress.patch +++ b/patches/server/0008-Add-v12-chunk-pdc-and-extra-nbt.-Fix-double-compress.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Add v12, chunk pdc and extra nbt. Fix double compression on diff --git a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -index eb426271140d9e36b09ef96e4c59c21d265a5edc..36d13632916b8e93d5f28c29ea80ef4ac87e6c89 100644 +index 6856a7254685b2d005bcb2a91841f53d8743e38d..de83872d147e790cb0fb98f1a407a22927faed28 100644 --- a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java +++ b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -@@ -70,11 +70,12 @@ class SimpleDataFixerConverter implements SlimeWorldReader { +@@ -69,11 +69,12 @@ class SimpleDataFixerConverter implements SlimeWorldReader { chunks.put(chunkPos, new SlimeChunkSkeleton( chunk.getX(), @@ -25,39 +25,46 @@ index eb426271140d9e36b09ef96e4c59c21d265a5edc..36d13632916b8e93d5f28c29ea80ef4a } diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -index 9a6e901b394d1e7740e616a33e6c251ae1d7e0e0..dc34469712bdd84d4b17dfd5e9657c3a12420241 100644 +index beb56b2495a52e1fac815de664677d73ce2bbcc3..33c0379c6ac41938296643a294ea362a96e3a5ea 100644 --- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -67,9 +67,11 @@ public class NMSSlimeChunk implements SlimeChunk { } private LevelChunk chunk; -+ private CompoundTag extra; ++ private CompoundBinaryTag extra; - public NMSSlimeChunk(LevelChunk chunk) { + public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference) { this.chunk = chunk; -+ this.extra = reference == null ? new CompoundTag("", new CompoundMap()) : reference.getExtraData(); ++ this.extra = reference == null ? CompoundBinaryTag.empty() : reference.getExtraData(); } @Override -@@ -192,6 +194,11 @@ public class NMSSlimeChunk implements SlimeChunk { - }); +@@ -176,6 +178,11 @@ public class NMSSlimeChunk implements SlimeChunk { + return Lists.transform(entities, Converter::convertTag); } + @Override -+ public CompoundTag getExtraData() { ++ public CompoundBinaryTag getExtraData() { + return extra; + } + public LevelChunk getChunk() { return chunk; } +@@ -184,4 +191,4 @@ public class NMSSlimeChunk implements SlimeChunk { + this.chunk = chunk; + } + +-} +\ No newline at end of file ++} diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java -index 76ee216925d9ced3c9bf1e7e8e1d8b80ca9f8e50..bd2f8da46d4a04f2777086a416015563f3b06cdf 100644 +index 25249743caca6f354005d7f9e4498fdf413df629..8cd79bf34a9074d06d342f956165891613ae6cf0 100644 --- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java +++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java -@@ -45,14 +45,14 @@ public class NMSSlimeWorld implements SlimeWorld { +@@ -47,14 +47,14 @@ public class NMSSlimeWorld implements SlimeWorld { return null; } @@ -75,7 +82,7 @@ index 76ee216925d9ced3c9bf1e7e8e1d8b80ca9f8e50..bd2f8da46d4a04f2777086a416015563 } diff --git a/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java b/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java -index 025da4dd831f9b8b35000be7de493d44caa41003..7dd1c52f718866f8918c30de9cc71d151eddc958 100644 +index fa8254ca4b2eafa4e5669c3e0467ed1f7d4dc159..4ca8d6f40b1e5e7e0f106a6880eaf8afc1128213 100644 --- a/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java +++ b/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java @@ -62,6 +62,15 @@ public class SafeNmsChunkWrapper implements SlimeChunk { @@ -83,7 +90,7 @@ index 025da4dd831f9b8b35000be7de493d44caa41003..7dd1c52f718866f8918c30de9cc71d15 } + @Override -+ public CompoundTag getExtraData() { ++ public CompoundBinaryTag getExtraData() { + if (shouldDefaultBackToSlimeChunk()) { + return this.safety.getExtraData(); + } @@ -95,10 +102,10 @@ index 025da4dd831f9b8b35000be7de493d44caa41003..7dd1c52f718866f8918c30de9cc71d15 Slime chunks can still be requested but not actually loaded, this caused some things to not properly save because they are not "loaded" into the chunk. diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -index 6b38f707b43e1e584c79a6c8d9ec1232ed2901b9..d3289cb71f9ff71d5122ed43e9a0ab40f93c774a 100644 +index b705b3133634c3696dee766cbfc95380293ccda3..05e520256b3d047a85b98552883044ca6b658b3d 100644 --- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -@@ -165,6 +165,13 @@ public class SlimeChunkConverter { +@@ -162,6 +162,13 @@ public class SlimeChunkConverter { Heightmap.primeHeightmaps(nmsChunk, unsetHeightMaps); } @@ -112,20 +119,11 @@ index 6b38f707b43e1e584c79a6c8d9ec1232ed2901b9..d3289cb71f9ff71d5122ed43e9a0ab40 return nmsChunk; } } -\ No newline at end of file diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -index 35d0dd30b3c91b423c03a8f1682a422bf5eb8bc1..15340aecc97a30767340f7837a21decc74afbe9c 100644 +index 70787a7b87a0ebb4d47de7d110fadc8952708c58..58b54839576b92e87f6941ab2457c0c0c5469df8 100644 --- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -1,6 +1,7 @@ - package com.infernalsuite.asp.level; - - import com.flowpowered.nbt.CompoundTag; -+import com.flowpowered.nbt.Tag; - import com.infernalsuite.asp.ChunkPos; - import com.infernalsuite.asp.Converter; - import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; -@@ -88,11 +89,11 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -90,11 +90,11 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { levelChunk = new SlimeChunkLevel(this.instance, pos, UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks, 0L, null, null, null); @@ -139,7 +137,7 @@ index 35d0dd30b3c91b423c03a8f1682a422bf5eb8bc1..15340aecc97a30767340f7837a21decc } this.chunkStorage.put(new ChunkPos(x, z), chunk); -@@ -105,7 +106,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -107,7 +107,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { final int x = providedChunk.locX; final int z = providedChunk.locZ; @@ -148,7 +146,7 @@ index 35d0dd30b3c91b423c03a8f1682a422bf5eb8bc1..15340aecc97a30767340f7837a21decc if (FastChunkPruner.canBePruned(this.liveWorld, providedChunk)) { this.chunkStorage.remove(new ChunkPos(x, z)); -@@ -114,7 +115,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -116,7 +116,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { this.chunkStorage.put(new ChunkPos(x, z), new SlimeChunkSkeleton(chunk.getX(), chunk.getZ(), chunk.getSections(), @@ -157,15 +155,14 @@ index 35d0dd30b3c91b423c03a8f1682a422bf5eb8bc1..15340aecc97a30767340f7837a21decc } @Override -@@ -227,13 +228,20 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -229,13 +229,19 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { continue; } + // Serialize Bukkit Values (PDC) + -+ Tag flowTag = Converter.convertTag("ChunkBukkitValues", chunk.persistentDataContainer.toTagCompound()); -+ -+ clonedChunk.getExtraData().getValue().put(flowTag); ++ CompoundBinaryTag adventureTag = Converter.convertTag(chunk.persistentDataContainer.toTagCompound()); ++ clonedChunk.getExtraData().put("ChunkBukkitValues", adventureTag); + clonedChunk = new SlimeChunkSkeleton( clonedChunk.getX(), diff --git a/patches/server/0009-Add-migration-from-SRF-1-8.patch b/patches/server/0009-Add-migration-from-SRF-1-8.patch index edfd8cd53..bae4cf22f 100644 --- a/patches/server/0009-Add-migration-from-SRF-1-8.patch +++ b/patches/server/0009-Add-migration-from-SRF-1-8.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add migration from SRF 1-8 diff --git a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -index 36d13632916b8e93d5f28c29ea80ef4ac87e6c89..b2a0913290694d27151779aac5fb6be57f01da8b 100644 +index de83872d147e790cb0fb98f1a407a22927faed28..ec45c627df14a87087e39556cb90eb2d5b52a981 100644 --- a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java +++ b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java @@ -1,5 +1,6 @@ @@ -15,7 +15,7 @@ index 36d13632916b8e93d5f28c29ea80ef4ac87e6c89..b2a0913290694d27151779aac5fb6be5 import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; import ca.spottedleaf.dataconverter.types.nbt.NBTMapType; -@@ -30,18 +31,21 @@ class SimpleDataFixerConverter implements SlimeWorldReader { +@@ -29,18 +30,21 @@ class SimpleDataFixerConverter implements SlimeWorldReader { return data; } @@ -24,36 +24,36 @@ index 36d13632916b8e93d5f28c29ea80ef4ac87e6c89..b2a0913290694d27151779aac5fb6be5 + Map chunks = new HashMap<>(); for (SlimeChunk chunk : data.getChunkStorage()) { - List entities = new ArrayList<>(); - List blockEntities = new ArrayList<>(); - for (CompoundTag upgradeEntity : chunk.getTileEntities()) { + List entities = new ArrayList<>(); + List blockEntities = new ArrayList<>(); + for (CompoundBinaryTag upgradeEntity : chunk.getTileEntities()) { blockEntities.add( - convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.TILE_ENTITY.convert(new NBTMapType(tag), currentVersion, newVersion)) + convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.TILE_ENTITY.convert(new NBTMapType(tag), encodedCurrentVersion, encodedNewVersion)) ); } - for (CompoundTag upgradeEntity : chunk.getEntities()) { + for (CompoundBinaryTag upgradeEntity : chunk.getEntities()) { entities.add( - convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.ENTITY.convert(new NBTMapType(tag), currentVersion, newVersion)) + convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.ENTITY.convert(new NBTMapType(tag), encodedCurrentVersion, encodedNewVersion)) ); } -@@ -53,11 +57,11 @@ class SimpleDataFixerConverter implements SlimeWorldReader { +@@ -52,11 +56,11 @@ class SimpleDataFixerConverter implements SlimeWorldReader { if (dataSection == null) continue; - com.flowpowered.nbt.CompoundTag blockStateTag = blockStateTag = convertAndBack(dataSection.getBlockStatesTag(), (tag) -> { + CompoundBinaryTag blockStateTag = blockStateTag = convertAndBack(dataSection.getBlockStatesTag(), (tag) -> { - WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, new NBTMapType(tag), "palette", currentVersion, newVersion); + WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, new NBTMapType(tag), "palette", encodedCurrentVersion, encodedNewVersion); }); - com.flowpowered.nbt.CompoundTag biomeTag = convertAndBack(dataSection.getBiomeTag(), (tag) -> { + CompoundBinaryTag biomeTag = convertAndBack(dataSection.getBiomeTag(), (tag) -> { - WalkerUtils.convertList(MCTypeRegistry.BIOME, new NBTMapType(tag), "palette", currentVersion, newVersion); + WalkerUtils.convertList(MCTypeRegistry.BIOME, new NBTMapType(tag), "palette", encodedCurrentVersion, encodedNewVersion); }); sections[i] = new SlimeChunkSectionSkeleton( -@@ -75,7 +79,8 @@ class SimpleDataFixerConverter implements SlimeWorldReader { +@@ -74,7 +78,8 @@ class SimpleDataFixerConverter implements SlimeWorldReader { chunk.getHeightMaps(), blockEntities, entities, @@ -64,7 +64,7 @@ index 36d13632916b8e93d5f28c29ea80ef4ac87e6c89..b2a0913290694d27151779aac5fb6be5 } diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -index 4c503e5a31ba38c5a52e9b6738a6ade4fab94b49..bfcd4fc5e0ce187c79491fc720bb4bebde51f8e1 100644 +index 7b702b41a1bc589bf405ea280b8fc1c744012081..95b4d139125f18414638c2b17266c6400a62bcf5 100644 --- a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java +++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java @@ -1,5 +1,8 @@ @@ -73,39 +73,31 @@ index 4c503e5a31ba38c5a52e9b6738a6ade4fab94b49..bfcd4fc5e0ce187c79491fc720bb4beb +import ca.spottedleaf.dataconverter.converters.DataConverter; +import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; +import ca.spottedleaf.dataconverter.types.nbt.NBTMapType; - import com.flowpowered.nbt.CompoundMap; import com.infernalsuite.asp.api.SlimeNMSBridge; import com.infernalsuite.asp.api.world.SlimeWorld; -@@ -9,7 +12,6 @@ import com.infernalsuite.asp.level.SlimeBootstrap; - import com.infernalsuite.asp.level.SlimeInMemoryWorld; - import com.infernalsuite.asp.level.SlimeLevelInstance; - import com.mojang.serialization.Lifecycle; --import net.kyori.adventure.util.Services; - import net.minecraft.SharedConstants; - import net.minecraft.core.registries.Registries; - import net.minecraft.nbt.CompoundTag; -@@ -76,6 +78,20 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { + import com.infernalsuite.asp.api.world.SlimeWorldInstance; +@@ -69,6 +72,20 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { return container; } + @Override -+ public com.flowpowered.nbt.CompoundTag convertChunkTo1_13(com.flowpowered.nbt.CompoundTag tag) { -+ CompoundTag converted = (CompoundTag) Converter.convertTag(tag); ++ public CompoundBinaryTag convertChunkTo1_13(CompoundBinaryTag tag) { ++ CompoundTag nmsTag = (CompoundTag) Converter.convertTag(tag); + -+ int version = converted.getInt("DataVersion"); ++ int version = nmsTag.getInt("DataVersion"); + + long encodedNewVersion = DataConverter.encodeVersions(1624, Integer.MAX_VALUE); + long encodedCurrentVersion = DataConverter.encodeVersions(version, Integer.MAX_VALUE); + -+ MCTypeRegistry.CHUNK.convert(new NBTMapType(converted), encodedCurrentVersion, encodedNewVersion); ++ MCTypeRegistry.CHUNK.convert(new NBTMapType(nmsTag), encodedCurrentVersion, encodedNewVersion); + -+ return (com.flowpowered.nbt.CompoundTag) Converter.convertTag(tag.getName(), converted); ++ return Converter.convertTag(nmsTag); + } + @Override public boolean loadOverworldOverride() { if (defaultWorld == null) { -@@ -166,7 +182,6 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { +@@ -159,7 +176,6 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { return DATA_FIXER_CONVERTER.readFromData(world); } @@ -114,7 +106,7 @@ index 4c503e5a31ba38c5a52e9b6738a6ade4fab94b49..bfcd4fc5e0ce187c79491fc720bb4beb public int getCurrentVersion() { return SharedConstants.getCurrentVersion().getDataVersion().getVersion(); diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -index dc34469712bdd84d4b17dfd5e9657c3a12420241..419c3c12177bc7b85c6643fb114b4d0ad8f80c46 100644 +index 33c0379c6ac41938296643a294ea362a96e3a5ea..4c627f8af92f29d9ba50745812acc83726a85683 100644 --- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -26,10 +26,7 @@ import net.minecraft.world.level.block.Block; @@ -133,23 +125,23 @@ index dc34469712bdd84d4b17dfd5e9657c3a12420241..419c3c12177bc7b85c6643fb114b4d0a } private LevelChunk chunk; -- private CompoundTag extra; -+ private final CompoundTag extra; -+ private final CompoundTag upgradeData; +- private CompoundBinaryTag extra; ++ private final CompoundBinaryTag extra; ++ private final CompoundBinaryTag upgradeData; public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference) { this.chunk = chunk; - this.extra = reference == null ? new CompoundTag("", new CompoundMap()) : reference.getExtraData(); + this.extra = reference == null ? CompoundBinaryTag.empty() : reference.getExtraData(); + this.upgradeData = reference == null ? null : reference.getUpgradeData(); } @Override -@@ -199,6 +198,11 @@ public class NMSSlimeChunk implements SlimeChunk { +@@ -183,6 +182,11 @@ public class NMSSlimeChunk implements SlimeChunk { return extra; } + @Override -+ public CompoundTag getUpgradeData() { ++ public CompoundBinaryTag getUpgradeData() { + return upgradeData; + } + @@ -157,7 +149,7 @@ index dc34469712bdd84d4b17dfd5e9657c3a12420241..419c3c12177bc7b85c6643fb114b4d0a return chunk; } diff --git a/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java b/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java -index 7dd1c52f718866f8918c30de9cc71d151eddc958..4df75c87f235ca5c55982c0b836f433eec9c9e9f 100644 +index 4ca8d6f40b1e5e7e0f106a6880eaf8afc1128213..b29c27424081885f10a93ae064d87871156f1f94 100644 --- a/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java +++ b/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java @@ -71,6 +71,15 @@ public class SafeNmsChunkWrapper implements SlimeChunk { @@ -165,7 +157,7 @@ index 7dd1c52f718866f8918c30de9cc71d151eddc958..4df75c87f235ca5c55982c0b836f433e } + @Override -+ public CompoundTag getUpgradeData() { ++ public CompoundBinaryTag getUpgradeData() { + if (shouldDefaultBackToSlimeChunk()) { + return this.safety.getUpgradeData(); + } @@ -177,10 +169,10 @@ index 7dd1c52f718866f8918c30de9cc71d151eddc958..4df75c87f235ca5c55982c0b836f433e Slime chunks can still be requested but not actually loaded, this caused some things to not properly save because they are not "loaded" into the chunk. diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -index d3289cb71f9ff71d5122ed43e9a0ab40f93c774a..ace4d6272560783fd7903495b5a3c84550b1b4d8 100644 +index 05e520256b3d047a85b98552883044ca6b658b3d..39e020135d996a4abb40dc6564d6c985e7bfbeda 100644 --- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -@@ -118,7 +118,14 @@ public class SlimeChunkConverter { +@@ -116,7 +116,14 @@ public class SlimeChunkConverter { LevelChunkTicks blockLevelChunkTicks = new LevelChunkTicks<>(); LevelChunkTicks fluidLevelChunkTicks = new LevelChunkTicks<>(); @@ -194,13 +186,13 @@ index d3289cb71f9ff71d5122ed43e9a0ab40f93c774a..ace4d6272560783fd7903495b5a3c845 + } + SlimeChunkLevel nmsChunk = new SlimeChunkLevel(instance, pos, upgradeData, blockLevelChunkTicks, fluidLevelChunkTicks, 0L, sections, loadEntities, null); - List tileEntities = chunk.getTileEntities(); + List tileEntities = chunk.getTileEntities(); diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -index 15340aecc97a30767340f7837a21decc74afbe9c..619075ededa0443cf8f888f04d863bf7b936a4b0 100644 +index 58b54839576b92e87f6941ab2457c0c0c5469df8..03d9c9448d7c010f5daf69cabce6bf861ea203aa 100644 --- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -115,7 +115,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -116,7 +116,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { this.chunkStorage.put(new ChunkPos(x, z), new SlimeChunkSkeleton(chunk.getX(), chunk.getZ(), chunk.getSections(), diff --git a/patches/server/0011-Fix-chunks-not-getting-serialized-when-reloaded.patch b/patches/server/0011-Fix-chunks-not-getting-serialized-when-reloaded.patch index 6e13e13db..96837ed92 100644 --- a/patches/server/0011-Fix-chunks-not-getting-serialized-when-reloaded.patch +++ b/patches/server/0011-Fix-chunks-not-getting-serialized-when-reloaded.patch @@ -21,10 +21,10 @@ index 0d218911fb8be1bc5272b6e291ec60404306c831..a92d17b5c6a7c8427ecbdf56a9c2a0c1 } \ No newline at end of file diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -index 619075ededa0443cf8f888f04d863bf7b936a4b0..70eb8b95740b46579ad3520ca1d3395a920a8a6a 100644 +index 03d9c9448d7c010f5daf69cabce6bf861ea203aa..8fcb0ab62ce098a07cc5a0d3b481a45e9f75e161 100644 --- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -219,7 +219,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -220,7 +220,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { } else { chunk = safeNmsChunkWrapper.getWrapper().getChunk(); } @@ -33,7 +33,7 @@ index 619075ededa0443cf8f888f04d863bf7b936a4b0..70eb8b95740b46579ad3520ca1d3395a chunk = nmsSlimeChunk.getChunk(); } -@@ -279,4 +279,10 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -278,4 +278,10 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { public @NotNull PersistentDataContainer getPersistentDataContainer() { return this.extraPDC; } diff --git a/patches/server/0012-Compile-fixes.patch b/patches/server/0012-Compile-fixes.patch index 070b28a17..03548c897 100644 --- a/patches/server/0012-Compile-fixes.patch +++ b/patches/server/0012-Compile-fixes.patch @@ -19,7 +19,7 @@ index b5b5c099e61f828edbcd18aba9d379a6e45fb8b4..838639a8bbeb59700037c3e101714f68 // Paper start implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -index 419c3c12177bc7b85c6643fb114b4d0ad8f80c46..b6c0ba9325b06e1d76609aa4de564af11f231a74 100644 +index 4c627f8af92f29d9ba50745812acc83726a85683..6972d6399628eda41756a98fb54fbe93eb827716 100644 --- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -46,18 +46,14 @@ public class NMSSlimeChunk implements SlimeChunk { @@ -31,7 +31,7 @@ index 419c3c12177bc7b85c6643fb114b4d0ad8f80c46..b6c0ba9325b06e1d76609aa4de564af1 - }); + Tag tag = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); - EMPTY_BLOCK_STATE_PALETTE = (CompoundTag) Converter.convertTag("", tag); + EMPTY_BLOCK_STATE_PALETTE = Converter.convertTag(tag); } { Registry biomes = net.minecraft.server.MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME); @@ -41,7 +41,7 @@ index 419c3c12177bc7b85c6643fb114b4d0ad8f80c46..b6c0ba9325b06e1d76609aa4de564af1 - }); + Tag tag = ChunkSerializer.makeBiomeCodec(biomes).encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); - EMPTY_BIOME_PALETTE = (CompoundTag) Converter.convertTag("", tag); + EMPTY_BIOME_PALETTE = Converter.convertTag(tag); } @@ -110,7 +106,7 @@ public class NMSSlimeChunk implements SlimeChunk { if (section.hasOnlyAir()) { @@ -49,7 +49,7 @@ index 419c3c12177bc7b85c6643fb114b4d0ad8f80c46..b6c0ba9325b06e1d76609aa4de564af1 } else { - Tag data = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, section.getStates()).getOrThrow(false, System.err::println); // todo error handling + Tag data = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, section.getStates()).getOrThrow(); // todo error handling - blockStateTag = (CompoundTag) Converter.convertTag("", data); + blockStateTag = Converter.convertTag(data); } @@ -120,7 +116,7 @@ public class NMSSlimeChunk implements SlimeChunk { @@ -58,23 +58,23 @@ index 419c3c12177bc7b85c6643fb114b4d0ad8f80c46..b6c0ba9325b06e1d76609aa4de564af1 } else { - Tag biomeData = codec.encodeStart(NbtOps.INSTANCE, section.getBiomes()).getOrThrow(false, System.err::println); // todo error handling + Tag biomeData = codec.encodeStart(NbtOps.INSTANCE, section.getBiomes()).getOrThrow(); // todo error handling - biomeTag = (CompoundTag) Converter.convertTag("", biomeData); + biomeTag = Converter.convertTag(biomeData); } -@@ -154,7 +150,7 @@ public class NMSSlimeChunk implements SlimeChunk { - List tileEntities = new ArrayList<>(); +@@ -148,7 +144,7 @@ public class NMSSlimeChunk implements SlimeChunk { + List tileEntities = new ArrayList<>(); - for (BlockEntity entity : chunk.blockEntities.values()) { -- net.minecraft.nbt.CompoundTag entityNbt = entity.saveWithFullMetadata(); -+ net.minecraft.nbt.CompoundTag entityNbt = entity.saveWithFullMetadata(net.minecraft.server.MinecraftServer.getServer().registryAccess()); + for (BlockEntity entity : this.chunk.blockEntities.values()) { +- CompoundTag entityNbt = entity.saveWithFullMetadata(); ++ CompoundTag entityNbt = entity.saveWithFullMetadata(net.minecraft.server.MinecraftServer.getServer().registryAccess()); tileEntities.add(entityNbt); } diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -index ace4d6272560783fd7903495b5a3c84550b1b4d8..6807767a2067b62558f749da0c25f184082d0769 100644 +index 39e020135d996a4abb40dc6564d6c985e7bfbeda..9bfb64e022db3bd9ed4d818d69df1f9a955cfa5d 100644 --- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -@@ -78,7 +78,7 @@ public class SlimeChunkConverter { +@@ -76,7 +76,7 @@ public class SlimeChunkConverter { DataResult> dataresult = ChunkSerializer.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, Converter.convertTag(slimeSection.getBlockStatesTag())).promotePartial((s) -> { System.out.println("Recoverable error when parsing section " + x + "," + z + ": " + s); // todo proper logging }); @@ -83,7 +83,7 @@ index ace4d6272560783fd7903495b5a3c84550b1b4d8..6807767a2067b62558f749da0c25f184 } else { blockPalette = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, null); } -@@ -89,7 +89,7 @@ public class SlimeChunkConverter { +@@ -87,7 +87,7 @@ public class SlimeChunkConverter { DataResult>> dataresult = codec.parse(NbtOps.INSTANCE, Converter.convertTag(slimeSection.getBiomeTag())).promotePartial((s) -> { System.out.println("Recoverable error when parsing section " + x + "," + z + ": " + s); // todo proper logging }); @@ -92,9 +92,9 @@ index ace4d6272560783fd7903495b5a3c84550b1b4d8..6807767a2067b62558f749da0c25f184 } else { biomePalette = new PalettedContainer<>(biomeRegistry.asHolderIdMap(), biomeRegistry.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); } -@@ -137,7 +137,7 @@ public class SlimeChunkConverter { - if (type.isPresent()) { - BlockPos blockPosition = new BlockPos(tag.getIntValue("x").get(), tag.getIntValue("y").get(), tag.getIntValue("z").get()); +@@ -134,7 +134,7 @@ public class SlimeChunkConverter { + if (!type.isEmpty()) { + BlockPos blockPosition = new BlockPos(tag.getInt("x"), tag.getInt("y"), tag.getInt("z")); BlockState blockData = nmsChunk.getBlockState(blockPosition); - BlockEntity entity = BlockEntity.loadStatic(blockPosition, blockData, (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)); + BlockEntity entity = BlockEntity.loadStatic(blockPosition, blockData, (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag), net.minecraft.server.MinecraftServer.getServer().registryAccess()); @@ -102,18 +102,18 @@ index ace4d6272560783fd7903495b5a3c84550b1b4d8..6807767a2067b62558f749da0c25f184 if (entity != null) { nmsChunk.setBlockEntity(entity); diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java -index b74ccd2b6b526f7b7955ce601a37185d3b6a2f59..18053d099145bd9351902ff062139c731eafc5d3 100644 +index b74ccd2b6b526f7b7955ce601a37185d3b6a2f59..5e72a283c9110a2a65939fda97c4e6f89a1b3755 100644 --- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java +++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java -@@ -1,6 +1,7 @@ +@@ -1,6 +1,6 @@ package com.infernalsuite.asp.level; - import com.mojang.serialization.Codec; +-import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; import net.minecraft.core.Holder; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.BiomeSource; -@@ -21,7 +22,7 @@ public class SlimeLevelGenerator extends FlatLevelSource { +@@ -21,7 +21,7 @@ public class SlimeLevelGenerator extends FlatLevelSource { private static BiomeSource getSource(Holder biome) { return new BiomeSource() { @Override diff --git a/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch b/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch index 8293c5747..a16752926 100644 --- a/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch +++ b/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch @@ -18,14 +18,12 @@ index 838639a8bbeb59700037c3e101714f68f8b79671..26be7ff48f2eb50a140e71372cfef54d implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ diff --git a/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java b/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java new file mode 100644 -index 0000000000000000000000000000000000000000..704cf0fa3d3c6114923d5b9b9594a4ba9d7ab0a6 +index 0000000000000000000000000000000000000000..06e91530198d9075434045893f95f7a6ae5bfbb3 --- /dev/null +++ b/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java -@@ -0,0 +1,243 @@ +@@ -0,0 +1,241 @@ +package com.infernalsuite.asp; + -+import com.flowpowered.nbt.CompoundMap; -+import com.flowpowered.nbt.CompoundTag; +import com.infernalsuite.asp.api.SlimeNMSBridge; +import com.infernalsuite.asp.api.AdvancedSlimePaperAPI; +import com.infernalsuite.asp.api.events.LoadSlimeWorldEvent; @@ -192,7 +190,7 @@ index 0000000000000000000000000000000000000000..704cf0fa3d3c6114923d5b9b9594a4ba + Objects.requireNonNull(worldName, "World name cannot be null"); + Objects.requireNonNull(propertyMap, "Properties cannot be null"); + -+ return new SkeletonSlimeWorld(worldName, loader, readOnly, Map.of(), new CompoundTag("", new CompoundMap()), propertyMap, BRIDGE_INSTANCE.getCurrentVersion()); ++ return new SkeletonSlimeWorld(worldName, loader, readOnly, Map.of(), new ConcurrentHashMap<>(), propertyMap, BRIDGE_INSTANCE.getCurrentVersion()); + } + + @Override @@ -228,7 +226,7 @@ index 0000000000000000000000000000000000000000..704cf0fa3d3c6114923d5b9b9594a4ba + SlimeWorld world; + + try { -+ world = AnvilWorldReader.INSTANCE.readFromData(new AnvilImportData(worldDir, worldName, loader)); ++ world = AnvilWorldReader.INSTANCE.readFromData(AnvilImportData.legacy(worldDir, worldName, loader)); + } catch (RuntimeException e) { + if (e.getCause() == null) { + throw e; @@ -424,19 +422,19 @@ index 4c7938c07e06810f475eac0bb4400c11154b56ba..cb8720e3961b897ae87a59c2c91d1502 } \ No newline at end of file diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -index bfcd4fc5e0ce187c79491fc720bb4bebde51f8e1..5d7afcb8e90bde6fd5aa3c1a10917f4fdb78ee3a 100644 +index 95b4d139125f18414638c2b17266c6400a62bcf5..328e70af280ccb32f4830e464f34499b8be0d72b 100644 --- a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java +++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -@@ -48,8 +48,6 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { +@@ -46,8 +46,6 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { private static final CraftPersistentDataTypeRegistry REGISTRY = new CraftPersistentDataTypeRegistry(); private static final SimpleDataFixerConverter DATA_FIXER_CONVERTER = new SimpleDataFixerConverter(); -- private static final Logger LOGGER = LogManager.getLogger("SWM"); +- private static final Logger LOGGER = LogManager.getLogger("ASP"); - private SlimeWorld defaultWorld; private SlimeWorld defaultNetherWorld; private SlimeWorld defaultEndWorld; -@@ -130,6 +128,13 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { +@@ -124,6 +122,13 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { return true; } @@ -451,10 +449,18 @@ index bfcd4fc5e0ce187c79491fc720bb4bebde51f8e1..5d7afcb8e90bde6fd5aa3c1a10917f4f public void setDefaultWorlds(SlimeWorld normalWorld, SlimeWorld netherWorld, SlimeWorld endWorld) { if (normalWorld != null) { diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -index b6c0ba9325b06e1d76609aa4de564af11f231a74..7b31aba65e30fdef7a3eeb96cd899e6be6839aa9 100644 +index 6972d6399628eda41756a98fb54fbe93eb827716..7326a5af48338d58ac657a5ab62e9fbeb96e4346 100644 --- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -@@ -31,13 +31,14 @@ import net.minecraft.world.level.chunk.storage.ChunkSerializer; +@@ -6,7 +6,6 @@ import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; + import com.infernalsuite.asp.api.utils.NibbleArray; + import com.infernalsuite.asp.api.world.SlimeChunk; + import com.infernalsuite.asp.api.world.SlimeChunkSection; +-import com.mojang.logging.LogUtils; + import com.mojang.serialization.Codec; + import io.papermc.paper.world.ChunkEntitySlices; + import net.kyori.adventure.nbt.CompoundBinaryTag; +@@ -31,13 +30,13 @@ import net.minecraft.world.level.chunk.storage.ChunkSerializer; import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.lighting.LevelLightEngine; import org.slf4j.Logger; @@ -462,19 +468,19 @@ index b6c0ba9325b06e1d76609aa4de564af11f231a74..7b31aba65e30fdef7a3eeb96cd899e6b import java.util.ArrayList; import java.util.List; - import java.util.Map; +-import java.util.Map; public class NMSSlimeChunk implements SlimeChunk { - private static final Logger LOGGER = LogUtils.getClassLogger(); + private static final Logger LOGGER = LoggerFactory.getLogger(NMSSlimeChunk.class); - private static final CompoundTag EMPTY_BLOCK_STATE_PALETTE; - private static final CompoundTag EMPTY_BIOME_PALETTE; + private static final CompoundBinaryTag EMPTY_BLOCK_STATE_PALETTE; + private static final CompoundBinaryTag EMPTY_BIOME_PALETTE; diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java -index bd2f8da46d4a04f2777086a416015563f3b06cdf..8c63ddf62415d0c88080fbe9a2ff9df4ffdd7a36 100644 +index 8cd79bf34a9074d06d342f956165891613ae6cf0..5e43f6094fdd0f7e0ab6f5c5379fc86e075d6173 100644 --- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java +++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java -@@ -35,7 +35,7 @@ public class NMSSlimeWorld implements SlimeWorld { +@@ -37,7 +37,7 @@ public class NMSSlimeWorld implements SlimeWorld { @Override public SlimeLoader getLoader() { @@ -483,7 +489,7 @@ index bd2f8da46d4a04f2777086a416015563f3b06cdf..8c63ddf62415d0c88080fbe9a2ff9df4 } @Override -@@ -50,7 +50,7 @@ public class NMSSlimeWorld implements SlimeWorld { +@@ -52,7 +52,7 @@ public class NMSSlimeWorld implements SlimeWorld { @Override public Collection getChunkStorage() { @@ -493,10 +499,10 @@ index bd2f8da46d4a04f2777086a416015563f3b06cdf..8c63ddf62415d0c88080fbe9a2ff9df4 .map((chunkLevel) -> new NMSSlimeChunk(chunkLevel, memoryWorld.getChunk(chunkLevel.getPos().x, chunkLevel.getPos().z))) // This sucks, is there a better way? .collect(Collectors.toList()); diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -index 70eb8b95740b46579ad3520ca1d3395a920a8a6a..e9b6114e1a799217b44001d66592bbae52b03e13 100644 +index 8fcb0ab62ce098a07cc5a0d3b481a45e9f75e161..9655bd071f435d8b33a78350abb804cafc77306f 100644 --- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -145,7 +145,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -146,7 +146,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { @Override public boolean isReadOnly() { @@ -505,7 +511,7 @@ index 70eb8b95740b46579ad3520ca1d3395a920a8a6a..e9b6114e1a799217b44001d66592bbae } @Override -@@ -185,11 +185,6 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -186,11 +186,6 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { return this.liveWorld.getDataVersion(); } @@ -515,7 +521,7 @@ index 70eb8b95740b46579ad3520ca1d3395a920a8a6a..e9b6114e1a799217b44001d66592bbae - } - @Override - public CompoundTag getExtraData() { + public ConcurrentMap getExtraData() { return this.extra; diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java index a8c103d435ac9473b1c5dd404e5c69ebf4353490..d6e5eac7732f32cabd6ed5ac6b10af20074a39b8 100644 diff --git a/patches/server/0014-replace-ChunkPos-with-long.patch b/patches/server/0014-replace-ChunkPos-with-long.patch index 1abdfd2e3..4059372e4 100644 --- a/patches/server/0014-replace-ChunkPos-with-long.patch +++ b/patches/server/0014-replace-ChunkPos-with-long.patch @@ -5,10 +5,10 @@ Subject: [PATCH] replace ChunkPos with long diff --git a/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java b/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java -index 704cf0fa3d3c6114923d5b9b9594a4ba9d7ab0a6..efa3639457e89870fc0a7dac8aa632579d74800f 100644 +index 06e91530198d9075434045893f95f7a6ae5bfbb3..7741a210ad71a66846cdae636917e1a89ac35c8d 100644 --- a/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java +++ b/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java -@@ -17,6 +17,7 @@ import com.infernalsuite.asp.serialization.slime.SlimeSerializer; +@@ -15,6 +15,7 @@ import com.infernalsuite.asp.serialization.slime.SlimeSerializer; import com.infernalsuite.asp.serialization.slime.reader.SlimeWorldReaderRegistry; import com.infernalsuite.asp.skeleton.SkeletonSlimeWorld; import com.infernalsuite.asp.util.NmsUtil; @@ -16,38 +16,42 @@ index 704cf0fa3d3c6114923d5b9b9594a4ba9d7ab0a6..efa3639457e89870fc0a7dac8aa63257 import net.minecraft.server.level.ServerLevel; import org.bukkit.Bukkit; import org.bukkit.World; -@@ -168,7 +169,7 @@ public class AdvancedSlimePaper implements AdvancedSlimePaperAPI { +@@ -166,7 +167,7 @@ public class AdvancedSlimePaper implements AdvancedSlimePaperAPI { Objects.requireNonNull(worldName, "World name cannot be null"); Objects.requireNonNull(propertyMap, "Properties cannot be null"); -- return new SkeletonSlimeWorld(worldName, loader, readOnly, Map.of(), new CompoundTag("", new CompoundMap()), propertyMap, BRIDGE_INSTANCE.getCurrentVersion()); -+ return new SkeletonSlimeWorld(worldName, loader, readOnly, new Long2ObjectOpenHashMap<>(0), new CompoundTag("", new CompoundMap()), propertyMap, BRIDGE_INSTANCE.getCurrentVersion()); +- return new SkeletonSlimeWorld(worldName, loader, readOnly, Map.of(), new ConcurrentHashMap<>(), propertyMap, BRIDGE_INSTANCE.getCurrentVersion()); ++ return new SkeletonSlimeWorld(worldName, loader, readOnly, new Long2ObjectOpenHashMap<>(0), new ConcurrentHashMap<>(), propertyMap, BRIDGE_INSTANCE.getCurrentVersion()); } @Override diff --git a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -index b2a0913290694d27151779aac5fb6be57f01da8b..f72953db6c79b62929244c56f1e76ce4ad72c0ee 100644 +index ec45c627df14a87087e39556cb90eb2d5b52a981..4fe388f4e7edc7a9207147f6cb610d0cc53d9e1e 100644 --- a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java +++ b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -@@ -12,6 +12,8 @@ import com.infernalsuite.asp.skeleton.SlimeChunkSkeleton; - import com.infernalsuite.asp.api.world.SlimeChunk; +@@ -12,10 +12,11 @@ import com.infernalsuite.asp.api.world.SlimeChunk; import com.infernalsuite.asp.api.world.SlimeChunkSection; import com.infernalsuite.asp.api.world.SlimeWorld; + import net.kyori.adventure.nbt.CompoundBinaryTag; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minecraft.SharedConstants; import java.util.ArrayList; -@@ -34,7 +36,7 @@ class SimpleDataFixerConverter implements SlimeWorldReader { +-import java.util.HashMap; + import java.util.List; + import java.util.function.Consumer; + +@@ -33,7 +34,7 @@ class SimpleDataFixerConverter implements SlimeWorldReader { long encodedNewVersion = DataConverter.encodeVersions(newVersion, Integer.MAX_VALUE); long encodedCurrentVersion = DataConverter.encodeVersions(currentVersion, Integer.MAX_VALUE); - Map chunks = new HashMap<>(); + Long2ObjectMap chunks = new Long2ObjectOpenHashMap<>(); for (SlimeChunk chunk : data.getChunkStorage()) { - List entities = new ArrayList<>(); - List blockEntities = new ArrayList<>(); -@@ -49,7 +51,7 @@ class SimpleDataFixerConverter implements SlimeWorldReader { + List entities = new ArrayList<>(); + List blockEntities = new ArrayList<>(); +@@ -48,7 +49,7 @@ class SimpleDataFixerConverter implements SlimeWorldReader { ); } @@ -57,29 +61,38 @@ index b2a0913290694d27151779aac5fb6be57f01da8b..f72953db6c79b62929244c56f1e76ce4 SlimeChunkSection[] sections = new SlimeChunkSection[chunk.getSections().length]; for (int i = 0; i < sections.length; i++) { diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -index e9b6114e1a799217b44001d66592bbae52b03e13..a150c5ebb1fa48542550d905a675a86444f8f22d 100644 +index 9655bd071f435d8b33a78350abb804cafc77306f..e6da199bf2179d8820c6e38725cea5f867031f15 100644 --- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -2,8 +2,8 @@ package com.infernalsuite.asp.level; +@@ -1,7 +1,7 @@ + package com.infernalsuite.asp.level; - import com.flowpowered.nbt.CompoundTag; - import com.flowpowered.nbt.Tag; -import com.infernalsuite.asp.ChunkPos; import com.infernalsuite.asp.Converter; +import com.infernalsuite.asp.Util; import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; import com.infernalsuite.asp.api.loaders.SlimeLoader; - import com.infernalsuite.asp.pdc.FlowPersistentDataContainer; -@@ -15,6 +15,8 @@ import com.infernalsuite.asp.api.world.SlimeChunk; - import com.infernalsuite.asp.api.world.SlimeWorld; - import com.infernalsuite.asp.api.world.SlimeWorldInstance; + import com.infernalsuite.asp.pdc.AdventurePersistentDataContainer; +@@ -15,6 +15,8 @@ import com.infernalsuite.asp.api.world.SlimeWorldInstance; import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; + import net.kyori.adventure.nbt.BinaryTag; + import net.kyori.adventure.nbt.CompoundBinaryTag; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.UpgradeData; -@@ -46,7 +48,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -27,9 +29,7 @@ import org.jetbrains.annotations.NotNull; + import java.io.IOException; + import java.util.ArrayList; + import java.util.Collection; +-import java.util.HashMap; + import java.util.List; +-import java.util.Map; + import java.util.concurrent.ConcurrentMap; + + /* +@@ -47,7 +47,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { private final SlimePropertyMap propertyMap; private final SlimeLoader loader; @@ -88,16 +101,16 @@ index e9b6114e1a799217b44001d66592bbae52b03e13..a150c5ebb1fa48542550d905a675a864 private boolean readOnly; // private final Map> entityStorage = new HashMap<>(); -@@ -58,7 +60,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -59,7 +59,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { this.readOnly = bootstrap.initial().isReadOnly(); for (SlimeChunk initial : bootstrap.initial().getChunkStorage()) { - ChunkPos pos = new ChunkPos(initial.getX(), initial.getZ()); + long pos = Util.chunkPosition(initial.getX(), initial.getZ()); - List tags = new ArrayList<>(initial.getEntities()); + List tags = new ArrayList<>(initial.getEntities()); // this.entityStorage.put(pos, tags); -@@ -95,7 +97,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -96,7 +96,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { levelChunk = SlimeChunkConverter.deserializeSlimeChunk(this.instance, chunk); chunk = new SafeNmsChunkWrapper(new NMSSlimeChunk(levelChunk, chunk), chunk); } @@ -106,7 +119,7 @@ index e9b6114e1a799217b44001d66592bbae52b03e13..a150c5ebb1fa48542550d905a675a864 return levelChunk; } -@@ -109,18 +111,18 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -110,18 +110,18 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { SlimeChunk chunk = new NMSSlimeChunk(providedChunk, getChunk(x, z)); if (FastChunkPruner.canBePruned(this.liveWorld, providedChunk)) { @@ -128,7 +141,7 @@ index e9b6114e1a799217b44001d66592bbae52b03e13..a150c5ebb1fa48542550d905a675a864 } @Override -@@ -202,8 +204,8 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -203,8 +203,8 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { public SlimeWorld getForSerialization() { SlimeWorld world = SkeletonCloning.weakCopy(this); @@ -139,7 +152,7 @@ index e9b6114e1a799217b44001d66592bbae52b03e13..a150c5ebb1fa48542550d905a675a864 SlimeChunk clonedChunk = entry.getValue(); // NMS "live" chunks need to be converted { -@@ -242,7 +244,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -242,7 +242,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { } } @@ -148,7 +161,7 @@ index e9b6114e1a799217b44001d66592bbae52b03e13..a150c5ebb1fa48542550d905a675a864 } // Serialize Bukkit Values (PDC) -@@ -276,8 +278,8 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -275,8 +275,8 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { } public void ensureChunkMarkedAsLoaded(SlimeChunkLevel chunk) { diff --git a/patches/server/0015-1.21-compatibility.patch b/patches/server/0015-1.21-compatibility.patch index 0b13e743b..59deac806 100644 --- a/patches/server/0015-1.21-compatibility.patch +++ b/patches/server/0015-1.21-compatibility.patch @@ -5,10 +5,10 @@ Subject: [PATCH] 1.21 compatibility diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -index 5d7afcb8e90bde6fd5aa3c1a10917f4fdb78ee3a..8c80b611c00ac09d9d45db5a712435c6534f937a 100644 +index 328e70af280ccb32f4830e464f34499b8be0d72b..c0f990e34544811e23497e286842e403b32f947e 100644 --- a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java +++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -@@ -212,7 +212,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { +@@ -206,7 +206,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { default -> throw new IllegalArgumentException("Unknown dimension supplied"); }; @@ -53,30 +53,29 @@ index 10bfcb7250c01c8361375c4d9b34d2b0ae17257d..7f86b1922f179a3ff9b4238ab2da5aea import net.minecraft.world.level.chunk.LevelChunkSection; diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -index 7b31aba65e30fdef7a3eeb96cd899e6be6839aa9..844d23310b2b38cc9f6e2ae1636ba8a485c07999 100644 +index 7326a5af48338d58ac657a5ab62e9fbeb96e4346..97e96f51a6369a328a46086ebb250c9c163e10cf 100644 --- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -@@ -1,17 +1,16 @@ +@@ -1,15 +1,15 @@ package com.infernalsuite.asp.level; +import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; - import com.flowpowered.nbt.CompoundMap; - import com.flowpowered.nbt.CompoundTag; - import com.flowpowered.nbt.LongArrayTag; import com.google.common.collect.Lists; import com.infernalsuite.asp.Converter; -import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; import com.infernalsuite.asp.api.utils.NibbleArray; import com.infernalsuite.asp.api.world.SlimeChunk; import com.infernalsuite.asp.api.world.SlimeChunkSection; --import com.mojang.logging.LogUtils; -+import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; - import com.mojang.serialization.Codec; +-import com.mojang.serialization.Codec; -import io.papermc.paper.world.ChunkEntitySlices; + import net.kyori.adventure.nbt.CompoundBinaryTag; + import net.kyori.adventure.nbt.LongArrayBinaryTag; ++import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; ++import com.mojang.serialization.Codec; import net.minecraft.core.Holder; import net.minecraft.core.Registry; import net.minecraft.core.SectionPos; -@@ -26,7 +25,10 @@ import net.minecraft.world.level.block.Block; +@@ -25,7 +25,10 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; @@ -89,7 +88,7 @@ index 7b31aba65e30fdef7a3eeb96cd899e6be6839aa9..844d23310b2b38cc9f6e2ae1636ba8a4 import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.lighting.LevelLightEngine; diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -index 6807767a2067b62558f749da0c25f184082d0769..d04ad95b65f764560aa1ca8c7137f951ed474003 100644 +index 9bfb64e022db3bd9ed4d818d69df1f9a955cfa5d..73f9473b52df2ae9cea5f6361d2f8d00136c84da 100644 --- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java @@ -1,6 +1,7 @@ @@ -98,10 +97,10 @@ index 6807767a2067b62558f749da0c25f184082d0769..d04ad95b65f764560aa1ca8c7137f951 -import ca.spottedleaf.starlight.common.light.SWMRNibbleArray; +import ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray; +import ca.spottedleaf.moonrise.patches.starlight.light.StarLightEngine; - import com.flowpowered.nbt.CompoundMap; - import com.flowpowered.nbt.CompoundTag; - import com.flowpowered.nbt.LongArrayTag; -@@ -15,8 +16,6 @@ import net.minecraft.core.Holder; + import com.infernalsuite.asp.Converter; + import com.infernalsuite.asp.api.utils.NibbleArray; + import com.infernalsuite.asp.api.world.SlimeChunk; +@@ -13,8 +14,6 @@ import net.minecraft.core.Holder; import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.NbtOps; @@ -110,7 +109,7 @@ index 6807767a2067b62558f749da0c25f184082d0769..d04ad95b65f764560aa1ca8c7137f951 import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biomes; -@@ -28,6 +27,7 @@ import net.minecraft.world.level.chunk.LevelChunk; +@@ -26,6 +25,7 @@ import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; import net.minecraft.world.level.chunk.PalettedContainer; import net.minecraft.world.level.chunk.UpgradeData; @@ -118,7 +117,7 @@ index 6807767a2067b62558f749da0c25f184082d0769..d04ad95b65f764560aa1ca8c7137f951 import net.minecraft.world.level.chunk.storage.ChunkSerializer; import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.material.Fluid; -@@ -48,8 +48,8 @@ public class SlimeChunkConverter { +@@ -46,8 +46,8 @@ public class SlimeChunkConverter { // Chunk sections LevelChunkSection[] sections = new LevelChunkSection[instance.getSectionsCount()]; @@ -129,22 +128,24 @@ index 6807767a2067b62558f749da0c25f184082d0769..d04ad95b65f764560aa1ca8c7137f951 instance.getServer().scheduleOnMain(() -> { instance.getLightEngine().retainData(pos, true); }); -@@ -111,7 +111,7 @@ public class SlimeChunkConverter { - List entities = chunk.getEntities(); +@@ -109,8 +109,8 @@ public class SlimeChunkConverter { + List entities = chunk.getEntities(); if (entities != null) { - net.minecraft.server.level.ChunkMap.postLoadProtoChunk(instance, entities.stream() +- .map(tag -> (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)).toList(), nmsChunk.getPos()); + ChunkStatusTasks.postLoadProtoChunk(instance, entities.stream() - .map(flowTag -> (net.minecraft.nbt.CompoundTag) Converter.convertTag(flowTag)).toList(), nmsChunk.getPos()); ++ .map(flowTag -> (net.minecraft.nbt.CompoundTag) Converter.convertTag(flowTag)).toList(), nmsChunk.getPos()); } }; -@@ -147,13 +147,13 @@ public class SlimeChunkConverter { + +@@ -144,13 +144,13 @@ public class SlimeChunkConverter { } // Height Maps - EnumSet heightMapTypes = nmsChunk.getStatus().heightmapsAfter(); + EnumSet heightMapTypes = nmsChunk.getPersistedStatus().heightmapsAfter(); - CompoundMap heightMaps = chunk.getHeightMaps().getValue(); + CompoundBinaryTag heightMaps = chunk.getHeightMaps(); EnumSet unsetHeightMaps = EnumSet.noneOf(Heightmap.Types.class); // Light diff --git a/patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch b/patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch index 7c6b44701..50b5893e2 100644 --- a/patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch +++ b/patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch @@ -5,17 +5,14 @@ Subject: [PATCH] fix chunk pdc getting wiped on chunk unload diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -index 844d23310b2b38cc9f6e2ae1636ba8a485c07999..c2dd10e46bd4c73b0db641b0a057e6e599033521 100644 +index 97e96f51a6369a328a46086ebb250c9c163e10cf..8053d224ca673c3abe60151b3b322e3e4c9c3fcf 100644 --- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -@@ -68,7 +68,9 @@ public class NMSSlimeChunk implements SlimeChunk { - +@@ -68,6 +68,7 @@ public class NMSSlimeChunk implements SlimeChunk { public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference) { this.chunk = chunk; -- this.extra = reference == null ? new CompoundTag("", new CompoundMap()) : reference.getExtraData(); -+ this.extra = new CompoundTag("", new CompoundMap()); -+ extra.getValue().put(Converter.convertTag("ChunkBukkitValues", chunk.persistentDataContainer.toTagCompound())); -+ + this.extra = reference == null ? CompoundBinaryTag.empty() : reference.getExtraData(); ++ this.extra.put("ChunkBukkitValues", Converter.convertTag(chunk.persistentDataContainer.toTagCompound())); this.upgradeData = reference == null ? null : reference.getUpgradeData(); } diff --git a/patches/server/0019-1.21.3-fixes.patch b/patches/server/0019-1.21.3-fixes.patch index 87b76633c..5e98844c9 100644 --- a/patches/server/0019-1.21.3-fixes.patch +++ b/patches/server/0019-1.21.3-fixes.patch @@ -5,10 +5,10 @@ Subject: [PATCH] 1.21.3 fixes diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -index 8c80b611c00ac09d9d45db5a712435c6534f937a..28d49e4e23b300b3b53de9cc4c276d5c40f43a0c 100644 +index c0f990e34544811e23497e286842e403b32f947e..8956b3c4456fdda86c5ce7f3bbf732f476f54f39 100644 --- a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java +++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -@@ -213,7 +213,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { +@@ -207,7 +207,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { }; ResourceKey worldKey = dimensionOverride == null ? ResourceKey.create(Registries.DIMENSION, ResourceLocation.parse(worldName.toLowerCase(Locale.ENGLISH))) : dimensionOverride; @@ -17,16 +17,16 @@ index 8c80b611c00ac09d9d45db5a712435c6534f937a..28d49e4e23b300b3b53de9cc4c276d5c SlimeLevelInstance level; -@@ -224,7 +224,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { +@@ -218,7 +218,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { } // level.setReady(true); - level.setSpawnSettings(world.getPropertyMap().getValue(SlimeProperties.ALLOW_MONSTERS), world.getPropertyMap().getValue(SlimeProperties.ALLOW_ANIMALS)); + level.setSpawnSettings(world.getPropertyMap().getValue(SlimeProperties.ALLOW_MONSTERS)); - var nmsExtraData = (CompoundTag) Converter.convertTag(world.getExtraData()); + CompoundTag nmsExtraData = (CompoundTag) Converter.convertTag(CompoundBinaryTag.from(world.getExtraData())); -@@ -244,7 +244,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { +@@ -238,7 +238,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { String worldName = world.getName(); LevelSettings worldsettings = new LevelSettings(worldName, serverProps.gamemode, false, serverProps.difficulty, @@ -85,14 +85,13 @@ index 2f0e34e105a27b12eb28dfc2b3c3b6590d76cbb2..2b700ec76e0eca7441676d48cf842cb9 } diff --git a/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java b/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java -index 9954db3eabd60ac0600af1efc6f8a1650ef4d85b..b8d82510cf66700abf0c1820c561b5cc78c7d318 100644 +index 9954db3eabd60ac0600af1efc6f8a1650ef4d85b..09e8a5fc5a56aefdee281b730c471e5f0907be66 100644 --- a/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java +++ b/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java -@@ -1,18 +1,19 @@ +@@ -1,18 +1,18 @@ package com.infernalsuite.asp.level; -import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.util.Priority; public interface CommonLoadTask { @@ -115,26 +114,27 @@ index 9954db3eabd60ac0600af1efc6f8a1650ef4d85b..b8d82510cf66700abf0c1820c561b5cc } \ No newline at end of file diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -index c2dd10e46bd4c73b0db641b0a057e6e599033521..43790021bdc50a37d4bda7a89586eb56eb032791 100644 +index 8053d224ca673c3abe60151b3b322e3e4c9c3fcf..fcdc22a4c107d2a9f4756a473e2b570a4d29b495 100644 --- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -@@ -29,7 +29,7 @@ import net.minecraft.world.level.chunk.LevelChunk; +@@ -29,8 +29,7 @@ import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; import net.minecraft.world.level.chunk.PalettedContainer; import net.minecraft.world.level.chunk.PalettedContainerRO; -import net.minecraft.world.level.chunk.storage.ChunkSerializer; +-import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.chunk.storage.SerializableChunkData; - import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.lighting.LevelLightEngine; import org.slf4j.Logger; -@@ -49,14 +49,14 @@ public class NMSSlimeChunk implements SlimeChunk { + import org.slf4j.LoggerFactory; +@@ -48,14 +47,14 @@ public class NMSSlimeChunk implements SlimeChunk { static { { PalettedContainer empty = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, null); - Tag tag = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); + Tag tag = SerializableChunkData.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); - EMPTY_BLOCK_STATE_PALETTE = (CompoundTag) Converter.convertTag("", tag); + EMPTY_BLOCK_STATE_PALETTE = Converter.convertTag(tag); } { - Registry biomes = net.minecraft.server.MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME); @@ -144,9 +144,9 @@ index c2dd10e46bd4c73b0db641b0a057e6e599033521..43790021bdc50a37d4bda7a89586eb56 + PalettedContainer> empty = new PalettedContainer<>(biomes.asHolderIdMap(), biomes.get(Biomes.PLAINS).orElseThrow(), PalettedContainer.Strategy.SECTION_BIOMES, null); + Tag tag = SerializableChunkData.makeBiomeCodec(biomes).encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); - EMPTY_BIOME_PALETTE = (CompoundTag) Converter.convertTag("", tag); + EMPTY_BIOME_PALETTE = Converter.convertTag(tag); } -@@ -89,10 +89,10 @@ public class NMSSlimeChunk implements SlimeChunk { +@@ -87,10 +86,10 @@ public class NMSSlimeChunk implements SlimeChunk { SlimeChunkSection[] sections = new SlimeChunkSection[this.chunk.getSectionsCount()]; LevelLightEngine lightEngine = chunk.getLevel().getChunkSource().getLightEngine(); @@ -159,20 +159,20 @@ index c2dd10e46bd4c73b0db641b0a057e6e599033521..43790021bdc50a37d4bda7a89586eb56 for (int sectionId = 0; sectionId < chunk.getSections().length; sectionId++) { LevelChunkSection section = chunk.getSections()[sectionId]; -@@ -111,7 +111,7 @@ public class NMSSlimeChunk implements SlimeChunk { +@@ -109,7 +108,7 @@ public class NMSSlimeChunk implements SlimeChunk { if (section.hasOnlyAir()) { blockStateTag = EMPTY_BLOCK_STATE_PALETTE; } else { - Tag data = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, section.getStates()).getOrThrow(); // todo error handling + Tag data = SerializableChunkData.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, section.getStates()).getOrThrow(); // todo error handling - blockStateTag = (CompoundTag) Converter.convertTag("", data); + blockStateTag = Converter.convertTag(data); } diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -index d04ad95b65f764560aa1ca8c7137f951ed474003..30d16c759e269ce0bffa5d5a4f7d90bc09e03eaa 100644 +index 73f9473b52df2ae9cea5f6361d2f8d00136c84da..baaf410852e8aac91c60fcb58acc63e01cc7e7d0 100644 --- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -@@ -28,7 +28,7 @@ import net.minecraft.world.level.chunk.LevelChunkSection; +@@ -26,14 +26,13 @@ import net.minecraft.world.level.chunk.LevelChunkSection; import net.minecraft.world.level.chunk.PalettedContainer; import net.minecraft.world.level.chunk.UpgradeData; import net.minecraft.world.level.chunk.status.ChunkStatusTasks; @@ -181,7 +181,14 @@ index d04ad95b65f764560aa1ca8c7137f951ed474003..30d16c759e269ce0bffa5d5a4f7d90bc import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.ticks.LevelChunkTicks; -@@ -54,10 +54,10 @@ public class SlimeChunkConverter { + + import java.util.EnumSet; + import java.util.List; +-import java.util.Optional; + + public class SlimeChunkConverter { + +@@ -52,10 +51,10 @@ public class SlimeChunkConverter { instance.getLightEngine().retainData(pos, true); }); @@ -194,7 +201,7 @@ index d04ad95b65f764560aa1ca8c7137f951ed474003..30d16c759e269ce0bffa5d5a4f7d90bc for (int sectionId = 0; sectionId < chunk.getSections().length; sectionId++) { SlimeChunkSection slimeSection = chunk.getSections()[sectionId]; -@@ -75,7 +75,7 @@ public class SlimeChunkConverter { +@@ -73,7 +72,7 @@ public class SlimeChunkConverter { PalettedContainer blockPalette; if (slimeSection.getBlockStatesTag() != null) { @@ -203,7 +210,7 @@ index d04ad95b65f764560aa1ca8c7137f951ed474003..30d16c759e269ce0bffa5d5a4f7d90bc System.out.println("Recoverable error when parsing section " + x + "," + z + ": " + s); // todo proper logging }); blockPalette = dataresult.getOrThrow(); // todo proper logging -@@ -91,7 +91,7 @@ public class SlimeChunkConverter { +@@ -89,7 +88,7 @@ public class SlimeChunkConverter { }); biomePalette = dataresult.getOrThrow(); // todo proper logging } else { @@ -213,19 +220,18 @@ index d04ad95b65f764560aa1ca8c7137f951ed474003..30d16c759e269ce0bffa5d5a4f7d90bc if (sectionId < sections.length) { diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -index dbc4620fea0b1b5aa130aaaa2af06fcaad93ed29..d672504eee439d96a9054b3308ba3a5d18cca867 100644 +index dbc4620fea0b1b5aa130aaaa2af06fcaad93ed29..9d15ab96bc72e5efffe443088ef482d4ec0e9457 100644 --- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -@@ -1,6 +1,7 @@ +@@ -1,6 +1,6 @@ package com.infernalsuite.asp.level; -import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.util.Priority; import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkLoadTask; import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.GenericDataLoadTask; -@@ -80,8 +81,8 @@ public class SlimeLevelInstance extends ServerLevel { +@@ -80,8 +80,8 @@ public class SlimeLevelInstance extends ServerLevel { super(slimeBootstrap, MinecraftServer.getServer(), MinecraftServer.getServer().executor, CUSTOM_LEVEL_STORAGE.createAccess(slimeBootstrap.initial().getName() + UUID.randomUUID(), dimensionKey), primaryLevelData, worldKey, worldDimension, @@ -236,7 +242,7 @@ index dbc4620fea0b1b5aa130aaaa2af06fcaad93ed29..d672504eee439d96a9054b3308ba3a5d this.slimeInstance = new SlimeInMemoryWorld(slimeBootstrap, this); -@@ -93,7 +94,7 @@ public class SlimeLevelInstance extends ServerLevel { +@@ -93,7 +93,7 @@ public class SlimeLevelInstance extends ServerLevel { propertyMap.getValue(SlimeProperties.SPAWN_Y), propertyMap.getValue(SlimeProperties.SPAWN_Z)), propertyMap.getValue(SlimeProperties.SPAWN_YAW)); @@ -245,7 +251,7 @@ index dbc4620fea0b1b5aa130aaaa2af06fcaad93ed29..d672504eee439d96a9054b3308ba3a5d this.pvpMode = propertyMap.getValue(SlimeProperties.PVP); } -@@ -102,7 +103,7 @@ public class SlimeLevelInstance extends ServerLevel { +@@ -102,7 +102,7 @@ public class SlimeLevelInstance extends ServerLevel { public ChunkGenerator getGenerator(SlimeBootstrap slimeBootstrap) { String biomeStr = slimeBootstrap.initial().getPropertyMap().getValue(SlimeProperties.DEFAULT_BIOME); ResourceKey biomeKey = ResourceKey.create(Registries.BIOME, ResourceLocation.parse(biomeStr)); @@ -254,7 +260,7 @@ index dbc4620fea0b1b5aa130aaaa2af06fcaad93ed29..d672504eee439d96a9054b3308ba3a5d return new SlimeLevelGenerator(defaultBiome); } -@@ -172,7 +173,7 @@ public class SlimeLevelInstance extends ServerLevel { +@@ -172,7 +172,7 @@ public class SlimeLevelInstance extends ServerLevel { return this.slimeInstance; } diff --git a/patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch b/patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch index ea821e8d6..ba61ccb82 100644 --- a/patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch +++ b/patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch @@ -23,12 +23,12 @@ index 62b526f7e147586977615ec8cec191d0aaf0bcdc..ad7c19ceb42da90bd995421be7fb764a if (chunk != null) { if (chunk instanceof LevelChunk levelChunk) { diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -index 43790021bdc50a37d4bda7a89586eb56eb032791..4f99fbafda6cd4500005a793bba73eee5a2061b9 100644 +index fcdc22a4c107d2a9f4756a473e2b570a4d29b495..17f99470787fa3d6709c892911d33a0a8ea1aadd 100644 --- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -@@ -66,12 +66,19 @@ public class NMSSlimeChunk implements SlimeChunk { - private final CompoundTag extra; - private final CompoundTag upgradeData; +@@ -64,11 +64,18 @@ public class NMSSlimeChunk implements SlimeChunk { + private final CompoundBinaryTag extra; + private final CompoundBinaryTag upgradeData; + private final ChunkEntitySlices entitySlices; + @@ -38,35 +38,30 @@ index 43790021bdc50a37d4bda7a89586eb56eb032791..4f99fbafda6cd4500005a793bba73eee + + public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference, ChunkEntitySlices slices) { this.chunk = chunk; - this.extra = new CompoundTag("", new CompoundMap()); - extra.getValue().put(Converter.convertTag("ChunkBukkitValues", chunk.persistentDataContainer.toTagCompound())); - + this.extra = reference == null ? CompoundBinaryTag.empty() : reference.getExtraData(); + this.extra.put("ChunkBukkitValues", Converter.convertTag(chunk.persistentDataContainer.toTagCompound())); this.upgradeData = reference == null ? null : reference.getUpgradeData(); + this.entitySlices = slices; } @Override -@@ -168,11 +175,7 @@ public class NMSSlimeChunk implements SlimeChunk { - public List getEntities() { - List entities = new ArrayList<>(); +@@ -157,9 +164,7 @@ public class NMSSlimeChunk implements SlimeChunk { + public List getEntities() { + List entities = new ArrayList<>(); -- if(this.chunk == null || this.chunk.getChunkHolder() == null) { -- return new ArrayList<>(); -- } +- if (this.chunk == null || this.chunk.getChunkHolder() == null) return new ArrayList<>(); - - ChunkEntitySlices slices = this.chunk.getChunkHolder().getEntityChunk(); + ChunkEntitySlices slices = getEntitySlices(); - if (slices == null) { - return new ArrayList<>(); - } -@@ -194,6 +197,18 @@ public class NMSSlimeChunk implements SlimeChunk { - }); + if (slices == null) return new ArrayList<>(); + + // Work by +@@ -175,6 +180,16 @@ public class NMSSlimeChunk implements SlimeChunk { + return Lists.transform(entities, Converter::convertTag); } + private ChunkEntitySlices getEntitySlices() { -+ if (this.entitySlices != null) { -+ return entitySlices; -+ } ++ if (this.entitySlices != null) return this.entitySlices; + + if (this.chunk == null || this.chunk.getChunkHolder() == null) { + return null; @@ -76,7 +71,7 @@ index 43790021bdc50a37d4bda7a89586eb56eb032791..4f99fbafda6cd4500005a793bba73eee + } + @Override - public CompoundTag getExtraData() { + public CompoundBinaryTag getExtraData() { return extra; diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java index a92d17b5c6a7c8427ecbdf56a9c2a0c1b66978e4..6313b235eb8ccbd63b57159964ba33d36db51933 100644 @@ -96,10 +91,10 @@ index a92d17b5c6a7c8427ecbdf56a9c2a0c1b66978e4..6313b235eb8ccbd63b57159964ba33d3 public void loadCallback() { super.loadCallback(); diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -index a150c5ebb1fa48542550d905a675a86444f8f22d..5daabf7d2c31972082fc618142643592535fb13f 100644 +index e6da199bf2179d8820c6e38725cea5f867031f15..77526b601745287cc309f4cda0a8093d871e888e 100644 --- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -104,11 +104,11 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -103,11 +103,11 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { // Authored by: Kenox // Don't use the NMS live chunk in the chunk map @@ -114,10 +109,10 @@ index a150c5ebb1fa48542550d905a675a86444f8f22d..5daabf7d2c31972082fc618142643592 if (FastChunkPruner.canBePruned(this.liveWorld, providedChunk)) { this.chunkStorage.remove(Util.chunkPosition(x, z)); diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -index d672504eee439d96a9054b3308ba3a5d18cca867..1b0d36854c190efefc7421f445a70b92f82a4fe5 100644 +index 9d15ab96bc72e5efffe443088ef482d4ec0e9457..1c5798fd15a61b6721df97214494788e9873c68c 100644 --- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -@@ -202,9 +202,7 @@ public class SlimeLevelInstance extends ServerLevel { +@@ -201,9 +201,7 @@ public class SlimeLevelInstance extends ServerLevel { propertyMap.setValue(SlimeProperties.SPAWN_YAW, angle); } diff --git a/patches/server/0021-fix-pdc-not-saving-when-chunks-are-unloaded.patch b/patches/server/0021-fix-pdc-not-saving-when-chunks-are-unloaded.patch index 324797989..bd726a4ab 100644 --- a/patches/server/0021-fix-pdc-not-saving-when-chunks-are-unloaded.patch +++ b/patches/server/0021-fix-pdc-not-saving-when-chunks-are-unloaded.patch @@ -5,10 +5,10 @@ Subject: [PATCH] fix pdc not saving when chunks are unloaded diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -index 5daabf7d2c31972082fc618142643592535fb13f..cdf0534ff6516eb631a200a5159461b99236c808 100644 +index 77526b601745287cc309f4cda0a8093d871e888e..166f8c17df110d4ed13dd31a9de06c3d7b5c070b 100644 --- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -114,6 +114,8 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +@@ -113,6 +113,8 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { this.chunkStorage.remove(Util.chunkPosition(x, z)); return; } diff --git a/patches/server/0022-Remove-leftover-FlowNBT-usage.patch b/patches/server/0022-Remove-leftover-FlowNBT-usage.patch new file mode 100644 index 000000000..3ec576c2b --- /dev/null +++ b/patches/server/0022-Remove-leftover-FlowNBT-usage.patch @@ -0,0 +1,21 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Philip Kelley +Date: Fri, 20 Dec 2024 11:31:09 +0000 +Subject: [PATCH] Remove leftover FlowNBT usage + + +diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +index 166f8c17df110d4ed13dd31a9de06c3d7b5c070b..a5f35f94d82928f120f02909086f57d4ceaa52c2 100644 +--- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java ++++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +@@ -113,8 +113,8 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { + this.chunkStorage.remove(Util.chunkPosition(x, z)); + return; + } +- Tag pdcTag = Converter.convertTag("ChunkBukkitValues", providedChunk.persistentDataContainer.toTagCompound()); +- chunk.getExtraData().getValue().put(pdcTag); ++ CompoundBinaryTag pdcTag = Converter.convertTag(providedChunk.persistentDataContainer.toTagCompound()); ++ chunk.getExtraData().put("ChunkBukkitValues", pdcTag); + + this.chunkStorage.put(Util.chunkPosition(x, z), + new SlimeChunkSkeleton(chunk.getX(), chunk.getZ(), chunk.getSections(), From 8290f918576bd6d158cb384969e5e61ad6dd2a5d Mon Sep 17 00:00:00 2001 From: Philip Kelley Date: Fri, 20 Dec 2024 20:36:18 +0000 Subject: [PATCH 028/133] chore(*): Update to 1.21.4 --- gradle.properties | 6 +-- patches/api/0001-Slime-World-Manager.patch | 6 +-- patches/server/0001-Build-Changes.patch | 38 +++++++++---------- patches/server/0012-Compile-fixes.patch | 4 +- ...e-plugin-and-server-rework-API-to-v3.patch | 6 +-- patches/server/0015-1.21-compatibility.patch | 6 +-- .../0017-fix-disable-dragon-fights.patch | 4 +- 7 files changed, 35 insertions(+), 35 deletions(-) diff --git a/gradle.properties b/gradle.properties index e51685592..8c992e6ee 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,9 +1,9 @@ group=com.infernalsuite.asp apiVersion=4.0.0-SNAPSHOT -version=1.21.3-R0.1-SNAPSHOT +version=1.21.4-R0.1-SNAPSHOT -mcVersion=1.21.3 -paperRef=da7138233f6392e791d790d1c3407414c855f9c2 +mcVersion=1.21.4 +paperRef=bb76819589fcd1a7ccac245998ca32f63d99772a org.gradle.caching=true org.gradle.parallel=true diff --git a/patches/api/0001-Slime-World-Manager.patch b/patches/api/0001-Slime-World-Manager.patch index ca201dbe1..e1cf9d839 100644 --- a/patches/api/0001-Slime-World-Manager.patch +++ b/patches/api/0001-Slime-World-Manager.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Slime World Manager diff --git a/build.gradle.kts b/build.gradle.kts -index e29e5024fa693baae469d47fe77b57118f14627c..a1ab3bc4f7853c83e79de52d2549586655ca569e 100644 +index 571534b42cd9c33d6a7bb6fe3bf3a28e33f8e5de..8e785e4d244abcfcfc3e37fc457baf62050670aa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -41,6 +41,7 @@ abstract class MockitoAgentProvider : CommandLineArgumentProvider { @@ -13,8 +13,8 @@ index e29e5024fa693baae469d47fe77b57118f14627c..a1ab3bc4f7853c83e79de52d25495866 api("com.mojang:brigadier:1.2.9") // Paper - Brigadier command api // api dependencies are listed transitively to API consumers + api(project(":api")) // ASWM - api("com.google.guava:guava:32.1.2-jre") - api("com.google.code.gson:gson:2.10.1") + api("com.google.guava:guava:33.3.1-jre") + api("com.google.code.gson:gson:2.11.0") // Paper start - adventure diff --git a/src/main/java/io/papermc/paper/ServerBuildInfo.java b/src/main/java/io/papermc/paper/ServerBuildInfo.java index 652ff54e7c50412503725d628bfe72ed03059790..9c5118e6193b0e9852ef6b52cb4ae92ded1ba464 100644 diff --git a/patches/server/0001-Build-Changes.patch b/patches/server/0001-Build-Changes.patch index 59c6e6b15..a5cf793b8 100644 --- a/patches/server/0001-Build-Changes.patch +++ b/patches/server/0001-Build-Changes.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Build Changes Update shadow plugin diff --git a/build.gradle.kts b/build.gradle.kts -index faf3e3fd72e8c915e7a4803dacbe1bb576c6663e..b5b5c099e61f828edbcd18aba9d379a6e45fb8b4 100644 +index 2da91ed6363c0851e4c459188f5e8ef5475e0c97..f0bfc068301c4a908a5856b7c72e7306adeeb38d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,6 +4,7 @@ import java.time.Instant @@ -29,10 +29,10 @@ index faf3e3fd72e8c915e7a4803dacbe1bb576c6663e..b5b5c099e61f828edbcd18aba9d379a6 + exclude("io.papermc.paper", "paper-api") + } + // ASWM end + implementation("ca.spottedleaf:concurrentutil:0.0.2") // Paper - Add ConcurrentUtil dependency // Paper start implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ - implementation("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21 -@@ -99,14 +106,14 @@ tasks.jar { +@@ -100,14 +107,14 @@ tasks.jar { val gitBranch = git("rev-parse", "--abbrev-ref", "HEAD").getText().trim() // Paper attributes( "Main-Class" to "org.bukkit.craftbukkit.Main", @@ -52,17 +52,17 @@ index faf3e3fd72e8c915e7a4803dacbe1bb576c6663e..b5b5c099e61f828edbcd18aba9d379a6 "Build-Number" to (build ?: ""), "Build-Time" to Instant.now().toString(), "Git-Branch" to gitBranch, // Paper -@@ -172,7 +179,7 @@ fun TaskContainer.registerRunTask( +@@ -173,7 +180,7 @@ fun TaskContainer.registerRunTask( name: String, block: JavaExec.() -> Unit ): TaskProvider = register(name) { - group = "paper" -+ group = "slimeworldmanager" ++ group = "asp" mainClass.set("org.bukkit.craftbukkit.Main") standardInput = System.`in` workingDir = rootProject.layout.projectDirectory diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java -index b3c993a790fc3fab6a408c731deb297f74c959ce..0bbd557602932b67212b8951ef769bbce70c5477 100644 +index d21ce54ebb5724c04eadf56a2cde701d5eeb5db2..d0a2d1d8dd41980b95303add867ca906dd089af6 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java @@ -42,7 +42,7 @@ public final class ChunkEntitySlices { @@ -70,12 +70,12 @@ index b3c993a790fc3fab6a408c731deb297f74c959ce..0bbd557602932b67212b8951ef769bbc private final Reference2ObjectOpenHashMap, EntityCollectionBySection> entitiesByClass; private final Reference2ObjectOpenHashMap, EntityCollectionBySection> entitiesByType; - private final EntityList entities = new EntityList(); -+ public final EntityList entities = new EntityList(); //ASWM ++ public final EntityList entities = new EntityList(); // ASP - private -> public public FullChunkStatus status; public final ChunkData chunkData; diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java -index 91a6f57f35fc1553159cca138a0619e703b2b014..0474325958293ea36bae0e44849e95a2fde819b8 100644 +index 3990834a41116682d6ae779a3bf24b0fd989d97d..2bc81d274769ed5bb33f94889e0cab0f37fa01a5 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java @@ -185,7 +185,8 @@ public final class ChunkHolderManager { @@ -2062,7 +2062,7 @@ index 790bad0494454ca12ee152e3de6da3da634d9b20..2d6b062c4a3cf682d8e4cdbb7b7c84a7 @Override diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 4158473fd553a16fec23bcbcf9a278d413120600..e49e329b4713fefb153b64aee35f5e2c9eaa51a4 100644 +index ae4ebf509837e8d44255781c61d02873f8b74be8..876be700dea01f8361c37cff8e17f9140ff8ba26 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -288,7 +288,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess(), iworlddataserver.getGameRules())), executor); // Paper - create paper world configs; Async-Anti-Xray: Pass executor this.pvpMode = minecraftserver.isPvpAllowed(); this.convertable = convertable_conversionsession; -@@ -623,6 +628,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -624,6 +629,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe chunkgenerator = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, chunkgenerator, gen); } // CraftBukkit end @@ -2221,7 +2221,7 @@ index 585e2b43a0326f0b81597fa1234d3c67c76af550..7eb21e0c8fc4103a4eb656bd1d81ae10 boolean flag2 = minecraftserver.forceSynchronousWrites(); DataFixer datafixer = minecraftserver.getFixerUpper(); EntityPersistentStorage entitypersistentstorage = new EntityStorage(new SimpleRegionStorage(new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, DataFixTypes.ENTITY_CHUNK), this, minecraftserver); -@@ -633,7 +644,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -634,7 +645,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe int k = this.spigotConfig.simulationDistance; // Spigot // Paper - rewrite chunk system @@ -2230,7 +2230,7 @@ index 585e2b43a0326f0b81597fa1234d3c67c76af550..7eb21e0c8fc4103a4eb656bd1d81ae10 return minecraftserver.overworld().getDataStorage(); }); this.chunkSource.getGeneratorState().ensureStructuresGenerated(); -@@ -692,6 +703,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -693,6 +704,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.dragonFight = enderDragonFight; } diff --git a/patches/server/0012-Compile-fixes.patch b/patches/server/0012-Compile-fixes.patch index 03548c897..7c831a66d 100644 --- a/patches/server/0012-Compile-fixes.patch +++ b/patches/server/0012-Compile-fixes.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Compile fixes diff --git a/build.gradle.kts b/build.gradle.kts -index b5b5c099e61f828edbcd18aba9d379a6e45fb8b4..838639a8bbeb59700037c3e101714f68f8b79671 100644 +index f0bfc068301c4a908a5856b7c72e7306adeeb38d..e6414d33e65233836db36040206c32a16b4d10ca 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -29,9 +29,6 @@ dependencies { @@ -16,8 +16,8 @@ index b5b5c099e61f828edbcd18aba9d379a6e45fb8b4..838639a8bbeb59700037c3e101714f68 - exclude("io.papermc.paper", "paper-api") - } // ASWM end + implementation("ca.spottedleaf:concurrentutil:0.0.2") // Paper - Add ConcurrentUtil dependency // Paper start - implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java index 4c627f8af92f29d9ba50745812acc83726a85683..6972d6399628eda41756a98fb54fbe93eb827716 100644 --- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java diff --git a/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch b/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch index a16752926..69eed2b51 100644 --- a/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch +++ b/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Separate plugin and server, rework API (to v3) diff --git a/build.gradle.kts b/build.gradle.kts -index 838639a8bbeb59700037c3e101714f68f8b79671..26be7ff48f2eb50a140e71372cfef54d4ff570f1 100644 +index e6414d33e65233836db36040206c32a16b4d10ca..2f52145f996e5055030d7960c4ad616ba0ea5321 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -29,6 +29,7 @@ dependencies { @@ -14,8 +14,8 @@ index 838639a8bbeb59700037c3e101714f68f8b79671..26be7ff48f2eb50a140e71372cfef54d implementation(project(":core")) + implementation("commons-io:commons-io:2.11.0") // ASWM end + implementation("ca.spottedleaf:concurrentutil:0.0.2") // Paper - Add ConcurrentUtil dependency // Paper start - implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ diff --git a/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java b/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java new file mode 100644 index 0000000000000000000000000000000000000000..06e91530198d9075434045893f95f7a6ae5bfbb3 @@ -712,7 +712,7 @@ index 26422904751647a061397ce978bba752149003cd..4940083475948eac4fc06446f7ee7e1e } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index ac8af406180bc680d46e8edc3da0fc2e5211345a..2bd2aa53b656012f49f3c4692a092b9f9d4a4d9a 100644 +index 97b5d6ba2b19a7c730730c74175a29157aed1840..4297100fea7f0053ad624e5eee12bbd8e15e55b5 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -8,6 +8,7 @@ import com.google.common.collect.ImmutableList; diff --git a/patches/server/0015-1.21-compatibility.patch b/patches/server/0015-1.21-compatibility.patch index 59deac806..5afa09659 100644 --- a/patches/server/0015-1.21-compatibility.patch +++ b/patches/server/0015-1.21-compatibility.patch @@ -249,7 +249,7 @@ index d6e5eac7732f32cabd6ed5ac6b10af20074a39b8..33af1d7e671c5aeb06482038e205efc8 @Override public void setDefaultSpawnPos(BlockPos pos, float angle) { diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index 4640baec5bed6c2d53cc0f8ca1d273cc115abe9b..589cb65f79bb05ee8c44b526c707e81dc02a4761 100644 +index 97937e3bd211997f0a0a3e9e671a1c59712d0003..7154f6050b01c234e00fab22f5e5f1d6a944500a 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -1,5 +1,7 @@ @@ -260,7 +260,7 @@ index 4640baec5bed6c2d53cc0f8ca1d273cc115abe9b..589cb65f79bb05ee8c44b526c707e81d import com.google.common.collect.ImmutableList; import com.google.common.collect.Maps; import com.google.common.collect.UnmodifiableIterator; -@@ -23,6 +25,7 @@ import net.minecraft.core.registries.Registries; +@@ -24,6 +26,7 @@ import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData; @@ -268,7 +268,7 @@ index 4640baec5bed6c2d53cc0f8ca1d273cc115abe9b..589cb65f79bb05ee8c44b526c707e81d import net.minecraft.server.level.FullChunkStatus; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.profiling.Profiler; -@@ -322,6 +325,12 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p +@@ -327,6 +330,12 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p } } diff --git a/patches/server/0017-fix-disable-dragon-fights.patch b/patches/server/0017-fix-disable-dragon-fights.patch index 09a8543b1..8bf690d8b 100644 --- a/patches/server/0017-fix-disable-dragon-fights.patch +++ b/patches/server/0017-fix-disable-dragon-fights.patch @@ -5,7 +5,7 @@ Subject: [PATCH] fix disable dragon fights diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 7eb21e0c8fc4103a4eb656bd1d81ae10e7ee9dc4..fecee66cf0ab3fe820273a6850c9d2f6c51501b6 100644 +index 18fe62b5f6f90099d321ad381a941d8e3bd1ea66..4e0550e917bc9110a87f92e75d6a2f31408386fc 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -2,6 +2,7 @@ package net.minecraft.server.level; @@ -16,7 +16,7 @@ index 7eb21e0c8fc4103a4eb656bd1d81ae10e7ee9dc4..fecee66cf0ab3fe820273a6850c9d2f6 import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.util.Pair; import com.mojang.logging.LogUtils; -@@ -662,7 +663,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -663,7 +664,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.structureCheck = new StructureCheck(this.chunkSource.chunkScanner(), this.registryAccess(), minecraftserver.getStructureManager(), this.getTypeKey(), chunkgenerator, this.chunkSource.randomState(), this, chunkgenerator.getBiomeSource(), l, datafixer); // Paper - Fix missing CB diff this.structureManager = new StructureManager(this, this.serverLevelData.worldGenOptions(), this.structureCheck); // CraftBukkit if ((this.dimension() == Level.END && this.dimensionTypeRegistration().is(BuiltinDimensionTypes.END)) || env == org.bukkit.World.Environment.THE_END) { // CraftBukkit - Allow to create EnderDragonBattle in default and custom END From fa101d8c017c3d6533dbd213311dee5b2e9d3a16 Mon Sep 17 00:00:00 2001 From: Philip Kelley Date: Fri, 20 Dec 2024 22:38:53 +0000 Subject: [PATCH 029/133] chore(settings): Add toolchain resolver plugin --- settings.gradle.kts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/settings.gradle.kts b/settings.gradle.kts index 78e57a832..c8408c9be 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -8,6 +8,10 @@ pluginManagement { includeBuild("gradle/build-logic") } +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0" +} + rootProject.name = "ASPaper" include(":gradle:platform") From 50c27aaf3371e37d017336d1ddc623276c2ff088 Mon Sep 17 00:00:00 2001 From: Philip Kelley Date: Sat, 21 Dec 2024 05:04:03 +0000 Subject: [PATCH 030/133] chore(conventions): Relocate gradle/build-logic -> buildSrc --- .../build-logic => buildSrc}/build.gradle.kts | 0 .../settings.gradle.kts | 4 +- .../kotlin/asp.base-conventions.gradle.kts | 0 .../asp.publishing-conventions.gradle.kts | 0 .../asp/conventions/PublishConfiguration.kt | 0 .../src/main/kotlin/constants.kt | 0 .../src/main/kotlin/extensions.kt | 0 .../asp.paperweight-conventions.gradle.kts | 42 ------------------- settings.gradle.kts | 1 - 9 files changed, 2 insertions(+), 45 deletions(-) rename {gradle/build-logic => buildSrc}/build.gradle.kts (100%) rename {gradle/build-logic => buildSrc}/settings.gradle.kts (71%) rename {gradle/build-logic => buildSrc}/src/main/kotlin/asp.base-conventions.gradle.kts (100%) rename {gradle/build-logic => buildSrc}/src/main/kotlin/asp.publishing-conventions.gradle.kts (100%) rename {gradle/build-logic => buildSrc}/src/main/kotlin/com/infernalsuite/asp/conventions/PublishConfiguration.kt (100%) rename {gradle/build-logic => buildSrc}/src/main/kotlin/constants.kt (100%) rename {gradle/build-logic => buildSrc}/src/main/kotlin/extensions.kt (100%) delete mode 100644 gradle/build-logic/src/main/kotlin/asp.paperweight-conventions.gradle.kts diff --git a/gradle/build-logic/build.gradle.kts b/buildSrc/build.gradle.kts similarity index 100% rename from gradle/build-logic/build.gradle.kts rename to buildSrc/build.gradle.kts diff --git a/gradle/build-logic/settings.gradle.kts b/buildSrc/settings.gradle.kts similarity index 71% rename from gradle/build-logic/settings.gradle.kts rename to buildSrc/settings.gradle.kts index ab6c4736e..bbf148c90 100644 --- a/gradle/build-logic/settings.gradle.kts +++ b/buildSrc/settings.gradle.kts @@ -1,4 +1,4 @@ -rootProject.name = "build-logic" +rootProject.name = "buildSrc" pluginManagement { repositories { @@ -11,7 +11,7 @@ pluginManagement { dependencyResolutionManagement { versionCatalogs { create("libs") { - from(files("../libs.versions.toml")) + from(files("../gradle/libs.versions.toml")) } } } diff --git a/gradle/build-logic/src/main/kotlin/asp.base-conventions.gradle.kts b/buildSrc/src/main/kotlin/asp.base-conventions.gradle.kts similarity index 100% rename from gradle/build-logic/src/main/kotlin/asp.base-conventions.gradle.kts rename to buildSrc/src/main/kotlin/asp.base-conventions.gradle.kts diff --git a/gradle/build-logic/src/main/kotlin/asp.publishing-conventions.gradle.kts b/buildSrc/src/main/kotlin/asp.publishing-conventions.gradle.kts similarity index 100% rename from gradle/build-logic/src/main/kotlin/asp.publishing-conventions.gradle.kts rename to buildSrc/src/main/kotlin/asp.publishing-conventions.gradle.kts diff --git a/gradle/build-logic/src/main/kotlin/com/infernalsuite/asp/conventions/PublishConfiguration.kt b/buildSrc/src/main/kotlin/com/infernalsuite/asp/conventions/PublishConfiguration.kt similarity index 100% rename from gradle/build-logic/src/main/kotlin/com/infernalsuite/asp/conventions/PublishConfiguration.kt rename to buildSrc/src/main/kotlin/com/infernalsuite/asp/conventions/PublishConfiguration.kt diff --git a/gradle/build-logic/src/main/kotlin/constants.kt b/buildSrc/src/main/kotlin/constants.kt similarity index 100% rename from gradle/build-logic/src/main/kotlin/constants.kt rename to buildSrc/src/main/kotlin/constants.kt diff --git a/gradle/build-logic/src/main/kotlin/extensions.kt b/buildSrc/src/main/kotlin/extensions.kt similarity index 100% rename from gradle/build-logic/src/main/kotlin/extensions.kt rename to buildSrc/src/main/kotlin/extensions.kt diff --git a/gradle/build-logic/src/main/kotlin/asp.paperweight-conventions.gradle.kts b/gradle/build-logic/src/main/kotlin/asp.paperweight-conventions.gradle.kts deleted file mode 100644 index 6aa2ebe35..000000000 --- a/gradle/build-logic/src/main/kotlin/asp.paperweight-conventions.gradle.kts +++ /dev/null @@ -1,42 +0,0 @@ -plugins { - id("io.papermc.paperweight.patcher") -} - -repositories { - mavenCentral() - maven(PAPER_MAVEN_PUBLIC_URL) { - content { onlyForConfigurations(configurations.paperclip.name) } - } -} - -dependencies { - remapper("net.fabricmc:tiny-remapper:0.10.3:fat") - decompiler("org.vineflower:vineflower:1.10.1") - paperclip("io.papermc:paperclip:3.0.3") -} - -paperweight { - serverProject.set(project(":aspaper-server")) - - remapRepo.set(PAPER_MAVEN_PUBLIC_URL) - decompileRepo.set(PAPER_MAVEN_PUBLIC_URL) - - usePaperUpstream(providers.gradleProperty("paperRef")) { - withPaperPatcher { - apiPatchDir.set(layout.projectDirectory.dir("patches/api")) - apiOutputDir.set(layout.projectDirectory.dir("aspaper-api")) - - serverPatchDir.set(layout.projectDirectory.dir("patches/server")) - serverOutputDir.set(layout.projectDirectory.dir("aspaper-server")) - - patchTasks { - register("generatedApi") { - isBareDirectory.set(true) - upstreamDirPath.set("paper-api-generator/generated") - patchDir.set(layout.projectDirectory.dir("patches/generatedApi")) - outputDir.set(layout.projectDirectory.dir("paper-api-generator/generated")) - } - } - } - } -} diff --git a/settings.gradle.kts b/settings.gradle.kts index c8408c9be..21cb2bd10 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,7 +5,6 @@ pluginManagement { gradlePluginPortal() maven("https://repo.papermc.io/repository/maven-public/") } - includeBuild("gradle/build-logic") } plugins { From a9788b37cb187157fd43842a28e77156b7d85628 Mon Sep 17 00:00:00 2001 From: Philip Kelley Date: Sat, 21 Dec 2024 05:04:57 +0000 Subject: [PATCH 031/133] chore(gradlew): Update gradle wrapper to 8.12 --- gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index df97d72b8..cea7a793a 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.10.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index f5feea6d6..f3b75f3b0 100755 --- a/gradlew +++ b/gradlew @@ -86,8 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s -' "$PWD" ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum From f7a4a97fb3e45acf3fbf7ea0cc0d81562d880658 Mon Sep 17 00:00:00 2001 From: Philip Kelley Date: Sat, 21 Dec 2024 05:09:18 +0000 Subject: [PATCH 032/133] chore(*): Setup initial hard fork structure - Update paperweight to v2 for hard fork support - Update paperRef to latest hard fork commit - Add new impl module and configure paperweight - Patch build scripts - Update gitignore --- .gitignore | 31 ++++----- build.gradle.kts | 19 ----- gradle.properties | 2 +- gradle/libs.versions.toml | 2 +- impl/aspaper-api/build.gradle.kts.patch | 53 ++++++++++++++ impl/aspaper-server/build.gradle.kts.patch | 57 +++++++++++++++ impl/build.gradle.kts | 80 ++++++++++++++++++++++ settings.gradle.kts | 15 ++-- 8 files changed, 216 insertions(+), 43 deletions(-) create mode 100644 impl/aspaper-api/build.gradle.kts.patch create mode 100644 impl/aspaper-server/build.gradle.kts.patch create mode 100644 impl/build.gradle.kts diff --git a/.gitignore b/.gitignore index dd9079f27..79bbf2a7a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,17 @@ -*.iml -*.ipr -*.iws .idea/ -.classpath -.project -.settings/ -slimeworldmanager-test/ -.DS_Store/ -release.properties -libs/ -.gradle/ +.vscode/ + +**/.gradle/ +.DS_Store build/ -slimeworldmanager-api -slimeworldmanager-server -run -*.hprof -paper-api-generator \ No newline at end of file +**/run/ + +**/*.iml + +impl/aspaper-server/build.gradle.kts +impl/aspaper-server/src/minecraft/ +impl/paper-server/ +impl/aspaper-api/build.gradle.kts +impl/paper-api/ +impl/paper-api-generator/ +/impl/aspaper-server/.gradle/ diff --git a/build.gradle.kts b/build.gradle.kts index 8dce44724..e69de29bb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,19 +0,0 @@ -plugins { - id("asp.paperweight-conventions") - id("com.gradleup.shadow") version "8.3.5" apply false - java -} - -allprojects { - repositories { - mavenLocal() - mavenCentral() - - maven("https://repo.papermc.io/repository/maven-public/") - maven("https://repo.codemc.io/repository/nms/") - maven("https://repo.rapture.pw/repository/maven-releases/") - maven("https://repo.glaremasters.me/repository/concuncan/") - maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") - maven("https://oss.sonatype.org/content/repositories/snapshots/") - } -} diff --git a/gradle.properties b/gradle.properties index 8c992e6ee..bee34f632 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ apiVersion=4.0.0-SNAPSHOT version=1.21.4-R0.1-SNAPSHOT mcVersion=1.21.4 -paperRef=bb76819589fcd1a7ccac245998ca32f63d99772a +paperRef=c45286cb08881ab4d28a16b8ef9c6a4fd0984ce8 org.gradle.caching=true org.gradle.parallel=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fe8780ecb..5395e70cb 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ lettuce = "6.5.1.RELEASE" lombok = "1.18.36" lombok-plugin = "8.11" mongo = "5.2.1" -paperweight = "1.7.7" +paperweight = "2.0.0-SNAPSHOT" plugin-yml-paper = "0.6.0" shadow = "8.3.5" slf4j = "2.0.16" diff --git a/impl/aspaper-api/build.gradle.kts.patch b/impl/aspaper-api/build.gradle.kts.patch new file mode 100644 index 000000000..e5daed3e2 --- /dev/null +++ b/impl/aspaper-api/build.gradle.kts.patch @@ -0,0 +1,53 @@ +--- a/paper-api/build.gradle.kts ++++ b/paper-api/build.gradle.kts +@@ -95,7 +_,7 @@ + } + + // Paper start +-val generatedApiPath: java.nio.file.Path = rootProject.projectDir.toPath().resolve("paper-api-generator/generated") ++val generatedApiPath: java.nio.file.Path = rootProject.projectDir.toPath().resolve("impl/paper-api-generator/generated") + idea { + module { + generatedSourceDirs.add(generatedApiPath.toFile()) +@@ -105,6 +_,18 @@ + main { + java { + srcDir(generatedApiPath) ++ srcDir(file("../paper-api/src/main/java")) ++ } ++ resources { ++ srcDir(file("../paper-api/src/main/resources")) ++ } ++ } ++ test { ++ java { ++ srcDir(file("../paper-api/src/test/java")) ++ } ++ resources { ++ srcDir(file("../paper-api/src/test/resources")) + } + } + } +@@ -169,7 +_,7 @@ + + tasks.withType { + val options = options as StandardJavadocDocletOptions +- options.overview = "src/main/javadoc/overview.html" ++ options.overview = "../paper-api/src/main/javadoc/overview.html" + options.use() + options.isDocFilesSubDirs = true + options.links( +@@ -207,11 +_,11 @@ + } + + // workaround for https://github.com/gradle/gradle/issues/4046 +- inputs.dir("src/main/javadoc").withPropertyName("javadoc-sourceset") ++ inputs.dir("../paper-api/src/main/javadoc").withPropertyName("javadoc-sourceset") + val fsOps = services.fileSystemOperations + doLast { + fsOps.copy { +- from("src/main/javadoc") { ++ from("../paper-api/src/main/javadoc") { + include("**/doc-files/**") + } + into("build/docs/javadoc") diff --git a/impl/aspaper-server/build.gradle.kts.patch b/impl/aspaper-server/build.gradle.kts.patch new file mode 100644 index 000000000..4e3598104 --- /dev/null +++ b/impl/aspaper-server/build.gradle.kts.patch @@ -0,0 +1,57 @@ +--- a/paper-server/build.gradle.kts ++++ b/paper-server/build.gradle.kts +@@ -17,11 +_,20 @@ + + paperweight { + minecraftVersion = providers.gradleProperty("mcVersion") +- // macheOldPath = file("F:\\Projects\\PaperTooling\\mache\\versions\\1.21.4\\src\\main\\java") +- // gitFilePatches = true ++ ++ val fork = forks.register("aspaper") { ++ upstream.patchDir("paperServer") { ++ upstreamPath = "paper-server" ++ excludes = setOf("src/minecraft", "patches", "build.gradle.kts") ++ patchesDir = rootDirectory.dir("aspaper-server/paper-patches") ++ outputDir = rootDirectory.dir("paper-server") ++ } ++ } ++ ++ activeFork = fork + + paper { +- reobfMappingsPatch = layout.projectDirectory.file("../build-data/reobf-mappings-patch.tiny") ++ paperServerDir = upstreamsDirectory().map { it.dir("paper/paper-server") } + } + + spigot { +@@ -104,7 +_,20 @@ + } + } + +-val log4jPlugins = sourceSets.create("log4jPlugins") ++sourceSets { ++ main { ++ java { srcDir("../paper-server/src/main/java") } ++ resources { srcDir("../paper-server/src/main/resources") } ++ } ++ test { ++ java { srcDir("../paper-server/src/test/java") } ++ resources { srcDir("../paper-server/src/test/resources") } ++ } ++} ++ ++val log4jPlugins = sourceSets.create("log4jPlugins") { ++ java { srcDir("../paper-server/src/log4jPlugins/java") } ++} + configurations.named(log4jPlugins.compileClasspathConfigurationName) { + extendsFrom(configurations.compileClasspath.get()) + } +@@ -123,7 +_,7 @@ + // Paper end - configure mockito agent that is needed in newer java versions + + dependencies { +- implementation(project(":paper-api")) ++ implementation(project(":impl:aspaper-api")) + implementation("ca.spottedleaf:concurrentutil:0.0.2") // Paper - Add ConcurrentUtil dependency + // Paper start + implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ diff --git a/impl/build.gradle.kts b/impl/build.gradle.kts new file mode 100644 index 000000000..498d5dec5 --- /dev/null +++ b/impl/build.gradle.kts @@ -0,0 +1,80 @@ +import org.gradle.api.tasks.testing.logging.TestExceptionFormat +import org.gradle.api.tasks.testing.logging.TestLogEvent + +plugins { + java + id("io.papermc.paperweight.patcher") +} + +paperweight { + upstreams.paper { + ref = providers.gradleProperty("paperRef") + + // Setup file patches for build scripts + patchFile { + path = "paper-api/build.gradle.kts" + outputFile = file("aspaper-api/build.gradle.kts") + patchFile = file("aspaper-api/build.gradle.kts.patch") + } + patchFile { + path = "paper-server/build.gradle.kts" + outputFile = file("aspaper-server/build.gradle.kts") + patchFile = file("aspaper-server/build.gradle.kts.patch") + } + + patchDir("paperApi") { + upstreamPath = "paper-api" + excludes = setOf("build.gradle.kts") + patchesDir = file("aspaper-api/paper-patches") + outputDir = file("paper-api") + } + patchDir("paperApiGenerator") { + upstreamPath = "paper-api-generator" + patchesDir = file("aspaper-api-generator/paper-patches") + outputDir = file("paper-api-generator") + } + } +} + +subprojects { + apply(plugin = "java-library") + apply(plugin = "maven-publish") + + extensions.configure { + toolchain { + languageVersion = JavaLanguageVersion.of(JAVA_VERSION) + } + } + + repositories { + mavenCentral() + maven(PAPER_MAVEN_PUBLIC_URL) + } + + dependencies { +// "testRuntimeOnly"("org.junit.platform:junit-platform-launcher") + } + + tasks.withType().configureEach { + isPreserveFileTimestamps = false + isReproducibleFileOrder = true + } + tasks.withType { + options.encoding = Charsets.UTF_8.name() + options.release = JAVA_VERSION + options.isFork = true + } + tasks.withType { + options.encoding = Charsets.UTF_8.name() + } + tasks.withType { + filteringCharset = Charsets.UTF_8.name() + } + tasks.withType { + testLogging { + showStackTraces = true + exceptionFormat = TestExceptionFormat.FULL + events(TestLogEvent.STANDARD_OUT) + } + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 21cb2bd10..b11387697 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -15,9 +15,12 @@ rootProject.name = "ASPaper" include(":gradle:platform") include(":api") -include(":core") -include(":importer") -include(":loaders") -include(":plugin") -include(":aspaper-api") -include(":aspaper-server") +//include(":core") +//include(":importer") +//include(":loaders") +//include(":plugin") +include(":impl") +include(":impl:aspaper-api") +include(":impl:aspaper-server") +//include(":aspaper-api") +//include(":aspaper-server") From 2cc62f623776051925c9dd01984a2b43a62fd569 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 09:00:52 +0100 Subject: [PATCH 033/133] feat: update gradle patches --- gradle.properties | 2 +- gradle/libs.versions.toml | 2 +- impl/aspaper-api/build.gradle.kts.patch | 12 ++++---- impl/aspaper-server/build.gradle.kts.patch | 32 +++++++++------------- impl/build.gradle.kts | 5 ---- 5 files changed, 21 insertions(+), 32 deletions(-) diff --git a/gradle.properties b/gradle.properties index bee34f632..30e701599 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ apiVersion=4.0.0-SNAPSHOT version=1.21.4-R0.1-SNAPSHOT mcVersion=1.21.4 -paperRef=c45286cb08881ab4d28a16b8ef9c6a4fd0984ce8 +paperRef=636ae0cd87d303c438db2e5a673fa729c39979ec org.gradle.caching=true org.gradle.parallel=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5395e70cb..0937f4663 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ lettuce = "6.5.1.RELEASE" lombok = "1.18.36" lombok-plugin = "8.11" mongo = "5.2.1" -paperweight = "2.0.0-SNAPSHOT" +paperweight = "2.0.0-beta.14" plugin-yml-paper = "0.6.0" shadow = "8.3.5" slf4j = "2.0.16" diff --git a/impl/aspaper-api/build.gradle.kts.patch b/impl/aspaper-api/build.gradle.kts.patch index e5daed3e2..0313e402c 100644 --- a/impl/aspaper-api/build.gradle.kts.patch +++ b/impl/aspaper-api/build.gradle.kts.patch @@ -1,15 +1,15 @@ --- a/paper-api/build.gradle.kts +++ b/paper-api/build.gradle.kts -@@ -95,7 +_,7 @@ +@@ -93,7 +_,7 @@ + testRuntimeOnly("org.junit.platform:junit-platform-launcher") } - // Paper start --val generatedApiPath: java.nio.file.Path = rootProject.projectDir.toPath().resolve("paper-api-generator/generated") -+val generatedApiPath: java.nio.file.Path = rootProject.projectDir.toPath().resolve("impl/paper-api-generator/generated") +-val generatedApiPath: java.nio.file.Path = layout.projectDirectory.dir("src/generated/java").asFile.toPath() ++val generatedApiPath: java.nio.file.Path = rootProject.layout.projectDirectory.dir("paper-api/src/generated/java").asFile.toPath() idea { module { generatedSourceDirs.add(generatedApiPath.toFile()) -@@ -105,6 +_,18 @@ +@@ -103,6 +_,18 @@ main { java { srcDir(generatedApiPath) @@ -37,7 +37,7 @@ options.use() options.isDocFilesSubDirs = true options.links( -@@ -207,11 +_,11 @@ +@@ -202,11 +_,11 @@ } // workaround for https://github.com/gradle/gradle/issues/4046 diff --git a/impl/aspaper-server/build.gradle.kts.patch b/impl/aspaper-server/build.gradle.kts.patch index 4e3598104..fdcd626b5 100644 --- a/impl/aspaper-server/build.gradle.kts.patch +++ b/impl/aspaper-server/build.gradle.kts.patch @@ -1,30 +1,24 @@ --- a/paper-server/build.gradle.kts +++ b/paper-server/build.gradle.kts -@@ -17,11 +_,20 @@ +@@ -21,6 +_,17 @@ + // macheOldPath = file("F:\\Projects\\PaperTooling\\mache\\versions\\1.21.4\\src\\main\\java") + // gitFilePatches = true - paperweight { - minecraftVersion = providers.gradleProperty("mcVersion") -- // macheOldPath = file("F:\\Projects\\PaperTooling\\mache\\versions\\1.21.4\\src\\main\\java") -- // gitFilePatches = true -+ + val fork = forks.register("aspaper") { + upstream.patchDir("paperServer") { + upstreamPath = "paper-server" + excludes = setOf("src/minecraft", "patches", "build.gradle.kts") -+ patchesDir = rootDirectory.dir("aspaper-server/paper-patches") -+ outputDir = rootDirectory.dir("paper-server") ++ patchesDir = rootDirectory.dir("impl/aspaper-server/paper-patches") ++ outputDir = rootDirectory.dir("impl/paper-server") + } + } + + activeFork = fork - - paper { -- reobfMappingsPatch = layout.projectDirectory.file("../build-data/reobf-mappings-patch.tiny") -+ paperServerDir = upstreamsDirectory().map { it.dir("paper/paper-server") } - } - ++ spigot { -@@ -104,7 +_,20 @@ + buildDataRef = "3edaf46ec1eed4115ce1b18d2846cded42577e42" + packageVersion = "v1_21_R3" // also needs to be updated in MappingEnvironment +@@ -101,7 +_,20 @@ } } @@ -46,12 +40,12 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) { extendsFrom(configurations.compileClasspath.get()) } -@@ -123,7 +_,7 @@ - // Paper end - configure mockito agent that is needed in newer java versions +@@ -119,7 +_,7 @@ + } dependencies { - implementation(project(":paper-api")) + implementation(project(":impl:aspaper-api")) - implementation("ca.spottedleaf:concurrentutil:0.0.2") // Paper - Add ConcurrentUtil dependency - // Paper start + implementation("ca.spottedleaf:concurrentutil:0.0.3") implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ + implementation("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21 diff --git a/impl/build.gradle.kts b/impl/build.gradle.kts index 498d5dec5..0d8ee5411 100644 --- a/impl/build.gradle.kts +++ b/impl/build.gradle.kts @@ -28,11 +28,6 @@ paperweight { patchesDir = file("aspaper-api/paper-patches") outputDir = file("paper-api") } - patchDir("paperApiGenerator") { - upstreamPath = "paper-api-generator" - patchesDir = file("aspaper-api-generator/paper-patches") - outputDir = file("paper-api-generator") - } } } From 826326e7a7824e5dd2a6e44816f75c42d547ba7f Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 09:05:36 +0100 Subject: [PATCH 034/133] feat: access transformer for Entitylist instead of manual patch --- build-data/aspaper.at | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 build-data/aspaper.at diff --git a/build-data/aspaper.at b/build-data/aspaper.at new file mode 100644 index 000000000..51c67cd30 --- /dev/null +++ b/build-data/aspaper.at @@ -0,0 +1,3 @@ +# This file is auto generated, any changes may be overridden! +# See CONTRIBUTING.md on how to add access transformers. +public ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices entities From 5c81507602a178fe4759c0f95407ccc1e05e2480 Mon Sep 17 00:00:00 2001 From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> Date: Sun, 9 Mar 2025 12:27:26 +0100 Subject: [PATCH 035/133] Port "0001-Build-Changes patch" Alongside gradle build changes, branding changes (which were temporarily discarded) this patch also contained the majority of ASP Original Patch by Owen1212055 initially created on Mon, 26. Dec 2022 --- build-data/aspaper.at | 2 + core/build.gradle.kts | 2 +- impl/aspaper-api/build.gradle.kts.patch | 9 + impl/aspaper-server/build.gradle.kts.patch | 13 +- .../features/0001-World-overrides.patch | 44 + .../level/entity/ChunkEntitySlices.java.patch | 11 + .../scheduling/ChunkHolderManager.java.patch | 13 + .../scheduling/task/ChunkLoadTask.java.patch | 48 + .../server/level/ServerChunkCache.java.patch | 21 + .../server/level/ServerLevel.java.patch | 76 + .../java/com/infernalsuite/asp/Converter.java | 128 + .../com/infernalsuite/asp/InternalPlugin.java | 28 + .../asp/SimpleDataFixerConverter.java | 98 + .../infernalsuite/asp/SlimeNMSBridgeImpl.java | 208 ++ .../asp/level/ChunkDataLoadTask.java | 122 + .../asp/level/CommonLoadTask.java | 19 + .../asp/level/FastChunkPruner.java | 59 + .../asp/level/NMSSlimeChunk.java | 187 ++ .../asp/level/NMSSlimeWorld.java | 93 + .../asp/level/SafeNmsChunkWrapper.java | 83 + .../asp/level/SlimeBootstrap.java | 8 + .../asp/level/SlimeChunkConverter.java | 161 ++ .../asp/level/SlimeChunkLevel.java | 27 + .../asp/level/SlimeInMemoryWorld.java | 253 ++ .../asp/level/SlimeLevelGenerator.java | 39 + .../asp/level/SlimeLevelInstance.java | 197 ++ .../com/infernalsuite/asp/util/NmsUtil.java | 9 + .../com.infernalsuite.asp.api.SlimeNMSBridge | 1 + patches/server/0001-Build-Changes.patch | 2278 ----------------- settings.gradle.kts | 2 +- 30 files changed, 1954 insertions(+), 2285 deletions(-) create mode 100644 impl/aspaper-server/minecraft-patches/features/0001-World-overrides.patch create mode 100644 impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java.patch create mode 100644 impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java.patch create mode 100644 impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch create mode 100644 impl/aspaper-server/minecraft-patches/sources/net/minecraft/server/level/ServerChunkCache.java.patch create mode 100644 impl/aspaper-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch create mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/Converter.java create mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/InternalPlugin.java create mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java create mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java create mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java create mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java create mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java create mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java create mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java create mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java create mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeBootstrap.java create mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java create mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java create mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java create mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java create mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java create mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/util/NmsUtil.java create mode 100644 impl/aspaper-server/src/main/resources/META-INF/services/com.infernalsuite.asp.api.SlimeNMSBridge delete mode 100644 patches/server/0001-Build-Changes.patch diff --git a/build-data/aspaper.at b/build-data/aspaper.at index 51c67cd30..6d275d624 100644 --- a/build-data/aspaper.at +++ b/build-data/aspaper.at @@ -1,3 +1,5 @@ # This file is auto generated, any changes may be overridden! # See CONTRIBUTING.md on how to add access transformers. public ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices entities +public ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkLoadTask chunkHolder +public net.minecraft.server.MinecraftServer commandStorage diff --git a/core/build.gradle.kts b/core/build.gradle.kts index d981c5b8d..647bbf71d 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -5,7 +5,7 @@ plugins { dependencies { compileOnly(project(":api")) - compileOnly(project(":aspaper-api")) +// compileOnly(project(":aspaper-api")) implementation(libs.zstd) } diff --git a/impl/aspaper-api/build.gradle.kts.patch b/impl/aspaper-api/build.gradle.kts.patch index 0313e402c..33a97d1b5 100644 --- a/impl/aspaper-api/build.gradle.kts.patch +++ b/impl/aspaper-api/build.gradle.kts.patch @@ -1,5 +1,14 @@ --- a/paper-api/build.gradle.kts +++ b/paper-api/build.gradle.kts +@@ -39,7 +_,7 @@ + } + + dependencies { +- ++ api(project(":api")) //ASP + // api dependencies are listed transitively to API consumers + api("com.google.guava:guava:33.3.1-jre") + api("com.google.code.gson:gson:2.11.0") @@ -93,7 +_,7 @@ testRuntimeOnly("org.junit.platform:junit-platform-launcher") } diff --git a/impl/aspaper-server/build.gradle.kts.patch b/impl/aspaper-server/build.gradle.kts.patch index fdcd626b5..37eb260f4 100644 --- a/impl/aspaper-server/build.gradle.kts.patch +++ b/impl/aspaper-server/build.gradle.kts.patch @@ -1,15 +1,17 @@ --- a/paper-server/build.gradle.kts +++ b/paper-server/build.gradle.kts -@@ -21,6 +_,17 @@ +@@ -21,6 +_,19 @@ // macheOldPath = file("F:\\Projects\\PaperTooling\\mache\\versions\\1.21.4\\src\\main\\java") // gitFilePatches = true + val fork = forks.register("aspaper") { ++ rootDirectory = project.rootProject.layout.projectDirectory.dir("impl") ++ + upstream.patchDir("paperServer") { + upstreamPath = "paper-server" + excludes = setOf("src/minecraft", "patches", "build.gradle.kts") -+ patchesDir = rootDirectory.dir("impl/aspaper-server/paper-patches") -+ outputDir = rootDirectory.dir("impl/paper-server") ++ patchesDir = rootDirectory.dir("aspaper-server/paper-patches") ++ outputDir = rootDirectory.dir("paper-server") + } + } + @@ -40,12 +42,13 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) { extendsFrom(configurations.compileClasspath.get()) } -@@ -119,7 +_,7 @@ +@@ -119,7 +_,8 @@ } dependencies { - implementation(project(":paper-api")) -+ implementation(project(":impl:aspaper-api")) ++ implementation(project(":impl:aspaper-api")) //ASP ++ implementation(project(":core")) //ASP implementation("ca.spottedleaf:concurrentutil:0.0.3") implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ implementation("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21 diff --git a/impl/aspaper-server/minecraft-patches/features/0001-World-overrides.patch b/impl/aspaper-server/minecraft-patches/features/0001-World-overrides.patch new file mode 100644 index 000000000..fe8016414 --- /dev/null +++ b/impl/aspaper-server/minecraft-patches/features/0001-World-overrides.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> +Date: Mon, 26 Dec 2022 11:25:35 -0500 +Subject: [PATCH] World overrides + + +diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java +index ae220a732c78ab076261f20b5a54c71d7fceb407..16a7dd68a59fb6762b149ef9d0c0879226a86a3a 100644 +--- a/net/minecraft/server/MinecraftServer.java ++++ b/net/minecraft/server/MinecraftServer.java +@@ -516,18 +516,33 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop, EntityCollectionBySection> entitiesByClass; + private final Reference2ObjectOpenHashMap, EntityCollectionBySection> entitiesByType; +- private final EntityList entities = new EntityList(); ++ public final EntityList entities = new EntityList(); + + public FullChunkStatus status; + public final ChunkData chunkData; diff --git a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java.patch b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java.patch new file mode 100644 index 000000000..cfd198c02 --- /dev/null +++ b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java.patch @@ -0,0 +1,13 @@ +--- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java ++++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java +@@ -184,7 +_,9 @@ + }; + } + +- public void close(final boolean save, final boolean halt) { ++ public void close(boolean save, boolean halt) { // ASP ++ if (this.world instanceof com.infernalsuite.asp.level.SlimeLevelInstance) save = false; // ASP ++ + TickThread.ensureTickThread("Closing world off-main"); + if (halt) { + LOGGER.info("Waiting 60s for chunk system to halt for world '" + WorldUtil.getWorldName(this.world) + "'"); diff --git a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch new file mode 100644 index 000000000..f263f0798 --- /dev/null +++ b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch @@ -0,0 +1,48 @@ +--- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java ++++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java +@@ -32,8 +_,8 @@ + + private static final Logger LOGGER = LoggerFactory.getLogger(ChunkLoadTask.class); + +- private final NewChunkHolder chunkHolder; +- private final ChunkDataLoadTask loadTask; ++ public final NewChunkHolder chunkHolder; ++ private final com.infernalsuite.asp.level.CommonLoadTask loadTask; // ASP + + private volatile boolean cancelled; + private NewChunkHolder.GenericDataLoadTaskCallback entityLoadTask; +@@ -45,11 +_,20 @@ + final NewChunkHolder chunkHolder, final Priority priority) { + super(scheduler, world, chunkX, chunkZ); + this.chunkHolder = chunkHolder; +- this.loadTask = new ChunkDataLoadTask(scheduler, world, chunkX, chunkZ, priority); +- this.loadTask.addCallback((final GenericDataLoadTask.TaskResult result) -> { +- ChunkLoadTask.this.loadResult = result; // must be before getAndDecrement +- ChunkLoadTask.this.tryCompleteLoad(); +- }); ++ // ASWM start ++ if (world instanceof com.infernalsuite.aswm.level.SlimeLevelInstance levelInstance) { ++ ++ this.loadTask = levelInstance.getLoadTask(this, scheduler, world, chunkX, chunkZ, priority, result -> { ++ ChunkLoadTask.this.complete(result == null ? null : result.left(), result == null ? null : result.right()); ++ }); ++ } else { ++ ChunkDataLoadTask task = new ChunkDataLoadTask(scheduler, world, chunkX, chunkZ, priority); ++ task.addCallback((final GenericDataLoadTask.TaskResult result) -> { ++ ChunkLoadTask.this.complete(result == null ? null : result.left(), result == null ? null : result.right()); ++ }); ++ this.loadTask = task; ++ } ++ // ASWM end + } + + private void tryCompleteLoad() { +@@ -276,7 +_,7 @@ + + private static record ReadChunk(ProtoChunk protoChunk, SerializableChunkData chunkData) {} + +- private static final class ChunkDataLoadTask extends CallbackDataLoadTask { ++ private static final class ChunkDataLoadTask extends CallbackDataLoadTask implements com.infernalsuite.asp.level.CommonLoadTask { // ASP + private ChunkDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, + final int chunkZ, final Priority priority) { + super(scheduler, world, chunkX, chunkZ, MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, priority); diff --git a/impl/aspaper-server/minecraft-patches/sources/net/minecraft/server/level/ServerChunkCache.java.patch b/impl/aspaper-server/minecraft-patches/sources/net/minecraft/server/level/ServerChunkCache.java.patch new file mode 100644 index 000000000..1ed2cc9d0 --- /dev/null +++ b/impl/aspaper-server/minecraft-patches/sources/net/minecraft/server/level/ServerChunkCache.java.patch @@ -0,0 +1,21 @@ +--- a/net/minecraft/server/level/ServerChunkCache.java ++++ b/net/minecraft/server/level/ServerChunkCache.java +@@ -181,8 +_,10 @@ + } + // Paper end - chunk tick iteration optimisations + ++ public final com.infernalsuite.asp.level.SlimeBootstrap bootstrap; //ASP + + public ServerChunkCache( ++ com.infernalsuite.asp.level.SlimeBootstrap bootstrap, //ASP + ServerLevel level, + LevelStorageSource.LevelStorageAccess levelStorageAccess, + DataFixer fixerUpper, +@@ -196,6 +_,7 @@ + ChunkStatusUpdateListener chunkStatusListener, + Supplier overworldDataStorage + ) { ++ this.bootstrap = bootstrap; //ASP + this.level = level; + this.mainThreadProcessor = new ServerChunkCache.MainThreadExecutor(level); + this.mainThread = Thread.currentThread(); diff --git a/impl/aspaper-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch b/impl/aspaper-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch new file mode 100644 index 000000000..6c795fee8 --- /dev/null +++ b/impl/aspaper-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch @@ -0,0 +1,76 @@ +--- a/net/minecraft/server/level/ServerLevel.java ++++ b/net/minecraft/server/level/ServerLevel.java +@@ -570,7 +_,32 @@ + } + // Paper end - chunk tick iteration + +- public ServerLevel( ++ public com.infernalsuite.asp.level.SlimeInMemoryWorld slimeInstance; // ASP ++ ++ public ServerLevel( ++ MinecraftServer server, ++ Executor dispatcher, ++ LevelStorageSource.LevelStorageAccess levelStorageAccess, ++ net.minecraft.world.level.storage.PrimaryLevelData serverLevelData, // CraftBukkit ++ ResourceKey dimension, ++ LevelStem levelStem, ++ ChunkProgressListener progressListener, ++ boolean isDebug, ++ long biomeZoomSeed, ++ List customSpawners, ++ boolean tickTime, ++ @Nullable RandomSequences randomSequences, ++ org.bukkit.World.Environment env, // CraftBukkit ++ org.bukkit.generator.ChunkGenerator gen, // CraftBukkit ++ org.bukkit.generator.BiomeProvider biomeProvider // CraftBukkit ++ ) { ++ //ASP start ++ this(null, server, dispatcher, levelStorageAccess, serverLevelData, dimension, levelStem, progressListener, ++ isDebug, biomeZoomSeed, customSpawners, tickTime, randomSequences, env, gen, biomeProvider); ++ } ++ ++ public ServerLevel( ++ @Nullable com.infernalsuite.asp.level.SlimeBootstrap bootstrap, + MinecraftServer server, + Executor dispatcher, + LevelStorageSource.LevelStorageAccess levelStorageAccess, +@@ -587,6 +_,7 @@ + org.bukkit.generator.ChunkGenerator gen, // CraftBukkit + org.bukkit.generator.BiomeProvider biomeProvider // CraftBukkit + ) { ++ //ASP end + // CraftBukkit start + super(serverLevelData, dimension, server.registryAccess(), levelStem.type(), false, isDebug, biomeZoomSeed, server.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> server.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(levelStorageAccess.levelDirectory.path(), serverLevelData.getLevelName(), dimension.location(), spigotConfig, server.registryAccess(), serverLevelData.getGameRules())), dispatcher); // Paper - create paper world configs; Async-Anti-Xray: Pass executor + this.pvpMode = server.isPvpAllowed(); +@@ -614,10 +_,18 @@ + chunkGenerator = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, chunkGenerator, gen); + } + // CraftBukkit end ++ // ASP START ++ ChunkGenerator result = this.getGenerator(bootstrap); ++ if (result != null) { ++ chunkGenerator = result; ++ } ++ // ASP END ++ + boolean flag = server.forceSynchronousWrites(); + DataFixer fixerUpper = server.getFixerUpper(); + // Paper - rewrite chunk system + this.chunkSource = new ServerChunkCache( ++ bootstrap, //ASP + this, + levelStorageAccess, + fixerUpper, +@@ -695,6 +_,12 @@ + public void setDragonFight(@Nullable EndDragonFight dragonFight) { + this.dragonFight = dragonFight; + } ++ ++ // ASP START ++ public ChunkGenerator getGenerator(com.infernalsuite.asp.level.SlimeBootstrap bootstrap) { ++ return null; ++ } ++ // ASP END + + public void setWeatherParameters(int clearTime, int weatherTime, boolean isRaining, boolean isThundering) { + this.serverLevelData.setClearWeatherTime(clearTime); diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/Converter.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/Converter.java new file mode 100644 index 000000000..22acbf7d0 --- /dev/null +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/Converter.java @@ -0,0 +1,128 @@ +package com.infernalsuite.asp; + +import com.infernalsuite.asp.api.utils.NibbleArray; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.ByteArrayBinaryTag; +import net.kyori.adventure.nbt.ByteBinaryTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.DoubleBinaryTag; +import net.kyori.adventure.nbt.EndBinaryTag; +import net.kyori.adventure.nbt.FloatBinaryTag; +import net.kyori.adventure.nbt.IntArrayBinaryTag; +import net.kyori.adventure.nbt.IntBinaryTag; +import net.kyori.adventure.nbt.ListBinaryTag; +import net.kyori.adventure.nbt.LongArrayBinaryTag; +import net.kyori.adventure.nbt.LongBinaryTag; +import net.kyori.adventure.nbt.ShortBinaryTag; +import net.kyori.adventure.nbt.StringBinaryTag; +import net.kyori.adventure.nbt.TagStringIO; +import net.minecraft.nbt.ByteArrayTag; +import net.minecraft.nbt.ByteTag; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.DoubleTag; +import net.minecraft.nbt.EndTag; +import net.minecraft.nbt.FloatTag; +import net.minecraft.nbt.IntArrayTag; +import net.minecraft.nbt.IntTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.LongArrayTag; +import net.minecraft.nbt.LongTag; +import net.minecraft.nbt.ShortTag; +import net.minecraft.nbt.StringTag; +import net.minecraft.nbt.Tag; +import net.minecraft.world.level.chunk.DataLayer; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class Converter { + + private static final Logger LOGGER = LogManager.getLogger("ASP NBT Converter"); + + static DataLayer convertArray(NibbleArray array) { + return new DataLayer(array.getBacking()); + } + + public static NibbleArray convertArray(DataLayer array) { + if(array == null) { + return null; + } + + return new NibbleArray(array.getData()); + } + + public static Tag convertTag(T tag) { + try { + return switch (tag.type().id()) { + case Tag.TAG_END -> EndTag.INSTANCE; + case Tag.TAG_BYTE -> ByteTag.valueOf(((ByteBinaryTag) tag).value()); + case Tag.TAG_SHORT -> ShortTag.valueOf(((ShortBinaryTag) tag).value()); + case Tag.TAG_INT -> IntTag.valueOf(((IntBinaryTag) tag).value()); + case Tag.TAG_LONG -> LongTag.valueOf(((LongBinaryTag) tag).value()); + case Tag.TAG_FLOAT -> FloatTag.valueOf(((FloatBinaryTag) tag).value()); + case Tag.TAG_DOUBLE -> DoubleTag.valueOf(((DoubleBinaryTag) tag).value()); + case Tag.TAG_BYTE_ARRAY -> new ByteArrayTag(((ByteArrayBinaryTag) tag).value()); + case Tag.TAG_STRING -> StringTag.valueOf(((StringBinaryTag) tag).value()); + case Tag.TAG_LIST -> { + ListTag list = new ListTag(); + for (BinaryTag entry : ((ListBinaryTag) tag)) list.add(convertTag(entry)); + yield list; + } + case Tag.TAG_COMPOUND -> { + CompoundTag compound = new CompoundTag(); + ((CompoundBinaryTag) tag).forEach(entry -> compound.put(entry.getKey(), convertTag(entry.getValue()))); + yield compound; + } + case Tag.TAG_INT_ARRAY -> new IntArrayTag(((IntArrayBinaryTag) tag).value()); + case Tag.TAG_LONG_ARRAY -> new LongArrayTag(((LongArrayBinaryTag) tag).value()); + default -> throw new IllegalArgumentException("Invalid tag type " + tag.type().id()); + }; + } catch (final Exception e) { + CompoundBinaryTag exceptionTag = CompoundBinaryTag.builder().put("failing_tag", tag).build(); + String tagString; + try { + tagString = TagStringIO.get().asString(exceptionTag); + } catch (final IOException ioEx) { + LOGGER.error("Error while trying to convert exception tag to string", ioEx); + tagString = "UNAVAILABLE"; + } + LOGGER.error("Failed to convert NBT object: {}", tagString); + throw e; + } + } + + @SuppressWarnings("unchecked") + public static T convertTag(Tag base) { + return switch (base.getId()) { + case Tag.TAG_END -> (T) EndBinaryTag.endBinaryTag(); + case Tag.TAG_BYTE -> (T) ByteBinaryTag.byteBinaryTag(((ByteTag) base).getAsByte()); + case Tag.TAG_SHORT -> (T) ShortBinaryTag.shortBinaryTag(((ShortTag) base).getAsShort()); + case Tag.TAG_INT -> (T) IntBinaryTag.intBinaryTag(((IntTag) base).getAsInt()); + case Tag.TAG_LONG -> (T) LongBinaryTag.longBinaryTag(((LongTag) base).getAsLong()); + case Tag.TAG_FLOAT -> (T) FloatBinaryTag.floatBinaryTag(((FloatTag) base).getAsFloat()); + case Tag.TAG_DOUBLE -> (T) DoubleBinaryTag.doubleBinaryTag(((DoubleTag) base).getAsDouble()); + case Tag.TAG_BYTE_ARRAY -> (T) ByteArrayBinaryTag.byteArrayBinaryTag(((ByteArrayTag) base).getAsByteArray()); + case Tag.TAG_STRING -> (T) StringBinaryTag.stringBinaryTag(((StringTag) base).getAsString()); + case Tag.TAG_LIST -> { + List list = new ArrayList<>(); + ListTag originalList = ((ListTag) base); + for (Tag entry : originalList) list.add(convertTag(entry)); + yield (T) ListBinaryTag.listBinaryTag(list.getFirst().type(), list); + } + case Tag.TAG_COMPOUND -> { + CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder(); + CompoundTag originalCompound = ((CompoundTag) base); + for (String key : originalCompound.getAllKeys()) builder.put(key, convertTag(Objects.requireNonNull(originalCompound.get(key)))); + yield (T) builder.build(); + } + case Tag.TAG_INT_ARRAY -> (T) IntArrayBinaryTag.intArrayBinaryTag(((IntArrayTag) base).getAsIntArray()); + case Tag.TAG_LONG_ARRAY -> (T) LongArrayBinaryTag.longArrayBinaryTag(((LongArrayTag) base).getAsLongArray()); + default -> throw new IllegalArgumentException("Invalid tag type " + base.getId()); + }; + } + +} diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/InternalPlugin.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/InternalPlugin.java new file mode 100644 index 000000000..48f996ff8 --- /dev/null +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/InternalPlugin.java @@ -0,0 +1,28 @@ +package com.infernalsuite.asp; + +import net.minecraft.server.MinecraftServer; +import org.bukkit.Server; +import org.bukkit.craftbukkit.scheduler.MinecraftInternalPlugin; +import org.bukkit.plugin.PluginLogger; +import org.jetbrains.annotations.NotNull; + +import java.util.logging.LogRecord; + +public class InternalPlugin extends MinecraftInternalPlugin { + + @Override + public @NotNull Server getServer() { + return MinecraftServer.getServer().server; + } + + @Override + public @NotNull PluginLogger getLogger() { + return new PluginLogger(new InternalPlugin()) { + @Override + public void log(@NotNull LogRecord logRecord) { + MinecraftServer.LOGGER.info(logRecord.getMessage()); + } + }; + } + +} diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java new file mode 100644 index 000000000..694bd135f --- /dev/null +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java @@ -0,0 +1,98 @@ +package com.infernalsuite.asp; + +import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; +import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; +import ca.spottedleaf.dataconverter.types.nbt.NBTMapType; +import com.infernalsuite.asp.serialization.SlimeWorldReader; +import com.infernalsuite.asp.skeleton.SkeletonSlimeWorld; +import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; +import com.infernalsuite.asp.skeleton.SlimeChunkSkeleton; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeChunkSection; +import com.infernalsuite.asp.api.world.SlimeWorld; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.minecraft.SharedConstants; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.function.Consumer; + +class SimpleDataFixerConverter implements SlimeWorldReader { + + @Override + public SlimeWorld readFromData(SlimeWorld data) { + int newVersion = SharedConstants.getCurrentVersion().getDataVersion().getVersion(); + int currentVersion = data.getDataVersion(); + // Already fixed + if (currentVersion == newVersion) { + return data; + } + + Map chunks = new HashMap<>(); + for (SlimeChunk chunk : data.getChunkStorage()) { + List entities = new ArrayList<>(); + List blockEntities = new ArrayList<>(); + for (CompoundBinaryTag upgradeEntity : chunk.getTileEntities()) { + blockEntities.add( + convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.TILE_ENTITY.convert(new NBTMapType(tag), currentVersion, newVersion)) + ); + } + for (CompoundBinaryTag upgradeEntity : chunk.getEntities()) { + entities.add( + convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.ENTITY.convert(new NBTMapType(tag), currentVersion, newVersion)) + ); + } + + SlimeChunkSection[] sections = new SlimeChunkSection[chunk.getSections().length]; + for (int i = 0; i < sections.length; i++) { + SlimeChunkSection dataSection = chunk.getSections()[i]; + + CompoundBinaryTag blockStateTag = blockStateTag = convertAndBack(dataSection.getBlockStatesTag(), (tag) -> { + WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, new NBTMapType(tag), "palette", currentVersion, newVersion); + }); + + CompoundBinaryTag biomeTag = convertAndBack(dataSection.getBiomeTag(), (tag) -> { + WalkerUtils.convertList(MCTypeRegistry.BIOME, new NBTMapType(tag), "palette", currentVersion, newVersion); + }); + + sections[i] = new SlimeChunkSectionSkeleton( + blockStateTag, + biomeTag, + dataSection.getBlockLight(), + dataSection.getSkyLight() + ); + + chunks.put(new ChunkPos(chunk.getX(), chunk.getZ()), new SlimeChunkSkeleton( + chunk.getX(), + chunk.getZ(), + sections, + chunk.getHeightMaps(), + blockEntities, + entities + )); + } + + } + + return new SkeletonSlimeWorld( + data.getName(), + data.getLoader(), + data.isReadOnly(), + chunks, + data.getExtraData(), + data.getPropertyMap(), + newVersion + ); + } + + + private static CompoundBinaryTag convertAndBack(CompoundBinaryTag value, Consumer acceptor) { + if (value == null) return null; + + net.minecraft.nbt.CompoundTag converted = (net.minecraft.nbt.CompoundTag) Converter.convertTag(value); + acceptor.accept(converted); + + return Converter.convertTag(converted); + } +} diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java new file mode 100644 index 000000000..f8fbb1f02 --- /dev/null +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java @@ -0,0 +1,208 @@ +package com.infernalsuite.asp; + +import com.infernalsuite.asp.api.SlimeNMSBridge; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.SlimeWorldInstance; +import com.infernalsuite.asp.api.world.properties.SlimeProperties; +import com.infernalsuite.asp.level.SlimeBootstrap; +import com.infernalsuite.asp.level.SlimeInMemoryWorld; +import com.infernalsuite.asp.level.SlimeLevelInstance; +import com.mojang.serialization.Lifecycle; +import net.kyori.adventure.util.Services; +import net.minecraft.SharedConstants; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.WorldLoader; +import net.minecraft.server.dedicated.DedicatedServer; +import net.minecraft.server.dedicated.DedicatedServerProperties; +import net.minecraft.world.level.GameRules; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelSettings; +import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.levelgen.WorldOptions; +import net.minecraft.world.level.storage.CommandStorage; +import net.minecraft.world.level.storage.DimensionDataStorage; +import net.minecraft.world.level.storage.PrimaryLevelData; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.craftbukkit.CraftWorld; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.util.Locale; + +public class SlimeNMSBridgeImpl implements SlimeNMSBridge { + + private static final SimpleDataFixerConverter DATA_FIXER_CONVERTER = new SimpleDataFixerConverter(); + + private static final Logger LOGGER = LogManager.getLogger("ASP"); + + private SlimeWorld defaultWorld; + private SlimeWorld defaultNetherWorld; + private SlimeWorld defaultEndWorld; + + public static SlimeNMSBridgeImpl instance() { + return (SlimeNMSBridgeImpl) SlimeNMSBridge.instance(); + } + + @Override + public boolean loadOverworldOverride() { + if (defaultWorld == null) { + return false; + } + + // See MinecraftServer loading logic + // Some stuff is needed when loading overworld world + SlimeLevelInstance instance = ((SlimeInMemoryWorld) this.loadInstance(defaultWorld, Level.OVERWORLD)).getInstance(); + DimensionDataStorage worldpersistentdata = instance.getDataStorage(); + instance.getCraftServer().scoreboardManager = new org.bukkit.craftbukkit.scoreboard.CraftScoreboardManager(instance.getServer(), instance.getScoreboard()); + instance.getServer().commandStorage = new CommandStorage(worldpersistentdata); + + return true; + } + + @Override + public boolean loadNetherOverride() { + if (defaultNetherWorld == null) { + return false; + } + + this.loadInstance(defaultNetherWorld, Level.NETHER); + + return true; + } + + @Override + public boolean loadEndOverride() { + if (defaultEndWorld == null) { + return false; + } + + this.loadInstance(defaultEndWorld, Level.END); + + return true; + } + + @Override + public void setDefaultWorlds(SlimeWorld normalWorld, SlimeWorld netherWorld, SlimeWorld endWorld) { + if (normalWorld != null) { + normalWorld.getPropertyMap().setValue(SlimeProperties.ENVIRONMENT, World.Environment.NORMAL.toString().toLowerCase()); + defaultWorld = normalWorld; + } + + if (netherWorld != null) { + netherWorld.getPropertyMap().setValue(SlimeProperties.ENVIRONMENT, World.Environment.NETHER.toString().toLowerCase()); + defaultNetherWorld = netherWorld; + } + + if (endWorld != null) { + endWorld.getPropertyMap().setValue(SlimeProperties.ENVIRONMENT, World.Environment.THE_END.toString().toLowerCase()); + defaultEndWorld = endWorld; + } + + } + + @Override + public SlimeWorldInstance loadInstance(SlimeWorld slimeWorld) { + return this.loadInstance(slimeWorld, null); + } + + public SlimeWorldInstance loadInstance(SlimeWorld slimeWorld, @Nullable ResourceKey dimensionOverride) { + String worldName = slimeWorld.getName(); + + if (Bukkit.getWorld(worldName) != null) { + throw new IllegalArgumentException("World " + worldName + " already exists! Maybe it's an outdated SlimeWorld object?"); + } + + SlimeLevelInstance server = createCustomWorld(slimeWorld, dimensionOverride); + registerWorld(server); + return server.getSlimeInstance(); + } + + @Override + public SlimeWorldInstance getInstance(World world) { + CraftWorld craftWorld = (CraftWorld) world; + + if (!(craftWorld.getHandle() instanceof SlimeLevelInstance worldServer)) { + return null; + } + + return worldServer.getSlimeInstance(); + } + + @Override + public SlimeWorld applyDataFixers(SlimeWorld world) { + return DATA_FIXER_CONVERTER.readFromData(world); + } + + + @Override + public int getCurrentVersion() { + return SharedConstants.getCurrentVersion().getDataVersion().getVersion(); + } + + public void registerWorld(SlimeLevelInstance server) { + MinecraftServer mcServer = MinecraftServer.getServer(); + mcServer.initWorld(server, server.serverLevelData, mcServer.getWorldData(), server.serverLevelData.worldGenOptions()); + + mcServer.addLevel(server); + } + + private SlimeLevelInstance createCustomWorld(SlimeWorld world, @Nullable ResourceKey dimensionOverride) { + SlimeBootstrap bootstrap = new SlimeBootstrap(world); + String worldName = world.getName(); + + PrimaryLevelData worldDataServer = createWorldData(world); + World.Environment environment = getEnvironment(world); + ResourceKey dimension = switch (environment) { + case NORMAL -> LevelStem.OVERWORLD; + case NETHER -> LevelStem.NETHER; + case THE_END -> LevelStem.END; + default -> throw new IllegalArgumentException("Unknown dimension supplied"); + }; + + ResourceKey worldKey = dimensionOverride == null ? ResourceKey.create(Registries.DIMENSION, new ResourceLocation(worldName.toLowerCase(Locale.ENGLISH))) : dimensionOverride; + LevelStem stem = MinecraftServer.getServer().registries().compositeAccess().registryOrThrow(Registries.LEVEL_STEM).get(dimension); + + SlimeLevelInstance level; + + try { + level = new SlimeLevelInstance(bootstrap, worldDataServer, worldKey, dimension, stem, environment); + } catch (IOException ex) { + throw new RuntimeException(ex); // TODO do something better with this? + } + + // level.setReady(true); + level.setSpawnSettings(world.getPropertyMap().getValue(SlimeProperties.ALLOW_MONSTERS), world.getPropertyMap().getValue(SlimeProperties.ALLOW_ANIMALS)); + + return level; + } + + private World.Environment getEnvironment(SlimeWorld world) { + return World.Environment.valueOf(world.getPropertyMap().getValue(SlimeProperties.ENVIRONMENT).toUpperCase()); + } + + private PrimaryLevelData createWorldData(SlimeWorld world) { + MinecraftServer mcServer = MinecraftServer.getServer(); + DedicatedServerProperties serverProps = ((DedicatedServer) mcServer).getProperties(); + String worldName = world.getName(); + WorldLoader.DataLoadContext context = mcServer.worldLoader; + + LevelSettings worldsettings = new LevelSettings(worldName, serverProps.gamemode, false, serverProps.difficulty, + true, new GameRules(context.dataConfiguration().enabledFeatures()), mcServer.worldLoader.dataConfiguration()); + + WorldOptions worldoptions = new WorldOptions(0, false, false); + + PrimaryLevelData data = new PrimaryLevelData(worldsettings, worldoptions, PrimaryLevelData.SpecialWorldProperty.FLAT, Lifecycle.stable()); + data.checkName(worldName); + data.setModdedInfo(mcServer.getServerModName(), mcServer.getModdedStatus().shouldReportAsModified()); + data.setInitialized(true); + + return data; + } + +} diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java new file mode 100644 index 000000000..9a627c165 --- /dev/null +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java @@ -0,0 +1,122 @@ +package com.infernalsuite.asp.level; + +import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.util.Priority; +import ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkLoadTask; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.GenericDataLoadTask; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.mojang.logging.LogUtils; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ImposterProtoChunk; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.UpgradeData; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.ticks.LevelChunkTicks; +import org.slf4j.Logger; + +import java.util.function.Consumer; + +public final class ChunkDataLoadTask implements CommonLoadTask { + + private static final Logger LOGGER = LogUtils.getClassLogger(); + + private final ChunkTaskScheduler scheduler; + private final ServerLevel world; + private final int chunkX; + private final int chunkZ; + private Consumer> onRun; + + private PrioritisedExecutor.PrioritisedTask task; + + private final ChunkLoadTask chunkLoadTask; + + protected ChunkDataLoadTask(ChunkLoadTask chunkLoadTask, final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, + final int chunkZ, final Priority priority, final Consumer> onRun) { + this.chunkLoadTask = chunkLoadTask; + this.scheduler = scheduler; + this.world = world; + this.chunkX = chunkX; + this.chunkZ = chunkZ; + this.onRun = onRun; + + this.task = this.scheduler.createChunkTask(this.chunkX, this.chunkZ, () -> { + try { + SlimeChunk chunk = ((SlimeLevelInstance) this.world).slimeInstance.getChunk(this.chunkX, this.chunkZ); + this.onRun.accept(new GenericDataLoadTask.TaskResult<>(runOnMain(chunk), null)); + } catch (Throwable e) { + LOGGER.error("ERROR", e); + this.onRun.accept(new GenericDataLoadTask.TaskResult<>(null, e)); + } + }, priority); + } + + private ChunkAccess getEmptyChunk() { + LevelChunkTicks blockLevelChunkTicks = new LevelChunkTicks<>(); + LevelChunkTicks fluidLevelChunkTicks = new LevelChunkTicks<>(); + + return new ImposterProtoChunk(new LevelChunk(this.world, new ChunkPos(this.chunkX, this.chunkZ), UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks, + 0L, null, null, null), true); + } + + protected ChunkAccess runOnMain(final SlimeChunk data) { + final PoiChunk poiChunk = this.chunkLoadTask.chunkHolder.getPoiChunk(); + if (poiChunk == null) { + LOGGER.error("Expected poi chunk to be loaded with chunk for task " + this.toString()); + } else { + poiChunk.load(); + } + + // have tasks to run (at this point, it's just the POI consistency checking) + try { + // if (data.tasks != null) { + // for (int i = 0, len = data.tasks.size(); i < len; i) { + // data.tasks.poll().run(); + // } + // } + + LevelChunk chunk = this.world.slimeInstance.promote(chunkX, chunkZ, data); + + return new ImposterProtoChunk(chunk, false); + } catch (final ThreadDeath death) { + throw death; + } catch (final Throwable thr2) { + LOGGER.error("Failed to parse main tasks for task " + this.toString() + ", chunk data will be lost", thr2); + return this.getEmptyChunk(); + } + } + + @Override + public Priority getPriority() { + return this.task.getPriority(); + } + + @Override + public void setPriority(Priority priority) { + this.task.setPriority(priority); + } + + @Override + public void raisePriority(Priority priority) { + this.task.raisePriority(priority); + } + + @Override + public void lowerPriority(Priority priority) { + this.task.lowerPriority(priority); + } + + @Override + public boolean cancel() { + return this.task.cancel(); + } + + public boolean schedule(boolean schedule) { + this.scheduler.scheduleChunkTask(chunkX, chunkZ, this.task::execute); + return true; + } +} diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java new file mode 100644 index 000000000..980b11942 --- /dev/null +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java @@ -0,0 +1,19 @@ +package com.infernalsuite.asp.level; + +import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.util.Priority; + +public interface CommonLoadTask { + + boolean schedule(boolean schedule); + + Priority getPriority(); + + boolean cancel(); + + void lowerPriority(Priority priority); + + void raisePriority(Priority priority); + + void setPriority(Priority priority); +} diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java new file mode 100644 index 000000000..ccacb856c --- /dev/null +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java @@ -0,0 +1,59 @@ +package com.infernalsuite.asp.level; + +import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.properties.SlimeProperties; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.LevelChunkSection; + +public class FastChunkPruner { + + public static boolean canBePruned(SlimeWorld world, LevelChunk chunk) { + // Kenox + // It's not safe to assume that the chunk can be pruned + // if there isn't a loaded chunk there + if (chunk == null || chunk.getChunkHolder() == null) { + return false; + } + + SlimePropertyMap propertyMap = world.getPropertyMap(); + if (propertyMap.getValue(SlimeProperties.SHOULD_LIMIT_SAVE)) { + int minX = propertyMap.getValue(SlimeProperties.SAVE_MIN_X); + int maxX = propertyMap.getValue(SlimeProperties.SAVE_MAX_X); + + int minZ = propertyMap.getValue(SlimeProperties.SAVE_MIN_Z); + int maxZ = propertyMap.getValue(SlimeProperties.SAVE_MAX_Z); + + int chunkX = chunk.locX; + int chunkZ = chunk.locZ; + + if (chunkX < minX || chunkX > maxX) { + return true; + } + + if (chunkZ < minZ || chunkZ > maxZ) { + return true; + } + } + + String pruningSetting = world.getPropertyMap().getValue(SlimeProperties.CHUNK_PRUNING); + if (pruningSetting.equals("aggressive")) { + ChunkEntitySlices slices = chunk.getChunkHolder().getEntityChunk(); + + return chunk.blockEntities.isEmpty() && (slices == null || slices.isEmpty()) && areSectionsEmpty(chunk); + } + + return false; + } + + private static boolean areSectionsEmpty(LevelChunk chunk) { + for (LevelChunkSection section : chunk.getSections()) { + if (!section.hasOnlyAir()) { + return false; + } + } + + return true; + } +} diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java new file mode 100644 index 000000000..5913b067e --- /dev/null +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -0,0 +1,187 @@ +package com.infernalsuite.asp.level; + +import com.google.common.collect.Lists; +import com.infernalsuite.asp.Converter; +import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; +import com.infernalsuite.asp.api.utils.NibbleArray; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeChunkSection; +import com.mojang.logging.LogUtils; +import com.mojang.serialization.Codec; +import io.papermc.paper.world.ChunkEntitySlices; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.LongArrayBinaryTag; +import net.minecraft.core.Holder; +import net.minecraft.core.Registry; +import net.minecraft.core.SectionPos; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; +import net.minecraft.nbt.Tag; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.LightLayer; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.Biomes; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.chunk.PalettedContainer; +import net.minecraft.world.level.chunk.PalettedContainerRO; +import net.minecraft.world.level.chunk.storage.ChunkSerializer; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.lighting.LevelLightEngine; +import org.slf4j.Logger; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class NMSSlimeChunk implements SlimeChunk { + private static final Logger LOGGER = LogUtils.getClassLogger(); + + private static final CompoundBinaryTag EMPTY_BLOCK_STATE_PALETTE; + private static final CompoundBinaryTag EMPTY_BIOME_PALETTE; + + // Optimized empty section serialization + static { + { + PalettedContainer empty = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, null); + Tag tag = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, empty).getOrThrow(false, (error) -> { + throw new AssertionError(error); + }); + + EMPTY_BLOCK_STATE_PALETTE = Converter.convertTag(tag); + } + { + Registry biomes = net.minecraft.server.MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME); + PalettedContainer> empty = new PalettedContainer<>(biomes.asHolderIdMap(), biomes.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); + Tag tag = ChunkSerializer.makeBiomeCodec(biomes).encodeStart(NbtOps.INSTANCE, empty).getOrThrow(false, (error) -> { + throw new AssertionError(error); + }); + + EMPTY_BIOME_PALETTE = Converter.convertTag(tag); + } + } + + private LevelChunk chunk; + + public NMSSlimeChunk(LevelChunk chunk) { + this.chunk = chunk; + } + + @Override + public int getX() { + return chunk.getPos().x; + } + + @Override + public int getZ() { + return chunk.getPos().z; + } + + @Override + public SlimeChunkSection[] getSections() { + SlimeChunkSection[] sections = new SlimeChunkSection[this.chunk.getSectionsCount()]; + LevelLightEngine lightEngine = chunk.getLevel().getChunkSource().getLightEngine(); + + Registry biomeRegistry = chunk.getLevel().registryAccess().registryOrThrow(Registries.BIOME); + + // Ignore deprecation, spigot only method + Codec>> codec = PalettedContainer.codecRO(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getHolderOrThrow(Biomes.PLAINS)); + + for (int sectionId = 0; sectionId < chunk.getSections().length; sectionId++) { + LevelChunkSection section = chunk.getSections()[sectionId]; + // Sections CANNOT be null in 1.18 + + // Block Light Nibble Array + NibbleArray blockLightArray = Converter.convertArray(lightEngine.getLayerListener(LightLayer.BLOCK).getDataLayerData(SectionPos.of(chunk.getPos(), sectionId))); + + // Sky light Nibble Array + NibbleArray skyLightArray = Converter.convertArray(lightEngine.getLayerListener(LightLayer.SKY).getDataLayerData(SectionPos.of(chunk.getPos(), sectionId))); + + // Tile/Entity Data + + // Block Data + CompoundBinaryTag blockStateTag; + if (section.hasOnlyAir()) { + blockStateTag = EMPTY_BLOCK_STATE_PALETTE; + } else { + Tag data = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, section.getStates()).getOrThrow(false, System.err::println); // todo error handling + blockStateTag = Converter.convertTag(data); + } + + + CompoundBinaryTag biomeTag; + PalettedContainer> biomes = (PalettedContainer>) section.getBiomes(); + if (biomes.data.palette().getSize() == 1 && biomes.data.palette().maybeHas((h) -> h.is(Biomes.PLAINS))) { + biomeTag = EMPTY_BIOME_PALETTE; + } else { + Tag biomeData = codec.encodeStart(NbtOps.INSTANCE, section.getBiomes()).getOrThrow(false, System.err::println); // todo error handling + biomeTag = Converter.convertTag(biomeData); + } + + sections[sectionId] = new SlimeChunkSectionSkeleton(blockStateTag, biomeTag, blockLightArray, skyLightArray); + } + + return sections; + } + + @Override + public CompoundBinaryTag getHeightMaps() { + CompoundBinaryTag.Builder heightMapsTagBuilder = CompoundBinaryTag.builder(); + + this.chunk.heightmaps.forEach((type, map) -> { + if (type.keepAfterWorldgen()) { + heightMapsTagBuilder.put(type.name(), LongArrayBinaryTag.longArrayBinaryTag(map.getRawData())); + } + }); + + return heightMapsTagBuilder.build(); + } + + @Override + public List getTileEntities() { + List tileEntities = new ArrayList<>(); + + for (BlockEntity entity : this.chunk.blockEntities.values()) { + CompoundTag entityNbt = entity.saveWithFullMetadata(); + tileEntities.add(entityNbt); + } + + return Lists.transform(tileEntities, Converter::convertTag); + } + + @Override + public List getEntities() { + List entities = new ArrayList<>(); + + if (this.chunk == null || this.chunk.getChunkHolder() == null) return new ArrayList<>(); + + ChunkEntitySlices slices = this.chunk.getChunkHolder().getEntityChunk(); + if (slices == null) return new ArrayList<>(); + + // Work by + for (Entity entity : slices.entities) { + CompoundTag entityNbt = new CompoundTag(); + try { + if (entity.save(entityNbt)) entities.add(entityNbt); + } catch (final Exception e) { + LOGGER.error("Could not save the entity = {}, exception = {}", entity, e); + } + } + + return Lists.transform(entities, Converter::convertTag); + } + + public LevelChunk getChunk() { + return chunk; + } + + public void setChunk(LevelChunk chunk) { + this.chunk = chunk; + } + +} diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java new file mode 100644 index 000000000..da5dfb98f --- /dev/null +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java @@ -0,0 +1,93 @@ +package com.infernalsuite.asp.level; + +import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.minecraft.SharedConstants; +import net.minecraft.server.level.ChunkHolder; +import net.minecraft.world.level.chunk.LevelChunk; + +import java.io.IOException; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.ConcurrentMap; +import java.util.stream.Collectors; + +public class NMSSlimeWorld implements SlimeWorld { + + private final SlimeInMemoryWorld memoryWorld; + private final SlimeLevelInstance instance; + + public NMSSlimeWorld(SlimeInMemoryWorld memoryWorld) { + this.instance = memoryWorld.getInstance(); + this.memoryWorld = memoryWorld; + } + + @Override + public String getName() { + return this.instance.getMinecraftWorld().serverLevelData.getLevelName(); + } + + @Override + public SlimeLoader getLoader() { + return this.instance.slimeInstance.getSaveStrategy(); + } + + @Override + public SlimeChunk getChunk(int x, int z) { + LevelChunk chunk = this.instance.getChunkIfLoaded(x, z); + if (chunk == null) { + return null; + } + + return new NMSSlimeChunk(chunk); + } + + @Override + public Collection getChunkStorage() { + List chunks = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.instance); // Paper + return chunks.stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull) + .map(NMSSlimeChunk::new) + .collect(Collectors.toList()); + } + + @Override + public ConcurrentMap getExtraData() { + return this.instance.slimeInstance.getExtraData(); + } + + @Override + public Collection getWorldMaps() { + return List.of(); + } + + @Override + public SlimePropertyMap getPropertyMap() { + return this.instance.slimeInstance.getPropertyMap(); + } + + @Override + public boolean isReadOnly() { + return this.getLoader() == null; + } + + @Override + public SlimeWorld clone(String worldName) { + return this.memoryWorld.clone(worldName); + } + + @Override + public SlimeWorld clone(String worldName, SlimeLoader loader) throws WorldAlreadyExistsException, IOException { + return this.memoryWorld.clone(worldName, loader); + } + + @Override + public int getDataVersion() { + return SharedConstants.getCurrentVersion().getDataVersion().getVersion(); + } +} diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java new file mode 100644 index 000000000..4ee4d2f00 --- /dev/null +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java @@ -0,0 +1,83 @@ +package com.infernalsuite.asp.level; + +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeChunkSection; +import net.kyori.adventure.nbt.CompoundBinaryTag; + +import java.util.List; + +public class SafeNmsChunkWrapper implements SlimeChunk { + + private final NMSSlimeChunk wrapper; + private final SlimeChunk safety; + + public SafeNmsChunkWrapper(NMSSlimeChunk wrapper, SlimeChunk safety) { + this.wrapper = wrapper; + this.safety = safety; + } + + @Override + public int getX() { + return this.wrapper.getX(); + } + + @Override + public int getZ() { + return this.wrapper.getZ(); + } + + @Override + public SlimeChunkSection[] getSections() { + if (shouldDefaultBackToSlimeChunk()) { + return this.safety.getSections(); + } + + return this.wrapper.getSections(); + } + + @Override + public CompoundBinaryTag getHeightMaps() { + if (shouldDefaultBackToSlimeChunk()) { + return this.safety.getHeightMaps(); + } + + return this.wrapper.getHeightMaps(); + } + + @Override + public List getTileEntities() { + if (shouldDefaultBackToSlimeChunk()) { + return this.safety.getTileEntities(); + } + + return this.wrapper.getTileEntities(); + } + + @Override + public List getEntities() { + if (shouldDefaultBackToSlimeChunk()) { + return this.safety.getEntities(); + } + + return this.wrapper.getEntities(); + } + + /* +Slime chunks can still be requested but not actually loaded, this caused +some things to not properly save because they are not "loaded" into the chunk. +See ChunkMap#protoChunkToFullChunk +anything in the if statement will not be loaded and is stuck inside the runnable. +Inorder to possibly not corrupt the state, simply refer back to the slime saved object. +*/ + public boolean shouldDefaultBackToSlimeChunk() { + return this.safety != null && !this.wrapper.getChunk().loaded; + } + + public NMSSlimeChunk getWrapper() { + return wrapper; + } + + public SlimeChunk getSafety() { + return safety; + } +} diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeBootstrap.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeBootstrap.java new file mode 100644 index 000000000..5e4e77384 --- /dev/null +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeBootstrap.java @@ -0,0 +1,8 @@ +package com.infernalsuite.asp.level; + +import com.infernalsuite.asp.api.world.SlimeWorld; + +public record SlimeBootstrap( + SlimeWorld initial +) { +} diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java new file mode 100644 index 000000000..b0d45837e --- /dev/null +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java @@ -0,0 +1,161 @@ +package com.infernalsuite.asp.level; + +import ca.spottedleaf.starlight.common.light.SWMRNibbleArray; +import com.infernalsuite.asp.Converter; +import com.infernalsuite.asp.api.utils.NibbleArray; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeChunkSection; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.core.Registry; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.NbtOps; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.Biomes; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.chunk.PalettedContainer; +import net.minecraft.world.level.chunk.UpgradeData; +import net.minecraft.world.level.chunk.storage.ChunkSerializer; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.ticks.LevelChunkTicks; + +import java.util.EnumSet; +import java.util.List; +import java.util.Optional; + +public class SlimeChunkConverter { + + static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeChunk chunk) { + int x = chunk.getX(); + int z = chunk.getZ(); + + ChunkPos pos = new ChunkPos(x, z); + + // Chunk sections + LevelChunkSection[] sections = new LevelChunkSection[instance.getSectionsCount()]; + + SWMRNibbleArray[] blockNibbles = ca.spottedleaf.starlight.common.light.StarLightEngine.getFilledEmptyLight(instance); + SWMRNibbleArray[] skyNibbles = ca.spottedleaf.starlight.common.light.StarLightEngine.getFilledEmptyLight(instance); + instance.getServer().scheduleOnMain(() -> { + instance.getLightEngine().retainData(pos, true); + }); + + Registry biomeRegistry = instance.registryAccess().registryOrThrow(Registries.BIOME); + // Ignore deprecated method + + Codec>> codec = PalettedContainer.codecRW(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getHolderOrThrow(Biomes.PLAINS), null); + + for (int sectionId = 0; sectionId < chunk.getSections().length; sectionId++) { + SlimeChunkSection slimeSection = chunk.getSections()[sectionId]; + + if (slimeSection != null) { + NibbleArray blockLight = slimeSection.getBlockLight(); + if (blockLight != null) { + blockNibbles[sectionId] = new SWMRNibbleArray(blockLight.getBacking()); + } + + NibbleArray skyLight = slimeSection.getSkyLight(); + if (skyLight != null) { + skyNibbles[sectionId] = new SWMRNibbleArray(skyLight.getBacking()); + } + + PalettedContainer blockPalette; + if (slimeSection.getBlockStatesTag() != null) { + DataResult> dataresult = ChunkSerializer.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, Converter.convertTag(slimeSection.getBlockStatesTag())).promotePartial((s) -> { + System.out.println("Recoverable error when parsing section " + x + "," + z + ": " + s); // todo proper logging + }); + blockPalette = dataresult.getOrThrow(false, System.err::println); // todo proper logging + } else { + blockPalette = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, null); + } + + PalettedContainer> biomePalette; + + if (slimeSection.getBiomeTag() != null) { + DataResult>> dataresult = codec.parse(NbtOps.INSTANCE, Converter.convertTag(slimeSection.getBiomeTag())).promotePartial((s) -> { + System.out.println("Recoverable error when parsing section " + x + "," + z + ": " + s); // todo proper logging + }); + biomePalette = dataresult.getOrThrow(false, System.err::println); // todo proper logging + } else { + biomePalette = new PalettedContainer<>(biomeRegistry.asHolderIdMap(), biomeRegistry.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); + } + + if (sectionId < sections.length) { + LevelChunkSection section = new LevelChunkSection(blockPalette, biomePalette); + sections[sectionId] = section; + } + } + } + + // Keep the chunk loaded at level 33 to avoid light glitches + // Such a high level will let the server not tick the chunk, + // but at the same time it won't be completely unloaded from memory + // getChunkProvider().addTicket(SWM_TICKET, pos, 33, Unit.INSTANCE); + + + LevelChunk.PostLoadProcessor loadEntities = (nmsChunk) -> { + + // TODO + // Load tile entities + List tileEntities = chunk.getTileEntities(); + + if (tileEntities != null) { + for (CompoundBinaryTag tag : tileEntities) { + String type = tag.getString("id"); + + if (!type.isEmpty()) { + BlockPos blockPosition = new BlockPos(tag.getInt("x"), tag.getInt("y"), tag.getInt("z")); + BlockState blockData = nmsChunk.getBlockState(blockPosition); + BlockEntity entity = BlockEntity.loadStatic(blockPosition, blockData, (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)); + + if (entity != null) { + nmsChunk.setBlockEntity(entity); + } + } + } + } + }; + + LevelChunkTicks blockLevelChunkTicks = new LevelChunkTicks<>(); + LevelChunkTicks fluidLevelChunkTicks = new LevelChunkTicks<>(); + SlimeChunkLevel nmsChunk = new SlimeChunkLevel(instance, pos, UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks, 0L, sections, loadEntities, null); + + // Height Maps + EnumSet heightMapTypes = nmsChunk.getStatus().heightmapsAfter(); + CompoundBinaryTag heightMaps = chunk.getHeightMaps(); + EnumSet unsetHeightMaps = EnumSet.noneOf(Heightmap.Types.class); + + // Light + nmsChunk.setBlockNibbles(blockNibbles); + nmsChunk.setSkyNibbles(skyNibbles); + + for (Heightmap.Types type : heightMapTypes) { + String name = type.getSerializedName(); + + long[] heightMap = heightMaps.getLongArray(name); + if (heightMap.length > 0) { + nmsChunk.setHeightmap(type, heightMap); + } else { + unsetHeightMaps.add(type); + } + } + + // Don't try to populate heightmaps if there are none. + // Does a crazy amount of block lookups + if (!unsetHeightMaps.isEmpty()) { + Heightmap.primeHeightmaps(nmsChunk, unsetHeightMaps); + } + + return nmsChunk; + } +} diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java new file mode 100644 index 000000000..397a655a6 --- /dev/null +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java @@ -0,0 +1,27 @@ +package com.infernalsuite.asp.level; + +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.chunk.UpgradeData; +import net.minecraft.world.level.levelgen.blending.BlendingData; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.ticks.LevelChunkTicks; +import org.jetbrains.annotations.Nullable; + +public class SlimeChunkLevel extends LevelChunk { + + private final SlimeInMemoryWorld inMemoryWorld; + + public SlimeChunkLevel(SlimeLevelInstance world, ChunkPos pos, UpgradeData upgradeData, LevelChunkTicks blockTickScheduler, LevelChunkTicks fluidTickScheduler, long inhabitedTime, @Nullable LevelChunkSection[] sectionArrayInitializer, @Nullable LevelChunk.PostLoadProcessor entityLoader, @Nullable BlendingData blendingData) { + super(world, pos, upgradeData, blockTickScheduler, fluidTickScheduler, inhabitedTime, sectionArrayInitializer, entityLoader, blendingData); + this.inMemoryWorld = world.slimeInstance; + } + + @Override + public void unloadCallback() { + super.unloadCallback(); + this.inMemoryWorld.unload(this); + } +} diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java new file mode 100644 index 000000000..636c553f4 --- /dev/null +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -0,0 +1,253 @@ +package com.infernalsuite.asp.level; + +import com.infernalsuite.asp.ChunkPos; +import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.serialization.slime.SlimeSerializer; +import com.infernalsuite.asp.skeleton.SkeletonCloning; +import com.infernalsuite.asp.skeleton.SkeletonSlimeWorld; +import com.infernalsuite.asp.skeleton.SlimeChunkSkeleton; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.SlimeWorldInstance; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.UpgradeData; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.ticks.LevelChunkTicks; +import org.bukkit.World; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentMap; + +/* +The concept of this is a bit flawed, since ideally this should be a 1:1 representation of the MC world. +However, due to the complexity of the chunk system we essentially need to wrap around it. +This stores slime chunks, and when unloaded, will properly convert it to a normal slime chunk for storage. + */ +public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { + + private final SlimeLevelInstance instance; + private final SlimeWorld liveWorld; + + private final ConcurrentMap extra; + private final SlimePropertyMap propertyMap; + private final SlimeLoader loader; + + private final Map chunkStorage = new HashMap<>(); + private boolean readOnly; + // private final Map> entityStorage = new HashMap<>(); + + public SlimeInMemoryWorld(SlimeBootstrap bootstrap, SlimeLevelInstance instance) { + this.instance = instance; + this.extra = bootstrap.initial().getExtraData(); + this.propertyMap = bootstrap.initial().getPropertyMap(); + this.loader = bootstrap.initial().getLoader(); + this.readOnly = bootstrap.initial().isReadOnly(); + + for (SlimeChunk initial : bootstrap.initial().getChunkStorage()) { + ChunkPos pos = new ChunkPos(initial.getX(), initial.getZ()); + List tags = new ArrayList<>(initial.getEntities()); + + // this.entityStorage.put(pos, tags); + this.chunkStorage.put(pos, initial); + } + + this.liveWorld = new NMSSlimeWorld(this); + } + + @Override + public String getName() { + return this.instance.getMinecraftWorld().serverLevelData.getLevelName(); + } + + @Override + public SlimeLoader getLoader() { + return this.loader; + } + + public LevelChunk promote(int x, int z, SlimeChunk chunk) { + SlimeChunkLevel levelChunk; + if (chunk == null) { + net.minecraft.world.level.ChunkPos pos = new net.minecraft.world.level.ChunkPos(x, z); + LevelChunkTicks blockLevelChunkTicks = new LevelChunkTicks<>(); + LevelChunkTicks fluidLevelChunkTicks = new LevelChunkTicks<>(); + + levelChunk = new SlimeChunkLevel(this.instance, pos, UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks, + 0L, null, null, null); + + chunk = new NMSSlimeChunk(levelChunk); + + } else { + levelChunk = SlimeChunkConverter.deserializeSlimeChunk(this.instance, chunk); + chunk = new SafeNmsChunkWrapper(new NMSSlimeChunk(levelChunk), chunk); + } + this.chunkStorage.put(new ChunkPos(x, z), chunk); + + return levelChunk; + } + + // Authored by: Kenox + // Don't use the NMS live chunk in the chunk map + public void unload(LevelChunk providedChunk) { + final int x = providedChunk.locX; + final int z = providedChunk.locZ; + + SlimeChunk chunk = new NMSSlimeChunk(providedChunk); + + if (FastChunkPruner.canBePruned(this.liveWorld, providedChunk)) { + this.chunkStorage.remove(new ChunkPos(x, z)); + return; + } + + this.chunkStorage.put(new ChunkPos(x, z), + new SlimeChunkSkeleton(chunk.getX(), chunk.getZ(), chunk.getSections(), + chunk.getHeightMaps(), chunk.getTileEntities(), chunk.getEntities())); + } + + @Override + public SlimeChunk getChunk(int x, int z) { + return this.chunkStorage.get(new ChunkPos(x, z)); + } + + @Override + public Collection getChunkStorage() { + return this.chunkStorage.values(); + } + + @Override + public World getBukkitWorld() { + return this.instance.getWorld(); + } + + @Override + public SlimeWorld getSlimeWorldMirror() { + return this.liveWorld; + } + + @Override + public SlimePropertyMap getPropertyMap() { + return this.propertyMap; + } + + @Override + public boolean isReadOnly() { + return this.getSaveStrategy() == null || this.readOnly; + } + + @Override + public SlimeWorld clone(String worldName) { + try { + return clone(worldName, null); + } catch (WorldAlreadyExistsException | IOException ignored) { + return null; // Never going to happen + } + } + + @Override + public SlimeWorld clone(String worldName, SlimeLoader loader) throws WorldAlreadyExistsException, IOException { + if (this.getName().equals(worldName)) { + throw new IllegalArgumentException("The clone world cannot have the same name as the original world!"); + } + + if (worldName == null) { + throw new IllegalArgumentException("The world name cannot be null!"); + } + if (loader != null) { + if (loader.worldExists(worldName)) { + throw new WorldAlreadyExistsException(worldName); + } + } + + SlimeWorld cloned = SkeletonCloning.fullClone(worldName, this, loader); + if (loader != null) { + loader.saveWorld(worldName, SlimeSerializer.serialize(cloned)); + } + + return cloned; + } + + @Override + public int getDataVersion() { + return this.liveWorld.getDataVersion(); + } + + @Override + public SlimeLoader getSaveStrategy() { + return this.loader; + } + + @Override + public ConcurrentMap getExtraData() { + return this.extra; + } + + @Override + public Collection getWorldMaps() { + return List.of(); + } + + // public Map> getEntityStorage() { + // return entityStorage; + // } + + public SlimeWorld getForSerialization() { + SlimeWorld world = SkeletonCloning.weakCopy(this); + + Map cloned = new HashMap<>(); + for (Map.Entry entry : this.chunkStorage.entrySet()) { + SlimeChunk clonedChunk = entry.getValue(); + // NMS "live" chunks need to be converted + { + LevelChunk chunk = null; + if (clonedChunk instanceof SafeNmsChunkWrapper safeNmsChunkWrapper) { + if (safeNmsChunkWrapper.shouldDefaultBackToSlimeChunk()) { + clonedChunk = safeNmsChunkWrapper.getSafety(); + } else { + chunk = safeNmsChunkWrapper.getWrapper().getChunk(); + } + } else if (clonedChunk instanceof NMSSlimeChunk nmsSlimeChunk) { + chunk = nmsSlimeChunk.getChunk(); + } + + if (chunk != null) { + if (FastChunkPruner.canBePruned(world, chunk)) { + continue; + } + + clonedChunk = new SlimeChunkSkeleton( + clonedChunk.getX(), + clonedChunk.getZ(), + clonedChunk.getSections(), + clonedChunk.getHeightMaps(), + clonedChunk.getTileEntities(), + clonedChunk.getEntities() + ); + } + } + + cloned.put(entry.getKey(), clonedChunk); + } + + return new SkeletonSlimeWorld(world.getName(), + world.getLoader(), + world.isReadOnly(), + cloned, + world.getExtraData(), + world.getPropertyMap(), + world.getDataVersion() + ); + } + + public SlimeLevelInstance getInstance() { + return instance; + } +} diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java new file mode 100644 index 000000000..fcf71851a --- /dev/null +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java @@ -0,0 +1,39 @@ +package com.infernalsuite.asp.level; + +import com.mojang.serialization.MapCodec; +import net.minecraft.core.Holder; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeSource; +import net.minecraft.world.level.biome.Climate; +import net.minecraft.world.level.levelgen.FlatLevelSource; +import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + +public class SlimeLevelGenerator extends FlatLevelSource { + + public SlimeLevelGenerator(Holder biome) { + super(new FlatLevelGeneratorSettings(Optional.empty(), biome, List.of()), getSource(biome)); + } + + private static BiomeSource getSource(Holder biome) { + return new BiomeSource() { + @Override + protected MapCodec codec() { + return null; + } + + @Override + protected Stream> collectPossibleBiomes() { + return Stream.of(biome); + } + + @Override + public Holder getNoiseBiome(int x, int y, int z, Climate.Sampler noise) { + return biome; + } + }; + } +} diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java new file mode 100644 index 000000000..2c593fe63 --- /dev/null +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -0,0 +1,197 @@ +package com.infernalsuite.asp.level; + +import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.infernalsuite.asp.Converter; +import com.infernalsuite.asp.serialization.slime.SlimeSerializer; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.SlimeWorldInstance; +import com.infernalsuite.asp.api.world.properties.SlimeProperties; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import io.papermc.paper.chunk.system.scheduling.ChunkLoadTask; +import io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler; +import io.papermc.paper.chunk.system.scheduling.GenericDataLoadTask; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.TicketType; +import net.minecraft.util.ProgressListener; +import net.minecraft.util.Unit; +import net.minecraft.util.datafix.DataFixers; +import net.minecraft.world.Difficulty; +import net.minecraft.world.RandomSequences; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.storage.LevelStorageSource; +import net.minecraft.world.level.storage.PrimaryLevelData; +import net.minecraft.world.level.validation.DirectoryValidator; +import net.minecraft.world.level.validation.PathAllowList; +import org.apache.commons.io.FileUtils; +import org.bukkit.Bukkit; +import org.bukkit.event.world.WorldSaveEvent; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collections; +import java.util.UUID; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.function.Consumer; +import java.util.logging.Level; +import java.util.stream.Collectors; + +public class SlimeLevelInstance extends ServerLevel { + + + public static LevelStorageSource CUSTOM_LEVEL_STORAGE; + + static { + try { + Path path = Files.createTempDirectory("swm-" + UUID.randomUUID().toString().substring(0, 5)).toAbsolutePath(); + DirectoryValidator directoryvalidator = LevelStorageSource.parseValidator(path.resolve("allowed_symlinks.txt")); + CUSTOM_LEVEL_STORAGE = new LevelStorageSource(path, path, directoryvalidator, DataFixers.getDataFixer()); + + FileUtils.forceDeleteOnExit(path.toFile()); + + } catch (IOException ex) { + throw new IllegalStateException("Couldn't create dummy file directory.", ex); + } + } + + private static final ExecutorService WORLD_SAVER_SERVICE = Executors.newFixedThreadPool(4, new ThreadFactoryBuilder() + .setNameFormat("SWM Pool Thread #%1$d").build()); + private static final TicketType SWM_TICKET = TicketType.create("swm-chunk", (a, b) -> 0); + + private final Object saveLock = new Object(); + + private boolean ready = false; + + public SlimeLevelInstance(SlimeBootstrap slimeBootstrap, PrimaryLevelData primaryLevelData, + ResourceKey worldKey, + ResourceKey dimensionKey, LevelStem worldDimension, + org.bukkit.World.Environment environment) throws IOException { + + super(slimeBootstrap, MinecraftServer.getServer(), MinecraftServer.getServer().executor, + CUSTOM_LEVEL_STORAGE.createAccess(slimeBootstrap.initial().getName() + UUID.randomUUID(), dimensionKey), + primaryLevelData, worldKey, worldDimension, + MinecraftServer.getServer().progressListenerFactory.create(11), false, null, 0, + Collections.emptyList(), true, environment, null, null); + this.slimeInstance = new SlimeInMemoryWorld(slimeBootstrap, this); + + + SlimePropertyMap propertyMap = slimeBootstrap.initial().getPropertyMap(); + + this.serverLevelData.setDifficulty(Difficulty.valueOf(propertyMap.getValue(SlimeProperties.DIFFICULTY).toUpperCase())); + this.serverLevelData.setSpawn(new BlockPos(propertyMap.getValue(SlimeProperties.SPAWN_X), propertyMap.getValue(SlimeProperties.SPAWN_Y), propertyMap.getValue(SlimeProperties.SPAWN_Z)), 0); + super.setSpawnSettings(propertyMap.getValue(SlimeProperties.ALLOW_MONSTERS), propertyMap.getValue(SlimeProperties.ALLOW_ANIMALS)); + + this.pvpMode = propertyMap.getValue(SlimeProperties.PVP); + + this.keepSpawnInMemory = false; + } + + @Override + public ChunkGenerator getGenerator(SlimeBootstrap slimeBootstrap) { + String biomeStr = slimeBootstrap.initial().getPropertyMap().getValue(SlimeProperties.DEFAULT_BIOME); + ResourceKey biomeKey = ResourceKey.create(Registries.BIOME, new ResourceLocation(biomeStr)); + Holder defaultBiome = MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME).getHolder(biomeKey).orElseThrow(); + return new SlimeLevelGenerator(defaultBiome); + } + + @Override + public void save(@Nullable ProgressListener progressUpdate, boolean forceSave, boolean savingDisabled, boolean close) { + try { + if (!this.slimeInstance.isReadOnly() && !savingDisabled) { + Bukkit.getPluginManager().callEvent(new WorldSaveEvent(getWorld())); + + //this.getChunkSource().save(forceSave); + this.serverLevelData.setWorldBorder(this.getWorldBorder().createSettings()); + this.serverLevelData.setCustomBossEvents(MinecraftServer.getServer().getCustomBossEvents().save()); + + // Update level data + net.minecraft.nbt.CompoundTag compound = new net.minecraft.nbt.CompoundTag(); + net.minecraft.nbt.CompoundTag nbtTagCompound = this.serverLevelData.createTag(MinecraftServer.getServer().registryAccess(), compound); + + if (MinecraftServer.getServer().isStopped()) { // Make sure the world gets saved before stopping the server by running it from the main thread + save().get(); // Async wait for it to finish + this.slimeInstance.getLoader().unlockWorld(this.slimeInstance.getName()); // Unlock + } else { + this.save(); + //WORLD_SAVER_SERVICE.execute(this::save); + } + } + } catch (Throwable e) { + e.printStackTrace(); + } + } + + @Override + public void saveIncrementally(boolean doFull) { + if (doFull) { + this.save(null, false, false); + } + } + + private Future save() { + synchronized (saveLock) { // Don't want to save the SlimeWorld from multiple threads simultaneously + SlimeWorldInstance slimeWorld = this.slimeInstance; + Bukkit.getLogger().log(Level.INFO, "Saving world " + this.slimeInstance.getName() + "..."); + long start = System.currentTimeMillis(); + + Bukkit.getLogger().log(Level.INFO, "CONVERTING NMS -> SKELETON"); + SlimeWorld world = this.slimeInstance.getForSerialization(); + Bukkit.getLogger().log(Level.INFO, "CONVERTED TO SKELETON, PUSHING OFF-THREAD"); + return WORLD_SAVER_SERVICE.submit(() -> { + try { + byte[] serializedWorld = SlimeSerializer.serialize(world); + long saveStart = System.currentTimeMillis(); + slimeWorld.getSaveStrategy().saveWorld(slimeWorld.getName(), serializedWorld); + Bukkit.getLogger().log(Level.INFO, "World " + slimeWorld.getName() + " serialized in " + (saveStart - start) + "ms and saved in " + (System.currentTimeMillis() - saveStart) + "ms."); + } catch (IOException | IllegalStateException ex) { + ex.printStackTrace(); + } + }); + + } + } + + public SlimeWorldInstance getSlimeInstance() { + return this.slimeInstance; + } + + public ChunkDataLoadTask getLoadTask(ChunkLoadTask task, ChunkTaskScheduler scheduler, ServerLevel world, int chunkX, int chunkZ, PrioritisedExecutor.Priority priority, Consumer> onRun) { + return new ChunkDataLoadTask(task, scheduler, world, chunkX, chunkZ, priority, onRun); + } + + public void loadEntities(int chunkX, int chunkZ) { + SlimeChunk slimeChunk = this.slimeInstance.getChunk(chunkX, chunkZ); + if (slimeChunk != null) { + this.getEntityLookup().addLegacyChunkEntities(new ArrayList<>( + EntityType.loadEntitiesRecursive(slimeChunk.getEntities() + .stream() + .map((tag) -> (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)) + .collect(Collectors.toList()), this) + .toList() + ), new ChunkPos(chunkX, chunkZ)); + } + } + + // @Override + // public void unload(LevelChunk chunk) { + // this.slimeInstance.unload(chunk); + // super.unload(chunk); + // } +} diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/util/NmsUtil.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/util/NmsUtil.java new file mode 100644 index 000000000..13cab3d74 --- /dev/null +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/util/NmsUtil.java @@ -0,0 +1,9 @@ +package com.infernalsuite.asp.util; + +public class NmsUtil { + + public static long asLong(int chunkX, int chunkZ) { + return (((long) chunkZ) * Integer.MAX_VALUE + ((long) chunkX)); + //return (long)chunkX & 4294967295L | ((long)chunkZ & 4294967295L) << 32; + } +} diff --git a/impl/aspaper-server/src/main/resources/META-INF/services/com.infernalsuite.asp.api.SlimeNMSBridge b/impl/aspaper-server/src/main/resources/META-INF/services/com.infernalsuite.asp.api.SlimeNMSBridge new file mode 100644 index 000000000..973f2f48d --- /dev/null +++ b/impl/aspaper-server/src/main/resources/META-INF/services/com.infernalsuite.asp.api.SlimeNMSBridge @@ -0,0 +1 @@ +com.infernalsuite.asp.SlimeNMSBridgeImpl \ No newline at end of file diff --git a/patches/server/0001-Build-Changes.patch b/patches/server/0001-Build-Changes.patch deleted file mode 100644 index a5cf793b8..000000000 --- a/patches/server/0001-Build-Changes.patch +++ /dev/null @@ -1,2278 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> -Date: Mon, 26 Dec 2022 11:25:35 -0500 -Subject: [PATCH] Build Changes - -Update shadow plugin - -diff --git a/build.gradle.kts b/build.gradle.kts -index 2da91ed6363c0851e4c459188f5e8ef5475e0c97..f0bfc068301c4a908a5856b7c72e7306adeeb38d 100644 ---- a/build.gradle.kts -+++ b/build.gradle.kts -@@ -4,6 +4,7 @@ import java.time.Instant - plugins { - java - `maven-publish` -+ id("com.gradleup.shadow") - } - - val log4jPlugins = sourceSets.create("log4jPlugins") -@@ -25,7 +26,13 @@ abstract class MockitoAgentProvider : CommandLineArgumentProvider { - // Paper end - configure mockito agent that is needed in newer java versions - - dependencies { -- implementation(project(":paper-api")) -+ // ASWM start -+ implementation(project(":aspaper-api")) -+ implementation(project(":core")) -+ implementation("io.papermc.paper:paper-mojangapi:1.20.4-R0.1-SNAPSHOT") { -+ exclude("io.papermc.paper", "paper-api") -+ } -+ // ASWM end - implementation("ca.spottedleaf:concurrentutil:0.0.2") // Paper - Add ConcurrentUtil dependency - // Paper start - implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ -@@ -100,14 +107,14 @@ tasks.jar { - val gitBranch = git("rev-parse", "--abbrev-ref", "HEAD").getText().trim() // Paper - attributes( - "Main-Class" to "org.bukkit.craftbukkit.Main", -- "Implementation-Title" to "Paper", -+ "Implementation-Title" to "AdvancedSlimePaper", - "Implementation-Version" to implementationVersion, - "Implementation-Vendor" to date, // Paper -- "Specification-Title" to "Paper", -+ "Specification-Title" to "AdvancedSlimePaper", - "Specification-Version" to project.version, -- "Specification-Vendor" to "Paper Team", -- "Brand-Id" to "papermc:paper", -- "Brand-Name" to "Paper", -+ "Specification-Vendor" to "InfernalSuite Team", -+ "Brand-Id" to "infernalsuite:advancedslimepaper", -+ "Brand-Name" to "AdvancedSlimePaper", - "Build-Number" to (build ?: ""), - "Build-Time" to Instant.now().toString(), - "Git-Branch" to gitBranch, // Paper -@@ -173,7 +180,7 @@ fun TaskContainer.registerRunTask( - name: String, - block: JavaExec.() -> Unit - ): TaskProvider = register(name) { -- group = "paper" -+ group = "asp" - mainClass.set("org.bukkit.craftbukkit.Main") - standardInput = System.`in` - workingDir = rootProject.layout.projectDirectory -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java -index d21ce54ebb5724c04eadf56a2cde701d5eeb5db2..d0a2d1d8dd41980b95303add867ca906dd089af6 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java -@@ -42,7 +42,7 @@ public final class ChunkEntitySlices { - private final EntityCollectionBySection hardCollidingEntities; - private final Reference2ObjectOpenHashMap, EntityCollectionBySection> entitiesByClass; - private final Reference2ObjectOpenHashMap, EntityCollectionBySection> entitiesByType; -- private final EntityList entities = new EntityList(); -+ public final EntityList entities = new EntityList(); // ASP - private -> public - - public FullChunkStatus status; - public final ChunkData chunkData; -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java -index 3990834a41116682d6ae779a3bf24b0fd989d97d..2bc81d274769ed5bb33f94889e0cab0f37fa01a5 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java -@@ -185,7 +185,8 @@ public final class ChunkHolderManager { - }; - } - -- public void close(final boolean save, final boolean halt) { -+ public void close(boolean save, final boolean halt) { // ASWM -+ if (this.world instanceof com.infernalsuite.asp.level.SlimeLevelInstance) save = false; // ASWM - TickThread.ensureTickThread("Closing world off-main"); - if (halt) { - LOGGER.info("Waiting 60s for chunk system to halt for world '" + WorldUtil.getWorldName(this.world) + "'"); -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java -index 1440c9e2b106616884edcb20201113320817ed9f..ae8b6fd79dd556499acb96114dfd38c85eca67f6 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java -@@ -6,6 +6,7 @@ import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock; - import ca.spottedleaf.concurrentutil.util.ConcurrentUtil; - import ca.spottedleaf.concurrentutil.util.Priority; - import ca.spottedleaf.moonrise.common.PlatformHooks; -+import com.infernalsuite.asp.level.CommonLoadTask; - import ca.spottedleaf.moonrise.patches.chunk_system.ChunkSystemConverters; - import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; - import ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk; -@@ -32,8 +33,8 @@ public final class ChunkLoadTask extends ChunkProgressionTask { - - private static final Logger LOGGER = LoggerFactory.getLogger(ChunkLoadTask.class); - -- private final NewChunkHolder chunkHolder; -- private final ChunkDataLoadTask loadTask; -+ public final NewChunkHolder chunkHolder; // ASWM -+ private final CommonLoadTask loadTask; - - private volatile boolean cancelled; - private NewChunkHolder.GenericDataLoadTaskCallback entityLoadTask; -@@ -45,11 +46,20 @@ public final class ChunkLoadTask extends ChunkProgressionTask { - final NewChunkHolder chunkHolder, final Priority priority) { - super(scheduler, world, chunkX, chunkZ); - this.chunkHolder = chunkHolder; -- this.loadTask = new ChunkDataLoadTask(scheduler, world, chunkX, chunkZ, priority); -- this.loadTask.addCallback((final GenericDataLoadTask.TaskResult result) -> { -- ChunkLoadTask.this.loadResult = result; // must be before getAndDecrement -- ChunkLoadTask.this.tryCompleteLoad(); -- }); -+ // ASWM start -+ if (world instanceof com.infernalsuite.asp.level.SlimeLevelInstance levelInstance) { -+ -+ this.loadTask = levelInstance.getLoadTask(this, scheduler, world, chunkX, chunkZ, priority, result -> { -+ ChunkLoadTask.this.complete(result == null ? null : result.left(), result == null ? null : result.right()); -+ }); -+ } else { -+ ChunkDataLoadTask task = new ChunkDataLoadTask(scheduler, world, chunkX, chunkZ, priority); -+ task.addCallback((final GenericDataLoadTask.TaskResult result) -> { -+ ChunkLoadTask.this.complete(result == null ? null : result.left(), result == null ? null : result.right()); -+ }); -+ this.loadTask = task; -+ } -+ // ASWM end - } - - private void tryCompleteLoad() { -@@ -276,7 +286,7 @@ public final class ChunkLoadTask extends ChunkProgressionTask { - - private static record ReadChunk(ProtoChunk protoChunk, SerializableChunkData chunkData) {} - -- private static final class ChunkDataLoadTask extends CallbackDataLoadTask { -+ private static final class ChunkDataLoadTask extends CallbackDataLoadTask implements CommonLoadTask { // ASWM - private ChunkDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, - final int chunkZ, final Priority priority) { - super(scheduler, world, chunkX, chunkZ, MoonriseRegionFileIO.RegionFileType.CHUNK_DATA, priority); -diff --git a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java -index 532306cacd52579cdf37e4aca25887b1ed3ba6a1..55864e5f9ba2ccca0160760e90d8f77819688b8e 100644 ---- a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java -+++ b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java -@@ -35,7 +35,7 @@ public class PaperVersionFetcher implements VersionFetcher { - private static final Logger LOGGER = LogUtils.getClassLogger(); - private static final int DISTANCE_ERROR = -1; - private static final int DISTANCE_UNKNOWN = -2; -- private static final String DOWNLOAD_PAGE = "https://papermc.io/downloads/paper"; -+ private static final String DOWNLOAD_PAGE = "https://discord.gg/YevvsMa"; - - @Override - public long getCacheTime() { -@@ -49,7 +49,7 @@ public class PaperVersionFetcher implements VersionFetcher { - if (build.buildNumber().isEmpty() && build.gitCommit().isEmpty()) { - updateMessage = text("You are running a development version without access to version information", color(0xFF5300)); - } else { -- updateMessage = getUpdateStatusMessage("PaperMC/Paper", build); -+ updateMessage = getUpdateStatusMessage("InfernalSuite/AdvancedSlimePaper", build); - } - final @Nullable Component history = this.getHistory(); - -@@ -58,17 +58,18 @@ public class PaperVersionFetcher implements VersionFetcher { - - private static Component getUpdateStatusMessage(final String repo, final ServerBuildInfo build) { - int distance = DISTANCE_ERROR; -- -+ /* // AdvancedSlimePaper start - final OptionalInt buildNumber = build.buildNumber(); - if (buildNumber.isPresent()) { - distance = fetchDistanceFromSiteApi(build, buildNumber.getAsInt()); - } else { -+ */ // AdvancedSlimePaper end - final Optional gitBranch = build.gitBranch(); - final Optional gitCommit = build.gitCommit(); - if (gitBranch.isPresent() && gitCommit.isPresent()) { - distance = fetchDistanceFromGitHub(repo, gitBranch.get(), gitCommit.get()); - } -- } -+ //} // AdvancedSlimePaper - - return switch (distance) { - case DISTANCE_ERROR -> text("Error obtaining version information", NamedTextColor.YELLOW); -@@ -76,7 +77,7 @@ public class PaperVersionFetcher implements VersionFetcher { - case DISTANCE_UNKNOWN -> text("Unknown version", NamedTextColor.YELLOW); - default -> text("You are " + distance + " version(s) behind", NamedTextColor.YELLOW) - .append(Component.newline()) -- .append(text("Download the new version at: ") -+ .append(text("Download the new version from our Discord: ") - .append(text(DOWNLOAD_PAGE, NamedTextColor.GOLD) - .hoverEvent(text("Click to open", NamedTextColor.WHITE)) - .clickEvent(ClickEvent.openUrl(DOWNLOAD_PAGE)))); -diff --git a/src/main/java/com/infernalsuite/asp/Converter.java b/src/main/java/com/infernalsuite/asp/Converter.java -new file mode 100644 -index 0000000000000000000000000000000000000000..22acbf7d0f7b8ac9eb41efc05d6050d0871c90a9 ---- /dev/null -+++ b/src/main/java/com/infernalsuite/asp/Converter.java -@@ -0,0 +1,128 @@ -+package com.infernalsuite.asp; -+ -+import com.infernalsuite.asp.api.utils.NibbleArray; -+import net.kyori.adventure.nbt.BinaryTag; -+import net.kyori.adventure.nbt.ByteArrayBinaryTag; -+import net.kyori.adventure.nbt.ByteBinaryTag; -+import net.kyori.adventure.nbt.CompoundBinaryTag; -+import net.kyori.adventure.nbt.DoubleBinaryTag; -+import net.kyori.adventure.nbt.EndBinaryTag; -+import net.kyori.adventure.nbt.FloatBinaryTag; -+import net.kyori.adventure.nbt.IntArrayBinaryTag; -+import net.kyori.adventure.nbt.IntBinaryTag; -+import net.kyori.adventure.nbt.ListBinaryTag; -+import net.kyori.adventure.nbt.LongArrayBinaryTag; -+import net.kyori.adventure.nbt.LongBinaryTag; -+import net.kyori.adventure.nbt.ShortBinaryTag; -+import net.kyori.adventure.nbt.StringBinaryTag; -+import net.kyori.adventure.nbt.TagStringIO; -+import net.minecraft.nbt.ByteArrayTag; -+import net.minecraft.nbt.ByteTag; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.nbt.DoubleTag; -+import net.minecraft.nbt.EndTag; -+import net.minecraft.nbt.FloatTag; -+import net.minecraft.nbt.IntArrayTag; -+import net.minecraft.nbt.IntTag; -+import net.minecraft.nbt.ListTag; -+import net.minecraft.nbt.LongArrayTag; -+import net.minecraft.nbt.LongTag; -+import net.minecraft.nbt.ShortTag; -+import net.minecraft.nbt.StringTag; -+import net.minecraft.nbt.Tag; -+import net.minecraft.world.level.chunk.DataLayer; -+import org.apache.logging.log4j.LogManager; -+import org.apache.logging.log4j.Logger; -+ -+import java.io.IOException; -+import java.util.ArrayList; -+import java.util.List; -+import java.util.Objects; -+ -+public class Converter { -+ -+ private static final Logger LOGGER = LogManager.getLogger("ASP NBT Converter"); -+ -+ static DataLayer convertArray(NibbleArray array) { -+ return new DataLayer(array.getBacking()); -+ } -+ -+ public static NibbleArray convertArray(DataLayer array) { -+ if(array == null) { -+ return null; -+ } -+ -+ return new NibbleArray(array.getData()); -+ } -+ -+ public static Tag convertTag(T tag) { -+ try { -+ return switch (tag.type().id()) { -+ case Tag.TAG_END -> EndTag.INSTANCE; -+ case Tag.TAG_BYTE -> ByteTag.valueOf(((ByteBinaryTag) tag).value()); -+ case Tag.TAG_SHORT -> ShortTag.valueOf(((ShortBinaryTag) tag).value()); -+ case Tag.TAG_INT -> IntTag.valueOf(((IntBinaryTag) tag).value()); -+ case Tag.TAG_LONG -> LongTag.valueOf(((LongBinaryTag) tag).value()); -+ case Tag.TAG_FLOAT -> FloatTag.valueOf(((FloatBinaryTag) tag).value()); -+ case Tag.TAG_DOUBLE -> DoubleTag.valueOf(((DoubleBinaryTag) tag).value()); -+ case Tag.TAG_BYTE_ARRAY -> new ByteArrayTag(((ByteArrayBinaryTag) tag).value()); -+ case Tag.TAG_STRING -> StringTag.valueOf(((StringBinaryTag) tag).value()); -+ case Tag.TAG_LIST -> { -+ ListTag list = new ListTag(); -+ for (BinaryTag entry : ((ListBinaryTag) tag)) list.add(convertTag(entry)); -+ yield list; -+ } -+ case Tag.TAG_COMPOUND -> { -+ CompoundTag compound = new CompoundTag(); -+ ((CompoundBinaryTag) tag).forEach(entry -> compound.put(entry.getKey(), convertTag(entry.getValue()))); -+ yield compound; -+ } -+ case Tag.TAG_INT_ARRAY -> new IntArrayTag(((IntArrayBinaryTag) tag).value()); -+ case Tag.TAG_LONG_ARRAY -> new LongArrayTag(((LongArrayBinaryTag) tag).value()); -+ default -> throw new IllegalArgumentException("Invalid tag type " + tag.type().id()); -+ }; -+ } catch (final Exception e) { -+ CompoundBinaryTag exceptionTag = CompoundBinaryTag.builder().put("failing_tag", tag).build(); -+ String tagString; -+ try { -+ tagString = TagStringIO.get().asString(exceptionTag); -+ } catch (final IOException ioEx) { -+ LOGGER.error("Error while trying to convert exception tag to string", ioEx); -+ tagString = "UNAVAILABLE"; -+ } -+ LOGGER.error("Failed to convert NBT object: {}", tagString); -+ throw e; -+ } -+ } -+ -+ @SuppressWarnings("unchecked") -+ public static T convertTag(Tag base) { -+ return switch (base.getId()) { -+ case Tag.TAG_END -> (T) EndBinaryTag.endBinaryTag(); -+ case Tag.TAG_BYTE -> (T) ByteBinaryTag.byteBinaryTag(((ByteTag) base).getAsByte()); -+ case Tag.TAG_SHORT -> (T) ShortBinaryTag.shortBinaryTag(((ShortTag) base).getAsShort()); -+ case Tag.TAG_INT -> (T) IntBinaryTag.intBinaryTag(((IntTag) base).getAsInt()); -+ case Tag.TAG_LONG -> (T) LongBinaryTag.longBinaryTag(((LongTag) base).getAsLong()); -+ case Tag.TAG_FLOAT -> (T) FloatBinaryTag.floatBinaryTag(((FloatTag) base).getAsFloat()); -+ case Tag.TAG_DOUBLE -> (T) DoubleBinaryTag.doubleBinaryTag(((DoubleTag) base).getAsDouble()); -+ case Tag.TAG_BYTE_ARRAY -> (T) ByteArrayBinaryTag.byteArrayBinaryTag(((ByteArrayTag) base).getAsByteArray()); -+ case Tag.TAG_STRING -> (T) StringBinaryTag.stringBinaryTag(((StringTag) base).getAsString()); -+ case Tag.TAG_LIST -> { -+ List list = new ArrayList<>(); -+ ListTag originalList = ((ListTag) base); -+ for (Tag entry : originalList) list.add(convertTag(entry)); -+ yield (T) ListBinaryTag.listBinaryTag(list.getFirst().type(), list); -+ } -+ case Tag.TAG_COMPOUND -> { -+ CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder(); -+ CompoundTag originalCompound = ((CompoundTag) base); -+ for (String key : originalCompound.getAllKeys()) builder.put(key, convertTag(Objects.requireNonNull(originalCompound.get(key)))); -+ yield (T) builder.build(); -+ } -+ case Tag.TAG_INT_ARRAY -> (T) IntArrayBinaryTag.intArrayBinaryTag(((IntArrayTag) base).getAsIntArray()); -+ case Tag.TAG_LONG_ARRAY -> (T) LongArrayBinaryTag.longArrayBinaryTag(((LongArrayTag) base).getAsLongArray()); -+ default -> throw new IllegalArgumentException("Invalid tag type " + base.getId()); -+ }; -+ } -+ -+} -diff --git a/src/main/java/com/infernalsuite/asp/InternalPlugin.java b/src/main/java/com/infernalsuite/asp/InternalPlugin.java -new file mode 100644 -index 0000000000000000000000000000000000000000..4c7938c07e06810f475eac0bb4400c11154b56ba ---- /dev/null -+++ b/src/main/java/com/infernalsuite/asp/InternalPlugin.java -@@ -0,0 +1,28 @@ -+package com.infernalsuite.asp; -+ -+import net.minecraft.server.MinecraftServer; -+import org.bukkit.Server; -+import org.bukkit.craftbukkit.scheduler.MinecraftInternalPlugin; -+import org.bukkit.plugin.PluginLogger; -+import org.jetbrains.annotations.NotNull; -+ -+import java.util.logging.LogRecord; -+ -+public class InternalPlugin extends MinecraftInternalPlugin { -+ -+ @Override -+ public @NotNull Server getServer() { -+ return MinecraftServer.getServer().server; -+ } -+ -+ @Override -+ public @NotNull PluginLogger getLogger() { -+ return new PluginLogger(new InternalPlugin()) { -+ @Override -+ public void log(@NotNull LogRecord logRecord) { -+ MinecraftServer.LOGGER.info(logRecord.getMessage()); -+ } -+ }; -+ } -+ -+} -\ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -new file mode 100644 -index 0000000000000000000000000000000000000000..694bd135fd4398ecf02940e638fae1047e217a29 ---- /dev/null -+++ b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -@@ -0,0 +1,98 @@ -+package com.infernalsuite.asp; -+ -+import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; -+import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; -+import ca.spottedleaf.dataconverter.types.nbt.NBTMapType; -+import com.infernalsuite.asp.serialization.SlimeWorldReader; -+import com.infernalsuite.asp.skeleton.SkeletonSlimeWorld; -+import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; -+import com.infernalsuite.asp.skeleton.SlimeChunkSkeleton; -+import com.infernalsuite.asp.api.world.SlimeChunk; -+import com.infernalsuite.asp.api.world.SlimeChunkSection; -+import com.infernalsuite.asp.api.world.SlimeWorld; -+import net.kyori.adventure.nbt.CompoundBinaryTag; -+import net.minecraft.SharedConstants; -+ -+import java.util.ArrayList; -+import java.util.HashMap; -+import java.util.List; -+import java.util.function.Consumer; -+ -+class SimpleDataFixerConverter implements SlimeWorldReader { -+ -+ @Override -+ public SlimeWorld readFromData(SlimeWorld data) { -+ int newVersion = SharedConstants.getCurrentVersion().getDataVersion().getVersion(); -+ int currentVersion = data.getDataVersion(); -+ // Already fixed -+ if (currentVersion == newVersion) { -+ return data; -+ } -+ -+ Map chunks = new HashMap<>(); -+ for (SlimeChunk chunk : data.getChunkStorage()) { -+ List entities = new ArrayList<>(); -+ List blockEntities = new ArrayList<>(); -+ for (CompoundBinaryTag upgradeEntity : chunk.getTileEntities()) { -+ blockEntities.add( -+ convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.TILE_ENTITY.convert(new NBTMapType(tag), currentVersion, newVersion)) -+ ); -+ } -+ for (CompoundBinaryTag upgradeEntity : chunk.getEntities()) { -+ entities.add( -+ convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.ENTITY.convert(new NBTMapType(tag), currentVersion, newVersion)) -+ ); -+ } -+ -+ SlimeChunkSection[] sections = new SlimeChunkSection[chunk.getSections().length]; -+ for (int i = 0; i < sections.length; i++) { -+ SlimeChunkSection dataSection = chunk.getSections()[i]; -+ -+ CompoundBinaryTag blockStateTag = blockStateTag = convertAndBack(dataSection.getBlockStatesTag(), (tag) -> { -+ WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, new NBTMapType(tag), "palette", currentVersion, newVersion); -+ }); -+ -+ CompoundBinaryTag biomeTag = convertAndBack(dataSection.getBiomeTag(), (tag) -> { -+ WalkerUtils.convertList(MCTypeRegistry.BIOME, new NBTMapType(tag), "palette", currentVersion, newVersion); -+ }); -+ -+ sections[i] = new SlimeChunkSectionSkeleton( -+ blockStateTag, -+ biomeTag, -+ dataSection.getBlockLight(), -+ dataSection.getSkyLight() -+ ); -+ -+ chunks.put(new ChunkPos(chunk.getX(), chunk.getZ()), new SlimeChunkSkeleton( -+ chunk.getX(), -+ chunk.getZ(), -+ sections, -+ chunk.getHeightMaps(), -+ blockEntities, -+ entities -+ )); -+ } -+ -+ } -+ -+ return new SkeletonSlimeWorld( -+ data.getName(), -+ data.getLoader(), -+ data.isReadOnly(), -+ chunks, -+ data.getExtraData(), -+ data.getPropertyMap(), -+ newVersion -+ ); -+ } -+ -+ -+ private static CompoundBinaryTag convertAndBack(CompoundBinaryTag value, Consumer acceptor) { -+ if (value == null) return null; -+ -+ net.minecraft.nbt.CompoundTag converted = (net.minecraft.nbt.CompoundTag) Converter.convertTag(value); -+ acceptor.accept(converted); -+ -+ return Converter.convertTag(converted); -+ } -+} -diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -new file mode 100644 -index 0000000000000000000000000000000000000000..98043b30614cc0ace252919367662a5e535fa1e1 ---- /dev/null -+++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -@@ -0,0 +1,206 @@ -+package com.infernalsuite.asp; -+ -+import com.infernalsuite.asp.api.SlimeNMSBridge; -+import com.infernalsuite.asp.api.world.SlimeWorld; -+import com.infernalsuite.asp.api.world.SlimeWorldInstance; -+import com.infernalsuite.asp.api.world.properties.SlimeProperties; -+import com.infernalsuite.asp.level.SlimeBootstrap; -+import com.infernalsuite.asp.level.SlimeInMemoryWorld; -+import com.infernalsuite.asp.level.SlimeLevelInstance; -+import com.mojang.serialization.Lifecycle; -+import net.kyori.adventure.util.Services; -+import net.minecraft.SharedConstants; -+import net.minecraft.core.registries.Registries; -+import net.minecraft.resources.ResourceKey; -+import net.minecraft.resources.ResourceLocation; -+import net.minecraft.server.MinecraftServer; -+import net.minecraft.server.dedicated.DedicatedServer; -+import net.minecraft.server.dedicated.DedicatedServerProperties; -+import net.minecraft.world.level.GameRules; -+import net.minecraft.world.level.Level; -+import net.minecraft.world.level.LevelSettings; -+import net.minecraft.world.level.dimension.LevelStem; -+import net.minecraft.world.level.levelgen.WorldOptions; -+import net.minecraft.world.level.storage.CommandStorage; -+import net.minecraft.world.level.storage.DimensionDataStorage; -+import net.minecraft.world.level.storage.PrimaryLevelData; -+import org.apache.logging.log4j.LogManager; -+import org.apache.logging.log4j.Logger; -+import org.bukkit.Bukkit; -+import org.bukkit.World; -+import org.bukkit.craftbukkit.CraftWorld; -+import org.jetbrains.annotations.Nullable; -+ -+import java.io.IOException; -+import java.util.Locale; -+ -+public class SlimeNMSBridgeImpl implements SlimeNMSBridge { -+ -+ private static final SimpleDataFixerConverter DATA_FIXER_CONVERTER = new SimpleDataFixerConverter(); -+ -+ private static final Logger LOGGER = LogManager.getLogger("ASP"); -+ -+ private SlimeWorld defaultWorld; -+ private SlimeWorld defaultNetherWorld; -+ private SlimeWorld defaultEndWorld; -+ -+ public static SlimeNMSBridgeImpl instance() { -+ return (SlimeNMSBridgeImpl) SlimeNMSBridge.instance(); -+ } -+ -+ @Override -+ public boolean loadOverworldOverride() { -+ if (defaultWorld == null) { -+ return false; -+ } -+ -+ // See MinecraftServer loading logic -+ // Some stuff is needed when loading overworld world -+ SlimeLevelInstance instance = ((SlimeInMemoryWorld) this.loadInstance(defaultWorld, Level.OVERWORLD)).getInstance(); -+ DimensionDataStorage worldpersistentdata = instance.getDataStorage(); -+ instance.getCraftServer().scoreboardManager = new org.bukkit.craftbukkit.scoreboard.CraftScoreboardManager(instance.getServer(), instance.getScoreboard()); -+ instance.getServer().commandStorage = new CommandStorage(worldpersistentdata); -+ -+ return true; -+ } -+ -+ @Override -+ public boolean loadNetherOverride() { -+ if (defaultNetherWorld == null) { -+ return false; -+ } -+ -+ this.loadInstance(defaultNetherWorld, Level.NETHER); -+ -+ return true; -+ } -+ -+ @Override -+ public boolean loadEndOverride() { -+ if (defaultEndWorld == null) { -+ return false; -+ } -+ -+ this.loadInstance(defaultEndWorld, Level.END); -+ -+ return true; -+ } -+ -+ @Override -+ public void setDefaultWorlds(SlimeWorld normalWorld, SlimeWorld netherWorld, SlimeWorld endWorld) { -+ if (normalWorld != null) { -+ normalWorld.getPropertyMap().setValue(SlimeProperties.ENVIRONMENT, World.Environment.NORMAL.toString().toLowerCase()); -+ defaultWorld = normalWorld; -+ } -+ -+ if (netherWorld != null) { -+ netherWorld.getPropertyMap().setValue(SlimeProperties.ENVIRONMENT, World.Environment.NETHER.toString().toLowerCase()); -+ defaultNetherWorld = netherWorld; -+ } -+ -+ if (endWorld != null) { -+ endWorld.getPropertyMap().setValue(SlimeProperties.ENVIRONMENT, World.Environment.THE_END.toString().toLowerCase()); -+ defaultEndWorld = endWorld; -+ } -+ -+ } -+ -+ @Override -+ public SlimeWorldInstance loadInstance(SlimeWorld slimeWorld) { -+ return this.loadInstance(slimeWorld, null); -+ } -+ -+ public SlimeWorldInstance loadInstance(SlimeWorld slimeWorld, @Nullable ResourceKey dimensionOverride) { -+ String worldName = slimeWorld.getName(); -+ -+ if (Bukkit.getWorld(worldName) != null) { -+ throw new IllegalArgumentException("World " + worldName + " already exists! Maybe it's an outdated SlimeWorld object?"); -+ } -+ -+ SlimeLevelInstance server = createCustomWorld(slimeWorld, dimensionOverride); -+ registerWorld(server); -+ return server.getSlimeInstance(); -+ } -+ -+ @Override -+ public SlimeWorldInstance getInstance(World world) { -+ CraftWorld craftWorld = (CraftWorld) world; -+ -+ if (!(craftWorld.getHandle() instanceof SlimeLevelInstance worldServer)) { -+ return null; -+ } -+ -+ return worldServer.getSlimeInstance(); -+ } -+ -+ @Override -+ public SlimeWorld applyDataFixers(SlimeWorld world) { -+ return DATA_FIXER_CONVERTER.readFromData(world); -+ } -+ -+ -+ @Override -+ public int getCurrentVersion() { -+ return SharedConstants.getCurrentVersion().getDataVersion().getVersion(); -+ } -+ -+ public void registerWorld(SlimeLevelInstance server) { -+ MinecraftServer mcServer = MinecraftServer.getServer(); -+ mcServer.initWorld(server, server.serverLevelData, mcServer.getWorldData(), server.serverLevelData.worldGenOptions()); -+ -+ mcServer.addLevel(server); -+ } -+ -+ private SlimeLevelInstance createCustomWorld(SlimeWorld world, @Nullable ResourceKey dimensionOverride) { -+ SlimeBootstrap bootstrap = new SlimeBootstrap(world); -+ String worldName = world.getName(); -+ -+ PrimaryLevelData worldDataServer = createWorldData(world); -+ World.Environment environment = getEnvironment(world); -+ ResourceKey dimension = switch (environment) { -+ case NORMAL -> LevelStem.OVERWORLD; -+ case NETHER -> LevelStem.NETHER; -+ case THE_END -> LevelStem.END; -+ default -> throw new IllegalArgumentException("Unknown dimension supplied"); -+ }; -+ -+ ResourceKey worldKey = dimensionOverride == null ? ResourceKey.create(Registries.DIMENSION, new ResourceLocation(worldName.toLowerCase(Locale.ENGLISH))) : dimensionOverride; -+ LevelStem stem = MinecraftServer.getServer().registries().compositeAccess().registryOrThrow(Registries.LEVEL_STEM).get(dimension); -+ -+ SlimeLevelInstance level; -+ -+ try { -+ level = new SlimeLevelInstance(bootstrap, worldDataServer, worldKey, dimension, stem, environment); -+ } catch (IOException ex) { -+ throw new RuntimeException(ex); // TODO do something better with this? -+ } -+ -+ // level.setReady(true); -+ level.setSpawnSettings(world.getPropertyMap().getValue(SlimeProperties.ALLOW_MONSTERS), world.getPropertyMap().getValue(SlimeProperties.ALLOW_ANIMALS)); -+ -+ return level; -+ } -+ -+ private World.Environment getEnvironment(SlimeWorld world) { -+ return World.Environment.valueOf(world.getPropertyMap().getValue(SlimeProperties.ENVIRONMENT).toUpperCase()); -+ } -+ -+ private PrimaryLevelData createWorldData(SlimeWorld world) { -+ MinecraftServer mcServer = MinecraftServer.getServer(); -+ DedicatedServerProperties serverProps = ((DedicatedServer) mcServer).getProperties(); -+ String worldName = world.getName(); -+ -+ LevelSettings worldsettings = new LevelSettings(worldName, serverProps.gamemode, false, serverProps.difficulty, -+ true, new GameRules(), mcServer.worldLoader.dataConfiguration()); -+ -+ WorldOptions worldoptions = new WorldOptions(0, false, false); -+ -+ PrimaryLevelData data = new PrimaryLevelData(worldsettings, worldoptions, PrimaryLevelData.SpecialWorldProperty.FLAT, Lifecycle.stable()); -+ data.checkName(worldName); -+ data.setModdedInfo(mcServer.getServerModName(), mcServer.getModdedStatus().shouldReportAsModified()); -+ data.setInitialized(true); -+ -+ return data; -+ } -+ -+} -\ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java -new file mode 100644 -index 0000000000000000000000000000000000000000..bb954b74739e22525f9a45648d3ecf54f5a9e61c ---- /dev/null -+++ b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java -@@ -0,0 +1,121 @@ -+package com.infernalsuite.asp.level; -+ -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import com.infernalsuite.asp.api.world.SlimeChunk; -+import com.mojang.logging.LogUtils; -+import io.papermc.paper.chunk.system.poi.PoiChunk; -+import io.papermc.paper.chunk.system.scheduling.ChunkLoadTask; -+import io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler; -+import io.papermc.paper.chunk.system.scheduling.GenericDataLoadTask; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.block.Block; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.ImposterProtoChunk; -+import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.chunk.UpgradeData; -+import net.minecraft.world.level.material.Fluid; -+import net.minecraft.world.ticks.LevelChunkTicks; -+import org.slf4j.Logger; -+ -+import java.util.function.Consumer; -+ -+public final class ChunkDataLoadTask implements CommonLoadTask { -+ -+ private static final Logger LOGGER = LogUtils.getClassLogger(); -+ -+ private final ChunkTaskScheduler scheduler; -+ private final ServerLevel world; -+ private final int chunkX; -+ private final int chunkZ; -+ private Consumer> onRun; -+ -+ private PrioritisedExecutor.PrioritisedTask task; -+ -+ private final ChunkLoadTask chunkLoadTask; -+ -+ protected ChunkDataLoadTask(ChunkLoadTask chunkLoadTask, final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, -+ final int chunkZ, final PrioritisedExecutor.Priority priority, final Consumer> onRun) { -+ this.chunkLoadTask = chunkLoadTask; -+ this.scheduler = scheduler; -+ this.world = world; -+ this.chunkX = chunkX; -+ this.chunkZ = chunkZ; -+ this.onRun = onRun; -+ -+ this.task = this.scheduler.createChunkTask(this.chunkX, this.chunkZ, () -> { -+ try { -+ SlimeChunk chunk = ((SlimeLevelInstance) this.world).slimeInstance.getChunk(this.chunkX, this.chunkZ); -+ this.onRun.accept(new GenericDataLoadTask.TaskResult<>(runOnMain(chunk), null)); -+ } catch (Throwable e) { -+ LOGGER.error("ERROR", e); -+ this.onRun.accept(new GenericDataLoadTask.TaskResult<>(null, e)); -+ } -+ }, priority); -+ } -+ -+ private ChunkAccess getEmptyChunk() { -+ LevelChunkTicks blockLevelChunkTicks = new LevelChunkTicks<>(); -+ LevelChunkTicks fluidLevelChunkTicks = new LevelChunkTicks<>(); -+ -+ return new ImposterProtoChunk(new LevelChunk(this.world, new ChunkPos(this.chunkX, this.chunkZ), UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks, -+ 0L, null, null, null), true); -+ } -+ -+ protected ChunkAccess runOnMain(final SlimeChunk data) { -+ final PoiChunk poiChunk = this.chunkLoadTask.chunkHolder.getPoiChunk(); -+ if (poiChunk == null) { -+ LOGGER.error("Expected poi chunk to be loaded with chunk for task " + this.toString()); -+ } else { -+ poiChunk.load(); -+ } -+ -+ // have tasks to run (at this point, it's just the POI consistency checking) -+ try { -+ // if (data.tasks != null) { -+ // for (int i = 0, len = data.tasks.size(); i < len; i) { -+ // data.tasks.poll().run(); -+ // } -+ // } -+ -+ LevelChunk chunk = this.world.slimeInstance.promote(chunkX, chunkZ, data); -+ -+ return new ImposterProtoChunk(chunk, false); -+ } catch (final ThreadDeath death) { -+ throw death; -+ } catch (final Throwable thr2) { -+ LOGGER.error("Failed to parse main tasks for task " + this.toString() + ", chunk data will be lost", thr2); -+ return this.getEmptyChunk(); -+ } -+ } -+ -+ @Override -+ public PrioritisedExecutor.Priority getPriority() { -+ return this.task.getPriority(); -+ } -+ -+ @Override -+ public void setPriority(PrioritisedExecutor.Priority priority) { -+ this.task.setPriority(priority); -+ } -+ -+ @Override -+ public void raisePriority(PrioritisedExecutor.Priority priority) { -+ this.task.raisePriority(priority); -+ } -+ -+ @Override -+ public void lowerPriority(PrioritisedExecutor.Priority priority) { -+ this.task.lowerPriority(priority); -+ } -+ -+ @Override -+ public boolean cancel() { -+ return this.task.cancel(); -+ } -+ -+ public boolean schedule(boolean schedule) { -+ this.scheduler.scheduleChunkTask(chunkX, chunkZ, this.task::execute); -+ return true; -+ } -+} -\ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java b/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java -new file mode 100644 -index 0000000000000000000000000000000000000000..9954db3eabd60ac0600af1efc6f8a1650ef4d85b ---- /dev/null -+++ b/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java -@@ -0,0 +1,18 @@ -+package com.infernalsuite.asp.level; -+ -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+ -+public interface CommonLoadTask { -+ -+ boolean schedule(boolean schedule); -+ -+ PrioritisedExecutor.Priority getPriority(); -+ -+ boolean cancel(); -+ -+ void lowerPriority(PrioritisedExecutor.Priority priority); -+ -+ void raisePriority(PrioritisedExecutor.Priority priority); -+ -+ void setPriority(PrioritisedExecutor.Priority priority); -+} -\ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java b/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java -new file mode 100644 -index 0000000000000000000000000000000000000000..10bfcb7250c01c8361375c4d9b34d2b0ae17257d ---- /dev/null -+++ b/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java -@@ -0,0 +1,59 @@ -+package com.infernalsuite.asp.level; -+ -+import com.infernalsuite.asp.api.world.SlimeWorld; -+import com.infernalsuite.asp.api.world.properties.SlimeProperties; -+import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; -+import io.papermc.paper.world.ChunkEntitySlices; -+import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.chunk.LevelChunkSection; -+ -+public class FastChunkPruner { -+ -+ public static boolean canBePruned(SlimeWorld world, LevelChunk chunk) { -+ // Kenox -+ // It's not safe to assume that the chunk can be pruned -+ // if there isn't a loaded chunk there -+ if (chunk == null || chunk.getChunkHolder() == null) { -+ return false; -+ } -+ -+ SlimePropertyMap propertyMap = world.getPropertyMap(); -+ if (propertyMap.getValue(SlimeProperties.SHOULD_LIMIT_SAVE)) { -+ int minX = propertyMap.getValue(SlimeProperties.SAVE_MIN_X); -+ int maxX = propertyMap.getValue(SlimeProperties.SAVE_MAX_X); -+ -+ int minZ = propertyMap.getValue(SlimeProperties.SAVE_MIN_Z); -+ int maxZ = propertyMap.getValue(SlimeProperties.SAVE_MAX_Z); -+ -+ int chunkX = chunk.locX; -+ int chunkZ = chunk.locZ; -+ -+ if (chunkX < minX || chunkX > maxX) { -+ return true; -+ } -+ -+ if (chunkZ < minZ || chunkZ > maxZ) { -+ return true; -+ } -+ } -+ -+ String pruningSetting = world.getPropertyMap().getValue(SlimeProperties.CHUNK_PRUNING); -+ if (pruningSetting.equals("aggressive")) { -+ ChunkEntitySlices slices = chunk.getChunkHolder().getEntityChunk(); -+ -+ return chunk.blockEntities.isEmpty() && (slices == null || slices.isEmpty()) && areSectionsEmpty(chunk); -+ } -+ -+ return false; -+ } -+ -+ private static boolean areSectionsEmpty(LevelChunk chunk) { -+ for (LevelChunkSection section : chunk.getSections()) { -+ if (!section.hasOnlyAir()) { -+ return false; -+ } -+ } -+ -+ return true; -+ } -+} -\ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -new file mode 100644 -index 0000000000000000000000000000000000000000..beb56b2495a52e1fac815de664677d73ce2bbcc3 ---- /dev/null -+++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -@@ -0,0 +1,187 @@ -+package com.infernalsuite.asp.level; -+ -+import com.google.common.collect.Lists; -+import com.infernalsuite.asp.Converter; -+import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; -+import com.infernalsuite.asp.api.utils.NibbleArray; -+import com.infernalsuite.asp.api.world.SlimeChunk; -+import com.infernalsuite.asp.api.world.SlimeChunkSection; -+import com.mojang.logging.LogUtils; -+import com.mojang.serialization.Codec; -+import io.papermc.paper.world.ChunkEntitySlices; -+import net.kyori.adventure.nbt.CompoundBinaryTag; -+import net.kyori.adventure.nbt.LongArrayBinaryTag; -+import net.minecraft.core.Holder; -+import net.minecraft.core.Registry; -+import net.minecraft.core.SectionPos; -+import net.minecraft.core.registries.Registries; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.nbt.NbtOps; -+import net.minecraft.nbt.Tag; -+import net.minecraft.world.entity.Entity; -+import net.minecraft.world.level.LightLayer; -+import net.minecraft.world.level.biome.Biome; -+import net.minecraft.world.level.biome.Biomes; -+import net.minecraft.world.level.block.Block; -+import net.minecraft.world.level.block.Blocks; -+import net.minecraft.world.level.block.entity.BlockEntity; -+import net.minecraft.world.level.block.state.BlockState; -+import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.chunk.LevelChunkSection; -+import net.minecraft.world.level.chunk.PalettedContainer; -+import net.minecraft.world.level.chunk.PalettedContainerRO; -+import net.minecraft.world.level.chunk.storage.ChunkSerializer; -+import net.minecraft.world.level.levelgen.Heightmap; -+import net.minecraft.world.level.lighting.LevelLightEngine; -+import org.slf4j.Logger; -+ -+import java.util.ArrayList; -+import java.util.List; -+import java.util.Map; -+ -+public class NMSSlimeChunk implements SlimeChunk { -+ private static final Logger LOGGER = LogUtils.getClassLogger(); -+ -+ private static final CompoundBinaryTag EMPTY_BLOCK_STATE_PALETTE; -+ private static final CompoundBinaryTag EMPTY_BIOME_PALETTE; -+ -+ // Optimized empty section serialization -+ static { -+ { -+ PalettedContainer empty = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, null); -+ Tag tag = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, empty).getOrThrow(false, (error) -> { -+ throw new AssertionError(error); -+ }); -+ -+ EMPTY_BLOCK_STATE_PALETTE = Converter.convertTag(tag); -+ } -+ { -+ Registry biomes = net.minecraft.server.MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME); -+ PalettedContainer> empty = new PalettedContainer<>(biomes.asHolderIdMap(), biomes.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); -+ Tag tag = ChunkSerializer.makeBiomeCodec(biomes).encodeStart(NbtOps.INSTANCE, empty).getOrThrow(false, (error) -> { -+ throw new AssertionError(error); -+ }); -+ -+ EMPTY_BIOME_PALETTE = Converter.convertTag(tag); -+ } -+ } -+ -+ private LevelChunk chunk; -+ -+ public NMSSlimeChunk(LevelChunk chunk) { -+ this.chunk = chunk; -+ } -+ -+ @Override -+ public int getX() { -+ return chunk.getPos().x; -+ } -+ -+ @Override -+ public int getZ() { -+ return chunk.getPos().z; -+ } -+ -+ @Override -+ public SlimeChunkSection[] getSections() { -+ SlimeChunkSection[] sections = new SlimeChunkSection[this.chunk.getSectionsCount()]; -+ LevelLightEngine lightEngine = chunk.getLevel().getChunkSource().getLightEngine(); -+ -+ Registry biomeRegistry = chunk.getLevel().registryAccess().registryOrThrow(Registries.BIOME); -+ -+ // Ignore deprecation, spigot only method -+ Codec>> codec = PalettedContainer.codecRO(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getHolderOrThrow(Biomes.PLAINS)); -+ -+ for (int sectionId = 0; sectionId < chunk.getSections().length; sectionId++) { -+ LevelChunkSection section = chunk.getSections()[sectionId]; -+ // Sections CANNOT be null in 1.18 -+ -+ // Block Light Nibble Array -+ NibbleArray blockLightArray = Converter.convertArray(lightEngine.getLayerListener(LightLayer.BLOCK).getDataLayerData(SectionPos.of(chunk.getPos(), sectionId))); -+ -+ // Sky light Nibble Array -+ NibbleArray skyLightArray = Converter.convertArray(lightEngine.getLayerListener(LightLayer.SKY).getDataLayerData(SectionPos.of(chunk.getPos(), sectionId))); -+ -+ // Tile/Entity Data -+ -+ // Block Data -+ CompoundBinaryTag blockStateTag; -+ if (section.hasOnlyAir()) { -+ blockStateTag = EMPTY_BLOCK_STATE_PALETTE; -+ } else { -+ Tag data = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, section.getStates()).getOrThrow(false, System.err::println); // todo error handling -+ blockStateTag = Converter.convertTag(data); -+ } -+ -+ -+ CompoundBinaryTag biomeTag; -+ PalettedContainer> biomes = (PalettedContainer>) section.getBiomes(); -+ if (biomes.data.palette().getSize() == 1 && biomes.data.palette().maybeHas((h) -> h.is(Biomes.PLAINS))) { -+ biomeTag = EMPTY_BIOME_PALETTE; -+ } else { -+ Tag biomeData = codec.encodeStart(NbtOps.INSTANCE, section.getBiomes()).getOrThrow(false, System.err::println); // todo error handling -+ biomeTag = Converter.convertTag(biomeData); -+ } -+ -+ sections[sectionId] = new SlimeChunkSectionSkeleton(blockStateTag, biomeTag, blockLightArray, skyLightArray); -+ } -+ -+ return sections; -+ } -+ -+ @Override -+ public CompoundBinaryTag getHeightMaps() { -+ CompoundBinaryTag.Builder heightMapsTagBuilder = CompoundBinaryTag.builder(); -+ -+ this.chunk.heightmaps.forEach((type, map) -> { -+ if (type.keepAfterWorldgen()) { -+ heightMapsTagBuilder.put(type.name(), LongArrayBinaryTag.longArrayBinaryTag(map.getRawData())); -+ } -+ }); -+ -+ return heightMapsTagBuilder.build(); -+ } -+ -+ @Override -+ public List getTileEntities() { -+ List tileEntities = new ArrayList<>(); -+ -+ for (BlockEntity entity : this.chunk.blockEntities.values()) { -+ CompoundTag entityNbt = entity.saveWithFullMetadata(); -+ tileEntities.add(entityNbt); -+ } -+ -+ return Lists.transform(tileEntities, Converter::convertTag); -+ } -+ -+ @Override -+ public List getEntities() { -+ List entities = new ArrayList<>(); -+ -+ if (this.chunk == null || this.chunk.getChunkHolder() == null) return new ArrayList<>(); -+ -+ ChunkEntitySlices slices = this.chunk.getChunkHolder().getEntityChunk(); -+ if (slices == null) return new ArrayList<>(); -+ -+ // Work by -+ for (Entity entity : slices.entities) { -+ CompoundTag entityNbt = new CompoundTag(); -+ try { -+ if (entity.save(entityNbt)) entities.add(entityNbt); -+ } catch (final Exception e) { -+ LOGGER.error("Could not save the entity = {}, exception = {}", entity, e); -+ } -+ } -+ -+ return Lists.transform(entities, Converter::convertTag); -+ } -+ -+ public LevelChunk getChunk() { -+ return chunk; -+ } -+ -+ public void setChunk(LevelChunk chunk) { -+ this.chunk = chunk; -+ } -+ -+} -\ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java -new file mode 100644 -index 0000000000000000000000000000000000000000..41119f2b0d208718c294076dc3c51f55680b0257 ---- /dev/null -+++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java -@@ -0,0 +1,93 @@ -+package com.infernalsuite.asp.level; -+ -+import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; -+import com.infernalsuite.asp.api.loaders.SlimeLoader; -+import com.infernalsuite.asp.api.world.SlimeChunk; -+import com.infernalsuite.asp.api.world.SlimeWorld; -+import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; -+import net.kyori.adventure.nbt.BinaryTag; -+import net.kyori.adventure.nbt.CompoundBinaryTag; -+import net.minecraft.SharedConstants; -+import net.minecraft.server.level.ChunkHolder; -+import net.minecraft.world.level.chunk.LevelChunk; -+ -+import java.io.IOException; -+import java.util.Collection; -+import java.util.List; -+import java.util.Objects; -+import java.util.concurrent.ConcurrentMap; -+import java.util.stream.Collectors; -+ -+public class NMSSlimeWorld implements SlimeWorld { -+ -+ private final SlimeInMemoryWorld memoryWorld; -+ private final SlimeLevelInstance instance; -+ -+ public NMSSlimeWorld(SlimeInMemoryWorld memoryWorld) { -+ this.instance = memoryWorld.getInstance(); -+ this.memoryWorld = memoryWorld; -+ } -+ -+ @Override -+ public String getName() { -+ return this.instance.getMinecraftWorld().serverLevelData.getLevelName(); -+ } -+ -+ @Override -+ public SlimeLoader getLoader() { -+ return this.instance.slimeInstance.getSaveStrategy(); -+ } -+ -+ @Override -+ public SlimeChunk getChunk(int x, int z) { -+ LevelChunk chunk = this.instance.getChunkIfLoaded(x, z); -+ if (chunk == null) { -+ return null; -+ } -+ -+ return new NMSSlimeChunk(chunk); -+ } -+ -+ @Override -+ public Collection getChunkStorage() { -+ List chunks = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.instance); // Paper -+ return chunks.stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull) -+ .map(NMSSlimeChunk::new) -+ .collect(Collectors.toList()); -+ } -+ -+ @Override -+ public ConcurrentMap getExtraData() { -+ return this.instance.slimeInstance.getExtraData(); -+ } -+ -+ @Override -+ public Collection getWorldMaps() { -+ return List.of(); -+ } -+ -+ @Override -+ public SlimePropertyMap getPropertyMap() { -+ return this.instance.slimeInstance.getPropertyMap(); -+ } -+ -+ @Override -+ public boolean isReadOnly() { -+ return this.getLoader() == null; -+ } -+ -+ @Override -+ public SlimeWorld clone(String worldName) { -+ return this.memoryWorld.clone(worldName); -+ } -+ -+ @Override -+ public SlimeWorld clone(String worldName, SlimeLoader loader) throws WorldAlreadyExistsException, IOException { -+ return this.memoryWorld.clone(worldName, loader); -+ } -+ -+ @Override -+ public int getDataVersion() { -+ return SharedConstants.getCurrentVersion().getDataVersion().getVersion(); -+ } -+} -\ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java b/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java -new file mode 100644 -index 0000000000000000000000000000000000000000..fa8254ca4b2eafa4e5669c3e0467ed1f7d4dc159 ---- /dev/null -+++ b/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java -@@ -0,0 +1,83 @@ -+package com.infernalsuite.asp.level; -+ -+import com.infernalsuite.asp.api.world.SlimeChunk; -+import com.infernalsuite.asp.api.world.SlimeChunkSection; -+import net.kyori.adventure.nbt.CompoundBinaryTag; -+ -+import java.util.List; -+ -+public class SafeNmsChunkWrapper implements SlimeChunk { -+ -+ private final NMSSlimeChunk wrapper; -+ private final SlimeChunk safety; -+ -+ public SafeNmsChunkWrapper(NMSSlimeChunk wrapper, SlimeChunk safety) { -+ this.wrapper = wrapper; -+ this.safety = safety; -+ } -+ -+ @Override -+ public int getX() { -+ return this.wrapper.getX(); -+ } -+ -+ @Override -+ public int getZ() { -+ return this.wrapper.getZ(); -+ } -+ -+ @Override -+ public SlimeChunkSection[] getSections() { -+ if (shouldDefaultBackToSlimeChunk()) { -+ return this.safety.getSections(); -+ } -+ -+ return this.wrapper.getSections(); -+ } -+ -+ @Override -+ public CompoundBinaryTag getHeightMaps() { -+ if (shouldDefaultBackToSlimeChunk()) { -+ return this.safety.getHeightMaps(); -+ } -+ -+ return this.wrapper.getHeightMaps(); -+ } -+ -+ @Override -+ public List getTileEntities() { -+ if (shouldDefaultBackToSlimeChunk()) { -+ return this.safety.getTileEntities(); -+ } -+ -+ return this.wrapper.getTileEntities(); -+ } -+ -+ @Override -+ public List getEntities() { -+ if (shouldDefaultBackToSlimeChunk()) { -+ return this.safety.getEntities(); -+ } -+ -+ return this.wrapper.getEntities(); -+ } -+ -+ /* -+Slime chunks can still be requested but not actually loaded, this caused -+some things to not properly save because they are not "loaded" into the chunk. -+See ChunkMap#protoChunkToFullChunk -+anything in the if statement will not be loaded and is stuck inside the runnable. -+Inorder to possibly not corrupt the state, simply refer back to the slime saved object. -+*/ -+ public boolean shouldDefaultBackToSlimeChunk() { -+ return this.safety != null && !this.wrapper.getChunk().loaded; -+ } -+ -+ public NMSSlimeChunk getWrapper() { -+ return wrapper; -+ } -+ -+ public SlimeChunk getSafety() { -+ return safety; -+ } -+} -\ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeBootstrap.java b/src/main/java/com/infernalsuite/asp/level/SlimeBootstrap.java -new file mode 100644 -index 0000000000000000000000000000000000000000..b1dde643ae719fa539c6986e86e12aecdd86957f ---- /dev/null -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeBootstrap.java -@@ -0,0 +1,8 @@ -+package com.infernalsuite.asp.level; -+ -+import com.infernalsuite.asp.api.world.SlimeWorld; -+ -+public record SlimeBootstrap( -+ SlimeWorld initial -+) { -+} -\ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -new file mode 100644 -index 0000000000000000000000000000000000000000..b0d45837e918ef720b49a3f4968d7781ecf6436d ---- /dev/null -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -@@ -0,0 +1,161 @@ -+package com.infernalsuite.asp.level; -+ -+import ca.spottedleaf.starlight.common.light.SWMRNibbleArray; -+import com.infernalsuite.asp.Converter; -+import com.infernalsuite.asp.api.utils.NibbleArray; -+import com.infernalsuite.asp.api.world.SlimeChunk; -+import com.infernalsuite.asp.api.world.SlimeChunkSection; -+import com.mojang.serialization.Codec; -+import com.mojang.serialization.DataResult; -+import net.kyori.adventure.nbt.CompoundBinaryTag; -+import net.minecraft.core.BlockPos; -+import net.minecraft.core.Holder; -+import net.minecraft.core.Registry; -+import net.minecraft.core.registries.Registries; -+import net.minecraft.nbt.NbtOps; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.biome.Biome; -+import net.minecraft.world.level.biome.Biomes; -+import net.minecraft.world.level.block.Block; -+import net.minecraft.world.level.block.Blocks; -+import net.minecraft.world.level.block.entity.BlockEntity; -+import net.minecraft.world.level.block.state.BlockState; -+import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.chunk.LevelChunkSection; -+import net.minecraft.world.level.chunk.PalettedContainer; -+import net.minecraft.world.level.chunk.UpgradeData; -+import net.minecraft.world.level.chunk.storage.ChunkSerializer; -+import net.minecraft.world.level.levelgen.Heightmap; -+import net.minecraft.world.level.material.Fluid; -+import net.minecraft.world.ticks.LevelChunkTicks; -+ -+import java.util.EnumSet; -+import java.util.List; -+import java.util.Optional; -+ -+public class SlimeChunkConverter { -+ -+ static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeChunk chunk) { -+ int x = chunk.getX(); -+ int z = chunk.getZ(); -+ -+ ChunkPos pos = new ChunkPos(x, z); -+ -+ // Chunk sections -+ LevelChunkSection[] sections = new LevelChunkSection[instance.getSectionsCount()]; -+ -+ SWMRNibbleArray[] blockNibbles = ca.spottedleaf.starlight.common.light.StarLightEngine.getFilledEmptyLight(instance); -+ SWMRNibbleArray[] skyNibbles = ca.spottedleaf.starlight.common.light.StarLightEngine.getFilledEmptyLight(instance); -+ instance.getServer().scheduleOnMain(() -> { -+ instance.getLightEngine().retainData(pos, true); -+ }); -+ -+ Registry biomeRegistry = instance.registryAccess().registryOrThrow(Registries.BIOME); -+ // Ignore deprecated method -+ -+ Codec>> codec = PalettedContainer.codecRW(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getHolderOrThrow(Biomes.PLAINS), null); -+ -+ for (int sectionId = 0; sectionId < chunk.getSections().length; sectionId++) { -+ SlimeChunkSection slimeSection = chunk.getSections()[sectionId]; -+ -+ if (slimeSection != null) { -+ NibbleArray blockLight = slimeSection.getBlockLight(); -+ if (blockLight != null) { -+ blockNibbles[sectionId] = new SWMRNibbleArray(blockLight.getBacking()); -+ } -+ -+ NibbleArray skyLight = slimeSection.getSkyLight(); -+ if (skyLight != null) { -+ skyNibbles[sectionId] = new SWMRNibbleArray(skyLight.getBacking()); -+ } -+ -+ PalettedContainer blockPalette; -+ if (slimeSection.getBlockStatesTag() != null) { -+ DataResult> dataresult = ChunkSerializer.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, Converter.convertTag(slimeSection.getBlockStatesTag())).promotePartial((s) -> { -+ System.out.println("Recoverable error when parsing section " + x + "," + z + ": " + s); // todo proper logging -+ }); -+ blockPalette = dataresult.getOrThrow(false, System.err::println); // todo proper logging -+ } else { -+ blockPalette = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, null); -+ } -+ -+ PalettedContainer> biomePalette; -+ -+ if (slimeSection.getBiomeTag() != null) { -+ DataResult>> dataresult = codec.parse(NbtOps.INSTANCE, Converter.convertTag(slimeSection.getBiomeTag())).promotePartial((s) -> { -+ System.out.println("Recoverable error when parsing section " + x + "," + z + ": " + s); // todo proper logging -+ }); -+ biomePalette = dataresult.getOrThrow(false, System.err::println); // todo proper logging -+ } else { -+ biomePalette = new PalettedContainer<>(biomeRegistry.asHolderIdMap(), biomeRegistry.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); -+ } -+ -+ if (sectionId < sections.length) { -+ LevelChunkSection section = new LevelChunkSection(blockPalette, biomePalette); -+ sections[sectionId] = section; -+ } -+ } -+ } -+ -+ // Keep the chunk loaded at level 33 to avoid light glitches -+ // Such a high level will let the server not tick the chunk, -+ // but at the same time it won't be completely unloaded from memory -+ // getChunkProvider().addTicket(SWM_TICKET, pos, 33, Unit.INSTANCE); -+ -+ -+ LevelChunk.PostLoadProcessor loadEntities = (nmsChunk) -> { -+ -+ // TODO -+ // Load tile entities -+ List tileEntities = chunk.getTileEntities(); -+ -+ if (tileEntities != null) { -+ for (CompoundBinaryTag tag : tileEntities) { -+ String type = tag.getString("id"); -+ -+ if (!type.isEmpty()) { -+ BlockPos blockPosition = new BlockPos(tag.getInt("x"), tag.getInt("y"), tag.getInt("z")); -+ BlockState blockData = nmsChunk.getBlockState(blockPosition); -+ BlockEntity entity = BlockEntity.loadStatic(blockPosition, blockData, (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)); -+ -+ if (entity != null) { -+ nmsChunk.setBlockEntity(entity); -+ } -+ } -+ } -+ } -+ }; -+ -+ LevelChunkTicks blockLevelChunkTicks = new LevelChunkTicks<>(); -+ LevelChunkTicks fluidLevelChunkTicks = new LevelChunkTicks<>(); -+ SlimeChunkLevel nmsChunk = new SlimeChunkLevel(instance, pos, UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks, 0L, sections, loadEntities, null); -+ -+ // Height Maps -+ EnumSet heightMapTypes = nmsChunk.getStatus().heightmapsAfter(); -+ CompoundBinaryTag heightMaps = chunk.getHeightMaps(); -+ EnumSet unsetHeightMaps = EnumSet.noneOf(Heightmap.Types.class); -+ -+ // Light -+ nmsChunk.setBlockNibbles(blockNibbles); -+ nmsChunk.setSkyNibbles(skyNibbles); -+ -+ for (Heightmap.Types type : heightMapTypes) { -+ String name = type.getSerializedName(); -+ -+ long[] heightMap = heightMaps.getLongArray(name); -+ if (heightMap.length > 0) { -+ nmsChunk.setHeightmap(type, heightMap); -+ } else { -+ unsetHeightMaps.add(type); -+ } -+ } -+ -+ // Don't try to populate heightmaps if there are none. -+ // Does a crazy amount of block lookups -+ if (!unsetHeightMaps.isEmpty()) { -+ Heightmap.primeHeightmaps(nmsChunk, unsetHeightMaps); -+ } -+ -+ return nmsChunk; -+ } -+} -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java -new file mode 100644 -index 0000000000000000000000000000000000000000..0d218911fb8be1bc5272b6e291ec60404306c831 ---- /dev/null -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java -@@ -0,0 +1,27 @@ -+package com.infernalsuite.asp.level; -+ -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.block.Block; -+import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.chunk.LevelChunkSection; -+import net.minecraft.world.level.chunk.UpgradeData; -+import net.minecraft.world.level.levelgen.blending.BlendingData; -+import net.minecraft.world.level.material.Fluid; -+import net.minecraft.world.ticks.LevelChunkTicks; -+import org.jetbrains.annotations.Nullable; -+ -+public class SlimeChunkLevel extends LevelChunk { -+ -+ private final SlimeInMemoryWorld inMemoryWorld; -+ -+ public SlimeChunkLevel(SlimeLevelInstance world, ChunkPos pos, UpgradeData upgradeData, LevelChunkTicks blockTickScheduler, LevelChunkTicks fluidTickScheduler, long inhabitedTime, @Nullable LevelChunkSection[] sectionArrayInitializer, @Nullable LevelChunk.PostLoadProcessor entityLoader, @Nullable BlendingData blendingData) { -+ super(world, pos, upgradeData, blockTickScheduler, fluidTickScheduler, inhabitedTime, sectionArrayInitializer, entityLoader, blendingData); -+ this.inMemoryWorld = world.slimeInstance; -+ } -+ -+ @Override -+ public void unloadCallback() { -+ super.unloadCallback(); -+ this.inMemoryWorld.unload(this); -+ } -+} -\ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -new file mode 100644 -index 0000000000000000000000000000000000000000..636c553f4407f19b3435d487250b041532b8f229 ---- /dev/null -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -0,0 +1,253 @@ -+package com.infernalsuite.asp.level; -+ -+import com.infernalsuite.asp.ChunkPos; -+import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; -+import com.infernalsuite.asp.api.loaders.SlimeLoader; -+import com.infernalsuite.asp.serialization.slime.SlimeSerializer; -+import com.infernalsuite.asp.skeleton.SkeletonCloning; -+import com.infernalsuite.asp.skeleton.SkeletonSlimeWorld; -+import com.infernalsuite.asp.skeleton.SlimeChunkSkeleton; -+import com.infernalsuite.asp.api.world.SlimeChunk; -+import com.infernalsuite.asp.api.world.SlimeWorld; -+import com.infernalsuite.asp.api.world.SlimeWorldInstance; -+import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; -+import net.kyori.adventure.nbt.BinaryTag; -+import net.kyori.adventure.nbt.CompoundBinaryTag; -+import net.minecraft.world.level.block.Block; -+import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.chunk.UpgradeData; -+import net.minecraft.world.level.material.Fluid; -+import net.minecraft.world.ticks.LevelChunkTicks; -+import org.bukkit.World; -+ -+import java.io.IOException; -+import java.util.ArrayList; -+import java.util.Collection; -+import java.util.HashMap; -+import java.util.List; -+import java.util.Map; -+import java.util.concurrent.ConcurrentMap; -+ -+/* -+The concept of this is a bit flawed, since ideally this should be a 1:1 representation of the MC world. -+However, due to the complexity of the chunk system we essentially need to wrap around it. -+This stores slime chunks, and when unloaded, will properly convert it to a normal slime chunk for storage. -+ */ -+public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { -+ -+ private final SlimeLevelInstance instance; -+ private final SlimeWorld liveWorld; -+ -+ private final ConcurrentMap extra; -+ private final SlimePropertyMap propertyMap; -+ private final SlimeLoader loader; -+ -+ private final Map chunkStorage = new HashMap<>(); -+ private boolean readOnly; -+ // private final Map> entityStorage = new HashMap<>(); -+ -+ public SlimeInMemoryWorld(SlimeBootstrap bootstrap, SlimeLevelInstance instance) { -+ this.instance = instance; -+ this.extra = bootstrap.initial().getExtraData(); -+ this.propertyMap = bootstrap.initial().getPropertyMap(); -+ this.loader = bootstrap.initial().getLoader(); -+ this.readOnly = bootstrap.initial().isReadOnly(); -+ -+ for (SlimeChunk initial : bootstrap.initial().getChunkStorage()) { -+ ChunkPos pos = new ChunkPos(initial.getX(), initial.getZ()); -+ List tags = new ArrayList<>(initial.getEntities()); -+ -+ // this.entityStorage.put(pos, tags); -+ this.chunkStorage.put(pos, initial); -+ } -+ -+ this.liveWorld = new NMSSlimeWorld(this); -+ } -+ -+ @Override -+ public String getName() { -+ return this.instance.getMinecraftWorld().serverLevelData.getLevelName(); -+ } -+ -+ @Override -+ public SlimeLoader getLoader() { -+ return this.loader; -+ } -+ -+ public LevelChunk promote(int x, int z, SlimeChunk chunk) { -+ SlimeChunkLevel levelChunk; -+ if (chunk == null) { -+ net.minecraft.world.level.ChunkPos pos = new net.minecraft.world.level.ChunkPos(x, z); -+ LevelChunkTicks blockLevelChunkTicks = new LevelChunkTicks<>(); -+ LevelChunkTicks fluidLevelChunkTicks = new LevelChunkTicks<>(); -+ -+ levelChunk = new SlimeChunkLevel(this.instance, pos, UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks, -+ 0L, null, null, null); -+ -+ chunk = new NMSSlimeChunk(levelChunk); -+ -+ } else { -+ levelChunk = SlimeChunkConverter.deserializeSlimeChunk(this.instance, chunk); -+ chunk = new SafeNmsChunkWrapper(new NMSSlimeChunk(levelChunk), chunk); -+ } -+ this.chunkStorage.put(new ChunkPos(x, z), chunk); -+ -+ return levelChunk; -+ } -+ -+ // Authored by: Kenox -+ // Don't use the NMS live chunk in the chunk map -+ public void unload(LevelChunk providedChunk) { -+ final int x = providedChunk.locX; -+ final int z = providedChunk.locZ; -+ -+ SlimeChunk chunk = new NMSSlimeChunk(providedChunk); -+ -+ if (FastChunkPruner.canBePruned(this.liveWorld, providedChunk)) { -+ this.chunkStorage.remove(new ChunkPos(x, z)); -+ return; -+ } -+ -+ this.chunkStorage.put(new ChunkPos(x, z), -+ new SlimeChunkSkeleton(chunk.getX(), chunk.getZ(), chunk.getSections(), -+ chunk.getHeightMaps(), chunk.getTileEntities(), chunk.getEntities())); -+ } -+ -+ @Override -+ public SlimeChunk getChunk(int x, int z) { -+ return this.chunkStorage.get(new ChunkPos(x, z)); -+ } -+ -+ @Override -+ public Collection getChunkStorage() { -+ return this.chunkStorage.values(); -+ } -+ -+ @Override -+ public World getBukkitWorld() { -+ return this.instance.getWorld(); -+ } -+ -+ @Override -+ public SlimeWorld getSlimeWorldMirror() { -+ return this.liveWorld; -+ } -+ -+ @Override -+ public SlimePropertyMap getPropertyMap() { -+ return this.propertyMap; -+ } -+ -+ @Override -+ public boolean isReadOnly() { -+ return this.getSaveStrategy() == null || this.readOnly; -+ } -+ -+ @Override -+ public SlimeWorld clone(String worldName) { -+ try { -+ return clone(worldName, null); -+ } catch (WorldAlreadyExistsException | IOException ignored) { -+ return null; // Never going to happen -+ } -+ } -+ -+ @Override -+ public SlimeWorld clone(String worldName, SlimeLoader loader) throws WorldAlreadyExistsException, IOException { -+ if (this.getName().equals(worldName)) { -+ throw new IllegalArgumentException("The clone world cannot have the same name as the original world!"); -+ } -+ -+ if (worldName == null) { -+ throw new IllegalArgumentException("The world name cannot be null!"); -+ } -+ if (loader != null) { -+ if (loader.worldExists(worldName)) { -+ throw new WorldAlreadyExistsException(worldName); -+ } -+ } -+ -+ SlimeWorld cloned = SkeletonCloning.fullClone(worldName, this, loader); -+ if (loader != null) { -+ loader.saveWorld(worldName, SlimeSerializer.serialize(cloned)); -+ } -+ -+ return cloned; -+ } -+ -+ @Override -+ public int getDataVersion() { -+ return this.liveWorld.getDataVersion(); -+ } -+ -+ @Override -+ public SlimeLoader getSaveStrategy() { -+ return this.loader; -+ } -+ -+ @Override -+ public ConcurrentMap getExtraData() { -+ return this.extra; -+ } -+ -+ @Override -+ public Collection getWorldMaps() { -+ return List.of(); -+ } -+ -+ // public Map> getEntityStorage() { -+ // return entityStorage; -+ // } -+ -+ public SlimeWorld getForSerialization() { -+ SlimeWorld world = SkeletonCloning.weakCopy(this); -+ -+ Map cloned = new HashMap<>(); -+ for (Map.Entry entry : this.chunkStorage.entrySet()) { -+ SlimeChunk clonedChunk = entry.getValue(); -+ // NMS "live" chunks need to be converted -+ { -+ LevelChunk chunk = null; -+ if (clonedChunk instanceof SafeNmsChunkWrapper safeNmsChunkWrapper) { -+ if (safeNmsChunkWrapper.shouldDefaultBackToSlimeChunk()) { -+ clonedChunk = safeNmsChunkWrapper.getSafety(); -+ } else { -+ chunk = safeNmsChunkWrapper.getWrapper().getChunk(); -+ } -+ } else if (clonedChunk instanceof NMSSlimeChunk nmsSlimeChunk) { -+ chunk = nmsSlimeChunk.getChunk(); -+ } -+ -+ if (chunk != null) { -+ if (FastChunkPruner.canBePruned(world, chunk)) { -+ continue; -+ } -+ -+ clonedChunk = new SlimeChunkSkeleton( -+ clonedChunk.getX(), -+ clonedChunk.getZ(), -+ clonedChunk.getSections(), -+ clonedChunk.getHeightMaps(), -+ clonedChunk.getTileEntities(), -+ clonedChunk.getEntities() -+ ); -+ } -+ } -+ -+ cloned.put(entry.getKey(), clonedChunk); -+ } -+ -+ return new SkeletonSlimeWorld(world.getName(), -+ world.getLoader(), -+ world.isReadOnly(), -+ cloned, -+ world.getExtraData(), -+ world.getPropertyMap(), -+ world.getDataVersion() -+ ); -+ } -+ -+ public SlimeLevelInstance getInstance() { -+ return instance; -+ } -+} -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java -new file mode 100644 -index 0000000000000000000000000000000000000000..b74ccd2b6b526f7b7955ce601a37185d3b6a2f59 ---- /dev/null -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java -@@ -0,0 +1,39 @@ -+package com.infernalsuite.asp.level; -+ -+import com.mojang.serialization.Codec; -+import net.minecraft.core.Holder; -+import net.minecraft.world.level.biome.Biome; -+import net.minecraft.world.level.biome.BiomeSource; -+import net.minecraft.world.level.biome.Climate; -+import net.minecraft.world.level.levelgen.FlatLevelSource; -+import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings; -+ -+import java.util.List; -+import java.util.Optional; -+import java.util.stream.Stream; -+ -+public class SlimeLevelGenerator extends FlatLevelSource { -+ -+ public SlimeLevelGenerator(Holder biome) { -+ super(new FlatLevelGeneratorSettings(Optional.empty(), biome, List.of()), getSource(biome)); -+ } -+ -+ private static BiomeSource getSource(Holder biome) { -+ return new BiomeSource() { -+ @Override -+ protected Codec codec() { -+ return null; -+ } -+ -+ @Override -+ protected Stream> collectPossibleBiomes() { -+ return Stream.of(biome); -+ } -+ -+ @Override -+ public Holder getNoiseBiome(int x, int y, int z, Climate.Sampler noise) { -+ return biome; -+ } -+ }; -+ } -+} -\ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -new file mode 100644 -index 0000000000000000000000000000000000000000..b8d789c93f7fef253d6ab0c35dcee37460f275eb ---- /dev/null -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -@@ -0,0 +1,197 @@ -+package com.infernalsuite.asp.level; -+ -+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import com.google.common.util.concurrent.ThreadFactoryBuilder; -+import com.infernalsuite.asp.Converter; -+import com.infernalsuite.asp.serialization.slime.SlimeSerializer; -+import com.infernalsuite.asp.api.world.SlimeChunk; -+import com.infernalsuite.asp.api.world.SlimeWorld; -+import com.infernalsuite.asp.api.world.SlimeWorldInstance; -+import com.infernalsuite.asp.api.world.properties.SlimeProperties; -+import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; -+import io.papermc.paper.chunk.system.scheduling.ChunkLoadTask; -+import io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler; -+import io.papermc.paper.chunk.system.scheduling.GenericDataLoadTask; -+import net.minecraft.core.BlockPos; -+import net.minecraft.core.Holder; -+import net.minecraft.core.registries.Registries; -+import net.minecraft.resources.ResourceKey; -+import net.minecraft.resources.ResourceLocation; -+import net.minecraft.server.MinecraftServer; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.TicketType; -+import net.minecraft.util.ProgressListener; -+import net.minecraft.util.Unit; -+import net.minecraft.util.datafix.DataFixers; -+import net.minecraft.world.Difficulty; -+import net.minecraft.world.RandomSequences; -+import net.minecraft.world.entity.EntityType; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.biome.Biome; -+import net.minecraft.world.level.chunk.ChunkAccess; -+import net.minecraft.world.level.chunk.ChunkGenerator; -+import net.minecraft.world.level.dimension.LevelStem; -+import net.minecraft.world.level.storage.LevelStorageSource; -+import net.minecraft.world.level.storage.PrimaryLevelData; -+import net.minecraft.world.level.validation.DirectoryValidator; -+import net.minecraft.world.level.validation.PathAllowList; -+import org.apache.commons.io.FileUtils; -+import org.bukkit.Bukkit; -+import org.bukkit.event.world.WorldSaveEvent; -+import org.jetbrains.annotations.Nullable; -+ -+import java.io.IOException; -+import java.nio.file.Files; -+import java.nio.file.Path; -+import java.util.ArrayList; -+import java.util.Collections; -+import java.util.UUID; -+import java.util.concurrent.ExecutorService; -+import java.util.concurrent.Executors; -+import java.util.concurrent.Future; -+import java.util.function.Consumer; -+import java.util.logging.Level; -+import java.util.stream.Collectors; -+ -+public class SlimeLevelInstance extends ServerLevel { -+ -+ -+ public static LevelStorageSource CUSTOM_LEVEL_STORAGE; -+ -+ static { -+ try { -+ Path path = Files.createTempDirectory("swm-" + UUID.randomUUID().toString().substring(0, 5)).toAbsolutePath(); -+ DirectoryValidator directoryvalidator = LevelStorageSource.parseValidator(path.resolve("allowed_symlinks.txt")); -+ CUSTOM_LEVEL_STORAGE = new LevelStorageSource(path, path, directoryvalidator, DataFixers.getDataFixer()); -+ -+ FileUtils.forceDeleteOnExit(path.toFile()); -+ -+ } catch (IOException ex) { -+ throw new IllegalStateException("Couldn't create dummy file directory.", ex); -+ } -+ } -+ -+ private static final ExecutorService WORLD_SAVER_SERVICE = Executors.newFixedThreadPool(4, new ThreadFactoryBuilder() -+ .setNameFormat("SWM Pool Thread #%1$d").build()); -+ private static final TicketType SWM_TICKET = TicketType.create("swm-chunk", (a, b) -> 0); -+ -+ private final Object saveLock = new Object(); -+ -+ private boolean ready = false; -+ -+ public SlimeLevelInstance(SlimeBootstrap slimeBootstrap, PrimaryLevelData primaryLevelData, -+ ResourceKey worldKey, -+ ResourceKey dimensionKey, LevelStem worldDimension, -+ org.bukkit.World.Environment environment) throws IOException { -+ -+ super(slimeBootstrap, MinecraftServer.getServer(), MinecraftServer.getServer().executor, -+ CUSTOM_LEVEL_STORAGE.createAccess(slimeBootstrap.initial().getName() + UUID.randomUUID(), dimensionKey), -+ primaryLevelData, worldKey, worldDimension, -+ MinecraftServer.getServer().progressListenerFactory.create(11), false, null, 0, -+ Collections.emptyList(), true, environment, null, null); -+ this.slimeInstance = new SlimeInMemoryWorld(slimeBootstrap, this); -+ -+ -+ SlimePropertyMap propertyMap = slimeBootstrap.initial().getPropertyMap(); -+ -+ this.serverLevelData.setDifficulty(Difficulty.valueOf(propertyMap.getValue(SlimeProperties.DIFFICULTY).toUpperCase())); -+ this.serverLevelData.setSpawn(new BlockPos(propertyMap.getValue(SlimeProperties.SPAWN_X), propertyMap.getValue(SlimeProperties.SPAWN_Y), propertyMap.getValue(SlimeProperties.SPAWN_Z)), 0); -+ super.setSpawnSettings(propertyMap.getValue(SlimeProperties.ALLOW_MONSTERS), propertyMap.getValue(SlimeProperties.ALLOW_ANIMALS)); -+ -+ this.pvpMode = propertyMap.getValue(SlimeProperties.PVP); -+ -+ this.keepSpawnInMemory = false; -+ } -+ -+ @Override -+ public ChunkGenerator getGenerator(SlimeBootstrap slimeBootstrap) { -+ String biomeStr = slimeBootstrap.initial().getPropertyMap().getValue(SlimeProperties.DEFAULT_BIOME); -+ ResourceKey biomeKey = ResourceKey.create(Registries.BIOME, new ResourceLocation(biomeStr)); -+ Holder defaultBiome = MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME).getHolder(biomeKey).orElseThrow(); -+ return new SlimeLevelGenerator(defaultBiome); -+ } -+ -+ @Override -+ public void save(@Nullable ProgressListener progressUpdate, boolean forceSave, boolean savingDisabled, boolean close) { -+ try { -+ if (!this.slimeInstance.isReadOnly() && !savingDisabled) { -+ Bukkit.getPluginManager().callEvent(new WorldSaveEvent(getWorld())); -+ -+ //this.getChunkSource().save(forceSave); -+ this.serverLevelData.setWorldBorder(this.getWorldBorder().createSettings()); -+ this.serverLevelData.setCustomBossEvents(MinecraftServer.getServer().getCustomBossEvents().save()); -+ -+ // Update level data -+ net.minecraft.nbt.CompoundTag compound = new net.minecraft.nbt.CompoundTag(); -+ net.minecraft.nbt.CompoundTag nbtTagCompound = this.serverLevelData.createTag(MinecraftServer.getServer().registryAccess(), compound); -+ -+ if (MinecraftServer.getServer().isStopped()) { // Make sure the world gets saved before stopping the server by running it from the main thread -+ save().get(); // Async wait for it to finish -+ this.slimeInstance.getLoader().unlockWorld(this.slimeInstance.getName()); // Unlock -+ } else { -+ this.save(); -+ //WORLD_SAVER_SERVICE.execute(this::save); -+ } -+ } -+ } catch (Throwable e) { -+ e.printStackTrace(); -+ } -+ } -+ -+ @Override -+ public void saveIncrementally(boolean doFull) { -+ if (doFull) { -+ this.save(null, false, false); -+ } -+ } -+ -+ private Future save() { -+ synchronized (saveLock) { // Don't want to save the SlimeWorld from multiple threads simultaneously -+ SlimeWorldInstance slimeWorld = this.slimeInstance; -+ Bukkit.getLogger().log(Level.INFO, "Saving world " + this.slimeInstance.getName() + "..."); -+ long start = System.currentTimeMillis(); -+ -+ Bukkit.getLogger().log(Level.INFO, "CONVERTING NMS -> SKELETON"); -+ SlimeWorld world = this.slimeInstance.getForSerialization(); -+ Bukkit.getLogger().log(Level.INFO, "CONVERTED TO SKELETON, PUSHING OFF-THREAD"); -+ return WORLD_SAVER_SERVICE.submit(() -> { -+ try { -+ byte[] serializedWorld = SlimeSerializer.serialize(world); -+ long saveStart = System.currentTimeMillis(); -+ slimeWorld.getSaveStrategy().saveWorld(slimeWorld.getName(), serializedWorld); -+ Bukkit.getLogger().log(Level.INFO, "World " + slimeWorld.getName() + " serialized in " + (saveStart - start) + "ms and saved in " + (System.currentTimeMillis() - saveStart) + "ms."); -+ } catch (IOException | IllegalStateException ex) { -+ ex.printStackTrace(); -+ } -+ }); -+ -+ } -+ } -+ -+ public SlimeWorldInstance getSlimeInstance() { -+ return this.slimeInstance; -+ } -+ -+ public ChunkDataLoadTask getLoadTask(ChunkLoadTask task, ChunkTaskScheduler scheduler, ServerLevel world, int chunkX, int chunkZ, PrioritisedExecutor.Priority priority, Consumer> onRun) { -+ return new ChunkDataLoadTask(task, scheduler, world, chunkX, chunkZ, priority, onRun); -+ } -+ -+ public void loadEntities(int chunkX, int chunkZ) { -+ SlimeChunk slimeChunk = this.slimeInstance.getChunk(chunkX, chunkZ); -+ if (slimeChunk != null) { -+ this.getEntityLookup().addLegacyChunkEntities(new ArrayList<>( -+ EntityType.loadEntitiesRecursive(slimeChunk.getEntities() -+ .stream() -+ .map((tag) -> (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)) -+ .collect(Collectors.toList()), this) -+ .toList() -+ ), new ChunkPos(chunkX, chunkZ)); -+ } -+ } -+ -+ // @Override -+ // public void unload(LevelChunk chunk) { -+ // this.slimeInstance.unload(chunk); -+ // super.unload(chunk); -+ // } -+} -\ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/asp/util/NmsUtil.java b/src/main/java/com/infernalsuite/asp/util/NmsUtil.java -new file mode 100644 -index 0000000000000000000000000000000000000000..04e43a22c1932dce66abb54337cdce802110a7af ---- /dev/null -+++ b/src/main/java/com/infernalsuite/asp/util/NmsUtil.java -@@ -0,0 +1,9 @@ -+package com.infernalsuite.asp.util; -+ -+public class NmsUtil { -+ -+ public static long asLong(int chunkX, int chunkZ) { -+ return (((long) chunkZ) * Integer.MAX_VALUE + ((long) chunkX)); -+ //return (long)chunkX & 4294967295L | ((long)chunkZ & 4294967295L) << 32; -+ } -+} -\ No newline at end of file -diff --git a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java b/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java -index 790bad0494454ca12ee152e3de6da3da634d9b20..2d6b062c4a3cf682d8e4cdbb7b7c84a7699285f2 100644 ---- a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java -+++ b/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java -@@ -31,6 +31,7 @@ public record ServerBuildInfoImpl( - private static final String ATTRIBUTE_GIT_COMMIT = "Git-Commit"; - - private static final String BRAND_PAPER_NAME = "Paper"; -+ private static final String BRAND_ADVANCED_SLIME_PAPER_NAME = "Paper"; - - private static final String BUILD_DEV = "DEV"; - -@@ -42,9 +43,9 @@ public record ServerBuildInfoImpl( - this( - getManifestAttribute(manifest, ATTRIBUTE_BRAND_ID) - .map(Key::key) -- .orElse(BRAND_PAPER_ID), -+ .orElse(BRAND_ADVANCED_SLIME_PAPER_ID), - getManifestAttribute(manifest, ATTRIBUTE_BRAND_NAME) -- .orElse(BRAND_PAPER_NAME), -+ .orElse(BRAND_ADVANCED_SLIME_PAPER_NAME), - SharedConstants.getCurrentVersion().getId(), - SharedConstants.getCurrentVersion().getName(), - getManifestAttribute(manifest, ATTRIBUTE_BUILD_NUMBER) -@@ -61,7 +62,7 @@ public record ServerBuildInfoImpl( - - @Override - public boolean isBrandCompatible(final @NotNull Key brandId) { -- return brandId.equals(this.brandId); -+ return brandId.equals(this.brandId) || brandId.equals(BRAND_PAPER_ID) || brandId.equals(BRAND_ADVANCED_SLIME_PAPER_ID); - } - - @Override -diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index ae4ebf509837e8d44255781c61d02873f8b74be8..876be700dea01f8361c37cff8e17f9140ff8ba26 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -288,7 +288,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop persistentStateManagerFactory) { -+ // ASWM START -+ public final com.infernalsuite.asp.level.SlimeBootstrap bootstrap; -+ public ServerChunkCache(com.infernalsuite.asp.level.SlimeBootstrap bootstrap, ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor workerExecutor, ChunkGenerator chunkGenerator, int viewDistance, int simulationDistance, boolean dsync, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory) { // ASWM -+ this.bootstrap = bootstrap; -+ // ASWM end - this.level = world; - this.mainThreadProcessor = new ServerChunkCache.MainThreadExecutor(world); - this.mainThread = Thread.currentThread(); -diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 1f898500d0e9b18a880645ceb0a8ff0fe75f4e48..18fe62b5f6f90099d321ad381a941d8e3bd1ea66 100644 ---- a/src/main/java/net/minecraft/server/level/ServerLevel.java -+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -145,7 +145,6 @@ import net.minecraft.world.level.entity.EntityTickList; - import net.minecraft.world.level.entity.EntityTypeTest; - import net.minecraft.world.level.entity.LevelCallback; - import net.minecraft.world.level.entity.LevelEntityGetter; --import net.minecraft.world.level.entity.PersistentEntitySectionManager; - import net.minecraft.world.level.gameevent.DynamicGameEventListener; - import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.level.gameevent.GameEventDispatcher; -@@ -596,8 +595,14 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - } - // Paper end - lag compensation - -- // Add env and gen to constructor, IWorldDataServer -> WorldDataServer - public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { -+ this(null, minecraftserver, executor, convertable_conversionsession, iworlddataserver, resourcekey, worlddimension, worldloadlistener, flag, i, list, flag1, randomsequences, env, gen, biomeProvider); -+ } -+ -+ public com.infernalsuite.asp.level.SlimeInMemoryWorld slimeInstance; // ASWM -+ -+ // Add env and gen to constructor, IWorldDataServer -> WorldDataServer -+ public ServerLevel(com.infernalsuite.asp.level.SlimeBootstrap bootstrap, MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { - super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess(), iworlddataserver.getGameRules())), executor); // Paper - create paper world configs; Async-Anti-Xray: Pass executor - this.pvpMode = minecraftserver.isPvpAllowed(); - this.convertable = convertable_conversionsession; -@@ -624,6 +629,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - chunkgenerator = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, chunkgenerator, gen); - } - // CraftBukkit end -+ // ASWM START -+ ChunkGenerator result = this.getGenerator(bootstrap); -+ if (result != null) { -+ chunkgenerator = result; -+ } -+ // ASWM END - boolean flag2 = minecraftserver.forceSynchronousWrites(); - DataFixer datafixer = minecraftserver.getFixerUpper(); - EntityPersistentStorage entitypersistentstorage = new EntityStorage(new SimpleRegionStorage(new RegionStorageInfo(convertable_conversionsession.getLevelId(), resourcekey, "entities"), convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, DataFixTypes.ENTITY_CHUNK), this, minecraftserver); -@@ -634,7 +645,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - int k = this.spigotConfig.simulationDistance; // Spigot - // Paper - rewrite chunk system - -- this.chunkSource = new ServerChunkCache(this, convertable_conversionsession, datafixer, structuretemplatemanager, executor, chunkgenerator, j, k, flag2, worldloadlistener, null, () -> { // Paper - rewrite chunk system -+ this.chunkSource = new ServerChunkCache(bootstrap, this, convertable_conversionsession, datafixer, structuretemplatemanager, executor, chunkgenerator, j, k, flag2, worldloadlistener, null, () -> { // Paper - rewrite chunk system // ASWM - return minecraftserver.overworld().getDataStorage(); - }); - this.chunkSource.getGeneratorState().ensureStructuresGenerated(); -@@ -693,6 +704,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - this.dragonFight = enderDragonFight; - } - -+ // ASWM START -+ public ChunkGenerator getGenerator(com.infernalsuite.asp.level.SlimeBootstrap bootstrap) { -+ return null; -+ } -+ // ASWM END -+ - public void setWeatherParameters(int clearDuration, int rainDuration, boolean raining, boolean thundering) { - this.serverLevelData.setClearWeatherTime(clearDuration); - this.serverLevelData.setRainTime(rainDuration); -diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -index 8b84bf2272556ac3321cbf16361d7f48a1cc6873..c8f018ec8c142f0e05fcf346f4b1a31cd887aec6 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -+++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java -@@ -468,7 +468,6 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - this.moonrise$palette = palette; - } - // Paper end - optimise palette reads -- - public void copyFrom(Palette palette, BitStorage storage) { - for (int i = 0; i < storage.getSize(); i++) { - T object = palette.valueFor(storage.get(i)); -diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java -index 774556a62eb240da42e84db4502e2ed43495be17..f3ff4b5f15959a3fc52c000f7636bc3f23dd7598 100644 ---- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java -+++ b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java -@@ -11,7 +11,7 @@ public final class Versioning { - public static String getBukkitVersion() { - String result = "Unknown-Version"; - -- InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/io.papermc.paper/paper-api/pom.properties"); -+ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/com.infernalsuite.asp/slimeworldmanager-api/pom.properties"); // ASWM - Properties properties = new Properties(); - - if (stream != null) { -diff --git a/src/main/resources/META-INF/services/com.infernalsuite.asp.api.SlimeNMSBridge b/src/main/resources/META-INF/services/com.infernalsuite.asp.api.SlimeNMSBridge -new file mode 100644 -index 0000000000000000000000000000000000000000..973f2f48d75f1912c12bb89a106379557747296d ---- /dev/null -+++ b/src/main/resources/META-INF/services/com.infernalsuite.asp.api.SlimeNMSBridge -@@ -0,0 +1 @@ -+com.infernalsuite.asp.SlimeNMSBridgeImpl -\ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index b11387697..fb034fdec 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -15,7 +15,7 @@ rootProject.name = "ASPaper" include(":gradle:platform") include(":api") -//include(":core") +include(":core") //include(":importer") //include(":loaders") //include(":plugin") From f01085bd13f3b0aca5d5790d01f65b145aae363c Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 12:52:49 +0100 Subject: [PATCH 036/133] fix: access transformer --- .../level/entity/ChunkEntitySlices.java.patch | 11 ----------- .../scheduling/task/ChunkLoadTask.java.patch | 6 ++---- {build-data => impl/build-data}/aspaper.at | 1 + {build-data => impl/build-data}/dev-imports.txt | 0 4 files changed, 3 insertions(+), 15 deletions(-) delete mode 100644 impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java.patch rename {build-data => impl/build-data}/aspaper.at (71%) rename {build-data => impl/build-data}/dev-imports.txt (100%) diff --git a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java.patch b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java.patch deleted file mode 100644 index 94989484e..000000000 --- a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java -+++ b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java -@@ -42,7 +_,7 @@ - private final EntityCollectionBySection hardCollidingEntities; - private final Reference2ObjectOpenHashMap, EntityCollectionBySection> entitiesByClass; - private final Reference2ObjectOpenHashMap, EntityCollectionBySection> entitiesByType; -- private final EntityList entities = new EntityList(); -+ public final EntityList entities = new EntityList(); - - public FullChunkStatus status; - public final ChunkData chunkData; diff --git a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch index f263f0798..20a94b7e3 100644 --- a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch +++ b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch @@ -1,12 +1,10 @@ --- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java -@@ -32,8 +_,8 @@ - +@@ -33,7 +_,7 @@ private static final Logger LOGGER = LoggerFactory.getLogger(ChunkLoadTask.class); -- private final NewChunkHolder chunkHolder; + public final NewChunkHolder chunkHolder; - private final ChunkDataLoadTask loadTask; -+ public final NewChunkHolder chunkHolder; + private final com.infernalsuite.asp.level.CommonLoadTask loadTask; // ASP private volatile boolean cancelled; diff --git a/build-data/aspaper.at b/impl/build-data/aspaper.at similarity index 71% rename from build-data/aspaper.at rename to impl/build-data/aspaper.at index 6d275d624..0b7647cb1 100644 --- a/build-data/aspaper.at +++ b/impl/build-data/aspaper.at @@ -3,3 +3,4 @@ public ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices entities public ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkLoadTask chunkHolder public net.minecraft.server.MinecraftServer commandStorage +public net.minecraft.world.level.chunk.storage.SerializableChunkData makeBiomeCodec(Lnet/minecraft/core/Registry;)Lcom/mojang/serialization/Codec; diff --git a/build-data/dev-imports.txt b/impl/build-data/dev-imports.txt similarity index 100% rename from build-data/dev-imports.txt rename to impl/build-data/dev-imports.txt From d4a2939d8f6492463d5b6192c4e5a81492765da5 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 13:04:30 +0100 Subject: [PATCH 037/133] Port "poi data loader" by Paul19988 from 11 Jun 2023 --- .../storage/SerializableChunkData.java.patch | 15 +++++ .../asp/level/ChunkDataLoadTask.java | 7 --- patches/server/0002-poi-data-loader.patch | 60 ------------------- 3 files changed, 15 insertions(+), 67 deletions(-) create mode 100644 impl/aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch delete mode 100644 patches/server/0002-poi-data-loader.patch diff --git a/impl/aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch b/impl/aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch new file mode 100644 index 000000000..e1b834742 --- /dev/null +++ b/impl/aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch @@ -0,0 +1,15 @@ +--- a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java ++++ b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +@@ -387,6 +_,12 @@ + if (flag2) { + lightEngine.queueSectionData(LightLayer.SKY, sectionPos, sectionData.skyLight); + } ++ ++ //ASP start ++ if (level instanceof com.infernalsuite.asp.level.SlimeLevelInstance) { ++ poiManager.checkConsistencyWithBlocks(SectionPos.of(chunkPos.getWorldPosition()), achunksection[j]); ++ } ++ //ASP end + } + } + diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java index 9a627c165..b8bca219b 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java @@ -64,13 +64,6 @@ private ChunkAccess getEmptyChunk() { } protected ChunkAccess runOnMain(final SlimeChunk data) { - final PoiChunk poiChunk = this.chunkLoadTask.chunkHolder.getPoiChunk(); - if (poiChunk == null) { - LOGGER.error("Expected poi chunk to be loaded with chunk for task " + this.toString()); - } else { - poiChunk.load(); - } - // have tasks to run (at this point, it's just the POI consistency checking) try { // if (data.tasks != null) { diff --git a/patches/server/0002-poi-data-loader.patch b/patches/server/0002-poi-data-loader.patch deleted file mode 100644 index 0b9b2cd54..000000000 --- a/patches/server/0002-poi-data-loader.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul19988 -Date: Sun, 11 Jun 2023 17:19:05 +0100 -Subject: [PATCH] poi data loader - - -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java -index bbf9d6c1c9525d97160806819a57be03eca290f1..38ca7bd039bc1b60a63ff68c53e3ec315545a175 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java -@@ -16,7 +16,7 @@ import org.slf4j.Logger; - import org.slf4j.LoggerFactory; - import java.util.Optional; - --public final class PoiChunk { -+public class PoiChunk { - - private static final Logger LOGGER = LoggerFactory.getLogger(PoiChunk.class); - -diff --git a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java -index bb954b74739e22525f9a45648d3ecf54f5a9e61c..7e7c560b89c45e8ff003813f3c7a141c2b0b7a1d 100644 ---- a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java -+++ b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java -@@ -14,6 +14,7 @@ import net.minecraft.world.level.chunk.ChunkAccess; - import net.minecraft.world.level.chunk.ImposterProtoChunk; - import net.minecraft.world.level.chunk.LevelChunk; - import net.minecraft.world.level.chunk.UpgradeData; -+import net.minecraft.world.level.chunk.storage.ChunkSerializer; - import net.minecraft.world.level.material.Fluid; - import net.minecraft.world.ticks.LevelChunkTicks; - import org.slf4j.Logger; -@@ -63,13 +64,6 @@ public final class ChunkDataLoadTask implements CommonLoadTask { - } - - protected ChunkAccess runOnMain(final SlimeChunk data) { -- final PoiChunk poiChunk = this.chunkLoadTask.chunkHolder.getPoiChunk(); -- if (poiChunk == null) { -- LOGGER.error("Expected poi chunk to be loaded with chunk for task " + this.toString()); -- } else { -- poiChunk.load(); -- } -- - // have tasks to run (at this point, it's just the POI consistency checking) - try { - // if (data.tasks != null) { -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index 018b24d7611c3fd11536441431abf8f125850129..6f482bf045cf7a14dceb5673d9d19ee87b7c03a8 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -@@ -369,6 +369,10 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun - if (flag3) { - levellightengine.queueSectionData(LightLayer.SKY, sectionposition, serializablechunkdata_b.skyLight); - } -+ -+ if (world instanceof com.infernalsuite.asp.level.SlimeLevelInstance) { -+ poiStorage.checkConsistencyWithBlocks(SectionPos.of(chunkPos.getWorldPosition()), achunksection[j]); -+ } - } - } - From 8961d09bc8ede4b2a5de3c2bfa93c80505e8172d Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 13:11:38 +0100 Subject: [PATCH 038/133] Port "Add support for serializing/deserializing PDC" by kyngs from 21 Oct 2023 --- .../infernalsuite/asp/SlimeNMSBridgeImpl.java | 6 ++ .../asp/level/SlimeInMemoryWorld.java | 12 ++++ ...rt-for-serializing-deserializing-PDC.patch | 60 ------------------- 3 files changed, 18 insertions(+), 60 deletions(-) delete mode 100644 patches/server/0003-Add-support-for-serializing-deserializing-PDC.patch diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java index f8fbb1f02..80a883d4b 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java @@ -11,6 +11,7 @@ import net.kyori.adventure.util.Services; import net.minecraft.SharedConstants; import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; @@ -179,6 +180,11 @@ private SlimeLevelInstance createCustomWorld(SlimeWorld world, @Nullable Resourc // level.setReady(true); level.setSpawnSettings(world.getPropertyMap().getValue(SlimeProperties.ALLOW_MONSTERS), world.getPropertyMap().getValue(SlimeProperties.ALLOW_ANIMALS)); + var nmsExtraData = (CompoundTag) Converter.convertTag(world.getExtraData()); + + //Attempt to read PDC + if (nmsExtraData.get("BukkitValues") != null) level.getWorld().readBukkitValues(nmsExtraData.get("BukkitValues")); + return level; } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java index 636c553f4..387954aae 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -1,6 +1,7 @@ package com.infernalsuite.asp.level; import com.infernalsuite.asp.ChunkPos; +import com.infernalsuite.asp.Converter; import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; import com.infernalsuite.asp.api.loaders.SlimeLoader; import com.infernalsuite.asp.serialization.slime.SlimeSerializer; @@ -237,6 +238,17 @@ public SlimeWorld getForSerialization() { cloned.put(entry.getKey(), clonedChunk); } + // Serialize Bukkit Values (PDC) + + var nmsTag = new net.minecraft.nbt.CompoundTag(); + + instance.getWorld().storeBukkitValues(nmsTag); + + // Bukkit stores the relevant tag as a tag with the key "BukkitValues" in the tag we supply to it + var flowTag = Converter.convertTag("BukkitValues", nmsTag.getCompound("BukkitValues")); + + world.getExtraData().getValue().put(flowTag); + return new SkeletonSlimeWorld(world.getName(), world.getLoader(), world.isReadOnly(), diff --git a/patches/server/0003-Add-support-for-serializing-deserializing-PDC.patch b/patches/server/0003-Add-support-for-serializing-deserializing-PDC.patch deleted file mode 100644 index 9ab91a0f4..000000000 --- a/patches/server/0003-Add-support-for-serializing-deserializing-PDC.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: kyngs -Date: Sat, 21 Oct 2023 18:11:15 +0200 -Subject: [PATCH] Add support for serializing/deserializing PDC - - -diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -index 98043b30614cc0ace252919367662a5e535fa1e1..68240b46ce911674ed288fe559737572fa44de6a 100644 ---- a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -+++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -@@ -11,6 +11,7 @@ import com.mojang.serialization.Lifecycle; - import net.kyori.adventure.util.Services; - import net.minecraft.SharedConstants; - import net.minecraft.core.registries.Registries; -+import net.minecraft.nbt.CompoundTag; - import net.minecraft.resources.ResourceKey; - import net.minecraft.resources.ResourceLocation; - import net.minecraft.server.MinecraftServer; -@@ -178,6 +179,11 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { - // level.setReady(true); - level.setSpawnSettings(world.getPropertyMap().getValue(SlimeProperties.ALLOW_MONSTERS), world.getPropertyMap().getValue(SlimeProperties.ALLOW_ANIMALS)); - -+ var nmsExtraData = (CompoundTag) Converter.convertTag(world.getExtraData()); -+ -+ //Attempt to read PDC -+ if (nmsExtraData.get("BukkitValues") != null) level.getWorld().readBukkitValues(nmsExtraData.get("BukkitValues")); -+ - return level; - } - -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -index 636c553f4407f19b3435d487250b041532b8f229..387954aae7ef1a39025a474ab1fe81b7216d8d6c 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -1,6 +1,7 @@ - package com.infernalsuite.asp.level; - - import com.infernalsuite.asp.ChunkPos; -+import com.infernalsuite.asp.Converter; - import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; - import com.infernalsuite.asp.api.loaders.SlimeLoader; - import com.infernalsuite.asp.serialization.slime.SlimeSerializer; -@@ -237,6 +238,17 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - cloned.put(entry.getKey(), clonedChunk); - } - -+ // Serialize Bukkit Values (PDC) -+ -+ var nmsTag = new net.minecraft.nbt.CompoundTag(); -+ -+ instance.getWorld().storeBukkitValues(nmsTag); -+ -+ // Bukkit stores the relevant tag as a tag with the key "BukkitValues" in the tag we supply to it -+ var flowTag = Converter.convertTag("BukkitValues", nmsTag.getCompound("BukkitValues")); -+ -+ world.getExtraData().getValue().put(flowTag); -+ - return new SkeletonSlimeWorld(world.getName(), - world.getLoader(), - world.isReadOnly(), From c64404b7d937cf408650d780106fb83e29be08c1 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 13:17:46 +0100 Subject: [PATCH 039/133] Port "Fix entity loading" by Philip Kelley from 2 Nov 2023 --- .../scheduling/NewChunkHolder.java.patch | 11 ++ .../asp/level/ChunkDataLoadTask.java | 12 +- .../asp/level/SlimeChunkConverter.java | 42 +++--- patches/server/0004-Fix-entity-loading.patch | 137 ------------------ 4 files changed, 44 insertions(+), 158 deletions(-) create mode 100644 impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch delete mode 100644 patches/server/0004-Fix-entity-loading.patch diff --git a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch new file mode 100644 index 000000000..2a288d906 --- /dev/null +++ b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch @@ -0,0 +1,11 @@ +--- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java ++++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java +@@ -116,7 +_,7 @@ + } + + if (!transientChunk) { +- if (entityChunk != null) { ++ if (!(this.world instanceof com.infernalsuite.asp.level.SlimeLevelInstance) && entityChunk != null) { //ASP + final List entities = ChunkEntitySlices.readEntities(this.world, entityChunk); + + ((ChunkSystemServerLevel)this.world).moonrise$getEntityLookup().addEntityChunkEntities(entities, new ChunkPos(this.chunkX, this.chunkZ)); diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java index b8bca219b..d4fa15c19 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java @@ -2,11 +2,12 @@ import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; import ca.spottedleaf.concurrentutil.util.Priority; -import ca.spottedleaf.moonrise.patches.chunk_system.level.poi.PoiChunk; import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkLoadTask; import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.GenericDataLoadTask; import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.Converter; +import net.minecraft.nbt.CompoundTag; import com.mojang.logging.LogUtils; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.ChunkPos; @@ -60,7 +61,7 @@ private ChunkAccess getEmptyChunk() { LevelChunkTicks fluidLevelChunkTicks = new LevelChunkTicks<>(); return new ImposterProtoChunk(new LevelChunk(this.world, new ChunkPos(this.chunkX, this.chunkZ), UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks, - 0L, null, null, null), true); + 0L, null, chunk -> {}, null), true); } protected ChunkAccess runOnMain(final SlimeChunk data) { @@ -74,7 +75,12 @@ protected ChunkAccess runOnMain(final SlimeChunk data) { LevelChunk chunk = this.world.slimeInstance.promote(chunkX, chunkZ, data); - return new ImposterProtoChunk(chunk, false); + ImposterProtoChunk protoChunk = new ImposterProtoChunk(chunk, false); + if (data != null) { + data.getEntities().stream().map(flowTag -> (CompoundTag) Converter.convertTag(flowTag)).forEach(protoChunk::addEntity); + } + + return protoChunk; } catch (final ThreadDeath death) { throw death; } catch (final Throwable thr2) { diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java index b0d45837e..b705b3133 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java @@ -13,6 +13,8 @@ import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.NbtOps; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biomes; @@ -104,25 +106,11 @@ static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeC LevelChunk.PostLoadProcessor loadEntities = (nmsChunk) -> { + List entities = chunk.getEntities(); - // TODO - // Load tile entities - List tileEntities = chunk.getTileEntities(); - - if (tileEntities != null) { - for (CompoundBinaryTag tag : tileEntities) { - String type = tag.getString("id"); - - if (!type.isEmpty()) { - BlockPos blockPosition = new BlockPos(tag.getInt("x"), tag.getInt("y"), tag.getInt("z")); - BlockState blockData = nmsChunk.getBlockState(blockPosition); - BlockEntity entity = BlockEntity.loadStatic(blockPosition, blockData, (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)); - - if (entity != null) { - nmsChunk.setBlockEntity(entity); - } - } - } + if (entities != null) { + net.minecraft.server.level.ChunkMap.postLoadProtoChunk(instance, entities.stream() + .map(tag -> (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)).toList(), nmsChunk.getPos()); } }; @@ -130,6 +118,24 @@ static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeC LevelChunkTicks fluidLevelChunkTicks = new LevelChunkTicks<>(); SlimeChunkLevel nmsChunk = new SlimeChunkLevel(instance, pos, UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks, 0L, sections, loadEntities, null); + List tileEntities = chunk.getTileEntities(); + + if (tileEntities != null) { + for (CompoundBinaryTag tag : tileEntities) { + String type = tag.getString("id"); + + if (!type.isEmpty()) { + BlockPos blockPosition = new BlockPos(tag.getInt("x"), tag.getInt("y"), tag.getInt("z")); + BlockState blockData = nmsChunk.getBlockState(blockPosition); + BlockEntity entity = BlockEntity.loadStatic(blockPosition, blockData, (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)); + + if (entity != null) { + nmsChunk.setBlockEntity(entity); + } + } + } + } + // Height Maps EnumSet heightMapTypes = nmsChunk.getStatus().heightmapsAfter(); CompoundBinaryTag heightMaps = chunk.getHeightMaps(); diff --git a/patches/server/0004-Fix-entity-loading.patch b/patches/server/0004-Fix-entity-loading.patch deleted file mode 100644 index e2a9a2672..000000000 --- a/patches/server/0004-Fix-entity-loading.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Philip Kelley -Date: Thu, 2 Nov 2023 22:56:51 +0000 -Subject: [PATCH] Fix entity loading - - -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -index eafa4e6d55cd0f9314ac0f2b96a7f48fbb5e1a4c..62b526f7e147586977615ec8cec191d0aaf0bcdc 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -@@ -117,7 +117,7 @@ public final class NewChunkHolder { - } - - if (!transientChunk) { -- if (entityChunk != null) { -+ if (!(this.world instanceof com.infernalsuite.asp.level.SlimeLevelInstance) && entityChunk != null) { - final List entities = ChunkEntitySlices.readEntities(this.world, entityChunk); - - ((ChunkSystemServerLevel)this.world).moonrise$getEntityLookup().addEntityChunkEntities(entities, new ChunkPos(this.chunkX, this.chunkZ)); -diff --git a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java -index 7e7c560b89c45e8ff003813f3c7a141c2b0b7a1d..e2c67548ff6341c1c981af83f6df7711c78330a9 100644 ---- a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java -+++ b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java -@@ -1,12 +1,13 @@ - package com.infernalsuite.asp.level; - - import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import com.infernalsuite.asp.Converter; - import com.infernalsuite.asp.api.world.SlimeChunk; - import com.mojang.logging.LogUtils; --import io.papermc.paper.chunk.system.poi.PoiChunk; - import io.papermc.paper.chunk.system.scheduling.ChunkLoadTask; - import io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler; - import io.papermc.paper.chunk.system.scheduling.GenericDataLoadTask; -+import net.minecraft.nbt.CompoundTag; - import net.minecraft.server.level.ServerLevel; - import net.minecraft.world.level.ChunkPos; - import net.minecraft.world.level.block.Block; -@@ -14,7 +15,6 @@ import net.minecraft.world.level.chunk.ChunkAccess; - import net.minecraft.world.level.chunk.ImposterProtoChunk; - import net.minecraft.world.level.chunk.LevelChunk; - import net.minecraft.world.level.chunk.UpgradeData; --import net.minecraft.world.level.chunk.storage.ChunkSerializer; - import net.minecraft.world.level.material.Fluid; - import net.minecraft.world.ticks.LevelChunkTicks; - import org.slf4j.Logger; -@@ -60,7 +60,7 @@ public final class ChunkDataLoadTask implements CommonLoadTask { - LevelChunkTicks fluidLevelChunkTicks = new LevelChunkTicks<>(); - - return new ImposterProtoChunk(new LevelChunk(this.world, new ChunkPos(this.chunkX, this.chunkZ), UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks, -- 0L, null, null, null), true); -+ 0L, null, chunk -> {}, null), true); - } - - protected ChunkAccess runOnMain(final SlimeChunk data) { -@@ -73,8 +73,12 @@ public final class ChunkDataLoadTask implements CommonLoadTask { - // } - - LevelChunk chunk = this.world.slimeInstance.promote(chunkX, chunkZ, data); -+ ImposterProtoChunk protoChunk = new ImposterProtoChunk(chunk, false); -+ if (data != null) { -+ data.getEntities().stream().map(flowTag -> (CompoundTag) Converter.convertTag(flowTag)).forEach(protoChunk::addEntity); -+ } - -- return new ImposterProtoChunk(chunk, false); -+ return protoChunk; - } catch (final ThreadDeath death) { - throw death; - } catch (final Throwable thr2) { -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -index b0d45837e918ef720b49a3f4968d7781ecf6436d..b705b3133634c3696dee766cbfc95380293ccda3 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -@@ -13,6 +13,8 @@ import net.minecraft.core.Holder; - import net.minecraft.core.Registry; - import net.minecraft.core.registries.Registries; - import net.minecraft.nbt.NbtOps; -+import net.minecraft.world.entity.Entity; -+import net.minecraft.world.entity.EntityType; - import net.minecraft.world.level.ChunkPos; - import net.minecraft.world.level.biome.Biome; - import net.minecraft.world.level.biome.Biomes; -@@ -104,25 +106,11 @@ public class SlimeChunkConverter { - - - LevelChunk.PostLoadProcessor loadEntities = (nmsChunk) -> { -+ List entities = chunk.getEntities(); - -- // TODO -- // Load tile entities -- List tileEntities = chunk.getTileEntities(); -- -- if (tileEntities != null) { -- for (CompoundBinaryTag tag : tileEntities) { -- String type = tag.getString("id"); -- -- if (!type.isEmpty()) { -- BlockPos blockPosition = new BlockPos(tag.getInt("x"), tag.getInt("y"), tag.getInt("z")); -- BlockState blockData = nmsChunk.getBlockState(blockPosition); -- BlockEntity entity = BlockEntity.loadStatic(blockPosition, blockData, (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)); -- -- if (entity != null) { -- nmsChunk.setBlockEntity(entity); -- } -- } -- } -+ if (entities != null) { -+ net.minecraft.server.level.ChunkMap.postLoadProtoChunk(instance, entities.stream() -+ .map(tag -> (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)).toList(), nmsChunk.getPos()); - } - }; - -@@ -130,6 +118,24 @@ public class SlimeChunkConverter { - LevelChunkTicks fluidLevelChunkTicks = new LevelChunkTicks<>(); - SlimeChunkLevel nmsChunk = new SlimeChunkLevel(instance, pos, UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks, 0L, sections, loadEntities, null); - -+ List tileEntities = chunk.getTileEntities(); -+ -+ if (tileEntities != null) { -+ for (CompoundBinaryTag tag : tileEntities) { -+ String type = tag.getString("id"); -+ -+ if (!type.isEmpty()) { -+ BlockPos blockPosition = new BlockPos(tag.getInt("x"), tag.getInt("y"), tag.getInt("z")); -+ BlockState blockData = nmsChunk.getBlockState(blockPosition); -+ BlockEntity entity = BlockEntity.loadStatic(blockPosition, blockData, (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)); -+ -+ if (entity != null) { -+ nmsChunk.setBlockEntity(entity); -+ } -+ } -+ } -+ } -+ - // Height Maps - EnumSet heightMapTypes = nmsChunk.getStatus().heightmapsAfter(); - CompoundBinaryTag heightMaps = chunk.getHeightMaps(); From a8a89525ee6a5639a5326f186efacf9ec2711815 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 13:20:09 +0100 Subject: [PATCH 040/133] Port "Remove catch throwable" by Philip Kelley from 2 Nov 2023 --- .../asp/level/ChunkDataLoadTask.java | 8 ++--- .../server/0005-Remove-catch-throwable.patch | 32 ------------------- 2 files changed, 3 insertions(+), 37 deletions(-) delete mode 100644 patches/server/0005-Remove-catch-throwable.patch diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java index d4fa15c19..782445108 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java @@ -49,7 +49,7 @@ protected ChunkDataLoadTask(ChunkLoadTask chunkLoadTask, final ChunkTaskSchedule try { SlimeChunk chunk = ((SlimeLevelInstance) this.world).slimeInstance.getChunk(this.chunkX, this.chunkZ); this.onRun.accept(new GenericDataLoadTask.TaskResult<>(runOnMain(chunk), null)); - } catch (Throwable e) { + } catch (final Exception e) { LOGGER.error("ERROR", e); this.onRun.accept(new GenericDataLoadTask.TaskResult<>(null, e)); } @@ -81,10 +81,8 @@ protected ChunkAccess runOnMain(final SlimeChunk data) { } return protoChunk; - } catch (final ThreadDeath death) { - throw death; - } catch (final Throwable thr2) { - LOGGER.error("Failed to parse main tasks for task " + this.toString() + ", chunk data will be lost", thr2); + } catch (final Exception e) { + LOGGER.error("Failed to parse main tasks for task {}, chunk data will be lost", this, e); return this.getEmptyChunk(); } } diff --git a/patches/server/0005-Remove-catch-throwable.patch b/patches/server/0005-Remove-catch-throwable.patch deleted file mode 100644 index d89ef86ee..000000000 --- a/patches/server/0005-Remove-catch-throwable.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Philip Kelley -Date: Thu, 2 Nov 2023 23:01:26 +0000 -Subject: [PATCH] Remove catch throwable - - -diff --git a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java -index e2c67548ff6341c1c981af83f6df7711c78330a9..bf44132f7614832119f798a2418e2014ec378cf9 100644 ---- a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java -+++ b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java -@@ -48,7 +48,7 @@ public final class ChunkDataLoadTask implements CommonLoadTask { - try { - SlimeChunk chunk = ((SlimeLevelInstance) this.world).slimeInstance.getChunk(this.chunkX, this.chunkZ); - this.onRun.accept(new GenericDataLoadTask.TaskResult<>(runOnMain(chunk), null)); -- } catch (Throwable e) { -+ } catch (final Exception e) { - LOGGER.error("ERROR", e); - this.onRun.accept(new GenericDataLoadTask.TaskResult<>(null, e)); - } -@@ -79,10 +79,8 @@ public final class ChunkDataLoadTask implements CommonLoadTask { - } - - return protoChunk; -- } catch (final ThreadDeath death) { -- throw death; -- } catch (final Throwable thr2) { -- LOGGER.error("Failed to parse main tasks for task " + this.toString() + ", chunk data will be lost", thr2); -+ } catch (final Exception e) { -+ LOGGER.error("Failed to parse main tasks for task {}, chunk data will be lost", this, e); - return this.getEmptyChunk(); - } - } From e68ce708635d7864eb69aa985dcc47ad5af1588c Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 13:23:55 +0100 Subject: [PATCH 041/133] Port "Handle null data properly" by Philip Kelley from 4 Nov 2023 --- .../asp/SimpleDataFixerConverter.java | 18 ++++--- .../0006-Handle-null-data-properly.patch | 50 ------------------- 2 files changed, 10 insertions(+), 58 deletions(-) delete mode 100644 patches/server/0006-Handle-null-data-properly.patch diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java index 694bd135f..d38fea59d 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java @@ -43,10 +43,12 @@ public SlimeWorld readFromData(SlimeWorld data) { convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.ENTITY.convert(new NBTMapType(tag), currentVersion, newVersion)) ); } + ChunkPos chunkPos = new ChunkPos(chunk.getX(), chunk.getZ()); SlimeChunkSection[] sections = new SlimeChunkSection[chunk.getSections().length]; for (int i = 0; i < sections.length; i++) { SlimeChunkSection dataSection = chunk.getSections()[i]; + if (dataSection == null) continue; CompoundBinaryTag blockStateTag = blockStateTag = convertAndBack(dataSection.getBlockStatesTag(), (tag) -> { WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, new NBTMapType(tag), "palette", currentVersion, newVersion); @@ -63,15 +65,15 @@ public SlimeWorld readFromData(SlimeWorld data) { dataSection.getSkyLight() ); - chunks.put(new ChunkPos(chunk.getX(), chunk.getZ()), new SlimeChunkSkeleton( - chunk.getX(), - chunk.getZ(), - sections, - chunk.getHeightMaps(), - blockEntities, - entities - )); } + chunks.put(new ChunkPos(chunk.getX(), chunk.getZ()), new SlimeChunkSkeleton( + chunk.getX(), + chunk.getZ(), + sections, + chunk.getHeightMaps(), + blockEntities, + entities + )); } diff --git a/patches/server/0006-Handle-null-data-properly.patch b/patches/server/0006-Handle-null-data-properly.patch deleted file mode 100644 index 512b843e6..000000000 --- a/patches/server/0006-Handle-null-data-properly.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Philip Kelley -Date: Sat, 4 Nov 2023 20:36:26 +0000 -Subject: [PATCH] Handle null data properly - - -diff --git a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -index 694bd135fd4398ecf02940e638fae1047e217a29..6856a7254685b2d005bcb2a91841f53d8743e38d 100644 ---- a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -+++ b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -@@ -44,9 +44,12 @@ class SimpleDataFixerConverter implements SlimeWorldReader { - ); - } - -+ ChunkPos chunkPos = new ChunkPos(chunk.getX(), chunk.getZ()); -+ - SlimeChunkSection[] sections = new SlimeChunkSection[chunk.getSections().length]; - for (int i = 0; i < sections.length; i++) { - SlimeChunkSection dataSection = chunk.getSections()[i]; -+ if (dataSection == null) continue; - - CompoundBinaryTag blockStateTag = blockStateTag = convertAndBack(dataSection.getBlockStatesTag(), (tag) -> { - WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, new NBTMapType(tag), "palette", currentVersion, newVersion); -@@ -62,17 +65,17 @@ class SimpleDataFixerConverter implements SlimeWorldReader { - dataSection.getBlockLight(), - dataSection.getSkyLight() - ); -- -- chunks.put(new ChunkPos(chunk.getX(), chunk.getZ()), new SlimeChunkSkeleton( -- chunk.getX(), -- chunk.getZ(), -- sections, -- chunk.getHeightMaps(), -- blockEntities, -- entities -- )); - } - -+ chunks.put(chunkPos, new SlimeChunkSkeleton( -+ chunk.getX(), -+ chunk.getX(), -+ sections, -+ chunk.getHeightMaps(), -+ blockEntities, -+ entities -+ )); -+ - } - - return new SkeletonSlimeWorld( From 2d58e8e967f610494ef02ff701f6f5dd79b4081f Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 13:29:59 +0100 Subject: [PATCH 042/133] Port "Make SlimeWorld a PersistentDataHolder" by kyngs from 26 Oct 2023 --- core/build.gradle.kts | 2 +- .../infernalsuite/asp/SlimeNMSBridgeImpl.java | 24 ++- .../asp/level/NMSSlimeWorld.java | 7 + .../asp/level/SlimeInMemoryWorld.java | 17 +- ...ke-SlimeWorld-a-PersistentDataHolder.patch | 158 ------------------ 5 files changed, 43 insertions(+), 165 deletions(-) delete mode 100644 patches/server/0007-Make-SlimeWorld-a-PersistentDataHolder.patch diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 647bbf71d..ad5d0e7fc 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -5,7 +5,7 @@ plugins { dependencies { compileOnly(project(":api")) -// compileOnly(project(":aspaper-api")) + compileOnly(project(":impl:aspaper-api")) implementation(libs.zstd) } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java index 80a883d4b..6ae554211 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java @@ -8,7 +8,7 @@ import com.infernalsuite.asp.level.SlimeInMemoryWorld; import com.infernalsuite.asp.level.SlimeLevelInstance; import com.mojang.serialization.Lifecycle; -import net.kyori.adventure.util.Services; +import net.kyori.adventure.nbt.CompoundBinaryTag; import net.minecraft.SharedConstants; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; @@ -31,6 +31,9 @@ import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer; +import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry; +import org.bukkit.persistence.PersistentDataContainer; import org.jetbrains.annotations.Nullable; import java.io.IOException; @@ -38,6 +41,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { + private static final CraftPersistentDataTypeRegistry REGISTRY = new CraftPersistentDataTypeRegistry(); private static final SimpleDataFixerConverter DATA_FIXER_CONVERTER = new SimpleDataFixerConverter(); private static final Logger LOGGER = LogManager.getLogger("ASP"); @@ -50,6 +54,22 @@ public static SlimeNMSBridgeImpl instance() { return (SlimeNMSBridgeImpl) SlimeNMSBridge.instance(); } + @Override + public void extractCraftPDC(PersistentDataContainer source, CompoundBinaryTag.Builder builder) { + if (source instanceof CraftPersistentDataContainer craftPDC) { + craftPDC.getRaw().forEach((key, nmsTag) -> builder.put(key, Converter.convertTag(nmsTag))); + } else { + throw new IllegalArgumentException("PersistentDataContainer is not a CraftPersistentDataContainer"); + } + } + + @Override + public PersistentDataContainer extractCompoundMapIntoCraftPDC(CompoundBinaryTag source) { + CraftPersistentDataContainer container = new CraftPersistentDataContainer(REGISTRY); + source.forEach(entry -> container.put(entry.getKey(), Converter.convertTag(entry.getValue()))); + return container; + } + @Override public boolean loadOverworldOverride() { if (defaultWorld == null) { @@ -180,7 +200,7 @@ private SlimeLevelInstance createCustomWorld(SlimeWorld world, @Nullable Resourc // level.setReady(true); level.setSpawnSettings(world.getPropertyMap().getValue(SlimeProperties.ALLOW_MONSTERS), world.getPropertyMap().getValue(SlimeProperties.ALLOW_ANIMALS)); - var nmsExtraData = (CompoundTag) Converter.convertTag(world.getExtraData()); + CompoundTag nmsExtraData = (CompoundTag) Converter.convertTag(CompoundBinaryTag.from(world.getExtraData())); //Attempt to read PDC if (nmsExtraData.get("BukkitValues") != null) level.getWorld().readBukkitValues(nmsExtraData.get("BukkitValues")); diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java index da5dfb98f..25249743c 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java @@ -10,6 +10,8 @@ import net.minecraft.SharedConstants; import net.minecraft.server.level.ChunkHolder; import net.minecraft.world.level.chunk.LevelChunk; +import org.bukkit.persistence.PersistentDataContainer; +import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.util.Collection; @@ -90,4 +92,9 @@ public SlimeWorld clone(String worldName, SlimeLoader loader) throws WorldAlread public int getDataVersion() { return SharedConstants.getCurrentVersion().getDataVersion().getVersion(); } + + @Override + public @NotNull PersistentDataContainer getPersistentDataContainer() { + return this.memoryWorld.getPersistentDataContainer(); + } } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java index 387954aae..70787a7b8 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -4,6 +4,7 @@ import com.infernalsuite.asp.Converter; import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.pdc.AdventurePersistentDataContainer; import com.infernalsuite.asp.serialization.slime.SlimeSerializer; import com.infernalsuite.asp.skeleton.SkeletonCloning; import com.infernalsuite.asp.skeleton.SkeletonSlimeWorld; @@ -20,6 +21,8 @@ import net.minecraft.world.level.material.Fluid; import net.minecraft.world.ticks.LevelChunkTicks; import org.bukkit.World; +import org.bukkit.persistence.PersistentDataContainer; +import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.util.ArrayList; @@ -40,6 +43,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { private final SlimeWorld liveWorld; private final ConcurrentMap extra; + private final AdventurePersistentDataContainer extraPDC; private final SlimePropertyMap propertyMap; private final SlimeLoader loader; @@ -62,6 +66,7 @@ public SlimeInMemoryWorld(SlimeBootstrap bootstrap, SlimeLevelInstance instance) this.chunkStorage.put(pos, initial); } + this.extraPDC = new AdventurePersistentDataContainer(this.extra); this.liveWorld = new NMSSlimeWorld(this); } @@ -241,13 +246,12 @@ public SlimeWorld getForSerialization() { // Serialize Bukkit Values (PDC) var nmsTag = new net.minecraft.nbt.CompoundTag(); - - instance.getWorld().storeBukkitValues(nmsTag); + this.instance.getWorld().storeBukkitValues(nmsTag); // Bukkit stores the relevant tag as a tag with the key "BukkitValues" in the tag we supply to it - var flowTag = Converter.convertTag("BukkitValues", nmsTag.getCompound("BukkitValues")); + var adventureTag = Converter.convertTag(nmsTag.getCompound("BukkitValues")); - world.getExtraData().getValue().put(flowTag); + world.getExtraData().put("BukkitValues", adventureTag); return new SkeletonSlimeWorld(world.getName(), world.getLoader(), @@ -262,4 +266,9 @@ public SlimeWorld getForSerialization() { public SlimeLevelInstance getInstance() { return instance; } + + @Override + public @NotNull PersistentDataContainer getPersistentDataContainer() { + return this.extraPDC; + } } diff --git a/patches/server/0007-Make-SlimeWorld-a-PersistentDataHolder.patch b/patches/server/0007-Make-SlimeWorld-a-PersistentDataHolder.patch deleted file mode 100644 index fc9588079..000000000 --- a/patches/server/0007-Make-SlimeWorld-a-PersistentDataHolder.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: kyngs -Date: Thu, 26 Oct 2023 14:55:39 +0200 -Subject: [PATCH] Make SlimeWorld a PersistentDataHolder - - -diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -index 68240b46ce911674ed288fe559737572fa44de6a..7b702b41a1bc589bf405ea280b8fc1c744012081 100644 ---- a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -+++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -@@ -8,7 +8,7 @@ import com.infernalsuite.asp.level.SlimeBootstrap; - import com.infernalsuite.asp.level.SlimeInMemoryWorld; - import com.infernalsuite.asp.level.SlimeLevelInstance; - import com.mojang.serialization.Lifecycle; --import net.kyori.adventure.util.Services; -+import net.kyori.adventure.nbt.CompoundBinaryTag; - import net.minecraft.SharedConstants; - import net.minecraft.core.registries.Registries; - import net.minecraft.nbt.CompoundTag; -@@ -30,6 +30,9 @@ import org.apache.logging.log4j.Logger; - import org.bukkit.Bukkit; - import org.bukkit.World; - import org.bukkit.craftbukkit.CraftWorld; -+import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer; -+import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry; -+import org.bukkit.persistence.PersistentDataContainer; - import org.jetbrains.annotations.Nullable; - - import java.io.IOException; -@@ -37,6 +40,7 @@ import java.util.Locale; - - public class SlimeNMSBridgeImpl implements SlimeNMSBridge { - -+ private static final CraftPersistentDataTypeRegistry REGISTRY = new CraftPersistentDataTypeRegistry(); - private static final SimpleDataFixerConverter DATA_FIXER_CONVERTER = new SimpleDataFixerConverter(); - - private static final Logger LOGGER = LogManager.getLogger("ASP"); -@@ -49,6 +53,22 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { - return (SlimeNMSBridgeImpl) SlimeNMSBridge.instance(); - } - -+ @Override -+ public void extractCraftPDC(PersistentDataContainer source, CompoundBinaryTag.Builder builder) { -+ if (source instanceof CraftPersistentDataContainer craftPDC) { -+ craftPDC.getRaw().forEach((key, nmsTag) -> builder.put(key, Converter.convertTag(nmsTag))); -+ } else { -+ throw new IllegalArgumentException("PersistentDataContainer is not a CraftPersistentDataContainer"); -+ } -+ } -+ -+ @Override -+ public PersistentDataContainer extractCompoundMapIntoCraftPDC(CompoundBinaryTag source) { -+ CraftPersistentDataContainer container = new CraftPersistentDataContainer(REGISTRY); -+ source.forEach(entry -> container.put(entry.getKey(), Converter.convertTag(entry.getValue()))); -+ return container; -+ } -+ - @Override - public boolean loadOverworldOverride() { - if (defaultWorld == null) { -@@ -179,7 +199,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { - // level.setReady(true); - level.setSpawnSettings(world.getPropertyMap().getValue(SlimeProperties.ALLOW_MONSTERS), world.getPropertyMap().getValue(SlimeProperties.ALLOW_ANIMALS)); - -- var nmsExtraData = (CompoundTag) Converter.convertTag(world.getExtraData()); -+ CompoundTag nmsExtraData = (CompoundTag) Converter.convertTag(CompoundBinaryTag.from(world.getExtraData())); - - //Attempt to read PDC - if (nmsExtraData.get("BukkitValues") != null) level.getWorld().readBukkitValues(nmsExtraData.get("BukkitValues")); -diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java -index 41119f2b0d208718c294076dc3c51f55680b0257..25249743caca6f354005d7f9e4498fdf413df629 100644 ---- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java -+++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java -@@ -10,6 +10,8 @@ import net.kyori.adventure.nbt.CompoundBinaryTag; - import net.minecraft.SharedConstants; - import net.minecraft.server.level.ChunkHolder; - import net.minecraft.world.level.chunk.LevelChunk; -+import org.bukkit.persistence.PersistentDataContainer; -+import org.jetbrains.annotations.NotNull; - - import java.io.IOException; - import java.util.Collection; -@@ -90,4 +92,9 @@ public class NMSSlimeWorld implements SlimeWorld { - public int getDataVersion() { - return SharedConstants.getCurrentVersion().getDataVersion().getVersion(); - } --} -\ No newline at end of file -+ -+ @Override -+ public @NotNull PersistentDataContainer getPersistentDataContainer() { -+ return this.memoryWorld.getPersistentDataContainer(); -+ } -+} -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -index 387954aae7ef1a39025a474ab1fe81b7216d8d6c..70787a7b87a0ebb4d47de7d110fadc8952708c58 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -4,6 +4,7 @@ import com.infernalsuite.asp.ChunkPos; - import com.infernalsuite.asp.Converter; - import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; - import com.infernalsuite.asp.api.loaders.SlimeLoader; -+import com.infernalsuite.asp.pdc.AdventurePersistentDataContainer; - import com.infernalsuite.asp.serialization.slime.SlimeSerializer; - import com.infernalsuite.asp.skeleton.SkeletonCloning; - import com.infernalsuite.asp.skeleton.SkeletonSlimeWorld; -@@ -20,6 +21,8 @@ import net.minecraft.world.level.chunk.UpgradeData; - import net.minecraft.world.level.material.Fluid; - import net.minecraft.world.ticks.LevelChunkTicks; - import org.bukkit.World; -+import org.bukkit.persistence.PersistentDataContainer; -+import org.jetbrains.annotations.NotNull; - - import java.io.IOException; - import java.util.ArrayList; -@@ -40,6 +43,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - private final SlimeWorld liveWorld; - - private final ConcurrentMap extra; -+ private final AdventurePersistentDataContainer extraPDC; - private final SlimePropertyMap propertyMap; - private final SlimeLoader loader; - -@@ -62,6 +66,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - this.chunkStorage.put(pos, initial); - } - -+ this.extraPDC = new AdventurePersistentDataContainer(this.extra); - this.liveWorld = new NMSSlimeWorld(this); - } - -@@ -241,13 +246,12 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - // Serialize Bukkit Values (PDC) - - var nmsTag = new net.minecraft.nbt.CompoundTag(); -- -- instance.getWorld().storeBukkitValues(nmsTag); -+ this.instance.getWorld().storeBukkitValues(nmsTag); - - // Bukkit stores the relevant tag as a tag with the key "BukkitValues" in the tag we supply to it -- var flowTag = Converter.convertTag("BukkitValues", nmsTag.getCompound("BukkitValues")); -+ var adventureTag = Converter.convertTag(nmsTag.getCompound("BukkitValues")); - -- world.getExtraData().getValue().put(flowTag); -+ world.getExtraData().put("BukkitValues", adventureTag); - - return new SkeletonSlimeWorld(world.getName(), - world.getLoader(), -@@ -262,4 +266,9 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - public SlimeLevelInstance getInstance() { - return instance; - } -+ -+ @Override -+ public @NotNull PersistentDataContainer getPersistentDataContainer() { -+ return this.extraPDC; -+ } - } From d1a2d6fa7c9759d97d673c75a519835cbab518e6 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 13:36:02 +0100 Subject: [PATCH 043/133] Port "Add v12, chunk pdc and extra nbt. Fix double compression on tile entities and entities. Fix horrible bug which made chunks go poof." by kyngs from 19 Dec 2023 --- .../asp/SimpleDataFixerConverter.java | 5 +- .../asp/level/NMSSlimeChunk.java | 9 +- .../asp/level/NMSSlimeWorld.java | 4 +- .../asp/level/SafeNmsChunkWrapper.java | 9 + .../asp/level/SlimeChunkConverter.java | 7 + .../asp/level/SlimeInMemoryWorld.java | 16 +- .../asp/level/SlimeLevelInstance.java | 2 - ...c-and-extra-nbt.-Fix-double-compress.patch | 192 ------------------ 8 files changed, 40 insertions(+), 204 deletions(-) delete mode 100644 patches/server/0008-Add-v12-chunk-pdc-and-extra-nbt.-Fix-double-compress.patch diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java index d38fea59d..45282b733 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java @@ -66,13 +66,14 @@ public SlimeWorld readFromData(SlimeWorld data) { ); } - chunks.put(new ChunkPos(chunk.getX(), chunk.getZ()), new SlimeChunkSkeleton( + chunks.put(chunkPos, new SlimeChunkSkeleton( chunk.getX(), chunk.getZ(), sections, chunk.getHeightMaps(), blockEntities, - entities + entities, + chunk.getExtraData() )); } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java index 5913b067e..33c0379c6 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -67,9 +67,11 @@ public class NMSSlimeChunk implements SlimeChunk { } private LevelChunk chunk; + private CompoundBinaryTag extra; - public NMSSlimeChunk(LevelChunk chunk) { + public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference) { this.chunk = chunk; + this.extra = reference == null ? CompoundBinaryTag.empty() : reference.getExtraData(); } @Override @@ -176,6 +178,11 @@ public List getEntities() { return Lists.transform(entities, Converter::convertTag); } + @Override + public CompoundBinaryTag getExtraData() { + return extra; + } + public LevelChunk getChunk() { return chunk; } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java index 25249743c..8cd79bf34 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java @@ -47,14 +47,14 @@ public SlimeChunk getChunk(int x, int z) { return null; } - return new NMSSlimeChunk(chunk); + return new NMSSlimeChunk(chunk, memoryWorld.getChunk(x, z)); } @Override public Collection getChunkStorage() { List chunks = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.instance); // Paper return chunks.stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull) - .map(NMSSlimeChunk::new) + .map((chunkLevel) -> new NMSSlimeChunk(chunkLevel, memoryWorld.getChunk(chunkLevel.getPos().x, chunkLevel.getPos().z))) // This sucks, is there a better way? .collect(Collectors.toList()); } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java index 4ee4d2f00..fd87fc20d 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java @@ -62,6 +62,15 @@ public List getEntities() { return this.wrapper.getEntities(); } + @Override + public CompoundBinaryTag getExtraData() { + if (shouldDefaultBackToSlimeChunk()) { + return this.safety.getExtraData(); + } + + return this.wrapper.getExtraData(); + } + /* Slime chunks can still be requested but not actually loaded, this caused some things to not properly save because they are not "loaded" into the chunk. diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java index b705b3133..05e520256 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java @@ -162,6 +162,13 @@ static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeC Heightmap.primeHeightmaps(nmsChunk, unsetHeightMaps); } + net.minecraft.nbt.CompoundTag nmsExtraData = (net.minecraft.nbt.CompoundTag) Converter.convertTag(chunk.getExtraData()); + + // Attempt to read PDC from the extra tag + if (nmsExtraData.get("ChunkBukkitValues") != null) { + nmsChunk.persistentDataContainer.putAll(nmsExtraData.getCompound("ChunkBukkitValues")); + } + return nmsChunk; } } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java index 70787a7b8..58b548395 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -90,11 +90,11 @@ public LevelChunk promote(int x, int z, SlimeChunk chunk) { levelChunk = new SlimeChunkLevel(this.instance, pos, UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks, 0L, null, null, null); - chunk = new NMSSlimeChunk(levelChunk); + chunk = new NMSSlimeChunk(levelChunk, getChunk(x, z)); } else { levelChunk = SlimeChunkConverter.deserializeSlimeChunk(this.instance, chunk); - chunk = new SafeNmsChunkWrapper(new NMSSlimeChunk(levelChunk), chunk); + chunk = new SafeNmsChunkWrapper(new NMSSlimeChunk(levelChunk, chunk), chunk); } this.chunkStorage.put(new ChunkPos(x, z), chunk); @@ -107,7 +107,7 @@ public void unload(LevelChunk providedChunk) { final int x = providedChunk.locX; final int z = providedChunk.locZ; - SlimeChunk chunk = new NMSSlimeChunk(providedChunk); + SlimeChunk chunk = new NMSSlimeChunk(providedChunk, getChunk(x, z)); if (FastChunkPruner.canBePruned(this.liveWorld, providedChunk)) { this.chunkStorage.remove(new ChunkPos(x, z)); @@ -116,7 +116,7 @@ public void unload(LevelChunk providedChunk) { this.chunkStorage.put(new ChunkPos(x, z), new SlimeChunkSkeleton(chunk.getX(), chunk.getZ(), chunk.getSections(), - chunk.getHeightMaps(), chunk.getTileEntities(), chunk.getEntities())); + chunk.getHeightMaps(), chunk.getTileEntities(), chunk.getEntities(), chunk.getExtraData())); } @Override @@ -229,13 +229,19 @@ public SlimeWorld getForSerialization() { continue; } + // Serialize Bukkit Values (PDC) + + CompoundBinaryTag adventureTag = Converter.convertTag(chunk.persistentDataContainer.toTagCompound()); + clonedChunk.getExtraData().put("ChunkBukkitValues", adventureTag); + clonedChunk = new SlimeChunkSkeleton( clonedChunk.getX(), clonedChunk.getZ(), clonedChunk.getSections(), clonedChunk.getHeightMaps(), clonedChunk.getTileEntities(), - clonedChunk.getEntities() + clonedChunk.getEntities(), + clonedChunk.getExtraData() ); } } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java index 2c593fe63..bbd7a9d65 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -151,9 +151,7 @@ private Future save() { Bukkit.getLogger().log(Level.INFO, "Saving world " + this.slimeInstance.getName() + "..."); long start = System.currentTimeMillis(); - Bukkit.getLogger().log(Level.INFO, "CONVERTING NMS -> SKELETON"); SlimeWorld world = this.slimeInstance.getForSerialization(); - Bukkit.getLogger().log(Level.INFO, "CONVERTED TO SKELETON, PUSHING OFF-THREAD"); return WORLD_SAVER_SERVICE.submit(() -> { try { byte[] serializedWorld = SlimeSerializer.serialize(world); diff --git a/patches/server/0008-Add-v12-chunk-pdc-and-extra-nbt.-Fix-double-compress.patch b/patches/server/0008-Add-v12-chunk-pdc-and-extra-nbt.-Fix-double-compress.patch deleted file mode 100644 index e06b417b2..000000000 --- a/patches/server/0008-Add-v12-chunk-pdc-and-extra-nbt.-Fix-double-compress.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: kyngs -Date: Tue, 19 Dec 2023 21:47:15 +0100 -Subject: [PATCH] Add v12, chunk pdc and extra nbt. Fix double compression on - tile entities and entities. Fix horrible bug which made chunks go poof. - - -diff --git a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -index 6856a7254685b2d005bcb2a91841f53d8743e38d..de83872d147e790cb0fb98f1a407a22927faed28 100644 ---- a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -+++ b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -@@ -69,11 +69,12 @@ class SimpleDataFixerConverter implements SlimeWorldReader { - - chunks.put(chunkPos, new SlimeChunkSkeleton( - chunk.getX(), -- chunk.getX(), -+ chunk.getZ(), - sections, - chunk.getHeightMaps(), - blockEntities, -- entities -+ entities, -+ chunk.getExtraData() - )); - - } -diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -index beb56b2495a52e1fac815de664677d73ce2bbcc3..33c0379c6ac41938296643a294ea362a96e3a5ea 100644 ---- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -+++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -@@ -67,9 +67,11 @@ public class NMSSlimeChunk implements SlimeChunk { - } - - private LevelChunk chunk; -+ private CompoundBinaryTag extra; - -- public NMSSlimeChunk(LevelChunk chunk) { -+ public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference) { - this.chunk = chunk; -+ this.extra = reference == null ? CompoundBinaryTag.empty() : reference.getExtraData(); - } - - @Override -@@ -176,6 +178,11 @@ public class NMSSlimeChunk implements SlimeChunk { - return Lists.transform(entities, Converter::convertTag); - } - -+ @Override -+ public CompoundBinaryTag getExtraData() { -+ return extra; -+ } -+ - public LevelChunk getChunk() { - return chunk; - } -@@ -184,4 +191,4 @@ public class NMSSlimeChunk implements SlimeChunk { - this.chunk = chunk; - } - --} -\ No newline at end of file -+} -diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java -index 25249743caca6f354005d7f9e4498fdf413df629..8cd79bf34a9074d06d342f956165891613ae6cf0 100644 ---- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java -+++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java -@@ -47,14 +47,14 @@ public class NMSSlimeWorld implements SlimeWorld { - return null; - } - -- return new NMSSlimeChunk(chunk); -+ return new NMSSlimeChunk(chunk, memoryWorld.getChunk(x, z)); - } - - @Override - public Collection getChunkStorage() { - List chunks = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.instance); // Paper - return chunks.stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull) -- .map(NMSSlimeChunk::new) -+ .map((chunkLevel) -> new NMSSlimeChunk(chunkLevel, memoryWorld.getChunk(chunkLevel.getPos().x, chunkLevel.getPos().z))) // This sucks, is there a better way? - .collect(Collectors.toList()); - } - -diff --git a/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java b/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java -index fa8254ca4b2eafa4e5669c3e0467ed1f7d4dc159..4ca8d6f40b1e5e7e0f106a6880eaf8afc1128213 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java -+++ b/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java -@@ -62,6 +62,15 @@ public class SafeNmsChunkWrapper implements SlimeChunk { - return this.wrapper.getEntities(); - } - -+ @Override -+ public CompoundBinaryTag getExtraData() { -+ if (shouldDefaultBackToSlimeChunk()) { -+ return this.safety.getExtraData(); -+ } -+ -+ return this.wrapper.getExtraData(); -+ } -+ - /* - Slime chunks can still be requested but not actually loaded, this caused - some things to not properly save because they are not "loaded" into the chunk. -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -index b705b3133634c3696dee766cbfc95380293ccda3..05e520256b3d047a85b98552883044ca6b658b3d 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -@@ -162,6 +162,13 @@ public class SlimeChunkConverter { - Heightmap.primeHeightmaps(nmsChunk, unsetHeightMaps); - } - -+ net.minecraft.nbt.CompoundTag nmsExtraData = (net.minecraft.nbt.CompoundTag) Converter.convertTag(chunk.getExtraData()); -+ -+ // Attempt to read PDC from the extra tag -+ if (nmsExtraData.get("ChunkBukkitValues") != null) { -+ nmsChunk.persistentDataContainer.putAll(nmsExtraData.getCompound("ChunkBukkitValues")); -+ } -+ - return nmsChunk; - } - } -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -index 70787a7b87a0ebb4d47de7d110fadc8952708c58..58b54839576b92e87f6941ab2457c0c0c5469df8 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -90,11 +90,11 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - levelChunk = new SlimeChunkLevel(this.instance, pos, UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks, - 0L, null, null, null); - -- chunk = new NMSSlimeChunk(levelChunk); -+ chunk = new NMSSlimeChunk(levelChunk, getChunk(x, z)); - - } else { - levelChunk = SlimeChunkConverter.deserializeSlimeChunk(this.instance, chunk); -- chunk = new SafeNmsChunkWrapper(new NMSSlimeChunk(levelChunk), chunk); -+ chunk = new SafeNmsChunkWrapper(new NMSSlimeChunk(levelChunk, chunk), chunk); - } - this.chunkStorage.put(new ChunkPos(x, z), chunk); - -@@ -107,7 +107,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - final int x = providedChunk.locX; - final int z = providedChunk.locZ; - -- SlimeChunk chunk = new NMSSlimeChunk(providedChunk); -+ SlimeChunk chunk = new NMSSlimeChunk(providedChunk, getChunk(x, z)); - - if (FastChunkPruner.canBePruned(this.liveWorld, providedChunk)) { - this.chunkStorage.remove(new ChunkPos(x, z)); -@@ -116,7 +116,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - - this.chunkStorage.put(new ChunkPos(x, z), - new SlimeChunkSkeleton(chunk.getX(), chunk.getZ(), chunk.getSections(), -- chunk.getHeightMaps(), chunk.getTileEntities(), chunk.getEntities())); -+ chunk.getHeightMaps(), chunk.getTileEntities(), chunk.getEntities(), chunk.getExtraData())); - } - - @Override -@@ -229,13 +229,19 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - continue; - } - -+ // Serialize Bukkit Values (PDC) -+ -+ CompoundBinaryTag adventureTag = Converter.convertTag(chunk.persistentDataContainer.toTagCompound()); -+ clonedChunk.getExtraData().put("ChunkBukkitValues", adventureTag); -+ - clonedChunk = new SlimeChunkSkeleton( - clonedChunk.getX(), - clonedChunk.getZ(), - clonedChunk.getSections(), - clonedChunk.getHeightMaps(), - clonedChunk.getTileEntities(), -- clonedChunk.getEntities() -+ clonedChunk.getEntities(), -+ clonedChunk.getExtraData() - ); - } - } -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -index b8d789c93f7fef253d6ab0c35dcee37460f275eb..5e3426a632d471aff38de29645fdee291c4931ae 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -@@ -151,9 +151,7 @@ public class SlimeLevelInstance extends ServerLevel { - Bukkit.getLogger().log(Level.INFO, "Saving world " + this.slimeInstance.getName() + "..."); - long start = System.currentTimeMillis(); - -- Bukkit.getLogger().log(Level.INFO, "CONVERTING NMS -> SKELETON"); - SlimeWorld world = this.slimeInstance.getForSerialization(); -- Bukkit.getLogger().log(Level.INFO, "CONVERTED TO SKELETON, PUSHING OFF-THREAD"); - return WORLD_SAVER_SERVICE.submit(() -> { - try { - byte[] serializedWorld = SlimeSerializer.serialize(world); From a0905cd76ad8cc8133a1dd7407967e618c7822b0 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 13:42:07 +0100 Subject: [PATCH 044/133] Port "Add migration from SRF 1-8" by kyngs from 6 Jan 2024 --- .../asp/SimpleDataFixerConverter.java | 15 +- .../infernalsuite/asp/SlimeNMSBridgeImpl.java | 17 ++ .../asp/level/NMSSlimeChunk.java | 9 +- .../asp/level/SafeNmsChunkWrapper.java | 9 + .../asp/level/SlimeChunkConverter.java | 8 +- .../asp/level/SlimeInMemoryWorld.java | 5 +- .../0009-Add-migration-from-SRF-1-8.patch | 213 ------------------ 7 files changed, 54 insertions(+), 222 deletions(-) delete mode 100644 patches/server/0009-Add-migration-from-SRF-1-8.patch diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java index 45282b733..be7c92f46 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java @@ -1,5 +1,6 @@ package com.infernalsuite.asp; +import ca.spottedleaf.dataconverter.converters.DataConverter; import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; import ca.spottedleaf.dataconverter.types.nbt.NBTMapType; @@ -29,18 +30,21 @@ public SlimeWorld readFromData(SlimeWorld data) { return data; } + long encodedNewVersion = DataConverter.encodeVersions(newVersion, Integer.MAX_VALUE); + long encodedCurrentVersion = DataConverter.encodeVersions(currentVersion, Integer.MAX_VALUE); + Map chunks = new HashMap<>(); for (SlimeChunk chunk : data.getChunkStorage()) { List entities = new ArrayList<>(); List blockEntities = new ArrayList<>(); for (CompoundBinaryTag upgradeEntity : chunk.getTileEntities()) { blockEntities.add( - convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.TILE_ENTITY.convert(new NBTMapType(tag), currentVersion, newVersion)) + convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.TILE_ENTITY.convert(new NBTMapType(tag), encodedCurrentVersion, encodedNewVersion)) ); } for (CompoundBinaryTag upgradeEntity : chunk.getEntities()) { entities.add( - convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.ENTITY.convert(new NBTMapType(tag), currentVersion, newVersion)) + convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.ENTITY.convert(new NBTMapType(tag), encodedCurrentVersion, encodedNewVersion)) ); } ChunkPos chunkPos = new ChunkPos(chunk.getX(), chunk.getZ()); @@ -51,11 +55,11 @@ public SlimeWorld readFromData(SlimeWorld data) { if (dataSection == null) continue; CompoundBinaryTag blockStateTag = blockStateTag = convertAndBack(dataSection.getBlockStatesTag(), (tag) -> { - WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, new NBTMapType(tag), "palette", currentVersion, newVersion); + WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, new NBTMapType(tag), "palette", encodedCurrentVersion, encodedNewVersion); }); CompoundBinaryTag biomeTag = convertAndBack(dataSection.getBiomeTag(), (tag) -> { - WalkerUtils.convertList(MCTypeRegistry.BIOME, new NBTMapType(tag), "palette", currentVersion, newVersion); + WalkerUtils.convertList(MCTypeRegistry.BIOME, new NBTMapType(tag), "palette", encodedCurrentVersion, encodedNewVersion); }); sections[i] = new SlimeChunkSectionSkeleton( @@ -73,7 +77,8 @@ public SlimeWorld readFromData(SlimeWorld data) { chunk.getHeightMaps(), blockEntities, entities, - chunk.getExtraData() + chunk.getExtraData(), + chunk.getUpgradeData() )); } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java index 6ae554211..76849052c 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java @@ -1,5 +1,8 @@ package com.infernalsuite.asp; +import ca.spottedleaf.dataconverter.converters.DataConverter; +import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; +import ca.spottedleaf.dataconverter.types.nbt.NBTMapType; import com.infernalsuite.asp.api.SlimeNMSBridge; import com.infernalsuite.asp.api.world.SlimeWorld; import com.infernalsuite.asp.api.world.SlimeWorldInstance; @@ -70,6 +73,20 @@ public PersistentDataContainer extractCompoundMapIntoCraftPDC(CompoundBinaryTag return container; } + @Override + public CompoundBinaryTag convertChunkTo1_13(CompoundBinaryTag tag) { + CompoundTag nmsTag = (CompoundTag) Converter.convertTag(tag); + + int version = nmsTag.getInt("DataVersion"); + + long encodedNewVersion = DataConverter.encodeVersions(1624, Integer.MAX_VALUE); + long encodedCurrentVersion = DataConverter.encodeVersions(version, Integer.MAX_VALUE); + + MCTypeRegistry.CHUNK.convert(new NBTMapType(nmsTag), encodedCurrentVersion, encodedNewVersion); + + return Converter.convertTag(nmsTag); + } + @Override public boolean loadOverworldOverride() { if (defaultWorld == null) { diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java index 33c0379c6..16f8e47aa 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -67,11 +67,13 @@ public class NMSSlimeChunk implements SlimeChunk { } private LevelChunk chunk; - private CompoundBinaryTag extra; + private final CompoundBinaryTag extra; + private final CompoundBinaryTag upgradeData; public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference) { this.chunk = chunk; this.extra = reference == null ? CompoundBinaryTag.empty() : reference.getExtraData(); + this.upgradeData = reference == null ? null : reference.getUpgradeData(); } @Override @@ -183,6 +185,11 @@ public CompoundBinaryTag getExtraData() { return extra; } + @Override + public CompoundBinaryTag getUpgradeData() { + return upgradeData; + } + public LevelChunk getChunk() { return chunk; } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java index fd87fc20d..1cbfd90a5 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java @@ -71,6 +71,15 @@ public CompoundBinaryTag getExtraData() { return this.wrapper.getExtraData(); } + @Override + public CompoundBinaryTag getUpgradeData() { + if (shouldDefaultBackToSlimeChunk()) { + return this.safety.getUpgradeData(); + } + + return this.wrapper.getUpgradeData(); + } + /* Slime chunks can still be requested but not actually loaded, this caused some things to not properly save because they are not "loaded" into the chunk. diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java index 05e520256..1149f444e 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java @@ -116,7 +116,13 @@ static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeC LevelChunkTicks blockLevelChunkTicks = new LevelChunkTicks<>(); LevelChunkTicks fluidLevelChunkTicks = new LevelChunkTicks<>(); - SlimeChunkLevel nmsChunk = new SlimeChunkLevel(instance, pos, UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks, 0L, sections, loadEntities, null); + UpgradeData upgradeData; + if (chunk.getUpgradeData() != null) { + upgradeData = new UpgradeData((net.minecraft.nbt.CompoundTag) Converter.convertTag(chunk.getUpgradeData()), instance); + } else { + upgradeData = UpgradeData.EMPTY; + } + SlimeChunkLevel nmsChunk = new SlimeChunkLevel(instance, pos, upgradeData, blockLevelChunkTicks, fluidLevelChunkTicks, 0L, sections, loadEntities, null); List tileEntities = chunk.getTileEntities(); diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java index 58b548395..03d9c9448 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -116,7 +116,7 @@ public void unload(LevelChunk providedChunk) { this.chunkStorage.put(new ChunkPos(x, z), new SlimeChunkSkeleton(chunk.getX(), chunk.getZ(), chunk.getSections(), - chunk.getHeightMaps(), chunk.getTileEntities(), chunk.getEntities(), chunk.getExtraData())); + chunk.getHeightMaps(), chunk.getTileEntities(), chunk.getEntities(), chunk.getExtraData(), null)); } @Override @@ -241,7 +241,8 @@ public SlimeWorld getForSerialization() { clonedChunk.getHeightMaps(), clonedChunk.getTileEntities(), clonedChunk.getEntities(), - clonedChunk.getExtraData() + clonedChunk.getExtraData(), + clonedChunk.getUpgradeData() ); } } diff --git a/patches/server/0009-Add-migration-from-SRF-1-8.patch b/patches/server/0009-Add-migration-from-SRF-1-8.patch deleted file mode 100644 index bae4cf22f..000000000 --- a/patches/server/0009-Add-migration-from-SRF-1-8.patch +++ /dev/null @@ -1,213 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: kyngs -Date: Sat, 6 Jan 2024 22:23:55 +0100 -Subject: [PATCH] Add migration from SRF 1-8 - - -diff --git a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -index de83872d147e790cb0fb98f1a407a22927faed28..ec45c627df14a87087e39556cb90eb2d5b52a981 100644 ---- a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -+++ b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -@@ -1,5 +1,6 @@ - package com.infernalsuite.asp; - -+import ca.spottedleaf.dataconverter.converters.DataConverter; - import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; - import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; - import ca.spottedleaf.dataconverter.types.nbt.NBTMapType; -@@ -29,18 +30,21 @@ class SimpleDataFixerConverter implements SlimeWorldReader { - return data; - } - -+ long encodedNewVersion = DataConverter.encodeVersions(newVersion, Integer.MAX_VALUE); -+ long encodedCurrentVersion = DataConverter.encodeVersions(currentVersion, Integer.MAX_VALUE); -+ - Map chunks = new HashMap<>(); - for (SlimeChunk chunk : data.getChunkStorage()) { - List entities = new ArrayList<>(); - List blockEntities = new ArrayList<>(); - for (CompoundBinaryTag upgradeEntity : chunk.getTileEntities()) { - blockEntities.add( -- convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.TILE_ENTITY.convert(new NBTMapType(tag), currentVersion, newVersion)) -+ convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.TILE_ENTITY.convert(new NBTMapType(tag), encodedCurrentVersion, encodedNewVersion)) - ); - } - for (CompoundBinaryTag upgradeEntity : chunk.getEntities()) { - entities.add( -- convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.ENTITY.convert(new NBTMapType(tag), currentVersion, newVersion)) -+ convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.ENTITY.convert(new NBTMapType(tag), encodedCurrentVersion, encodedNewVersion)) - ); - } - -@@ -52,11 +56,11 @@ class SimpleDataFixerConverter implements SlimeWorldReader { - if (dataSection == null) continue; - - CompoundBinaryTag blockStateTag = blockStateTag = convertAndBack(dataSection.getBlockStatesTag(), (tag) -> { -- WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, new NBTMapType(tag), "palette", currentVersion, newVersion); -+ WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, new NBTMapType(tag), "palette", encodedCurrentVersion, encodedNewVersion); - }); - - CompoundBinaryTag biomeTag = convertAndBack(dataSection.getBiomeTag(), (tag) -> { -- WalkerUtils.convertList(MCTypeRegistry.BIOME, new NBTMapType(tag), "palette", currentVersion, newVersion); -+ WalkerUtils.convertList(MCTypeRegistry.BIOME, new NBTMapType(tag), "palette", encodedCurrentVersion, encodedNewVersion); - }); - - sections[i] = new SlimeChunkSectionSkeleton( -@@ -74,7 +78,8 @@ class SimpleDataFixerConverter implements SlimeWorldReader { - chunk.getHeightMaps(), - blockEntities, - entities, -- chunk.getExtraData() -+ chunk.getExtraData(), -+ chunk.getUpgradeData() - )); - - } -diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -index 7b702b41a1bc589bf405ea280b8fc1c744012081..95b4d139125f18414638c2b17266c6400a62bcf5 100644 ---- a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -+++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -@@ -1,5 +1,8 @@ - package com.infernalsuite.asp; - -+import ca.spottedleaf.dataconverter.converters.DataConverter; -+import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; -+import ca.spottedleaf.dataconverter.types.nbt.NBTMapType; - import com.infernalsuite.asp.api.SlimeNMSBridge; - import com.infernalsuite.asp.api.world.SlimeWorld; - import com.infernalsuite.asp.api.world.SlimeWorldInstance; -@@ -69,6 +72,20 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { - return container; - } - -+ @Override -+ public CompoundBinaryTag convertChunkTo1_13(CompoundBinaryTag tag) { -+ CompoundTag nmsTag = (CompoundTag) Converter.convertTag(tag); -+ -+ int version = nmsTag.getInt("DataVersion"); -+ -+ long encodedNewVersion = DataConverter.encodeVersions(1624, Integer.MAX_VALUE); -+ long encodedCurrentVersion = DataConverter.encodeVersions(version, Integer.MAX_VALUE); -+ -+ MCTypeRegistry.CHUNK.convert(new NBTMapType(nmsTag), encodedCurrentVersion, encodedNewVersion); -+ -+ return Converter.convertTag(nmsTag); -+ } -+ - @Override - public boolean loadOverworldOverride() { - if (defaultWorld == null) { -@@ -159,7 +176,6 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { - return DATA_FIXER_CONVERTER.readFromData(world); - } - -- - @Override - public int getCurrentVersion() { - return SharedConstants.getCurrentVersion().getDataVersion().getVersion(); -diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -index 33c0379c6ac41938296643a294ea362a96e3a5ea..4c627f8af92f29d9ba50745812acc83726a85683 100644 ---- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -+++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -@@ -26,10 +26,7 @@ import net.minecraft.world.level.block.Block; - import net.minecraft.world.level.block.Blocks; - import net.minecraft.world.level.block.entity.BlockEntity; - import net.minecraft.world.level.block.state.BlockState; --import net.minecraft.world.level.chunk.LevelChunk; --import net.minecraft.world.level.chunk.LevelChunkSection; --import net.minecraft.world.level.chunk.PalettedContainer; --import net.minecraft.world.level.chunk.PalettedContainerRO; -+import net.minecraft.world.level.chunk.*; - import net.minecraft.world.level.chunk.storage.ChunkSerializer; - import net.minecraft.world.level.levelgen.Heightmap; - import net.minecraft.world.level.lighting.LevelLightEngine; -@@ -67,11 +64,13 @@ public class NMSSlimeChunk implements SlimeChunk { - } - - private LevelChunk chunk; -- private CompoundBinaryTag extra; -+ private final CompoundBinaryTag extra; -+ private final CompoundBinaryTag upgradeData; - - public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference) { - this.chunk = chunk; - this.extra = reference == null ? CompoundBinaryTag.empty() : reference.getExtraData(); -+ this.upgradeData = reference == null ? null : reference.getUpgradeData(); - } - - @Override -@@ -183,6 +182,11 @@ public class NMSSlimeChunk implements SlimeChunk { - return extra; - } - -+ @Override -+ public CompoundBinaryTag getUpgradeData() { -+ return upgradeData; -+ } -+ - public LevelChunk getChunk() { - return chunk; - } -diff --git a/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java b/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java -index 4ca8d6f40b1e5e7e0f106a6880eaf8afc1128213..b29c27424081885f10a93ae064d87871156f1f94 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java -+++ b/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java -@@ -71,6 +71,15 @@ public class SafeNmsChunkWrapper implements SlimeChunk { - return this.wrapper.getExtraData(); - } - -+ @Override -+ public CompoundBinaryTag getUpgradeData() { -+ if (shouldDefaultBackToSlimeChunk()) { -+ return this.safety.getUpgradeData(); -+ } -+ -+ return this.wrapper.getUpgradeData(); -+ } -+ - /* - Slime chunks can still be requested but not actually loaded, this caused - some things to not properly save because they are not "loaded" into the chunk. -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -index 05e520256b3d047a85b98552883044ca6b658b3d..39e020135d996a4abb40dc6564d6c985e7bfbeda 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -@@ -116,7 +116,14 @@ public class SlimeChunkConverter { - - LevelChunkTicks blockLevelChunkTicks = new LevelChunkTicks<>(); - LevelChunkTicks fluidLevelChunkTicks = new LevelChunkTicks<>(); -- SlimeChunkLevel nmsChunk = new SlimeChunkLevel(instance, pos, UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks, 0L, sections, loadEntities, null); -+ -+ UpgradeData upgradeData; -+ if (chunk.getUpgradeData() != null) { -+ upgradeData = new UpgradeData((net.minecraft.nbt.CompoundTag) Converter.convertTag(chunk.getUpgradeData()), instance); -+ } else { -+ upgradeData = UpgradeData.EMPTY; -+ } -+ SlimeChunkLevel nmsChunk = new SlimeChunkLevel(instance, pos, upgradeData, blockLevelChunkTicks, fluidLevelChunkTicks, 0L, sections, loadEntities, null); - - List tileEntities = chunk.getTileEntities(); - -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -index 58b54839576b92e87f6941ab2457c0c0c5469df8..03d9c9448d7c010f5daf69cabce6bf861ea203aa 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -116,7 +116,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - - this.chunkStorage.put(new ChunkPos(x, z), - new SlimeChunkSkeleton(chunk.getX(), chunk.getZ(), chunk.getSections(), -- chunk.getHeightMaps(), chunk.getTileEntities(), chunk.getEntities(), chunk.getExtraData())); -+ chunk.getHeightMaps(), chunk.getTileEntities(), chunk.getEntities(), chunk.getExtraData(), null)); - } - - @Override -@@ -241,7 +241,8 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - clonedChunk.getHeightMaps(), - clonedChunk.getTileEntities(), - clonedChunk.getEntities(), -- clonedChunk.getExtraData() -+ clonedChunk.getExtraData(), -+ clonedChunk.getUpgradeData() - ); - } - } From 4ab063bbf287b8d2ab20144762fd29c280e8d813 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 13:43:34 +0100 Subject: [PATCH 045/133] Port "Add default spawn yaw, propagate CraftWorld#setSpawnLocation" by kyngs from 18 May 2024 --- .../asp/level/SlimeLevelInstance.java | 17 +++++++- ...n-yaw-propagate-CraftWorld-setSpawnL.patch | 42 ------------------- 2 files changed, 16 insertions(+), 43 deletions(-) delete mode 100644 patches/server/0010-Add-default-spawn-yaw-propagate-CraftWorld-setSpawnL.patch diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java index bbd7a9d65..31317303d 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -95,7 +95,11 @@ public SlimeLevelInstance(SlimeBootstrap slimeBootstrap, PrimaryLevelData primar SlimePropertyMap propertyMap = slimeBootstrap.initial().getPropertyMap(); this.serverLevelData.setDifficulty(Difficulty.valueOf(propertyMap.getValue(SlimeProperties.DIFFICULTY).toUpperCase())); - this.serverLevelData.setSpawn(new BlockPos(propertyMap.getValue(SlimeProperties.SPAWN_X), propertyMap.getValue(SlimeProperties.SPAWN_Y), propertyMap.getValue(SlimeProperties.SPAWN_Z)), 0); + this.serverLevelData.setSpawn(new BlockPos( + propertyMap.getValue(SlimeProperties.SPAWN_X), + propertyMap.getValue(SlimeProperties.SPAWN_Y), + propertyMap.getValue(SlimeProperties.SPAWN_Z)), + propertyMap.getValue(SlimeProperties.SPAWN_YAW)); super.setSpawnSettings(propertyMap.getValue(SlimeProperties.ALLOW_MONSTERS), propertyMap.getValue(SlimeProperties.ALLOW_ANIMALS)); this.pvpMode = propertyMap.getValue(SlimeProperties.PVP); @@ -187,6 +191,17 @@ public void loadEntities(int chunkX, int chunkZ) { } } + @Override + public void setDefaultSpawnPos(BlockPos pos, float angle) { + super.setDefaultSpawnPos(pos, angle); + + SlimePropertyMap propertyMap = this.slimeInstance.getPropertyMap(); + propertyMap.setValue(SlimeProperties.SPAWN_X, pos.getX()); + propertyMap.setValue(SlimeProperties.SPAWN_Y, pos.getY()); + propertyMap.setValue(SlimeProperties.SPAWN_Z, pos.getZ()); + propertyMap.setValue(SlimeProperties.SPAWN_YAW, angle); + } + // @Override // public void unload(LevelChunk chunk) { // this.slimeInstance.unload(chunk); diff --git a/patches/server/0010-Add-default-spawn-yaw-propagate-CraftWorld-setSpawnL.patch b/patches/server/0010-Add-default-spawn-yaw-propagate-CraftWorld-setSpawnL.patch deleted file mode 100644 index 4798b9012..000000000 --- a/patches/server/0010-Add-default-spawn-yaw-propagate-CraftWorld-setSpawnL.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: kyngs -Date: Sat, 18 May 2024 20:34:06 +0200 -Subject: [PATCH] Add default spawn yaw, propagate CraftWorld#setSpawnLocation - to the SlimeProperties. - - -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -index 5e3426a632d471aff38de29645fdee291c4931ae..eddae8fc510d6e263df55a725148d96f677bcb0b 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -@@ -95,7 +95,11 @@ public class SlimeLevelInstance extends ServerLevel { - SlimePropertyMap propertyMap = slimeBootstrap.initial().getPropertyMap(); - - this.serverLevelData.setDifficulty(Difficulty.valueOf(propertyMap.getValue(SlimeProperties.DIFFICULTY).toUpperCase())); -- this.serverLevelData.setSpawn(new BlockPos(propertyMap.getValue(SlimeProperties.SPAWN_X), propertyMap.getValue(SlimeProperties.SPAWN_Y), propertyMap.getValue(SlimeProperties.SPAWN_Z)), 0); -+ this.serverLevelData.setSpawn(new BlockPos( -+ propertyMap.getValue(SlimeProperties.SPAWN_X), -+ propertyMap.getValue(SlimeProperties.SPAWN_Y), -+ propertyMap.getValue(SlimeProperties.SPAWN_Z)), -+ propertyMap.getValue(SlimeProperties.SPAWN_YAW)); - super.setSpawnSettings(propertyMap.getValue(SlimeProperties.ALLOW_MONSTERS), propertyMap.getValue(SlimeProperties.ALLOW_ANIMALS)); - - this.pvpMode = propertyMap.getValue(SlimeProperties.PVP); -@@ -187,6 +191,17 @@ public class SlimeLevelInstance extends ServerLevel { - } - } - -+ @Override -+ public void setDefaultSpawnPos(BlockPos pos, float angle) { -+ super.setDefaultSpawnPos(pos, angle); -+ -+ SlimePropertyMap propertyMap = this.slimeInstance.getPropertyMap(); -+ propertyMap.setValue(SlimeProperties.SPAWN_X, pos.getX()); -+ propertyMap.setValue(SlimeProperties.SPAWN_Y, pos.getY()); -+ propertyMap.setValue(SlimeProperties.SPAWN_Z, pos.getZ()); -+ propertyMap.setValue(SlimeProperties.SPAWN_YAW, angle); -+ } -+ - // @Override - // public void unload(LevelChunk chunk) { - // this.slimeInstance.unload(chunk); From c65654913c349ed17e8576acd18cb9dd06271ba5 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 13:44:56 +0100 Subject: [PATCH 046/133] Port "Fix chunks not getting serialized when reloaded." by kyngs from 19 May 2024 --- .../asp/level/SlimeChunkLevel.java | 6 +++ .../asp/level/SlimeInMemoryWorld.java | 8 +++- ...not-getting-serialized-when-reloaded.patch | 46 ------------------- 3 files changed, 13 insertions(+), 47 deletions(-) delete mode 100644 patches/server/0011-Fix-chunks-not-getting-serialized-when-reloaded.patch diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java index 397a655a6..6e711d9d7 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java @@ -24,4 +24,10 @@ public void unloadCallback() { super.unloadCallback(); this.inMemoryWorld.unload(this); } + + @Override + public void loadCallback() { + super.loadCallback(); + this.inMemoryWorld.ensureChunkMarkedAsLoaded(this); + } } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java index 03d9c9448..8fcb0ab62 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -220,7 +220,7 @@ public SlimeWorld getForSerialization() { } else { chunk = safeNmsChunkWrapper.getWrapper().getChunk(); } - } else if (clonedChunk instanceof NMSSlimeChunk nmsSlimeChunk) { + } else if (clonedChunk instanceof NMSSlimeChunk nmsSlimeChunk) { chunk = nmsSlimeChunk.getChunk(); } @@ -278,4 +278,10 @@ public SlimeLevelInstance getInstance() { public @NotNull PersistentDataContainer getPersistentDataContainer() { return this.extraPDC; } + + public void ensureChunkMarkedAsLoaded(SlimeChunkLevel chunk) { + if (chunkStorage.get(new ChunkPos(chunk.locX, chunk.locZ)) instanceof SlimeChunkSkeleton skeleton) { + chunkStorage.put(new ChunkPos(chunk.locX, chunk.locZ), new NMSSlimeChunk(chunk, skeleton)); + } + } } diff --git a/patches/server/0011-Fix-chunks-not-getting-serialized-when-reloaded.patch b/patches/server/0011-Fix-chunks-not-getting-serialized-when-reloaded.patch deleted file mode 100644 index 96837ed92..000000000 --- a/patches/server/0011-Fix-chunks-not-getting-serialized-when-reloaded.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: kyngs -Date: Sun, 19 May 2024 19:17:07 +0200 -Subject: [PATCH] Fix chunks not getting serialized when reloaded. - - -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java -index 0d218911fb8be1bc5272b6e291ec60404306c831..a92d17b5c6a7c8427ecbdf56a9c2a0c1b66978e4 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java -@@ -24,4 +24,10 @@ public class SlimeChunkLevel extends LevelChunk { - super.unloadCallback(); - this.inMemoryWorld.unload(this); - } -+ -+ @Override -+ public void loadCallback() { -+ super.loadCallback(); -+ this.inMemoryWorld.ensureChunkMarkedAsLoaded(this); -+ } - } -\ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -index 03d9c9448d7c010f5daf69cabce6bf861ea203aa..8fcb0ab62ce098a07cc5a0d3b481a45e9f75e161 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -220,7 +220,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - } else { - chunk = safeNmsChunkWrapper.getWrapper().getChunk(); - } -- } else if (clonedChunk instanceof NMSSlimeChunk nmsSlimeChunk) { -+ } else if (clonedChunk instanceof NMSSlimeChunk nmsSlimeChunk) { - chunk = nmsSlimeChunk.getChunk(); - } - -@@ -278,4 +278,10 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - public @NotNull PersistentDataContainer getPersistentDataContainer() { - return this.extraPDC; - } -+ -+ public void ensureChunkMarkedAsLoaded(SlimeChunkLevel chunk) { -+ if (chunkStorage.get(new ChunkPos(chunk.locX, chunk.locZ)) instanceof SlimeChunkSkeleton skeleton) { -+ chunkStorage.put(new ChunkPos(chunk.locX, chunk.locZ), new NMSSlimeChunk(chunk, skeleton)); -+ } -+ } - } From 7a6751eb5815a60b48a8bced1fba766333484553 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 14:22:41 +0100 Subject: [PATCH 047/133] Port "Compile fixes" by AverageGithub from 4 May 2024 --- .../asp/level/NMSSlimeChunk.java | 14 +- .../asp/level/SlimeChunkConverter.java | 6 +- .../asp/level/SlimeLevelInstance.java | 4 +- patches/server/0012-Compile-fixes.patch | 146 ------------------ 4 files changed, 9 insertions(+), 161 deletions(-) delete mode 100644 patches/server/0012-Compile-fixes.patch diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java index 16f8e47aa..6fcd1878c 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -49,18 +49,14 @@ public class NMSSlimeChunk implements SlimeChunk { static { { PalettedContainer empty = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, null); - Tag tag = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, empty).getOrThrow(false, (error) -> { - throw new AssertionError(error); - }); + Tag tag = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); EMPTY_BLOCK_STATE_PALETTE = Converter.convertTag(tag); } { Registry biomes = net.minecraft.server.MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME); PalettedContainer> empty = new PalettedContainer<>(biomes.asHolderIdMap(), biomes.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); - Tag tag = ChunkSerializer.makeBiomeCodec(biomes).encodeStart(NbtOps.INSTANCE, empty).getOrThrow(false, (error) -> { - throw new AssertionError(error); - }); + Tag tag = ChunkSerializer.makeBiomeCodec(biomes).encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); EMPTY_BIOME_PALETTE = Converter.convertTag(tag); } @@ -113,7 +109,7 @@ public SlimeChunkSection[] getSections() { if (section.hasOnlyAir()) { blockStateTag = EMPTY_BLOCK_STATE_PALETTE; } else { - Tag data = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, section.getStates()).getOrThrow(false, System.err::println); // todo error handling + Tag data = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, section.getStates()).getOrThrow(); // todo error handling blockStateTag = Converter.convertTag(data); } @@ -123,7 +119,7 @@ public SlimeChunkSection[] getSections() { if (biomes.data.palette().getSize() == 1 && biomes.data.palette().maybeHas((h) -> h.is(Biomes.PLAINS))) { biomeTag = EMPTY_BIOME_PALETTE; } else { - Tag biomeData = codec.encodeStart(NbtOps.INSTANCE, section.getBiomes()).getOrThrow(false, System.err::println); // todo error handling + Tag biomeData = codec.encodeStart(NbtOps.INSTANCE, section.getBiomes()).getOrThrow(); // todo error handling biomeTag = Converter.convertTag(biomeData); } @@ -151,7 +147,7 @@ public List getTileEntities() { List tileEntities = new ArrayList<>(); for (BlockEntity entity : this.chunk.blockEntities.values()) { - CompoundTag entityNbt = entity.saveWithFullMetadata(); + CompoundTag entityNbt = entity.saveWithFullMetadata(net.minecraft.server.MinecraftServer.getServer().registryAccess()); tileEntities.add(entityNbt); } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java index 1149f444e..87a6acfee 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java @@ -76,7 +76,7 @@ static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeC DataResult> dataresult = ChunkSerializer.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, Converter.convertTag(slimeSection.getBlockStatesTag())).promotePartial((s) -> { System.out.println("Recoverable error when parsing section " + x + "," + z + ": " + s); // todo proper logging }); - blockPalette = dataresult.getOrThrow(false, System.err::println); // todo proper logging + blockPalette = dataresult.getOrThrow(); // todo proper logging } else { blockPalette = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, null); } @@ -87,7 +87,7 @@ static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeC DataResult>> dataresult = codec.parse(NbtOps.INSTANCE, Converter.convertTag(slimeSection.getBiomeTag())).promotePartial((s) -> { System.out.println("Recoverable error when parsing section " + x + "," + z + ": " + s); // todo proper logging }); - biomePalette = dataresult.getOrThrow(false, System.err::println); // todo proper logging + biomePalette = dataresult.getOrThrow(); // todo proper logging } else { biomePalette = new PalettedContainer<>(biomeRegistry.asHolderIdMap(), biomeRegistry.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); } @@ -133,7 +133,7 @@ static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeC if (!type.isEmpty()) { BlockPos blockPosition = new BlockPos(tag.getInt("x"), tag.getInt("y"), tag.getInt("z")); BlockState blockData = nmsChunk.getBlockState(blockPosition); - BlockEntity entity = BlockEntity.loadStatic(blockPosition, blockData, (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)); + BlockEntity entity = BlockEntity.loadStatic(blockPosition, blockData, (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag), net.minecraft.server.MinecraftServer.getServer().registryAccess()); if (entity != null) { nmsChunk.setBlockEntity(entity); diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java index 31317303d..5cf264962 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -103,8 +103,6 @@ public SlimeLevelInstance(SlimeBootstrap slimeBootstrap, PrimaryLevelData primar super.setSpawnSettings(propertyMap.getValue(SlimeProperties.ALLOW_MONSTERS), propertyMap.getValue(SlimeProperties.ALLOW_ANIMALS)); this.pvpMode = propertyMap.getValue(SlimeProperties.PVP); - - this.keepSpawnInMemory = false; } @Override @@ -123,7 +121,7 @@ public void save(@Nullable ProgressListener progressUpdate, boolean forceSave, b //this.getChunkSource().save(forceSave); this.serverLevelData.setWorldBorder(this.getWorldBorder().createSettings()); - this.serverLevelData.setCustomBossEvents(MinecraftServer.getServer().getCustomBossEvents().save()); + this.serverLevelData.setCustomBossEvents(MinecraftServer.getServer().getCustomBossEvents().save(MinecraftServer.getServer().registryAccess())); // Update level data net.minecraft.nbt.CompoundTag compound = new net.minecraft.nbt.CompoundTag(); diff --git a/patches/server/0012-Compile-fixes.patch b/patches/server/0012-Compile-fixes.patch deleted file mode 100644 index 7c831a66d..000000000 --- a/patches/server/0012-Compile-fixes.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: AverageGithub -Date: Sat, 4 May 2024 20:18:16 +0200 -Subject: [PATCH] Compile fixes - - -diff --git a/build.gradle.kts b/build.gradle.kts -index f0bfc068301c4a908a5856b7c72e7306adeeb38d..e6414d33e65233836db36040206c32a16b4d10ca 100644 ---- a/build.gradle.kts -+++ b/build.gradle.kts -@@ -29,9 +29,6 @@ dependencies { - // ASWM start - implementation(project(":aspaper-api")) - implementation(project(":core")) -- implementation("io.papermc.paper:paper-mojangapi:1.20.4-R0.1-SNAPSHOT") { -- exclude("io.papermc.paper", "paper-api") -- } - // ASWM end - implementation("ca.spottedleaf:concurrentutil:0.0.2") // Paper - Add ConcurrentUtil dependency - // Paper start -diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -index 4c627f8af92f29d9ba50745812acc83726a85683..6972d6399628eda41756a98fb54fbe93eb827716 100644 ---- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -+++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -@@ -46,18 +46,14 @@ public class NMSSlimeChunk implements SlimeChunk { - static { - { - PalettedContainer empty = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, null); -- Tag tag = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, empty).getOrThrow(false, (error) -> { -- throw new AssertionError(error); -- }); -+ Tag tag = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); - - EMPTY_BLOCK_STATE_PALETTE = Converter.convertTag(tag); - } - { - Registry biomes = net.minecraft.server.MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME); - PalettedContainer> empty = new PalettedContainer<>(biomes.asHolderIdMap(), biomes.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); -- Tag tag = ChunkSerializer.makeBiomeCodec(biomes).encodeStart(NbtOps.INSTANCE, empty).getOrThrow(false, (error) -> { -- throw new AssertionError(error); -- }); -+ Tag tag = ChunkSerializer.makeBiomeCodec(biomes).encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); - - EMPTY_BIOME_PALETTE = Converter.convertTag(tag); - } -@@ -110,7 +106,7 @@ public class NMSSlimeChunk implements SlimeChunk { - if (section.hasOnlyAir()) { - blockStateTag = EMPTY_BLOCK_STATE_PALETTE; - } else { -- Tag data = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, section.getStates()).getOrThrow(false, System.err::println); // todo error handling -+ Tag data = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, section.getStates()).getOrThrow(); // todo error handling - blockStateTag = Converter.convertTag(data); - } - -@@ -120,7 +116,7 @@ public class NMSSlimeChunk implements SlimeChunk { - if (biomes.data.palette().getSize() == 1 && biomes.data.palette().maybeHas((h) -> h.is(Biomes.PLAINS))) { - biomeTag = EMPTY_BIOME_PALETTE; - } else { -- Tag biomeData = codec.encodeStart(NbtOps.INSTANCE, section.getBiomes()).getOrThrow(false, System.err::println); // todo error handling -+ Tag biomeData = codec.encodeStart(NbtOps.INSTANCE, section.getBiomes()).getOrThrow(); // todo error handling - biomeTag = Converter.convertTag(biomeData); - } - -@@ -148,7 +144,7 @@ public class NMSSlimeChunk implements SlimeChunk { - List tileEntities = new ArrayList<>(); - - for (BlockEntity entity : this.chunk.blockEntities.values()) { -- CompoundTag entityNbt = entity.saveWithFullMetadata(); -+ CompoundTag entityNbt = entity.saveWithFullMetadata(net.minecraft.server.MinecraftServer.getServer().registryAccess()); - tileEntities.add(entityNbt); - } - -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -index 39e020135d996a4abb40dc6564d6c985e7bfbeda..9bfb64e022db3bd9ed4d818d69df1f9a955cfa5d 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -@@ -76,7 +76,7 @@ public class SlimeChunkConverter { - DataResult> dataresult = ChunkSerializer.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, Converter.convertTag(slimeSection.getBlockStatesTag())).promotePartial((s) -> { - System.out.println("Recoverable error when parsing section " + x + "," + z + ": " + s); // todo proper logging - }); -- blockPalette = dataresult.getOrThrow(false, System.err::println); // todo proper logging -+ blockPalette = dataresult.getOrThrow(); // todo proper logging - } else { - blockPalette = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, null); - } -@@ -87,7 +87,7 @@ public class SlimeChunkConverter { - DataResult>> dataresult = codec.parse(NbtOps.INSTANCE, Converter.convertTag(slimeSection.getBiomeTag())).promotePartial((s) -> { - System.out.println("Recoverable error when parsing section " + x + "," + z + ": " + s); // todo proper logging - }); -- biomePalette = dataresult.getOrThrow(false, System.err::println); // todo proper logging -+ biomePalette = dataresult.getOrThrow(); // todo proper logging - } else { - biomePalette = new PalettedContainer<>(biomeRegistry.asHolderIdMap(), biomeRegistry.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); - } -@@ -134,7 +134,7 @@ public class SlimeChunkConverter { - if (!type.isEmpty()) { - BlockPos blockPosition = new BlockPos(tag.getInt("x"), tag.getInt("y"), tag.getInt("z")); - BlockState blockData = nmsChunk.getBlockState(blockPosition); -- BlockEntity entity = BlockEntity.loadStatic(blockPosition, blockData, (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)); -+ BlockEntity entity = BlockEntity.loadStatic(blockPosition, blockData, (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag), net.minecraft.server.MinecraftServer.getServer().registryAccess()); - - if (entity != null) { - nmsChunk.setBlockEntity(entity); -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java -index b74ccd2b6b526f7b7955ce601a37185d3b6a2f59..5e72a283c9110a2a65939fda97c4e6f89a1b3755 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java -@@ -1,6 +1,6 @@ - package com.infernalsuite.asp.level; - --import com.mojang.serialization.Codec; -+import com.mojang.serialization.MapCodec; - import net.minecraft.core.Holder; - import net.minecraft.world.level.biome.Biome; - import net.minecraft.world.level.biome.BiomeSource; -@@ -21,7 +21,7 @@ public class SlimeLevelGenerator extends FlatLevelSource { - private static BiomeSource getSource(Holder biome) { - return new BiomeSource() { - @Override -- protected Codec codec() { -+ protected MapCodec codec() { - return null; - } - -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -index eddae8fc510d6e263df55a725148d96f677bcb0b..a8c103d435ac9473b1c5dd404e5c69ebf4353490 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -@@ -103,8 +103,6 @@ public class SlimeLevelInstance extends ServerLevel { - super.setSpawnSettings(propertyMap.getValue(SlimeProperties.ALLOW_MONSTERS), propertyMap.getValue(SlimeProperties.ALLOW_ANIMALS)); - - this.pvpMode = propertyMap.getValue(SlimeProperties.PVP); -- -- this.keepSpawnInMemory = false; - } - - @Override -@@ -123,7 +121,7 @@ public class SlimeLevelInstance extends ServerLevel { - - //this.getChunkSource().save(forceSave); - this.serverLevelData.setWorldBorder(this.getWorldBorder().createSettings()); -- this.serverLevelData.setCustomBossEvents(MinecraftServer.getServer().getCustomBossEvents().save()); -+ this.serverLevelData.setCustomBossEvents(MinecraftServer.getServer().getCustomBossEvents().save(MinecraftServer.getServer().registryAccess())); - - // Update level data - net.minecraft.nbt.CompoundTag compound = new net.minecraft.nbt.CompoundTag(); From d1048d1909bac525250f4eb9397538bcf8a66156 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 14:42:35 +0100 Subject: [PATCH 048/133] Port "Separate plugin and server, rework API (to v3)" by kyngs from 1 Jun 2024 --- impl/aspaper-server/build.gradle.kts.patch | 3 +- ...01-Warning-if-people-use-old-swm-api.patch | 26 + ...Warning-if-people-use-old-swm-plugin.patch | 26 + .../bukkit/craftbukkit/CraftServer.java.patch | 11 + .../infernalsuite/asp/AdvancedSlimePaper.java | 241 ++++++ .../com/infernalsuite/asp/InternalPlugin.java | 135 +++- .../infernalsuite/asp/SlimeNMSBridgeImpl.java | 9 +- .../asp/level/NMSSlimeChunk.java | 3 +- .../asp/level/NMSSlimeWorld.java | 4 +- .../asp/level/SlimeInMemoryWorld.java | 7 +- .../asp/level/SlimeLevelInstance.java | 24 +- .../com/infernalsuite/asp/util/NmsUtil.java | 37 + ...nfernalsuite.asp.api.AdvancedSlimePaperAPI | 1 + ...e-plugin-and-server-rework-API-to-v3.patch | 764 ------------------ 14 files changed, 503 insertions(+), 788 deletions(-) create mode 100644 impl/aspaper-server/paper-patches/features/0001-Warning-if-people-use-old-swm-api.patch create mode 100644 impl/aspaper-server/paper-patches/features/0002-Warning-if-people-use-old-swm-plugin.patch create mode 100644 impl/aspaper-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/CraftServer.java.patch create mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java create mode 100644 impl/aspaper-server/src/main/resources/META-INF/services/com.infernalsuite.asp.api.AdvancedSlimePaperAPI delete mode 100644 patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch diff --git a/impl/aspaper-server/build.gradle.kts.patch b/impl/aspaper-server/build.gradle.kts.patch index 37eb260f4..3accc1566 100644 --- a/impl/aspaper-server/build.gradle.kts.patch +++ b/impl/aspaper-server/build.gradle.kts.patch @@ -42,13 +42,14 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) { extendsFrom(configurations.compileClasspath.get()) } -@@ -119,7 +_,8 @@ +@@ -119,7 +_,9 @@ } dependencies { - implementation(project(":paper-api")) + implementation(project(":impl:aspaper-api")) //ASP + implementation(project(":core")) //ASP ++ implementation("commons-io:commons-io:2.11.0") implementation("ca.spottedleaf:concurrentutil:0.0.3") implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ implementation("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21 diff --git a/impl/aspaper-server/paper-patches/features/0001-Warning-if-people-use-old-swm-api.patch b/impl/aspaper-server/paper-patches/features/0001-Warning-if-people-use-old-swm-api.patch new file mode 100644 index 000000000..0f685c0ec --- /dev/null +++ b/impl/aspaper-server/paper-patches/features/0001-Warning-if-people-use-old-swm-api.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: kyngs +Date: Sat, 1 Jun 2024 18:57:39 +0200 +Subject: [PATCH] Warning if people use old swm api + + +diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java +index 3e82ea07ca4194844c5528446e2c4a46ff4acee5..1f8bff31ce60f9a1b143e749916fa51cf115f5d7 100644 +--- a/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java ++++ b/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java +@@ -64,6 +64,15 @@ class PaperPluginInstanceManager { + } + + public @Nullable Plugin getPlugin(@NotNull String name) { ++ // ASP start - Warn if someone tries to get the old API instance ++ if (name.equals("SlimeWorldManager")) { ++ server.getLogger().warning(""" ++ Hey! It seems like you're trying to access the old SlimeWorldManager API. ++ Since 1.21.0 the API is now provided by the server directly. ++ See the documentation at https://infernalsuite.com/docs/asp/migrating for more information. ++ """); ++ } ++ // ASP end + return this.lookupNames.get(name.replace(' ', '_').toLowerCase(java.util.Locale.ENGLISH)); // Paper + } + diff --git a/impl/aspaper-server/paper-patches/features/0002-Warning-if-people-use-old-swm-plugin.patch b/impl/aspaper-server/paper-patches/features/0002-Warning-if-people-use-old-swm-plugin.patch new file mode 100644 index 000000000..85c1ae904 --- /dev/null +++ b/impl/aspaper-server/paper-patches/features/0002-Warning-if-people-use-old-swm-plugin.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: kyngs +Date: Sat, 1 Jun 2024 18:57:39 +0200 +Subject: [PATCH] Warning if people use old swm plugin + + +diff --git a/src/main/java/io/papermc/paper/plugin/storage/SimpleProviderStorage.java b/src/main/java/io/papermc/paper/plugin/storage/SimpleProviderStorage.java +index 26422904751647a061397ce978bba752149003cd..4940083475948eac4fc06446f7ee7e1e8e04d676 100644 +--- a/src/main/java/io/papermc/paper/plugin/storage/SimpleProviderStorage.java ++++ b/src/main/java/io/papermc/paper/plugin/storage/SimpleProviderStorage.java +@@ -26,6 +26,15 @@ public abstract class SimpleProviderStorage implements ProviderStorage { + + @Override + public void register(PluginProvider provider) { ++ // ASP start - sanity check for old SlimeWorldManager ++ if (provider.getMeta().getName().equals("SlimeWorldManager")) { ++ LOGGER.warn(""" ++ Hey! It looks like you're trying to load the old SlimeWorldManager plugin. ++ ASP no longer works like that, and you should remove the plugin from your server. ++ See the documentation at https://infernalsuite.com/docs/asp/migrating for more information. ++ """); ++ return; ++ } // ASP end + this.providers.add(provider); + } + diff --git a/impl/aspaper-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/CraftServer.java.patch b/impl/aspaper-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/CraftServer.java.patch new file mode 100644 index 000000000..94ef404f6 --- /dev/null +++ b/impl/aspaper-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/CraftServer.java.patch @@ -0,0 +1,11 @@ +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -1508,6 +_,8 @@ + return false; + } + ++ com.infernalsuite.asp.AdvancedSlimePaper.instance().onWorldUnload(world.getName()); // ASP - Remove unloaded world from map ++ + try { + if (save) { + handle.save(null, true, false); // Paper - Fix saving in unloadWorld diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java new file mode 100644 index 000000000..06e915301 --- /dev/null +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java @@ -0,0 +1,241 @@ +package com.infernalsuite.asp; + +import com.infernalsuite.asp.api.SlimeNMSBridge; +import com.infernalsuite.asp.api.AdvancedSlimePaperAPI; +import com.infernalsuite.asp.api.events.LoadSlimeWorldEvent; +import com.infernalsuite.asp.api.exceptions.*; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.SlimeWorldInstance; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.level.SlimeLevelInstance; +import com.infernalsuite.asp.serialization.anvil.AnvilImportData; +import com.infernalsuite.asp.serialization.anvil.AnvilWorldReader; +import com.infernalsuite.asp.serialization.slime.SlimeSerializer; +import com.infernalsuite.asp.serialization.slime.reader.SlimeWorldReaderRegistry; +import com.infernalsuite.asp.skeleton.SkeletonSlimeWorld; +import com.infernalsuite.asp.util.NmsUtil; +import net.minecraft.server.level.ServerLevel; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.event.world.WorldLoadEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.spigotmc.AsyncCatcher; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +public class AdvancedSlimePaper implements AdvancedSlimePaperAPI { + + private static final Logger LOGGER = LoggerFactory.getLogger(AdvancedSlimePaper.class); + private static final SlimeNMSBridge BRIDGE_INSTANCE = SlimeNMSBridge.instance(); + + private final Map loadedWorlds = new ConcurrentHashMap<>(); + + static { + System.setProperty("org.slf4j.simpleLogger.showShortLogName", "true"); + } + + public static AdvancedSlimePaper instance() { + return (AdvancedSlimePaper) AdvancedSlimePaperAPI.instance(); + } + + @Override + public SlimeWorld readWorld(SlimeLoader loader, String worldName, boolean readOnly, SlimePropertyMap propertyMap) throws UnknownWorldException, IOException, CorruptedWorldException, NewerFormatException { + Objects.requireNonNull(loader, "Loader cannot be null"); + Objects.requireNonNull(worldName, "World name cannot be null"); + Objects.requireNonNull(propertyMap, "Properties cannot be null"); + + long start = System.currentTimeMillis(); + + LOGGER.info("Reading world {}.", worldName); + byte[] serializedWorld = loader.readWorld(worldName); + + SlimeWorld slimeWorld = SlimeWorldReaderRegistry.readWorld(loader, worldName, serializedWorld, propertyMap, readOnly); + LOGGER.info("Applying datafixers for {}.", worldName); + SlimeWorld dataFixed = SlimeNMSBridge.instance().applyDataFixers(slimeWorld); + + // If the dataFixed and slimeWorld are same, then no datafixers were applied + if (!readOnly && dataFixed != slimeWorld) + loader.saveWorld(worldName, SlimeSerializer.serialize(dataFixed)); // Write dataFixed world back to loader + + LOGGER.info("World {} read in {}ms.", worldName, System.currentTimeMillis() - start); + + return dataFixed; + } + + @Override + public SlimeWorld loadWorld(SlimeWorld world, boolean callWorldLoadEvent) throws IllegalArgumentException { + AsyncCatcher.catchOp("SWM world load"); + Objects.requireNonNull(world, "SlimeWorld cannot be null"); + + if (Bukkit.getWorld(world.getName()) != null) { + throw new IllegalArgumentException("World " + world.getName() + " is already loaded"); + } + + LOGGER.info("Loading world {}...", world.getName()); + long start = System.currentTimeMillis(); + + SlimeWorldInstance instance = BRIDGE_INSTANCE.loadInstance(world); + SlimeWorld mirror = instance.getSlimeWorldMirror(); + + Bukkit.getPluginManager().callEvent(new LoadSlimeWorldEvent(mirror)); + if (callWorldLoadEvent) { + Bukkit.getPluginManager().callEvent(new WorldLoadEvent(instance.getBukkitWorld())); + } + + registerWorld(mirror); + + LOGGER.info("World {} loaded in {}ms.", world.getName(), System.currentTimeMillis() - start); + return mirror; + } + + @Override + public boolean worldLoaded(SlimeWorld world) { + return loadedWorlds.containsKey(world.getName()); + } + + @Override + public void saveWorld(SlimeWorld world) throws IOException { + Objects.requireNonNull(world, "SlimeWorld cannot be null"); + if (worldLoaded(world)) { + Future[] future = new Future[1]; + + // This is not pretty, but we really need to hop onto the main thread + NmsUtil.runSyncAndWait(() -> { + World bukkitWorld = Bukkit.getWorld(world.getName()); + + ServerLevel level = ((CraftWorld) bukkitWorld).getHandle(); + if (level instanceof SlimeLevelInstance slimeLevel) { + future[0] = slimeLevel.save(); + } else { + // Shouldn't happen + LOGGER.warn("ServerLevel based off of SlimeWorld is not an instance of SlimeLevelInstance. Falling back to default save method."); + bukkitWorld.save(); + } + }); + + if (future[0] != null) { + try { + future[0].get(); + } catch (InterruptedException exception) { + throw new RuntimeException(exception); + } catch (ExecutionException e) { + if (e.getCause() instanceof IOException ioException) { + throw ioException; + } else { + throw new RuntimeException(e.getCause()); + } + } + } + } else { + LOGGER.info("Saving unloaded world {}...", world.getName()); + Objects.requireNonNull(world.getLoader(), "World loader cannot be null"); + long start = System.currentTimeMillis(); + + byte[] serializedWorld = SlimeSerializer.serialize(world); + + long saveStart = System.currentTimeMillis(); + world.getLoader().saveWorld(world.getName(), serializedWorld); + + LOGGER.info("World {} serialized in {}ms and saved in {}ms.", world.getName(), saveStart - start, System.currentTimeMillis() - saveStart); + } + + } + + @Override + public SlimeWorld getLoadedWorld(String worldName) { + return loadedWorlds.get(worldName); + } + + @Override + public List getLoadedWorlds() { + return List.copyOf(loadedWorlds.values()); + } + + @Override + public SlimeWorld createEmptyWorld(String worldName, boolean readOnly, SlimePropertyMap propertyMap, SlimeLoader loader) { + Objects.requireNonNull(worldName, "World name cannot be null"); + Objects.requireNonNull(propertyMap, "Properties cannot be null"); + + return new SkeletonSlimeWorld(worldName, loader, readOnly, Map.of(), new ConcurrentHashMap<>(), propertyMap, BRIDGE_INSTANCE.getCurrentVersion()); + } + + @Override + public void migrateWorld(String worldName, SlimeLoader currentLoader, SlimeLoader newLoader) throws IOException, WorldAlreadyExistsException, UnknownWorldException { + Objects.requireNonNull(worldName, "World name cannot be null"); + Objects.requireNonNull(currentLoader, "Current loader cannot be null"); + Objects.requireNonNull(newLoader, "New loader cannot be null"); + + if (newLoader.worldExists(worldName)) { + throw new WorldAlreadyExistsException(worldName); + } + + byte[] serializedWorld = currentLoader.readWorld(worldName); + newLoader.saveWorld(worldName, serializedWorld); + currentLoader.deleteWorld(worldName); + } + + @Override + public SlimeWorld readVanillaWorld(File worldDir, String worldName, SlimeLoader loader) throws InvalidWorldException, WorldLoadedException, WorldTooBigException, IOException, WorldAlreadyExistsException { + Objects.requireNonNull(worldDir, "World directory cannot be null"); + Objects.requireNonNull(worldName, "World name cannot be null"); + + if (loader != null && loader.worldExists(worldName)) { + throw new WorldAlreadyExistsException(worldName); + } + + World bukkitWorld = Bukkit.getWorld(worldName); + + if (bukkitWorld != null && BRIDGE_INSTANCE.getInstance(bukkitWorld) == null) { + throw new WorldLoadedException(worldDir.getName()); + } + + SlimeWorld world; + + try { + world = AnvilWorldReader.INSTANCE.readFromData(AnvilImportData.legacy(worldDir, worldName, loader)); + } catch (RuntimeException e) { + if (e.getCause() == null) { + throw e; + } + if (e.getCause() instanceof IOException ioException) { + throw ioException; + } else if (e.getCause() instanceof InvalidWorldException invalidWorldException) { + throw invalidWorldException; + } else { + throw e; + } + } + + // A sanity check to make sure the world is not too big to be serialized + try { + SlimeSerializer.serialize(world); + } catch (IndexOutOfBoundsException ex) { + throw new WorldTooBigException(worldDir.getName()); + } + + return world; + } + + /** + * Utility method to register a loaded {@link SlimeWorld} with the internal map (for {@link #getLoadedWorld} calls) + * + * @param world the world to register + */ + private void registerWorld(SlimeWorld world) { + this.loadedWorlds.put(world.getName(), world); + } + + public void onWorldUnload(String name) { + this.loadedWorlds.remove(name); + } +} diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/InternalPlugin.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/InternalPlugin.java index 48f996ff8..f8a3a68f4 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/InternalPlugin.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/InternalPlugin.java @@ -1,14 +1,36 @@ package com.infernalsuite.asp; +import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager; import net.minecraft.server.MinecraftServer; import org.bukkit.Server; -import org.bukkit.craftbukkit.scheduler.MinecraftInternalPlugin; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.generator.BiomeProvider; +import org.bukkit.generator.ChunkGenerator; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginBase; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.PluginLoader; import org.bukkit.plugin.PluginLogger; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.logging.LogRecord; +import java.io.File; +import java.io.InputStream; +import java.util.List; -public class InternalPlugin extends MinecraftInternalPlugin { +public class InternalPlugin extends PluginBase { + private boolean enabled = true; + + private final String pluginName; + private PluginDescriptionFile pdf; + + public InternalPlugin() { + this.pluginName = "Minecraft"; + pdf = new PluginDescriptionFile(pluginName, "1.0", "nms"); + } @Override public @NotNull Server getServer() { @@ -25,4 +47,113 @@ public void log(@NotNull LogRecord logRecord) { }; } + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + @Override + public File getDataFolder() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public PluginDescriptionFile getDescription() { + return pdf; + } + // Paper start + @Override + public io.papermc.paper.plugin.configuration.PluginMeta getPluginMeta() { + return pdf; + } + // Paper end + + @Override + public FileConfiguration getConfig() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public InputStream getResource(String filename) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public void saveConfig() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public void saveDefaultConfig() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public void saveResource(String resourcePath, boolean replace) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public void reloadConfig() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public PluginLoader getPluginLoader() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public boolean isEnabled() { + return enabled; + } + + @Override + public void onDisable() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public void onLoad() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public void onEnable() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public boolean isNaggable() { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public void setNaggable(boolean canNag) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public @Nullable BiomeProvider getDefaultBiomeProvider(@NotNull String worldName, @Nullable String id) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public LifecycleEventManager getLifecycleManager() { + throw new UnsupportedOperationException("Not supported."); + } } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java index 76849052c..033c2f2f0 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java @@ -47,8 +47,6 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { private static final CraftPersistentDataTypeRegistry REGISTRY = new CraftPersistentDataTypeRegistry(); private static final SimpleDataFixerConverter DATA_FIXER_CONVERTER = new SimpleDataFixerConverter(); - private static final Logger LOGGER = LogManager.getLogger("ASP"); - private SlimeWorld defaultWorld; private SlimeWorld defaultNetherWorld; private SlimeWorld defaultEndWorld; @@ -125,6 +123,13 @@ public boolean loadEndOverride() { return true; } + /** + * Sets the default worlds for the server.
    + * NOTE: These worlds should be unloaded! + * @param normalWorld The default overworld + * @param netherWorld The default nether + * @param endWorld The default end + */ @Override public void setDefaultWorlds(SlimeWorld normalWorld, SlimeWorld netherWorld, SlimeWorld endWorld) { if (normalWorld != null) { diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java index 6fcd1878c..91af462ab 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -34,13 +34,14 @@ import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.lighting.LevelLightEngine; import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; import java.util.Map; public class NMSSlimeChunk implements SlimeChunk { - private static final Logger LOGGER = LogUtils.getClassLogger(); + private static final Logger LOGGER = LoggerFactory.getLogger(NMSSlimeChunk.class); private static final CompoundBinaryTag EMPTY_BLOCK_STATE_PALETTE; private static final CompoundBinaryTag EMPTY_BIOME_PALETTE; diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java index 8cd79bf34..5e43f6094 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java @@ -37,7 +37,7 @@ public String getName() { @Override public SlimeLoader getLoader() { - return this.instance.slimeInstance.getSaveStrategy(); + return this.instance.slimeInstance.getLoader(); } @Override @@ -52,7 +52,7 @@ public SlimeChunk getChunk(int x, int z) { @Override public Collection getChunkStorage() { - List chunks = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.instance); // Paper + List chunks = ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.instance); // Paper return chunks.stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull) .map((chunkLevel) -> new NMSSlimeChunk(chunkLevel, memoryWorld.getChunk(chunkLevel.getPos().x, chunkLevel.getPos().z))) // This sucks, is there a better way? .collect(Collectors.toList()); diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java index 8fcb0ab62..9655bd071 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -146,7 +146,7 @@ public SlimePropertyMap getPropertyMap() { @Override public boolean isReadOnly() { - return this.getSaveStrategy() == null || this.readOnly; + return this.getLoader() == null || this.readOnly; } @Override @@ -186,11 +186,6 @@ public int getDataVersion() { return this.liveWorld.getDataVersion(); } - @Override - public SlimeLoader getSaveStrategy() { - return this.loader; - } - @Override public ConcurrentMap getExtraData() { return this.extra; diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java index 5cf264962..d8041d506 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -24,7 +24,6 @@ import net.minecraft.util.Unit; import net.minecraft.util.datafix.DataFixers; import net.minecraft.world.Difficulty; -import net.minecraft.world.RandomSequences; import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.biome.Biome; @@ -34,11 +33,11 @@ import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; import net.minecraft.world.level.validation.DirectoryValidator; -import net.minecraft.world.level.validation.PathAllowList; import org.apache.commons.io.FileUtils; import org.bukkit.Bukkit; import org.bukkit.event.world.WorldSaveEvent; import org.jetbrains.annotations.Nullable; +import org.spigotmc.AsyncCatcher; import java.io.IOException; import java.nio.file.Files; @@ -46,6 +45,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.UUID; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; @@ -77,8 +77,6 @@ public class SlimeLevelInstance extends ServerLevel { private final Object saveLock = new Object(); - private boolean ready = false; - public SlimeLevelInstance(SlimeBootstrap slimeBootstrap, PrimaryLevelData primaryLevelData, ResourceKey worldKey, ResourceKey dimensionKey, LevelStem worldDimension, @@ -115,8 +113,13 @@ public ChunkGenerator getGenerator(SlimeBootstrap slimeBootstrap) { @Override public void save(@Nullable ProgressListener progressUpdate, boolean forceSave, boolean savingDisabled, boolean close) { + if (!savingDisabled) save(); + } + + public Future save() { + AsyncCatcher.catchOp("SWM world save"); try { - if (!this.slimeInstance.isReadOnly() && !savingDisabled) { + if (!this.slimeInstance.isReadOnly() && this.slimeInstance.getLoader() != null) { Bukkit.getPluginManager().callEvent(new WorldSaveEvent(getWorld())); //this.getChunkSource().save(forceSave); @@ -128,16 +131,17 @@ public void save(@Nullable ProgressListener progressUpdate, boolean forceSave, b net.minecraft.nbt.CompoundTag nbtTagCompound = this.serverLevelData.createTag(MinecraftServer.getServer().registryAccess(), compound); if (MinecraftServer.getServer().isStopped()) { // Make sure the world gets saved before stopping the server by running it from the main thread - save().get(); // Async wait for it to finish - this.slimeInstance.getLoader().unlockWorld(this.slimeInstance.getName()); // Unlock + saveInternal().get(); // Async wait for it to finish } else { - this.save(); + return this.saveInternal(); //WORLD_SAVER_SERVICE.execute(this::save); } } } catch (Throwable e) { e.printStackTrace(); + return CompletableFuture.failedFuture(e); } + return CompletableFuture.completedFuture(null); } @Override @@ -147,7 +151,7 @@ public void saveIncrementally(boolean doFull) { } } - private Future save() { + private Future saveInternal() { synchronized (saveLock) { // Don't want to save the SlimeWorld from multiple threads simultaneously SlimeWorldInstance slimeWorld = this.slimeInstance; Bukkit.getLogger().log(Level.INFO, "Saving world " + this.slimeInstance.getName() + "..."); @@ -158,7 +162,7 @@ private Future save() { try { byte[] serializedWorld = SlimeSerializer.serialize(world); long saveStart = System.currentTimeMillis(); - slimeWorld.getSaveStrategy().saveWorld(slimeWorld.getName(), serializedWorld); + slimeWorld.getLoader().saveWorld(slimeWorld.getName(), serializedWorld); Bukkit.getLogger().log(Level.INFO, "World " + slimeWorld.getName() + " serialized in " + (saveStart - start) + "ms and saved in " + (System.currentTimeMillis() - saveStart) + "ms."); } catch (IOException | IllegalStateException ex) { ex.printStackTrace(); diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/util/NmsUtil.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/util/NmsUtil.java index 13cab3d74..c3bcfadf4 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/util/NmsUtil.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/util/NmsUtil.java @@ -1,9 +1,46 @@ package com.infernalsuite.asp.util; +import com.infernalsuite.asp.InternalPlugin; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.scheduler.CraftScheduler; +import org.bukkit.plugin.Plugin; + +import java.util.concurrent.CountDownLatch; + public class NmsUtil { public static long asLong(int chunkX, int chunkZ) { return (((long) chunkZ) * Integer.MAX_VALUE + ((long) chunkX)); //return (long)chunkX & 4294967295L | ((long)chunkZ & 4294967295L) << 32; } + + public static void runSyncAndWait(Runnable runnable) { + if (Bukkit.isPrimaryThread()) { + runnable.run(); + return; + } + + CountDownLatch latch = new CountDownLatch(1); + RuntimeException[] runtimeException = new RuntimeException[1]; + + Bukkit.getScheduler().runTask(new InternalPlugin(), () -> { + try { + runnable.run(); + } catch (RuntimeException e) { + runtimeException[0] = e; + } finally { + latch.countDown(); + } + }); + + try { + latch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); // Rather propagate the interrupt (and thus prevent further execution) than continue + } + + if (runtimeException[0] != null) { + throw runtimeException[0]; + } + } } diff --git a/impl/aspaper-server/src/main/resources/META-INF/services/com.infernalsuite.asp.api.AdvancedSlimePaperAPI b/impl/aspaper-server/src/main/resources/META-INF/services/com.infernalsuite.asp.api.AdvancedSlimePaperAPI new file mode 100644 index 000000000..d2fcf45a1 --- /dev/null +++ b/impl/aspaper-server/src/main/resources/META-INF/services/com.infernalsuite.asp.api.AdvancedSlimePaperAPI @@ -0,0 +1 @@ +com.infernalsuite.asp.AdvancedSlimePaper diff --git a/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch b/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch deleted file mode 100644 index 69eed2b51..000000000 --- a/patches/server/0013-Separate-plugin-and-server-rework-API-to-v3.patch +++ /dev/null @@ -1,764 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: kyngs -Date: Sat, 1 Jun 2024 18:57:39 +0200 -Subject: [PATCH] Separate plugin and server, rework API (to v3) - - -diff --git a/build.gradle.kts b/build.gradle.kts -index e6414d33e65233836db36040206c32a16b4d10ca..2f52145f996e5055030d7960c4ad616ba0ea5321 100644 ---- a/build.gradle.kts -+++ b/build.gradle.kts -@@ -29,6 +29,7 @@ dependencies { - // ASWM start - implementation(project(":aspaper-api")) - implementation(project(":core")) -+ implementation("commons-io:commons-io:2.11.0") - // ASWM end - implementation("ca.spottedleaf:concurrentutil:0.0.2") // Paper - Add ConcurrentUtil dependency - // Paper start -diff --git a/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java b/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java -new file mode 100644 -index 0000000000000000000000000000000000000000..06e91530198d9075434045893f95f7a6ae5bfbb3 ---- /dev/null -+++ b/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java -@@ -0,0 +1,241 @@ -+package com.infernalsuite.asp; -+ -+import com.infernalsuite.asp.api.SlimeNMSBridge; -+import com.infernalsuite.asp.api.AdvancedSlimePaperAPI; -+import com.infernalsuite.asp.api.events.LoadSlimeWorldEvent; -+import com.infernalsuite.asp.api.exceptions.*; -+import com.infernalsuite.asp.api.loaders.SlimeLoader; -+import com.infernalsuite.asp.api.world.SlimeWorld; -+import com.infernalsuite.asp.api.world.SlimeWorldInstance; -+import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; -+import com.infernalsuite.asp.level.SlimeLevelInstance; -+import com.infernalsuite.asp.serialization.anvil.AnvilImportData; -+import com.infernalsuite.asp.serialization.anvil.AnvilWorldReader; -+import com.infernalsuite.asp.serialization.slime.SlimeSerializer; -+import com.infernalsuite.asp.serialization.slime.reader.SlimeWorldReaderRegistry; -+import com.infernalsuite.asp.skeleton.SkeletonSlimeWorld; -+import com.infernalsuite.asp.util.NmsUtil; -+import net.minecraft.server.level.ServerLevel; -+import org.bukkit.Bukkit; -+import org.bukkit.World; -+import org.bukkit.craftbukkit.CraftWorld; -+import org.bukkit.event.world.WorldLoadEvent; -+import org.slf4j.Logger; -+import org.slf4j.LoggerFactory; -+import org.spigotmc.AsyncCatcher; -+ -+import java.io.File; -+import java.io.IOException; -+import java.util.List; -+import java.util.Map; -+import java.util.Objects; -+import java.util.concurrent.ConcurrentHashMap; -+import java.util.concurrent.ExecutionException; -+import java.util.concurrent.Future; -+ -+public class AdvancedSlimePaper implements AdvancedSlimePaperAPI { -+ -+ private static final Logger LOGGER = LoggerFactory.getLogger(AdvancedSlimePaper.class); -+ private static final SlimeNMSBridge BRIDGE_INSTANCE = SlimeNMSBridge.instance(); -+ -+ private final Map loadedWorlds = new ConcurrentHashMap<>(); -+ -+ static { -+ System.setProperty("org.slf4j.simpleLogger.showShortLogName", "true"); -+ } -+ -+ public static AdvancedSlimePaper instance() { -+ return (AdvancedSlimePaper) AdvancedSlimePaperAPI.instance(); -+ } -+ -+ @Override -+ public SlimeWorld readWorld(SlimeLoader loader, String worldName, boolean readOnly, SlimePropertyMap propertyMap) throws UnknownWorldException, IOException, CorruptedWorldException, NewerFormatException { -+ Objects.requireNonNull(loader, "Loader cannot be null"); -+ Objects.requireNonNull(worldName, "World name cannot be null"); -+ Objects.requireNonNull(propertyMap, "Properties cannot be null"); -+ -+ long start = System.currentTimeMillis(); -+ -+ LOGGER.info("Reading world {}.", worldName); -+ byte[] serializedWorld = loader.readWorld(worldName); -+ -+ SlimeWorld slimeWorld = SlimeWorldReaderRegistry.readWorld(loader, worldName, serializedWorld, propertyMap, readOnly); -+ LOGGER.info("Applying datafixers for {}.", worldName); -+ SlimeWorld dataFixed = SlimeNMSBridge.instance().applyDataFixers(slimeWorld); -+ -+ // If the dataFixed and slimeWorld are same, then no datafixers were applied -+ if (!readOnly && dataFixed != slimeWorld) -+ loader.saveWorld(worldName, SlimeSerializer.serialize(dataFixed)); // Write dataFixed world back to loader -+ -+ LOGGER.info("World {} read in {}ms.", worldName, System.currentTimeMillis() - start); -+ -+ return dataFixed; -+ } -+ -+ @Override -+ public SlimeWorld loadWorld(SlimeWorld world, boolean callWorldLoadEvent) throws IllegalArgumentException { -+ AsyncCatcher.catchOp("SWM world load"); -+ Objects.requireNonNull(world, "SlimeWorld cannot be null"); -+ -+ if (Bukkit.getWorld(world.getName()) != null) { -+ throw new IllegalArgumentException("World " + world.getName() + " is already loaded"); -+ } -+ -+ LOGGER.info("Loading world {}...", world.getName()); -+ long start = System.currentTimeMillis(); -+ -+ SlimeWorldInstance instance = BRIDGE_INSTANCE.loadInstance(world); -+ SlimeWorld mirror = instance.getSlimeWorldMirror(); -+ -+ Bukkit.getPluginManager().callEvent(new LoadSlimeWorldEvent(mirror)); -+ if (callWorldLoadEvent) { -+ Bukkit.getPluginManager().callEvent(new WorldLoadEvent(instance.getBukkitWorld())); -+ } -+ -+ registerWorld(mirror); -+ -+ LOGGER.info("World {} loaded in {}ms.", world.getName(), System.currentTimeMillis() - start); -+ return mirror; -+ } -+ -+ @Override -+ public boolean worldLoaded(SlimeWorld world) { -+ return loadedWorlds.containsKey(world.getName()); -+ } -+ -+ @Override -+ public void saveWorld(SlimeWorld world) throws IOException { -+ Objects.requireNonNull(world, "SlimeWorld cannot be null"); -+ if (worldLoaded(world)) { -+ Future[] future = new Future[1]; -+ -+ // This is not pretty, but we really need to hop onto the main thread -+ NmsUtil.runSyncAndWait(() -> { -+ World bukkitWorld = Bukkit.getWorld(world.getName()); -+ -+ ServerLevel level = ((CraftWorld) bukkitWorld).getHandle(); -+ if (level instanceof SlimeLevelInstance slimeLevel) { -+ future[0] = slimeLevel.save(); -+ } else { -+ // Shouldn't happen -+ LOGGER.warn("ServerLevel based off of SlimeWorld is not an instance of SlimeLevelInstance. Falling back to default save method."); -+ bukkitWorld.save(); -+ } -+ }); -+ -+ if (future[0] != null) { -+ try { -+ future[0].get(); -+ } catch (InterruptedException exception) { -+ throw new RuntimeException(exception); -+ } catch (ExecutionException e) { -+ if (e.getCause() instanceof IOException ioException) { -+ throw ioException; -+ } else { -+ throw new RuntimeException(e.getCause()); -+ } -+ } -+ } -+ } else { -+ LOGGER.info("Saving unloaded world {}...", world.getName()); -+ Objects.requireNonNull(world.getLoader(), "World loader cannot be null"); -+ long start = System.currentTimeMillis(); -+ -+ byte[] serializedWorld = SlimeSerializer.serialize(world); -+ -+ long saveStart = System.currentTimeMillis(); -+ world.getLoader().saveWorld(world.getName(), serializedWorld); -+ -+ LOGGER.info("World {} serialized in {}ms and saved in {}ms.", world.getName(), saveStart - start, System.currentTimeMillis() - saveStart); -+ } -+ -+ } -+ -+ @Override -+ public SlimeWorld getLoadedWorld(String worldName) { -+ return loadedWorlds.get(worldName); -+ } -+ -+ @Override -+ public List getLoadedWorlds() { -+ return List.copyOf(loadedWorlds.values()); -+ } -+ -+ @Override -+ public SlimeWorld createEmptyWorld(String worldName, boolean readOnly, SlimePropertyMap propertyMap, SlimeLoader loader) { -+ Objects.requireNonNull(worldName, "World name cannot be null"); -+ Objects.requireNonNull(propertyMap, "Properties cannot be null"); -+ -+ return new SkeletonSlimeWorld(worldName, loader, readOnly, Map.of(), new ConcurrentHashMap<>(), propertyMap, BRIDGE_INSTANCE.getCurrentVersion()); -+ } -+ -+ @Override -+ public void migrateWorld(String worldName, SlimeLoader currentLoader, SlimeLoader newLoader) throws IOException, WorldAlreadyExistsException, UnknownWorldException { -+ Objects.requireNonNull(worldName, "World name cannot be null"); -+ Objects.requireNonNull(currentLoader, "Current loader cannot be null"); -+ Objects.requireNonNull(newLoader, "New loader cannot be null"); -+ -+ if (newLoader.worldExists(worldName)) { -+ throw new WorldAlreadyExistsException(worldName); -+ } -+ -+ byte[] serializedWorld = currentLoader.readWorld(worldName); -+ newLoader.saveWorld(worldName, serializedWorld); -+ currentLoader.deleteWorld(worldName); -+ } -+ -+ @Override -+ public SlimeWorld readVanillaWorld(File worldDir, String worldName, SlimeLoader loader) throws InvalidWorldException, WorldLoadedException, WorldTooBigException, IOException, WorldAlreadyExistsException { -+ Objects.requireNonNull(worldDir, "World directory cannot be null"); -+ Objects.requireNonNull(worldName, "World name cannot be null"); -+ -+ if (loader != null && loader.worldExists(worldName)) { -+ throw new WorldAlreadyExistsException(worldName); -+ } -+ -+ World bukkitWorld = Bukkit.getWorld(worldName); -+ -+ if (bukkitWorld != null && BRIDGE_INSTANCE.getInstance(bukkitWorld) == null) { -+ throw new WorldLoadedException(worldDir.getName()); -+ } -+ -+ SlimeWorld world; -+ -+ try { -+ world = AnvilWorldReader.INSTANCE.readFromData(AnvilImportData.legacy(worldDir, worldName, loader)); -+ } catch (RuntimeException e) { -+ if (e.getCause() == null) { -+ throw e; -+ } -+ if (e.getCause() instanceof IOException ioException) { -+ throw ioException; -+ } else if (e.getCause() instanceof InvalidWorldException invalidWorldException) { -+ throw invalidWorldException; -+ } else { -+ throw e; -+ } -+ } -+ -+ // A sanity check to make sure the world is not too big to be serialized -+ try { -+ SlimeSerializer.serialize(world); -+ } catch (IndexOutOfBoundsException ex) { -+ throw new WorldTooBigException(worldDir.getName()); -+ } -+ -+ return world; -+ } -+ -+ /** -+ * Utility method to register a loaded {@link SlimeWorld} with the internal map (for {@link #getLoadedWorld} calls) -+ * -+ * @param world the world to register -+ */ -+ private void registerWorld(SlimeWorld world) { -+ this.loadedWorlds.put(world.getName(), world); -+ } -+ -+ public void onWorldUnload(String name) { -+ this.loadedWorlds.remove(name); -+ } -+} -diff --git a/src/main/java/com/infernalsuite/asp/InternalPlugin.java b/src/main/java/com/infernalsuite/asp/InternalPlugin.java -index 4c7938c07e06810f475eac0bb4400c11154b56ba..cb8720e3961b897ae87a59c2c91d1502be3e62cf 100644 ---- a/src/main/java/com/infernalsuite/asp/InternalPlugin.java -+++ b/src/main/java/com/infernalsuite/asp/InternalPlugin.java -@@ -1,14 +1,36 @@ - package com.infernalsuite.asp; - -+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager; - import net.minecraft.server.MinecraftServer; - import org.bukkit.Server; --import org.bukkit.craftbukkit.scheduler.MinecraftInternalPlugin; -+import org.bukkit.command.Command; -+import org.bukkit.command.CommandSender; -+import org.bukkit.configuration.file.FileConfiguration; -+import org.bukkit.generator.BiomeProvider; -+import org.bukkit.generator.ChunkGenerator; -+import org.bukkit.plugin.Plugin; -+import org.bukkit.plugin.PluginBase; -+import org.bukkit.plugin.PluginDescriptionFile; -+import org.bukkit.plugin.PluginLoader; - import org.bukkit.plugin.PluginLogger; - import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; - - import java.util.logging.LogRecord; -+import java.io.File; -+import java.io.InputStream; -+import java.util.List; - --public class InternalPlugin extends MinecraftInternalPlugin { -+public class InternalPlugin extends PluginBase { -+ private boolean enabled = true; -+ -+ private final String pluginName; -+ private PluginDescriptionFile pdf; -+ -+ public InternalPlugin() { -+ this.pluginName = "Minecraft"; -+ pdf = new PluginDescriptionFile(pluginName, "1.0", "nms"); -+ } - - @Override - public @NotNull Server getServer() { -@@ -25,4 +47,113 @@ public class InternalPlugin extends MinecraftInternalPlugin { - }; - } - -+ public void setEnabled(boolean enabled) { -+ this.enabled = enabled; -+ } -+ -+ @Override -+ public File getDataFolder() { -+ throw new UnsupportedOperationException("Not supported."); -+ } -+ -+ @Override -+ public PluginDescriptionFile getDescription() { -+ return pdf; -+ } -+ // Paper start -+ @Override -+ public io.papermc.paper.plugin.configuration.PluginMeta getPluginMeta() { -+ return pdf; -+ } -+ // Paper end -+ -+ @Override -+ public FileConfiguration getConfig() { -+ throw new UnsupportedOperationException("Not supported."); -+ } -+ -+ @Override -+ public InputStream getResource(String filename) { -+ throw new UnsupportedOperationException("Not supported."); -+ } -+ -+ @Override -+ public void saveConfig() { -+ throw new UnsupportedOperationException("Not supported."); -+ } -+ -+ @Override -+ public void saveDefaultConfig() { -+ throw new UnsupportedOperationException("Not supported."); -+ } -+ -+ @Override -+ public void saveResource(String resourcePath, boolean replace) { -+ throw new UnsupportedOperationException("Not supported."); -+ } -+ -+ @Override -+ public void reloadConfig() { -+ throw new UnsupportedOperationException("Not supported."); -+ } -+ -+ @Override -+ public PluginLoader getPluginLoader() { -+ throw new UnsupportedOperationException("Not supported."); -+ } -+ -+ @Override -+ public boolean isEnabled() { -+ return enabled; -+ } -+ -+ @Override -+ public void onDisable() { -+ throw new UnsupportedOperationException("Not supported."); -+ } -+ -+ @Override -+ public void onLoad() { -+ throw new UnsupportedOperationException("Not supported."); -+ } -+ -+ @Override -+ public void onEnable() { -+ throw new UnsupportedOperationException("Not supported."); -+ } -+ -+ @Override -+ public boolean isNaggable() { -+ throw new UnsupportedOperationException("Not supported."); -+ } -+ -+ @Override -+ public void setNaggable(boolean canNag) { -+ throw new UnsupportedOperationException("Not supported."); -+ } -+ -+ @Override -+ public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) { -+ throw new UnsupportedOperationException("Not supported."); -+ } -+ -+ @Override -+ public @Nullable BiomeProvider getDefaultBiomeProvider(@NotNull String worldName, @Nullable String id) { -+ throw new UnsupportedOperationException("Not supported."); -+ } -+ -+ @Override -+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { -+ throw new UnsupportedOperationException("Not supported."); -+ } -+ -+ @Override -+ public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { -+ throw new UnsupportedOperationException("Not supported."); -+ } -+ -+ @Override -+ public LifecycleEventManager getLifecycleManager() { -+ throw new UnsupportedOperationException("Not supported."); -+ } - } -\ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -index 95b4d139125f18414638c2b17266c6400a62bcf5..328e70af280ccb32f4830e464f34499b8be0d72b 100644 ---- a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -+++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -@@ -46,8 +46,6 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { - private static final CraftPersistentDataTypeRegistry REGISTRY = new CraftPersistentDataTypeRegistry(); - private static final SimpleDataFixerConverter DATA_FIXER_CONVERTER = new SimpleDataFixerConverter(); - -- private static final Logger LOGGER = LogManager.getLogger("ASP"); -- - private SlimeWorld defaultWorld; - private SlimeWorld defaultNetherWorld; - private SlimeWorld defaultEndWorld; -@@ -124,6 +122,13 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { - return true; - } - -+ /** -+ * Sets the default worlds for the server.
    -+ * NOTE: These worlds should be unloaded! -+ * @param normalWorld The default overworld -+ * @param netherWorld The default nether -+ * @param endWorld The default end -+ */ - @Override - public void setDefaultWorlds(SlimeWorld normalWorld, SlimeWorld netherWorld, SlimeWorld endWorld) { - if (normalWorld != null) { -diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -index 6972d6399628eda41756a98fb54fbe93eb827716..7326a5af48338d58ac657a5ab62e9fbeb96e4346 100644 ---- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -+++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -@@ -6,7 +6,6 @@ import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; - import com.infernalsuite.asp.api.utils.NibbleArray; - import com.infernalsuite.asp.api.world.SlimeChunk; - import com.infernalsuite.asp.api.world.SlimeChunkSection; --import com.mojang.logging.LogUtils; - import com.mojang.serialization.Codec; - import io.papermc.paper.world.ChunkEntitySlices; - import net.kyori.adventure.nbt.CompoundBinaryTag; -@@ -31,13 +30,13 @@ import net.minecraft.world.level.chunk.storage.ChunkSerializer; - import net.minecraft.world.level.levelgen.Heightmap; - import net.minecraft.world.level.lighting.LevelLightEngine; - import org.slf4j.Logger; -+import org.slf4j.LoggerFactory; - - import java.util.ArrayList; - import java.util.List; --import java.util.Map; - - public class NMSSlimeChunk implements SlimeChunk { -- private static final Logger LOGGER = LogUtils.getClassLogger(); -+ private static final Logger LOGGER = LoggerFactory.getLogger(NMSSlimeChunk.class); - - private static final CompoundBinaryTag EMPTY_BLOCK_STATE_PALETTE; - private static final CompoundBinaryTag EMPTY_BIOME_PALETTE; -diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java -index 8cd79bf34a9074d06d342f956165891613ae6cf0..5e43f6094fdd0f7e0ab6f5c5379fc86e075d6173 100644 ---- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java -+++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java -@@ -37,7 +37,7 @@ public class NMSSlimeWorld implements SlimeWorld { - - @Override - public SlimeLoader getLoader() { -- return this.instance.slimeInstance.getSaveStrategy(); -+ return this.instance.slimeInstance.getLoader(); - } - - @Override -@@ -52,7 +52,7 @@ public class NMSSlimeWorld implements SlimeWorld { - - @Override - public Collection getChunkStorage() { -- List chunks = io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.instance); // Paper -+ List chunks = ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.instance); // Paper - return chunks.stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull) - .map((chunkLevel) -> new NMSSlimeChunk(chunkLevel, memoryWorld.getChunk(chunkLevel.getPos().x, chunkLevel.getPos().z))) // This sucks, is there a better way? - .collect(Collectors.toList()); -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -index 8fcb0ab62ce098a07cc5a0d3b481a45e9f75e161..9655bd071f435d8b33a78350abb804cafc77306f 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -146,7 +146,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - - @Override - public boolean isReadOnly() { -- return this.getSaveStrategy() == null || this.readOnly; -+ return this.getLoader() == null || this.readOnly; - } - - @Override -@@ -186,11 +186,6 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - return this.liveWorld.getDataVersion(); - } - -- @Override -- public SlimeLoader getSaveStrategy() { -- return this.loader; -- } -- - @Override - public ConcurrentMap getExtraData() { - return this.extra; -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -index a8c103d435ac9473b1c5dd404e5c69ebf4353490..d6e5eac7732f32cabd6ed5ac6b10af20074a39b8 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -@@ -24,7 +24,6 @@ import net.minecraft.util.ProgressListener; - import net.minecraft.util.Unit; - import net.minecraft.util.datafix.DataFixers; - import net.minecraft.world.Difficulty; --import net.minecraft.world.RandomSequences; - import net.minecraft.world.entity.EntityType; - import net.minecraft.world.level.ChunkPos; - import net.minecraft.world.level.biome.Biome; -@@ -34,11 +33,11 @@ import net.minecraft.world.level.dimension.LevelStem; - import net.minecraft.world.level.storage.LevelStorageSource; - import net.minecraft.world.level.storage.PrimaryLevelData; - import net.minecraft.world.level.validation.DirectoryValidator; --import net.minecraft.world.level.validation.PathAllowList; - import org.apache.commons.io.FileUtils; - import org.bukkit.Bukkit; - import org.bukkit.event.world.WorldSaveEvent; - import org.jetbrains.annotations.Nullable; -+import org.spigotmc.AsyncCatcher; - - import java.io.IOException; - import java.nio.file.Files; -@@ -46,6 +45,7 @@ import java.nio.file.Path; - import java.util.ArrayList; - import java.util.Collections; - import java.util.UUID; -+import java.util.concurrent.CompletableFuture; - import java.util.concurrent.ExecutorService; - import java.util.concurrent.Executors; - import java.util.concurrent.Future; -@@ -77,8 +77,6 @@ public class SlimeLevelInstance extends ServerLevel { - - private final Object saveLock = new Object(); - -- private boolean ready = false; -- - public SlimeLevelInstance(SlimeBootstrap slimeBootstrap, PrimaryLevelData primaryLevelData, - ResourceKey worldKey, - ResourceKey dimensionKey, LevelStem worldDimension, -@@ -115,8 +113,13 @@ public class SlimeLevelInstance extends ServerLevel { - - @Override - public void save(@Nullable ProgressListener progressUpdate, boolean forceSave, boolean savingDisabled, boolean close) { -+ if (!savingDisabled) save(); -+ } -+ -+ public Future save() { -+ AsyncCatcher.catchOp("SWM world save"); - try { -- if (!this.slimeInstance.isReadOnly() && !savingDisabled) { -+ if (!this.slimeInstance.isReadOnly() && this.slimeInstance.getLoader() != null) { - Bukkit.getPluginManager().callEvent(new WorldSaveEvent(getWorld())); - - //this.getChunkSource().save(forceSave); -@@ -128,16 +131,17 @@ public class SlimeLevelInstance extends ServerLevel { - net.minecraft.nbt.CompoundTag nbtTagCompound = this.serverLevelData.createTag(MinecraftServer.getServer().registryAccess(), compound); - - if (MinecraftServer.getServer().isStopped()) { // Make sure the world gets saved before stopping the server by running it from the main thread -- save().get(); // Async wait for it to finish -- this.slimeInstance.getLoader().unlockWorld(this.slimeInstance.getName()); // Unlock -+ saveInternal().get(); // Async wait for it to finish - } else { -- this.save(); -+ return this.saveInternal(); - //WORLD_SAVER_SERVICE.execute(this::save); - } - } - } catch (Throwable e) { - e.printStackTrace(); -+ return CompletableFuture.failedFuture(e); - } -+ return CompletableFuture.completedFuture(null); - } - - @Override -@@ -147,7 +151,7 @@ public class SlimeLevelInstance extends ServerLevel { - } - } - -- private Future save() { -+ private Future saveInternal() { - synchronized (saveLock) { // Don't want to save the SlimeWorld from multiple threads simultaneously - SlimeWorldInstance slimeWorld = this.slimeInstance; - Bukkit.getLogger().log(Level.INFO, "Saving world " + this.slimeInstance.getName() + "..."); -@@ -158,7 +162,7 @@ public class SlimeLevelInstance extends ServerLevel { - try { - byte[] serializedWorld = SlimeSerializer.serialize(world); - long saveStart = System.currentTimeMillis(); -- slimeWorld.getSaveStrategy().saveWorld(slimeWorld.getName(), serializedWorld); -+ slimeWorld.getLoader().saveWorld(slimeWorld.getName(), serializedWorld); - Bukkit.getLogger().log(Level.INFO, "World " + slimeWorld.getName() + " serialized in " + (saveStart - start) + "ms and saved in " + (System.currentTimeMillis() - saveStart) + "ms."); - } catch (IOException | IllegalStateException ex) { - ex.printStackTrace(); -diff --git a/src/main/java/com/infernalsuite/asp/util/NmsUtil.java b/src/main/java/com/infernalsuite/asp/util/NmsUtil.java -index 04e43a22c1932dce66abb54337cdce802110a7af..c8e8d61b9b9f5f0ce639aae95ddacb16442ba73f 100644 ---- a/src/main/java/com/infernalsuite/asp/util/NmsUtil.java -+++ b/src/main/java/com/infernalsuite/asp/util/NmsUtil.java -@@ -1,9 +1,46 @@ - package com.infernalsuite.asp.util; - -+import com.infernalsuite.asp.InternalPlugin; -+import org.bukkit.Bukkit; -+import org.bukkit.craftbukkit.scheduler.CraftScheduler; -+import org.bukkit.plugin.Plugin; -+ -+import java.util.concurrent.CountDownLatch; -+ - public class NmsUtil { - - public static long asLong(int chunkX, int chunkZ) { - return (((long) chunkZ) * Integer.MAX_VALUE + ((long) chunkX)); - //return (long)chunkX & 4294967295L | ((long)chunkZ & 4294967295L) << 32; - } -+ -+ public static void runSyncAndWait(Runnable runnable) { -+ if (Bukkit.isPrimaryThread()) { -+ runnable.run(); -+ return; -+ } -+ -+ CountDownLatch latch = new CountDownLatch(1); -+ RuntimeException[] runtimeException = new RuntimeException[1]; -+ -+ Bukkit.getScheduler().runTask(new InternalPlugin(), () -> { -+ try { -+ runnable.run(); -+ } catch (RuntimeException e) { -+ runtimeException[0] = e; -+ } finally { -+ latch.countDown(); -+ } -+ }); -+ -+ try { -+ latch.await(); -+ } catch (InterruptedException e) { -+ throw new RuntimeException(e); // Rather propagate the interrupt (and thus prevent further execution) than continue -+ } -+ -+ if (runtimeException[0] != null) { -+ throw runtimeException[0]; -+ } -+ } - } -\ No newline at end of file -diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java -index 3e82ea07ca4194844c5528446e2c4a46ff4acee5..1f8bff31ce60f9a1b143e749916fa51cf115f5d7 100644 ---- a/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java -+++ b/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java -@@ -64,6 +64,15 @@ class PaperPluginInstanceManager { - } - - public @Nullable Plugin getPlugin(@NotNull String name) { -+ // ASP start - Warn if someone tries to get the old API instance -+ if (name.equals("SlimeWorldManager")) { -+ server.getLogger().warning(""" -+ Hey! It seems like you're trying to access the old SlimeWorldManager API. -+ Since 1.21.0 the API is now provided by the server directly. -+ See the documentation at https://infernalsuite.com/docs/asp/migrating for more information. -+ """); -+ } -+ // ASP end - return this.lookupNames.get(name.replace(' ', '_').toLowerCase(java.util.Locale.ENGLISH)); // Paper - } - -diff --git a/src/main/java/io/papermc/paper/plugin/storage/SimpleProviderStorage.java b/src/main/java/io/papermc/paper/plugin/storage/SimpleProviderStorage.java -index 26422904751647a061397ce978bba752149003cd..4940083475948eac4fc06446f7ee7e1e8e04d676 100644 ---- a/src/main/java/io/papermc/paper/plugin/storage/SimpleProviderStorage.java -+++ b/src/main/java/io/papermc/paper/plugin/storage/SimpleProviderStorage.java -@@ -26,6 +26,15 @@ public abstract class SimpleProviderStorage implements ProviderStorage { - - @Override - public void register(PluginProvider provider) { -+ // ASP start - sanity check for old SlimeWorldManager -+ if (provider.getMeta().getName().equals("SlimeWorldManager")) { -+ LOGGER.warn(""" -+ Hey! It looks like you're trying to load the old SlimeWorldManager plugin. -+ ASP no longer works like that, and you should remove the plugin from your server. -+ See the documentation at https://infernalsuite.com/docs/asp/migrating for more information. -+ """); -+ return; -+ } // ASP end - this.providers.add(provider); - } - -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 97b5d6ba2b19a7c730730c74175a29157aed1840..4297100fea7f0053ad624e5eee12bbd8e15e55b5 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -8,6 +8,7 @@ import com.google.common.collect.ImmutableList; - import com.google.common.collect.Iterators; - import com.google.common.collect.Lists; - import com.google.common.collect.MapMaker; -+import com.infernalsuite.asp.AdvancedSlimePaper; - import com.mojang.authlib.GameProfile; - import com.mojang.brigadier.StringReader; - import com.mojang.brigadier.exceptions.CommandSyntaxException; -@@ -1487,6 +1488,8 @@ public final class CraftServer implements Server { - return false; - } - -+ AdvancedSlimePaper.instance().onWorldUnload(world.getName()); // ASP - Remove unloaded world from map -+ - try { - if (save) { - handle.save(null, true, false); // Paper - Fix saving in unloadWorld -diff --git a/src/main/resources/META-INF/services/com.infernalsuite.aswm.api.AdvancedSlimePaperAPI b/src/main/resources/META-INF/services/com.infernalsuite.aswm.api.AdvancedSlimePaperAPI -new file mode 100644 -index 0000000000000000000000000000000000000000..a01c19e4ddbc844c71ba3a0db6efb2a8082091cf ---- /dev/null -+++ b/src/main/resources/META-INF/services/com.infernalsuite.aswm.api.AdvancedSlimePaperAPI -@@ -0,0 +1 @@ -+com.infernalsuite.aswm.AdvancedSlimePaper -\ No newline at end of file -diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml -index d2a75850af9c6ad2aca66a5f994f1b587d73eac4..3b090baf12044e19150ec66017c76fc48358f1b7 100644 ---- a/src/main/resources/log4j2.xml -+++ b/src/main/resources/log4j2.xml -@@ -6,7 +6,7 @@ - - - -- -+ - - - - - -- -+ - - - Date: Sun, 9 Mar 2025 14:46:34 +0100 Subject: [PATCH 049/133] Port "replace ChunkPos with long" by Aaron from 16 Jun 2024 --- .../infernalsuite/asp/AdvancedSlimePaper.java | 3 +- .../asp/SimpleDataFixerConverter.java | 6 +- .../asp/level/SlimeInMemoryWorld.java | 26 +-- .../0014-replace-ChunkPos-with-long.patch | 174 ------------------ 4 files changed, 20 insertions(+), 189 deletions(-) delete mode 100644 patches/server/0014-replace-ChunkPos-with-long.patch diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java index 06e915301..7741a210a 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java @@ -15,6 +15,7 @@ import com.infernalsuite.asp.serialization.slime.reader.SlimeWorldReaderRegistry; import com.infernalsuite.asp.skeleton.SkeletonSlimeWorld; import com.infernalsuite.asp.util.NmsUtil; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minecraft.server.level.ServerLevel; import org.bukkit.Bukkit; import org.bukkit.World; @@ -166,7 +167,7 @@ public SlimeWorld createEmptyWorld(String worldName, boolean readOnly, SlimeProp Objects.requireNonNull(worldName, "World name cannot be null"); Objects.requireNonNull(propertyMap, "Properties cannot be null"); - return new SkeletonSlimeWorld(worldName, loader, readOnly, Map.of(), new ConcurrentHashMap<>(), propertyMap, BRIDGE_INSTANCE.getCurrentVersion()); + return new SkeletonSlimeWorld(worldName, loader, readOnly, new Long2ObjectOpenHashMap<>(0), new ConcurrentHashMap<>(), propertyMap, BRIDGE_INSTANCE.getCurrentVersion()); } @Override diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java index be7c92f46..68b632999 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java @@ -12,6 +12,8 @@ import com.infernalsuite.asp.api.world.SlimeChunkSection; import com.infernalsuite.asp.api.world.SlimeWorld; import net.kyori.adventure.nbt.CompoundBinaryTag; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minecraft.SharedConstants; import java.util.ArrayList; @@ -33,7 +35,7 @@ public SlimeWorld readFromData(SlimeWorld data) { long encodedNewVersion = DataConverter.encodeVersions(newVersion, Integer.MAX_VALUE); long encodedCurrentVersion = DataConverter.encodeVersions(currentVersion, Integer.MAX_VALUE); - Map chunks = new HashMap<>(); + Long2ObjectMap chunks = new Long2ObjectOpenHashMap<>(); for (SlimeChunk chunk : data.getChunkStorage()) { List entities = new ArrayList<>(); List blockEntities = new ArrayList<>(); @@ -47,7 +49,7 @@ public SlimeWorld readFromData(SlimeWorld data) { convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.ENTITY.convert(new NBTMapType(tag), encodedCurrentVersion, encodedNewVersion)) ); } - ChunkPos chunkPos = new ChunkPos(chunk.getX(), chunk.getZ()); + long chunkPos = Util.chunkPosition(chunk.getX(), chunk.getZ()); SlimeChunkSection[] sections = new SlimeChunkSection[chunk.getSections().length]; for (int i = 0; i < sections.length; i++) { diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java index 9655bd071..f3fd1d04c 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -1,7 +1,7 @@ package com.infernalsuite.asp.level; -import com.infernalsuite.asp.ChunkPos; import com.infernalsuite.asp.Converter; +import com.infernalsuite.asp.Util; import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; import com.infernalsuite.asp.api.loaders.SlimeLoader; import com.infernalsuite.asp.pdc.AdventurePersistentDataContainer; @@ -15,6 +15,8 @@ import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.UpgradeData; @@ -47,7 +49,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { private final SlimePropertyMap propertyMap; private final SlimeLoader loader; - private final Map chunkStorage = new HashMap<>(); + private final Long2ObjectMap chunkStorage = new Long2ObjectOpenHashMap<>(); private boolean readOnly; // private final Map> entityStorage = new HashMap<>(); @@ -59,7 +61,7 @@ public SlimeInMemoryWorld(SlimeBootstrap bootstrap, SlimeLevelInstance instance) this.readOnly = bootstrap.initial().isReadOnly(); for (SlimeChunk initial : bootstrap.initial().getChunkStorage()) { - ChunkPos pos = new ChunkPos(initial.getX(), initial.getZ()); + long pos = Util.chunkPosition(initial.getX(), initial.getZ()); List tags = new ArrayList<>(initial.getEntities()); // this.entityStorage.put(pos, tags); @@ -96,7 +98,7 @@ public LevelChunk promote(int x, int z, SlimeChunk chunk) { levelChunk = SlimeChunkConverter.deserializeSlimeChunk(this.instance, chunk); chunk = new SafeNmsChunkWrapper(new NMSSlimeChunk(levelChunk, chunk), chunk); } - this.chunkStorage.put(new ChunkPos(x, z), chunk); + this.chunkStorage.put(Util.chunkPosition(x, z), chunk); return levelChunk; } @@ -110,18 +112,18 @@ public void unload(LevelChunk providedChunk) { SlimeChunk chunk = new NMSSlimeChunk(providedChunk, getChunk(x, z)); if (FastChunkPruner.canBePruned(this.liveWorld, providedChunk)) { - this.chunkStorage.remove(new ChunkPos(x, z)); + this.chunkStorage.remove(Util.chunkPosition(x, z)); return; } - this.chunkStorage.put(new ChunkPos(x, z), + this.chunkStorage.put(Util.chunkPosition(x, z), new SlimeChunkSkeleton(chunk.getX(), chunk.getZ(), chunk.getSections(), chunk.getHeightMaps(), chunk.getTileEntities(), chunk.getEntities(), chunk.getExtraData(), null)); } @Override public SlimeChunk getChunk(int x, int z) { - return this.chunkStorage.get(new ChunkPos(x, z)); + return this.chunkStorage.get(Util.chunkPosition(x, z)); } @Override @@ -203,8 +205,8 @@ public Collection getWorldMaps() { public SlimeWorld getForSerialization() { SlimeWorld world = SkeletonCloning.weakCopy(this); - Map cloned = new HashMap<>(); - for (Map.Entry entry : this.chunkStorage.entrySet()) { + Long2ObjectMap cloned = new Long2ObjectOpenHashMap<>(); + for (Long2ObjectMap.Entry entry : this.chunkStorage.long2ObjectEntrySet()) { SlimeChunk clonedChunk = entry.getValue(); // NMS "live" chunks need to be converted { @@ -242,7 +244,7 @@ public SlimeWorld getForSerialization() { } } - cloned.put(entry.getKey(), clonedChunk); + cloned.put(entry.getLongKey(), clonedChunk); } // Serialize Bukkit Values (PDC) @@ -275,8 +277,8 @@ public SlimeLevelInstance getInstance() { } public void ensureChunkMarkedAsLoaded(SlimeChunkLevel chunk) { - if (chunkStorage.get(new ChunkPos(chunk.locX, chunk.locZ)) instanceof SlimeChunkSkeleton skeleton) { - chunkStorage.put(new ChunkPos(chunk.locX, chunk.locZ), new NMSSlimeChunk(chunk, skeleton)); + if (chunkStorage.get(Util.chunkPosition(chunk.locX, chunk.locZ)) instanceof SlimeChunkSkeleton skeleton) { + chunkStorage.put(Util.chunkPosition(chunk.locX, chunk.locZ), new NMSSlimeChunk(chunk, skeleton)); } } } diff --git a/patches/server/0014-replace-ChunkPos-with-long.patch b/patches/server/0014-replace-ChunkPos-with-long.patch deleted file mode 100644 index 4059372e4..000000000 --- a/patches/server/0014-replace-ChunkPos-with-long.patch +++ /dev/null @@ -1,174 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aaron -Date: Sun, 16 Jun 2024 03:06:08 +0200 -Subject: [PATCH] replace ChunkPos with long - - -diff --git a/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java b/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java -index 06e91530198d9075434045893f95f7a6ae5bfbb3..7741a210ad71a66846cdae636917e1a89ac35c8d 100644 ---- a/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java -+++ b/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java -@@ -15,6 +15,7 @@ import com.infernalsuite.asp.serialization.slime.SlimeSerializer; - import com.infernalsuite.asp.serialization.slime.reader.SlimeWorldReaderRegistry; - import com.infernalsuite.asp.skeleton.SkeletonSlimeWorld; - import com.infernalsuite.asp.util.NmsUtil; -+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; - import net.minecraft.server.level.ServerLevel; - import org.bukkit.Bukkit; - import org.bukkit.World; -@@ -166,7 +167,7 @@ public class AdvancedSlimePaper implements AdvancedSlimePaperAPI { - Objects.requireNonNull(worldName, "World name cannot be null"); - Objects.requireNonNull(propertyMap, "Properties cannot be null"); - -- return new SkeletonSlimeWorld(worldName, loader, readOnly, Map.of(), new ConcurrentHashMap<>(), propertyMap, BRIDGE_INSTANCE.getCurrentVersion()); -+ return new SkeletonSlimeWorld(worldName, loader, readOnly, new Long2ObjectOpenHashMap<>(0), new ConcurrentHashMap<>(), propertyMap, BRIDGE_INSTANCE.getCurrentVersion()); - } - - @Override -diff --git a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -index ec45c627df14a87087e39556cb90eb2d5b52a981..4fe388f4e7edc7a9207147f6cb610d0cc53d9e1e 100644 ---- a/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -+++ b/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java -@@ -12,10 +12,11 @@ import com.infernalsuite.asp.api.world.SlimeChunk; - import com.infernalsuite.asp.api.world.SlimeChunkSection; - import com.infernalsuite.asp.api.world.SlimeWorld; - import net.kyori.adventure.nbt.CompoundBinaryTag; -+import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; - import net.minecraft.SharedConstants; - - import java.util.ArrayList; --import java.util.HashMap; - import java.util.List; - import java.util.function.Consumer; - -@@ -33,7 +34,7 @@ class SimpleDataFixerConverter implements SlimeWorldReader { - long encodedNewVersion = DataConverter.encodeVersions(newVersion, Integer.MAX_VALUE); - long encodedCurrentVersion = DataConverter.encodeVersions(currentVersion, Integer.MAX_VALUE); - -- Map chunks = new HashMap<>(); -+ Long2ObjectMap chunks = new Long2ObjectOpenHashMap<>(); - for (SlimeChunk chunk : data.getChunkStorage()) { - List entities = new ArrayList<>(); - List blockEntities = new ArrayList<>(); -@@ -48,7 +49,7 @@ class SimpleDataFixerConverter implements SlimeWorldReader { - ); - } - -- ChunkPos chunkPos = new ChunkPos(chunk.getX(), chunk.getZ()); -+ long chunkPos = Util.chunkPosition(chunk.getX(), chunk.getZ()); - - SlimeChunkSection[] sections = new SlimeChunkSection[chunk.getSections().length]; - for (int i = 0; i < sections.length; i++) { -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -index 9655bd071f435d8b33a78350abb804cafc77306f..e6da199bf2179d8820c6e38725cea5f867031f15 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -1,7 +1,7 @@ - package com.infernalsuite.asp.level; - --import com.infernalsuite.asp.ChunkPos; - import com.infernalsuite.asp.Converter; -+import com.infernalsuite.asp.Util; - import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; - import com.infernalsuite.asp.api.loaders.SlimeLoader; - import com.infernalsuite.asp.pdc.AdventurePersistentDataContainer; -@@ -15,6 +15,8 @@ import com.infernalsuite.asp.api.world.SlimeWorldInstance; - import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; - import net.kyori.adventure.nbt.BinaryTag; - import net.kyori.adventure.nbt.CompoundBinaryTag; -+import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; - import net.minecraft.world.level.block.Block; - import net.minecraft.world.level.chunk.LevelChunk; - import net.minecraft.world.level.chunk.UpgradeData; -@@ -27,9 +29,7 @@ import org.jetbrains.annotations.NotNull; - import java.io.IOException; - import java.util.ArrayList; - import java.util.Collection; --import java.util.HashMap; - import java.util.List; --import java.util.Map; - import java.util.concurrent.ConcurrentMap; - - /* -@@ -47,7 +47,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - private final SlimePropertyMap propertyMap; - private final SlimeLoader loader; - -- private final Map chunkStorage = new HashMap<>(); -+ private final Long2ObjectMap chunkStorage = new Long2ObjectOpenHashMap<>(); - private boolean readOnly; - // private final Map> entityStorage = new HashMap<>(); - -@@ -59,7 +59,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - this.readOnly = bootstrap.initial().isReadOnly(); - - for (SlimeChunk initial : bootstrap.initial().getChunkStorage()) { -- ChunkPos pos = new ChunkPos(initial.getX(), initial.getZ()); -+ long pos = Util.chunkPosition(initial.getX(), initial.getZ()); - List tags = new ArrayList<>(initial.getEntities()); - - // this.entityStorage.put(pos, tags); -@@ -96,7 +96,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - levelChunk = SlimeChunkConverter.deserializeSlimeChunk(this.instance, chunk); - chunk = new SafeNmsChunkWrapper(new NMSSlimeChunk(levelChunk, chunk), chunk); - } -- this.chunkStorage.put(new ChunkPos(x, z), chunk); -+ this.chunkStorage.put(Util.chunkPosition(x, z), chunk); - - return levelChunk; - } -@@ -110,18 +110,18 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - SlimeChunk chunk = new NMSSlimeChunk(providedChunk, getChunk(x, z)); - - if (FastChunkPruner.canBePruned(this.liveWorld, providedChunk)) { -- this.chunkStorage.remove(new ChunkPos(x, z)); -+ this.chunkStorage.remove(Util.chunkPosition(x, z)); - return; - } - -- this.chunkStorage.put(new ChunkPos(x, z), -+ this.chunkStorage.put(Util.chunkPosition(x, z), - new SlimeChunkSkeleton(chunk.getX(), chunk.getZ(), chunk.getSections(), - chunk.getHeightMaps(), chunk.getTileEntities(), chunk.getEntities(), chunk.getExtraData(), null)); - } - - @Override - public SlimeChunk getChunk(int x, int z) { -- return this.chunkStorage.get(new ChunkPos(x, z)); -+ return this.chunkStorage.get(Util.chunkPosition(x, z)); - } - - @Override -@@ -203,8 +203,8 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - public SlimeWorld getForSerialization() { - SlimeWorld world = SkeletonCloning.weakCopy(this); - -- Map cloned = new HashMap<>(); -- for (Map.Entry entry : this.chunkStorage.entrySet()) { -+ Long2ObjectMap cloned = new Long2ObjectOpenHashMap<>(); -+ for (Long2ObjectMap.Entry entry : this.chunkStorage.long2ObjectEntrySet()) { - SlimeChunk clonedChunk = entry.getValue(); - // NMS "live" chunks need to be converted - { -@@ -242,7 +242,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - } - } - -- cloned.put(entry.getKey(), clonedChunk); -+ cloned.put(entry.getLongKey(), clonedChunk); - } - - // Serialize Bukkit Values (PDC) -@@ -275,8 +275,8 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - } - - public void ensureChunkMarkedAsLoaded(SlimeChunkLevel chunk) { -- if (chunkStorage.get(new ChunkPos(chunk.locX, chunk.locZ)) instanceof SlimeChunkSkeleton skeleton) { -- chunkStorage.put(new ChunkPos(chunk.locX, chunk.locZ), new NMSSlimeChunk(chunk, skeleton)); -+ if (chunkStorage.get(Util.chunkPosition(chunk.locX, chunk.locZ)) instanceof SlimeChunkSkeleton skeleton) { -+ chunkStorage.put(Util.chunkPosition(chunk.locX, chunk.locZ), new NMSSlimeChunk(chunk, skeleton)); - } - } - } From 04d627682dd6ad345c6b5e15e796fd065f0cd54a Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 14:54:20 +0100 Subject: [PATCH 050/133] Port "1.21 compatibility" by kyngs from 9 Jul 2024 --- .../world/level/chunk/LevelChunk.java.patch | 16 + .../infernalsuite/asp/SlimeNMSBridgeImpl.java | 2 +- .../asp/level/NMSSlimeChunk.java | 2 +- .../asp/level/SlimeChunkConverter.java | 20 +- .../asp/level/SlimeLevelInstance.java | 15 +- patches/server/0015-1.21-compatibility.patch | 296 ------------------ 6 files changed, 37 insertions(+), 314 deletions(-) create mode 100644 impl/aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/LevelChunk.java.patch delete mode 100644 patches/server/0015-1.21-compatibility.patch diff --git a/impl/aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/LevelChunk.java.patch b/impl/aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/LevelChunk.java.patch new file mode 100644 index 000000000..bc3ac2d13 --- /dev/null +++ b/impl/aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/LevelChunk.java.patch @@ -0,0 +1,16 @@ +--- a/net/minecraft/world/level/chunk/LevelChunk.java ++++ b/net/minecraft/world/level/chunk/LevelChunk.java +@@ -313,6 +_,13 @@ + } + } + ++ ++ // ASWM start - maintain binary compatibility with 1.20.6 ++ public ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder getChunkHolder() { ++ return this.level.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(chunkPos.x, chunkPos.z); ++ } ++ // ASWM end ++ + // Paper start - If loaded util + @Override + public final FluidState getFluidIfLoaded(BlockPos blockposition) { diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java index 033c2f2f0..48db6b755 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java @@ -208,7 +208,7 @@ private SlimeLevelInstance createCustomWorld(SlimeWorld world, @Nullable Resourc default -> throw new IllegalArgumentException("Unknown dimension supplied"); }; - ResourceKey worldKey = dimensionOverride == null ? ResourceKey.create(Registries.DIMENSION, new ResourceLocation(worldName.toLowerCase(Locale.ENGLISH))) : dimensionOverride; + ResourceKey worldKey = dimensionOverride == null ? ResourceKey.create(Registries.DIMENSION, ResourceLocation.parse(worldName.toLowerCase(Locale.ENGLISH))) : dimensionOverride; LevelStem stem = MinecraftServer.getServer().registries().compositeAccess().registryOrThrow(Registries.LEVEL_STEM).get(dimension); SlimeLevelInstance level; diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java index 91af462ab..5cdb857fe 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -8,7 +8,7 @@ import com.infernalsuite.asp.api.world.SlimeChunkSection; import com.mojang.logging.LogUtils; import com.mojang.serialization.Codec; -import io.papermc.paper.world.ChunkEntitySlices; +import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.nbt.LongArrayBinaryTag; import net.minecraft.core.Holder; diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java index 87a6acfee..47d5e3d45 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java @@ -1,6 +1,7 @@ package com.infernalsuite.asp.level; -import ca.spottedleaf.starlight.common.light.SWMRNibbleArray; +import ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray; +import ca.spottedleaf.moonrise.patches.starlight.light.StarLightEngine; import com.infernalsuite.asp.Converter; import com.infernalsuite.asp.api.utils.NibbleArray; import com.infernalsuite.asp.api.world.SlimeChunk; @@ -13,8 +14,6 @@ import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.NbtOps; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biomes; @@ -26,6 +25,7 @@ import net.minecraft.world.level.chunk.LevelChunkSection; import net.minecraft.world.level.chunk.PalettedContainer; import net.minecraft.world.level.chunk.UpgradeData; +import net.minecraft.world.level.chunk.status.ChunkStatusTasks; import net.minecraft.world.level.chunk.storage.ChunkSerializer; import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.material.Fluid; @@ -46,8 +46,8 @@ static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeC // Chunk sections LevelChunkSection[] sections = new LevelChunkSection[instance.getSectionsCount()]; - SWMRNibbleArray[] blockNibbles = ca.spottedleaf.starlight.common.light.StarLightEngine.getFilledEmptyLight(instance); - SWMRNibbleArray[] skyNibbles = ca.spottedleaf.starlight.common.light.StarLightEngine.getFilledEmptyLight(instance); + SWMRNibbleArray[] blockNibbles = StarLightEngine.getFilledEmptyLight(instance); + SWMRNibbleArray[] skyNibbles = StarLightEngine.getFilledEmptyLight(instance); instance.getServer().scheduleOnMain(() -> { instance.getLightEngine().retainData(pos, true); }); @@ -109,8 +109,8 @@ static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeC List entities = chunk.getEntities(); if (entities != null) { - net.minecraft.server.level.ChunkMap.postLoadProtoChunk(instance, entities.stream() - .map(tag -> (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)).toList(), nmsChunk.getPos()); + ChunkStatusTasks.postLoadProtoChunk(instance, entities.stream() + .map(flowTag -> (net.minecraft.nbt.CompoundTag) Converter.convertTag(flowTag)).toList(), nmsChunk.getPos()); } }; @@ -143,13 +143,13 @@ static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeC } // Height Maps - EnumSet heightMapTypes = nmsChunk.getStatus().heightmapsAfter(); + EnumSet heightMapTypes = nmsChunk.getPersistedStatus().heightmapsAfter(); CompoundBinaryTag heightMaps = chunk.getHeightMaps(); EnumSet unsetHeightMaps = EnumSet.noneOf(Heightmap.Types.class); // Light - nmsChunk.setBlockNibbles(blockNibbles); - nmsChunk.setSkyNibbles(skyNibbles); + nmsChunk.starlight$setBlockNibbles(blockNibbles); + nmsChunk.starlight$setSkyNibbles(skyNibbles); for (Heightmap.Types type : heightMapTypes) { String name = type.getSerializedName(); diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java index d8041d506..c03aab52f 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -1,6 +1,9 @@ package com.infernalsuite.asp.level; import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkLoadTask; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.GenericDataLoadTask; import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.infernalsuite.asp.Converter; import com.infernalsuite.asp.serialization.slime.SlimeSerializer; @@ -9,9 +12,7 @@ import com.infernalsuite.asp.api.world.SlimeWorldInstance; import com.infernalsuite.asp.api.world.properties.SlimeProperties; import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; -import io.papermc.paper.chunk.system.scheduling.ChunkLoadTask; -import io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler; -import io.papermc.paper.chunk.system.scheduling.GenericDataLoadTask; +import com.infernalsuite.asp.serialization.slime.SlimeSerializer; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; import net.minecraft.core.registries.Registries; @@ -106,7 +107,7 @@ public SlimeLevelInstance(SlimeBootstrap slimeBootstrap, PrimaryLevelData primar @Override public ChunkGenerator getGenerator(SlimeBootstrap slimeBootstrap) { String biomeStr = slimeBootstrap.initial().getPropertyMap().getValue(SlimeProperties.DEFAULT_BIOME); - ResourceKey biomeKey = ResourceKey.create(Registries.BIOME, new ResourceLocation(biomeStr)); + ResourceKey biomeKey = ResourceKey.create(Registries.BIOME, ResourceLocation.parse(biomeStr)); Holder defaultBiome = MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME).getHolder(biomeKey).orElseThrow(); return new SlimeLevelGenerator(defaultBiome); } @@ -144,12 +145,13 @@ public Future save() { return CompletableFuture.completedFuture(null); } + /* @Override public void saveIncrementally(boolean doFull) { if (doFull) { this.save(null, false, false); } - } + }*/ // Most likely unused - kyngs private Future saveInternal() { synchronized (saveLock) { // Don't want to save the SlimeWorld from multiple threads simultaneously @@ -180,6 +182,7 @@ public ChunkDataLoadTask getLoadTask(ChunkLoadTask task, ChunkTaskScheduler sche return new ChunkDataLoadTask(task, scheduler, world, chunkX, chunkZ, priority, onRun); } + /* public void loadEntities(int chunkX, int chunkZ) { SlimeChunk slimeChunk = this.slimeInstance.getChunk(chunkX, chunkZ); if (slimeChunk != null) { @@ -191,7 +194,7 @@ public void loadEntities(int chunkX, int chunkZ) { .toList() ), new ChunkPos(chunkX, chunkZ)); } - } + }*/ // Most likely unused - kyngs @Override public void setDefaultSpawnPos(BlockPos pos, float angle) { diff --git a/patches/server/0015-1.21-compatibility.patch b/patches/server/0015-1.21-compatibility.patch deleted file mode 100644 index 5afa09659..000000000 --- a/patches/server/0015-1.21-compatibility.patch +++ /dev/null @@ -1,296 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: kyngs -Date: Tue, 9 Jul 2024 02:00:22 +0200 -Subject: [PATCH] 1.21 compatibility - - -diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -index 328e70af280ccb32f4830e464f34499b8be0d72b..c0f990e34544811e23497e286842e403b32f947e 100644 ---- a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -+++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -@@ -206,7 +206,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { - default -> throw new IllegalArgumentException("Unknown dimension supplied"); - }; - -- ResourceKey worldKey = dimensionOverride == null ? ResourceKey.create(Registries.DIMENSION, new ResourceLocation(worldName.toLowerCase(Locale.ENGLISH))) : dimensionOverride; -+ ResourceKey worldKey = dimensionOverride == null ? ResourceKey.create(Registries.DIMENSION, ResourceLocation.parse(worldName.toLowerCase(Locale.ENGLISH))) : dimensionOverride; - LevelStem stem = MinecraftServer.getServer().registries().compositeAccess().registryOrThrow(Registries.LEVEL_STEM).get(dimension); - - SlimeLevelInstance level; -diff --git a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java -index bf44132f7614832119f798a2418e2014ec378cf9..2f0e34e105a27b12eb28dfc2b3c3b6590d76cbb2 100644 ---- a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java -+++ b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java -@@ -1,12 +1,12 @@ - package com.infernalsuite.asp.level; - - import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; -+import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkLoadTask; -+import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.GenericDataLoadTask; - import com.infernalsuite.asp.Converter; - import com.infernalsuite.asp.api.world.SlimeChunk; - import com.mojang.logging.LogUtils; --import io.papermc.paper.chunk.system.scheduling.ChunkLoadTask; --import io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler; --import io.papermc.paper.chunk.system.scheduling.GenericDataLoadTask; - import net.minecraft.nbt.CompoundTag; - import net.minecraft.server.level.ServerLevel; - import net.minecraft.world.level.ChunkPos; -diff --git a/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java b/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java -index 10bfcb7250c01c8361375c4d9b34d2b0ae17257d..7f86b1922f179a3ff9b4238ab2da5aea5dde5564 100644 ---- a/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java -+++ b/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java -@@ -1,9 +1,9 @@ - package com.infernalsuite.asp.level; - -+import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; - import com.infernalsuite.asp.api.world.SlimeWorld; - import com.infernalsuite.asp.api.world.properties.SlimeProperties; - import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; --import io.papermc.paper.world.ChunkEntitySlices; - import net.minecraft.world.level.chunk.LevelChunk; - import net.minecraft.world.level.chunk.LevelChunkSection; - -diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -index 7326a5af48338d58ac657a5ab62e9fbeb96e4346..97e96f51a6369a328a46086ebb250c9c163e10cf 100644 ---- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -+++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -@@ -1,15 +1,15 @@ - package com.infernalsuite.asp.level; - -+import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; - import com.google.common.collect.Lists; - import com.infernalsuite.asp.Converter; --import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; - import com.infernalsuite.asp.api.utils.NibbleArray; - import com.infernalsuite.asp.api.world.SlimeChunk; - import com.infernalsuite.asp.api.world.SlimeChunkSection; --import com.mojang.serialization.Codec; --import io.papermc.paper.world.ChunkEntitySlices; - import net.kyori.adventure.nbt.CompoundBinaryTag; - import net.kyori.adventure.nbt.LongArrayBinaryTag; -+import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; -+import com.mojang.serialization.Codec; - import net.minecraft.core.Holder; - import net.minecraft.core.Registry; - import net.minecraft.core.SectionPos; -@@ -25,7 +25,10 @@ import net.minecraft.world.level.block.Block; - import net.minecraft.world.level.block.Blocks; - import net.minecraft.world.level.block.entity.BlockEntity; - import net.minecraft.world.level.block.state.BlockState; --import net.minecraft.world.level.chunk.*; -+import net.minecraft.world.level.chunk.LevelChunk; -+import net.minecraft.world.level.chunk.LevelChunkSection; -+import net.minecraft.world.level.chunk.PalettedContainer; -+import net.minecraft.world.level.chunk.PalettedContainerRO; - import net.minecraft.world.level.chunk.storage.ChunkSerializer; - import net.minecraft.world.level.levelgen.Heightmap; - import net.minecraft.world.level.lighting.LevelLightEngine; -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -index 9bfb64e022db3bd9ed4d818d69df1f9a955cfa5d..73f9473b52df2ae9cea5f6361d2f8d00136c84da 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -@@ -1,6 +1,7 @@ - package com.infernalsuite.asp.level; - --import ca.spottedleaf.starlight.common.light.SWMRNibbleArray; -+import ca.spottedleaf.moonrise.patches.starlight.light.SWMRNibbleArray; -+import ca.spottedleaf.moonrise.patches.starlight.light.StarLightEngine; - import com.infernalsuite.asp.Converter; - import com.infernalsuite.asp.api.utils.NibbleArray; - import com.infernalsuite.asp.api.world.SlimeChunk; -@@ -13,8 +14,6 @@ import net.minecraft.core.Holder; - import net.minecraft.core.Registry; - import net.minecraft.core.registries.Registries; - import net.minecraft.nbt.NbtOps; --import net.minecraft.world.entity.Entity; --import net.minecraft.world.entity.EntityType; - import net.minecraft.world.level.ChunkPos; - import net.minecraft.world.level.biome.Biome; - import net.minecraft.world.level.biome.Biomes; -@@ -26,6 +25,7 @@ import net.minecraft.world.level.chunk.LevelChunk; - import net.minecraft.world.level.chunk.LevelChunkSection; - import net.minecraft.world.level.chunk.PalettedContainer; - import net.minecraft.world.level.chunk.UpgradeData; -+import net.minecraft.world.level.chunk.status.ChunkStatusTasks; - import net.minecraft.world.level.chunk.storage.ChunkSerializer; - import net.minecraft.world.level.levelgen.Heightmap; - import net.minecraft.world.level.material.Fluid; -@@ -46,8 +46,8 @@ public class SlimeChunkConverter { - // Chunk sections - LevelChunkSection[] sections = new LevelChunkSection[instance.getSectionsCount()]; - -- SWMRNibbleArray[] blockNibbles = ca.spottedleaf.starlight.common.light.StarLightEngine.getFilledEmptyLight(instance); -- SWMRNibbleArray[] skyNibbles = ca.spottedleaf.starlight.common.light.StarLightEngine.getFilledEmptyLight(instance); -+ SWMRNibbleArray[] blockNibbles = StarLightEngine.getFilledEmptyLight(instance); -+ SWMRNibbleArray[] skyNibbles = StarLightEngine.getFilledEmptyLight(instance); - instance.getServer().scheduleOnMain(() -> { - instance.getLightEngine().retainData(pos, true); - }); -@@ -109,8 +109,8 @@ public class SlimeChunkConverter { - List entities = chunk.getEntities(); - - if (entities != null) { -- net.minecraft.server.level.ChunkMap.postLoadProtoChunk(instance, entities.stream() -- .map(tag -> (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)).toList(), nmsChunk.getPos()); -+ ChunkStatusTasks.postLoadProtoChunk(instance, entities.stream() -+ .map(flowTag -> (net.minecraft.nbt.CompoundTag) Converter.convertTag(flowTag)).toList(), nmsChunk.getPos()); - } - }; - -@@ -144,13 +144,13 @@ public class SlimeChunkConverter { - } - - // Height Maps -- EnumSet heightMapTypes = nmsChunk.getStatus().heightmapsAfter(); -+ EnumSet heightMapTypes = nmsChunk.getPersistedStatus().heightmapsAfter(); - CompoundBinaryTag heightMaps = chunk.getHeightMaps(); - EnumSet unsetHeightMaps = EnumSet.noneOf(Heightmap.Types.class); - - // Light -- nmsChunk.setBlockNibbles(blockNibbles); -- nmsChunk.setSkyNibbles(skyNibbles); -+ nmsChunk.starlight$setBlockNibbles(blockNibbles); -+ nmsChunk.starlight$setSkyNibbles(skyNibbles); - - for (Heightmap.Types type : heightMapTypes) { - String name = type.getSerializedName(); -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -index d6e5eac7732f32cabd6ed5ac6b10af20074a39b8..33af1d7e671c5aeb06482038e205efc831641ec0 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -@@ -1,17 +1,15 @@ - package com.infernalsuite.asp.level; - - import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; -+import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkLoadTask; -+import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.GenericDataLoadTask; - import com.google.common.util.concurrent.ThreadFactoryBuilder; --import com.infernalsuite.asp.Converter; --import com.infernalsuite.asp.serialization.slime.SlimeSerializer; --import com.infernalsuite.asp.api.world.SlimeChunk; - import com.infernalsuite.asp.api.world.SlimeWorld; - import com.infernalsuite.asp.api.world.SlimeWorldInstance; - import com.infernalsuite.asp.api.world.properties.SlimeProperties; - import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; --import io.papermc.paper.chunk.system.scheduling.ChunkLoadTask; --import io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler; --import io.papermc.paper.chunk.system.scheduling.GenericDataLoadTask; -+import com.infernalsuite.asp.serialization.slime.SlimeSerializer; - import net.minecraft.core.BlockPos; - import net.minecraft.core.Holder; - import net.minecraft.core.registries.Registries; -@@ -24,8 +22,6 @@ import net.minecraft.util.ProgressListener; - import net.minecraft.util.Unit; - import net.minecraft.util.datafix.DataFixers; - import net.minecraft.world.Difficulty; --import net.minecraft.world.entity.EntityType; --import net.minecraft.world.level.ChunkPos; - import net.minecraft.world.level.biome.Biome; - import net.minecraft.world.level.chunk.ChunkAccess; - import net.minecraft.world.level.chunk.ChunkGenerator; -@@ -42,7 +38,6 @@ import org.spigotmc.AsyncCatcher; - import java.io.IOException; - import java.nio.file.Files; - import java.nio.file.Path; --import java.util.ArrayList; - import java.util.Collections; - import java.util.UUID; - import java.util.concurrent.CompletableFuture; -@@ -51,7 +46,6 @@ import java.util.concurrent.Executors; - import java.util.concurrent.Future; - import java.util.function.Consumer; - import java.util.logging.Level; --import java.util.stream.Collectors; - - public class SlimeLevelInstance extends ServerLevel { - -@@ -106,7 +100,7 @@ public class SlimeLevelInstance extends ServerLevel { - @Override - public ChunkGenerator getGenerator(SlimeBootstrap slimeBootstrap) { - String biomeStr = slimeBootstrap.initial().getPropertyMap().getValue(SlimeProperties.DEFAULT_BIOME); -- ResourceKey biomeKey = ResourceKey.create(Registries.BIOME, new ResourceLocation(biomeStr)); -+ ResourceKey biomeKey = ResourceKey.create(Registries.BIOME, ResourceLocation.parse(biomeStr)); - Holder defaultBiome = MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME).getHolder(biomeKey).orElseThrow(); - return new SlimeLevelGenerator(defaultBiome); - } -@@ -144,12 +138,13 @@ public class SlimeLevelInstance extends ServerLevel { - return CompletableFuture.completedFuture(null); - } - -+ /* - @Override - public void saveIncrementally(boolean doFull) { - if (doFull) { - this.save(null, false, false); - } -- } -+ }*/ // Most likely unused - kyngs - - private Future saveInternal() { - synchronized (saveLock) { // Don't want to save the SlimeWorld from multiple threads simultaneously -@@ -180,6 +175,7 @@ public class SlimeLevelInstance extends ServerLevel { - return new ChunkDataLoadTask(task, scheduler, world, chunkX, chunkZ, priority, onRun); - } - -+ /* - public void loadEntities(int chunkX, int chunkZ) { - SlimeChunk slimeChunk = this.slimeInstance.getChunk(chunkX, chunkZ); - if (slimeChunk != null) { -@@ -191,7 +187,7 @@ public class SlimeLevelInstance extends ServerLevel { - .toList() - ), new ChunkPos(chunkX, chunkZ)); - } -- } -+ }*/ // Most likely unused - kyngs - - @Override - public void setDefaultSpawnPos(BlockPos pos, float angle) { -diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -index 97937e3bd211997f0a0a3e9e671a1c59712d0003..7154f6050b01c234e00fab22f5e5f1d6a944500a 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -1,5 +1,7 @@ - package net.minecraft.world.level.chunk; - -+import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager; -+import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder; - import com.google.common.collect.ImmutableList; - import com.google.common.collect.Maps; - import com.google.common.collect.UnmodifiableIterator; -@@ -24,6 +26,7 @@ import net.minecraft.core.registries.Registries; - import net.minecraft.nbt.CompoundTag; - import net.minecraft.network.FriendlyByteBuf; - import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData; -+import net.minecraft.server.level.ChunkHolder; - import net.minecraft.server.level.FullChunkStatus; - import net.minecraft.server.level.ServerLevel; - import net.minecraft.util.profiling.Profiler; -@@ -327,6 +330,12 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p - } - } - -+ // ASWM start - maintain binary compatibility with 1.20.6 -+ public NewChunkHolder getChunkHolder() { -+ return this.level.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(chunkPos.x, chunkPos.z); -+ } -+ // ASWM end -+ - // Paper start - If loaded util - @Override - public final FluidState getFluidIfLoaded(BlockPos blockposition) { -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index 6f482bf045cf7a14dceb5673d9d19ee87b7c03a8..cb0c551bb3899201e2ca55a72babc76b3704501b 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -@@ -469,7 +469,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun - SerializableChunkData.LOGGER.error("Recoverable errors when loading section [{}, {}, {}]: {}", new Object[]{chunkPos.x, y, chunkPos.z, message}); - } - -- private static Codec>> makeBiomeCodec(Registry biomeRegistry) { -+ public static Codec>> makeBiomeCodec(Registry biomeRegistry) { - return PalettedContainer.codecRO(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getOrThrow(Biomes.PLAINS)); - } - From 45a253c7a0cf015cca9acc79d0152dc27b2b5a20 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 14:55:18 +0100 Subject: [PATCH 051/133] Port "Fix chunk saving when unloading" by TechStreet from 26 Aug 2024 --- .../asp/level/SlimeLevelInstance.java | 11 +++--- ...0016-Fix-chunk-saving-when-unloading.patch | 34 ------------------- 2 files changed, 6 insertions(+), 39 deletions(-) delete mode 100644 patches/server/0016-Fix-chunk-saving-when-unloading.patch diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java index c03aab52f..3f1b9b95a 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -30,6 +30,7 @@ import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.dimension.LevelStem; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; @@ -207,9 +208,9 @@ public void setDefaultSpawnPos(BlockPos pos, float angle) { propertyMap.setValue(SlimeProperties.SPAWN_YAW, angle); } - // @Override - // public void unload(LevelChunk chunk) { - // this.slimeInstance.unload(chunk); - // super.unload(chunk); - // } + @Override + public void unload(LevelChunk chunk) { + this.slimeInstance.unload(chunk); + super.unload(chunk); + } } diff --git a/patches/server/0016-Fix-chunk-saving-when-unloading.patch b/patches/server/0016-Fix-chunk-saving-when-unloading.patch deleted file mode 100644 index 5eb3342be..000000000 --- a/patches/server/0016-Fix-chunk-saving-when-unloading.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: TechStreet <80351782+TechStreetDev@users.noreply.github.com> -Date: Mon, 26 Aug 2024 21:27:08 +0100 -Subject: [PATCH] Fix chunk saving when unloading - - -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -index 33af1d7e671c5aeb06482038e205efc831641ec0..dbc4620fea0b1b5aa130aaaa2af06fcaad93ed29 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -@@ -25,6 +25,7 @@ import net.minecraft.world.Difficulty; - import net.minecraft.world.level.biome.Biome; - import net.minecraft.world.level.chunk.ChunkAccess; - import net.minecraft.world.level.chunk.ChunkGenerator; -+import net.minecraft.world.level.chunk.LevelChunk; - import net.minecraft.world.level.dimension.LevelStem; - import net.minecraft.world.level.storage.LevelStorageSource; - import net.minecraft.world.level.storage.PrimaryLevelData; -@@ -200,9 +201,9 @@ public class SlimeLevelInstance extends ServerLevel { - propertyMap.setValue(SlimeProperties.SPAWN_YAW, angle); - } - -- // @Override -- // public void unload(LevelChunk chunk) { -- // this.slimeInstance.unload(chunk); -- // super.unload(chunk); -- // } -+ @Override -+ public void unload(LevelChunk chunk) { -+ this.slimeInstance.unload(chunk); -+ super.unload(chunk); -+ } - } -\ No newline at end of file From 41869332a7086068145922d6cd672f1a7e0e8de4 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 14:59:34 +0100 Subject: [PATCH 052/133] Port "fix disable dragon fights" by evlad from 9 Sep 2024 --- .../features/0001-Disable-dragon-battle.patch | 25 ++++++++++++++ .../0017-fix-disable-dragon-fights.patch | 33 ------------------- 2 files changed, 25 insertions(+), 33 deletions(-) create mode 100644 impl/aspaper-server/minecraft-patches/features/0001-Disable-dragon-battle.patch delete mode 100644 patches/server/0017-fix-disable-dragon-fights.patch diff --git a/impl/aspaper-server/minecraft-patches/features/0001-Disable-dragon-battle.patch b/impl/aspaper-server/minecraft-patches/features/0001-Disable-dragon-battle.patch new file mode 100644 index 000000000..a7c61d1a6 --- /dev/null +++ b/impl/aspaper-server/minecraft-patches/features/0001-Disable-dragon-battle.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: evlad +Date: Mon, 9 Sep 2024 21:33:11 +0300 +Subject: [PATCH] Disable dragon battle + + +diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java +index 253280d5bc2c050ce727e85c7daeccd306903af3..426a9fa0000266c569d69c6418e4d772adacd38c 100644 +--- a/net/minecraft/server/level/ServerLevel.java ++++ b/net/minecraft/server/level/ServerLevel.java +@@ -690,7 +690,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + ); + this.structureManager = new StructureManager(this, this.serverLevelData.worldGenOptions(), this.structureCheck); // CraftBukkit + if (this.dimension() == Level.END && this.dimensionTypeRegistration().is(BuiltinDimensionTypes.END) || env == org.bukkit.World.Environment.THE_END) { // CraftBukkit - Allow to create EnderDragonBattle in default and custom END +- this.dragonFight = new EndDragonFight(this, this.serverLevelData.worldGenOptions().seed(), this.serverLevelData.endDragonFightData()); // CraftBukkit ++ // ASP START ++ if (bootstrap == null || bootstrap.initial().getPropertyMap().getValue(com.infernalsuite.asp.api.world.properties.SlimeProperties.DRAGON_BATTLE)) { ++ this.dragonFight = new EndDragonFight(this, this.serverLevelData.worldGenOptions().seed(), this.serverLevelData.endDragonFightData()); // CraftBukkit ++ } else { ++ this.dragonFight = new EndDragonFight(this, this.serverLevelData.worldGenOptions().seed(), new EndDragonFight.Data(false, true, true, false,Optional.empty(),Optional.empty(),Optional.empty())); // ASP - disable dragon ++ } ++ // ASP END + } else { + this.dragonFight = null; + } diff --git a/patches/server/0017-fix-disable-dragon-fights.patch b/patches/server/0017-fix-disable-dragon-fights.patch deleted file mode 100644 index 8bf690d8b..000000000 --- a/patches/server/0017-fix-disable-dragon-fights.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: evlad -Date: Mon, 9 Sep 2024 21:33:11 +0300 -Subject: [PATCH] fix disable dragon fights - - -diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 18fe62b5f6f90099d321ad381a941d8e3bd1ea66..4e0550e917bc9110a87f92e75d6a2f31408386fc 100644 ---- a/src/main/java/net/minecraft/server/level/ServerLevel.java -+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2,6 +2,7 @@ package net.minecraft.server.level; - - import com.google.common.annotations.VisibleForTesting; - import com.google.common.collect.Lists; -+import com.infernalsuite.asp.api.world.properties.SlimeProperties; // ASP - import com.mojang.datafixers.DataFixer; - import com.mojang.datafixers.util.Pair; - import com.mojang.logging.LogUtils; -@@ -663,7 +664,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - this.structureCheck = new StructureCheck(this.chunkSource.chunkScanner(), this.registryAccess(), minecraftserver.getStructureManager(), this.getTypeKey(), chunkgenerator, this.chunkSource.randomState(), this, chunkgenerator.getBiomeSource(), l, datafixer); // Paper - Fix missing CB diff - this.structureManager = new StructureManager(this, this.serverLevelData.worldGenOptions(), this.structureCheck); // CraftBukkit - if ((this.dimension() == Level.END && this.dimensionTypeRegistration().is(BuiltinDimensionTypes.END)) || env == org.bukkit.World.Environment.THE_END) { // CraftBukkit - Allow to create EnderDragonBattle in default and custom END -- this.dragonFight = new EndDragonFight(this, this.serverLevelData.worldGenOptions().seed(), this.serverLevelData.endDragonFightData()); // CraftBukkit -+ // ASP START -+ if (bootstrap == null || bootstrap.initial().getPropertyMap().getValue(SlimeProperties.DRAGON_BATTLE)) { -+ this.dragonFight = new EndDragonFight(this, this.serverLevelData.worldGenOptions().seed(), this.serverLevelData.endDragonFightData()); // CraftBukkit -+ } else { -+ this.dragonFight = new EndDragonFight(this, this.serverLevelData.worldGenOptions().seed(), new EndDragonFight.Data(false, true, true, false,Optional.empty(),Optional.empty(),Optional.empty())); // ASP - disable dragon -+ } -+ // ASP END - } else { - this.dragonFight = null; - } From 9c8f470937335bed9f309f0c62ba0b5d80b828a4 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 15:00:32 +0100 Subject: [PATCH 053/133] Port "fix chunk pdc getting wiped on chunk unload" by evlad from 19 Sep 2024 --- .../infernalsuite/asp/level/NMSSlimeChunk.java | 1 + ...unk-pdc-getting-wiped-on-chunk-unload.patch | 18 ------------------ 2 files changed, 1 insertion(+), 18 deletions(-) delete mode 100644 patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java index 5cdb857fe..053368e10 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -70,6 +70,7 @@ public class NMSSlimeChunk implements SlimeChunk { public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference) { this.chunk = chunk; this.extra = reference == null ? CompoundBinaryTag.empty() : reference.getExtraData(); + this.extra.put("ChunkBukkitValues", Converter.convertTag(chunk.persistentDataContainer.toTagCompound())); this.upgradeData = reference == null ? null : reference.getUpgradeData(); } diff --git a/patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch b/patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch deleted file mode 100644 index 50b5893e2..000000000 --- a/patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch +++ /dev/null @@ -1,18 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: evlad -Date: Thu, 19 Sep 2024 20:47:32 +0300 -Subject: [PATCH] fix chunk pdc getting wiped on chunk unload - - -diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -index 97e96f51a6369a328a46086ebb250c9c163e10cf..8053d224ca673c3abe60151b3b322e3e4c9c3fcf 100644 ---- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -+++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -@@ -68,6 +68,7 @@ public class NMSSlimeChunk implements SlimeChunk { - public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference) { - this.chunk = chunk; - this.extra = reference == null ? CompoundBinaryTag.empty() : reference.getExtraData(); -+ this.extra.put("ChunkBukkitValues", Converter.convertTag(chunk.persistentDataContainer.toTagCompound())); - this.upgradeData = reference == null ? null : reference.getUpgradeData(); - } - From 15cf7d754696aae25cb7d446a06b4735d13caf15 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 18:24:27 +0100 Subject: [PATCH 054/133] Port "1.21.3 fixes" by AverageGithub from 10 Nev 2024 --- .../storage/SerializableChunkData.java.patch | 2 +- .../infernalsuite/asp/SlimeNMSBridgeImpl.java | 4 +- .../asp/level/NMSSlimeChunk.java | 17 +- .../asp/level/SlimeChunkConverter.java | 11 +- .../asp/level/SlimeLevelInstance.java | 12 +- patches/server/0019-1.21.3-fixes.patch | 284 ------------------ 6 files changed, 22 insertions(+), 308 deletions(-) delete mode 100644 patches/server/0019-1.21.3-fixes.patch diff --git a/impl/aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch b/impl/aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch index e1b834742..81744efd8 100644 --- a/impl/aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch +++ b/impl/aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch @@ -7,7 +7,7 @@ + + //ASP start + if (level instanceof com.infernalsuite.asp.level.SlimeLevelInstance) { -+ poiManager.checkConsistencyWithBlocks(SectionPos.of(chunkPos.getWorldPosition()), achunksection[j]); ++ poiManager.checkConsistencyWithBlocks(sectionPos, sectionData.chunkSection); + } + //ASP end } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java index 48db6b755..e7e3f7e53 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java @@ -209,7 +209,7 @@ private SlimeLevelInstance createCustomWorld(SlimeWorld world, @Nullable Resourc }; ResourceKey worldKey = dimensionOverride == null ? ResourceKey.create(Registries.DIMENSION, ResourceLocation.parse(worldName.toLowerCase(Locale.ENGLISH))) : dimensionOverride; - LevelStem stem = MinecraftServer.getServer().registries().compositeAccess().registryOrThrow(Registries.LEVEL_STEM).get(dimension); + LevelStem stem = MinecraftServer.getServer().registries().compositeAccess().lookupOrThrow(Registries.LEVEL_STEM).get(dimension).orElseThrow().value(); SlimeLevelInstance level; @@ -220,7 +220,7 @@ private SlimeLevelInstance createCustomWorld(SlimeWorld world, @Nullable Resourc } // level.setReady(true); - level.setSpawnSettings(world.getPropertyMap().getValue(SlimeProperties.ALLOW_MONSTERS), world.getPropertyMap().getValue(SlimeProperties.ALLOW_ANIMALS)); + level.setSpawnSettings(world.getPropertyMap().getValue(SlimeProperties.ALLOW_MONSTERS)); CompoundTag nmsExtraData = (CompoundTag) Converter.convertTag(CompoundBinaryTag.from(world.getExtraData())); diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java index 053368e10..a5afbe639 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -30,8 +30,7 @@ import net.minecraft.world.level.chunk.LevelChunkSection; import net.minecraft.world.level.chunk.PalettedContainer; import net.minecraft.world.level.chunk.PalettedContainerRO; -import net.minecraft.world.level.chunk.storage.ChunkSerializer; -import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.chunk.storage.SerializableChunkData; import net.minecraft.world.level.lighting.LevelLightEngine; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,14 +49,14 @@ public class NMSSlimeChunk implements SlimeChunk { static { { PalettedContainer empty = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, null); - Tag tag = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); + Tag tag = SerializableChunkData.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); EMPTY_BLOCK_STATE_PALETTE = Converter.convertTag(tag); } { - Registry biomes = net.minecraft.server.MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME); - PalettedContainer> empty = new PalettedContainer<>(biomes.asHolderIdMap(), biomes.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); - Tag tag = ChunkSerializer.makeBiomeCodec(biomes).encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); + Registry biomes = net.minecraft.server.MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BIOME); + PalettedContainer> empty = new PalettedContainer<>(biomes.asHolderIdMap(), biomes.get(Biomes.PLAINS).orElseThrow(), PalettedContainer.Strategy.SECTION_BIOMES, null); + Tag tag = SerializableChunkData.makeBiomeCodec(biomes).encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); EMPTY_BIOME_PALETTE = Converter.convertTag(tag); } @@ -89,10 +88,10 @@ public SlimeChunkSection[] getSections() { SlimeChunkSection[] sections = new SlimeChunkSection[this.chunk.getSectionsCount()]; LevelLightEngine lightEngine = chunk.getLevel().getChunkSource().getLightEngine(); - Registry biomeRegistry = chunk.getLevel().registryAccess().registryOrThrow(Registries.BIOME); + Registry biomeRegistry = chunk.getLevel().registryAccess().lookupOrThrow(Registries.BIOME); // Ignore deprecation, spigot only method - Codec>> codec = PalettedContainer.codecRO(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getHolderOrThrow(Biomes.PLAINS)); + Codec>> codec = PalettedContainer.codecRO(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.get(Biomes.PLAINS).orElseThrow()); for (int sectionId = 0; sectionId < chunk.getSections().length; sectionId++) { LevelChunkSection section = chunk.getSections()[sectionId]; @@ -111,7 +110,7 @@ public SlimeChunkSection[] getSections() { if (section.hasOnlyAir()) { blockStateTag = EMPTY_BLOCK_STATE_PALETTE; } else { - Tag data = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, section.getStates()).getOrThrow(); // todo error handling + Tag data = SerializableChunkData.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, section.getStates()).getOrThrow(); // todo error handling blockStateTag = Converter.convertTag(data); } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java index 47d5e3d45..8cbd78e09 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java @@ -26,14 +26,13 @@ import net.minecraft.world.level.chunk.PalettedContainer; import net.minecraft.world.level.chunk.UpgradeData; import net.minecraft.world.level.chunk.status.ChunkStatusTasks; -import net.minecraft.world.level.chunk.storage.ChunkSerializer; +import net.minecraft.world.level.chunk.storage.SerializableChunkData; import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.ticks.LevelChunkTicks; import java.util.EnumSet; import java.util.List; -import java.util.Optional; public class SlimeChunkConverter { @@ -52,10 +51,10 @@ static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeC instance.getLightEngine().retainData(pos, true); }); - Registry biomeRegistry = instance.registryAccess().registryOrThrow(Registries.BIOME); + Registry biomeRegistry = instance.registryAccess().lookupOrThrow(Registries.BIOME); // Ignore deprecated method - Codec>> codec = PalettedContainer.codecRW(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getHolderOrThrow(Biomes.PLAINS), null); + Codec>> codec = PalettedContainer.codecRW(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.get(Biomes.PLAINS).orElseThrow(), null); for (int sectionId = 0; sectionId < chunk.getSections().length; sectionId++) { SlimeChunkSection slimeSection = chunk.getSections()[sectionId]; @@ -73,7 +72,7 @@ static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeC PalettedContainer blockPalette; if (slimeSection.getBlockStatesTag() != null) { - DataResult> dataresult = ChunkSerializer.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, Converter.convertTag(slimeSection.getBlockStatesTag())).promotePartial((s) -> { + DataResult> dataresult = SerializableChunkData.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, Converter.convertTag(slimeSection.getBlockStatesTag())).promotePartial((s) -> { System.out.println("Recoverable error when parsing section " + x + "," + z + ": " + s); // todo proper logging }); blockPalette = dataresult.getOrThrow(); // todo proper logging @@ -89,7 +88,7 @@ static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeC }); biomePalette = dataresult.getOrThrow(); // todo proper logging } else { - biomePalette = new PalettedContainer<>(biomeRegistry.asHolderIdMap(), biomeRegistry.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); + biomePalette = new PalettedContainer<>(biomeRegistry.asHolderIdMap(), biomeRegistry.get(Biomes.PLAINS).orElseThrow(), PalettedContainer.Strategy.SECTION_BIOMES, null); } if (sectionId < sections.length) { diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java index 3f1b9b95a..cd993f0bf 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -1,6 +1,6 @@ package com.infernalsuite.asp.level; -import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; +import ca.spottedleaf.concurrentutil.util.Priority; import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkLoadTask; import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.GenericDataLoadTask; @@ -87,8 +87,8 @@ public SlimeLevelInstance(SlimeBootstrap slimeBootstrap, PrimaryLevelData primar super(slimeBootstrap, MinecraftServer.getServer(), MinecraftServer.getServer().executor, CUSTOM_LEVEL_STORAGE.createAccess(slimeBootstrap.initial().getName() + UUID.randomUUID(), dimensionKey), primaryLevelData, worldKey, worldDimension, - MinecraftServer.getServer().progressListenerFactory.create(11), false, null, 0, - Collections.emptyList(), true, environment, null, null); + MinecraftServer.getServer().progressListenerFactory.create(11), false, 0, + Collections.emptyList(), true, null, environment, null, null); this.slimeInstance = new SlimeInMemoryWorld(slimeBootstrap, this); @@ -100,7 +100,7 @@ public SlimeLevelInstance(SlimeBootstrap slimeBootstrap, PrimaryLevelData primar propertyMap.getValue(SlimeProperties.SPAWN_Y), propertyMap.getValue(SlimeProperties.SPAWN_Z)), propertyMap.getValue(SlimeProperties.SPAWN_YAW)); - super.setSpawnSettings(propertyMap.getValue(SlimeProperties.ALLOW_MONSTERS), propertyMap.getValue(SlimeProperties.ALLOW_ANIMALS)); + super.setSpawnSettings(propertyMap.getValue(SlimeProperties.ALLOW_MONSTERS)); this.pvpMode = propertyMap.getValue(SlimeProperties.PVP); } @@ -109,7 +109,7 @@ public SlimeLevelInstance(SlimeBootstrap slimeBootstrap, PrimaryLevelData primar public ChunkGenerator getGenerator(SlimeBootstrap slimeBootstrap) { String biomeStr = slimeBootstrap.initial().getPropertyMap().getValue(SlimeProperties.DEFAULT_BIOME); ResourceKey biomeKey = ResourceKey.create(Registries.BIOME, ResourceLocation.parse(biomeStr)); - Holder defaultBiome = MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME).getHolder(biomeKey).orElseThrow(); + Holder defaultBiome = MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BIOME).get(biomeKey).orElseThrow(); return new SlimeLevelGenerator(defaultBiome); } @@ -179,7 +179,7 @@ public SlimeWorldInstance getSlimeInstance() { return this.slimeInstance; } - public ChunkDataLoadTask getLoadTask(ChunkLoadTask task, ChunkTaskScheduler scheduler, ServerLevel world, int chunkX, int chunkZ, PrioritisedExecutor.Priority priority, Consumer> onRun) { + public ChunkDataLoadTask getLoadTask(ChunkLoadTask task, ChunkTaskScheduler scheduler, ServerLevel world, int chunkX, int chunkZ, Priority priority, Consumer> onRun) { return new ChunkDataLoadTask(task, scheduler, world, chunkX, chunkZ, priority, onRun); } diff --git a/patches/server/0019-1.21.3-fixes.patch b/patches/server/0019-1.21.3-fixes.patch deleted file mode 100644 index 5e98844c9..000000000 --- a/patches/server/0019-1.21.3-fixes.patch +++ /dev/null @@ -1,284 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: AverageGithub -Date: Sun, 10 Nov 2024 13:06:42 +0100 -Subject: [PATCH] 1.21.3 fixes - - -diff --git a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -index c0f990e34544811e23497e286842e403b32f947e..8956b3c4456fdda86c5ce7f3bbf732f476f54f39 100644 ---- a/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -+++ b/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java -@@ -207,7 +207,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { - }; - - ResourceKey worldKey = dimensionOverride == null ? ResourceKey.create(Registries.DIMENSION, ResourceLocation.parse(worldName.toLowerCase(Locale.ENGLISH))) : dimensionOverride; -- LevelStem stem = MinecraftServer.getServer().registries().compositeAccess().registryOrThrow(Registries.LEVEL_STEM).get(dimension); -+ LevelStem stem = MinecraftServer.getServer().registries().compositeAccess().lookupOrThrow(Registries.LEVEL_STEM).get(dimension).orElseThrow().value(); - - SlimeLevelInstance level; - -@@ -218,7 +218,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { - } - - // level.setReady(true); -- level.setSpawnSettings(world.getPropertyMap().getValue(SlimeProperties.ALLOW_MONSTERS), world.getPropertyMap().getValue(SlimeProperties.ALLOW_ANIMALS)); -+ level.setSpawnSettings(world.getPropertyMap().getValue(SlimeProperties.ALLOW_MONSTERS)); - - CompoundTag nmsExtraData = (CompoundTag) Converter.convertTag(CompoundBinaryTag.from(world.getExtraData())); - -@@ -238,7 +238,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { - String worldName = world.getName(); - - LevelSettings worldsettings = new LevelSettings(worldName, serverProps.gamemode, false, serverProps.difficulty, -- true, new GameRules(), mcServer.worldLoader.dataConfiguration()); -+ true, new GameRules(net.minecraft.world.flag.FeatureFlagSet.of()), mcServer.worldLoader.dataConfiguration()); - - WorldOptions worldoptions = new WorldOptions(0, false, false); - -diff --git a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java -index 2f0e34e105a27b12eb28dfc2b3c3b6590d76cbb2..2b700ec76e0eca7441676d48cf842cb944261668 100644 ---- a/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java -+++ b/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java -@@ -1,6 +1,7 @@ - package com.infernalsuite.asp.level; - --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.util.Priority; - import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; - import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkLoadTask; - import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.GenericDataLoadTask; -@@ -36,7 +37,7 @@ public final class ChunkDataLoadTask implements CommonLoadTask { - private final ChunkLoadTask chunkLoadTask; - - protected ChunkDataLoadTask(ChunkLoadTask chunkLoadTask, final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX, -- final int chunkZ, final PrioritisedExecutor.Priority priority, final Consumer> onRun) { -+ final int chunkZ, final Priority priority, final Consumer> onRun) { - this.chunkLoadTask = chunkLoadTask; - this.scheduler = scheduler; - this.world = world; -@@ -86,22 +87,22 @@ public final class ChunkDataLoadTask implements CommonLoadTask { - } - - @Override -- public PrioritisedExecutor.Priority getPriority() { -+ public Priority getPriority() { - return this.task.getPriority(); - } - - @Override -- public void setPriority(PrioritisedExecutor.Priority priority) { -+ public void setPriority(Priority priority) { - this.task.setPriority(priority); - } - - @Override -- public void raisePriority(PrioritisedExecutor.Priority priority) { -+ public void raisePriority(Priority priority) { - this.task.raisePriority(priority); - } - - @Override -- public void lowerPriority(PrioritisedExecutor.Priority priority) { -+ public void lowerPriority(Priority priority) { - this.task.lowerPriority(priority); - } - -diff --git a/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java b/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java -index 9954db3eabd60ac0600af1efc6f8a1650ef4d85b..09e8a5fc5a56aefdee281b730c471e5f0907be66 100644 ---- a/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java -+++ b/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java -@@ -1,18 +1,18 @@ - package com.infernalsuite.asp.level; - --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.util.Priority; - - public interface CommonLoadTask { - - boolean schedule(boolean schedule); - -- PrioritisedExecutor.Priority getPriority(); -+ Priority getPriority(); - - boolean cancel(); - -- void lowerPriority(PrioritisedExecutor.Priority priority); -+ void lowerPriority(Priority priority); - -- void raisePriority(PrioritisedExecutor.Priority priority); -+ void raisePriority(Priority priority); - -- void setPriority(PrioritisedExecutor.Priority priority); -+ void setPriority(Priority priority); - } -\ No newline at end of file -diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -index 8053d224ca673c3abe60151b3b322e3e4c9c3fcf..fcdc22a4c107d2a9f4756a473e2b570a4d29b495 100644 ---- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -+++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -@@ -29,8 +29,7 @@ import net.minecraft.world.level.chunk.LevelChunk; - import net.minecraft.world.level.chunk.LevelChunkSection; - import net.minecraft.world.level.chunk.PalettedContainer; - import net.minecraft.world.level.chunk.PalettedContainerRO; --import net.minecraft.world.level.chunk.storage.ChunkSerializer; --import net.minecraft.world.level.levelgen.Heightmap; -+import net.minecraft.world.level.chunk.storage.SerializableChunkData; - import net.minecraft.world.level.lighting.LevelLightEngine; - import org.slf4j.Logger; - import org.slf4j.LoggerFactory; -@@ -48,14 +47,14 @@ public class NMSSlimeChunk implements SlimeChunk { - static { - { - PalettedContainer empty = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, null); -- Tag tag = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); -+ Tag tag = SerializableChunkData.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); - - EMPTY_BLOCK_STATE_PALETTE = Converter.convertTag(tag); - } - { -- Registry biomes = net.minecraft.server.MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME); -- PalettedContainer> empty = new PalettedContainer<>(biomes.asHolderIdMap(), biomes.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); -- Tag tag = ChunkSerializer.makeBiomeCodec(biomes).encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); -+ Registry biomes = net.minecraft.server.MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BIOME); -+ PalettedContainer> empty = new PalettedContainer<>(biomes.asHolderIdMap(), biomes.get(Biomes.PLAINS).orElseThrow(), PalettedContainer.Strategy.SECTION_BIOMES, null); -+ Tag tag = SerializableChunkData.makeBiomeCodec(biomes).encodeStart(NbtOps.INSTANCE, empty).getOrThrow(); - - EMPTY_BIOME_PALETTE = Converter.convertTag(tag); - } -@@ -87,10 +86,10 @@ public class NMSSlimeChunk implements SlimeChunk { - SlimeChunkSection[] sections = new SlimeChunkSection[this.chunk.getSectionsCount()]; - LevelLightEngine lightEngine = chunk.getLevel().getChunkSource().getLightEngine(); - -- Registry biomeRegistry = chunk.getLevel().registryAccess().registryOrThrow(Registries.BIOME); -+ Registry biomeRegistry = chunk.getLevel().registryAccess().lookupOrThrow(Registries.BIOME); - - // Ignore deprecation, spigot only method -- Codec>> codec = PalettedContainer.codecRO(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getHolderOrThrow(Biomes.PLAINS)); -+ Codec>> codec = PalettedContainer.codecRO(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.get(Biomes.PLAINS).orElseThrow()); - - for (int sectionId = 0; sectionId < chunk.getSections().length; sectionId++) { - LevelChunkSection section = chunk.getSections()[sectionId]; -@@ -109,7 +108,7 @@ public class NMSSlimeChunk implements SlimeChunk { - if (section.hasOnlyAir()) { - blockStateTag = EMPTY_BLOCK_STATE_PALETTE; - } else { -- Tag data = ChunkSerializer.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, section.getStates()).getOrThrow(); // todo error handling -+ Tag data = SerializableChunkData.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, section.getStates()).getOrThrow(); // todo error handling - blockStateTag = Converter.convertTag(data); - } - -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -index 73f9473b52df2ae9cea5f6361d2f8d00136c84da..baaf410852e8aac91c60fcb58acc63e01cc7e7d0 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java -@@ -26,14 +26,13 @@ import net.minecraft.world.level.chunk.LevelChunkSection; - import net.minecraft.world.level.chunk.PalettedContainer; - import net.minecraft.world.level.chunk.UpgradeData; - import net.minecraft.world.level.chunk.status.ChunkStatusTasks; --import net.minecraft.world.level.chunk.storage.ChunkSerializer; -+import net.minecraft.world.level.chunk.storage.SerializableChunkData; - import net.minecraft.world.level.levelgen.Heightmap; - import net.minecraft.world.level.material.Fluid; - import net.minecraft.world.ticks.LevelChunkTicks; - - import java.util.EnumSet; - import java.util.List; --import java.util.Optional; - - public class SlimeChunkConverter { - -@@ -52,10 +51,10 @@ public class SlimeChunkConverter { - instance.getLightEngine().retainData(pos, true); - }); - -- Registry biomeRegistry = instance.registryAccess().registryOrThrow(Registries.BIOME); -+ Registry biomeRegistry = instance.registryAccess().lookupOrThrow(Registries.BIOME); - // Ignore deprecated method - -- Codec>> codec = PalettedContainer.codecRW(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getHolderOrThrow(Biomes.PLAINS), null); -+ Codec>> codec = PalettedContainer.codecRW(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.get(Biomes.PLAINS).orElseThrow(), null); - - for (int sectionId = 0; sectionId < chunk.getSections().length; sectionId++) { - SlimeChunkSection slimeSection = chunk.getSections()[sectionId]; -@@ -73,7 +72,7 @@ public class SlimeChunkConverter { - - PalettedContainer blockPalette; - if (slimeSection.getBlockStatesTag() != null) { -- DataResult> dataresult = ChunkSerializer.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, Converter.convertTag(slimeSection.getBlockStatesTag())).promotePartial((s) -> { -+ DataResult> dataresult = SerializableChunkData.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, Converter.convertTag(slimeSection.getBlockStatesTag())).promotePartial((s) -> { - System.out.println("Recoverable error when parsing section " + x + "," + z + ": " + s); // todo proper logging - }); - blockPalette = dataresult.getOrThrow(); // todo proper logging -@@ -89,7 +88,7 @@ public class SlimeChunkConverter { - }); - biomePalette = dataresult.getOrThrow(); // todo proper logging - } else { -- biomePalette = new PalettedContainer<>(biomeRegistry.asHolderIdMap(), biomeRegistry.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); -+ biomePalette = new PalettedContainer<>(biomeRegistry.asHolderIdMap(), biomeRegistry.get(Biomes.PLAINS).orElseThrow(), PalettedContainer.Strategy.SECTION_BIOMES, null); - } - - if (sectionId < sections.length) { -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -index dbc4620fea0b1b5aa130aaaa2af06fcaad93ed29..9d15ab96bc72e5efffe443088ef482d4ec0e9457 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -@@ -1,6 +1,6 @@ - package com.infernalsuite.asp.level; - --import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -+import ca.spottedleaf.concurrentutil.util.Priority; - import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; - import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkLoadTask; - import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.GenericDataLoadTask; -@@ -80,8 +80,8 @@ public class SlimeLevelInstance extends ServerLevel { - super(slimeBootstrap, MinecraftServer.getServer(), MinecraftServer.getServer().executor, - CUSTOM_LEVEL_STORAGE.createAccess(slimeBootstrap.initial().getName() + UUID.randomUUID(), dimensionKey), - primaryLevelData, worldKey, worldDimension, -- MinecraftServer.getServer().progressListenerFactory.create(11), false, null, 0, -- Collections.emptyList(), true, environment, null, null); -+ MinecraftServer.getServer().progressListenerFactory.create(11), false, 0, -+ Collections.emptyList(), true, null, environment, null, null); - this.slimeInstance = new SlimeInMemoryWorld(slimeBootstrap, this); - - -@@ -93,7 +93,7 @@ public class SlimeLevelInstance extends ServerLevel { - propertyMap.getValue(SlimeProperties.SPAWN_Y), - propertyMap.getValue(SlimeProperties.SPAWN_Z)), - propertyMap.getValue(SlimeProperties.SPAWN_YAW)); -- super.setSpawnSettings(propertyMap.getValue(SlimeProperties.ALLOW_MONSTERS), propertyMap.getValue(SlimeProperties.ALLOW_ANIMALS)); -+ super.setSpawnSettings(propertyMap.getValue(SlimeProperties.ALLOW_MONSTERS)); - - this.pvpMode = propertyMap.getValue(SlimeProperties.PVP); - } -@@ -102,7 +102,7 @@ public class SlimeLevelInstance extends ServerLevel { - public ChunkGenerator getGenerator(SlimeBootstrap slimeBootstrap) { - String biomeStr = slimeBootstrap.initial().getPropertyMap().getValue(SlimeProperties.DEFAULT_BIOME); - ResourceKey biomeKey = ResourceKey.create(Registries.BIOME, ResourceLocation.parse(biomeStr)); -- Holder defaultBiome = MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME).getHolder(biomeKey).orElseThrow(); -+ Holder defaultBiome = MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BIOME).get(biomeKey).orElseThrow(); - return new SlimeLevelGenerator(defaultBiome); - } - -@@ -172,7 +172,7 @@ public class SlimeLevelInstance extends ServerLevel { - return this.slimeInstance; - } - -- public ChunkDataLoadTask getLoadTask(ChunkLoadTask task, ChunkTaskScheduler scheduler, ServerLevel world, int chunkX, int chunkZ, PrioritisedExecutor.Priority priority, Consumer> onRun) { -+ public ChunkDataLoadTask getLoadTask(ChunkLoadTask task, ChunkTaskScheduler scheduler, ServerLevel world, int chunkX, int chunkZ, Priority priority, Consumer> onRun) { - return new ChunkDataLoadTask(task, scheduler, world, chunkX, chunkZ, priority, onRun); - } - -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index cb0c551bb3899201e2ca55a72babc76b3704501b..def0ae9a3a3e7a884d24275bb5f0f9b8e87f7d64 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -@@ -371,7 +371,7 @@ public record SerializableChunkData(Registry biomeRegistry, ChunkPos chun - } - - if (world instanceof com.infernalsuite.asp.level.SlimeLevelInstance) { -- poiStorage.checkConsistencyWithBlocks(SectionPos.of(chunkPos.getWorldPosition()), achunksection[j]); -+ poiStorage.checkConsistencyWithBlocks(sectionposition, serializablechunkdata_b.chunkSection); - } - } - } From 384c9460825e2fb07ce8b36badcaf3b914460bf9 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 18:33:31 +0100 Subject: [PATCH 055/133] Port "Fix missing chunks & entities when chunk saving" by me from 5 Dec 2024 --- .../scheduling/NewChunkHolder.java.patch | 14 ++ .../asp/level/NMSSlimeChunk.java | 21 ++- .../asp/level/SlimeChunkLevel.java | 6 - .../asp/level/SlimeInMemoryWorld.java | 4 +- .../asp/level/SlimeLevelInstance.java | 6 +- ...ng-chunks-entities-when-chunk-saving.patch | 127 ------------------ 6 files changed, 36 insertions(+), 142 deletions(-) delete mode 100644 patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch diff --git a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch index 2a288d906..f38ea67fc 100644 --- a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch +++ b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch @@ -9,3 +9,17 @@ final List entities = ChunkEntitySlices.readEntities(this.world, entityChunk); ((ChunkSystemServerLevel)this.world).moonrise$getEntityLookup().addEntityChunkEntities(entities, new ChunkPos(this.chunkX, this.chunkZ)); +@@ -895,6 +_,13 @@ + final PoiChunk poiChunk = state.poiChunk(); + + final boolean shouldLevelChunkNotSave = PlatformHooks.get().forceNoSave(chunk); ++ ++ // ASP start - Chunk unloading ++ if (world instanceof com.infernalsuite.asp.level.SlimeLevelInstance slime && chunk instanceof LevelChunk levelChunk) { ++ //The custom entity slices need to be passed on for entities to be saved ++ slime.onChunkUnloaded(levelChunk, entityChunk); ++ } ++ // ASP end - Chunk unloading + + // unload chunk data + if (chunk != null) { diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java index a5afbe639..8b48358c6 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -66,11 +66,18 @@ public class NMSSlimeChunk implements SlimeChunk { private final CompoundBinaryTag extra; private final CompoundBinaryTag upgradeData; + private final ChunkEntitySlices entitySlices; + public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference) { + this(chunk, reference, null); + } + + public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference, ChunkEntitySlices slices) { this.chunk = chunk; this.extra = reference == null ? CompoundBinaryTag.empty() : reference.getExtraData(); this.extra.put("ChunkBukkitValues", Converter.convertTag(chunk.persistentDataContainer.toTagCompound())); this.upgradeData = reference == null ? null : reference.getUpgradeData(); + this.entitySlices = slices; } @Override @@ -159,9 +166,7 @@ public List getTileEntities() { public List getEntities() { List entities = new ArrayList<>(); - if (this.chunk == null || this.chunk.getChunkHolder() == null) return new ArrayList<>(); - - ChunkEntitySlices slices = this.chunk.getChunkHolder().getEntityChunk(); + ChunkEntitySlices slices = getEntitySlices(); if (slices == null) return new ArrayList<>(); // Work by @@ -177,6 +182,16 @@ public List getEntities() { return Lists.transform(entities, Converter::convertTag); } + private ChunkEntitySlices getEntitySlices() { + if (this.entitySlices != null) return this.entitySlices; + + if (this.chunk == null || this.chunk.getChunkHolder() == null) { + return null; + } + + return this.chunk.getChunkHolder().getEntityChunk(); + } + @Override public CompoundBinaryTag getExtraData() { return extra; diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java index 6e711d9d7..bce1750e7 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java @@ -19,12 +19,6 @@ public SlimeChunkLevel(SlimeLevelInstance world, ChunkPos pos, UpgradeData upgra this.inMemoryWorld = world.slimeInstance; } - @Override - public void unloadCallback() { - super.unloadCallback(); - this.inMemoryWorld.unload(this); - } - @Override public void loadCallback() { super.loadCallback(); diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java index f3fd1d04c..01172379f 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -105,11 +105,11 @@ public LevelChunk promote(int x, int z, SlimeChunk chunk) { // Authored by: Kenox // Don't use the NMS live chunk in the chunk map - public void unload(LevelChunk providedChunk) { + public void unload(LevelChunk providedChunk, ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices entitySlices) { final int x = providedChunk.locX; final int z = providedChunk.locZ; - SlimeChunk chunk = new NMSSlimeChunk(providedChunk, getChunk(x, z)); + SlimeChunk chunk = new NMSSlimeChunk(providedChunk, getChunk(x, z), entitySlices); if (FastChunkPruner.canBePruned(this.liveWorld, providedChunk)) { this.chunkStorage.remove(Util.chunkPosition(x, z)); diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java index cd993f0bf..38658b34f 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -208,9 +208,7 @@ public void setDefaultSpawnPos(BlockPos pos, float angle) { propertyMap.setValue(SlimeProperties.SPAWN_YAW, angle); } - @Override - public void unload(LevelChunk chunk) { - this.slimeInstance.unload(chunk); - super.unload(chunk); + public void onChunkUnloaded(LevelChunk chunk, ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices entityChunk) { + this.slimeInstance.unload(chunk, entityChunk); } } diff --git a/patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch b/patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch deleted file mode 100644 index ba61ccb82..000000000 --- a/patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: David Mayr -Date: Thu, 5 Dec 2024 01:41:21 +0100 -Subject: [PATCH] Fix missing chunks & entities when chunk saving - - -diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -index 62b526f7e147586977615ec8cec191d0aaf0bcdc..ad7c19ceb42da90bd995421be7fb764aa7ee48e0 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -@@ -897,6 +897,13 @@ public final class NewChunkHolder { - - final boolean shouldLevelChunkNotSave = PlatformHooks.get().forceNoSave(chunk); - -+ // ASP start - Chunk unloading -+ if (world instanceof com.infernalsuite.asp.level.SlimeLevelInstance slime && chunk instanceof LevelChunk levelChunk) { -+ //The custom entity slices need to be passed on for entities to be saved -+ slime.onChunkUnloaded(levelChunk, entityChunk); -+ } -+ // ASP end - Chunk unloading -+ - // unload chunk data - if (chunk != null) { - if (chunk instanceof LevelChunk levelChunk) { -diff --git a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -index fcdc22a4c107d2a9f4756a473e2b570a4d29b495..17f99470787fa3d6709c892911d33a0a8ea1aadd 100644 ---- a/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -+++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java -@@ -64,11 +64,18 @@ public class NMSSlimeChunk implements SlimeChunk { - private final CompoundBinaryTag extra; - private final CompoundBinaryTag upgradeData; - -+ private final ChunkEntitySlices entitySlices; -+ - public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference) { -+ this(chunk, reference, null); -+ } -+ -+ public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference, ChunkEntitySlices slices) { - this.chunk = chunk; - this.extra = reference == null ? CompoundBinaryTag.empty() : reference.getExtraData(); - this.extra.put("ChunkBukkitValues", Converter.convertTag(chunk.persistentDataContainer.toTagCompound())); - this.upgradeData = reference == null ? null : reference.getUpgradeData(); -+ this.entitySlices = slices; - } - - @Override -@@ -157,9 +164,7 @@ public class NMSSlimeChunk implements SlimeChunk { - public List getEntities() { - List entities = new ArrayList<>(); - -- if (this.chunk == null || this.chunk.getChunkHolder() == null) return new ArrayList<>(); -- -- ChunkEntitySlices slices = this.chunk.getChunkHolder().getEntityChunk(); -+ ChunkEntitySlices slices = getEntitySlices(); - if (slices == null) return new ArrayList<>(); - - // Work by -@@ -175,6 +180,16 @@ public class NMSSlimeChunk implements SlimeChunk { - return Lists.transform(entities, Converter::convertTag); - } - -+ private ChunkEntitySlices getEntitySlices() { -+ if (this.entitySlices != null) return this.entitySlices; -+ -+ if (this.chunk == null || this.chunk.getChunkHolder() == null) { -+ return null; -+ } -+ -+ return this.chunk.getChunkHolder().getEntityChunk(); -+ } -+ - @Override - public CompoundBinaryTag getExtraData() { - return extra; -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java b/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java -index a92d17b5c6a7c8427ecbdf56a9c2a0c1b66978e4..6313b235eb8ccbd63b57159964ba33d36db51933 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java -@@ -19,12 +19,6 @@ public class SlimeChunkLevel extends LevelChunk { - this.inMemoryWorld = world.slimeInstance; - } - -- @Override -- public void unloadCallback() { -- super.unloadCallback(); -- this.inMemoryWorld.unload(this); -- } -- - @Override - public void loadCallback() { - super.loadCallback(); -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -index e6da199bf2179d8820c6e38725cea5f867031f15..77526b601745287cc309f4cda0a8093d871e888e 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -103,11 +103,11 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - - // Authored by: Kenox - // Don't use the NMS live chunk in the chunk map -- public void unload(LevelChunk providedChunk) { -+ public void unload(LevelChunk providedChunk, ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices entitySlices) { - final int x = providedChunk.locX; - final int z = providedChunk.locZ; - -- SlimeChunk chunk = new NMSSlimeChunk(providedChunk, getChunk(x, z)); -+ SlimeChunk chunk = new NMSSlimeChunk(providedChunk, getChunk(x, z), entitySlices); - - if (FastChunkPruner.canBePruned(this.liveWorld, providedChunk)) { - this.chunkStorage.remove(Util.chunkPosition(x, z)); -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -index 9d15ab96bc72e5efffe443088ef482d4ec0e9457..1c5798fd15a61b6721df97214494788e9873c68c 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java -@@ -201,9 +201,7 @@ public class SlimeLevelInstance extends ServerLevel { - propertyMap.setValue(SlimeProperties.SPAWN_YAW, angle); - } - -- @Override -- public void unload(LevelChunk chunk) { -- this.slimeInstance.unload(chunk); -- super.unload(chunk); -+ public void onChunkUnloaded(LevelChunk chunk, ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices entityChunk) { -+ this.slimeInstance.unload(chunk, entityChunk); - } - } -\ No newline at end of file From 7a8423ad2e6c1d52e98c309a5e5bfa2e4205faa8 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 18:39:39 +0100 Subject: [PATCH 056/133] Port "fix pdc not saving when chunks are unloaded" by me from 5 Dec 2024 --- .../asp/level/SlimeInMemoryWorld.java | 3 +++ ...-not-saving-when-chunks-are-unloaded.patch | 19 ----------------- .../0022-Remove-leftover-FlowNBT-usage.patch | 21 ------------------- 3 files changed, 3 insertions(+), 40 deletions(-) delete mode 100644 patches/server/0021-fix-pdc-not-saving-when-chunks-are-unloaded.patch delete mode 100644 patches/server/0022-Remove-leftover-FlowNBT-usage.patch diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java index 01172379f..c40cf4690 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -22,6 +22,7 @@ import net.minecraft.world.level.chunk.UpgradeData; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.ticks.LevelChunkTicks; +import org.bukkit.Tag; import org.bukkit.World; import org.bukkit.persistence.PersistentDataContainer; import org.jetbrains.annotations.NotNull; @@ -115,6 +116,8 @@ public void unload(LevelChunk providedChunk, ca.spottedleaf.moonrise.patches.chu this.chunkStorage.remove(Util.chunkPosition(x, z)); return; } + CompoundBinaryTag pdcTag = Converter.convertTag(providedChunk.persistentDataContainer.toTagCompound()); + chunk.getExtraData().put("ChunkBukkitValues", pdcTag); this.chunkStorage.put(Util.chunkPosition(x, z), new SlimeChunkSkeleton(chunk.getX(), chunk.getZ(), chunk.getSections(), diff --git a/patches/server/0021-fix-pdc-not-saving-when-chunks-are-unloaded.patch b/patches/server/0021-fix-pdc-not-saving-when-chunks-are-unloaded.patch deleted file mode 100644 index bd726a4ab..000000000 --- a/patches/server/0021-fix-pdc-not-saving-when-chunks-are-unloaded.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: David Mayr -Date: Thu, 5 Dec 2024 01:46:03 +0100 -Subject: [PATCH] fix pdc not saving when chunks are unloaded - - -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -index 77526b601745287cc309f4cda0a8093d871e888e..166f8c17df110d4ed13dd31a9de06c3d7b5c070b 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -113,6 +113,8 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - this.chunkStorage.remove(Util.chunkPosition(x, z)); - return; - } -+ Tag pdcTag = Converter.convertTag("ChunkBukkitValues", providedChunk.persistentDataContainer.toTagCompound()); -+ chunk.getExtraData().getValue().put(pdcTag); - - this.chunkStorage.put(Util.chunkPosition(x, z), - new SlimeChunkSkeleton(chunk.getX(), chunk.getZ(), chunk.getSections(), diff --git a/patches/server/0022-Remove-leftover-FlowNBT-usage.patch b/patches/server/0022-Remove-leftover-FlowNBT-usage.patch deleted file mode 100644 index 3ec576c2b..000000000 --- a/patches/server/0022-Remove-leftover-FlowNBT-usage.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Philip Kelley -Date: Fri, 20 Dec 2024 11:31:09 +0000 -Subject: [PATCH] Remove leftover FlowNBT usage - - -diff --git a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -index 166f8c17df110d4ed13dd31a9de06c3d7b5c070b..a5f35f94d82928f120f02909086f57d4ceaa52c2 100644 ---- a/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -+++ b/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java -@@ -113,8 +113,8 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { - this.chunkStorage.remove(Util.chunkPosition(x, z)); - return; - } -- Tag pdcTag = Converter.convertTag("ChunkBukkitValues", providedChunk.persistentDataContainer.toTagCompound()); -- chunk.getExtraData().getValue().put(pdcTag); -+ CompoundBinaryTag pdcTag = Converter.convertTag(providedChunk.persistentDataContainer.toTagCompound()); -+ chunk.getExtraData().put("ChunkBukkitValues", pdcTag); - - this.chunkStorage.put(Util.chunkPosition(x, z), - new SlimeChunkSkeleton(chunk.getX(), chunk.getZ(), chunk.getSections(), From 46e9aa10b8bae134499c850621479d13ef6a09bd Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 19:10:49 +0100 Subject: [PATCH 057/133] fix: make this compile --- impl/aspaper-api/build.gradle.kts.patch | 2 +- .../chunk_system/scheduling/task/ChunkLoadTask.java.patch | 2 +- .../main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java | 2 +- settings.gradle.kts | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/impl/aspaper-api/build.gradle.kts.patch b/impl/aspaper-api/build.gradle.kts.patch index 33a97d1b5..48232e356 100644 --- a/impl/aspaper-api/build.gradle.kts.patch +++ b/impl/aspaper-api/build.gradle.kts.patch @@ -14,7 +14,7 @@ } -val generatedApiPath: java.nio.file.Path = layout.projectDirectory.dir("src/generated/java").asFile.toPath() -+val generatedApiPath: java.nio.file.Path = rootProject.layout.projectDirectory.dir("paper-api/src/generated/java").asFile.toPath() ++val generatedApiPath: java.nio.file.Path = rootProject.layout.projectDirectory.dir("impl/paper-api/src/generated/java").asFile.toPath() idea { module { generatedSourceDirs.add(generatedApiPath.toFile()) diff --git a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch index 20a94b7e3..fa9f836fb 100644 --- a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch +++ b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch @@ -19,7 +19,7 @@ - ChunkLoadTask.this.tryCompleteLoad(); - }); + // ASWM start -+ if (world instanceof com.infernalsuite.aswm.level.SlimeLevelInstance levelInstance) { ++ if (world instanceof com.infernalsuite.asp.level.SlimeLevelInstance levelInstance) { + + this.loadTask = levelInstance.getLoadTask(this, scheduler, world, chunkX, chunkZ, priority, result -> { + ChunkLoadTask.this.complete(result == null ? null : result.left(), result == null ? null : result.right()); diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java index 5e43f6094..1c2d0c701 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java @@ -52,7 +52,7 @@ public SlimeChunk getChunk(int x, int z) { @Override public Collection getChunkStorage() { - List chunks = ca.spottedleaf.moonrise.common.util.ChunkSystem.getVisibleChunkHolders(this.instance); // Paper + List chunks = ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.instance); // Paper return chunks.stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull) .map((chunkLevel) -> new NMSSlimeChunk(chunkLevel, memoryWorld.getChunk(chunkLevel.getPos().x, chunkLevel.getPos().z))) // This sucks, is there a better way? .collect(Collectors.toList()); diff --git a/settings.gradle.kts b/settings.gradle.kts index fb034fdec..83bfa1433 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -17,8 +17,8 @@ include(":gradle:platform") include(":api") include(":core") //include(":importer") -//include(":loaders") -//include(":plugin") +include(":loaders") +include(":plugin") include(":impl") include(":impl:aspaper-api") include(":impl:aspaper-server") From ff7d700bcbcf4678b8316623cabd65e0fa50ad82 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 19:31:53 +0100 Subject: [PATCH 058/133] feat: update paper --- gradle.properties | 2 +- .../{0001-World-overrides.patch => 0002-World-overrides.patch} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename impl/aspaper-server/minecraft-patches/features/{0001-World-overrides.patch => 0002-World-overrides.patch} (95%) diff --git a/gradle.properties b/gradle.properties index 30e701599..11d9848fe 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ apiVersion=4.0.0-SNAPSHOT version=1.21.4-R0.1-SNAPSHOT mcVersion=1.21.4 -paperRef=636ae0cd87d303c438db2e5a673fa729c39979ec +paperRef=1a7288aa05cfb0a168850a7cc879f55235fe5934 org.gradle.caching=true org.gradle.parallel=true diff --git a/impl/aspaper-server/minecraft-patches/features/0001-World-overrides.patch b/impl/aspaper-server/minecraft-patches/features/0002-World-overrides.patch similarity index 95% rename from impl/aspaper-server/minecraft-patches/features/0001-World-overrides.patch rename to impl/aspaper-server/minecraft-patches/features/0002-World-overrides.patch index fe8016414..d7db4aa7f 100644 --- a/impl/aspaper-server/minecraft-patches/features/0001-World-overrides.patch +++ b/impl/aspaper-server/minecraft-patches/features/0002-World-overrides.patch @@ -5,7 +5,7 @@ Subject: [PATCH] World overrides diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index ae220a732c78ab076261f20b5a54c71d7fceb407..16a7dd68a59fb6762b149ef9d0c0879226a86a3a 100644 +index 1509c96ae9247d1d5ddd0fc50210f88da10bf3de..bbc4be3c3811ee19bd791cb6626474038d35a298 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java @@ -516,18 +516,33 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop Date: Sun, 9 Mar 2025 19:32:00 +0100 Subject: [PATCH 059/133] fix: slime property validation --- .../infernalsuite/asp/api/world/properties/SlimeProperty.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperty.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperty.java index e3c47b5c1..b6bc8b185 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperty.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperty.java @@ -35,7 +35,7 @@ protected SlimeProperty(String key, T defaultValue, Function validat protected abstract Z cast(BinaryTag rawTag); public final boolean applyValidator(T value) { - return this.validator != null && this.validator.apply(value); + return this.validator == null || this.validator.apply(value); } public final String getKey() { From de45ac840aa062786bb30931e154ccf845f1b055 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 20:45:55 +0100 Subject: [PATCH 060/133] fix: specific entities not saving --- .../src/main/java/com/infernalsuite/asp/Converter.java | 4 ++++ .../java/com/infernalsuite/asp/level/SlimeLevelInstance.java | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/Converter.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/Converter.java index 22acbf7d0..85497baa2 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/Converter.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/Converter.java @@ -111,6 +111,10 @@ public static T convertTag(Tag base) { List list = new ArrayList<>(); ListTag originalList = ((ListTag) base); for (Tag entry : originalList) list.add(convertTag(entry)); + + if(list.isEmpty()) { + yield (T) ListBinaryTag.empty(); + } yield (T) ListBinaryTag.listBinaryTag(list.getFirst().type(), list); } case Tag.TAG_COMPOUND -> { diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java index 38658b34f..0b30ebe62 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -129,8 +129,8 @@ public Future save() { this.serverLevelData.setCustomBossEvents(MinecraftServer.getServer().getCustomBossEvents().save(MinecraftServer.getServer().registryAccess())); // Update level data - net.minecraft.nbt.CompoundTag compound = new net.minecraft.nbt.CompoundTag(); - net.minecraft.nbt.CompoundTag nbtTagCompound = this.serverLevelData.createTag(MinecraftServer.getServer().registryAccess(), compound); +// net.minecraft.nbt.CompoundTag compound = new net.minecraft.nbt.CompoundTag(); +// net.minecraft.nbt.CompoundTag nbtTagCompound = this.serverLevelData.createTag(MinecraftServer.getServer().registryAccess(), compound); if (MinecraftServer.getServer().isStopped()) { // Make sure the world gets saved before stopping the server by running it from the main thread saveInternal().get(); // Async wait for it to finish From 56c82f688586e1852e183efbed5e55364ed81d30 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 20:59:26 +0100 Subject: [PATCH 061/133] feat: Branding patch --- .../features/0001-API-Branding.patch | 23 ++++ .../features/0003-Branding.patch | 103 ++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 impl/aspaper-api/paper-patches/features/0001-API-Branding.patch create mode 100644 impl/aspaper-server/paper-patches/features/0003-Branding.patch diff --git a/impl/aspaper-api/paper-patches/features/0001-API-Branding.patch b/impl/aspaper-api/paper-patches/features/0001-API-Branding.patch new file mode 100644 index 000000000..6d40e9cfe --- /dev/null +++ b/impl/aspaper-api/paper-patches/features/0001-API-Branding.patch @@ -0,0 +1,23 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: David Mayr +Date: Sun, 9 Mar 2025 20:50:45 +0100 +Subject: [PATCH] API Branding + + +diff --git a/src/main/java/io/papermc/paper/ServerBuildInfo.java b/src/main/java/io/papermc/paper/ServerBuildInfo.java +index 652ff54e7c50412503725d628bfe72ed03059790..d26bbab5b67b6456a2713e67c2bcfa17e7478992 100644 +--- a/src/main/java/io/papermc/paper/ServerBuildInfo.java ++++ b/src/main/java/io/papermc/paper/ServerBuildInfo.java +@@ -19,6 +19,12 @@ public interface ServerBuildInfo { + */ + Key BRAND_PAPER_ID = Key.key("papermc", "paper"); + ++ ++ /** ++ * The brand id for AdvancedSlimePaper. ++ */ ++ Key BRAND_ADVANCED_SLIME_PAPER_ID = Key.key("infernalsuite", "advancedslimepaper"); ++ + /** + * Gets the {@code ServerBuildInfo}. + * diff --git a/impl/aspaper-server/paper-patches/features/0003-Branding.patch b/impl/aspaper-server/paper-patches/features/0003-Branding.patch new file mode 100644 index 000000000..225d0e654 --- /dev/null +++ b/impl/aspaper-server/paper-patches/features/0003-Branding.patch @@ -0,0 +1,103 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: David Mayr +Date: Sun, 9 Mar 2025 20:58:19 +0100 +Subject: [PATCH] Branding + + +diff --git a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java +index 532306cacd52579cdf37e4aca25887b1ed3ba6a1..eec04fcdd4b6c6f92a2db37bfe06dca2a93e300d 100644 +--- a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java ++++ b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java +@@ -35,7 +35,7 @@ public class PaperVersionFetcher implements VersionFetcher { + private static final Logger LOGGER = LogUtils.getClassLogger(); + private static final int DISTANCE_ERROR = -1; + private static final int DISTANCE_UNKNOWN = -2; +- private static final String DOWNLOAD_PAGE = "https://papermc.io/downloads/paper"; ++ private static final String DOWNLOAD_PAGE = "https://discord.gg/YevvsMa"; + + @Override + public long getCacheTime() { +@@ -49,7 +49,7 @@ public class PaperVersionFetcher implements VersionFetcher { + if (build.buildNumber().isEmpty() && build.gitCommit().isEmpty()) { + updateMessage = text("You are running a development version without access to version information", color(0xFF5300)); + } else { +- updateMessage = getUpdateStatusMessage("PaperMC/Paper", build); ++ updateMessage = getUpdateStatusMessage("InfernalSuite/AdvancedSlimePaper", build); + } + final @Nullable Component history = this.getHistory(); + +@@ -59,16 +59,16 @@ public class PaperVersionFetcher implements VersionFetcher { + private static Component getUpdateStatusMessage(final String repo, final ServerBuildInfo build) { + int distance = DISTANCE_ERROR; + +- final OptionalInt buildNumber = build.buildNumber(); ++ /*final OptionalInt buildNumber = build.buildNumber(); //ASP start + if (buildNumber.isPresent()) { + distance = fetchDistanceFromSiteApi(build, buildNumber.getAsInt()); +- } else { ++ } else { */ //ASP End + final Optional gitBranch = build.gitBranch(); + final Optional gitCommit = build.gitCommit(); + if (gitBranch.isPresent() && gitCommit.isPresent()) { + distance = fetchDistanceFromGitHub(repo, gitBranch.get(), gitCommit.get()); + } +- } ++ //} //ASP + + return switch (distance) { + case DISTANCE_ERROR -> text("Error obtaining version information", NamedTextColor.YELLOW); +@@ -76,7 +76,7 @@ public class PaperVersionFetcher implements VersionFetcher { + case DISTANCE_UNKNOWN -> text("Unknown version", NamedTextColor.YELLOW); + default -> text("You are " + distance + " version(s) behind", NamedTextColor.YELLOW) + .append(Component.newline()) +- .append(text("Download the new version at: ") ++ .append(text("Download the new version from our Discord: ") + .append(text(DOWNLOAD_PAGE, NamedTextColor.GOLD) + .hoverEvent(text("Click to open", NamedTextColor.WHITE)) + .clickEvent(ClickEvent.openUrl(DOWNLOAD_PAGE)))); +diff --git a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java b/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java +index 790bad0494454ca12ee152e3de6da3da634d9b20..d047646990ff52b31a24bdebf000ecfbebdae99a 100644 +--- a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java ++++ b/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java +@@ -31,6 +31,7 @@ public record ServerBuildInfoImpl( + private static final String ATTRIBUTE_GIT_COMMIT = "Git-Commit"; + + private static final String BRAND_PAPER_NAME = "Paper"; ++ private static final String BRAND_ADVANCED_SLIME_PAPER_NAME = "AdvancedSlimePaper"; + + private static final String BUILD_DEV = "DEV"; + +@@ -42,9 +43,9 @@ public record ServerBuildInfoImpl( + this( + getManifestAttribute(manifest, ATTRIBUTE_BRAND_ID) + .map(Key::key) +- .orElse(BRAND_PAPER_ID), ++ .orElse(BRAND_ADVANCED_SLIME_PAPER_ID), + getManifestAttribute(manifest, ATTRIBUTE_BRAND_NAME) +- .orElse(BRAND_PAPER_NAME), ++ .orElse(BRAND_ADVANCED_SLIME_PAPER_NAME), + SharedConstants.getCurrentVersion().getId(), + SharedConstants.getCurrentVersion().getName(), + getManifestAttribute(manifest, ATTRIBUTE_BUILD_NUMBER) +@@ -61,7 +62,7 @@ public record ServerBuildInfoImpl( + + @Override + public boolean isBrandCompatible(final @NotNull Key brandId) { +- return brandId.equals(this.brandId); ++ return brandId.equals(this.brandId) || brandId.equals(BRAND_PAPER_ID) || brandId.equals(BRAND_ADVANCED_SLIME_PAPER_ID); + } + + @Override +diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java +index 774556a62eb240da42e84db4502e2ed43495be17..ee1ffebaf4e9f7e2f8e0fd8406357b64d38b7399 100644 +--- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java ++++ b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java +@@ -11,7 +11,7 @@ public final class Versioning { + public static String getBukkitVersion() { + String result = "Unknown-Version"; + +- InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/io.papermc.paper/paper-api/pom.properties"); ++ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/com.infernalsuite.aswm/slimeworldmanager-api/pom.properties"); + Properties properties = new Properties(); + + if (stream != null) { From e400dae6e163f25a7208374c43d403e94c55c117 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 21:02:27 +0100 Subject: [PATCH 062/133] feat: build attributes --- impl/aspaper-server/build.gradle.kts.patch | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/impl/aspaper-server/build.gradle.kts.patch b/impl/aspaper-server/build.gradle.kts.patch index 3accc1566..f3b863a4e 100644 --- a/impl/aspaper-server/build.gradle.kts.patch +++ b/impl/aspaper-server/build.gradle.kts.patch @@ -53,3 +53,23 @@ implementation("ca.spottedleaf:concurrentutil:0.0.3") implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ implementation("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21 +@@ -189,14 +_,14 @@ + val gitBranch = git.exec(providers, "rev-parse", "--abbrev-ref", "HEAD").get().trim() + attributes( + "Main-Class" to "org.bukkit.craftbukkit.Main", +- "Implementation-Title" to "Paper", ++ "Implementation-Title" to "AdvancedSlimePaper", //ASP + "Implementation-Version" to implementationVersion, + "Implementation-Vendor" to date, +- "Specification-Title" to "Paper", ++ "Specification-Title" to "AdvancedSlimePaper", //ASP + "Specification-Version" to project.version, +- "Specification-Vendor" to "Paper Team", +- "Brand-Id" to "papermc:paper", +- "Brand-Name" to "Paper", ++ "Specification-Vendor" to "InfernalSuite Team", //ASP ++ "Brand-Id" to "infernalsuite:advancedslimepaper", //ASP ++ "Brand-Name" to "AdvancedSlimePaper", //ASP + "Build-Number" to (build ?: ""), + "Build-Time" to buildTime.toString(), + "Git-Branch" to gitBranch, From 9f017435ea3435cc91371e2b87b823c407b82e8b Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 9 Mar 2025 21:04:38 +0100 Subject: [PATCH 063/133] fix: catch all exceptions during async save --- .../java/com/infernalsuite/asp/level/SlimeLevelInstance.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java index 0b30ebe62..4dfc803dd 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -167,8 +167,8 @@ private Future saveInternal() { long saveStart = System.currentTimeMillis(); slimeWorld.getLoader().saveWorld(slimeWorld.getName(), serializedWorld); Bukkit.getLogger().log(Level.INFO, "World " + slimeWorld.getName() + " serialized in " + (saveStart - start) + "ms and saved in " + (System.currentTimeMillis() - saveStart) + "ms."); - } catch (IOException | IllegalStateException ex) { - ex.printStackTrace(); + } catch (Exception ex) { + Bukkit.getLogger().log(Level.SEVERE, "There was an issue saving world " + slimeWorld.getName() + " asynchronously.", ex); } }); From bcc96984a1b8ae43f3b741a4090f185132211abf Mon Sep 17 00:00:00 2001 From: David Mayr Date: Mon, 10 Mar 2025 11:40:31 +0100 Subject: [PATCH 064/133] feat: dont save level dat --- .../com/infernalsuite/asp/level/SlimeLevelInstance.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java index 4dfc803dd..74386affa 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -118,6 +118,14 @@ public void save(@Nullable ProgressListener progressUpdate, boolean forceSave, b if (!savingDisabled) save(); } + @Override + public void saveIncrementally(boolean doFull) { + if(doFull) { + //Avoid doing the internal save because it saves the level.dat into the temp folder. That causes pterodactyl users to have issues. + save(); + } + } + public Future save() { AsyncCatcher.catchOp("SWM world save"); try { From b50cca9d74682ec827f4e78a80343abadb40c860 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Mon, 10 Mar 2025 11:42:52 +0100 Subject: [PATCH 065/133] feat: avoid useless uuid io call --- .../0003-Avoid-IO-call-for-UUID.patch | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 impl/aspaper-server/minecraft-patches/features/0003-Avoid-IO-call-for-UUID.patch diff --git a/impl/aspaper-server/minecraft-patches/features/0003-Avoid-IO-call-for-UUID.patch b/impl/aspaper-server/minecraft-patches/features/0003-Avoid-IO-call-for-UUID.patch new file mode 100644 index 000000000..f30c854ad --- /dev/null +++ b/impl/aspaper-server/minecraft-patches/features/0003-Avoid-IO-call-for-UUID.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: David Mayr +Date: Mon, 10 Mar 2025 11:41:14 +0100 +Subject: [PATCH] Avoid IO call for UUID + + +diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java +index 8429a97047f4321df96fd11559867bce74d0a49c..60608cea4e564c1ce47f8a4de2c1a48986bbdecb 100644 +--- a/net/minecraft/server/level/ServerLevel.java ++++ b/net/minecraft/server/level/ServerLevel.java +@@ -617,7 +617,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + super(serverLevelData, dimension, server.registryAccess(), levelStem.type(), false, isDebug, biomeZoomSeed, server.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> server.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(levelStorageAccess.levelDirectory.path(), serverLevelData.getLevelName(), dimension.location(), spigotConfig, server.registryAccess(), serverLevelData.getGameRules())), dispatcher); // Paper - create paper world configs; Async-Anti-Xray: Pass executor + this.pvpMode = server.isPvpAllowed(); + this.levelStorageAccess = levelStorageAccess; +- this.uuid = org.bukkit.craftbukkit.util.WorldUUID.getUUID(levelStorageAccess.levelDirectory.path().toFile()); ++ this.uuid = bootstrap == null ? org.bukkit.craftbukkit.util.WorldUUID.getUUID(levelStorageAccess.levelDirectory.path().toFile()) : UUID.randomUUID(); //ASP - avoid IO calls + // CraftBukkit end + this.tickTime = tickTime; + this.server = server; From e2714ed2d84d1d04c3f0989183ca3e17591d86a8 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Mon, 10 Mar 2025 12:12:38 +0100 Subject: [PATCH 066/133] feat: delete temp world folder async after world is unloaded --- ...-temp-folder-after-world-is-unloaded.patch | 23 +++++++++++ .../asp/level/SlimeLevelInstance.java | 40 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 impl/aspaper-server/paper-patches/features/0004-Delete-temp-folder-after-world-is-unloaded.patch diff --git a/impl/aspaper-server/paper-patches/features/0004-Delete-temp-folder-after-world-is-unloaded.patch b/impl/aspaper-server/paper-patches/features/0004-Delete-temp-folder-after-world-is-unloaded.patch new file mode 100644 index 000000000..ff237d481 --- /dev/null +++ b/impl/aspaper-server/paper-patches/features/0004-Delete-temp-folder-after-world-is-unloaded.patch @@ -0,0 +1,23 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: David Mayr +Date: Mon, 10 Mar 2025 12:09:41 +0100 +Subject: [PATCH] Delete temp folder after world is unloaded + + +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +index 090b295ccd7f61c2f1cc5131ffb0371c22e48f04..0bbc51dcf0ba7773b818994890d14fd0300608f3 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -1518,6 +1518,12 @@ public final class CraftServer implements Server { + handle.getChunkSource().close(save); + io.papermc.paper.FeatureHooks.closeEntityManager(handle, save); // SPIGOT-6722: close entityManager // Paper - chunk system + handle.levelStorageAccess.close(); ++ ++ //ASP start - avoid temp storage leak during runtime ++ if(handle instanceof com.infernalsuite.asp.level.SlimeLevelInstance asp) { ++ asp.deleteTempFiles(); ++ } ++ //ASP end + } catch (Exception ex) { + this.getLogger().log(Level.SEVERE, null, ex); + } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java index 74386affa..4457305e9 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -38,12 +38,16 @@ import org.apache.commons.io.FileUtils; import org.bukkit.Bukkit; import org.bukkit.event.world.WorldSaveEvent; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.spigotmc.AsyncCatcher; import java.io.IOException; +import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Collections; import java.util.UUID; @@ -219,4 +223,40 @@ public void setDefaultSpawnPos(BlockPos pos, float angle) { public void onChunkUnloaded(LevelChunk chunk, ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices entityChunk) { this.slimeInstance.unload(chunk, entityChunk); } + + public void deleteTempFiles() { + WORLD_SAVER_SERVICE.execute(() -> { + Path path = this.levelStorageAccess.levelDirectory.path(); + try { + // We do this manually and not use the deleteLevel function as it would cause a level deleted message + // to appear in the log which might be confusing for our users + Files.walkFileTree(path, new SimpleFileVisitor<>() { + @Override + public @NotNull FileVisitResult visitFile(Path file, @NotNull BasicFileAttributes attrs) throws IOException { + if (!file.equals(path)) { + Files.delete(file); + } + + return FileVisitResult.CONTINUE; + } + + @Override + public @NotNull FileVisitResult postVisitDirectory(Path dir, @javax.annotation.Nullable IOException exception) throws IOException { + if (exception != null) { + throw exception; + } else { + if (dir.equals(levelStorageAccess.levelDirectory.path())) { + Files.deleteIfExists(path); + } + + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + } + }); + } catch (IOException e) { + Bukkit.getLogger().log(Level.WARNING, "Unable to delete temp level directory" , e); + } + }); + } } From 06dea1975b40a69f61c2e7b699b931a97dd83ffc Mon Sep 17 00:00:00 2001 From: David Mayr Date: Tue, 11 Mar 2025 06:37:26 +0100 Subject: [PATCH 067/133] feat: idk? Needs testing --- .../asp/level/ChunkDataLoadTask.java | 6 +-- .../asp/level/SlimeChunkConverter.java | 43 ++++--------------- 2 files changed, 12 insertions(+), 37 deletions(-) diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java index 782445108..73cd2d67a 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java @@ -76,9 +76,9 @@ protected ChunkAccess runOnMain(final SlimeChunk data) { LevelChunk chunk = this.world.slimeInstance.promote(chunkX, chunkZ, data); ImposterProtoChunk protoChunk = new ImposterProtoChunk(chunk, false); - if (data != null) { - data.getEntities().stream().map(flowTag -> (CompoundTag) Converter.convertTag(flowTag)).forEach(protoChunk::addEntity); - } +// if (data != null) { +// data.getEntities().stream().map(flowTag -> (CompoundTag) Converter.convertTag(flowTag)).forEach(protoChunk::addEntity); +// } return protoChunk; } catch (final Exception e) { diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java index 8cbd78e09..0b93f0a6a 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java @@ -52,9 +52,9 @@ static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeC }); Registry biomeRegistry = instance.registryAccess().lookupOrThrow(Registries.BIOME); - // Ignore deprecated method - Codec>> codec = PalettedContainer.codecRW(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.get(Biomes.PLAINS).orElseThrow(), null); + Codec>> codec = PalettedContainer.codecRW(biomeRegistry.asHolderIdMap(), + biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.get(Biomes.PLAINS).orElseThrow(), null); for (int sectionId = 0; sectionId < chunk.getSections().length; sectionId++) { SlimeChunkSection slimeSection = chunk.getSections()[sectionId]; @@ -98,21 +98,6 @@ static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeC } } - // Keep the chunk loaded at level 33 to avoid light glitches - // Such a high level will let the server not tick the chunk, - // but at the same time it won't be completely unloaded from memory - // getChunkProvider().addTicket(SWM_TICKET, pos, 33, Unit.INSTANCE); - - - LevelChunk.PostLoadProcessor loadEntities = (nmsChunk) -> { - List entities = chunk.getEntities(); - - if (entities != null) { - ChunkStatusTasks.postLoadProtoChunk(instance, entities.stream() - .map(flowTag -> (net.minecraft.nbt.CompoundTag) Converter.convertTag(flowTag)).toList(), nmsChunk.getPos()); - } - }; - LevelChunkTicks blockLevelChunkTicks = new LevelChunkTicks<>(); LevelChunkTicks fluidLevelChunkTicks = new LevelChunkTicks<>(); UpgradeData upgradeData; @@ -121,25 +106,15 @@ static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeC } else { upgradeData = UpgradeData.EMPTY; } - SlimeChunkLevel nmsChunk = new SlimeChunkLevel(instance, pos, upgradeData, blockLevelChunkTicks, fluidLevelChunkTicks, 0L, sections, loadEntities, null); - List tileEntities = chunk.getTileEntities(); + LevelChunk.PostLoadProcessor processor = SerializableChunkData.postLoadChunk( + instance, + chunk.getEntities().stream().map(tag -> (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)).toList(), + chunk.getTileEntities().stream().map(tag -> (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)).toList() + ); - if (tileEntities != null) { - for (CompoundBinaryTag tag : tileEntities) { - String type = tag.getString("id"); - - if (!type.isEmpty()) { - BlockPos blockPosition = new BlockPos(tag.getInt("x"), tag.getInt("y"), tag.getInt("z")); - BlockState blockData = nmsChunk.getBlockState(blockPosition); - BlockEntity entity = BlockEntity.loadStatic(blockPosition, blockData, (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag), net.minecraft.server.MinecraftServer.getServer().registryAccess()); - - if (entity != null) { - nmsChunk.setBlockEntity(entity); - } - } - } - } + SlimeChunkLevel nmsChunk = new SlimeChunkLevel(instance, pos, upgradeData, blockLevelChunkTicks, + fluidLevelChunkTicks, 0L, sections, processor, null); // Height Maps EnumSet heightMapTypes = nmsChunk.getPersistedStatus().heightmapsAfter(); From 42039bb21e9c34522aadcefcb35b1f5af698f887 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Tue, 11 Mar 2025 22:46:08 +0100 Subject: [PATCH 068/133] fix: chunk pruner not working --- .../com/infernalsuite/asp/serialization/slime/ChunkPruner.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/ChunkPruner.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/ChunkPruner.java index 1d9d96dea..892a327bd 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/ChunkPruner.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/ChunkPruner.java @@ -57,7 +57,7 @@ private static boolean areSectionsEmpty(SlimeChunkSection[] sections) { } List palette = paletteTag.stream().map(tag -> (CompoundBinaryTag) tag).toList(); if (palette.size() > 1) return false; // If there is more than one palette, the section is not empty - if (palette.getFirst().getString("Name").equals("minecraft:air")) return false; // If the only palette entry is not air, the section is not empty + if (!palette.getFirst().getString("Name").equals("minecraft:air")) return false; // If the only palette entry is not air, the section is not empty } catch (final Exception e) { return false; } From 729571e4f432dd6b36ee04487287b25aa3908528 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Wed, 12 Mar 2025 12:08:06 +0100 Subject: [PATCH 069/133] feat: get rid of NMS Slime World, as InMemoryWorld is doing all the heavy lifting anyway NMS SlimeWorld was an API-only thing returning only the currently loaded chunk within the api. This has little actual use for API-users as a world has more than the chunks that are currently loaded --- .../asp/level/NMSSlimeChunk.java | 1 - .../asp/level/NMSSlimeWorld.java | 100 ------------------ .../asp/level/SlimeInMemoryWorld.java | 29 ++--- 3 files changed, 8 insertions(+), 122 deletions(-) delete mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java index 8b48358c6..6a9069f57 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -97,7 +97,6 @@ public SlimeChunkSection[] getSections() { Registry biomeRegistry = chunk.getLevel().registryAccess().lookupOrThrow(Registries.BIOME); - // Ignore deprecation, spigot only method Codec>> codec = PalettedContainer.codecRO(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.get(Biomes.PLAINS).orElseThrow()); for (int sectionId = 0; sectionId < chunk.getSections().length; sectionId++) { diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java deleted file mode 100644 index 1c2d0c701..000000000 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeWorld.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.infernalsuite.asp.level; - -import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; -import com.infernalsuite.asp.api.loaders.SlimeLoader; -import com.infernalsuite.asp.api.world.SlimeChunk; -import com.infernalsuite.asp.api.world.SlimeWorld; -import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; -import net.kyori.adventure.nbt.BinaryTag; -import net.kyori.adventure.nbt.CompoundBinaryTag; -import net.minecraft.SharedConstants; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.world.level.chunk.LevelChunk; -import org.bukkit.persistence.PersistentDataContainer; -import org.jetbrains.annotations.NotNull; - -import java.io.IOException; -import java.util.Collection; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.ConcurrentMap; -import java.util.stream.Collectors; - -public class NMSSlimeWorld implements SlimeWorld { - - private final SlimeInMemoryWorld memoryWorld; - private final SlimeLevelInstance instance; - - public NMSSlimeWorld(SlimeInMemoryWorld memoryWorld) { - this.instance = memoryWorld.getInstance(); - this.memoryWorld = memoryWorld; - } - - @Override - public String getName() { - return this.instance.getMinecraftWorld().serverLevelData.getLevelName(); - } - - @Override - public SlimeLoader getLoader() { - return this.instance.slimeInstance.getLoader(); - } - - @Override - public SlimeChunk getChunk(int x, int z) { - LevelChunk chunk = this.instance.getChunkIfLoaded(x, z); - if (chunk == null) { - return null; - } - - return new NMSSlimeChunk(chunk, memoryWorld.getChunk(x, z)); - } - - @Override - public Collection getChunkStorage() { - List chunks = ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.instance); // Paper - return chunks.stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull) - .map((chunkLevel) -> new NMSSlimeChunk(chunkLevel, memoryWorld.getChunk(chunkLevel.getPos().x, chunkLevel.getPos().z))) // This sucks, is there a better way? - .collect(Collectors.toList()); - } - - @Override - public ConcurrentMap getExtraData() { - return this.instance.slimeInstance.getExtraData(); - } - - @Override - public Collection getWorldMaps() { - return List.of(); - } - - @Override - public SlimePropertyMap getPropertyMap() { - return this.instance.slimeInstance.getPropertyMap(); - } - - @Override - public boolean isReadOnly() { - return this.getLoader() == null; - } - - @Override - public SlimeWorld clone(String worldName) { - return this.memoryWorld.clone(worldName); - } - - @Override - public SlimeWorld clone(String worldName, SlimeLoader loader) throws WorldAlreadyExistsException, IOException { - return this.memoryWorld.clone(worldName, loader); - } - - @Override - public int getDataVersion() { - return SharedConstants.getCurrentVersion().getDataVersion().getVersion(); - } - - @Override - public @NotNull PersistentDataContainer getPersistentDataContainer() { - return this.memoryWorld.getPersistentDataContainer(); - } -} diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java index c40cf4690..7a0ad2145 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -1,5 +1,6 @@ package com.infernalsuite.asp.level; +import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; import com.infernalsuite.asp.Converter; import com.infernalsuite.asp.Util; import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; @@ -17,22 +18,19 @@ import net.kyori.adventure.nbt.CompoundBinaryTag; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import net.minecraft.SharedConstants; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.UpgradeData; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.ticks.LevelChunkTicks; -import org.bukkit.Tag; import org.bukkit.World; import org.bukkit.persistence.PersistentDataContainer; import org.jetbrains.annotations.NotNull; import java.io.IOException; -import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.concurrent.ConcurrentMap; /* @@ -43,7 +41,6 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { private final SlimeLevelInstance instance; - private final SlimeWorld liveWorld; private final ConcurrentMap extra; private final AdventurePersistentDataContainer extraPDC; @@ -52,7 +49,6 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { private final Long2ObjectMap chunkStorage = new Long2ObjectOpenHashMap<>(); private boolean readOnly; - // private final Map> entityStorage = new HashMap<>(); public SlimeInMemoryWorld(SlimeBootstrap bootstrap, SlimeLevelInstance instance) { this.instance = instance; @@ -63,14 +59,11 @@ public SlimeInMemoryWorld(SlimeBootstrap bootstrap, SlimeLevelInstance instance) for (SlimeChunk initial : bootstrap.initial().getChunkStorage()) { long pos = Util.chunkPosition(initial.getX(), initial.getZ()); - List tags = new ArrayList<>(initial.getEntities()); - // this.entityStorage.put(pos, tags); this.chunkStorage.put(pos, initial); } this.extraPDC = new AdventurePersistentDataContainer(this.extra); - this.liveWorld = new NMSSlimeWorld(this); } @Override @@ -94,7 +87,6 @@ public LevelChunk promote(int x, int z, SlimeChunk chunk) { 0L, null, null, null); chunk = new NMSSlimeChunk(levelChunk, getChunk(x, z)); - } else { levelChunk = SlimeChunkConverter.deserializeSlimeChunk(this.instance, chunk); chunk = new SafeNmsChunkWrapper(new NMSSlimeChunk(levelChunk, chunk), chunk); @@ -106,16 +98,16 @@ public LevelChunk promote(int x, int z, SlimeChunk chunk) { // Authored by: Kenox // Don't use the NMS live chunk in the chunk map - public void unload(LevelChunk providedChunk, ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices entitySlices) { + public void unload(LevelChunk providedChunk, ChunkEntitySlices entitySlices) { final int x = providedChunk.locX; final int z = providedChunk.locZ; - SlimeChunk chunk = new NMSSlimeChunk(providedChunk, getChunk(x, z), entitySlices); - - if (FastChunkPruner.canBePruned(this.liveWorld, providedChunk)) { + if (FastChunkPruner.canBePruned(this, providedChunk)) { this.chunkStorage.remove(Util.chunkPosition(x, z)); return; } + SlimeChunk chunk = new NMSSlimeChunk(providedChunk, getChunk(x, z), entitySlices); + CompoundBinaryTag pdcTag = Converter.convertTag(providedChunk.persistentDataContainer.toTagCompound()); chunk.getExtraData().put("ChunkBukkitValues", pdcTag); @@ -141,7 +133,7 @@ public World getBukkitWorld() { @Override public SlimeWorld getSlimeWorldMirror() { - return this.liveWorld; + return this; } @Override @@ -188,7 +180,7 @@ public SlimeWorld clone(String worldName, SlimeLoader loader) throws WorldAlread @Override public int getDataVersion() { - return this.liveWorld.getDataVersion(); + return SharedConstants.getCurrentVersion().getDataVersion().getVersion(); } @Override @@ -201,10 +193,6 @@ public Collection getWorldMaps() { return List.of(); } - // public Map> getEntityStorage() { - // return entityStorage; - // } - public SlimeWorld getForSerialization() { SlimeWorld world = SkeletonCloning.weakCopy(this); @@ -257,7 +245,6 @@ public SlimeWorld getForSerialization() { // Bukkit stores the relevant tag as a tag with the key "BukkitValues" in the tag we supply to it var adventureTag = Converter.convertTag(nmsTag.getCompound("BukkitValues")); - world.getExtraData().put("BukkitValues", adventureTag); return new SkeletonSlimeWorld(world.getName(), From fd22e87b8c5f2ecee260097d24342fd8ae8189a5 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Wed, 12 Mar 2025 12:16:46 +0100 Subject: [PATCH 070/133] feat: return a world instance in api. Makes it easier to grab a bukkit world from them and makes it clearer that the user is getting a live representation --- .../asp/api/AdvancedSlimePaperAPI.java | 9 +++++---- .../asp/api/world/SlimeWorldInstance.java | 5 +++-- .../infernalsuite/asp/AdvancedSlimePaper.java | 16 ++++++++-------- .../asp/level/SlimeInMemoryWorld.java | 2 +- .../asp/plugin/commands/sub/DSListCmd.java | 2 +- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/api/src/main/java/com/infernalsuite/asp/api/AdvancedSlimePaperAPI.java b/api/src/main/java/com/infernalsuite/asp/api/AdvancedSlimePaperAPI.java index 50441d0e7..ed877d9a4 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/AdvancedSlimePaperAPI.java +++ b/api/src/main/java/com/infernalsuite/asp/api/AdvancedSlimePaperAPI.java @@ -8,6 +8,7 @@ import com.infernalsuite.asp.api.exceptions.WorldLoadedException; import com.infernalsuite.asp.api.exceptions.WorldTooBigException; import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.SlimeWorldInstance; import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import com.infernalsuite.asp.api.loaders.SlimeLoader; import net.kyori.adventure.util.Services; @@ -50,7 +51,7 @@ SlimeWorld readWorld(SlimeLoader loader, String worldName, boolean readOnly, Sli * @param worldName the name of the world to get * @return the loaded world, or {@code null} if no loaded world matches the given name */ - SlimeWorld getLoadedWorld(String worldName); + SlimeWorldInstance getLoadedWorld(String worldName); /** * Gets a list of worlds which have been loaded by ASWM. @@ -58,7 +59,7 @@ SlimeWorld readWorld(SlimeLoader loader, String worldName, boolean readOnly, Sli * * @return a list of worlds */ - List getLoadedWorlds(); + List getLoadedWorlds(); /** * Generates a Minecraft World from a {@link SlimeWorld} and @@ -66,12 +67,12 @@ SlimeWorld readWorld(SlimeLoader loader, String worldName, boolean readOnly, Sli *
    * This method must be called in sync with the Server Thread * - * @param world {@link SlimeWorld} world to be added to the server's world list + * @param world {@link SlimeWorldInstance} world to be added to the server's world list * @param callWorldLoadEvent Whether to call {@link org.bukkit.event.world.WorldLoadEvent} * @throws IllegalArgumentException if the world is already loaded * @return Returns a slime world representing a live minecraft world */ - SlimeWorld loadWorld(SlimeWorld world, boolean callWorldLoadEvent) throws IllegalArgumentException; + SlimeWorldInstance loadWorld(SlimeWorld world, boolean callWorldLoadEvent) throws IllegalArgumentException; /** * Checks if a {@link SlimeWorld} is loaded on the server. diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java index ed93b4b6b..0ffaa6a9c 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java @@ -1,6 +1,7 @@ package com.infernalsuite.asp.api.world; import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import net.kyori.adventure.nbt.BinaryTag; import org.bukkit.World; @@ -12,9 +13,9 @@ public interface SlimeWorldInstance { World getBukkitWorld(); - SlimeWorld getSlimeWorldMirror(); + SlimeWorld getSlimeWorld(); - com.infernalsuite.asp.api.world.properties.SlimePropertyMap getPropertyMap(); + SlimePropertyMap getPropertyMap(); boolean isReadOnly(); diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java index 7741a210a..f965fc528 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java @@ -39,7 +39,7 @@ public class AdvancedSlimePaper implements AdvancedSlimePaperAPI { private static final Logger LOGGER = LoggerFactory.getLogger(AdvancedSlimePaper.class); private static final SlimeNMSBridge BRIDGE_INSTANCE = SlimeNMSBridge.instance(); - private final Map loadedWorlds = new ConcurrentHashMap<>(); + private final Map loadedWorlds = new ConcurrentHashMap<>(); static { System.setProperty("org.slf4j.simpleLogger.showShortLogName", "true"); @@ -74,7 +74,7 @@ public SlimeWorld readWorld(SlimeLoader loader, String worldName, boolean readOn } @Override - public SlimeWorld loadWorld(SlimeWorld world, boolean callWorldLoadEvent) throws IllegalArgumentException { + public SlimeWorldInstance loadWorld(SlimeWorld world, boolean callWorldLoadEvent) throws IllegalArgumentException { AsyncCatcher.catchOp("SWM world load"); Objects.requireNonNull(world, "SlimeWorld cannot be null"); @@ -86,17 +86,17 @@ public SlimeWorld loadWorld(SlimeWorld world, boolean callWorldLoadEvent) throws long start = System.currentTimeMillis(); SlimeWorldInstance instance = BRIDGE_INSTANCE.loadInstance(world); - SlimeWorld mirror = instance.getSlimeWorldMirror(); + SlimeWorld mirror = instance.getSlimeWorld(); Bukkit.getPluginManager().callEvent(new LoadSlimeWorldEvent(mirror)); if (callWorldLoadEvent) { Bukkit.getPluginManager().callEvent(new WorldLoadEvent(instance.getBukkitWorld())); } - registerWorld(mirror); + registerWorld(instance); LOGGER.info("World {} loaded in {}ms.", world.getName(), System.currentTimeMillis() - start); - return mirror; + return instance; } @Override @@ -153,12 +153,12 @@ public void saveWorld(SlimeWorld world) throws IOException { } @Override - public SlimeWorld getLoadedWorld(String worldName) { + public SlimeWorldInstance getLoadedWorld(String worldName) { return loadedWorlds.get(worldName); } @Override - public List getLoadedWorlds() { + public List getLoadedWorlds() { return List.copyOf(loadedWorlds.values()); } @@ -232,7 +232,7 @@ public SlimeWorld readVanillaWorld(File worldDir, String worldName, SlimeLoader * * @param world the world to register */ - private void registerWorld(SlimeWorld world) { + private void registerWorld(SlimeWorldInstance world) { this.loadedWorlds.put(world.getName(), world); } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java index 7a0ad2145..0d8c890fe 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -132,7 +132,7 @@ public World getBukkitWorld() { } @Override - public SlimeWorld getSlimeWorldMirror() { + public SlimeWorld getSlimeWorld() { return this; } diff --git a/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/DSListCmd.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/DSListCmd.java index 9bbf12c0c..f7f51f770 100644 --- a/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/DSListCmd.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/DSListCmd.java @@ -91,7 +91,7 @@ private boolean isLoaded(SlimeLoader loader, String worldName) { World world = Bukkit.getWorld(worldName); if (world != null) { - SlimeWorld slimeWorld = SlimeNMSBridge.instance().getInstance(world).getSlimeWorldMirror(); + SlimeWorld slimeWorld = SlimeNMSBridge.instance().getInstance(world).getSlimeWorld(); if (slimeWorld != null) { return loader.equals(slimeWorld.getLoader()); From f4cb37028cac9c109b2bb7e1eb733472c3866cc6 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Wed, 12 Mar 2025 12:21:55 +0100 Subject: [PATCH 071/133] feat: make SlimeWorldInstance extend SlimeWorld --- .../asp/api/events/LoadSlimeWorldEvent.java | 7 ++++--- .../asp/api/world/SlimeWorldInstance.java | 19 ++++++------------- .../infernalsuite/asp/AdvancedSlimePaper.java | 3 +-- .../asp/level/SlimeInMemoryWorld.java | 6 +----- 4 files changed, 12 insertions(+), 23 deletions(-) diff --git a/api/src/main/java/com/infernalsuite/asp/api/events/LoadSlimeWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/LoadSlimeWorldEvent.java index 490021fed..64690b9c1 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/events/LoadSlimeWorldEvent.java +++ b/api/src/main/java/com/infernalsuite/asp/api/events/LoadSlimeWorldEvent.java @@ -1,5 +1,6 @@ package com.infernalsuite.asp.api.events; +import com.infernalsuite.asp.api.world.SlimeWorldInstance; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; @@ -9,9 +10,9 @@ public class LoadSlimeWorldEvent extends Event { private static final HandlerList handlers = new HandlerList(); - private final com.infernalsuite.asp.api.world.SlimeWorld slimeWorld; + private final SlimeWorldInstance slimeWorld; - public LoadSlimeWorldEvent(com.infernalsuite.asp.api.world.SlimeWorld slimeWorld) { + public LoadSlimeWorldEvent(SlimeWorldInstance slimeWorld) { super(false); this.slimeWorld = Objects.requireNonNull(slimeWorld, "slimeWorld cannot be null"); } @@ -25,7 +26,7 @@ public static HandlerList getHandlerList() { return handlers; } - public com.infernalsuite.asp.api.world.SlimeWorld getSlimeWorld() { + public SlimeWorldInstance getSlimeWorld() { return slimeWorld; } } diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java index 0ffaa6a9c..08fe615ab 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java @@ -4,23 +4,16 @@ import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import net.kyori.adventure.nbt.BinaryTag; import org.bukkit.World; +import org.jetbrains.annotations.NotNull; import java.util.concurrent.ConcurrentMap; -public interface SlimeWorldInstance { - - String getName(); +/* + * Represents a loaded SlimeWorld. This world is synchronized with the state of the bukkit world. + */ +public interface SlimeWorldInstance extends SlimeWorld { + @NotNull World getBukkitWorld(); - SlimeWorld getSlimeWorld(); - - SlimePropertyMap getPropertyMap(); - - boolean isReadOnly(); - - SlimeLoader getLoader(); - - ConcurrentMap getExtraData(); - } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java index f965fc528..3ca504c7d 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java @@ -86,9 +86,8 @@ public SlimeWorldInstance loadWorld(SlimeWorld world, boolean callWorldLoadEvent long start = System.currentTimeMillis(); SlimeWorldInstance instance = BRIDGE_INSTANCE.loadInstance(world); - SlimeWorld mirror = instance.getSlimeWorld(); - Bukkit.getPluginManager().callEvent(new LoadSlimeWorldEvent(mirror)); + Bukkit.getPluginManager().callEvent(new LoadSlimeWorldEvent(instance)); if (callWorldLoadEvent) { Bukkit.getPluginManager().callEvent(new WorldLoadEvent(instance.getBukkitWorld())); } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java index 0d8c890fe..3dbc72394 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -127,14 +127,10 @@ public Collection getChunkStorage() { } @Override - public World getBukkitWorld() { + public @NotNull World getBukkitWorld() { return this.instance.getWorld(); } - @Override - public SlimeWorld getSlimeWorld() { - return this; - } @Override public SlimePropertyMap getPropertyMap() { From 6899fde5169bb0fa459e5120813639b3b827d529 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Wed, 12 Mar 2025 12:44:18 +0100 Subject: [PATCH 072/133] chore: remove unused internal api --- .../infernalsuite/asp/api/SlimeNMSBridge.java | 4 ---- .../asp/SimpleDataFixerConverter.java | 3 +-- .../infernalsuite/asp/SlimeNMSBridgeImpl.java | 21 ------------------- 3 files changed, 1 insertion(+), 27 deletions(-) diff --git a/api/src/main/java/com/infernalsuite/asp/api/SlimeNMSBridge.java b/api/src/main/java/com/infernalsuite/asp/api/SlimeNMSBridge.java index e4f31574e..535cc5208 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/SlimeNMSBridge.java +++ b/api/src/main/java/com/infernalsuite/asp/api/SlimeNMSBridge.java @@ -37,13 +37,9 @@ static SlimeNMSBridge instance() { void extractCraftPDC(PersistentDataContainer source, CompoundBinaryTag.Builder builder); - PersistentDataContainer extractCompoundMapIntoCraftPDC(CompoundBinaryTag source); - @ApiStatus.Internal class Holder { private static final SlimeNMSBridge INSTANCE = Services.service(SlimeNMSBridge.class).orElseThrow(); } - CompoundBinaryTag convertChunkTo1_13(CompoundBinaryTag tag); - } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java index 68b632999..15ebd6388 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java @@ -17,7 +17,6 @@ import net.minecraft.SharedConstants; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.function.Consumer; @@ -56,7 +55,7 @@ public SlimeWorld readFromData(SlimeWorld data) { SlimeChunkSection dataSection = chunk.getSections()[i]; if (dataSection == null) continue; - CompoundBinaryTag blockStateTag = blockStateTag = convertAndBack(dataSection.getBlockStatesTag(), (tag) -> { + CompoundBinaryTag blockStateTag = convertAndBack(dataSection.getBlockStatesTag(), (tag) -> { WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, new NBTMapType(tag), "palette", encodedCurrentVersion, encodedNewVersion); }); diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java index e7e3f7e53..2cba0515e 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java @@ -64,27 +64,6 @@ public void extractCraftPDC(PersistentDataContainer source, CompoundBinaryTag.Bu } } - @Override - public PersistentDataContainer extractCompoundMapIntoCraftPDC(CompoundBinaryTag source) { - CraftPersistentDataContainer container = new CraftPersistentDataContainer(REGISTRY); - source.forEach(entry -> container.put(entry.getKey(), Converter.convertTag(entry.getValue()))); - return container; - } - - @Override - public CompoundBinaryTag convertChunkTo1_13(CompoundBinaryTag tag) { - CompoundTag nmsTag = (CompoundTag) Converter.convertTag(tag); - - int version = nmsTag.getInt("DataVersion"); - - long encodedNewVersion = DataConverter.encodeVersions(1624, Integer.MAX_VALUE); - long encodedCurrentVersion = DataConverter.encodeVersions(version, Integer.MAX_VALUE); - - MCTypeRegistry.CHUNK.convert(new NBTMapType(nmsTag), encodedCurrentVersion, encodedNewVersion); - - return Converter.convertTag(nmsTag); - } - @Override public boolean loadOverworldOverride() { if (defaultWorld == null) { From 2be4b342e170d1ebc2b325dde800cf6f0b4fa89e Mon Sep 17 00:00:00 2001 From: David Mayr Date: Wed, 12 Mar 2025 12:46:01 +0100 Subject: [PATCH 073/133] feat: Optimize getTileEntities and getEntities --- .../infernalsuite/asp/level/NMSSlimeChunk.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java index 6a9069f57..94e5c4941 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -36,6 +36,7 @@ import org.slf4j.LoggerFactory; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Map; @@ -151,34 +152,36 @@ public CompoundBinaryTag getHeightMaps() { @Override public List getTileEntities() { - List tileEntities = new ArrayList<>(); + Collection blockEntities = this.chunk.blockEntities.values(); + List tileEntities = new ArrayList<>(blockEntities.size()); - for (BlockEntity entity : this.chunk.blockEntities.values()) { + for (BlockEntity entity : blockEntities) { CompoundTag entityNbt = entity.saveWithFullMetadata(net.minecraft.server.MinecraftServer.getServer().registryAccess()); - tileEntities.add(entityNbt); + tileEntities.add(Converter.convertTag(entityNbt)); } - return Lists.transform(tileEntities, Converter::convertTag); + return tileEntities; } @Override public List getEntities() { - List entities = new ArrayList<>(); ChunkEntitySlices slices = getEntitySlices(); if (slices == null) return new ArrayList<>(); + List entities = new ArrayList<>(slices.entities.size()); + // Work by for (Entity entity : slices.entities) { CompoundTag entityNbt = new CompoundTag(); try { - if (entity.save(entityNbt)) entities.add(entityNbt); + if (entity.save(entityNbt)) entities.add(Converter.convertTag(entityNbt)); } catch (final Exception e) { LOGGER.error("Could not save the entity = {}, exception = {}", entity, e); } } - return Lists.transform(entities, Converter::convertTag); + return entities; } private ChunkEntitySlices getEntitySlices() { From 577258f6b55a167a93e381abd4ca2f1729a5a596 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Wed, 12 Mar 2025 12:54:33 +0100 Subject: [PATCH 074/133] fix: SlimeWorld read-only status always true when importing vanilla world (Closes #152) --- .../asp/serialization/anvil/AnvilWorldReader.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java b/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java index c446b8fe1..a3c86a651 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java @@ -128,7 +128,8 @@ public SlimeWorld readFromData(AnvilImportData importData) { propertyMap.setValue(SlimeProperties.SPAWN_Y, data.y); propertyMap.setValue(SlimeProperties.SPAWN_Z, data.z); - return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld(importData.newName(), importData.loader(), true, chunks, new ConcurrentHashMap<>(), propertyMap, worldVersion); + return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld(importData.newName(), importData.loader(), importData.loader() == null, + chunks, new ConcurrentHashMap<>(), propertyMap, worldVersion); } catch (IOException | InvalidWorldException e) { throw new RuntimeException(e); From 06212dade6fd7cd452dbd62344ef2231d753ca2e Mon Sep 17 00:00:00 2001 From: David Mayr Date: Wed, 12 Mar 2025 21:19:03 +0100 Subject: [PATCH 075/133] feat: Improve Config IO --- ...Prevent-config-disk-io-on-world-load.patch | 32 +++++++++ ...Prevent-config-disk-io-on-world-load.patch | 71 +++++++++++++++++++ .../asp/config/SlimePaperWorldConfig.java | 56 +++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 impl/aspaper-server/minecraft-patches/features/0004-Prevent-config-disk-io-on-world-load.patch create mode 100644 impl/aspaper-server/paper-patches/features/0005-Prevent-config-disk-io-on-world-load.patch create mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/config/SlimePaperWorldConfig.java diff --git a/impl/aspaper-server/minecraft-patches/features/0004-Prevent-config-disk-io-on-world-load.patch b/impl/aspaper-server/minecraft-patches/features/0004-Prevent-config-disk-io-on-world-load.patch new file mode 100644 index 000000000..8d003194a --- /dev/null +++ b/impl/aspaper-server/minecraft-patches/features/0004-Prevent-config-disk-io-on-world-load.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: David Mayr +Date: Wed, 12 Mar 2025 21:14:56 +0100 +Subject: [PATCH] Prevent config disk io on world load + + +diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java +index 60608cea4e564c1ce47f8a4de2c1a48986bbdecb..1b5d65136421b63353b1c6cd8ae5d413ec070b92 100644 +--- a/net/minecraft/server/level/ServerLevel.java ++++ b/net/minecraft/server/level/ServerLevel.java +@@ -614,7 +614,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + ) { + //ASP end + // CraftBukkit start +- super(serverLevelData, dimension, server.registryAccess(), levelStem.type(), false, isDebug, biomeZoomSeed, server.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> server.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(levelStorageAccess.levelDirectory.path(), serverLevelData.getLevelName(), dimension.location(), spigotConfig, server.registryAccess(), serverLevelData.getGameRules())), dispatcher); // Paper - create paper world configs; Async-Anti-Xray: Pass executor ++ super(serverLevelData, dimension, server.registryAccess(), levelStem.type(), false, isDebug, biomeZoomSeed, server.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> bootstrap != null ? com.infernalsuite.asp.config.SlimePaperWorldConfig.initializeOrGet() : server.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(levelStorageAccess.levelDirectory.path(), serverLevelData.getLevelName(), dimension.location(), spigotConfig, server.registryAccess(), serverLevelData.getGameRules())), dispatcher); // Paper - create paper world configs; Async-Anti-Xray: Pass executor //ASP - Optimize world config + this.pvpMode = server.isPvpAllowed(); + this.levelStorageAccess = levelStorageAccess; + this.uuid = bootstrap == null ? org.bukkit.craftbukkit.util.WorldUUID.getUUID(levelStorageAccess.levelDirectory.path().toFile()) : UUID.randomUUID(); //ASP - avoid IO calls +diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java +index 1dbe7c7c1051c3972105534a07ce50d4cf98fc85..e1d3c292b9efccb032245f4f1618f2650f0bc619 100644 +--- a/net/minecraft/world/level/Level.java ++++ b/net/minecraft/world/level/Level.java +@@ -851,7 +851,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl + this.maxSectionY = this.maxY >> 4; + this.sectionsCount = this.maxSectionY - this.minSectionY + 1; + // Paper end - getblock optimisations - cache world height/sections +- this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName()); // Spigot ++ this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName(), !(this instanceof com.infernalsuite.asp.level.SlimeLevelInstance)); // Spigot //ASP - Improve Slime IO + this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config + this.generator = gen; + this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env); diff --git a/impl/aspaper-server/paper-patches/features/0005-Prevent-config-disk-io-on-world-load.patch b/impl/aspaper-server/paper-patches/features/0005-Prevent-config-disk-io-on-world-load.patch new file mode 100644 index 000000000..70c5ff9d8 --- /dev/null +++ b/impl/aspaper-server/paper-patches/features/0005-Prevent-config-disk-io-on-world-load.patch @@ -0,0 +1,71 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: David Mayr +Date: Wed, 12 Mar 2025 21:14:56 +0100 +Subject: [PATCH] Prevent config disk io on world load + + +diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java +index e0d4222a99f22d7130d95cf29b034a98f2f3b76e..776440ec20c7bf0acac8678773b0a5d29548c270 100644 +--- a/src/main/java/org/spigotmc/SpigotConfig.java ++++ b/src/main/java/org/spigotmc/SpigotConfig.java +@@ -78,7 +78,12 @@ public class SpigotConfig { + } + } + ++ // ASP start - Improve Slime IO + public static void readConfig(Class clazz, Object instance) { // Paper - package-private -> public ++ readConfig(clazz, instance, true); ++ } ++ public static void readConfig(Class clazz, Object instance, boolean save) { ++ // ASP end - Improve Slime IO + for (Method method : clazz.getDeclaredMethods()) { + if (Modifier.isPrivate(method.getModifiers())) { + if (method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE) { +@@ -95,7 +100,11 @@ public class SpigotConfig { + } + + try { +- SpigotConfig.config.save(SpigotConfig.CONFIG_FILE); ++ // ASP start - Improve Slime IO ++ if(save) { ++ SpigotConfig.config.save(SpigotConfig.CONFIG_FILE); ++ } ++ // ASP end - Improve Slime IO + } catch (IOException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Could not save " + SpigotConfig.CONFIG_FILE, ex); + } +diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java +index 89e2adbc1e1a0709d03e151e3ffcdbff10a44098..6b2241efbc248324f178a547aea9f398ed624247 100644 +--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java ++++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java +@@ -10,17 +10,28 @@ public class SpigotWorldConfig { + private final YamlConfiguration config; + private boolean verbose; + ++ // ASP start - Improve Slime IO + public SpigotWorldConfig(String worldName) { ++ this(worldName, true); ++ } ++ // ASP end - Improve Slime IO ++ ++ public SpigotWorldConfig(String worldName, boolean saveOnLoad) { // ASP - Improve Slime IO + this.worldName = worldName; + this.config = SpigotConfig.config; +- this.init(); ++ this.init(saveOnLoad); // ASP - Improve Slime IO + } + ++ // ASP start - Improve Slime IO + public void init() { ++ init(true); ++ } ++ public void init(boolean saveOnLoad) { ++ // ASP end - Improve Slime IO + this.verbose = this.getBoolean("verbose", false); // Paper + + this.log("-------- World Settings For [" + this.worldName + "] --------"); +- SpigotConfig.readConfig(SpigotWorldConfig.class, this); ++ SpigotConfig.readConfig(SpigotWorldConfig.class, this, saveOnLoad); // ASP - Improve Slime IO + } + + private void log(String s) { diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/config/SlimePaperWorldConfig.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/config/SlimePaperWorldConfig.java new file mode 100644 index 000000000..9087e71d5 --- /dev/null +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/config/SlimePaperWorldConfig.java @@ -0,0 +1,56 @@ +package com.infernalsuite.asp.config; + +import io.papermc.paper.configuration.Configurations; +import io.papermc.paper.configuration.PaperConfigurations; +import io.papermc.paper.configuration.WorldConfiguration; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.level.GameRules; +import org.spigotmc.SpigotWorldConfig; + +import java.nio.file.Path; + +public class SlimePaperWorldConfig { + + private static final ResourceLocation FAKE_WORLD_KEY = ResourceLocation.fromNamespaceAndPath("infernalsuite", "asp-slimeworld"); + public static WorldConfiguration cachedSlimeWorldConfig; + + private SlimePaperWorldConfig() {} + + public static WorldConfiguration initializeOrGet() { + if(cachedSlimeWorldConfig != null) + return cachedSlimeWorldConfig; + + + initialize(MinecraftServer.getServer().paperConfigurations, MinecraftServer.getServer()); + return cachedSlimeWorldConfig; + } + + private static void initialize( + PaperConfigurations paperConfigurations, + MinecraftServer server + ) { + SpigotWorldConfig spigotWorldConfig = new SpigotWorldConfig("asp-slimeworld"); + + GameRules gameRules = new GameRules(server.worldLoader.dataConfiguration().enabledFeatures()); + + Configurations.ContextMap contextMap = PaperConfigurations.createWorldContextMap( + /* + * This might break if Paper team decides to extend/edit the functionality of this the world path property. + * But the goal is for paper to treat the supplied folder as a world folder and create a paper-world.yml file there. + * + * Users can edit this file to change the config for all slime worlds. + */ + Path.of("config", "advancedslimepaper"), + + "asp-slimeworld", + FAKE_WORLD_KEY, + spigotWorldConfig, + server.registryAccess(), + gameRules + ); + cachedSlimeWorldConfig = paperConfigurations.createWorldConfig(contextMap); + } + + +} From dc9f14ecf9d7e4fe28976474bdf349fec3c404e9 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Wed, 12 Mar 2025 22:25:17 +0100 Subject: [PATCH 076/133] fix: missing at --- .../java/com/infernalsuite/asp/level/SlimeChunkConverter.java | 1 + impl/build-data/aspaper.at | 1 + 2 files changed, 2 insertions(+) diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java index 0b93f0a6a..a11d171ae 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java @@ -48,6 +48,7 @@ static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeC SWMRNibbleArray[] blockNibbles = StarLightEngine.getFilledEmptyLight(instance); SWMRNibbleArray[] skyNibbles = StarLightEngine.getFilledEmptyLight(instance); instance.getServer().scheduleOnMain(() -> { + //TODO: Figure out if this is important. Seems empty in paper instance.getLightEngine().retainData(pos, true); }); diff --git a/impl/build-data/aspaper.at b/impl/build-data/aspaper.at index 0b7647cb1..2014669a0 100644 --- a/impl/build-data/aspaper.at +++ b/impl/build-data/aspaper.at @@ -4,3 +4,4 @@ public ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlic public ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkLoadTask chunkHolder public net.minecraft.server.MinecraftServer commandStorage public net.minecraft.world.level.chunk.storage.SerializableChunkData makeBiomeCodec(Lnet/minecraft/core/Registry;)Lcom/mojang/serialization/Codec; +public net.minecraft.world.level.chunk.storage.SerializableChunkData postLoadChunk(Lnet/minecraft/server/level/ServerLevel;Ljava/util/List;Ljava/util/List;)Lnet/minecraft/world/level/chunk/LevelChunk$PostLoadProcessor; From 7ebe52cff942ae38d4a191446869a1124ce44485 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Wed, 12 Mar 2025 22:42:22 +0100 Subject: [PATCH 077/133] feat: hook into paper hooks for chunk saving instead --- .../moonrise/paper/PaperHooks.java.patch | 14 +++++++++++ .../scheduling/NewChunkHolder.java.patch | 25 ------------------- 2 files changed, 14 insertions(+), 25 deletions(-) create mode 100644 impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch delete mode 100644 impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch diff --git a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch new file mode 100644 index 000000000..e400ccfdb --- /dev/null +++ b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch @@ -0,0 +1,14 @@ +--- a/ca/spottedleaf/moonrise/paper/PaperHooks.java ++++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java +@@ -79,7 +_,10 @@ + + @Override + public void chunkUnloadFromWorld(final LevelChunk chunk) { +- ++ if (chunk.level instanceof com.infernalsuite.asp.level.SlimeLevelInstance slime) { ++ //The custom entity slices need to be passed on for entities to be saved ++ slime.onChunkUnloaded(chunk, chunk.getChunkHolder().getEntityChunk()); ++ } + } + + @Override diff --git a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch deleted file mode 100644 index f38ea67fc..000000000 --- a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -+++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -@@ -116,7 +_,7 @@ - } - - if (!transientChunk) { -- if (entityChunk != null) { -+ if (!(this.world instanceof com.infernalsuite.asp.level.SlimeLevelInstance) && entityChunk != null) { //ASP - final List entities = ChunkEntitySlices.readEntities(this.world, entityChunk); - - ((ChunkSystemServerLevel)this.world).moonrise$getEntityLookup().addEntityChunkEntities(entities, new ChunkPos(this.chunkX, this.chunkZ)); -@@ -895,6 +_,13 @@ - final PoiChunk poiChunk = state.poiChunk(); - - final boolean shouldLevelChunkNotSave = PlatformHooks.get().forceNoSave(chunk); -+ -+ // ASP start - Chunk unloading -+ if (world instanceof com.infernalsuite.asp.level.SlimeLevelInstance slime && chunk instanceof LevelChunk levelChunk) { -+ //The custom entity slices need to be passed on for entities to be saved -+ slime.onChunkUnloaded(levelChunk, entityChunk); -+ } -+ // ASP end - Chunk unloading - - // unload chunk data - if (chunk != null) { From b9443256599ce3401267a018d1d1740cab512b9e Mon Sep 17 00:00:00 2001 From: David Mayr Date: Wed, 12 Mar 2025 23:07:24 +0100 Subject: [PATCH 078/133] fix: use unloadcallback instead of paper hook --- .../moonrise/paper/PaperHooks.java.patch | 14 ------- .../server/level/ServerChunkCache.java.patch | 21 ---------- .../asp/level/SlimeChunkLevel.java | 12 ++++++ .../asp/level/SlimeLevelInstance.java | 39 +------------------ 4 files changed, 13 insertions(+), 73 deletions(-) delete mode 100644 impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch delete mode 100644 impl/aspaper-server/minecraft-patches/sources/net/minecraft/server/level/ServerChunkCache.java.patch diff --git a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch deleted file mode 100644 index e400ccfdb..000000000 --- a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/ca/spottedleaf/moonrise/paper/PaperHooks.java -+++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java -@@ -79,7 +_,10 @@ - - @Override - public void chunkUnloadFromWorld(final LevelChunk chunk) { -- -+ if (chunk.level instanceof com.infernalsuite.asp.level.SlimeLevelInstance slime) { -+ //The custom entity slices need to be passed on for entities to be saved -+ slime.onChunkUnloaded(chunk, chunk.getChunkHolder().getEntityChunk()); -+ } - } - - @Override diff --git a/impl/aspaper-server/minecraft-patches/sources/net/minecraft/server/level/ServerChunkCache.java.patch b/impl/aspaper-server/minecraft-patches/sources/net/minecraft/server/level/ServerChunkCache.java.patch deleted file mode 100644 index 1ed2cc9d0..000000000 --- a/impl/aspaper-server/minecraft-patches/sources/net/minecraft/server/level/ServerChunkCache.java.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- a/net/minecraft/server/level/ServerChunkCache.java -+++ b/net/minecraft/server/level/ServerChunkCache.java -@@ -181,8 +_,10 @@ - } - // Paper end - chunk tick iteration optimisations - -+ public final com.infernalsuite.asp.level.SlimeBootstrap bootstrap; //ASP - - public ServerChunkCache( -+ com.infernalsuite.asp.level.SlimeBootstrap bootstrap, //ASP - ServerLevel level, - LevelStorageSource.LevelStorageAccess levelStorageAccess, - DataFixer fixerUpper, -@@ -196,6 +_,7 @@ - ChunkStatusUpdateListener chunkStatusListener, - Supplier overworldDataStorage - ) { -+ this.bootstrap = bootstrap; //ASP - this.level = level; - this.mainThreadProcessor = new ServerChunkCache.MainThreadExecutor(level); - this.mainThread = Thread.currentThread(); diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java index bce1750e7..805749598 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java @@ -1,5 +1,8 @@ package com.infernalsuite.asp.level; +import ca.spottedleaf.moonrise.common.list.EntityList; +import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; +import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.chunk.LevelChunk; @@ -24,4 +27,13 @@ public void loadCallback() { super.loadCallback(); this.inMemoryWorld.ensureChunkMarkedAsLoaded(this); } + + @Override + public void unloadCallback() { + super.unloadCallback(); + + ChunkEntitySlices entities = ((ChunkSystemServerLevel) this.level).moonrise$getChunkTaskScheduler() + .chunkHolderManager.getChunkHolder(this.locX, this.locZ).getEntityChunk(); + inMemoryWorld.unload(this, entities); + } } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java index 4457305e9..5a0a05ab9 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -5,14 +5,11 @@ import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkLoadTask; import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.GenericDataLoadTask; import com.google.common.util.concurrent.ThreadFactoryBuilder; -import com.infernalsuite.asp.Converter; import com.infernalsuite.asp.serialization.slime.SlimeSerializer; -import com.infernalsuite.asp.api.world.SlimeChunk; import com.infernalsuite.asp.api.world.SlimeWorld; import com.infernalsuite.asp.api.world.SlimeWorldInstance; import com.infernalsuite.asp.api.world.properties.SlimeProperties; import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; -import com.infernalsuite.asp.serialization.slime.SlimeSerializer; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; import net.minecraft.core.registries.Registries; @@ -20,17 +17,12 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.TicketType; import net.minecraft.util.ProgressListener; -import net.minecraft.util.Unit; import net.minecraft.util.datafix.DataFixers; import net.minecraft.world.Difficulty; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.dimension.LevelStem; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; @@ -48,7 +40,6 @@ import java.nio.file.Path; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; -import java.util.ArrayList; import java.util.Collections; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -57,7 +48,6 @@ import java.util.concurrent.Future; import java.util.function.Consumer; import java.util.logging.Level; -import java.util.stream.Collectors; public class SlimeLevelInstance extends ServerLevel { @@ -79,7 +69,6 @@ public class SlimeLevelInstance extends ServerLevel { private static final ExecutorService WORLD_SAVER_SERVICE = Executors.newFixedThreadPool(4, new ThreadFactoryBuilder() .setNameFormat("SWM Pool Thread #%1$d").build()); - private static final TicketType SWM_TICKET = TicketType.create("swm-chunk", (a, b) -> 0); private final Object saveLock = new Object(); @@ -110,7 +99,7 @@ public SlimeLevelInstance(SlimeBootstrap slimeBootstrap, PrimaryLevelData primar } @Override - public ChunkGenerator getGenerator(SlimeBootstrap slimeBootstrap) { + public @NotNull ChunkGenerator getGenerator(SlimeBootstrap slimeBootstrap) { String biomeStr = slimeBootstrap.initial().getPropertyMap().getValue(SlimeProperties.DEFAULT_BIOME); ResourceKey biomeKey = ResourceKey.create(Registries.BIOME, ResourceLocation.parse(biomeStr)); Holder defaultBiome = MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BIOME).get(biomeKey).orElseThrow(); @@ -158,14 +147,6 @@ public Future save() { return CompletableFuture.completedFuture(null); } - /* - @Override - public void saveIncrementally(boolean doFull) { - if (doFull) { - this.save(null, false, false); - } - }*/ // Most likely unused - kyngs - private Future saveInternal() { synchronized (saveLock) { // Don't want to save the SlimeWorld from multiple threads simultaneously SlimeWorldInstance slimeWorld = this.slimeInstance; @@ -195,20 +176,6 @@ public ChunkDataLoadTask getLoadTask(ChunkLoadTask task, ChunkTaskScheduler sche return new ChunkDataLoadTask(task, scheduler, world, chunkX, chunkZ, priority, onRun); } - /* - public void loadEntities(int chunkX, int chunkZ) { - SlimeChunk slimeChunk = this.slimeInstance.getChunk(chunkX, chunkZ); - if (slimeChunk != null) { - this.getEntityLookup().addLegacyChunkEntities(new ArrayList<>( - EntityType.loadEntitiesRecursive(slimeChunk.getEntities() - .stream() - .map((tag) -> (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)) - .collect(Collectors.toList()), this) - .toList() - ), new ChunkPos(chunkX, chunkZ)); - } - }*/ // Most likely unused - kyngs - @Override public void setDefaultSpawnPos(BlockPos pos, float angle) { super.setDefaultSpawnPos(pos, angle); @@ -220,10 +187,6 @@ public void setDefaultSpawnPos(BlockPos pos, float angle) { propertyMap.setValue(SlimeProperties.SPAWN_YAW, angle); } - public void onChunkUnloaded(LevelChunk chunk, ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices entityChunk) { - this.slimeInstance.unload(chunk, entityChunk); - } - public void deleteTempFiles() { WORLD_SAVER_SERVICE.execute(() -> { Path path = this.levelStorageAccess.levelDirectory.path(); From f375cfa109801d05b07c2036b814994ab6e000e5 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Wed, 12 Mar 2025 23:18:23 +0100 Subject: [PATCH 079/133] fix: compile error --- .../features/0001-Disable-dragon-battle.patch | 4 ++-- .../net/minecraft/server/level/ServerLevel.java.patch | 7 +------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/impl/aspaper-server/minecraft-patches/features/0001-Disable-dragon-battle.patch b/impl/aspaper-server/minecraft-patches/features/0001-Disable-dragon-battle.patch index a7c61d1a6..a48979525 100644 --- a/impl/aspaper-server/minecraft-patches/features/0001-Disable-dragon-battle.patch +++ b/impl/aspaper-server/minecraft-patches/features/0001-Disable-dragon-battle.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Disable dragon battle diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 253280d5bc2c050ce727e85c7daeccd306903af3..426a9fa0000266c569d69c6418e4d772adacd38c 100644 +index c5ddf6c0f0ff795da2f7aec8915a081b334423ec..a373f5b8e03f4179a4d9f63d79abc19a38f952b6 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -690,7 +690,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -689,7 +689,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe ); this.structureManager = new StructureManager(this, this.serverLevelData.worldGenOptions(), this.structureCheck); // CraftBukkit if (this.dimension() == Level.END && this.dimensionTypeRegistration().is(BuiltinDimensionTypes.END) || env == org.bukkit.World.Environment.THE_END) { // CraftBukkit - Allow to create EnderDragonBattle in default and custom END diff --git a/impl/aspaper-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch b/impl/aspaper-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch index 6c795fee8..44ce62a20 100644 --- a/impl/aspaper-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch +++ b/impl/aspaper-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch @@ -42,7 +42,7 @@ // CraftBukkit start super(serverLevelData, dimension, server.registryAccess(), levelStem.type(), false, isDebug, biomeZoomSeed, server.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> server.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(levelStorageAccess.levelDirectory.path(), serverLevelData.getLevelName(), dimension.location(), spigotConfig, server.registryAccess(), serverLevelData.getGameRules())), dispatcher); // Paper - create paper world configs; Async-Anti-Xray: Pass executor this.pvpMode = server.isPvpAllowed(); -@@ -614,10 +_,18 @@ +@@ -614,6 +_,13 @@ chunkGenerator = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, chunkGenerator, gen); } // CraftBukkit end @@ -56,11 +56,6 @@ boolean flag = server.forceSynchronousWrites(); DataFixer fixerUpper = server.getFixerUpper(); // Paper - rewrite chunk system - this.chunkSource = new ServerChunkCache( -+ bootstrap, //ASP - this, - levelStorageAccess, - fixerUpper, @@ -695,6 +_,12 @@ public void setDragonFight(@Nullable EndDragonFight dragonFight) { this.dragonFight = dragonFight; From 1b05a8edd8d742686e7444175787b673959624d6 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Wed, 12 Mar 2025 23:45:44 +0100 Subject: [PATCH 080/133] chore: move away from patch --- gradle.properties | 1 + .../world/level/chunk/LevelChunk.java.patch | 16 ---------------- .../infernalsuite/asp/level/FastChunkPruner.java | 8 ++++++-- .../infernalsuite/asp/level/NMSSlimeChunk.java | 13 ++++++++----- .../java/com/infernalsuite/asp/util/NmsUtil.java | 6 ++++++ 5 files changed, 21 insertions(+), 23 deletions(-) delete mode 100644 impl/aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/LevelChunk.java.patch diff --git a/gradle.properties b/gradle.properties index 11d9848fe..b866e639d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,3 +10,4 @@ org.gradle.parallel=true org.gradle.vfs.watch=false org.gradle.jvmargs=-Xmx10g +paper.runDisableWatchdog=true \ No newline at end of file diff --git a/impl/aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/LevelChunk.java.patch b/impl/aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/LevelChunk.java.patch deleted file mode 100644 index bc3ac2d13..000000000 --- a/impl/aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/LevelChunk.java.patch +++ /dev/null @@ -1,16 +0,0 @@ ---- a/net/minecraft/world/level/chunk/LevelChunk.java -+++ b/net/minecraft/world/level/chunk/LevelChunk.java -@@ -313,6 +_,13 @@ - } - } - -+ -+ // ASWM start - maintain binary compatibility with 1.20.6 -+ public ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder getChunkHolder() { -+ return this.level.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(chunkPos.x, chunkPos.z); -+ } -+ // ASWM end -+ - // Paper start - If loaded util - @Override - public final FluidState getFluidIfLoaded(BlockPos blockposition) { diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java index ccacb856c..8d1d30572 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java @@ -1,19 +1,23 @@ package com.infernalsuite.asp.level; import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder; import com.infernalsuite.asp.api.world.SlimeWorld; import com.infernalsuite.asp.api.world.properties.SlimeProperties; import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.util.NmsUtil; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; public class FastChunkPruner { public static boolean canBePruned(SlimeWorld world, LevelChunk chunk) { + NewChunkHolder chunkHolder = NmsUtil.getChunkHolder(chunk); + // Kenox // It's not safe to assume that the chunk can be pruned // if there isn't a loaded chunk there - if (chunk == null || chunk.getChunkHolder() == null) { + if (chunkHolder == null) { return false; } @@ -39,7 +43,7 @@ public static boolean canBePruned(SlimeWorld world, LevelChunk chunk) { String pruningSetting = world.getPropertyMap().getValue(SlimeProperties.CHUNK_PRUNING); if (pruningSetting.equals("aggressive")) { - ChunkEntitySlices slices = chunk.getChunkHolder().getEntityChunk(); + ChunkEntitySlices slices = chunkHolder.getEntityChunk(); return chunk.blockEntities.isEmpty() && (slices == null || slices.isEmpty()) && areSectionsEmpty(chunk); } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java index 94e5c4941..d141c37cd 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -1,12 +1,12 @@ package com.infernalsuite.asp.level; -import com.google.common.collect.Lists; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder; import com.infernalsuite.asp.Converter; import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; import com.infernalsuite.asp.api.utils.NibbleArray; import com.infernalsuite.asp.api.world.SlimeChunk; import com.infernalsuite.asp.api.world.SlimeChunkSection; -import com.mojang.logging.LogUtils; +import com.infernalsuite.asp.util.NmsUtil; import com.mojang.serialization.Codec; import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; import net.kyori.adventure.nbt.CompoundBinaryTag; @@ -38,7 +38,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.Map; public class NMSSlimeChunk implements SlimeChunk { private static final Logger LOGGER = LoggerFactory.getLogger(NMSSlimeChunk.class); @@ -187,11 +186,15 @@ public List getEntities() { private ChunkEntitySlices getEntitySlices() { if (this.entitySlices != null) return this.entitySlices; - if (this.chunk == null || this.chunk.getChunkHolder() == null) { + if (this.chunk == null) { + return null; + } + NewChunkHolder chunkHolder = NmsUtil.getChunkHolder(chunk); + if(chunkHolder == null) { return null; } - return this.chunk.getChunkHolder().getEntityChunk(); + return chunkHolder.getEntityChunk(); } @Override diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/util/NmsUtil.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/util/NmsUtil.java index c3bcfadf4..c62d4c1d1 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/util/NmsUtil.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/util/NmsUtil.java @@ -1,6 +1,8 @@ package com.infernalsuite.asp.util; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder; import com.infernalsuite.asp.InternalPlugin; +import net.minecraft.world.level.chunk.LevelChunk; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.scheduler.CraftScheduler; import org.bukkit.plugin.Plugin; @@ -43,4 +45,8 @@ public static void runSyncAndWait(Runnable runnable) { throw runtimeException[0]; } } + + public static NewChunkHolder getChunkHolder(LevelChunk chunk) { + return chunk.level.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(chunk.getPos().x, chunk.getPos().z); + } } From 9b17dcef3cc94c1d50822f6a2c18cfffd78e8a31 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Thu, 13 Mar 2025 00:10:39 +0100 Subject: [PATCH 081/133] feat: Read only dimension data store --- .../0005-Read-only-dimension-data-store.patch | 25 +++++++++++ .../level/ReadOnlyDimensionDataStorage.java | 41 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 impl/aspaper-server/minecraft-patches/features/0005-Read-only-dimension-data-store.patch create mode 100644 impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ReadOnlyDimensionDataStorage.java diff --git a/impl/aspaper-server/minecraft-patches/features/0005-Read-only-dimension-data-store.patch b/impl/aspaper-server/minecraft-patches/features/0005-Read-only-dimension-data-store.patch new file mode 100644 index 000000000..bd3e2ff80 --- /dev/null +++ b/impl/aspaper-server/minecraft-patches/features/0005-Read-only-dimension-data-store.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: David Mayr +Date: Thu, 13 Mar 2025 00:09:20 +0100 +Subject: [PATCH] Read only dimension data store + + +diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java +index 6540b2d6a1062d883811ce240c49d30d1925b291..f89eb4e909c2eeb22732dcb368b3758637f036f7 100644 +--- a/net/minecraft/server/level/ServerChunkCache.java ++++ b/net/minecraft/server/level/ServerChunkCache.java +@@ -207,7 +207,13 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + LOGGER.error("Failed to create dimension data storage directory", (Throwable)var15); + } + +- this.dataStorage = new DimensionDataStorage(path, fixerUpper, level.registryAccess()); ++ //ASP start - No dimension data storage ++ if(level instanceof com.infernalsuite.asp.level.SlimeLevelInstance) { ++ this.dataStorage = new com.infernalsuite.asp.level.ReadOnlyDimensionDataStorage(path, fixerUpper, level.registryAccess()); ++ } else { ++ this.dataStorage = new DimensionDataStorage(path, fixerUpper, level.registryAccess()); ++ } ++ //ASP end - No dimension data storage + this.chunkMap = new ChunkMap( + level, + levelStorageAccess, diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ReadOnlyDimensionDataStorage.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ReadOnlyDimensionDataStorage.java new file mode 100644 index 000000000..dc0026fa8 --- /dev/null +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ReadOnlyDimensionDataStorage.java @@ -0,0 +1,41 @@ +package com.infernalsuite.asp.level; + +import com.mojang.datafixers.DataFixer; +import net.minecraft.core.HolderLookup; +import net.minecraft.world.level.saveddata.SavedData; +import net.minecraft.world.level.storage.DimensionDataStorage; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.nio.file.Path; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; + +public class ReadOnlyDimensionDataStorage extends DimensionDataStorage { + + public ReadOnlyDimensionDataStorage(Path dataFolder, DataFixer fixerUpper, HolderLookup.Provider registries) { + super(dataFolder, fixerUpper, registries); + } + + @SuppressWarnings("unchecked") + @Override + public @Nullable T get(SavedData.@NotNull Factory factory, @NotNull String name) { + Optional optional = this.cache.get(name); + if(optional == null) { + return null; + } + return (T) optional.orElse(null); + } + + @Override + public @NotNull CompletableFuture scheduleSave() { + return CompletableFuture.completedFuture(null); + } + + @Override + public void saveAndJoin() {} + + @Override + public void close() {} + +} From d228563c126d691e474358b82d83af4d55647458 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Thu, 13 Mar 2025 00:14:14 +0100 Subject: [PATCH 082/133] chore: move empty list call up --- .../src/main/java/com/infernalsuite/asp/Converter.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/Converter.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/Converter.java index 85497baa2..848a6e1ce 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/Converter.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/Converter.java @@ -108,13 +108,12 @@ public static T convertTag(Tag base) { case Tag.TAG_BYTE_ARRAY -> (T) ByteArrayBinaryTag.byteArrayBinaryTag(((ByteArrayTag) base).getAsByteArray()); case Tag.TAG_STRING -> (T) StringBinaryTag.stringBinaryTag(((StringTag) base).getAsString()); case Tag.TAG_LIST -> { - List list = new ArrayList<>(); ListTag originalList = ((ListTag) base); - for (Tag entry : originalList) list.add(convertTag(entry)); - - if(list.isEmpty()) { + if(originalList.isEmpty()) { yield (T) ListBinaryTag.empty(); } + List list = new ArrayList<>(originalList.size()); + for (Tag entry : originalList) list.add(convertTag(entry)); yield (T) ListBinaryTag.listBinaryTag(list.getFirst().type(), list); } case Tag.TAG_COMPOUND -> { From 77c1ae4bfaa5ee1b22d8b7106e2bc2bb6f7248c5 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Thu, 13 Mar 2025 00:14:23 +0100 Subject: [PATCH 083/133] fix: delete temp files function --- .../java/com/infernalsuite/asp/level/SlimeLevelInstance.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java index 5a0a05ab9..791bd2b33 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -197,7 +197,7 @@ public void deleteTempFiles() { @Override public @NotNull FileVisitResult visitFile(Path file, @NotNull BasicFileAttributes attrs) throws IOException { if (!file.equals(path)) { - Files.delete(file); + Files.deleteIfExists(file); } return FileVisitResult.CONTINUE; @@ -212,7 +212,7 @@ public void deleteTempFiles() { Files.deleteIfExists(path); } - Files.delete(dir); + Files.deleteIfExists(dir); return FileVisitResult.CONTINUE; } } From 37d673f795548230389235b6571db16c4eb40371 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Thu, 13 Mar 2025 11:05:58 +0100 Subject: [PATCH 084/133] chore: remove old comments --- .../asp/level/ChunkDataLoadTask.java | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java index 73cd2d67a..705bb2bea 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java @@ -47,7 +47,7 @@ protected ChunkDataLoadTask(ChunkLoadTask chunkLoadTask, final ChunkTaskSchedule this.task = this.scheduler.createChunkTask(this.chunkX, this.chunkZ, () -> { try { - SlimeChunk chunk = ((SlimeLevelInstance) this.world).slimeInstance.getChunk(this.chunkX, this.chunkZ); + SlimeChunk chunk = this.world.slimeInstance.getChunk(this.chunkX, this.chunkZ); this.onRun.accept(new GenericDataLoadTask.TaskResult<>(runOnMain(chunk), null)); } catch (final Exception e) { LOGGER.error("ERROR", e); @@ -64,23 +64,10 @@ private ChunkAccess getEmptyChunk() { 0L, null, chunk -> {}, null), true); } - protected ChunkAccess runOnMain(final SlimeChunk data) { - // have tasks to run (at this point, it's just the POI consistency checking) + private ChunkAccess runOnMain(final SlimeChunk data) { try { - // if (data.tasks != null) { - // for (int i = 0, len = data.tasks.size(); i < len; i) { - // data.tasks.poll().run(); - // } - // } - LevelChunk chunk = this.world.slimeInstance.promote(chunkX, chunkZ, data); - - ImposterProtoChunk protoChunk = new ImposterProtoChunk(chunk, false); -// if (data != null) { -// data.getEntities().stream().map(flowTag -> (CompoundTag) Converter.convertTag(flowTag)).forEach(protoChunk::addEntity); -// } - - return protoChunk; + return new ImposterProtoChunk(chunk, false); } catch (final Exception e) { LOGGER.error("Failed to parse main tasks for task {}, chunk data will be lost", this, e); return this.getEmptyChunk(); From 0598e60a5bb0f6cdd326d4bcb2dd3d3cd87c73d0 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Thu, 13 Mar 2025 11:06:41 +0100 Subject: [PATCH 085/133] chore: use the chunk biome registry --- .../main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java index d141c37cd..071b6bd3f 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -95,7 +95,7 @@ public SlimeChunkSection[] getSections() { SlimeChunkSection[] sections = new SlimeChunkSection[this.chunk.getSectionsCount()]; LevelLightEngine lightEngine = chunk.getLevel().getChunkSource().getLightEngine(); - Registry biomeRegistry = chunk.getLevel().registryAccess().lookupOrThrow(Registries.BIOME); + Registry biomeRegistry = chunk.biomeRegistry; Codec>> codec = PalettedContainer.codecRO(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.get(Biomes.PLAINS).orElseThrow()); From 4f70f5d9ef467ed507ac1a651bd6f674e334b88e Mon Sep 17 00:00:00 2001 From: David Mayr Date: Thu, 13 Mar 2025 11:07:50 +0100 Subject: [PATCH 086/133] fix: plugin compile issue --- .../com/infernalsuite/asp/plugin/commands/sub/DSListCmd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/DSListCmd.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/DSListCmd.java index f7f51f770..e00ca549f 100644 --- a/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/DSListCmd.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/DSListCmd.java @@ -91,7 +91,7 @@ private boolean isLoaded(SlimeLoader loader, String worldName) { World world = Bukkit.getWorld(worldName); if (world != null) { - SlimeWorld slimeWorld = SlimeNMSBridge.instance().getInstance(world).getSlimeWorld(); + SlimeWorld slimeWorld = SlimeNMSBridge.instance().getInstance(world); if (slimeWorld != null) { return loader.equals(slimeWorld.getLoader()); From fdf7a43921a6059e85156524bb7e3de7b384a3e1 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 13 Mar 2025 11:31:18 +0100 Subject: [PATCH 087/133] feat: log save errors instead of just printing exceptions, remove commented out code --- .../com/infernalsuite/asp/level/SlimeLevelInstance.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java index 791bd2b33..787b1d436 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -129,19 +129,14 @@ public Future save() { this.serverLevelData.setWorldBorder(this.getWorldBorder().createSettings()); this.serverLevelData.setCustomBossEvents(MinecraftServer.getServer().getCustomBossEvents().save(MinecraftServer.getServer().registryAccess())); - // Update level data -// net.minecraft.nbt.CompoundTag compound = new net.minecraft.nbt.CompoundTag(); -// net.minecraft.nbt.CompoundTag nbtTagCompound = this.serverLevelData.createTag(MinecraftServer.getServer().registryAccess(), compound); - if (MinecraftServer.getServer().isStopped()) { // Make sure the world gets saved before stopping the server by running it from the main thread saveInternal().get(); // Async wait for it to finish } else { return this.saveInternal(); - //WORLD_SAVER_SERVICE.execute(this::save); } } } catch (Throwable e) { - e.printStackTrace(); + Bukkit.getLogger().log(Level.SEVERE, "There was a problem saving the SlimeLevelInstance " + serverLevelData.getLevelName(), e); return CompletableFuture.failedFuture(e); } return CompletableFuture.completedFuture(null); From 27486b19e38dbdd41a6579d0c6d1a39b50084eaa Mon Sep 17 00:00:00 2001 From: David Date: Thu, 13 Mar 2025 14:06:11 +0100 Subject: [PATCH 088/133] chore: remove old patches dir --- patches/api/0001-Slime-World-Manager.patch | 34 ------------------- ...-Dont-close-Slime-Plugin-Classloader.patch | 20 ----------- 2 files changed, 54 deletions(-) delete mode 100644 patches/api/0001-Slime-World-Manager.patch delete mode 100644 patches/api/0002-Dont-close-Slime-Plugin-Classloader.patch diff --git a/patches/api/0001-Slime-World-Manager.patch b/patches/api/0001-Slime-World-Manager.patch deleted file mode 100644 index e1cf9d839..000000000 --- a/patches/api/0001-Slime-World-Manager.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> -Date: Mon, 26 Dec 2022 12:08:15 -0500 -Subject: [PATCH] Slime World Manager - - -diff --git a/build.gradle.kts b/build.gradle.kts -index 571534b42cd9c33d6a7bb6fe3bf3a28e33f8e5de..8e785e4d244abcfcfc3e37fc457baf62050670aa 100644 ---- a/build.gradle.kts -+++ b/build.gradle.kts -@@ -41,6 +41,7 @@ abstract class MockitoAgentProvider : CommandLineArgumentProvider { - dependencies { - api("com.mojang:brigadier:1.2.9") // Paper - Brigadier command api - // api dependencies are listed transitively to API consumers -+ api(project(":api")) // ASWM - api("com.google.guava:guava:33.3.1-jre") - api("com.google.code.gson:gson:2.11.0") - // Paper start - adventure -diff --git a/src/main/java/io/papermc/paper/ServerBuildInfo.java b/src/main/java/io/papermc/paper/ServerBuildInfo.java -index 652ff54e7c50412503725d628bfe72ed03059790..9c5118e6193b0e9852ef6b52cb4ae92ded1ba464 100644 ---- a/src/main/java/io/papermc/paper/ServerBuildInfo.java -+++ b/src/main/java/io/papermc/paper/ServerBuildInfo.java -@@ -19,6 +19,11 @@ public interface ServerBuildInfo { - */ - Key BRAND_PAPER_ID = Key.key("papermc", "paper"); - -+ /** -+ * The brand id for AdvancedSlimePaper. -+ */ -+ Key BRAND_ADVANCED_SLIME_PAPER_ID = Key.key("infernalsuite", "advancedslimepaper"); -+ - /** - * Gets the {@code ServerBuildInfo}. - * diff --git a/patches/api/0002-Dont-close-Slime-Plugin-Classloader.patch b/patches/api/0002-Dont-close-Slime-Plugin-Classloader.patch deleted file mode 100644 index cd8036f16..000000000 --- a/patches/api/0002-Dont-close-Slime-Plugin-Classloader.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> -Date: Sat, 28 Jan 2023 14:10:43 -0500 -Subject: [PATCH] Dont close Slime Plugin Classloader - - -diff --git a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java -index f9b57b872780aa6b9b959494874b57c7a8ff0c53..489a9dd31dd68325213110e5b2f144f7159b8d63 100644 ---- a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java -+++ b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java -@@ -265,7 +265,9 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm - // Paper end - super.close(); - } finally { -+ if (this.plugin == null || !this.plugin.getName().equals("SlimeWorldManager")) { // ASWM - Don't close - jar.close(); -+ } // ASWM - Don't close - } - } - From b2521db3141bc1855fd59406d0c50d303d798ae9 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 13 Mar 2025 14:06:18 +0100 Subject: [PATCH 089/133] feat: update paper --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index b866e639d..c69aa6ea1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ apiVersion=4.0.0-SNAPSHOT version=1.21.4-R0.1-SNAPSHOT mcVersion=1.21.4 -paperRef=1a7288aa05cfb0a168850a7cc879f55235fe5934 +paperRef=6ea42025a49f232f47861c6ca943b0fc66b7effe org.gradle.caching=true org.gradle.parallel=true From 458c6fe36cb068ec2cfc3dce5c949867eb7b0f31 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 13 Mar 2025 17:47:23 +0100 Subject: [PATCH 090/133] feat: separate loaders --- .../asp/api/loaders/UpdatableLoader.java | 28 +++++++++++++++++ loaders/api-loader/build.gradle.kts | 14 +++++++++ .../asp/loaders/api/APILoader.java | 0 .../asp/loaders/api/MapStructure.java | 0 loaders/build.gradle.kts | 10 ++++--- loaders/file-loader/build.gradle.kts | 14 +++++++++ .../asp/loaders/file/FileLoader.java | 0 loaders/mongo-loader/build.gradle.kts | 16 ++++++++++ .../asp/loaders/mongo/MongoLoader.java | 15 +++++++++- loaders/mysql-loader/build.gradle.kts | 16 ++++++++++ .../asp/loaders/mysql/MysqlLoader.java | 7 +++-- loaders/redis-loader/build.gradle.kts | 17 +++++++++++ .../asp/loaders/redis/RedisLoader.java | 3 +- .../loaders/redis/util/StringByteCodec.java | 0 .../asp/loaders/UpdatableLoader.java | 30 ------------------- .../asp/plugin/commands/CommandManager.java | 20 +++++++++++++ .../asp/plugin/loader/LoaderManager.java | 8 ++--- settings.gradle.kts | 11 +++++++ 18 files changed, 166 insertions(+), 43 deletions(-) create mode 100644 api/src/main/java/com/infernalsuite/asp/api/loaders/UpdatableLoader.java create mode 100644 loaders/api-loader/build.gradle.kts rename loaders/{ => api-loader}/src/main/java/com/infernalsuite/asp/loaders/api/APILoader.java (100%) rename loaders/{ => api-loader}/src/main/java/com/infernalsuite/asp/loaders/api/MapStructure.java (100%) create mode 100644 loaders/file-loader/build.gradle.kts rename loaders/{ => file-loader}/src/main/java/com/infernalsuite/asp/loaders/file/FileLoader.java (100%) create mode 100644 loaders/mongo-loader/build.gradle.kts rename loaders/{ => mongo-loader}/src/main/java/com/infernalsuite/asp/loaders/mongo/MongoLoader.java (95%) create mode 100644 loaders/mysql-loader/build.gradle.kts rename loaders/{ => mysql-loader}/src/main/java/com/infernalsuite/asp/loaders/mysql/MysqlLoader.java (97%) create mode 100644 loaders/redis-loader/build.gradle.kts rename loaders/{ => redis-loader}/src/main/java/com/infernalsuite/asp/loaders/redis/RedisLoader.java (95%) rename loaders/{ => redis-loader}/src/main/java/com/infernalsuite/asp/loaders/redis/util/StringByteCodec.java (100%) delete mode 100644 loaders/src/main/java/com/infernalsuite/asp/loaders/UpdatableLoader.java diff --git a/api/src/main/java/com/infernalsuite/asp/api/loaders/UpdatableLoader.java b/api/src/main/java/com/infernalsuite/asp/api/loaders/UpdatableLoader.java new file mode 100644 index 000000000..c84d42c6e --- /dev/null +++ b/api/src/main/java/com/infernalsuite/asp/api/loaders/UpdatableLoader.java @@ -0,0 +1,28 @@ +package com.infernalsuite.asp.api.loaders; + +import java.io.IOException; + +public abstract class UpdatableLoader implements SlimeLoader { + + public abstract void update() throws NewerStorageException, IOException; + + public class NewerStorageException extends Exception { + + private final int implementationVersion; + private final int storageVersion; + + + public NewerStorageException(int implementationVersion, int storageVersion) { + this.implementationVersion = implementationVersion; + this.storageVersion = storageVersion; + } + + public int getImplementationVersion() { + return implementationVersion; + } + + public int getStorageVersion() { + return storageVersion; + } + } +} diff --git a/loaders/api-loader/build.gradle.kts b/loaders/api-loader/build.gradle.kts new file mode 100644 index 000000000..d7f34aa1a --- /dev/null +++ b/loaders/api-loader/build.gradle.kts @@ -0,0 +1,14 @@ +plugins { + id("asp.base-conventions") + id("asp.publishing-conventions") +} + +dependencies { + compileOnly(project(":api")) + compileOnly(paperApi()) +} + +publishConfiguration { + name = "Advanced Slime Paper API loader" + description = "HTTP-API based loader for Advanced Slime Paper" +} diff --git a/loaders/src/main/java/com/infernalsuite/asp/loaders/api/APILoader.java b/loaders/api-loader/src/main/java/com/infernalsuite/asp/loaders/api/APILoader.java similarity index 100% rename from loaders/src/main/java/com/infernalsuite/asp/loaders/api/APILoader.java rename to loaders/api-loader/src/main/java/com/infernalsuite/asp/loaders/api/APILoader.java diff --git a/loaders/src/main/java/com/infernalsuite/asp/loaders/api/MapStructure.java b/loaders/api-loader/src/main/java/com/infernalsuite/asp/loaders/api/MapStructure.java similarity index 100% rename from loaders/src/main/java/com/infernalsuite/asp/loaders/api/MapStructure.java rename to loaders/api-loader/src/main/java/com/infernalsuite/asp/loaders/api/MapStructure.java diff --git a/loaders/build.gradle.kts b/loaders/build.gradle.kts index 134bd46f6..73dc43757 100644 --- a/loaders/build.gradle.kts +++ b/loaders/build.gradle.kts @@ -6,14 +6,16 @@ plugins { dependencies { compileOnly(project(":api")) - api(libs.hikari) - api(libs.mongo) - api(libs.lettuce) + api(project(":loaders:api-loader")) + api(project(":loaders:file-loader")) + api(project(":loaders:mongo-loader")) + api(project(":loaders:mysql-loader")) + api(project(":loaders:redis-loader")) compileOnly(paperApi()) } publishConfiguration { name = "Advanced Slime Paper Loaders" - description = "Default loaders for Advanced Slime Paper" + description = "Default loaders for Advanced Slime Paper. There might be more loaders available then included in this BOM package" } diff --git a/loaders/file-loader/build.gradle.kts b/loaders/file-loader/build.gradle.kts new file mode 100644 index 000000000..eabf68322 --- /dev/null +++ b/loaders/file-loader/build.gradle.kts @@ -0,0 +1,14 @@ +plugins { + id("asp.base-conventions") + id("asp.publishing-conventions") +} + +dependencies { + compileOnly(project(":api")) + compileOnly(paperApi()) +} + +publishConfiguration { + name = "Advanced Slime Paper File Loader" + description = "File loader for Advanced Slime Paper" +} diff --git a/loaders/src/main/java/com/infernalsuite/asp/loaders/file/FileLoader.java b/loaders/file-loader/src/main/java/com/infernalsuite/asp/loaders/file/FileLoader.java similarity index 100% rename from loaders/src/main/java/com/infernalsuite/asp/loaders/file/FileLoader.java rename to loaders/file-loader/src/main/java/com/infernalsuite/asp/loaders/file/FileLoader.java diff --git a/loaders/mongo-loader/build.gradle.kts b/loaders/mongo-loader/build.gradle.kts new file mode 100644 index 000000000..c3861aed2 --- /dev/null +++ b/loaders/mongo-loader/build.gradle.kts @@ -0,0 +1,16 @@ +plugins { + id("asp.base-conventions") + id("asp.publishing-conventions") +} + +dependencies { + compileOnly(project(":api")) + compileOnly(paperApi()) + + api(libs.mongo) +} + +publishConfiguration { + name = "Advanced Slime Paper MongoDB Loader" + description = "MongoDB GridFS Loader for Advanced Slime Paper" +} diff --git a/loaders/src/main/java/com/infernalsuite/asp/loaders/mongo/MongoLoader.java b/loaders/mongo-loader/src/main/java/com/infernalsuite/asp/loaders/mongo/MongoLoader.java similarity index 95% rename from loaders/src/main/java/com/infernalsuite/asp/loaders/mongo/MongoLoader.java rename to loaders/mongo-loader/src/main/java/com/infernalsuite/asp/loaders/mongo/MongoLoader.java index 0cb15e42c..533ffbdac 100644 --- a/loaders/src/main/java/com/infernalsuite/asp/loaders/mongo/MongoLoader.java +++ b/loaders/mongo-loader/src/main/java/com/infernalsuite/asp/loaders/mongo/MongoLoader.java @@ -1,6 +1,7 @@ package com.infernalsuite.asp.loaders.mongo; import com.infernalsuite.asp.api.exceptions.UnknownWorldException; +import com.infernalsuite.asp.api.loaders.UpdatableLoader; import com.mongodb.MongoException; import com.mongodb.MongoNamespace; import com.mongodb.client.*; @@ -20,7 +21,7 @@ import java.util.ArrayList; import java.util.List; -public class MongoLoader extends com.infernalsuite.asp.loaders.UpdatableLoader { +public class MongoLoader extends UpdatableLoader { private static final Logger LOGGER = LoggerFactory.getLogger(MongoLoader.class); @@ -39,6 +40,18 @@ public MongoLoader(String database, String collection, @Nullable String username this.client = MongoClients.create(parsedUri); + init(); + } + + public MongoLoader(MongoClient client, String database, String collection) { + this.database = database; + this.collection = collection; + this.client = client; + + init(); + } + + private void init() { MongoDatabase mongoDatabase = client.getDatabase(database); MongoCollection mongoCollection = mongoDatabase.getCollection(collection); diff --git a/loaders/mysql-loader/build.gradle.kts b/loaders/mysql-loader/build.gradle.kts new file mode 100644 index 000000000..03df1323d --- /dev/null +++ b/loaders/mysql-loader/build.gradle.kts @@ -0,0 +1,16 @@ +plugins { + id("asp.base-conventions") + id("asp.publishing-conventions") +} + +dependencies { + compileOnly(project(":api")) + + api(libs.hikari) + compileOnly(paperApi()) +} + +publishConfiguration { + name = "Advanced Slime Paper MySQL Loader" + description = "MySQL loader for Advanced Slime Paper" +} diff --git a/loaders/src/main/java/com/infernalsuite/asp/loaders/mysql/MysqlLoader.java b/loaders/mysql-loader/src/main/java/com/infernalsuite/asp/loaders/mysql/MysqlLoader.java similarity index 97% rename from loaders/src/main/java/com/infernalsuite/asp/loaders/mysql/MysqlLoader.java rename to loaders/mysql-loader/src/main/java/com/infernalsuite/asp/loaders/mysql/MysqlLoader.java index 756ab7605..adf9383ba 100644 --- a/loaders/src/main/java/com/infernalsuite/asp/loaders/mysql/MysqlLoader.java +++ b/loaders/mysql-loader/src/main/java/com/infernalsuite/asp/loaders/mysql/MysqlLoader.java @@ -1,6 +1,7 @@ package com.infernalsuite.asp.loaders.mysql; import com.infernalsuite.asp.api.exceptions.UnknownWorldException; +import com.infernalsuite.asp.api.loaders.UpdatableLoader; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import org.slf4j.Logger; @@ -14,7 +15,7 @@ import java.util.ArrayList; import java.util.List; -public class MysqlLoader extends com.infernalsuite.asp.loaders.UpdatableLoader { +public class MysqlLoader extends UpdatableLoader { private static final Logger LOGGER = LoggerFactory.getLogger(MysqlLoader.class); @@ -79,7 +80,7 @@ public MysqlLoader(String sqlURL, String host, int port, String database, boolea } @Override - public void update() throws IOException, NewerDatabaseException { + public void update() throws IOException, NewerStorageException { try (Connection con = source.getConnection()) { int version; @@ -89,7 +90,7 @@ public void update() throws IOException, NewerDatabaseException { } if (version > CURRENT_DB_VERSION) { - throw new NewerDatabaseException(CURRENT_DB_VERSION, version); + throw new NewerStorageException(CURRENT_DB_VERSION, version); } if (version < CURRENT_DB_VERSION) { diff --git a/loaders/redis-loader/build.gradle.kts b/loaders/redis-loader/build.gradle.kts new file mode 100644 index 000000000..b41810de0 --- /dev/null +++ b/loaders/redis-loader/build.gradle.kts @@ -0,0 +1,17 @@ +plugins { + id("asp.base-conventions") + id("asp.publishing-conventions") +} + +dependencies { + compileOnly(project(":api")) + + api(libs.lettuce) + + compileOnly(paperApi()) +} + +publishConfiguration { + name = "Advanced Slime Paper Redis Loader" + description = "Redis loader for Advanced Slime Paper" +} diff --git a/loaders/src/main/java/com/infernalsuite/asp/loaders/redis/RedisLoader.java b/loaders/redis-loader/src/main/java/com/infernalsuite/asp/loaders/redis/RedisLoader.java similarity index 95% rename from loaders/src/main/java/com/infernalsuite/asp/loaders/redis/RedisLoader.java rename to loaders/redis-loader/src/main/java/com/infernalsuite/asp/loaders/redis/RedisLoader.java index e4b873147..b4f6c0d98 100644 --- a/loaders/src/main/java/com/infernalsuite/asp/loaders/redis/RedisLoader.java +++ b/loaders/redis-loader/src/main/java/com/infernalsuite/asp/loaders/redis/RedisLoader.java @@ -4,6 +4,7 @@ import com.infernalsuite.asp.api.loaders.SlimeLoader; import io.lettuce.core.RedisClient; import io.lettuce.core.api.sync.RedisCommands; +import com.infernalsuite.asp.loaders.redis.util.StringByteCodec; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -20,7 +21,7 @@ public class RedisLoader implements SlimeLoader { public RedisLoader(String uri) { this.connection = RedisClient .create(uri) - .connect(com.infernalsuite.asp.loaders.redis.util.StringByteCodec.INSTANCE) + .connect(StringByteCodec.INSTANCE) .sync(); } diff --git a/loaders/src/main/java/com/infernalsuite/asp/loaders/redis/util/StringByteCodec.java b/loaders/redis-loader/src/main/java/com/infernalsuite/asp/loaders/redis/util/StringByteCodec.java similarity index 100% rename from loaders/src/main/java/com/infernalsuite/asp/loaders/redis/util/StringByteCodec.java rename to loaders/redis-loader/src/main/java/com/infernalsuite/asp/loaders/redis/util/StringByteCodec.java diff --git a/loaders/src/main/java/com/infernalsuite/asp/loaders/UpdatableLoader.java b/loaders/src/main/java/com/infernalsuite/asp/loaders/UpdatableLoader.java deleted file mode 100644 index ca0415efa..000000000 --- a/loaders/src/main/java/com/infernalsuite/asp/loaders/UpdatableLoader.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.infernalsuite.asp.loaders; - -import com.infernalsuite.asp.api.loaders.SlimeLoader; - -import java.io.IOException; - -public abstract class UpdatableLoader implements SlimeLoader { - - public abstract void update() throws NewerDatabaseException, IOException; - - public class NewerDatabaseException extends Exception { - - private final int currentVersion; - private final int databaseVersion; - - - public NewerDatabaseException(int currentVersion, int databaseVersion) { - this.currentVersion = currentVersion; - this.databaseVersion = databaseVersion; - } - - public int getCurrentVersion() { - return currentVersion; - } - - public int getDatabaseVersion() { - return databaseVersion; - } - } -} diff --git a/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/CommandManager.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/CommandManager.java index 6f7c85aab..5e8ab1f56 100644 --- a/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/CommandManager.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/CommandManager.java @@ -1,11 +1,20 @@ package com.infernalsuite.asp.plugin.commands; +import com.infernalsuite.asp.api.AdvancedSlimePaperAPI; +import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; +import com.infernalsuite.asp.api.exceptions.NewerFormatException; +import com.infernalsuite.asp.api.exceptions.UnknownWorldException; +import com.infernalsuite.asp.api.world.SlimeChunk; import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.plugin.SWPlugin; import com.infernalsuite.asp.plugin.commands.parser.*; import com.infernalsuite.asp.plugin.commands.sub.*; import io.leangen.geantyref.TypeToken; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.Bukkit; +import org.bukkit.Chunk; import org.bukkit.World; import org.bukkit.command.CommandSender; import org.incendo.cloud.annotations.AnnotationParser; @@ -22,11 +31,16 @@ import org.incendo.cloud.paper.LegacyPaperCommandManager; import org.incendo.cloud.paper.PaperCommandManager; import org.incendo.cloud.parser.ParserRegistry; +import org.incendo.cloud.parser.standard.IntegerParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import static org.incendo.cloud.parser.standard.StringParser.greedyStringParser; @@ -52,6 +66,12 @@ public CommandManager(com.infernalsuite.asp.plugin.SWPlugin plugin) { LOGGER.warn("Brigadier is not supported on this server version."); // This should never happen since we use ASP, but just in case } + commandManager.command(commandManager.commandBuilder("test").required("count", IntegerParser.integerParser()).handler(commandContext -> { + int count = commandContext.get("count"); + + + })); + ParserRegistry parserRegistry = commandManager.parserRegistry(); parserRegistry.registerSuggestionProvider("known-slime-worlds", new com.infernalsuite.asp.plugin.commands.parser.suggestion.KnownSlimeWorldSuggestionProvider()); diff --git a/plugin/src/main/java/com/infernalsuite/asp/plugin/loader/LoaderManager.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/loader/LoaderManager.java index 7d73e01a2..ccf09ad7e 100644 --- a/plugin/src/main/java/com/infernalsuite/asp/plugin/loader/LoaderManager.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/loader/LoaderManager.java @@ -1,7 +1,7 @@ package com.infernalsuite.asp.plugin.loader; import com.infernalsuite.asp.api.loaders.SlimeLoader; -import com.infernalsuite.asp.loaders.UpdatableLoader; +import com.infernalsuite.asp.api.loaders.UpdatableLoader; import com.infernalsuite.asp.loaders.api.APILoader; import com.infernalsuite.asp.loaders.file.FileLoader; import com.infernalsuite.asp.loaders.mongo.MongoLoader; @@ -94,9 +94,9 @@ public void registerLoader(String dataSource, SlimeLoader loader) { if (loader instanceof UpdatableLoader) { try { ((UpdatableLoader) loader).update(); - } catch (final UpdatableLoader.NewerDatabaseException e) { - LOGGER.error("Data source {} version is {}, while this SWM version only supports up to version {}.", - dataSource, e.getDatabaseVersion(), e.getCurrentVersion(), e); + } catch (final UpdatableLoader.NewerStorageException e) { + LOGGER.error("Data source {} version is {}, while this loader version only supports up to version {}.", + dataSource, e.getStorageVersion(), e.getImplementationVersion(), e); return; } catch (final IOException ex) { LOGGER.error("Failed to update data source {}", dataSource, ex); diff --git a/settings.gradle.kts b/settings.gradle.kts index 83bfa1433..102077497 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -24,3 +24,14 @@ include(":impl:aspaper-api") include(":impl:aspaper-server") //include(":aspaper-api") //include(":aspaper-server") + +include("loaders:mongo-loader") +findProject(":loaders:mongo-loader")?.name = "mongo-loader" +include("loaders:api-loader") +findProject(":loaders:api-loader")?.name = "api-loader" +include("loaders:file-loader") +findProject(":loaders:file-loader")?.name = "file-loader" +include("loaders:mysql-loader") +findProject(":loaders:mysql-loader")?.name = "mysql-loader" +include("loaders:redis-loader") +findProject(":loaders:redis-loader")?.name = "redis-loader" From 543d8bfea53fd06fe9feb7d856d0d6d19c2ba307 Mon Sep 17 00:00:00 2001 From: David Date: Fri, 14 Mar 2025 10:49:40 +0100 Subject: [PATCH 091/133] chore: remove unused events and unsed exceptions --- .../AsyncPostCreateEmptyWorldEvent.java | 31 -------- .../api/events/AsyncPostGetWorldEvent.java | 31 -------- .../api/events/AsyncPostImportWorldEvent.java | 45 ----------- .../api/events/AsyncPostLoadWorldEvent.java | 31 -------- .../events/AsyncPostMigrateWorldEvent.java | 44 ----------- .../events/AsyncPreCreateEmptyWorldEvent.java | 78 ------------------- .../asp/api/events/AsyncPreGetWorldEvent.java | 47 ----------- .../api/events/AsyncPreImportWorldEvent.java | 69 ---------------- .../api/events/AsyncPreLoadWorldEvent.java | 78 ------------------- .../asp/api/events/PreGenerateWorldEvent.java | 47 ----------- .../exceptions/InvalidVersionException.java | 12 --- .../asp/api/loaders/UpdatableLoader.java | 2 +- 12 files changed, 1 insertion(+), 514 deletions(-) delete mode 100644 api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostCreateEmptyWorldEvent.java delete mode 100644 api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostGetWorldEvent.java delete mode 100644 api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostImportWorldEvent.java delete mode 100644 api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostLoadWorldEvent.java delete mode 100644 api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostMigrateWorldEvent.java delete mode 100644 api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreCreateEmptyWorldEvent.java delete mode 100644 api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreGetWorldEvent.java delete mode 100644 api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreImportWorldEvent.java delete mode 100644 api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreLoadWorldEvent.java delete mode 100644 api/src/main/java/com/infernalsuite/asp/api/events/PreGenerateWorldEvent.java delete mode 100644 api/src/main/java/com/infernalsuite/asp/api/exceptions/InvalidVersionException.java diff --git a/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostCreateEmptyWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostCreateEmptyWorldEvent.java deleted file mode 100644 index ebf10f1dd..000000000 --- a/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostCreateEmptyWorldEvent.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.infernalsuite.asp.api.events; - -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; -import org.jetbrains.annotations.NotNull; - -import java.util.Objects; - -public class AsyncPostCreateEmptyWorldEvent extends Event { - - private static final HandlerList handlers = new HandlerList(); - private final com.infernalsuite.asp.api.world.SlimeWorld slimeWorld; - - public AsyncPostCreateEmptyWorldEvent(com.infernalsuite.asp.api.world.SlimeWorld slimeWorld) { - super(true); - this.slimeWorld = Objects.requireNonNull(slimeWorld, "slimeWorld cannot be null"); - } - - public static HandlerList getHandlerList() { - return handlers; - } - - @Override - public @NotNull HandlerList getHandlers() { - return handlers; - } - - public com.infernalsuite.asp.api.world.SlimeWorld getSlimeWorld() { - return slimeWorld; - } -} diff --git a/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostGetWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostGetWorldEvent.java deleted file mode 100644 index 69bbbea5d..000000000 --- a/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostGetWorldEvent.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.infernalsuite.asp.api.events; - -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; -import org.jetbrains.annotations.NotNull; - -import java.util.Objects; - -public class AsyncPostGetWorldEvent extends Event { - - private static final HandlerList handlers = new HandlerList(); - private final com.infernalsuite.asp.api.world.SlimeWorld slimeWorld; - - public AsyncPostGetWorldEvent(com.infernalsuite.asp.api.world.SlimeWorld slimeWorld) { - super(true); - this.slimeWorld = Objects.requireNonNull(slimeWorld, "slimeWorld cannot be null"); - } - - public static HandlerList getHandlerList() { - return handlers; - } - - @Override - public @NotNull HandlerList getHandlers() { - return handlers; - } - - public com.infernalsuite.asp.api.world.SlimeWorld getSlimeWorld() { - return slimeWorld; - } -} diff --git a/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostImportWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostImportWorldEvent.java deleted file mode 100644 index 3bf078393..000000000 --- a/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostImportWorldEvent.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.infernalsuite.asp.api.events; - -import com.infernalsuite.asp.api.loaders.SlimeLoader; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.util.Objects; - -public class AsyncPostImportWorldEvent extends Event { - - private static final HandlerList handlers = new HandlerList(); - private final File worldDir; - private final String worldName; - private final SlimeLoader slimeLoader; - - public AsyncPostImportWorldEvent(File worldDir, String worldName, SlimeLoader slimeLoader) { - super(true); - this.worldDir = Objects.requireNonNull(worldDir, "worldDir cannot be null"); - this.worldName = Objects.requireNonNull(worldName, "worldName cannot be null"); - this.slimeLoader = Objects.requireNonNull(slimeLoader, "slimeLoader cannot be null"); - } - - public static HandlerList getHandlerList() { - return handlers; - } - - @Override - public @NotNull HandlerList getHandlers() { - return handlers; - } - - public File getWorldDir() { - return this.worldDir; - } - - public String getWorldName() { - return this.worldName; - } - - public SlimeLoader getSlimeLoader() { - return this.slimeLoader; - } -} diff --git a/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostLoadWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostLoadWorldEvent.java deleted file mode 100644 index ae9e2eb3d..000000000 --- a/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostLoadWorldEvent.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.infernalsuite.asp.api.events; - -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; -import org.jetbrains.annotations.NotNull; - -import java.util.Objects; - -public class AsyncPostLoadWorldEvent extends Event { - - private static final HandlerList handlers = new HandlerList(); - private final com.infernalsuite.asp.api.world.SlimeWorld slimeWorld; - - public AsyncPostLoadWorldEvent(com.infernalsuite.asp.api.world.SlimeWorld slimeWorld) { - super(true); - this.slimeWorld = Objects.requireNonNull(slimeWorld, "slimeWorld cannot be null"); - } - - public static HandlerList getHandlerList() { - return handlers; - } - - @Override - public @NotNull HandlerList getHandlers() { - return handlers; - } - - public com.infernalsuite.asp.api.world.SlimeWorld getSlimeWorld() { - return this.slimeWorld; - } -} diff --git a/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostMigrateWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostMigrateWorldEvent.java deleted file mode 100644 index be1e257a6..000000000 --- a/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPostMigrateWorldEvent.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.infernalsuite.asp.api.events; - -import com.infernalsuite.asp.api.loaders.SlimeLoader; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; -import org.jetbrains.annotations.NotNull; - -import java.util.Objects; - -public class AsyncPostMigrateWorldEvent extends Event { - - private static final HandlerList handlers = new HandlerList(); - private final String worldName; - private final SlimeLoader currentLoader; - private final SlimeLoader newLoader; - - public AsyncPostMigrateWorldEvent(String worldName, SlimeLoader currentLoader, SlimeLoader newLoader) { - super(true); - this.worldName = Objects.requireNonNull(worldName, "worldName cannot be null"); - this.currentLoader = Objects.requireNonNull(currentLoader, "currentLoader cannot be null"); - this.newLoader = Objects.requireNonNull(newLoader, "newLoader cannot be null"); - } - - public static HandlerList getHandlerList() { - return handlers; - } - - @Override - public @NotNull HandlerList getHandlers() { - return handlers; - } - - public String getWorldName() { - return this.worldName; - } - - public SlimeLoader getCurrentLoader() { - return this.currentLoader; - } - - public SlimeLoader getNewLoader() { - return this.newLoader; - } -} diff --git a/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreCreateEmptyWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreCreateEmptyWorldEvent.java deleted file mode 100644 index a7468fff6..000000000 --- a/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreCreateEmptyWorldEvent.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.infernalsuite.asp.api.events; - -import com.infernalsuite.asp.api.loaders.SlimeLoader; -import org.bukkit.event.Cancellable; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; -import org.jetbrains.annotations.NotNull; - -import java.util.Objects; - -public class AsyncPreCreateEmptyWorldEvent extends Event implements Cancellable { - - private static final HandlerList handlers = new HandlerList(); - private boolean isCancelled; - private SlimeLoader slimeLoader; - private String worldName; - private boolean readOnly; - private com.infernalsuite.asp.api.world.properties.SlimePropertyMap slimePropertyMap; - - public AsyncPreCreateEmptyWorldEvent(SlimeLoader slimeLoader, String worldName, boolean readOnly, com.infernalsuite.asp.api.world.properties.SlimePropertyMap slimePropertyMap) { - super(true); - this.slimeLoader = Objects.requireNonNull(slimeLoader, "slimeLoader cannot be null"); - this.worldName = Objects.requireNonNull(worldName, "worldName cannot be null"); - this.readOnly = readOnly; - this.slimePropertyMap = Objects.requireNonNull(slimePropertyMap, "slimePropertyMap cannot be null"); - } - - public static HandlerList getHandlerList() { - return handlers; - } - - @Override - public @NotNull HandlerList getHandlers() { - return handlers; - } - - @Override - public boolean isCancelled() { - return this.isCancelled; - } - - @Override - public void setCancelled(boolean cancelled) { - this.isCancelled = cancelled; - } - - public SlimeLoader getSlimeLoader() { - return this.slimeLoader; - } - - public void setSlimeLoader(SlimeLoader slimeLoader) { - this.slimeLoader = Objects.requireNonNull(slimeLoader, "slimeLoader cannot be null"); - } - - public String getWorldName() { - return this.worldName; - } - - public void setWorldName(String worldName) { - this.worldName = Objects.requireNonNull(worldName, "worldName cannot be null"); - } - - public boolean isReadOnly() { - return this.readOnly; - } - - public void setReadOnly(boolean readOnly) { - this.readOnly = readOnly; - } - - public com.infernalsuite.asp.api.world.properties.SlimePropertyMap getSlimePropertyMap() { - return this.slimePropertyMap; - } - - public void setSlimePropertyMap(com.infernalsuite.asp.api.world.properties.SlimePropertyMap slimePropertyMap) { - this.slimePropertyMap = Objects.requireNonNull(slimePropertyMap, "slimePropertyMap cannot be null"); - } -} diff --git a/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreGetWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreGetWorldEvent.java deleted file mode 100644 index 6d6fc28c7..000000000 --- a/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreGetWorldEvent.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.infernalsuite.asp.api.events; - -import org.bukkit.event.Cancellable; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; -import org.jetbrains.annotations.NotNull; - -import java.util.Objects; - -public class AsyncPreGetWorldEvent extends Event implements Cancellable { - - private static final HandlerList handlers = new HandlerList(); - private boolean isCancelled; - private String worldName; - - public AsyncPreGetWorldEvent(String worldName) { - super(true); - this.worldName = Objects.requireNonNull(worldName, "worldName cannot be null"); - } - - public static HandlerList getHandlerList() { - return handlers; - } - - @Override - public @NotNull HandlerList getHandlers() { - return handlers; - } - - @Override - public boolean isCancelled() { - return this.isCancelled; - } - - @Override - public void setCancelled(boolean cancelled) { - this.isCancelled = cancelled; - } - - public String getWorldName() { - return this.worldName; - } - - public void setWorldName(String worldName) { - this.worldName = Objects.requireNonNull(worldName, "worldName cannot be null"); - } -} diff --git a/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreImportWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreImportWorldEvent.java deleted file mode 100644 index ec4eb6a61..000000000 --- a/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreImportWorldEvent.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.infernalsuite.asp.api.events; - -import com.infernalsuite.asp.api.loaders.SlimeLoader; -import org.bukkit.event.Cancellable; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.util.Objects; - -public class AsyncPreImportWorldEvent extends Event implements Cancellable { - - private static final HandlerList handlers = new HandlerList(); - private boolean isCancelled; - private File worldDir; - private String worldName; - private SlimeLoader slimeLoader; - - public AsyncPreImportWorldEvent(File worldDir, String worldName, SlimeLoader slimeLoader) { - super(true); - this.worldDir = Objects.requireNonNull(worldDir, "worldDir cannot be null"); - this.worldName = Objects.requireNonNull(worldName, "worldName cannot be null"); - this.slimeLoader = Objects.requireNonNull(slimeLoader, "slimeLoader cannot be null"); - } - - public static HandlerList getHandlerList() { - return handlers; - } - - @Override - public @NotNull HandlerList getHandlers() { - return handlers; - } - - @Override - public boolean isCancelled() { - return this.isCancelled; - } - - @Override - public void setCancelled(boolean cancelled) { - this.isCancelled = cancelled; - } - - public File getWorldDir() { - return this.worldDir; - } - - public void setWorldDir(File worldDir) { - this.worldDir = Objects.requireNonNull(worldDir, "worldDir cannot be null"); - } - - public String getWorldName() { - return this.worldName; - } - - public void setWorldName(String worldName) { - this.worldName = Objects.requireNonNull(worldName, "worldName cannot be null"); - } - - public SlimeLoader getSlimeLoader() { - return this.slimeLoader; - } - - public void setSlimeLoader(SlimeLoader slimeLoader) { - this.slimeLoader = Objects.requireNonNull(slimeLoader, "slimeLoader cannot be null"); - } -} diff --git a/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreLoadWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreLoadWorldEvent.java deleted file mode 100644 index c241e3a94..000000000 --- a/api/src/main/java/com/infernalsuite/asp/api/events/AsyncPreLoadWorldEvent.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.infernalsuite.asp.api.events; - -import com.infernalsuite.asp.api.loaders.SlimeLoader; -import org.bukkit.event.Cancellable; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; -import org.jetbrains.annotations.NotNull; - -import java.util.Objects; - -public class AsyncPreLoadWorldEvent extends Event implements Cancellable { - - private static final HandlerList handlers = new HandlerList(); - private boolean isCancelled; - private SlimeLoader slimeLoader; - private String worldName; - private boolean readOnly; - private com.infernalsuite.asp.api.world.properties.SlimePropertyMap slimePropertyMap; - - public AsyncPreLoadWorldEvent(SlimeLoader slimeLoader, String worldName, boolean readOnly, com.infernalsuite.asp.api.world.properties.SlimePropertyMap slimePropertyMap) { - super(true); - this.slimeLoader = Objects.requireNonNull(slimeLoader, "slimeLoader cannot be null"); - this.worldName = Objects.requireNonNull(worldName, "worldName cannot be null"); - this.readOnly = readOnly; - this.slimePropertyMap = Objects.requireNonNull(slimePropertyMap, "slimePropertyMap cannot be null"); - } - - public static HandlerList getHandlerList() { - return handlers; - } - - @Override - public @NotNull HandlerList getHandlers() { - return handlers; - } - - @Override - public boolean isCancelled() { - return this.isCancelled; - } - - @Override - public void setCancelled(boolean cancelled) { - this.isCancelled = cancelled; - } - - public SlimeLoader getSlimeLoader() { - return this.slimeLoader; - } - - public void setSlimeLoader(SlimeLoader slimeLoader) { - this.slimeLoader = Objects.requireNonNull(slimeLoader, "Loader cannot be null"); - } - - public String getWorldName() { - return this.worldName; - } - - public void setWorldName(String worldName) { - this.worldName = Objects.requireNonNull(worldName, "worldName cannot be null"); - } - - public boolean isReadOnly() { - return this.readOnly; - } - - public void setReadOnly(boolean readOnly) { - this.readOnly = readOnly; - } - - public com.infernalsuite.asp.api.world.properties.SlimePropertyMap getSlimePropertyMap() { - return this.slimePropertyMap; - } - - public void setSlimePropertyMap(com.infernalsuite.asp.api.world.properties.SlimePropertyMap slimePropertyMap) { - this.slimePropertyMap = Objects.requireNonNull(slimePropertyMap, "slimePropertyMap cannot be null"); - } -} diff --git a/api/src/main/java/com/infernalsuite/asp/api/events/PreGenerateWorldEvent.java b/api/src/main/java/com/infernalsuite/asp/api/events/PreGenerateWorldEvent.java deleted file mode 100644 index 739a88906..000000000 --- a/api/src/main/java/com/infernalsuite/asp/api/events/PreGenerateWorldEvent.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.infernalsuite.asp.api.events; - -import org.bukkit.event.Cancellable; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; -import org.jetbrains.annotations.NotNull; - -import java.util.Objects; - -public class PreGenerateWorldEvent extends Event implements Cancellable { - - private static final HandlerList handlers = new HandlerList(); - private boolean isCancelled; - private com.infernalsuite.asp.api.world.SlimeWorld slimeWorld; - - public PreGenerateWorldEvent(com.infernalsuite.asp.api.world.SlimeWorld slimeWorld) { - super(false); - this.slimeWorld = Objects.requireNonNull(slimeWorld, "slimeWorld cannot be null"); - } - - public static HandlerList getHandlerList() { - return handlers; - } - - @Override - public @NotNull HandlerList getHandlers() { - return handlers; - } - - @Override - public boolean isCancelled() { - return this.isCancelled; - } - - @Override - public void setCancelled(boolean cancelled) { - this.isCancelled = cancelled; - } - - public com.infernalsuite.asp.api.world.SlimeWorld getSlimeWorld() { - return this.slimeWorld; - } - - public void setSlimeWorld(com.infernalsuite.asp.api.world.SlimeWorld slimeWorld) { - this.slimeWorld = Objects.requireNonNull(slimeWorld, "slimeWorld cannot be null"); - } -} diff --git a/api/src/main/java/com/infernalsuite/asp/api/exceptions/InvalidVersionException.java b/api/src/main/java/com/infernalsuite/asp/api/exceptions/InvalidVersionException.java deleted file mode 100644 index c02c46e0f..000000000 --- a/api/src/main/java/com/infernalsuite/asp/api/exceptions/InvalidVersionException.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.infernalsuite.asp.api.exceptions; - -/** - * Exception thrown when SWM is loaded - * on a non-supported Spigot version. - */ -public class InvalidVersionException extends SlimeException { - - public InvalidVersionException(String version) { - super("SlimeWorldManager does not support Spigot " + version + "!"); - } -} diff --git a/api/src/main/java/com/infernalsuite/asp/api/loaders/UpdatableLoader.java b/api/src/main/java/com/infernalsuite/asp/api/loaders/UpdatableLoader.java index c84d42c6e..772769b38 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/loaders/UpdatableLoader.java +++ b/api/src/main/java/com/infernalsuite/asp/api/loaders/UpdatableLoader.java @@ -6,7 +6,7 @@ public abstract class UpdatableLoader implements SlimeLoader { public abstract void update() throws NewerStorageException, IOException; - public class NewerStorageException extends Exception { + public static class NewerStorageException extends Exception { private final int implementationVersion; private final int storageVersion; From ad95161563a9a68a73edcaf9a027021eebc0926d Mon Sep 17 00:00:00 2001 From: David Date: Fri, 14 Mar 2025 12:39:01 +0100 Subject: [PATCH 092/133] chore: remove debug "test" command --- .../infernalsuite/asp/api/world/SlimeWorldInstance.java | 8 ++++++-- .../asp/plugin/commands/CommandManager.java | 9 ++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java index 08fe615ab..b4401c9f0 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java @@ -13,7 +13,11 @@ */ public interface SlimeWorldInstance extends SlimeWorld { - @NotNull - World getBukkitWorld(); + /** + * Returns the bukkit instance of the loaded world. + * + * @return The bukkit world. + */ + @NotNull World getBukkitWorld(); } diff --git a/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/CommandManager.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/CommandManager.java index 5e8ab1f56..ecae9f757 100644 --- a/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/CommandManager.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/CommandManager.java @@ -66,12 +66,6 @@ public CommandManager(com.infernalsuite.asp.plugin.SWPlugin plugin) { LOGGER.warn("Brigadier is not supported on this server version."); // This should never happen since we use ASP, but just in case } - commandManager.command(commandManager.commandBuilder("test").required("count", IntegerParser.integerParser()).handler(commandContext -> { - int count = commandContext.get("count"); - - - })); - ParserRegistry parserRegistry = commandManager.parserRegistry(); parserRegistry.registerSuggestionProvider("known-slime-worlds", new com.infernalsuite.asp.plugin.commands.parser.suggestion.KnownSlimeWorldSuggestionProvider()); @@ -140,7 +134,8 @@ public CommandManager(com.infernalsuite.asp.plugin.SWPlugin plugin) { new com.infernalsuite.asp.plugin.commands.sub.UnloadWorldCmd(this), new com.infernalsuite.asp.plugin.commands.sub.VersionCmd(this), new com.infernalsuite.asp.plugin.commands.sub.WorldListCmd(this), - new com.infernalsuite.asp.plugin.commands.sub.HelpCmd(this, commandManager) + new com.infernalsuite.asp.plugin.commands.sub.HelpCmd(this, commandManager), + new TestCommand(this) ); } From 58f217a9ae5e33b35007b871d846eca22e754842 Mon Sep 17 00:00:00 2001 From: David Date: Fri, 14 Mar 2025 15:29:35 +0100 Subject: [PATCH 093/133] fix: remove test command reference --- .../com/infernalsuite/asp/plugin/commands/CommandManager.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/CommandManager.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/CommandManager.java index ecae9f757..78a64f8dd 100644 --- a/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/CommandManager.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/CommandManager.java @@ -134,8 +134,7 @@ public CommandManager(com.infernalsuite.asp.plugin.SWPlugin plugin) { new com.infernalsuite.asp.plugin.commands.sub.UnloadWorldCmd(this), new com.infernalsuite.asp.plugin.commands.sub.VersionCmd(this), new com.infernalsuite.asp.plugin.commands.sub.WorldListCmd(this), - new com.infernalsuite.asp.plugin.commands.sub.HelpCmd(this, commandManager), - new TestCommand(this) + new com.infernalsuite.asp.plugin.commands.sub.HelpCmd(this, commandManager) ); } From 25168e5c071c88ee21e8dee6f3b828ee788b773e Mon Sep 17 00:00:00 2001 From: David Date: Fri, 14 Mar 2025 15:29:43 +0100 Subject: [PATCH 094/133] chore: comments --- .../main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java | 2 -- .../infernalsuite/asp/level/ReadOnlyDimensionDataStorage.java | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java index 071b6bd3f..241afa94a 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -109,8 +109,6 @@ public SlimeChunkSection[] getSections() { // Sky light Nibble Array NibbleArray skyLightArray = Converter.convertArray(lightEngine.getLayerListener(LightLayer.SKY).getDataLayerData(SectionPos.of(chunk.getPos(), sectionId))); - // Tile/Entity Data - // Block Data CompoundBinaryTag blockStateTag; if (section.hasOnlyAir()) { diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ReadOnlyDimensionDataStorage.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ReadOnlyDimensionDataStorage.java index dc0026fa8..f58a673d0 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ReadOnlyDimensionDataStorage.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ReadOnlyDimensionDataStorage.java @@ -11,6 +11,9 @@ import java.util.Optional; import java.util.concurrent.CompletableFuture; +/* + * This dimension data storage does not serialize and/or load from disk. + */ public class ReadOnlyDimensionDataStorage extends DimensionDataStorage { public ReadOnlyDimensionDataStorage(Path dataFolder, DataFixer fixerUpper, HolderLookup.Provider registries) { From 330e8c20c8ef6783fcda7190512bb23a4b4b16f7 Mon Sep 17 00:00:00 2001 From: David Date: Fri, 14 Mar 2025 17:09:07 +0100 Subject: [PATCH 095/133] feat: re-add importer module --- importer/build.gradle.kts | 2 +- settings.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/importer/build.gradle.kts b/importer/build.gradle.kts index f55f9d48a..1033f415b 100644 --- a/importer/build.gradle.kts +++ b/importer/build.gradle.kts @@ -6,7 +6,7 @@ plugins { dependencies { implementation(project(":api")) implementation(project(":core")) - implementation(project(":aspaper-api")) + implementation(project(":impl:aspaper-api")) } tasks { diff --git a/settings.gradle.kts b/settings.gradle.kts index 102077497..e71b880c3 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -16,7 +16,7 @@ rootProject.name = "ASPaper" include(":gradle:platform") include(":api") include(":core") -//include(":importer") +include(":importer") include(":loaders") include(":plugin") include(":impl") From 927905c3071e24752694d4ffe2f1bc4e19fec29f Mon Sep 17 00:00:00 2001 From: David Date: Fri, 14 Mar 2025 17:17:19 +0100 Subject: [PATCH 096/133] fix: make importer work --- importer/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/importer/build.gradle.kts b/importer/build.gradle.kts index 1033f415b..e3d18c1ab 100644 --- a/importer/build.gradle.kts +++ b/importer/build.gradle.kts @@ -12,7 +12,7 @@ dependencies { tasks { jar { manifest { - attributes["Main-Class"] = "com.infernalsuite.asp.importer.ASPImporter" + attributes["Main-Class"] = "com.infernalsuite.asp.importer.SWMImporter" } } shadowJar { From f7b05eac2c06b576a0a0fd31ca92ea989ffaf9d9 Mon Sep 17 00:00:00 2001 From: David Date: Fri, 14 Mar 2025 18:02:44 +0100 Subject: [PATCH 097/133] fix: default biomes. Closes #85 --- .../java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java index 3dbc72394..bc32ced3d 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -86,6 +86,10 @@ public LevelChunk promote(int x, int z, SlimeChunk chunk) { levelChunk = new SlimeChunkLevel(this.instance, pos, UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks, 0L, null, null, null); + //Make SlimeProperties.DEFAULT_BIOME work + levelChunk.fillBiomesFromNoise(instance.chunkSource.getGenerator().getBiomeSource(), + instance.chunkSource.randomState().sampler()); + chunk = new NMSSlimeChunk(levelChunk, getChunk(x, z)); } else { levelChunk = SlimeChunkConverter.deserializeSlimeChunk(this.instance, chunk); From b1f04a964440870e2b9d2c96202666a943319792 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Fri, 14 Mar 2025 21:23:14 +0100 Subject: [PATCH 098/133] feat: make assemble run shadowJar in importer --- importer/build.gradle.kts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/importer/build.gradle.kts b/importer/build.gradle.kts index e3d18c1ab..4adf78e7a 100644 --- a/importer/build.gradle.kts +++ b/importer/build.gradle.kts @@ -18,6 +18,9 @@ tasks { shadowJar { minimize() } + assemble { + dependsOn(shadowJar) + } } description = "asp-importer" From f690973ecf78bead8e6dcb9781174ce9bfee78cb Mon Sep 17 00:00:00 2001 From: David Mayr Date: Fri, 14 Mar 2025 22:20:13 +0100 Subject: [PATCH 099/133] fix: poi warnings (Closes #136) Signed-off-by: David Mayr --- .../scheduling/task/ChunkLoadTask.java.patch | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch index fa9f836fb..03353e87b 100644 --- a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch +++ b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch @@ -20,16 +20,16 @@ - }); + // ASWM start + if (world instanceof com.infernalsuite.asp.level.SlimeLevelInstance levelInstance) { -+ + this.loadTask = levelInstance.getLoadTask(this, scheduler, world, chunkX, chunkZ, priority, result -> { -+ ChunkLoadTask.this.complete(result == null ? null : result.left(), result == null ? null : result.right()); ++ ChunkLoadTask.this.loadResult = result; // must be before getAndDecrement ++ ChunkLoadTask.this.tryCompleteLoad(); + }); + } else { -+ ChunkDataLoadTask task = new ChunkDataLoadTask(scheduler, world, chunkX, chunkZ, priority); -+ task.addCallback((final GenericDataLoadTask.TaskResult result) -> { -+ ChunkLoadTask.this.complete(result == null ? null : result.left(), result == null ? null : result.right()); ++ this.loadTask = new ChunkDataLoadTask(scheduler, world, chunkX, chunkZ, priority); ++ ((ChunkDataLoadTask) this.loadTask).addCallback((final GenericDataLoadTask.TaskResult result) -> { ++ ChunkLoadTask.this.loadResult = result; // must be before getAndDecrement ++ ChunkLoadTask.this.tryCompleteLoad(); + }); -+ this.loadTask = task; + } + // ASWM end } From fa6c7e15314bbcd12da57d7b71ebb468ea2e9f2a Mon Sep 17 00:00:00 2001 From: David Mayr Date: Fri, 14 Mar 2025 23:19:29 +0100 Subject: [PATCH 100/133] fix: Entities not saving on world unload Signed-off-by: David Mayr --- .../asp/level/NMSSlimeChunk.java | 23 +------------------ .../asp/level/SlimeChunkLevel.java | 9 -------- .../asp/level/SlimeInMemoryWorld.java | 4 ++-- .../asp/level/SlimeLevelInstance.java | 7 ++++++ 4 files changed, 10 insertions(+), 33 deletions(-) diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java index 241afa94a..14aa0b9dc 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -66,18 +66,11 @@ public class NMSSlimeChunk implements SlimeChunk { private final CompoundBinaryTag extra; private final CompoundBinaryTag upgradeData; - private final ChunkEntitySlices entitySlices; - public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference) { - this(chunk, reference, null); - } - - public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference, ChunkEntitySlices slices) { this.chunk = chunk; this.extra = reference == null ? CompoundBinaryTag.empty() : reference.getExtraData(); this.extra.put("ChunkBukkitValues", Converter.convertTag(chunk.persistentDataContainer.toTagCompound())); this.upgradeData = reference == null ? null : reference.getUpgradeData(); - this.entitySlices = slices; } @Override @@ -163,7 +156,7 @@ public List getTileEntities() { @Override public List getEntities() { - ChunkEntitySlices slices = getEntitySlices(); + ChunkEntitySlices slices = NmsUtil.getChunkHolder(chunk).getEntityChunk(); if (slices == null) return new ArrayList<>(); List entities = new ArrayList<>(slices.entities.size()); @@ -181,20 +174,6 @@ public List getEntities() { return entities; } - private ChunkEntitySlices getEntitySlices() { - if (this.entitySlices != null) return this.entitySlices; - - if (this.chunk == null) { - return null; - } - NewChunkHolder chunkHolder = NmsUtil.getChunkHolder(chunk); - if(chunkHolder == null) { - return null; - } - - return chunkHolder.getEntityChunk(); - } - @Override public CompoundBinaryTag getExtraData() { return extra; diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java index 805749598..b9abb27fe 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java @@ -27,13 +27,4 @@ public void loadCallback() { super.loadCallback(); this.inMemoryWorld.ensureChunkMarkedAsLoaded(this); } - - @Override - public void unloadCallback() { - super.unloadCallback(); - - ChunkEntitySlices entities = ((ChunkSystemServerLevel) this.level).moonrise$getChunkTaskScheduler() - .chunkHolderManager.getChunkHolder(this.locX, this.locZ).getEntityChunk(); - inMemoryWorld.unload(this, entities); - } } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java index bc32ced3d..6fd9c5e0e 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -102,7 +102,7 @@ public LevelChunk promote(int x, int z, SlimeChunk chunk) { // Authored by: Kenox // Don't use the NMS live chunk in the chunk map - public void unload(LevelChunk providedChunk, ChunkEntitySlices entitySlices) { + public void unload(LevelChunk providedChunk) { final int x = providedChunk.locX; final int z = providedChunk.locZ; @@ -110,7 +110,7 @@ public void unload(LevelChunk providedChunk, ChunkEntitySlices entitySlices) { this.chunkStorage.remove(Util.chunkPosition(x, z)); return; } - SlimeChunk chunk = new NMSSlimeChunk(providedChunk, getChunk(x, z), entitySlices); + SlimeChunk chunk = new NMSSlimeChunk(providedChunk, getChunk(x, z)); CompoundBinaryTag pdcTag = Converter.convertTag(providedChunk.persistentDataContainer.toTagCompound()); chunk.getExtraData().put("ChunkBukkitValues", pdcTag); diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java index 787b1d436..0a9bacc78 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -23,6 +23,7 @@ import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.dimension.LevelStem; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; @@ -111,6 +112,12 @@ public void save(@Nullable ProgressListener progressUpdate, boolean forceSave, b if (!savingDisabled) save(); } + @Override + public void unload(@NotNull LevelChunk chunk) { + slimeInstance.unload(chunk); + super.unload(chunk); + } + @Override public void saveIncrementally(boolean doFull) { if(doFull) { From a6082dcca3af734726ff8c5a19b52a051b6ed670 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sat, 15 Mar 2025 08:20:48 +0100 Subject: [PATCH 101/133] chore: dont disable watchdog in test env Signed-off-by: David Mayr --- gradle.properties | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index c69aa6ea1..fe0c636c9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,5 +9,4 @@ org.gradle.caching=true org.gradle.parallel=true org.gradle.vfs.watch=false -org.gradle.jvmargs=-Xmx10g -paper.runDisableWatchdog=true \ No newline at end of file +org.gradle.jvmargs=-Xmx10g \ No newline at end of file From 34ad3c1872d641913b90021b3cf6d2623496f6bd Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sat, 15 Mar 2025 11:07:50 +0100 Subject: [PATCH 102/133] fix: Memory leak with some slime chunks Sometimes slime chunks are not really loaded after being created, but they were stored in the map. The safe wrapper should have mitigated any issues caused, but it was wasted memory. Now chunks get promoted in the chunk storage when they are properly loaded (after the loadCallback was called). Signed-off-by: David Mayr --- .../asp/level/ChunkDataLoadTask.java | 4 +-- .../asp/level/NMSSlimeChunk.java | 10 ++++-- .../asp/level/SlimeChunkConverter.java | 2 +- .../asp/level/SlimeChunkLevel.java | 35 ++++++++++++++++--- .../asp/level/SlimeInMemoryWorld.java | 24 +++++++------ 5 files changed, 53 insertions(+), 22 deletions(-) diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java index 705bb2bea..132547558 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java @@ -6,8 +6,6 @@ import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkLoadTask; import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.GenericDataLoadTask; import com.infernalsuite.asp.api.world.SlimeChunk; -import com.infernalsuite.asp.Converter; -import net.minecraft.nbt.CompoundTag; import com.mojang.logging.LogUtils; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.ChunkPos; @@ -66,7 +64,7 @@ private ChunkAccess getEmptyChunk() { private ChunkAccess runOnMain(final SlimeChunk data) { try { - LevelChunk chunk = this.world.slimeInstance.promote(chunkX, chunkZ, data); + LevelChunk chunk = this.world.slimeInstance.createChunk(chunkX, chunkZ, data); return new ImposterProtoChunk(chunk, false); } catch (final Exception e) { LOGGER.error("Failed to parse main tasks for task {}, chunk data will be lost", this, e); diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java index 14aa0b9dc..4439cfb8d 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -69,8 +69,12 @@ public class NMSSlimeChunk implements SlimeChunk { public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference) { this.chunk = chunk; this.extra = reference == null ? CompoundBinaryTag.empty() : reference.getExtraData(); - this.extra.put("ChunkBukkitValues", Converter.convertTag(chunk.persistentDataContainer.toTagCompound())); this.upgradeData = reference == null ? null : reference.getUpgradeData(); + updateExtraData(); + } + + public void updateExtraData() { + this.extra.put("ChunkBukkitValues", Converter.convertTag(chunk.persistentDataContainer.toTagCompound())); } @Override @@ -155,8 +159,10 @@ public List getTileEntities() { @Override public List getEntities() { + NewChunkHolder chunkHolder = NmsUtil.getChunkHolder(chunk); + if(chunkHolder == null) return new ArrayList<>(); - ChunkEntitySlices slices = NmsUtil.getChunkHolder(chunk).getEntityChunk(); + ChunkEntitySlices slices = chunkHolder.getEntityChunk(); if (slices == null) return new ArrayList<>(); List entities = new ArrayList<>(slices.entities.size()); diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java index a11d171ae..e7e22c7fa 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java @@ -114,7 +114,7 @@ static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeC chunk.getTileEntities().stream().map(tag -> (net.minecraft.nbt.CompoundTag) Converter.convertTag(tag)).toList() ); - SlimeChunkLevel nmsChunk = new SlimeChunkLevel(instance, pos, upgradeData, blockLevelChunkTicks, + SlimeChunkLevel nmsChunk = new SlimeChunkLevel(instance, chunk, pos, upgradeData, blockLevelChunkTicks, fluidLevelChunkTicks, 0L, sections, processor, null); // Height Maps diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java index b9abb27fe..afa58f69b 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java @@ -1,8 +1,6 @@ package com.infernalsuite.asp.level; -import ca.spottedleaf.moonrise.common.list.EntityList; -import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; -import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; +import com.infernalsuite.asp.api.world.SlimeChunk; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.chunk.LevelChunk; @@ -16,15 +14,42 @@ public class SlimeChunkLevel extends LevelChunk { private final SlimeInMemoryWorld inMemoryWorld; + private final NMSSlimeChunk nmsSlimeChunk; + private final @Nullable SlimeChunk slimeReference; - public SlimeChunkLevel(SlimeLevelInstance world, ChunkPos pos, UpgradeData upgradeData, LevelChunkTicks blockTickScheduler, LevelChunkTicks fluidTickScheduler, long inhabitedTime, @Nullable LevelChunkSection[] sectionArrayInitializer, @Nullable LevelChunk.PostLoadProcessor entityLoader, @Nullable BlendingData blendingData) { + public SlimeChunkLevel( + SlimeLevelInstance world, + @Nullable SlimeChunk reference, + ChunkPos pos, + UpgradeData upgradeData, + LevelChunkTicks blockTickScheduler, + LevelChunkTicks fluidTickScheduler, + long inhabitedTime, + @Nullable LevelChunkSection[] sectionArrayInitializer, + @Nullable LevelChunk.PostLoadProcessor entityLoader, + @Nullable BlendingData blendingData + ) { super(world, pos, upgradeData, blockTickScheduler, fluidTickScheduler, inhabitedTime, sectionArrayInitializer, entityLoader, blendingData); this.inMemoryWorld = world.slimeInstance; + this.nmsSlimeChunk = new NMSSlimeChunk(this, reference); + this.slimeReference = reference; } @Override public void loadCallback() { + //Not the earliest point where we can do promote the chunk in storage, but it's the easiest without any further patches, + //and without causing a potential memory leak, and It's where bukkit calls its chunk load event so we should be fine. + this.inMemoryWorld.promoteInChunkStorage(this); + super.loadCallback(); - this.inMemoryWorld.ensureChunkMarkedAsLoaded(this); + } + + public SlimeChunk getSafeSlimeReference() { + if(this.slimeReference == null) return this.nmsSlimeChunk; + return new SafeNmsChunkWrapper(this.nmsSlimeChunk, this.slimeReference); + } + + public NMSSlimeChunk getNmsSlimeChunk() { + return nmsSlimeChunk; } } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java index 6fd9c5e0e..cd9351c4e 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -1,6 +1,5 @@ package com.infernalsuite.asp.level; -import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; import com.infernalsuite.asp.Converter; import com.infernalsuite.asp.Util; import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; @@ -76,26 +75,25 @@ public SlimeLoader getLoader() { return this.loader; } - public LevelChunk promote(int x, int z, SlimeChunk chunk) { + public LevelChunk createChunk(int x, int z, SlimeChunk chunk) { SlimeChunkLevel levelChunk; if (chunk == null) { net.minecraft.world.level.ChunkPos pos = new net.minecraft.world.level.ChunkPos(x, z); LevelChunkTicks blockLevelChunkTicks = new LevelChunkTicks<>(); LevelChunkTicks fluidLevelChunkTicks = new LevelChunkTicks<>(); - levelChunk = new SlimeChunkLevel(this.instance, pos, UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks, + levelChunk = new SlimeChunkLevel(this.instance, null, pos, UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks, 0L, null, null, null); //Make SlimeProperties.DEFAULT_BIOME work levelChunk.fillBiomesFromNoise(instance.chunkSource.getGenerator().getBiomeSource(), instance.chunkSource.randomState().sampler()); - chunk = new NMSSlimeChunk(levelChunk, getChunk(x, z)); } else { levelChunk = SlimeChunkConverter.deserializeSlimeChunk(this.instance, chunk); - chunk = new SafeNmsChunkWrapper(new NMSSlimeChunk(levelChunk, chunk), chunk); } - this.chunkStorage.put(Util.chunkPosition(x, z), chunk); + + //Don't put this chunk in chunkStorage yet, as creating a chunk does not guarantee it is loaded in the future. return levelChunk; } @@ -110,7 +108,13 @@ public void unload(LevelChunk providedChunk) { this.chunkStorage.remove(Util.chunkPosition(x, z)); return; } - SlimeChunk chunk = new NMSSlimeChunk(providedChunk, getChunk(x, z)); + NMSSlimeChunk chunk; + if(providedChunk instanceof SlimeChunkLevel slimeChunkLevel) { + chunk = slimeChunkLevel.getNmsSlimeChunk(); + chunk.updateExtraData(); + } else { + chunk = new NMSSlimeChunk(providedChunk, getChunk(x, z)); + } CompoundBinaryTag pdcTag = Converter.convertTag(providedChunk.persistentDataContainer.toTagCompound()); chunk.getExtraData().put("ChunkBukkitValues", pdcTag); @@ -266,9 +270,7 @@ public SlimeLevelInstance getInstance() { return this.extraPDC; } - public void ensureChunkMarkedAsLoaded(SlimeChunkLevel chunk) { - if (chunkStorage.get(Util.chunkPosition(chunk.locX, chunk.locZ)) instanceof SlimeChunkSkeleton skeleton) { - chunkStorage.put(Util.chunkPosition(chunk.locX, chunk.locZ), new NMSSlimeChunk(chunk, skeleton)); - } + public void promoteInChunkStorage(SlimeChunkLevel chunk) { + chunkStorage.put(Util.chunkPosition(chunk.locX, chunk.locZ), chunk.getSafeSlimeReference()); } } From 995c7de800ab0bde5a6ac338000d659b4728ba91 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sat, 15 Mar 2025 11:26:51 +0100 Subject: [PATCH 103/133] fix: persistent data container/extra data not being modifiable Signed-off-by: David Mayr --- .../com/infernalsuite/asp/api/world/SlimeChunk.java | 4 +++- .../asp/serialization/anvil/AnvilWorldReader.java | 10 +++------- .../asp/serialization/slime/SlimeSerializer.java | 2 +- .../reader/impl/v12/v12SlimeWorldDeSerializer.java | 12 +++++++----- .../infernalsuite/asp/skeleton/SkeletonCloning.java | 3 ++- .../asp/skeleton/SlimeChunkSkeleton.java | 6 ++++-- .../com/infernalsuite/asp/level/NMSSlimeChunk.java | 11 +++++------ .../infernalsuite/asp/level/SafeNmsChunkWrapper.java | 4 +++- .../infernalsuite/asp/level/SlimeChunkConverter.java | 7 +++---- 9 files changed, 31 insertions(+), 28 deletions(-) diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunk.java b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunk.java index cbd31f7d6..71abfed05 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunk.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunk.java @@ -1,8 +1,10 @@ package com.infernalsuite.asp.api.world; +import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag; import java.util.List; +import java.util.Map; import javax.annotation.Nullable; /** @@ -63,7 +65,7 @@ public interface SlimeChunk { * * @return A {@link CompoundBinaryTag} containing the extra data of the chunk, */ - CompoundBinaryTag getExtraData(); + Map getExtraData(); /** * Upgrade data used to fix the chunks. diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java b/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java index a3c86a651..e330a456d 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java @@ -30,10 +30,7 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import java.util.stream.Collectors; @@ -309,10 +306,9 @@ private static SlimeChunk readChunk(CompoundBinaryTag compound, int worldVersion sectionArray[index - minSectionY] = new SlimeChunkSectionSkeleton(blockStatesTag, biomesTag, blockLightArray, skyLightArray); } - CompoundBinaryTag.Builder extraTagBuilder = CompoundBinaryTag.builder(); + Map extraTag = new HashMap<>(); CompoundBinaryTag chunkBukkitValues = compound.getCompound("ChunkBukkitValues"); - if (chunkBukkitValues.size() > 0) extraTagBuilder.put("ChunkBukkitValues", chunkBukkitValues); - CompoundBinaryTag extraTag = extraTagBuilder.build(); + if (!chunkBukkitValues.isEmpty()) extraTag.put("ChunkBukkitValues", chunkBukkitValues); // Find first non-null chunk section. If all sections are null, chunk is empty so return null return Arrays.stream(sectionArray) diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/SlimeSerializer.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/SlimeSerializer.java index 5352359be..7252a6400 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/SlimeSerializer.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/SlimeSerializer.java @@ -142,7 +142,7 @@ static byte[] serializeChunks(SlimeWorld world, Collection chunks) t if (chunk.getExtraData() == null) { LOGGER.warn("Chunk at " + chunk.getX() + ", " + chunk.getZ() + " from world " + world.getName() + " has no extra data! When deserialized, this chunk will have an empty extra data tag!"); } - byte[] extra = serializeCompoundTag(chunk.getExtraData()); + byte[] extra = serializeCompoundTag(CompoundBinaryTag.from(chunk.getExtraData())); outStream.writeInt(extra.length); outStream.write(extra); diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12SlimeWorldDeSerializer.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12SlimeWorldDeSerializer.java index 0ab7bbb8d..87faf2c36 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12SlimeWorldDeSerializer.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12SlimeWorldDeSerializer.java @@ -11,6 +11,7 @@ import com.infernalsuite.asp.api.world.SlimeWorld; import com.infernalsuite.asp.api.world.properties.SlimeProperties; import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.skeleton.SlimeChunkSkeleton; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.kyori.adventure.nbt.BinaryTag; @@ -23,7 +24,9 @@ import java.io.DataInputStream; import java.io.IOException; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -138,12 +141,11 @@ private static Long2ObjectMap readChunks(SlimePropertyMap slimePrope // Extra Tag byte[] rawExtra = read(chunkData); CompoundBinaryTag extra = readCompound(rawExtra); - // If the extra tag is empty, the serializer will save it as null. - // So if we deserialize a null extra tag, we will assume it was empty. - if (extra == null) extra = CompoundBinaryTag.empty(); - chunkMap.put(Util.chunkPosition(x, z), - new com.infernalsuite.asp.skeleton.SlimeChunkSkeleton(x, z, chunkSections, heightMaps, tileEntities, entities, extra, null)); + Map extraData = new HashMap<>(); + if (extra != null) extra.forEach(entry -> extraData.put(entry.getKey(), entry.getValue())); + + chunkMap.put(Util.chunkPosition(x, z), new SlimeChunkSkeleton(x, z, chunkSections, heightMaps, tileEntities, entities, extraData, null)); } return chunkMap; } diff --git a/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java b/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java index a08f9f262..bcb015b92 100644 --- a/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java +++ b/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java @@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; import java.util.concurrent.ConcurrentHashMap; @@ -74,7 +75,7 @@ private static Long2ObjectMap cloneChunkStorage(Collection(chunk.getExtraData()), null )); } diff --git a/core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSkeleton.java b/core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSkeleton.java index f4cf2a9ef..00268e96c 100644 --- a/core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSkeleton.java +++ b/core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSkeleton.java @@ -2,15 +2,17 @@ import com.infernalsuite.asp.api.world.SlimeChunk; import com.infernalsuite.asp.api.world.SlimeChunkSection; +import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag; import java.util.List; +import java.util.Map; public record SlimeChunkSkeleton(int x, int z, SlimeChunkSection[] sections, CompoundBinaryTag heightMap, List blockEntities, List entities, - CompoundBinaryTag extra, + Map extra, CompoundBinaryTag upgradeData) implements SlimeChunk { @Override @@ -44,7 +46,7 @@ public List getEntities() { } @Override - public CompoundBinaryTag getExtraData() { + public Map getExtraData() { return this.extra; } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java index 4439cfb8d..831d57a45 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -9,6 +9,7 @@ import com.infernalsuite.asp.util.NmsUtil; import com.mojang.serialization.Codec; import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; +import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.nbt.LongArrayBinaryTag; import net.minecraft.core.Holder; @@ -35,9 +36,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; +import java.util.*; public class NMSSlimeChunk implements SlimeChunk { private static final Logger LOGGER = LoggerFactory.getLogger(NMSSlimeChunk.class); @@ -63,12 +62,12 @@ public class NMSSlimeChunk implements SlimeChunk { } private LevelChunk chunk; - private final CompoundBinaryTag extra; + private final Map extra; private final CompoundBinaryTag upgradeData; public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference) { this.chunk = chunk; - this.extra = reference == null ? CompoundBinaryTag.empty() : reference.getExtraData(); + this.extra = reference == null ? new HashMap<>() : reference.getExtraData(); this.upgradeData = reference == null ? null : reference.getUpgradeData(); updateExtraData(); } @@ -181,7 +180,7 @@ public List getEntities() { } @Override - public CompoundBinaryTag getExtraData() { + public Map getExtraData() { return extra; } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java index 1cbfd90a5..f2b41f803 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java @@ -2,9 +2,11 @@ import com.infernalsuite.asp.api.world.SlimeChunk; import com.infernalsuite.asp.api.world.SlimeChunkSection; +import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag; import java.util.List; +import java.util.Map; public class SafeNmsChunkWrapper implements SlimeChunk { @@ -63,7 +65,7 @@ public List getEntities() { } @Override - public CompoundBinaryTag getExtraData() { + public Map getExtraData() { if (shouldDefaultBackToSlimeChunk()) { return this.safety.getExtraData(); } diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java index e7e22c7fa..39e677a39 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java @@ -13,6 +13,7 @@ import net.minecraft.core.Holder; import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtOps; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.biome.Biome; @@ -143,11 +144,9 @@ static SlimeChunkLevel deserializeSlimeChunk(SlimeLevelInstance instance, SlimeC Heightmap.primeHeightmaps(nmsChunk, unsetHeightMaps); } - net.minecraft.nbt.CompoundTag nmsExtraData = (net.minecraft.nbt.CompoundTag) Converter.convertTag(chunk.getExtraData()); - // Attempt to read PDC from the extra tag - if (nmsExtraData.get("ChunkBukkitValues") != null) { - nmsChunk.persistentDataContainer.putAll(nmsExtraData.getCompound("ChunkBukkitValues")); + if (chunk.getExtraData().containsKey("ChunkBukkitValues")) { + nmsChunk.persistentDataContainer.putAll((CompoundTag) Converter.convertTag(chunk.getExtraData().get("ChunkBukkitValues"))); } return nmsChunk; From adb5aebbc5f624c46c7e5b84d59014f5f00e78ec Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sat, 15 Mar 2025 11:47:02 +0100 Subject: [PATCH 104/133] chore: dont save pdc twice + Remove it in NMS constructor as updating it there is unnecessary Signed-off-by: David Mayr --- .../java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java index cd9351c4e..bf56be3f9 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -111,13 +111,10 @@ public void unload(LevelChunk providedChunk) { NMSSlimeChunk chunk; if(providedChunk instanceof SlimeChunkLevel slimeChunkLevel) { chunk = slimeChunkLevel.getNmsSlimeChunk(); - chunk.updateExtraData(); } else { chunk = new NMSSlimeChunk(providedChunk, getChunk(x, z)); } - - CompoundBinaryTag pdcTag = Converter.convertTag(providedChunk.persistentDataContainer.toTagCompound()); - chunk.getExtraData().put("ChunkBukkitValues", pdcTag); + chunk.updatePersistentDataContainer(); this.chunkStorage.put(Util.chunkPosition(x, z), new SlimeChunkSkeleton(chunk.getX(), chunk.getZ(), chunk.getSections(), From f5398500a6c8a130e7503b667b4137e6e2448818 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sat, 15 Mar 2025 12:04:52 +0100 Subject: [PATCH 105/133] fix: seems like I really cannot go around patching NewChunkHolder :/ Now with documentation why Signed-off-by: David Mayr --- .../scheduling/NewChunkHolder.java.patch | 18 ++++++++++++++++++ .../infernalsuite/asp/level/NMSSlimeChunk.java | 7 +++++-- .../asp/level/SlimeInMemoryWorld.java | 17 ++++++++++++----- .../asp/level/SlimeLevelInstance.java | 7 +++---- 4 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch diff --git a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch new file mode 100644 index 000000000..f8c3b6a3e --- /dev/null +++ b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch @@ -0,0 +1,18 @@ +--- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java ++++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java +@@ -910,8 +_,15 @@ + } + + if (chunk instanceof LevelChunk levelChunk) { ++ //ASP start - unloadStage1 sets the entitySlices to null, so we can't get them otherwise unfortunately. ++ //This needs to be above world.unload since world.unload removes block entities ++ if(world instanceof com.infernalsuite.asp.level.SlimeLevelInstance instance) { ++ instance.unload(levelChunk, entityChunk); ++ } ++ //ASP end + this.world.unload(levelChunk); + } ++ + } + + // unload entity data diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java index 831d57a45..897c9a921 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -69,10 +69,9 @@ public NMSSlimeChunk(LevelChunk chunk, SlimeChunk reference) { this.chunk = chunk; this.extra = reference == null ? new HashMap<>() : reference.getExtraData(); this.upgradeData = reference == null ? null : reference.getUpgradeData(); - updateExtraData(); } - public void updateExtraData() { + public void updatePersistentDataContainer() { this.extra.put("ChunkBukkitValues", Converter.convertTag(chunk.persistentDataContainer.toTagCompound())); } @@ -164,6 +163,10 @@ public List getEntities() { ChunkEntitySlices slices = chunkHolder.getEntityChunk(); if (slices == null) return new ArrayList<>(); + return getEntities(slices); + } + + public List getEntities(ChunkEntitySlices slices) { List entities = new ArrayList<>(slices.entities.size()); // Work by diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java index bf56be3f9..709d9ef8a 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -1,5 +1,6 @@ package com.infernalsuite.asp.level; +import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; import com.infernalsuite.asp.Converter; import com.infernalsuite.asp.Util; import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; @@ -100,7 +101,7 @@ public LevelChunk createChunk(int x, int z, SlimeChunk chunk) { // Authored by: Kenox // Don't use the NMS live chunk in the chunk map - public void unload(LevelChunk providedChunk) { + public void unload(LevelChunk providedChunk, ChunkEntitySlices slices) { final int x = providedChunk.locX; final int z = providedChunk.locZ; @@ -116,9 +117,16 @@ public void unload(LevelChunk providedChunk) { } chunk.updatePersistentDataContainer(); - this.chunkStorage.put(Util.chunkPosition(x, z), - new SlimeChunkSkeleton(chunk.getX(), chunk.getZ(), chunk.getSections(), - chunk.getHeightMaps(), chunk.getTileEntities(), chunk.getEntities(), chunk.getExtraData(), null)); + this.chunkStorage.put(Util.chunkPosition(x, z), new SlimeChunkSkeleton( + chunk.getX(), + chunk.getZ(), + chunk.getSections(), + chunk.getHeightMaps(), + chunk.getTileEntities(), + chunk.getEntities(slices), //As the slices are not available anymore, we can't get the entities otherwise + chunk.getExtraData(), + null + )); } @Override @@ -136,7 +144,6 @@ public Collection getChunkStorage() { return this.instance.getWorld(); } - @Override public SlimePropertyMap getPropertyMap() { return this.propertyMap; diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java index 0a9bacc78..0469b5243 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -1,6 +1,7 @@ package com.infernalsuite.asp.level; import ca.spottedleaf.concurrentutil.util.Priority; +import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler; import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.ChunkLoadTask; import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.task.GenericDataLoadTask; @@ -112,10 +113,8 @@ public void save(@Nullable ProgressListener progressUpdate, boolean forceSave, b if (!savingDisabled) save(); } - @Override - public void unload(@NotNull LevelChunk chunk) { - slimeInstance.unload(chunk); - super.unload(chunk); + public void unload(@NotNull LevelChunk chunk, ChunkEntitySlices slices) { + slimeInstance.unload(chunk, slices); } @Override From bbf89c075251d254e0de3372d58d3c602b2247ea Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sat, 15 Mar 2025 12:13:12 +0100 Subject: [PATCH 106/133] fix: move slices null check --- .../main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java index 897c9a921..ccbc1ea4f 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java @@ -161,12 +161,11 @@ public List getEntities() { if(chunkHolder == null) return new ArrayList<>(); ChunkEntitySlices slices = chunkHolder.getEntityChunk(); - if (slices == null) return new ArrayList<>(); - return getEntities(slices); } public List getEntities(ChunkEntitySlices slices) { + if (slices == null) return new ArrayList<>(); List entities = new ArrayList<>(slices.entities.size()); // Work by From e64ac5677ab6e116b5749a907b5bb452440b29ed Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sat, 15 Mar 2025 12:13:12 +0100 Subject: [PATCH 107/133] fix: pass slices to pruner Signed-off-by: David Mayr --- .../com/infernalsuite/asp/level/FastChunkPruner.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java index 8d1d30572..40a17eedf 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java @@ -12,6 +12,10 @@ public class FastChunkPruner { public static boolean canBePruned(SlimeWorld world, LevelChunk chunk) { + return canBePruned(world, chunk); + } + + public static boolean canBePruned(SlimeWorld world, LevelChunk chunk, ChunkEntitySlices slices) { NewChunkHolder chunkHolder = NmsUtil.getChunkHolder(chunk); // Kenox @@ -43,7 +47,10 @@ public static boolean canBePruned(SlimeWorld world, LevelChunk chunk) { String pruningSetting = world.getPropertyMap().getValue(SlimeProperties.CHUNK_PRUNING); if (pruningSetting.equals("aggressive")) { - ChunkEntitySlices slices = chunkHolder.getEntityChunk(); + if(slices == null) { + //in case no slices were provided, try getting them from the chunk holder + slices = chunkHolder.getEntityChunk(); + } return chunk.blockEntities.isEmpty() && (slices == null || slices.isEmpty()) && areSectionsEmpty(chunk); } From ef52766aae41e09def219bf4c7a04c204d209a2d Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sat, 15 Mar 2025 12:18:55 +0100 Subject: [PATCH 108/133] fix: pass slices to pruner Signed-off-by: David Mayr --- .../java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java index 709d9ef8a..5f1c42509 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -105,7 +105,7 @@ public void unload(LevelChunk providedChunk, ChunkEntitySlices slices) { final int x = providedChunk.locX; final int z = providedChunk.locZ; - if (FastChunkPruner.canBePruned(this, providedChunk)) { + if (FastChunkPruner.canBePruned(this, providedChunk, slices)) { this.chunkStorage.remove(Util.chunkPosition(x, z)); return; } From b9df2e0a16a236dfe7702c062a31ef1de24298d1 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sat, 15 Mar 2025 13:30:43 +0100 Subject: [PATCH 109/133] fix: imports and readme Signed-off-by: David Mayr --- README.md | 2 -- .../asp/plugin/commands/CommandManager.java | 21 ------------------- settings.gradle.kts | 2 -- 3 files changed, 25 deletions(-) diff --git a/README.md b/README.md index fb674a624..f443bfdda 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,6 @@ releases can be found in the [Discord](https://discord.gg/YevvsMa) under the #ne ## Wiki For API and usage info check out the docs at https://infernalsuite.com/ -**If you run into any Flow-NBT errors when building your project, add the additional repository: `https://repo.rapture.pw/repository/maven-releases/`** - ## Javadocs The Javadocs can be found [here](https://docs.infernalsuite.com/). diff --git a/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/CommandManager.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/CommandManager.java index 78a64f8dd..8ccc06739 100644 --- a/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/CommandManager.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/CommandManager.java @@ -1,48 +1,27 @@ package com.infernalsuite.asp.plugin.commands; -import com.infernalsuite.asp.api.AdvancedSlimePaperAPI; -import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; -import com.infernalsuite.asp.api.exceptions.NewerFormatException; -import com.infernalsuite.asp.api.exceptions.UnknownWorldException; -import com.infernalsuite.asp.api.world.SlimeChunk; import com.infernalsuite.asp.api.world.SlimeWorld; -import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; -import com.infernalsuite.asp.plugin.SWPlugin; -import com.infernalsuite.asp.plugin.commands.parser.*; -import com.infernalsuite.asp.plugin.commands.sub.*; import io.leangen.geantyref.TypeToken; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; -import org.bukkit.Bukkit; -import org.bukkit.Chunk; import org.bukkit.World; import org.bukkit.command.CommandSender; import org.incendo.cloud.annotations.AnnotationParser; import org.incendo.cloud.annotations.Command; import org.incendo.cloud.bukkit.CloudBukkitCapabilities; -import org.incendo.cloud.component.DefaultValue; import org.incendo.cloud.exception.ArgumentParseException; import org.incendo.cloud.exception.CommandExecutionException; import org.incendo.cloud.exception.InvalidSyntaxException; import org.incendo.cloud.exception.NoPermissionException; import org.incendo.cloud.exception.handling.ExceptionHandler; import org.incendo.cloud.execution.ExecutionCoordinator; -import org.incendo.cloud.minecraft.extras.MinecraftHelp; import org.incendo.cloud.paper.LegacyPaperCommandManager; -import org.incendo.cloud.paper.PaperCommandManager; import org.incendo.cloud.parser.ParserRegistry; -import org.incendo.cloud.parser.standard.IntegerParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.util.ArrayList; import java.util.HashSet; -import java.util.List; import java.util.Set; -import java.util.stream.Collectors; - -import static org.incendo.cloud.parser.standard.StringParser.greedyStringParser; public class CommandManager { private static final Logger LOGGER = LoggerFactory.getLogger(CommandManager.class); diff --git a/settings.gradle.kts b/settings.gradle.kts index e71b880c3..c38b3ec81 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -22,8 +22,6 @@ include(":plugin") include(":impl") include(":impl:aspaper-api") include(":impl:aspaper-server") -//include(":aspaper-api") -//include(":aspaper-server") include("loaders:mongo-loader") findProject(":loaders:mongo-loader")?.name = "mongo-loader" From ee2a20e0546fdc680fb344d7bd8c44d3476021bf Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sat, 15 Mar 2025 14:27:11 +0100 Subject: [PATCH 110/133] fix: accidental recursion Signed-off-by: David Mayr --- .../main/java/com/infernalsuite/asp/level/FastChunkPruner.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java index 40a17eedf..bd9f6d564 100644 --- a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java +++ b/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java @@ -12,7 +12,7 @@ public class FastChunkPruner { public static boolean canBePruned(SlimeWorld world, LevelChunk chunk) { - return canBePruned(world, chunk); + return canBePruned(world, chunk, null); } public static boolean canBePruned(SlimeWorld world, LevelChunk chunk, ChunkEntitySlices slices) { From 85183fd72bcf4dadfbdda42d6c07f32e8a6798bf Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sat, 15 Mar 2025 14:38:59 +0100 Subject: [PATCH 111/133] fix: unload worlds in slime plugin (Closes #134) Signed-off-by: David Mayr --- .../infernalsuite/asp/plugin/SWPlugin.java | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/plugin/src/main/java/com/infernalsuite/asp/plugin/SWPlugin.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/SWPlugin.java index 9443ad209..600e8cb63 100644 --- a/plugin/src/main/java/com/infernalsuite/asp/plugin/SWPlugin.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/SWPlugin.java @@ -1,6 +1,7 @@ package com.infernalsuite.asp.plugin; import com.infernalsuite.asp.plugin.commands.CommandManager; +import com.infernalsuite.asp.plugin.config.ConfigManager; import com.infernalsuite.asp.plugin.config.WorldData; import com.infernalsuite.asp.plugin.config.WorldsConfig; import com.infernalsuite.asp.plugin.loader.LoaderManager; @@ -19,6 +20,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.util.*; +import java.util.logging.Level; public class SWPlugin extends JavaPlugin { @@ -96,9 +98,27 @@ public void onEnable() { worldsToLoad.clear(); // Don't unnecessarily hog up memory } + @Override + public void onDisable() { + WorldsConfig config = ConfigManager.getWorldConfig(); + + for (Map.Entry entry : config.getWorlds().entrySet()) { + SlimeWorld world = ASP.getLoadedWorld(entry.getKey()); + + if (world != null && !world.isReadOnly()) { + try { + ASP.saveWorld(world); //Save the world sync + } catch (RuntimeException | IOException ex) { + getLogger().log(Level.SEVERE, "Failed to unload world " + world.getName(), ex); + } + } + Bukkit.unloadWorld(world.getName(), false); //Unload without saving as we have just saved (if not read only) + } + } + private List loadWorlds() { List erroredWorlds = new ArrayList<>(); - WorldsConfig config = com.infernalsuite.asp.plugin.config.ConfigManager.getWorldConfig(); + WorldsConfig config = ConfigManager.getWorldConfig(); for (Map.Entry entry : config.getWorlds().entrySet()) { String worldName = entry.getKey(); From a1126cb7eb54e409a42bd987987e79f4a899fcde Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sat, 15 Mar 2025 16:58:24 +0100 Subject: [PATCH 112/133] fix: chunk entity re-loading warning, dont save region/entities in temp dir Signed-off-by: David Mayr --- .../scheduling/NewChunkHolder.java.patch | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch index f8c3b6a3e..ff3cc89a5 100644 --- a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch +++ b/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch @@ -1,6 +1,24 @@ --- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -@@ -910,8 +_,15 @@ +@@ -116,7 +_,7 @@ + } + + if (!transientChunk) { +- if (entityChunk != null) { ++ if (!(this.world instanceof com.infernalsuite.asp.level.SlimeLevelInstance) && entityChunk != null) { + final List entities = ChunkEntitySlices.readEntities(this.world, entityChunk); + + ((ChunkSystemServerLevel)this.world).moonrise$getEntityLookup().addEntityChunkEntities(entities, new ChunkPos(this.chunkX, this.chunkZ)); +@@ -894,7 +_,7 @@ + final ChunkEntitySlices entityChunk = state.entityChunk(); + final PoiChunk poiChunk = state.poiChunk(); + +- final boolean shouldLevelChunkNotSave = PlatformHooks.get().forceNoSave(chunk); ++ final boolean shouldLevelChunkNotSave = PlatformHooks.get().forceNoSave(chunk) || world instanceof com.infernalsuite.asp.level.SlimeLevelInstance; //ASP - prevent saving + + // unload chunk data + if (chunk != null) { +@@ -910,13 +_,24 @@ } if (chunk instanceof LevelChunk levelChunk) { @@ -16,3 +34,13 @@ } // unload entity data + if (entityChunk != null) { +- this.saveEntities(entityChunk, true); ++ //ASP start - prevent saving ++ if(!(world instanceof com.infernalsuite.asp.level.SlimeLevelInstance)) { ++ this.saveEntities(entityChunk, true); ++ } ++ //ASP end - prevent saving + // yes this is a hack to pass the compound tag through... + final CompoundTag lastEntityUnload = this.lastEntityUnload; + this.lastEntityUnload = null; From 712cbe2964b3373b44f41342908ec58e3c96ef1e Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sat, 15 Mar 2025 18:11:47 +0100 Subject: [PATCH 113/133] fix: CHUNK_SECTION_MAX property name being wrong Signed-off-by: David Mayr --- .../infernalsuite/asp/api/world/properties/SlimeProperties.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperties.java b/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperties.java index d338f939f..90a56d53d 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperties.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperties.java @@ -103,7 +103,7 @@ public class SlimeProperties { @ApiStatus.Experimental public static final SlimePropertyInt CHUNK_SECTION_MIN = SlimePropertyInt.create("chunkSectionMin", -4); @ApiStatus.Experimental - public static final SlimePropertyInt CHUNK_SECTION_MAX = SlimePropertyInt.create("chunkSectionMin", 19); + public static final SlimePropertyInt CHUNK_SECTION_MAX = SlimePropertyInt.create("chunkSectionMax", 19); } From 21aac06e7afeaece1ff5217e5d0a85abd982f9b9 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sat, 15 Mar 2025 19:22:47 +0100 Subject: [PATCH 114/133] fix: comment out platform thing from ComputerNerd Signed-off-by: David Mayr --- buildSrc/src/main/kotlin/asp.base-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/asp.base-conventions.gradle.kts b/buildSrc/src/main/kotlin/asp.base-conventions.gradle.kts index 6eecf8740..209a239a6 100644 --- a/buildSrc/src/main/kotlin/asp.base-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/asp.base-conventions.gradle.kts @@ -28,7 +28,7 @@ repositories { } dependencies { - api(platform(project(":gradle:platform"))) +// api(platform(project(":gradle:platform"))) } tasks { From cd0ebbd4cfc77327044f9d7252d75893fe818d6f Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sat, 15 Mar 2025 19:22:47 +0100 Subject: [PATCH 115/133] fix: branding bukkit version Signed-off-by: David Mayr --- impl/aspaper-server/paper-patches/features/0003-Branding.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impl/aspaper-server/paper-patches/features/0003-Branding.patch b/impl/aspaper-server/paper-patches/features/0003-Branding.patch index 225d0e654..bddf7be57 100644 --- a/impl/aspaper-server/paper-patches/features/0003-Branding.patch +++ b/impl/aspaper-server/paper-patches/features/0003-Branding.patch @@ -97,7 +97,7 @@ index 774556a62eb240da42e84db4502e2ed43495be17..ee1ffebaf4e9f7e2f8e0fd8406357b64 String result = "Unknown-Version"; - InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/io.papermc.paper/paper-api/pom.properties"); -+ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/com.infernalsuite.aswm/slimeworldmanager-api/pom.properties"); ++ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/com.infernalsuite.asp/aspaper-api/pom.properties"); Properties properties = new Properties(); if (stream != null) { From 3b4a54f5f53b886c903683d30322a08d3e7d11f7 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 16 Mar 2025 12:04:07 +0100 Subject: [PATCH 116/133] build: remove shadowjar classifier from plugin Signed-off-by: David Mayr --- plugin/build.gradle.kts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts index 31e30b316..d71cf8060 100644 --- a/plugin/build.gradle.kts +++ b/plugin/build.gradle.kts @@ -24,6 +24,8 @@ tasks { } shadowJar { + archiveClassifier.set("") + relocate("org.bstats", "com.infernalsuite.asp.libs.bstats") relocate("org.spongepowered.configurate", "com.infernalsuite.asp.libs.configurate") relocate("com.zaxxer.hikari", "com.infernalsuite.asp.libs.hikari") From 2e23ac5465648b85fc8b2098c00d408a057659d2 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 23 Mar 2025 18:23:45 +0100 Subject: [PATCH 117/133] fix: anvil reader compression Signed-off-by: David Mayr --- .../asp/serialization/anvil/AnvilWorldReader.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java b/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java index e330a456d..38b7c03d5 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java @@ -94,15 +94,16 @@ public SlimeWorld readFromData(AnvilImportData importData) { Path entityDir = environmentDir.resolve("entities"); if (Files.exists(entityDir)) { if (!Files.isDirectory(entityDir)) throw new InvalidWorldException(environmentDir, "'entities' is not a directory!"); - } - try (var stream = Files.newDirectoryStream(entityDir, path -> path.toString().endsWith(".mca"))) { - for (final Path path : stream) { - LOGGER.info("Loading entity region file {}...", path.getFileName()); - loadEntities(path, worldVersion, chunks); + try (var stream = Files.newDirectoryStream(entityDir, path -> path.toString().endsWith(".mca"))) { + for (final Path path : stream) { + LOGGER.info("Loading entity region file {}...", path.getFileName()); + loadEntities(path, worldVersion, chunks); + } } } + if (chunks.isEmpty()) { throw new InvalidWorldException(environmentDir); } @@ -152,7 +153,7 @@ private static CompoundBinaryTag loadMap(Path mapFile) throws IOException { private static LevelData readLevelData(Path file) throws IOException, InvalidWorldException { CompoundBinaryTag tag; - tag = BinaryTagIO.unlimitedReader().read(file); + tag = BinaryTagIO.unlimitedReader().read(file, BinaryTagIO.Compression.GZIP); CompoundBinaryTag dataTag = tag.getCompound("Data"); if (dataTag.size() != 0) { From 85d569c73689fe6f8a9b243716e878f50497ffca Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 23 Mar 2025 18:24:27 +0100 Subject: [PATCH 118/133] fix: prevent spawn location being incomplete (the slime properties have defaults anyway) Signed-off-by: David Mayr --- .../asp/plugin/commands/sub/ImportWorldCmd.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/ImportWorldCmd.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/ImportWorldCmd.java index 1a269d73a..e4f463378 100644 --- a/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/ImportWorldCmd.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/commands/sub/ImportWorldCmd.java @@ -87,14 +87,9 @@ public CompletableFuture importWorld(CommandSender sender, String[] args, )); com.infernalsuite.asp.plugin.config.WorldData worldData = new com.infernalsuite.asp.plugin.config.WorldData(); - StringBuilder spawn = new StringBuilder(); + for (String key : world.getPropertyMap().getProperties().keySet()) { switch (key.toLowerCase()) { - case "spawnx" -> - spawn.append(world.getPropertyMap().getValue(SlimeProperties.SPAWN_X)).append(", "); - case "spawny" -> - spawn.append(world.getPropertyMap().getValue(SlimeProperties.SPAWN_Y)).append(", "); - case "spawnz" -> spawn.append(world.getPropertyMap().getValue(SlimeProperties.SPAWN_Z)); case "environment" -> worldData.setEnvironment(world.getPropertyMap().getValue(SlimeProperties.ENVIRONMENT)); case "difficulty" -> @@ -112,7 +107,11 @@ public CompletableFuture importWorld(CommandSender sender, String[] args, } worldData.setDataSource(loader.name()); - worldData.setSpawn(spawn.toString().isEmpty() ? "0.5, 255, 0.5" : spawn.toString()); + worldData.setSpawn( + world.getPropertyMap().getValue(SlimeProperties.SPAWN_X) + ", " + + world.getPropertyMap().getValue(SlimeProperties.SPAWN_Y) + ", " + + world.getPropertyMap().getValue(SlimeProperties.SPAWN_Z) + ); config.getWorlds().put(worldName, worldData); config.save(); From 2f7eb0d17e7000488408a01d77e05ff6440b7cba Mon Sep 17 00:00:00 2001 From: David Mayr Date: Mon, 24 Mar 2025 19:30:23 +0100 Subject: [PATCH 119/133] build: move stuff out of impl directory as paperweight doesn't like it. I needed to remove the java platform as it collided with the java plugin Signed-off-by: David Mayr --- .gitignore | 14 ++-- .../build.gradle.kts.patch | 2 +- .../features/0001-API-Branding.patch | 0 .../build.gradle.kts.patch | 10 +-- .../features/0001-Disable-dragon-battle.patch | 0 .../features/0002-World-overrides.patch | 0 .../0003-Avoid-IO-call-for-UUID.patch | 0 ...Prevent-config-disk-io-on-world-load.patch | 0 .../0005-Read-only-dimension-data-store.patch | 0 .../scheduling/ChunkHolderManager.java.patch | 0 .../scheduling/NewChunkHolder.java.patch | 0 .../scheduling/task/ChunkLoadTask.java.patch | 0 .../server/level/ServerLevel.java.patch | 0 .../storage/SerializableChunkData.java.patch | 0 ...01-Warning-if-people-use-old-swm-api.patch | 0 ...Warning-if-people-use-old-swm-plugin.patch | 0 .../features/0003-Branding.patch | 0 ...-temp-folder-after-world-is-unloaded.patch | 0 ...Prevent-config-disk-io-on-world-load.patch | 0 .../bukkit/craftbukkit/CraftServer.java.patch | 0 .../infernalsuite/asp/AdvancedSlimePaper.java | 0 .../java/com/infernalsuite/asp/Converter.java | 0 .../com/infernalsuite/asp/InternalPlugin.java | 0 .../asp/SimpleDataFixerConverter.java | 0 .../infernalsuite/asp/SlimeNMSBridgeImpl.java | 0 .../asp/config/SlimePaperWorldConfig.java | 0 .../asp/level/ChunkDataLoadTask.java | 0 .../asp/level/CommonLoadTask.java | 0 .../asp/level/FastChunkPruner.java | 0 .../asp/level/NMSSlimeChunk.java | 0 .../level/ReadOnlyDimensionDataStorage.java | 0 .../asp/level/SafeNmsChunkWrapper.java | 0 .../asp/level/SlimeBootstrap.java | 0 .../asp/level/SlimeChunkConverter.java | 0 .../asp/level/SlimeChunkLevel.java | 0 .../asp/level/SlimeInMemoryWorld.java | 0 .../asp/level/SlimeLevelGenerator.java | 0 .../asp/level/SlimeLevelInstance.java | 0 .../com/infernalsuite/asp/util/NmsUtil.java | 0 ...nfernalsuite.asp.api.AdvancedSlimePaperAPI | 0 .../com.infernalsuite.asp.api.SlimeNMSBridge | 0 {impl/build-data => build-data}/aspaper.at | 0 .../build-data => build-data}/dev-imports.txt | 0 build.gradle.kts | 71 ++++++++++++++++++ core/build.gradle.kts | 2 +- gradle/platform/build.gradle.kts | 26 ------- impl/build.gradle.kts | 75 ------------------- importer/build.gradle.kts | 2 +- settings.gradle.kts | 5 +- 49 files changed, 87 insertions(+), 120 deletions(-) rename {impl/aspaper-api => aspaper-api}/build.gradle.kts.patch (96%) rename {impl/aspaper-api => aspaper-api}/paper-patches/features/0001-API-Branding.patch (100%) rename {impl/aspaper-server => aspaper-server}/build.gradle.kts.patch (92%) rename {impl/aspaper-server => aspaper-server}/minecraft-patches/features/0001-Disable-dragon-battle.patch (100%) rename {impl/aspaper-server => aspaper-server}/minecraft-patches/features/0002-World-overrides.patch (100%) rename {impl/aspaper-server => aspaper-server}/minecraft-patches/features/0003-Avoid-IO-call-for-UUID.patch (100%) rename {impl/aspaper-server => aspaper-server}/minecraft-patches/features/0004-Prevent-config-disk-io-on-world-load.patch (100%) rename {impl/aspaper-server => aspaper-server}/minecraft-patches/features/0005-Read-only-dimension-data-store.patch (100%) rename {impl/aspaper-server => aspaper-server}/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java.patch (100%) rename {impl/aspaper-server => aspaper-server}/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch (100%) rename {impl/aspaper-server => aspaper-server}/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch (100%) rename {impl/aspaper-server => aspaper-server}/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch (100%) rename {impl/aspaper-server => aspaper-server}/minecraft-patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch (100%) rename {impl/aspaper-server => aspaper-server}/paper-patches/features/0001-Warning-if-people-use-old-swm-api.patch (100%) rename {impl/aspaper-server => aspaper-server}/paper-patches/features/0002-Warning-if-people-use-old-swm-plugin.patch (100%) rename {impl/aspaper-server => aspaper-server}/paper-patches/features/0003-Branding.patch (100%) rename {impl/aspaper-server => aspaper-server}/paper-patches/features/0004-Delete-temp-folder-after-world-is-unloaded.patch (100%) rename {impl/aspaper-server => aspaper-server}/paper-patches/features/0005-Prevent-config-disk-io-on-world-load.patch (100%) rename {impl/aspaper-server => aspaper-server}/paper-patches/files/src/main/java/org/bukkit/craftbukkit/CraftServer.java.patch (100%) rename {impl/aspaper-server => aspaper-server}/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java (100%) rename {impl/aspaper-server => aspaper-server}/src/main/java/com/infernalsuite/asp/Converter.java (100%) rename {impl/aspaper-server => aspaper-server}/src/main/java/com/infernalsuite/asp/InternalPlugin.java (100%) rename {impl/aspaper-server => aspaper-server}/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java (100%) rename {impl/aspaper-server => aspaper-server}/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java (100%) rename {impl/aspaper-server => aspaper-server}/src/main/java/com/infernalsuite/asp/config/SlimePaperWorldConfig.java (100%) rename {impl/aspaper-server => aspaper-server}/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java (100%) rename {impl/aspaper-server => aspaper-server}/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java (100%) rename {impl/aspaper-server => aspaper-server}/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java (100%) rename {impl/aspaper-server => aspaper-server}/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java (100%) rename {impl/aspaper-server => aspaper-server}/src/main/java/com/infernalsuite/asp/level/ReadOnlyDimensionDataStorage.java (100%) rename {impl/aspaper-server => aspaper-server}/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java (100%) rename {impl/aspaper-server => aspaper-server}/src/main/java/com/infernalsuite/asp/level/SlimeBootstrap.java (100%) rename {impl/aspaper-server => aspaper-server}/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java (100%) rename {impl/aspaper-server => aspaper-server}/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java (100%) rename {impl/aspaper-server => aspaper-server}/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java (100%) rename {impl/aspaper-server => aspaper-server}/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java (100%) rename {impl/aspaper-server => aspaper-server}/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java (100%) rename {impl/aspaper-server => aspaper-server}/src/main/java/com/infernalsuite/asp/util/NmsUtil.java (100%) rename {impl/aspaper-server => aspaper-server}/src/main/resources/META-INF/services/com.infernalsuite.asp.api.AdvancedSlimePaperAPI (100%) rename {impl/aspaper-server => aspaper-server}/src/main/resources/META-INF/services/com.infernalsuite.asp.api.SlimeNMSBridge (100%) rename {impl/build-data => build-data}/aspaper.at (100%) rename {impl/build-data => build-data}/dev-imports.txt (100%) delete mode 100644 gradle/platform/build.gradle.kts delete mode 100644 impl/build.gradle.kts diff --git a/.gitignore b/.gitignore index 79bbf2a7a..56d01e2ab 100644 --- a/.gitignore +++ b/.gitignore @@ -8,10 +8,10 @@ build/ **/*.iml -impl/aspaper-server/build.gradle.kts -impl/aspaper-server/src/minecraft/ -impl/paper-server/ -impl/aspaper-api/build.gradle.kts -impl/paper-api/ -impl/paper-api-generator/ -/impl/aspaper-server/.gradle/ +aspaper-server/build.gradle.kts +aspaper-server/src/minecraft/ +paper-server/ +aspaper-api/build.gradle.kts +paper-api/ +paper-api-generator/ +aspaper-server/.gradle/ diff --git a/impl/aspaper-api/build.gradle.kts.patch b/aspaper-api/build.gradle.kts.patch similarity index 96% rename from impl/aspaper-api/build.gradle.kts.patch rename to aspaper-api/build.gradle.kts.patch index 48232e356..33a97d1b5 100644 --- a/impl/aspaper-api/build.gradle.kts.patch +++ b/aspaper-api/build.gradle.kts.patch @@ -14,7 +14,7 @@ } -val generatedApiPath: java.nio.file.Path = layout.projectDirectory.dir("src/generated/java").asFile.toPath() -+val generatedApiPath: java.nio.file.Path = rootProject.layout.projectDirectory.dir("impl/paper-api/src/generated/java").asFile.toPath() ++val generatedApiPath: java.nio.file.Path = rootProject.layout.projectDirectory.dir("paper-api/src/generated/java").asFile.toPath() idea { module { generatedSourceDirs.add(generatedApiPath.toFile()) diff --git a/impl/aspaper-api/paper-patches/features/0001-API-Branding.patch b/aspaper-api/paper-patches/features/0001-API-Branding.patch similarity index 100% rename from impl/aspaper-api/paper-patches/features/0001-API-Branding.patch rename to aspaper-api/paper-patches/features/0001-API-Branding.patch diff --git a/impl/aspaper-server/build.gradle.kts.patch b/aspaper-server/build.gradle.kts.patch similarity index 92% rename from impl/aspaper-server/build.gradle.kts.patch rename to aspaper-server/build.gradle.kts.patch index f3b863a4e..35b337a9e 100644 --- a/impl/aspaper-server/build.gradle.kts.patch +++ b/aspaper-server/build.gradle.kts.patch @@ -1,12 +1,10 @@ --- a/paper-server/build.gradle.kts +++ b/paper-server/build.gradle.kts -@@ -21,6 +_,19 @@ +@@ -21,6 +_,17 @@ // macheOldPath = file("F:\\Projects\\PaperTooling\\mache\\versions\\1.21.4\\src\\main\\java") // gitFilePatches = true -+ val fork = forks.register("aspaper") { -+ rootDirectory = project.rootProject.layout.projectDirectory.dir("impl") -+ ++ val aspaper = forks.register("aspaper") { + upstream.patchDir("paperServer") { + upstreamPath = "paper-server" + excludes = setOf("src/minecraft", "patches", "build.gradle.kts") @@ -15,7 +13,7 @@ + } + } + -+ activeFork = fork ++ activeFork = aspaper + spigot { buildDataRef = "3edaf46ec1eed4115ce1b18d2846cded42577e42" @@ -47,7 +45,7 @@ dependencies { - implementation(project(":paper-api")) -+ implementation(project(":impl:aspaper-api")) //ASP ++ implementation(project(":aspaper-api")) //ASP + implementation(project(":core")) //ASP + implementation("commons-io:commons-io:2.11.0") implementation("ca.spottedleaf:concurrentutil:0.0.3") diff --git a/impl/aspaper-server/minecraft-patches/features/0001-Disable-dragon-battle.patch b/aspaper-server/minecraft-patches/features/0001-Disable-dragon-battle.patch similarity index 100% rename from impl/aspaper-server/minecraft-patches/features/0001-Disable-dragon-battle.patch rename to aspaper-server/minecraft-patches/features/0001-Disable-dragon-battle.patch diff --git a/impl/aspaper-server/minecraft-patches/features/0002-World-overrides.patch b/aspaper-server/minecraft-patches/features/0002-World-overrides.patch similarity index 100% rename from impl/aspaper-server/minecraft-patches/features/0002-World-overrides.patch rename to aspaper-server/minecraft-patches/features/0002-World-overrides.patch diff --git a/impl/aspaper-server/minecraft-patches/features/0003-Avoid-IO-call-for-UUID.patch b/aspaper-server/minecraft-patches/features/0003-Avoid-IO-call-for-UUID.patch similarity index 100% rename from impl/aspaper-server/minecraft-patches/features/0003-Avoid-IO-call-for-UUID.patch rename to aspaper-server/minecraft-patches/features/0003-Avoid-IO-call-for-UUID.patch diff --git a/impl/aspaper-server/minecraft-patches/features/0004-Prevent-config-disk-io-on-world-load.patch b/aspaper-server/minecraft-patches/features/0004-Prevent-config-disk-io-on-world-load.patch similarity index 100% rename from impl/aspaper-server/minecraft-patches/features/0004-Prevent-config-disk-io-on-world-load.patch rename to aspaper-server/minecraft-patches/features/0004-Prevent-config-disk-io-on-world-load.patch diff --git a/impl/aspaper-server/minecraft-patches/features/0005-Read-only-dimension-data-store.patch b/aspaper-server/minecraft-patches/features/0005-Read-only-dimension-data-store.patch similarity index 100% rename from impl/aspaper-server/minecraft-patches/features/0005-Read-only-dimension-data-store.patch rename to aspaper-server/minecraft-patches/features/0005-Read-only-dimension-data-store.patch diff --git a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java.patch b/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java.patch similarity index 100% rename from impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java.patch rename to aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java.patch diff --git a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch b/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch similarity index 100% rename from impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch rename to aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch diff --git a/impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch b/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch similarity index 100% rename from impl/aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch rename to aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkLoadTask.java.patch diff --git a/impl/aspaper-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch b/aspaper-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch similarity index 100% rename from impl/aspaper-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch rename to aspaper-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch diff --git a/impl/aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch b/aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch similarity index 100% rename from impl/aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch rename to aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch diff --git a/impl/aspaper-server/paper-patches/features/0001-Warning-if-people-use-old-swm-api.patch b/aspaper-server/paper-patches/features/0001-Warning-if-people-use-old-swm-api.patch similarity index 100% rename from impl/aspaper-server/paper-patches/features/0001-Warning-if-people-use-old-swm-api.patch rename to aspaper-server/paper-patches/features/0001-Warning-if-people-use-old-swm-api.patch diff --git a/impl/aspaper-server/paper-patches/features/0002-Warning-if-people-use-old-swm-plugin.patch b/aspaper-server/paper-patches/features/0002-Warning-if-people-use-old-swm-plugin.patch similarity index 100% rename from impl/aspaper-server/paper-patches/features/0002-Warning-if-people-use-old-swm-plugin.patch rename to aspaper-server/paper-patches/features/0002-Warning-if-people-use-old-swm-plugin.patch diff --git a/impl/aspaper-server/paper-patches/features/0003-Branding.patch b/aspaper-server/paper-patches/features/0003-Branding.patch similarity index 100% rename from impl/aspaper-server/paper-patches/features/0003-Branding.patch rename to aspaper-server/paper-patches/features/0003-Branding.patch diff --git a/impl/aspaper-server/paper-patches/features/0004-Delete-temp-folder-after-world-is-unloaded.patch b/aspaper-server/paper-patches/features/0004-Delete-temp-folder-after-world-is-unloaded.patch similarity index 100% rename from impl/aspaper-server/paper-patches/features/0004-Delete-temp-folder-after-world-is-unloaded.patch rename to aspaper-server/paper-patches/features/0004-Delete-temp-folder-after-world-is-unloaded.patch diff --git a/impl/aspaper-server/paper-patches/features/0005-Prevent-config-disk-io-on-world-load.patch b/aspaper-server/paper-patches/features/0005-Prevent-config-disk-io-on-world-load.patch similarity index 100% rename from impl/aspaper-server/paper-patches/features/0005-Prevent-config-disk-io-on-world-load.patch rename to aspaper-server/paper-patches/features/0005-Prevent-config-disk-io-on-world-load.patch diff --git a/impl/aspaper-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/CraftServer.java.patch b/aspaper-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/CraftServer.java.patch similarity index 100% rename from impl/aspaper-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/CraftServer.java.patch rename to aspaper-server/paper-patches/files/src/main/java/org/bukkit/craftbukkit/CraftServer.java.patch diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java b/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java similarity index 100% rename from impl/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java rename to aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/Converter.java b/aspaper-server/src/main/java/com/infernalsuite/asp/Converter.java similarity index 100% rename from impl/aspaper-server/src/main/java/com/infernalsuite/asp/Converter.java rename to aspaper-server/src/main/java/com/infernalsuite/asp/Converter.java diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/InternalPlugin.java b/aspaper-server/src/main/java/com/infernalsuite/asp/InternalPlugin.java similarity index 100% rename from impl/aspaper-server/src/main/java/com/infernalsuite/asp/InternalPlugin.java rename to aspaper-server/src/main/java/com/infernalsuite/asp/InternalPlugin.java diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java similarity index 100% rename from impl/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java rename to aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java similarity index 100% rename from impl/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java rename to aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/config/SlimePaperWorldConfig.java b/aspaper-server/src/main/java/com/infernalsuite/asp/config/SlimePaperWorldConfig.java similarity index 100% rename from impl/aspaper-server/src/main/java/com/infernalsuite/asp/config/SlimePaperWorldConfig.java rename to aspaper-server/src/main/java/com/infernalsuite/asp/config/SlimePaperWorldConfig.java diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java b/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java similarity index 100% rename from impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java rename to aspaper-server/src/main/java/com/infernalsuite/asp/level/ChunkDataLoadTask.java diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java b/aspaper-server/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java similarity index 100% rename from impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java rename to aspaper-server/src/main/java/com/infernalsuite/asp/level/CommonLoadTask.java diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java b/aspaper-server/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java similarity index 100% rename from impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java rename to aspaper-server/src/main/java/com/infernalsuite/asp/level/FastChunkPruner.java diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java b/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java similarity index 100% rename from impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java rename to aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ReadOnlyDimensionDataStorage.java b/aspaper-server/src/main/java/com/infernalsuite/asp/level/ReadOnlyDimensionDataStorage.java similarity index 100% rename from impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/ReadOnlyDimensionDataStorage.java rename to aspaper-server/src/main/java/com/infernalsuite/asp/level/ReadOnlyDimensionDataStorage.java diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java b/aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java similarity index 100% rename from impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java rename to aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeBootstrap.java b/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeBootstrap.java similarity index 100% rename from impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeBootstrap.java rename to aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeBootstrap.java diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java b/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java similarity index 100% rename from impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java rename to aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java b/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java similarity index 100% rename from impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java rename to aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkLevel.java diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java similarity index 100% rename from impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java rename to aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java b/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java similarity index 100% rename from impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java rename to aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelGenerator.java diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java similarity index 100% rename from impl/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java rename to aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java diff --git a/impl/aspaper-server/src/main/java/com/infernalsuite/asp/util/NmsUtil.java b/aspaper-server/src/main/java/com/infernalsuite/asp/util/NmsUtil.java similarity index 100% rename from impl/aspaper-server/src/main/java/com/infernalsuite/asp/util/NmsUtil.java rename to aspaper-server/src/main/java/com/infernalsuite/asp/util/NmsUtil.java diff --git a/impl/aspaper-server/src/main/resources/META-INF/services/com.infernalsuite.asp.api.AdvancedSlimePaperAPI b/aspaper-server/src/main/resources/META-INF/services/com.infernalsuite.asp.api.AdvancedSlimePaperAPI similarity index 100% rename from impl/aspaper-server/src/main/resources/META-INF/services/com.infernalsuite.asp.api.AdvancedSlimePaperAPI rename to aspaper-server/src/main/resources/META-INF/services/com.infernalsuite.asp.api.AdvancedSlimePaperAPI diff --git a/impl/aspaper-server/src/main/resources/META-INF/services/com.infernalsuite.asp.api.SlimeNMSBridge b/aspaper-server/src/main/resources/META-INF/services/com.infernalsuite.asp.api.SlimeNMSBridge similarity index 100% rename from impl/aspaper-server/src/main/resources/META-INF/services/com.infernalsuite.asp.api.SlimeNMSBridge rename to aspaper-server/src/main/resources/META-INF/services/com.infernalsuite.asp.api.SlimeNMSBridge diff --git a/impl/build-data/aspaper.at b/build-data/aspaper.at similarity index 100% rename from impl/build-data/aspaper.at rename to build-data/aspaper.at diff --git a/impl/build-data/dev-imports.txt b/build-data/dev-imports.txt similarity index 100% rename from impl/build-data/dev-imports.txt rename to build-data/dev-imports.txt diff --git a/build.gradle.kts b/build.gradle.kts index e69de29bb..6249f1aa3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -0,0 +1,71 @@ +import org.gradle.api.tasks.testing.logging.TestExceptionFormat +import org.gradle.api.tasks.testing.logging.TestLogEvent + +plugins { + java + id("io.papermc.paperweight.patcher") +} + +paperweight { + upstreams.paper { + ref = providers.gradleProperty("paperRef") + + // Setup file patches for build scripts + patchFile { + path = "paper-api/build.gradle.kts" + outputFile = file("aspaper-api/build.gradle.kts") + patchFile = file("aspaper-api/build.gradle.kts.patch") + } + patchFile { + path = "paper-server/build.gradle.kts" + outputFile = file("aspaper-server/build.gradle.kts") + patchFile = file("aspaper-server/build.gradle.kts.patch") + } + + patchDir("paperApi") { + upstreamPath = "paper-api" + excludes = setOf("build.gradle.kts") + patchesDir = file("aspaper-api/paper-patches") + outputDir = file("paper-api") + } + } +} + +subprojects { + apply(plugin = "java-library") + apply(plugin = "maven-publish") + + extensions.configure { + toolchain { + languageVersion = JavaLanguageVersion.of(JAVA_VERSION) + } + } + + repositories { + mavenCentral() + maven(PAPER_MAVEN_PUBLIC_URL) + } + + tasks.withType().configureEach { + isPreserveFileTimestamps = false + isReproducibleFileOrder = true + } + tasks.withType { + options.encoding = Charsets.UTF_8.name() + options.release = JAVA_VERSION + options.isFork = true + } + tasks.withType { + options.encoding = Charsets.UTF_8.name() + } + tasks.withType { + filteringCharset = Charsets.UTF_8.name() + } + tasks.withType { + testLogging { + showStackTraces = true + exceptionFormat = TestExceptionFormat.FULL + events(TestLogEvent.STANDARD_OUT) + } + } +} diff --git a/core/build.gradle.kts b/core/build.gradle.kts index ad5d0e7fc..d981c5b8d 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -5,7 +5,7 @@ plugins { dependencies { compileOnly(project(":api")) - compileOnly(project(":impl:aspaper-api")) + compileOnly(project(":aspaper-api")) implementation(libs.zstd) } diff --git a/gradle/platform/build.gradle.kts b/gradle/platform/build.gradle.kts deleted file mode 100644 index e0f923aa7..000000000 --- a/gradle/platform/build.gradle.kts +++ /dev/null @@ -1,26 +0,0 @@ -plugins { - `java-platform` -} - -javaPlatform { - allowDependencies() -} - -dependencies { - constraints { - api(libs.adventure.nbt) - api(libs.auto.service) - api(libs.auto.service.annotations) - api(libs.bstats) - api(platform(libs.cloud.bom)) - api(platform(libs.cloud.minecraft.bom)) - api(libs.configurate.core) - api(libs.configurate.yaml) - api(libs.hikari) - api(libs.lettuce) - api(libs.lombok) - api(libs.mongo) - api(libs.slf4j.api) - api(libs.zstd) - } -} diff --git a/impl/build.gradle.kts b/impl/build.gradle.kts deleted file mode 100644 index 0d8ee5411..000000000 --- a/impl/build.gradle.kts +++ /dev/null @@ -1,75 +0,0 @@ -import org.gradle.api.tasks.testing.logging.TestExceptionFormat -import org.gradle.api.tasks.testing.logging.TestLogEvent - -plugins { - java - id("io.papermc.paperweight.patcher") -} - -paperweight { - upstreams.paper { - ref = providers.gradleProperty("paperRef") - - // Setup file patches for build scripts - patchFile { - path = "paper-api/build.gradle.kts" - outputFile = file("aspaper-api/build.gradle.kts") - patchFile = file("aspaper-api/build.gradle.kts.patch") - } - patchFile { - path = "paper-server/build.gradle.kts" - outputFile = file("aspaper-server/build.gradle.kts") - patchFile = file("aspaper-server/build.gradle.kts.patch") - } - - patchDir("paperApi") { - upstreamPath = "paper-api" - excludes = setOf("build.gradle.kts") - patchesDir = file("aspaper-api/paper-patches") - outputDir = file("paper-api") - } - } -} - -subprojects { - apply(plugin = "java-library") - apply(plugin = "maven-publish") - - extensions.configure { - toolchain { - languageVersion = JavaLanguageVersion.of(JAVA_VERSION) - } - } - - repositories { - mavenCentral() - maven(PAPER_MAVEN_PUBLIC_URL) - } - - dependencies { -// "testRuntimeOnly"("org.junit.platform:junit-platform-launcher") - } - - tasks.withType().configureEach { - isPreserveFileTimestamps = false - isReproducibleFileOrder = true - } - tasks.withType { - options.encoding = Charsets.UTF_8.name() - options.release = JAVA_VERSION - options.isFork = true - } - tasks.withType { - options.encoding = Charsets.UTF_8.name() - } - tasks.withType { - filteringCharset = Charsets.UTF_8.name() - } - tasks.withType { - testLogging { - showStackTraces = true - exceptionFormat = TestExceptionFormat.FULL - events(TestLogEvent.STANDARD_OUT) - } - } -} diff --git a/importer/build.gradle.kts b/importer/build.gradle.kts index 4adf78e7a..fda4eb5ff 100644 --- a/importer/build.gradle.kts +++ b/importer/build.gradle.kts @@ -6,7 +6,7 @@ plugins { dependencies { implementation(project(":api")) implementation(project(":core")) - implementation(project(":impl:aspaper-api")) + implementation(project(":aspaper-api")) } tasks { diff --git a/settings.gradle.kts b/settings.gradle.kts index c38b3ec81..ccd12612a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -19,9 +19,8 @@ include(":core") include(":importer") include(":loaders") include(":plugin") -include(":impl") -include(":impl:aspaper-api") -include(":impl:aspaper-server") +include(":aspaper-api") +include(":aspaper-server") include("loaders:mongo-loader") findProject(":loaders:mongo-loader")?.name = "mongo-loader" From 42f887016868423a2f7c0c3ab2a2158c983191eb Mon Sep 17 00:00:00 2001 From: David Mayr Date: Tue, 25 Mar 2025 17:53:46 +0100 Subject: [PATCH 120/133] fix: remove archive classifier from shadowjar for importer Signed-off-by: David Mayr --- importer/build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/importer/build.gradle.kts b/importer/build.gradle.kts index fda4eb5ff..b69b82191 100644 --- a/importer/build.gradle.kts +++ b/importer/build.gradle.kts @@ -16,6 +16,7 @@ tasks { } } shadowJar { + archiveClassifier.set("") minimize() } assemble { From 89a9b21ae6ef9a4cb26dcb166c6fbb6c83c6ea8d Mon Sep 17 00:00:00 2001 From: David Mayr Date: Wed, 26 Mar 2025 18:52:12 +0100 Subject: [PATCH 121/133] fix: entity chunk importing Signed-off-by: David Mayr --- .../serialization/anvil/AnvilWorldReader.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java b/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java index 38b7c03d5..7a9820249 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java @@ -255,7 +255,21 @@ private static void readEntityChunk(CompoundBinaryTag compound, int worldVersion if (chunk == null) { LOGGER.warn("Lost entity chunk data at: {},{}", chunkX, chunkZ); } else { - compound.getList("Entities", BinaryTagTypes.COMPOUND).forEach(entityTag -> chunk.getEntities().add((CompoundBinaryTag) entityTag)); + List entities = new ArrayList<>(chunk.getEntities()); + for (BinaryTag binaryTag : compound.getList("Entities", BinaryTagTypes.COMPOUND)) { + entities.add((CompoundBinaryTag) binaryTag); + } + + slimeChunkMap.put(Util.chunkPosition(chunkX, chunkZ), new SlimeChunkSkeleton( + chunk.getX(), + chunk.getZ(), + chunk.getSections(), + chunk.getHeightMaps(), + chunk.getTileEntities(), + entities, + chunk.getExtraData(), + chunk.getUpgradeData() + )); } } From dc95a8187eb86a5c3d7379f77974ebdd76d25735 Mon Sep 17 00:00:00 2001 From: David Date: Tue, 8 Apr 2025 07:52:37 +0200 Subject: [PATCH 122/133] fix: npe on plugin disable (Closes #156) Signed-off-by: David --- .../main/java/com/infernalsuite/asp/plugin/SWPlugin.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugin/src/main/java/com/infernalsuite/asp/plugin/SWPlugin.java b/plugin/src/main/java/com/infernalsuite/asp/plugin/SWPlugin.java index 600e8cb63..7f85212f9 100644 --- a/plugin/src/main/java/com/infernalsuite/asp/plugin/SWPlugin.java +++ b/plugin/src/main/java/com/infernalsuite/asp/plugin/SWPlugin.java @@ -104,12 +104,15 @@ public void onDisable() { for (Map.Entry entry : config.getWorlds().entrySet()) { SlimeWorld world = ASP.getLoadedWorld(entry.getKey()); + if(world == null) { + continue; + } - if (world != null && !world.isReadOnly()) { + if (!world.isReadOnly()) { try { ASP.saveWorld(world); //Save the world sync } catch (RuntimeException | IOException ex) { - getLogger().log(Level.SEVERE, "Failed to unload world " + world.getName(), ex); + getLogger().log(Level.SEVERE, "Failed to save world " + world.getName(), ex); } } Bukkit.unloadWorld(world.getName(), false); //Unload without saving as we have just saved (if not read only) From 3d8f04c1e64be6bb563f041b72f8a68002af0743 Mon Sep 17 00:00:00 2001 From: David Date: Tue, 8 Apr 2025 08:02:56 +0200 Subject: [PATCH 123/133] Revert "chore(core): remove legacy SRF support" This reverts commit 699f99a53716b9eccd47af98a163edfbf61b1fc1. --- .../reader/SlimeWorldReaderRegistry.java | 6 + .../impl/v10/v10SlimeWorldDeSerializer.java | 205 ++++++++ .../slime/reader/impl/v10/v10WorldFormat.java | 8 + .../impl/v11/v11SlimeWorldDeSerializer.java | 159 ++++++ .../slime/reader/impl/v11/v11WorldFormat.java | 7 + .../slime/reader/impl/v1_9/Upgrade.java | 7 + .../impl/v1_9/upgrade/v1_11WorldUpgrade.java | 69 +++ .../impl/v1_9/upgrade/v1_13WorldUpgrade.java | 107 ++++ .../impl/v1_9/upgrade/v1_14WorldUpgrade.java | 199 ++++++++ .../impl/v1_9/upgrade/v1_16WorldUpgrade.java | 131 +++++ .../impl/v1_9/upgrade/v1_17WorldUpgrade.java | 48 ++ .../impl/v1_9/upgrade/v1_18WorldUpgrade.java | 360 +++++++++++++ .../impl/v1_9/upgrade/v1_9WorldUpgrade.java | 51 ++ .../reader/impl/v1_9/v1_9SlimeChunk.java | 45 ++ .../impl/v1_9/v1_9SlimeChunkSection.java | 35 ++ .../reader/impl/v1_9/v1_9SlimeWorld.java | 35 ++ .../impl/v1_9/v1_9SlimeWorldDeserializer.java | 480 ++++++++++++++++++ .../reader/impl/v1_9/v1_9WorldFormat.java | 7 + .../reader/impl/v1_9/v1_v9SlimeConverter.java | 131 +++++ 19 files changed, 2090 insertions(+) create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10WorldFormat.java create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11WorldFormat.java create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/Upgrade.java create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9WorldFormat.java create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java index 67ecd8a7c..f8f19e057 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java @@ -6,7 +6,10 @@ import com.infernalsuite.asp.api.utils.SlimeFormat; import com.infernalsuite.asp.api.world.SlimeWorld; import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.serialization.slime.reader.impl.v11.v11WorldFormat; import com.infernalsuite.asp.serialization.slime.reader.impl.v12.v12WorldFormat; +import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9WorldFormat; +import com.infernalsuite.asp.serialization.slime.reader.impl.v10.v10WorldFormat; import java.io.ByteArrayInputStream; import java.io.DataInputStream; @@ -20,6 +23,9 @@ public class SlimeWorldReaderRegistry { private static final Map> FORMATS = new HashMap<>(); static { + register(v1_9WorldFormat.FORMAT, 1, 2, 3, 4, 5, 6, 7, 8, 9); + register(v10WorldFormat.FORMAT, 10); + register(v11WorldFormat.FORMAT, 11); register(v12WorldFormat.FORMAT, 12); } diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java new file mode 100644 index 000000000..3baf1fb1b --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java @@ -0,0 +1,205 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v10; + +import com.flowpowered.nbt.CompoundMap; +import com.flowpowered.nbt.CompoundTag; +import com.flowpowered.nbt.DoubleTag; +import com.flowpowered.nbt.IntTag; +import com.flowpowered.nbt.ListTag; +import com.flowpowered.nbt.stream.NBTInputStream; +import com.github.luben.zstd.Zstd; +import com.infernalsuite.asp.Util; +import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.serialization.slime.reader.VersionedByteSlimeWorldReader; +import com.infernalsuite.asp.api.utils.NibbleArray; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeChunkSection; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.properties.SlimeProperties; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; + +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + + +class v10SlimeWorldDeSerializer implements VersionedByteSlimeWorldReader { + + public static final int ARRAY_SIZE = 16 * 16 * 16 / (8 / 4); // blocks / bytes per block + + @SuppressWarnings("unchecked") + @Override + public SlimeWorld deserializeWorld(byte version, SlimeLoader loader, String worldName, DataInputStream dataStream, SlimePropertyMap propertyMap, boolean readOnly) + throws IOException, CorruptedWorldException { + + // World version + int worldVersion = dataStream.readInt(); + // Chunk Data + + byte[] chunkBytes = readCompressed(dataStream); + Long2ObjectMap chunks = readChunks(propertyMap, chunkBytes); + + byte[] tileEntities = readCompressed(dataStream); + byte[] entities = readCompressed(dataStream); + byte[] extra = readCompressed(dataStream); + + // Entity deserialization + com.flowpowered.nbt.CompoundTag entitiesCompound = readCompound(entities); + { + List serializedEntities = ((ListTag) entitiesCompound.getValue().get("entities")).getValue(); + for (CompoundTag entityCompound : serializedEntities) { + ListTag listTag = (ListTag) entityCompound.getAsListTag("Pos").get(); + + int chunkX = listTag.getValue().get(0).getValue().intValue() >> 4; + int chunkZ = listTag.getValue().get(2).getValue().intValue() >> 4; + long chunkKey = Util.chunkPosition(chunkX, chunkZ); + SlimeChunk chunk = chunks.get(chunkKey); + if (chunk != null) { + chunk.getEntities().add(entityCompound); + } + } + } + + // Tile Entity deserialization + com.flowpowered.nbt.CompoundTag tileEntitiesCompound = readCompound(tileEntities); + for (CompoundTag tileEntityCompound : ((com.flowpowered.nbt.ListTag) tileEntitiesCompound.getValue().get("tiles")).getValue()) { + int chunkX = ((IntTag) tileEntityCompound.getValue().get("x")).getValue() >> 4; + int chunkZ = ((IntTag) tileEntityCompound.getValue().get("z")).getValue() >> 4; + long pos = Util.chunkPosition(chunkX, chunkZ); + SlimeChunk chunk = chunks.get(pos); + + if (chunk == null) { + throw new CorruptedWorldException(worldName); + } + + chunk.getTileEntities().add(tileEntityCompound); + } + + // Extra Data + com.flowpowered.nbt.CompoundTag extraCompound = readCompound(extra); + + // World properties + SlimePropertyMap worldPropertyMap = propertyMap; + Optional propertiesMap = extraCompound + .getAsCompoundTag("properties") + .map(com.flowpowered.nbt.CompoundTag::getValue); + + if (propertiesMap.isPresent()) { + worldPropertyMap = new SlimePropertyMap(propertiesMap.get()); + worldPropertyMap.merge(propertyMap); // Override world properties + } + + return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld(worldName, loader, readOnly, chunks, + extraCompound, + worldPropertyMap, + worldVersion + ); + } + + private static Long2ObjectMap readChunks(SlimePropertyMap slimePropertyMap, byte[] bytes) throws IOException { + Long2ObjectMap chunkMap = new Long2ObjectOpenHashMap<>(); + DataInputStream chunkData = new DataInputStream(new ByteArrayInputStream(bytes)); + + int chunks = chunkData.readInt(); + for (int i = 0; i < chunks; i++) { + // coords + int x = chunkData.readInt(); + int z = chunkData.readInt(); + + // Height Maps + byte[] heightMapData = new byte[chunkData.readInt()]; + chunkData.read(heightMapData); + com.flowpowered.nbt.CompoundTag heightMaps = readCompound(heightMapData); + + // Chunk Sections + { + // See WorldUtils + int sectionAmount = slimePropertyMap.getValue(SlimeProperties.CHUNK_SECTION_MAX) - slimePropertyMap.getValue(SlimeProperties.CHUNK_SECTION_MIN) + 1; + SlimeChunkSection[] chunkSectionArray = new SlimeChunkSection[sectionAmount]; + + int sectionCount = chunkData.readInt(); + for (int sectionId = 0; sectionId < sectionCount; sectionId++) { + // Block Light Nibble Array + NibbleArray blockLightArray; + if (chunkData.readBoolean()) { + byte[] blockLightByteArray = new byte[ARRAY_SIZE]; + chunkData.read(blockLightByteArray); + blockLightArray = new NibbleArray(blockLightByteArray); + } else { + blockLightArray = null; + } + + // Sky Light Nibble Array + NibbleArray skyLightArray; + if (chunkData.readBoolean()) { + byte[] skyLightByteArray = new byte[ARRAY_SIZE]; + chunkData.read(skyLightByteArray); + skyLightArray = new NibbleArray(skyLightByteArray); + } else { + skyLightArray = null; + } + + // Block data + byte[] blockStateData = new byte[chunkData.readInt()]; + chunkData.read(blockStateData); + com.flowpowered.nbt.CompoundTag blockStateTag = readCompound(blockStateData); + + // Biome Data + byte[] biomeData = new byte[chunkData.readInt()]; + chunkData.read(biomeData); + com.flowpowered.nbt.CompoundTag biomeTag = readCompound(biomeData); + + chunkSectionArray[sectionId] = new com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton( + blockStateTag, + biomeTag, + blockLightArray, + skyLightArray); + } + + chunkMap.put(Util.chunkPosition(x, z), + new com.infernalsuite.asp.skeleton.SlimeChunkSkeleton(x, z, chunkSectionArray, heightMaps, new ArrayList<>(), new ArrayList<>(), new CompoundTag("", new CompoundMap()), null) + ); + } + } + + return chunkMap; + } + + private static int[] toIntArray(byte[] buf) { + ByteBuffer buffer = ByteBuffer.wrap(buf).order(ByteOrder.BIG_ENDIAN); + int[] ret = new int[buf.length / 4]; + + buffer.asIntBuffer().get(ret); + + return ret; + } + + private static byte[] readCompressed(DataInputStream stream) throws IOException { + int compressedLength = stream.readInt(); + int normalLength = stream.readInt(); + byte[] compressed = new byte[compressedLength]; + byte[] normal = new byte[normalLength]; + + stream.read(compressed); + Zstd.decompress(normal, compressed); + return normal; + } + + private static com.flowpowered.nbt.CompoundTag readCompound(byte[] bytes) throws IOException { + if (bytes.length == 0) { + return null; + } + + NBTInputStream stream = new NBTInputStream(new ByteArrayInputStream(bytes), NBTInputStream.NO_COMPRESSION, ByteOrder.BIG_ENDIAN); + return (com.flowpowered.nbt.CompoundTag) stream.readTag(); + } + + +} \ No newline at end of file diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10WorldFormat.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10WorldFormat.java new file mode 100644 index 000000000..033377a17 --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10WorldFormat.java @@ -0,0 +1,8 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v10; + +public interface v10WorldFormat { + + // Latest, returns same + com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat FORMAT = new com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat<>(data -> data, new v10SlimeWorldDeSerializer()); + +} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java new file mode 100644 index 000000000..5e664d1d2 --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java @@ -0,0 +1,159 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v11; + +import com.flowpowered.nbt.CompoundMap; +import com.flowpowered.nbt.CompoundTag; +import com.flowpowered.nbt.ListTag; +import com.flowpowered.nbt.stream.NBTInputStream; +import com.github.luben.zstd.Zstd; +import com.infernalsuite.asp.Util; +import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; +import com.infernalsuite.asp.api.exceptions.NewerFormatException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.utils.NibbleArray; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeChunkSection; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.properties.SlimeProperties; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import org.jetbrains.annotations.Nullable; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.nio.ByteOrder; +import java.util.List; +import java.util.Optional; + +public class v11SlimeWorldDeSerializer implements com.infernalsuite.asp.serialization.slime.reader.VersionedByteSlimeWorldReader { + + public static final int ARRAY_SIZE = 16 * 16 * 16 / (8 / 4); + + @Override + public SlimeWorld deserializeWorld(byte version, @Nullable SlimeLoader loader, String worldName, DataInputStream dataStream, SlimePropertyMap propertyMap, boolean readOnly) throws IOException, CorruptedWorldException, NewerFormatException { + int worldVersion = dataStream.readInt(); + + byte[] chunkBytes = readCompressed(dataStream); + Long2ObjectMap chunks = readChunks(propertyMap, chunkBytes); + + byte[] extraTagBytes = readCompressed(dataStream); + CompoundTag extraTag = readCompound(extraTagBytes); + + SlimePropertyMap worldPropertyMap = propertyMap; + Optional propertiesMap = extraTag + .getAsCompoundTag("properties") + .map(CompoundTag::getValue); + + if (propertiesMap.isPresent()) { + worldPropertyMap = new SlimePropertyMap(propertiesMap.get()); + worldPropertyMap.merge(propertyMap); + } + + return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld(worldName, loader, readOnly, chunks, extraTag, worldPropertyMap, worldVersion); + } + + private static Long2ObjectMap readChunks(SlimePropertyMap slimePropertyMap, byte[] chunkBytes) throws IOException { + Long2ObjectMap chunkMap = new Long2ObjectOpenHashMap<>(); + DataInputStream chunkData = new DataInputStream(new ByteArrayInputStream(chunkBytes)); + + int chunks = chunkData.readInt(); + for (int i = 0; i < chunks; i++) { + // ChunkPos + int x = chunkData.readInt(); + int z = chunkData.readInt(); + + // Sections + int sectionAmount = slimePropertyMap.getValue(SlimeProperties.CHUNK_SECTION_MAX) - slimePropertyMap.getValue(SlimeProperties.CHUNK_SECTION_MIN) + 1; + SlimeChunkSection[] chunkSections = new SlimeChunkSection[sectionAmount]; + + int sectionCount = chunkData.readInt(); + for (int sectionId = 0; sectionId < sectionCount; sectionId++) { + + // Block Light Nibble Array + NibbleArray blockLightArray; + if (chunkData.readBoolean()) { + byte[] blockLightByteArray = new byte[ARRAY_SIZE]; + chunkData.read(blockLightByteArray); + blockLightArray = new NibbleArray(blockLightByteArray); + } else { + blockLightArray = null; + } + + // Sky Light Nibble Array + NibbleArray skyLightArray; + if (chunkData.readBoolean()) { + byte[] skyLightByteArray = new byte[ARRAY_SIZE]; + chunkData.read(skyLightByteArray); + skyLightArray = new NibbleArray(skyLightByteArray); + } else { + skyLightArray = null; + } + + // Block Data + byte[] blockStateData = new byte[chunkData.readInt()]; + chunkData.read(blockStateData); + CompoundTag blockStateTag = readCompound(blockStateData); + + // Biome Data + byte[] biomeData = new byte[chunkData.readInt()]; + chunkData.read(biomeData); + CompoundTag biomeTag = readCompound(biomeData); + + chunkSections[sectionId] = new com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton(blockStateTag, biomeTag, blockLightArray, skyLightArray); + } + + // HeightMaps + byte[] heightMapData = new byte[chunkData.readInt()]; + chunkData.read(heightMapData); + CompoundTag heightMaps = readCompound(heightMapData); + + // Tile Entities + + int compressedTileEntitiesLength = chunkData.readInt(); + int decompressedTileEntitiesLength = chunkData.readInt(); + byte[] compressedTileEntitiesData = new byte[compressedTileEntitiesLength]; + byte[] decompressedTileEntitiesData = new byte[decompressedTileEntitiesLength]; + chunkData.read(compressedTileEntitiesData); + Zstd.decompress(decompressedTileEntitiesData, compressedTileEntitiesData); + + CompoundTag tileEntitiesCompound = readCompound(decompressedTileEntitiesData); + @SuppressWarnings("unchecked") + List serializedTileEntities = ((ListTag) tileEntitiesCompound.getValue().get("tileEntities")).getValue(); + + // Entities + + int compressedEntitiesLength = chunkData.readInt(); + int decompressedEntitiesLength = chunkData.readInt(); + byte[] compressedEntitiesData = new byte[compressedEntitiesLength]; + byte[] decompressedEntitiesData = new byte[decompressedEntitiesLength]; + chunkData.read(compressedEntitiesData); + Zstd.decompress(decompressedEntitiesData, compressedEntitiesData); + + CompoundTag entitiesCompound = readCompound(decompressedEntitiesData); + @SuppressWarnings("unchecked") + List serializedEntities = ((ListTag) entitiesCompound.getValue().get("entities")).getValue(); + + chunkMap.put(Util.chunkPosition(x, z), + new com.infernalsuite.asp.skeleton.SlimeChunkSkeleton(x, z, chunkSections, heightMaps, serializedTileEntities, serializedEntities, new CompoundTag("", new CompoundMap()), null)); + } + return chunkMap; + } + + private static byte[] readCompressed(DataInputStream stream) throws IOException { + int compressedLength = stream.readInt(); + int decompressedLength = stream.readInt(); + byte[] compressedData = new byte[compressedLength]; + byte[] decompressedData = new byte[decompressedLength]; + stream.read(compressedData); + Zstd.decompress(decompressedData, compressedData); + return decompressedData; + } + + private static CompoundTag readCompound(byte[] tagBytes) throws IOException { + if (tagBytes.length == 0) return null; + + NBTInputStream nbtStream = new NBTInputStream(new ByteArrayInputStream(tagBytes), NBTInputStream.NO_COMPRESSION, ByteOrder.BIG_ENDIAN); + return (CompoundTag) nbtStream.readTag(); + } +} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11WorldFormat.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11WorldFormat.java new file mode 100644 index 000000000..779eeb28b --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11WorldFormat.java @@ -0,0 +1,7 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v11; + +public interface v11WorldFormat { + + com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat FORMAT = new com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat<>(data -> data, new v11SlimeWorldDeSerializer()); + +} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/Upgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/Upgrade.java new file mode 100644 index 000000000..62f4254e6 --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/Upgrade.java @@ -0,0 +1,7 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; + +public interface Upgrade { + + void upgrade(v1_9SlimeWorld world); + +} \ No newline at end of file diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java new file mode 100644 index 000000000..4e35d3ddd --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java @@ -0,0 +1,69 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; + +import com.flowpowered.nbt.CompoundTag; +import com.flowpowered.nbt.StringTag; + +import java.util.HashMap; +import java.util.Map; + +public class v1_11WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { + + private static Map oldToNewMap = new HashMap<>(); + private static Map newToOldMap = new HashMap<>(); + + static { + rename("Furnace", "minecraft:furnace"); + rename("Chest", "minecraft:chest"); + rename("EnderChest", "minecraft:ender_chest"); + rename("RecordPlayer", "minecraft:jukebox"); + rename("Trap", "minecraft:dispenser"); + rename("Dropper", "minecraft:dropper"); + rename("Sign", "minecraft:sign"); + rename("MobSpawner", "minecraft:mob_spawner"); + rename("Music", "minecraft:noteblock"); + rename("Piston", "minecraft:piston"); + rename("Cauldron", "minecraft:brewing_stand"); + rename("EnchantTable", "minecraft:enchanting_table"); + rename("Airportal", "minecraft:end_portal"); + rename("Beacon", "minecraft:beacon"); + rename("Skull", "minecraft:skull"); + rename("DLDetector", "minecraft:daylight_detector"); + rename("Hopper", "minecraft:hopper"); + rename("Comparator", "minecraft:comparator"); + rename("FlowerPot", "minecraft:flower_pot"); + rename("Banner", "minecraft:banner"); + rename("Structure", "minecraft:structure_block"); + rename("EndGateway", "minecraft:end_gateway"); + rename("Control", "minecraft:command_block"); + rename(null, "minecraft:bed"); // Patch for issue s#62 + } + + private static void rename(String oldName, String newName) { + if (oldName != null) { + oldToNewMap.put(oldName, newName); + } + + newToOldMap.put(newName, oldName); + } + + @Override + public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld world) { + // 1.11 changed the way Tile Entities are named + for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : world.chunks.values()) { + for (CompoundTag entityTag : chunk.tileEntities) { + String oldType = entityTag.getAsStringTag("id").get().getValue(); + String newType = oldToNewMap.get(oldType); + + if (newType == null) { + if (newToOldMap.containsKey(oldType)) { // Maybe it's in the new format for some reason? + continue; + } + + throw new IllegalStateException("Failed to find 1.11 upgrade for tile entity " + oldType); + } + + entityTag.getValue().put("id", new StringTag("id", newType)); + } + } + } +} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java new file mode 100644 index 000000000..14d613582 --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java @@ -0,0 +1,107 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; + +import com.flowpowered.nbt.*; +import com.infernalsuite.asp.api.SlimeNMSBridge; +import com.infernalsuite.asp.api.utils.NibbleArray; +import org.bukkit.ChatColor; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +public class v1_13WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { + + @Override + public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld world) { + Logger.getLogger("v1_13WorldUpgrade").warning("Updating world to the 1.13 format. This may take a while."); + + List chunks = new ArrayList<>(world.chunks.values()); + long lastMessage = -1; + + for (int i = 0; i < chunks.size(); i++) { + com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk = chunks.get(i); + + // The world upgrade process is a very complex task, and there's already a + // built-in upgrade tool inside the server, so we can simply use it + CompoundTag globalTag = new CompoundTag("", new CompoundMap()); + globalTag.getValue().put("DataVersion", new IntTag("DataVersion", 1343)); + + CompoundTag chunkTag = new CompoundTag("Level", new CompoundMap()); + + chunkTag.getValue().put("xPos", new IntTag("xPos", chunk.x)); + chunkTag.getValue().put("zPos", new IntTag("zPos", chunk.z)); + chunkTag.getValue().put("Sections", serializeSections(chunk.sections)); + chunkTag.getValue().put("Entities", new ListTag<>("Entities", TagType.TAG_COMPOUND, chunk.entities)); + chunkTag.getValue().put("TileEntities", new ListTag<>("TileEntities", TagType.TAG_COMPOUND, chunk.tileEntities)); + chunkTag.getValue().put("TileTicks", new ListTag<>("TileTicks", TagType.TAG_COMPOUND, new ArrayList<>())); + chunkTag.getValue().put("TerrainPopulated", new ByteTag("TerrainPopulated", (byte) 1)); + chunkTag.getValue().put("LightPopulated", new ByteTag("LightPopulated", (byte) 1)); + + globalTag.getValue().put("Level", chunkTag); + + globalTag = SlimeNMSBridge.instance().convertChunkTo1_13(globalTag); + chunkTag = globalTag.getAsCompoundTag("Level").get(); + + // Chunk sections + com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[] newSections = new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[16]; + ListTag serializedSections = (ListTag) chunkTag.getAsListTag("Sections").get(); + + for (CompoundTag sectionTag : serializedSections.getValue()) { + ListTag palette = (ListTag) sectionTag.getAsListTag("Palette").get(); + long[] blockStates = sectionTag.getLongArrayValue("BlockStates").get(); + + NibbleArray blockLight = new NibbleArray(sectionTag.getByteArrayValue("BlockLight").get()); + NibbleArray skyLight = new NibbleArray(sectionTag.getByteArrayValue("SkyLight").get()); + + int index = sectionTag.getIntValue("Y").get(); + + com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection section = new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection(null, null, palette, blockStates, null, null, blockLight, skyLight); + newSections[index] = section; + } + + // Biomes + int[] newBiomes = new int[256]; + + for (int index = 0; index < chunk.biomes.length; index++) { + newBiomes[index] = chunk.biomes[index] & 255; + } + + chunk.sections = newSections; + chunk.biomes = newBiomes; + + // Upgrade data + chunk.upgradeData = chunkTag.getAsCompoundTag("UpgradeData").orElse(null); + + int done = i + 1; + if (done == chunks.size()) { + Logger.getLogger("v1_13WorldUpgrade").info("World successfully converted to the 1.13 format!"); + } else if (System.currentTimeMillis() - lastMessage > 1000) { + int percentage = (done * 100) / chunks.size(); + Logger.getLogger("v1_13WorldUpgrade").info("Converting world... " + percentage + "%"); + lastMessage = System.currentTimeMillis(); + } + } + } + + private ListTag serializeSections(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[] sections) { + ListTag sectionList = new ListTag<>("Sections", TagType.TAG_COMPOUND, new ArrayList<>()); + + for (int i = 0; i < sections.length; i++) { + com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection section = sections[i]; + + if (section != null) { + CompoundTag sectionTag = new CompoundTag(i + "", new CompoundMap()); + + sectionTag.getValue().put("Y", new IntTag("Y", i)); + sectionTag.getValue().put("Blocks", new ByteArrayTag("Blocks", section.blocks)); + sectionTag.getValue().put("Data", new ByteArrayTag("Data", section.data.getBacking())); + sectionTag.getValue().put("BlockLight", new ByteArrayTag("Data", section.blockLight.getBacking())); + sectionTag.getValue().put("SkyLight", new ByteArrayTag("Data", section.skyLight.getBacking())); + + sectionList.getValue().add(sectionTag); + } + } + + return sectionList; + } +} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java new file mode 100644 index 000000000..edd60c393 --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java @@ -0,0 +1,199 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; + +import com.flowpowered.nbt.*; +import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection; +import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld; + +import java.util.*; + +public class v1_14WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { + + private static final int[] VILLAGER_XP = { 0, 10, 50, 100, 150 }; + + private static Map oldToNewMap = new HashMap<>(); + private static Map newToOldMap = new HashMap<>(); + + static { + rename("minecraft:tube_coral_fan", "minecraft:tube_coral_wall_fan"); + rename("minecraft:brain_coral_fan", "minecraft:brain_coral_wall_fan"); + rename("minecraft:bubble_coral_fan", "minecraft:bubble_coral_wall_fan"); + rename("minecraft:fire_coral_fan", "minecraft:fire_coral_wall_fan"); + rename("minecraft:horn_coral_fan", "minecraft:horn_coral_wall_fan"); + rename("minecraft:stone_slab", "minecraft:smooth_stone_slab"); + rename("minecraft:sign", "minecraft:oak_sign"); + rename("minecraft:wall_sign", "minecraft:oak_wall_sign"); + } + + private static void rename(String oldName, String newName) { + oldToNewMap.put(oldName, newName); + newToOldMap.put(newName, oldName); + } + + @Override + public void upgrade(v1_9SlimeWorld world) { + for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : new ArrayList<>(world.chunks.values())) { + // Update renamed blocks + for (int sectionIndex = 0; sectionIndex < chunk.sections.length; sectionIndex++) { + v1_9SlimeChunkSection section = chunk.sections[sectionIndex]; + + if (section != null) { + List palette = section.palette.getValue(); + + for (int paletteIndex = 0; paletteIndex < palette.size(); paletteIndex++) { + CompoundTag blockTag = palette.get(paletteIndex); + String name = blockTag.getStringValue("Name").get(); + + // Trapped chests have now a different tile entity, + // so we have to update every block entity type + if (name.equals("minecraft:trapped_chest")) { + updateBlockEntities(chunk, sectionIndex, paletteIndex, "minecraft:chest", "minecraft:trapped_chest"); + } + + String newName = oldToNewMap.get(name); + + if (newName != null) { + blockTag.getValue().put("Name", new StringTag("Name", newName)); + } + } + } + } + + if (chunk.entities != null) { + for (CompoundTag entityTag : chunk.entities) { + String type = entityTag.getStringValue("id").get(); + + switch (type) { + case "minecraft:ocelot": + // Cats are no longer ocelots + int catType = entityTag.getIntValue("CatType").orElse(0); + + if (catType == 0) { + Optional owner = entityTag.getStringValue("Owner"); + Optional ownerId = entityTag.getStringValue("OwnerUUID"); + + if (owner.isPresent() || ownerId.isPresent()) { + entityTag.getValue().put("Trusting", new ByteTag("Trusting", (byte) 1)); + } + + entityTag.getValue().remove("CatType"); + } else if (catType > 0 && catType < 4) { + entityTag.getValue().put("id", new StringTag("id", "minecraft:cat")); + } + break; + case "minecraft:villager": + case "minecraft:zombie_villager": + // Villager data has changed + int profession = entityTag.getIntValue("Profession").orElse(0); + int career = entityTag.getIntValue("Career").orElse(0); + int careerLevel = entityTag.getIntValue("CareerLevel").orElse(1); + + // Villager level and xp has to be rebuilt + Optional offersOpt = entityTag.getAsCompoundTag("Offers"); + + if (offersOpt.isPresent()) { + if (careerLevel == 0 || careerLevel == 1) { + int amount = offersOpt.flatMap((offers) -> offers.getAsCompoundTag("Recipes")).map((recipes) -> recipes.getValue().size()).orElse(0); + careerLevel = clamp(amount / 2, 1, 5); + } + } + + Optional xp = entityTag.getAsCompoundTag("Xp"); + + if (!xp.isPresent()) { + entityTag.getValue().put("Xp", new IntTag("Xp", VILLAGER_XP[clamp(careerLevel - 1, 0, VILLAGER_XP.length - 1)])); + } + + entityTag.getValue().remove("Profession"); + entityTag.getValue().remove("Career"); + entityTag.getValue().remove("CareerLevel"); + + CompoundMap dataMap = new CompoundMap(); + dataMap.put("type", new StringTag("type", "minecraft:plains")); + dataMap.put("profession", new StringTag("profession", getVillagerProfession(profession, career))); + dataMap.put("level", new IntTag("level", careerLevel)); + + entityTag.getValue().put("VillagerData", new CompoundTag("VillagerData", dataMap)); + break; + case "minecraft:banner": + // The illager banners changed the translation message + Optional customName = entityTag.getStringValue("CustomName"); + + if (customName.isPresent()) { + String newName = customName.get().replace("\"translate\":\"block.minecraft.illager_banner\"", + "\"translate\":\"block.minecraft.ominous_banner\""); + + entityTag.getValue().put("CustomName", new StringTag("CustomName", newName)); + } + break; + } + } + } + } + } + + private int clamp(int i, int i1, int i2) { + return i < i1 ? i1 : (i > i2 ? i2 : i); + } + + private String getVillagerProfession(int profession, int career) { + return profession == 0 ? (career == 2 ? "minecraft:fisherman" : (career == 3 ? "minecraft:shepherd" : (career == 4 ? "minecraft:fletcher" : "minecraft:farmer"))) + : (profession == 1 ? (career == 2 ? "minecraft:cartographer" : "minecraft:librarian") : (profession == 2 ? "minecraft:cleric" : + (profession == 3 ? (career == 2 ? "minecraft:weaponsmith" : (career == 3 ? "minecraft:toolsmith" : "minecraft:armorer")) : + (profession == 4 ? (career == 2 ? "minecraft:leatherworker" : "minecraft:butcher") : (profession == 5 ? "minecraft:nitwit" : "minecraft:none"))))); + } + + private void updateBlockEntities(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk, int sectionIndex, int paletteIndex, String oldName, String newName) { + if (chunk.tileEntities != null) { + v1_9SlimeChunkSection section = chunk.sections[sectionIndex]; + long[] blockData = section.blockStates; + + int bitsPerBlock = Math.max(4, blockData.length * 64 / 4096); + long maxEntryValue = (1L << bitsPerBlock) - 1; + + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { + int arrayIndex = y << 8 | z << 4 | x; + int bitIndex = arrayIndex * bitsPerBlock; + int startIndex = bitIndex / 64; + int endIndex = ((arrayIndex + 1) * bitsPerBlock - 1) / 64; + int startBitSubIndex = bitIndex % 64; + + int val; + + if (startIndex == endIndex) { + val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue); + } else { + int endBitSubIndex = 64 - startBitSubIndex; + val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); + } + + // It's the right block type + if (val == paletteIndex) { + int blockX = x + chunk.x * 16; + int blockY = y + sectionIndex * 16; + int blockZ = z + chunk.z * 16; + + for (CompoundTag tileEntityTag : chunk.tileEntities) { + int tileX = tileEntityTag.getIntValue("x").get(); + int tileY = tileEntityTag.getIntValue("y").get(); + int tileZ = tileEntityTag.getIntValue("z").get(); + + if (tileX == blockX && tileY == blockY && tileZ == blockZ) { + String type = tileEntityTag.getStringValue("id").get(); + + if (!type.equals(oldName)) { + throw new IllegalStateException("Expected block entity to be " + oldName + ", not " + type); + } + + tileEntityTag.getValue().put("id", new StringTag("id", newName)); + break; + } + } + } + } + } + } + } + } +} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java new file mode 100644 index 000000000..520f88142 --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java @@ -0,0 +1,131 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; + +import com.flowpowered.nbt.CompoundTag; +import com.flowpowered.nbt.LongArrayTag; +import com.flowpowered.nbt.Tag; +import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection; +import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld; + +import java.util.Arrays; + +public class v1_16WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { + + private static final int[] MULTIPLY_DE_BRUIJN_BIT_POSITION = new int[]{ + 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 + }; + + @Override + public void upgrade(v1_9SlimeWorld world) { + for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : world.chunks.values()) { + // Add padding to height maps and block states + CompoundTag heightMaps = chunk.heightMap; + + for (Tag map : heightMaps.getValue().values()) { + if (map instanceof LongArrayTag arrayTag) { + arrayTag.setValue(addPadding(256, 9, arrayTag.getValue())); + } + } + + for (int sectionIndex = 0; sectionIndex < chunk.sections.length; sectionIndex++) { + v1_9SlimeChunkSection section = chunk.sections[sectionIndex]; + + if (section != null) { + int bitsPerBlock = Math.max(4, ceillog2(section.palette.getValue().size())); + + if (!isPowerOfTwo(bitsPerBlock)) { + section = new v1_9SlimeChunkSection(null, null, section.palette, + addPadding(4096, bitsPerBlock, section.blockStates), null, null, + section.blockLight, section.skyLight); + chunk.sections[sectionIndex] = section; + } + } + } + + // Update biome array size + int[] newBiomes = new int[1024]; + Arrays.fill(newBiomes, -1); + int[] biomes = chunk.biomes; + System.arraycopy(biomes, 0, newBiomes, 0, biomes.length); + + chunk.biomes = newBiomes; + } + } + + private static int ceillog2(int input) { + input = isPowerOfTwo(input) ? input : smallestEncompassingPowerOfTwo(input); + return MULTIPLY_DE_BRUIJN_BIT_POSITION[(int) ((long) input * 125613361L >> 27) & 31]; + } + + private static int smallestEncompassingPowerOfTwo(int input) { + int result = input - 1; + result |= result >> 1; + result |= result >> 2; + result |= result >> 4; + result |= result >> 8; + result |= result >> 16; + return result + 1; + } + + private static boolean isPowerOfTwo(int input) { + return input != 0 && (input & input - 1) == 0; + } + + // Taken from DataConverterBitStorageAlign.java + private static long[] addPadding(int indices, int bitsPerIndex, long[] originalArray) { + int k = originalArray.length; + + if (k == 0) { + return originalArray; + } + + long l = (1L << bitsPerIndex) - 1L; + int i1 = 64 / bitsPerIndex; + int j1 = (indices + i1 - 1) / i1; + long[] along1 = new long[j1]; + int k1 = 0; + int l1 = 0; + long i2 = 0L; + int j2 = 0; + long k2 = originalArray[0]; + long l2 = k > 1 ? originalArray[1] : 0L; + + for (int i3 = 0; i3 < indices; ++i3) { + int j3 = i3 * bitsPerIndex; + int k3 = j3 >> 6; + int l3 = (i3 + 1) * bitsPerIndex - 1 >> 6; + int i4 = j3 ^ k3 << 6; + + if (k3 != j2) { + k2 = l2; + l2 = k3 + 1 < k ? originalArray[k3 + 1] : 0L; + j2 = k3; + } + + long j4; + int k4; + + if (k3 == l3) { + j4 = k2 >>> i4 & l; + } else { + k4 = 64 - i4; + j4 = (k2 >>> i4 | l2 << k4) & l; + } + + k4 = l1 + bitsPerIndex; + if (k4 >= 64) { + along1[k1++] = i2; + i2 = j4; + l1 = bitsPerIndex; + } else { + i2 |= j4 << l1; + l1 = k4; + } + } + + if (i2 != 0L) { + along1[k1] = i2; + } + + return along1; + } +} \ No newline at end of file diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java new file mode 100644 index 000000000..0455b9c33 --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java @@ -0,0 +1,48 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; + +import com.flowpowered.nbt.CompoundMap; +import com.flowpowered.nbt.CompoundTag; +import com.flowpowered.nbt.StringTag; + +import java.util.List; +import java.util.Optional; + +public class v1_17WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { + + @Override + public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld world) { + for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : world.chunks.values()) { + for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection section : chunk.sections) { + if (section == null) { + continue; + } + + List palette = section.palette.getValue(); + + for (CompoundTag blockTag : palette) { + Optional name = blockTag.getStringValue("Name"); + CompoundMap map = blockTag.getValue(); + + // CauldronRenameFix + if (name.equals(Optional.of("minecraft:cauldron"))) { + Optional properties = blockTag.getAsCompoundTag("Properties"); + if (properties.isPresent()) { + String waterLevel = blockTag.getStringValue("level").orElse("0"); + if (waterLevel.equals("0")) { + map.remove("Properties"); + } else { + map.put("Name", new StringTag("Name", "minecraft:water_cauldron")); + } + } + } + + // Renamed grass path item to dirt path + if (name.equals(Optional.of("minecraft:grass_path"))) { + map.put("Name", new StringTag("Name", "minecraft:dirt_path")); + } + } + } + } + } + +} \ No newline at end of file diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java new file mode 100644 index 000000000..c1e0bc799 --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java @@ -0,0 +1,360 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; + +import com.flowpowered.nbt.*; + +import java.util.*; + +public class v1_18WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { + + private static final String[] BIOMES_BY_ID = new String[256]; // rip datapacks + + static { + BIOMES_BY_ID[0] = "minecraft:ocean"; + BIOMES_BY_ID[1] = "minecraft:plains"; + BIOMES_BY_ID[2] = "minecraft:desert"; + BIOMES_BY_ID[3] = "minecraft:mountains"; + BIOMES_BY_ID[4] = "minecraft:forest"; + BIOMES_BY_ID[5] = "minecraft:taiga"; + BIOMES_BY_ID[6] = "minecraft:swamp"; + BIOMES_BY_ID[7] = "minecraft:river"; + BIOMES_BY_ID[8] = "minecraft:nether_wastes"; + BIOMES_BY_ID[9] = "minecraft:the_end"; + BIOMES_BY_ID[10] = "minecraft:frozen_ocean"; + BIOMES_BY_ID[11] = "minecraft:frozen_river"; + BIOMES_BY_ID[12] = "minecraft:snowy_tundra"; + BIOMES_BY_ID[13] = "minecraft:snowy_mountains"; + BIOMES_BY_ID[14] = "minecraft:mushroom_fields"; + BIOMES_BY_ID[15] = "minecraft:mushroom_field_shore"; + BIOMES_BY_ID[16] = "minecraft:beach"; + BIOMES_BY_ID[17] = "minecraft:desert_hills"; + BIOMES_BY_ID[18] = "minecraft:wooded_hills"; + BIOMES_BY_ID[19] = "minecraft:taiga_hills"; + BIOMES_BY_ID[20] = "minecraft:mountain_edge"; + BIOMES_BY_ID[21] = "minecraft:jungle"; + BIOMES_BY_ID[22] = "minecraft:jungle_hills"; + BIOMES_BY_ID[23] = "minecraft:jungle_edge"; + BIOMES_BY_ID[24] = "minecraft:deep_ocean"; + BIOMES_BY_ID[25] = "minecraft:stone_shore"; + BIOMES_BY_ID[26] = "minecraft:snowy_beach"; + BIOMES_BY_ID[27] = "minecraft:birch_forest"; + BIOMES_BY_ID[28] = "minecraft:birch_forest_hills"; + BIOMES_BY_ID[29] = "minecraft:dark_forest"; + BIOMES_BY_ID[30] = "minecraft:snowy_taiga"; + BIOMES_BY_ID[31] = "minecraft:snowy_taiga_hills"; + BIOMES_BY_ID[32] = "minecraft:giant_tree_taiga"; + BIOMES_BY_ID[33] = "minecraft:giant_tree_taiga_hills"; + BIOMES_BY_ID[34] = "minecraft:wooded_mountains"; + BIOMES_BY_ID[35] = "minecraft:savanna"; + BIOMES_BY_ID[36] = "minecraft:savanna_plateau"; + BIOMES_BY_ID[37] = "minecraft:badlands"; + BIOMES_BY_ID[38] = "minecraft:wooded_badlands_plateau"; + BIOMES_BY_ID[39] = "minecraft:badlands_plateau"; + BIOMES_BY_ID[40] = "minecraft:small_end_islands"; + BIOMES_BY_ID[41] = "minecraft:end_midlands"; + BIOMES_BY_ID[42] = "minecraft:end_highlands"; + BIOMES_BY_ID[43] = "minecraft:end_barrens"; + BIOMES_BY_ID[44] = "minecraft:warm_ocean"; + BIOMES_BY_ID[45] = "minecraft:lukewarm_ocean"; + BIOMES_BY_ID[46] = "minecraft:cold_ocean"; + BIOMES_BY_ID[47] = "minecraft:deep_warm_ocean"; + BIOMES_BY_ID[48] = "minecraft:deep_lukewarm_ocean"; + BIOMES_BY_ID[49] = "minecraft:deep_cold_ocean"; + BIOMES_BY_ID[50] = "minecraft:deep_frozen_ocean"; + BIOMES_BY_ID[127] = "minecraft:the_void"; + BIOMES_BY_ID[129] = "minecraft:sunflower_plains"; + BIOMES_BY_ID[130] = "minecraft:desert_lakes"; + BIOMES_BY_ID[131] = "minecraft:gravelly_mountains"; + BIOMES_BY_ID[132] = "minecraft:flower_forest"; + BIOMES_BY_ID[133] = "minecraft:taiga_mountains"; + BIOMES_BY_ID[134] = "minecraft:swamp_hills"; + BIOMES_BY_ID[140] = "minecraft:ice_spikes"; + BIOMES_BY_ID[149] = "minecraft:modified_jungle"; + BIOMES_BY_ID[151] = "minecraft:modified_jungle_edge"; + BIOMES_BY_ID[155] = "minecraft:tall_birch_forest"; + BIOMES_BY_ID[156] = "minecraft:tall_birch_hills"; + BIOMES_BY_ID[157] = "minecraft:dark_forest_hills"; + BIOMES_BY_ID[158] = "minecraft:snowy_taiga_mountains"; + BIOMES_BY_ID[160] = "minecraft:giant_spruce_taiga"; + BIOMES_BY_ID[161] = "minecraft:giant_spruce_taiga_hills"; + BIOMES_BY_ID[162] = "minecraft:modified_gravelly_mountains"; + BIOMES_BY_ID[163] = "minecraft:shattered_savanna"; + BIOMES_BY_ID[164] = "minecraft:shattered_savanna_plateau"; + BIOMES_BY_ID[165] = "minecraft:eroded_badlands"; + BIOMES_BY_ID[166] = "minecraft:modified_wooded_badlands_plateau"; + BIOMES_BY_ID[167] = "minecraft:modified_badlands_plateau"; + BIOMES_BY_ID[168] = "minecraft:bamboo_jungle"; + BIOMES_BY_ID[169] = "minecraft:bamboo_jungle_hills"; + BIOMES_BY_ID[170] = "minecraft:soul_sand_valley"; + BIOMES_BY_ID[171] = "minecraft:crimson_forest"; + BIOMES_BY_ID[172] = "minecraft:warped_forest"; + BIOMES_BY_ID[173] = "minecraft:basalt_deltas"; + BIOMES_BY_ID[174] = "minecraft:dripstone_caves"; + BIOMES_BY_ID[175] = "minecraft:lush_caves"; + BIOMES_BY_ID[177] = "minecraft:meadow"; + BIOMES_BY_ID[178] = "minecraft:grove"; + BIOMES_BY_ID[179] = "minecraft:snowy_slopes"; + BIOMES_BY_ID[180] = "minecraft:snowcapped_peaks"; + BIOMES_BY_ID[181] = "minecraft:lofty_peaks"; + BIOMES_BY_ID[182] = "minecraft:stony_peaks"; + } + + public static final Map BIOME_UPDATE = new HashMap<>(); + + static { + BIOME_UPDATE.put("minecraft:badlands_plateau", "minecraft:badlands"); + BIOME_UPDATE.put("minecraft:bamboo_jungle_hills", "minecraft:bamboo_jungle"); + BIOME_UPDATE.put("minecraft:birch_forest_hills", "minecraft:birch_forest"); + BIOME_UPDATE.put("minecraft:dark_forest_hills", "minecraft:dark_forest"); + BIOME_UPDATE.put("minecraft:desert_hills", "minecraft:desert"); + BIOME_UPDATE.put("minecraft:desert_lakes", "minecraft:desert"); + BIOME_UPDATE.put("minecraft:giant_spruce_taiga_hills", "minecraft:old_growth_spruce_taiga"); + BIOME_UPDATE.put("minecraft:giant_spruce_taiga", "minecraft:old_growth_spruce_taiga"); + BIOME_UPDATE.put("minecraft:giant_tree_taiga_hills", "minecraft:old_growth_pine_taiga"); + BIOME_UPDATE.put("minecraft:giant_tree_taiga", "minecraft:old_growth_pine_taiga"); + BIOME_UPDATE.put("minecraft:gravelly_mountains", "minecraft:windswept_gravelly_hills"); + BIOME_UPDATE.put("minecraft:jungle_edge", "minecraft:sparse_jungle"); + BIOME_UPDATE.put("minecraft:jungle_hills", "minecraft:jungle"); + BIOME_UPDATE.put("minecraft:modified_badlands_plateau", "minecraft:badlands"); + BIOME_UPDATE.put("minecraft:modified_gravelly_mountains", "minecraft:windswept_gravelly_hills"); + BIOME_UPDATE.put("minecraft:modified_jungle_edge", "minecraft:sparse_jungle"); + BIOME_UPDATE.put("minecraft:modified_jungle", "minecraft:jungle"); + BIOME_UPDATE.put("minecraft:modified_wooded_badlands_plateau", "minecraft:wooded_badlands"); + BIOME_UPDATE.put("minecraft:mountain_edge", "minecraft:windswept_hills"); + BIOME_UPDATE.put("minecraft:mountains", "minecraft:windswept_hills"); + BIOME_UPDATE.put("minecraft:mushroom_field_shore", "minecraft:mushroom_fields"); + BIOME_UPDATE.put("minecraft:shattered_savanna", "minecraft:windswept_savanna"); + BIOME_UPDATE.put("minecraft:shattered_savanna_plateau", "minecraft:windswept_savanna"); + BIOME_UPDATE.put("minecraft:snowy_mountains", "minecraft:snowy_plains"); + BIOME_UPDATE.put("minecraft:snowy_taiga_hills", "minecraft:snowy_taiga"); + BIOME_UPDATE.put("minecraft:snowy_taiga_mountains", "minecraft:snowy_taiga"); + BIOME_UPDATE.put("minecraft:snowy_tundra", "minecraft:snowy_plains"); + BIOME_UPDATE.put("minecraft:stone_shore", "minecraft:stony_shore"); + BIOME_UPDATE.put("minecraft:swamp_hills", "minecraft:swamp"); + BIOME_UPDATE.put("minecraft:taiga_hills", "minecraft:taiga"); + BIOME_UPDATE.put("minecraft:taiga_mountains", "minecraft:taiga"); + BIOME_UPDATE.put("minecraft:tall_birch_forest", "minecraft:old_growth_birch_forest"); + BIOME_UPDATE.put("minecraft:tall_birch_hills", "minecraft:old_growth_birch_forest"); + BIOME_UPDATE.put("minecraft:wooded_badlands_plateau", "minecraft:wooded_badlands"); + BIOME_UPDATE.put("minecraft:wooded_hills", "minecraft:forest"); + BIOME_UPDATE.put("minecraft:wooded_mountains", "minecraft:windswept_forest"); + BIOME_UPDATE.put("minecraft:lofty_peaks", "minecraft:jagged_peaks"); + BIOME_UPDATE.put("minecraft:snowcapped_peaks", "minecraft:frozen_peaks"); + } + + @Override + public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld world) { + for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : world.chunks.values()) { + + // SpawnerSpawnDataFix + for (CompoundTag tileEntity : chunk.tileEntities) { + CompoundMap value = tileEntity.getValue(); + Optional id = tileEntity.getStringValue("id"); + if (id.equals(Optional.of("minecraft:mob_spawner"))) { + Optional> spawnPotentials = tileEntity.getAsListTag("SpawnPotentials"); + Optional spawnData = tileEntity.getAsCompoundTag("SpawnData"); + if (spawnPotentials.isPresent()) { + ListTag spawnPotentialsList = (ListTag) spawnPotentials.get(); + List spawnPotentialsListValue = spawnPotentialsList.getValue(); + for (CompoundTag spawnPotentialsTag : spawnPotentialsListValue) { + CompoundMap spawnPotentialsValue = spawnPotentialsTag.getValue(); + Optional weight = spawnPotentialsTag.getIntValue("Weight"); + if (weight.isPresent()) { + int weightVal = weight.get(); + spawnPotentialsValue.remove("Weight"); + spawnPotentialsValue.put("weight", new IntTag("weight", weightVal)); + } + Optional entity = spawnPotentialsTag.getAsCompoundTag("Entity"); + if (entity.isPresent()) { + CompoundTag entityTag = entity.get(); + spawnPotentialsValue.remove("Entity"); + entityTag.getValue(); + CompoundMap dataMap = new CompoundMap(); + dataMap.put(new CompoundTag("entity", entityTag.getValue())); + spawnPotentialsValue.put("data", new CompoundTag("data", dataMap)); + } + } + value.put("SpawnPotentials", spawnPotentialsList); + if (!spawnPotentialsListValue.isEmpty()) { + CompoundTag compoundTag = spawnPotentialsListValue.get(0); + CompoundTag entityTag = compoundTag.getAsCompoundTag("data"). + get().getAsCompoundTag("entity").get(); + CompoundMap spawnDataMap = new CompoundMap(); + spawnDataMap.put(entityTag.clone()); + value.put("SpawnData", new CompoundTag("SpawnData", spawnDataMap)); + } + } else if (spawnData.isPresent()) { + CompoundTag spawnDataTag = spawnData.get(); + CompoundMap spawnDataValue = spawnDataTag.getValue(); + Optional entityTag = spawnDataTag.getAsCompoundTag("entity"); + Optional idTag = spawnDataTag.getAsStringTag("id"); + if (entityTag.isEmpty() && idTag.isPresent()) { + StringTag entityTypeTag = idTag.get(); + spawnDataValue.remove("id"); + CompoundMap entityMap = new CompoundMap(); + entityMap.put(entityTypeTag); + spawnDataValue.put("entity", new CompoundTag("entity", entityMap)); + value.put("SpawnData", spawnDataTag); + } + } + } + } + + CompoundTag[] tags = createBiomeSections(chunk.biomes, false, 0); + + com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[] sections = chunk.sections; + for (int i = 0; i < sections.length; i++) { + com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection section = sections[i]; + if (section == null) { + continue; + } + + + section.blockStatesTag = wrapPalette(section.palette, section.blockStates); + section.biomeTag = tags[i]; + } + + com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[] shiftedSections = new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[sections.length + 4]; + System.arraycopy(sections, 0, shiftedSections, 4, sections.length); + + chunk.sections = shiftedSections; // Shift all sections up 4 + + + com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[] sectionArray = chunk.sections; + + CompoundMap emptyBiomes = new CompoundMap(); + emptyBiomes.put("palette", new ListTag<>("palette", TagType.TAG_STRING, List.of(new StringTag("", "minecraft:plains")))); + + CompoundMap blocks = new CompoundMap(); + emptyBiomes.put("palette", new ListTag<>("palette", TagType.TAG_STRING, List.of(new StringTag("", "minecraft:air")))); + + CompoundTag blockTag = new CompoundTag("", blocks); + CompoundTag emptyBiomesTag = new CompoundTag("", emptyBiomes); + for (int i = 0; i < sectionArray.length; i++) { + com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection section = sectionArray[i]; + if (section == null) { + sectionArray[i] = new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection( + null, + null, + null, + null, + blockTag, + emptyBiomesTag, + null, + null + ); + } + } + } + } + + private static CompoundTag[] createBiomeSections(int[] biomes, final boolean wantExtendedHeight, final int minSection) { + final CompoundTag[] ret = new CompoundTag[wantExtendedHeight ? 24 : 16]; + + if (biomes != null && biomes.length == 1536) { // magic value for 24 sections of biomes (24 * 4^3) + //isAlreadyExtended.setValue(true); + for (int sectionIndex = 0; sectionIndex < 24; ++sectionIndex) { + ret[sectionIndex] = createBiomeSection(biomes, sectionIndex * 64, -1); // -1 is all 1s + } + } else if (biomes != null && biomes.length == 1024) { // magic value for 24 sections of biomes (16 * 4^3) + for (int sectionY = 0; sectionY < 16; ++sectionY) { + ret[sectionY - minSection] = createBiomeSection(biomes, sectionY * 64, -1); // -1 is all 1s + } + +// if (wantExtendedHeight) { +// // must set the new sections at top and bottom +// final MapType bottomCopy = createBiomeSection(biomes, 0, 15); // just want the biomes at y = 0 +// final MapType topCopy = createBiomeSection(biomes, 1008, 15); // just want the biomes at y = 252 +// +// for (int sectionIndex = 0; sectionIndex < 4; ++sectionIndex) { +// ret[sectionIndex] = bottomCopy.copy(); // copy palette so that later possible modifications don't trash all sections +// } +// +// for (int sectionIndex = 20; sectionIndex < 24; ++sectionIndex) { +// ret[sectionIndex] = topCopy.copy(); // copy palette so that later possible modifications don't trash all sections +// } +// } + } else { + ArrayList palette = new ArrayList<>(); + palette.add(new StringTag("", "minecraft:plains")); + + for (int i = 0; i < ret.length; ++i) { + ret[i] = wrapPalette(new ListTag<>("", TagType.TAG_STRING, palette).clone(), null); // copy palette so that later possible modifications don't trash all sections + } + } + + return ret; + } + + public static int ceilLog2(final int value) { + return value == 0 ? 0 : Integer.SIZE - Integer.numberOfLeadingZeros(value - 1); // see doc of numberOfLeadingZeros + } + + private static CompoundTag createBiomeSection(final int[] biomes, final int offset, final int mask) { + final Map paletteId = new HashMap<>(); + + for (int idx = 0; idx < 64; ++idx) { + final int biome = biomes[offset + (idx & mask)]; + paletteId.putIfAbsent(biome, paletteId.size()); + } + + List paletteString = new ArrayList<>(); + for (final Iterator iterator = paletteId.keySet().iterator(); iterator.hasNext(); ) { + final int biomeId = iterator.next(); + String biome = biomeId >= 0 && biomeId < BIOMES_BY_ID.length ? BIOMES_BY_ID[biomeId] : null; + String update = BIOME_UPDATE.get(biome); + if (update != null) { + biome = update; + } + + paletteString.add(new StringTag("", biome == null ? "minecraft:plains" : biome)); + } + + final int bitsPerObject = ceilLog2(paletteString.size()); + if (bitsPerObject == 0) { + return wrapPalette(new ListTag<>("", TagType.TAG_STRING, paletteString), null); + } + + // manually create packed integer data + final int objectsPerValue = 64 / bitsPerObject; + final long[] packed = new long[(64 + objectsPerValue - 1) / objectsPerValue]; + + int shift = 0; + int idx = 0; + long curr = 0; + + for (int biome_idx = 0; biome_idx < 64; ++biome_idx) { + final int biome = biomes[offset + (biome_idx & mask)]; + + curr |= ((long) paletteId.get(biome)) << shift; + + shift += bitsPerObject; + + if (shift + bitsPerObject > 64) { // will next write overflow? + // must move to next idx + packed[idx++] = curr; + shift = 0; + curr = 0L; + } + } + + // don't forget to write the last one + if (shift != 0) { + packed[idx] = curr; + } + + return wrapPalette(new ListTag<>("", TagType.TAG_STRING, paletteString), packed); + } + + private static CompoundTag wrapPalette(ListTag palette, final long[] blockStates) { + CompoundMap map = new CompoundMap(); + CompoundTag tag = new CompoundTag("", map); + + map.put(new ListTag<>("palette", palette.getElementType(), palette.getValue())); + if (blockStates != null) { + map.put(new LongArrayTag("data", blockStates)); + } + + return tag; + } + +} \ No newline at end of file diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java new file mode 100644 index 000000000..bc1a5c6b2 --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java @@ -0,0 +1,51 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; + +import com.flowpowered.nbt.CompoundMap; +import com.flowpowered.nbt.CompoundTag; +import com.flowpowered.nbt.StringTag; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; +import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld; + +public class v1_9WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { + + private static final JsonParser PARSER = new JsonParser(); + + @Override + public void upgrade(v1_9SlimeWorld world) { + // In 1.9, all signs must be formatted using JSON + for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : world.chunks.values()) { + for (CompoundTag entityTag : chunk.tileEntities) { + String type = entityTag.getAsStringTag("id").get().getValue(); + + if (type.equals("Sign")) { + CompoundMap map = entityTag.getValue(); + + for (int i = 1; i < 5; i++) { + String id = "Text" + i; + + map.put(id, new StringTag(id, fixJson(entityTag.getAsStringTag(id).map(StringTag::getValue).orElse(null)))); + } + } + } + } + } + + private static String fixJson(String value) { + if (value == null || value.equalsIgnoreCase("null") || value.isEmpty()) { + return "{\"text\":\"\"}"; + } + + try { + PARSER.parse(value); + } catch (JsonSyntaxException ex) { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("text", value); + + return jsonObject.toString(); + } + + return value; + } +} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java new file mode 100644 index 000000000..306f54fdd --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java @@ -0,0 +1,45 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; + +import com.flowpowered.nbt.CompoundTag; + +import java.util.List; + +public final class v1_9SlimeChunk { + public final String worldName; + public final int x; + public final int z; + public v1_9SlimeChunkSection[] sections; + public final int minY; + public final int maxY; + public final CompoundTag heightMap; + public int[] biomes; + public final List tileEntities; + public final List entities; + // Used for 1.13 world upgrading + public CompoundTag upgradeData; + + v1_9SlimeChunk(String worldName, + int x, + int z, + v1_9SlimeChunkSection[] sections, + int minY, + int maxY, + CompoundTag heightMap, + int[] biomes, + List tileEntities, + List entities) { + this.worldName = worldName; + this.x = x; + this.z = z; + this.sections = sections; + this.minY = minY; + this.maxY = maxY; + this.heightMap = heightMap; + this.biomes = biomes; + this.tileEntities = tileEntities; + this.entities = entities; + } + +} + + diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java new file mode 100644 index 000000000..5379c3dbf --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java @@ -0,0 +1,35 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; + +import com.flowpowered.nbt.CompoundTag; +import com.flowpowered.nbt.ListTag; +import com.infernalsuite.asp.api.utils.NibbleArray; + +public class v1_9SlimeChunkSection { + + // Pre 1.13 block data + public final byte[] blocks; + public final NibbleArray data; + + // Post 1.13 block data + public final ListTag palette; + public final long[] blockStates; + + // Post 1.17 block data + public CompoundTag blockStatesTag; + public CompoundTag biomeTag; + + public final NibbleArray blockLight; + public final NibbleArray skyLight; + + public v1_9SlimeChunkSection(byte[] blocks, NibbleArray data, ListTag palette, long[] blockStates, CompoundTag blockStatesTag, CompoundTag biomeTag, NibbleArray blockLight, NibbleArray skyLight) { + this.blocks = blocks; + this.data = data; + this.palette = palette; + this.blockStates = blockStates; + this.blockStatesTag = blockStatesTag; + this.biomeTag = biomeTag; + this.blockLight = blockLight; + this.skyLight = skyLight; + } + +} \ No newline at end of file diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java new file mode 100644 index 000000000..0864c6b92 --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java @@ -0,0 +1,35 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; + +import com.flowpowered.nbt.CompoundTag; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; + +public class v1_9SlimeWorld { + + public byte version; + public final String worldName; + public final SlimeLoader loader; + public final Long2ObjectMap chunks; + public final CompoundTag extraCompound; + public final SlimePropertyMap propertyMap; + public final boolean readOnly; + + public v1_9SlimeWorld(byte version, + String worldName, + SlimeLoader loader, + Long2ObjectMap chunks, + CompoundTag extraCompound, + SlimePropertyMap propertyMap, + boolean readOnly) { + this.version = version; + this.worldName = worldName; + this.loader = loader; + this.chunks = chunks; + this.extraCompound = extraCompound; + this.propertyMap = propertyMap; + this.readOnly = readOnly; + } + + +} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java new file mode 100644 index 000000000..07b7e24d3 --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java @@ -0,0 +1,480 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; + +import com.flowpowered.nbt.CompoundMap; +import com.flowpowered.nbt.CompoundTag; +import com.flowpowered.nbt.DoubleTag; +import com.flowpowered.nbt.IntArrayTag; +import com.flowpowered.nbt.IntTag; +import com.flowpowered.nbt.ListTag; +import com.flowpowered.nbt.TagType; +import com.flowpowered.nbt.stream.NBTInputStream; +import com.github.luben.zstd.Zstd; +import com.infernalsuite.asp.SlimeLogger; +import com.infernalsuite.asp.Util; +import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.utils.NibbleArray; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; + +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.EOFException; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.List; +import java.util.Optional; + +class v1_9SlimeWorldDeserializer implements com.infernalsuite.asp.serialization.slime.reader.VersionedByteSlimeWorldReader { + + @Override + public v1_9SlimeWorld deserializeWorld(byte version, SlimeLoader loader, String worldName, DataInputStream dataStream, SlimePropertyMap propertyMap, boolean readOnly) + throws IOException, CorruptedWorldException { + + try { + + // World version + byte worldVersion; + + if (version >= 6) { + worldVersion = dataStream.readByte(); + } else if (version >= 4) { // In v4 there's just a boolean indicating whether the world is pre-1.13 or post-1.13 + worldVersion = (byte) (dataStream.readBoolean() ? 0x04 : 0x01); + } else { + worldVersion = 0; // We'll try to automatically detect it later + } + + // Chunk + short minX = dataStream.readShort(); + short minZ = dataStream.readShort(); + int width = dataStream.readShort(); + int depth = dataStream.readShort(); + + if (width <= 0 || depth <= 0) { + throw new CorruptedWorldException(worldName); + } + + int bitmaskSize = (int) Math.ceil((width * depth) / 8.0D); + byte[] chunkBitmask = new byte[bitmaskSize]; + dataStream.read(chunkBitmask); + BitSet chunkBitset = BitSet.valueOf(chunkBitmask); + + int compressedChunkDataLength = dataStream.readInt(); + int chunkDataLength = dataStream.readInt(); + byte[] compressedChunkData = new byte[compressedChunkDataLength]; + byte[] chunkData = new byte[chunkDataLength]; + + dataStream.read(compressedChunkData); + + // Tile Entities + int compressedTileEntitiesLength = dataStream.readInt(); + int tileEntitiesLength = dataStream.readInt(); + byte[] compressedTileEntities = new byte[compressedTileEntitiesLength]; + byte[] tileEntities = new byte[tileEntitiesLength]; + + dataStream.read(compressedTileEntities); + + // Entities + byte[] compressedEntities = new byte[0]; + byte[] entities = new byte[0]; + + if (version >= 3) { + boolean hasEntities = dataStream.readBoolean(); + + if (hasEntities) { + int compressedEntitiesLength = dataStream.readInt(); + int entitiesLength = dataStream.readInt(); + compressedEntities = new byte[compressedEntitiesLength]; + entities = new byte[entitiesLength]; + + dataStream.read(compressedEntities); + } + } + + // Extra NBT tag + byte[] compressedExtraTag = new byte[0]; + byte[] extraTag = new byte[0]; + + if (version >= 2) { + int compressedExtraTagLength = dataStream.readInt(); + int extraTagLength = dataStream.readInt(); + compressedExtraTag = new byte[compressedExtraTagLength]; + extraTag = new byte[extraTagLength]; + + dataStream.read(compressedExtraTag); + } + + // World Map NBT tag + byte[] compressedMapsTag = new byte[0]; + byte[] mapsTag = new byte[0]; + + if (version >= 7) { + int compressedMapsTagLength = dataStream.readInt(); + int mapsTagLength = dataStream.readInt(); + compressedMapsTag = new byte[compressedMapsTagLength]; + mapsTag = new byte[mapsTagLength]; + + dataStream.read(compressedMapsTag); + } + + if (dataStream.read() != -1) { + throw new CorruptedWorldException(worldName); + } + + // Data decompression + Zstd.decompress(chunkData, compressedChunkData); + Zstd.decompress(tileEntities, compressedTileEntities); + Zstd.decompress(entities, compressedEntities); + Zstd.decompress(extraTag, compressedExtraTag); + Zstd.decompress(mapsTag, compressedMapsTag); + + // Chunk deserialization + Long2ObjectMap chunks = readChunks(worldVersion, version, worldName, minX, minZ, width, depth, chunkBitset, chunkData); + + // Entity deserialization + CompoundTag entitiesCompound = readCompoundTag(entities); + + Long2ObjectMap> entityStorage = new Long2ObjectOpenHashMap<>(); + if (entitiesCompound != null) { + List serializedEntities = ((ListTag) entitiesCompound.getValue().get("entities")).getValue(); + + SlimeLogger.debug("Serialized entities: " + serializedEntities); + for (CompoundTag entityCompound : serializedEntities) { + ListTag listTag = (ListTag) entityCompound.getAsListTag("Pos").get(); + + int chunkX = floor(listTag.getValue().get(0).getValue()) >> 4; + int chunkZ = floor(listTag.getValue().get(2).getValue()) >> 4; + long chunkKey = Util.chunkPosition(chunkX, chunkZ); + v1_9SlimeChunk chunk = chunks.get(chunkKey); + if (chunk != null) { + chunk.entities.add(entityCompound); + } + if (entityStorage.containsKey(chunkKey)) { + entityStorage.get(chunkKey).add(entityCompound); + } else { + List entityStorageList = new ArrayList<>(); + entityStorageList.add(entityCompound); + entityStorage.put(chunkKey, entityStorageList); + } + } + } + + // Tile Entity deserialization + CompoundTag tileEntitiesCompound = readCompoundTag(tileEntities); + + if (tileEntitiesCompound != null) { + ListTag tileEntitiesList = (ListTag) tileEntitiesCompound.getValue().get("tiles"); + for (CompoundTag tileEntityCompound : tileEntitiesList.getValue()) { + int chunkX = ((IntTag) tileEntityCompound.getValue().get("x")).getValue() >> 4; + int chunkZ = ((IntTag) tileEntityCompound.getValue().get("z")).getValue() >> 4; + v1_9SlimeChunk chunk = chunks.get(Util.chunkPosition(chunkX, chunkZ)); + + if (chunk == null) { + throw new CorruptedWorldException(worldName); + } + + chunk.tileEntities.add(tileEntityCompound); + } + } + + // Extra Data + CompoundTag extraCompound = readCompoundTag(extraTag); + + if (extraCompound == null) { + extraCompound = new CompoundTag("", new CompoundMap()); + } + + if (version <= 0x05) {} + + // World Maps +// CompoundTag mapsCompound = readCompoundTag(mapsTag); +// List mapList; +// +// if (mapsCompound != null) { +// mapList = (List) mapsCompound.getAsListTag("maps").map(ListTag::getValue).orElse(new ArrayList<>()); +// } else { +// mapList = new ArrayList<>(); +// } + + + // World properties + SlimePropertyMap worldPropertyMap = propertyMap; + Optional propertiesMap = extraCompound + .getAsCompoundTag("properties") + .map(CompoundTag::getValue); + + if (propertiesMap.isPresent()) { + worldPropertyMap = new SlimePropertyMap(propertiesMap.get()); + worldPropertyMap.merge(propertyMap); // Override world properties + } else if (propertyMap == null) { // Make sure the property map is never null + worldPropertyMap = new SlimePropertyMap(); + } + + return new v1_9SlimeWorld( + worldVersion, + worldName, + loader, + chunks, + extraCompound, + propertyMap, + readOnly + ); + } catch (EOFException ex) { + throw new CorruptedWorldException(worldName, ex); + } + } + + private static int floor(double num) { + final int floor = (int) num; + return floor == num ? floor : floor - (int) (Double.doubleToRawLongBits(num) >>> 63); + } + + private static Long2ObjectMap readChunks(byte worldVersion, int version, String worldName, int minX, int minZ, int width, int depth, BitSet chunkBitset, byte[] chunkData) throws IOException { + DataInputStream dataStream = new DataInputStream(new ByteArrayInputStream(chunkData)); + Long2ObjectMap chunkMap = new Long2ObjectOpenHashMap<>(); + + for (int z = 0; z < depth; z++) { + for (int x = 0; x < width; x++) { + int bitsetIndex = z * width + x; + + if (chunkBitset.get(bitsetIndex)) { + // Height Maps + CompoundTag heightMaps; + + if (worldVersion >= 0x04) { + int heightMapsLength = dataStream.readInt(); + byte[] heightMapsArray = new byte[heightMapsLength]; + dataStream.read(heightMapsArray); + heightMaps = readCompoundTag(heightMapsArray); + + // Height Maps might be null if empty + if (heightMaps == null) { + heightMaps = new CompoundTag("", new CompoundMap()); + } + } else { + int[] heightMap = new int[256]; + + for (int i = 0; i < 256; i++) { + heightMap[i] = dataStream.readInt(); + } + + CompoundMap map = new CompoundMap(); + map.put("heightMap", new IntArrayTag("heightMap", heightMap)); + + heightMaps = new CompoundTag("", map); + } + + // Biome array + int[] biomes = null; + + if (version == 8 && worldVersion < 0x04) { + // Patch the v8 bug: biome array size is wrong for old worlds + dataStream.readInt(); + } + + if (worldVersion < 0x04) { + byte[] byteBiomes = new byte[256]; + dataStream.read(byteBiomes); + biomes = toIntArray(byteBiomes); + } else if (worldVersion < 0x08) { + int biomesArrayLength = version >= 8 ? dataStream.readInt() : 256; + biomes = new int[biomesArrayLength]; + + for (int i = 0; i < biomes.length; i++) { + biomes[i] = dataStream.readInt(); + } + } + + // Chunk Sections + ChunkSectionData data = worldVersion < 0x08 ? readChunkSections(dataStream, worldVersion, version) : readChunkSectionsNew(dataStream, worldVersion, version); + + int chunkX = minX + x; + int chunkZ = minZ + z; + + chunkMap.put(Util.chunkPosition(chunkX, chunkZ), new v1_9SlimeChunk( + worldName, + chunkX, + chunkZ, + data.sections, + data.minSectionY, + data.maxSectionY, + heightMaps, + biomes, + new ArrayList<>(), + new ArrayList<>() + )); + } + } + } + + return chunkMap; + } + + private static int[] toIntArray(byte[] buf) { + ByteBuffer buffer = ByteBuffer.wrap(buf).order(ByteOrder.BIG_ENDIAN); + int[] ret = new int[buf.length / 4]; + + buffer.asIntBuffer().get(ret); + + return ret; + } + + private record ChunkSectionData(v1_9SlimeChunkSection[] sections, int minSectionY, int maxSectionY) { + } + + private static ChunkSectionData readChunkSectionsNew(DataInputStream dataStream, int worldVersion, int version) throws IOException { + int minSectionY = dataStream.readInt(); + int maxSectionY = dataStream.readInt(); + int sectionCount = dataStream.readInt(); + v1_9SlimeChunkSection[] chunkSectionArray = new v1_9SlimeChunkSection[maxSectionY - minSectionY]; + + for (int i = 0; i < sectionCount; i++) { + int y = dataStream.readInt(); + + // Block Light Nibble Array + NibbleArray blockLightArray; + + if (version < 5 || dataStream.readBoolean()) { + byte[] blockLightByteArray = new byte[2048]; + dataStream.read(blockLightByteArray); + blockLightArray = new NibbleArray((blockLightByteArray)); + } else { + blockLightArray = null; + } + + // Block data + byte[] blockStateData = new byte[dataStream.readInt()]; + dataStream.read(blockStateData); + CompoundTag blockStateTag = readCompoundTag(blockStateData); + + byte[] biomeData = new byte[dataStream.readInt()]; + dataStream.read(biomeData); + CompoundTag biomeTag = readCompoundTag(biomeData); + + // Sky Light Nibble Array + NibbleArray skyLightArray; + + if (version < 5 || dataStream.readBoolean()) { + byte[] skyLightByteArray = new byte[2048]; + dataStream.read(skyLightByteArray); + skyLightArray = new NibbleArray((skyLightByteArray)); + } else { + skyLightArray = null; + } + + // HypixelBlocks 3 + if (version < 4) { + short hypixelBlocksLength = dataStream.readShort(); + dataStream.skip(hypixelBlocksLength); + } + + chunkSectionArray[y] = new v1_9SlimeChunkSection(null, null, null, null, blockStateTag, biomeTag, blockLightArray, skyLightArray); + } + + return new ChunkSectionData(chunkSectionArray, minSectionY, maxSectionY); + } + + private static ChunkSectionData readChunkSections(DataInputStream dataStream, byte worldVersion, int version) throws IOException { + v1_9SlimeChunkSection[] chunkSectionArray = new v1_9SlimeChunkSection[16]; + byte[] sectionBitmask = new byte[2]; + dataStream.read(sectionBitmask); + BitSet sectionBitset = BitSet.valueOf(sectionBitmask); + + for (int i = 0; i < 16; i++) { + if (sectionBitset.get(i)) { + // Block Light Nibble Array + NibbleArray blockLightArray; + + if (version < 5 || dataStream.readBoolean()) { + byte[] blockLightByteArray = new byte[2048]; + dataStream.read(blockLightByteArray); + blockLightArray = new NibbleArray((blockLightByteArray)); + } else { + blockLightArray = null; + } + + // Block data + byte[] blockArray; + NibbleArray dataArray; + + ListTag paletteTag; + long[] blockStatesArray; + + if (worldVersion >= 0x04) { + // Post 1.13 + // Palette + int paletteLength = dataStream.readInt(); + List paletteList = new ArrayList<>(paletteLength); + for (int index = 0; index < paletteLength; index++) { + int tagLength = dataStream.readInt(); + byte[] serializedTag = new byte[tagLength]; + dataStream.read(serializedTag); + + CompoundTag tag = readCompoundTag(serializedTag); + paletteList.add(tag); + } + + paletteTag = new ListTag<>("", TagType.TAG_COMPOUND, paletteList); + + // Block states + int blockStatesArrayLength = dataStream.readInt(); + blockStatesArray = new long[blockStatesArrayLength]; + + for (int index = 0; index < blockStatesArrayLength; index++) { + blockStatesArray[index] = dataStream.readLong(); + } + + blockArray = null; + dataArray = null; + } else { + // Pre 1.13 + blockArray = new byte[4096]; + dataStream.read(blockArray); + + // Block Data Nibble Array + byte[] dataByteArray = new byte[2048]; + dataStream.read(dataByteArray); + dataArray = new NibbleArray((dataByteArray)); + + paletteTag = null; + blockStatesArray = null; + } + + // Sky Light Nibble Array + NibbleArray skyLightArray; + + if (version < 5 || dataStream.readBoolean()) { + byte[] skyLightByteArray = new byte[2048]; + dataStream.read(skyLightByteArray); + skyLightArray = new NibbleArray((skyLightByteArray)); + } else { + skyLightArray = null; + } + + // HypixelBlocks 3 + if (version < 4) { + short hypixelBlocksLength = dataStream.readShort(); + dataStream.skip(hypixelBlocksLength); + } + + chunkSectionArray[i] = new v1_9SlimeChunkSection(blockArray, dataArray, paletteTag, blockStatesArray, null, null, blockLightArray, skyLightArray); + } + } + + return new ChunkSectionData(chunkSectionArray, 0, 16); + } + + private static CompoundTag readCompoundTag(byte[] serializedCompound) throws IOException { + if (serializedCompound.length == 0) { + return null; + } + + NBTInputStream stream = new NBTInputStream(new ByteArrayInputStream(serializedCompound), NBTInputStream.NO_COMPRESSION, ByteOrder.BIG_ENDIAN); + + return (CompoundTag) stream.readTag(); + } +} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9WorldFormat.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9WorldFormat.java new file mode 100644 index 000000000..62bf97f07 --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9WorldFormat.java @@ -0,0 +1,7 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; + +public interface v1_9WorldFormat { + + com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat FORMAT = new com.infernalsuite.asp.serialization.slime.reader.impl.SimpleWorldFormat<>(new v1_v9SlimeConverter(), new v1_9SlimeWorldDeserializer()); + +} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java new file mode 100644 index 000000000..f5a06898e --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java @@ -0,0 +1,131 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; + +import com.flowpowered.nbt.*; +import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.*; +import com.infernalsuite.asp.api.world.SlimeChunk; +import com.infernalsuite.asp.api.world.SlimeChunkSection; +import com.infernalsuite.asp.api.world.SlimeWorld; + +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Logger; + +class v1_v9SlimeConverter implements com.infernalsuite.asp.serialization.SlimeWorldReader { + + public static final Map UPGRADES = new HashMap<>(); + + static { + UPGRADES.put((byte) 0x02, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_9WorldUpgrade()); + UPGRADES.put((byte) 0x03, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_11WorldUpgrade()); + UPGRADES.put((byte) 0x04, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_13WorldUpgrade()); + UPGRADES.put((byte) 0x05, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_14WorldUpgrade()); + UPGRADES.put((byte) 0x06, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_16WorldUpgrade()); + UPGRADES.put((byte) 0x07, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_17WorldUpgrade()); + UPGRADES.put((byte) 0x08, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_18WorldUpgrade()); + } + + @Override + public SlimeWorld readFromData(v1_9SlimeWorld data) { + int dataVersion = upgradeWorld(data); + + Long2ObjectMap chunks = new Long2ObjectOpenHashMap<>(); + for (Long2ObjectMap.Entry entry : data.chunks.long2ObjectEntrySet()) { + v1_9SlimeChunk slimeChunk = entry.getValue(); + + SlimeChunkSection[] sections = new SlimeChunkSection[slimeChunk.sections.length]; + for (int i = 0; i < sections.length; i++) { + v1_9SlimeChunkSection dataSection = slimeChunk.sections[i]; + if (dataSection != null) { + // I'm not sure which upgrader should handle this, so I'm leaving it here + if (dataSection.biomeTag != null) { + ListTag palette = (ListTag) dataSection.biomeTag.getValue().get("palette"); + + ArrayList newPalette = new ArrayList(); + if (palette != null) { + for (StringTag stringTag : palette.getValue()) { + // air is no longer a valid biome, I'm not sure when this changed, + // so I cannot pick the proper upgrader to place it in. + if (stringTag.getValue().equals("minecraft:air")) continue; + newPalette.add(stringTag); + } + } + + if (palette == null || palette.getValue().isEmpty()) { + newPalette.add(new StringTag(null, "minecraft:plains")); + } + + dataSection.biomeTag.getValue().put("palette", new ListTag<>("palette", TagType.TAG_STRING, newPalette)); + } + + sections[i] = new com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton( + // SlimeChunkConverter can handle null blockState, but cannot handle empty blockState + dataSection.blockStatesTag.getValue().isEmpty() ? null : dataSection.blockStatesTag, + dataSection.biomeTag, + dataSection.blockLight, + dataSection.skyLight + ); + } else { + sections[i] = new com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton( + null, + null, + null, + null + ); + } + + } + // TODO: + // slimeChunk.minY, + // slimeChunk.maxY, + + chunks.put(entry.getLongKey(), new com.infernalsuite.asp.skeleton.SlimeChunkSkeleton( + slimeChunk.x, + slimeChunk.z, + sections, + slimeChunk.heightMap, + slimeChunk.tileEntities, + slimeChunk.entities, + new CompoundTag("", new CompoundMap()), + slimeChunk.upgradeData + )); + } + + + return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld( + data.worldName, + data.loader, + data.readOnly, + chunks, + data.extraCompound, + data.propertyMap, + dataVersion + ); + } + + + public static int upgradeWorld(v1_9SlimeWorld world) { + byte upgradeTo = 0x08; // Last version + int dataVersion = 3120; // MCVersions.V1_19_2 + + for (byte ver = (byte) (world.version + 1); ver <= upgradeTo; ver++) { + Upgrade upgrade = UPGRADES.get(ver); + + if (upgrade == null) { + Logger.getLogger("v1_9WorldUpgrader").warning("Missing world upgrader for version " + ver + ". World will not be upgraded."); + continue; + } + + upgrade.upgrade(world); + + if (ver == 0x08) { + dataVersion = 2975; + } + } + + world.version = 0x09; + return dataVersion; + } +} From deb07746fe10a9b3c7af1c5d3826c9e970330ccc Mon Sep 17 00:00:00 2001 From: David Date: Sat, 12 Apr 2025 13:00:56 +0200 Subject: [PATCH 124/133] feat: get legacy importer going with dataconverters Signed-off-by: David --- .../asp/api/SlimeDataConverter.java | 22 ++ .../infernalsuite/asp/api/SlimeNMSBridge.java | 8 +- .../infernalsuite/asp/AdvancedSlimePaper.java | 2 +- .../asp/SimpleDataFixerConverter.java | 80 ++++++- .../infernalsuite/asp/SlimeNMSBridgeImpl.java | 13 +- .../reader/SlimeWorldReaderRegistry.java | 8 +- .../slime/reader/impl/v1_9/Upgrade.java | 4 +- .../impl/v1_9/upgrade/v1_11WorldUpgrade.java | 69 ------ .../impl/v1_9/upgrade/v1_13WorldUpgrade.java | 97 +++++---- .../impl/v1_9/upgrade/v1_14WorldUpgrade.java | 199 ------------------ .../impl/v1_9/upgrade/v1_16WorldUpgrade.java | 35 ++- .../impl/v1_9/upgrade/v1_17WorldUpgrade.java | 48 ----- .../impl/v1_9/upgrade/v1_18WorldUpgrade.java | 120 ++++------- .../impl/v1_9/upgrade/v1_9WorldUpgrade.java | 51 ----- .../reader/impl/v1_9/v1_9SlimeChunk.java | 16 +- .../impl/v1_9/v1_9SlimeChunkSection.java | 12 +- .../reader/impl/v1_9/v1_9SlimeWorld.java | 22 +- .../impl/v1_9/v1_9SlimeWorldDeserializer.java | 100 ++++----- .../reader/impl/v1_9/v1_v9SlimeConverter.java | 67 ++---- 19 files changed, 341 insertions(+), 632 deletions(-) create mode 100644 api/src/main/java/com/infernalsuite/asp/api/SlimeDataConverter.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java delete mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java diff --git a/api/src/main/java/com/infernalsuite/asp/api/SlimeDataConverter.java b/api/src/main/java/com/infernalsuite/asp/api/SlimeDataConverter.java new file mode 100644 index 000000000..5820073d9 --- /dev/null +++ b/api/src/main/java/com/infernalsuite/asp/api/SlimeDataConverter.java @@ -0,0 +1,22 @@ +package com.infernalsuite.asp.api; + +import com.infernalsuite.asp.api.world.SlimeWorld; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.ListBinaryTag; +import org.jetbrains.annotations.ApiStatus; + +import java.util.List; + +@ApiStatus.Internal +public interface SlimeDataConverter { + + // Will return new (fixed) instance + SlimeWorld applyDataFixers(SlimeWorld world); + + CompoundBinaryTag convertChunkTo1_13(CompoundBinaryTag globalTag); + + List convertEntities(List input, int from, int to); + List convertTileEntities(List input, int from, int to); + ListBinaryTag convertBlockPalette(ListBinaryTag input, int from, int to); + +} diff --git a/api/src/main/java/com/infernalsuite/asp/api/SlimeNMSBridge.java b/api/src/main/java/com/infernalsuite/asp/api/SlimeNMSBridge.java index 535cc5208..81ab7450e 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/SlimeNMSBridge.java +++ b/api/src/main/java/com/infernalsuite/asp/api/SlimeNMSBridge.java @@ -3,12 +3,14 @@ import com.infernalsuite.asp.api.world.SlimeWorld; import com.infernalsuite.asp.api.world.SlimeWorldInstance; import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.ListBinaryTag; import net.kyori.adventure.util.Services; import org.bukkit.World; import org.bukkit.persistence.PersistentDataContainer; import org.jetbrains.annotations.ApiStatus; import java.io.IOException; +import java.util.List; @ApiStatus.Internal public interface SlimeNMSBridge { @@ -26,9 +28,6 @@ public interface SlimeNMSBridge { SlimeWorldInstance getInstance(World world); - // Will return new (fixed) instance - SlimeWorld applyDataFixers(SlimeWorld world); - int getCurrentVersion(); static SlimeNMSBridge instance() { @@ -37,9 +36,10 @@ static SlimeNMSBridge instance() { void extractCraftPDC(PersistentDataContainer source, CompoundBinaryTag.Builder builder); + SlimeDataConverter getSlimeDataConverter(); + @ApiStatus.Internal class Holder { private static final SlimeNMSBridge INSTANCE = Services.service(SlimeNMSBridge.class).orElseThrow(); } - } diff --git a/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java b/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java index 3ca504c7d..76c1f242c 100644 --- a/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java +++ b/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java @@ -62,7 +62,7 @@ public SlimeWorld readWorld(SlimeLoader loader, String worldName, boolean readOn SlimeWorld slimeWorld = SlimeWorldReaderRegistry.readWorld(loader, worldName, serializedWorld, propertyMap, readOnly); LOGGER.info("Applying datafixers for {}.", worldName); - SlimeWorld dataFixed = SlimeNMSBridge.instance().applyDataFixers(slimeWorld); + SlimeWorld dataFixed = SlimeNMSBridge.instance().getSlimeDataConverter().applyDataFixers(slimeWorld); // If the dataFixed and slimeWorld are same, then no datafixers were applied if (!readOnly && dataFixed != slimeWorld) diff --git a/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java b/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java index 15ebd6388..d1b255e55 100644 --- a/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java +++ b/aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java @@ -1,9 +1,13 @@ package com.infernalsuite.asp; import ca.spottedleaf.dataconverter.converters.DataConverter; +import ca.spottedleaf.dataconverter.minecraft.datatypes.MCDataType; import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; +import ca.spottedleaf.dataconverter.types.MapType; +import ca.spottedleaf.dataconverter.types.nbt.NBTListType; import ca.spottedleaf.dataconverter.types.nbt.NBTMapType; +import com.infernalsuite.asp.api.SlimeDataConverter; import com.infernalsuite.asp.serialization.SlimeWorldReader; import com.infernalsuite.asp.skeleton.SkeletonSlimeWorld; import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; @@ -14,13 +18,19 @@ import net.kyori.adventure.nbt.CompoundBinaryTag; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import net.kyori.adventure.nbt.ListBinaryTag; +import net.kyori.adventure.nbt.TagStringIO; import net.minecraft.SharedConstants; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.StringTag; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; -class SimpleDataFixerConverter implements SlimeWorldReader { +class SimpleDataFixerConverter implements SlimeWorldReader, SlimeDataConverter { @Override public SlimeWorld readFromData(SlimeWorld data) { @@ -95,6 +105,10 @@ public SlimeWorld readFromData(SlimeWorld data) { ); } + @Override + public SlimeWorld applyDataFixers(SlimeWorld world) { + return readFromData(world); + } private static CompoundBinaryTag convertAndBack(CompoundBinaryTag value, Consumer acceptor) { if (value == null) return null; @@ -104,4 +118,68 @@ private static CompoundBinaryTag convertAndBack(CompoundBinaryTag value, Consume return Converter.convertTag(converted); } + + @Override + public CompoundBinaryTag convertChunkTo1_13(CompoundBinaryTag tag) { + CompoundTag nmsTag = (CompoundTag) Converter.convertTag(tag); + + int version = nmsTag.getInt("DataVersion"); + + long encodedNewVersion = DataConverter.encodeVersions(1631, Integer.MAX_VALUE); + long encodedCurrentVersion = DataConverter.encodeVersions(version, Integer.MAX_VALUE); + + MCTypeRegistry.CHUNK.convert(new NBTMapType(nmsTag), encodedCurrentVersion, encodedNewVersion); + + return Converter.convertTag(nmsTag); + } + + @Override + public List convertEntities(List input, int from, int to) { + List entities = new ArrayList<>(input.size()); + + long encodedNewVersion = DataConverter.encodeVersions(to, Integer.MAX_VALUE); + long encodedCurrentVersion = DataConverter.encodeVersions(from, Integer.MAX_VALUE); + + for (CompoundBinaryTag upgradeEntity : input) { + entities.add( + convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.ENTITY.convert(new NBTMapType(tag), encodedCurrentVersion, encodedNewVersion)) + ); + } + return entities; + } + + @Override + public List convertTileEntities(List input, int from, int to) { + List blockEntities = new ArrayList<>(input.size()); + + long encodedNewVersion = DataConverter.encodeVersions(to, Integer.MAX_VALUE); + long encodedCurrentVersion = DataConverter.encodeVersions(from, Integer.MAX_VALUE); + + for (CompoundBinaryTag upgradeEntity : input) { + blockEntities.add( + convertAndBack(upgradeEntity, (tag) -> MCTypeRegistry.TILE_ENTITY.convert(new NBTMapType(tag), encodedCurrentVersion, encodedNewVersion)) + ); + } + return blockEntities; + } + + @Override + public ListBinaryTag convertBlockPalette(ListBinaryTag input, int from, int to) { + + long encodedNewVersion = DataConverter.encodeVersions(to, Integer.MAX_VALUE); + long encodedCurrentVersion = DataConverter.encodeVersions(from, Integer.MAX_VALUE); + + ListTag nbtList = (ListTag) Converter.convertTag(input); + NBTListType listType = new NBTListType(nbtList); + + for (int i = 0, len = listType.size(); i < len; ++i) { + final MapType replace = MCTypeRegistry.BLOCK_STATE.convert(listType.getMap(i), + encodedCurrentVersion, encodedNewVersion); + if (replace != null) { + listType.setMap(i, replace); + } + } + + return Converter.convertTag(listType.getTag()); + } } diff --git a/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java b/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java index 2cba0515e..65f812185 100644 --- a/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java +++ b/aspaper-server/src/main/java/com/infernalsuite/asp/SlimeNMSBridgeImpl.java @@ -3,6 +3,7 @@ import ca.spottedleaf.dataconverter.converters.DataConverter; import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; import ca.spottedleaf.dataconverter.types.nbt.NBTMapType; +import com.infernalsuite.asp.api.SlimeDataConverter; import com.infernalsuite.asp.api.SlimeNMSBridge; import com.infernalsuite.asp.api.world.SlimeWorld; import com.infernalsuite.asp.api.world.SlimeWorldInstance; @@ -12,6 +13,7 @@ import com.infernalsuite.asp.level.SlimeLevelInstance; import com.mojang.serialization.Lifecycle; import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.ListBinaryTag; import net.minecraft.SharedConstants; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; @@ -40,6 +42,7 @@ import org.jetbrains.annotations.Nullable; import java.io.IOException; +import java.util.List; import java.util.Locale; public class SlimeNMSBridgeImpl implements SlimeNMSBridge { @@ -64,6 +67,11 @@ public void extractCraftPDC(PersistentDataContainer source, CompoundBinaryTag.Bu } } + @Override + public SlimeDataConverter getSlimeDataConverter() { + return DATA_FIXER_CONVERTER; + } + @Override public boolean loadOverworldOverride() { if (defaultWorld == null) { @@ -156,11 +164,6 @@ public SlimeWorldInstance getInstance(World world) { return worldServer.getSlimeInstance(); } - @Override - public SlimeWorld applyDataFixers(SlimeWorld world) { - return DATA_FIXER_CONVERTER.readFromData(world); - } - @Override public int getCurrentVersion() { diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java index f8f19e057..146a96ed8 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java @@ -6,10 +6,10 @@ import com.infernalsuite.asp.api.utils.SlimeFormat; import com.infernalsuite.asp.api.world.SlimeWorld; import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; -import com.infernalsuite.asp.serialization.slime.reader.impl.v11.v11WorldFormat; +//import com.infernalsuite.asp.serialization.slime.reader.impl.v11.v11WorldFormat; import com.infernalsuite.asp.serialization.slime.reader.impl.v12.v12WorldFormat; import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9WorldFormat; -import com.infernalsuite.asp.serialization.slime.reader.impl.v10.v10WorldFormat; +//import com.infernalsuite.asp.serialization.slime.reader.impl.v10.v10WorldFormat; import java.io.ByteArrayInputStream; import java.io.DataInputStream; @@ -24,8 +24,8 @@ public class SlimeWorldReaderRegistry { static { register(v1_9WorldFormat.FORMAT, 1, 2, 3, 4, 5, 6, 7, 8, 9); - register(v10WorldFormat.FORMAT, 10); - register(v11WorldFormat.FORMAT, 11); + //register(v10WorldFormat.FORMAT, 10); + //register(v11WorldFormat.FORMAT, 11); register(v12WorldFormat.FORMAT, 12); } diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/Upgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/Upgrade.java index 62f4254e6..41f9468a8 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/Upgrade.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/Upgrade.java @@ -1,7 +1,9 @@ package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; +import com.infernalsuite.asp.api.SlimeDataConverter; + public interface Upgrade { - void upgrade(v1_9SlimeWorld world); + void upgrade(v1_9SlimeWorld world, SlimeDataConverter converter); } \ No newline at end of file diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java deleted file mode 100644 index 4e35d3ddd..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; - -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.StringTag; - -import java.util.HashMap; -import java.util.Map; - -public class v1_11WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { - - private static Map oldToNewMap = new HashMap<>(); - private static Map newToOldMap = new HashMap<>(); - - static { - rename("Furnace", "minecraft:furnace"); - rename("Chest", "minecraft:chest"); - rename("EnderChest", "minecraft:ender_chest"); - rename("RecordPlayer", "minecraft:jukebox"); - rename("Trap", "minecraft:dispenser"); - rename("Dropper", "minecraft:dropper"); - rename("Sign", "minecraft:sign"); - rename("MobSpawner", "minecraft:mob_spawner"); - rename("Music", "minecraft:noteblock"); - rename("Piston", "minecraft:piston"); - rename("Cauldron", "minecraft:brewing_stand"); - rename("EnchantTable", "minecraft:enchanting_table"); - rename("Airportal", "minecraft:end_portal"); - rename("Beacon", "minecraft:beacon"); - rename("Skull", "minecraft:skull"); - rename("DLDetector", "minecraft:daylight_detector"); - rename("Hopper", "minecraft:hopper"); - rename("Comparator", "minecraft:comparator"); - rename("FlowerPot", "minecraft:flower_pot"); - rename("Banner", "minecraft:banner"); - rename("Structure", "minecraft:structure_block"); - rename("EndGateway", "minecraft:end_gateway"); - rename("Control", "minecraft:command_block"); - rename(null, "minecraft:bed"); // Patch for issue s#62 - } - - private static void rename(String oldName, String newName) { - if (oldName != null) { - oldToNewMap.put(oldName, newName); - } - - newToOldMap.put(newName, oldName); - } - - @Override - public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld world) { - // 1.11 changed the way Tile Entities are named - for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : world.chunks.values()) { - for (CompoundTag entityTag : chunk.tileEntities) { - String oldType = entityTag.getAsStringTag("id").get().getValue(); - String newType = oldToNewMap.get(oldType); - - if (newType == null) { - if (newToOldMap.containsKey(oldType)) { // Maybe it's in the new format for some reason? - continue; - } - - throw new IllegalStateException("Failed to find 1.11 upgrade for tile entity " + oldType); - } - - entityTag.getValue().put("id", new StringTag("id", newType)); - } - } - } -} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java index 14d613582..1cac5f9b7 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java @@ -1,61 +1,76 @@ package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; -import com.flowpowered.nbt.*; +import com.infernalsuite.asp.api.SlimeDataConverter; import com.infernalsuite.asp.api.SlimeNMSBridge; import com.infernalsuite.asp.api.utils.NibbleArray; -import org.bukkit.ChatColor; +import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade; +import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk; +import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection; +import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld; +import net.kyori.adventure.nbt.*; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; -public class v1_13WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { +public class v1_13WorldUpgrade implements Upgrade { + + private static final int DATA_VERSION = 1631; @Override - public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld world) { + public void upgrade(v1_9SlimeWorld world, SlimeDataConverter slimeDataConverter) { Logger.getLogger("v1_13WorldUpgrade").warning("Updating world to the 1.13 format. This may take a while."); - List chunks = new ArrayList<>(world.chunks.values()); + + List chunks = new ArrayList<>(world.chunks.values()); long lastMessage = -1; + System.out.println("Upgrading from " + world.getDataVersion()); for (int i = 0; i < chunks.size(); i++) { - com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk = chunks.get(i); + v1_9SlimeChunk chunk = chunks.get(i); + + //Make sure that entities and tile entities are up-to-date with pre-1.13 + chunk.tileEntities = slimeDataConverter.convertTileEntities(chunk.tileEntities, world.getDataVersion(), 1343); + chunk.entities = slimeDataConverter.convertEntities(chunk.entities, world.getDataVersion(), 1343); // The world upgrade process is a very complex task, and there's already a // built-in upgrade tool inside the server, so we can simply use it - CompoundTag globalTag = new CompoundTag("", new CompoundMap()); - globalTag.getValue().put("DataVersion", new IntTag("DataVersion", 1343)); + CompoundBinaryTag.Builder globalTag = CompoundBinaryTag.builder(); + globalTag.put("DataVersion", IntBinaryTag.intBinaryTag(1343)); + - CompoundTag chunkTag = new CompoundTag("Level", new CompoundMap()); + CompoundBinaryTag.Builder chunkTag = CompoundBinaryTag.builder(); - chunkTag.getValue().put("xPos", new IntTag("xPos", chunk.x)); - chunkTag.getValue().put("zPos", new IntTag("zPos", chunk.z)); - chunkTag.getValue().put("Sections", serializeSections(chunk.sections)); - chunkTag.getValue().put("Entities", new ListTag<>("Entities", TagType.TAG_COMPOUND, chunk.entities)); - chunkTag.getValue().put("TileEntities", new ListTag<>("TileEntities", TagType.TAG_COMPOUND, chunk.tileEntities)); - chunkTag.getValue().put("TileTicks", new ListTag<>("TileTicks", TagType.TAG_COMPOUND, new ArrayList<>())); - chunkTag.getValue().put("TerrainPopulated", new ByteTag("TerrainPopulated", (byte) 1)); - chunkTag.getValue().put("LightPopulated", new ByteTag("LightPopulated", (byte) 1)); + chunkTag.put("xPos", IntBinaryTag.intBinaryTag(chunk.x)); + chunkTag.put("zPos", IntBinaryTag.intBinaryTag(chunk.z)); + chunkTag.put("Sections", serializeSections(chunk.sections)); + chunkTag.put("Entities", ListBinaryTag.builder().add(chunk.entities).build()); + chunkTag.put("TileEntities", ListBinaryTag.builder().add(chunk.tileEntities).build()); + chunkTag.put("TileTicks", ListBinaryTag.empty()); + chunkTag.put("TerrainPopulated", ByteBinaryTag.byteBinaryTag((byte) 1)); + chunkTag.put("LightPopulated", ByteBinaryTag.byteBinaryTag((byte) 1)); - globalTag.getValue().put("Level", chunkTag); + globalTag.put("Level", chunkTag.build()); - globalTag = SlimeNMSBridge.instance().convertChunkTo1_13(globalTag); - chunkTag = globalTag.getAsCompoundTag("Level").get(); + CompoundBinaryTag convertedTag = slimeDataConverter.convertChunkTo1_13(globalTag.build()); + CompoundBinaryTag convertedChunk = convertedTag.getCompound("Level"); // Chunk sections - com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[] newSections = new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[16]; - ListTag serializedSections = (ListTag) chunkTag.getAsListTag("Sections").get(); + v1_9SlimeChunkSection[] newSections = new v1_9SlimeChunkSection[16]; + ListBinaryTag serializedSections = convertedChunk.getList("Sections"); - for (CompoundTag sectionTag : serializedSections.getValue()) { - ListTag palette = (ListTag) sectionTag.getAsListTag("Palette").get(); - long[] blockStates = sectionTag.getLongArrayValue("BlockStates").get(); + for (BinaryTag sectionTag : serializedSections) { + CompoundBinaryTag sectionCompound = (CompoundBinaryTag) sectionTag; + ListBinaryTag palette = sectionCompound.getList("Palette"); + long[] blockStates = sectionCompound.getLongArray("BlockStates"); - NibbleArray blockLight = new NibbleArray(sectionTag.getByteArrayValue("BlockLight").get()); - NibbleArray skyLight = new NibbleArray(sectionTag.getByteArrayValue("SkyLight").get()); + NibbleArray blockLight = new NibbleArray(sectionCompound.getByteArray("BlockLight")); + NibbleArray skyLight = new NibbleArray(sectionCompound.getByteArray("SkyLight")); - int index = sectionTag.getIntValue("Y").get(); + int index = sectionCompound.getInt("Y"); - com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection section = new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection(null, null, palette, blockStates, null, null, blockLight, skyLight); + v1_9SlimeChunkSection section = new v1_9SlimeChunkSection(null, null, palette, blockStates, null, null, blockLight, skyLight); newSections[index] = section; } @@ -70,7 +85,7 @@ public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v chunk.biomes = newBiomes; // Upgrade data - chunk.upgradeData = chunkTag.getAsCompoundTag("UpgradeData").orElse(null); + chunk.upgradeData = convertedChunk.getCompound("UpgradeData"); int done = i + 1; if (done == chunks.size()) { @@ -83,25 +98,25 @@ public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v } } - private ListTag serializeSections(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[] sections) { - ListTag sectionList = new ListTag<>("Sections", TagType.TAG_COMPOUND, new ArrayList<>()); + private ListBinaryTag serializeSections(v1_9SlimeChunkSection[] sections) { + ListBinaryTag.@NotNull Builder builder = ListBinaryTag.builder(); for (int i = 0; i < sections.length; i++) { - com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection section = sections[i]; + v1_9SlimeChunkSection section = sections[i]; if (section != null) { - CompoundTag sectionTag = new CompoundTag(i + "", new CompoundMap()); + CompoundBinaryTag.Builder sectionTag = CompoundBinaryTag.builder(); - sectionTag.getValue().put("Y", new IntTag("Y", i)); - sectionTag.getValue().put("Blocks", new ByteArrayTag("Blocks", section.blocks)); - sectionTag.getValue().put("Data", new ByteArrayTag("Data", section.data.getBacking())); - sectionTag.getValue().put("BlockLight", new ByteArrayTag("Data", section.blockLight.getBacking())); - sectionTag.getValue().put("SkyLight", new ByteArrayTag("Data", section.skyLight.getBacking())); + sectionTag.put("Y", IntBinaryTag.intBinaryTag(i)); + sectionTag.put("Blocks", ByteArrayBinaryTag.byteArrayBinaryTag(section.blocks)); + sectionTag.put("Data", ByteArrayBinaryTag.byteArrayBinaryTag(section.data.getBacking())); + sectionTag.put("BlockLight", ByteArrayBinaryTag.byteArrayBinaryTag(section.blockLight.getBacking())); + sectionTag.put("SkyLight", ByteArrayBinaryTag.byteArrayBinaryTag(section.skyLight.getBacking())); - sectionList.getValue().add(sectionTag); + builder.add(sectionTag.build()); } } - return sectionList; + return builder.build(); } } diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java deleted file mode 100644 index edd60c393..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java +++ /dev/null @@ -1,199 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; - -import com.flowpowered.nbt.*; -import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection; -import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld; - -import java.util.*; - -public class v1_14WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { - - private static final int[] VILLAGER_XP = { 0, 10, 50, 100, 150 }; - - private static Map oldToNewMap = new HashMap<>(); - private static Map newToOldMap = new HashMap<>(); - - static { - rename("minecraft:tube_coral_fan", "minecraft:tube_coral_wall_fan"); - rename("minecraft:brain_coral_fan", "minecraft:brain_coral_wall_fan"); - rename("minecraft:bubble_coral_fan", "minecraft:bubble_coral_wall_fan"); - rename("minecraft:fire_coral_fan", "minecraft:fire_coral_wall_fan"); - rename("minecraft:horn_coral_fan", "minecraft:horn_coral_wall_fan"); - rename("minecraft:stone_slab", "minecraft:smooth_stone_slab"); - rename("minecraft:sign", "minecraft:oak_sign"); - rename("minecraft:wall_sign", "minecraft:oak_wall_sign"); - } - - private static void rename(String oldName, String newName) { - oldToNewMap.put(oldName, newName); - newToOldMap.put(newName, oldName); - } - - @Override - public void upgrade(v1_9SlimeWorld world) { - for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : new ArrayList<>(world.chunks.values())) { - // Update renamed blocks - for (int sectionIndex = 0; sectionIndex < chunk.sections.length; sectionIndex++) { - v1_9SlimeChunkSection section = chunk.sections[sectionIndex]; - - if (section != null) { - List palette = section.palette.getValue(); - - for (int paletteIndex = 0; paletteIndex < palette.size(); paletteIndex++) { - CompoundTag blockTag = palette.get(paletteIndex); - String name = blockTag.getStringValue("Name").get(); - - // Trapped chests have now a different tile entity, - // so we have to update every block entity type - if (name.equals("minecraft:trapped_chest")) { - updateBlockEntities(chunk, sectionIndex, paletteIndex, "minecraft:chest", "minecraft:trapped_chest"); - } - - String newName = oldToNewMap.get(name); - - if (newName != null) { - blockTag.getValue().put("Name", new StringTag("Name", newName)); - } - } - } - } - - if (chunk.entities != null) { - for (CompoundTag entityTag : chunk.entities) { - String type = entityTag.getStringValue("id").get(); - - switch (type) { - case "minecraft:ocelot": - // Cats are no longer ocelots - int catType = entityTag.getIntValue("CatType").orElse(0); - - if (catType == 0) { - Optional owner = entityTag.getStringValue("Owner"); - Optional ownerId = entityTag.getStringValue("OwnerUUID"); - - if (owner.isPresent() || ownerId.isPresent()) { - entityTag.getValue().put("Trusting", new ByteTag("Trusting", (byte) 1)); - } - - entityTag.getValue().remove("CatType"); - } else if (catType > 0 && catType < 4) { - entityTag.getValue().put("id", new StringTag("id", "minecraft:cat")); - } - break; - case "minecraft:villager": - case "minecraft:zombie_villager": - // Villager data has changed - int profession = entityTag.getIntValue("Profession").orElse(0); - int career = entityTag.getIntValue("Career").orElse(0); - int careerLevel = entityTag.getIntValue("CareerLevel").orElse(1); - - // Villager level and xp has to be rebuilt - Optional offersOpt = entityTag.getAsCompoundTag("Offers"); - - if (offersOpt.isPresent()) { - if (careerLevel == 0 || careerLevel == 1) { - int amount = offersOpt.flatMap((offers) -> offers.getAsCompoundTag("Recipes")).map((recipes) -> recipes.getValue().size()).orElse(0); - careerLevel = clamp(amount / 2, 1, 5); - } - } - - Optional xp = entityTag.getAsCompoundTag("Xp"); - - if (!xp.isPresent()) { - entityTag.getValue().put("Xp", new IntTag("Xp", VILLAGER_XP[clamp(careerLevel - 1, 0, VILLAGER_XP.length - 1)])); - } - - entityTag.getValue().remove("Profession"); - entityTag.getValue().remove("Career"); - entityTag.getValue().remove("CareerLevel"); - - CompoundMap dataMap = new CompoundMap(); - dataMap.put("type", new StringTag("type", "minecraft:plains")); - dataMap.put("profession", new StringTag("profession", getVillagerProfession(profession, career))); - dataMap.put("level", new IntTag("level", careerLevel)); - - entityTag.getValue().put("VillagerData", new CompoundTag("VillagerData", dataMap)); - break; - case "minecraft:banner": - // The illager banners changed the translation message - Optional customName = entityTag.getStringValue("CustomName"); - - if (customName.isPresent()) { - String newName = customName.get().replace("\"translate\":\"block.minecraft.illager_banner\"", - "\"translate\":\"block.minecraft.ominous_banner\""); - - entityTag.getValue().put("CustomName", new StringTag("CustomName", newName)); - } - break; - } - } - } - } - } - - private int clamp(int i, int i1, int i2) { - return i < i1 ? i1 : (i > i2 ? i2 : i); - } - - private String getVillagerProfession(int profession, int career) { - return profession == 0 ? (career == 2 ? "minecraft:fisherman" : (career == 3 ? "minecraft:shepherd" : (career == 4 ? "minecraft:fletcher" : "minecraft:farmer"))) - : (profession == 1 ? (career == 2 ? "minecraft:cartographer" : "minecraft:librarian") : (profession == 2 ? "minecraft:cleric" : - (profession == 3 ? (career == 2 ? "minecraft:weaponsmith" : (career == 3 ? "minecraft:toolsmith" : "minecraft:armorer")) : - (profession == 4 ? (career == 2 ? "minecraft:leatherworker" : "minecraft:butcher") : (profession == 5 ? "minecraft:nitwit" : "minecraft:none"))))); - } - - private void updateBlockEntities(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk, int sectionIndex, int paletteIndex, String oldName, String newName) { - if (chunk.tileEntities != null) { - v1_9SlimeChunkSection section = chunk.sections[sectionIndex]; - long[] blockData = section.blockStates; - - int bitsPerBlock = Math.max(4, blockData.length * 64 / 4096); - long maxEntryValue = (1L << bitsPerBlock) - 1; - - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++) { - int arrayIndex = y << 8 | z << 4 | x; - int bitIndex = arrayIndex * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((arrayIndex + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - - int val; - - if (startIndex == endIndex) { - val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue); - } else { - int endBitSubIndex = 64 - startBitSubIndex; - val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); - } - - // It's the right block type - if (val == paletteIndex) { - int blockX = x + chunk.x * 16; - int blockY = y + sectionIndex * 16; - int blockZ = z + chunk.z * 16; - - for (CompoundTag tileEntityTag : chunk.tileEntities) { - int tileX = tileEntityTag.getIntValue("x").get(); - int tileY = tileEntityTag.getIntValue("y").get(); - int tileZ = tileEntityTag.getIntValue("z").get(); - - if (tileX == blockX && tileY == blockY && tileZ == blockZ) { - String type = tileEntityTag.getStringValue("id").get(); - - if (!type.equals(oldName)) { - throw new IllegalStateException("Expected block entity to be " + oldName + ", not " + type); - } - - tileEntityTag.getValue().put("id", new StringTag("id", newName)); - break; - } - } - } - } - } - } - } - } -} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java index 520f88142..8c1f54730 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java @@ -1,28 +1,41 @@ package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.LongArrayTag; -import com.flowpowered.nbt.Tag; +import com.infernalsuite.asp.api.SlimeDataConverter; +import com.infernalsuite.asp.api.SlimeNMSBridge; import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection; import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.LongArrayBinaryTag; import java.util.Arrays; +import java.util.Map; public class v1_16WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { + private static final int DATA_VERSION = 2586; + private static final int[] MULTIPLY_DE_BRUIJN_BIT_POSITION = new int[]{ 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 }; @Override - public void upgrade(v1_9SlimeWorld world) { + public void upgrade(v1_9SlimeWorld world, SlimeDataConverter slimeDataConverter) { for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : world.chunks.values()) { - // Add padding to height maps and block states - CompoundTag heightMaps = chunk.heightMap; + chunk.tileEntities = slimeDataConverter.convertTileEntities(chunk.tileEntities, world.getDataVersion(), DATA_VERSION); + chunk.entities = slimeDataConverter.convertEntities(chunk.entities, world.getDataVersion(), DATA_VERSION); + - for (Tag map : heightMaps.getValue().values()) { - if (map instanceof LongArrayTag arrayTag) { - arrayTag.setValue(addPadding(256, 9, arrayTag.getValue())); + // Add padding to height maps and block states + CompoundBinaryTag heightMaps = CompoundBinaryTag.builder().build(); + + for (Map.Entry heightMapEntry : chunk.heightMap) { + if (heightMapEntry.getValue() instanceof LongArrayBinaryTag arrayTag) { + heightMaps.put(heightMapEntry.getKey(), LongArrayBinaryTag.longArrayBinaryTag( + addPadding(256, 9, arrayTag.value()) + )); + } else { + heightMaps.put(heightMapEntry.getKey(), heightMapEntry.getValue()); } } @@ -30,7 +43,9 @@ public void upgrade(v1_9SlimeWorld world) { v1_9SlimeChunkSection section = chunk.sections[sectionIndex]; if (section != null) { - int bitsPerBlock = Math.max(4, ceillog2(section.palette.getValue().size())); + section.palette = slimeDataConverter.convertBlockPalette(section.palette, world.getDataVersion(), DATA_VERSION); + + int bitsPerBlock = Math.max(4, ceillog2(section.palette.size())); if (!isPowerOfTwo(bitsPerBlock)) { section = new v1_9SlimeChunkSection(null, null, section.palette, diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java deleted file mode 100644 index 0455b9c33..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; - -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.StringTag; - -import java.util.List; -import java.util.Optional; - -public class v1_17WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { - - @Override - public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld world) { - for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : world.chunks.values()) { - for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection section : chunk.sections) { - if (section == null) { - continue; - } - - List palette = section.palette.getValue(); - - for (CompoundTag blockTag : palette) { - Optional name = blockTag.getStringValue("Name"); - CompoundMap map = blockTag.getValue(); - - // CauldronRenameFix - if (name.equals(Optional.of("minecraft:cauldron"))) { - Optional properties = blockTag.getAsCompoundTag("Properties"); - if (properties.isPresent()) { - String waterLevel = blockTag.getStringValue("level").orElse("0"); - if (waterLevel.equals("0")) { - map.remove("Properties"); - } else { - map.put("Name", new StringTag("Name", "minecraft:water_cauldron")); - } - } - } - - // Renamed grass path item to dirt path - if (name.equals(Optional.of("minecraft:grass_path"))) { - map.put("Name", new StringTag("Name", "minecraft:dirt_path")); - } - } - } - } - } - -} \ No newline at end of file diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java index c1e0bc799..bdb69ad00 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java @@ -1,14 +1,17 @@ package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; -import com.flowpowered.nbt.*; +import com.infernalsuite.asp.api.SlimeDataConverter; +import net.kyori.adventure.nbt.*; import java.util.*; public class v1_18WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { private static final String[] BIOMES_BY_ID = new String[256]; // rip datapacks + private static final int DATA_VERSION = 2975; static { + //Unfortunately DFU only supports 1.18 biome upgrades on chunk conversion, so we have to do this manually BIOMES_BY_ID[0] = "minecraft:ocean"; BIOMES_BY_ID[1] = "minecraft:plains"; BIOMES_BY_ID[2] = "minecraft:desert"; @@ -142,64 +145,12 @@ public class v1_18WorldUpgrade implements com.infernalsuite.asp.serialization.sl } @Override - public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld world) { + public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld world, SlimeDataConverter converter) { for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : world.chunks.values()) { + chunk.tileEntities = converter.convertTileEntities(chunk.tileEntities, world.getDataVersion(), DATA_VERSION); + chunk.entities = converter.convertEntities(chunk.entities, world.getDataVersion(), DATA_VERSION); - // SpawnerSpawnDataFix - for (CompoundTag tileEntity : chunk.tileEntities) { - CompoundMap value = tileEntity.getValue(); - Optional id = tileEntity.getStringValue("id"); - if (id.equals(Optional.of("minecraft:mob_spawner"))) { - Optional> spawnPotentials = tileEntity.getAsListTag("SpawnPotentials"); - Optional spawnData = tileEntity.getAsCompoundTag("SpawnData"); - if (spawnPotentials.isPresent()) { - ListTag spawnPotentialsList = (ListTag) spawnPotentials.get(); - List spawnPotentialsListValue = spawnPotentialsList.getValue(); - for (CompoundTag spawnPotentialsTag : spawnPotentialsListValue) { - CompoundMap spawnPotentialsValue = spawnPotentialsTag.getValue(); - Optional weight = spawnPotentialsTag.getIntValue("Weight"); - if (weight.isPresent()) { - int weightVal = weight.get(); - spawnPotentialsValue.remove("Weight"); - spawnPotentialsValue.put("weight", new IntTag("weight", weightVal)); - } - Optional entity = spawnPotentialsTag.getAsCompoundTag("Entity"); - if (entity.isPresent()) { - CompoundTag entityTag = entity.get(); - spawnPotentialsValue.remove("Entity"); - entityTag.getValue(); - CompoundMap dataMap = new CompoundMap(); - dataMap.put(new CompoundTag("entity", entityTag.getValue())); - spawnPotentialsValue.put("data", new CompoundTag("data", dataMap)); - } - } - value.put("SpawnPotentials", spawnPotentialsList); - if (!spawnPotentialsListValue.isEmpty()) { - CompoundTag compoundTag = spawnPotentialsListValue.get(0); - CompoundTag entityTag = compoundTag.getAsCompoundTag("data"). - get().getAsCompoundTag("entity").get(); - CompoundMap spawnDataMap = new CompoundMap(); - spawnDataMap.put(entityTag.clone()); - value.put("SpawnData", new CompoundTag("SpawnData", spawnDataMap)); - } - } else if (spawnData.isPresent()) { - CompoundTag spawnDataTag = spawnData.get(); - CompoundMap spawnDataValue = spawnDataTag.getValue(); - Optional entityTag = spawnDataTag.getAsCompoundTag("entity"); - Optional idTag = spawnDataTag.getAsStringTag("id"); - if (entityTag.isEmpty() && idTag.isPresent()) { - StringTag entityTypeTag = idTag.get(); - spawnDataValue.remove("id"); - CompoundMap entityMap = new CompoundMap(); - entityMap.put(entityTypeTag); - spawnDataValue.put("entity", new CompoundTag("entity", entityMap)); - value.put("SpawnData", spawnDataTag); - } - } - } - } - - CompoundTag[] tags = createBiomeSections(chunk.biomes, false, 0); + CompoundBinaryTag[] tags = createBiomeSections(chunk.biomes, false, 0); com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[] sections = chunk.sections; for (int i = 0; i < sections.length; i++) { @@ -208,7 +159,7 @@ public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v continue; } - + section.palette = converter.convertBlockPalette(section.palette, world.getDataVersion(), DATA_VERSION); section.blockStatesTag = wrapPalette(section.palette, section.blockStates); section.biomeTag = tags[i]; } @@ -221,14 +172,19 @@ public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection[] sectionArray = chunk.sections; - CompoundMap emptyBiomes = new CompoundMap(); - emptyBiomes.put("palette", new ListTag<>("palette", TagType.TAG_STRING, List.of(new StringTag("", "minecraft:plains")))); + CompoundBinaryTag emptyBiomes = CompoundBinaryTag.builder() + .put("palette", ListBinaryTag.listBinaryTag(BinaryTagTypes.STRING, List.of(StringBinaryTag.stringBinaryTag("minecraft:plains")))) + .build(); + + CompoundBinaryTag blocks = CompoundBinaryTag.builder() + .put("palette", ListBinaryTag.listBinaryTag(BinaryTagTypes.COMPOUND, List.of( + CompoundBinaryTag.builder() + .put("Name", StringBinaryTag.stringBinaryTag("minecraft:air")) + .build() + ))) + .build(); - CompoundMap blocks = new CompoundMap(); - emptyBiomes.put("palette", new ListTag<>("palette", TagType.TAG_STRING, List.of(new StringTag("", "minecraft:air")))); - CompoundTag blockTag = new CompoundTag("", blocks); - CompoundTag emptyBiomesTag = new CompoundTag("", emptyBiomes); for (int i = 0; i < sectionArray.length; i++) { com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunkSection section = sectionArray[i]; if (section == null) { @@ -237,8 +193,8 @@ public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v null, null, null, - blockTag, - emptyBiomesTag, + blocks, + emptyBiomes, null, null ); @@ -247,8 +203,8 @@ public void upgrade(com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v } } - private static CompoundTag[] createBiomeSections(int[] biomes, final boolean wantExtendedHeight, final int minSection) { - final CompoundTag[] ret = new CompoundTag[wantExtendedHeight ? 24 : 16]; + private static CompoundBinaryTag[] createBiomeSections(int[] biomes, final boolean wantExtendedHeight, final int minSection) { + final CompoundBinaryTag[] ret = new CompoundBinaryTag[wantExtendedHeight ? 24 : 16]; if (biomes != null && biomes.length == 1536) { // magic value for 24 sections of biomes (24 * 4^3) //isAlreadyExtended.setValue(true); @@ -274,11 +230,11 @@ private static CompoundTag[] createBiomeSections(int[] biomes, final boolean wan // } // } } else { - ArrayList palette = new ArrayList<>(); - palette.add(new StringTag("", "minecraft:plains")); + ArrayList palette = new ArrayList<>(); + palette.add(StringBinaryTag.stringBinaryTag("minecraft:plains")); for (int i = 0; i < ret.length; ++i) { - ret[i] = wrapPalette(new ListTag<>("", TagType.TAG_STRING, palette).clone(), null); // copy palette so that later possible modifications don't trash all sections + ret[i] = wrapPalette(ListBinaryTag.listBinaryTag(BinaryTagTypes.STRING, palette), null); // copy palette so that later possible modifications don't trash all sections } } @@ -289,7 +245,7 @@ public static int ceilLog2(final int value) { return value == 0 ? 0 : Integer.SIZE - Integer.numberOfLeadingZeros(value - 1); // see doc of numberOfLeadingZeros } - private static CompoundTag createBiomeSection(final int[] biomes, final int offset, final int mask) { + private static CompoundBinaryTag createBiomeSection(final int[] biomes, final int offset, final int mask) { final Map paletteId = new HashMap<>(); for (int idx = 0; idx < 64; ++idx) { @@ -297,7 +253,7 @@ private static CompoundTag createBiomeSection(final int[] biomes, final int offs paletteId.putIfAbsent(biome, paletteId.size()); } - List paletteString = new ArrayList<>(); + List paletteString = new ArrayList<>(); for (final Iterator iterator = paletteId.keySet().iterator(); iterator.hasNext(); ) { final int biomeId = iterator.next(); String biome = biomeId >= 0 && biomeId < BIOMES_BY_ID.length ? BIOMES_BY_ID[biomeId] : null; @@ -306,12 +262,12 @@ private static CompoundTag createBiomeSection(final int[] biomes, final int offs biome = update; } - paletteString.add(new StringTag("", biome == null ? "minecraft:plains" : biome)); + paletteString.add(StringBinaryTag.stringBinaryTag(biome == null ? "minecraft:plains" : biome)); } final int bitsPerObject = ceilLog2(paletteString.size()); if (bitsPerObject == 0) { - return wrapPalette(new ListTag<>("", TagType.TAG_STRING, paletteString), null); + return wrapPalette(ListBinaryTag.listBinaryTag(BinaryTagTypes.STRING, paletteString), null); } // manually create packed integer data @@ -342,19 +298,17 @@ private static CompoundTag createBiomeSection(final int[] biomes, final int offs packed[idx] = curr; } - return wrapPalette(new ListTag<>("", TagType.TAG_STRING, paletteString), packed); + return wrapPalette(ListBinaryTag.listBinaryTag(BinaryTagTypes.STRING, paletteString), packed); } - private static CompoundTag wrapPalette(ListTag palette, final long[] blockStates) { - CompoundMap map = new CompoundMap(); - CompoundTag tag = new CompoundTag("", map); - - map.put(new ListTag<>("palette", palette.getElementType(), palette.getValue())); + private static CompoundBinaryTag wrapPalette(ListBinaryTag palette, final long[] blockStates) { + CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder() + .put("palette", palette); if (blockStates != null) { - map.put(new LongArrayTag("data", blockStates)); + builder.put("data", LongArrayBinaryTag.longArrayBinaryTag(blockStates)); } - return tag; + return builder.build(); } } \ No newline at end of file diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java deleted file mode 100644 index bc1a5c6b2..000000000 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade; - -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.StringTag; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.JsonSyntaxException; -import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeWorld; - -public class v1_9WorldUpgrade implements com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.Upgrade { - - private static final JsonParser PARSER = new JsonParser(); - - @Override - public void upgrade(v1_9SlimeWorld world) { - // In 1.9, all signs must be formatted using JSON - for (com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9SlimeChunk chunk : world.chunks.values()) { - for (CompoundTag entityTag : chunk.tileEntities) { - String type = entityTag.getAsStringTag("id").get().getValue(); - - if (type.equals("Sign")) { - CompoundMap map = entityTag.getValue(); - - for (int i = 1; i < 5; i++) { - String id = "Text" + i; - - map.put(id, new StringTag(id, fixJson(entityTag.getAsStringTag(id).map(StringTag::getValue).orElse(null)))); - } - } - } - } - } - - private static String fixJson(String value) { - if (value == null || value.equalsIgnoreCase("null") || value.isEmpty()) { - return "{\"text\":\"\"}"; - } - - try { - PARSER.parse(value); - } catch (JsonSyntaxException ex) { - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("text", value); - - return jsonObject.toString(); - } - - return value; - } -} diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java index 306f54fdd..c6dd2cc75 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java @@ -1,6 +1,6 @@ package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; -import com.flowpowered.nbt.CompoundTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; import java.util.List; @@ -11,12 +11,12 @@ public final class v1_9SlimeChunk { public v1_9SlimeChunkSection[] sections; public final int minY; public final int maxY; - public final CompoundTag heightMap; + public CompoundBinaryTag heightMap; public int[] biomes; - public final List tileEntities; - public final List entities; + public List tileEntities; + public List entities; // Used for 1.13 world upgrading - public CompoundTag upgradeData; + public CompoundBinaryTag upgradeData; v1_9SlimeChunk(String worldName, int x, @@ -24,10 +24,10 @@ public final class v1_9SlimeChunk { v1_9SlimeChunkSection[] sections, int minY, int maxY, - CompoundTag heightMap, + CompoundBinaryTag heightMap, int[] biomes, - List tileEntities, - List entities) { + List tileEntities, + List entities) { this.worldName = worldName; this.x = x; this.z = z; diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java index 5379c3dbf..36dd48fb2 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java @@ -1,8 +1,8 @@ package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.ListTag; import com.infernalsuite.asp.api.utils.NibbleArray; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.ListBinaryTag; public class v1_9SlimeChunkSection { @@ -11,17 +11,17 @@ public class v1_9SlimeChunkSection { public final NibbleArray data; // Post 1.13 block data - public final ListTag palette; + public ListBinaryTag palette; public final long[] blockStates; // Post 1.17 block data - public CompoundTag blockStatesTag; - public CompoundTag biomeTag; + public CompoundBinaryTag blockStatesTag; + public CompoundBinaryTag biomeTag; public final NibbleArray blockLight; public final NibbleArray skyLight; - public v1_9SlimeChunkSection(byte[] blocks, NibbleArray data, ListTag palette, long[] blockStates, CompoundTag blockStatesTag, CompoundTag biomeTag, NibbleArray blockLight, NibbleArray skyLight) { + public v1_9SlimeChunkSection(byte[] blocks, NibbleArray data, ListBinaryTag palette, long[] blockStates, CompoundBinaryTag blockStatesTag, CompoundBinaryTag biomeTag, NibbleArray blockLight, NibbleArray skyLight) { this.blocks = blocks; this.data = data; this.palette = palette; diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java index 0864c6b92..87656a073 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java @@ -1,17 +1,20 @@ package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; -import com.flowpowered.nbt.CompoundTag; import com.infernalsuite.asp.api.loaders.SlimeLoader; import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import net.kyori.adventure.nbt.BinaryTag; + +import java.util.concurrent.ConcurrentMap; public class v1_9SlimeWorld { public byte version; + public final String worldName; public final SlimeLoader loader; public final Long2ObjectMap chunks; - public final CompoundTag extraCompound; + public final ConcurrentMap extraCompound; public final SlimePropertyMap propertyMap; public final boolean readOnly; @@ -19,7 +22,7 @@ public v1_9SlimeWorld(byte version, String worldName, SlimeLoader loader, Long2ObjectMap chunks, - CompoundTag extraCompound, + ConcurrentMap extraCompound, SlimePropertyMap propertyMap, boolean readOnly) { this.version = version; @@ -31,5 +34,18 @@ public v1_9SlimeWorld(byte version, this.readOnly = readOnly; } + public int getDataVersion() { + return switch (version) { + case 0x01 -> 99;//1.8; 99 as 1.8 does not have a dataversion yet and 100 is the first one + case 0x02 -> 184;//1.9.4 + case 0x03 -> 922;//1.11.2 + case 0x04 -> 1631;//1.13.2 + case 0x05 -> 1976;//1.14.4 + case 0x06 -> 2586;//1.16.5 + case 0x07 -> 2730;//1.17.1 + case 0x08 -> 2975;//1.18 + default -> throw new IllegalStateException("Unexpected value: " + version); + }; + } } diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java index 07b7e24d3..1086e2fd0 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java @@ -1,13 +1,5 @@ package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.DoubleTag; -import com.flowpowered.nbt.IntArrayTag; -import com.flowpowered.nbt.IntTag; -import com.flowpowered.nbt.ListTag; -import com.flowpowered.nbt.TagType; -import com.flowpowered.nbt.stream.NBTInputStream; import com.github.luben.zstd.Zstd; import com.infernalsuite.asp.SlimeLogger; import com.infernalsuite.asp.Util; @@ -18,16 +10,17 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import net.kyori.adventure.nbt.*; + import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.EOFException; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.List; -import java.util.Optional; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; class v1_9SlimeWorldDeserializer implements com.infernalsuite.asp.serialization.slime.reader.VersionedByteSlimeWorldReader { @@ -136,18 +129,20 @@ public v1_9SlimeWorld deserializeWorld(byte version, SlimeLoader loader, String Long2ObjectMap chunks = readChunks(worldVersion, version, worldName, minX, minZ, width, depth, chunkBitset, chunkData); // Entity deserialization - CompoundTag entitiesCompound = readCompoundTag(entities); + CompoundBinaryTag entitiesCompound = readCompoundTag(entities); - Long2ObjectMap> entityStorage = new Long2ObjectOpenHashMap<>(); + Long2ObjectMap> entityStorage = new Long2ObjectOpenHashMap<>(); if (entitiesCompound != null) { - List serializedEntities = ((ListTag) entitiesCompound.getValue().get("entities")).getValue(); + ListBinaryTag serializedEntities = entitiesCompound.getList("entities", BinaryTagTypes.COMPOUND); SlimeLogger.debug("Serialized entities: " + serializedEntities); - for (CompoundTag entityCompound : serializedEntities) { - ListTag listTag = (ListTag) entityCompound.getAsListTag("Pos").get(); + for (BinaryTag entityCompoundTag : serializedEntities) { + CompoundBinaryTag entityCompound = (CompoundBinaryTag) entityCompoundTag; + + ListBinaryTag listTag = entityCompound.getList("Pos"); - int chunkX = floor(listTag.getValue().get(0).getValue()) >> 4; - int chunkZ = floor(listTag.getValue().get(2).getValue()) >> 4; + int chunkX = floor(listTag.getDouble(0)) >> 4; + int chunkZ = floor(listTag.getDouble(2)) >> 4; long chunkKey = Util.chunkPosition(chunkX, chunkZ); v1_9SlimeChunk chunk = chunks.get(chunkKey); if (chunk != null) { @@ -156,7 +151,7 @@ public v1_9SlimeWorld deserializeWorld(byte version, SlimeLoader loader, String if (entityStorage.containsKey(chunkKey)) { entityStorage.get(chunkKey).add(entityCompound); } else { - List entityStorageList = new ArrayList<>(); + List entityStorageList = new ArrayList<>(); entityStorageList.add(entityCompound); entityStorage.put(chunkKey, entityStorageList); } @@ -164,13 +159,14 @@ public v1_9SlimeWorld deserializeWorld(byte version, SlimeLoader loader, String } // Tile Entity deserialization - CompoundTag tileEntitiesCompound = readCompoundTag(tileEntities); + CompoundBinaryTag tileEntitiesCompound = readCompoundTag(tileEntities); if (tileEntitiesCompound != null) { - ListTag tileEntitiesList = (ListTag) tileEntitiesCompound.getValue().get("tiles"); - for (CompoundTag tileEntityCompound : tileEntitiesList.getValue()) { - int chunkX = ((IntTag) tileEntityCompound.getValue().get("x")).getValue() >> 4; - int chunkZ = ((IntTag) tileEntityCompound.getValue().get("z")).getValue() >> 4; + ListBinaryTag tileEntitiesList = tileEntitiesCompound.getList("tiles"); + for (BinaryTag tileEntityCompoundTag : tileEntitiesList) { + CompoundBinaryTag tileEntityCompound = (CompoundBinaryTag) tileEntityCompoundTag; + int chunkX = tileEntityCompound.getInt("x") >> 4; + int chunkZ = tileEntityCompound.getInt("z") >> 4; v1_9SlimeChunk chunk = chunks.get(Util.chunkPosition(chunkX, chunkZ)); if (chunk == null) { @@ -182,10 +178,10 @@ public v1_9SlimeWorld deserializeWorld(byte version, SlimeLoader loader, String } // Extra Data - CompoundTag extraCompound = readCompoundTag(extraTag); + CompoundBinaryTag extraCompound = readCompoundTag(extraTag); if (extraCompound == null) { - extraCompound = new CompoundTag("", new CompoundMap()); + extraCompound = CompoundBinaryTag.empty(); } if (version <= 0x05) {} @@ -203,24 +199,30 @@ public v1_9SlimeWorld deserializeWorld(byte version, SlimeLoader loader, String // World properties SlimePropertyMap worldPropertyMap = propertyMap; - Optional propertiesMap = extraCompound - .getAsCompoundTag("properties") - .map(CompoundTag::getValue); + CompoundBinaryTag propertiesMap = extraCompound + .getCompound("properties"); - if (propertiesMap.isPresent()) { - worldPropertyMap = new SlimePropertyMap(propertiesMap.get()); + if (!propertiesMap.isEmpty()) { + Map wpm = new HashMap<>(); + propertiesMap.forEach(entry -> wpm.put(entry.getKey(), entry.getValue())); + + worldPropertyMap = new SlimePropertyMap(wpm); worldPropertyMap.merge(propertyMap); // Override world properties } else if (propertyMap == null) { // Make sure the property map is never null worldPropertyMap = new SlimePropertyMap(); } + + ConcurrentMap extraData = new ConcurrentHashMap<>(); + extraCompound.forEach(entry -> extraData.put(entry.getKey(), entry.getValue())); + return new v1_9SlimeWorld( worldVersion, worldName, loader, chunks, - extraCompound, - propertyMap, + extraData, + worldPropertyMap, readOnly ); } catch (EOFException ex) { @@ -243,7 +245,7 @@ private static Long2ObjectMap readChunks(byte worldVersion, int if (chunkBitset.get(bitsetIndex)) { // Height Maps - CompoundTag heightMaps; + CompoundBinaryTag heightMaps; if (worldVersion >= 0x04) { int heightMapsLength = dataStream.readInt(); @@ -253,7 +255,7 @@ private static Long2ObjectMap readChunks(byte worldVersion, int // Height Maps might be null if empty if (heightMaps == null) { - heightMaps = new CompoundTag("", new CompoundMap()); + heightMaps = CompoundBinaryTag.empty(); } } else { int[] heightMap = new int[256]; @@ -262,10 +264,8 @@ private static Long2ObjectMap readChunks(byte worldVersion, int heightMap[i] = dataStream.readInt(); } - CompoundMap map = new CompoundMap(); - map.put("heightMap", new IntArrayTag("heightMap", heightMap)); - - heightMaps = new CompoundTag("", map); + heightMaps = CompoundBinaryTag.builder() + .put("heightMap", IntArrayBinaryTag.intArrayBinaryTag(heightMap)).build(); } // Biome array @@ -349,11 +349,11 @@ private static ChunkSectionData readChunkSectionsNew(DataInputStream dataStream, // Block data byte[] blockStateData = new byte[dataStream.readInt()]; dataStream.read(blockStateData); - CompoundTag blockStateTag = readCompoundTag(blockStateData); + CompoundBinaryTag blockStateTag = readCompoundTag(blockStateData); byte[] biomeData = new byte[dataStream.readInt()]; dataStream.read(biomeData); - CompoundTag biomeTag = readCompoundTag(biomeData); + CompoundBinaryTag biomeTag = readCompoundTag(biomeData); // Sky Light Nibble Array NibbleArray skyLightArray; @@ -401,24 +401,26 @@ private static ChunkSectionData readChunkSections(DataInputStream dataStream, by byte[] blockArray; NibbleArray dataArray; - ListTag paletteTag; + ListBinaryTag paletteTag; long[] blockStatesArray; if (worldVersion >= 0x04) { // Post 1.13 // Palette int paletteLength = dataStream.readInt(); - List paletteList = new ArrayList<>(paletteLength); + List paletteList = new ArrayList<>(paletteLength); for (int index = 0; index < paletteLength; index++) { int tagLength = dataStream.readInt(); byte[] serializedTag = new byte[tagLength]; dataStream.read(serializedTag); - CompoundTag tag = readCompoundTag(serializedTag); + CompoundBinaryTag tag = readCompoundTag(serializedTag); paletteList.add(tag); } - paletteTag = new ListTag<>("", TagType.TAG_COMPOUND, paletteList); + paletteTag = ListBinaryTag.builder() + .add(paletteList) + .build(); // Block states int blockStatesArrayLength = dataStream.readInt(); @@ -468,13 +470,11 @@ private static ChunkSectionData readChunkSections(DataInputStream dataStream, by return new ChunkSectionData(chunkSectionArray, 0, 16); } - private static CompoundTag readCompoundTag(byte[] serializedCompound) throws IOException { + private static CompoundBinaryTag readCompoundTag(byte[] serializedCompound) throws IOException { if (serializedCompound.length == 0) { return null; } - NBTInputStream stream = new NBTInputStream(new ByteArrayInputStream(serializedCompound), NBTInputStream.NO_COMPRESSION, ByteOrder.BIG_ENDIAN); - - return (CompoundTag) stream.readTag(); + return BinaryTagIO.unlimitedReader().read(new ByteArrayInputStream(serializedCompound)); } } diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java index f5a06898e..64ed21953 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java @@ -1,30 +1,29 @@ package com.infernalsuite.asp.serialization.slime.reader.impl.v1_9; -import com.flowpowered.nbt.*; +import com.infernalsuite.asp.api.SlimeNMSBridge; +import com.infernalsuite.asp.serialization.SlimeWorldReader; import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.*; import com.infernalsuite.asp.api.world.SlimeChunk; import com.infernalsuite.asp.api.world.SlimeChunkSection; import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.skeleton.SkeletonSlimeWorld; +import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; +import com.infernalsuite.asp.skeleton.SlimeChunkSkeleton; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import java.util.ArrayList; + import java.util.HashMap; import java.util.Map; -import java.util.logging.Logger; -class v1_v9SlimeConverter implements com.infernalsuite.asp.serialization.SlimeWorldReader { +class v1_v9SlimeConverter implements SlimeWorldReader { public static final Map UPGRADES = new HashMap<>(); static { - UPGRADES.put((byte) 0x02, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_9WorldUpgrade()); - UPGRADES.put((byte) 0x03, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_11WorldUpgrade()); - UPGRADES.put((byte) 0x04, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_13WorldUpgrade()); - UPGRADES.put((byte) 0x05, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_14WorldUpgrade()); - UPGRADES.put((byte) 0x06, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_16WorldUpgrade()); - UPGRADES.put((byte) 0x07, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_17WorldUpgrade()); - UPGRADES.put((byte) 0x08, new com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.upgrade.v1_18WorldUpgrade()); + UPGRADES.put((byte) 0x04, new v1_13WorldUpgrade()); + UPGRADES.put((byte) 0x06, new v1_16WorldUpgrade()); + UPGRADES.put((byte) 0x08, new v1_18WorldUpgrade()); } @Override @@ -39,36 +38,15 @@ public SlimeWorld readFromData(v1_9SlimeWorld data) { for (int i = 0; i < sections.length; i++) { v1_9SlimeChunkSection dataSection = slimeChunk.sections[i]; if (dataSection != null) { - // I'm not sure which upgrader should handle this, so I'm leaving it here - if (dataSection.biomeTag != null) { - ListTag palette = (ListTag) dataSection.biomeTag.getValue().get("palette"); - - ArrayList newPalette = new ArrayList(); - if (palette != null) { - for (StringTag stringTag : palette.getValue()) { - // air is no longer a valid biome, I'm not sure when this changed, - // so I cannot pick the proper upgrader to place it in. - if (stringTag.getValue().equals("minecraft:air")) continue; - newPalette.add(stringTag); - } - } - - if (palette == null || palette.getValue().isEmpty()) { - newPalette.add(new StringTag(null, "minecraft:plains")); - } - - dataSection.biomeTag.getValue().put("palette", new ListTag<>("palette", TagType.TAG_STRING, newPalette)); - } - - sections[i] = new com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton( + sections[i] = new SlimeChunkSectionSkeleton( // SlimeChunkConverter can handle null blockState, but cannot handle empty blockState - dataSection.blockStatesTag.getValue().isEmpty() ? null : dataSection.blockStatesTag, + dataSection.blockStatesTag.isEmpty() ? null : dataSection.blockStatesTag, dataSection.biomeTag, dataSection.blockLight, dataSection.skyLight ); } else { - sections[i] = new com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton( + sections[i] = new SlimeChunkSectionSkeleton( null, null, null, @@ -81,20 +59,20 @@ public SlimeWorld readFromData(v1_9SlimeWorld data) { // slimeChunk.minY, // slimeChunk.maxY, - chunks.put(entry.getLongKey(), new com.infernalsuite.asp.skeleton.SlimeChunkSkeleton( + chunks.put(entry.getLongKey(), new SlimeChunkSkeleton( slimeChunk.x, slimeChunk.z, sections, slimeChunk.heightMap, slimeChunk.tileEntities, slimeChunk.entities, - new CompoundTag("", new CompoundMap()), + new HashMap<>(), slimeChunk.upgradeData )); } - return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld( + return new SkeletonSlimeWorld( data.worldName, data.loader, data.readOnly, @@ -108,24 +86,17 @@ public SlimeWorld readFromData(v1_9SlimeWorld data) { public static int upgradeWorld(v1_9SlimeWorld world) { byte upgradeTo = 0x08; // Last version - int dataVersion = 3120; // MCVersions.V1_19_2 for (byte ver = (byte) (world.version + 1); ver <= upgradeTo; ver++) { Upgrade upgrade = UPGRADES.get(ver); if (upgrade == null) { - Logger.getLogger("v1_9WorldUpgrader").warning("Missing world upgrader for version " + ver + ". World will not be upgraded."); continue; } - upgrade.upgrade(world); - - if (ver == 0x08) { - dataVersion = 2975; - } + upgrade.upgrade(world, SlimeNMSBridge.instance().getSlimeDataConverter()); + world.version=ver; } - - world.version = 0x09; - return dataVersion; + return world.getDataVersion(); } } From 26239f644d3822360743c67c8941b94d74bc163b Mon Sep 17 00:00:00 2001 From: David Date: Sat, 12 Apr 2025 13:45:31 +0200 Subject: [PATCH 125/133] feat: reintroduce v10 and v11 deserializer Signed-off-by: David --- .../reader/SlimeWorldReaderRegistry.java | 8 +- .../impl/v10/v10SlimeWorldDeSerializer.java | 101 +++++++++--------- .../impl/v11/v11SlimeWorldDeSerializer.java | 74 ++++++++----- 3 files changed, 103 insertions(+), 80 deletions(-) diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java index 146a96ed8..57ff7f257 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java @@ -6,10 +6,10 @@ import com.infernalsuite.asp.api.utils.SlimeFormat; import com.infernalsuite.asp.api.world.SlimeWorld; import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; -//import com.infernalsuite.asp.serialization.slime.reader.impl.v11.v11WorldFormat; +import com.infernalsuite.asp.serialization.slime.reader.impl.v10.v10WorldFormat; +import com.infernalsuite.asp.serialization.slime.reader.impl.v11.v11WorldFormat; import com.infernalsuite.asp.serialization.slime.reader.impl.v12.v12WorldFormat; import com.infernalsuite.asp.serialization.slime.reader.impl.v1_9.v1_9WorldFormat; -//import com.infernalsuite.asp.serialization.slime.reader.impl.v10.v10WorldFormat; import java.io.ByteArrayInputStream; import java.io.DataInputStream; @@ -24,8 +24,8 @@ public class SlimeWorldReaderRegistry { static { register(v1_9WorldFormat.FORMAT, 1, 2, 3, 4, 5, 6, 7, 8, 9); - //register(v10WorldFormat.FORMAT, 10); - //register(v11WorldFormat.FORMAT, 11); + register(v10WorldFormat.FORMAT, 10); + register(v11WorldFormat.FORMAT, 11); register(v12WorldFormat.FORMAT, 12); } diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java index 3baf1fb1b..e83dbb544 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java @@ -1,11 +1,5 @@ package com.infernalsuite.asp.serialization.slime.reader.impl.v10; -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.DoubleTag; -import com.flowpowered.nbt.IntTag; -import com.flowpowered.nbt.ListTag; -import com.flowpowered.nbt.stream.NBTInputStream; import com.github.luben.zstd.Zstd; import com.infernalsuite.asp.Util; import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; @@ -18,16 +12,19 @@ import com.infernalsuite.asp.api.world.properties.SlimeProperties; import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import net.kyori.adventure.nbt.*; + import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; class v10SlimeWorldDeSerializer implements VersionedByteSlimeWorldReader { @@ -51,14 +48,15 @@ public SlimeWorld deserializeWorld(byte version, SlimeLoader loader, String worl byte[] extra = readCompressed(dataStream); // Entity deserialization - com.flowpowered.nbt.CompoundTag entitiesCompound = readCompound(entities); - { - List serializedEntities = ((ListTag) entitiesCompound.getValue().get("entities")).getValue(); - for (CompoundTag entityCompound : serializedEntities) { - ListTag listTag = (ListTag) entityCompound.getAsListTag("Pos").get(); - - int chunkX = listTag.getValue().get(0).getValue().intValue() >> 4; - int chunkZ = listTag.getValue().get(2).getValue().intValue() >> 4; + CompoundBinaryTag entitiesCompound = readCompound(entities); + if(entitiesCompound != null) { + for (BinaryTag binaryTag : entitiesCompound.getList("entities", BinaryTagTypes.COMPOUND)) { + CompoundBinaryTag entityCompound = (CompoundBinaryTag) binaryTag; + + ListBinaryTag listTag = entityCompound.getList("Pos", BinaryTagTypes.DOUBLE); + + int chunkX = ((int) listTag.getDouble(0)) >> 4; + int chunkZ = ((int) listTag.getDouble(2)) >> 4; long chunkKey = Util.chunkPosition(chunkX, chunkZ); SlimeChunk chunk = chunks.get(chunkKey); if (chunk != null) { @@ -68,36 +66,46 @@ public SlimeWorld deserializeWorld(byte version, SlimeLoader loader, String worl } // Tile Entity deserialization - com.flowpowered.nbt.CompoundTag tileEntitiesCompound = readCompound(tileEntities); - for (CompoundTag tileEntityCompound : ((com.flowpowered.nbt.ListTag) tileEntitiesCompound.getValue().get("tiles")).getValue()) { - int chunkX = ((IntTag) tileEntityCompound.getValue().get("x")).getValue() >> 4; - int chunkZ = ((IntTag) tileEntityCompound.getValue().get("z")).getValue() >> 4; - long pos = Util.chunkPosition(chunkX, chunkZ); - SlimeChunk chunk = chunks.get(pos); - - if (chunk == null) { - throw new CorruptedWorldException(worldName); - } + CompoundBinaryTag tileEntitiesCompound = readCompound(tileEntities); + if(tileEntitiesCompound != null) { + for (BinaryTag binaryTag : (tileEntitiesCompound.getList("tiles", BinaryTagTypes.COMPOUND))) { + CompoundBinaryTag tileEntityCompound = (CompoundBinaryTag) binaryTag; + + int chunkX = tileEntityCompound.getInt("x") >> 4; + int chunkZ = tileEntityCompound.getInt("z") >> 4; + long pos = Util.chunkPosition(chunkX, chunkZ); + SlimeChunk chunk = chunks.get(pos); + + if (chunk == null) { + throw new CorruptedWorldException(worldName); + } - chunk.getTileEntities().add(tileEntityCompound); + chunk.getTileEntities().add(tileEntityCompound); + } } // Extra Data - com.flowpowered.nbt.CompoundTag extraCompound = readCompound(extra); + CompoundBinaryTag extraCompound = readCompound(extra); // World properties SlimePropertyMap worldPropertyMap = propertyMap; - Optional propertiesMap = extraCompound - .getAsCompoundTag("properties") - .map(com.flowpowered.nbt.CompoundTag::getValue); + CompoundBinaryTag propertiesMap = extraCompound != null && extraCompound.get("properties") != null + ? extraCompound.getCompound("properties") + : null; + + if (propertiesMap != null) { + Map wpm = new HashMap<>(); + propertiesMap.forEach(entry -> wpm.put(entry.getKey(), entry.getValue())); - if (propertiesMap.isPresent()) { - worldPropertyMap = new SlimePropertyMap(propertiesMap.get()); + worldPropertyMap = new SlimePropertyMap(wpm); worldPropertyMap.merge(propertyMap); // Override world properties } + ConcurrentMap extraData = new ConcurrentHashMap<>(); + if (extraCompound != null) extraCompound.forEach(entry -> extraData.put(entry.getKey(), entry.getValue())); + return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld(worldName, loader, readOnly, chunks, - extraCompound, + extraData, worldPropertyMap, worldVersion ); @@ -116,7 +124,7 @@ private static Long2ObjectMap readChunks(SlimePropertyMap slimePrope // Height Maps byte[] heightMapData = new byte[chunkData.readInt()]; chunkData.read(heightMapData); - com.flowpowered.nbt.CompoundTag heightMaps = readCompound(heightMapData); + CompoundBinaryTag heightMaps = readCompound(heightMapData); // Chunk Sections { @@ -149,22 +157,23 @@ private static Long2ObjectMap readChunks(SlimePropertyMap slimePrope // Block data byte[] blockStateData = new byte[chunkData.readInt()]; chunkData.read(blockStateData); - com.flowpowered.nbt.CompoundTag blockStateTag = readCompound(blockStateData); + CompoundBinaryTag blockStateTag = readCompound(blockStateData); // Biome Data byte[] biomeData = new byte[chunkData.readInt()]; chunkData.read(biomeData); - com.flowpowered.nbt.CompoundTag biomeTag = readCompound(biomeData); + CompoundBinaryTag biomeTag = readCompound(biomeData); - chunkSectionArray[sectionId] = new com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton( + chunkSectionArray[sectionId] = new SlimeChunkSectionSkeleton( blockStateTag, biomeTag, blockLightArray, - skyLightArray); + skyLightArray + ); } chunkMap.put(Util.chunkPosition(x, z), - new com.infernalsuite.asp.skeleton.SlimeChunkSkeleton(x, z, chunkSectionArray, heightMaps, new ArrayList<>(), new ArrayList<>(), new CompoundTag("", new CompoundMap()), null) + new com.infernalsuite.asp.skeleton.SlimeChunkSkeleton(x, z, chunkSectionArray, heightMaps, new ArrayList<>(), new ArrayList<>(), new HashMap<>(), null) ); } } @@ -192,14 +201,10 @@ private static byte[] readCompressed(DataInputStream stream) throws IOException return normal; } - private static com.flowpowered.nbt.CompoundTag readCompound(byte[] bytes) throws IOException { - if (bytes.length == 0) { - return null; - } + private static CompoundBinaryTag readCompound(byte[] tagBytes) throws IOException { + if (tagBytes.length == 0) return null; - NBTInputStream stream = new NBTInputStream(new ByteArrayInputStream(bytes), NBTInputStream.NO_COMPRESSION, ByteOrder.BIG_ENDIAN); - return (com.flowpowered.nbt.CompoundTag) stream.readTag(); + return BinaryTagIO.unlimitedReader().read(new ByteArrayInputStream(tagBytes)); } - } \ No newline at end of file diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java index 5e664d1d2..b4a99a1c6 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java @@ -1,9 +1,5 @@ package com.infernalsuite.asp.serialization.slime.reader.impl.v11; -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.ListTag; -import com.flowpowered.nbt.stream.NBTInputStream; import com.github.luben.zstd.Zstd; import com.infernalsuite.asp.Util; import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; @@ -17,14 +13,18 @@ import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import net.kyori.adventure.nbt.*; import org.jetbrains.annotations.Nullable; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; -import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; -import java.util.Optional; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; public class v11SlimeWorldDeSerializer implements com.infernalsuite.asp.serialization.slime.reader.VersionedByteSlimeWorldReader { @@ -38,19 +38,25 @@ public SlimeWorld deserializeWorld(byte version, @Nullable SlimeLoader loader, S Long2ObjectMap chunks = readChunks(propertyMap, chunkBytes); byte[] extraTagBytes = readCompressed(dataStream); - CompoundTag extraTag = readCompound(extraTagBytes); + CompoundBinaryTag extraTag = readCompound(extraTagBytes); SlimePropertyMap worldPropertyMap = propertyMap; - Optional propertiesMap = extraTag - .getAsCompoundTag("properties") - .map(CompoundTag::getValue); + CompoundBinaryTag propertiesMap = extraTag != null && extraTag.get("properties") != null + ? extraTag.getCompound("properties") + : null; - if (propertiesMap.isPresent()) { - worldPropertyMap = new SlimePropertyMap(propertiesMap.get()); - worldPropertyMap.merge(propertyMap); + if (propertiesMap != null) { + Map wpm = new HashMap<>(); + propertiesMap.forEach(entry -> wpm.put(entry.getKey(), entry.getValue())); + + worldPropertyMap = new SlimePropertyMap(wpm); + worldPropertyMap.merge(propertyMap); // Override world properties } - return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld(worldName, loader, readOnly, chunks, extraTag, worldPropertyMap, worldVersion); + ConcurrentMap extraData = new ConcurrentHashMap<>(); + if (extraTag != null) extraTag.forEach(entry -> extraData.put(entry.getKey(), entry.getValue())); + + return new com.infernalsuite.asp.skeleton.SkeletonSlimeWorld(worldName, loader, readOnly, chunks, extraData, worldPropertyMap, worldVersion); } private static Long2ObjectMap readChunks(SlimePropertyMap slimePropertyMap, byte[] chunkBytes) throws IOException { @@ -93,12 +99,12 @@ private static Long2ObjectMap readChunks(SlimePropertyMap slimePrope // Block Data byte[] blockStateData = new byte[chunkData.readInt()]; chunkData.read(blockStateData); - CompoundTag blockStateTag = readCompound(blockStateData); + CompoundBinaryTag blockStateTag = readCompound(blockStateData); // Biome Data byte[] biomeData = new byte[chunkData.readInt()]; chunkData.read(biomeData); - CompoundTag biomeTag = readCompound(biomeData); + CompoundBinaryTag biomeTag = readCompound(biomeData); chunkSections[sectionId] = new com.infernalsuite.asp.skeleton.SlimeChunkSectionSkeleton(blockStateTag, biomeTag, blockLightArray, skyLightArray); } @@ -106,7 +112,7 @@ private static Long2ObjectMap readChunks(SlimePropertyMap slimePrope // HeightMaps byte[] heightMapData = new byte[chunkData.readInt()]; chunkData.read(heightMapData); - CompoundTag heightMaps = readCompound(heightMapData); + CompoundBinaryTag heightMaps = readCompound(heightMapData); // Tile Entities @@ -117,9 +123,13 @@ private static Long2ObjectMap readChunks(SlimePropertyMap slimePrope chunkData.read(compressedTileEntitiesData); Zstd.decompress(decompressedTileEntitiesData, compressedTileEntitiesData); - CompoundTag tileEntitiesCompound = readCompound(decompressedTileEntitiesData); - @SuppressWarnings("unchecked") - List serializedTileEntities = ((ListTag) tileEntitiesCompound.getValue().get("tileEntities")).getValue(); + CompoundBinaryTag tileEntitiesCompound = readCompoundOrEmpty(decompressedTileEntitiesData); + + ListBinaryTag tileEntitiesTag = tileEntitiesCompound.getList("tileEntities", BinaryTagTypes.COMPOUND); + List serializedTileEntities = new ArrayList<>(tileEntitiesTag.size()); + for (BinaryTag binaryTag : tileEntitiesTag) { + serializedTileEntities.add((CompoundBinaryTag) binaryTag); + } // Entities @@ -130,12 +140,15 @@ private static Long2ObjectMap readChunks(SlimePropertyMap slimePrope chunkData.read(compressedEntitiesData); Zstd.decompress(decompressedEntitiesData, compressedEntitiesData); - CompoundTag entitiesCompound = readCompound(decompressedEntitiesData); - @SuppressWarnings("unchecked") - List serializedEntities = ((ListTag) entitiesCompound.getValue().get("entities")).getValue(); - + CompoundBinaryTag entitiesCompound = readCompoundOrEmpty(decompressedEntitiesData); + ListBinaryTag entitiesTag = entitiesCompound.getList("entities", BinaryTagTypes.COMPOUND); + List serializedEntities = new ArrayList<>(entitiesTag.size()); + for (BinaryTag binaryTag : entitiesTag) { + serializedEntities.add((CompoundBinaryTag) binaryTag); + } + chunkMap.put(Util.chunkPosition(x, z), - new com.infernalsuite.asp.skeleton.SlimeChunkSkeleton(x, z, chunkSections, heightMaps, serializedTileEntities, serializedEntities, new CompoundTag("", new CompoundMap()), null)); + new com.infernalsuite.asp.skeleton.SlimeChunkSkeleton(x, z, chunkSections, heightMaps, serializedTileEntities, serializedEntities, new HashMap<>(), null)); } return chunkMap; } @@ -150,10 +163,15 @@ private static byte[] readCompressed(DataInputStream stream) throws IOException return decompressedData; } - private static CompoundTag readCompound(byte[] tagBytes) throws IOException { + private static CompoundBinaryTag readCompound(byte[] tagBytes) throws IOException { if (tagBytes.length == 0) return null; - NBTInputStream nbtStream = new NBTInputStream(new ByteArrayInputStream(tagBytes), NBTInputStream.NO_COMPRESSION, ByteOrder.BIG_ENDIAN); - return (CompoundTag) nbtStream.readTag(); + return BinaryTagIO.unlimitedReader().read(new ByteArrayInputStream(tagBytes)); + } + + private static CompoundBinaryTag readCompoundOrEmpty(byte[] tagBytes) throws IOException { + CompoundBinaryTag tag = readCompound(tagBytes); + if(tag == null) return CompoundBinaryTag.empty(); + return tag; } } From 74ae0514492ddcdd5b339e437ed7851cc325fa47 Mon Sep 17 00:00:00 2001 From: David Date: Sat, 12 Apr 2025 13:51:32 +0200 Subject: [PATCH 126/133] chore: remove my debug msg Signed-off-by: David --- .../slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java index 1cac5f9b7..3831f05df 100644 --- a/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java @@ -26,7 +26,6 @@ public void upgrade(v1_9SlimeWorld world, SlimeDataConverter slimeDataConverter) List chunks = new ArrayList<>(world.chunks.values()); long lastMessage = -1; - System.out.println("Upgrading from " + world.getDataVersion()); for (int i = 0; i < chunks.size(); i++) { v1_9SlimeChunk chunk = chunks.get(i); From 55609f36237729671da60dc192fa0ac90fcaa263 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Wed, 26 Mar 2025 19:04:51 +0100 Subject: [PATCH 127/133] feat: make skeleton cloning faster Signed-off-by: David Mayr --- .../asp/skeleton/SkeletonCloning.java | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java b/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java index bcb015b92..95b8d0107 100644 --- a/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java +++ b/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java @@ -60,8 +60,8 @@ private static Long2ObjectMap cloneChunkStorage(Collection cloneChunkStorage(Collection(chunk.getExtraData()), + chunk.getHeightMaps(), //No need to copy heightmaps since adventure nbt is immutable + new ArrayList<>(chunk.getTileEntities()), //No need to copy contents since adventure nbt is immutable + new ArrayList<>(chunk.getEntities()), //No need to copy contents since adventure nbt is immutable + new ConcurrentHashMap<>(chunk.getExtraData()), null )); } return cloned; } - - private static List deepClone(List tags) { - List cloned = new ArrayList<>(tags.size()); - for (CompoundBinaryTag tag : tags) { - cloned.add(CompoundBinaryTag.builder().put(tag).build()); - } - - return cloned; - } } From 07ae605942443f347a9f464803946ed9e7170f18 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 20 Apr 2025 16:00:04 +0200 Subject: [PATCH 128/133] feat: make core not dependent on aspaper-api for faster publishing Signed-off-by: David Mayr --- core/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/build.gradle.kts b/core/build.gradle.kts index d981c5b8d..a06779a0a 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -5,7 +5,7 @@ plugins { dependencies { compileOnly(project(":api")) - compileOnly(project(":aspaper-api")) + compileOnly(paperApi()) implementation(libs.zstd) } From 8a0b8ed02d529764af54d4d3565a0537e385c370 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 20 Apr 2025 16:49:16 +0200 Subject: [PATCH 129/133] feat: add slime serialization api based on the work of @Unoqwy. Closes #80 Signed-off-by: David Mayr --- .../asp/api/AdvancedSlimePaperAPI.java | 12 ++ .../loaders/SlimeSerializationAdapter.java | 56 +++++++++ .../asp/api/world/SlimeWorldInstance.java | 2 + .../infernalsuite/asp/AdvancedSlimePaper.java | 9 ++ .../asp/level/SlimeInMemoryWorld.java | 115 +++++++++--------- .../asp/level/SlimeLevelInstance.java | 2 +- .../SlimeSerializationAdapterImpl.java | 40 ++++++ 7 files changed, 178 insertions(+), 58 deletions(-) create mode 100644 api/src/main/java/com/infernalsuite/asp/api/loaders/SlimeSerializationAdapter.java create mode 100644 core/src/main/java/com/infernalsuite/asp/serialization/SlimeSerializationAdapterImpl.java diff --git a/api/src/main/java/com/infernalsuite/asp/api/AdvancedSlimePaperAPI.java b/api/src/main/java/com/infernalsuite/asp/api/AdvancedSlimePaperAPI.java index ed877d9a4..f2d6f3bc9 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/AdvancedSlimePaperAPI.java +++ b/api/src/main/java/com/infernalsuite/asp/api/AdvancedSlimePaperAPI.java @@ -7,6 +7,7 @@ import com.infernalsuite.asp.api.exceptions.WorldAlreadyExistsException; import com.infernalsuite.asp.api.exceptions.WorldLoadedException; import com.infernalsuite.asp.api.exceptions.WorldTooBigException; +import com.infernalsuite.asp.api.loaders.SlimeSerializationAdapter; import com.infernalsuite.asp.api.world.SlimeWorld; import com.infernalsuite.asp.api.world.SlimeWorldInstance; import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; @@ -133,6 +134,17 @@ SlimeWorld readWorld(SlimeLoader loader, String worldName, boolean readOnly, Sli */ SlimeWorld readVanillaWorld(File worldDir, String worldName, @Nullable SlimeLoader loader) throws InvalidWorldException, WorldLoadedException, WorldTooBigException, IOException, WorldAlreadyExistsException; + /** + * Returns the {@link SlimeSerializationAdapter} used to serialize and deserialize SlimeWorlds. + * Manual de-/serialization is considered experimental and may change in future versions. + *

    + * Please use SlimeLoaders where possible

    + * + * @return A adapter for serializing and deserializing SlimeWorlds + */ + @ApiStatus.Experimental + SlimeSerializationAdapter getSerializer(); + /** * Gets the instance of the AdvancedSlimePaper API. * diff --git a/api/src/main/java/com/infernalsuite/asp/api/loaders/SlimeSerializationAdapter.java b/api/src/main/java/com/infernalsuite/asp/api/loaders/SlimeSerializationAdapter.java new file mode 100644 index 000000000..7ca000585 --- /dev/null +++ b/api/src/main/java/com/infernalsuite/asp/api/loaders/SlimeSerializationAdapter.java @@ -0,0 +1,56 @@ +package com.infernalsuite.asp.api.loaders; + +import com.infernalsuite.asp.api.AdvancedSlimePaperAPI; +import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; +import com.infernalsuite.asp.api.exceptions.NewerFormatException; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.SlimeWorldInstance; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; + +@ApiStatus.Experimental +public interface SlimeSerializationAdapter { + + /** + * Serializes a {@link SlimeWorld} with the current format {@link SlimeSerializationAdapter#getSlimeFormat()}. + *

    + * If the world is loaded, make sure to use a serializable copy that can be obtained with {@link SlimeWorldInstance#getSerializableCopy()}. + * + * @param slimeWorld World to serialize. + * @return Serialized world data in bytes. + * @throws IllegalArgumentException If the world is a {@link SlimeWorldInstance} + */ + byte[] serializeWorld(@NotNull SlimeWorld slimeWorld); + + /** + * Deserializes a world from the given byte array and applies data fixers to the world. + *

    + * Unlike {@link AdvancedSlimePaperAPI#readWorld(SlimeLoader, String, boolean, SlimePropertyMap)} this does not + * save data fixed worlds to the provided {@link SlimeLoader} automatically. + * + * @param worldName Name of the world. + * @param serializedWorld Serialized world data in bytes. + * @param loader {@link SlimeLoader} used when saving the world. + * @param propertyMap A {@link SlimePropertyMap} object containing all the properties of the world. + * @param readOnly Whether read-only mode is enabled. + * @return A {@link SlimeWorld}, which is the in-memory representation of the world. + * @throws IOException if there was a generic problem reading the world. + * @throws CorruptedWorldException if the world retrieved cannot be properly parsed into a {@link SlimeWorld} object. + * @throws NewerFormatException if the world uses a newer version of the SRF. + */ + @NotNull SlimeWorld deserializeWorld(@NotNull String worldName, byte[] serializedWorld, @Nullable SlimeLoader loader, + @NotNull SlimePropertyMap propertyMap, boolean readOnly) + throws CorruptedWorldException, NewerFormatException, IOException; + + /** + * The current slime format version used by AdvancedSlimePaper. + * + * @return The slime format version + */ + int getSlimeFormat(); + +} diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java index b4401c9f0..82927703c 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java @@ -20,4 +20,6 @@ public interface SlimeWorldInstance extends SlimeWorld { */ @NotNull World getBukkitWorld(); + SlimeWorld getSerializableCopy(); + } diff --git a/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java b/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java index 76c1f242c..3fb8c8ca6 100644 --- a/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java +++ b/aspaper-server/src/main/java/com/infernalsuite/asp/AdvancedSlimePaper.java @@ -5,10 +5,12 @@ import com.infernalsuite.asp.api.events.LoadSlimeWorldEvent; import com.infernalsuite.asp.api.exceptions.*; import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.loaders.SlimeSerializationAdapter; import com.infernalsuite.asp.api.world.SlimeWorld; import com.infernalsuite.asp.api.world.SlimeWorldInstance; import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; import com.infernalsuite.asp.level.SlimeLevelInstance; +import com.infernalsuite.asp.serialization.SlimeSerializationAdapterImpl; import com.infernalsuite.asp.serialization.anvil.AnvilImportData; import com.infernalsuite.asp.serialization.anvil.AnvilWorldReader; import com.infernalsuite.asp.serialization.slime.SlimeSerializer; @@ -45,6 +47,8 @@ public class AdvancedSlimePaper implements AdvancedSlimePaperAPI { System.setProperty("org.slf4j.simpleLogger.showShortLogName", "true"); } + private final SlimeSerializationAdapter serializationAdapter = new SlimeSerializationAdapterImpl(); + public static AdvancedSlimePaper instance() { return (AdvancedSlimePaper) AdvancedSlimePaperAPI.instance(); } @@ -226,6 +230,11 @@ public SlimeWorld readVanillaWorld(File worldDir, String worldName, SlimeLoader return world; } + @Override + public SlimeSerializationAdapter getSerializer() { + return this.serializationAdapter; + } + /** * Utility method to register a loaded {@link SlimeWorld} with the internal map (for {@link #getLoadedWorld} calls) * diff --git a/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java index 5f1c42509..42198b611 100644 --- a/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -145,63 +145,7 @@ public Collection getChunkStorage() { } @Override - public SlimePropertyMap getPropertyMap() { - return this.propertyMap; - } - - @Override - public boolean isReadOnly() { - return this.getLoader() == null || this.readOnly; - } - - @Override - public SlimeWorld clone(String worldName) { - try { - return clone(worldName, null); - } catch (WorldAlreadyExistsException | IOException ignored) { - return null; // Never going to happen - } - } - - @Override - public SlimeWorld clone(String worldName, SlimeLoader loader) throws WorldAlreadyExistsException, IOException { - if (this.getName().equals(worldName)) { - throw new IllegalArgumentException("The clone world cannot have the same name as the original world!"); - } - - if (worldName == null) { - throw new IllegalArgumentException("The world name cannot be null!"); - } - if (loader != null) { - if (loader.worldExists(worldName)) { - throw new WorldAlreadyExistsException(worldName); - } - } - - SlimeWorld cloned = SkeletonCloning.fullClone(worldName, this, loader); - if (loader != null) { - loader.saveWorld(worldName, SlimeSerializer.serialize(cloned)); - } - - return cloned; - } - - @Override - public int getDataVersion() { - return SharedConstants.getCurrentVersion().getDataVersion().getVersion(); - } - - @Override - public ConcurrentMap getExtraData() { - return this.extra; - } - - @Override - public Collection getWorldMaps() { - return List.of(); - } - - public SlimeWorld getForSerialization() { + public SlimeWorld getSerializableCopy() { SlimeWorld world = SkeletonCloning.weakCopy(this); Long2ObjectMap cloned = new Long2ObjectOpenHashMap<>(); @@ -265,6 +209,63 @@ public SlimeWorld getForSerialization() { ); } + @Override + public SlimePropertyMap getPropertyMap() { + return this.propertyMap; + } + + @Override + public boolean isReadOnly() { + return this.getLoader() == null || this.readOnly; + } + + @Override + public SlimeWorld clone(String worldName) { + try { + return clone(worldName, null); + } catch (WorldAlreadyExistsException | IOException ignored) { + return null; // Never going to happen + } + } + + @Override + public SlimeWorld clone(String worldName, SlimeLoader loader) throws WorldAlreadyExistsException, IOException { + if (this.getName().equals(worldName)) { + throw new IllegalArgumentException("The clone world cannot have the same name as the original world!"); + } + + if (worldName == null) { + throw new IllegalArgumentException("The world name cannot be null!"); + } + if (loader != null) { + if (loader.worldExists(worldName)) { + throw new WorldAlreadyExistsException(worldName); + } + } + + SlimeWorld cloned = SkeletonCloning.fullClone(worldName, this, loader); + if (loader != null) { + loader.saveWorld(worldName, SlimeSerializer.serialize(cloned)); + } + + return cloned; + } + + @Override + public int getDataVersion() { + return SharedConstants.getCurrentVersion().getDataVersion().getVersion(); + } + + @Override + public ConcurrentMap getExtraData() { + return this.extra; + } + + @Override + public Collection getWorldMaps() { + return List.of(); + } + public SlimeLevelInstance getInstance() { return instance; } diff --git a/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java b/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java index 0469b5243..c5fbe3a67 100644 --- a/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java +++ b/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java @@ -154,7 +154,7 @@ private Future saveInternal() { Bukkit.getLogger().log(Level.INFO, "Saving world " + this.slimeInstance.getName() + "..."); long start = System.currentTimeMillis(); - SlimeWorld world = this.slimeInstance.getForSerialization(); + SlimeWorld world = this.slimeInstance.getSerializableCopy(); return WORLD_SAVER_SERVICE.submit(() -> { try { byte[] serializedWorld = SlimeSerializer.serialize(world); diff --git a/core/src/main/java/com/infernalsuite/asp/serialization/SlimeSerializationAdapterImpl.java b/core/src/main/java/com/infernalsuite/asp/serialization/SlimeSerializationAdapterImpl.java new file mode 100644 index 000000000..451bcdaff --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/SlimeSerializationAdapterImpl.java @@ -0,0 +1,40 @@ +package com.infernalsuite.asp.serialization; + +import com.infernalsuite.asp.api.SlimeNMSBridge; +import com.infernalsuite.asp.api.exceptions.CorruptedWorldException; +import com.infernalsuite.asp.api.exceptions.NewerFormatException; +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import com.infernalsuite.asp.api.loaders.SlimeSerializationAdapter; +import com.infernalsuite.asp.api.utils.SlimeFormat; +import com.infernalsuite.asp.api.world.SlimeWorld; +import com.infernalsuite.asp.api.world.SlimeWorldInstance; +import com.infernalsuite.asp.api.world.properties.SlimePropertyMap; +import com.infernalsuite.asp.serialization.slime.SlimeSerializer; +import com.infernalsuite.asp.serialization.slime.reader.SlimeWorldReaderRegistry; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; + +public class SlimeSerializationAdapterImpl implements SlimeSerializationAdapter { + + @Override + public byte[] serializeWorld(@NotNull SlimeWorld slimeWorld) { + if(slimeWorld instanceof SlimeWorldInstance) { + throw new IllegalArgumentException("SlimeWorldInstances cannot be serialized directly. Use SlimeWorldInstance.getSerializableCopy() instead."); + } + return SlimeSerializer.serialize(slimeWorld); + } + + @Override + public @NotNull SlimeWorld deserializeWorld(@NotNull String worldName, byte[] serializedWorld, @Nullable SlimeLoader loader, @NotNull SlimePropertyMap propertyMap, boolean readOnly) throws CorruptedWorldException, NewerFormatException, IOException { + SlimeWorld slimeWorld = SlimeWorldReaderRegistry.readWorld(loader, worldName, serializedWorld, propertyMap, loader == null || readOnly); + return SlimeNMSBridge.instance().getSlimeDataConverter().applyDataFixers(slimeWorld); + } + + @Override + public int getSlimeFormat() { + return SlimeFormat.SLIME_VERSION; + } + +} From c9a8c6bec4929ae651af1c27fcc3eb6b03c3ca07 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 20 Apr 2025 17:06:43 +0200 Subject: [PATCH 130/133] fix(breaking): cloned worlds with a loader are no longer readOnly if the parent world is readOnly Signed-off-by: David Mayr --- .../java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java | 3 ++- .../java/com/infernalsuite/asp/skeleton/SkeletonCloning.java | 4 ++-- .../com/infernalsuite/asp/skeleton/SkeletonSlimeWorld.java | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java b/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java index 42198b611..f42eb9ffd 100644 --- a/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java +++ b/aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java @@ -243,7 +243,8 @@ public SlimeWorld clone(String worldName, SlimeLoader loader) throws WorldAlread } } - SlimeWorld cloned = SkeletonCloning.fullClone(worldName, this, loader); + //Make new worlds always non-read-only. if the provided loader is null, the fullClone method will set it to true again + SlimeWorld cloned = SkeletonCloning.fullClone(worldName, this, loader, false); if (loader != null) { loader.saveWorld(worldName, SlimeSerializer.serialize(cloned)); } diff --git a/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java b/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java index 95b8d0107..7f731fb2c 100644 --- a/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java +++ b/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java @@ -18,10 +18,10 @@ public class SkeletonCloning { - public static SkeletonSlimeWorld fullClone(String worldName, SlimeWorld world, SlimeLoader loader) { + public static SkeletonSlimeWorld fullClone(String worldName, SlimeWorld world, SlimeLoader loader, boolean readOnly) { return new SkeletonSlimeWorld(worldName, loader == null ? world.getLoader() : loader, - loader == null || world.isReadOnly(), + loader == null || readOnly, cloneChunkStorage(world.getChunkStorage()), new ConcurrentHashMap<>(world.getExtraData()), world.getPropertyMap().clone(), diff --git a/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonSlimeWorld.java b/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonSlimeWorld.java index d20fffca5..fdb7b85f9 100644 --- a/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonSlimeWorld.java +++ b/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonSlimeWorld.java @@ -119,7 +119,8 @@ public SlimeWorld clone(String worldName, SlimeLoader loader) throws WorldAlread } } - SlimeWorld cloned = SkeletonCloning.fullClone(worldName, this, loader); + //Make new worlds always non-read-only. if the provided loader is null, the fullClone method will set it to true again + SlimeWorld cloned = SkeletonCloning.fullClone(worldName, this, loader, false); if (loader != null) { loader.saveWorld(worldName, SlimeSerializer.serialize(cloned)); } From bf13df75af20e08eff106dd259cfdff4cd2e2bc1 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 20 Apr 2025 17:15:00 +0200 Subject: [PATCH 131/133] fix: javadoc mistake Signed-off-by: David Mayr --- .../java/com/infernalsuite/asp/api/AdvancedSlimePaperAPI.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/com/infernalsuite/asp/api/AdvancedSlimePaperAPI.java b/api/src/main/java/com/infernalsuite/asp/api/AdvancedSlimePaperAPI.java index f2d6f3bc9..3125c48e6 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/AdvancedSlimePaperAPI.java +++ b/api/src/main/java/com/infernalsuite/asp/api/AdvancedSlimePaperAPI.java @@ -138,7 +138,7 @@ SlimeWorld readWorld(SlimeLoader loader, String worldName, boolean readOnly, Sli * Returns the {@link SlimeSerializationAdapter} used to serialize and deserialize SlimeWorlds. * Manual de-/serialization is considered experimental and may change in future versions. *

    - * Please use SlimeLoaders where possible

    + * Please use SlimeLoaders where possible * * @return A adapter for serializing and deserializing SlimeWorlds */ From 2c5d52fcb62d3ddc79170b1906aa209e81141342 Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 20 Apr 2025 17:32:24 +0200 Subject: [PATCH 132/133] feat: updated to latest paper commit (a838a886dcbc93664283034a41673e802a6b3098) Signed-off-by: David Mayr --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index fe0c636c9..b32ea63d9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ apiVersion=4.0.0-SNAPSHOT version=1.21.4-R0.1-SNAPSHOT mcVersion=1.21.4 -paperRef=6ea42025a49f232f47861c6ca943b0fc66b7effe +paperRef=a838a886dcbc93664283034a41673e802a6b3098 org.gradle.caching=true org.gradle.parallel=true From 6de9d10b9b8bcfb7abb1af10ab439e369638e57c Mon Sep 17 00:00:00 2001 From: David Mayr Date: Sun, 20 Apr 2025 18:28:52 +0200 Subject: [PATCH 133/133] chore: updated javadoc to reflect on compound tag -> map change Signed-off-by: David Mayr --- .../java/com/infernalsuite/asp/api/world/SlimeChunk.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunk.java b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunk.java index 71abfed05..b6d3a0b48 100644 --- a/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunk.java +++ b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunk.java @@ -56,14 +56,13 @@ public interface SlimeChunk { /** * Returns the extra data of the chunk. - * Inside this {@link CompoundBinaryTag} - * can be stored any information to then be retrieved later, as it's - * saved alongside the chunk data. + * Any information can be stored in this {@link Map} + * and later retrieved, as it's saved alongside the chunk data. *
    * Beware, a compound tag under the key "ChunkBukkitValues" will be stored here. * It is used for storing chunk-based Bukkit PDC. Do not overwrite it. * - * @return A {@link CompoundBinaryTag} containing the extra data of the chunk, + * @return A {@link Map} containing the extra data of the chunk as NBT tags, */ Map getExtraData();