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 100a873d5..b5f087825 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 @@ -19,11 +19,12 @@ package com.seibel.distanthorizons.common.wrappers.block; +import com.seibel.distanthorizons.api.enums.config.ELoggerMode; +import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; -import net.minecraft.client.Minecraft; import net.minecraft.core.Holder; -import net.minecraft.core.Registry; +import net.minecraft.core.RegistryAccess; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.Level; import net.minecraft.world.level.biome.Biome; @@ -35,31 +36,21 @@ import java.io.IOException; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; #if POST_MC_1_17 import net.minecraft.core.Holder; 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 #if MC_1_16_5 || MC_1_17_1 import net.minecraft.core.Registry; #elif MC_1_18_2 || MC_1_19_2 #else -import net.minecraft.core.Holder; import net.minecraft.core.registries.Registries; #endif -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 @@ -76,6 +67,8 @@ public class BiomeWrapper implements IBiomeWrapper public final Holder biome; #endif + private final ILevelWrapper levelWrapper; + /** * 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. @@ -86,12 +79,13 @@ public class BiomeWrapper implements IBiomeWrapper // constructors // //==============// - static public IBiomeWrapper getBiomeWrapper(#if PRE_MC_1_18_2 Biome #else Holder #endif biome) { - return biomeWrapperMap.computeIfAbsent(biome, BiomeWrapper::new); + static public IBiomeWrapper getBiomeWrapper(#if PRE_MC_1_18_2 Biome #else Holder #endif biome, ILevelWrapper levelWrapper) { + return biomeWrapperMap.computeIfAbsent(biome, biomeHolder -> new BiomeWrapper(biomeHolder, levelWrapper)); } - private BiomeWrapper(#if PRE_MC_1_18_2 Biome #else Holder #endif biome) { + private BiomeWrapper(#if PRE_MC_1_18_2 Biome #else Holder #endif biome, ILevelWrapper levelWrapper) { this.biome = biome; + this.levelWrapper = levelWrapper; } //=========// @@ -117,18 +111,25 @@ public class BiomeWrapper implements IBiomeWrapper 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()); + return Objects.equals(this.serialize(this.getLevelWrapper()), that.serialize(this.getLevelWrapper())); } @Override public int hashCode() { - return Objects.hash(this.serialize()); + return Objects.hash(this.serialize(this.getLevelWrapper())); } @Override public String serialize(ILevelWrapper levelWrapper) { if (this.serializationResult == null) { - net.minecraft.core.RegistryAccess registryAccess = ((Level) levelWrapper.getWrappedMcObject()).registryAccess(); + // FIXME: Workaround for serverside support + RegistryAccess registryAccess; + try { + registryAccess = ((Level) levelWrapper.getWrappedMcObject()).registryAccess(); + } catch (Exception ignored) { + this.serializationResult = ""; + return this.serializationResult; + } ResourceLocation resourceLocation; #if MC_1_16_5 || MC_1_17_1 @@ -140,34 +141,6 @@ public class BiomeWrapper implements IBiomeWrapper #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; - } - - // FIXME: Old code that might create a nullpointer exception - @Override - public String serialize() { - if (this.serializationResult == null) { - 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) - { String biomeName; #if MC_1_16_5 || MC_1_17_1 biomeName = this.biome.toString(); @@ -186,12 +159,19 @@ public class BiomeWrapper implements IBiomeWrapper return this.serializationResult; } + @Override + public ILevelWrapper getLevelWrapper() { + return levelWrapper; + } + public static IBiomeWrapper deserialize(String resourceLocationString, ILevelWrapper levelWrapper) throws IOException { if (resourceLocationString.trim().isEmpty() || resourceLocationString.equals("")) { - LOGGER.warn("null biome string deserialized"); + if (Config.Client.Advanced.Logging.logWorldGenEvent.get() == ELoggerMode.LOG_WARNING_TO_CHAT_AND_FILE) { + 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) + resourceLocationString = new ResourceLocation("minecraft", "the_void").toString(); // just "void" in MC 1.12 through 1.9 (inclusive) } // parse the resource location @@ -219,7 +199,7 @@ public class BiomeWrapper implements IBiomeWrapper Holder biome = new Holder.Direct<>(unwrappedBiome); #endif - return getBiomeWrapper(biome); + return getBiomeWrapper(biome, levelWrapper); } catch (Exception e) { throw new IOException( "Failed to deserialize the string [" + resourceLocationString + "] into a BiomeWrapper: " + e.getMessage(), e); @@ -227,9 +207,13 @@ public class BiomeWrapper implements IBiomeWrapper } @Override - public Object getWrappedMcObject() {return this.biome;} + public Object getWrappedMcObject() { + return this.biome; + } @Override - public String toString() {return this.serialize();} + public String toString() { + return this.serialize(this.getLevelWrapper()); + } } 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 4df996c33..bcebd1934 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 @@ -4,11 +4,11 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; +import net.minecraft.core.RegistryAccess; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.Level; 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; @@ -20,11 +20,9 @@ import java.util.concurrent.ConcurrentHashMap; #if MC_1_16_5 || MC_1_17_1 import net.minecraft.core.Registry; #elif MC_1_18_2 || MC_1_19_2 -import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.core.Registry; #else -import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.core.registries.Registries; import net.minecraft.world.level.EmptyBlockGetter; @@ -41,7 +39,7 @@ public class BlockStateWrapper implements IBlockStateWrapper // must be defined before AIR, otherwise a null pointer will be thrown private static final Logger LOGGER = DhLoggerBuilder.getLogger(); - public static final BlockStateWrapper AIR = new BlockStateWrapper(null); + public static final BlockStateWrapper AIR = new BlockStateWrapper(null, null); public static final ConcurrentHashMap cache = new ConcurrentHashMap<>(); /** @@ -55,20 +53,23 @@ public class BlockStateWrapper implements IBlockStateWrapper // constructors // //==============// - public static BlockStateWrapper fromBlockState(BlockState blockState) + public static BlockStateWrapper fromBlockState(BlockState blockState, ILevelWrapper levelWrapper) { if (blockState == null || blockState.isAir()) { return AIR; } - return cache.computeIfAbsent(blockState, BlockStateWrapper::new); + return cache.computeIfAbsent(blockState, blockState1 -> new BlockStateWrapper(blockState1, levelWrapper)); } public final BlockState blockState; - BlockStateWrapper(BlockState blockState) + public final ILevelWrapper levelWrapper; + + BlockStateWrapper(BlockState blockState, ILevelWrapper levelWrapper) { this.blockState = blockState; + this.levelWrapper = levelWrapper; LOGGER.trace("Created BlockStateWrapper for ["+blockState+"]"); } @@ -108,14 +109,21 @@ public class BlockStateWrapper implements IBlockStateWrapper return "AIR"; } + // FIXME: Workaround for serverside support + RegistryAccess registryAccess; + try { + registryAccess = ((Level) levelWrapper.getWrappedMcObject()).registryAccess(); + } catch (Exception ignored) { + this.serializationResult = ""; + return this.serializationResult; + } + 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 = ((Level)levelWrapper.getWrappedMcObject()).registryAccess(); resourceLocation = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).getKey(this.blockState.getBlock()); #else - net.minecraft.core.RegistryAccess registryAccess = ((Level)levelWrapper.getWrappedMcObject()).registryAccess(); resourceLocation = registryAccess.registryOrThrow(Registries.BLOCK).getKey(this.blockState.getBlock()); #endif @@ -131,40 +139,11 @@ public class BlockStateWrapper implements IBlockStateWrapper return this.serializationResult; } - // FIXME: Old code that might create a nullpointer exception @Override - public String serialize() { - // cache the serialization result so it can be quickly used as a semi-stable hashing method - if (this.serializationResult == null) - { - 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); - } - - return this.serializationResult; + public ILevelWrapper getLevelWrapper() { + return levelWrapper; } - + public static BlockStateWrapper deserialize(String resourceStateString, ILevelWrapper levelWrapper) throws IOException { if (resourceStateString.equals("AIR") || resourceStateString.equals("")) // the empty string shouldn't normally happen, but just in case @@ -227,7 +206,7 @@ public class BlockStateWrapper implements IBlockStateWrapper LOGGER.warn("Unable to find BlockState for Block ["+resourceLocation+"] with properties: ["+blockStatePropertiesString+"]."); foundState = block.defaultBlockState(); } - return new BlockStateWrapper(foundState); + return new BlockStateWrapper(foundState, levelWrapper); } catch (Exception e) { @@ -281,12 +260,13 @@ public class BlockStateWrapper implements IBlockStateWrapper BlockStateWrapper that = (BlockStateWrapper) obj; // the serialized value is used so we can test the contents instead of the references - return Objects.equals(this.serialize(), that.serialize()); + return Objects.equals(this.serialize(this.getLevelWrapper()), that.serialize(this.getLevelWrapper())); } @Override - public int hashCode() { return Objects.hash(this.serialize()); } - + public int hashCode() { + return Objects.hash(this.serialize(this.getLevelWrapper())); + } @Override public Object getWrappedMcObject() { return this.blockState; } @@ -321,6 +301,8 @@ public class BlockStateWrapper implements IBlockStateWrapper } @Override - public String toString() { return this.serialize(); } + public String toString() { + return this.serialize(this.getLevelWrapper()); + } } diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/chunk/ChunkWrapper.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/chunk/ChunkWrapper.java index 949e25c01..5ebacfaa4 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/chunk/ChunkWrapper.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/chunk/ChunkWrapper.java @@ -167,7 +167,7 @@ public class ChunkWrapper implements IChunkWrapper QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ))); #else //Now returns a Holder instead of Biome return BiomeWrapper.getBiomeWrapper(this.chunk.getNoiseBiome( - QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ))); + QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ)), wrappedLevel); #endif } @@ -366,7 +366,7 @@ public class ChunkWrapper implements IChunkWrapper public IBlockStateWrapper getBlockState(int relX, int relY, int relZ) { //if (wrappedLevel != null) return wrappedLevel.getBlockState(new DhBlockPos(x + getMinX(), y, z + getMinZ())); - return BlockStateWrapper.fromBlockState(this.chunk.getBlockState(new BlockPos(relX, relY, relZ))); + return BlockStateWrapper.fromBlockState(this.chunk.getBlockState(new BlockPos(relX, relY, relZ)), wrappedLevel); } @Override diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java index 665bf9d7c..3d56b043a 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java @@ -187,11 +187,13 @@ public class ClientLevelWrapper implements IClientLevelWrapper @Override public IBlockStateWrapper getBlockState(DhBlockPos pos) { - return BlockStateWrapper.fromBlockState(this.level.getBlockState(McObjectConverter.Convert(pos))); + return BlockStateWrapper.fromBlockState(this.level.getBlockState(McObjectConverter.Convert(pos)), getWrapper(level)); } @Override - public IBiomeWrapper getBiome(DhBlockPos pos) { return BiomeWrapper.getBiomeWrapper(this.level.getBiome(McObjectConverter.Convert(pos))); } + public IBiomeWrapper getBiome(DhBlockPos pos) { + return BiomeWrapper.getBiomeWrapper(this.level.getBiome(McObjectConverter.Convert(pos)), this); + } @Override public ClientLevel getWrappedMcObject() { return this.level; } diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ServerLevelWrapper.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ServerLevelWrapper.java index 9c0b5c3b5..23146c60f 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ServerLevelWrapper.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ServerLevelWrapper.java @@ -171,12 +171,12 @@ public class ServerLevelWrapper implements IServerLevelWrapper @Override public IBlockStateWrapper getBlockState(DhBlockPos pos) { - return BlockStateWrapper.fromBlockState(level.getBlockState(McObjectConverter.Convert(pos))); + return BlockStateWrapper.fromBlockState(level.getBlockState(McObjectConverter.Convert(pos)), getWrapper(level)); } @Override public IBiomeWrapper getBiome(DhBlockPos pos) { - return BiomeWrapper.getBiomeWrapper(level.getBiome(McObjectConverter.Convert(pos))); + return BiomeWrapper.getBiomeWrapper(level.getBiome(McObjectConverter.Convert(pos)), this); } @Override diff --git a/coreSubProjects b/coreSubProjects index 8dcec7a1b..87a9e9327 160000 --- a/coreSubProjects +++ b/coreSubProjects @@ -1 +1 @@ -Subproject commit 8dcec7a1bdc2af25129ad0f065a57d9edb601b4f +Subproject commit 87a9e93278f1f73f952af5c486aa58f0f29ecfc3