33import static net .minecraftforge .common .config .Configuration .CATEGORY_GENERAL ;
44
55import java .io .File ;
6+ import java .io .IOException ;
7+ import java .io .InputStream ;
68import java .io .Reader ;
79import java .net .URL ;
10+ import java .net .URLConnection ;
811import java .nio .charset .StandardCharsets ;
912import java .nio .file .Files ;
1013import java .nio .file .Path ;
1518import java .util .List ;
1619import java .util .Map ;
1720
21+ import net .minecraft .client .Minecraft ;
1822import net .minecraft .client .multiplayer .ServerData ;
1923import net .minecraftforge .common .config .Configuration ;
2024
2125import org .apache .commons .io .IOUtils ;
2226
2327import com .google .common .reflect .TypeToken ;
2428import com .google .gson .Gson ;
29+ import com .google .gson .JsonSyntaxException ;
2530import com .google .gson .annotations .SerializedName ;
2631
2732public class Config {
@@ -41,7 +46,7 @@ public class Config {
4146 * spotless:on
4247 */
4348
44- public static void init (File configDir ) {
49+ static void init (File configDir ) {
4550
4651 // Setup
4752 File configFile = new File (configDir , "defaultserverlist.cfg" );
@@ -84,65 +89,49 @@ public static void init(File configDir) {
8489 CATEGORY_GENERAL ,
8590 "" ,
8691 "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)." );
87- Map <String , String > servers = toMap (
92+ final Map <String , String > servers = toMap (
8893 config .getStringList (
8994 "servers" ,
9095 CATEGORY_GENERAL ,
9196 new String [0 ],
9297 "The default servers. Format: ip|name" ));
9398 String [] prevDefaultServersArray = config
9499 .getStringList ("prevDefaultServers" , CATEGORY_GENERAL , new String [0 ], "DO NOT EDIT!" );
95- Collection <String > prevDefaultServers = new ArrayList <>(prevDefaultServersArray .length );
100+ final Collection <String > prevDefaultServers = new ArrayList <>(prevDefaultServersArray .length );
96101 Arrays .stream (prevDefaultServersArray ).forEachOrdered (prevDefaultServers ::add );
97102
98- // Fetch servers from the specified remote location.
99- if (useURL ) {
100- try {
101- // servers that are currently at the remote location
102- Map <String , String > remoteDefaultServers = gson .fromJson (
103- IOUtils .toString (new URL (url ), StandardCharsets .UTF_8 ),
104- new TypeToken <LinkedHashMap <String , String >>() {
105-
106- private static final long serialVersionUID = -1786059589535074931L ;
107- }.getType ());
108-
109- if (allowModifications ) {
110- // servers that were added to the remote location since the last time the list was fetched
111- Map <String , String > diff = new LinkedHashMap <>();
112-
113- // calculate diff
114- for (Map .Entry <String , String > entry : remoteDefaultServers .entrySet ()) {
115- String ip = entry .getValue ();
116- if (!prevDefaultServers .contains (ip )) {
117- diff .put (entry .getKey (), ip );
118- }
119- }
120-
121- // save if the remote location was updated
122- if (!diff .isEmpty ()) {
123- servers .putAll (diff );
124- prevDefaultServers = remoteDefaultServers .values ();
125- setStringList ("servers" , toArray (servers ));
126- setStringList ("prevDefaultServers" , prevDefaultServers .toArray (new String [0 ]));
127- }
128-
129- } else {
130- servers = remoteDefaultServers ;
131- setStringList ("servers" , toArray (servers ));
132- }
133- } catch (Exception e ) {
134- LoadingPlugin .LOGGER
135- .error ("Could not get default server list from {}! Are you connected to the internet?" , url , e );
136- }
137- }
138-
139103 // save the config if it changed.
140104 if (config .hasChanged ()) {
141105 config .save ();
142106 }
143107
144- // Convert from Map<String, String> to List<ServerData>
145- servers .forEach ((name , ip ) -> SERVERS .add (new ServerData (name , ip )));
108+ // Fetch servers from the specified remote location.
109+ if (useURL ) {
110+ final Map <String , String > remoteDefaultServers = new LinkedHashMap <>();
111+
112+ new Thread (() -> {
113+ LoadingPlugin .LOGGER .info ("Attempting to load servers from remote location..." );
114+ try {
115+ fetchRemoteServers (url , remoteDefaultServers );
116+ } catch (Exception e ) {
117+ LoadingPlugin .LOGGER .error (
118+ "Could not get default server list from {}! Are you connected to the internet?" ,
119+ url ,
120+ e );
121+ return ;
122+ }
123+
124+ LoadingPlugin .LOGGER .info ("Successfully fetched {} servers from {}" , remoteDefaultServers .size (), url );
125+
126+ // func_152344_a = addScheduledTask
127+ Minecraft .getMinecraft ()
128+ .func_152344_a (() -> parseServers (servers , prevDefaultServers , remoteDefaultServers ));
129+ }, "DSL Config Thread" ).start ();
130+ } else {
131+ // Convert from Map<String, String> to List<ServerData>
132+ // This has to be executed even if the servers aren't fetched from a remote server
133+ servers .forEach (Config ::addServer );
134+ }
146135 }
147136
148137 private static String [] toArray (Map <String , String > map ) {
@@ -160,14 +149,72 @@ private static Map<String, String> toMap(String[] array) {
160149 for (String entry : array ) {
161150 String [] parts = entry .split ("\\ |" , 2 );
162151 if (parts .length < 2 ) {
163- LoadingPlugin .LOGGER .warn ("Could not parse entry {} because not '|' was found!" , entry );
152+ LoadingPlugin .LOGGER .warn ("Could not parse entry {} because no '|' was found!" , entry );
164153 continue ;
165154 }
166155 map .put (parts [1 ], parts [0 ]);
167156 }
168157 return map ;
169158 }
170159
160+ private static void fetchRemoteServers (String url , Map <String , String > remoteDefaultServers )
161+ throws JsonSyntaxException , IOException {
162+ URLConnection connection = new URL (url ).openConnection ();
163+ connection .setConnectTimeout (10000 );
164+ connection .setReadTimeout (10000 );
165+
166+ try (InputStream is = connection .getInputStream ()) {
167+ String rawJson = IOUtils .toString (is , StandardCharsets .UTF_8 );
168+ TypeToken <LinkedHashMap <String , String >> typeToken = new TypeToken <>() {
169+
170+ private static final long serialVersionUID = -1786059589535074931L ;
171+ };
172+ remoteDefaultServers .putAll (new Gson ().fromJson (rawJson , typeToken .getType ()));
173+ }
174+ }
175+
176+ private static void parseServers (Map <String , String > servers , Collection <String > prevDefaultServers ,
177+ Map <String , String > remoteDefaultServers ) {
178+ if (allowModifications ) {
179+ // servers that were added to the remote location since the last time the list was fetched
180+ Map <String , String > diff = new LinkedHashMap <>();
181+
182+ // calculate diff
183+ for (Map .Entry <String , String > entry : remoteDefaultServers .entrySet ()) {
184+ String ip = entry .getValue ();
185+ if (!prevDefaultServers .contains (ip )) {
186+ diff .put (entry .getKey (), ip );
187+ }
188+ }
189+
190+ // save if the remote location was updated
191+ if (!diff .isEmpty ()) {
192+ servers .putAll (diff );
193+ prevDefaultServers .clear ();
194+ prevDefaultServers .addAll (remoteDefaultServers .values ());
195+ setStringList ("servers" , toArray (servers ));
196+ setStringList ("prevDefaultServers" , prevDefaultServers .toArray (new String [0 ]));
197+ }
198+
199+ } else {
200+ servers .clear ();
201+ servers .putAll (remoteDefaultServers );
202+ setStringList ("servers" , toArray (servers ));
203+ }
204+
205+ // Convert from Map<String, String> to List<ServerData>
206+ servers .forEach (Config ::addServer );
207+
208+ // save the config if it changed.
209+ if (config .hasChanged ()) {
210+ config .save ();
211+ }
212+ }
213+
214+ private static void addServer (String name , String ip ) {
215+ SERVERS .add (new ServerData (name , ip ));
216+ }
217+
171218 public static void saveServers (String [] servers ) {
172219 setStringList ("servers" , servers );
173220 config .save ();
0 commit comments