diff --git a/src/main/java/com/terraformersmc/modmenu/ModMenu.java b/src/main/java/com/terraformersmc/modmenu/ModMenu.java index 018faeb8..0821c92e 100644 --- a/src/main/java/com/terraformersmc/modmenu/ModMenu.java +++ b/src/main/java/com/terraformersmc/modmenu/ModMenu.java @@ -25,6 +25,7 @@ import net.minecraft.client.resource.language.I18n; import net.minecraft.text.MutableText; import net.minecraft.text.Text; +import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -59,21 +60,31 @@ public class ModMenu implements ClientModInitializer { public static final boolean DEV_ENVIRONMENT = FabricLoader.getInstance().isDevelopmentEnvironment(); public static final boolean TEXT_PLACEHOLDER_COMPAT = FabricLoader.getInstance().isModLoaded("placeholder-api"); - public static Screen getConfigScreen(String modid, Screen menuScreen) { + public static boolean hasConfigScreen(String modId) { + return getConfigScreenFactory(modId) != null; + } + + public static @Nullable Screen getConfigScreen(String modId, Screen parent) { + ConfigScreenFactory factory = getConfigScreenFactory(modId); + if (factory != null) { + return factory.create(parent); + } + return null; + } + + private static @Nullable ConfigScreenFactory getConfigScreenFactory(String modId) { + if (ModMenuConfig.HIDDEN_CONFIGS.getValue().contains(modId)) { + return null; + } + for (ModMenuApi api : apiImplementations) { var factoryProviders = api.getProvidedConfigScreenFactories(); if (!factoryProviders.isEmpty()) { factoryProviders.forEach(configScreenFactories::putIfAbsent); } } - if (ModMenuConfig.HIDDEN_CONFIGS.getValue().contains(modid)) { - return null; - } - ConfigScreenFactory factory = configScreenFactories.get(modid); - if (factory != null) { - return factory.create(menuScreen); - } - return null; + + return configScreenFactories.get(modId); } @Override diff --git a/src/main/java/com/terraformersmc/modmenu/gui/ModsScreen.java b/src/main/java/com/terraformersmc/modmenu/gui/ModsScreen.java index 6d6f9430..cce611a7 100644 --- a/src/main/java/com/terraformersmc/modmenu/gui/ModsScreen.java +++ b/src/main/java/com/terraformersmc/modmenu/gui/ModsScreen.java @@ -102,26 +102,6 @@ public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmou @Override protected void init() { - for (Mod mod : ModMenu.MODS.values()) { - String id = mod.getId(); - if (!modHasConfigScreen.containsKey(id)) { - try { - Screen configScreen = ModMenu.getConfigScreen(id, this); - modHasConfigScreen.put(id, configScreen != null); - } catch (java.lang.NoClassDefFoundError e) { - LOGGER.warn( - "The '" + id + "' mod config screen is not available because " + e.getLocalizedMessage() + - " is missing."); - modScreenErrors.put(id, e); - modHasConfigScreen.put(id, false); - } catch (Throwable e) { - LOGGER.error("Error from mod '" + id + "'", e); - modScreenErrors.put(id, e); - modHasConfigScreen.put(id, false); - } - } - } - int paneY = ModMenuConfig.CONFIG_MODE.getValue() ? 48 : 48 + 19; this.paneWidth = this.width / 2 - 8; this.rightPaneX = this.width - this.paneWidth; @@ -203,9 +183,8 @@ protected void init() { if (!ModMenuConfig.HIDE_CONFIG_BUTTONS.getValue()) { this.configureButton = LegacyTexturedButtonWidget.legacyTexturedBuilder(ScreenTexts.EMPTY, button -> { final String id = Objects.requireNonNull(selected).getMod().getId(); - if (modHasConfigScreen.get(id)) { - Screen configScreen = ModMenu.getConfigScreen(id, this); - client.setScreen(configScreen); + if (getModHasConfigScreen(id)) { + this.safelyOpenConfigScreen(id); } else { button.active = false; } @@ -540,9 +519,9 @@ public void updateSelectedEntry(ModListEntry entry) { if (this.configureButton != null) { - this.configureButton.active = modHasConfigScreen.get(modId); + this.configureButton.active = getModHasConfigScreen(modId); this.configureButton.visible = - selected != null && modHasConfigScreen.get(modId) || modScreenErrors.containsKey(modId); + selected != null && getModHasConfigScreen(modId) || modScreenErrors.containsKey(modId); if (modScreenErrors.containsKey(modId)) { Throwable e = modScreenErrors.get(modId); @@ -646,7 +625,29 @@ private static boolean isFabricMod(Path mod) { } } - public Map getModHasConfigScreen() { - return this.modHasConfigScreen; + public boolean getModHasConfigScreen(String modId) { + if (this.modScreenErrors.containsKey(modId)) { + return false; + } else { + return this.modHasConfigScreen.computeIfAbsent(modId, ModMenu::hasConfigScreen); + } + } + + public void safelyOpenConfigScreen(String modId) { + try { + Screen screen = ModMenu.getConfigScreen(modId, this); + + if (screen != null) { + this.client.setScreen(screen); + } + } catch (java.lang.NoClassDefFoundError e) { + LOGGER.warn( + "The '" + modId + "' mod config screen is not available because " + e.getLocalizedMessage() + + " is missing."); + modScreenErrors.put(modId, e); + } catch (Throwable e) { + LOGGER.error("Error from mod '" + modId + "'", e); + modScreenErrors.put(modId, e); + } } } diff --git a/src/main/java/com/terraformersmc/modmenu/gui/widget/ModListWidget.java b/src/main/java/com/terraformersmc/modmenu/gui/widget/ModListWidget.java index df695e8f..e02d3e2c 100644 --- a/src/main/java/com/terraformersmc/modmenu/gui/widget/ModListWidget.java +++ b/src/main/java/com/terraformersmc/modmenu/gui/widget/ModListWidget.java @@ -136,11 +136,7 @@ private void filter(String searchTerm, boolean refresh, boolean search) { addedMods.clear(); Collection mods = ModMenu.MODS.values().stream().filter(mod -> { if (ModMenuConfig.CONFIG_MODE.getValue()) { - Map modHasConfigScreen = parent.getModHasConfigScreen(); - var hasConfig = modHasConfigScreen.get(mod.getId()); - if (!hasConfig) { - return false; - } + return !parent.getModHasConfigScreen(mod.getId()); } return !mod.isHidden(); diff --git a/src/main/java/com/terraformersmc/modmenu/gui/widget/entries/ModListEntry.java b/src/main/java/com/terraformersmc/modmenu/gui/widget/entries/ModListEntry.java index 724b1bc1..12167219 100644 --- a/src/main/java/com/terraformersmc/modmenu/gui/widget/entries/ModListEntry.java +++ b/src/main/java/com/terraformersmc/modmenu/gui/widget/entries/ModListEntry.java @@ -124,8 +124,7 @@ public void render( } if (!(this instanceof ParentEntry) && ModMenuConfig.QUICK_CONFIGURE.getValue() && (this.list.getParent() - .getModHasConfigScreen() - .get(modId) || this.list.getParent().modScreenErrors.containsKey(modId))) { + .getModHasConfigScreen(modId) || this.list.getParent().modScreenErrors.containsKey(modId))) { final int textureSize = ModMenuConfig.COMPACT_LIST.getValue() ? (int) (256 / (FULL_ICON_SIZE / (double) COMPACT_ICON_SIZE)) : 256; @@ -167,9 +166,7 @@ public void render( @Override public boolean mouseClicked(double mouseX, double mouseY, int delta) { list.select(this); - if (ModMenuConfig.QUICK_CONFIGURE.getValue() && this.list.getParent() - .getModHasConfigScreen() - .get(this.mod.getId())) { + if (ModMenuConfig.QUICK_CONFIGURE.getValue() && this.list.getParent().getModHasConfigScreen(this.mod.getId())) { int iconSize = ModMenuConfig.COMPACT_LIST.getValue() ? COMPACT_ICON_SIZE : FULL_ICON_SIZE; if (mouseX - list.getRowLeft() <= iconSize) { this.openConfig(); @@ -182,7 +179,7 @@ public boolean mouseClicked(double mouseX, double mouseY, int delta) { } public void openConfig() { - MinecraftClient.getInstance().setScreen(ModMenu.getConfigScreen(mod.getId(), list.getParent())); + this.list.getParent().safelyOpenConfigScreen(mod.getId()); } public Mod getMod() { diff --git a/src/main/java/com/terraformersmc/modmenu/util/mod/ModSearch.java b/src/main/java/com/terraformersmc/modmenu/util/mod/ModSearch.java index 91612888..cd771e71 100644 --- a/src/main/java/com/terraformersmc/modmenu/util/mod/ModSearch.java +++ b/src/main/java/com/terraformersmc/modmenu/util/mod/ModSearch.java @@ -68,8 +68,7 @@ private static int passesFilters(ModsScreen screen, Mod mod, String query) { || deprecated.contains(query) && mod.getBadges() .contains(Mod.Badge.DEPRECATED) // Search for deprecated mods || clientside.contains(query) && mod.getBadges().contains(Mod.Badge.CLIENT) // Search for clientside mods - || configurable.contains(query) && screen.getModHasConfigScreen() - .get(modId) // Search for mods that can be configured + || configurable.contains(query) && screen.getModHasConfigScreen(modId) // Search for mods that can be configured || hasUpdate.contains(query) && mod.hasUpdate() // Search for mods that have updates ) { return 1;