From 897cec88d39ee316b03f780435245c82edf9cf6f Mon Sep 17 00:00:00 2001 From: TheBrokenRail Date: Thu, 25 Jun 2020 16:56:09 -0400 Subject: [PATCH] 1.1.0 --- CHANGELOG.md | 4 + gradle.properties | 2 +- .../thebrokenrail/modupdater/ModUpdater.java | 12 +-- .../modupdater/api/ConfigObject.java | 15 +++ .../modupdater/api/UpdateStrategy.java | 10 ++ .../api/impl/ConfigObjectCustom.java | 38 +++++++ .../api/impl/ConfigObjectHardcoded.java | 39 ++++++++ .../client/gui/ModUpdateScreen.java | 2 +- .../modupdater/{util => data}/ModUpdate.java | 2 +- .../strategy/CurseForgeStrategy.java | 18 ++-- .../strategy/GitHubReleasesStrategy.java | 18 ++-- .../modupdater/strategy/MavenStrategy.java | 23 +++-- .../strategy/ModUpdateStrategies.java | 99 ------------------- .../strategy/util/UpdateStrategyRegistry.java | 25 +++++ .../strategy/util/UpdateStrategyRunner.java | 96 ++++++++++++++++++ .../modupdater/util/ConfigObject.java | 81 --------------- .../modupdater/util/HardcodedData.java | 28 ------ .../modupdater/util/ModUpdateStrategy.java | 5 - .../thebrokenrail/modupdater/util/Util.java | 26 +++++ 19 files changed, 293 insertions(+), 250 deletions(-) create mode 100644 src/main/java/com/thebrokenrail/modupdater/api/ConfigObject.java create mode 100644 src/main/java/com/thebrokenrail/modupdater/api/UpdateStrategy.java create mode 100644 src/main/java/com/thebrokenrail/modupdater/api/impl/ConfigObjectCustom.java create mode 100644 src/main/java/com/thebrokenrail/modupdater/api/impl/ConfigObjectHardcoded.java rename src/main/java/com/thebrokenrail/modupdater/{util => data}/ModUpdate.java (93%) delete mode 100644 src/main/java/com/thebrokenrail/modupdater/strategy/ModUpdateStrategies.java create mode 100644 src/main/java/com/thebrokenrail/modupdater/strategy/util/UpdateStrategyRegistry.java create mode 100644 src/main/java/com/thebrokenrail/modupdater/strategy/util/UpdateStrategyRunner.java delete mode 100644 src/main/java/com/thebrokenrail/modupdater/util/ConfigObject.java delete mode 100644 src/main/java/com/thebrokenrail/modupdater/util/HardcodedData.java delete mode 100644 src/main/java/com/thebrokenrail/modupdater/util/ModUpdateStrategy.java diff --git a/CHANGELOG.md b/CHANGELOG.md index dbab4d3..ab9e900 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +**1.1.0** +* Stabilize +* Improve Error Messages + **1.0.11** * Close Input Stream Properly diff --git a/gradle.properties b/gradle.properties index c9b2392..8d9d802 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.11 + mod_version = 1.1.0 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 1a3801d..a4df783 100644 --- a/src/main/java/com/thebrokenrail/modupdater/ModUpdater.java +++ b/src/main/java/com/thebrokenrail/modupdater/ModUpdater.java @@ -1,7 +1,7 @@ package com.thebrokenrail.modupdater; -import com.thebrokenrail.modupdater.strategy.ModUpdateStrategies; -import com.thebrokenrail.modupdater.util.ModUpdate; +import com.thebrokenrail.modupdater.strategy.util.UpdateStrategyRunner; +import com.thebrokenrail.modupdater.data.ModUpdate; import net.fabricmc.api.ModInitializer; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -13,12 +13,12 @@ public class ModUpdater implements ModInitializer { private static final String LOGGER_NAME = "ModUpdater"; - public static Logger getLogger() { + private static Logger getLogger() { return LogManager.getLogger(LOGGER_NAME); } - public static void invalidModUpdaterConfig(String modID) { - getLogger().warn("Invalid JSON Configuration: " + modID); + public static void log(String name, String msg) { + getLogger().warn(String.format("%s: %s", name, msg)); } private static volatile ModUpdate[] updates; @@ -28,7 +28,7 @@ public class ModUpdater implements ModInitializer { public static ModUpdate[] getUpdates() { if (updates == null) { if (Thread.currentThread() == updateThread) { - updates = ModUpdateStrategies.findAvailableUpdates(); + updates = UpdateStrategyRunner.checkAllModsForUpdates(); } else { return null; } diff --git a/src/main/java/com/thebrokenrail/modupdater/api/ConfigObject.java b/src/main/java/com/thebrokenrail/modupdater/api/ConfigObject.java new file mode 100644 index 0000000..b2f9523 --- /dev/null +++ b/src/main/java/com/thebrokenrail/modupdater/api/ConfigObject.java @@ -0,0 +1,15 @@ +package com.thebrokenrail.modupdater.api; + +public interface ConfigObject { + String getString(String str) throws MissingValueException; + int getInt(String str) throws MissingValueException; + + class MissingValueException extends Exception { + private static final String MISSING_MSG = "Missing Configuration Property: %s"; + private static final String INVALID_MSG = "Invalid Configuration Property: %s"; + + public MissingValueException(boolean invalid, String property) { + super(String.format(invalid ? INVALID_MSG : MISSING_MSG, property)); + } + } +} diff --git a/src/main/java/com/thebrokenrail/modupdater/api/UpdateStrategy.java b/src/main/java/com/thebrokenrail/modupdater/api/UpdateStrategy.java new file mode 100644 index 0000000..c8af551 --- /dev/null +++ b/src/main/java/com/thebrokenrail/modupdater/api/UpdateStrategy.java @@ -0,0 +1,10 @@ +package com.thebrokenrail.modupdater.api; + +import com.thebrokenrail.modupdater.data.ModUpdate; + +import javax.annotation.Nullable; + +public interface UpdateStrategy { + @Nullable + ModUpdate run(ConfigObject obj, String oldVersion, String name); +} diff --git a/src/main/java/com/thebrokenrail/modupdater/api/impl/ConfigObjectCustom.java b/src/main/java/com/thebrokenrail/modupdater/api/impl/ConfigObjectCustom.java new file mode 100644 index 0000000..f37634c --- /dev/null +++ b/src/main/java/com/thebrokenrail/modupdater/api/impl/ConfigObjectCustom.java @@ -0,0 +1,38 @@ +package com.thebrokenrail.modupdater.api.impl; + +import com.thebrokenrail.modupdater.api.ConfigObject; +import net.fabricmc.loader.api.metadata.CustomValue; + +public class ConfigObjectCustom implements ConfigObject { + private final CustomValue.CvObject obj; + + public ConfigObjectCustom(CustomValue.CvObject obj) { + this.obj = obj; + } + + @Override + public String getString(String str) throws MissingValueException { + if (obj.containsKey(str)) { + try { + return obj.get(str).getAsString(); + } catch (ClassCastException e) { + throw new MissingValueException(true, str); + } + } else { + throw new MissingValueException(false, str); + } + } + + @Override + public int getInt(String str) throws MissingValueException { + if (obj.containsKey(str)) { + try { + return obj.get(str).getAsNumber().intValue(); + } catch (ClassCastException e) { + throw new MissingValueException(true, str); + } + } else { + throw new MissingValueException(false, str); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/thebrokenrail/modupdater/api/impl/ConfigObjectHardcoded.java b/src/main/java/com/thebrokenrail/modupdater/api/impl/ConfigObjectHardcoded.java new file mode 100644 index 0000000..2cace9d --- /dev/null +++ b/src/main/java/com/thebrokenrail/modupdater/api/impl/ConfigObjectHardcoded.java @@ -0,0 +1,39 @@ +package com.thebrokenrail.modupdater.api.impl; + +import com.thebrokenrail.modupdater.api.ConfigObject; + +import java.util.Map; + +public class ConfigObjectHardcoded implements ConfigObject { + private final Map map; + + public ConfigObjectHardcoded(Map map) { + this.map = map; + } + + @Override + public String getString(String str) throws MissingValueException { + if (map.containsKey(str)) { + try { + return (String) map.get(str); + } catch (ClassCastException e) { + throw new MissingValueException(true, str); + } + } else { + throw new MissingValueException(false, str); + } + } + + @Override + public int getInt(String str) throws MissingValueException { + if (map.containsKey(str)) { + try { + return (Integer) map.get(str); + } catch (ClassCastException e) { + throw new MissingValueException(true, str); + } + } else { + throw new MissingValueException(false, str); + } + } +} diff --git a/src/main/java/com/thebrokenrail/modupdater/client/gui/ModUpdateScreen.java b/src/main/java/com/thebrokenrail/modupdater/client/gui/ModUpdateScreen.java index e2296b9..e1b3f47 100644 --- a/src/main/java/com/thebrokenrail/modupdater/client/gui/ModUpdateScreen.java +++ b/src/main/java/com/thebrokenrail/modupdater/client/gui/ModUpdateScreen.java @@ -1,7 +1,7 @@ package com.thebrokenrail.modupdater.client.gui; import com.thebrokenrail.modupdater.ModUpdater; -import com.thebrokenrail.modupdater.util.ModUpdate; +import com.thebrokenrail.modupdater.data.ModUpdate; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; diff --git a/src/main/java/com/thebrokenrail/modupdater/util/ModUpdate.java b/src/main/java/com/thebrokenrail/modupdater/data/ModUpdate.java similarity index 93% rename from src/main/java/com/thebrokenrail/modupdater/util/ModUpdate.java rename to src/main/java/com/thebrokenrail/modupdater/data/ModUpdate.java index e3bbb90..d3f0b33 100644 --- a/src/main/java/com/thebrokenrail/modupdater/util/ModUpdate.java +++ b/src/main/java/com/thebrokenrail/modupdater/data/ModUpdate.java @@ -1,4 +1,4 @@ -package com.thebrokenrail.modupdater.util; +package com.thebrokenrail.modupdater.data; import net.fabricmc.loader.api.Version; import net.fabricmc.loader.util.version.VersionParsingException; diff --git a/src/main/java/com/thebrokenrail/modupdater/strategy/CurseForgeStrategy.java b/src/main/java/com/thebrokenrail/modupdater/strategy/CurseForgeStrategy.java index f82941c..04a2c58 100644 --- a/src/main/java/com/thebrokenrail/modupdater/strategy/CurseForgeStrategy.java +++ b/src/main/java/com/thebrokenrail/modupdater/strategy/CurseForgeStrategy.java @@ -5,17 +5,18 @@ 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.api.ConfigObject; +import com.thebrokenrail.modupdater.data.ModUpdate; +import com.thebrokenrail.modupdater.api.UpdateStrategy; 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.util.Arrays; -class CurseForgeStrategy implements ModUpdateStrategy { +public class CurseForgeStrategy implements UpdateStrategy { @SuppressWarnings({"unused", "MismatchedReadAndWriteOfArray"}) private static class CurseForgeFile { private String fileName; @@ -24,12 +25,13 @@ class CurseForgeStrategy implements ModUpdateStrategy { } @Override - public ModUpdate checkForUpdate(ConfigObject obj, String oldVersion, String name) { + @Nullable + public ModUpdate run(ConfigObject obj, String oldVersion, String name) { int projectID; try { projectID = obj.getInt("projectID"); } catch (ConfigObject.MissingValueException e) { - ModUpdater.invalidModUpdaterConfig(name); + ModUpdater.log(name, e.getMessage()); return null; } @@ -37,7 +39,7 @@ class CurseForgeStrategy implements ModUpdateStrategy { try { data = Util.urlToString("https://addons-ecs.forgesvc.net/api/v2/addon/" + projectID + "/files"); } catch (IOException e) { - ModUpdater.getLogger().warn("Unable To Access CurseForge: " + name); + ModUpdater.log(name, e.toString()); return null; } @@ -48,7 +50,7 @@ class CurseForgeStrategy implements ModUpdateStrategy { files = jsonAdapter.fromJson(data); } catch (JsonDataException | IOException e) { - ModUpdater.getLogger().warn("CurseForge Sent Invalid Data: ", e); + ModUpdater.log(name, e.toString()); return null; } diff --git a/src/main/java/com/thebrokenrail/modupdater/strategy/GitHubReleasesStrategy.java b/src/main/java/com/thebrokenrail/modupdater/strategy/GitHubReleasesStrategy.java index 065bae4..f608dc1 100644 --- a/src/main/java/com/thebrokenrail/modupdater/strategy/GitHubReleasesStrategy.java +++ b/src/main/java/com/thebrokenrail/modupdater/strategy/GitHubReleasesStrategy.java @@ -4,16 +4,17 @@ 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.api.ConfigObject; +import com.thebrokenrail.modupdater.data.ModUpdate; +import com.thebrokenrail.modupdater.api.UpdateStrategy; 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; -public class GitHubReleasesStrategy implements ModUpdateStrategy { +public class GitHubReleasesStrategy implements UpdateStrategy { @SuppressWarnings({"unused", "MismatchedReadAndWriteOfArray"}) private static class GitHubRelease { private GitHubReleaseAsset[] assets; @@ -26,14 +27,15 @@ public class GitHubReleasesStrategy implements ModUpdateStrategy { } @Override - public ModUpdate checkForUpdate(ConfigObject obj, String oldVersion, String name) { + @Nullable + public ModUpdate run(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); + ModUpdater.log(name, e.getMessage()); return null; } @@ -41,7 +43,7 @@ public class GitHubReleasesStrategy implements ModUpdateStrategy { try { data = Util.urlToString(String.format("https://api.github.com/repos/%s/%s/releases", owner, repo)); } catch (IOException e) { - ModUpdater.getLogger().warn("Unable To Access GitHub: " + name); + ModUpdater.log(name, e.toString()); return null; } @@ -53,7 +55,7 @@ public class GitHubReleasesStrategy implements ModUpdateStrategy { // GitHub's API never omits values, they're always null releases = jsonAdapter.nonNull().fromJson(data); } catch (JsonDataException | IOException e) { - ModUpdater.getLogger().warn("GitHub Sent Invalid Data: ", e); + ModUpdater.log(name, e.toString()); 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 3d9d027..7bbb40b 100644 --- a/src/main/java/com/thebrokenrail/modupdater/strategy/MavenStrategy.java +++ b/src/main/java/com/thebrokenrail/modupdater/strategy/MavenStrategy.java @@ -1,9 +1,9 @@ package com.thebrokenrail.modupdater.strategy; 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.api.ConfigObject; +import com.thebrokenrail.modupdater.data.ModUpdate; +import com.thebrokenrail.modupdater.api.UpdateStrategy; import com.thebrokenrail.modupdater.util.Util; import net.fabricmc.loader.api.SemanticVersion; import net.fabricmc.loader.util.version.VersionParsingException; @@ -12,14 +12,16 @@ import org.dom4j.DocumentException; import org.dom4j.Node; import org.dom4j.io.SAXReader; +import javax.annotation.Nullable; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; -public class MavenStrategy implements ModUpdateStrategy { +public class MavenStrategy implements UpdateStrategy { @Override - public ModUpdate checkForUpdate(ConfigObject obj, String oldVersion, String name) { + @Nullable + public ModUpdate run(ConfigObject obj, String oldVersion, String name) { String repository; String group; String artifact; @@ -28,7 +30,7 @@ public class MavenStrategy implements ModUpdateStrategy { group = obj.getString("group"); artifact = obj.getString("artifact"); } catch (ConfigObject.MissingValueException e) { - ModUpdater.invalidModUpdaterConfig(name); + ModUpdater.log(name, e.getMessage()); return null; } @@ -38,7 +40,7 @@ public class MavenStrategy implements ModUpdateStrategy { try { data = Util.urlToString(mavenRoot + "/maven-metadata.xml"); } catch (IOException e) { - ModUpdater.getLogger().warn("Unable To Access Maven Repository: " + name); + ModUpdater.log(name, e.toString()); return null; } @@ -46,11 +48,8 @@ public class MavenStrategy implements ModUpdateStrategy { try (InputStream source = new ByteArrayInputStream(data.getBytes())) { SAXReader reader = new SAXReader(); doc = reader.read(source); - } catch (DocumentException e) { - ModUpdater.getLogger().warn("Maven Repository Sent Invalid Data: " + name); - return null; - } catch (IOException e) { - e.printStackTrace(); + } catch (DocumentException | IOException e) { + ModUpdater.log(name, e.toString()); return null; } diff --git a/src/main/java/com/thebrokenrail/modupdater/strategy/ModUpdateStrategies.java b/src/main/java/com/thebrokenrail/modupdater/strategy/ModUpdateStrategies.java deleted file mode 100644 index 30c550b..0000000 --- a/src/main/java/com/thebrokenrail/modupdater/strategy/ModUpdateStrategies.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.thebrokenrail.modupdater.strategy; - -import com.thebrokenrail.modupdater.ModUpdater; -import com.thebrokenrail.modupdater.util.ConfigObject; -import com.thebrokenrail.modupdater.util.HardcodedData; -import com.thebrokenrail.modupdater.util.ModUpdate; -import com.thebrokenrail.modupdater.util.ModUpdateStrategy; -import net.fabricmc.loader.api.FabricLoader; -import net.fabricmc.loader.api.ModContainer; -import net.fabricmc.loader.api.metadata.ModMetadata; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; - -public class ModUpdateStrategies { - private static final Map data = new HashMap<>(); - - private static ModUpdate checkForUpdate(ModMetadata metadata, ConfigObject obj, String name) { - String oldVersion = metadata.getVersion().toString(); - - String strategy; - try { - strategy = obj.getString("strategy"); - } catch (ConfigObject.MissingValueException e) { - ModUpdater.invalidModUpdaterConfig(name); - return null; - } - - ModUpdateStrategy strategyObj = data.get(strategy); - if (strategyObj == null) { - ModUpdater.invalidModUpdaterConfig(name); - return null; - } - - return strategyObj.checkForUpdate(obj, oldVersion, name); - } - - public static ModUpdate[] findAvailableUpdates() { - List updates = new ArrayList<>(); - - AtomicInteger remaining = new AtomicInteger(0); - - for (ModContainer mod : FabricLoader.getInstance().getAllMods()) { - Thread thread = new Thread(() -> { - ModMetadata metadata = mod.getMetadata(); - String name = metadata.getName() + " (" + metadata.getId() + ')'; - - ModUpdate update = null; - if (metadata.containsCustomValue(ModUpdater.NAMESPACE)) { - try { - update = checkForUpdate(metadata, new ConfigObject.ConfigObjectCustom(metadata.getCustomValue(ModUpdater.NAMESPACE).getAsObject()), name); - } catch (ClassCastException e) { - ModUpdater.invalidModUpdaterConfig(name); - } - } else { - ConfigObject obj = HardcodedData.getData(metadata.getId()); - if (obj != null) { - update = checkForUpdate(metadata, obj, name); - } - } - - if (update != null) { - synchronized (updates) { - updates.add(update); - } - } - - synchronized (remaining) { - remaining.decrementAndGet(); - remaining.notifyAll(); - } - }); - synchronized (remaining) { - remaining.incrementAndGet(); - } - thread.start(); - } - - synchronized (remaining) { - while (remaining.get() > 0) { - try { - remaining.wait(); - } catch (InterruptedException ignored) { - } - } - } - - return updates.toArray(new ModUpdate[0]); - } - - 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/strategy/util/UpdateStrategyRegistry.java b/src/main/java/com/thebrokenrail/modupdater/strategy/util/UpdateStrategyRegistry.java new file mode 100644 index 0000000..55ea4b2 --- /dev/null +++ b/src/main/java/com/thebrokenrail/modupdater/strategy/util/UpdateStrategyRegistry.java @@ -0,0 +1,25 @@ +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.MavenStrategy; + +import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.Map; + +public class UpdateStrategyRegistry { + private static final Map data = new HashMap<>(); + + @Nullable + static UpdateStrategy get(String name) { + return data.get(name); + } + + 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/strategy/util/UpdateStrategyRunner.java b/src/main/java/com/thebrokenrail/modupdater/strategy/util/UpdateStrategyRunner.java new file mode 100644 index 0000000..017c8cf --- /dev/null +++ b/src/main/java/com/thebrokenrail/modupdater/strategy/util/UpdateStrategyRunner.java @@ -0,0 +1,96 @@ +package com.thebrokenrail.modupdater.strategy.util; + +import com.thebrokenrail.modupdater.ModUpdater; +import com.thebrokenrail.modupdater.api.ConfigObject; +import com.thebrokenrail.modupdater.api.impl.ConfigObjectCustom; +import com.thebrokenrail.modupdater.data.ModUpdate; +import com.thebrokenrail.modupdater.api.UpdateStrategy; +import com.thebrokenrail.modupdater.util.Util; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.ModContainer; +import net.fabricmc.loader.api.metadata.ModMetadata; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +public class UpdateStrategyRunner { + @Nullable + private static ModUpdate checkModForUpdate(ModMetadata metadata) { + String name = metadata.getName() + " (" + metadata.getId() + ')'; + + ConfigObject obj; + if (metadata.containsCustomValue(ModUpdater.NAMESPACE)) { + try { + obj = new ConfigObjectCustom(metadata.getCustomValue(ModUpdater.NAMESPACE).getAsObject()); + } catch (ClassCastException e) { + ModUpdater.log(name, String.format("\"%s\" Is Not An Object", ModUpdater.NAMESPACE)); + return null; + } + } else { + obj = Util.getHardcodedConfig(metadata.getId()); + if (obj == null) { + return null; + } + } + + String oldVersion = metadata.getVersion().toString(); + + String strategy; + try { + strategy = obj.getString("strategy"); + } catch (ConfigObject.MissingValueException e) { + ModUpdater.log(name, e.getMessage()); + return null; + } + + UpdateStrategy strategyObj = UpdateStrategyRegistry.get(strategy); + if (strategyObj == null) { + ModUpdater.log(name, "Invalid Strategy: " + name); + return null; + } + + return strategyObj.run(obj, oldVersion, name); + } + + public static ModUpdate[] checkAllModsForUpdates() { + List updates = new ArrayList<>(); + + AtomicInteger remaining = new AtomicInteger(0); + + for (ModContainer mod : FabricLoader.getInstance().getAllMods()) { + Thread thread = new Thread(() -> { + ModMetadata metadata = mod.getMetadata(); + + ModUpdate update = checkModForUpdate(metadata); + + if (update != null) { + synchronized (updates) { + updates.add(update); + } + } + + synchronized (remaining) { + remaining.decrementAndGet(); + remaining.notifyAll(); + } + }); + synchronized (remaining) { + remaining.incrementAndGet(); + } + thread.start(); + } + + synchronized (remaining) { + while (remaining.get() > 0) { + try { + remaining.wait(); + } catch (InterruptedException ignored) { + } + } + } + + return updates.toArray(new ModUpdate[0]); + } +} diff --git a/src/main/java/com/thebrokenrail/modupdater/util/ConfigObject.java b/src/main/java/com/thebrokenrail/modupdater/util/ConfigObject.java deleted file mode 100644 index aaf291b..0000000 --- a/src/main/java/com/thebrokenrail/modupdater/util/ConfigObject.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.thebrokenrail.modupdater.util; - -import net.fabricmc.loader.api.metadata.CustomValue; - -import java.util.Map; - -public interface ConfigObject { - String getString(String str) throws MissingValueException; - int getInt(String str) throws MissingValueException; - - class ConfigObjectCustom implements ConfigObject { - private final CustomValue.CvObject obj; - - public ConfigObjectCustom(CustomValue.CvObject obj) { - this.obj = obj; - } - - @Override - public String getString(String str) throws MissingValueException { - if (obj.containsKey(str)) { - try { - return obj.get(str).getAsString(); - } catch (ClassCastException e) { - throw new MissingValueException(); - } - } else { - throw new MissingValueException(); - } - } - - @Override - public int getInt(String str) throws MissingValueException { - if (obj.containsKey(str)) { - try { - return obj.get(str).getAsNumber().intValue(); - } catch (ClassCastException e) { - throw new MissingValueException(); - } - } else { - throw new MissingValueException(); - } - } - } - - class ConfigObjectHardcoded implements ConfigObject { - private final Map map; - - public ConfigObjectHardcoded(Map map) { - this.map = map; - } - - @Override - public String getString(String str) throws MissingValueException { - if (map.containsKey(str)) { - try { - return (String) map.get(str); - } catch (ClassCastException e) { - throw new MissingValueException(); - } - } else { - throw new MissingValueException(); - } - } - - @Override - public int getInt(String str) throws MissingValueException { - if (map.containsKey(str)) { - try { - return (Integer) map.get(str); - } catch (ClassCastException e) { - throw new MissingValueException(); - } - } else { - throw new MissingValueException(); - } - } - } - - class MissingValueException extends Exception { - } -} diff --git a/src/main/java/com/thebrokenrail/modupdater/util/HardcodedData.java b/src/main/java/com/thebrokenrail/modupdater/util/HardcodedData.java deleted file mode 100644 index 0e5d13d..0000000 --- a/src/main/java/com/thebrokenrail/modupdater/util/HardcodedData.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.thebrokenrail.modupdater.util; - -import java.util.HashMap; -import java.util.Map; - -public class HardcodedData { - public static ConfigObject getData(String modID) { - switch (modID) { - case "fabric": { - Map map = new HashMap<>(); - map.put("strategy", "maven"); - map.put("repository", "https://maven.fabricmc.net"); - map.put("group", "net.fabricmc.fabric-api"); - map.put("artifact", "fabric-api"); - return new ConfigObject.ConfigObjectHardcoded(map); - } - case "modmenu": { - Map map = new HashMap<>(); - map.put("strategy", "curseforge"); - map.put("projectID", 308702); - return new ConfigObject.ConfigObjectHardcoded(map); - } - default: { - return null; - } - } - } -} diff --git a/src/main/java/com/thebrokenrail/modupdater/util/ModUpdateStrategy.java b/src/main/java/com/thebrokenrail/modupdater/util/ModUpdateStrategy.java deleted file mode 100644 index 4bdac12..0000000 --- a/src/main/java/com/thebrokenrail/modupdater/util/ModUpdateStrategy.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.thebrokenrail.modupdater.util; - -public interface ModUpdateStrategy { - ModUpdate checkForUpdate(ConfigObject obj, String oldVersion, String name); -} diff --git a/src/main/java/com/thebrokenrail/modupdater/util/Util.java b/src/main/java/com/thebrokenrail/modupdater/util/Util.java index 4054f16..a5a070a 100644 --- a/src/main/java/com/thebrokenrail/modupdater/util/Util.java +++ b/src/main/java/com/thebrokenrail/modupdater/util/Util.java @@ -1,6 +1,8 @@ package com.thebrokenrail.modupdater.util; import com.mojang.bridge.game.GameVersion; +import com.thebrokenrail.modupdater.api.ConfigObject; +import com.thebrokenrail.modupdater.api.impl.ConfigObjectHardcoded; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.ModContainer; import net.minecraft.MinecraftVersion; @@ -9,6 +11,8 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; +import java.util.HashMap; +import java.util.Map; import java.util.Optional; public class Util { @@ -88,4 +92,26 @@ public class Util { updateMinecraftVersion(); return minecraftVersion; } + + public static ConfigObject getHardcodedConfig(String modID) { + switch (modID) { + case "fabric": { + Map map = new HashMap<>(); + map.put("strategy", "maven"); + map.put("repository", "https://maven.fabricmc.net"); + map.put("group", "net.fabricmc.fabric-api"); + map.put("artifact", "fabric-api"); + return new ConfigObjectHardcoded(map); + } + case "modmenu": { + Map map = new HashMap<>(); + map.put("strategy", "curseforge"); + map.put("projectID", 308702); + return new ConfigObjectHardcoded(map); + } + default: { + return null; + } + } + } }