This commit is contained in:
parent
1a48e714b0
commit
897cec88d3
@ -1,5 +1,9 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
**1.1.0**
|
||||||
|
* Stabilize
|
||||||
|
* Improve Error Messages
|
||||||
|
|
||||||
**1.0.11**
|
**1.0.11**
|
||||||
* Close Input Stream Properly
|
* Close Input Stream Properly
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ org.gradle.jvmargs = -Xmx1G
|
|||||||
fabric_loader_version = 0.8.8+build.202
|
fabric_loader_version = 0.8.8+build.202
|
||||||
|
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version = 1.0.11
|
mod_version = 1.1.0
|
||||||
maven_group = com.thebrokenrail
|
maven_group = com.thebrokenrail
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.thebrokenrail.modupdater;
|
package com.thebrokenrail.modupdater;
|
||||||
|
|
||||||
import com.thebrokenrail.modupdater.strategy.ModUpdateStrategies;
|
import com.thebrokenrail.modupdater.strategy.util.UpdateStrategyRunner;
|
||||||
import com.thebrokenrail.modupdater.util.ModUpdate;
|
import com.thebrokenrail.modupdater.data.ModUpdate;
|
||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
@ -13,12 +13,12 @@ public class ModUpdater implements ModInitializer {
|
|||||||
|
|
||||||
private static final String LOGGER_NAME = "ModUpdater";
|
private static final String LOGGER_NAME = "ModUpdater";
|
||||||
|
|
||||||
public static Logger getLogger() {
|
private static Logger getLogger() {
|
||||||
return LogManager.getLogger(LOGGER_NAME);
|
return LogManager.getLogger(LOGGER_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void invalidModUpdaterConfig(String modID) {
|
public static void log(String name, String msg) {
|
||||||
getLogger().warn("Invalid JSON Configuration: " + modID);
|
getLogger().warn(String.format("%s: %s", name, msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static volatile ModUpdate[] updates;
|
private static volatile ModUpdate[] updates;
|
||||||
@ -28,7 +28,7 @@ public class ModUpdater implements ModInitializer {
|
|||||||
public static ModUpdate[] getUpdates() {
|
public static ModUpdate[] getUpdates() {
|
||||||
if (updates == null) {
|
if (updates == null) {
|
||||||
if (Thread.currentThread() == updateThread) {
|
if (Thread.currentThread() == updateThread) {
|
||||||
updates = ModUpdateStrategies.findAvailableUpdates();
|
updates = UpdateStrategyRunner.checkAllModsForUpdates();
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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<String, Object> map;
|
||||||
|
|
||||||
|
public ConfigObjectHardcoded(Map<String, Object> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package com.thebrokenrail.modupdater.client.gui;
|
package com.thebrokenrail.modupdater.client.gui;
|
||||||
|
|
||||||
import com.thebrokenrail.modupdater.ModUpdater;
|
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.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.thebrokenrail.modupdater.util;
|
package com.thebrokenrail.modupdater.data;
|
||||||
|
|
||||||
import net.fabricmc.loader.api.Version;
|
import net.fabricmc.loader.api.Version;
|
||||||
import net.fabricmc.loader.util.version.VersionParsingException;
|
import net.fabricmc.loader.util.version.VersionParsingException;
|
@ -5,17 +5,18 @@ import com.squareup.moshi.JsonAdapter;
|
|||||||
import com.squareup.moshi.JsonDataException;
|
import com.squareup.moshi.JsonDataException;
|
||||||
import com.squareup.moshi.Moshi;
|
import com.squareup.moshi.Moshi;
|
||||||
import com.thebrokenrail.modupdater.ModUpdater;
|
import com.thebrokenrail.modupdater.ModUpdater;
|
||||||
import com.thebrokenrail.modupdater.util.ConfigObject;
|
import com.thebrokenrail.modupdater.api.ConfigObject;
|
||||||
import com.thebrokenrail.modupdater.util.ModUpdate;
|
import com.thebrokenrail.modupdater.data.ModUpdate;
|
||||||
import com.thebrokenrail.modupdater.util.ModUpdateStrategy;
|
import com.thebrokenrail.modupdater.api.UpdateStrategy;
|
||||||
import com.thebrokenrail.modupdater.util.Util;
|
import com.thebrokenrail.modupdater.util.Util;
|
||||||
import net.fabricmc.loader.api.SemanticVersion;
|
import net.fabricmc.loader.api.SemanticVersion;
|
||||||
import net.fabricmc.loader.util.version.VersionParsingException;
|
import net.fabricmc.loader.util.version.VersionParsingException;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
class CurseForgeStrategy implements ModUpdateStrategy {
|
public class CurseForgeStrategy implements UpdateStrategy {
|
||||||
@SuppressWarnings({"unused", "MismatchedReadAndWriteOfArray"})
|
@SuppressWarnings({"unused", "MismatchedReadAndWriteOfArray"})
|
||||||
private static class CurseForgeFile {
|
private static class CurseForgeFile {
|
||||||
private String fileName;
|
private String fileName;
|
||||||
@ -24,12 +25,13 @@ class CurseForgeStrategy implements ModUpdateStrategy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ModUpdate checkForUpdate(ConfigObject obj, String oldVersion, String name) {
|
@Nullable
|
||||||
|
public ModUpdate run(ConfigObject obj, String oldVersion, String name) {
|
||||||
int projectID;
|
int projectID;
|
||||||
try {
|
try {
|
||||||
projectID = obj.getInt("projectID");
|
projectID = obj.getInt("projectID");
|
||||||
} catch (ConfigObject.MissingValueException e) {
|
} catch (ConfigObject.MissingValueException e) {
|
||||||
ModUpdater.invalidModUpdaterConfig(name);
|
ModUpdater.log(name, e.getMessage());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,7 +39,7 @@ class CurseForgeStrategy implements ModUpdateStrategy {
|
|||||||
try {
|
try {
|
||||||
data = Util.urlToString("https://addons-ecs.forgesvc.net/api/v2/addon/" + projectID + "/files");
|
data = Util.urlToString("https://addons-ecs.forgesvc.net/api/v2/addon/" + projectID + "/files");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
ModUpdater.getLogger().warn("Unable To Access CurseForge: " + name);
|
ModUpdater.log(name, e.toString());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +50,7 @@ class CurseForgeStrategy implements ModUpdateStrategy {
|
|||||||
|
|
||||||
files = jsonAdapter.fromJson(data);
|
files = jsonAdapter.fromJson(data);
|
||||||
} catch (JsonDataException | IOException e) {
|
} catch (JsonDataException | IOException e) {
|
||||||
ModUpdater.getLogger().warn("CurseForge Sent Invalid Data: ", e);
|
ModUpdater.log(name, e.toString());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,16 +4,17 @@ import com.squareup.moshi.JsonAdapter;
|
|||||||
import com.squareup.moshi.JsonDataException;
|
import com.squareup.moshi.JsonDataException;
|
||||||
import com.squareup.moshi.Moshi;
|
import com.squareup.moshi.Moshi;
|
||||||
import com.thebrokenrail.modupdater.ModUpdater;
|
import com.thebrokenrail.modupdater.ModUpdater;
|
||||||
import com.thebrokenrail.modupdater.util.ConfigObject;
|
import com.thebrokenrail.modupdater.api.ConfigObject;
|
||||||
import com.thebrokenrail.modupdater.util.ModUpdate;
|
import com.thebrokenrail.modupdater.data.ModUpdate;
|
||||||
import com.thebrokenrail.modupdater.util.ModUpdateStrategy;
|
import com.thebrokenrail.modupdater.api.UpdateStrategy;
|
||||||
import com.thebrokenrail.modupdater.util.Util;
|
import com.thebrokenrail.modupdater.util.Util;
|
||||||
import net.fabricmc.loader.api.SemanticVersion;
|
import net.fabricmc.loader.api.SemanticVersion;
|
||||||
import net.fabricmc.loader.util.version.VersionParsingException;
|
import net.fabricmc.loader.util.version.VersionParsingException;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class GitHubReleasesStrategy implements ModUpdateStrategy {
|
public class GitHubReleasesStrategy implements UpdateStrategy {
|
||||||
@SuppressWarnings({"unused", "MismatchedReadAndWriteOfArray"})
|
@SuppressWarnings({"unused", "MismatchedReadAndWriteOfArray"})
|
||||||
private static class GitHubRelease {
|
private static class GitHubRelease {
|
||||||
private GitHubReleaseAsset[] assets;
|
private GitHubReleaseAsset[] assets;
|
||||||
@ -26,14 +27,15 @@ public class GitHubReleasesStrategy implements ModUpdateStrategy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ModUpdate checkForUpdate(ConfigObject obj, String oldVersion, String name) {
|
@Nullable
|
||||||
|
public ModUpdate run(ConfigObject obj, String oldVersion, String name) {
|
||||||
String owner;
|
String owner;
|
||||||
String repo;
|
String repo;
|
||||||
try {
|
try {
|
||||||
owner = obj.getString("owner");
|
owner = obj.getString("owner");
|
||||||
repo = obj.getString("repository");
|
repo = obj.getString("repository");
|
||||||
} catch (ConfigObject.MissingValueException e) {
|
} catch (ConfigObject.MissingValueException e) {
|
||||||
ModUpdater.invalidModUpdaterConfig(name);
|
ModUpdater.log(name, e.getMessage());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +43,7 @@ public class GitHubReleasesStrategy implements ModUpdateStrategy {
|
|||||||
try {
|
try {
|
||||||
data = Util.urlToString(String.format("https://api.github.com/repos/%s/%s/releases", owner, repo));
|
data = Util.urlToString(String.format("https://api.github.com/repos/%s/%s/releases", owner, repo));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
ModUpdater.getLogger().warn("Unable To Access GitHub: " + name);
|
ModUpdater.log(name, e.toString());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +55,7 @@ public class GitHubReleasesStrategy implements ModUpdateStrategy {
|
|||||||
// GitHub's API never omits values, they're always null
|
// GitHub's API never omits values, they're always null
|
||||||
releases = jsonAdapter.nonNull().fromJson(data);
|
releases = jsonAdapter.nonNull().fromJson(data);
|
||||||
} catch (JsonDataException | IOException e) {
|
} catch (JsonDataException | IOException e) {
|
||||||
ModUpdater.getLogger().warn("GitHub Sent Invalid Data: ", e);
|
ModUpdater.log(name, e.toString());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package com.thebrokenrail.modupdater.strategy;
|
package com.thebrokenrail.modupdater.strategy;
|
||||||
|
|
||||||
import com.thebrokenrail.modupdater.ModUpdater;
|
import com.thebrokenrail.modupdater.ModUpdater;
|
||||||
import com.thebrokenrail.modupdater.util.ConfigObject;
|
import com.thebrokenrail.modupdater.api.ConfigObject;
|
||||||
import com.thebrokenrail.modupdater.util.ModUpdate;
|
import com.thebrokenrail.modupdater.data.ModUpdate;
|
||||||
import com.thebrokenrail.modupdater.util.ModUpdateStrategy;
|
import com.thebrokenrail.modupdater.api.UpdateStrategy;
|
||||||
import com.thebrokenrail.modupdater.util.Util;
|
import com.thebrokenrail.modupdater.util.Util;
|
||||||
import net.fabricmc.loader.api.SemanticVersion;
|
import net.fabricmc.loader.api.SemanticVersion;
|
||||||
import net.fabricmc.loader.util.version.VersionParsingException;
|
import net.fabricmc.loader.util.version.VersionParsingException;
|
||||||
@ -12,14 +12,16 @@ import org.dom4j.DocumentException;
|
|||||||
import org.dom4j.Node;
|
import org.dom4j.Node;
|
||||||
import org.dom4j.io.SAXReader;
|
import org.dom4j.io.SAXReader;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class MavenStrategy implements ModUpdateStrategy {
|
public class MavenStrategy implements UpdateStrategy {
|
||||||
@Override
|
@Override
|
||||||
public ModUpdate checkForUpdate(ConfigObject obj, String oldVersion, String name) {
|
@Nullable
|
||||||
|
public ModUpdate run(ConfigObject obj, String oldVersion, String name) {
|
||||||
String repository;
|
String repository;
|
||||||
String group;
|
String group;
|
||||||
String artifact;
|
String artifact;
|
||||||
@ -28,7 +30,7 @@ public class MavenStrategy implements ModUpdateStrategy {
|
|||||||
group = obj.getString("group");
|
group = obj.getString("group");
|
||||||
artifact = obj.getString("artifact");
|
artifact = obj.getString("artifact");
|
||||||
} catch (ConfigObject.MissingValueException e) {
|
} catch (ConfigObject.MissingValueException e) {
|
||||||
ModUpdater.invalidModUpdaterConfig(name);
|
ModUpdater.log(name, e.getMessage());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,7 +40,7 @@ public class MavenStrategy implements ModUpdateStrategy {
|
|||||||
try {
|
try {
|
||||||
data = Util.urlToString(mavenRoot + "/maven-metadata.xml");
|
data = Util.urlToString(mavenRoot + "/maven-metadata.xml");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
ModUpdater.getLogger().warn("Unable To Access Maven Repository: " + name);
|
ModUpdater.log(name, e.toString());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,11 +48,8 @@ public class MavenStrategy implements ModUpdateStrategy {
|
|||||||
try (InputStream source = new ByteArrayInputStream(data.getBytes())) {
|
try (InputStream source = new ByteArrayInputStream(data.getBytes())) {
|
||||||
SAXReader reader = new SAXReader();
|
SAXReader reader = new SAXReader();
|
||||||
doc = reader.read(source);
|
doc = reader.read(source);
|
||||||
} catch (DocumentException e) {
|
} catch (DocumentException | IOException e) {
|
||||||
ModUpdater.getLogger().warn("Maven Repository Sent Invalid Data: " + name);
|
ModUpdater.log(name, e.toString());
|
||||||
return null;
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
return 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<String, ModUpdateStrategy> 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<ModUpdate> 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());
|
|
||||||
}
|
|
||||||
}
|
|
@ -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<String, UpdateStrategy> 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());
|
||||||
|
}
|
||||||
|
}
|
@ -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<ModUpdate> 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]);
|
||||||
|
}
|
||||||
|
}
|
@ -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<String, Object> map;
|
|
||||||
|
|
||||||
public ConfigObjectHardcoded(Map<String, Object> 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 {
|
|
||||||
}
|
|
||||||
}
|
|
@ -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<String, Object> 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<String, Object> map = new HashMap<>();
|
|
||||||
map.put("strategy", "curseforge");
|
|
||||||
map.put("projectID", 308702);
|
|
||||||
return new ConfigObject.ConfigObjectHardcoded(map);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
package com.thebrokenrail.modupdater.util;
|
|
||||||
|
|
||||||
public interface ModUpdateStrategy {
|
|
||||||
ModUpdate checkForUpdate(ConfigObject obj, String oldVersion, String name);
|
|
||||||
}
|
|
@ -1,6 +1,8 @@
|
|||||||
package com.thebrokenrail.modupdater.util;
|
package com.thebrokenrail.modupdater.util;
|
||||||
|
|
||||||
import com.mojang.bridge.game.GameVersion;
|
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.FabricLoader;
|
||||||
import net.fabricmc.loader.api.ModContainer;
|
import net.fabricmc.loader.api.ModContainer;
|
||||||
import net.minecraft.MinecraftVersion;
|
import net.minecraft.MinecraftVersion;
|
||||||
@ -9,6 +11,8 @@ import java.io.BufferedReader;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class Util {
|
public class Util {
|
||||||
@ -88,4 +92,26 @@ public class Util {
|
|||||||
updateMinecraftVersion();
|
updateMinecraftVersion();
|
||||||
return minecraftVersion;
|
return minecraftVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ConfigObject getHardcodedConfig(String modID) {
|
||||||
|
switch (modID) {
|
||||||
|
case "fabric": {
|
||||||
|
Map<String, Object> 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<String, Object> map = new HashMap<>();
|
||||||
|
map.put("strategy", "curseforge");
|
||||||
|
map.put("projectID", 308702);
|
||||||
|
return new ConfigObjectHardcoded(map);
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user