diff --git a/CHANGELOG.md b/CHANGELOG.md index 25fb821..d176a37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +**1.1.5** +* Add JSON Strategy + **1.1.4** * Add Refresh Button To GUI * Add ``/modupdater`` Command diff --git a/MOD_DEVELOPERS.md b/MOD_DEVELOPERS.md new file mode 100644 index 0000000..d9a5e07 --- /dev/null +++ b/MOD_DEVELOPERS.md @@ -0,0 +1,110 @@ +# Mod Developers +To opt-in a mod for ModUpdater, you must select an update strategy in ```fabric.mod.json```. + +## CurseForge +This update strategy uses the CurseForge API to check for updates. + +### ```fabric.mod.json``` +```json +{ + "custom": { + "modupdater": { + "strategy": "curseforge", + "projectID": 306612 + } + } +} +``` + +- Requires Semantic Versioning +- [Requires ```build.gradle``` modification](#buildgradle-modification) + +## GitHub Releases +This update strategy uses the GitHub Releases API to check for updates. + +### ```fabric.mod.json``` +```json +{ + "custom": { + "modupdater": { + "strategy": "github", + "owner": "Repository Owner", + "repository": "Repository Name" + } + } +} +``` + +- Requires Semantic Versioning +- [Requires ```build.gradle``` Modification](#buildgradle-modification) + +## Maven +This update strategy uses the specified Maven repository to check for updates. + +### ```fabric.mod.json``` +```json +{ + "custom": { + "modupdater": { + "strategy": "maven", + "repository": "https://maven.fabricmc.net", + "group": "net.fabricmc.fabric-api", + "artifact": "fabric-api" + } + } +} +``` + +- Requires Semantic Versioning +- [Requires ```build.gradle``` Modification](#buildgradle-modification) + +## JSON +This update strategy uses the specified JSON file to check for updates. + +### ```fabric.mod.json``` +```json +{ + "custom": { + "modupdater": { + "strategy": "json", + "url": "https://example.com/thing.json" + } + } +} +``` + +### JSON Format +```json +{ + "1.16.1": { + "version": "1.0.1", + "downloadUrl": "https://example.com/thing2.jar" + }, + "20w20a": { + "version": "1.0.0", + "downloadUrl": "https://example.com/thing.jar" + } +} +``` + +- Does Not Require Semantic Versioning +- ```build.gradle``` Modification Is Not Required + +## ```build.gradle``` Modification +Multiple update strategies require the Minecraft version to be appended to the end of the JAR version to detect what Minecraft version a JAR supports. + +Replace: +```gradle +version = project.mod_version +``` +with: +```gradle +version = "${project.mod_version}+${project.minecraft_version}" +``` + +If you prefer hyphens you can also use: +```gradle +version = "${project.mod_version}-${project.minecraft_version}" +``` + +You can also just use the major version of Minecraft instead of the full version (like ```1.16``` instead of ```1.16.1``` or ```20w20a```). \ No newline at end of file diff --git a/README.md b/README.md index d2e5338..d51fcbf 100644 --- a/README.md +++ b/README.md @@ -6,69 +6,10 @@ Created For [ModFest 1.16](https://modfest.net/1.16) **NOTE:** This is only able to scan mods that have opted-in! ## Mod Users -Go to the Mod Menu and click the configure icon for ModUpdater to view available updates. +Go to the Mod Menu and click the configure icon to show the ModUpdater GUI or use the ```/modupdater``` command. ## Mod Developers -Both ```fabric.mod.json``` and ```build.gradle``` must be modified to opt-in to ModUpdater. - -### ```fabric.mod.json``` -**Maven** -```json -{ - "custom": { - "modupdater": { - "strategy": "maven", - "repository": "https://maven.fabricmc.net", - "group": "net.fabricmc.fabric-api", - "artifact": "fabric-api" - } - } -} -``` - -**CurseForge** -```json -{ - "custom": { - "modupdater": { - "strategy": "curseforge", - "projectID": 306612 - } - } -} -``` - -**GitHub Releases** -```json -{ - "custom": { - "modupdater": { - "strategy": "github", - "owner": "Repository Owner", - "repository": "Repository Name" - } - } -} -``` - -### ```build.gradle``` -To properly detect the version of a file, the Minecraft version must be appended to the file name. - -Replace: -```gradle -version = project.mod_version -``` -with: -```gradle -version = "${project.mod_version}+${project.minecraft_version}" -``` - -If you prefer hyphens you can also use: -```gradle -version = "${project.mod_version}-${project.minecraft_version}" -``` - -You can also just use the major version of Minecraft instead of the full version (like ```1.16``` instead of ```1.16.1``` or ```20w20a```). +[View Mod Developers](MOD_DEVELOPERS.md) ## Changelog [View Changelog](CHANGELOG.md) diff --git a/gradle.properties b/gradle.properties index bff1d27..d7ef084 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ org.gradle.jvmargs = -Xmx1G fabric_loader_version = 0.8.8+build.202 # Mod Properties - mod_version = 1.1.4 + mod_version = 1.1.5 maven_group = com.thebrokenrail # Dependencies diff --git a/src/main/java/com/thebrokenrail/modupdater/strategy/JSONStrategy.java b/src/main/java/com/thebrokenrail/modupdater/strategy/JSONStrategy.java new file mode 100644 index 0000000..6cc05cc --- /dev/null +++ b/src/main/java/com/thebrokenrail/modupdater/strategy/JSONStrategy.java @@ -0,0 +1,87 @@ +package com.thebrokenrail.modupdater.strategy; + +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.JsonDataException; +import com.squareup.moshi.Moshi; +import com.squareup.moshi.Types; +import com.thebrokenrail.modupdater.ModUpdater; +import com.thebrokenrail.modupdater.api.ConfigObject; +import com.thebrokenrail.modupdater.api.UpdateStrategy; +import com.thebrokenrail.modupdater.data.ModUpdate; +import com.thebrokenrail.modupdater.util.Util; +import net.fabricmc.loader.api.SemanticVersion; +import net.fabricmc.loader.util.version.VersionParsingException; + +import javax.annotation.Nullable; +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.Map; + +public class JSONStrategy implements UpdateStrategy { + @SuppressWarnings("unused") + private static class LatestVersionEntry { + private String version; + private String downloadUrl; + } + + private final JsonAdapter> jsonAdapter; + + public JSONStrategy() { + Moshi moshi = new Moshi.Builder().build(); + Type map = Types.newParameterizedType(Map.class, String.class, LatestVersionEntry.class); + jsonAdapter = moshi.adapter(map); + } + + @Override + @Nullable + public ModUpdate run(ConfigObject obj, String oldVersion, String name) { + String url; + try { + url = obj.getString("url"); + } catch (ConfigObject.MissingValueException e) { + ModUpdater.logWarn(name, e.getMessage()); + return null; + } + + String data; + try { + data = Util.urlToString(url); + } catch (IOException e) { + ModUpdater.logWarn(name, e.toString()); + return null; + } + + Map map; + try { + map = jsonAdapter.fromJson(data); + } catch (JsonDataException | IOException e) { + ModUpdater.logWarn(name, e.toString()); + return null; + } + + if (map == null) { + return null; + } + + String version = Util.getMinecraftVersion().getName(); + if (map.containsKey(version)) { + LatestVersionEntry entry = map.get(version); + ModUpdate update = new ModUpdate(oldVersion, entry.version, entry.downloadUrl, name); + try { + if (SemanticVersion.parse(entry.version).compareTo(SemanticVersion.parse(oldVersion)) > 0) { + return update; + } else { + return null; + } + } catch (VersionParsingException e) { + if (!oldVersion.equals(entry.version)) { + return update; + } else { + return null; + } + } + } else { + return null; + } + } +} diff --git a/src/main/java/com/thebrokenrail/modupdater/strategy/util/UpdateStrategyRegistry.java b/src/main/java/com/thebrokenrail/modupdater/strategy/util/UpdateStrategyRegistry.java index 55ea4b2..8d492a4 100644 --- a/src/main/java/com/thebrokenrail/modupdater/strategy/util/UpdateStrategyRegistry.java +++ b/src/main/java/com/thebrokenrail/modupdater/strategy/util/UpdateStrategyRegistry.java @@ -3,6 +3,7 @@ package com.thebrokenrail.modupdater.strategy.util; import com.thebrokenrail.modupdater.api.UpdateStrategy; import com.thebrokenrail.modupdater.strategy.CurseForgeStrategy; import com.thebrokenrail.modupdater.strategy.GitHubReleasesStrategy; +import com.thebrokenrail.modupdater.strategy.JSONStrategy; import com.thebrokenrail.modupdater.strategy.MavenStrategy; import javax.annotation.Nullable; @@ -21,5 +22,6 @@ public class UpdateStrategyRegistry { data.put("curseforge", new CurseForgeStrategy()); data.put("maven", new MavenStrategy()); data.put("github", new GitHubReleasesStrategy()); + data.put("json", new JSONStrategy()); } }