Fix Bootstrap to use bin/ directory properly
- Read version from bin/.version file (reliable, no JAR locking) - Save version to bin/.version when downloading JAR - Use getLauncherJar() for all JAR path references - Create binDir in main() - Remove build.version dependency completely
This commit is contained in:
@@ -4,17 +4,15 @@ import java.io.*;
|
|||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
import java.util.jar.Attributes;
|
import java.util.Arrays;
|
||||||
import java.util.jar.Manifest;
|
import java.util.List;
|
||||||
|
|
||||||
public class Bootstrap {
|
public class Bootstrap {
|
||||||
private static final String JAR_NAME = "zernmclauncher.jar";
|
private static final String JAR_NAME = "zernmclauncher.jar";
|
||||||
private static final String BASE_URL = "http://87.120.187.36:1582";
|
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 baseDir;
|
||||||
private static Path binDir;
|
private static Path binDir;
|
||||||
@@ -23,6 +21,10 @@ public class Bootstrap {
|
|||||||
private static Path getLauncherJar() {
|
private static Path getLauncherJar() {
|
||||||
return binDir.resolve(JAR_NAME);
|
return binDir.resolve(JAR_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Path getVersionFile() {
|
||||||
|
return binDir.resolve(".version");
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
baseDir = Paths.get("").toAbsolutePath();
|
baseDir = Paths.get("").toAbsolutePath();
|
||||||
@@ -69,90 +71,20 @@ public class Bootstrap {
|
|||||||
} catch (Exception ignored) {}
|
} catch (Exception ignored) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Path VERSION_FILE = baseDir.resolve("bin/.version");
|
|
||||||
|
|
||||||
private static String readCurrentVersion() {
|
private static String readCurrentVersion() {
|
||||||
// Читаем версию из файла (быстро и надёжно)
|
Path versionFile = getVersionFile();
|
||||||
if (Files.exists(VERSION_FILE)) {
|
if (Files.exists(versionFile)) {
|
||||||
try {
|
try {
|
||||||
String v = Files.readString(VERSION_FILE).trim();
|
String v = Files.readString(versionFile).trim();
|
||||||
if (!v.isBlank()) return v;
|
if (!v.isBlank()) return v;
|
||||||
} catch (Exception ignored) {}
|
} catch (Exception ignored) {}
|
||||||
}
|
}
|
||||||
return "0.0.0";
|
return "0.0.0";
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
System.out.println("[DEBUG] Ошибка чтения манифеста: " + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return "0.0.0";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Стандартный способ чтения манифеста JAR
|
|
||||||
try (java.util.jar.JarFile jar = new java.util.jar.JarFile(launcherJar.toFile())) {
|
|
||||||
java.util.jar.Manifest manifest = jar.getManifest();
|
|
||||||
if (manifest != null) {
|
|
||||||
java.util.jar.Attributes attrs = manifest.getMainAttributes();
|
|
||||||
String version = attrs.getValue(java.util.jar.Attributes.Name.IMPLEMENTATION_VERSION);
|
|
||||||
if (version != null && !version.isBlank()) {
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception ignored) {}
|
|
||||||
|
|
||||||
return "0.0.0";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Простой способ: читаем JAR как ZIP и ищем строку Implementation-Version
|
|
||||||
try (java.util.zip.ZipFile zip = new java.util.zip.ZipFile(launcherJar.toFile())) {
|
|
||||||
java.util.zip.ZipEntry entry = zip.getEntry("META-INF/MANIFEST.MF");
|
|
||||||
if (entry != null) {
|
|
||||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(zip.getInputStream(entry)))) {
|
|
||||||
String line;
|
|
||||||
while ((line = reader.readLine()) != null) {
|
|
||||||
if (line.contains("Implementation-Version:")) {
|
|
||||||
String version = line.substring(line.indexOf(':') + 1).trim();
|
|
||||||
if (!version.isBlank()) {
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception ignored) {}
|
|
||||||
|
|
||||||
return "0.0.0";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getServerVersion() {
|
private static String getServerVersion() {
|
||||||
try {
|
try {
|
||||||
// Пробуем получить версию из мета-системы
|
URL url = new URL(BASE_URL.replace("download?type=jar", "version"));
|
||||||
URL url = new URL(BASE_URL + "/launcher/meta");
|
|
||||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
|
||||||
conn.setRequestMethod("GET");
|
|
||||||
if (conn.getResponseCode() == 200) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
|
|
||||||
String line;
|
|
||||||
while ((line = br.readLine()) != null) sb.append(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
String json = sb.toString();
|
|
||||||
// Ищем первую версию в мета
|
|
||||||
int vIndex = json.indexOf("\"version\"");
|
|
||||||
if (vIndex != -1) {
|
|
||||||
int start = json.indexOf("\"", vIndex + 9) + 1;
|
|
||||||
int end = json.indexOf("\"", start);
|
|
||||||
if (start > 0 && end > start) {
|
|
||||||
return json.substring(start, end);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception ignored) {}
|
|
||||||
|
|
||||||
// Fallback на старый метод
|
|
||||||
try {
|
|
||||||
URL url = new URL(BASE_URL + "/launcher/version");
|
|
||||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
conn.setRequestMethod("GET");
|
conn.setRequestMethod("GET");
|
||||||
if (conn.getResponseCode() == 200) {
|
if (conn.getResponseCode() == 200) {
|
||||||
@@ -183,338 +115,17 @@ public class Bootstrap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void downloadUpdate(String newVersion) throws Exception {
|
private static void downloadUpdate(String newVersion) throws Exception {
|
||||||
// Пытаемся использовать инкрементное обновление через мета-систему
|
|
||||||
try {
|
|
||||||
// 1. Получаем мета с сервера
|
|
||||||
Map<String, Object> meta = getLauncherMeta();
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
List<Map<String, Object>> files = (List<Map<String, Object>>) meta.get("files");
|
|
||||||
|
|
||||||
if (files == null || files.isEmpty()) {
|
|
||||||
// Мета пустая - fallback на JAR обновление
|
|
||||||
log("Мета пустая, используем JAR обновление");
|
|
||||||
downloadUpdateJar(newVersion);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
log("Мета получена: " + files.size() + " файлов");
|
|
||||||
|
|
||||||
// 2. Сканируем локальные файлы
|
|
||||||
Map<String, String> localFiles = scanLocalFiles();
|
|
||||||
log("Локально: " + localFiles.size() + " файлов");
|
|
||||||
|
|
||||||
// 3. Получаем diff
|
|
||||||
Map<String, Object> diff = getLauncherDiff(localFiles);
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
List<Map<String, Object>> toDownload = (List<Map<String, Object>>) diff.get("to_download");
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
List<String> toDelete = (List<String>) diff.get("to_delete");
|
|
||||||
|
|
||||||
log("К скачиванию: " + toDownload.size() + ", к удалению: " + toDelete.size());
|
|
||||||
|
|
||||||
// 4. Удаляем лишние файлы (пропускаем заблокированные)
|
|
||||||
for (String filePath : toDelete) {
|
|
||||||
Path f = baseDir.resolve(filePath);
|
|
||||||
if (Files.exists(f)) {
|
|
||||||
try {
|
|
||||||
Files.delete(f);
|
|
||||||
log("Удален: " + filePath);
|
|
||||||
} catch (AccessDeniedException e) {
|
|
||||||
log("Пропущен (заблокирован): " + filePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. Скачиваем новые/измененные файлы (пропускаем заблокированные)
|
|
||||||
String serverVersion = (String) diff.get("version");
|
|
||||||
for (Map<String, Object> file : toDownload) {
|
|
||||||
String path = (String) file.get("path");
|
|
||||||
try {
|
|
||||||
downloadLauncherFile(serverVersion, path);
|
|
||||||
log("Скачан: " + path);
|
|
||||||
} catch (AccessDeniedException e) {
|
|
||||||
log("Пропущен (заблокирован): " + path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 6. Версия уже в манифесте JAR
|
|
||||||
log("Обновлено до v" + serverVersion);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
log("Ошибка инкрементного обновления: " + e.getMessage());
|
|
||||||
log("Fallback на JAR обновление...");
|
|
||||||
// Fallback на JAR обновление (не ZIP!)
|
|
||||||
downloadUpdateJar(newVersion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Map<String, Object> getLauncherMeta() throws Exception {
|
|
||||||
URL url = new URL(BASE_URL + "/launcher/meta");
|
|
||||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
|
||||||
conn.setRequestMethod("GET");
|
|
||||||
|
|
||||||
if (conn.getResponseCode() != 200) {
|
|
||||||
throw new IOException("Не удалось получить мета");
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
|
|
||||||
String line;
|
|
||||||
while ((line = br.readLine()) != null) sb.append(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Парсим JSON вручную - находим первую версию и её meta
|
|
||||||
String json = sb.toString();
|
|
||||||
|
|
||||||
// Находим первый объект в массиве versions
|
|
||||||
int versionsIdx = json.indexOf("\"versions\"");
|
|
||||||
if (versionsIdx == -1) throw new IOException("Нет versions в ответе");
|
|
||||||
|
|
||||||
// Находим начало массива
|
|
||||||
int arrStart = json.indexOf("[", versionsIdx);
|
|
||||||
if (arrStart == -1) throw new IOException("Нет массива versions");
|
|
||||||
|
|
||||||
// Находим первый объект версии
|
|
||||||
int verObjStart = json.indexOf("{", arrStart);
|
|
||||||
if (verObjStart == -1) throw new IOException("Нет объектов версий");
|
|
||||||
|
|
||||||
// Находим конец этого объекта (с учётом вложенности)
|
|
||||||
int braceCount = 0;
|
|
||||||
int verObjEnd = verObjStart;
|
|
||||||
for (int i = verObjStart; i < json.length(); i++) {
|
|
||||||
char c = json.charAt(i);
|
|
||||||
if (c == '{') braceCount++;
|
|
||||||
else if (c == '}') {
|
|
||||||
braceCount--;
|
|
||||||
if (braceCount == 0) {
|
|
||||||
verObjEnd = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String firstVersionJson = json.substring(verObjStart, verObjEnd + 1);
|
|
||||||
|
|
||||||
// Извлекаем meta объект из первой версии
|
|
||||||
int metaIdx = firstVersionJson.indexOf("\"meta\"");
|
|
||||||
if (metaIdx == -1) throw new IOException("Нет meta в версии");
|
|
||||||
|
|
||||||
int metaObjStart = firstVersionJson.indexOf("{", metaIdx);
|
|
||||||
if (metaObjStart == -1) throw new IOException("Нет объекта meta");
|
|
||||||
|
|
||||||
// Находим конец meta объекта
|
|
||||||
braceCount = 0;
|
|
||||||
int metaObjEnd = metaObjStart;
|
|
||||||
for (int i = metaObjStart; i < firstVersionJson.length(); i++) {
|
|
||||||
char c = firstVersionJson.charAt(i);
|
|
||||||
if (c == '{') braceCount++;
|
|
||||||
else if (c == '}') {
|
|
||||||
braceCount--;
|
|
||||||
if (braceCount == 0) {
|
|
||||||
metaObjEnd = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String metaJson = firstVersionJson.substring(metaObjStart, metaObjEnd + 1);
|
|
||||||
return parseMetaJson(metaJson);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private static Map<String, Object> parseMetaJson(String json) {
|
|
||||||
Map<String, Object> result = new HashMap<>();
|
|
||||||
List<Map<String, Object>> files = new ArrayList<>();
|
|
||||||
|
|
||||||
// Простой парсинг
|
|
||||||
String[] lines = json.split(",");
|
|
||||||
for (String line : lines) {
|
|
||||||
line = line.trim();
|
|
||||||
if (line.contains("\"version\"")) {
|
|
||||||
String v = line.split(":")[1].replaceAll("[\"\\s]", "");
|
|
||||||
result.put("version", v);
|
|
||||||
} else if (line.contains("\"files\"")) {
|
|
||||||
// Файлы парсим отдельно
|
|
||||||
} else if (line.contains("\"path\"") && line.contains("\"size\"") && line.contains("\"hash\"")) {
|
|
||||||
Map<String, Object> file = new HashMap<>();
|
|
||||||
String[] parts = line.split(":");
|
|
||||||
for (String part : parts) {
|
|
||||||
if (part.contains("path")) file.put("path", extractJsonValue(part));
|
|
||||||
else if (part.contains("size")) file.put("size", Long.parseLong(extractJsonValue(part)));
|
|
||||||
else if (part.contains("hash")) file.put("hash", extractJsonValue(part));
|
|
||||||
}
|
|
||||||
if (!file.isEmpty()) files.add(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.put("files", files);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String extractJsonValue(String part) {
|
|
||||||
int idx = part.indexOf(":");
|
|
||||||
if (idx == -1) return "";
|
|
||||||
String val = part.substring(idx + 1).trim();
|
|
||||||
if (val.startsWith("\"")) val = val.substring(1);
|
|
||||||
if (val.endsWith("\"")) val = val.substring(0, val.length() - 1);
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Map<String, String> scanLocalFiles() throws Exception {
|
|
||||||
Map<String, String> hashes = new HashMap<>();
|
|
||||||
|
|
||||||
// Сканируем основную директорию
|
|
||||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(baseDir)) {
|
|
||||||
for (Path p : stream) {
|
|
||||||
if (p.getFileName().toString().equals("logs")) continue;
|
|
||||||
if (p.getFileName().toString().equals("data")) continue;
|
|
||||||
|
|
||||||
if (Files.isRegularFile(p)) {
|
|
||||||
hashes.put(p.getFileName().toString(), calculateSHA256(p));
|
|
||||||
} else if (Files.isDirectory(p)) {
|
|
||||||
scanDirectory(p, p.getFileName().toString(), hashes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hashes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void scanDirectory(Path dir, String basePath, Map<String, String> hashes) throws Exception {
|
|
||||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
|
|
||||||
for (Path p : stream) {
|
|
||||||
String relPath = basePath + "/" + p.getFileName().toString();
|
|
||||||
if (Files.isRegularFile(p)) {
|
|
||||||
hashes.put(relPath, calculateSHA256(p));
|
|
||||||
} else if (Files.isDirectory(p)) {
|
|
||||||
scanDirectory(p, relPath, hashes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String calculateSHA256(Path file) throws Exception {
|
|
||||||
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
|
||||||
try (InputStream is = Files.newInputStream(file)) {
|
|
||||||
byte[] buf = new byte[BUFFER_SIZE];
|
|
||||||
int len;
|
|
||||||
while ((len = is.read(buf)) != -1) {
|
|
||||||
md.update(buf, 0, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (byte b : md.digest()) sb.append(String.format("%02x", b));
|
|
||||||
return "sha256:" + sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Map<String, Object> getLauncherDiff(Map<String, String> localFiles) throws Exception {
|
|
||||||
// Создаем JSON {filename: hash, ...}
|
|
||||||
StringBuilder json = new StringBuilder("{");
|
|
||||||
int i = 0;
|
|
||||||
for (Map.Entry<String, String> e : localFiles.entrySet()) {
|
|
||||||
if (i > 0) json.append(",");
|
|
||||||
json.append("\"").append(e.getKey()).append("\":\"").append(e.getValue()).append("\"");
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
json.append("}");
|
|
||||||
|
|
||||||
URL url = new URL(BASE_URL + "/launcher/diff");
|
|
||||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
|
||||||
conn.setRequestMethod("POST");
|
|
||||||
conn.setDoOutput(true);
|
|
||||||
conn.setRequestProperty("Content-Type", "application/json");
|
|
||||||
|
|
||||||
try (OutputStream os = conn.getOutputStream()) {
|
|
||||||
os.write(json.toString().getBytes("UTF-8"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conn.getResponseCode() != 200) {
|
|
||||||
throw new IOException("Diff запрос вернул: " + conn.getResponseCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
|
|
||||||
String line;
|
|
||||||
while ((line = br.readLine()) != null) sb.append(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
return parseDiffJson(sb.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private static Map<String, Object> parseDiffJson(String json) {
|
|
||||||
Map<String, Object> result = new HashMap<>();
|
|
||||||
List<Map<String, Object>> toDownload = new ArrayList<>();
|
|
||||||
List<String> toDelete = new ArrayList<>();
|
|
||||||
|
|
||||||
String[] parts = json.split(",");
|
|
||||||
for (String part : parts) {
|
|
||||||
part = part.trim();
|
|
||||||
if (part.contains("\"version\"")) {
|
|
||||||
result.put("version", extractJsonValue(part));
|
|
||||||
} else if (part.contains("\"to_download\"")) {
|
|
||||||
// Парсим файлы
|
|
||||||
} else if (part.contains("\"to_delete\"")) {
|
|
||||||
// Парсим удаляемые
|
|
||||||
} else if (part.contains("\"path\"") && part.contains("\"size\"")) {
|
|
||||||
Map<String, Object> file = new HashMap<>();
|
|
||||||
if (part.contains("\"hash\"")) file.put("hash", "need");
|
|
||||||
file.put("path", extractJsonValue(part));
|
|
||||||
String sizePart = part.split("size")[1].split(",")[0];
|
|
||||||
file.put("size", Long.parseLong(extractJsonValue(sizePart.split(":")[1])));
|
|
||||||
toDownload.add(file);
|
|
||||||
} else if (part.startsWith("\"")) {
|
|
||||||
toDelete.add(extractJsonValue(part));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result.put("to_download", toDownload);
|
|
||||||
result.put("to_delete", toDelete);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void downloadLauncherFile(String version, String filePath) throws Exception {
|
|
||||||
String encodedPath = filePath.replace(" ", "%20");
|
|
||||||
URL url = new URL(BASE_URL + "/launcher/file/" + version + "/" + encodedPath);
|
|
||||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
|
||||||
conn.setRequestMethod("GET");
|
|
||||||
|
|
||||||
if (conn.getResponseCode() != 200) {
|
|
||||||
throw new IOException("Не удалось скачать файл: " + filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
Path targetPath = baseDir.resolve(filePath);
|
|
||||||
Files.createDirectories(targetPath.getParent());
|
|
||||||
|
|
||||||
try (InputStream in = conn.getInputStream();
|
|
||||||
OutputStream out = new FileOutputStream(targetPath.toFile())) {
|
|
||||||
byte[] buf = new byte[BUFFER_SIZE];
|
|
||||||
int len;
|
|
||||||
long total = 0;
|
|
||||||
while ((len = in.read(buf)) > 0) {
|
|
||||||
out.write(buf, 0, len);
|
|
||||||
total += len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback на JAR обновление (без ZIP, чтобы избежать блокировки JRE)
|
|
||||||
private static void downloadUpdateLegacy(String newVersion) throws Exception {
|
|
||||||
log("Пропускаем ZIP обновление (может заблокировать JRE)...");
|
|
||||||
log("Используем JAR обновление...");
|
|
||||||
downloadUpdateJar(newVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void downloadUpdateJar(String newVersion) throws Exception {
|
|
||||||
URL url = new URL(BASE_URL + "/launcher/download/jar");
|
URL url = new URL(BASE_URL + "/launcher/download/jar");
|
||||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
conn.setRequestMethod("GET");
|
conn.setRequestMethod("GET");
|
||||||
|
|
||||||
if (conn.getResponseCode() == 200) {
|
if (conn.getResponseCode() == 200) {
|
||||||
Path jarFile = getLauncherJar();
|
Path jarFile = getLauncherJar();
|
||||||
|
|
||||||
// Скачиваем сразу в целевой файл (без tmp)
|
// Скачиваем сразу в целевой файл (без tmp)
|
||||||
try (InputStream in = conn.getInputStream();
|
try (InputStream in = conn.getInputStream();
|
||||||
OutputStream out = new FileOutputStream(jarFile.toFile())) {
|
OutputStream out = new FileOutputStream(jarFile.toFile())) {
|
||||||
byte[] buf = new byte[BUFFER_SIZE];
|
byte[] buf = new byte[8192];
|
||||||
int len;
|
int len;
|
||||||
long total = 0;
|
long total = 0;
|
||||||
while ((len = in.read(buf)) > 0) {
|
while ((len = in.read(buf)) > 0) {
|
||||||
@@ -526,14 +137,15 @@ public class Bootstrap {
|
|||||||
log("JAR скачан: " + Files.size(jarFile) + " bytes");
|
log("JAR скачан: " + Files.size(jarFile) + " bytes");
|
||||||
|
|
||||||
// Сохраняем версию в файл
|
// Сохраняем версию в файл
|
||||||
|
Path versionFile = getVersionFile();
|
||||||
try {
|
try {
|
||||||
Files.writeString(VERSION_FILE, newVersion);
|
Files.writeString(versionFile, newVersion);
|
||||||
log("Версия сохранена в " + VERSION_FILE);
|
log("Версия сохранена в " + versionFile);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log("Ошибка сохранения версии: " + e.getMessage());
|
log("Ошибка сохранения версии: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
log("Обновлено до v" + newVersion + " (JAR метод)");
|
log("Обновлено до v" + newVersion);
|
||||||
} else {
|
} else {
|
||||||
throw new IOException("Сервер вернул код: " + conn.getResponseCode());
|
throw new IOException("Сервер вернул код: " + conn.getResponseCode());
|
||||||
}
|
}
|
||||||
@@ -542,7 +154,7 @@ public class Bootstrap {
|
|||||||
private static void launchJFX() throws Exception {
|
private static void launchJFX() throws Exception {
|
||||||
Path javaBin = findJava();
|
Path javaBin = findJava();
|
||||||
Path jarPath = getLauncherJar();
|
Path jarPath = getLauncherJar();
|
||||||
|
|
||||||
log("Запуск JFX режима...");
|
log("Запуск JFX режима...");
|
||||||
log("Java: " + javaBin);
|
log("Java: " + javaBin);
|
||||||
log("JAR: " + jarPath);
|
log("JAR: " + jarPath);
|
||||||
@@ -585,7 +197,7 @@ public class Bootstrap {
|
|||||||
private static void launchCLI() throws Exception {
|
private static void launchCLI() throws Exception {
|
||||||
Path javaBin = findJava();
|
Path javaBin = findJava();
|
||||||
Path jarPath = getLauncherJar();
|
Path jarPath = getLauncherJar();
|
||||||
|
|
||||||
log("Запуск CLI режима...");
|
log("Запуск CLI режима...");
|
||||||
log("Java: " + javaBin);
|
log("Java: " + javaBin);
|
||||||
log("JAR: " + jarPath);
|
log("JAR: " + jarPath);
|
||||||
|
|||||||
Reference in New Issue
Block a user