Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/1.20.3' into 1.20.5
Browse files Browse the repository at this point in the history
# Conflicts:
#	gradle.properties
#	src/main/java/com/terraformersmc/modmenu/gui/ModMenuOptionsScreen.java
#	src/main/resources/fabric.mod.json
  • Loading branch information
Prospector committed Apr 22, 2024
2 parents c36bdf3 + 77f63a4 commit 07e4804
Show file tree
Hide file tree
Showing 27 changed files with 985 additions and 245 deletions.
45 changes: 31 additions & 14 deletions src/main/java/com/terraformersmc/modmenu/ModMenu.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package com.terraformersmc.modmenu;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.LinkedListMultimap;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;
import com.terraformersmc.modmenu.api.UpdateChecker;
import com.terraformersmc.modmenu.config.ModMenuConfig;
import com.terraformersmc.modmenu.config.ModMenuConfigManager;
import com.terraformersmc.modmenu.event.ModMenuEventHandler;
import com.terraformersmc.modmenu.util.ModMenuScreenTexts;
import com.terraformersmc.modmenu.util.ModrinthUtil;
import com.terraformersmc.modmenu.util.UpdateCheckerUtil;
import com.terraformersmc.modmenu.util.mod.Mod;
import com.terraformersmc.modmenu.util.mod.fabric.FabricDummyParentMod;
import com.terraformersmc.modmenu.util.mod.fabric.FabricMod;
Expand All @@ -29,7 +29,6 @@

import java.text.NumberFormat;
import java.util.*;
import java.util.function.Supplier;

public class ModMenu implements ClientModInitializer {
public static final String MOD_ID = "modmenu";
Expand All @@ -42,17 +41,19 @@ public class ModMenu implements ClientModInitializer {
public static final Map<String, Mod> ROOT_MODS = new HashMap<>();
public static final LinkedListMultimap<Mod, Mod> PARENT_MAP = LinkedListMultimap.create();

private static Map<String, ConfigScreenFactory<?>> configScreenFactories = new HashMap<>();
private static List<Map<String, ConfigScreenFactory<?>>> delayedScreenFactoryProviders = new ArrayList<>();
private static final Map<String, ConfigScreenFactory<?>> configScreenFactories = new HashMap<>();
private static final List<ModMenuApi> apiImplementations = new ArrayList<>();

private static int cachedDisplayedModCount = -1;
public static boolean runningQuilt = FabricLoader.getInstance().isModLoaded("quilt_loader");
public static boolean devEnvironment = FabricLoader.getInstance().isDevelopmentEnvironment();

public static Screen getConfigScreen(String modid, Screen menuScreen) {
if(!delayedScreenFactoryProviders.isEmpty()) {
delayedScreenFactoryProviders.forEach(map -> map.forEach(configScreenFactories::putIfAbsent));
delayedScreenFactoryProviders.clear();
for (ModMenuApi api : apiImplementations) {
var factoryProviders = api.getProvidedConfigScreenFactories();
if (!factoryProviders.isEmpty()) {
factoryProviders.forEach(configScreenFactories::putIfAbsent);
}
}
if (ModMenuConfig.HIDDEN_CONFIGS.getValue().contains(modid)) {
return null;
Expand All @@ -68,13 +69,18 @@ public static Screen getConfigScreen(String modid, Screen menuScreen) {
public void onInitializeClient() {
ModMenuConfigManager.initializeConfig();
Set<String> modpackMods = new HashSet<>();
Map<String, UpdateChecker> updateCheckers = new HashMap<>();
Map<String, UpdateChecker> providedUpdateCheckers = new HashMap<>();

FabricLoader.getInstance().getEntrypointContainers("modmenu", ModMenuApi.class).forEach(entrypoint -> {
ModMetadata metadata = entrypoint.getProvider().getMetadata();
String modId = metadata.getId();
try {
ModMenuApi api = entrypoint.getEntrypoint();
configScreenFactories.put(modId, api.getModConfigScreenFactory());
delayedScreenFactoryProviders.add(api.getProvidedConfigScreenFactories());
apiImplementations.add(api);
updateCheckers.put(modId, api.getUpdateChecker());
providedUpdateCheckers.putAll(api.getProvidedUpdateCheckers());
api.attachModpackBadges(modpackMods::add);
} catch (Throwable e) {
LOGGER.error("Mod {} provides a broken implementation of ModMenuApi", modId, e);
Expand All @@ -91,10 +97,17 @@ public void onInitializeClient() {
mod = new FabricMod(modContainer, modpackMods);
}

var updateChecker = updateCheckers.get(mod.getId());

if (updateChecker == null) {
updateChecker = providedUpdateCheckers.get(mod.getId());
}

MODS.put(mod.getId(), mod);
mod.setUpdateChecker(updateChecker);
}

ModrinthUtil.checkForUpdates();
checkForUpdates();

Map<String, Mod> dummyParents = new HashMap<>();

Expand Down Expand Up @@ -122,6 +135,10 @@ public static void clearModCountCache() {
cachedDisplayedModCount = -1;
}

public static void checkForUpdates() {
UpdateCheckerUtil.checkForUpdates();
}

public static boolean areModUpdatesAvailable() {
if (!ModMenuConfig.UPDATE_CHECKER.getValue()) {
return false;
Expand All @@ -136,7 +153,7 @@ public static boolean areModUpdatesAvailable() {
continue;
}

if (mod.getModrinthData() != null || mod.getChildHasUpdate()) {
if (mod.hasUpdate() || mod.getChildHasUpdate()) {
return true; // At least one currently visible mod has an update
}
}
Expand All @@ -148,9 +165,9 @@ public static String getDisplayedModCount() {
if (cachedDisplayedModCount == -1) {
// listen, if you have >= 2^32 mods then that's on you
cachedDisplayedModCount = Math.toIntExact(MODS.values().stream().filter(mod ->
(ModMenuConfig.COUNT_CHILDREN.getValue() || mod.getParent() == null) &&
(ModMenuConfig.COUNT_LIBRARIES.getValue() || !mod.getBadges().contains(Mod.Badge.LIBRARY)) &&
(ModMenuConfig.COUNT_HIDDEN_MODS.getValue() || !mod.isHidden())
(ModMenuConfig.COUNT_CHILDREN.getValue() || mod.getParent() == null) &&
(ModMenuConfig.COUNT_LIBRARIES.getValue() || !mod.getBadges().contains(Mod.Badge.LIBRARY)) &&
(ModMenuConfig.COUNT_HIDDEN_MODS.getValue() || !mod.isHidden())
).count());
}
return NumberFormat.getInstance().format(cachedDisplayedModCount);
Expand Down
17 changes: 14 additions & 3 deletions src/main/java/com/terraformersmc/modmenu/ModMenuModMenuCompat.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
package com.terraformersmc.modmenu;

import com.google.common.collect.ImmutableMap;
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;
import com.terraformersmc.modmenu.api.UpdateChecker;
import com.terraformersmc.modmenu.gui.ModMenuOptionsScreen;
import com.terraformersmc.modmenu.util.mod.fabric.FabricLoaderUpdateChecker;
import com.terraformersmc.modmenu.util.mod.quilt.QuiltLoaderUpdateChecker;

import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.option.OptionsScreen;

import java.util.Map;

public class ModMenuModMenuCompat implements ModMenuApi {

@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
return ModMenuOptionsScreen::new;
}

@Override
public Map<String, ConfigScreenFactory<?>> getProvidedConfigScreenFactories() {
return ImmutableMap.of("minecraft", parent -> new OptionsScreen(parent, MinecraftClient.getInstance().options));
return Map.of("minecraft", parent -> new OptionsScreen(parent, MinecraftClient.getInstance().options));
}

@Override
public Map<String, UpdateChecker> getProvidedUpdateCheckers() {
if (ModMenu.runningQuilt) {
return Map.of("quilt_loader", new QuiltLoaderUpdateChecker());
} else {
return Map.of("fabricloader", new FabricLoaderUpdateChecker());
}
}
}
23 changes: 21 additions & 2 deletions src/main/java/com/terraformersmc/modmenu/api/ModMenuApi.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.terraformersmc.modmenu.api;

import com.google.common.collect.ImmutableMap;
import com.terraformersmc.modmenu.ModMenu;
import com.terraformersmc.modmenu.gui.ModsScreen;
import net.minecraft.client.gui.screen.Screen;
Expand Down Expand Up @@ -43,6 +42,16 @@ default ConfigScreenFactory<?> getModConfigScreenFactory() {
return screen -> null;
}

/**
* Used for mods that have their own update checking logic.
* By returning your own {@link UpdateChecker} instance, you can override ModMenus built-in update checking logic.
*
* @return An {@link UpdateChecker} or <code>null</code> if ModMenu should handle update checking.
*/
default UpdateChecker getUpdateChecker() {
return null;
}

/**
* Used to provide config screen factories for other mods. This takes second
* priority to a mod's own config screen factory provider. For example, if
Expand All @@ -56,7 +65,17 @@ default ConfigScreenFactory<?> getModConfigScreenFactory() {
* @return a map of mod ids to screen factories.
*/
default Map<String, ConfigScreenFactory<?>> getProvidedConfigScreenFactories() {
return ImmutableMap.of();
return Map.of();
}

/**
* Used to provide update checkers for other mods. A mod registering its own
* update checker will take priority over any provided ones should both exist.
*
* @return a map of mod ids to update checkers.
*/
default Map<String, UpdateChecker> getProvidedUpdateCheckers() {
return Map.of();
}

/**
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/com/terraformersmc/modmenu/api/UpdateChannel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.terraformersmc.modmenu.api;

import com.terraformersmc.modmenu.config.ModMenuConfig;

/**
* Supported update channels, in ascending order by stability.
*/
public enum UpdateChannel {
ALPHA,
BETA,
RELEASE;

/**
* @return the user's preferred update channel.
*/
public static UpdateChannel getUserPreference() {
return ModMenuConfig.UPDATE_CHANNEL.getValue();
}
}
13 changes: 13 additions & 0 deletions src/main/java/com/terraformersmc/modmenu/api/UpdateChecker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.terraformersmc.modmenu.api;

public interface UpdateChecker {
/**
* Gets called when ModMenu is checking for updates.
* This is done in a separate thread, so this call can/should be blocking.
*
* <p>Your update checker should aim to return an update on the same or a more stable channel than the user's preference which you can get via {@link UpdateChannel#getUserPreference()}.</p>
*
* @return The update info
*/
UpdateInfo checkForUpdates();
}
29 changes: 29 additions & 0 deletions src/main/java/com/terraformersmc/modmenu/api/UpdateInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.terraformersmc.modmenu.api;

import net.minecraft.text.Text;
import org.jetbrains.annotations.Nullable;

public interface UpdateInfo {
/**
* @return If an update for the mod is available.
*/
boolean isUpdateAvailable();

/**
* @return The message that is getting displayed when an update is available or <code>null</code> to let ModMenu handle displaying the message.
*/
@Nullable
default Text getUpdateMessage() {
return null;
}

/**
* @return The URL to the mod download.
*/
String getDownloadLink();

/**
* @return The update channel this update is available for.
*/
UpdateChannel getUpdateChannel();
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.terraformersmc.modmenu.config;

import com.google.gson.annotations.SerializedName;
import com.terraformersmc.modmenu.api.UpdateChannel;
import com.terraformersmc.modmenu.config.option.BooleanConfigOption;
import com.terraformersmc.modmenu.config.option.EnumConfigOption;
import com.terraformersmc.modmenu.config.option.OptionConvertable;
Expand Down Expand Up @@ -43,6 +44,7 @@ public class ModMenuConfig {
public static final StringSetConfigOption DISABLE_UPDATE_CHECKER = new StringSetConfigOption("disable_update_checker", new HashSet<>());
public static final BooleanConfigOption UPDATE_CHECKER = new BooleanConfigOption("update_checker", true);
public static final BooleanConfigOption BUTTON_UPDATE_BADGE = new BooleanConfigOption("button_update_badge", true);
public static final EnumConfigOption<UpdateChannel> UPDATE_CHANNEL = new EnumConfigOption<>("update_channel", UpdateChannel.RELEASE);
public static final BooleanConfigOption QUICK_CONFIGURE = new BooleanConfigOption("quick_configure", true);

public static SimpleOption<?>[] asOptions() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import com.terraformersmc.modmenu.gui.ModsScreen;
import com.terraformersmc.modmenu.gui.widget.ModMenuButtonWidget;
import com.terraformersmc.modmenu.gui.widget.UpdateCheckerTexturedButtonWidget;
import com.terraformersmc.modmenu.util.ModrinthUtil;
import com.terraformersmc.modmenu.util.UpdateCheckerUtil;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
Expand Down Expand Up @@ -91,7 +91,7 @@ private static void afterTitleScreenInit(Screen screen) {
}
}
}
ModrinthUtil.triggerV2DeprecatedToast();
UpdateCheckerUtil.triggerV2DeprecatedToast();
}

private static void onClientEndTick(MinecraftClient client) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package com.terraformersmc.modmenu.gui;

import com.terraformersmc.modmenu.ModMenu;
import com.terraformersmc.modmenu.config.ModMenuConfig;
import com.terraformersmc.modmenu.config.ModMenuConfigManager;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.option.GameOptionsScreen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.OptionListWidget;
import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;

public class ModMenuOptionsScreen extends GameOptionsScreen {
Expand Down Expand Up @@ -42,5 +41,6 @@ public void render(DrawContext DrawContext, int mouseX, int mouseY, float delta)
@Override
public void removed() {
ModMenuConfigManager.save();
ModMenu.checkForUpdates();
}
}
Loading

0 comments on commit 07e4804

Please sign in to comment.