fix: inject real version into UI, add timeout to FabricInstaller process
This commit is contained in:
+10
-48
@@ -6,20 +6,13 @@ import me.sashegdev.zernmc.launcher.utils.ZAnsi;
|
|||||||
import me.sashegdev.zernmc.launcher.utils.ZHttpClient;
|
import me.sashegdev.zernmc.launcher.utils.ZHttpClient;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
|
||||||
import java.net.http.HttpClient;
|
|
||||||
import java.net.http.HttpRequest;
|
|
||||||
import java.net.http.HttpResponse;
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.time.Duration;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class FabricInstaller {
|
public class FabricInstaller {
|
||||||
|
|
||||||
private final Instance instance;
|
private final Instance instance;
|
||||||
private final HttpClient httpClient = HttpClient.newBuilder()
|
|
||||||
.connectTimeout(Duration.ofSeconds(15))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
public FabricInstaller(Instance instance) {
|
public FabricInstaller(Instance instance) {
|
||||||
this.instance = instance;
|
this.instance = instance;
|
||||||
@@ -68,7 +61,13 @@ public class FabricInstaller {
|
|||||||
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
|
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
|
||||||
|
|
||||||
Process process = pb.start();
|
Process process = pb.start();
|
||||||
int exitCode = process.waitFor();
|
boolean finished = process.waitFor(10, TimeUnit.MINUTES);
|
||||||
|
if (!finished) {
|
||||||
|
process.destroyForcibly();
|
||||||
|
System.out.println(ZAnsi.brightRed("Fabric Installer timed out after 10 minutes"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int exitCode = process.exitValue();
|
||||||
|
|
||||||
if (exitCode != 0) {
|
if (exitCode != 0) {
|
||||||
System.out.println(ZAnsi.brightRed("Fabric Installer failed (code " + exitCode + ")"));
|
System.out.println(ZAnsi.brightRed("Fabric Installer failed (code " + exitCode + ")"));
|
||||||
@@ -166,48 +165,11 @@ public class FabricInstaller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// under refactor - keep
|
|
||||||
private String downloadString(String url) throws Exception {
|
private String downloadString(String url) throws Exception {
|
||||||
Exception lastException = null;
|
return ZHttpClient.getWithSmartProxy(url);
|
||||||
|
|
||||||
for (int attempt = 1; attempt <= 3; attempt++) {
|
|
||||||
try {
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
|
||||||
.uri(URI.create(url))
|
|
||||||
.timeout(Duration.ofSeconds(30 * attempt))
|
|
||||||
.header("User-Agent", "ZernMC-Launcher/1.0")
|
|
||||||
.GET()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
HttpResponse<String> resp = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
|
||||||
if (resp.statusCode() == 200) {
|
|
||||||
return resp.body();
|
|
||||||
}
|
|
||||||
throw new IOException("HTTP " + resp.statusCode());
|
|
||||||
} catch (Exception e) {
|
|
||||||
lastException = e;
|
|
||||||
System.out.println(ZAnsi.yellow("Attempt " + attempt + " failed: " + e.getMessage()));
|
|
||||||
if (attempt < 3) {
|
|
||||||
Thread.sleep(1000 * attempt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw lastException;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void downloadFile(String url, Path target) throws Exception {
|
private void downloadFile(String url, Path target) throws Exception {
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
ZHttpClient.downloadFileWithSmartProxy(url, target);
|
||||||
.uri(URI.create(url))
|
|
||||||
.timeout(Duration.ofSeconds(60))
|
|
||||||
.GET()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
HttpResponse<Path> response = httpClient.send(request,
|
|
||||||
HttpResponse.BodyHandlers.ofFile(target));
|
|
||||||
|
|
||||||
if (response.statusCode() != 200) {
|
|
||||||
throw new IOException("HTTP " + response.statusCode() + " when downloading " + url);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1229,6 +1229,12 @@ public class JFXLauncher extends Application {
|
|||||||
log("[UI] Loaded " + content.length + " bytes: " + path);
|
log("[UI] Loaded " + content.length + " bytes: " + path);
|
||||||
String ct = getContentType(path);
|
String ct = getContentType(path);
|
||||||
|
|
||||||
|
if (ct.startsWith("text/")) {
|
||||||
|
String text = new String(content, java.nio.charset.StandardCharsets.UTF_8);
|
||||||
|
text = text.replace("__LAUNCHER_VERSION__", me.sashegdev.zernmc.launcher.utils.Version.getCurrentVersion());
|
||||||
|
content = text.getBytes(java.nio.charset.StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
exchange.getResponseHeaders().set("Content-Type", ct);
|
exchange.getResponseHeaders().set("Content-Type", ct);
|
||||||
exchange.sendResponseHeaders(200, content.length);
|
exchange.sendResponseHeaders(200, content.length);
|
||||||
exchange.getResponseBody().write(content);
|
exchange.getResponseBody().write(content);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<h1 class="login-title" id="login-title" data-i18n="login.title">Sign In</h1>
|
<h1 class="login-title" id="login-title" data-i18n="login.title">Sign In</h1>
|
||||||
<p class="login-subtitle" id="login-subtitle" data-i18n="login.subtitle">Welcome back to ZernMC</p>
|
<p class="login-subtitle" id="login-subtitle" data-i18n="login.subtitle">Welcome back to ZernMC</p>
|
||||||
<span id="version" class="hidden">1.0.12</span>
|
<span id="version" class="hidden">__LAUNCHER_VERSION__</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form id="login-form" class="login-form">
|
<form id="login-form" class="login-form">
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
<div class="sidebar-brand-text">
|
<div class="sidebar-brand-text">
|
||||||
<span class="sidebar-brand-name">ZernMC</span>
|
<span class="sidebar-brand-name">ZernMC</span>
|
||||||
<span class="sidebar-brand-ver">v<span id="header-version">1.0.12</span></span>
|
<span class="sidebar-brand-ver">v<span id="header-version">__LAUNCHER_VERSION__</span></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
TODO / ideas backlog
|
||||||
|
====================
|
||||||
|
|
||||||
|
Java Agent + IPC (low priority, overkill now)
|
||||||
|
- Заменить прямой ProcessBuilder.start() на прокси-класс (-javaagent или -cp прокси)
|
||||||
|
- Прокси класс: подключается к localhost RPC, ждёт "launch", потом reflection вызывает реальный main
|
||||||
|
- Даёт: двустороннюю связь лаунчер-игра, контроль жизненного цикла, crash-репорты из процесса игры,
|
||||||
|
передачу настроек/токенов на лету, патчинг классов через Instrumentation API
|
||||||
|
- Для ZernMC сейчас оверхед — но запомнить на будущее
|
||||||
Reference in New Issue
Block a user