Skip to content

Commit

Permalink
Add option to choose which update channel to receive notifications for (
Browse files Browse the repository at this point in the history
#704)

* Allow choosing an update channel to receive notifications for

* Pass user preferred update channel to UpdateChecker

* Change method of getting the preferred update channel

* Request preferred version types from Modrinth only

* Switch update channel and quick configure button order

* Rerun update checks when clicking done in the modmenu options screen

- No longer promotes updates to beta or alpha versions by default
  • Loading branch information
LostLuma authored Apr 22, 2024
1 parent 3560444 commit 5eba246
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 14 deletions.
6 changes: 5 additions & 1 deletion src/main/java/com/terraformersmc/modmenu/ModMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public void onInitializeClient() {
MODS.put(mod.getId(), mod);
}

UpdateCheckerUtil.checkForUpdates();
checkForUpdates();

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

Expand Down Expand Up @@ -127,6 +127,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 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();
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +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();

}
5 changes: 4 additions & 1 deletion src/main/java/com/terraformersmc/modmenu/api/UpdateInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import org.jetbrains.annotations.Nullable;

public interface UpdateInfo {

/**
* @return If an update for the mod is available.
*/
Expand All @@ -23,4 +22,8 @@ default Text getUpdateMessage() {
*/
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
@@ -1,5 +1,6 @@
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;
Expand Down Expand Up @@ -29,6 +30,7 @@ protected void init() {
this.addSelectableChild(this.list);
this.addDrawableChild(
ButtonWidget.builder(ScreenTexts.DONE, (button) -> {
ModMenu.checkForUpdates();
ModMenuConfigManager.save();
this.client.setScreen(this.previous);
}).position(this.width / 2 - 100, this.height - 27)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.google.gson.JsonParser;
import com.google.gson.annotations.SerializedName;
import com.terraformersmc.modmenu.ModMenu;
import com.terraformersmc.modmenu.api.UpdateChannel;
import com.terraformersmc.modmenu.api.UpdateChecker;
import com.terraformersmc.modmenu.config.ModMenuConfig;
import com.terraformersmc.modmenu.util.mod.Mod;
Expand Down Expand Up @@ -85,7 +86,20 @@ public static void checkForModrinthUpdates() {
.get().getMetadata().getVersion().getFriendlyString().split("\\+", 1); // Strip build metadata for privacy
final var modMenuVersion = splitVersion.length > 1 ? splitVersion[1] : splitVersion[0];
final var userAgent = "%s/%s (%s/%s%s)".formatted(ModMenu.GITHUB_REF, modMenuVersion, mcVer, primaryLoader, environment);
String body = ModMenu.GSON_MINIFIED.toJson(new LatestVersionsFromHashesBody(modHashes.keySet(), loaders, mcVer));

List<UpdateChannel> updateChannels;
UpdateChannel preferredChannel = UpdateChannel.getUserPreference();

if (preferredChannel == UpdateChannel.RELEASE) {
updateChannels = List.of(UpdateChannel.RELEASE);
} else if (preferredChannel == UpdateChannel.BETA) {
updateChannels = List.of(UpdateChannel.BETA, UpdateChannel.RELEASE);
} else {
updateChannels = List.of(UpdateChannel.ALPHA, UpdateChannel.BETA, UpdateChannel.RELEASE);
}

String body = ModMenu.GSON_MINIFIED.toJson(new LatestVersionsFromHashesBody(modHashes.keySet(), loaders, mcVer, updateChannels));

LOGGER.debug("User agent: " + userAgent);
LOGGER.debug("Body: " + body);
var latestVersionsRequest = HttpRequest.newBuilder()
Expand All @@ -109,6 +123,7 @@ public static void checkForModrinthUpdates() {
responseObject.asMap().forEach((lookupHash, versionJson) -> {
var versionObj = versionJson.getAsJsonObject();
var projectId = versionObj.get("project_id").getAsString();
var versionType = versionObj.get("version_type").getAsString();
var versionNumber = versionObj.get("version_number").getAsString();
var versionId = versionObj.get("id").getAsString();
var primaryFile = versionObj.get("files").getAsJsonArray().asList().stream()
Expand All @@ -118,13 +133,14 @@ public static void checkForModrinthUpdates() {
return;
}

var updateChannel = UpdateCheckerUtil.getUpdateChannel(versionType);
var versionHash = primaryFile.get().getAsJsonObject().get("hashes").getAsJsonObject().get("sha512").getAsString();

if (!Objects.equals(versionHash, lookupHash)) {
// hashes different, there's an update.
modHashes.get(lookupHash).forEach(mod -> {
LOGGER.info("Update available for '{}@{}', (-> {})", mod.getId(), mod.getVersion(), versionNumber);
mod.setUpdateInfo(new ModrinthUpdateInfo(projectId, versionId, versionNumber));
mod.setUpdateInfo(new ModrinthUpdateInfo(projectId, versionId, versionNumber, updateChannel));
});
}
});
Expand All @@ -134,6 +150,14 @@ public static void checkForModrinthUpdates() {
}
}

private static UpdateChannel getUpdateChannel(String versionType) {
try {
return UpdateChannel.valueOf(versionType.toUpperCase(Locale.ROOT));
} catch (IllegalArgumentException | NullPointerException e) {
return UpdateChannel.RELEASE;
}
}

public static void triggerV2DeprecatedToast() {
if (modrinthApiV2Deprecated && ModMenuConfig.UPDATE_CHECKER.getValue()) {
MinecraftClient.getInstance().getToastManager().add(new SystemToast(
Expand All @@ -150,11 +174,14 @@ public static class LatestVersionsFromHashesBody {
public Collection<String> loaders;
@SerializedName("game_versions")
public Collection<String> gameVersions;
@SerializedName("version_types")
public Collection<String> versionTypes;

public LatestVersionsFromHashesBody(Collection<String> hashes, Collection<String> loaders, String mcVersion) {
public LatestVersionsFromHashesBody(Collection<String> hashes, Collection<String> loaders, String mcVersion, Collection<UpdateChannel> updateChannels) {
this.hashes = hashes;
this.loaders = loaders;
this.gameVersions = Set.of(mcVersion);
this.versionTypes = updateChannels.stream().map(value -> value.toString().toLowerCase()).toList();
}
}
}
3 changes: 2 additions & 1 deletion src/main/java/com/terraformersmc/modmenu/util/mod/Mod.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ default boolean hasUpdate() {
if (updateInfo == null) {
return false;
}
return updateInfo.isUpdateAvailable();

return updateInfo.isUpdateAvailable() && updateInfo.getUpdateChannel().compareTo(ModMenuConfig.UPDATE_CHANNEL.getValue()) >= 0;
}

default @Nullable String getSha512Hash() throws IOException {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package com.terraformersmc.modmenu.util.mod;

import com.terraformersmc.modmenu.api.UpdateChannel;
import com.terraformersmc.modmenu.api.UpdateInfo;

public class ModrinthUpdateInfo implements UpdateInfo {
protected final String projectId;
protected final String versionId;
protected final String versionNumber;
protected final UpdateChannel updateChannel;

protected String projectId;
protected String versionId;
protected String versionNumber;

public ModrinthUpdateInfo(String projectId, String versionId, String versionNumber) {
public ModrinthUpdateInfo(String projectId, String versionId, String versionNumber, UpdateChannel updateChannel) {
this.projectId = projectId;
this.versionId = versionId;
this.versionNumber = versionNumber;
this.updateChannel = updateChannel;
}

@Override
Expand All @@ -36,4 +38,8 @@ public String getVersionNumber() {
return versionNumber;
}

@Override
public UpdateChannel getUpdateChannel() {
return this.updateChannel;
}
}
6 changes: 5 additions & 1 deletion src/main/resources/assets/modmenu/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -164,5 +164,9 @@
"option.modmenu.button_update_badge.false": "Hidden",
"option.modmenu.quick_configure": "Quick Configure",
"option.modmenu.quick_configure.true": "Enabled",
"option.modmenu.quick_configure.false": "Disabled"
"option.modmenu.quick_configure.false": "Disabled",
"option.modmenu.update_channel": "Update Channel",
"option.modmenu.update_channel.alpha": "All",
"option.modmenu.update_channel.beta": "Release & Beta",
"option.modmenu.update_channel.release": "Release"
}

0 comments on commit 5eba246

Please sign in to comment.