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

[1.20.3] Add support for custom update checking logic #708

Merged
merged 5 commits into from
Apr 18, 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
11 changes: 8 additions & 3 deletions src/main/java/com/terraformersmc/modmenu/ModMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
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 Down Expand Up @@ -68,13 +69,15 @@ public static Screen getConfigScreen(String modid, Screen menuScreen) {
public void onInitializeClient() {
ModMenuConfigManager.initializeConfig();
Set<String> modpackMods = new HashSet<>();
Map<String, UpdateChecker> updateCheckers = 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());
apiImplementations.add(api);
updateCheckers.put(modId, api.getUpdateChecker());
api.attachModpackBadges(modpackMods::add);
} catch (Throwable e) {
LOGGER.error("Mod {} provides a broken implementation of ModMenuApi", modId, e);
Expand All @@ -91,10 +94,12 @@ public void onInitializeClient() {
mod = new FabricMod(modContainer, modpackMods);
}

mod.setUpdateChecker(updateCheckers.get(mod.getId()));

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

ModrinthUtil.checkForUpdates();
UpdateCheckerUtil.checkForUpdates();

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

Expand Down Expand Up @@ -136,7 +141,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 Down
10 changes: 10 additions & 0 deletions src/main/java/com/terraformersmc/modmenu/api/ModMenuApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,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 Down
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.
*
* @return The update info
*/
UpdateInfo checkForUpdates();

}
26 changes: 26 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,26 @@
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();

}
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
Expand Up @@ -2,11 +2,13 @@

import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import com.terraformersmc.modmenu.api.UpdateInfo;
import com.terraformersmc.modmenu.config.ModMenuConfig;
import com.terraformersmc.modmenu.gui.ModsScreen;
import com.terraformersmc.modmenu.gui.widget.entries.ModListEntry;
import com.terraformersmc.modmenu.util.VersionUtil;
import com.terraformersmc.modmenu.util.mod.Mod;
import com.terraformersmc.modmenu.util.mod.ModrinthUpdateInfo;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
Expand Down Expand Up @@ -37,6 +39,7 @@ public class DescriptionListWidget extends EntryListWidget<DescriptionListWidget
private static final Text HAS_UPDATE_TEXT = Text.translatable("modmenu.hasUpdate");
private static final Text EXPERIMENTAL_TEXT = Text.translatable("modmenu.experimental").formatted(Formatting.GOLD);
private static final Text MODRINTH_TEXT = Text.translatable("modmenu.modrinth");
private static final Text DOWNLOAD_TEXT = Text.translatable("modmenu.downloadLink").formatted(Formatting.BLUE).formatted(Formatting.UNDERLINE);
private static final Text CHILD_HAS_UPDATE_TEXT = Text.translatable("modmenu.childHasUpdate");
private static final Text LINKS_TEXT = Text.translatable("modmenu.links");
private static final Text SOURCE_TEXT = Text.translatable("modmenu.source").formatted(Formatting.BLUE).formatted(Formatting.UNDERLINE);
Expand Down Expand Up @@ -95,7 +98,8 @@ public void renderList(DrawContext DrawContext, int mouseX, int mouseY, float de
}

if (ModMenuConfig.UPDATE_CHECKER.getValue() && !ModMenuConfig.DISABLE_UPDATE_CHECKER.getValue().contains(mod.getId())) {
if (mod.getModrinthData() != null) {
UpdateInfo updateInfo = mod.getUpdateInfo();
if (updateInfo != null && updateInfo.isUpdateAvailable()) {
children().add(emptyEntry);

int index = 0;
Expand All @@ -111,14 +115,31 @@ public void renderList(DrawContext DrawContext, int mouseX, int mouseY, float de
children().add(new DescriptionEntry(line, 8));
}

Text updateText = Text.translatable("modmenu.updateText", VersionUtil.stripPrefix(mod.getModrinthData().versionNumber()), MODRINTH_TEXT)
.formatted(Formatting.BLUE)
.formatted(Formatting.UNDERLINE);
if (updateInfo instanceof ModrinthUpdateInfo modrinthUpdateInfo) {
Text updateText = Text.translatable("modmenu.updateText", VersionUtil.stripPrefix(modrinthUpdateInfo.getVersionNumber()), MODRINTH_TEXT)
.formatted(Formatting.BLUE)
.formatted(Formatting.UNDERLINE);

String versionLink = "https://modrinth.com/project/%s/version/%s".formatted(mod.getModrinthData().projectId(), mod.getModrinthData().versionId());

for (OrderedText line : textRenderer.wrapLines(updateText, wrapWidth - 16)) {
children().add(new LinkEntry(line, versionLink, 8));
for (OrderedText line : textRenderer.wrapLines(updateText, wrapWidth - 16)) {
children().add(new LinkEntry(line, modrinthUpdateInfo.getDownloadLink(), 8));
}
} else {
Text updateMessage = updateInfo.getUpdateMessage();
String downloadLink = updateInfo.getDownloadLink();
if (updateMessage == null) {
updateMessage = DOWNLOAD_TEXT;
} else {
if (downloadLink != null) {
updateMessage = updateMessage.copy().formatted(Formatting.BLUE).formatted(Formatting.UNDERLINE);
}
}
for (OrderedText line : textRenderer.wrapLines(updateMessage, wrapWidth - 16)) {
if (downloadLink != null) {
children().add(new LinkEntry(line, downloadLink, 8));
} else {
children().add(new DescriptionEntry(line, 8));
}
}
}
}
if (mod.getChildHasUpdate()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public void render(DrawContext DrawContext, int index, int y, int x, int rowWidt
}
DrawContext.drawText(font, Language.getInstance().reorder(trimmedName), x + iconSize + 3, y + 1, 0xFFFFFF, false);
var updateBadgeXOffset = 0;
if (ModMenuConfig.UPDATE_CHECKER.getValue() && !ModMenuConfig.DISABLE_UPDATE_CHECKER.getValue().contains(modId) && (mod.getModrinthData() != null || mod.getChildHasUpdate())) {
if (ModMenuConfig.UPDATE_CHECKER.getValue() && !ModMenuConfig.DISABLE_UPDATE_CHECKER.getValue().contains(modId) && (mod.hasUpdate() || mod.getChildHasUpdate())) {
UpdateAvailableBadge.renderBadge(DrawContext, x + iconSize + 3 + font.getWidth(name) + 2, y);
updateBadgeXOffset = 11;
}
Expand Down
143 changes: 0 additions & 143 deletions src/main/java/com/terraformersmc/modmenu/util/ModrinthUtil.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.terraformersmc.modmenu.util;

import com.terraformersmc.modmenu.util.mod.Mod;

public class UpdateCheckerThread extends Thread {

protected UpdateCheckerThread(Mod mod, Runnable runnable) {
super(runnable);
setDaemon(true);
setName("Update Checker/%s".formatted(mod.getName()));
}

public static void run(Mod mod, Runnable runnable) {
new UpdateCheckerThread(mod, runnable).start();
}

}
Loading
Loading