Fix: Fabric loader launch and Bootstrap paths
- Add Fabric support in LaunchCommandBuilder.findVersionJson() - Fix Bootstrap to properly use bin/ directory for launcher JAR - Fix server.py to accept both ZernMC-win-*.zip and ZernMCLauncher-*.zip - Add debug output for version.json resolution
This commit is contained in:
@@ -16,12 +16,19 @@ public class Bootstrap {
|
||||
private static final String JAR_NAME = "zernmclauncher.jar";
|
||||
private static final String BASE_URL = "http://87.120.187.36:1582";
|
||||
private static final int BUFFER_SIZE = 8192;
|
||||
|
||||
|
||||
private static Path baseDir;
|
||||
private static Path binDir;
|
||||
private static Path logDir;
|
||||
|
||||
private static Path getLauncherJar() {
|
||||
return binDir.resolve(JAR_NAME);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
baseDir = Paths.get("").toAbsolutePath();
|
||||
binDir = baseDir.resolve("bin");
|
||||
Files.createDirectories(binDir);
|
||||
logDir = baseDir.resolve("logs");
|
||||
Files.createDirectories(logDir);
|
||||
|
||||
@@ -65,7 +72,7 @@ public class Bootstrap {
|
||||
|
||||
private static String readCurrentVersion() {
|
||||
// Читаем версию из манифеста zernmclauncher.jar в папке bin/
|
||||
Path launcherJar = baseDir.resolve("bin").resolve("zernmclauncher.jar");
|
||||
Path launcherJar = getLauncherJar();
|
||||
try {
|
||||
if (Files.exists(launcherJar)) {
|
||||
try (FileInputStream fis = new FileInputStream(launcherJar.toFile())) {
|
||||
@@ -77,13 +84,13 @@ public class Bootstrap {
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
|
||||
// Fallback: из build.version
|
||||
Path f = baseDir.resolve(VERSION_FILE);
|
||||
try {
|
||||
if (Files.exists(f)) return Files.readString(f).trim();
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
|
||||
return "0.0.0";
|
||||
}
|
||||
|
||||
@@ -469,11 +476,11 @@ public class Bootstrap {
|
||||
URL url = new URL(BASE_URL + "/launcher/download/jar");
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setRequestMethod("GET");
|
||||
|
||||
|
||||
if (conn.getResponseCode() == 200) {
|
||||
Path jarFile = baseDir.resolve(JAR_NAME);
|
||||
Path jarFile = getLauncherJar();
|
||||
Path tmp = jarFile.resolveSibling("zernmc-launcher-new.jar");
|
||||
|
||||
|
||||
try (InputStream in = conn.getInputStream();
|
||||
OutputStream out = new FileOutputStream(tmp.toFile())) {
|
||||
byte[] buf = new byte[BUFFER_SIZE];
|
||||
@@ -486,12 +493,12 @@ public class Bootstrap {
|
||||
}
|
||||
}
|
||||
log("JAR скачан");
|
||||
|
||||
|
||||
Path backup = jarFile.resolveSibling(JAR_NAME + ".old");
|
||||
if (Files.exists(jarFile)) Files.move(jarFile, backup, StandardCopyOption.REPLACE_EXISTING);
|
||||
Files.move(tmp, jarFile, StandardCopyOption.REPLACE_EXISTING);
|
||||
if (Files.exists(backup)) Files.delete(backup);
|
||||
|
||||
|
||||
Files.writeString(baseDir.resolve(VERSION_FILE), newVersion);
|
||||
log("Обновлено до v" + newVersion + " (JAR метод)");
|
||||
} else {
|
||||
@@ -501,8 +508,8 @@ public class Bootstrap {
|
||||
|
||||
private static void launchJFX() throws Exception {
|
||||
Path javaBin = findJava();
|
||||
Path jarPath = baseDir.resolve(JAR_NAME);
|
||||
|
||||
Path jarPath = getLauncherJar();
|
||||
|
||||
log("Запуск JFX режима...");
|
||||
log("Java: " + javaBin);
|
||||
log("JAR: " + jarPath);
|
||||
@@ -544,8 +551,8 @@ public class Bootstrap {
|
||||
|
||||
private static void launchCLI() throws Exception {
|
||||
Path javaBin = findJava();
|
||||
Path jarPath = baseDir.resolve(JAR_NAME);
|
||||
|
||||
Path jarPath = getLauncherJar();
|
||||
|
||||
log("Запуск CLI режима...");
|
||||
log("Java: " + javaBin);
|
||||
log("JAR: " + jarPath);
|
||||
|
||||
+40
@@ -63,6 +63,10 @@ public class LaunchCommandBuilder {
|
||||
JSONObject json = new JSONObject(content);
|
||||
System.out.println(ZAnsi.green("Найден version.json: " + versionJson.getFileName()));
|
||||
return new VersionManifest(json);
|
||||
} else {
|
||||
System.out.println(ZAnsi.yellow("version.json не найден для " + instance.getName()));
|
||||
System.out.println(ZAnsi.yellow(" loaderType=" + instance.getLoaderType() + " mcVersion=" + instance.getMinecraftVersion() + " loaderVersion=" + instance.getLoaderVersion()));
|
||||
System.out.println(ZAnsi.yellow(" path=" + instance.getPath()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println(ZAnsi.yellow("Не удалось загрузить version.json: " + e.getMessage()));
|
||||
@@ -76,6 +80,38 @@ public class LaunchCommandBuilder {
|
||||
String mcVersion = instance.getMinecraftVersion();
|
||||
String loaderVersion = instance.getLoaderVersion();
|
||||
|
||||
if ("fabric".equals(loaderType)) {
|
||||
String versionId = getVersionId();
|
||||
// Try fabric version ID first
|
||||
Path jsonPath = versionsDir.resolve(versionId).resolve(versionId + ".json");
|
||||
if (Files.exists(jsonPath)) {
|
||||
return jsonPath;
|
||||
}
|
||||
// Try instance's fabricVersionId if available
|
||||
String fabricId = instance.getFabricVersionId();
|
||||
if (fabricId != null && !fabricId.isEmpty()) {
|
||||
Path fabricPath = versionsDir.resolve(fabricId).resolve(fabricId + ".json");
|
||||
if (Files.exists(fabricPath)) {
|
||||
return fabricPath;
|
||||
}
|
||||
}
|
||||
// Try generic fabric pattern
|
||||
try {
|
||||
if (Files.exists(versionsDir)) {
|
||||
try (var stream = Files.list(versionsDir)) {
|
||||
return stream
|
||||
.filter(Files::isDirectory)
|
||||
.filter(dir -> dir.getFileName().toString().contains("fabric"))
|
||||
.filter(dir -> dir.getFileName().toString().contains(mcVersion))
|
||||
.findFirst()
|
||||
.map(dir -> dir.resolve(dir.getFileName().toString() + ".json"))
|
||||
.filter(Files::exists)
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
if ("forge".equals(loaderType) || "neoforge".equals(loaderType)) {
|
||||
String[] candidates = {
|
||||
getVersionId(),
|
||||
@@ -152,6 +188,10 @@ public class LaunchCommandBuilder {
|
||||
String loaderType = instance.getLoaderType().toLowerCase();
|
||||
if ("fabric".equals(loaderType)) {
|
||||
return "net.fabricmc.loader.impl.launch.knot.KnotClient";
|
||||
} else if ("forge".equals(loaderType)) {
|
||||
return "net.minecraftforge.client.main.ForgeClient";
|
||||
} else if ("neoforge".equals(loaderType)) {
|
||||
return "cpw.mods.bootstraplauncher.BootstrapLauncher";
|
||||
}
|
||||
return "net.minecraft.client.main.Main";
|
||||
}
|
||||
|
||||
+2
-1
@@ -1080,7 +1080,8 @@ async def download_launcher_exe():
|
||||
@app.get("/launcher/download/zip/{filename}")
|
||||
async def download_launcher_zip(filename: str):
|
||||
"""Download specific launcher ZIP archive"""
|
||||
if ".." in filename or not filename.startswith("ZernMCLauncher-") or not filename.endswith(".zip"):
|
||||
valid_patterns = ["ZernMCLauncher-", "ZernMC-win-"]
|
||||
if ".." in filename or not any(filename.startswith(p) for p in valid_patterns) or not filename.endswith(".zip"):
|
||||
raise HTTPException(400, "Invalid filename")
|
||||
|
||||
file_path = BUILDS_DIR / filename
|
||||
|
||||
Reference in New Issue
Block a user