From 4ad9bb0d71219744c39d784800eb3678694e1505 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sat, 12 Aug 2023 16:17:59 -0500 Subject: [PATCH 1/3] Fix FullDataPointIdMap (de)serialization duplicate Entries Potentially fix serializing Biomes/Blocks after a level has been shut down. Also increase DATA_FORMAT_VERSION 2 -> 3 --- .../common/wrappers/block/BiomeWrapper.java | 109 ++++++++++++------ .../wrappers/block/BlockStateWrapper.java | 61 ++++++---- coreSubProjects | 2 +- 3 files changed, 116 insertions(+), 56 deletions(-) diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/BiomeWrapper.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/BiomeWrapper.java index 665ddfd56..4729789b3 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/BiomeWrapper.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/BiomeWrapper.java @@ -33,8 +33,6 @@ import net.minecraft.resources.RegistryOps; #endif #if POST_MC_1_19_2 -import net.minecraft.data.worldgen.biome.EndBiomes; -import net.minecraft.data.worldgen.biome.NetherBiomes; #endif @@ -54,12 +52,17 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.biome.Biome; #if !PRE_MC_1_18_2 import net.minecraft.world.level.biome.Biomes; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; #endif /** This class wraps the minecraft BlockPos.Mutable (and BlockPos) class */ public class BiomeWrapper implements IBiomeWrapper { + private static final Logger LOGGER = LogManager.getLogger(); + + #if PRE_MC_1_18_2 public static final ConcurrentMap biomeWrapperMap = new ConcurrentHashMap<>(); public final Biome biome; @@ -67,7 +70,19 @@ public class BiomeWrapper implements IBiomeWrapper public static final ConcurrentMap, BiomeWrapper> biomeWrapperMap = new ConcurrentHashMap<>(); public final Holder biome; #endif - + + /** + * Cached so it can be quickly used as a semi-stable hashing method.
+ * This may also fix the issue where we can serialize and save after a level has been shut down. + */ + private String serializationResult = null; + + + + //==============// + // constructors // + //==============// + static public IBiomeWrapper getBiomeWrapper(#if PRE_MC_1_18_2 Biome #else Holder #endif biome) { return biomeWrapperMap.computeIfAbsent(biome, BiomeWrapper::new); @@ -77,61 +92,80 @@ public class BiomeWrapper implements IBiomeWrapper { this.biome = biome; } - - @Override + + + + //=========// + // methods // + //=========// + + @Override public String getName() { #if PRE_MC_1_18_2 return biome.toString(); #else - return biome.unwrapKey().orElse(Biomes.THE_VOID).registry().toString(); + return this.biome.unwrapKey().orElse(Biomes.THE_VOID).registry().toString(); #endif } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - BiomeWrapper that = (BiomeWrapper) o; - return Objects.equals(biome, that.biome); + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + else if (obj == null || this.getClass() != obj.getClass()) + { + return false; + } + + BiomeWrapper that = (BiomeWrapper) obj; + // the serialized value is used so we can test the contents instead of the references + return Objects.equals(this.serialize(), that.serialize()); } @Override - public int hashCode() { - return Objects.hash(biome); - } + public int hashCode() { return Objects.hash(this.serialize()); } @Override public String serialize() // FIXME pass in level to prevent null pointers (or maybe just RegistryAccess?) { - - net.minecraft.core.RegistryAccess registryAccess = Minecraft.getInstance().level.registryAccess(); - - ResourceLocation resourceLocation; - #if MC_1_16_5 || MC_1_17_1 - resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome); - #elif MC_1_18_2 || MC_1_19_2 - resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome.value()); - #else - resourceLocation = registryAccess.registryOrThrow(Registries.BIOME).getKey(this.biome.value()); - #endif - - if (resourceLocation == null) + if (this.serializationResult == null) { - // shouldn't normally happen, but just in case - return ""; - } - else - { - String resourceLocationString = resourceLocation.getNamespace()+":"+resourceLocation.getPath(); - return resourceLocationString; + net.minecraft.core.RegistryAccess registryAccess = Minecraft.getInstance().level.registryAccess(); + + ResourceLocation resourceLocation; + #if MC_1_16_5 || MC_1_17_1 + resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome); + #elif MC_1_18_2 || MC_1_19_2 + resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome.value()); + #else + resourceLocation = registryAccess.registryOrThrow(Registries.BIOME).getKey(this.biome.value()); + #endif + + if (resourceLocation == null) + { + LOGGER.warn("unable to serialize: "+this.biome.value()); + // shouldn't normally happen, but just in case + this.serializationResult = ""; + } + else + { + this.serializationResult = resourceLocation.getNamespace()+":"+resourceLocation.getPath(); + } } + + return this.serializationResult; } public static IBiomeWrapper deserialize(String resourceLocationString) throws IOException // FIXME pass in level to prevent null pointers (or maybe just RegistryAccess?) { if (resourceLocationString.trim().isEmpty() || resourceLocationString.equals("")) { + LOGGER.warn("null biome string deserialized"); + // shouldn't normally happen, but just in case new ResourceLocation("minecraft", "the_void"); // just "void" in MC 1.12 through 1.9 (inclusive) } @@ -157,6 +191,10 @@ public class BiomeWrapper implements IBiomeWrapper Holder biome = new Holder.Direct<>(unwrappedBiome); #else Biome unwrappedBiome = registryAccess.registryOrThrow(Registries.BIOME).get(resourceLocation); + if (unwrappedBiome == null) + { + LOGGER.warn("null biome string deserialized from string: "+resourceLocationString); + } Holder biome = new Holder.Direct<>(unwrappedBiome); #endif @@ -172,4 +210,7 @@ public class BiomeWrapper implements IBiomeWrapper @Override public Object getWrappedMcObject() { return this.biome; } + @Override + public String toString() { return this.serialize(); } + } diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/BlockStateWrapper.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/BlockStateWrapper.java index 2b0cb4ba0..6a1c5f430 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/BlockStateWrapper.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/BlockStateWrapper.java @@ -6,6 +6,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrappe import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; +import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.io.IOException; @@ -39,10 +40,13 @@ public class BlockStateWrapper implements IBlockStateWrapper private static final Logger LOGGER = DhLoggerBuilder.getLogger(); public static final BlockStateWrapper AIR = new BlockStateWrapper(null); + public static final ConcurrentHashMap cache = new ConcurrentHashMap<>(); - - public static ConcurrentHashMap cache = new ConcurrentHashMap<>(); - + /** + * Cached so it can be quickly used as a semi-stable hashing method.
+ * This may also fix the issue where we can serialize and save after a level has been shut down. + */ + private String serializationResult = null; //==============// @@ -95,25 +99,36 @@ public class BlockStateWrapper implements IBlockStateWrapper @Override public String serialize() // FIXME pass in level to prevent null pointers (or maybe just RegistryAccess?) { - if (this.blockState == null) + // cache the serialization result so it can be quickly used as a semi-stable hashing method + if (this.serializationResult == null) { - return "AIR"; + if (this.blockState == null) + { + return "AIR"; + } + + ResourceLocation resourceLocation; + #if MC_1_16_5 || MC_1_17_1 + resourceLocation = Registry.BLOCK.getKey(this.blockState.getBlock()); + #elif MC_1_18_2 || MC_1_19_2 + net.minecraft.core.RegistryAccess registryAccess = Minecraft.getInstance().level.registryAccess(); + resourceLocation = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).getKey(this.blockState.getBlock()); + #else + net.minecraft.core.RegistryAccess registryAccess = Minecraft.getInstance().level.registryAccess(); + resourceLocation = registryAccess.registryOrThrow(Registries.BLOCK).getKey(this.blockState.getBlock()); + #endif + + if (resourceLocation == null) + { + LOGGER.warn("unable to serialize: "+this.blockState); + } + + this.serializationResult = resourceLocation.getNamespace() + RESOURCE_LOCATION_SEPARATOR + resourceLocation.getPath() + + STATE_STRING_SEPARATOR + serializeBlockStateProperties(this.blockState); } - ResourceLocation resourceLocation; - #if MC_1_16_5 || MC_1_17_1 - resourceLocation = Registry.BLOCK.getKey(this.blockState.getBlock()); - #elif MC_1_18_2 || MC_1_19_2 - net.minecraft.core.RegistryAccess registryAccess = Minecraft.getInstance().level.registryAccess(); - resourceLocation = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).getKey(this.blockState.getBlock()); - #else - net.minecraft.core.RegistryAccess registryAccess = Minecraft.getInstance().level.registryAccess(); - resourceLocation = registryAccess.registryOrThrow(Registries.BLOCK).getKey(this.blockState.getBlock()); - #endif - String resourceStateString = resourceLocation.getNamespace() + RESOURCE_LOCATION_SEPARATOR + resourceLocation.getPath() - + STATE_STRING_SEPARATOR + serializeBlockStateProperties(this.blockState); - return resourceStateString; + return this.serializationResult; } public static BlockStateWrapper deserialize(String resourceStateString) throws IOException // FIXME pass in level to prevent null pointers (or maybe just RegistryAccess?) @@ -175,7 +190,7 @@ public class BlockStateWrapper implements IBlockStateWrapper // use the default if no state was found if (foundState == null) { - LOGGER.debug("Unable to find BlockState for Block ["+resourceLocation+"] with properties: ["+blockStatePropertiesString+"]."); + LOGGER.warn("Unable to find BlockState for Block ["+resourceLocation+"] with properties: ["+blockStatePropertiesString+"]."); foundState = block.defaultBlockState(); } return new BlockStateWrapper(foundState); @@ -231,11 +246,12 @@ public class BlockStateWrapper implements IBlockStateWrapper } BlockStateWrapper that = (BlockStateWrapper) obj; - return Objects.equals(this.blockState, that.blockState); + // the serialized value is used so we can test the contents instead of the references + return Objects.equals(this.serialize(), that.serialize()); } @Override - public int hashCode() { return Objects.hash(this.blockState); } + public int hashCode() { return Objects.hash(this.serialize()); } @Override @@ -270,4 +286,7 @@ public class BlockStateWrapper implements IBlockStateWrapper #endif } + @Override + public String toString() { return this.serialize(); } + } diff --git a/coreSubProjects b/coreSubProjects index c2f7ca8f3..d3cf47ccd 160000 --- a/coreSubProjects +++ b/coreSubProjects @@ -1 +1 @@ -Subproject commit c2f7ca8f38eac1fe370f8cd1d153dabcd866a0a9 +Subproject commit d3cf47ccd78afcec88504b3769f0de3e5b2b09b0 From 27df83f8e7e988ed12bc5529295f5510839fe982 Mon Sep 17 00:00:00 2001 From: Null 511 Date: Sat, 12 Aug 2023 22:05:29 +0000 Subject: [PATCH 2/3] Local docker compile --- .dockerignore | 19 +++++++++++++++++++ .gitignore | 1 + Dockerfile | 12 ++++++++++++ Readme.md | 14 ++++++++++++-- compile.sh | 31 +++++++++++++++++++++++++++++++ 5 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 compile.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..a190fb110 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,19 @@ +**/.git +**/.gitlab +**/.cache + +buildAllJars + +**/_Misc Files +*.bat +*.md +*.sh +*.txt + +coreSubProjects/*.md +coreSubProjects/*.txt + +**/.gitignore +**/.gitattributes +**/.gitlab-cy.yml +**/.gitmodules diff --git a/.gitignore b/.gitignore index 547998298..0fa2bd272 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ run/ out/ *.iml .gradle/ +.gradle-cache/ output/ bin/ libs/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..8df81edfb --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM eclipse-temurin:17-jdk + +WORKDIR /home/build/ +COPY ./gradlew . +RUN chmod +x ./gradlew +CMD echo "\r========== [CLEAN: $MC_VER] ==========" && \ + ./gradlew clean -PmcVer="$MC_VER" --gradle-user-home .gradle-cache/ && \ + echo "\r========== [BUILD: $MC_VER] ==========" && \ + ./gradlew build -PmcVer="$MC_VER" --gradle-user-home .gradle-cache/ && \ + echo "\r========== [MERGE: $MC_VER] ==========" && \ + ./gradlew mergeJars -PmcVer="$MC_VER" --gradle-user-home .gradle-cache/ && \ + echo "\r========== [DONE: $MC_VER] ==========" diff --git a/Readme.md b/Readme.md index 737724030..2566023d5 100644 --- a/Readme.md +++ b/Readme.md @@ -109,7 +109,8 @@ If running in an IDE, to ensure the IDE noticed the version change, run any grad >Note: There may be a `java.nio.file.FileSystemException` thrown when running the command after switching versions. To fix it, either restart your IDE (as your IDE is probably locking a file) or use a tool like LockHunter to unlock the linked file(s). (Generally it is a lib file under `common\build\lib`, `forge\build\lib`, or `fabric\build\lib`). \ > If anyone knows how to solve this issue please let us know here: \ > https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues/233 - + +
## Compiling @@ -138,7 +139,16 @@ Run tests with: `./gradlew test` > Example: `./gradlew assemble -PmcVer=1.18.2` -
+
+ +## Compiling with Docker + +`./compile ` + +You can also locally compile the DH jars without a Java environment by using Docker. Where `` is the version of Minecraft to compile for (ie `1.20.1`), or the keyword `all`. See [Versions](#minecraft-and-library-versions) for a list of all supported values. + + +
## Other commands diff --git a/compile.sh b/compile.sh new file mode 100644 index 000000000..9cc9a628b --- /dev/null +++ b/compile.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +publish_version() +{ + if [[ "$2" == "all" || "$1" == "$2" ]] + then + docker run --name=dh-build-$1 --rm -v /${PWD}:/home/build -e MC_VER=$1 dh-eclipse-temurin + cp ./fabric/build/libs/*$1.jar ./buildAllJars/fabric/ + cp ./forge/build/libs/*$1.jar ./buildAllJars/forge/ + cp ./Merged/*.jar ./buildAllJars/merged/ + fi +} + + +if [ -z "$1" ] +then + echo "Build target is undefined! [all] [1.20.1] [1.19.4] [1.19.2] [1.18.2] [1.17.1] [1.16.5]" + exit 1 +fi + +docker build --tag=dh-eclipse-temurin -q . + +mkdir -p buildAllJars/fabric +mkdir -p buildAllJars/forge +mkdir -p buildAllJars/merged +publish_version 1.20.1 $1 +publish_version 1.19.4 $1 +publish_version 1.19.2 $1 +publish_version 1.18.2 $1 +publish_version 1.17.1 $1 +publish_version 1.16.5 $1 From e9c1f41f508b1634f9fed54ef2233f8d6c07a7ee Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sun, 13 Aug 2023 13:37:35 -0500 Subject: [PATCH 3/3] Fix the game instantly crashing due to running out of memory --- coreSubProjects | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreSubProjects b/coreSubProjects index d3cf47ccd..8df8ed4a0 160000 --- a/coreSubProjects +++ b/coreSubProjects @@ -1 +1 @@ -Subproject commit d3cf47ccd78afcec88504b3769f0de3e5b2b09b0 +Subproject commit 8df8ed4a02819d6d90db0ac69a69dc21d1eb91d1