Skip to content

Commit

Permalink
auto create config gui if no gui factory is registered (#79)
Browse files Browse the repository at this point in the history
Co-authored-by: Martin Robertz <[email protected]>
  • Loading branch information
Lyfts and Dream-Master authored Oct 21, 2024
1 parent 4ddb3e8 commit 3d6099b
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 8 deletions.
8 changes: 8 additions & 0 deletions src/main/java/com/gtnewhorizon/gtnhlib/config/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public class ConfigurationManager {
static final Logger LOGGER = LogManager.getLogger("GTNHLibConfig");
private static final Map<String, Configuration> configs = new HashMap<>();
private static final Map<Configuration, Map<String, Set<Class<?>>>> configToCategoryClassMap = new HashMap<>();
private static final Map<String, Set<Class<?>>> 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");
Expand All @@ -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()) {
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,18 @@ 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)
throws ConfigException {
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(
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/com/gtnewhorizon/gtnhlib/mixins/Mixins.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> mixinClasses;
private final Supplier<Boolean> applyIf;
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}
}

0 comments on commit 3d6099b

Please sign in to comment.