Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto create config gui if no gui factory is registered #79

Merged
merged 4 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
}
}
}