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- static synchronized void init (File configDir ) {
49+ static void init (File configDir ) {
4550
4651 // Setup
4752 File configFile = new File (configDir , "defaultserverlist.cfg" );
@@ -84,69 +89,49 @@ static synchronized 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
103+ // save the config if it changed.
104+ if (config .hasChanged ()) {
105+ config .save ();
106+ }
107+
98108 // Fetch servers from the specified remote location.
99109 if (useURL ) {
100- try {
101- LoadingPlugin .LOGGER .info ("Attempting to load servers from remote location..." );
110+ final Map <String , String > remoteDefaultServers = new LinkedHashMap <>();
102111
103- // servers that are currently at the remote location
104- Map <String , String > remoteDefaultServers = gson .fromJson (
105- IOUtils .toString (new URL (url ), StandardCharsets .UTF_8 ),
106- new TypeToken <LinkedHashMap <String , String >>() {
107-
108- private static final long serialVersionUID = -1786059589535074931L ;
109- }.getType ());
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+ }
110123
111124 LoadingPlugin .LOGGER .info ("Successfully fetched {} servers from {}" , remoteDefaultServers .size (), url );
112125
113- if (allowModifications ) {
114- // servers that were added to the remote location since the last time the list was fetched
115- Map <String , String > diff = new LinkedHashMap <>();
116-
117- // calculate diff
118- for (Map .Entry <String , String > entry : remoteDefaultServers .entrySet ()) {
119- String ip = entry .getValue ();
120- if (!prevDefaultServers .contains (ip )) {
121- diff .put (entry .getKey (), ip );
122- }
123- }
124-
125- // save if the remote location was updated
126- if (!diff .isEmpty ()) {
127- servers .putAll (diff );
128- prevDefaultServers = remoteDefaultServers .values ();
129- setStringList ("servers" , toArray (servers ));
130- setStringList ("prevDefaultServers" , prevDefaultServers .toArray (new String [0 ]));
131- }
132-
133- } else {
134- servers = remoteDefaultServers ;
135- setStringList ("servers" , toArray (servers ));
136- }
137- } catch (Exception e ) {
138- LoadingPlugin .LOGGER
139- .error ("Could not get default server list from {}! Are you connected to the internet?" , url , e );
140- }
141- }
142-
143- // save the config if it changed.
144- if (config .hasChanged ()) {
145- config .save ();
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 );
146134 }
147-
148- // Convert from Map<String, String> to List<ServerData>
149- servers .forEach ((name , ip ) -> SERVERS .add (new ServerData (name , ip )));
150135 }
151136
152137 private static String [] toArray (Map <String , String > map ) {
@@ -164,15 +149,73 @@ private static Map<String, String> toMap(String[] array) {
164149 for (String entry : array ) {
165150 String [] parts = entry .split ("\\ |" , 2 );
166151 if (parts .length < 2 ) {
167- 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 );
168153 continue ;
169154 }
170155 map .put (parts [1 ], parts [0 ]);
171156 }
172157 return map ;
173158 }
174159
175- public static synchronized void saveServers (String [] servers ) {
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+
218+ public static void saveServers (String [] servers ) {
176219 setStringList ("servers" , servers );
177220 config .save ();
178221 }
0 commit comments