Convert Biome/Block wrapper serialization methods to use ResourceLocations
This commit is contained in:
+57
-17
@@ -24,19 +24,36 @@ import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
#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
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
|
||||
|
||||
#if MC_1_16_5
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.resources.RegistryReadOps;
|
||||
import net.minecraft.resources.RegistryWriteOps;
|
||||
#else
|
||||
import net.minecraft.resources.RegistryReadOps;
|
||||
#endif
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
#if !PRE_MC_1_18_2
|
||||
import net.minecraft.world.level.biome.Biomes;
|
||||
#endif
|
||||
|
||||
|
||||
/** This class wraps the minecraft BlockPos.Mutable (and BlockPos) class */
|
||||
@@ -70,14 +87,6 @@ public class BiomeWrapper implements IBiomeWrapper
|
||||
#endif
|
||||
}
|
||||
|
||||
@Override
|
||||
public String serialize() {
|
||||
//FIXME: Pass in a level obj
|
||||
String data = Biome.CODEC.encodeStart(RegistryOps.create(JsonOps.INSTANCE, Minecraft.getInstance().level.registryAccess()),
|
||||
biome).get().orThrow().toString();
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
@@ -91,19 +100,50 @@ public class BiomeWrapper implements IBiomeWrapper
|
||||
return Objects.hash(biome);
|
||||
}
|
||||
|
||||
public static IBiomeWrapper deserialize(String str) throws IOException
|
||||
@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 = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome);
|
||||
if (resourceLocation == null)
|
||||
{
|
||||
// shouldn't normally happen, but just in case
|
||||
return "";
|
||||
}
|
||||
else
|
||||
{
|
||||
String resourceLocationString = resourceLocation.getNamespace()+":"+resourceLocation.getPath();
|
||||
return resourceLocationString;
|
||||
}
|
||||
}
|
||||
|
||||
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(""))
|
||||
{
|
||||
// shouldn't normally happen, but just in case
|
||||
new ResourceLocation("minecraft", "the_void"); // just "void" in MC 1.12 through 1.9 (inclusive)
|
||||
}
|
||||
|
||||
|
||||
// parse the resource location
|
||||
int separatorIndex = resourceLocationString.indexOf(":");
|
||||
if (separatorIndex == -1)
|
||||
{
|
||||
throw new IOException("Unable to parse resource location string: ["+resourceLocationString+"].");
|
||||
}
|
||||
ResourceLocation resourceLocation = new ResourceLocation(resourceLocationString.substring(0, separatorIndex), resourceLocationString.substring(separatorIndex+1));
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
#if PRE_MC_1_18_2 Biome #else
|
||||
Holder<Biome> #endif
|
||||
biome = Biome.CODEC.decode(RegistryOps.create(JsonOps.INSTANCE, Minecraft.getInstance().level.registryAccess()),
|
||||
JsonParser.parseString(str)).get().orThrow().getFirst();
|
||||
net.minecraft.core.RegistryAccess registryAccess = Minecraft.getInstance().level.registryAccess();
|
||||
Biome biome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
|
||||
return getBiomeWrapper(biome);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new IOException("Failed to deserialize the string ["+str+"] into a BiomeWrapper: "+e.getMessage(), e);
|
||||
throw new IOException("Failed to deserialize the string ["+resourceLocationString+"] into a BiomeWrapper: "+e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+97
-16
@@ -1,29 +1,35 @@
|
||||
package com.seibel.distanthorizons.common.wrappers.block;
|
||||
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||
import net.minecraft.client.resources.model.Material;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.EmptyBlockGetter;
|
||||
import net.minecraft.core.Registry;
|
||||
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.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class BlockStateWrapper implements IBlockStateWrapper
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
public static final BlockStateWrapper AIR = new BlockStateWrapper(null);
|
||||
/** example "minecraft:plains" */
|
||||
public static final String RESOURCE_LOCATION_SEPARATOR = ":";
|
||||
/** example "minecraft:water_state_{level:0}" */
|
||||
public static final String STATE_STRING_SEPARATOR = "_STATE_";
|
||||
|
||||
public static final BlockStateWrapper AIR = new BlockStateWrapper(null);
|
||||
|
||||
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
|
||||
public static ConcurrentHashMap<BlockState, BlockStateWrapper> cache = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// constructors //
|
||||
//==============//
|
||||
@@ -79,27 +85,102 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
||||
return "AIR";
|
||||
}
|
||||
|
||||
return BlockState.CODEC.encodeStart(JsonOps.INSTANCE, this.blockState).get().orThrow().toString();
|
||||
ResourceLocation resourceLocation = Registry.BLOCK.getKey(this.blockState.getBlock());
|
||||
String resourceStateString = resourceLocation.getNamespace() + RESOURCE_LOCATION_SEPARATOR + resourceLocation.getPath()
|
||||
+ STATE_STRING_SEPARATOR + serializeBlockStateProperties(this.blockState);
|
||||
return resourceStateString;
|
||||
}
|
||||
|
||||
public static BlockStateWrapper deserialize(String str) throws IOException
|
||||
public static BlockStateWrapper deserialize(String resourceStateString) throws IOException
|
||||
{
|
||||
if (str.equals("AIR"))
|
||||
if (resourceStateString.equals("AIR") || resourceStateString.equals("")) // the empty string shouldn't normally happen, but just in case
|
||||
{
|
||||
return AIR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// parse the BlockState
|
||||
int stateSeparatorIndex = resourceStateString.indexOf(STATE_STRING_SEPARATOR);
|
||||
if (stateSeparatorIndex == -1)
|
||||
{
|
||||
throw new IOException("Unable to parse BlockState out of string: ["+resourceStateString+"].");
|
||||
}
|
||||
String blockStatePropertiesString = resourceStateString.substring(stateSeparatorIndex+STATE_STRING_SEPARATOR.length());
|
||||
resourceStateString = resourceStateString.substring(0, stateSeparatorIndex);
|
||||
|
||||
// parse the resource location
|
||||
int resourceSeparatorIndex = resourceStateString.indexOf(RESOURCE_LOCATION_SEPARATOR);
|
||||
if (resourceSeparatorIndex == -1)
|
||||
{
|
||||
throw new IOException("Unable to parse Resource Location out of string: ["+resourceStateString+"].");
|
||||
}
|
||||
ResourceLocation resourceLocation = new ResourceLocation(resourceStateString.substring(0, resourceSeparatorIndex), resourceStateString.substring(resourceSeparatorIndex+1));
|
||||
|
||||
|
||||
|
||||
// attempt to get the BlockState from all possible BlockStates
|
||||
try
|
||||
{
|
||||
return new BlockStateWrapper(
|
||||
BlockState.CODEC.decode(JsonOps.INSTANCE, JsonParser.parseString(str)).get().orThrow().getFirst()
|
||||
);
|
||||
Block block = Registry.BLOCK.get(resourceLocation);
|
||||
|
||||
BlockState foundState = null;
|
||||
List<BlockState> possibleStateList = block.getStateDefinition().getPossibleStates();
|
||||
for (BlockState possibleState : possibleStateList)
|
||||
{
|
||||
String possibleStatePropertiesString = serializeBlockStateProperties(possibleState);
|
||||
if (possibleStatePropertiesString.equals(blockStatePropertiesString))
|
||||
{
|
||||
foundState = possibleState;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// use the default if no state was found
|
||||
if (foundState == null)
|
||||
{
|
||||
LOGGER.debug("Unable to find BlockState for Block ["+resourceLocation+"] with properties: ["+blockStatePropertiesString+"].");
|
||||
foundState = block.defaultBlockState();
|
||||
}
|
||||
return new BlockStateWrapper(foundState);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new IOException("Failed to deserialize the string ["+str+"] into a BlockStateWrapper: "+e.getMessage(), e);
|
||||
throw new IOException("Failed to deserialize the string ["+resourceStateString+"] into a BlockStateWrapper: "+e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** used to compare and save BlockStates based on their properties */
|
||||
private static String serializeBlockStateProperties(BlockState blockState)
|
||||
{
|
||||
// get the property list for this block (doesn't contain this block state's values, just the names and possible values)
|
||||
java.util.Collection<net.minecraft.world.level.block.state.properties.Property<?>> blockPropertyCollection = blockState.getProperties();
|
||||
|
||||
// alphabetically sort the list so they are always in the same order
|
||||
List<net.minecraft.world.level.block.state.properties.Property<?>> sortedBlockPropteryList = new ArrayList<>(blockPropertyCollection);
|
||||
sortedBlockPropteryList.sort((a,b) -> a.getName().compareTo(b.getName()));
|
||||
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (net.minecraft.world.level.block.state.properties.Property<?> property : sortedBlockPropteryList)
|
||||
{
|
||||
String propertyName = property.getName();
|
||||
|
||||
String value = "NULL";
|
||||
if (blockState.hasProperty(property))
|
||||
{
|
||||
value = blockState.getValue(property).toString();
|
||||
}
|
||||
|
||||
stringBuilder.append("{");
|
||||
stringBuilder.append(propertyName).append(RESOURCE_LOCATION_SEPARATOR).append(value);
|
||||
stringBuilder.append("}");
|
||||
}
|
||||
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user