Skip to content

Commit

Permalink
Improved fault tolerance for json file deserialization (Grasscutters#595
Browse files Browse the repository at this point in the history
)

* 修复一个Gson发序列化json文件的空值问题

* Improved fault tolerance for json file deserialization
  • Loading branch information
cfuncode committed May 6, 2022
1 parent 6d89477 commit 2b58d69
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 16 deletions.
18 changes: 10 additions & 8 deletions src/main/java/emu/grasscutter/data/ResourceLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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<String, Object> tempMap = Utils.switchPropertiesUpperLowerCase((Map<String, Object>) o, c);
GameResource res = gson.fromJson(gson.toJson(tempMap), TypeToken.get(c).getType());
res.onLoad();
map.put(res.getId(), res);
}
}

Expand Down
55 changes: 47 additions & 8 deletions src/main/java/emu/grasscutter/utils/Utils.java
Original file line number Diff line number Diff line change
@@ -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();
Expand Down Expand Up @@ -230,4 +234,39 @@ public static int GetNextTimestampOfThisHourInNextMonth(int hour, String timeZon
}
return (int)zonedDateTime.toInstant().atZone(ZoneOffset.UTC).toEpochSecond();
}

public static Map<String, Object> switchPropertiesUpperLowerCase(Map<String, Object> objMap, Class<?> cls) {
Map<String, Object> 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;
}

}

0 comments on commit 2b58d69

Please sign in to comment.