Skip to content

Commit 2eece8f

Browse files
committed
[FEATURE] Experimental detection of a suitable LaunchAuthlib version
1 parent faf6cb1 commit 2eece8f

2 files changed

Lines changed: 115 additions & 11 deletions

File tree

components/serverwrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,13 @@ public void run(String... args) throws Throwable {
202202
bridge.run(args[1], args[2]);
203203
System.exit(0);
204204
}
205-
if (args.length > 1 && args[0].equalsIgnoreCase("installAuthlib") && !disableSetup) {
205+
if (args.length > 0 && args[0].equalsIgnoreCase("installAuthlib") && !disableSetup) {
206206
InstallAuthlib command = new InstallAuthlib();
207-
command.run(args[1]);
207+
if (args.length > 1) {
208+
command.run(args[1]);
209+
} else {
210+
command.run();
211+
}
208212
System.exit(0);
209213
}
210214
if (args.length > 0 && args[0].equalsIgnoreCase("save") && !disableSetup) {

components/serverwrapper/src/main/java/pro/gravit/launcher/server/authlib/InstallAuthlib.java

Lines changed: 109 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import org.slf4j.Logger;
44
import org.slf4j.LoggerFactory;
55
import pro.gravit.utils.helper.IOHelper;
6-
import pro.gravit.utils.helper.LogHelper;
76

87
import java.io.*;
98
import java.net.URL;
@@ -32,16 +31,84 @@ public class InstallAuthlib {
3231
public void run(String... args) throws Exception {
3332
boolean deleteAuthlibAfterInstall = false;
3433
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;
4099
}
41-
context.pathToAuthlib = tempAuthlib.toAbsolutePath();
42-
deleteAuthlibAfterInstall = true;
43100
} 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+
}
45112
}
46113
if(Files.notExists(context.pathToAuthlib)) {
47114
throw new FileNotFoundException(context.pathToAuthlib.toString());
@@ -187,6 +254,39 @@ private Set<String> getNames(Path path) throws IOException {
187254
return set;
188255
}
189256

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+
190290
private byte[] repackAuthlibJar(byte[] data, Path path) throws IOException {
191291
try(ZipInputStream input = new ZipInputStream(new ByteArrayInputStream(data))) {
192292
ByteArrayOutputStream result = new ByteArrayOutputStream();

0 commit comments

Comments
 (0)