From d930d84f8014176dd35c9a1c694a512ed75d9a27 Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Mon, 19 Jan 2026 16:55:52 -0500 Subject: [PATCH 1/8] Add boolean config commands --- .../java/de/hysky/skyblocker/DisableAll.java | 17 +--- .../config/SkyblockerConfigManager.java | 85 +++++++++++++++++-- 2 files changed, 81 insertions(+), 21 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/DisableAll.java b/src/main/java/de/hysky/skyblocker/DisableAll.java index 8ae78718b12..27570f7fbdb 100644 --- a/src/main/java/de/hysky/skyblocker/DisableAll.java +++ b/src/main/java/de/hysky/skyblocker/DisableAll.java @@ -23,7 +23,6 @@ */ public class DisableAll { private static final Logger LOGGER = LogUtils.getLogger(); - private static final String CONFIGS_PACKAGE = "de.hysky.skyblocker.config.configs"; @Init public static void init() { @@ -95,23 +94,9 @@ private static void disableBooleans(Object target) throws IllegalAccessException m.put(entry.getKey(), Boolean.FALSE); } } - } else if (value != null && isConfigClass(type)) { + } else if (value != null && SkyblockerConfigManager.isConfigClass(type)) { disableBooleans(value); } } } - - /** - * Returns {@code true} if the given class represents one of our config - * classes. This prevents {@link #disableBooleans(Object)} from touching - * unrelated objects from other mods. - */ - private static boolean isConfigClass(Class clazz) { - return !clazz.isPrimitive() - && !clazz.isEnum() - && !clazz.isRecord() - && !clazz.equals(String.class) - && !Number.class.isAssignableFrom(clazz) - && clazz.getPackageName().startsWith(CONFIGS_PACKAGE); - } } diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java index 7b2f647f87e..d7a9b1d1adb 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java @@ -1,8 +1,9 @@ package de.hysky.skyblocker.config; -import com.mojang.brigadier.arguments.StringArgumentType; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import com.mojang.brigadier.Command; +import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.logging.LogUtils; import de.hysky.skyblocker.SkyblockerMod; @@ -42,10 +43,13 @@ import net.minecraft.network.chat.Component; import org.apache.commons.lang3.function.Consumers; import org.jspecify.annotations.Nullable; +import org.slf4j.Logger; import java.io.BufferedReader; import java.io.BufferedWriter; import java.lang.StackWalker.Option; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.nio.file.Files; import java.nio.file.Path; import java.util.function.Consumer; @@ -53,11 +57,11 @@ import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument; import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; -import org.slf4j.Logger; public class SkyblockerConfigManager { public static final int CONFIG_VERSION = 6; private static final Logger LOGGER = LogUtils.getLogger(); + private static final String CONFIGS_PACKAGE = "de.hysky.skyblocker.config.configs"; private static final Path CONFIG_DIR = FabricLoader.getInstance().getConfigDir(); private static final Path CONFIG_FILE = CONFIG_DIR.resolve("skyblocker.json"); private static final ConfigManager CONFIG_MANAGER = ConfigManager.create(SkyblockerConfig.class, CONFIG_FILE, UnaryOperator.identity()); @@ -103,7 +107,7 @@ public static void update(Consumer action) { CONFIG_MANAGER.save(); } - public static Screen createGUI(Screen parent) { + public static Screen createGUI(@Nullable Screen parent) { return createGUI(parent, ""); } @@ -150,8 +154,79 @@ public static void reload() { * @return the command builder */ private static LiteralArgumentBuilder configLiteral(String name) { - return literal(name).executes(Scheduler.queueOpenScreenCommand(() -> createGUI(null))) - .then(argument("option", StringArgumentType.greedyString()).executes((ctx) -> Scheduler.queueOpenScreen(createGUI(null, ctx.getArgument("option", String.class))))); + LiteralArgumentBuilder builder = literal(name).executes(Scheduler.queueOpenScreenCommand(() -> createGUI(null))) + .then(literal("search").then(argument("option", StringArgumentType.greedyString()).executes((ctx) -> Scheduler.queueOpenScreen(createGUI(null, ctx.getArgument("option", String.class)))))); + registerConfigEntriesCommand(builder); + return builder; + } + + private static void registerConfigEntriesCommand(LiteralArgumentBuilder builder) { + try { + registerConfigEntriesCommand(builder, SkyblockerConfigManager.get()); + } catch (Exception e) { + LOGGER.error("[Skyblocker Config Manager] Failed to register config entries command!", e); + } + } + + private static void registerConfigEntriesCommand(LiteralArgumentBuilder builder, Object object) throws IllegalAccessException { + for (Field field : object.getClass().getDeclaredFields()) { + if (Modifier.isStatic(field.getModifiers())) continue; + field.setAccessible(true); + + LiteralArgumentBuilder entryBuilder = literal(field.getName()); + Class type = field.getType(); + Object value = field.get(object); + + if (type == boolean.class) { + entryBuilder.then(literal("true").executes(context -> { + SkyblockerConfigManager.update(config -> { + try { + field.setBoolean(object, true); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + }); + return Command.SINGLE_SUCCESS; + })).then(literal("false").executes(context -> { + SkyblockerConfigManager.update(config -> { + try { + field.setBoolean(object, false); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + }); + return Command.SINGLE_SUCCESS; + })).then(literal("toggle").executes(context -> { + SkyblockerConfigManager.update(config -> { + try { + field.setBoolean(object, !field.getBoolean(object)); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + }); + return Command.SINGLE_SUCCESS; + })); + } else if (value != null && SkyblockerConfigManager.isConfigClass(type)) { + registerConfigEntriesCommand(entryBuilder, value); + } + + builder.then(entryBuilder); + } + } + + /** + * Returns {@code true} if the given class represents one of our config + * classes. This prevents {@link de.hysky.skyblocker.DisableAll#disableBooleans(Object)} from touching + * unrelated objects from other mods. + */ + @SuppressWarnings("JavadocReference") + public static boolean isConfigClass(Class clazz) { + return !clazz.isPrimitive() + && !clazz.isEnum() + && !clazz.isRecord() + && !clazz.equals(String.class) + && !Number.class.isAssignableFrom(clazz) + && clazz.getPackageName().startsWith(CONFIGS_PACKAGE); } public static void dataFix(Path configDir, Path backupDir) { From 2aef8c90d92cac553ab8a41dc7c86a5e2ac6d23f Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Mon, 19 Jan 2026 17:01:28 -0500 Subject: [PATCH 2/8] Clean up null fields fix --- .../config/ConfigNullFieldsFix.java | 47 ++++++------------- .../config/SkyblockerConfigManager.java | 4 ++ 2 files changed, 19 insertions(+), 32 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/config/ConfigNullFieldsFix.java b/src/main/java/de/hysky/skyblocker/config/ConfigNullFieldsFix.java index ab8709d73b3..54c8d57f35e 100644 --- a/src/main/java/de/hysky/skyblocker/config/ConfigNullFieldsFix.java +++ b/src/main/java/de/hysky/skyblocker/config/ConfigNullFieldsFix.java @@ -1,8 +1,6 @@ package de.hysky.skyblocker.config; import java.lang.reflect.Field; -import java.util.Collection; -import java.util.Map; import org.slf4j.Logger; @@ -16,49 +14,34 @@ */ public class ConfigNullFieldsFix { private static final Logger LOGGER = LogUtils.getLogger(); - private static final String CONFIGS_PACKAGE = "de.hysky.skyblocker.config.configs"; - @SuppressWarnings("removal") public static void init() { - SkyblockerConfig current = SkyblockerConfigManager.get(); - SkyblockerConfig clean = new SkyblockerConfig(); - - try { - fixNullFields(current, clean); - SkyblockerConfigManager.save(); - } catch (Exception e) { - LOGGER.error("[Skyblocker Config Null Fields Fixer] Failed to ensure that the config has no null fields! You may encounter crashes :(", e); - } + SkyblockerConfigManager.update(config -> { + try { + fixNullFields(config, new SkyblockerConfig()); + } catch (Exception e) { + LOGGER.error("[Skyblocker Config Null Fields Fixer] Failed to ensure that the config has no null fields! You may encounter crashes :(", e); + } + }); } /** * Traverse through every config field to ensure that is isn't null, if it is then reset the value. */ - private static void fixNullFields(Object target, Object source) throws Exception { - for (Field field : target.getClass().getDeclaredFields()) { + private static void fixNullFields(Object config, Object defaultConfig) throws Exception { + for (Field field : config.getClass().getDeclaredFields()) { if (field.isAnnotationPresent(SerialEntry.class)) { field.setAccessible(true); - Object targetValue = field.get(target); - Object sourceValue = field.get(source); + Object configValue = field.get(config); + Object defaultValue = field.get(defaultConfig); - if (targetValue == null && sourceValue != null) { - field.set(target, sourceValue); - } else if (targetValue != null && sourceValue != null && isFixable(field.getType())) { - fixNullFields(targetValue, sourceValue); + if (configValue == null && defaultValue != null) { + field.set(config, defaultValue); + } else if (configValue != null && defaultValue != null && SkyblockerConfigManager.isConfigClass(field.getType())) { + fixNullFields(configValue, defaultValue); } } } } - - private static boolean isFixable(Class clazz) { - return !clazz.isPrimitive() - && !clazz.isEnum() - && !clazz.isRecord() - && !clazz.equals(String.class) - && !Number.class.isAssignableFrom(clazz) - && !Map.class.isAssignableFrom(clazz) - && !Collection.class.isAssignableFrom(clazz) - && clazz.getPackageName().startsWith(CONFIGS_PACKAGE); - } } diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java index d7a9b1d1adb..f6d875a9690 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java @@ -52,6 +52,8 @@ import java.lang.reflect.Modifier; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Collection; +import java.util.Map; import java.util.function.Consumer; import java.util.function.UnaryOperator; @@ -226,6 +228,8 @@ public static boolean isConfigClass(Class clazz) { && !clazz.isRecord() && !clazz.equals(String.class) && !Number.class.isAssignableFrom(clazz) + && !Map.class.isAssignableFrom(clazz) + && !Collection.class.isAssignableFrom(clazz) && clazz.getPackageName().startsWith(CONFIGS_PACKAGE); } From c5d8a31ff70dcac107225f838d3eab943abfcabc Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Mon, 19 Jan 2026 17:11:58 -0500 Subject: [PATCH 3/8] Intellij is being weird with indents --- .../skyblocker/config/SkyblockerConfigManager.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java index f6d875a9690..f78475607af 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java @@ -224,13 +224,13 @@ private static void registerConfigEntriesCommand(LiteralArgumentBuilder clazz) { return !clazz.isPrimitive() - && !clazz.isEnum() - && !clazz.isRecord() - && !clazz.equals(String.class) - && !Number.class.isAssignableFrom(clazz) - && !Map.class.isAssignableFrom(clazz) - && !Collection.class.isAssignableFrom(clazz) - && clazz.getPackageName().startsWith(CONFIGS_PACKAGE); + && !clazz.isEnum() + && !clazz.isRecord() + && !clazz.equals(String.class) + && !Number.class.isAssignableFrom(clazz) + && !Map.class.isAssignableFrom(clazz) + && !Collection.class.isAssignableFrom(clazz) + && clazz.getPackageName().startsWith(CONFIGS_PACKAGE); } public static void dataFix(Path configDir, Path backupDir) { From 73f92fe204374a2be76dbffc151c15fb5b565c3b Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Mon, 19 Jan 2026 17:19:01 -0500 Subject: [PATCH 4/8] Clean up more config stuff --- .../skyblock/item/HotbarSlotLock.java | 9 ++-- .../skyblock/item/ItemProtection.java | 48 +++++++++---------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/HotbarSlotLock.java b/src/main/java/de/hysky/skyblocker/skyblock/item/HotbarSlotLock.java index 1a207443739..3c76c79367c 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/HotbarSlotLock.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/HotbarSlotLock.java @@ -28,11 +28,12 @@ public static boolean isLocked(int slot) { public static void handleInputEvents(LocalPlayer player) { while (hotbarSlotLock.consumeClick()) { - List lockedSlots = SkyblockerConfigManager.get().general.lockedSlots; int selected = player.getInventory().getSelectedSlot(); - if (!isLocked(player.getInventory().getSelectedSlot())) lockedSlots.add(selected); - else lockedSlots.remove(Integer.valueOf(selected)); - SkyblockerConfigManager.save(); + SkyblockerConfigManager.update(config -> { + List lockedSlots = config.general.lockedSlots; + if (!lockedSlots.contains(selected)) lockedSlots.add(selected); + else lockedSlots.remove(Integer.valueOf(selected)); + }); } } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/ItemProtection.java b/src/main/java/de/hysky/skyblocker/skyblock/item/ItemProtection.java index cb6b7a8357f..bb91f5181b9 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/ItemProtection.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/ItemProtection.java @@ -65,17 +65,17 @@ private static int protectMyItem(FabricClientCommandSource source) { String itemUuid = heldItem.getUuid(); if (!itemUuid.isEmpty()) { - ObjectOpenHashSet protectedItems = SkyblockerConfigManager.get().general.protectedItems; - - if (!protectedItems.contains(itemUuid)) { - protectedItems.add(itemUuid); - SkyblockerConfigManager.save(); - source.sendFeedback(Constants.PREFIX.get().append(Component.translatable("skyblocker.itemProtection.added", heldItem.getHoverName()))); - } else { - protectedItems.remove(itemUuid); - SkyblockerConfigManager.save(); - source.sendFeedback(Constants.PREFIX.get().append(Component.translatable("skyblocker.itemProtection.removed", heldItem.getHoverName()))); - } + SkyblockerConfigManager.update(config -> { + ObjectOpenHashSet protectedItems = config.general.protectedItems; + + if (!protectedItems.contains(itemUuid)) { + protectedItems.add(itemUuid); + source.sendFeedback(Constants.PREFIX.get().append(Component.translatable("skyblocker.itemProtection.added", heldItem.getHoverName()))); + } else { + protectedItems.remove(itemUuid); + source.sendFeedback(Constants.PREFIX.get().append(Component.translatable("skyblocker.itemProtection.removed", heldItem.getHoverName()))); + } + }); } else { source.sendFeedback(Constants.PREFIX.get().append(Component.translatable("skyblocker.itemProtection.noItemUuid"))); } @@ -105,21 +105,21 @@ public static void handleKeyPressed(ItemStack heldItem) { String itemUuid = heldItem.getUuid(); if (!itemUuid.isEmpty()) { - ObjectOpenHashSet protectedItems = SkyblockerConfigManager.get().general.protectedItems; + SkyblockerConfigManager.update(config -> { + ObjectOpenHashSet protectedItems = config.general.protectedItems; - if (!protectedItems.contains(itemUuid)) { - protectedItems.add(itemUuid); - SkyblockerConfigManager.save(); - if (notifyConfiguration) { - playerEntity.displayClientMessage(Constants.PREFIX.get().append(Component.translatable("skyblocker.itemProtection.added", heldItem.getHoverName())), false); - } - } else { - protectedItems.remove(itemUuid); - SkyblockerConfigManager.save(); - if (notifyConfiguration) { - playerEntity.displayClientMessage(Constants.PREFIX.get().append(Component.translatable("skyblocker.itemProtection.removed", heldItem.getHoverName())), false); + if (!protectedItems.contains(itemUuid)) { + protectedItems.add(itemUuid); + if (notifyConfiguration) { + playerEntity.displayClientMessage(Constants.PREFIX.get().append(Component.translatable("skyblocker.itemProtection.added", heldItem.getHoverName())), false); + } + } else { + protectedItems.remove(itemUuid); + if (notifyConfiguration) { + playerEntity.displayClientMessage(Constants.PREFIX.get().append(Component.translatable("skyblocker.itemProtection.removed", heldItem.getHoverName())), false); + } } - } + }); } else { playerEntity.displayClientMessage(Constants.PREFIX.get().append(Component.translatable("skyblocker.itemProtection.noItemUuid")), false); } From 6ed84e54967d9584b75cde28481bece587864d91 Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Sun, 25 Jan 2026 16:09:14 -0500 Subject: [PATCH 5/8] Add feedback and refactor --- .../skyblocker/config/ConfigCommands.java | 75 +++++++++++++++++++ .../config/SkyblockerConfigManager.java | 61 +-------------- .../assets/skyblocker/lang/en_us.json | 2 + 3 files changed, 79 insertions(+), 59 deletions(-) create mode 100644 src/main/java/de/hysky/skyblocker/config/ConfigCommands.java diff --git a/src/main/java/de/hysky/skyblocker/config/ConfigCommands.java b/src/main/java/de/hysky/skyblocker/config/ConfigCommands.java new file mode 100644 index 00000000000..3996c2905c4 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/config/ConfigCommands.java @@ -0,0 +1,75 @@ +package de.hysky.skyblocker.config; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.minecraft.network.chat.Component; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; + +public class ConfigCommands { + static void registerConfigEntries(LiteralArgumentBuilder builder) { + try { + registerConfigEntries(builder, SkyblockerConfigManager.get()); + } catch (Exception e) { + SkyblockerConfigManager.LOGGER.error("[Skyblocker Config Manager] Failed to register config entries command!", e); + } + } + + private static LiteralArgumentBuilder registerConfigEntries(LiteralArgumentBuilder builder, Object object) throws IllegalAccessException { + for (Field field : object.getClass().getDeclaredFields()) { + if (Modifier.isStatic(field.getModifiers())) continue; + field.setAccessible(true); + + Class type = field.getType(); + String name = field.getName(); + Object value = field.get(object); + + if (type == boolean.class) { + builder.then(registerBooleanConfigEntry(field, object, name)); + } else if (value != null && SkyblockerConfigManager.isConfigClass(type)) { + builder.then(registerConfigEntries(literal(name), value)); + } + } + + return builder; + } + + private static LiteralArgumentBuilder registerBooleanConfigEntry(Field field, Object object, String name) { + return literal(name).then(literal("true").executes(context -> { + SkyblockerConfigManager.update(config -> { + try { + field.setBoolean(object, true); + context.getSource().sendFeedback(Component.translatable("skyblocker.config.commands.set", name, true)); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + }); + return Command.SINGLE_SUCCESS; + })).then(literal("false").executes(context -> { + SkyblockerConfigManager.update(config -> { + try { + field.setBoolean(object, false); + context.getSource().sendFeedback(Component.translatable("skyblocker.config.commands.set", name, false)); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + }); + return Command.SINGLE_SUCCESS; + })).then(literal("toggle").executes(context -> { + SkyblockerConfigManager.update(config -> { + try { + boolean toggled = !field.getBoolean(object); + field.setBoolean(object, toggled); + context.getSource().sendFeedback(Component.translatable("skyblocker.config.commands.set", name, toggled)); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + }); + return Command.SINGLE_SUCCESS; + })); + } +} diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java index f78475607af..f9a5c44fae8 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java @@ -2,7 +2,6 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; -import com.mojang.brigadier.Command; import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.logging.LogUtils; @@ -48,8 +47,6 @@ import java.io.BufferedReader; import java.io.BufferedWriter; import java.lang.StackWalker.Option; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collection; @@ -62,7 +59,7 @@ public class SkyblockerConfigManager { public static final int CONFIG_VERSION = 6; - private static final Logger LOGGER = LogUtils.getLogger(); + static final Logger LOGGER = LogUtils.getLogger(); private static final String CONFIGS_PACKAGE = "de.hysky.skyblocker.config.configs"; private static final Path CONFIG_DIR = FabricLoader.getInstance().getConfigDir(); private static final Path CONFIG_FILE = CONFIG_DIR.resolve("skyblocker.json"); @@ -158,64 +155,10 @@ public static void reload() { private static LiteralArgumentBuilder configLiteral(String name) { LiteralArgumentBuilder builder = literal(name).executes(Scheduler.queueOpenScreenCommand(() -> createGUI(null))) .then(literal("search").then(argument("option", StringArgumentType.greedyString()).executes((ctx) -> Scheduler.queueOpenScreen(createGUI(null, ctx.getArgument("option", String.class)))))); - registerConfigEntriesCommand(builder); + ConfigCommands.registerConfigEntries(builder); return builder; } - private static void registerConfigEntriesCommand(LiteralArgumentBuilder builder) { - try { - registerConfigEntriesCommand(builder, SkyblockerConfigManager.get()); - } catch (Exception e) { - LOGGER.error("[Skyblocker Config Manager] Failed to register config entries command!", e); - } - } - - private static void registerConfigEntriesCommand(LiteralArgumentBuilder builder, Object object) throws IllegalAccessException { - for (Field field : object.getClass().getDeclaredFields()) { - if (Modifier.isStatic(field.getModifiers())) continue; - field.setAccessible(true); - - LiteralArgumentBuilder entryBuilder = literal(field.getName()); - Class type = field.getType(); - Object value = field.get(object); - - if (type == boolean.class) { - entryBuilder.then(literal("true").executes(context -> { - SkyblockerConfigManager.update(config -> { - try { - field.setBoolean(object, true); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - }); - return Command.SINGLE_SUCCESS; - })).then(literal("false").executes(context -> { - SkyblockerConfigManager.update(config -> { - try { - field.setBoolean(object, false); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - }); - return Command.SINGLE_SUCCESS; - })).then(literal("toggle").executes(context -> { - SkyblockerConfigManager.update(config -> { - try { - field.setBoolean(object, !field.getBoolean(object)); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - }); - return Command.SINGLE_SUCCESS; - })); - } else if (value != null && SkyblockerConfigManager.isConfigClass(type)) { - registerConfigEntriesCommand(entryBuilder, value); - } - - builder.then(entryBuilder); - } - } - /** * Returns {@code true} if the given class represents one of our config * classes. This prevents {@link de.hysky.skyblocker.DisableAll#disableBooleans(Object)} from touching diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index c3d22daa44f..a3be6de7802 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -147,6 +147,8 @@ "skyblocker.config.chat.skyblockXpMessages": "SkyBlock XP Messages", "skyblocker.config.chat.skyblockXpMessages.@Tooltip": "Notifies you in the chat when you gain SkyBlock XP.", + "skyblocker.config.commands.set": "Option '%s' is now set to %s", + "skyblocker.config.crimsonIsle": "Crimson Isle", "skyblocker.config.crimsonIsle.extendNetherFog": "Extend Nether Fog", From 1e36379be935473b15ea293975b6d54760c4c17e Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Sun, 25 Jan 2026 16:18:20 -0500 Subject: [PATCH 6/8] Add config query --- .../hysky/skyblocker/config/ConfigCommands.java | 17 +++++++++++++---- .../resources/assets/skyblocker/lang/en_us.json | 1 + 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/config/ConfigCommands.java b/src/main/java/de/hysky/skyblocker/config/ConfigCommands.java index 3996c2905c4..0eb15d7be1d 100644 --- a/src/main/java/de/hysky/skyblocker/config/ConfigCommands.java +++ b/src/main/java/de/hysky/skyblocker/config/ConfigCommands.java @@ -2,7 +2,9 @@ import com.mojang.brigadier.Command; import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import de.hysky.skyblocker.utils.Constants; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.minecraft.ChatFormatting; import net.minecraft.network.chat.Component; import java.lang.reflect.Field; @@ -43,7 +45,7 @@ private static LiteralArgumentBuilder registerBoolean SkyblockerConfigManager.update(config -> { try { field.setBoolean(object, true); - context.getSource().sendFeedback(Component.translatable("skyblocker.config.commands.set", name, true)); + context.getSource().sendFeedback(Constants.PREFIX.get().append(Component.translatable("skyblocker.config.commands.set", name, true).withStyle(ChatFormatting.GREEN))); } catch (IllegalAccessException e) { throw new RuntimeException(e); } @@ -53,7 +55,7 @@ private static LiteralArgumentBuilder registerBoolean SkyblockerConfigManager.update(config -> { try { field.setBoolean(object, false); - context.getSource().sendFeedback(Component.translatable("skyblocker.config.commands.set", name, false)); + context.getSource().sendFeedback(Constants.PREFIX.get().append(Component.translatable("skyblocker.config.commands.set", name, false).withStyle(ChatFormatting.GREEN))); } catch (IllegalAccessException e) { throw new RuntimeException(e); } @@ -64,12 +66,19 @@ private static LiteralArgumentBuilder registerBoolean try { boolean toggled = !field.getBoolean(object); field.setBoolean(object, toggled); - context.getSource().sendFeedback(Component.translatable("skyblocker.config.commands.set", name, toggled)); + context.getSource().sendFeedback(Constants.PREFIX.get().append(Component.translatable("skyblocker.config.commands.set", name, toggled).withStyle(ChatFormatting.GREEN))); } catch (IllegalAccessException e) { throw new RuntimeException(e); } }); return Command.SINGLE_SUCCESS; - })); + })).executes(context -> { + try { + context.getSource().sendFeedback(Constants.PREFIX.get().append(Component.translatable("skyblocker.config.commands.query", name, field.getBoolean(object)).withStyle(ChatFormatting.GREEN))); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + return Command.SINGLE_SUCCESS; + }); } } diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index a3be6de7802..ccf8922d466 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -147,6 +147,7 @@ "skyblocker.config.chat.skyblockXpMessages": "SkyBlock XP Messages", "skyblocker.config.chat.skyblockXpMessages.@Tooltip": "Notifies you in the chat when you gain SkyBlock XP.", + "skyblocker.config.commands.query": "Option '%s' is currently set to %s", "skyblocker.config.commands.set": "Option '%s' is now set to %s", "skyblocker.config.crimsonIsle": "Crimson Isle", From 0ceab99da4cb1d2ce6af0a3c0376ac64cd545c62 Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Sun, 25 Jan 2026 16:23:38 -0500 Subject: [PATCH 7/8] Fix spotless --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 042c37bebc0..e91b6a92bff 100644 --- a/build.gradle +++ b/build.gradle @@ -295,7 +295,7 @@ spotless { // The third and remaining stems are optional, allowing matching lines with only two stems (in this case "skyblocker.config"), and separating it from other keys that start with "skyblocker.config.[whatever]". /^( "skyblocker\.config(?:\.([^."]++)(?:\.[^"]++)?)?": "(?:[^\\"]++|\\.)*+",)$\n^(?= "skyblocker\.config\.(?!\2[."]))/, '$1\n\n' - final List excludeCategories = ["debug", "eventNotifications", "quickNav", "shortcutToKeybindsSettings", "title"] + final List excludeCategories = ["commands", "debug", "eventNotifications", "quickNav", "shortcutToKeybindsSettings", "title"] final String excludeCategoriesLookahead = /(?!(?:${excludeCategories.join('|')})(?=[."]))/ replaceRegex \ "Separate different fouth stems if the first three stems are skyblocker.config.[configCategory]", From e5a9a931dbccbf85856bcc7fc9eea30abc0b1fcd Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Fri, 30 Jan 2026 13:40:47 -0500 Subject: [PATCH 8/8] Update commands --- .../skyblocker/config/ConfigCommands.java | 19 ++++++------------- .../config/SkyblockerConfigManager.java | 2 +- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/config/ConfigCommands.java b/src/main/java/de/hysky/skyblocker/config/ConfigCommands.java index 0eb15d7be1d..657f1e92233 100644 --- a/src/main/java/de/hysky/skyblocker/config/ConfigCommands.java +++ b/src/main/java/de/hysky/skyblocker/config/ConfigCommands.java @@ -1,6 +1,7 @@ package de.hysky.skyblocker.config; import com.mojang.brigadier.Command; +import com.mojang.brigadier.arguments.BoolArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import de.hysky.skyblocker.utils.Constants; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; @@ -10,6 +11,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument; import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; public class ConfigCommands { @@ -41,21 +43,12 @@ private static LiteralArgumentBuilder registerConfigE } private static LiteralArgumentBuilder registerBooleanConfigEntry(Field field, Object object, String name) { - return literal(name).then(literal("true").executes(context -> { + return literal(name).then(argument("value", BoolArgumentType.bool()).executes(context -> { SkyblockerConfigManager.update(config -> { try { - field.setBoolean(object, true); - context.getSource().sendFeedback(Constants.PREFIX.get().append(Component.translatable("skyblocker.config.commands.set", name, true).withStyle(ChatFormatting.GREEN))); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - }); - return Command.SINGLE_SUCCESS; - })).then(literal("false").executes(context -> { - SkyblockerConfigManager.update(config -> { - try { - field.setBoolean(object, false); - context.getSource().sendFeedback(Constants.PREFIX.get().append(Component.translatable("skyblocker.config.commands.set", name, false).withStyle(ChatFormatting.GREEN))); + boolean value = BoolArgumentType.getBool(context, "value"); + field.setBoolean(object, value); + context.getSource().sendFeedback(Constants.PREFIX.get().append(Component.translatable("skyblocker.config.commands.set", name, value).withStyle(ChatFormatting.GREEN))); } catch (IllegalAccessException e) { throw new RuntimeException(e); } diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java index f9a5c44fae8..404472f7c05 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java @@ -154,7 +154,7 @@ public static void reload() { */ private static LiteralArgumentBuilder configLiteral(String name) { LiteralArgumentBuilder builder = literal(name).executes(Scheduler.queueOpenScreenCommand(() -> createGUI(null))) - .then(literal("search").then(argument("option", StringArgumentType.greedyString()).executes((ctx) -> Scheduler.queueOpenScreen(createGUI(null, ctx.getArgument("option", String.class)))))); + .then(argument("option", StringArgumentType.greedyString()).executes((ctx) -> Scheduler.queueOpenScreen(createGUI(null, ctx.getArgument("option", String.class))))); ConfigCommands.registerConfigEntries(builder); return builder; }