From dc70abf450e9bca5a3bd7b44029fd77241832506 Mon Sep 17 00:00:00 2001 From: Leo dev Date: Thu, 3 Apr 2025 02:07:04 +0200 Subject: [PATCH] nested namespaces --- .../saturnclient/config/ConfigManager.java | 189 ++++++++++-------- .../saturnclient/config/Property.java | 41 +++- .../saturnclient/menus/ConfigEditor.java | 53 +++-- .../menus/SaturnConfigEditor.java | 99 ++++----- .../saturnmods/ModDimensions.java | 37 ++-- .../saturnmods/mods/Particles.java | 8 +- 6 files changed, 244 insertions(+), 183 deletions(-) diff --git a/src/main/java/org/saturnclient/saturnclient/config/ConfigManager.java b/src/main/java/org/saturnclient/saturnclient/config/ConfigManager.java index 835c1c7..ccf332d 100644 --- a/src/main/java/org/saturnclient/saturnclient/config/ConfigManager.java +++ b/src/main/java/org/saturnclient/saturnclient/config/ConfigManager.java @@ -20,20 +20,28 @@ public class ConfigManager { "saturn.json"); private static Map>> properties = new HashMap<>(); - private String namespace; + private Map> currentMap; public ConfigManager(String namespace) { - this.namespace = namespace; - properties.put(namespace, new LinkedHashMap<>()); + currentMap = new LinkedHashMap<>(); + properties.put(namespace, currentMap); + } + + public ConfigManager(ConfigManager config, String namespace) { + currentMap = new LinkedHashMap<>(); + Property>> namespaceProperty = new Property<>(currentMap, + Property.PropertyType.NAMESPACE); + config.property(namespace, namespaceProperty); + // Update the parent's state + config.currentMap.put(namespace, namespaceProperty); } // Generic method to store any type of property public Property property(String name, Property value) { - properties.get(namespace).put(name, value); + currentMap.put(name, value); return value; } - @SuppressWarnings("unchecked") public static void load() { try { SaturnClient.LOGGER.info("Starting to load config..."); @@ -57,48 +65,59 @@ public class ConfigManager { continue; } - Map> propertyMap = properties.get( - namespace); - - for (String propertyName : propertyMap.keySet()) { - JsonElement c = config.get(propertyName); - - if (c == null) { - continue; - } - - Property p = propertyMap.get(propertyName); - if (p.matchesJson(c)) { - switch (p.getType()) { - case BOOLEAN: - ((Property) p).value = c.getAsBoolean(); - break; - case INTEGER: - ((Property) p).value = c.getAsInt(); - break; - case FLOAT: - ((Property) p).value = c.getAsFloat(); - break; - case STRING: - ((Property) p).value = c.getAsString(); - break; - case HEX: - ((Property) p).value = c.getAsInt(); - break; - default: - break; - } - } else { - SaturnClient.LOGGER.warn( - "Property does not match JSON: " + propertyName); - } - } + Map> propertyMap = properties.get(namespace); + loadProperties(config, propertyMap); } } catch (IOException e) { SaturnClient.LOGGER.error("Error reading the config file", e); } } + @SuppressWarnings("unchecked") + private static void loadProperties(JsonObject config, Map> propertyMap) { + for (String propertyName : propertyMap.keySet()) { + JsonElement c = config.get(propertyName); + + if (c == null) { + continue; + } + + Property p = propertyMap.get(propertyName); + if (p.matchesJson(c)) { + if (p.getType() == Property.PropertyType.NAMESPACE) { + // Handle nested namespace + JsonObject nestedConfig = c.getAsJsonObject(); + Map> nestedProperties = (Map>) p.value; + loadProperties(nestedConfig, nestedProperties); + } else { + // Handle regular properties + switch (p.getType()) { + case BOOLEAN: + ((Property) p).value = c.getAsBoolean(); + break; + case INTEGER: + ((Property) p).value = c.getAsInt(); + break; + case FLOAT: + ((Property) p).value = c.getAsFloat(); + break; + case STRING: + ((Property) p).value = c.getAsString(); + break; + case HEX: + ((Property) p).value = c.getAsInt(); + break; + default: + break; + } + } + } else { + SaturnClient.LOGGER.warn( + "Property does not match JSON: " + propertyName); + } + } + } + public static void save() { try { SaturnClient.LOGGER.info("Starting to save config..."); @@ -108,46 +127,10 @@ public class ConfigManager { // Iterate through all namespaces and their properties for (String namespace : properties.keySet()) { JsonObject namespaceConfig = new JsonObject(); - Map> propertyMap = properties.get( - namespace); + Map> propertyMap = properties.get(namespace); - // Iterate through each property in the namespace - for (String propertyName : propertyMap.keySet()) { - Property property = propertyMap.get(propertyName); - JsonElement propertyValue = null; - - // Convert the property value based on its type - switch (property.getType()) { - case BOOLEAN: - propertyValue = new JsonPrimitive( - (Boolean) property.value); - break; - case INTEGER: - propertyValue = new JsonPrimitive( - (Integer) property.value); - break; - case FLOAT: - propertyValue = new JsonPrimitive( - (Float) property.value); - break; - case STRING: - propertyValue = new JsonPrimitive( - (String) property.value); - break; - case HEX: - propertyValue = new JsonPrimitive( - (Integer) property.value); - break; - default: - SaturnClient.LOGGER.warn( - "Unknown property type for: " + propertyName); - break; - } - - if (propertyValue != null) { - namespaceConfig.add(propertyName, propertyValue); - } - } + // Save properties for this namespace + saveProperties(namespaceConfig, propertyMap); // Add the namespace config to the main JSON object jsonObject.add(namespace, namespaceConfig); @@ -161,7 +144,51 @@ public class ConfigManager { } } + @SuppressWarnings("unchecked") + private static void saveProperties(JsonObject config, Map> propertyMap) { + // Iterate through each property in the namespace + for (String propertyName : propertyMap.keySet()) { + Property property = propertyMap.get(propertyName); + JsonElement propertyValue = null; + + if (property.getType() == Property.PropertyType.NAMESPACE) { + // Handle nested namespace + JsonObject nestedConfig = new JsonObject(); + Map> nestedProperties = (Map>) property.value; + saveProperties(nestedConfig, nestedProperties); + propertyValue = nestedConfig; + } else { + // Convert the property value based on its type + switch (property.getType()) { + case BOOLEAN: + propertyValue = new JsonPrimitive((Boolean) property.value); + break; + case INTEGER: + propertyValue = new JsonPrimitive((Integer) property.value); + break; + case FLOAT: + propertyValue = new JsonPrimitive((Float) property.value); + break; + case STRING: + propertyValue = new JsonPrimitive((String) property.value); + break; + case HEX: + propertyValue = new JsonPrimitive((Integer) property.value); + break; + default: + SaturnClient.LOGGER.warn( + "Unknown property type for: " + propertyName); + break; + } + } + + if (propertyValue != null) { + config.add(propertyName, propertyValue); + } + } + } + public Map> getProperties() { - return properties.get(namespace); + return currentMap; } } diff --git a/src/main/java/org/saturnclient/saturnclient/config/Property.java b/src/main/java/org/saturnclient/saturnclient/config/Property.java index a03e2e9..0de955e 100644 --- a/src/main/java/org/saturnclient/saturnclient/config/Property.java +++ b/src/main/java/org/saturnclient/saturnclient/config/Property.java @@ -1,5 +1,7 @@ package org.saturnclient.saturnclient.config; +import java.util.Map; + import com.google.gson.JsonElement; import com.google.gson.JsonPrimitive; @@ -11,6 +13,7 @@ public class Property { FLOAT, STRING, HEX, + NAMESPACE } public T value; @@ -26,6 +29,8 @@ public class Property { type = PropertyType.FLOAT; } else if (value instanceof String) { type = PropertyType.STRING; + } else if (isMapOfStringToProperty(value)) { + type = PropertyType.NAMESPACE; } } @@ -70,14 +75,12 @@ public class Property { return Integer.parseInt(str.substring(2), 16); } catch (NumberFormatException e) { throw new IllegalStateException( - "Invalid hexadecimal integer format" - ); + "Invalid hexadecimal integer format"); } } } throw new IllegalStateException( - "Property does not contain a valid hex integer" - ); + "Property does not contain a valid hex integer"); } public PropertyType getType() { @@ -87,10 +90,16 @@ public class Property { public boolean matchesJson(JsonElement element) { if (element.isJsonPrimitive()) { JsonPrimitive primitive = element.getAsJsonPrimitive(); - if (value instanceof Boolean && primitive.isBoolean()) return true; - if (value instanceof Integer && primitive.isNumber()) return true; - if (value instanceof Float && primitive.isNumber()) return true; - if (value instanceof String && primitive.isString()) return true; + if (value instanceof Boolean && primitive.isBoolean()) + return true; + if (value instanceof Integer && primitive.isNumber()) + return true; + if (value instanceof Float && primitive.isNumber()) + return true; + if (value instanceof String && primitive.isString()) + return true; + if (isMapOfStringToProperty(value) && primitive.isJsonObject()) + return true; // Check if JSON string represents a valid hex integer if (value instanceof String && primitive.isString()) { @@ -105,4 +114,20 @@ public class Property { public String toString() { return String.valueOf(value); } + + public static boolean isMapOfStringToProperty(Object obj) { + if (!(obj instanceof Map map)) { + return false; + } + + for (Map.Entry entry : map.entrySet()) { + if (!(entry.getKey() instanceof String)) { + return false; + } + if (!(entry.getValue() instanceof Property)) { + return false; + } + } + return true; + } } diff --git a/src/main/java/org/saturnclient/saturnclient/menus/ConfigEditor.java b/src/main/java/org/saturnclient/saturnclient/menus/ConfigEditor.java index 0cbb107..89a511d 100644 --- a/src/main/java/org/saturnclient/saturnclient/menus/ConfigEditor.java +++ b/src/main/java/org/saturnclient/saturnclient/menus/ConfigEditor.java @@ -26,7 +26,6 @@ public class ConfigEditor extends SaturnUi { this.config = config; } - @SuppressWarnings("unchecked") @Override protected void init() { int rectWidth = 330; @@ -57,9 +56,24 @@ public class ConfigEditor extends SaturnUi { int row = 0; int col = 0; - for (Map.Entry> propEntry : config - .getProperties() - .entrySet()) { + drawProperties(configScroll, config.getProperties(), rectWidth, row, col); + + draw( + configScroll + .setX(rectX + 17) + .setY(rectY + 10) + .setWidth(rectWidth - 17) + .setHeight(rectHeight - 10) + .setAnimations(SaturnClient.getAnimations())); + + super.init(); + } + + @SuppressWarnings("unchecked") + private int drawProperties(SaturnScroll configScroll, Map> properties, int rectWidth, + int row, int col) { + int totalRows = row; + for (Map.Entry> propEntry : properties.entrySet()) { Property prop = propEntry.getValue(); String propName = propEntry.getKey(); @@ -67,11 +81,11 @@ public class ConfigEditor extends SaturnUi { if (full && col > 0) { col = 0; - row++; + totalRows++; } int modX = ((rectWidth / 2) - 17) * col; - int modY = 14 * row; + int modY = 14 * totalRows; switch (prop.getType()) { case BOOLEAN: @@ -151,28 +165,31 @@ public class ConfigEditor extends SaturnUi { modY, 70)); break; + case NAMESPACE: + configScroll.draw( + new SaturnText( + propName.substring(0, 1).toUpperCase() + + propName.substring(1)) + .setX(modX) + .setY(modY) + .setScale(0.8f)); + + // Recursively draw nested properties and update total rows + Map> nestedProperties = (Map>) prop.value; + totalRows = drawProperties(configScroll, nestedProperties, rectWidth, totalRows + 1, 0); } if (full) { - row++; + totalRows++; } else { col++; if (col > 1) { col = 0; - row++; + totalRows++; } } } - - draw( - configScroll - .setX(rectX + 17) - .setY(rectY + 10) - .setWidth(rectWidth - 17) - .setHeight(rectHeight - 10) - .setAnimations(SaturnClient.getAnimations())); - - super.init(); + return totalRows; } public static boolean isFull(Property prop) { diff --git a/src/main/java/org/saturnclient/saturnclient/menus/SaturnConfigEditor.java b/src/main/java/org/saturnclient/saturnclient/menus/SaturnConfigEditor.java index fb466ab..af0b242 100644 --- a/src/main/java/org/saturnclient/saturnclient/menus/SaturnConfigEditor.java +++ b/src/main/java/org/saturnclient/saturnclient/menus/SaturnConfigEditor.java @@ -22,7 +22,6 @@ public class SaturnConfigEditor extends SaturnUi { super(Text.of("Config editor")); } - @SuppressWarnings("unchecked") @Override protected void init() { int rectWidth = 330; @@ -38,48 +37,14 @@ public class SaturnConfigEditor extends SaturnUi { .setHeight(rectHeight) .setAnimations(SaturnClient.getAnimations())); - int tabsX = (width - 43) / 2; - int tabsY = rectY - 17; - draw( - new SaturnSprite(Textures.TABS) - .setX(tabsX) - .setY(tabsY) - .setWidth(43) - .setHeight(15) - .setAnimations(SaturnClient.getAnimations())); - - int tabSize = 9; - tabsX = (width - tabSize) / 2; - draw( - new SaturnClickableImage(Textures.SETTINGS, () -> { - client.setScreen(new SaturnConfigEditor()); + new SaturnClickableImage(Textures.CLOSE, () -> { + this.close(); }) - .setColor(SaturnClient.COLOR.value) - .setX(tabsX) - .setY(tabsY + 3) - .setWidth(tabSize) - .setHeight(tabSize) - .setAnimations(SaturnClient.getAnimations())); - - draw( - new SaturnClickableImage(Textures.MODS_TAB, () -> { - client.setScreen(new ModMenu()); - }) - .setX(tabsX - 12) - .setY(tabsY + 3) - .setWidth(tabSize) - .setHeight(tabSize) - .setAnimations(SaturnClient.getAnimations())); - - draw( - new SaturnClickableImage(Textures.SEARCH, () -> { - System.out.println("Pressed"); - }) - .setX(tabsX + 12) - .setY(tabsY + 3) - .setWidth(tabSize) - .setHeight(tabSize) + .setX(rectX) + .setY(rectY - 15) + .setWidth(13) + .setHeight(13) .setAnimations(SaturnClient.getAnimations())); SaturnScroll configScroll = new SaturnScroll(); @@ -87,9 +52,24 @@ public class SaturnConfigEditor extends SaturnUi { int row = 0; int col = 0; - for (Map.Entry> propEntry : SaturnClient.config - .getProperties() - .entrySet()) { + drawProperties(configScroll, SaturnClient.config.getProperties(), rectWidth, row, col); + + draw( + configScroll + .setX(rectX + 17) + .setY(rectY + 10) + .setWidth(rectWidth - 17) + .setHeight(rectHeight - 10) + .setAnimations(SaturnClient.getAnimations())); + + super.init(); + } + + @SuppressWarnings("unchecked") + private int drawProperties(SaturnScroll configScroll, Map> properties, int rectWidth, + int row, int col) { + int totalRows = row; + for (Map.Entry> propEntry : properties.entrySet()) { Property prop = propEntry.getValue(); String propName = propEntry.getKey(); @@ -97,11 +77,11 @@ public class SaturnConfigEditor extends SaturnUi { if (full && col > 0) { col = 0; - row++; + totalRows++; } int modX = ((rectWidth / 2) - 17) * col; - int modY = 14 * row; + int modY = 14 * totalRows; switch (prop.getType()) { case BOOLEAN: @@ -181,28 +161,31 @@ public class SaturnConfigEditor extends SaturnUi { modY, 70)); break; + case NAMESPACE: + configScroll.draw( + new SaturnText( + propName.substring(0, 1).toUpperCase() + + propName.substring(1)) + .setX(modX) + .setY(modY) + .setScale(0.8f)); + + // Recursively draw nested properties and update total rows + Map> nestedProperties = (Map>) prop.value; + totalRows = drawProperties(configScroll, nestedProperties, rectWidth, totalRows + 1, 0); } if (full) { - row++; + totalRows++; } else { col++; if (col > 1) { col = 0; - row++; + totalRows++; } } } - - draw( - configScroll - .setX(rectX + 17) - .setY(rectY + 10) - .setWidth(rectWidth - 17) - .setHeight(rectHeight - 10) - .setAnimations(SaturnClient.getAnimations())); - - super.init(); + return totalRows; } public static boolean isFull(Property prop) { diff --git a/src/main/java/org/saturnclient/saturnmods/ModDimensions.java b/src/main/java/org/saturnclient/saturnmods/ModDimensions.java index 412eb55..698e200 100644 --- a/src/main/java/org/saturnclient/saturnmods/ModDimensions.java +++ b/src/main/java/org/saturnclient/saturnmods/ModDimensions.java @@ -11,47 +11,54 @@ public class ModDimensions { public int width = 0; public int height = 0; + private final ConfigManager dimensionsConfig; + public ModDimensions(ConfigManager configManager) { - configManager.property("x", this.x); - configManager.property("y", this.y); - configManager.property("scale", this.scale); + dimensionsConfig = new ConfigManager(configManager, "Dimensions"); + dimensionsConfig.property("x", this.x); + dimensionsConfig.property("y", this.y); + dimensionsConfig.property("scale", this.scale); } public ModDimensions(ConfigManager configManager, int x, int y) { + dimensionsConfig = new ConfigManager(configManager, "Dimensions"); this.x.value = x; this.y.value = y; - configManager.property("x", this.x); - configManager.property("y", this.y); - configManager.property("scale", this.scale); + dimensionsConfig.property("x", this.x); + dimensionsConfig.property("y", this.y); + dimensionsConfig.property("scale", this.scale); } public ModDimensions(ConfigManager configManager, int x, int y, int width, int height) { + dimensionsConfig = new ConfigManager(configManager, "Dimensions"); this.x.value = x; this.y.value = y; this.width = width; this.height = height; - configManager.property("x", this.x); - configManager.property("y", this.y); - configManager.property("scale", this.scale); + dimensionsConfig.property("x", this.x); + dimensionsConfig.property("y", this.y); + dimensionsConfig.property("scale", this.scale); } public ModDimensions(ConfigManager configManager, int x, int y, float scale) { + dimensionsConfig = new ConfigManager(configManager, "Dimensions"); this.x.value = x; this.y.value = y; this.scale.value = scale; - configManager.property("x", this.x); - configManager.property("y", this.y); - configManager.property("scale", this.scale); + dimensionsConfig.property("x", this.x); + dimensionsConfig.property("y", this.y); + dimensionsConfig.property("scale", this.scale); } public ModDimensions(ConfigManager configManager, int x, int y, int width, int height, float scale) { + dimensionsConfig = new ConfigManager(configManager, "Dimensions"); this.x.value = x; this.y.value = y; this.scale.value = scale; this.width = width; this.height = height; - configManager.property("x", this.x); - configManager.property("y", this.y); - configManager.property("scale", this.scale); + dimensionsConfig.property("x", this.x); + dimensionsConfig.property("y", this.y); + dimensionsConfig.property("scale", this.scale); } } diff --git a/src/main/java/org/saturnclient/saturnmods/mods/Particles.java b/src/main/java/org/saturnclient/saturnmods/mods/Particles.java index 039a4bd..66a34ca 100644 --- a/src/main/java/org/saturnclient/saturnmods/mods/Particles.java +++ b/src/main/java/org/saturnclient/saturnmods/mods/Particles.java @@ -14,15 +14,17 @@ public class Particles implements SaturnMod { "Enabled", new Property<>(false)); - public static Property totem_enabled = config.property( + public static ConfigManager totem = new ConfigManager(config, "Totem particles"); + + public static Property totem_enabled = totem.property( "Change totem color", new Property<>(false)); - public static Property totem_1 = config.property( + public static Property totem_1 = totem.property( "Totem particle color 1", new Property<>(SaturnClient.COLOR.value, Property.PropertyType.HEX)); - public static Property totem_2 = config.property( + public static Property totem_2 = totem.property( "Totem particle color 2", new Property<>(SaturnClient.COLOR.value, Property.PropertyType.HEX));