package emu.grasscutter.utils; import com.google.gson.*; import com.google.gson.reflect.TypeToken; import emu.grasscutter.data.common.DynamicFloat; import emu.grasscutter.game.world.*; import emu.grasscutter.utils.JsonAdapters.*; import emu.grasscutter.utils.objects.*; import it.unimi.dsi.fastutil.ints.IntList; import java.io.*; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.nio.file.*; import java.util.*; public final class JsonUtils { static final Gson gson = new GsonBuilder() .setPrettyPrinting() .registerTypeAdapter(DynamicFloat.class, new DynamicFloatAdapter()) .registerTypeAdapter(DropType.class, new DropTypeAdapter()) .registerTypeAdapter(IntList.class, new IntListAdapter()) .registerTypeAdapter(Position.class, new PositionAdapter()) .registerTypeAdapter(GridPosition.class, new GridPositionAdapter()) .registerTypeAdapter(byte[].class, new ByteArrayAdapter()) .registerTypeAdapter(JObject.class, new JObject.Adapter()) .registerTypeAdapterFactory(new EnumTypeAdapterFactory()) .disableHtmlEscaping() .create(); /** * Converts the given object to a JsonElement. * * @param object The object to convert. * @return The JsonElement. */ public static JsonElement toJson(Object object) { return gson.toJsonTree(object); } /* * 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); } } public static Map loadToMap(Path filename, Class keyType, Type valueType) throws IOException { try (var fileReader = Files.newBufferedReader(filename, StandardCharsets.UTF_8)) { return gson.fromJson( fileReader, TypeToken.getParameterized(Map.class, keyType, valueType).getType()); } } /** * 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; } } }