package net.viper.status; import net.md_5.bungee.api.plugin.Plugin; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.logging.Level; import java.util.regex.Matcher; import java.util.regex.Pattern; public class UpdateChecker { private final Plugin plugin; private final String currentVersion; private final int intervalHours; // Neue Domain und korrekter API-Pfad für Releases private final String apiUrl = "https://git.viper.ipv64.net/api/v1/repos/M_Viper/StatusAPI/releases"; private volatile String latestVersion = ""; private volatile String latestUrl = ""; private static final Pattern ASSET_NAME_PATTERN = Pattern.compile("\"name\"\\s*:\\s*\"([^\"]+)\"", Pattern.CASE_INSENSITIVE); private static final Pattern DOWNLOAD_PATTERN = Pattern.compile("\"browser_download_url\"\\s*:\\s*\"([^\"]+)\"", Pattern.CASE_INSENSITIVE); private static final Pattern TAG_NAME_PATTERN = Pattern.compile("\"tag_name\"\\s*:\\s*\"([^\"]+)\"", Pattern.CASE_INSENSITIVE); public UpdateChecker(Plugin plugin, String currentVersion, int intervalHours) { this.plugin = plugin; this.currentVersion = currentVersion != null ? currentVersion : "0.0.0"; this.intervalHours = Math.max(1, intervalHours); } public void checkNow() { try { HttpURLConnection conn = (HttpURLConnection) new URL(apiUrl).openConnection(); conn.setRequestMethod("GET"); conn.setRequestProperty("Accept", "application/json"); conn.setRequestProperty("User-Agent", "StatusAPI-UpdateChecker/2.0"); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); int code = conn.getResponseCode(); if (code != 200) { plugin.getLogger().warning("Gitea/Forgejo API nicht erreichbar (HTTP " + code + ")"); return; } StringBuilder sb = new StringBuilder(); try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"))) { String line; while ((line = br.readLine()) != null) sb.append(line).append("\n"); } String body = sb.toString(); // Neu: Da die API ein JSON-Array von Releases zurückgibt, nehmen wir das erste (neueste) Release // Wir suchen den ersten Block mit tag_name String foundVersion = null; Matcher tagM = TAG_NAME_PATTERN.matcher(body); if (tagM.find()) { foundVersion = tagM.group(1).trim(); } if (foundVersion == null) { plugin.getLogger().warning("Keine Version (Tag) im Release gefunden."); return; } if (foundVersion.startsWith("v") || foundVersion.startsWith("V")) { foundVersion = foundVersion.substring(1); } String foundUrl = null; // Wir suchen im gesamten Body nach der JAR-Datei "StatusAPI.jar" // Da das neueste Release zuerst kommt, brechen wir ab, sobald wir eine passende JAR finden Matcher nameMatcher = ASSET_NAME_PATTERN.matcher(body); Matcher downloadMatcher = DOWNLOAD_PATTERN.matcher(body); java.util.List names = new java.util.ArrayList<>(); java.util.List urls = new java.util.ArrayList<>(); while (nameMatcher.find()) { names.add(nameMatcher.group(1)); } while (downloadMatcher.find()) { urls.add(downloadMatcher.group(1)); } int pairs = Math.min(names.size(), urls.size()); for (int i = 0; i < pairs; i++) { String name = names.get(i).trim(); String url = urls.get(i); if ("StatusAPI.jar".equalsIgnoreCase(name)) { foundUrl = url; break; // Erste (also neueste) passende JAR nehmen } } if (foundUrl == null) { plugin.getLogger().warning("Keine StatusAPI.jar im neuesten Release gefunden."); return; } latestVersion = foundVersion; latestUrl = foundUrl; } catch (Exception e) { plugin.getLogger().log(Level.SEVERE, "Fehler beim Update-Check: " + e.getMessage(), e); } } public String getLatestVersion() { return latestVersion != null ? latestVersion : ""; } public String getLatestUrl() { return latestUrl != null ? latestUrl : ""; } public boolean isUpdateAvailable(String currentVer) { String lv = getLatestVersion(); if (lv.isEmpty()) return false; return compareVersions(lv, currentVer) > 0; } private int compareVersions(String a, String b) { try { String[] aa = a.split("\\."); String[] bb = b.split("\\."); int len = Math.max(aa.length, bb.length); for (int i = 0; i < len; i++) { int ai = i < aa.length ? Integer.parseInt(aa[i].replaceAll("\\D", "")) : 0; int bi = i < bb.length ? Integer.parseInt(bb[i].replaceAll("\\D", "")) : 0; if (ai != bi) return Integer.compare(ai, bi); } return 0; } catch (Exception ex) { return a.compareTo(b); } } }