diff --git a/src/main/java/com/gtnewhorizon/gtnhlib/config/Config.java b/src/main/java/com/gtnewhorizon/gtnhlib/config/Config.java index 09dd51d..a0bf1ca 100644 --- a/src/main/java/com/gtnewhorizon/gtnhlib/config/Config.java +++ b/src/main/java/com/gtnewhorizon/gtnhlib/config/Config.java @@ -216,4 +216,12 @@ ModDetectedDefault[] values() default {}; } + + /** + * Excludes this class from the auto config GUI, only applicable to a {@link Config} annotated class. Has no effect + * if a gui factory is registered for the mod. + */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE) + @interface ExcludeFromAutoGui {} } diff --git a/src/main/java/com/gtnewhorizon/gtnhlib/config/ConfigurationManager.java b/src/main/java/com/gtnewhorizon/gtnhlib/config/ConfigurationManager.java index 03d4027..4bbc23c 100644 --- a/src/main/java/com/gtnewhorizon/gtnhlib/config/ConfigurationManager.java +++ b/src/main/java/com/gtnewhorizon/gtnhlib/config/ConfigurationManager.java @@ -43,6 +43,7 @@ public class ConfigurationManager { static final Logger LOGGER = LogManager.getLogger("GTNHLibConfig"); private static final Map configs = new HashMap<>(); private static final Map>>> configToCategoryClassMap = new HashMap<>(); + private static final Map>> modIdToConfigClasses = new HashMap<>(); private static final String[] langKeyPlaceholders = new String[] { "%mod", "%file", "%cat", "%field" }; private static final Boolean PRINT_KEYS = Boolean.getBoolean("gtnhlib.printkeys"); private static final Boolean DUMP_KEYS = Boolean.getBoolean("gtnhlib.dumpkeys"); @@ -68,6 +69,10 @@ public static void registerConfig(Class configClass) throws ConfigException { val modid = cfg.modid(); val filename = Optional.of(cfg.filename().trim()).filter(s -> !s.isEmpty()).orElse(modid); + if (!configClass.isAnnotationPresent(Config.ExcludeFromAutoGui.class)) { + modIdToConfigClasses.computeIfAbsent(modid, (ignored) -> new HashSet<>()).add(configClass); + } + Configuration rawConfig = configs.computeIfAbsent(getConfigKey(cfg), (ignored) -> { Path newConfigDir = configDir; if (!cfg.configSubDirectory().trim().isEmpty()) { @@ -447,6 +452,14 @@ private static File minecraftHome() { return Launch.minecraftHome != null ? Launch.minecraftHome : new File("."); } + public static boolean isModRegistered(String modid) { + return modIdToConfigClasses.containsKey(modid); + } + + static Class[] getConfigClasses(String modid) { + return modIdToConfigClasses.getOrDefault(modid, Collections.emptySet()).toArray(new Class[0]); + } + public static void onInit() { cullDeadCategories(); if (DUMP_KEYS) { diff --git a/src/main/java/com/gtnewhorizon/gtnhlib/config/SimpleGuiConfig.java b/src/main/java/com/gtnewhorizon/gtnhlib/config/SimpleGuiConfig.java index 9802317..285302c 100644 --- a/src/main/java/com/gtnewhorizon/gtnhlib/config/SimpleGuiConfig.java +++ b/src/main/java/com/gtnewhorizon/gtnhlib/config/SimpleGuiConfig.java @@ -11,13 +11,7 @@ public class SimpleGuiConfig extends GuiConfig { public SimpleGuiConfig(GuiScreen parent, Class configClass, String modID, String modName) throws ConfigException { - super( - parent, - ConfigurationManager.getConfigElements(configClass), - modID, - false, - false, - modName + " Configuration"); + this(parent, modID, modName, false, configClass); } public SimpleGuiConfig(GuiScreen parent, String modID, String modName, Class... configClasses) @@ -25,6 +19,10 @@ public SimpleGuiConfig(GuiScreen parent, String modID, String modName, Class. this(parent, modID, modName, false, configClasses); } + public SimpleGuiConfig(GuiScreen parent, String modID, String modName) throws ConfigException { + this(parent, modID, modName, true, ConfigurationManager.getConfigClasses(modID)); + } + public SimpleGuiConfig(GuiScreen parent, String modID, String modName, boolean categorized, Class... configClasses) throws ConfigException { super( diff --git a/src/main/java/com/gtnewhorizon/gtnhlib/mixins/Mixins.java b/src/main/java/com/gtnewhorizon/gtnhlib/mixins/Mixins.java index 8f9aa11..11b7fb1 100644 --- a/src/main/java/com/gtnewhorizon/gtnhlib/mixins/Mixins.java +++ b/src/main/java/com/gtnewhorizon/gtnhlib/mixins/Mixins.java @@ -18,8 +18,12 @@ public enum Mixins { .setApplyIf(() -> true).addMixinClasses("MixinTessellator")), WAVEFRONT_VBO(new Builder("WavefrontObject").addTargetedMod(TargetedMod.VANILLA).setSide(Side.CLIENT) .setPhase(Phase.EARLY).setApplyIf(() -> true).addMixinClasses("MixinWavefrontObject")), + + GUI_MOD_LIST(new Builder("Auto config ui").addTargetedMod(TargetedMod.VANILLA).setSide(Side.CLIENT) + .setPhase(Phase.EARLY).addMixinClasses("fml.MixinGuiModList")), + EVENT_BUS_ACCESSOR(new Builder("EventBusAccessor").addTargetedMod(TargetedMod.VANILLA).setSide(Side.BOTH) - .setPhase(Phase.EARLY).addMixinClasses("fml.EventBusAccessor", "fml.EnumHolderAccessor")),; + .setPhase(Phase.EARLY).addMixinClasses("fml.EventBusAccessor", "fml.EnumHolderAccessor")); private final List mixinClasses; private final Supplier applyIf; diff --git a/src/main/java/com/gtnewhorizon/gtnhlib/mixins/early/fml/MixinGuiModList.java b/src/main/java/com/gtnewhorizon/gtnhlib/mixins/early/fml/MixinGuiModList.java new file mode 100644 index 0000000..04ca184 --- /dev/null +++ b/src/main/java/com/gtnewhorizon/gtnhlib/mixins/early/fml/MixinGuiModList.java @@ -0,0 +1,63 @@ +package com.gtnewhorizon.gtnhlib.mixins.early.fml; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; + +import org.spongepowered.asm.lib.Opcodes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.gtnewhorizon.gtnhlib.config.ConfigException; +import com.gtnewhorizon.gtnhlib.config.ConfigurationManager; +import com.gtnewhorizon.gtnhlib.config.SimpleGuiConfig; +import com.llamalad7.mixinextras.sugar.Local; + +import cpw.mods.fml.client.GuiModList; +import cpw.mods.fml.client.IModGuiFactory; +import cpw.mods.fml.common.ModContainer; + +@Mixin(GuiModList.class) +public abstract class MixinGuiModList extends GuiScreen { + + @Shadow(remap = false) + private ModContainer selectedMod; + + @Shadow(remap = false) + private GuiButton configModButton; + + @Inject( + method = "actionPerformed", + at = @At( + value = "INVOKE", + target = "Lcpw/mods/fml/client/IModGuiFactory;mainConfigGuiClass()Ljava/lang/Class;", + remap = false), + cancellable = true) + private void gtnhlib$autoCreateGuiConfig(GuiButton button, CallbackInfo ci, @Local IModGuiFactory guiFactory) { + if (guiFactory == null && ConfigurationManager.isModRegistered(selectedMod.getModId())) { + ci.cancel(); + try { + GuiScreen config = new SimpleGuiConfig(this, selectedMod.getModId(), selectedMod.getName()); + mc.displayGuiScreen(config); + } catch (ConfigException e) { + throw new RuntimeException(e); + } + } + } + + @Inject( + method = "drawScreen", + at = @At( + value = "FIELD", + opcode = Opcodes.PUTFIELD, + target = "Lnet/minecraft/client/gui/GuiButton;enabled:Z", + shift = At.Shift.AFTER, + ordinal = 4)) + private void gtnhlib$checkForRegisteredConfig(int p_571_1_, int p_571_2_, float p_571_3_, CallbackInfo ci) { + if (ConfigurationManager.isModRegistered(selectedMod.getModId())) { + configModButton.enabled = true; + } + } +}