|
3 | 3 | import org.slf4j.Logger; |
4 | 4 | import org.slf4j.LoggerFactory; |
5 | 5 | import pro.gravit.utils.helper.IOHelper; |
6 | | -import pro.gravit.utils.helper.LogHelper; |
7 | 6 |
|
8 | 7 | import java.io.*; |
9 | 8 | import java.net.URL; |
@@ -32,16 +31,84 @@ public class InstallAuthlib { |
32 | 31 | public void run(String... args) throws Exception { |
33 | 32 | boolean deleteAuthlibAfterInstall = false; |
34 | 33 | InstallAuthlibContext context = new InstallAuthlibContext(); |
35 | | - if(args[0].startsWith("http://") || args[0].startsWith("https://")) { |
36 | | - Path tempAuthlib = Paths.get(tempLaunchAuthLibName); |
37 | | - logger.info("Download {} to {}", args[0], tempAuthlib); |
38 | | - try(InputStream input = IOHelper.newInput(new URL(args[0]))) { |
39 | | - IOHelper.transfer(input, tempAuthlib); |
| 34 | + String source = null; |
| 35 | + if (args != null && args.length > 0) { |
| 36 | + source = args[0]; |
| 37 | + } |
| 38 | + if (source == null || source.isEmpty()) { |
| 39 | + // Detect version from libraries/com/mojang/authlib/ |
| 40 | + try { |
| 41 | + Path libs = context.workdir.resolve("libraries").resolve("com").resolve("mojang").resolve("authlib"); |
| 42 | + if (Files.exists(libs) && Files.isDirectory(libs)) { |
| 43 | + Optional<String> best = Files.list(libs) |
| 44 | + .filter(Files::isDirectory) |
| 45 | + .map(p -> p.getFileName().toString()) |
| 46 | + .max(InstallAuthlib::compareVersion); |
| 47 | + if (best.isPresent()) { |
| 48 | + String version = best.get(); |
| 49 | + int major = parseMajor(version); |
| 50 | + String fileName; |
| 51 | + if (major == 3 && inRange(version, "3.5.41", "3.18.38")) { |
| 52 | + fileName = "LauncherAuthlib3-1.19.jar"; |
| 53 | + } else { |
| 54 | + fileName = "LauncherAuthlib" + major + ".jar"; |
| 55 | + } |
| 56 | + // Get mirrors from system property or env, fallback to default |
| 57 | + String prop = System.getProperty("installAuthlib.mirrors"); |
| 58 | + List<String> mirrors; |
| 59 | + if (prop != null && !prop.isEmpty()) { |
| 60 | + mirrors = Arrays.asList(prop.split(",")); |
| 61 | + } else if (System.getenv("SERVERWRAPPER_MIRRORS") != null) { |
| 62 | + mirrors = Arrays.asList(System.getenv("SERVERWRAPPER_MIRRORS").split(",")); |
| 63 | + } else { |
| 64 | + mirrors = List.of("https://mirror.gravitlauncher.com/5.7.x/"); |
| 65 | + } |
| 66 | + String chosen = null; |
| 67 | + for (String base : mirrors) { |
| 68 | + String b = base.endsWith("/") ? base : base + "/"; |
| 69 | + String urlStr = b + "authlib/" + fileName; |
| 70 | + try { |
| 71 | + logger.info("Try download {}", urlStr); |
| 72 | + try (InputStream input = IOHelper.newInput(new URL(urlStr))) { |
| 73 | + Path tempAuthlib = Paths.get(tempLaunchAuthLibName); |
| 74 | + IOHelper.transfer(input, tempAuthlib); |
| 75 | + context.pathToAuthlib = tempAuthlib.toAbsolutePath(); |
| 76 | + deleteAuthlibAfterInstall = true; |
| 77 | + chosen = urlStr; |
| 78 | + break; |
| 79 | + } |
| 80 | + } catch (FileNotFoundException fnf) { |
| 81 | + logger.info("Not found on mirror: {}", urlStr); |
| 82 | + continue; |
| 83 | + } catch (IOException ioe) { |
| 84 | + logger.info("Failed to download from {}: {}", urlStr, ioe.getMessage()); |
| 85 | + continue; |
| 86 | + } |
| 87 | + } |
| 88 | + if (chosen == null) { |
| 89 | + throw new FileNotFoundException("LauncherAuthlib for detected version " + version + " not found on mirrors. Please notify developers."); |
| 90 | + } |
| 91 | + } else { |
| 92 | + throw new FileNotFoundException("No authlib versions found in " + libs.toString()); |
| 93 | + } |
| 94 | + } else { |
| 95 | + throw new FileNotFoundException("Libraries authlib directory not found: " + libs.toString()); |
| 96 | + } |
| 97 | + } catch (IOException e) { |
| 98 | + throw e; |
40 | 99 | } |
41 | | - context.pathToAuthlib = tempAuthlib.toAbsolutePath(); |
42 | | - deleteAuthlibAfterInstall = true; |
43 | 100 | } else { |
44 | | - context.pathToAuthlib = Paths.get(args[0]).toAbsolutePath(); |
| 101 | + if(source.startsWith("http://") || source.startsWith("https://")) { |
| 102 | + Path tempAuthlib = Paths.get(tempLaunchAuthLibName); |
| 103 | + logger.info("Download {} to {}", source, tempAuthlib); |
| 104 | + try(InputStream input = IOHelper.newInput(new URL(source))) { |
| 105 | + IOHelper.transfer(input, tempAuthlib); |
| 106 | + } |
| 107 | + context.pathToAuthlib = tempAuthlib.toAbsolutePath(); |
| 108 | + deleteAuthlibAfterInstall = true; |
| 109 | + } else { |
| 110 | + context.pathToAuthlib = Paths.get(source).toAbsolutePath(); |
| 111 | + } |
45 | 112 | } |
46 | 113 | if(Files.notExists(context.pathToAuthlib)) { |
47 | 114 | throw new FileNotFoundException(context.pathToAuthlib.toString()); |
@@ -187,6 +254,39 @@ private Set<String> getNames(Path path) throws IOException { |
187 | 254 | return set; |
188 | 255 | } |
189 | 256 |
|
| 257 | + private static int compareVersion(String a, String b) { |
| 258 | + int[] va = parseVersion(a); |
| 259 | + int[] vb = parseVersion(b); |
| 260 | + for (int i = 0; i < Math.max(va.length, vb.length); i++) { |
| 261 | + int ca = i < va.length ? va[i] : 0; |
| 262 | + int cb = i < vb.length ? vb[i] : 0; |
| 263 | + if (ca != cb) return Integer.compare(ca, cb); |
| 264 | + } |
| 265 | + return 0; |
| 266 | + } |
| 267 | + |
| 268 | + private static int[] parseVersion(String v) { |
| 269 | + try { |
| 270 | + String[] parts = v.split("[.-]"); |
| 271 | + int[] res = new int[parts.length]; |
| 272 | + for (int i = 0; i < parts.length; i++) { |
| 273 | + try { res[i] = Integer.parseInt(parts[i]); } catch (NumberFormatException e) { res[i] = 0; } |
| 274 | + } |
| 275 | + return res; |
| 276 | + } catch (Exception e) { |
| 277 | + return new int[]{0}; |
| 278 | + } |
| 279 | + } |
| 280 | + |
| 281 | + private static int parseMajor(String v) { |
| 282 | + int[] vv = parseVersion(v); |
| 283 | + return vv.length > 0 ? vv[0] : 0; |
| 284 | + } |
| 285 | + |
| 286 | + private static boolean inRange(String v, String from, String to) { |
| 287 | + return compareVersion(v, from) >= 0 && compareVersion(v, to) <= 0; |
| 288 | + } |
| 289 | + |
190 | 290 | private byte[] repackAuthlibJar(byte[] data, Path path) throws IOException { |
191 | 291 | try(ZipInputStream input = new ZipInputStream(new ByteArrayInputStream(data))) { |
192 | 292 | ByteArrayOutputStream result = new ByteArrayOutputStream(); |
|
0 commit comments