diff options
47 files changed, 942 insertions, 1611 deletions
diff --git a/build.gradle b/build.gradle index f8b092a7..ee016d82 100644 --- a/build.gradle +++ b/build.gradle @@ -125,6 +125,16 @@ repositories { includeGroup "net.azureaaron" } } + + maven { + url = "https://maven.notenoughupdates.org/releases" + + content { + includeGroup "org.notenoughupdates.moulconfig" + } + } + + //mavenLocal() } dependencies { @@ -145,9 +155,15 @@ dependencies { // Fabric API modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" + // Dandelion + include modImplementation("net.azureaaron:dandelion:${project.dandelion_version}") + // YACL include modImplementation("dev.isxander:yet-another-config-lib:${project.yacl_version}-fabric") + // MoulConfig - Dandelion shades it in already + modImplementation("org.notenoughupdates.moulconfig:${project.moulconfig_flavour}:${project.moulconfig_version}") + // HM API (Hypixel Mod API Library) include modImplementation("net.azureaaron:hm-api:${project.hm_api_version}") @@ -189,6 +205,9 @@ dependencies { // Apache Commons Text include implementation("org.apache.commons:commons-text:${project.commons_text_version}") + + // Fabric Language Kotlin for using MoulConfig - we are still a Java-exclusive mod + modImplementation("net.fabricmc:fabric-language-kotlin:${project.flk_version}") } loom { diff --git a/gradle.properties b/gradle.properties index a4f76ae6..1d884401 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,8 +12,13 @@ loader_version=0.16.10 fabric_api_version=0.119.9+1.21.5 # Minecraft Mods +## Dandelion +dandelion_version=1.0.0-alpha.3 ## YACL (https://github.com/isXander/YetAnotherConfigLib) yacl_version=3.7.1+1.21.5 +## MoulConfig (https://github.com/NotEnoughUpdates/MoulConfig) +moulconfig_flavour=modern-1.21.5 +moulconfig_version=3.12.0 ## HM API (https://github.com/AzureAaron/hm-api) hm_api_version=1.0.1+1.21.2 ## Mod Menu (https://modrinth.com/mod/modmenu/versions) @@ -34,6 +39,8 @@ repoparser_version = 1.6.0 networth_calculator_version = 1.0.5 ## Legacy Item DFU (https://github.com/AzureAaron/legacy-item-dfu) legacy_item_dfu_version = 1.0.3+1.21.5 +## Fabric Language Kotlin +flk_version=1.13.4+kotlin.2.2.0 # Other Libraries ## JGit (https://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit) diff --git a/src/main/java/de/hysky/skyblocker/config/ConfigNullFieldsFix.java b/src/main/java/de/hysky/skyblocker/config/ConfigNullFieldsFix.java index a16b3359..ab8709d7 100644 --- a/src/main/java/de/hysky/skyblocker/config/ConfigNullFieldsFix.java +++ b/src/main/java/de/hysky/skyblocker/config/ConfigNullFieldsFix.java @@ -18,6 +18,7 @@ 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(); diff --git a/src/main/java/de/hysky/skyblocker/config/ConfigUtils.java b/src/main/java/de/hysky/skyblocker/config/ConfigUtils.java index 1aa588b7..952a6bc9 100644 --- a/src/main/java/de/hysky/skyblocker/config/ConfigUtils.java +++ b/src/main/java/de/hysky/skyblocker/config/ConfigUtils.java @@ -1,75 +1,58 @@ package de.hysky.skyblocker.config; -import dev.isxander.yacl3.api.ButtonOption; -import dev.isxander.yacl3.api.Option; -import dev.isxander.yacl3.api.OptionDescription; -import dev.isxander.yacl3.api.controller.*; +import java.util.function.Function; + +import org.apache.commons.lang3.StringUtils; + +import net.azureaaron.dandelion.systems.ButtonOption; +import net.azureaaron.dandelion.systems.controllers.BooleanController; +import net.azureaaron.dandelion.systems.controllers.BooleanController.BooleanStyle; +import net.azureaaron.dandelion.systems.controllers.ColourController; +import net.azureaaron.dandelion.systems.controllers.EnumController; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.option.KeybindsScreen; import net.minecraft.text.Text; import net.minecraft.util.Formatting; -import net.minecraft.util.Identifier; - -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.StringUtils; -import org.jetbrains.annotations.Nullable; - -import de.hysky.skyblocker.SkyblockerMod; -import de.hysky.skyblocker.utils.FileUtils; - -import java.nio.file.Path; -import java.util.function.Function; public class ConfigUtils { - public static final ValueFormatter<Formatting> FORMATTING_FORMATTER = formatting -> Text.literal(StringUtils.capitalize(formatting.getName().replaceAll("_", " "))); - public static final ValueFormatter<Float> FLOAT_TWO_FORMATTER = value -> Text.literal(String.format("%,.2f", value).replaceAll("[\u00a0\u202F]", " ")); - private static final Path IMAGE_DIRECTORY = ImageRepoLoader.REPO_DIRECTORY.resolve("Skyblocker-Assets-images"); + public static final Function<Formatting, Text> FORMATTING_FORMATTER = formatting -> Text.literal(StringUtils.capitalize(formatting.getName().replaceAll("_", " "))); - public static BooleanControllerBuilder createBooleanController(Option<Boolean> opt) { - return BooleanControllerBuilder.create(opt).yesNoFormatter().coloured(true); + public static BooleanController createBooleanController() { + return BooleanController.createBuilder() + .coloured(true) + .booleanStyle(BooleanStyle.YES_NO) + .build(); } - @SuppressWarnings("unchecked") - public static <E extends Enum<E>> EnumControllerBuilder<E> createEnumCyclingListController(Option<E> opt) { - return EnumControllerBuilder.create(opt).enumClass((Class<E>) opt.stateManager().get().getClass()); + public static ColourController createColourController(boolean hasAlpha) { + return ColourController.createBuilder() + .hasAlpha(hasAlpha) + .build(); } - public static <E extends Enum<E>> Function<Option<E>, ControllerBuilder<E>> getFormattedEnumCyclingControllerFactory(Class<E> enumType, ValueFormatter<E> formatter) { - return opt -> EnumControllerBuilder.create(opt).enumClass(enumType).formatValue(formatter); + @SuppressWarnings("unchecked") + public static <T extends Enum<T>> EnumController<T> createEnumController() { + return (EnumController<T>) EnumController.createBuilder().build(); } + @SuppressWarnings("unchecked") + public static <T extends Enum<T>> EnumController<T> createEnumController(Function<T, Text> formatter) { + return (EnumController<T>) EnumController.createBuilder().formatter(Function.class.cast(formatter)).build(); + } - /** - * Creates a factory for {@link EnumDropdownControllerBuilder}s with the given function for converting enum constants to texts. - * Use this if a custom formatter function for an enum is needed. - * Use it like this: - * <pre>{@code Option.<MyEnum>createBuilder().controller(ConfigUtils.getEnumDropdownControllerFactory(MY_CUSTOM_ENUM_TO_TEXT_FUNCTION))}</pre> - * - * @param formatter The function used to convert enum constants to texts used for display, suggestion, and validation - * @param <E> the enum type - * @return a factory for {@link EnumDropdownControllerBuilder}s - */ - public static <E extends Enum<E>> Function<Option<E>, ControllerBuilder<E>> getEnumDropdownControllerFactory(ValueFormatter<E> formatter) { - return opt -> EnumDropdownControllerBuilder.create(opt).formatValue(formatter); + @SuppressWarnings("unchecked") + public static <T extends Enum<T>> EnumController<T> createEnumDropdownController(Function<T, Text> formatter) { + return (EnumController<T>) EnumController.createBuilder().dropdown(true).formatter(Function.class.cast(formatter)).build(); } public static ButtonOption createShortcutToKeybindsScreen() { MinecraftClient client = MinecraftClient.getInstance(); return ButtonOption.createBuilder() .name(Text.translatable("skyblocker.config.shortcutToKeybindsSettings")) - .action((screen, opt) -> client.setScreen(new KeybindsScreen(screen, client.options))) - .text(Text.translatable("skyblocker.config.shortcutToKeybindsSettings.@Text")) + .action(screen -> client.setScreen(new KeybindsScreen(screen, client.options))) + .prompt(Text.translatable("skyblocker.config.shortcutToKeybindsSettings.@Text")) .build(); } - /** - * Creates an {@link OptionDescription} with an image and text. - */ - @SafeVarargs - public static OptionDescription withImage(Path imagePath, @Nullable Text... texts) { - return OptionDescription.createBuilder() - .text(ArrayUtils.isNotEmpty(texts) ? texts : new Text[] {}) - .image(IMAGE_DIRECTORY.resolve(imagePath), Identifier.of(SkyblockerMod.NAMESPACE, "config_image_" + FileUtils.normalizePath(imagePath))) - .build(); - } + //FIXME Would probably be a good idea to add a utility method for creating a waypoint type option } diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index 342eea53..43c827c7 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java @@ -1,57 +1,39 @@ package de.hysky.skyblocker.config; import de.hysky.skyblocker.config.configs.*; -import dev.isxander.yacl3.config.v2.api.SerialEntry; public class SkyblockerConfig { - @SerialEntry - public int version = SkyblockerConfigManager.CONFIG_VERSION; + public int version = SkyblockerConfigManager.CONFIG_VERSION; - @SerialEntry - public GeneralConfig general = new GeneralConfig(); + public GeneralConfig general = new GeneralConfig(); - @SerialEntry - public UIAndVisualsConfig uiAndVisuals = new UIAndVisualsConfig(); + public UIAndVisualsConfig uiAndVisuals = new UIAndVisualsConfig(); - @SerialEntry - public HelperConfig helpers = new HelperConfig(); + public HelperConfig helpers = new HelperConfig(); - @SerialEntry - public DungeonsConfig dungeons = new DungeonsConfig(); + public DungeonsConfig dungeons = new DungeonsConfig(); - @SerialEntry - public ForagingConfig foraging = new ForagingConfig(); + public ForagingConfig foraging = new ForagingConfig(); - @SerialEntry - public CrimsonIsleConfig crimsonIsle = new CrimsonIsleConfig(); + public CrimsonIsleConfig crimsonIsle = new CrimsonIsleConfig(); - @SerialEntry - public MiningConfig mining = new MiningConfig(); + public MiningConfig mining = new MiningConfig(); - @SerialEntry - public FarmingConfig farming = new FarmingConfig(); + public FarmingConfig farming = new FarmingConfig(); - @SerialEntry - public HuntingConfig hunting = new HuntingConfig(); + public HuntingConfig hunting = new HuntingConfig(); - @SerialEntry - public OtherLocationsConfig otherLocations = new OtherLocationsConfig(); + public OtherLocationsConfig otherLocations = new OtherLocationsConfig(); - @SerialEntry - public SlayersConfig slayers = new SlayersConfig(); + public SlayersConfig slayers = new SlayersConfig(); - @SerialEntry - public ChatConfig chat = new ChatConfig(); + public ChatConfig chat = new ChatConfig(); - @SerialEntry - public QuickNavigationConfig quickNav = new QuickNavigationConfig(); + public QuickNavigationConfig quickNav = new QuickNavigationConfig(); - @SerialEntry - public EventNotificationsConfig eventNotifications = new EventNotificationsConfig(); + public EventNotificationsConfig eventNotifications = new EventNotificationsConfig(); - @SerialEntry - public MiscConfig misc = new MiscConfig(); + public MiscConfig misc = new MiscConfig(); - @SerialEntry - public DebugConfig debug = new DebugConfig(); + public DebugConfig debug = new DebugConfig(); } diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java index 5d35baf8..2f557fe2 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java @@ -1,18 +1,13 @@ package de.hysky.skyblocker.config; -import com.google.gson.FieldNamingPolicy; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.categories.*; -import de.hysky.skyblocker.config.serialization.CodecTypeAdapter; -import de.hysky.skyblocker.config.serialization.ItemTypeAdapter; -import de.hysky.skyblocker.config.serialization.VanillaGsonConfigSerializer; import de.hysky.skyblocker.debug.Debug; import de.hysky.skyblocker.mixins.accessors.HandledScreenAccessor; -import de.hysky.skyblocker.utils.CodecUtils; import de.hysky.skyblocker.utils.scheduler.Scheduler; -import dev.isxander.yacl3.api.YetAnotherConfigLib; -import dev.isxander.yacl3.config.v2.api.ConfigClassHandler; +import net.azureaaron.dandelion.systems.ConfigManager; +import net.azureaaron.dandelion.systems.DandelionConfigScreen; import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; @@ -23,38 +18,22 @@ import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; import net.minecraft.client.gui.tooltip.Tooltip; import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.item.Item; -import net.minecraft.text.Style; import net.minecraft.text.Text; -import net.minecraft.text.TextCodecs; -import net.minecraft.util.Identifier; -import java.awt.Color; import java.lang.StackWalker.Option; import java.nio.file.Path; import java.util.function.Consumer; +import java.util.function.UnaryOperator; import org.apache.commons.lang3.function.Consumers; public class SkyblockerConfigManager { public static final int CONFIG_VERSION = 4; private static final Path CONFIG_FILE = FabricLoader.getInstance().getConfigDir().resolve("skyblocker.json"); - private static final ConfigClassHandler<SkyblockerConfig> HANDLER = ConfigClassHandler.createBuilder(SkyblockerConfig.class) - .serializer(config -> new VanillaGsonConfigSerializer<>(config, CONFIG_FILE, builder -> builder - .setFieldNamingPolicy(FieldNamingPolicy.IDENTITY) - .setPrettyPrinting() - .serializeNulls() - .registerTypeHierarchyAdapter(Color.class, new CodecTypeAdapter<>(CodecUtils.COLOR_CODEC)) - .registerTypeHierarchyAdapter(Text.class, new CodecTypeAdapter<>(TextCodecs.CODEC)) - .registerTypeHierarchyAdapter(Style.class, new CodecTypeAdapter<>(Style.Codecs.CODEC)) - .registerTypeHierarchyAdapter(Identifier.class, new CodecTypeAdapter<>(Identifier.CODEC)) - .registerTypeHierarchyAdapter(Item.class, new ItemTypeAdapter()) - ) - ) - .build(); + private static final ConfigManager<SkyblockerConfig> CONFIG_MANAGER = ConfigManager.create(SkyblockerConfig.class, CONFIG_FILE, UnaryOperator.identity()); public static SkyblockerConfig get() { - return HANDLER.instance(); + return CONFIG_MANAGER.instance(); } /** @@ -66,7 +45,7 @@ public class SkyblockerConfigManager { throw new RuntimeException("Skyblocker: Called config init from an illegal place!"); } - HANDLER.load(); + CONFIG_MANAGER.load(); ClientCommandRegistrationCallback.EVENT.register(((dispatcher, registryAccess) -> dispatcher.register(ClientCommandManager.literal(SkyblockerMod.NAMESPACE).then(optionsLiteral("config")).then(optionsLiteral("options"))))); ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> { if (get().uiAndVisuals.showConfigButton && screen instanceof GenericContainerScreen genericContainerScreen && screen.getTitle().getString().equals("SkyBlock Menu")) { @@ -89,32 +68,29 @@ public class SkyblockerConfigManager { */ public static void update(Consumer<SkyblockerConfig> action) { action.accept(get()); - HANDLER.save(); + CONFIG_MANAGER.save(); } public static Screen createGUI(Screen parent) { - return YetAnotherConfigLib.create(HANDLER, (defaults, config, builder) -> { - builder.title(Text.translatable("skyblocker.config.title")) - .category(GeneralCategory.create(defaults, config)) - .category(UIAndVisualsCategory.create(defaults, config)) - .category(HelperCategory.create(defaults, config)) - .category(DungeonsCategory.create(defaults, config)) - .category(ForagingCategory.create(defaults, config)) - .category(CrimsonIsleCategory.create(defaults, config)) - .category(MiningCategory.create(defaults, config)) - .category(FarmingCategory.create(defaults, config)) - .category(HuntingCategory.create(defaults, config)) - .category(OtherLocationsCategory.create(defaults, config)) - .category(SlayersCategory.create(defaults, config)) - .category(ChatCategory.create(defaults, config)) - .category(QuickNavigationCategory.create(defaults, config)) - .category(EventNotificationsCategory.create(defaults, config)) - .category(MiscCategory.create(defaults, config)); - if (Debug.debugEnabled()) { - builder.category(DebugCategory.create(defaults, config)); - } - return builder; - }).generateScreen(parent); + return DandelionConfigScreen.create(CONFIG_MANAGER, (defaults, config, builder) -> builder + .title(Text.translatable("skyblocker.config.title", SkyblockerMod.VERSION)) + .category(GeneralCategory.create(defaults, config)) + .category(UIAndVisualsCategory.create(defaults, config)) + .category(HelperCategory.create(defaults, config)) + .category(DungeonsCategory.create(defaults, config)) + .category(ForagingCategory.create(defaults, config)) + .category(CrimsonIsleCategory.create(defaults, config)) + .category(MiningCategory.create(defaults, config)) + .category(FarmingCategory.create(defaults, config)) + .category(HuntingCategory.create(defaults, config)) + .category(OtherLocationsCategory.create(defaults, config)) + .category(SlayersCategory.create(defaults, config)) + .category(ChatCategory.create(defaults, config)) + .category(QuickNavigationCategory.create(defaults, config)) + .category(EventNotificationsCategory.create(defaults, config)) + .category(MiscCategory.create(defaults, config)) + .categoryIf(Debug.debugEnabled(), DebugCategory.create(defaults, config)) + ).generateScreen(parent, get().misc.configBackend); } /** diff --git a/src/main/java/de/hysky/skyblocker/config/categories/ChatCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/ChatCategory.java index b25cff4e..d50578e4 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/ChatCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/ChatCategory.java @@ -1,34 +1,40 @@ package de.hysky.skyblocker.config.categories; +import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.ConfigUtils; import de.hysky.skyblocker.config.SkyblockerConfig; import de.hysky.skyblocker.skyblock.chat.ChatRulesConfigScreen; import de.hysky.skyblocker.utils.chat.ChatFilterResult; -import dev.isxander.yacl3.api.*; -import dev.isxander.yacl3.api.controller.IntegerSliderControllerBuilder; +import net.azureaaron.dandelion.systems.ButtonOption; +import net.azureaaron.dandelion.systems.ConfigCategory; +import net.azureaaron.dandelion.systems.Option; +import net.azureaaron.dandelion.systems.OptionGroup; +import net.azureaaron.dandelion.systems.controllers.IntegerController; import net.minecraft.client.MinecraftClient; import net.minecraft.text.Text; +import net.minecraft.util.Identifier; public class ChatCategory { public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) { return ConfigCategory.createBuilder() + .id(Identifier.of(SkyblockerMod.NAMESPACE, "config/chat")) .name(Text.translatable("skyblocker.config.chat")) .option(Option.<Boolean>createBuilder() .name(Text.translatable("skyblocker.config.chat.skyblockXpMessages")) - .description(OptionDescription.of(Text.translatable("skyblocker.config.chat.skyblockXpMessages.@Tooltip"))) + .description(Text.translatable("skyblocker.config.chat.skyblockXpMessages.@Tooltip")) .binding(defaults.chat.skyblockXpMessages, () -> config.chat.skyblockXpMessages, newValue -> config.chat.skyblockXpMessages = newValue) - .controller(ConfigUtils::createBooleanController) + .controller(ConfigUtils.createBooleanController()) .build()) .option(Option.<Boolean>createBuilder() .name(Text.translatable("skyblocker.config.chat.confirmationPromptHelper")) - .description(OptionDescription.of(Text.translatable("skyblocker.config.chat.confirmationPromptHelper.@Tooltip"))) + .description(Text.translatable("skyblocker.config.chat.confirmationPromptHelper.@Tooltip")) .binding(defaults.chat.confirmationPromptHelper, () -> config.chat.confirmationPromptHelper, newValue -> config.chat.confirmationPromptHelper = newValue) - .controller(ConfigUtils::createBooleanController) + .controller(ConfigUtils.createBooleanController()) .build()) //Uncategorized Options @@ -39,112 +45,112 @@ public class ChatCategory { .binding(defaults.chat.hideAbility, () -> config.chat.hideAbility, newValue -> config.chat.hideAbility = newValue) - .controller(ConfigUtils::createEnumCyclingListController) + .controller(ConfigUtils.createEnumController()) .build()) .option(Option.<ChatFilterResult>createBuilder() .name(Text.translatable("skyblocker.config.chat.filter.hideHeal")) .binding(defaults.chat.hideHeal, () -> config.chat.hideHeal, newValue -> config.chat.hideHeal = newValue) - .controller(ConfigUtils::createEnumCyclingListController) + .contro |
