From e1966de8a44be9d97ee073602411cd24284816ff Mon Sep 17 00:00:00 2001 From: glowredman <35727266+glowredman@users.noreply.github.com> Date: Sun, 10 Aug 2025 21:29:37 +0200 Subject: [PATCH 1/5] Connect to remote location off main thread --- gradle.properties | 2 +- settings.gradle | 2 +- src/main/java/glowredman/defaultserverlist/Config.java | 8 ++++++-- .../java/glowredman/defaultserverlist/ModContainer.java | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/gradle.properties b/gradle.properties index 1c3e1eb..dff92f7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -151,7 +151,7 @@ modrinthProjectId = defaultserverlist # type can be one of [project, version], # and the name is the Modrinth project or version slug/id of the other mod. # Example: required-project:fplib;optional-project:gasstation;incompatible-project:gregtech -# Note: GTNH Mixins is automatically set as a required dependency if usesMixins = true +# Note: UniMixins is automatically set as a required dependency if usesMixins = true. modrinthRelations = required-project\:spongemixin1710 # Publishing to CurseForge requires you to set the CURSEFORGE_TOKEN environment variable to one of your CurseForge API tokens. diff --git a/settings.gradle b/settings.gradle index ff436f2..7622cde 100644 --- a/settings.gradle +++ b/settings.gradle @@ -17,7 +17,7 @@ pluginManagement { } plugins { - id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.38' + id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.41' } diff --git a/src/main/java/glowredman/defaultserverlist/Config.java b/src/main/java/glowredman/defaultserverlist/Config.java index 54b4066..e4716ba 100644 --- a/src/main/java/glowredman/defaultserverlist/Config.java +++ b/src/main/java/glowredman/defaultserverlist/Config.java @@ -41,7 +41,7 @@ public class Config { * spotless:on */ - public static void init(File configDir) { + static synchronized void init(File configDir) { // Setup File configFile = new File(configDir, "defaultserverlist.cfg"); @@ -98,6 +98,8 @@ public static void init(File configDir) { // Fetch servers from the specified remote location. if (useURL) { try { + LoadingPlugin.LOGGER.info("Attempting to load servers from remote location..."); + // servers that are currently at the remote location Map remoteDefaultServers = gson.fromJson( IOUtils.toString(new URL(url), StandardCharsets.UTF_8), @@ -106,6 +108,8 @@ public static void init(File configDir) { private static final long serialVersionUID = -1786059589535074931L; }.getType()); + LoadingPlugin.LOGGER.info("Successfully fetched {} servers from {}", remoteDefaultServers.size(), url); + if (allowModifications) { // servers that were added to the remote location since the last time the list was fetched Map diff = new LinkedHashMap<>(); @@ -168,7 +172,7 @@ private static Map toMap(String[] array) { return map; } - public static void saveServers(String[] servers) { + public static synchronized void saveServers(String[] servers) { setStringList("servers", servers); config.save(); } diff --git a/src/main/java/glowredman/defaultserverlist/ModContainer.java b/src/main/java/glowredman/defaultserverlist/ModContainer.java index 2fbfc2d..b6e1f51 100644 --- a/src/main/java/glowredman/defaultserverlist/ModContainer.java +++ b/src/main/java/glowredman/defaultserverlist/ModContainer.java @@ -54,6 +54,6 @@ public boolean registerBus(EventBus bus, LoadController controller) { @Subscribe public void preInit(FMLPreInitializationEvent event) { - Config.init(event.getModConfigurationDirectory()); + new Thread(() -> Config.init(event.getModConfigurationDirectory()), "DSL Config Thread").start();; } } From 4091958cb371c406e15d5e6f25914f67130a4ea5 Mon Sep 17 00:00:00 2001 From: glowredman <35727266+glowredman@users.noreply.github.com> Date: Mon, 22 Dec 2025 21:07:51 +0100 Subject: [PATCH 2/5] Schedule parsing on main thread --- .../glowredman/defaultserverlist/Config.java | 71 ++++++++++++------- .../defaultserverlist/ModContainer.java | 2 +- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/src/main/java/glowredman/defaultserverlist/Config.java b/src/main/java/glowredman/defaultserverlist/Config.java index e4716ba..caf4d99 100644 --- a/src/main/java/glowredman/defaultserverlist/Config.java +++ b/src/main/java/glowredman/defaultserverlist/Config.java @@ -11,10 +11,12 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ServerData; import net.minecraftforge.common.config.Configuration; @@ -41,7 +43,7 @@ public class Config { * spotless:on */ - static synchronized void init(File configDir) { + static void init(File configDir) { // Setup File configFile = new File(configDir, "defaultserverlist.cfg"); @@ -84,7 +86,7 @@ static synchronized void init(File configDir) { CATEGORY_GENERAL, "", "The remote location to fetch the default servers from. The returned content must be in JSON format (formatted as a map where the keys are the server names and the values the corresponding ip-adresses)."); - Map servers = toMap( + final Map servers = toMap( config.getStringList( "servers", CATEGORY_GENERAL, @@ -92,24 +94,41 @@ static synchronized void init(File configDir) { "The default servers. Format: ip|name")); String[] prevDefaultServersArray = config .getStringList("prevDefaultServers", CATEGORY_GENERAL, new String[0], "DO NOT EDIT!"); - Collection prevDefaultServers = new ArrayList<>(prevDefaultServersArray.length); + final Collection prevDefaultServers = new ArrayList<>(prevDefaultServersArray.length); Arrays.stream(prevDefaultServersArray).forEachOrdered(prevDefaultServers::add); + // save the config if it changed. + if (config.hasChanged()) { + config.save(); + } + // Fetch servers from the specified remote location. if (useURL) { - try { - LoadingPlugin.LOGGER.info("Attempting to load servers from remote location..."); - - // servers that are currently at the remote location - Map remoteDefaultServers = gson.fromJson( - IOUtils.toString(new URL(url), StandardCharsets.UTF_8), - new TypeToken>() { - - private static final long serialVersionUID = -1786059589535074931L; - }.getType()); + final Map remoteDefaultServers = new HashMap<>(); + new Thread(() -> { + LoadingPlugin.LOGGER.info("Attempting to load servers from remote location..."); + try { + // servers that are currently at the remote location + remoteDefaultServers.putAll( + gson.fromJson( + IOUtils.toString(new URL(url), StandardCharsets.UTF_8), + new TypeToken>() { + + private static final long serialVersionUID = -1786059589535074931L; + }.getType())); + } catch (Exception e) { + LoadingPlugin.LOGGER.error( + "Could not get default server list from {}! Are you connected to the internet?", + url, + e); + return; + } LoadingPlugin.LOGGER.info("Successfully fetched {} servers from {}", remoteDefaultServers.size(), url); + }, "DSL Config Thread").start(); + // func_152344_a = addScheduledTask + Minecraft.getMinecraft().func_152344_a(() -> { if (allowModifications) { // servers that were added to the remote location since the last time the list was fetched Map diff = new LinkedHashMap<>(); @@ -125,28 +144,28 @@ static synchronized void init(File configDir) { // save if the remote location was updated if (!diff.isEmpty()) { servers.putAll(diff); - prevDefaultServers = remoteDefaultServers.values(); + prevDefaultServers.clear(); + prevDefaultServers.addAll(remoteDefaultServers.values()); setStringList("servers", toArray(servers)); setStringList("prevDefaultServers", prevDefaultServers.toArray(new String[0])); } } else { - servers = remoteDefaultServers; + servers.clear(); + servers.putAll(remoteDefaultServers); setStringList("servers", toArray(servers)); } - } catch (Exception e) { - LoadingPlugin.LOGGER - .error("Could not get default server list from {}! Are you connected to the internet?", url, e); - } - } - // save the config if it changed. - if (config.hasChanged()) { - config.save(); + // save the config if it changed. + if (config.hasChanged()) { + config.save(); + } + }); } // Convert from Map to List - servers.forEach((name, ip) -> SERVERS.add(new ServerData(name, ip))); + Minecraft.getMinecraft() + .func_152344_a(() -> servers.forEach((name, ip) -> SERVERS.add(new ServerData(name, ip)))); } private static String[] toArray(Map map) { @@ -164,7 +183,7 @@ private static Map toMap(String[] array) { for (String entry : array) { String[] parts = entry.split("\\|", 2); if (parts.length < 2) { - LoadingPlugin.LOGGER.warn("Could not parse entry {} because not '|' was found!", entry); + LoadingPlugin.LOGGER.warn("Could not parse entry {} because no '|' was found!", entry); continue; } map.put(parts[1], parts[0]); @@ -172,7 +191,7 @@ private static Map toMap(String[] array) { return map; } - public static synchronized void saveServers(String[] servers) { + public static void saveServers(String[] servers) { setStringList("servers", servers); config.save(); } diff --git a/src/main/java/glowredman/defaultserverlist/ModContainer.java b/src/main/java/glowredman/defaultserverlist/ModContainer.java index b6e1f51..2fbfc2d 100644 --- a/src/main/java/glowredman/defaultserverlist/ModContainer.java +++ b/src/main/java/glowredman/defaultserverlist/ModContainer.java @@ -54,6 +54,6 @@ public boolean registerBus(EventBus bus, LoadController controller) { @Subscribe public void preInit(FMLPreInitializationEvent event) { - new Thread(() -> Config.init(event.getModConfigurationDirectory()), "DSL Config Thread").start();; + Config.init(event.getModConfigurationDirectory()); } } From 47dda177ada96a3e2f46e30ac3fbb1ffc3add76c Mon Sep 17 00:00:00 2001 From: glowredman <35727266+glowredman@users.noreply.github.com> Date: Mon, 22 Dec 2025 22:34:51 +0100 Subject: [PATCH 3/5] Remove useless `replace` calls --- .../defaultserverlist/mixins/early/ServerListMixin.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/glowredman/defaultserverlist/mixins/early/ServerListMixin.java b/src/main/java/glowredman/defaultserverlist/mixins/early/ServerListMixin.java index 94bcb53..0009f0a 100644 --- a/src/main/java/glowredman/defaultserverlist/mixins/early/ServerListMixin.java +++ b/src/main/java/glowredman/defaultserverlist/mixins/early/ServerListMixin.java @@ -33,9 +33,9 @@ public abstract class ServerListMixin { @Inject(at = @At("TAIL"), method = "loadServerList()V") private void removeDuplicateServers(CallbackInfo ci) { servers.removeIf(o -> { - String s1 = o.serverIP.replace("http://", "").replace("https://", "").replace(":25565", ""); + String s1 = o.serverIP.replace(":25565", ""); for (ServerData s2 : Config.SERVERS) { - if (s1.equals(s2.serverIP.replace("http://", "").replace("https://", "").replace(":25565", ""))) { + if (s1.equals(s2.serverIP.replace(":25565", ""))) { return true; } } From 1aa7a144a571794913c30a647672e40854d19b51 Mon Sep 17 00:00:00 2001 From: glowredman <35727266+glowredman@users.noreply.github.com> Date: Mon, 22 Dec 2025 22:35:51 +0100 Subject: [PATCH 4/5] Put `func_152344_a` at the right place, extract methods --- .../glowredman/defaultserverlist/Config.java | 118 ++++++++++-------- 1 file changed, 69 insertions(+), 49 deletions(-) diff --git a/src/main/java/glowredman/defaultserverlist/Config.java b/src/main/java/glowredman/defaultserverlist/Config.java index caf4d99..e8ec1e1 100644 --- a/src/main/java/glowredman/defaultserverlist/Config.java +++ b/src/main/java/glowredman/defaultserverlist/Config.java @@ -3,15 +3,16 @@ import static net.minecraftforge.common.config.Configuration.CATEGORY_GENERAL; import java.io.File; +import java.io.IOException; import java.io.Reader; import java.net.URL; +import java.net.URLConnection; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -24,6 +25,7 @@ import com.google.common.reflect.TypeToken; import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; import com.google.gson.annotations.SerializedName; public class Config { @@ -104,19 +106,12 @@ static void init(File configDir) { // Fetch servers from the specified remote location. if (useURL) { - final Map remoteDefaultServers = new HashMap<>(); + final Map remoteDefaultServers = new LinkedHashMap<>(); new Thread(() -> { LoadingPlugin.LOGGER.info("Attempting to load servers from remote location..."); try { - // servers that are currently at the remote location - remoteDefaultServers.putAll( - gson.fromJson( - IOUtils.toString(new URL(url), StandardCharsets.UTF_8), - new TypeToken>() { - - private static final long serialVersionUID = -1786059589535074931L; - }.getType())); + fetchRemoteServers(url, remoteDefaultServers); } catch (Exception e) { LoadingPlugin.LOGGER.error( "Could not get default server list from {}! Are you connected to the internet?", @@ -124,48 +119,18 @@ static void init(File configDir) { e); return; } - LoadingPlugin.LOGGER.info("Successfully fetched {} servers from {}", remoteDefaultServers.size(), url); - }, "DSL Config Thread").start(); - // func_152344_a = addScheduledTask - Minecraft.getMinecraft().func_152344_a(() -> { - if (allowModifications) { - // servers that were added to the remote location since the last time the list was fetched - Map diff = new LinkedHashMap<>(); - - // calculate diff - for (Map.Entry entry : remoteDefaultServers.entrySet()) { - String ip = entry.getValue(); - if (!prevDefaultServers.contains(ip)) { - diff.put(entry.getKey(), ip); - } - } - - // save if the remote location was updated - if (!diff.isEmpty()) { - servers.putAll(diff); - prevDefaultServers.clear(); - prevDefaultServers.addAll(remoteDefaultServers.values()); - setStringList("servers", toArray(servers)); - setStringList("prevDefaultServers", prevDefaultServers.toArray(new String[0])); - } - - } else { - servers.clear(); - servers.putAll(remoteDefaultServers); - setStringList("servers", toArray(servers)); - } + LoadingPlugin.LOGGER.info("Successfully fetched {} servers from {}", remoteDefaultServers.size(), url); - // save the config if it changed. - if (config.hasChanged()) { - config.save(); - } - }); + // func_152344_a = addScheduledTask + Minecraft.getMinecraft() + .func_152344_a(() -> parseServers(servers, prevDefaultServers, remoteDefaultServers)); + }, "DSL Config Thread").start(); + } else { + // Convert from Map to List + // This has to be executed even if the servers aren't fetched from a remote server + servers.forEach(Config::addServer); } - - // Convert from Map to List - Minecraft.getMinecraft() - .func_152344_a(() -> servers.forEach((name, ip) -> SERVERS.add(new ServerData(name, ip)))); } private static String[] toArray(Map map) { @@ -191,6 +156,61 @@ private static Map toMap(String[] array) { return map; } + private static void fetchRemoteServers(String url, Map remoteDefaultServers) + throws JsonSyntaxException, IOException { + URLConnection connection = new URL(url).openConnection(); + connection.setConnectTimeout(10000); + connection.setReadTimeout(10000); + String rawJson = IOUtils.toString(connection.getInputStream(), StandardCharsets.UTF_8); + TypeToken> typeToken = new TypeToken<>() { + + private static final long serialVersionUID = -1786059589535074931L; + }; + remoteDefaultServers.putAll(new Gson().fromJson(rawJson, typeToken.getType())); + } + + private static void parseServers(Map servers, Collection prevDefaultServers, + Map remoteDefaultServers) { + if (allowModifications) { + // servers that were added to the remote location since the last time the list was fetched + Map diff = new LinkedHashMap<>(); + + // calculate diff + for (Map.Entry entry : remoteDefaultServers.entrySet()) { + String ip = entry.getValue(); + if (!prevDefaultServers.contains(ip)) { + diff.put(entry.getKey(), ip); + } + } + + // save if the remote location was updated + if (!diff.isEmpty()) { + servers.putAll(diff); + prevDefaultServers.clear(); + prevDefaultServers.addAll(remoteDefaultServers.values()); + setStringList("servers", toArray(servers)); + setStringList("prevDefaultServers", prevDefaultServers.toArray(new String[0])); + } + + } else { + servers.clear(); + servers.putAll(remoteDefaultServers); + setStringList("servers", toArray(servers)); + } + + // Convert from Map to List + servers.forEach(Config::addServer); + + // save the config if it changed. + if (config.hasChanged()) { + config.save(); + } + } + + private static void addServer(String name, String ip) { + SERVERS.add(new ServerData(name, ip)); + } + public static void saveServers(String[] servers) { setStringList("servers", servers); config.save(); From f858ad424d066554b73d7e3fa996f72cc7435c45 Mon Sep 17 00:00:00 2001 From: glowredman <35727266+glowredman@users.noreply.github.com> Date: Mon, 22 Dec 2025 22:43:17 +0100 Subject: [PATCH 5/5] Close InputStream --- .../java/glowredman/defaultserverlist/Config.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/glowredman/defaultserverlist/Config.java b/src/main/java/glowredman/defaultserverlist/Config.java index e8ec1e1..05bd876 100644 --- a/src/main/java/glowredman/defaultserverlist/Config.java +++ b/src/main/java/glowredman/defaultserverlist/Config.java @@ -4,6 +4,7 @@ import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.io.Reader; import java.net.URL; import java.net.URLConnection; @@ -161,12 +162,15 @@ private static void fetchRemoteServers(String url, Map remoteDef URLConnection connection = new URL(url).openConnection(); connection.setConnectTimeout(10000); connection.setReadTimeout(10000); - String rawJson = IOUtils.toString(connection.getInputStream(), StandardCharsets.UTF_8); - TypeToken> typeToken = new TypeToken<>() { - private static final long serialVersionUID = -1786059589535074931L; - }; - remoteDefaultServers.putAll(new Gson().fromJson(rawJson, typeToken.getType())); + try (InputStream is = connection.getInputStream()) { + String rawJson = IOUtils.toString(is, StandardCharsets.UTF_8); + TypeToken> typeToken = new TypeToken<>() { + + private static final long serialVersionUID = -1786059589535074931L; + }; + remoteDefaultServers.putAll(new Gson().fromJson(rawJson, typeToken.getType())); + } } private static void parseServers(Map servers, Collection prevDefaultServers,