diff --git a/src/main/java/org/teacon/sync/Config.java b/src/main/java/org/teacon/sync/Config.java index 9070309..5d617a2 100644 --- a/src/main/java/org/teacon/sync/Config.java +++ b/src/main/java/org/teacon/sync/Config.java @@ -20,8 +20,7 @@ package org.teacon.sync; -import java.net.URL; -import java.util.Collections; +import java.util.ArrayList; import java.util.List; public final class Config { @@ -29,11 +28,8 @@ public final class Config { /** * URL that points to the mod list to download. Supported protocols include * http, https, files (i.e. local file) and others. - * - * @see URL - * @see URL#getProtocol() */ - public URL modList; + public String modList; /** * Path to the directory where all downloaded mods are held, relative to the * Minecraft home directory. @@ -53,13 +49,13 @@ public final class Config { * List of URLs of key servers. These key servers SHOULD support the HTTP * Keyserver Protocol. */ - public List keyServers = Collections.emptyList(); + public List keyServers = new ArrayList<>(); /** * List of public keys identified by key IDs. 32-bit key ID, 64-bit key ID, * version 3 fingerprint and version 4 fingerprint are acceptable; these key * IDs SHOULD be prefixed with {@code 0x} as a mark of hexadecimal number. */ - public List keyIds = Collections.emptyList(); + public List keyIds = new ArrayList<>(); /** * Amount of time to wait before giving up a connection, measured in milliseconds. */ diff --git a/src/main/java/org/teacon/sync/PGPKeyStore.java b/src/main/java/org/teacon/sync/PGPKeyStore.java index 52ee6a8..b882178 100644 --- a/src/main/java/org/teacon/sync/PGPKeyStore.java +++ b/src/main/java/org/teacon/sync/PGPKeyStore.java @@ -87,7 +87,7 @@ public final class PGPKeyStore { private final PGPPublicKeyRingCollection keyRings; - public PGPKeyStore(Path localKeyStorePath, List keyServers, List keyIds) throws Exception { + public PGPKeyStore(Path localKeyStorePath, List keyServers, List keyIds) throws Exception { final Map keyRings = new HashMap<>(); if (Files.exists(localKeyStorePath)) { LOGGER.debug(MARKER, "Try reading keys from local key ring at {}", localKeyStorePath); @@ -99,8 +99,8 @@ public PGPKeyStore(Path localKeyStorePath, List keyServers, List ke continue; } final String queryParams = "/pks/lookup?op=get&search=".concat(keyId); - for (URL keyServer : keyServers) { - final URL resolved = resolveSrv(keyServer); + for (String keyServer : keyServers) { + final URL resolved = resolveSrv(new URL(keyServer)); final URL keyQuery = new URL(resolved.getProtocol(), resolved.getHost(), resolved.getPort(), queryParams); try (InputStream input = keyQuery.openStream()) { LOGGER.debug(MARKER, "Receiving key {} from {}", keyId, keyServer); diff --git a/src/main/java/org/teacon/sync/SyncedModLocator.java b/src/main/java/org/teacon/sync/SyncedModLocator.java index bd0b0c1..1123d38 100644 --- a/src/main/java/org/teacon/sync/SyncedModLocator.java +++ b/src/main/java/org/teacon/sync/SyncedModLocator.java @@ -20,6 +20,8 @@ package org.teacon.sync; +import com.electronwill.nightconfig.core.conversion.ObjectConverter; +import com.electronwill.nightconfig.toml.TomlParser; import com.google.gson.Gson; import com.google.gson.JsonParseException; import cpw.mods.modlauncher.Launcher; @@ -36,9 +38,9 @@ import java.io.IOException; import java.io.InputStream; import java.io.Reader; +import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.FileChannel; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -52,6 +54,8 @@ import java.util.function.Consumer; import java.util.stream.Stream; +import static java.nio.charset.StandardCharsets.UTF_8; + public final class SyncedModLocator extends AbstractJarFileModLocator { private static final Logger LOGGER = LogManager.getLogger("RemoteSync"); @@ -68,12 +72,17 @@ public final class SyncedModLocator extends AbstractJarFileModLocator { public SyncedModLocator() throws Exception { this.progressFeed = Launcher.INSTANCE.environment().getProperty(Environment.Keys.PROGRESSMESSAGE.get()).orElse(msg -> {}); final Path gameDir = Launcher.INSTANCE.environment().getProperty(IEnvironment.Keys.GAMEDIR.get()).orElse(Paths.get(".")); - final Path cfgPath = gameDir.resolve("remote_sync.json"); + final Path cfgTomlPath = gameDir.resolve("remote_sync.toml"); + final Path cfgJsonPath = gameDir.resolve("remote_sync.json"); final Config cfg; - if (Files.exists(cfgPath)) { - cfg = GSON.fromJson(Files.newBufferedReader(cfgPath, StandardCharsets.UTF_8), Config.class); + if (Files.exists(cfgTomlPath)) { + LOGGER.info("RemoteSync config remote_sync.toml is considered as the TOML config to be read."); + cfg = new ObjectConverter().toObject(new TomlParser().parse(Files.newBufferedReader(cfgTomlPath, UTF_8)), Config::new); + } else if (Files.exists(cfgJsonPath)) { + LOGGER.info("RemoteSync config remote_sync.json is considered as the JSON config to be read."); + cfg = GSON.fromJson(Files.newBufferedReader(cfgJsonPath, UTF_8), Config.class); } else { - LOGGER.warn("RemoteSync config remote_sync.json does not exist. All configurable values will use their default values instead."); + LOGGER.warn("Neither remote_sync.toml nor remote_sync.json exists. All configurable values will use their default values instead."); cfg = new Config(); } final Path keyStorePath = gameDir.resolve(cfg.keyRingPath); @@ -85,7 +94,7 @@ public SyncedModLocator() throws Exception { try { this.progressFeed.accept("RemoteSync: fetching mod list"); // Intentionally do not use config value to ensure that the mod list is always up-to-date - return Utils.fetch(cfg.modList, localCache, cfg.timeout, false); + return Utils.fetch(new URL(cfg.modList), localCache, cfg.timeout, false); } catch (IOException e) { LOGGER.warn("Failed to download mod list, will try using locally cached mod list instead. Mods may be outdated.", e); System.setProperty("org.teacon.sync.failed", "true"); @@ -96,7 +105,7 @@ public SyncedModLocator() throws Exception { } } }).thenApplyAsync((fcModList) -> { - try (Reader reader = Channels.newReader(fcModList, StandardCharsets.UTF_8)) { + try (Reader reader = Channels.newReader(fcModList, UTF_8)) { return GSON.fromJson(reader, ModEntry[].class); } catch (JsonParseException e) { LOGGER.warn("Error parsing mod list", e); @@ -185,5 +194,4 @@ private boolean isValid(Path modFile) { return false; } } - }