From e17b1d073a52d6c36e340f71e149640fc20b8719 Mon Sep 17 00:00:00 2001 From: SashegDev Date: Sat, 9 May 2026 23:55:08 +0000 Subject: [PATCH] Launcher UI: MC/loader versions from server, split instances, console log sync, disable ZernMC for FREE --- .../zernmc/launcher/api/LauncherAPI.java | 132 +++++++++-- .../zernmc/launcher/api/auth/AuthService.java | 4 + .../zernmc/launcher/ui/jfx/JFXLauncher.java | 14 ++ launcher/launcher/src/resources/ui/index.html | 17 +- .../launcher/src/resources/ui/launcher.js | 220 ++++++++++++++---- 5 files changed, 314 insertions(+), 73 deletions(-) diff --git a/launcher/launcher/src/main/java/sashegdev/zernmc/launcher/api/LauncherAPI.java b/launcher/launcher/src/main/java/sashegdev/zernmc/launcher/api/LauncherAPI.java index 13f9936..adbed6e 100644 --- a/launcher/launcher/src/main/java/sashegdev/zernmc/launcher/api/LauncherAPI.java +++ b/launcher/launcher/src/main/java/sashegdev/zernmc/launcher/api/LauncherAPI.java @@ -4,7 +4,13 @@ import me.sashegdev.zernmc.launcher.api.auth.AuthService; import me.sashegdev.zernmc.launcher.api.instance.InstanceService; import me.sashegdev.zernmc.launcher.api.launch.LaunchService; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; import java.util.List; +import java.util.stream.Collectors; /** * Центральный фасад для внутреннего API лаунчера. @@ -12,6 +18,8 @@ import java.util.List; */ public class LauncherAPI { + private static final String LAUNCHER_SERVER = System.getProperty("launcher.server", "http://87.120.187.36:1582"); + private final AuthService authService; private final InstanceService instanceService; private final LaunchService launchService; @@ -74,37 +82,115 @@ public class LauncherAPI { public ApiResponse> getMCVersions() { try { - return ApiResponse.success(java.util.List.of("1.21", "1.20.6", "1.20.4", "1.20.1", "1.19.4", "1.18.2", "1.17.1", "1.16.5")); + URL url = new URL(LAUNCHER_SERVER + "/launcher/minecraft-versions"); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setConnectTimeout(5000); + conn.setReadTimeout(10000); + if (conn.getResponseCode() == 200) { + try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) { + StringBuilder sb = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) sb.append(line); + org.json.JSONArray arr = new org.json.JSONArray(sb.toString()); + List versions = new java.util.ArrayList<>(); + for (int i = 0; i < arr.length(); i++) { + versions.add(arr.getString(i)); + } + return ApiResponse.success(versions); + } + } } catch (Exception e) { - return ApiResponse.error(e.getMessage()); + System.out.println("[API] MC versions fetch failed, using fallback: " + e.getMessage()); } + return ApiResponse.success(java.util.List.of("1.21", "1.20.6", "1.20.4", "1.20.1", "1.19.4", "1.18.2", "1.17.1", "1.16.5")); } public ApiResponse> getLoaderVersions(String mcVersion, String loader) { try { - java.util.List versions = new java.util.ArrayList<>(); - switch (loader.toLowerCase()) { - case "fabric": - versions.add("0.15.11"); - versions.add("0.15.9"); - versions.add("0.15.8"); - versions.add("0.14.21"); - break; - case "forge": - versions.add("47.1.0"); - versions.add("46.0.1"); - versions.add("45.0.2"); - break; - case "neoforge": - versions.add("1.21-rc.2"); - versions.add("1.20.4-rc.4"); - break; - default: - break; + URL url = new URL(LAUNCHER_SERVER + "/launcher/loader-versions?mc=" + mcVersion + "&loader=" + loader.toLowerCase()); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setConnectTimeout(5000); + conn.setReadTimeout(10000); + if (conn.getResponseCode() == 200) { + try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) { + StringBuilder sb = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) sb.append(line); + org.json.JSONArray arr = new org.json.JSONArray(sb.toString()); + List versions = new java.util.ArrayList<>(); + for (int i = 0; i < arr.length(); i++) { + versions.add(arr.getString(i)); + } + return ApiResponse.success(versions); + } } - return ApiResponse.success(versions); } catch (Exception e) { - return ApiResponse.error(e.getMessage()); + System.out.println("[API] Loader versions fetch failed, using fallback: " + e.getMessage()); } + + java.util.List versions = new java.util.ArrayList<>(); + switch (loader.toLowerCase()) { + case "fabric": + versions.add("0.15.11"); + versions.add("0.15.9"); + versions.add("0.15.8"); + versions.add("0.14.21"); + break; + case "forge": + versions.add("47.1.0"); + versions.add("46.0.1"); + versions.add("45.0.2"); + break; + case "neoforge": + versions.add("1.21-rc.2"); + versions.add("1.20.4-rc.4"); + break; + default: + break; + } + return ApiResponse.success(versions); + } + + public ApiResponse>> getZernMCPacks() { + try { + String token = authService.getCurrentToken(); + if (token == null) { + return ApiResponse.error("Не авторизован"); + } + + URL url = new URL(LAUNCHER_SERVER + "/packs"); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setConnectTimeout(5000); + conn.setReadTimeout(10000); + conn.setRequestProperty("Authorization", "Bearer " + token); + + if (conn.getResponseCode() == 200) { + try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) { + StringBuilder sb = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) sb.append(line); + org.json.JSONArray arr = new org.json.JSONArray(sb.toString()); + List> packs = new java.util.ArrayList<>(); + for (int i = 0; i < arr.length(); i++) { + org.json.JSONObject pack = arr.getJSONObject(i); + java.util.Map packInfo = new java.util.HashMap<>(); + packInfo.put("name", pack.optString("name", "")); + packInfo.put("displayName", pack.optString("displayName", pack.optString("name", ""))); + packInfo.put("version", pack.optString("version", "")); + packInfo.put("mcVersion", pack.optString("mcVersion", "")); + packInfo.put("loader", pack.optString("loader", "vanilla")); + packInfo.put("description", pack.optString("description", "")); + packs.add(packInfo); + } + return ApiResponse.success(packs); + } + } else if (conn.getResponseCode() == 403) { + return ApiResponse.error("Требуется проходка"); + } + } catch (Exception e) { + System.out.println("[API] Packs fetch failed: " + e.getMessage()); + return ApiResponse.error("Ошибка загрузки сборок: " + e.getMessage()); + } + return ApiResponse.success(java.util.List.of()); } } diff --git a/launcher/launcher/src/main/java/sashegdev/zernmc/launcher/api/auth/AuthService.java b/launcher/launcher/src/main/java/sashegdev/zernmc/launcher/api/auth/AuthService.java index b74c945..1d88cd1 100644 --- a/launcher/launcher/src/main/java/sashegdev/zernmc/launcher/api/auth/AuthService.java +++ b/launcher/launcher/src/main/java/sashegdev/zernmc/launcher/api/auth/AuthService.java @@ -105,6 +105,10 @@ public class AuthService { return AuthManager.getUsername(); } + public String getCurrentToken() { + return AuthManager.getAccessToken(); + } + public static class LoginResult { private String username; private String token; diff --git a/launcher/launcher/src/main/java/sashegdev/zernmc/launcher/ui/jfx/JFXLauncher.java b/launcher/launcher/src/main/java/sashegdev/zernmc/launcher/ui/jfx/JFXLauncher.java index 43e1b2d..e6e836e 100644 --- a/launcher/launcher/src/main/java/sashegdev/zernmc/launcher/ui/jfx/JFXLauncher.java +++ b/launcher/launcher/src/main/java/sashegdev/zernmc/launcher/ui/jfx/JFXLauncher.java @@ -261,6 +261,7 @@ public class JFXLauncher extends Application { server.createContext("/api/game-logs", this::handleGameLogs); server.createContext("/api/mc-versions", this::handleMCVersions); server.createContext("/api/loader-versions", this::handleLoaderVersions); + server.createContext("/api/packs", this::handlePacks); server.createContext("/api/exit", this::handleExit); server.createContext("/assets/", this::handleStatic); @@ -429,6 +430,19 @@ public class JFXLauncher extends Application { } } + private void handlePacks(HttpExchange exchange) { + try { + var result = api.getZernMCPacks(); + if (result.isSuccess()) { + sendJson(exchange, Map.of("success", true, "data", result.getData())); + } else { + sendJson(exchange, Map.of("success", false, "error", result.getError())); + } + } catch (Exception e) { + sendJson(exchange, Map.of("success", false, "error", e.getMessage())); + } + } + private Map parseQuery(String query) { Map params = new HashMap<>(); if (query != null && !query.isEmpty()) { diff --git a/launcher/launcher/src/resources/ui/index.html b/launcher/launcher/src/resources/ui/index.html index 73dce83..7be66c5 100644 --- a/launcher/launcher/src/resources/ui/index.html +++ b/launcher/launcher/src/resources/ui/index.html @@ -62,20 +62,17 @@