package pm.j4.kerosene.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.kerosene.KeroseneMod; import pm.j4.kerosene.modules.bindings.BindingInfo; import pm.j4.kerosene.util.data.ModuleConfig; import pm.j4.kerosene.util.data.OptionSerializiable; import pm.j4.kerosene.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 Map configs = new HashMap<>(); /** * 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(String moduleName) { if (configs.containsKey(moduleName)) { return; } ConfigHolder config = new ConfigHolder(); config.globalConfig = new DefaultConfig(); config.serverConfigs = new HashMap<>(); config = load(moduleName + "/", moduleName +".json", ConfigHolder.class); initModules(moduleName); } /** * Init modules. */ public static void initModules(String moduleName) { KeroseneMod.getRegisteredMods().forEach(module -> { ModuleConfig options = load(moduleName + "/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(String modName, ModuleBase b) { ModuleConfig c = new ModuleConfig(); c.options = GlobalConfig.serializeModuleConfiguration(b); save(modName + "/modules/", b.getModuleName() + ".json", c); } /** * Save all modules. */ public static void saveAllModules() { List mods = KeroseneMod.getRegisteredMods(); mods.forEach((module) -> { ConfigManager.saveModule(module.getParent(), module); }); } /** * Save global config. */ public static void saveGlobalConfig(String modName) { if(configs.containsKey(modName)) { save(modName + "/", modName + ".json", configs.get(modName)); } } /** * Gets config. * * @return the config */ public static Optional getConfig(String modName) { if (configs.containsKey(modName)) { return Optional.of(configs.get(modName)); } return Optional.empty(); } } /** * 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); 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<>(); } KeroseneMod.getRegisteredMods().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; } }