diff --git a/CHANGELOG.md b/CHANGELOG.md index 8928b05..a5232d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +**1.0.3** +* Add Support For GitHub Releases +* Use Multi-Threading + **1.0.2** * Improve Errors * Improve GUI diff --git a/README.md b/README.md index ab9ab00..c73b29b 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,19 @@ Place this in your ``fabric.mod.json``: } ``` +**GitHub Releases** +```json +{ + "custom": { + "modupdater": { + "strategy": "github", + "owner": "Repository Owner", + "repository": "Repository Name" + } + } +} +``` + Also replace this in ````build.gradle````: ```gradle version = project.mod_version @@ -48,4 +61,5 @@ version = "${project.mod_version}+${project.minecraft_version}" [View Changelog](CHANGELOG.md) ## Credits -The icon was created by ``ProspectorDev``. \ No newline at end of file +- The icon was created by ``ProspectorDev`` +- The GitHub Releases strategy was written by ``AppleTheGolden`` \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 82dc78d..2794d25 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.0.2 + mod_version = 1.0.3 maven_group = com.thebrokenrail # Dependencies diff --git a/src/main/java/com/thebrokenrail/modupdater/ModUpdater.java b/src/main/java/com/thebrokenrail/modupdater/ModUpdater.java index 274697d..1a3801d 100644 --- a/src/main/java/com/thebrokenrail/modupdater/ModUpdater.java +++ b/src/main/java/com/thebrokenrail/modupdater/ModUpdater.java @@ -21,7 +21,7 @@ public class ModUpdater implements ModInitializer { getLogger().warn("Invalid JSON Configuration: " + modID); } - private static ModUpdate[] updates; + private static volatile ModUpdate[] updates; private static Thread updateThread; @@ -45,6 +45,6 @@ public class ModUpdater implements ModInitializer { } getLogger().info(updates.length + " Mod Update(s) Found"); }); - //updateThread.start(); + updateThread.start(); } } diff --git a/src/main/java/com/thebrokenrail/modupdater/strategy/CurseForgeStrategy.java b/src/main/java/com/thebrokenrail/modupdater/strategy/CurseForgeStrategy.java index d362230..f0f3059 100644 --- a/src/main/java/com/thebrokenrail/modupdater/strategy/CurseForgeStrategy.java +++ b/src/main/java/com/thebrokenrail/modupdater/strategy/CurseForgeStrategy.java @@ -2,6 +2,7 @@ package com.thebrokenrail.modupdater.strategy; import com.mojang.bridge.game.GameVersion; import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.JsonDataException; import com.squareup.moshi.Moshi; import com.thebrokenrail.modupdater.ModUpdater; import com.thebrokenrail.modupdater.util.ConfigObject; @@ -43,6 +44,9 @@ class CurseForgeStrategy implements ModUpdateStrategy { } catch (IOException e) { ModUpdater.getLogger().warn("Unable To Access CurseForge: " + name); return null; + } catch (JsonDataException e) { + ModUpdater.getLogger().warn("CurseForge Sent Invalid Data: ", e); + return null; } if (files == null) { @@ -59,18 +63,20 @@ class CurseForgeStrategy implements ModUpdateStrategy { CurseForgeFile newestFile = null; for (CurseForgeFile file : files) { - String fileVersion = Util.getVersionFromFileName(file.fileName); - if (Arrays.asList(file.gameVersion).contains(versionStr) || Util.isVersionCompatible(fileVersion)) { - if (newestFile != null) { - String newestFileVersion = Util.getVersionFromFileName(newestFile.fileName); - try { - if (SemanticVersion.parse(fileVersion).compareTo(SemanticVersion.parse(newestFileVersion)) > 0) { - newestFile = file; + if (Util.isFileCompatible(file.fileName)) { + String fileVersion = Util.getVersionFromFileName(file.fileName); + if (Arrays.asList(file.gameVersion).contains(versionStr) || Util.isVersionCompatible(fileVersion)) { + if (newestFile != null) { + String newestFileVersion = Util.getVersionFromFileName(newestFile.fileName); + try { + if (SemanticVersion.parse(fileVersion).compareTo(SemanticVersion.parse(newestFileVersion)) > 0) { + newestFile = file; + } + } catch (VersionParsingException ignored) { } - } catch (VersionParsingException ignored) { + } else { + newestFile = file; } - } else { - newestFile = file; } } } diff --git a/src/main/java/com/thebrokenrail/modupdater/strategy/GitHubReleasesStrategy.java b/src/main/java/com/thebrokenrail/modupdater/strategy/GitHubReleasesStrategy.java new file mode 100644 index 0000000..0ba23f9 --- /dev/null +++ b/src/main/java/com/thebrokenrail/modupdater/strategy/GitHubReleasesStrategy.java @@ -0,0 +1,97 @@ +package com.thebrokenrail.modupdater.strategy; + +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.JsonDataException; +import com.squareup.moshi.Moshi; +import com.thebrokenrail.modupdater.ModUpdater; +import com.thebrokenrail.modupdater.util.ConfigObject; +import com.thebrokenrail.modupdater.util.ModUpdate; +import com.thebrokenrail.modupdater.util.ModUpdateStrategy; +import com.thebrokenrail.modupdater.util.Util; +import net.fabricmc.loader.api.SemanticVersion; +import net.fabricmc.loader.util.version.VersionParsingException; + +import java.io.IOException; + +public class GitHubReleasesStrategy implements ModUpdateStrategy { + @SuppressWarnings({"unused", "MismatchedReadAndWriteOfArray"}) + private static class GitHubRelease { + private GitHubReleaseAsset[] assets; + } + + @SuppressWarnings("unused") + private static class GitHubReleaseAsset { + private String name; + private String browser_download_url; + } + + @Override + public ModUpdate checkForUpdate(ConfigObject obj, String oldVersion, String name) { + String owner; + String repo; + try { + owner = obj.getString("owner"); + repo = obj.getString("repository"); + } catch (ConfigObject.MissingValueException e) { + ModUpdater.invalidModUpdaterConfig(name); + return null; + } + + String data = Util.urlToString(String.format("https://api.github.com/repos/%s/%s/releases", owner, repo)); + + Moshi moshi = new Moshi.Builder().build(); + JsonAdapter jsonAdapter = moshi.adapter(GitHubRelease[].class); + + GitHubRelease[] releases; + try { + // GitHub's API never omits values, they're always null + releases = jsonAdapter.nonNull().fromJson(data); + } catch (IOException e) { + ModUpdater.getLogger().warn("Unable To Access GitHub: " + name); + return null; + } catch (JsonDataException e) { + ModUpdater.getLogger().warn("GitHub Sent Invalid Data: ", e); + return null; + } + + if (releases == null) { + return null; + } + + GitHubReleaseAsset newestFile = null; + for (GitHubRelease release : releases) { + for (GitHubReleaseAsset asset : release.assets) { + if (Util.isFileCompatible(asset.name)) { + String fileVersion = Util.getVersionFromFileName(asset.name); + if (Util.isVersionCompatible(fileVersion)) { + if (newestFile != null) { + try { + if (SemanticVersion.parse(fileVersion).compareTo(SemanticVersion.parse(fileVersion)) > 0) { + newestFile = asset; + } + } catch (VersionParsingException ignored) { + } + } else { + newestFile = asset; + } + } + } + } + } + + if (newestFile != null) { + String newestFileVersion = Util.getVersionFromFileName(newestFile.name); + try { + if (SemanticVersion.parse(newestFileVersion).compareTo(SemanticVersion.parse(oldVersion)) > 0) { + return new ModUpdate(oldVersion, newestFileVersion, newestFile.browser_download_url, name); + } else { + return null; + } + } catch (VersionParsingException e) { + return null; + } + } else { + return null; + } + } +} diff --git a/src/main/java/com/thebrokenrail/modupdater/strategy/MavenStrategy.java b/src/main/java/com/thebrokenrail/modupdater/strategy/MavenStrategy.java index 5ec4de5..e5431bb 100644 --- a/src/main/java/com/thebrokenrail/modupdater/strategy/MavenStrategy.java +++ b/src/main/java/com/thebrokenrail/modupdater/strategy/MavenStrategy.java @@ -31,7 +31,7 @@ public class MavenStrategy implements ModUpdateStrategy { return null; } - String mavenRoot = repository + '/' + group.replaceAll("\\.", "/") + '/' + artifact; + String mavenRoot = String.format("%s/%s/%s", repository, group.replaceAll("\\.", "/"), artifact); Document doc; try { diff --git a/src/main/java/com/thebrokenrail/modupdater/strategy/ModUpdateStrategies.java b/src/main/java/com/thebrokenrail/modupdater/strategy/ModUpdateStrategies.java index f902dd4..30c550b 100644 --- a/src/main/java/com/thebrokenrail/modupdater/strategy/ModUpdateStrategies.java +++ b/src/main/java/com/thebrokenrail/modupdater/strategy/ModUpdateStrategies.java @@ -94,5 +94,6 @@ public class ModUpdateStrategies { static { data.put("curseforge", new CurseForgeStrategy()); data.put("maven", new MavenStrategy()); + data.put("github", new GitHubReleasesStrategy()); } } diff --git a/src/main/java/com/thebrokenrail/modupdater/util/Util.java b/src/main/java/com/thebrokenrail/modupdater/util/Util.java index 5f619d1..f40d708 100644 --- a/src/main/java/com/thebrokenrail/modupdater/util/Util.java +++ b/src/main/java/com/thebrokenrail/modupdater/util/Util.java @@ -75,6 +75,10 @@ public class Util { return isVersionCompatible(versionStr,'+') || isVersionCompatible(versionStr, '-'); } + public static boolean isFileCompatible(String fileName) { + return !fileName.endsWith("-dev" + JAR_EXTENSION) && !fileName.endsWith("-sources" + JAR_EXTENSION) && !fileName.endsWith("-sources-dev" + JAR_EXTENSION); + } + public static GameVersion getMinecraftVersion() { updateMinecraftVersion(); return minecraftVersion;