通常であれば特段困らないが、コンフィグで管理したいとき、非常に困る。
というわけで、Gsonを使ってBlockStateのPropertyからJsonへと相互変換するSerializerを作った。
コード: 全て選択
import java.lang.reflect.Type;
import java.util.Map;
import org.apache.commons.lang3.tuple.Pair;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import net.minecraft.block.AirBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.state.IProperty;
import net.minecraft.state.IStateHolder;
import net.minecraft.state.StateContainer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Util;
import net.minecraftforge.registries.ForgeRegistries;
public class BlockStateSerializer implements JsonSerializer<BlockState>, JsonDeserializer<BlockState>
{
@Override
public JsonElement serialize(BlockState src, Type typeOfSrc, JsonSerializationContext context)
{
JsonObject object = new JsonObject();
object.addProperty("name", src.getBlock().getRegistryName().toString());
JsonObject propsObject = new JsonObject();
for (Map.Entry<IProperty<?>, Comparable<?>> entry : src.getValues().entrySet())
{
Pair<String, String> value = getPropertyString(entry);
propsObject.addProperty(value.getLeft(), value.getRight());
}
object.add("properties", propsObject);
return object;
}
@Override
public BlockState deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
{
JsonObject object = json.getAsJsonObject();
String name = object.get("name").getAsString();
Block block = ForgeRegistries.BLOCKS.getValue(new ResourceLocation(name));
if (block == null || block instanceof AirBlock)
{
return Blocks.AIR.getDefaultState();
}
JsonObject propsObject = object.get("properties").getAsJsonObject();
BlockState state = block.getDefaultState();
StateContainer<Block, BlockState> stateContainer = block.getStateContainer();
for (Map.Entry<String, JsonElement> entry : propsObject.entrySet())
{
String key = entry.getKey();
IProperty<?> prop = stateContainer.getProperty(key);
if (prop != null)
{
String value = entry.getValue().getAsString();
state = IStateHolder.withString(state, prop, key, value, value);
}
}
return state;
}
private Pair<String, String> getPropertyString(Map.Entry<IProperty<?>, Comparable<?>> entry)
{
IProperty<?> key = entry.getKey();
Comparable<?> value = entry.getValue();
return Pair.of(key.getName(), Util.getValueName(key, value));
}
}
コード: 全て選択
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import net.minecraft.block.BlockState;
public class BlockStateHelper
{
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().registerTypeAdapter(BlockState.class, new BlockStateSerializer()).create();
public static String toJson(BlockState state)
{
return GSON.toJson(state);
}
public static JsonElement toJsonTree(BlockState state)
{
return GSON.toJsonTree(state);
}
public static BlockState fromJson(String value)
{
return GSON.fromJson(value, BlockState.class);
}
public static BlockState fromJson(JsonElement value)
{
return GSON.fromJson(value, BlockState.class);
}
}