fix: Fix server trying to access client instance

This commit is contained in:
Steveplays28
2023-08-14 19:23:57 +02:00
parent f7131fd2ca
commit a08feebde0
6 changed files with 72 additions and 104 deletions
@@ -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> biome;
#endif
private final ILevelWrapper levelWrapper;
/**
* Cached so it can be quickly used as a semi-stable hashing method. <br>
* 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<Biome> #endif biome) {
return biomeWrapperMap.computeIfAbsent(biome, BiomeWrapper::new);
static public IBiomeWrapper getBiomeWrapper(#if PRE_MC_1_18_2 Biome #else Holder<Biome> #endif biome, ILevelWrapper levelWrapper) {
return biomeWrapperMap.computeIfAbsent(biome, biomeHolder -> new BiomeWrapper(biomeHolder, levelWrapper));
}
private BiomeWrapper(#if PRE_MC_1_18_2 Biome #else Holder<Biome> #endif biome) {
private BiomeWrapper(#if PRE_MC_1_18_2 Biome #else Holder<Biome> #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> 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());
}
}
@@ -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<BlockState, BlockStateWrapper> 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());
}
}
@@ -167,7 +167,7 @@ public class ChunkWrapper implements IChunkWrapper
QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ)));
#else //Now returns a Holder<Biome> 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
@@ -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; }
@@ -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