@@ -82,6 +82,49 @@ private static File tryLocateSeedmapperLootDir()
8282 if (appdata != null && !appdata .isBlank ())
8383 addRootAndParents (searchRoots , new File (appdata , ".minecraft" ), 0 );
8484
85+ // Also check common locations used by flatpak / other launchers
86+ if (user != null && !user .isBlank ())
87+ {
88+ File varApp = new File (user , ".var/app" );
89+ if (varApp .exists () && varApp .isDirectory ())
90+ {
91+ File [] vendors = varApp .listFiles (File ::isDirectory );
92+ if (vendors != null )
93+ {
94+ for (File vendor : vendors )
95+ {
96+ // look inside vendor/data and vendor/data/* for
97+ // SeedMapper folders
98+ File data = new File (vendor , "data" );
99+ if (data .exists () && data .isDirectory ())
100+ {
101+ File found = searchTreeForSeedmapper (data , 4 );
102+ if (found != null )
103+ return found ;
104+ }
105+ }
106+ }
107+ }
108+
109+ // common user-level locations used by some launchers
110+ File localShare = new File (user , ".local/share" );
111+ if (localShare .exists () && localShare .isDirectory ())
112+ {
113+ File found = searchTreeForSeedmapper (localShare , 3 );
114+ if (found != null )
115+ return found ;
116+ }
117+
118+ File config = new File (user , ".config" );
119+ if (config .exists () && config .isDirectory ())
120+ {
121+ File found = searchTreeForSeedmapper (config , 3 );
122+ if (found != null )
123+ return found ;
124+ }
125+
126+ }
127+
85128 for (File root : searchRoots )
86129 {
87130 File resolved = resolveSeedmapperLoot (root );
@@ -142,6 +185,39 @@ private static File resolveSeedmapperLoot(File root)
142185 return null ;
143186 }
144187
188+ /**
189+ * Search a directory tree up to the given depth for a SeedMapper loot
190+ * folder.
191+ */
192+ private static File searchTreeForSeedmapper (File base , int maxDepth )
193+ {
194+ if (base == null || !base .exists () || !base .isDirectory ())
195+ return null ;
196+ java .util .ArrayDeque <File > dq = new java .util .ArrayDeque <>();
197+ java .util .ArrayDeque <Integer > depth = new java .util .ArrayDeque <>();
198+ dq .add (base );
199+ depth .add (0 );
200+ while (!dq .isEmpty ())
201+ {
202+ File cur = dq .removeFirst ();
203+ int d = depth .removeFirst ();
204+ File resolved = resolveSeedmapperLoot (cur );
205+ if (resolved != null )
206+ return resolved ;
207+ if (d >= maxDepth )
208+ continue ;
209+ File [] children = cur .listFiles (File ::isDirectory );
210+ if (children == null )
211+ continue ;
212+ for (File c : children )
213+ {
214+ dq .addLast (c );
215+ depth .addLast (d + 1 );
216+ }
217+ }
218+ return null ;
219+ }
220+
145221 public static File findFileForServer (String serverIp )
146222 {
147223 if (serverIp == null )
@@ -154,24 +230,35 @@ public static File findFileForServer(String serverIp)
154230 dir .listFiles ((d , name ) -> name .toLowerCase ().endsWith (".json" ));
155231 if (files == null )
156232 return null ;
157- // Build candidate tokens to try: raw, host-only, and colon->underscore
233+ // Build candidate tokens based on SeedMapper's serverId generation
234+ // serverId = serverIp with non-alnum/dot/dash/underscore -> '_',
235+ // collapse '_' repeats,
236+ // trim leading/trailing '-' or '_' and fallback to "local" when blank.
158237 java .util .List <String > candidates = new java .util .ArrayList <>();
159- candidates .add (serverIp );
160- if (serverIp .contains (":" ))
161- {
162- candidates .add (serverIp .replace (':' , '_' ));
163- String host = serverIp .split (":" , 2 )[0 ];
164- candidates .add (host );
165- }else
238+ try
166239 {
167- // also add variant without trailing port-like suffix after
168- // underscore
169- int u = serverIp .indexOf ('_' );
170- if (u > 0 )
240+ String full = serverIp ;
241+ if (full == null )
242+ full = "" ;
243+ String sanitizedFull = full .replaceAll ("[^A-Za-z0-9._-]" , "_" )
244+ .replaceAll ("_+" , "_" ).replaceAll ("^[-_]+|[-_]+$" , "" );
245+ if (sanitizedFull .isBlank ())
246+ sanitizedFull = "local" ;
247+ candidates .add (sanitizedFull );
248+
249+ // Also add host-only sanitized (strip port) for extra tolerance
250+ if (full .contains (":" ))
171251 {
172- candidates .add (serverIp .substring (0 , u ));
252+ String host = full .split (":" , 2 )[0 ];
253+ String sanitizedHost = host .replaceAll ("[^A-Za-z0-9._-]" , "_" )
254+ .replaceAll ("_+" , "_" ).replaceAll ("^[-_]+|[-_]+$" , "" );
255+ if (sanitizedHost .isBlank ())
256+ sanitizedHost = "local" ;
257+ if (!sanitizedHost .equals (sanitizedFull ))
258+ candidates .add (sanitizedHost );
173259 }
174- }
260+ }catch (Throwable ignored )
261+ {}
175262 for (File f : files )
176263 {
177264 String name = f .getName ();
0 commit comments