Fix: JFX launcher inherit console, no game output capture, SSE log optimization

This commit is contained in:
SashegDev
2026-05-10 00:25:49 +00:00
parent ee1e4fa8d2
commit 389280f7f1
2 changed files with 12 additions and 41 deletions
@@ -361,15 +361,11 @@ public class Bootstrap {
log("Java: " + javaBin); log("Java: " + javaBin);
log("JAR: " + jarPath); log("JAR: " + jarPath);
// JVM аргументы для UTF-8 и JavaFX Path consoleLog = logDir.resolve("console.log");
List<String> jvmArgs = List.of(
"-Dfile.encoding=UTF-8",
"-Dsun.stdout.encoding=UTF-8",
"-Dsun.stderr.encoding=UTF-8"
);
// Путь к JavaFX модулям // JVM аргументы для UTF-8 и JavaFX
Path javafxPath = baseDir.resolve("lib").resolve("javafx"); Path javafxPath = baseDir.resolve("lib").resolve("javafx");
List<String> jvmArgs;
if (Files.exists(javafxPath)) { if (Files.exists(javafxPath)) {
jvmArgs = List.of( jvmArgs = List.of(
"-Dfile.encoding=UTF-8", "-Dfile.encoding=UTF-8",
@@ -397,7 +393,10 @@ public class Bootstrap {
ProcessBuilder pb = new ProcessBuilder(cmd); ProcessBuilder pb = new ProcessBuilder(cmd);
pb.directory(baseDir.toFile()); pb.directory(baseDir.toFile());
// inheritIO позволяет лаунчеру закрываться при закрытии консоли
pb.inheritIO(); pb.inheritIO();
Process p = pb.start(); Process p = pb.start();
int code = p.waitFor(); int code = p.waitFor();
log("Завершено с кодом: " + code); log("Завершено с кодом: " + code);
@@ -46,8 +46,6 @@ public class LaunchService {
return ApiResponse.error("Сборка не найдена: " + instanceName); return ApiResponse.error("Сборка не найдена: " + instanceName);
} }
JFXLauncher.initGameLog(instance.getPath());
LaunchCommandBuilder builder = new LaunchCommandBuilder(instance); LaunchCommandBuilder builder = new LaunchCommandBuilder(instance);
LaunchOptions options = new LaunchOptions(); LaunchOptions options = new LaunchOptions();
@@ -63,42 +61,16 @@ public class LaunchService {
ProcessBuilder processBuilder = new ProcessBuilder(command); ProcessBuilder processBuilder = new ProcessBuilder(command);
processBuilder.directory(instance.getPath().toFile()); processBuilder.directory(instance.getPath().toFile());
processBuilder.redirectErrorStream(true); processBuilder.redirectErrorStream(true);
// Не перехватываем вывод игры - пусть выводится напрямую в консоль
// Инициализируем лог файл для игры, но не дублируем вывод
Path logsDir = instance.getPath().resolve("logs");
java.nio.file.Files.createDirectories(logsDir);
Path gameLog = logsDir.resolve("game.log");
processBuilder.redirectOutput(ProcessBuilder.Redirect.to(gameLog.toFile()));
Process process = processBuilder.start(); Process process = processBuilder.start();
System.out.println("[LAUNCH] Process started, pid=" + process.pid()); System.out.println("[LAUNCH] Process started, pid=" + process.pid());
// Capture output (stdout)
Thread outThread = new Thread(() -> {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println("[STDOUT] " + line);
JFXLauncher.appendGameLog(line);
}
} catch (Exception e) {
System.out.println("[STDOUT ERROR] " + e.getMessage());
JFXLauncher.appendGameLog("[Ошибка чтения вывода: " + e.getMessage());
}
});
outThread.setDaemon(true);
outThread.start();
// Capture errors (stderr)
Thread errThread = new Thread(() -> {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println("[STDERR] " + line);
JFXLauncher.appendGameLog("[ERR] " + line);
}
} catch (Exception e) {
System.out.println("[STDERR ERROR] " + e.getMessage());
JFXLauncher.appendGameLog("[Ошибка чтения ошибок: " + e.getMessage());
}
});
errThread.setDaemon(true);
errThread.start();
ProcessInfo info = new ProcessInfo( ProcessInfo info = new ProcessInfo(
instanceName, instanceName,
process.pid(), process.pid(),