Skip to content

Commit 5eba246

Browse files
authored
Add option to choose which update channel to receive notifications for (#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
1 parent 3560444 commit 5eba246

File tree

10 files changed

+82
-14
lines changed

10 files changed

+82
-14
lines changed

src/main/java/com/terraformersmc/modmenu/ModMenu.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public void onInitializeClient() {
9999
MODS.put(mod.getId(), mod);
100100
}
101101

102-
UpdateCheckerUtil.checkForUpdates();
102+
checkForUpdates();
103103

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

@@ -127,6 +127,10 @@ public static void clearModCountCache() {
127127
cachedDisplayedModCount = -1;
128128
}
129129

130+
public static void checkForUpdates() {
131+
UpdateCheckerUtil.checkForUpdates();
132+
}
133+
130134
public static boolean areModUpdatesAvailable() {
131135
if (!ModMenuConfig.UPDATE_CHECKER.getValue()) {
132136
return false;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.terraformersmc.modmenu.api;
2+
3+
import com.terraformersmc.modmenu.config.ModMenuConfig;
4+
5+
/**
6+
* Supported update channels, in ascending order by stability.
7+
*/
8+
public enum UpdateChannel {
9+
ALPHA,
10+
BETA,
11+
RELEASE;
12+
13+
/**
14+
* @return the user's preferred update channel.
15+
*/
16+
public static UpdateChannel getUserPreference() {
17+
return ModMenuConfig.UPDATE_CHANNEL.getValue();
18+
}
19+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package com.terraformersmc.modmenu.api;
22

33
public interface UpdateChecker {
4-
54
/**
65
* Gets called when ModMenu is checking for updates.
76
* This is done in a separate thread, so this call can/should be blocking.
87
*
8+
* <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>
9+
*
910
* @return The update info
1011
*/
1112
UpdateInfo checkForUpdates();
12-
1313
}

src/main/java/com/terraformersmc/modmenu/api/UpdateInfo.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import org.jetbrains.annotations.Nullable;
55

66
public interface UpdateInfo {
7-
87
/**
98
* @return If an update for the mod is available.
109
*/
@@ -23,4 +22,8 @@ default Text getUpdateMessage() {
2322
*/
2423
String getDownloadLink();
2524

25+
/**
26+
* @return The update channel this update is available for.
27+
*/
28+
UpdateChannel getUpdateChannel();
2629
}

src/main/java/com/terraformersmc/modmenu/config/ModMenuConfig.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.terraformersmc.modmenu.config;
22

33
import com.google.gson.annotations.SerializedName;
4+
import com.terraformersmc.modmenu.api.UpdateChannel;
45
import com.terraformersmc.modmenu.config.option.BooleanConfigOption;
56
import com.terraformersmc.modmenu.config.option.EnumConfigOption;
67
import com.terraformersmc.modmenu.config.option.OptionConvertable;
@@ -43,6 +44,7 @@ public class ModMenuConfig {
4344
public static final StringSetConfigOption DISABLE_UPDATE_CHECKER = new StringSetConfigOption("disable_update_checker", new HashSet<>());
4445
public static final BooleanConfigOption UPDATE_CHECKER = new BooleanConfigOption("update_checker", true);
4546
public static final BooleanConfigOption BUTTON_UPDATE_BADGE = new BooleanConfigOption("button_update_badge", true);
47+
public static final EnumConfigOption<UpdateChannel> UPDATE_CHANNEL = new EnumConfigOption<>("update_channel", UpdateChannel.RELEASE);
4648
public static final BooleanConfigOption QUICK_CONFIGURE = new BooleanConfigOption("quick_configure", true);
4749

4850
public static SimpleOption<?>[] asOptions() {

src/main/java/com/terraformersmc/modmenu/gui/ModMenuOptionsScreen.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.terraformersmc.modmenu.gui;
22

3+
import com.terraformersmc.modmenu.ModMenu;
34
import com.terraformersmc.modmenu.config.ModMenuConfig;
45
import com.terraformersmc.modmenu.config.ModMenuConfigManager;
56
import net.minecraft.client.MinecraftClient;
@@ -29,6 +30,7 @@ protected void init() {
2930
this.addSelectableChild(this.list);
3031
this.addDrawableChild(
3132
ButtonWidget.builder(ScreenTexts.DONE, (button) -> {
33+
ModMenu.checkForUpdates();
3234
ModMenuConfigManager.save();
3335
this.client.setScreen(this.previous);
3436
}).position(this.width / 2 - 100, this.height - 27)

src/main/java/com/terraformersmc/modmenu/util/UpdateCheckerUtil.java

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.google.gson.JsonParser;
55
import com.google.gson.annotations.SerializedName;
66
import com.terraformersmc.modmenu.ModMenu;
7+
import com.terraformersmc.modmenu.api.UpdateChannel;
78
import com.terraformersmc.modmenu.api.UpdateChecker;
89
import com.terraformersmc.modmenu.config.ModMenuConfig;
910
import com.terraformersmc.modmenu.util.mod.Mod;
@@ -85,7 +86,20 @@ public static void checkForModrinthUpdates() {
8586
.get().getMetadata().getVersion().getFriendlyString().split("\\+", 1); // Strip build metadata for privacy
8687
final var modMenuVersion = splitVersion.length > 1 ? splitVersion[1] : splitVersion[0];
8788
final var userAgent = "%s/%s (%s/%s%s)".formatted(ModMenu.GITHUB_REF, modMenuVersion, mcVer, primaryLoader, environment);
88-
String body = ModMenu.GSON_MINIFIED.toJson(new LatestVersionsFromHashesBody(modHashes.keySet(), loaders, mcVer));
89+
90+
List<UpdateChannel> updateChannels;
91+
UpdateChannel preferredChannel = UpdateChannel.getUserPreference();
92+
93+
if (preferredChannel == UpdateChannel.RELEASE) {
94+
updateChannels = List.of(UpdateChannel.RELEASE);
95+
} else if (preferredChannel == UpdateChannel.BETA) {
96+
updateChannels = List.of(UpdateChannel.BETA, UpdateChannel.RELEASE);
97+
} else {
98+
updateChannels = List.of(UpdateChannel.ALPHA, UpdateChannel.BETA, UpdateChannel.RELEASE);
99+
}
100+
101+
String body = ModMenu.GSON_MINIFIED.toJson(new LatestVersionsFromHashesBody(modHashes.keySet(), loaders, mcVer, updateChannels));
102+
89103
LOGGER.debug("User agent: " + userAgent);
90104
LOGGER.debug("Body: " + body);
91105
var latestVersionsRequest = HttpRequest.newBuilder()
@@ -109,6 +123,7 @@ public static void checkForModrinthUpdates() {
109123
responseObject.asMap().forEach((lookupHash, versionJson) -> {
110124
var versionObj = versionJson.getAsJsonObject();
111125
var projectId = versionObj.get("project_id").getAsString();
126+
var versionType = versionObj.get("version_type").getAsString();
112127
var versionNumber = versionObj.get("version_number").getAsString();
113128
var versionId = versionObj.get("id").getAsString();
114129
var primaryFile = versionObj.get("files").getAsJsonArray().asList().stream()
@@ -118,13 +133,14 @@ public static void checkForModrinthUpdates() {
118133
return;
119134
}
120135

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

123139
if (!Objects.equals(versionHash, lookupHash)) {
124140
// hashes different, there's an update.
125141
modHashes.get(lookupHash).forEach(mod -> {
126142
LOGGER.info("Update available for '{}@{}', (-> {})", mod.getId(), mod.getVersion(), versionNumber);
127-
mod.setUpdateInfo(new ModrinthUpdateInfo(projectId, versionId, versionNumber));
143+
mod.setUpdateInfo(new ModrinthUpdateInfo(projectId, versionId, versionNumber, updateChannel));
128144
});
129145
}
130146
});
@@ -134,6 +150,14 @@ public static void checkForModrinthUpdates() {
134150
}
135151
}
136152

153+
private static UpdateChannel getUpdateChannel(String versionType) {
154+
try {
155+
return UpdateChannel.valueOf(versionType.toUpperCase(Locale.ROOT));
156+
} catch (IllegalArgumentException | NullPointerException e) {
157+
return UpdateChannel.RELEASE;
158+
}
159+
}
160+
137161
public static void triggerV2DeprecatedToast() {
138162
if (modrinthApiV2Deprecated && ModMenuConfig.UPDATE_CHECKER.getValue()) {
139163
MinecraftClient.getInstance().getToastManager().add(new SystemToast(
@@ -150,11 +174,14 @@ public static class LatestVersionsFromHashesBody {
150174
public Collection<String> loaders;
151175
@SerializedName("game_versions")
152176
public Collection<String> gameVersions;
177+
@SerializedName("version_types")
178+
public Collection<String> versionTypes;
153179

154-
public LatestVersionsFromHashesBody(Collection<String> hashes, Collection<String> loaders, String mcVersion) {
180+
public LatestVersionsFromHashesBody(Collection<String> hashes, Collection<String> loaders, String mcVersion, Collection<UpdateChannel> updateChannels) {
155181
this.hashes = hashes;
156182
this.loaders = loaders;
157183
this.gameVersions = Set.of(mcVersion);
184+
this.versionTypes = updateChannels.stream().map(value -> value.toString().toLowerCase()).toList();
158185
}
159186
}
160187
}

src/main/java/com/terraformersmc/modmenu/util/mod/Mod.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ default boolean hasUpdate() {
114114
if (updateInfo == null) {
115115
return false;
116116
}
117-
return updateInfo.isUpdateAvailable();
117+
118+
return updateInfo.isUpdateAvailable() && updateInfo.getUpdateChannel().compareTo(ModMenuConfig.UPDATE_CHANNEL.getValue()) >= 0;
118119
}
119120

120121
default @Nullable String getSha512Hash() throws IOException {

src/main/java/com/terraformersmc/modmenu/util/mod/ModrinthUpdateInfo.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
package com.terraformersmc.modmenu.util.mod;
22

3+
import com.terraformersmc.modmenu.api.UpdateChannel;
34
import com.terraformersmc.modmenu.api.UpdateInfo;
45

56
public class ModrinthUpdateInfo implements UpdateInfo {
7+
protected final String projectId;
8+
protected final String versionId;
9+
protected final String versionNumber;
10+
protected final UpdateChannel updateChannel;
611

7-
protected String projectId;
8-
protected String versionId;
9-
protected String versionNumber;
10-
11-
public ModrinthUpdateInfo(String projectId, String versionId, String versionNumber) {
12+
public ModrinthUpdateInfo(String projectId, String versionId, String versionNumber, UpdateChannel updateChannel) {
1213
this.projectId = projectId;
1314
this.versionId = versionId;
1415
this.versionNumber = versionNumber;
16+
this.updateChannel = updateChannel;
1517
}
1618

1719
@Override
@@ -36,4 +38,8 @@ public String getVersionNumber() {
3638
return versionNumber;
3739
}
3840

41+
@Override
42+
public UpdateChannel getUpdateChannel() {
43+
return this.updateChannel;
44+
}
3945
}

src/main/resources/assets/modmenu/lang/en_us.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,5 +164,9 @@
164164
"option.modmenu.button_update_badge.false": "Hidden",
165165
"option.modmenu.quick_configure": "Quick Configure",
166166
"option.modmenu.quick_configure.true": "Enabled",
167-
"option.modmenu.quick_configure.false": "Disabled"
167+
"option.modmenu.quick_configure.false": "Disabled",
168+
"option.modmenu.update_channel": "Update Channel",
169+
"option.modmenu.update_channel.alpha": "All",
170+
"option.modmenu.update_channel.beta": "Release & Beta",
171+
"option.modmenu.update_channel.release": "Release"
168172
}

0 commit comments

Comments
 (0)