package emu.grasscutter.utils; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; import java.util.Map; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; import com.google.gson.JsonSyntaxException; import com.google.gson.reflect.TypeToken; import emu.grasscutter.data.common.DynamicFloat; import emu.grasscutter.utils.JsonAdapters.*; import it.unimi.dsi.fastutil.ints.IntList; public final class JsonUtils { static final Gson gson = new GsonBuilder() .setPrettyPrinting() .registerTypeAdapter(DynamicFloat.class, new DynamicFloatAdapter()) .registerTypeAdapter(IntList.class, new IntListAdapter()) .registerTypeAdapterFactory(new EnumTypeAdapterFactory()) .create(); /* * Encode an object to a JSON string */ public static String encode(Object object) { return gson.toJson(object); } public static T decode(JsonElement jsonElement, Class classType) throws JsonSyntaxException { return gson.fromJson(jsonElement, classType); } public static T loadToClass(Reader fileReader, Class classType) throws IOException { return gson.fromJson(fileReader, classType); } @Deprecated(forRemoval = true) public static T loadToClass(String filename, Class classType) throws IOException { try (InputStreamReader fileReader = new InputStreamReader(new FileInputStream(Utils.toFilePath(filename)), StandardCharsets.UTF_8)) { return loadToClass(fileReader, classType); } } public static T loadToClass(Path filename, Class classType) throws IOException { try (var fileReader = Files.newBufferedReader(filename, StandardCharsets.UTF_8)) { return loadToClass(fileReader, classType); } } public static List loadToList(Reader fileReader, Class classType) throws IOException { return gson.fromJson(fileReader, TypeToken.getParameterized(List.class, classType).getType()); } @Deprecated(forRemoval = true) public static List loadToList(String filename, Class classType) throws IOException { try (InputStreamReader fileReader = new InputStreamReader(new FileInputStream(Utils.toFilePath(filename)), StandardCharsets.UTF_8)) { return loadToList(fileReader, classType); } } public static List loadToList(Path filename, Class classType) throws IOException { try (var fileReader = Files.newBufferedReader(filename, StandardCharsets.UTF_8)) { return loadToList(fileReader, classType); } } public static Map loadToMap(Reader fileReader, Class keyType, Class valueType) throws IOException { return gson.fromJson(fileReader, TypeToken.getParameterized(Map.class, keyType, valueType).getType()); } @Deprecated(forRemoval = true) public static Map loadToMap(String filename, Class keyType, Class valueType) throws IOException { try (InputStreamReader fileReader = new InputStreamReader(new FileInputStream(Utils.toFilePath(filename)), StandardCharsets.UTF_8)) { return loadToMap(fileReader, keyType, valueType); } } public static Map loadToMap(Path filename, Class keyType, Class valueType) throws IOException { try (var fileReader = Files.newBufferedReader(filename, StandardCharsets.UTF_8)) { return loadToMap(fileReader, keyType, valueType); } } /** * Safely JSON decodes a given string. * @param jsonData The JSON-encoded data. * @return JSON decoded data, or null if an exception occurred. */ public static T decode(String jsonData, Class classType) { try { return gson.fromJson(jsonData, classType); } catch (Exception ignored) { return null; } } public static T decode(String jsonData, Type type) { try { return gson.fromJson(jsonData, type); } catch (Exception ignored) { return null; } } }