Skip to content

Commit

Permalink
Merge branch '1.21' into 1.21.2
Browse files Browse the repository at this point in the history
# Conflicts:
#	gradle.properties
  • Loading branch information
Prospector committed Oct 14, 2024
2 parents c532d3f + 39f0fcf commit f900e42
Show file tree
Hide file tree
Showing 31 changed files with 265 additions and 171 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Mod Menu
![Screenshot of the Mods screen, showing a list of a few mods on the left side below a search bar and filters button, where Mod Menu is selected. On the right side of the screen, it shows more details about the mod, such as authors, a description, links, credits, and a button to configure the mod.](https://cdn.modrinth.com/data/mOgUt4GM/images/1b837be3f93c3e99e0ab70600698bd9f37723cec.png)
![Screenshot of the Mods screen, showing a list of a few mods on the left side below a search bar and filters button, where Mod Menu is selected. On the right side of the screen, it shows more details about the mod, such as authors, a description, links, credits, and a button to configure the mod.](res/screenshot1.jpg)

Mod Menu lets you view the mods you have installed and, if supported by the mod, enables quick and easy access to the mod's config screens.

Expand Down
Binary file added res/screenshot1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
62 changes: 49 additions & 13 deletions src/main/java/com/terraformersmc/modmenu/ModMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -127,21 +138,46 @@ public void onInitializeClient() {
Map<String, Mod> dummyParents = new HashMap<>();

// Initialize parent map
HashSet<String> modParentSet = new HashSet<>();
for (Mod mod : MODS.values()) {
String parentId = mod.getParent();
if (parentId != null) {
Mod parent = MODS.getOrDefault(parentId, dummyParents.get(parentId));
if (parentId == null) {
ROOT_MODS.put(mod.getId(), mod);
continue;
}

Mod parent;
modParentSet.clear();
while (true) {
parent = MODS.getOrDefault(parentId, dummyParents.get(parentId));
if (parent == null) {
if (mod instanceof FabricMod) {
parent = new FabricDummyParentMod((FabricMod) mod, parentId);
dummyParents.put(parentId, parent);
}
}
PARENT_MAP.put(parent, mod);
} else {

parentId = parent != null ? parent.getParent() : null;
if (parentId == null) {
// It will most likely end here in the first iteration
break;
}

if (modParentSet.contains(parentId)) {
LOGGER.warn("Mods contain each other as parents: {}", modParentSet);
parent = null;
break;
}
modParentSet.add(parentId);
}

if (parent == null) {
ROOT_MODS.put(mod.getId(), mod);
continue;
}
PARENT_MAP.put(parent, mod);
}

MODS.putAll(dummyParents);
ModMenuEventHandler.register();
}
Expand Down
69 changes: 38 additions & 31 deletions src/main/java/com/terraformersmc/modmenu/gui/ModsScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,26 +103,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;
Expand Down Expand Up @@ -204,9 +184,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;
}
Expand Down Expand Up @@ -541,9 +520,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);
Expand Down Expand Up @@ -601,7 +580,7 @@ public void filesDragged(List<Path> paths) {
Path modsDirectory = FabricLoader.getInstance().getGameDir().resolve("mods");

// Filter out none mods
List<Path> mods = paths.stream().filter(ModsScreen::isFabricMod).collect(Collectors.toList());
List<Path> mods = paths.stream().filter(ModsScreen::isValidMod).collect(Collectors.toList());

if (mods.isEmpty()) {
return;
Expand Down Expand Up @@ -631,23 +610,51 @@ public void filesDragged(List<Path> paths) {
SystemToast.add(client.getToastManager(),
SystemToast.Type.PERIODIC_NOTIFICATION,
ModMenuScreenTexts.DROP_SUCCESSFUL_LINE_1,
ModMenuScreenTexts.DROP_SUCCESSFUL_LINE_1
ModMenuScreenTexts.DROP_SUCCESSFUL_LINE_2
);
}
}
this.client.setScreen(this);
}, ModMenuScreenTexts.DROP_CONFIRM, Text.literal(modList)));
}

private static boolean isFabricMod(Path mod) {
private static boolean isValidMod(Path mod) {
try (JarFile jarFile = new JarFile(mod.toFile())) {
return jarFile.getEntry("fabric.mod.json") != null;
var isFabricMod = jarFile.getEntry("fabric.mod.json") != null;

if (!ModMenu.RUNNING_QUILT) {
return isFabricMod;
} else {
return isFabricMod || jarFile.getEntry("quilt.mod.json") != null;
}
} catch (IOException e) {
return false;
}
}

public Map<String, Boolean> 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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,7 @@ private void filter(String searchTerm, boolean refresh, boolean search) {
addedMods.clear();
Collection<Mod> mods = ModMenu.MODS.values().stream().filter(mod -> {
if (ModMenuConfig.CONFIG_MODE.getValue()) {
Map<String, Boolean> modHasConfigScreen = parent.getModHasConfigScreen();
var hasConfig = modHasConfigScreen.get(mod.getId());
if (!hasConfig) {
return false;
}
return !parent.getModHasConfigScreen(mod.getId());
}

return !mod.isHidden();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,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;
Expand Down Expand Up @@ -168,9 +167,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();
Expand All @@ -183,7 +180,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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Binary file modified src/main/resources/assets/modmenu/fabric.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/main/resources/assets/modmenu/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/main/resources/assets/modmenu/java_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/main/resources/assets/modmenu/lang/be_by.json
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@
"option.modmenu.update_checker.false": "Адключана",
"option.modmenu.button_update_badge": "Індыкатар абнаўленняў",
"option.modmenu.button_update_badge.true": "Паказаны",
"option.modmenu.button_update_badge.false": "Схаваны"
"option.modmenu.button_update_badge.false": "Схаваны",
"option.modmenu.quick_configure": "Хуткія налады",
"option.modmenu.quick_configure.true": "Уключана",
"option.modmenu.quick_configure.false": "Адключана",
Expand Down
Loading

0 comments on commit f900e42

Please sign in to comment.