From ab7256dff5d6d37488081ba7a01b36d3ee9ef563 Mon Sep 17 00:00:00 2001 From: DeDiamondPro <67508414+DeDiamondPro@users.noreply.github.com> Date: Sun, 5 Jun 2022 17:43:23 +0200 Subject: refactor (#36) * refactor * fix vig compat * fix nanovg thingy * e * finalize * gui utils package thingy --- .../java/cc/polyfrost/oneconfig/config/Config.java | 263 +++++++++++++++++++++ .../oneconfig/config/OneConfigConfig.java | 91 ------- .../config/compatibility/VigilanceConfig.java | 202 ---------------- .../config/compatibility/VigilantAccessor.java | 11 - .../compatibility/vigilance/VigilanceConfig.java | 202 ++++++++++++++++ .../compatibility/vigilance/VigilantAccessor.java | 11 + .../cc/polyfrost/oneconfig/config/data/Mod.java | 5 +- .../oneconfig/config/data/OptionCategory.java | 7 - .../oneconfig/config/data/OptionPage.java | 19 -- .../oneconfig/config/data/OptionSubcategory.java | 122 ---------- .../oneconfig/config/elements/BasicOption.java | 98 ++++++++ .../oneconfig/config/elements/OptionCategory.java | 7 + .../oneconfig/config/elements/OptionPage.java | 16 ++ .../config/elements/OptionSubcategory.java | 122 ++++++++++ .../oneconfig/config/interfaces/BasicOption.java | 98 -------- .../oneconfig/config/interfaces/Config.java | 259 -------------------- .../oneconfig/config/migration/Migrator.java | 14 -- .../config/migration/VigilanceMigrator.java | 84 ------- .../config/migration/vigilance/Migrator.java | 14 ++ .../migration/vigilance/VigilanceMigrator.java | 84 +++++++ .../oneconfig/config/profiles/Profiles.java | 4 +- 21 files changed, 822 insertions(+), 911 deletions(-) create mode 100644 src/main/java/cc/polyfrost/oneconfig/config/Config.java delete mode 100644 src/main/java/cc/polyfrost/oneconfig/config/OneConfigConfig.java delete mode 100644 src/main/java/cc/polyfrost/oneconfig/config/compatibility/VigilanceConfig.java delete mode 100644 src/main/java/cc/polyfrost/oneconfig/config/compatibility/VigilantAccessor.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/config/compatibility/vigilance/VigilanceConfig.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/config/compatibility/vigilance/VigilantAccessor.java delete mode 100644 src/main/java/cc/polyfrost/oneconfig/config/data/OptionCategory.java delete mode 100644 src/main/java/cc/polyfrost/oneconfig/config/data/OptionPage.java delete mode 100644 src/main/java/cc/polyfrost/oneconfig/config/data/OptionSubcategory.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/config/elements/BasicOption.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/config/elements/OptionCategory.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/config/elements/OptionPage.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/config/elements/OptionSubcategory.java delete mode 100644 src/main/java/cc/polyfrost/oneconfig/config/interfaces/BasicOption.java delete mode 100644 src/main/java/cc/polyfrost/oneconfig/config/interfaces/Config.java delete mode 100644 src/main/java/cc/polyfrost/oneconfig/config/migration/Migrator.java delete mode 100644 src/main/java/cc/polyfrost/oneconfig/config/migration/VigilanceMigrator.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/config/migration/vigilance/Migrator.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/config/migration/vigilance/VigilanceMigrator.java (limited to 'src/main/java/cc/polyfrost/oneconfig/config') diff --git a/src/main/java/cc/polyfrost/oneconfig/config/Config.java b/src/main/java/cc/polyfrost/oneconfig/config/Config.java new file mode 100644 index 0000000..d0d8acf --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/config/Config.java @@ -0,0 +1,263 @@ +package cc.polyfrost.oneconfig.config; + +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.elements.BasicOption; +import cc.polyfrost.oneconfig.config.elements.OptionCategory; +import cc.polyfrost.oneconfig.config.elements.OptionPage; +import cc.polyfrost.oneconfig.config.elements.OptionSubcategory; +import cc.polyfrost.oneconfig.config.profiles.Profiles; +import cc.polyfrost.oneconfig.gui.OneConfigGui; +import cc.polyfrost.oneconfig.gui.elements.config.*; +import cc.polyfrost.oneconfig.gui.pages.ModConfigPage; +import cc.polyfrost.oneconfig.hud.BasicHud; +import cc.polyfrost.oneconfig.hud.HudCore; +import cc.polyfrost.oneconfig.utils.gui.GuiUtils; +import com.google.gson.*; + +import java.io.*; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.*; +import java.util.function.Supplier; + +public class Config { + public final transient HashMap optionNames = new HashMap<>(); + transient protected final String configFile; + transient protected final Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).setPrettyPrinting().create(); + transient public Mod mod; + public transient boolean hasBeenInitialized = false; + public boolean enabled = true; + + /** + * @param modData information about the mod + * @param configFile file where config is stored + */ + public Config(Mod modData, String configFile) { + this.configFile = configFile; + 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, migrate); + if (migrate) save(); + ConfigCore.oneConfigMods.add(mod); + this.mod = mod; + hasBeenInitialized = true; + } + + /** + * Save current config to file + */ + public void save() { + try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(Profiles.getProfileFile(configFile).toPath()), StandardCharsets.UTF_8))) { + writer.write(gson.toJson(this)); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Load file and overwrite current values + */ + public void load() { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(Files.newInputStream(Profiles.getProfileFile(configFile).toPath()), StandardCharsets.UTF_8))) { + deserializePart(new JsonParser().parse(reader).getAsJsonObject(), this); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Generate the option list, for internal use only + * + * @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, boolean migrate) { + Class clazz = instance.getClass(); + for (Field field : clazz.getDeclaredFields()) { + String pagePrefix = page.equals(mod.defaultPage) ? "" : page.name + "."; + if (!field.isAnnotationPresent(Option.class) && !field.isAnnotationPresent(ConfigPage.class)) { + processCustomOption(field, page); + continue; + } else if (field.isAnnotationPresent(ConfigPage.class)) { + ConfigPage option = field.getAnnotation(ConfigPage.class); + if (!page.categories.containsKey(option.category())) + page.categories.put(option.category(), new OptionCategory()); + 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())); + OptionSubcategory subcategory = category.subcategories.get(category.subcategories.size() - 1); + OptionPage newPage = new OptionPage(option.name(), mod); + try { + field.setAccessible(true); + Object object = field.get(clazz); + generateOptionList(object, newPage, mod, migrate); + ConfigPageButton configPageButton = new ConfigPageButton(field, instance, option.name(), option.description(), newPage); + switch (option.location()) { + case TOP: + subcategory.topButtons.add(configPageButton); + break; + case BOTTOM: + subcategory.bottomButtons.add(configPageButton); + break; + } + optionNames.put(pagePrefix + field.getName(), configPageButton); + } catch (IllegalAccessException ignored) { + } + continue; + } + Option option = field.getAnnotation(Option.class); + if (!page.categories.containsKey(option.category())) + page.categories.put(option.category(), new OptionCategory()); + 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 options = category.subcategories.get(category.subcategories.size() - 1).options; + switch (option.type()) { + case SWITCH: + options.add(new ConfigSwitch(field, instance, option.name(), option.size())); + break; + case CHECKBOX: + options.add(new ConfigCheckbox(field, instance, option.name(), option.size())); + break; + case TEXT: + options.add(new ConfigTextBox(field, instance, option.name(), option.size(), option.placeholder(), option.secure(), option.multiLine())); + break; + case DUAL_OPTION: + options.add(new ConfigDualOption(field, instance, option.name(), option.size(), option.options())); + break; + case DROPDOWN: + options.add(new ConfigDropdown(field, instance, option.name(), option.size(), option.options())); + break; + case SLIDER: + options.add(new ConfigSlider(field, instance, option.name(), option.size(), option.min(), option.max(), option.step())); + break; + case INFO: + options.add(new ConfigInfo(field, instance, option.name(), option.size(), option.infoType())); + break; + case COLOR: + options.add(new ConfigColorElement(field, instance, option.name(), option.size())); + break; + case HEADER: + options.add(new ConfigHeader(field, instance, option.name(), option.size())); + break; + case BUTTON: + options.add(new ConfigButton(field, instance, option.name(), option.size(), option.buttonText())); + break; + case KEYBIND: + options.add(new ConfigKeyBind(field, instance, option.name(), option.size())); + break; + case HUD: + try { + field.setAccessible(true); + BasicHud hud = (BasicHud) field.get(instance); + HudCore.huds.add(hud); + options.add(new ConfigHeader(field, hud, option.name(), 1)); + options.add(new ConfigSwitch(hud.getClass().getField("enabled"), hud, "Enabled", 1)); + options.add(new ConfigCheckbox(hud.getClass().getField("rounded"), hud, "Rounded corners", 1)); + options.get(options.size() - 1).setDependency(() -> hud.enabled); + options.add(new ConfigCheckbox(hud.getClass().getField("border"), hud, "Outline/border", 1)); + options.get(options.size() - 1).setDependency(() -> hud.enabled); + options.add(new ConfigColorElement(hud.getClass().getField("bgColor"), hud, "Background color:", 1)); + options.get(options.size() - 1).setDependency(() -> hud.enabled); + options.add(new ConfigColorElement(hud.getClass().getField("borderColor"), hud, "Border color:", 1)); + options.get(options.size() - 1).setDependency(() -> hud.enabled && hud.border); + options.add(new ConfigSlider(hud.getClass().getField("cornerRadius"), hud, "Corner radius:", 2, 0, 10, 0)); + options.get(options.size() - 1).setDependency(() -> hud.enabled && hud.rounded); + options.add(new ConfigSlider(hud.getClass().getField("borderSize"), hud, "Border thickness:", 2, 0, 10, 0)); + options.get(options.size() - 1).setDependency(() -> hud.enabled && hud.border); + options.add(new ConfigSlider(hud.getClass().getField("paddingX"), hud, "X-Padding", 2, 0, 50, 0)); + options.get(options.size() - 1).setDependency(() -> hud.enabled); + options.add(new ConfigSlider(hud.getClass().getField("paddingY"), hud, "Y-Padding", 2, 0, 50, 0)); + options.get(options.size() - 1).setDependency(() -> hud.enabled); + } catch (IllegalAccessException | NoSuchFieldException e) { + e.printStackTrace(); + } + break; + } + if (!option.type().equals(OptionType.HUD)) + optionNames.put(pagePrefix + field.getName(), options.get(options.size() - 1)); + } + } + + /** + * Overwrite this method to add your own custom option types + * + * @param field target field + * @param page page to add options too + */ + protected void processCustomOption(Field field, OptionPage page) { + } + + /** + * Deserialize part of config and load values + * + * @param json json to deserialize + * @param instance instance of target class + */ + protected void deserializePart(JsonObject json, Object instance) { + Class clazz = instance.getClass(); + for (Map.Entry element : json.entrySet()) { + String name = element.getKey(); + JsonElement value = element.getValue(); + if (value.isJsonObject()) { + Optional> innerClass = Arrays.stream(clazz.getClasses()).filter(aClass -> aClass.getSimpleName().equals(name)).findFirst(); + if (innerClass.isPresent()) { + deserializePart(value.getAsJsonObject(), innerClass.get()); + continue; + } + } + try { + Field field = clazz.getField(name); + TypeAdapter adapter = gson.getAdapter(field.getType()); + Object object = adapter.fromJsonTree(value); + field.setAccessible(true); + field.set(instance, object); + } catch (Exception ignored) { + } + } + } + + /** + * Function to open the gui of this mod + */ + public void openGui() { + if (mod == null) return; + GuiUtils.displayScreen(new OneConfigGui(new ModConfigPage(mod.defaultPage))); + } + + /** + * Disable an option if a certain condition is not met + * + * @param option The name of the field, or if the field is in a page "pageName.fieldName" + * @param condition The condition that has to be met for the option to be enabled + */ + protected void addDependency(String option, Supplier condition) { + if (!optionNames.containsKey(option)) return; + optionNames.get(option).setDependency(condition); + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/OneConfigConfig.java b/src/main/java/cc/polyfrost/oneconfig/config/OneConfigConfig.java deleted file mode 100644 index b867bc0..0000000 --- a/src/main/java/cc/polyfrost/oneconfig/config/OneConfigConfig.java +++ /dev/null @@ -1,91 +0,0 @@ -package cc.polyfrost.oneconfig.config; - -import cc.polyfrost.oneconfig.config.core.OneColor; -import cc.polyfrost.oneconfig.config.data.Mod; -import cc.polyfrost.oneconfig.config.interfaces.Config; -import com.google.gson.JsonParser; - -import java.awt.*; -import java.io.*; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; - -public class OneConfigConfig extends Config { - - // the color library - public static final int TRANSPARENT = new Color(0, 0, 0, 0).getRGB(); // Transparent - public static final int BLACK = new Color(0, 0, 0, 255).getRGB(); // Black - public static final int GRAY_900 = new Color(13, 14, 15, 255).getRGB(); // Gray 900 - public static final int GRAY_900_80 = new Color(13, 14, 15, 204).getRGB(); // Gray 900 80% - public static final int GRAY_800 = new Color(21, 22, 23, 255).getRGB(); // Gray 800 - public static final int GRAY_800_95 = new Color(21, 22, 23, 242).getRGB(); - public static final int GRAY_700 = new Color(34, 35, 38, 255).getRGB(); // Gray 700 - public static final int GRAY_600 = new Color(42, 44, 48, 255).getRGB(); // Gray 600 - public static final int GRAY_500 = new Color(49, 51, 56, 255).getRGB(); // Gray 500 // button sidebar hover, button gray normal - public static final int GRAY_500_80 = new Color(49, 51, 56, 204).getRGB(); // Gray 500 80% // button sidebar pressed - public static final int GRAY_400 = new Color(55, 59, 69, 255).getRGB(); // Gray 400 - public static final int GRAY_300 = new Color(73, 79, 92, 255).getRGB(); // Gray 300 // button gray hover - public static final int GRAY_400_80 = new Color(55, 59, 69, 204).getRGB(); // Gray 400 80% // button gray pressed - public static final int PRIMARY_800 = new Color(13, 51, 128, 255).getRGB(); // Blue 800 - public static final int PRIMARY_700 = new Color(18, 71, 178, 255).getRGB(); // Blue 700 - public static final int PRIMARY_700_80 = new Color(18, 71, 178, 204).getRGB(); // Blue 700 80% - public static final int PRIMARY_600 = new Color(20, 82, 204, 255).getRGB(); // Blue 600 // button blue normal - public static final int PRIMARY_500 = new Color(25, 103, 255, 255).getRGB(); // Blue 500 // button blue hover - public static final int PRIMARY_400 = new Color(48, 129, 242, 255).getRGB(); - public static final int WHITE_50 = new Color(255, 255, 255, 127).getRGB(); // White 60% - public static final int WHITE_60 = new Color(255, 255, 255, 153).getRGB(); // White 60% - public static final int WHITE_80 = new Color(255, 255, 255, 204).getRGB(); // White 80% - public static final int WHITE_90 = new Color(255, 255, 255, 229).getRGB(); // White 90% - public static final int WHITE_95 = new Color(255, 255, 255, 242).getRGB(); // White 90% - public static final int WHITE = new Color(255, 255, 255, 255).getRGB(); // White 100% - public static final int SUCCESS_600 = new Color(3, 152, 85).getRGB(); - public static final int SUCCESS_700 = new Color(2, 121, 72).getRGB(); - public static final int WARNING_500 = new Color(247, 144, 9).getRGB(); - public static final int WARNING_600 = new Color(220, 104, 3).getRGB(); - public static final int ERROR_600_80 = new Color(217, 32, 32, 204).getRGB(); - public static final int ERROR_600 = new Color(217, 32, 32).getRGB(); - public static final int ERROR_700 = new Color(180, 24, 24).getRGB(); // Red 700 - public static final int ERROR_800 = new Color(145, 24, 24).getRGB(); // Red 800 - public static final int ERROR_800_80 = new Color(145, 24, 24, 204).getRGB(); // Red 800 - public static final int ERROR_300 = new Color(253, 155, 155).getRGB(); - public static final int ERROR_300_80 = new Color(253, 155, 155, 204).getRGB(); - public static String currentProfile = "Default Profile"; - public static ArrayList favoriteMods = new ArrayList<>(); - public static ArrayList favoriteColors = new ArrayList<>(); - public static ArrayList recentColors = new ArrayList<>(); - public static boolean ROUNDED_CORNERS = true; - public static float CORNER_RADIUS_WIN = 20f; - public static float CORNER_RADIUS = 12f; - - public static boolean allShowShortCut = false; - - public OneConfigConfig() { - super(null, "OneConfig.json"); - } - - @Override - public void init(Mod mod) { - if (new File("OneConfig/" + configFile).exists()) load(); - else save(); - } - - @Override - public void save() { - try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(Paths.get("OneConfig/" + configFile)), StandardCharsets.UTF_8))) { - writer.write(gson.toJson(this)); - } catch (IOException e) { - e.printStackTrace(); - } - } - - @Override - public void load() { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(Files.newInputStream(Paths.get("OneConfig/" + configFile)), StandardCharsets.UTF_8))) { - deserializePart(new JsonParser().parse(reader).getAsJsonObject(), this); - } catch (IOException e) { - e.printStackTrace(); - } - } -} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/compatibility/VigilanceConfig.java b/src/main/java/cc/polyfrost/oneconfig/config/compatibility/VigilanceConfig.java deleted file mode 100644 index fa4f058..0000000 --- a/src/main/java/cc/polyfrost/oneconfig/config/compatibility/VigilanceConfig.java +++ /dev/null @@ -1,202 +0,0 @@ -package cc.polyfrost.oneconfig.config.compatibility; - -import cc.polyfrost.oneconfig.config.core.ConfigCore; -import cc.polyfrost.oneconfig.config.core.OneColor; -import cc.polyfrost.oneconfig.config.data.Mod; -import cc.polyfrost.oneconfig.config.data.OptionCategory; -import cc.polyfrost.oneconfig.config.data.OptionPage; -import cc.polyfrost.oneconfig.config.data.OptionSubcategory; -import cc.polyfrost.oneconfig.config.interfaces.BasicOption; -import cc.polyfrost.oneconfig.config.interfaces.Config; -import cc.polyfrost.oneconfig.gui.elements.config.*; -import gg.essential.vigilance.Vigilant; -import gg.essential.vigilance.data.*; -import kotlin.reflect.KMutableProperty0; -import kotlin.reflect.jvm.ReflectJvmMapping; -import net.minecraft.client.resources.I18n; - -import java.awt.*; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Objects; - -/** - * This class is used to convert the Vigilance config to the new config system. - * It is not meant to be used outside the config system. - */ -public class VigilanceConfig extends Config { - public final Vigilant vigilant; - - public VigilanceConfig(Mod modData, String configFile, Vigilant vigilant) { - super(modData, configFile); - this.vigilant = vigilant; - init(modData); - } - - @Override - public void init(Mod mod) { - if (vigilant != null) { - mod.config = this; - generateOptionsList(mod.defaultPage); - ConfigCore.oneConfigMods.add(mod); - this.mod = mod; - } - } - - @Override - public void save() { - vigilant.markDirty(); - vigilant.writeData(); - } - - @Override - public void load() { - //no-op - } - - private void generateOptionsList(OptionPage page) { - for (PropertyData option : ((VigilantAccessor) vigilant).getPropertyCollector().getProperties()) { - PropertyAttributesExt attributes = option.getAttributesExt(); - if (attributes.getHidden()) continue; - if (!page.categories.containsKey(getCategory(attributes))) - page.categories.put(getCategory(attributes), new OptionCategory()); - OptionCategory category = page.categories.get(getCategory(attributes)); - if (category.subcategories.size() == 0 || !category.subcategories.get(category.subcategories.size() - 1).getName().equals(getSubcategory(attributes))) - category.subcategories.add(new OptionSubcategory(getSubcategory(attributes))); - ArrayList options = category.subcategories.get(category.subcategories.size() - 1).options; - switch (attributes.getType()) { - case SWITCH: - options.add(new ConfigSwitch(getFieldOfProperty(option), option.getInstance(), getName(attributes), 2)); - break; - case CHECKBOX: - options.add(new ConfigCheckbox(getFieldOfProperty(option), option.getInstance(), getName(attributes), 2)); - break; - case PARAGRAPH: - case TEXT: - options.add(new ConfigTextBox(getFieldOfProperty(option), option.getInstance(), getName(attributes), 2, attributes.getPlaceholder(), attributes.getProtected(), attributes.getType() == PropertyType.PARAGRAPH)); - break; - case SELECTOR: - options.add(new ConfigDropdown(getFieldOfProperty(option), option.getInstance(), getName(attributes), 2, attributes.getOptions().toArray(new String[0]))); - break; - case PERCENT_SLIDER: - options.add(new ConfigSlider(getFieldOfProperty(option), option.getInstance(), getName(attributes), 2, 0, 1, 0)); - break; - case DECIMAL_SLIDER: - options.add(new ConfigSlider(getFieldOfProperty(option), option.getInstance(), getName(attributes), 2, attributes.getMinF(), attributes.getMaxF(), 0)); - break; - case SLIDER: - options.add(new ConfigSlider(getFieldOfProperty(option), option.getInstance(), getName(attributes), 2, attributes.getMin(), attributes.getMax(), 0)); - break; - case COLOR: - options.add(new CompatConfigColorElement(getFieldOfProperty(option), option.getInstance(), getName(attributes), 2)); - break; - case BUTTON: - options.add(new ConfigButton(() -> ((CallablePropertyValue) option.getValue()).invoke(option.getInstance()), option.getInstance(), getName(attributes), 2, attributes.getPlaceholder().isEmpty() ? "Activate" : attributes.getPlaceholder())); - break; - } - if (attributes.getType() == PropertyType.SWITCH || attributes.getType() == PropertyType.CHECKBOX) { - optionNames.put(PropertyKt.fullPropertyPath(option.getAttributesExt()), options.get(options.size() - 1)); - } - } - } - - private Field getFieldOfProperty(PropertyData data) { - if (data.getValue() instanceof FieldBackedPropertyValue) { - FieldBackedPropertyValue fieldBackedPropertyValue = (FieldBackedPropertyValue) data.getValue(); - try { - Field field = fieldBackedPropertyValue.getClass().getDeclaredField("field"); - field.setAccessible(true); - return (Field) field.get(fieldBackedPropertyValue); - } catch (IllegalAccessException | NoSuchFieldException e) { - throw new RuntimeException(e); - } - } else if (data.getValue() instanceof ValueBackedPropertyValue) { - ValueBackedPropertyValue valueBackedPropertyValue = (ValueBackedPropertyValue) data.getValue(); - try { - Field field = valueBackedPropertyValue.getClass().getDeclaredField("obj"); - field.setAccessible(true); - return (Field) field.get(valueBackedPropertyValue); - } catch (IllegalAccessException | NoSuchFieldException e) { - throw new RuntimeException(e); - } - } else if (data.getValue() instanceof KPropertyBackedPropertyValue) { - KPropertyBackedPropertyValue kPropertyBackedPropertyValue = (KPropertyBackedPropertyValue) data.getValue(); - try { - Field field = kPropertyBackedPropertyValue.getClass().getDeclaredField("property"); - field.setAccessible(true); - KMutableProperty0 property = (KMutableProperty0) field.get(kPropertyBackedPropertyValue); - return ReflectJvmMapping.getJavaField(property); - } catch (IllegalAccessException | NoSuchFieldException e) { - throw new RuntimeException(e); - } - } else throw new RuntimeException("Unknown property value type: " + data.getValue().getClass()); - } - - private String getName(PropertyAttributesExt ext) { - try { - PropertyAttributesExt.class.getDeclaredField("i18nName").setAccessible(true); - return I18n.format((String) PropertyAttributesExt.class.getDeclaredField("i18nName").get(ext)); - } catch (IllegalAccessException | NoSuchFieldException e) { - return ext.getName(); - } - } - - private String getCategory(PropertyAttributesExt ext) { - try { - PropertyAttributesExt.class.getDeclaredField("i18nCategory").setAccessible(true); - return I18n.format((String) PropertyAttributesExt.class.getDeclaredField("i18nCategory").get(ext)); - } catch (IllegalAccessException | NoSuchFieldException e) { - return ext.getCategory(); - } - } - - private String getSubcategory(PropertyAttributesExt ext) { - try { - PropertyAttributesExt.class.getDeclaredField("i18nSubcategory").setAccessible(true); - return I18n.format((String) PropertyAttributesExt.class.getDeclaredField("i18nSubcategory").get(ext)); - } catch (IllegalAccessException | NoSuchFieldException e) { - return ext.getSubcategory(); - } - } - - @SuppressWarnings("unused") - public void addDependency(PropertyData property, PropertyData dependency) { - BasicOption option = optionNames.get(PropertyKt.fullPropertyPath(property.getAttributesExt())); - if (option != null) { - option.setDependency(() -> Objects.equals(dependency.getValue().getValue(vigilant), true)); - } - } - - private static class CompatConfigColorElement extends ConfigColorElement { - private final Field color; - private Color prevColor = null; - private OneColor cachedColor = null; - - public CompatConfigColorElement(Field color, Vigilant parent, String name, int size) { - super(null, parent, name, size); - this.color = color; - } - - @Override - protected Object get() throws IllegalAccessException { - Color currentColor = (Color) color.get(parent); - if (cachedColor == null || prevColor != color.get(parent)) { - cachedColor = new OneColor(currentColor); - } - prevColor = currentColor; - return cachedColor; - } - - @Override - protected void setColor(OneColor color) { - if (cachedColor != color) { - Color newColor = new Color(color.getRGB(), true); - try { - this.color.set(parent, newColor); - } catch (IllegalAccessException ignored) { - - } - } - } - } -} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/compatibility/VigilantAccessor.java b/src/main/java/cc/polyfrost/oneconfig/config/compatibility/VigilantAccessor.java deleted file mode 100644 index ca2b1da..0000000 --- a/src/main/java/cc/polyfrost/oneconfig/config/compatibility/VigilantAccessor.java +++ /dev/null @@ -1,11 +0,0 @@ -package cc.polyfrost.oneconfig.config.compatibility; - -import gg.essential.vigilance.data.PropertyCollector; - -/** - * Interface for accessing the {@link PropertyCollector} in a Vigilant config. - *

Not recommended for non-internal OneConfig usage, as Systemless will get really angry at us

- */ -public interface VigilantAccessor { - PropertyCollector getPropertyCollector(); -} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/compatibility/vigilance/VigilanceConfig.java b/src/main/java/cc/polyfrost/oneconfig/config/compatibility/vigilance/VigilanceConfig.java new file mode 100644 index 0000000..cfa717f --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/config/compatibility/vigilance/VigilanceConfig.java @@ -0,0 +1,202 @@ +package cc.polyfrost.oneconfig.config.compatibility.vigilance; + +import cc.polyfrost.oneconfig.config.core.ConfigCore; +import cc.polyfrost.oneconfig.config.core.OneColor; +import cc.polyfrost.oneconfig.config.data.Mod; +import cc.polyfrost.oneconfig.config.elements.OptionCategory; +import cc.polyfrost.oneconfig.config.elements.OptionPage; +import cc.polyfrost.oneconfig.config.elements.OptionSubcategory; +import cc.polyfrost.oneconfig.config.elements.BasicOption; +import cc.polyfrost.oneconfig.config.Config; +import cc.polyfrost.oneconfig.gui.elements.config.*; +import gg.essential.vigilance.Vigilant; +import gg.essential.vigilance.data.*; +import kotlin.reflect.KMutableProperty0; +import kotlin.reflect.jvm.ReflectJvmMapping; +import net.minecraft.client.resources.I18n; + +import java.awt.*; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Objects; + +/** + * This class is used to convert the Vigilance config to the new config system. + * It is not meant to be used outside the config system. + */ +public class VigilanceConfig extends Config { + public final Vigilant vigilant; + + public VigilanceConfig(Mod modData, String configFile, Vigilant vigilant) { + super(modData, configFile); + this.vigilant = vigilant; + init(modData); + } + + @Override + public void init(Mod mod) { + if (vigilant != null) { + mod.config = this; + generateOptionsList(mod.defaultPage); + ConfigCore.oneConfigMods.add(mod); + this.mod = mod; + } + } + + @Override + public void save() { + vigilant.markDirty(); + vigilant.writeData(); + } + + @Override + public void load() { + //no-op + } + + private void generateOptionsList(OptionPage page) { + for (PropertyData option : ((VigilantAccessor) vigilant).getPropertyCollector().getProperties()) { + PropertyAttributesExt attributes = option.getAttributesExt(); + if (attributes.getHidden()) continue; + if (!page.categories.containsKey(getCategory(attributes))) + page.categories.put(getCategory(attributes), new OptionCategory()); + OptionCategory category = page.categories.get(getCategory(attributes)); + if (category.subcategories.size() == 0 || !category.subcategories.get(category.subcategories.size() - 1).getName().equals(getSubcategory(attributes))) + category.subcategories.add(new OptionSubcategory(getSubcategory(attributes))); + ArrayList options = category.subcategories.get(category.subcategories.size() - 1).options; + switch (attributes.getType()) { + case SWITCH: + options.add(new ConfigSwitch(getFieldOfProperty(option), option.getInstance(), getName(attributes), 2)); + break; + case CHECKBOX: + options.add(new ConfigCheckbox(getFieldOfProperty(option), option.getInstance(), getName(attributes), 2)); + break; + case PARAGRAPH: + case TEXT: + options.add(new ConfigTextBox(getFieldOfProperty(option), option.getInstance(), getName(attributes), 2, attributes.getPlaceholder(), attributes.getProtected(), attributes.getType() == PropertyType.PARAGRAPH)); + break; + case SELECTOR: + options.add(new ConfigDropdown(getFieldOfProperty(option), option.getInstance(), getName(attributes), 2, attributes.getOptions().toArray(new String[0]))); + break; + case PERCENT_SLIDER: + options.add(new ConfigSlider(getFieldOfProperty(option), option.getInstance(), getName(attributes), 2, 0, 1, 0)); + break; + case DECIMAL_SLIDER: + options.add(new ConfigSlider(getFieldOfProperty(option), option.getInstance(), getName(attributes), 2, attributes.getMinF(), attributes.getMaxF(), 0)); + break; + case SLIDER: + options.add(new ConfigSlider(getFieldOfProperty(option), option.getInstance(), getName(attributes), 2, attributes.getMin(), attributes.getMax(), 0)); + break; + case COLOR: + options.add(new CompatConfigColorElement(getFieldOfProperty(option), option.getInstance(), getName(attributes), 2)); + break; + case BUTTON: + options.add(new ConfigButton(() -> ((CallablePropertyValue) option.getValue()).invoke(option.getInstance()), option.getInstance(), getName(attributes), 2, attributes.getPlaceholder().isEmpty() ? "Activate" : attributes.getPlaceholder())); + break; + } + if (attributes.getType() == PropertyType.SWITCH || attributes.getType() == PropertyType.CHECKBOX) { + optionNames.put(PropertyKt.fullPropertyPath(option.getAttributesExt()), options.get(options.size() - 1)); + } + } + } + + private Field getFieldOfProperty(PropertyData data) { + if (data.getValue() instanceof FieldBackedPropertyValue) { + FieldBackedPropertyValue fieldBackedPropertyValue = (FieldBackedPropertyValue) data.getValue(); + try { + Field field = fieldBackedPropertyValue.getClass().getDeclaredField("field"); + field.setAccessible(true); + return (Field) field.get(fieldBackedPropertyValue); + } catch (IllegalAccessException | NoSuchFieldException e) { + throw new RuntimeException(e); + } + } else if (data.getValue() instanceof ValueBackedPropertyValue) { + ValueBackedPropertyValue valueBackedPropertyValue = (ValueBackedPropertyValue) data.getValue(); + try { + Field field = valueBackedPropertyValue.getClass().getDeclaredField("obj"); + field.setAccessible(true); + return (Field) field.get(valueBackedPropertyValue); + } catch (IllegalAccessException | NoSuchFieldException e) { + throw new RuntimeException(e); + } + } else if (data.getValue() instanceof KPropertyBackedPropertyValue) { + KPropertyBackedPropertyValue kPropertyBackedPropertyValue = (KPropertyBackedPropertyValue) data.getValue(); + try { + Field field = kPropertyBackedPropertyValue.getClass().getDeclaredField("property"); + field.setAccessible(true); + KMutableProperty0 property = (KMutableProperty0) field.get(kPropertyBackedPropertyValue); + return ReflectJvmMapping.getJavaField(property); + } catch (IllegalAccessException | NoSuchFieldException e) { + throw new RuntimeException(e); + } + } else throw new RuntimeException("Unknown property value type: " + data.getValue().getClass()); + } + + private String getName(PropertyAttributesExt ext) { + try { + PropertyAttributesExt.class.getDeclaredField("i18nName").setAccessible(true); + return I18n.format((String) PropertyAttributesExt.class.getDeclaredField("i18nName").get(ext)); + } catch (IllegalAccessException | NoSuchFieldException e) { + return ext.getName(); + } + } + + private String getCategory(PropertyAttributesExt ext) { + try { + PropertyAttributesExt.class.getDeclaredField("i18nCategory").setAccessible(true); + return I18n.format((String) PropertyAttributesExt.class.getDeclaredField("i18nCategory").get(ext)); + } catch (IllegalAccessException | NoSuchFieldException e) { + return ext.getCategory(); + } + } + + private String getSubcategory(PropertyAttributesExt ext) { + try { + PropertyAttributesExt.class.getDeclaredField("i18nSubcategory").setAccessible(true); + return I18n.format((String) PropertyAttributesExt.class.getDeclaredField("i18nSubcategory").get(ext)); + } catch (IllegalAccessException | NoSuchFieldException e) { + return ext.getSubcategory(); + } + } + + @SuppressWarnings("unused") + public void addDependency(PropertyData property, PropertyData dependency) { + BasicOption option = optionNames.get(PropertyKt.fullPropertyPath(property.getAttributesExt())); + if (option != null) { + option.setDependency(() -> Objects.equals(dependency.getValue().getValue(vigilant), true)); + } + } + + private static class CompatConfigColorElement extends ConfigColorElement { + private final Field color; + private Color prevColor = null; + private OneColor cachedColor = null; + + public CompatConfigColorElement(Field color, Vigilant parent, String name, int size) { + super(null, parent, name, size); + this.color = color; + } + + @Override + protected Object get() throws IllegalAccessException { + Color currentColor = (Color) color.get(parent); + if (cachedColor == null || prevColor != color.get(parent)) { + cachedColor = new OneColor(currentColor); + } + prevColor = currentColor; + return cachedColor; + } + + @Override + protected void setColor(OneColor color) { + if (cachedColor != color) { + Color newColor = new Color(color.getRGB(), true); + try { + this.color.set(parent, newColor); + } catch (IllegalAccessException ignored) { + + } + } + } + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/compatibility/vigilance/VigilantAccessor.java b/src/main/java/cc/polyfrost/oneconfig/config/compatibility/vigilance/VigilantAccessor.java new file mode 100644 index 0000000..c449bd9 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/config/compatibility/vigilance/VigilantAccessor.java @@ -0,0 +1,11 @@ +package cc.polyfrost.oneconfig.config.compatibility.vigilance; + +import gg.essential.vigilance.data.PropertyCollector; + +/** + * Interface for accessing the {@link PropertyCollector} in a Vigilant config. + *

Not recommended for non-internal OneConfig usage, as Systemless will get really angry at us

+ */ +public interface VigilantAccessor { + PropertyCollector getPropertyCollector(); +} 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 241dca7..090d1f8 100644 --- a/src/main/java/cc/polyfrost/oneconfig/config/data/Mod.java +++ b/src/main/java/cc/polyfrost/oneconfig/config/data/Mod.java @@ -1,7 +1,8 @@ package cc.polyfrost.oneconfig.config.data; -import cc.polyfrost.oneconfig.config.interfaces.Config; -import cc.polyfrost.oneconfig.config.migration.Migrator; +import cc.polyfrost.oneconfig.config.Config; +import cc.polyfrost.oneconfig.config.elements.OptionPage; +import cc.polyfrost.oneconfig.config.migration.vigilance.Migrator; import org.jetbrains.annotations.Nullable; public class Mod { diff --git a/src/main/java/cc/polyfrost/oneconfig/config/data/OptionCategory.java b/src/main/java/cc/polyfrost/oneconfig/config/data/OptionCategory.java deleted file mode 100644 index 76b2b34..0000000 --- a/src/main/java/cc/polyfrost/oneconfig/config/data/OptionCategory.java +++ /dev/null @@ -1,7 +0,0 @@ -package cc.polyfrost.oneconfig.config.data; - -import java.util.ArrayList; - -public class OptionCategory { - public final ArrayList subcategories = new ArrayList<>(); -} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/data/OptionPage.java b/src/main/java/cc/polyfrost/oneconfig/config/data/OptionPage.java deleted file mode 100644 index 32a07b9..0000000 --- a/src/main/java/cc/polyfrost/oneconfig/config/data/OptionPage.java +++ /dev/null @@ -1,19 +0,0 @@ -package cc.polyfrost.oneconfig.config.data; - -import java.util.LinkedHashMap; - -public class OptionPage { - public final String name; - public final Mod mod; - /** - * Depth 1 = categories - * Depth 2 = subcategories - * Depth 3 = list of options - */ - public final LinkedHashMap categories = new LinkedHashMap<>(); - - public OptionPage(String name, Mod mod) { - this.name = name; - this.mod = mod; - } -} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/data/OptionSubcategory.java b/src/main/java/cc/polyfrost/oneconfig/config/data/OptionSubcategory.java deleted file mode 100644 index e69e077..0000000 --- a/src/main/java/cc/polyfrost/oneconfig/config/data/OptionSubcategory.java +++ /dev/null @@ -1,122 +0,0 @@ -package cc.polyfrost.oneconfig.config.data; - -import cc.polyfrost.oneconfig.config.OneConfigConfig; -import cc.polyfrost.oneconfig.config.interfaces.BasicOption; -import cc.polyfrost.oneconfig.gui.OneConfigGui; -import cc.polyfrost.oneconfig.gui.elements.config.ConfigPageButton; -import cc.polyfrost.oneconfig.lwjgl.RenderManager; -import cc.polyfrost.oneconfig.lwjgl.font.Fonts; - -import java.util.ArrayList; - -public class OptionSubcategory { - private final String name; - public ArrayList options = new ArrayList<>(); - public ArrayList topButtons = new ArrayList<>(); - public ArrayList bottomButtons = new ArrayList<>(); - private ArrayList filteredOptions = new ArrayList<>(); - private int drawLastY; - - public OptionSubcategory(String name) { - this.name = name; - } - - public int draw(long vg, int x, int y) { - String filter = OneConfigGui.INSTANCE == null ? "" : OneConfigGui.INSTANCE.getSearchValue().toLowerCase().trim(); - filteredOptions = new ArrayList<>(options); - ArrayList filteredTop = new ArrayList<>(topButtons); - ArrayList filteredBottom = new ArrayList<>(bottomButtons); - if (!filter.equals("") && !name.toLowerCase().contains(filter)) { - filteredOptions.clear(); - filteredTop.clear(); - filteredBottom.clear(); - for (BasicOption option : options) { - if (option.getName().toLowerCase().contains(filter)) filteredOptions.add(option); - } - for (ConfigPageButton page : topButtons) { - if (page.getName().toLowerCase().contains(filter) || page.description.toLowerCase().contains(filter)) - filteredTop.add(page); - } - for (ConfigPageButton page : bottomButtons) { - if (page.getName().toLowerCase().contains(filter) || page.description.toLowerCase().contains(filter)) - filteredBottom.add(page); - } - } - if (filteredOptions.size() == 0 && filteredTop.size() == 0 && filteredBottom.size() == 0) return 0; - int optionY = y; - if (!name.equals("")) { - RenderManager.drawText(vg, name, x, y + 12, OneConfigConfig.WHITE_90, 24, Fonts.MEDIUM); - optionY += 36; - } - - for (ConfigPageButton page : filteredTop) { - page.draw(vg, x, optionY); - optionY += page.getHeight() + 16; - } - - if (filteredOptions.size() > 0) { - int backgroundSize = 16; - for (int i = 0; i < filteredOptions.size(); i++) { - BasicOption option = filteredOptions.get(i); - if (i + 1 < filteredOptions.size()) { - BasicOption nextOption = filteredOptions.get(i + 1); - if (option.size == 1 && option.hasHalfSize() && nextOption.size == 1 && nextOption.hasHalfSize()) { - backgroundSize += Math.max(option.getHeight(), nextOption.getHeight()) + 16; - i++; - continue; - } - } - backgroundSize += option.getHeight() + 16; - } - RenderManager.drawRoundedRect(vg, x - 16, optionY, 1024, backgroundSize, OneConfigConfig.GRAY_900, 20); - optionY += 16; - } - - drawLastY = optionY; - if (filteredOptions.size() > 0) { - for (int i = 0; i < filteredOptions.size(); i++) { - BasicOption option = filteredOptions.get(i); - option.draw(vg, x, optionY); - if (i + 1 < filteredOptions.size()) { - BasicOption nextOption = filteredOptions.get(i + 1); - if (option.size == 1 && option.hasHalfSize() && nextOption.size == 1 && nextOption.hasHalfSize()) { - nextOption.draw(vg, x + 512, optionY); - optionY += Math.max(option.getHeight(), nextOption.getHeight()) + 16; - i++; - continue; - } - } - optionY += option.getHeight() + 16; - } - optionY += 16; - } - - for (ConfigPageButton page : filteredBottom) { - page.draw(vg, x, optionY); - optionY += page.getHeight() + 16; - } - - return optionY - y; - } - - public void drawLast(long vg, int x) { - for (int i = 0; i < filteredOptions.size(); i++) { - BasicOption option = filteredOptions.get(i); - option.drawLast(vg, x, drawLastY); - if (i + 1 < filteredOptions.size()) { - BasicOption nextOption = filteredOptions.get(i + 1); - if (option.size == 1 && option.hasHalfSize() && nextOption.size == 1 && nextOption.hasHalfSize()) { - nextOption.drawLast(vg, x + 512, drawLastY); - drawLastY += Math.max(option.getHeight(), nextOption.getHeight()) + 16; - i++; - continue; - } - } - drawLastY += option.getHeight() + 16; - } - } - - public String getName() { - return name; - } -} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/elements/BasicOption.java b/src/main/java/cc/polyfrost/oneconfig/config/elements/BasicOption.java new file mode 100644 index 0000000..d4efeaa --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/config/elements/BasicOption.java @@ -0,0 +1,98 @@ +package cc.polyfrost.oneconfig.config.elements; + +import java.lang.reflect.Field; +import java.util.function.Supplier; + +@SuppressWarnings({"unused"}) +public abstract class BasicOption { + public final int size; + protected final Field field; + protected final String name; + protected final Object parent; + private Supplier dependency; + + /** + * Initialize option + * + * @param field variable attached to option (null for category) + * @param parent the parent object of the field, used for getting and setting the variable + * @param name name of option + * @param size size of option, 0 for single column, 1 for double. + */ + public BasicOption(Field field, Object parent, String name, int size) { + this.field = field; + this.parent = parent; + this.name = name; + this.size = size; + if (field != null) field.setAccessible(true); + } + + /** + * @param object Java object to set the variable to + */ + protected void set(Object object) throws IllegalAccessException { + if (field == null) return; + field.set(parent, object); + } + + /** + * @return value of variable as Java object + */ + protected Object get() throws IllegalAccessException { + if (field == null) return null; + return field.get(parent); + } + + /** + * @return height of option to align other options accordingly + */ + public abstract int getHeight(); + + /** + * Function that gets called when drawing option + * + * @param vg NanoVG context + * @param x x position + * @param y y position + */ + public abstract void draw(long vg, int x, int y); + + /** + * Function that gets called last drawing option, + * should be used for things that draw above other options + * + * @param vg NanoVG context + * @param x x position + * @param y y position + */ + public void drawLast(long vg, int x, int y) { + } + + /** + * Function that gets called when a key is typed + * + * @param key char that has been typed + * @param keyCode code of key + */ + public void keyTyped(char key, int keyCode) { + } + + /** + * @return If the component has an option to render at half size + */ + public boolean hasHalfSize() { + return true; + } + + public String getName() { + return name; + } + + public void setDependency(Supplier supplier) { + this.dependency = supplier; + } + + protected boolean isEnabled() { + return dependency == null || dependency.get(); + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/elements/OptionCategory.java b/src/main/java/cc/polyfrost/oneconfig/config/elements/OptionCategory.java new file mode 100644 index 0000000..4a37bfc --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/config/elements/OptionCategory.java @@ -0,0 +1,7 @@ +package cc.polyfrost.oneconfig.config.elements; + +import java.util.ArrayList; + +public class OptionCategory { + public final ArrayList subcategories = new ArrayList<>(); +} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/elements/OptionPage.java b/src/main/java/cc/polyfrost/oneconfig/config/elements/OptionPage.java new file mode 100644 index 0000000..5eaac8b --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/config/elements/OptionPage.java @@ -0,0 +1,16 @@ +package cc.polyfrost.oneconfig.config.elements; + +import cc.polyfrost.oneconfig.config.data.Mod; + +import java.util.LinkedHashMap; + +public class OptionPage { + public final String name; + public final Mod mod; + public final LinkedHashMap categories = new LinkedHashMap<>(); + + public OptionPage(String name, Mod mod) { + this.name = name; + this.mod = mod; + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/elements/OptionSubcategory.java b/src/main/java/cc/polyfrost/oneconfig/config/elements/OptionSubcategory.java new file mode 100644 index 0000000..ff1d770 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/config/elements/OptionSubcategory.java @@ -0,0 +1,122 @@ +package cc.polyfrost.oneconfig.config.elements; + +import cc.polyfrost.oneconfig.gui.Colors; +import cc.polyfrost.oneconfig.config.elements.BasicOption; +import cc.polyfrost.oneconfig.gui.OneConfigGui; +import cc.polyfrost.oneconfig.gui.elements.config.ConfigPageButton; +import cc.polyfrost.oneconfig.renderer.RenderManager; +import cc.polyfrost.oneconfig.renderer.font.Fonts; + +import java.util.ArrayList; + +public class OptionSubcategory { + private final String name; + public ArrayList options = new ArrayList<>(); + public ArrayList topButtons = new ArrayList<>(); + public ArrayList bottomButtons = new ArrayList<>(); + private ArrayList filteredOptions = new ArrayList<>(); + private int drawLastY; + + public OptionSubcategory(String name) { + this.name = name; + } + + public int draw(long vg, int x, int y) { + String filter = OneConfigGui.INSTANCE == null ? "" : OneConfigGui.INSTANCE.getSearchValue().toLowerCase().trim(); + filteredOptions = new ArrayList<>(options); + ArrayList filteredTop = new ArrayList<>(topButtons); + ArrayList filteredBottom = new ArrayList<>(bottomButtons); + if (!filter.equals("") && !name.toLowerCase().contains(filter)) { + filteredOptions.clear(); + filteredTop.clear(); + filteredBottom.clear(); + for (BasicOption option : options) { + if (option.getName().toLowerCase().contains(filter)) filteredOptions.add(option); + } + for (ConfigPageButton page : topButtons) { + if (page.getName().toLowerCase().contains(filter) || page.description.toLowerCase().contains(filter)) + filteredTop.add(page); + } + for (ConfigPageButton page : bottomButtons) { + if (page.getName().toLowerCase().contains(filter) || page.description.toLowerCase().contains(filter)) + filteredBottom.add(page); + } + } + if (filteredOptions.size() == 0 && filteredTop.size() == 0 && filteredBottom.size() == 0) return 0; + int optionY = y; + if (!name.equals("")) { + RenderManager.drawText(vg, name, x, y + 12, Colors.WHITE_90, 24, Fonts.MEDIUM); + optionY += 36; + } + + for (ConfigPageButton page : filteredTop) { + page.draw(vg, x, optionY); + optionY += page.getHeight() + 16; + } + + if (filteredOptions.size() > 0) { + int backgroundSize = 16; + for (int i = 0; i < filteredOptions.size(); i++) { + BasicOption option = filteredOptions.get(i); + if (i + 1 < filteredOptions.size()) { + BasicOption nextOption = filteredOptions.get(i + 1); + if (option.size == 1 && option.hasHalfSize() && nextOption.size == 1 && nextOption.hasHalfSize()) { + backgroundSize += Math.max(option.getHeight(), nextOption.getHeight()) + 16; + i++; + continue; + } + } + backgroundSize += option.getHeight() + 16; + } + RenderManager.drawRoundedRect(vg, x - 16, optionY, 1024, backgroundSize, Colors.GRAY_900, 20); + optionY += 16; + } + + drawLastY = optionY; + if (filteredOptions.size() > 0) { + for (int i = 0; i < filteredOptions.size(); i++) { + BasicOption option = filteredOptions.get(i); + option.draw(vg, x, optionY); + if (i + 1 < filteredOptions.size()) { + BasicOption nextOption = filteredOptions.get(i + 1); + if (option.size == 1 && option.hasHalfSize() && nextOption.size == 1 && nextOption.hasHalfSize()) { + nextOption.draw(vg, x + 512, optionY); + optionY += Math.max(option.getHeight(), nextOption.getHeight()) + 16; + i++; + continue; + } + } + optionY += option.getHeight() + 16; + } + optionY += 16; + } + + for (ConfigPageButton page : filteredBottom) { + page.draw(vg, x, optionY); + optionY += page.getHeight() + 16; + } + + return optionY - y; + } + + public void drawLast(long vg, int x) { + for (int i = 0; i < filteredOptions.size(); i++) { + BasicOption option = filteredOptions.get(i); + option.drawLast(vg, x, drawLastY); + if (i + 1 < filteredOptions.size()) { + BasicOption nextOption = filteredOptions.get(i + 1); + if (option.size == 1 && option.hasHalfSize() && nextOption.size == 1 && nextOption.hasHalfSize()) { + nextOption.drawLast(vg, x + 512, drawLastY); + drawLastY += Math.max(option.getHeight(), nextOption.getHeight()) + 16; + i++; + continue; + } + } + drawLastY += option.getHeight() + 16; + } + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/interfaces/BasicOption.java b/src/main/java/cc/polyfrost/oneconfig/config/interfaces/BasicOption.java deleted file mode 100644 index d4b4498..0000000 --- a/src/main/java/cc/polyfrost/oneconfig/config/interfaces/BasicOption.java +++ /dev/null @@ -1,98 +0,0 @@ -package cc.polyfrost.oneconfig.config.interfaces; - -import java.lang.reflect.Field; -import java.util.function.Supplier; - -@SuppressWarnings({"unused"}) -public abstract class BasicOption { - public final int size; - protected final Field field; - protected final String name; - protected final Object parent; - private Supplier dependency; - - /** - * Initialize option - * - * @param field variable attached to option (null for category) - * @param parent the parent object of the field, used for getting and setting the variable - * @param name name of option - * @param size size of option, 0 for single column, 1 for double. - */ - public BasicOption(Field field, Object parent, String name, int size) { - this.field = field; - this.parent = parent; - this.name = name; - this.size = size; - if (field != null) field.setAccessible(true); - } - - /** - * @param object Java object to set the variable to - */ - protected void set(Object object) throws IllegalAccessException { - if (field == null) return; - field.set(parent, object); - } - - /** - * @return value of variable as Java object - */ - protected Object get() throws IllegalAccessException { - if (field == null) return null; - return field.get(parent); - } - - /** - * @return height of option to align other options accordingly - */ - public abstract int getHeight(); - - /** - * Function that gets called when drawing option - * - * @param vg NanoVG context - * @param x x position - * @param y y position - */ - public abstract void draw(long vg, int x, int y); - - /** - * Function that gets called last drawing option, - * should be used for things that draw above other options - * - * @param vg NanoVG context - * @param x x position - * @param y y position - */ - public void drawLast(long vg, int x, int y) { - } - - /** - * Function that gets called when a key is typed - * - * @param key char that has been typed - * @param keyCode code of key - */ - public void keyTyped(char key, int keyCode) { - } - - /** - * @return If the component has an option to render at half size - */ - public boolean hasHalfSize() { - return true; - } - - public String getName() { - return name; - } - - public void setDependency(Supplier supplier) { - this.dependency = supplier; - } - - protected boolean isEnabled() { - return dependency == null || dependency.get(); - } -} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/interfaces/Config.java b/src/main/java/cc/polyfrost/oneconfig/config/interfaces/Config.java deleted file mode 100644 index 8eb5eb1..0000000 --- a/src/main/java/cc/polyfrost/oneconfig/config/interfaces/Config.java +++ /dev/null @@ -1,259 +0,0 @@ -package cc.polyfrost.oneconfig.config.interfaces; - -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.profiles.Profiles; -import cc.polyfrost.oneconfig.gui.OneConfigGui; -import cc.polyfrost.oneconfig.gui.elements.config.*; -import cc.polyfrost.oneconfig.gui.pages.ModConfigPage; -import cc.polyfrost.oneconfig.hud.BasicHud; -import cc.polyfrost.oneconfig.hud.HudCore; -import cc.polyfrost.oneconfig.utils.GuiUtils; -import com.google.gson.*; - -import java.io.*; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.util.*; -import java.util.function.Supplier; - -public class Config { - public final transient HashMap optionNames = new HashMap<>(); - transient protected final String configFile; - transient protected final Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).setPrettyPrinting().create(); - transient public Mod mod; - public transient boolean hasBeenInitialized = false; - public boolean enabled = true; - - /** - * @param modData information about the mod - * @param configFile file where config is stored - */ - public Config(Mod modData, String configFile) { - this.configFile = configFile; - 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, migrate); - if (migrate) save(); - ConfigCore.oneConfigMods.add(mod); - this.mod = mod; - hasBeenInitialized = true; - } - - /** - * Save current config to file - */ - public void save() { - try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(Profiles.getProfileFile(configFile).toPath()), StandardCharsets.UTF_8))) { - writer.write(gson.toJson(this)); - } catch (IOException e) { - e.printStackTrace(); - } - } - - /** - * Load file and overwrite current values - */ - public void load() { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(Files.newInputStream(Profiles.getProfileFile(configFile).toPath()), StandardCharsets.UTF_8))) { - deserializePart(new JsonParser().parse(reader).getAsJsonObject(), this); - } catch (IOException e) { - e.printStackTrace(); - } - } - - /** - * Generate the option list, for internal use only - * - * @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, boolean migrate) { - Class clazz = instance.getClass(); - for (Field field : clazz.getDeclaredFields()) { - String pagePrefix = page.equals(mod.defaultPage) ? "" : page.name + "."; - if (!field.isAnnotationPresent(Option.class) && !field.isAnnotationPresent(ConfigPage.class)) { - processCustomOption(field, page); - continue; - } else if (field.isAnnotationPresent(ConfigPage.class)) { - ConfigPage option = field.getAnnotation(ConfigPage.class); - if (!page.categories.containsKey(option.category())) - page.categories.put(option.category(), new OptionCategory()); - 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())); - OptionSubcategory subcategory = category.subcategories.get(category.subcategories.size() - 1); - OptionPage newPage = new OptionPage(option.name(), mod); - try { - field.setAccessible(true); - Object object = field.get(clazz); - generateOptionList(object, newPage, mod, migrate); - ConfigPageButton configPageButton = new ConfigPageButton(field, instance, option.name(), option.description(), newPage); - switch (option.location()) { - case TOP: - subcategory.topButtons.add(configPageButton); - break; - case BOTTOM: - subcategory.bottomButtons.add(configPageButton); - break; - } - optionNames.put(pagePrefix + field.getName(), configPageButton); - } catch (IllegalAccessException ignored) { - } - continue; - } - Option option = field.getAnnotation(Option.class); - if (!page.categories.containsKey(option.category())) - page.categories.put(option.category(), new OptionCategory()); - 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 options = category.subcategories.get(category.subcategories.size() - 1).options; - switch (option.type()) { - case SWITCH: - options.add(new ConfigSwitch(field, instance, option.name(), option.size())); - break; - case CHECKBOX: - options.add(new ConfigCheckbox(field, instance, option.name(), option.size())); - break; - case TEXT: - options.add(new ConfigTextBox(field, instance, option.name(), option.size(), option.placeholder(), option.secure(), option.multiLine())); - break; - case DUAL_OPTION: - options.add(new ConfigDualOption(field, instance, option.name(), option.size(), option.options())); - break; - case DROPDOWN: - options.add(new ConfigDropdown(field, instance, option.name(), option.size(), option.options())); - break; - case SLIDER: - options.add(new ConfigSlider(field, instance, option.name(), option.size(), option.min(), option.max(), option.step())); - break; - case INFO: - options.add(new ConfigInfo(field, instance, option.name(), option.size(), option.infoType())); - break; - case COLOR: - options.add(new ConfigColorElement(field, instance, option.name(), option.size())); - break; - case HEADER: - options.add(new ConfigHeader(field, instance, option.name(), option.size())); - break; - case BUTTON: - options.add(new ConfigButton(field, instance, option.name(), option.size(), option.buttonText())); - break; - case KEYBIND: - options.add(new ConfigKeyBind(field, instance, option.name(), option.size())); - break; - case HUD: - try { - field.setAccessible(true); - BasicHud hud = (BasicHud) field.get(instance); - HudCore.huds.add(hud); - options.add(new ConfigHeader(field, hud, option.name(), 1)); - options.add(new ConfigSwitch(hud.getClass().getField("enabled"), hud, "Enabled", 1)); - options.add(new ConfigCheckbox(hud.getClass().getField("rounded"), hud, "Rounded corners", 1)); - options.get(options.size() - 1).setDependency(() -> hud.enabled); - options.add(new ConfigCheckbox(hud.getClass().getField("border"), hud, "Outline/border", 1)); - options.get(options.size() - 1).setDependency(() -> hud.enabled); - options.add(new ConfigColorElement(hud.getClass().getField("bgColor"), hud, "Background color:", 1)); - options.get(options.size() - 1).setDependency(() -> hud.enabled); - options.add(new ConfigColorElement(hud.getClass().getField("borderColor"), hud, "Border color:", 1)); - options.get(options.size() - 1).setDependency(() -> hud.enabled && hud.border); - options.add(new ConfigSlider(hud.getClass().getField("cornerRadius"), hud, "Corner radius:", 2, 0, 10, 0)); - options.get(options.size() - 1).setDependency(() -> hud.enabled && hud.rounded); - options.add(new ConfigSlider(hud.getClass().getField("borderSize"), hud, "Border thickness:", 2, 0, 10, 0)); - options.get(options.size() - 1).setDependency(() -> hud.enabled && hud.border); - options.add(new ConfigSlider(hud.getClass().getField("paddingX"), hud, "X-Padding", 2, 0, 50, 0)); - options.get(options.size() - 1).setDependency(() -> hud.enabled); - options.add(new ConfigSlider(hud.getClass().getField("paddingY"), hud, "Y-Padding", 2, 0, 50, 0)); - options.get(options.size() - 1).setDependency(() -> hud.enabled); - } catch (IllegalAccessException | NoSuchFieldException e) { - e.printStackTrace(); - } - break; - } - if (!option.type().equals(OptionType.HUD)) - optionNames.put(pagePrefix + field.getName(), options.get(options.size() - 1)); - } - } - - /** - * Overwrite this method to add your own custom option types - * - * @param field target field - * @param page page to add options too - */ - protected void processCustomOption(Field field, OptionPage page) { - } - - /** - * Deserialize part of config and load values - * - * @param json json to deserialize - * @param instance instance of target class - */ - protected void deserializePart(JsonObject json, Object instance) { - Class clazz = instance.getClass(); - for (Map.Entry element : json.entrySet()) { - String name = element.getKey(); - JsonElement value = element.getValue(); - if (value.isJsonObject()) { - Optional> innerClass = Arrays.stream(clazz.getClasses()).filter(aClass -> aClass.getSimpleName().equals(name)).findFirst(); - if (innerClass.isPresent()) { - deserializePart(value.getAsJsonObject(), innerClass.get()); - continue; - } - } - try { - Field field = clazz.getField(name); - TypeAdapter adapter = gson.getAdapter(field.getType()); - Object object = adapter.fromJsonTree(value); - field.setAccessible(true); - field.set(instance, object); - } catch (Exception ignored) { - } - } - } - - /** - * Function to open the gui of this mod - */ - public void openGui() { - if (mod == null) return; - GuiUtils.displayScreen(new OneConfigGui(new ModConfigPage(mod.defaultPage))); - } - - /** - * Disable an option if a certain condition is not met - * - * @param option The name of the field, or if the field is in a page "pageName.fieldName" - * @param condition The condition that has to be met for the option to be enabled - */ - protected void addDependency(String option, Supplier condition) { - if (!optionNames.containsKey(option)) return; - optionNames.get(option).setDependency(condition); - } -} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/migration/Migrator.java b/src/main/java/cc/polyfrost/oneconfig/config/migration/Migrator.java deleted file mode 100644 index abfb2a0..0000000 --- a/src/main/java/cc/polyfrost/oneconfig/config/migration/Migrator.java +++ /dev/null @@ -1,14 +0,0 @@ -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 deleted file mode 100644 index b45aeba..0000000 --- a/src/main/java/cc/polyfrost/oneconfig/config/migration/VigilanceMigrator.java +++ /dev/null @@ -1,84 +0,0 @@ -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("\\[\"?(?[^.\\[\\]\"]+)\"?\\.\"?(?[^.\\[\\]\"]+)\"?]"); - private static final Pattern booleanPattern = Pattern.compile("\"?(?[^\\s\"]+)\"? = (?true|false)"); - private static final Pattern numberPattern = Pattern.compile("\"?(?[^\\s\"]+)\"? = (?[\\d.]+)"); - private static final Pattern stringPattern = Pattern.compile("\"?(?[^\\s\"]+)\"? = \"(?.+)\""); - protected final String filePath; - protected HashMap>> values = null; - - 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 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(); - } - } -} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/migration/vigilance/Migrator.java b/src/main/java/cc/polyfrost/oneconfig/config/migration/vigilance/Migrator.java new file mode 100644 index 0000000..f3f60b7 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/config/migration/vigilance/Migrator.java @@ -0,0 +1,14 @@ +package cc.polyfrost.oneconfig.config.migration.vigilance; + +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/vigilance/VigilanceMigrator.java b/src/main/java/cc/polyfrost/oneconfig/config/migration/vigilance/VigilanceMigrator.java new file mode 100644 index 0000000..2870e03 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/config/migration/vigilance/VigilanceMigrator.java @@ -0,0 +1,84 @@ +package cc.polyfrost.oneconfig.config.migration.vigilance; + +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("\\[\"?(?[^.\\[\\]\"]+)\"?\\.\"?(?[^.\\[\\]\"]+)\"?]"); + private static final Pattern booleanPattern = Pattern.compile("\"?(?[^\\s\"]+)\"? = (?true|false)"); + private static final Pattern numberPattern = Pattern.compile("\"?(?[^\\s\"]+)\"? = (?[\\d.]+)"); + private static final Pattern stringPattern = Pattern.compile("\"?(?[^\\s\"]+)\"? = \"(?.+)\""); + protected final String filePath; + protected HashMap>> values = null; + + 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 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(); + } + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/config/profiles/Profiles.java b/src/main/java/cc/polyfrost/oneconfig/config/profiles/Profiles.java index dfc5e16..006fea9 100644 --- a/src/main/java/cc/polyfrost/oneconfig/config/profiles/Profiles.java +++ b/src/main/java/cc/polyfrost/oneconfig/config/profiles/Profiles.java @@ -1,8 +1,8 @@ package cc.polyfrost.oneconfig.config.profiles; -import cc.polyfrost.oneconfig.OneConfig; -import cc.polyfrost.oneconfig.config.OneConfigConfig; +import cc.polyfrost.oneconfig.internal.OneConfig; import cc.polyfrost.oneconfig.config.core.ConfigCore; +import cc.polyfrost.oneconfig.internal.config.OneConfigConfig; import org.apache.commons.io.FileUtils; import java.io.File; -- cgit