package pm.j4.petroleum.util.config; import com.google.common.reflect.TypeToken; import com.google.gson.*; import java.io.*; import java.lang.reflect.Type; import java.util.*; import net.fabricmc.loader.api.FabricLoader; import pm.j4.petroleum.PetroleumMod; import pm.j4.petroleum.modules.bindings.BindingInfo; import pm.j4.petroleum.modules.menu.ModMenu; import pm.j4.petroleum.util.data.ButtonInformation; import pm.j4.petroleum.util.data.ModuleConfig; import pm.j4.petroleum.util.data.OptionSerializiable; import pm.j4.petroleum.util.module.ModuleBase; /** * The type Config manager. */ public class ConfigManager { /** * The constant GSON. */ public static final Gson GSON = new GsonBuilder() .registerTypeAdapter(GlobalConfig.class, SerializationHelper.getGlobalSerializer()) .registerTypeAdapter(GlobalConfig.class, SerializationHelper.getGlobalDeserializer()) .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).setPrettyPrinting().create(); /** * The constant config. */ private static ConfigHolder config; /** * Prepare config file. * * @param path the path * @param filename the filename * @return the file */ private static File prepareConfigFile(String path, String filename) { if (path != "") { File directory = new File(FabricLoader.getInstance().getConfigDir().toString(), path); if (!directory.exists()) directory.mkdir(); } return new File(FabricLoader.getInstance().getConfigDir().toString(), path + filename); } /** * Init config. */ public static void initConfig() { if (config != null) { return; } config = new ConfigHolder(); config.globalConfig = new DefaultConfig(); config.serverConfigs = new HashMap<>(); config = load("petroleum/", "petroleum.json", ConfigHolder.class); initModules(); } /** * Init modules. */ public static void initModules() { PetroleumMod.getActiveMods().forEach(module -> { ModuleConfig options = load("petroleum/modules/", module.getModuleName() + ".json", ModuleConfig.class); if (options != null && options.options != null) { options.options.forEach((key, option) -> { if (module.hasOption(option.key)) { module.setConfigOption(option.key, option.value); } }); } }); } /** * Load. * * @param the type parameter * @param path the path * @param filename the filename * @param tClass the t class * @return the t */ private static T load(String path, String filename, Class tClass) { File file = prepareConfigFile(path, filename); try { if (!file.exists()) { save(path, filename, tClass.newInstance()); } if (file.exists()) { BufferedReader reader = new BufferedReader(new FileReader(file)); T parsedConfig = null; try { parsedConfig = GSON.fromJson(reader, tClass); } catch (Exception e) { System.out.println("Couldn't parse config file"); e.printStackTrace(); } if (parsedConfig != null) { return parsedConfig; } } } catch (FileNotFoundException | InstantiationException | IllegalAccessException e) { System.out.println("Couldn't load configuration file at " + path); e.printStackTrace(); } return null; } /** * Deserialize element t. * * @param the type parameter * @param element the element * @param tClass the t class * @return the t */ public static T deserializeElement(JsonElement element, Class tClass) { return GSON.fromJson(element, tClass); } /** * Save. * * @param the type parameter * @param path the path * @param filename the filename * @param data the data */ private static void save(String path, String filename, T data) { File file = prepareConfigFile(path, filename); String json = GSON.toJson(data); try (FileWriter fileWriter = new FileWriter(file)) { fileWriter.write(json); } catch (IOException e) { System.out.println("Couldn't save configuration file at " + path); e.printStackTrace(); } } /** * Save module. * * @param b the b */ public static void saveModule(ModuleBase b) { ModuleConfig c = new ModuleConfig(); c.options = GlobalConfig.serializeModuleConfiguration(b); save("petroleum/modules/", b.getModuleName() + ".json", c); } /** * Save all modules. */ public static void saveAllModules() { List mods = PetroleumMod.getActiveMods(); mods.forEach(ConfigManager::saveModule); } /** * Save global config. */ public static void saveGlobalConfig() { save("petroleum/", "petroleum.json", config); } /** * Gets config. * * @return the config */ public static Optional getConfig() { if (config == null) { return Optional.empty(); } return Optional.of(config); } } /** * The type Serialization helper. */ class SerializationHelper { /** * The constant s. */ private static final JsonSerializer GLOBAL_CONFIG_JSON_SERIALIZER = (src, typeOfSrc, ctx) -> { JsonObject jsonConfig = new JsonObject(); JsonArray bindings = ctx.serialize(src.serializeBindings()).getAsJsonArray(); jsonConfig.add("bindings", bindings); JsonArray modules = ctx.serialize(src.enabledModules).getAsJsonArray(); jsonConfig.add("enabled_modules", modules); JsonObject tabCoordinates = new JsonObject(); ModMenu.getButtons().forEach((category, coordinates) -> { tabCoordinates.add(category, ctx.serialize(coordinates)); }); jsonConfig.add("button_coordinates", tabCoordinates); return jsonConfig; }; /** * The constant ds. */ private static final JsonDeserializer GLOBAL_CONFIG_JSON_DESERIALIZER = ((json, typeOfT, ctx) -> { JsonObject obj = json.getAsJsonObject(); List bindings = new ArrayList<>(); if (obj.has("bindings")) { obj.get("bindings").getAsJsonArray().forEach(b -> bindings.add(ctx.deserialize(b, BindingInfo.class))); } List modules = new ArrayList<>(); if (obj.has("enabled_modules")) { obj.get("enabled_modules").getAsJsonArray().forEach(m -> modules.add(m.getAsString())); } GlobalConfig cfg = new GlobalConfig(); Map> options; Type type = new TypeToken>>() { }.getType(); if (obj.has("module_configuration")) { options = ctx.deserialize(obj.get("module_configuration"), type); } else { options = new HashMap<>(); } if (obj.has("button_coordinates")) { obj.get("button_coordinates").getAsJsonObject().entrySet().forEach( value -> { cfg.setButton(value.getKey(), ctx.deserialize(value.getValue(), ButtonInformation.class)); } ); } PetroleumMod.getActiveMods().forEach(module -> { if (options.containsKey(module.getModuleName())) { cfg.deserializeModuleConfiguration(options.get(module.getModuleName()), module); } }); cfg.deserializeBindings(bindings); cfg.enabledModules = modules; return cfg; }); /** * Gets serializer. * * @return the serializer */ public static JsonSerializer getGlobalSerializer() { return GLOBAL_CONFIG_JSON_SERIALIZER; } /** * Gets deserializer. * * @return the deserializer */ public static JsonDeserializer getGlobalDeserializer() { return GLOBAL_CONFIG_JSON_DESERIALIZER; } }