Именно поэтому и ищу готовое решениеСложно только с НБТ, даже муторно скорее.
public class JsonItemStack
implements JsonSerializer<ItemStack>,
JsonDeserializer<ItemStack> {
public static final Type TYPE = new TypeToken<ItemStack>(){}.getType();
public ItemStack deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject object = json.getAsJsonObject();
GameRegistry.UniqueIdentifier id = new GameRegistry.UniqueIdentifier(object.get("item").getAsString());
ItemStack stack = GameRegistry.findItemStack((String)id.modId, (String)id.name, (int)(object.has("stacksize") ? object.get("stacksize").getAsInt() : 1));
if (stack == null) {
String info = "Invalid item: " + json.toString();
ArrayList<String> lore = new ArrayList<String>();
ItemStack item = new ItemStack(Items.apple);
lore.add("Name: " + object.get("item").getAsString());
if (object.has("damage")) {
lore.add("Count: " + object.get("damage").getAsInt());
}
LogManager.getLogger((String)"Daily Rewards 1.26b").log(Level.ERROR, info);
ItemStackUtils.setStackDisplayNameAndLore(item, (Object)EnumChatFormatting.DARK_RED + "INVALID_ITEM", lore);
return item;
}
if (object.has("damage")) {
stack.setItemDamage(object.get("damage").getAsInt());
}
if (object.has("nbt")) {
stack.stackTagCompound = (NBTTagCompound)context.deserialize(object.get("nbt"), JsonNBT.TYPE);
}
return stack;
}
public JsonElement serialize(ItemStack src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject object = new JsonObject();
GameRegistry.UniqueIdentifier id = GameRegistry.findUniqueIdentifierFor(src.getItem());
object.addProperty("item", id.toString());
object.addProperty("stacksize", (Number)src.stackSize);
object.addProperty("damage", (Number)src.getItemDamage());
if (src.stackTagCompound != null) {
object.add("nbt", context.serialize((Object)src.stackTagCompound));
}
return object;
}
}
public class JsonNBT
implements JsonSerializer<NBTBase>,
JsonDeserializer<NBTBase> {
public static final Type TYPE = new TypeToken<NBTBase>(){}.getType();
public NBTBase deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if (json.isJsonNull()) {
return null;
}
if (json.isJsonObject()) {
NBTTagCompound compound = new NBTTagCompound();
JsonObject object = json.getAsJsonObject();
for (Map.Entry entry : object.entrySet()) {
NBTBase nbtBase = (NBTBase)context.deserialize((JsonElement)entry.getValue(), TYPE);
compound.setTag((String)entry.getKey(), nbtBase);
}
return compound;
}
if (json.isJsonArray()) {
NBTTagList nbtList = new NBTTagList();
JsonArray jsonList = json.getAsJsonArray();
for (JsonElement element : jsonList) {
NBTBase nbtBase = (NBTBase)context.deserialize(element, TYPE);
nbtList.appendTag(nbtBase);
}
return nbtList;
}
if (json.isJsonPrimitive()) {
String string = json.getAsString();
if (string.matches("[-+]?[0-9]*\\.?[0-9]+[d|D]")) {
return new NBTTagDouble(Double.parseDouble(string.substring(0, string.length() - 1)));
}
if (string.matches("[-+]?[0-9]*\\.?[0-9]+[f|F]")) {
return new NBTTagFloat(Float.parseFloat(string.substring(0, string.length() - 1)));
}
if (string.matches("[-+]?[0-9]+[b|B]")) {
return new NBTTagByte(Byte.parseByte(string.substring(0, string.length() - 1)));
}
if (string.matches("[-+]?[0-9]+[l|L]")) {
return new NBTTagLong(Long.parseLong(string.substring(0, string.length() - 1)));
}
if (string.matches("[-+]?[0-9]+[s|S]")) {
return new NBTTagShort(Short.parseShort(string.substring(0, string.length() - 1)));
}
if (string.matches("[-+]?[0-9]+")) {
return new NBTTagInt(Integer.parseInt(string.substring(0, string.length())));
}
if (string.matches("[-+]?[0-9]*\\.?[0-9]+")) {
return new NBTTagDouble(Double.parseDouble(string.substring(0, string.length())));
}
if (!string.equalsIgnoreCase("true") && !string.equalsIgnoreCase("false")) {
if (string.startsWith("[") && string.endsWith("]")) {
if (string.length() > 2) {
String s = string.substring(1, string.length() - 1);
String[] astring = s.split(",");
try {
if (astring.length <= 1) {
return new NBTTagIntArray(new int[]{Integer.parseInt(s.trim())});
}
int[] aint = new int[astring.length];
for (int i = 0; i < astring.length; ++i) {
aint[i] = Integer.parseInt(astring[i].trim());
}
return new NBTTagIntArray(aint);
}
catch (NumberFormatException numberformatexception) {
return new NBTTagString(string);
}
}
return new NBTTagIntArray(new int[0]);
}
if (string.startsWith("\"") && string.endsWith("\"") && string.length() > 2) {
string = string.substring(1, string.length() - 1);
}
string = string.replaceAll("\\\\\"", "\"");
return new NBTTagString(string);
}
return new NBTTagByte((byte)(Boolean.parseBoolean(string) ? 1 : 0));
}
throw new JsonParseException("Invalid NBT: " + json.toString());
}
public JsonElement serialize(NBTBase src, Type typeOfSrc, JsonSerializationContext context) {
if (src instanceof NBTBase.NBTPrimitive) {
return new JsonPrimitive(src.toString());
}
if (src instanceof NBTTagString) {
return new JsonPrimitive(((NBTTagString)src).func_150285_a_());
}
if (src instanceof NBTTagCompound) {
NBTTagCompound compound = (NBTTagCompound)src;
JsonObject object = new JsonObject();
for (Object name : compound.func_150296_c()) {
object.add((String)name, context.serialize((Object)compound.getTag((String)name)));
}
return object;
}
if (src instanceof NBTTagList) {
NBTTagList list = (NBTTagList)src.copy();
JsonArray array = new JsonArray();
while (list.tagCount() != 0) {
array.add(context.serialize((Object)list.removeTag(0)));
}
return array;
}
if (src instanceof NBTTagIntArray) {
JsonArray array = new JsonArray();
for (int val : ((NBTTagIntArray)src).func_150302_c()) {
array.add((JsonElement)new JsonPrimitive((Number)val));
}
return array;
}
throw new IllegalArgumentException("Not supported by MC's JSON code. Type: " + src.getClass() + " Value: " + (Object)src);
}
}
string.startsWith
, Integer.parseInt
и уж тем более string.matches
.when (nbtTag.id.toInt()) {
NBT.TAG_BYTE -> ...
NBT.TAG_SHORT -> ...
NBT.TAG_INT -> ...
...
}
Это не из-за твоего сериализатора.Но у меня с этим кодом сейчас есть проблемы, вроде того, что типы теряются (Integer становится String, а ItemStack - LinkedTreeMap)
gson.fromJson(string, Map.class)
Type type = new TypeToken<HashMap<Integer, ItemStack>>(){}.getType();
gson.fromJson(string, type);
HashMap<Integer, ItemStack>
. Но на самом деле не обычная хэш мапа, а особая gson'овская linked tree мапа. Если хочется именно обычная хэш мапа, то стоит зарегать InstanceCreator для простой хэш мапы.Ну или опционально переменную с айдишником тага.Чтобы не терять типы, можно к имени добавлять суффикс (.i, .f, .d, .s)