From 2b58d6953418b285cc8a609989c5844789c992cd Mon Sep 17 00:00:00 2001 From: cfuncode <36926346+cfuncode@users.noreply.github.com> Date: Sat, 7 May 2022 04:39:37 +0800 Subject: [PATCH] Improved fault tolerance for json file deserialization (#595) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 修复一个Gson发序列化json文件的空值问题 * Improved fault tolerance for json file deserialization --- .../emu/grasscutter/data/ResourceLoader.java | 18 +++--- .../java/emu/grasscutter/utils/Utils.java | 55 ++++++++++++++++--- 2 files changed, 57 insertions(+), 16 deletions(-) diff --git a/src/main/java/emu/grasscutter/data/ResourceLoader.java b/src/main/java/emu/grasscutter/data/ResourceLoader.java index 5478052d82c..b1e3da9ff01 100644 --- a/src/main/java/emu/grasscutter/data/ResourceLoader.java +++ b/src/main/java/emu/grasscutter/data/ResourceLoader.java @@ -7,6 +7,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.google.gson.Gson; import emu.grasscutter.utils.Utils; import org.reflections.Reflections; @@ -120,14 +121,15 @@ protected static void loadFromResource(Class c, ResourceType type, Int2Object @SuppressWarnings({"rawtypes", "unchecked"}) protected static void loadFromResource(Class c, String fileName, Int2ObjectMap map) throws Exception { - try (FileReader fileReader = new FileReader(Grasscutter.getConfig().RESOURCE_FOLDER + "ExcelBinOutput/" + fileName)) { - List list = Grasscutter.getGsonFactory().fromJson(fileReader, TypeToken.getParameterized(Collection.class, c).getType()); - - for (Object o : list) { - GameResource res = (GameResource) o; - res.onLoad(); - map.put(res.getId(), res); - } + FileReader fileReader = new FileReader(Grasscutter.getConfig().RESOURCE_FOLDER + "ExcelBinOutput/" + fileName); + Gson gson = Grasscutter.getGsonFactory(); + List list = gson.fromJson(fileReader, List.class); + + for (Object o : list) { + Map tempMap = Utils.switchPropertiesUpperLowerCase((Map) o, c); + GameResource res = gson.fromJson(gson.toJson(tempMap), TypeToken.get(c).getType()); + res.onLoad(); + map.put(res.getId(), res); } } diff --git a/src/main/java/emu/grasscutter/utils/Utils.java b/src/main/java/emu/grasscutter/utils/Utils.java index 1b4a00b9099..931a37617f0 100644 --- a/src/main/java/emu/grasscutter/utils/Utils.java +++ b/src/main/java/emu/grasscutter/utils/Utils.java @@ -1,20 +1,24 @@ package emu.grasscutter.utils; -import java.io.*; -import java.nio.file.Files; -import java.nio.file.StandardCopyOption; -import java.time.*; -import java.time.temporal.TemporalAdjusters; -import java.util.Random; - import emu.grasscutter.Config; import emu.grasscutter.Grasscutter; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; - import org.slf4j.Logger; +import java.io.*; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.time.DayOfWeek; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.temporal.TemporalAdjusters; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + @SuppressWarnings({"UnusedReturnValue", "BooleanMethodIsAlwaysInverted"}) public final class Utils { public static final Random random = new Random(); @@ -230,4 +234,39 @@ public static int GetNextTimestampOfThisHourInNextMonth(int hour, String timeZon } return (int)zonedDateTime.toInstant().atZone(ZoneOffset.UTC).toEpochSecond(); } + + public static Map switchPropertiesUpperLowerCase(Map objMap, Class cls) { + Map map = new HashMap<>(objMap.size()); + for (String key : objMap.keySet()) { + try { + char c = key.charAt(0); + if (c >= 'a' && c <= 'z') { + try { + cls.getDeclaredField(key); + map.put(key, objMap.get(key)); + } catch (NoSuchFieldException e) { + String s1 = String.valueOf(c).toUpperCase(); + String after = key.length() > 1 ? s1 + key.substring(1) : s1; + cls.getDeclaredField(after); + map.put(after, objMap.get(key)); + } + } else if (c >= 'A' && c <= 'Z') { + try { + cls.getDeclaredField(key); + map.put(key, objMap.get(key)); + } catch (NoSuchFieldException e) { + String s1 = String.valueOf(c).toLowerCase(); + String after = key.length() > 1 ? s1 + key.substring(1) : s1; + cls.getDeclaredField(after); + map.put(after, objMap.get(key)); + } + } + } catch (NoSuchFieldException e) { + map.put(key, objMap.get(key)); + } + } + + return map; + } + }