diff options
Diffstat (limited to 'src/main/java/cc/polyfrost/oneconfig/config')
5 files changed, 161 insertions, 21 deletions
diff --git a/src/main/java/cc/polyfrost/oneconfig/config/annotations/VigilanceName.java b/src/main/java/cc/polyfrost/oneconfig/config/annotations/VigilanceName.java new file mode 100644 index 0000000..03e94af --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/config/annotations/VigilanceName.java @@ -0,0 +1,14 @@ +package cc.polyfrost.oneconfig.config.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface VigilanceName { + String name(); + String category(); + String subcategory(); +} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/data/Mod.java b/src/main/java/cc/polyfrost/oneconfig/config/data/Mod.java index da069c5..7849124 100644 --- a/src/main/java/cc/polyfrost/oneconfig/config/data/Mod.java +++ b/src/main/java/cc/polyfrost/oneconfig/config/data/Mod.java @@ -1,36 +1,55 @@ package cc.polyfrost.oneconfig.config.data; import cc.polyfrost.oneconfig.config.interfaces.Config; +import cc.polyfrost.oneconfig.config.migration.Migrator; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Objects; - public class Mod { public final String name; public final ModType modType; public final String modIcon; + public final Migrator migrator; public Config config; public final OptionPage defaultPage; public boolean isShortCut = false; /** - * @param name Friendly name of the mod - * @param modType Type of the mod (for example ModType.QOL) - * @param modIcon path to icon of the mod (png or svg format) + * @param name Friendly name of the mod + * @param modType Type of the mod (for example ModType.QOL) + * @param modIcon Path to icon of the mod (png or svg format) + * @param migrator Migrator class to port the old config */ - public Mod(String name, ModType modType, @Nullable String modIcon) { + public Mod(String name, ModType modType, @Nullable String modIcon, @Nullable Migrator migrator) { this.name = name; this.modType = modType; this.modIcon = modIcon; + this.migrator = migrator; this.defaultPage = new OptionPage(name, this); } /** * @param name Friendly name of the mod * @param modType Type of the mod (for example ModType.QOL) + * @param modIcon path to icon of the mod (png or svg format) + */ + public Mod(String name, ModType modType, @Nullable String modIcon) { + this(name, modType, modIcon, null); + } + + /** + * @param name Friendly name of the mod + * @param modType Type of the mod (for example ModType.QOL) + * @param migrator Migrator class to port the old config + */ + public Mod(String name, ModType modType, @Nullable Migrator migrator) { + this(name, modType, null, migrator); + } + + /** + * @param name Friendly name of the mod + * @param modType Type of the mod (for example ModType.QOL) */ public Mod(String name, ModType modType) { - this(name, modType, null); + this(name, modType, null, null); } } diff --git a/src/main/java/cc/polyfrost/oneconfig/config/interfaces/Config.java b/src/main/java/cc/polyfrost/oneconfig/config/interfaces/Config.java index 49d2049..a9d1d1e 100644 --- a/src/main/java/cc/polyfrost/oneconfig/config/interfaces/Config.java +++ b/src/main/java/cc/polyfrost/oneconfig/config/interfaces/Config.java @@ -4,6 +4,7 @@ import cc.polyfrost.oneconfig.config.annotations.ConfigPage; import cc.polyfrost.oneconfig.config.annotations.Option; import cc.polyfrost.oneconfig.config.core.ConfigCore; import cc.polyfrost.oneconfig.config.data.*; +import cc.polyfrost.oneconfig.config.migration.Migrator; import cc.polyfrost.oneconfig.config.profiles.Profiles; import cc.polyfrost.oneconfig.gui.OneConfigGui; import cc.polyfrost.oneconfig.gui.elements.config.*; @@ -26,6 +27,7 @@ public class Config { transient protected final Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).setPrettyPrinting().create(); transient public Mod mod; public final transient HashMap<String, BasicOption> optionNames = new HashMap<>(); + public transient boolean hasBeenInitialized = false; public boolean enabled = true; /** @@ -33,26 +35,21 @@ public class Config { * @param configFile file where config is stored */ public Config(Mod modData, String configFile) { - this(modData, configFile, true); - } - - /** - * @param modData information about the mod - * @param configFile file where config is stored - * @param initialize whether to load the config immediately or not - */ - public Config(Mod modData, String configFile, boolean initialize) { this.configFile = configFile; - if (initialize) init(modData); + init(modData); } public void init(Mod mod) { + boolean migrate = false; if (Profiles.getProfileFile(configFile).exists()) load(); + else if (!hasBeenInitialized && mod.migrator != null) migrate = true; else save(); mod.config = this; - generateOptionList(this, mod.defaultPage, mod); + generateOptionList(this, mod.defaultPage, mod, migrate); + if (migrate) save(); ConfigCore.oneConfigMods.add(mod); this.mod = mod; + hasBeenInitialized = true; } /** @@ -83,8 +80,9 @@ public class Config { * @param instance instance of target class * @param page page to add options too * @param mod data about the mod + * @param migrate whether the migrator should be run */ - protected void generateOptionList(Object instance, OptionPage page, Mod mod) { + protected void generateOptionList(Object instance, OptionPage page, Mod mod, boolean migrate) { Class<?> clazz = instance.getClass(); for (Field field : clazz.getDeclaredFields()) { String pagePrefix = page.equals(mod.defaultPage) ? "" : page.name + "."; @@ -103,7 +101,7 @@ public class Config { try { field.setAccessible(true); Object object = field.get(clazz); - generateOptionList(object, newPage, mod); + generateOptionList(object, newPage, mod, migrate); ConfigPageButton configPageButton = new ConfigPageButton(field, instance, option.name(), option.description(), newPage); switch (option.location()) { case TOP: @@ -124,6 +122,17 @@ public class Config { OptionCategory category = page.categories.get(option.category()); if (category.subcategories.size() == 0 || !category.subcategories.get(category.subcategories.size() - 1).getName().equals(option.subcategory())) category.subcategories.add(new OptionSubcategory(option.subcategory())); + if (migrate) { + try { + Object value = mod.migrator.getValue(field, option.name(), option.category(), option.subcategory()); + if (value != null) { + field.setAccessible(true); + field.set(instance, value); + } + } catch (Exception e) { + e.printStackTrace(); + } + } ArrayList<BasicOption> options = category.subcategories.get(category.subcategories.size() - 1).options; switch (option.type()) { case SWITCH: diff --git a/src/main/java/cc/polyfrost/oneconfig/config/migration/Migrator.java b/src/main/java/cc/polyfrost/oneconfig/config/migration/Migrator.java new file mode 100644 index 0000000..abfb2a0 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/config/migration/Migrator.java @@ -0,0 +1,14 @@ +package cc.polyfrost.oneconfig.config.migration; + +import java.lang.reflect.Field; + +public interface Migrator { + /** + * @param field The field of the option + * @param name The name of the option + * @param category The category of the option + * @param subcategory The subcategory of the option + * @return Value of the option, null if not found + */ + Object getValue(Field field, String name, String category, String subcategory); +} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/migration/VigilanceMigrator.java b/src/main/java/cc/polyfrost/oneconfig/config/migration/VigilanceMigrator.java new file mode 100644 index 0000000..5573a3e --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/config/migration/VigilanceMigrator.java @@ -0,0 +1,84 @@ +package cc.polyfrost.oneconfig.config.migration; + +import cc.polyfrost.oneconfig.config.annotations.VigilanceName; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class VigilanceMigrator implements Migrator { + private static final Pattern categoryPattern = Pattern.compile("\\[\"?(?<category>[^.\\[\\]\"]+)\"?\\.\"?(?<subcategory>[^.\\[\\]\"]+)\"?]"); + private static final Pattern booleanPattern = Pattern.compile("\"?(?<name>[^\\s\"]+)\"? = (?<value>true|false)"); + private static final Pattern numberPattern = Pattern.compile("\"?(?<name>[^\\s\"]+)\"? = (?<value>[\\d.]+)"); + private static final Pattern stringPattern = Pattern.compile("\"?(?<name>[^\\s\"]+)\"? = \"(?<value>.+)\""); + protected HashMap<String, HashMap<String, HashMap<String, Object>>> values = null; + protected final String filePath; + + public VigilanceMigrator(String filePath) { + this.filePath = filePath; + } + + @Override + public Object getValue(Field field, String name, String category, String subcategory) { + if (values == null) getOptions(); + if (field.isAnnotationPresent(VigilanceName.class)) { + VigilanceName annotation = field.getAnnotation(VigilanceName.class); + name = annotation.name(); + category = annotation.category(); + subcategory = annotation.subcategory(); + } + name = parse(name); + category = parse(category); + subcategory = parse(subcategory); + if (values.containsKey(category) && values.get(category).containsKey(subcategory) && values.get(category).get(subcategory).containsKey(name)) + return values.get(category).get(subcategory).get(name); + return null; + } + + protected String parse(String value) { + return value.toLowerCase().replace(" ", "_"); + } + + protected void getOptions() { + if (values == null) values = new HashMap<>(); + try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) { + String currentCategory = null; + String currentSubcategory = null; + String line; + while ((line = reader.readLine()) != null) { + Matcher categoryMatcher = categoryPattern.matcher(line); + if (categoryMatcher.find()) { + currentCategory = categoryMatcher.group("category"); + currentSubcategory = categoryMatcher.group("subcategory"); + if (!values.containsKey(currentCategory)) values.put(currentCategory, new HashMap<>()); + if (!values.get(currentCategory).containsKey(currentSubcategory)) + values.get(currentCategory).put(currentSubcategory, new HashMap<>()); + continue; + } + if (currentCategory == null) continue; + HashMap<String, Object> options = values.get(currentCategory).get(currentSubcategory); + Matcher booleanMatcher = booleanPattern.matcher(line); + if (booleanMatcher.find()) { + options.put(booleanMatcher.group("name"), Boolean.parseBoolean(booleanMatcher.group("value"))); + continue; + } + Matcher numberMatcher = numberPattern.matcher(line); + if (numberMatcher.find()) { + String value = numberMatcher.group("value"); + if (value.contains(".")) options.put(numberMatcher.group("name"), Float.parseFloat(value)); + else options.put(numberMatcher.group("name"), Integer.parseInt(value)); + continue; + } + Matcher stringMatcher = stringPattern.matcher(line); + if (stringMatcher.find()) { + options.put(stringMatcher.group("name"), stringMatcher.group("value")); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} |