diff --git a/.gitignore b/.gitignore index dd9079f2..79bbf2a7 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/api/build.gradle.kts b/api/build.gradle.kts index 6b52c8ae..0da106cd 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -1,96 +1,16 @@ plugins { - `java-library` - `maven-publish` - signing + id("asp.base-conventions") + id("asp.publishing-conventions") } dependencies { - api("com.flowpowered:flow-nbt:2.0.2") - api("org.jetbrains:annotations:23.0.0") + api(libs.annotations) + api(libs.adventure.nbt) - 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 88d36977..50441d0e 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,15 @@ -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.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 77% 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 9aef6612..e4f31574 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,8 @@ -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.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/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 65489623..ebf10f1d 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 0a055206..69bbbea5 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 08fe0261..3bf07839 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 3c9374f6..ae9e2eb3 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 d9a8fa2b..be1e257a 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 4bc35a5f..a7468fff 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 a73796e9..6d6fc28c 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 a42df4b3..ec4eb6a6 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 716bc431..c241e3a9 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 7f8f144a..490021fe 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 a0401d68..739a8890 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 7b29bf58..2d5f491f 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 eb25d0af..c02c46e0 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/asp/api/exceptions/InvalidWorldException.java b/api/src/main/java/com/infernalsuite/asp/api/exceptions/InvalidWorldException.java new file mode 100644 index 00000000..a9d40f19 --- /dev/null +++ b/api/src/main/java/com/infernalsuite/asp/api/exceptions/InvalidWorldException.java @@ -0,0 +1,28 @@ +package com.infernalsuite.asp.api.exceptions; + +import java.io.File; +import java.nio.file.Path; + +/** + * Exception thrown when a folder does + * not contain a valid Minecraft world. + */ +public class InvalidWorldException extends SlimeException { + + public InvalidWorldException(Path worldDir, String reason) { + super("Directory " + worldDir.toString() + " does not contain a valid MC world! " + reason); + } + + 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/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 dd54386e..e29eb552 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 545fcff0..a7a4d976 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 89499cdf..e50ce81c 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 425eeab4..22c36657 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 30a01445..646e9d35 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 913b7486..a35c4255 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 722a63f4..6cc1ff27 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 89419ce7..23318a82 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 d41e4477..4ada699f 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 57% 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 770f79e8..cbd31f7d 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,6 +1,6 @@ -package com.infernalsuite.aswm.api.world; +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; @@ -32,46 +32,44 @@ 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 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/aswm/api/world/SlimeChunkSection.java b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunkSection.java similarity index 68% 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 53b44508..12dc9341 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,7 +1,7 @@ -package com.infernalsuite.aswm.api.world; +package com.infernalsuite.asp.api.world; -import com.infernalsuite.aswm.api.utils.NibbleArray; -import com.flowpowered.nbt.CompoundTag; +import com.infernalsuite.asp.api.utils.NibbleArray; +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/aswm/api/world/SlimeWorld.java b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorld.java similarity index 72% 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 c86fd9dd..0fce84fa 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,13 +1,16 @@ -package com.infernalsuite.aswm.api.world; +package com.infernalsuite.asp.api.world; -import com.infernalsuite.aswm.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.world.properties.SlimePropertyMap; +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 new file mode 100644 index 00000000..ed93b4b6 --- /dev/null +++ b/api/src/main/java/com/infernalsuite/asp/api/world/SlimeWorldInstance.java @@ -0,0 +1,25 @@ +package com.infernalsuite.asp.api.world; + +import com.infernalsuite.asp.api.loaders.SlimeLoader; +import net.kyori.adventure.nbt.BinaryTag; +import org.bukkit.World; + +import java.util.concurrent.ConcurrentMap; + +public interface SlimeWorldInstance { + + String getName(); + + World getBukkitWorld(); + + SlimeWorld getSlimeWorldMirror(); + + com.infernalsuite.asp.api.world.properties.SlimePropertyMap getPropertyMap(); + + boolean isReadOnly(); + + SlimeLoader getLoader(); + + ConcurrentMap 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 new file mode 100644 index 00000000..d338f939 --- /dev/null +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperties.java @@ -0,0 +1,109 @@ +package com.infernalsuite.asp.api.world.properties; + +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; + +/** + * Class with all existing slime world properties. + */ +public class SlimeProperties { + + /** + * The X coordinate of the world spawn + */ + public static final SlimePropertyInt SPAWN_X = SlimePropertyInt.create("spawnX", 0); + + /** + * The Y coordinate of the world spawn + */ + public static final SlimePropertyInt SPAWN_Y = SlimePropertyInt.create("spawnY", 255); + + /** + * The Z coordinate of the world spawn + */ + public static final SlimePropertyInt SPAWN_Z = SlimePropertyInt.create("spawnZ", 0); + + /** + * The yaw of the world spawn + */ + public static final SlimePropertyFloat SPAWN_YAW = SlimePropertyFloat.create("spawnYaw", 0.0f); + + /** + * The difficulty set for the world + */ + public static final SlimePropertyString DIFFICULTY = SlimePropertyString.create("difficulty", "peaceful", (value) -> + value.equalsIgnoreCase("peaceful") || value.equalsIgnoreCase("easy") + || value.equalsIgnoreCase("normal") || value.equalsIgnoreCase("hard") + ); + + /** + * Whether monsters are allowed to spawn at night or in the dark + */ + public static final SlimePropertyBoolean ALLOW_MONSTERS = SlimePropertyBoolean.create("allowMonsters", true); + + /** + * Whether peaceful animals are allowed to spawn + */ + public static final SlimePropertyBoolean ALLOW_ANIMALS = SlimePropertyBoolean.create("allowAnimals", true); + + /** + * Whether the dragon battle should be enabled in end worlds + */ + public static final SlimePropertyBoolean DRAGON_BATTLE = SlimePropertyBoolean.create("dragonBattle", false); + + /** + * Whether PVP combat is allowed + */ + public static final SlimePropertyBoolean PVP = SlimePropertyBoolean.create("pvp", true); + + /** + * The environment of the world + */ + 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 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") + ); + + /** + * The default biome generated in empty chunks + */ + public static final SlimePropertyString DEFAULT_BIOME = SlimePropertyString.create("defaultBiome", "minecraft:plains"); + + @ApiStatus.Experimental + public static final SlimePropertyBoolean SHOULD_LIMIT_SAVE = SlimePropertyBoolean.create("hasSaveBounds", false); + + @ApiStatus.Experimental + public static final SlimePropertyInt SAVE_MIN_X = SlimePropertyInt.create("saveMinX", 0); + @ApiStatus.Experimental + public static final SlimePropertyInt SAVE_MIN_Z = SlimePropertyInt.create("saveMinZ", 0); + + @ApiStatus.Experimental + public static final SlimePropertyInt SAVE_MAX_X = SlimePropertyInt.create("saveMaxX", 0); + @ApiStatus.Experimental + public static final SlimePropertyInt SAVE_MAX_Z = SlimePropertyInt.create("saveMaxZ", 0); + + @ApiStatus.Experimental + public static final SlimePropertyString CHUNK_PRUNING = SlimePropertyString.create("pruning", "aggressive", (value) -> + value.equalsIgnoreCase("aggressive") || value.equalsIgnoreCase("never") + ); + + + + @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); + + +} 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 new file mode 100644 index 00000000..e3c47b5c --- /dev/null +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperty.java @@ -0,0 +1,61 @@ +package com.infernalsuite.asp.api.world.properties; + +import net.kyori.adventure.nbt.BinaryTag; + +import java.util.function.Function; + +/** + * A property describing behavior of a slime world. + */ +public abstract class SlimeProperty { + + private final String key; + private final T defaultValue; + private final Function validator; + + protected SlimeProperty(String key, T defaultValue) { + this(key, defaultValue, null); + } + + 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 " + key + "! " + defaultValue); + } + + this.defaultValue = defaultValue; + this.validator = validator; + } + + protected abstract Z createTag(T value); + + protected abstract T readValue(Z tag); + + 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 final T getDefaultValue() { + return this.defaultValue; + } + + public final Function getValidator() { + return this.validator; + } + + @Override + public final String toString() { + return "SlimeProperty{" + + "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 new file mode 100644 index 00000000..1c687ee3 --- /dev/null +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimePropertyMap.java @@ -0,0 +1,95 @@ +package com.infernalsuite.asp.api.world.properties; + +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 Map properties; + + public SlimePropertyMap() { + this(new HashMap<>()); + } + + public SlimePropertyMap(final Map properties) { + this.properties = properties; + } + + /** + * Return the current value of the given property + * + * @param property The slime property + * @return The current value + */ + 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(); + } + } + + /** + * Return the properties (CompoundMap) + * + * @return The properties + */ + public Map getProperties() { + return this.properties; + } + + /** + * Update the value of the given property + * + * @param property The slime property + * @param value The new value + * @throws IllegalArgumentException if the value fails validation. + */ + 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 provided map will be used. + * + * @param other A {@link SlimePropertyMap}. + */ + public void merge(final SlimePropertyMap other) { + this.properties.putAll(other.properties); + } + + /** + * Returns a {@link CompoundBinaryTag} containing every property set in this map. + * + * @return A {@link CompoundBinaryTag} with all the properties stored in this map. + */ + public CompoundBinaryTag toCompound() { + return CompoundBinaryTag.builder().put(this.properties).build(); + } + + 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 HashMap<>(this.properties)); + } + + @Override + public String toString() { + 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 new file mode 100644 index 00000000..c32f5af3 --- /dev/null +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyBoolean.java @@ -0,0 +1,57 @@ +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; + +/** + * A slime property of type boolean + */ +public class SlimePropertyBoolean extends SlimeProperty { + + public static SlimePropertyBoolean create(final @NotNull String key, final boolean defaultValue) { + Preconditions.checkNotNull(key, "Key cannot be null"); + return new SlimePropertyBoolean(key, defaultValue); + } + + 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 Boolean readValue(final ByteBinaryTag tag) { + return tag.value() == 1; + } + + @Override + 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 00000000..3640ee00 --- /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 00000000..1f71d53f --- /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 00000000..ade36175 --- /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 new file mode 100644 index 00000000..239ff0c5 --- /dev/null +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyFloat.java @@ -0,0 +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 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 SlimeProperty { + + public static SlimePropertyFloat create(final @NotNull String key, final float defaultValue) { + Preconditions.checkNotNull(key, "Key cannot be null"); + return new SlimePropertyFloat(key, 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 FloatBinaryTag createTag(final Float value) { + return FloatBinaryTag.floatBinaryTag(value); + } + + @Override + 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 new file mode 100644 index 00000000..4d13026f --- /dev/null +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyInt.java @@ -0,0 +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 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 static SlimePropertyInt create(final @NotNull String key, final int defaultValue) { + Preconditions.checkNotNull(key, "Key cannot be null"); + return new SlimePropertyInt(key, defaultValue); + } + + 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 IntBinaryTag createTag(final Integer value) { + return IntBinaryTag.intBinaryTag(value); + } + + @Override + 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 00000000..e74cb6aa --- /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 00000000..02931bf4 --- /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 00000000..31e0a150 --- /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 00000000..46a9be66 --- /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 00000000..f3418448 --- /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 new file mode 100644 index 00000000..fccfeae9 --- /dev/null +++ b/api/src/main/java/com/infernalsuite/asp/api/world/properties/type/SlimePropertyString.java @@ -0,0 +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 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 SlimeProperty { + + public static SlimePropertyString create(final @NotNull String key, final String defaultValue) { + Preconditions.checkNotNull(key, "Key cannot be null"); + return new SlimePropertyString(key, defaultValue); + } + + 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 StringBinaryTag createTag(final String value) { + return StringBinaryTag.stringBinaryTag(value); + } + + @Override + protected String readValue(final StringBinaryTag tag) { + return tag.value(); + } + + @Override + protected StringBinaryTag cast(BinaryTag rawTag) { + return (StringBinaryTag) rawTag; + } + +} diff --git a/api/src/main/java/com/infernalsuite/aswm/api/exceptions/InvalidWorldException.java b/api/src/main/java/com/infernalsuite/aswm/api/exceptions/InvalidWorldException.java deleted file mode 100644 index 0ad2d751..00000000 --- a/api/src/main/java/com/infernalsuite/aswm/api/exceptions/InvalidWorldException.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.infernalsuite.aswm.api.exceptions; - -import java.io.File; - -/** - * Exception thrown when a folder does - * not contain a valid Minecraft world. - */ -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(File worldDir) { - super("Directory " + worldDir.getPath() + " does not contain a valid MC world!"); - } -} diff --git a/api/src/main/java/com/infernalsuite/aswm/api/world/SlimeWorldInstance.java b/api/src/main/java/com/infernalsuite/aswm/api/world/SlimeWorldInstance.java deleted file mode 100644 index d8fc5c2c..00000000 --- a/api/src/main/java/com/infernalsuite/aswm/api/world/SlimeWorldInstance.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.infernalsuite.aswm.api.world; - -import com.flowpowered.nbt.CompoundTag; -import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import org.bukkit.World; - -public interface SlimeWorldInstance { - - String getName(); - - World getBukkitWorld(); - - SlimeWorld getSlimeWorldMirror(); - - SlimePropertyMap getPropertyMap(); - - boolean isReadOnly(); - - SlimeLoader getLoader(); - - CompoundTag getExtraData(); - -} diff --git a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/SlimeProperties.java b/api/src/main/java/com/infernalsuite/aswm/api/world/properties/SlimeProperties.java deleted file mode 100644 index fb4f35e6..00000000 --- a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/SlimeProperties.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.infernalsuite.aswm.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 org.jetbrains.annotations.ApiStatus; - -/** - * Class with all existing slime world properties. - */ -public class SlimeProperties { - - /** - * The X coordinate of the world spawn - */ - public static final SlimeProperty SPAWN_X = new SlimePropertyInt("spawnX", 0); - - /** - * The Y coordinate of the world spawn - */ - public static final SlimeProperty SPAWN_Y = new SlimePropertyInt("spawnY", 255); - - /** - * The Z coordinate of the world spawn - */ - public static final SlimeProperty SPAWN_Z = new SlimePropertyInt("spawnZ", 0); - - /** - * The yaw of the world spawn - */ - public static final SlimeProperty SPAWN_YAW = new SlimePropertyFloat("spawnYaw", 0.0f); - - /** - * The difficulty set for the world - */ - public static final SlimeProperty DIFFICULTY = new SlimePropertyString("difficulty", "peaceful", (value) -> - value.equalsIgnoreCase("peaceful") || value.equalsIgnoreCase("easy") - || value.equalsIgnoreCase("normal") || value.equalsIgnoreCase("hard") - ); - - /** - * Whether monsters are allowed to spawn at night or in the dark - */ - public static final SlimeProperty ALLOW_MONSTERS = new SlimePropertyBoolean("allowMonsters", true); - - /** - * Whether peaceful animals are allowed to spawn - */ - public static final SlimeProperty ALLOW_ANIMALS = new SlimePropertyBoolean("allowAnimals", true); - - /** - * Whether the dragon battle should be enabled in end worlds - */ - public static final SlimeProperty DRAGON_BATTLE = new SlimePropertyBoolean("dragonBattle", false); - - /** - * Whether PVP combat is allowed - */ - public static final SlimeProperty PVP = new SlimePropertyBoolean("pvp", true); - - /** - * The environment of the world - */ - public static final SlimeProperty ENVIRONMENT = new SlimePropertyString("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) -> - 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") - ); - - /** - * The default biome generated in empty chunks - */ - public static final SlimeProperty DEFAULT_BIOME = new SlimePropertyString("defaultBiome", "minecraft:plains"); - - @ApiStatus.Experimental - public static final SlimeProperty SHOULD_LIMIT_SAVE = new SlimePropertyBoolean("hasSaveBounds", false); - - @ApiStatus.Experimental - public static final SlimeProperty SAVE_MIN_X = new SlimePropertyInt("saveMinX", 0); - @ApiStatus.Experimental - public static final SlimeProperty SAVE_MIN_Z = new SlimePropertyInt("saveMinZ", 0); - - @ApiStatus.Experimental - public static final SlimeProperty SAVE_MAX_X = new SlimePropertyInt("saveMaxX", 0); - @ApiStatus.Experimental - public static final SlimeProperty SAVE_MAX_Z = new SlimePropertyInt("saveMaxZ", 0); - - @ApiStatus.Experimental - public static final SlimeProperty CHUNK_PRUNING = new SlimePropertyString("pruning", "aggressive", (value) -> - value.equalsIgnoreCase("aggressive") || value.equalsIgnoreCase("never") - ); - - - - @ApiStatus.Experimental - public static final SlimeProperty CHUNK_SECTION_MIN = new SlimePropertyInt("chunkSectionMin", -4); - @ApiStatus.Experimental - public static final SlimeProperty CHUNK_SECTION_MAX = new SlimePropertyInt("chunkSectionMin", 19); - - -} diff --git a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/SlimeProperty.java b/api/src/main/java/com/infernalsuite/aswm/api/world/properties/SlimeProperty.java deleted file mode 100644 index 9023fa1f..00000000 --- a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/SlimeProperty.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.infernalsuite.aswm.api.world.properties; - -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.Tag; - -import java.util.function.Function; - -/** - * A property describing behavior of a slime world. - */ -public abstract class SlimeProperty { - - private final String nbtName; - private final T defaultValue; - private final Function validator; - - protected SlimeProperty(String nbtName, T defaultValue) { - this(nbtName, defaultValue, null); - } - - protected SlimeProperty(String nbtName, T defaultValue, Function validator) { - this.nbtName = nbtName; - - if (defaultValue != null && validator != null && !validator.apply(defaultValue)) { - throw new IllegalArgumentException("Invalid default value for property " + nbtName + "! " + defaultValue); - } - - this.defaultValue = defaultValue; - this.validator = validator; - } - - protected abstract void writeValue(CompoundMap compound, T value); - - protected abstract T readValue(Tag compoundTag); - - public String getNbtName() { - return nbtName; - } - - public T getDefaultValue() { - return defaultValue; - } - - public Function getValidator() { - return validator; - } - - @Override - public String toString() { - return "SlimeProperty{" + - "nbtName='" + nbtName + '\'' + - ", defaultValue=" + defaultValue + - '}'; - } -} diff --git a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/SlimePropertyMap.java b/api/src/main/java/com/infernalsuite/aswm/api/world/properties/SlimePropertyMap.java deleted file mode 100644 index a537a4f7..00000000 --- a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/SlimePropertyMap.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.infernalsuite.aswm.api.world.properties; - -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.CompoundTag; - -/** - * A Property Map object. - */ -public class SlimePropertyMap { - - private final CompoundMap properties; - - public SlimePropertyMap(CompoundMap compoundMap) { - this.properties = compoundMap; - } - - public SlimePropertyMap() { - this(new CompoundMap()); - } - - /** - * Return the current value of the given property - * - * @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())); - } else { - return property.getDefaultValue(); - } - } - - /** - * Return the properties (CompoundMap) - * - * @return The properties - */ - public CompoundMap getProperties() { - return this.properties; - } - - /** - * Update the value of the given property - * - * @param property The slime property - * @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); - } - - /** - * 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. - * - * @param propertyMap A {@link SlimePropertyMap}. - */ - public void merge(SlimePropertyMap propertyMap) { - properties.putAll(propertyMap.properties); - } - - /** - * Returns a {@link CompoundTag} containing every property set in this map. - * - * @return A {@link CompoundTag} with all the properties stored in this map. - */ - public CompoundTag toCompound() { - return new CompoundTag("properties", properties); - } - - public static SlimePropertyMap fromCompound(CompoundTag compound) { - return new SlimePropertyMap(compound.getValue()); - } - - public SlimePropertyMap clone() { - return new SlimePropertyMap(new CompoundMap(this.properties)); - } - - @Override - public String toString() { - return "SlimePropertyMap" + properties; - } -} diff --git a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyBoolean.java b/api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyBoolean.java deleted file mode 100644 index 6b43ec4e..00000000 --- a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyBoolean.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.infernalsuite.aswm.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; - -import java.util.function.Function; - -/** - * A slime property of type boolean - */ -public class SlimePropertyBoolean extends SlimeProperty { - - public SlimePropertyBoolean(String nbtName, Boolean defaultValue) { - super(nbtName, defaultValue); - } - - public SlimePropertyBoolean(String nbtName, Boolean defaultValue, Function validator) { - super(nbtName, defaultValue, validator); - } - - @Override - protected void writeValue(CompoundMap compound, Boolean value) { - compound.put(getNbtName(), new ByteTag(getNbtName(), (byte) (value ? 1 : 0))); - } - - @Override - protected Boolean readValue(Tag compoundTag) { - return compoundTag.getAsByteTag() - .map((value) -> value.getValue() == 1) - .orElse(getDefaultValue()); - } -} diff --git a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyFloat.java b/api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyFloat.java deleted file mode 100644 index 5c0bfc00..00000000 --- a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyFloat.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.infernalsuite.aswm.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 SlimePropertyFloat(String nbtName, Float defaultValue, Function validator) { - super(nbtName, defaultValue, validator); - } - - public SlimePropertyFloat(String nbtName, Float defaultValue) { - super(nbtName, defaultValue); - } - - @Override - protected void writeValue(CompoundMap compound, Float value) { - compound.put(getNbtName(), new FloatTag(getNbtName(), value)); - } - - @Override - protected Float readValue(Tag compoundTag) { - return compoundTag.getAsFloatTag() - .map(Tag::getValue) - .orElse(getDefaultValue()); - } -} diff --git a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyInt.java b/api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyInt.java deleted file mode 100644 index 2a51125c..00000000 --- a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyInt.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.infernalsuite.aswm.api.world.properties.type; - -import com.infernalsuite.aswm.api.world.properties.SlimeProperty; -import com.flowpowered.nbt.CompoundMap; -import com.flowpowered.nbt.IntTag; -import com.flowpowered.nbt.Tag; - -import java.util.function.Function; - -/** - * A slime property of type integer - */ -public class SlimePropertyInt extends SlimeProperty { - - public SlimePropertyInt(String nbtName, Integer defaultValue) { - super(nbtName, defaultValue); - } - - public SlimePropertyInt(String nbtName, Integer defaultValue, Function validator) { - super(nbtName, defaultValue, validator); - } - - @Override - protected void writeValue(CompoundMap compound, Integer value) { - compound.put(getNbtName(), new IntTag(getNbtName(), value)); - } - - @Override - protected Integer readValue(Tag compoundTag) { - return compoundTag.getAsIntTag() - .map(Tag::getValue) - .orElse(getDefaultValue()); - } -} diff --git a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyString.java b/api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyString.java deleted file mode 100644 index 02eeb058..00000000 --- a/api/src/main/java/com/infernalsuite/aswm/api/world/properties/type/SlimePropertyString.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.infernalsuite.aswm.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; - -import java.util.function.Function; - -/** - * A slime property of type integer - */ -public class SlimePropertyString extends SlimeProperty { - - public SlimePropertyString(String nbtName, String defaultValue) { - super(nbtName, defaultValue); - } - - public SlimePropertyString(String nbtName, String defaultValue, Function validator) { - super(nbtName, defaultValue, validator); - } - - @Override - protected void writeValue(CompoundMap compound, String value) { - compound.put(getNbtName(), new StringTag(getNbtName(), value)); - } - - @Override - protected String readValue(Tag compoundTag) { - return compoundTag.getAsStringTag() - .map(Tag::getValue) - .orElse(getDefaultValue()); - } -} diff --git a/build.gradle.kts b/build.gradle.kts index 91aabfcf..e69de29b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,89 +0,0 @@ -plugins { - java - `maven-publish` - id("io.github.goooler.shadow") version "8.1.7" apply false - id("io.papermc.paperweight.patcher") version "1.7.1" - id("org.kordamp.gradle.profiles") version "0.47.0" -} - -val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/" - -repositories { - mavenCentral() - maven(paperMavenPublicUrl) { - content { onlyForConfigurations(configurations.paperclip.name) } - } -} - -allprojects { - apply(plugin = "java") - apply(plugin = "maven-publish") - - java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(21)) - } - } - - 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/") - } -} - -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/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 00000000..a47ba2a4 --- /dev/null +++ b/buildSrc/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/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts new file mode 100644 index 00000000..bbf148c9 --- /dev/null +++ b/buildSrc/settings.gradle.kts @@ -0,0 +1,17 @@ +rootProject.name = "buildSrc" + +pluginManagement { + repositories { + mavenLocal() + mavenCentral() + gradlePluginPortal() + } +} + +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} diff --git a/buildSrc/src/main/kotlin/asp.base-conventions.gradle.kts b/buildSrc/src/main/kotlin/asp.base-conventions.gradle.kts new file mode 100644 index 00000000..6eecf874 --- /dev/null +++ b/buildSrc/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").get() +version = rootProject.providers.gradleProperty("apiVersion").get() + +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/buildSrc/src/main/kotlin/asp.publishing-conventions.gradle.kts b/buildSrc/src/main/kotlin/asp.publishing-conventions.gradle.kts new file mode 100644 index 00000000..c0ea0d6c --- /dev/null +++ b/buildSrc/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/buildSrc/src/main/kotlin/com/infernalsuite/asp/conventions/PublishConfiguration.kt b/buildSrc/src/main/kotlin/com/infernalsuite/asp/conventions/PublishConfiguration.kt new file mode 100644 index 00000000..65841170 --- /dev/null +++ b/buildSrc/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/buildSrc/src/main/kotlin/constants.kt b/buildSrc/src/main/kotlin/constants.kt new file mode 100644 index 00000000..6f6fe73c --- /dev/null +++ b/buildSrc/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/buildSrc/src/main/kotlin/extensions.kt b/buildSrc/src/main/kotlin/extensions.kt new file mode 100644 index 00000000..2b7913f9 --- /dev/null +++ b/buildSrc/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/core/build.gradle.kts b/core/build.gradle.kts index 3a1cad60..d981c5b8 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 02e6d682..f71da1ed 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 643a5098..1a3652ff 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/asp/pdc/AdventureDataTypeRegistry.java b/core/src/main/java/com/infernalsuite/asp/pdc/AdventureDataTypeRegistry.java new file mode 100644 index 00000000..fa162219 --- /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 00000000..07ec8295 --- /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/serialization/SlimeWorldReader.java b/core/src/main/java/com/infernalsuite/asp/serialization/SlimeWorldReader.java new file mode 100644 index 00000000..a6e166ca --- /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/asp/serialization/anvil/AnvilImportData.java b/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilImportData.java new file mode 100644 index 00000000..bf8c4eb4 --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilImportData.java @@ -0,0 +1,15 @@ +package com.infernalsuite.asp.serialization.anvil; + +import com.infernalsuite.asp.api.loaders.SlimeLoader; +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); + } + +} 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 new file mode 100644 index 00000000..c446b8fe --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java @@ -0,0 +1,333 @@ +package com.infernalsuite.asp.serialization.anvil; + +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 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 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.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 { + + 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) { + Path worldDir = importData.worldDir(); + + try { + Path levelFile = worldDir.resolve("level.dat"); + if (!Files.exists(levelFile) || !Files.isRegularFile(levelFile)) { + throw new RuntimeException(new InvalidWorldException(worldDir)); + } + + LevelData data = readLevelData(levelFile); + + int worldVersion = data.version; + + SlimePropertyMap propertyMap = new SlimePropertyMap(); + + // TODO - Really? There has to be a better way... + Path environmentDir = worldDir.resolve("DIM-1"); + propertyMap.setValue(SlimeProperties.ENVIRONMENT, "nether"); + if (!Files.isDirectory(environmentDir)) { + environmentDir = worldDir.resolve("DIM1"); + propertyMap.setValue(SlimeProperties.ENVIRONMENT, "the_end"); + if (!Files.isDirectory(environmentDir)) { + environmentDir = worldDir; + propertyMap.setValue(SlimeProperties.ENVIRONMENT, "normal"); + } + } + + // Chunks + Path regionDir = environmentDir.resolve("region"); + + if (!Files.exists(regionDir) || !Files.isDirectory(regionDir)) { + throw new InvalidWorldException(environmentDir); + } + + Long2ObjectMap chunks = new Long2ObjectOpenHashMap<>(); + + 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 + 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); + } + } + + if (chunks.isEmpty()) { + throw new InvalidWorldException(environmentDir); + } + + // World maps +// File dataDir = new File(worldDir, "data"); +// List maps = new ArrayList<>(); +// +// if (dataDir.exists()) { +// if (!dataDir.isDirectory()) { +// throw new InvalidWorldException(worldDir); +// } +// +// for (File mapFile : dataDir.listFiles((dir, name) -> MAP_FILE_PATTERN.matcher(name).matches())) { +// maps.add(loadMap(mapFile)); +// } +// } + + 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 ConcurrentHashMap<>(), propertyMap, worldVersion); + } catch (IOException | InvalidWorldException e) { + + throw new RuntimeException(e); + } + } + + private static CompoundBinaryTag loadMap(File mapFile) throws IOException { + String fileName = mapFile.getName(); + int mapId = Integer.parseInt(fileName.substring(4, fileName.length() - 4)); + CompoundBinaryTag tag = BinaryTagIO.unlimitedReader().read(new BufferedInputStream(new FileInputStream(mapFile))).getCompound("data"); + tag.put("id", IntBinaryTag.intBinaryTag(mapId)); + return tag; + } + + 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; + } + + private static LevelData readLevelData(Path file) throws IOException, InvalidWorldException { + CompoundBinaryTag tag; + + tag = BinaryTagIO.unlimitedReader().read(file); + + 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.getParent()); + } + + 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); + + for (int i = 0; i < 1024; i++) { + int entry = inputStream.readInt(); + int chunkOffset = entry >>> 8; + int chunkSize = entry & 15; + + if (entry != 0) { + ChunkEntry chunkEntry = new ChunkEntry(chunkOffset * SECTOR_SIZE, chunkSize * SECTOR_SIZE); + chunks.add(chunkEntry); + } + } + + for (ChunkEntry entry : chunks) { + try { + DataInputStream headerStream = new DataInputStream(new ByteArrayInputStream(regionByteArray, entry.offset(), entry.paddedSize())); + + int chunkSize = headerStream.readInt() - 1; + int compressionScheme = headerStream.readByte(); + + DataInputStream chunkStream = new DataInputStream(new ByteArrayInputStream(regionByteArray, entry.offset() + 5, chunkSize)); + InputStream decompressorStream = compressionScheme == 1 ? new GZIPInputStream(chunkStream) : new InflaterInputStream(chunkStream); + CompoundBinaryTag tag = BinaryTagIO.unlimitedReader().read(decompressorStream); + + readEntityChunk(tag, version, chunkMap); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + } + + 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); + + for (int i = 0; i < 1024; i++) { + int entry = inputStream.readInt(); + int chunkOffset = entry >>> 8; + int chunkSize = entry & 15; + + if (entry != 0) { + ChunkEntry chunkEntry = new ChunkEntry(chunkOffset * SECTOR_SIZE, chunkSize * SECTOR_SIZE); + chunks.add(chunkEntry); + } + } + + return chunks.stream().map((entry) -> { + + try { + DataInputStream headerStream = new DataInputStream(new ByteArrayInputStream(regionByteArray, entry.offset(), entry.paddedSize())); + + int chunkSize = headerStream.readInt() - 1; + int compressionScheme = headerStream.readByte(); + + DataInputStream chunkStream = new DataInputStream(new ByteArrayInputStream(regionByteArray, entry.offset() + 5, chunkSize)); + InputStream decompressorStream = compressionScheme == 1 ? new GZIPInputStream(chunkStream) : new InflaterInputStream(chunkStream); + CompoundBinaryTag tag = BinaryTagIO.unlimitedReader().read(decompressorStream); + return readChunk(tag, worldVersion); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + + }).filter(Objects::nonNull).collect(Collectors.toList()); + } + + 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.getInt("DataVersion", -1); + if (dataVersion != 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) { + LOGGER.warn("Lost entity chunk data at: {},{}", chunkX, chunkZ); + } else { + compound.getList("Entities", BinaryTagTypes.COMPOUND).forEach(entityTag -> chunk.getEntities().add((CompoundBinaryTag) entityTag)); + } + } + + private static SlimeChunk readChunk(CompoundBinaryTag compound, int worldVersion) { + int chunkX = compound.getInt("xPos"); + int chunkZ = compound.getInt("zPos"); + + 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; + } + + 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; + } + } + + CompoundBinaryTag heightMaps = compound.getCompound("Heightmaps"); + + 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); + + 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. + + SlimeChunkSection[] sectionArray = new SlimeChunkSection[maxSectionY - minSectionY]; + + for (final BinaryTag rawRag : sectionsTag) { + final CompoundBinaryTag sectionTag = (CompoundBinaryTag) rawRag; + int index = sectionTag.getByte("Y"); + + CompoundBinaryTag blockStatesTag = sectionTag.getCompound("block_states"); + CompoundBinaryTag biomesTag = sectionTag.getCompound("biomes"); + + // 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 + + NibbleArray blockLightArray = applyByteArrayOrNull(sectionTag, "BlockLight", NibbleArray::new); + NibbleArray skyLightArray = applyByteArrayOrNull(sectionTag, "SkyLight", NibbleArray::new); + + sectionArray[index - minSectionY] = new SlimeChunkSectionSkeleton(blockStatesTag, biomesTag, blockLightArray, skyLightArray); + } + + 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 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 LevelData(int version, int x, int y, int z) {} + +} 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 59% 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 389c6f6e..1d9d96de 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,13 @@ -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 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/aswm/serialization/slime/SlimeSerializer.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/SlimeSerializer.java similarity index 62% 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 b2ed62c0..5352359b 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,39 +1,41 @@ -package com.infernalsuite.aswm.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; +package com.infernalsuite.asp.serialization.slime; + 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 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/aswm/serialization/slime/reader/SlimeWorldReaderRegistry.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java similarity index 62% 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 b0d734e8..67ecd8a7 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,12 @@ -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.v12.v12WorldFormat; 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/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 e6507f01..4c1d9535 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 4069f0df..8d4c60dc 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/v12/v12SlimeWorldDeSerializer.java b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12SlimeWorldDeSerializer.java similarity index 53% 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 cb57b94a..0ab7bbb8 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,38 +1,33 @@ -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 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.HashMap; +import java.util.Collections; import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; -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); @@ -44,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 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 { @@ -99,49 +94,56 @@ 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 SlimeChunkSectionSkeleton(blockStateTag, biomeTag, blockLightArray, skyLightArray); + 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); + 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 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; } @@ -163,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 new file mode 100644 index 00000000..bb8057fb --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v12/v12WorldFormat.java @@ -0,0 +1,9 @@ +package com.infernalsuite.asp.serialization.slime.reader.impl.v12; + +import com.infernalsuite.asp.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/skeleton/SkeletonCloning.java b/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java similarity index 68% 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 c6d42db7..a08f9f26 100644 --- a/core/src/main/java/com/infernalsuite/aswm/skeleton/SkeletonCloning.java +++ b/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonCloning.java @@ -1,16 +1,19 @@ -package com.infernalsuite.aswm.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; - +package com.infernalsuite.asp.skeleton; + +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/aswm/skeleton/SkeletonSlimeWorld.java b/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonSlimeWorld.java similarity index 82% 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 2ae1d623..d20fffca 100644 --- a/core/src/main/java/com/infernalsuite/aswm/skeleton/SkeletonSlimeWorld.java +++ b/core/src/main/java/com/infernalsuite/asp/skeleton/SkeletonSlimeWorld.java @@ -1,15 +1,16 @@ -package com.infernalsuite.aswm.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; +package com.infernalsuite.asp.skeleton; + +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.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; @@ -17,25 +18,25 @@ import java.io.IOException; import java.util.Collection; import java.util.List; -import java.util.Map; 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 ) { @@ -46,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 @@ -70,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(); } @@ -147,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 new file mode 100644 index 00000000..662937e2 --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSectionSkeleton.java @@ -0,0 +1,28 @@ +package com.infernalsuite.asp.skeleton; + +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(CompoundBinaryTag blockStates, CompoundBinaryTag biome, NibbleArray block, NibbleArray light) implements SlimeChunkSection { + @Override + public CompoundBinaryTag getBlockStatesTag() { + return this.blockStates; + } + + @Override + public CompoundBinaryTag getBiomeTag() { + return this.biome; + } + + @Override + public @Nullable NibbleArray getBlockLight() { + return this.block; + } + + @Override + public NibbleArray getSkyLight() { + return this.light; + } +} diff --git a/core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSkeleton.java b/core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSkeleton.java new file mode 100644 index 00000000..f4cf2a9e --- /dev/null +++ b/core/src/main/java/com/infernalsuite/asp/skeleton/SlimeChunkSkeleton.java @@ -0,0 +1,55 @@ +package com.infernalsuite.asp.skeleton; + +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, + CompoundBinaryTag heightMap, + List blockEntities, + List entities, + CompoundBinaryTag extra, + CompoundBinaryTag upgradeData) implements SlimeChunk { + + @Override + public int getX() { + return this.x; + } + + @Override + public int getZ() { + return this.z; + } + + @Override + public SlimeChunkSection[] getSections() { + return this.sections; + } + + @Override + public CompoundBinaryTag getHeightMaps() { + return this.heightMap; + } + + @Override + public List getTileEntities() { + return this.blockEntities; + } + + @Override + public List getEntities() { + return this.entities; + } + + @Override + public CompoundBinaryTag getExtraData() { + return this.extra; + } + + @Override + public CompoundBinaryTag getUpgradeData() { + return this.upgradeData; + } +} diff --git a/core/src/main/java/com/infernalsuite/aswm/pdc/FlowDataTypeRegistry.java b/core/src/main/java/com/infernalsuite/aswm/pdc/FlowDataTypeRegistry.java deleted file mode 100644 index 2fb42c8e..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/pdc/FlowDataTypeRegistry.java +++ /dev/null @@ -1,239 +0,0 @@ -package com.infernalsuite.aswm.pdc; - -import com.flowpowered.nbt.*; -import com.google.common.base.Preconditions; -import com.google.common.primitives.Primitives; -import com.infernalsuite.aswm.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/aswm/pdc/FlowPersistentDataContainer.java b/core/src/main/java/com/infernalsuite/aswm/pdc/FlowPersistentDataContainer.java deleted file mode 100644 index deb69bfb..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/pdc/FlowPersistentDataContainer.java +++ /dev/null @@ -1,174 +0,0 @@ -package com.infernalsuite.aswm.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/aswm/serialization/SlimeWorldReader.java b/core/src/main/java/com/infernalsuite/aswm/serialization/SlimeWorldReader.java deleted file mode 100644 index c90854f9..00000000 --- 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/anvil/AnvilImportData.java b/core/src/main/java/com/infernalsuite/aswm/serialization/anvil/AnvilImportData.java deleted file mode 100644 index cb05608f..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/anvil/AnvilImportData.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.infernalsuite.aswm.serialization.anvil; - -import com.infernalsuite.aswm.api.loaders.SlimeLoader; -import org.jetbrains.annotations.Nullable; - -import java.io.File; - -public record AnvilImportData(File worldDir, String newName, @Nullable SlimeLoader loader) { -} diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/anvil/AnvilWorldReader.java b/core/src/main/java/com/infernalsuite/aswm/serialization/anvil/AnvilWorldReader.java deleted file mode 100644 index af011961..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/anvil/AnvilWorldReader.java +++ /dev/null @@ -1,434 +0,0 @@ -package com.infernalsuite.aswm.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.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 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 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; -import java.util.stream.Collectors; -import java.util.zip.GZIPInputStream; -import java.util.zip.InflaterInputStream; - -public class AnvilWorldReader implements 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; - - 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"); - - if (!levelFile.exists() || !levelFile.isFile()) { - 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"); - propertyMap.setValue(SlimeProperties.ENVIRONMENT, "nether"); - if (!environmentDir.isDirectory()) { - environmentDir = new File(worldDir, "DIM1"); - propertyMap.setValue(SlimeProperties.ENVIRONMENT, "the_end"); - if (!environmentDir.isDirectory()) { - environmentDir = worldDir; - propertyMap.setValue(SlimeProperties.ENVIRONMENT, "normal"); - } - } - - // Chunks - File regionDir = new File(environmentDir, "region"); - - if (!regionDir.exists() || !regionDir.isDirectory()) { - 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)) - ); - } - } - - // 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); - } - } - } - } - - if (chunks.isEmpty()) { - throw new InvalidWorldException(environmentDir); - } - - // World maps -// File dataDir = new File(worldDir, "data"); -// List maps = new ArrayList<>(); -// -// if (dataDir.exists()) { -// if (!dataDir.isDirectory()) { -// throw new InvalidWorldException(worldDir); -// } -// -// for (File mapFile : dataDir.listFiles((dir, name) -> MAP_FILE_PATTERN.matcher(name).matches())) { -// maps.add(loadMap(mapFile)); -// } -// } - - // 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 SkeletonSlimeWorld(importData.newName(), importData.loader(), true, chunks, new CompoundTag("", extraData), propertyMap, worldVersion); - } catch (IOException | InvalidWorldException e) { - - throw new RuntimeException(e); - } - } - - private static CompoundTag 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)); - - 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"); - - if (dataTag.isPresent()) { - // Data version - int dataVersion = dataTag.get().getIntValue("DataVersion").orElse(-1); - - int spawnX = dataTag.get().getIntValue("SpawnX").orElse(0); - int spawnY = dataTag.get().getIntValue("SpawnY").orElse(255); - int spawnZ = dataTag.get().getIntValue("SpawnZ").orElse(0); - - return new LevelData(dataVersion, spawnX, spawnY, spawnZ); - } - } - - throw new InvalidWorldException(file.getParentFile()); - } - - private static void loadEntities(File file, int version, Long2ObjectMap chunkMap) throws IOException { - byte[] regionByteArray = Files.readAllBytes(file.toPath()); - DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(regionByteArray)); - - List chunks = new ArrayList<>(1024); - - for (int i = 0; i < 1024; i++) { - int entry = inputStream.readInt(); - int chunkOffset = entry >>> 8; - int chunkSize = entry & 15; - - if (entry != 0) { - ChunkEntry chunkEntry = new ChunkEntry(chunkOffset * SECTOR_SIZE, chunkSize * SECTOR_SIZE); - chunks.add(chunkEntry); - } - } - - for (ChunkEntry entry : chunks) { - try { - DataInputStream headerStream = new DataInputStream(new ByteArrayInputStream(regionByteArray, entry.offset(), entry.paddedSize())); - - int chunkSize = headerStream.readInt() - 1; - int compressionScheme = headerStream.readByte(); - - 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(); - - - readEntityChunk(new CompoundTag("entityChunk", globalMap), version, chunkMap); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - } - - } - - private static List loadChunks(File file, int worldVersion) throws IOException { - byte[] regionByteArray = Files.readAllBytes(file.toPath()); - DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(regionByteArray)); - - List chunks = new ArrayList<>(1024); - - for (int i = 0; i < 1024; i++) { - int entry = inputStream.readInt(); - int chunkOffset = entry >>> 8; - int chunkSize = entry & 15; - - if (entry != 0) { - ChunkEntry chunkEntry = new ChunkEntry(chunkOffset * SECTOR_SIZE, chunkSize * SECTOR_SIZE); - chunks.add(chunkEntry); - } - } - - return chunks.stream().map((entry) -> { - - try { - DataInputStream headerStream = new DataInputStream(new ByteArrayInputStream(regionByteArray, entry.offset(), entry.paddedSize())); - - int chunkSize = headerStream.readInt() - 1; - int compressionScheme = headerStream.readByte(); - - 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); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - - }).filter(Objects::nonNull).collect(Collectors.toList()); - } - - private static void readEntityChunk(CompoundTag compound, int worldVersion, Long2ObjectMap slimeChunkMap) { - int[] position = compound.getAsIntArrayTag("Position").orElseThrow().getValue(); - int chunkX = position[0]; - int chunkZ = position[1]; - - int dataVersion = compound.getAsIntTag("DataVersion").map(IntTag::getValue).orElse(-1); - if (dataVersion != worldVersion) { - System.err.println("Cannot load entity chunk at " + chunkX + "," + chunkZ + ": data version " + dataVersion + " does not match world version " + worldVersion); - return; - } - - SlimeChunk chunk = slimeChunkMap.get(Util.chunkPosition(chunkX, chunkZ)); - if (chunk == null) { - System.out.println("Lost entity chunk data at: " + chunkX + " " + chunkZ); - } else { - chunk.getEntities().addAll((List) compound.getAsListTag("Entities").get().getValue()); - } - } - - private static SlimeChunk readChunk(CompoundTag compound, int worldVersion) { - int chunkX = compound.getAsIntTag("xPos").get().getValue(); - int chunkZ = compound.getAsIntTag("zPos").get().getValue(); - - 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 - 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(); - } - - 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; - - 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(); - } - - 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; - - // There is no need to do any custom processing here. - sectionArray[index - minSectionY] = new 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 SlimeChunkSkeleton(chunkX, chunkZ, sectionArray, heightMapsCompound, tileEntities, entities, extraTag, null); - } - } - - // Chunk is empty - return null; - } - - 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 boolean isEmpty(byte[] array) { - for (byte b : array) { - if (b != 0) { - return false; - } - } - - return true; - } - - private static boolean isEmpty(long[] array) { - for (long b : array) { - if (b != 0L) { - return false; - } - } - - return true; - } - - - private record ChunkEntry(int offset, int paddedSize) { - - } - - private record LevelData(int version, int x, int y, int z) { - } -} diff --git a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java b/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java deleted file mode 100644 index 8ece7660..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java +++ /dev/null @@ -1,210 +0,0 @@ -package com.infernalsuite.aswm.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.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 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.HashMap; -import java.util.List; -import java.util.Map; -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 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 SlimeChunkSectionSkeleton( - blockStateTag, - biomeTag, - blockLightArray, - skyLightArray); - } - - chunkMap.put(Util.chunkPosition(x, z), - new 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/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 d56ecbf7..00000000 --- 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/v11SlimeWorldDeSerializer.java b/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java deleted file mode 100644 index 0cc8bb09..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v11/v11SlimeWorldDeSerializer.java +++ /dev/null @@ -1,165 +0,0 @@ -package com.infernalsuite.aswm.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 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.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -public class v11SlimeWorldDeSerializer implements 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 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 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 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/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 aea58ec5..00000000 --- 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 8fdef840..00000000 --- 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/Upgrade.java b/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/Upgrade.java deleted file mode 100644 index fecd95b5..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/Upgrade.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.infernalsuite.aswm.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/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java b/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java deleted file mode 100644 index e1ee0b20..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_11WorldUpgrade.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.infernalsuite.aswm.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 { - - 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(v1_9SlimeWorld world) { - // 1.11 changed the way Tile Entities are named - for (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/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java b/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java deleted file mode 100644 index afc9238e..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_13WorldUpgrade.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.infernalsuite.aswm.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 org.bukkit.ChatColor; - -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Logger; - -public class v1_13WorldUpgrade implements Upgrade { - - @Override - public void upgrade(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++) { - 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 - v1_9SlimeChunkSection[] newSections = new 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(); - - v1_9SlimeChunkSection section = new 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(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]; - - 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/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java b/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java deleted file mode 100644 index be0d1d93..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_14WorldUpgrade.java +++ /dev/null @@ -1,201 +0,0 @@ -package com.infernalsuite.aswm.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_14WorldUpgrade implements 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 (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(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/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java b/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java deleted file mode 100644 index e83bfe63..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_16WorldUpgrade.java +++ /dev/null @@ -1,133 +0,0 @@ -package com.infernalsuite.aswm.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 java.util.Arrays; - -public class v1_16WorldUpgrade implements 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 (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/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java b/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java deleted file mode 100644 index 0149f6dc..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_17WorldUpgrade.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.infernalsuite.aswm.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 { - - @Override - public void upgrade(v1_9SlimeWorld world) { - for (v1_9SlimeChunk chunk : world.chunks.values()) { - for (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/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java b/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java deleted file mode 100644 index 009a79cd..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_18WorldUpgrade.java +++ /dev/null @@ -1,364 +0,0 @@ -package com.infernalsuite.aswm.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 { - - 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(v1_9SlimeWorld world) { - for (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); - - v1_9SlimeChunkSection[] sections = chunk.sections; - for (int i = 0; i < sections.length; i++) { - v1_9SlimeChunkSection section = sections[i]; - if (section == null) { - continue; - } - - - section.blockStatesTag = wrapPalette(section.palette, section.blockStates); - section.biomeTag = tags[i]; - } - - v1_9SlimeChunkSection[] shiftedSections = new 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; - - 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++) { - v1_9SlimeChunkSection section = sectionArray[i]; - if (section == null) { - sectionArray[i] = new 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/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java b/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java deleted file mode 100644 index b5b48ca2..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/upgrade/v1_9WorldUpgrade.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.infernalsuite.aswm.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.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; - -public class v1_9WorldUpgrade implements 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 (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/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java b/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java deleted file mode 100644 index 92fe6bbf..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeChunk.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.infernalsuite.aswm.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/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java b/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java deleted file mode 100644 index 80f8fbb6..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeChunkSection.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.infernalsuite.aswm.serialization.slime.reader.impl.v1_9; - -import com.flowpowered.nbt.CompoundTag; -import com.flowpowered.nbt.ListTag; -import com.infernalsuite.aswm.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/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java b/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java deleted file mode 100644 index cc59043a..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeWorld.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.infernalsuite.aswm.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 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/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java b/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java deleted file mode 100644 index 8401801f..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_9SlimeWorldDeserializer.java +++ /dev/null @@ -1,481 +0,0 @@ -package com.infernalsuite.aswm.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.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 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 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/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 8316cf53..00000000 --- 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/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java b/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java deleted file mode 100644 index 5316bb50..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/serialization/slime/reader/impl/v1_9/v1_v9SlimeConverter.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.infernalsuite.aswm.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 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 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()); - } - - @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 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 SlimeChunkSectionSkeleton( - null, - null, - null, - null - ); - } - - } - // TODO: - // slimeChunk.minY, - // slimeChunk.maxY, - - chunks.put(entry.getLongKey(), new SlimeChunkSkeleton( - slimeChunk.x, - slimeChunk.z, - sections, - slimeChunk.heightMap, - slimeChunk.tileEntities, - slimeChunk.entities, - new CompoundTag("", new CompoundMap()), - slimeChunk.upgradeData - )); - } - - - return new 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; - } -} diff --git a/core/src/main/java/com/infernalsuite/aswm/skeleton/SlimeChunkSectionSkeleton.java b/core/src/main/java/com/infernalsuite/aswm/skeleton/SlimeChunkSectionSkeleton.java deleted file mode 100644 index afa22963..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/skeleton/SlimeChunkSectionSkeleton.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.infernalsuite.aswm.skeleton; - -import com.flowpowered.nbt.CompoundTag; -import com.infernalsuite.aswm.api.utils.NibbleArray; -import com.infernalsuite.aswm.api.world.SlimeChunkSection; -import org.jetbrains.annotations.Nullable; - -public record SlimeChunkSectionSkeleton(CompoundTag blockStates, CompoundTag biome, NibbleArray block, NibbleArray light) implements SlimeChunkSection { - @Override - public CompoundTag getBlockStatesTag() { - return this.blockStates; - } - - @Override - public CompoundTag getBiomeTag() { - return this.biome; - } - - @Override - public @Nullable NibbleArray getBlockLight() { - return this.block; - } - - @Override - public NibbleArray getSkyLight() { - return this.light; - } -} diff --git a/core/src/main/java/com/infernalsuite/aswm/skeleton/SlimeChunkSkeleton.java b/core/src/main/java/com/infernalsuite/aswm/skeleton/SlimeChunkSkeleton.java deleted file mode 100644 index 2aba39fb..00000000 --- a/core/src/main/java/com/infernalsuite/aswm/skeleton/SlimeChunkSkeleton.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.infernalsuite.aswm.skeleton; - -import com.flowpowered.nbt.CompoundTag; -import com.infernalsuite.aswm.api.world.SlimeChunk; -import com.infernalsuite.aswm.api.world.SlimeChunkSection; - -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 { - - @Override - public int getX() { - return this.x; - } - - @Override - public int getZ() { - return this.z; - } - - @Override - public SlimeChunkSection[] getSections() { - return this.sections; - } - - @Override - public CompoundTag getHeightMaps() { - return this.heightMap; - } - - @Override - public List getTileEntities() { - return this.blockEntities; - } - - @Override - public List getEntities() { - return this.entities; - } - - @Override - public CompoundTag getExtraData() { - return this.extra; - } - - @Override - public CompoundTag getUpgradeData() { - return this.upgradeData; - } -} diff --git a/gradle.properties b/gradle.properties index 4aed08c0..bee34f63 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,9 @@ -group=com.infernalsuite.aswm -version=1.21-R0.1-SNAPSHOT +group=com.infernalsuite.asp +apiVersion=4.0.0-SNAPSHOT +version=1.21.4-R0.1-SNAPSHOT -mcVersion=1.21 -paperRef=b1b5d4c1e4b7c95afd5c932ca392bee66533a60c +mcVersion=1.21.4 +paperRef=c45286cb08881ab4d28a16b8ef9c6a4fd0984ce8 org.gradle.caching=true org.gradle.parallel=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 00000000..5395e70c --- /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 = "2.0.0-SNAPSHOT" +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 00000000..e0f923aa --- /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/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd491..a4b76b95 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a80b22ce..cea7a793 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.12-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1aa94a42..f3b75f3b 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,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 "${APP_HOME:-./}" > /dev/null && pwd -P ) || 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 diff --git a/gradlew.bat b/gradlew.bat index 7101f8e4..9d21a218 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,92 +1,94 @@ -@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 +@rem SPDX-License-Identifier: Apache-2.0 +@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/impl/aspaper-api/build.gradle.kts.patch b/impl/aspaper-api/build.gradle.kts.patch new file mode 100644 index 00000000..e5daed3e --- /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 00000000..4e359810 --- /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 00000000..498d5dec --- /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/importer/build.gradle.kts b/importer/build.gradle.kts index c4ca1419..f55f9d48 100644 --- a/importer/build.gradle.kts +++ b/importer/build.gradle.kts @@ -1,17 +1,18 @@ plugins { - id("com.github.johnrengelman.shadow") version "8.1.1" + 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 87% 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 4f02aa0b..97911f96 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; @@ -50,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."); diff --git a/loaders/build.gradle.kts b/loaders/build.gradle.kts index 79cfc7a9..134bd46f 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 23c0f529..ca0415ef 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 93bc69a0..10e7b6ec 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 be56adb4..95bf1a78 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 0366a7b2..3fa87292 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 95% 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 b82e92f2..0cb15e42 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); @@ -36,7 +35,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); 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 1a05d7c1..756ab760 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 f0f75766..e4b87314 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 d9d4fadb..6203b5a8 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 bc6fec6c..e1cf9d83 100644 --- a/patches/api/0001-Slime-World-Manager.patch +++ b/patches/api/0001-Slime-World-Manager.patch @@ -5,28 +5,22 @@ Subject: [PATCH] Slime World Manager diff --git a/build.gradle.kts b/build.gradle.kts -index fd39ed209b20c927054b8482c400beeeeab460a3..9e413e83f422bba611adb8855b8700be68097006 100644 +index 571534b42cd9c33d6a7bb6fe3bf3a28e33f8e5de..8e785e4d244abcfcfc3e37fc457baf62050670aa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -1,3 +1,5 @@ -+ -+ - plugins { - `java-library` - `maven-publish` -@@ -29,6 +31,7 @@ configurations.api { +@@ -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: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 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 8ae0f058..a5cf793b 100644 --- a/patches/server/0001-Build-Changes.patch +++ b/patches/server/0001-Build-Changes.patch @@ -3,36 +3,36 @@ 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 2da91ed6363c0851e4c459188f5e8ef5475e0c97..f0bfc068301c4a908a5856b7c72e7306adeeb38d 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") -@@ -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")) + // 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") + } + // ASWM end + implementation("ca.spottedleaf:concurrentutil:0.0.2") // Paper - Add ConcurrentUtil dependency // Paper start - implementation("org.jline:jline-terminal-jansi:3.21.0") - implementation("net.minecrell:terminalconsoleappender:1.3.0") -@@ -84,14 +91,14 @@ tasks.jar { + 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", @@ -52,55 +52,55 @@ index 421f6b3dc8890d63d2e7aa774d0bf8f7e15890ab..ef23b818c58015cd4be77962ea257d4c "Build-Number" to (build ?: ""), "Build-Time" to Instant.now().toString(), "Git-Branch" to gitBranch, // Paper -@@ -148,7 +155,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 87d2b3ec165e2e9e4bdbedd7adddaa2130ed507b..286d63e017b8bfabbbecee0c4f994d9e5fbd072b 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 -@@ -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; - 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 58d3d1a47e9f2423c467bb329c2d5f4b58a8b5ef..19a590bd5b08dc7377fc17262bb343753a482c68 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 -@@ -184,7 +184,8 @@ public final class ChunkHolderManager { +@@ -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.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 1ab93f219246d0b4dcdfd0f685f47c13091425f8..3f5fbc7a1394972e55ac5b345e81b40cefa7d246 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 -@@ -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 com.infernalsuite.aswm.level.CommonLoadTask; + 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.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); @@ -121,7 +121,7 @@ index 1ab93f219246d0b4dcdfd0f685f47c13091425f8..3f5fbc7a1394972e55ac5b345e81b40c - 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()); @@ -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 @@ -198,28 +198,56 @@ 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..22acbf7d0f7b8ac9eb41efc05d6050d0871c90a9 --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/Converter.java -@@ -0,0 +1,118 @@ -+package com.infernalsuite.aswm; -+ -+import com.flowpowered.nbt.CompoundMap; -+import com.flowpowered.nbt.TagType; -+import com.infernalsuite.aswm.api.utils.NibbleArray; -+import net.minecraft.nbt.*; ++++ 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("SWM Converter"); ++ private static final Logger LOGGER = LogManager.getLogger("ASP NBT Converter"); + + static DataLayer convertArray(NibbleArray array) { + return new DataLayer(array.getBacking()); @@ -233,103 +261,84 @@ index 0000000000000000000000000000000000000000..7d1753c0b7e89bbf0c245a0231b62773 + 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/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,31 +367,30 @@ 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..694bd135fd4398ecf02940e638fae1047e217a29 --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java -@@ -0,0 +1,101 @@ -+package com.infernalsuite.aswm; ++++ 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.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.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 { @@ -396,16 +404,16 @@ 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<>(); -+ 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..1affe4c94b490a05184deccc9eb80530 + 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,33 +462,30 @@ index 0000000000000000000000000000000000000000..1affe4c94b490a05184deccc9eb80530 + } + + -+ 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/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..98043b30614cc0ace252919367662a5e535fa1e1 --- /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; @@ -512,7 +517,7 @@ index 0000000000000000000000000000000000000000..20f16757ba8b8da525ff17d51d4f7eb6 + + 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; @@ -679,16 +684,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 +812,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 +837,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,30 +903,30 @@ 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..beb56b2495a52e1fac815de664677d73ce2bbcc3 --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java -@@ -0,0 +1,203 @@ -+package com.infernalsuite.aswm.level; ++++ b/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java +@@ -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.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; ++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..f1db2fe121bb3aabfad727a8133b6455 +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..f1db2fe121bb3aabfad727a8133b6455 + 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..f1db2fe121bb3aabfad727a8133b6455 + throw new AssertionError(error); + }); + -+ EMPTY_BIOME_PALETTE = (CompoundTag) Converter.convertTag("", tag); ++ EMPTY_BIOME_PALETTE = Converter.convertTag(tag); + } + } + @@ -1011,22 +1016,22 @@ index 0000000000000000000000000000000000000000..f1db2fe121bb3aabfad727a8133b6455 + // 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..f1db2fe121bb3aabfad727a8133b6455 + } + + @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() { @@ -1108,20 +1097,21 @@ 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..41119f2b0d208718c294076dc3c51f55680b0257 --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeWorld.java -@@ -0,0 +1,91 @@ -+package com.infernalsuite.aswm.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; ++++ 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; @@ -1130,6 +1120,7 @@ index 0000000000000000000000000000000000000000..9a27369c00345bbb94aa19f77687269d +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..9a27369c00345bbb94aa19f77687269d + } + + @Override -+ public CompoundTag getExtraData() { ++ public ConcurrentMap getExtraData() { + return this.instance.slimeInstance.getExtraData(); + } + + @Override -+ public Collection getWorldMaps() { ++ public Collection getWorldMaps() { + return List.of(); + } + @@ -1206,17 +1197,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..fa8254ca4b2eafa4e5669c3e0467ed1f7d4dc159 --- /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 net.kyori.adventure.nbt.CompoundBinaryTag; + +import java.util.List; + @@ -1250,7 +1241,7 @@ index 0000000000000000000000000000000000000000..b20a037679182e3c4a8bf31f084078f6 + } + + @Override -+ public CompoundTag getHeightMaps() { ++ public CompoundBinaryTag getHeightMaps() { + if (shouldDefaultBackToSlimeChunk()) { + return this.safety.getHeightMaps(); + } @@ -1259,7 +1250,7 @@ index 0000000000000000000000000000000000000000..b20a037679182e3c4a8bf31f084078f6 + } + + @Override -+ public List getTileEntities() { ++ public List getTileEntities() { + if (shouldDefaultBackToSlimeChunk()) { + return this.safety.getTileEntities(); + } @@ -1268,7 +1259,7 @@ index 0000000000000000000000000000000000000000..b20a037679182e3c4a8bf31f084078f6 + } + + @Override -+ public List getEntities() { ++ public List getEntities() { + if (shouldDefaultBackToSlimeChunk()) { + return this.safety.getEntities(); + } @@ -1296,39 +1287,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..b0d45837e918ef720b49a3f4968d7781ecf6436d --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java -@@ -0,0 +1,164 @@ -+package com.infernalsuite.aswm.level; ++++ 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.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.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..91a7f41db47c7df3ecc301e0827a1d07 + + // 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..91a7f41db47c7df3ecc301e0827a1d07 + + // 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..91a7f41db47c7df3ecc301e0827a1d07 + 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,14 +1469,13 @@ index 0000000000000000000000000000000000000000..91a7f41db47c7df3ecc301e0827a1d07 + return nmsChunk; + } +} -\ 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 +1503,27 @@ 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..636c553f4407f19b3435d487250b041532b8f229 --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java -@@ -0,0 +1,251 @@ -+package com.infernalsuite.aswm.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; ++++ 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; @@ -1549,6 +1537,7 @@ index 0000000000000000000000000000000000000000..fd4cfb9cceb4f23265cb3cce7f1f2510 +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..fd4cfb9cceb4f23265cb3cce7f1f2510 + 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..fd4cfb9cceb4f23265cb3cce7f1f2510 + + 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..fd4cfb9cceb4f23265cb3cce7f1f2510 + } + + @Override -+ public CompoundTag getExtraData() { ++ public ConcurrentMap getExtraData() { + return this.extra; + } + + @Override -+ public Collection getWorldMaps() { ++ public Collection getWorldMaps() { + return List.of(); + } + @@ -1773,13 +1762,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 +1808,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 +2012,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,10 +2062,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 ae4ebf509837e8d44255781c61d02873f8b74be8..876be700dea01f8361c37cff8e17f9140ff8ba26 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 -+ 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 2fe9d9b38c01d04416843fdd48d3e33899b7de63..5aae3c7692a6e4bc04b843878da063f6d2a5c7f2 100644 +index 1f898500d0e9b18a880645ceb0a8ff0fe75f4e48..18fe62b5f6f90099d321ad381a941d8e3bd1ea66 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. +@@ -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 +- // 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.asp.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.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 @@ -2223,7 +2221,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. +@@ -634,7 +645,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe int k = this.spigotConfig.simulationDistance; // Spigot // Paper - rewrite chunk system @@ -2232,12 +2230,12 @@ index 2fe9d9b38c01d04416843fdd48d3e33899b7de63..5aae3c7692a6e4bc04b843878da063f6 return minecraftserver.overworld().getDataStorage(); }); this.chunkSource.getGeneratorState().ensureStructuresGenerated(); -@@ -606,6 +620,12 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -693,6 +704,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 @@ -2246,20 +2244,19 @@ 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/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 +2264,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 b4e8ebee..0b9b2cd5 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; @@ -17,10 +17,10 @@ index fd35e4db0c8fec8f86b8743bcc2b15ed2e7433f1..212595f0533f152384e010089660ebdd 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; @@ -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 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 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 93cc1915..9ab91a0f 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 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; @@ -28,19 +28,19 @@ 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 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.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; -@@ -235,6 +236,17 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { + 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); } diff --git a/patches/server/0004-Fix-entity-loading.patch b/patches/server/0004-Fix-entity-loading.patch index a731901b..e2a9a267 100644 --- a/patches/server/0004-Fix-entity-loading.patch +++ b/patches/server/0004-Fix-entity-loading.patch @@ -5,28 +5,28 @@ 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..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 -@@ -112,7 +112,7 @@ public final class NewChunkHolder { +@@ -117,7 +117,7 @@ public final class NewChunkHolder { } 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,11 +67,11 @@ 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 -@@ -15,6 +15,8 @@ import net.minecraft.core.Holder; +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; @@ -80,23 +80,22 @@ index 91a7f41db47c7df3ecc301e0827a1d07305f604e..27af3aa6ba8ffb100a6b1b50ba584e65 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 91a7f41db47c7df3ecc301e0827a1d07305f604e..27af3aa6ba8ffb100a6b1b50ba584e65 - } + 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 91a7f41db47c7df3ecc301e0827a1d07305f604e..27af3aa6ba8ffb100a6b1b50ba584e65 + // Height Maps EnumSet heightMapTypes = nmsChunk.getStatus().heightmapsAfter(); - CompoundMap heightMaps = chunk.getHeightMaps().getValue(); + CompoundBinaryTag heightMaps = chunk.getHeightMaps(); diff --git a/patches/server/0005-Remove-catch-throwable.patch b/patches/server/0005-Remove-catch-throwable.patch index 89b3cf28..d89ef86e 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 3f30631e..512b843e 100644 --- a/patches/server/0006-Handle-null-data-properly.patch +++ b/patches/server/0006-Handle-null-data-properly.patch @@ -4,11 +4,11 @@ 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 -@@ -45,9 +45,12 @@ class SimpleDataFixerConverter implements SlimeWorldReader { +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 { ); } @@ -19,9 +19,9 @@ index 1affe4c94b490a05184deccc9eb80530f67fd5ea..1a4be97069f01a82deadd26a94e86dbe 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 8db8760b..fc958807 100644 --- a/patches/server/0007-Make-SlimeWorld-a-PersistentDataHolder.patch +++ b/patches/server/0007-Make-SlimeWorld-a-PersistentDataHolder.patch @@ -4,26 +4,20 @@ 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 -@@ -1,5 +1,6 @@ - package com.infernalsuite.aswm; - -+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; -@@ -12,6 +13,7 @@ import net.kyori.adventure.util.Services; +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; -+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 97a3c0401d1bcf34d8022da5163b8169a66fd5b3..21c3ea3596a1f954618348afae2b2f7f 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) { -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; +@@ -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; @@ -82,30 +80,31 @@ index 9a27369c00345bbb94aa19f77687269dc94c0b0a..07e542e3f75bf272f53345dc040d9035 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/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; -@@ -19,6 +20,8 @@ import net.minecraft.world.level.chunk.UpgradeData; ++} +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; @@ -114,23 +113,40 @@ index 03f0a5c88a6b2d28a5a69649fc1295b51aaf879f..092dae1f9e68f1c395cd0f8151cd696c 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 f047a320..e06b417b 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,11 +5,11 @@ 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 -@@ -70,11 +70,12 @@ class SimpleDataFixerConverter implements SlimeWorldReader { +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(), @@ -24,40 +24,47 @@ 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 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; } -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 -@@ -45,14 +45,14 @@ public class NMSSlimeWorld implements SlimeWorld { +@@ -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; } @@ -74,16 +81,16 @@ 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 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 CompoundTag getExtraData() { ++ public CompoundBinaryTag getExtraData() { + if (shouldDefaultBackToSlimeChunk()) { + return this.safety.getExtraData(); + } @@ -94,11 +101,11 @@ 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 -@@ -165,6 +165,13 @@ public class SlimeChunkConverter { +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); } @@ -112,20 +119,11 @@ index 27af3aa6ba8ffb100a6b1b50ba584e65c4aee86a..a03c59d2800885e90467812f0088787a return nmsChunk; } } -\ 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 -@@ -1,6 +1,7 @@ - package com.infernalsuite.aswm.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; -@@ -88,11 +89,11 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +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); @@ -139,7 +137,7 @@ index 092dae1f9e68f1c395cd0f8151cd696c0bcdceb0..72a74f0c2cf21c32fa4ffd600cf95eae } 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 092dae1f9e68f1c395cd0f8151cd696c0bcdceb0..72a74f0c2cf21c32fa4ffd600cf95eae 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 092dae1f9e68f1c395cd0f8151cd696c0bcdceb0..72a74f0c2cf21c32fa4ffd600cf95eae } @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(), @@ -179,10 +176,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 800ce1c8..bae4cf22 100644 --- a/patches/server/0009-Add-migration-from-SRF-1-8.patch +++ b/patches/server/0009-Add-migration-from-SRF-1-8.patch @@ -4,56 +4,56 @@ 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 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.aswm; + 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; -@@ -30,18 +31,21 @@ class SimpleDataFixerConverter implements SlimeWorldReader { +@@ -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<>(); + 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, @@ -63,49 +63,41 @@ 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 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.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.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.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 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); } @@ -113,10 +105,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 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; @@ -133,39 +125,39 @@ index ad30e83670ca88f09fa7625fc52c224247410623..e183ca25bf67a0519de7a91615fbcfc6 } 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; + } + 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 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 CompoundTag getUpgradeData() { ++ public CompoundBinaryTag getUpgradeData() { + if (shouldDefaultBackToSlimeChunk()) { + return this.safety.getUpgradeData(); + } @@ -176,11 +168,11 @@ 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 -@@ -118,7 +118,14 @@ public class SlimeChunkConverter { +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<>(); @@ -194,13 +186,13 @@ index a03c59d2800885e90467812f0088787a85d8cd88..75bb1e9355141215c4850f1b57db9434 + } + 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/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 -@@ -115,7 +115,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +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(), 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 d2dd3d0b..4798b901 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 8684f2c0..96837ed9 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,11 +20,11 @@ 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 -@@ -219,7 +219,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +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(); } @@ -33,7 +33,7 @@ index 95133e0ff8a8bdfc84c1dd7ff6b2c7ed7ae9a2f9..b54b231e22967eb0b34e6ba9b7ec9cdf 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 253ffcca..7c831a66 100644 --- a/patches/server/0012-Compile-fixes.patch +++ b/patches/server/0012-Compile-fixes.patch @@ -5,23 +5,23 @@ Subject: [PATCH] Compile fixes diff --git a/build.gradle.kts b/build.gradle.kts -index f947b82537e5858dd0020a7a6fff48c54f3b49a3..316d03791a97af50f882c0271cbacf3d2a7af5b3 100644 +index f0bfc068301c4a908a5856b7c72e7306adeeb38d..e6414d33e65233836db36040206c32a16b4d10ca 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(":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-jansi:3.21.0") -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 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 { { @@ -31,7 +31,7 @@ index e183ca25bf67a0519de7a91615fbcfc6ff45a56e..b295d159200e3bf0e48f851ac206b2e0 - }); + 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 e183ca25bf67a0519de7a91615fbcfc6ff45a56e..b295d159200e3bf0e48f851ac206b2e0 - }); + 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 e183ca25bf67a0519de7a91615fbcfc6ff45a56e..b295d159200e3bf0e48f851ac206b2e0 } 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 e183ca25bf67a0519de7a91615fbcfc6ff45a56e..b295d159200e3bf0e48f851ac206b2e0 } 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/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 -@@ -78,7 +78,7 @@ public class SlimeChunkConverter { +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 }); @@ -83,7 +83,7 @@ index 75bb1e9355141215c4850f1b57db9434d8212637..003778f3ba9db1f52d7746d3b4b1132e } 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,28 +92,28 @@ index 75bb1e9355141215c4850f1b57db9434d8212637..003778f3ba9db1f52d7746d3b4b1132e } 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()); 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 -@@ -1,6 +1,7 @@ - package com.infernalsuite.aswm.level; +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.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 @@ -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 2805c93a..69eed2b5 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,40 @@ 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 e6414d33e65233836db36040206c32a16b4d10ca..2f52145f996e5055030d7960c4ad616ba0ea5321 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(":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 - implementation("org.jline:jline-terminal-jansi:3.21.0") -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..06e91530198d9075434045893f95f7a6ae5bfbb3 --- /dev/null -+++ b/src/main/java/com/infernalsuite/aswm/AdvancedSlimePaper.java -@@ -0,0 +1,243 @@ -+package com.infernalsuite.aswm; -+ -+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; ++++ 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; @@ -192,7 +190,7 @@ index 0000000000000000000000000000000000000000..719bfb548cfe69cbb726d95b68527bdf + 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..719bfb548cfe69cbb726d95b68527bdf + 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; @@ -265,12 +263,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,20 +421,20 @@ 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 -@@ -48,8 +48,6 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { +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("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; } @@ -450,11 +448,19 @@ 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 -@@ -31,13 +31,14 @@ import net.minecraft.world.level.chunk.storage.ChunkSerializer; +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; @@ -462,19 +468,19 @@ index b295d159200e3bf0e48f851ac206b2e09b756bb2..6ef45be4a76c00be5fbfcdb543882fcf 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; -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 -@@ -35,7 +35,7 @@ public class NMSSlimeWorld implements SlimeWorld { + 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() { @@ -483,7 +489,7 @@ index 004d7bcc5b35c76855787dcf32fe460e73cab38f..56c5db9a22af8ddd1d459bcf1f5b3fc7 } @Override -@@ -50,7 +50,7 @@ public class NMSSlimeWorld implements SlimeWorld { +@@ -52,7 +52,7 @@ public class NMSSlimeWorld implements SlimeWorld { @Override public Collection getChunkStorage() { @@ -492,11 +498,11 @@ 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 -@@ -145,7 +145,7 @@ public class SlimeInMemoryWorld implements SlimeWorld, SlimeWorldInstance { +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() { @@ -505,7 +511,7 @@ index b54b231e22967eb0b34e6ba9b7ec9cdf64bad87e..114da62698c2897b16042327a4171f78 } @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,12 +521,12 @@ index b54b231e22967eb0b34e6ba9b7ec9cdf64bad87e..114da62698c2897b16042327a4171f78 - } - @Override - public CompoundTag getExtraData() { + public ConcurrentMap 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 +619,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,18 +712,18 @@ 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 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.aswm.AdvancedSlimePaper; ++import com.infernalsuite.asp.AdvancedSlimePaper; 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 { +@@ -1487,6 +1488,8 @@ public final class CraftServer implements Server { return false; } diff --git a/patches/server/0014-replace-ChunkPos-with-long.patch b/patches/server/0014-replace-ChunkPos-with-long.patch index 755f44a7..4059372e 100644 --- a/patches/server/0014-replace-ChunkPos-with-long.patch +++ b/patches/server/0014-replace-ChunkPos-with-long.patch @@ -4,50 +4,54 @@ 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 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; -@@ -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/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 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; -@@ -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<>(); +- 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 { ); } @@ -56,30 +60,39 @@ 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; - - 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; +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; -@@ -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 114da62698c2897b16042327a4171f785bc58cec..770679851baba2ddb9f8f427f4cd80ea 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 114da62698c2897b16042327a4171f785bc58cec..770679851baba2ddb9f8f427f4cd80ea 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 114da62698c2897b16042327a4171f785bc58cec..770679851baba2ddb9f8f427f4cd80ea } @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 114da62698c2897b16042327a4171f785bc58cec..770679851baba2ddb9f8f427f4cd80ea 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 114da62698c2897b16042327a4171f785bc58cec..770679851baba2ddb9f8f427f4cd80ea } // 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 4e34ce35..5afa0965 100644 --- a/patches/server/0015-1.21-compatibility.patch +++ b/patches/server/0015-1.21-compatibility.patch @@ -4,11 +4,11 @@ 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 -@@ -212,7 +212,7 @@ public class SlimeNMSBridgeImpl implements SlimeNMSBridge { +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"); }; @@ -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,55 +37,45 @@ 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..0f4de8602c3b897e4eb7246951a1a1db646c59fa 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; -@@ -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 -+++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeChunk.java -@@ -1,17 +1,16 @@ - package com.infernalsuite.aswm.level; +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.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.mojang.logging.LogUtils; -+import com.infernalsuite.aswm.skeleton.SlimeChunkSectionSkeleton; - import com.mojang.serialization.Codec; + 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; -@@ -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; @@ -97,20 +87,20 @@ 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 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.aswm.level; + 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.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; @@ -119,7 +109,7 @@ index 003778f3ba9db1f52d7746d3b4b1132e373dd365..86a5b457bdca63713769d2b708be905d 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; @@ -127,7 +117,7 @@ index 003778f3ba9db1f52d7746d3b4b1132e373dd365..86a5b457bdca63713769d2b708be905d 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()]; @@ -138,22 +128,24 @@ index 003778f3ba9db1f52d7746d3b4b1132e373dd365..86a5b457bdca63713769d2b708be905d 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 @@ -164,29 +156,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; @@ -257,7 +249,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 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 @@ @@ -268,15 +260,15 @@ index 5453b7051337908ac1c8201827c1b5eec9e1608b..ca011a8803f7a35cc8e24a0b3be15c23 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; +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; +@@ -327,6 +330,12 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p } } @@ -289,16 +281,16 @@ index 5453b7051337908ac1c8201827c1b5eec9e1608b..ca011a8803f7a35cc8e24a0b3be15c23 // 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 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) { // 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 new file mode 100644 index 00000000..5eb3342b --- /dev/null +++ b/patches/server/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/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 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 00000000..8bf690d8 --- /dev/null +++ b/patches/server/0017-fix-disable-dragon-fights.patch @@ -0,0 +1,33 @@ +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; + } 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 00000000..50b5893e --- /dev/null +++ b/patches/server/0018-fix-chunk-pdc-getting-wiped-on-chunk-unload.patch @@ -0,0 +1,18 @@ +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(); + } + 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 00000000..5e98844c --- /dev/null +++ b/patches/server/0019-1.21.3-fixes.patch @@ -0,0 +1,284 @@ +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); + } + } + } 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 00000000..ba61ccb8 --- /dev/null +++ b/patches/server/0020-Fix-missing-chunks-entities-when-chunk-saving.patch @@ -0,0 +1,127 @@ +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 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 00000000..bd726a4a --- /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/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 new file mode 100644 index 00000000..3ec576c2 --- /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(), diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts index 54357579..31e30b31 100644 --- a/plugin/build.gradle.kts +++ b/plugin/build.gradle.kts @@ -1,43 +1,35 @@ plugins { - id("com.github.johnrengelman.shadow") version "8.1.1" - 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("") + withType { + archiveBaseName.set("asp-plugin") + } - 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") + shadowJar { + 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 +37,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 a32f83a2..9443ad20 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 ee801836..6f7c85aa 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 9496fcd4..34b6499a 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 e6eab23d..385fb939 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 3adcb4db..be78f128 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 e27aef7d..5a7ed2a7 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 c9df2af8..9b5efea9 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 00000000..b15ab60b --- /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 51f5743f..036e7045 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 efe1e178..ed6ddea8 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 25e36ae5..4a57928d 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 78a12839..fd4e17e7 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 6685df33..b1634d86 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 4c7dbf5a..9bbf12c0 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 a94a7549..12c9359e 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 5dad6ccc..d6dd7f96 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 89c72d01..f60c2f11 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 e3d3ef01..1a269d73 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 66a57fbd..5cb1f3cf 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 87% 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 3581354c..12f29e12 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; @@ -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()); } }); } 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 06a99cd3..f76c56bc 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 261bf16f..1ebd8d7e 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 38b82ab1..5f55c5e7 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 38b0f5fe..98b2f102 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 f7717bd4..dfd1d270 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 69e7bfdb..83e40b45 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 49d70a48..2896dbfc 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 f90dd35c..6dba89ba 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 f28a6f8b..1b8e0677 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 30dd9feb..6ce08da9 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 8d65ab38..1b429741 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 73b35b25..7d73e01a 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 95fe092b..7e4fea23 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 35d03d2f..00000000 --- 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/plugin/src/main/resources/sources.yml b/plugin/src/main/resources/sources.yml index 0a949906..c15b5951 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 diff --git a/settings.gradle.kts b/settings.gradle.kts index 2fe280a2..b1138769 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,13 +1,26 @@ pluginManagement { repositories { mavenLocal() + mavenCentral() gradlePluginPortal() maven("https://repo.papermc.io/repository/maven-public/") } } -rootProject.name = "slimeworldmanager" +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0" +} + +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(":impl") +include(":impl:aspaper-api") +include(":impl:aspaper-server") +//include(":aspaper-api") +//include(":aspaper-server")