diff --git a/Common/src/main/java/me/hypherionmc/craterlib/common/config/ConfigController.java b/Common/src/main/java/me/hypherionmc/craterlib/common/config/ConfigController.java index f1f85b5..ca7e747 100644 --- a/Common/src/main/java/me/hypherionmc/craterlib/common/config/ConfigController.java +++ b/Common/src/main/java/me/hypherionmc/craterlib/common/config/ConfigController.java @@ -39,4 +39,7 @@ public class ConfigController implements Serializable { } } + public static HashMap getMonitoredConfigs() { + return monitoredConfigs; + } } diff --git a/Common/src/main/java/me/hypherionmc/craterlib/common/config/ModuleConfig.java b/Common/src/main/java/me/hypherionmc/craterlib/common/config/ModuleConfig.java index 3e654f9..4f48bcf 100644 --- a/Common/src/main/java/me/hypherionmc/craterlib/common/config/ModuleConfig.java +++ b/Common/src/main/java/me/hypherionmc/craterlib/common/config/ModuleConfig.java @@ -18,6 +18,8 @@ public class ModuleConfig { private final transient String configName; + private final transient String modId; + /** * Set up the config * @@ -36,6 +38,7 @@ public class ModuleConfig { File configDir = new File("config" + (subFolder.isEmpty() ? "" : File.separator + subFolder)); configPath = new File(configDir + File.separator + configName + ".toml"); networkID = modId + ":conf_" + configName.replace("-", "_"); + this.modId = modId; this.configName = configName; /* Check if the required directories exists, otherwise we create them */ @@ -154,4 +157,12 @@ public class ModuleConfig { public String getConfigName() { return configName; } + + /** + * Get the MODID of the Module the config is registered to + * @return + */ + public String getModId() { + return modId; + } } diff --git a/Common/src/main/java/me/hypherionmc/craterlib/common/config/annotations/NoConfigScreen.java b/Common/src/main/java/me/hypherionmc/craterlib/common/config/annotations/NoConfigScreen.java new file mode 100644 index 0000000..89ac2b3 --- /dev/null +++ b/Common/src/main/java/me/hypherionmc/craterlib/common/config/annotations/NoConfigScreen.java @@ -0,0 +1,13 @@ +package me.hypherionmc.craterlib.common.config.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * @author HypherionSA + * @date 06/08/2022 + * Allows Modules to disable Automatic Config Screens + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface NoConfigScreen { +} diff --git a/Fabric/build.gradle b/Fabric/build.gradle index d2dea89..8b6b445 100644 --- a/Fabric/build.gradle +++ b/Fabric/build.gradle @@ -14,6 +14,10 @@ dependencies { include 'me.hypherionmc.night-config:toml:3.6.5_custom' include 'me.hypherionmc.night-config:core:3.6.5_custom' implementation project(":Common") + + modApi("com.terraformersmc:modmenu:${mod_menu_version}") { + exclude(group: "net.fabricmc.fabric-api") + } } loom { diff --git a/Fabric/src/main/java/me/hypherionmc/craterlib/CraterLibModMenuIntegration.java b/Fabric/src/main/java/me/hypherionmc/craterlib/CraterLibModMenuIntegration.java new file mode 100644 index 0000000..81b42a9 --- /dev/null +++ b/Fabric/src/main/java/me/hypherionmc/craterlib/CraterLibModMenuIntegration.java @@ -0,0 +1,31 @@ +package me.hypherionmc.craterlib; + +import com.terraformersmc.modmenu.api.ConfigScreenFactory; +import com.terraformersmc.modmenu.api.ModMenuApi; +import me.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; +import me.hypherionmc.craterlib.common.config.ConfigController; +import me.hypherionmc.craterlib.common.config.ModuleConfig; +import me.hypherionmc.craterlib.common.config.annotations.NoConfigScreen; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author HypherionSA + * @date 06/08/2022 + */ +public class CraterLibModMenuIntegration implements ModMenuApi { + + @Override + public Map> getProvidedConfigScreenFactories() { + Map> configScreens = new HashMap<>(); + + ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { + if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { + configScreens.put(((ModuleConfig) conf).getModId(), screen -> new CraterConfigScreen((ModuleConfig) conf, screen)); + } + }); + + return configScreens; + } +} diff --git a/Fabric/src/main/resources/fabric.mod.json b/Fabric/src/main/resources/fabric.mod.json index 67d361c..92ec6fe 100644 --- a/Fabric/src/main/resources/fabric.mod.json +++ b/Fabric/src/main/resources/fabric.mod.json @@ -24,6 +24,9 @@ ], "client": [ "me.hypherionmc.craterlib.client.CraterLibClientInitializer" + ], + "modmenu": [ + "me.hypherionmc.craterlib.CraterLibModMenuIntegration" ] }, "mixins": [ diff --git a/Forge/src/main/java/me/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java b/Forge/src/main/java/me/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java new file mode 100644 index 0000000..03540f1 --- /dev/null +++ b/Forge/src/main/java/me/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java @@ -0,0 +1,45 @@ +package me.hypherionmc.craterlib.mixin; + +import me.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; +import me.hypherionmc.craterlib.common.config.ConfigController; +import me.hypherionmc.craterlib.common.config.ModuleConfig; +import me.hypherionmc.craterlib.common.config.annotations.NoConfigScreen; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.Screen; +import net.minecraftforge.client.ConfigScreenHandler; +import net.minecraftforge.forgespi.language.IModInfo; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Optional; +import java.util.function.BiFunction; + +/** + * @author HypherionSA + * @date 06/08/2022 + */ +@Mixin(ConfigScreenHandler.class) +public class ConfigScreenHandlerMixin { + + /** + * Inject Auto Generated config Screens into forge + * @param selectedMod + * @param cir + */ + @Inject(at = @At("RETURN"), method = "getScreenFactoryFor", cancellable = true, remap = false) + private static void injectConfigScreen(IModInfo selectedMod, CallbackInfoReturnable>> cir) { + ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { + if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { + ModuleConfig config = (ModuleConfig) conf; + if (config.getModId().equals(selectedMod.getModId())) { + cir.setReturnValue( + Optional.of((minecraft, screen) -> new CraterConfigScreen(config, screen)) + ); + } + } + }); + } + +} diff --git a/Forge/src/main/resources/craterlib.forge.mixins.json b/Forge/src/main/resources/craterlib.forge.mixins.json index 7b33759..7ed9188 100644 --- a/Forge/src/main/resources/craterlib.forge.mixins.json +++ b/Forge/src/main/resources/craterlib.forge.mixins.json @@ -6,6 +6,7 @@ "mixins": [ ], "client": [ + "ConfigScreenHandlerMixin" ], "server": [ ], diff --git a/README.md b/README.md index 7e6082c..cd7db5f 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ A library mod used by HypherionSA's mods. Mostly used by Hyper Lighting 2. * Various utilities for Blockstates, LANG, Math and Rendering * Cross Mod-Loader Events * Cross Mod-Loader Config Screens (Based on [Cloth Config Lite](https://github.com/shedaniel/cloth-config-lite)) +* Automatic ModMenu and Forge Config screen registration * TODO: Built in Cross Mod-Loader Network system * TODO: Various GUI widgets and Utilities * TODO: Cross Mod-Loader Dynamic Lighting diff --git a/build.gradle b/build.gradle index 471bdc9..5747795 100644 --- a/build.gradle +++ b/build.gradle @@ -62,6 +62,10 @@ subprojects { name = 'Hypherion Maven' url = 'https://maven.firstdarkdev.xyz/releases/' } + maven { + name = "TerraformersMC Maven" + url = "https://maven.terraformersmc.com/releases" + } } dependencies { diff --git a/gradle.properties b/gradle.properties index c265052..774342b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -26,3 +26,6 @@ mod_id=craterlib # Gradle org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false + +# Dependencies +mod_menu_version=4.0.5