Update from Git Manager GUI
This commit is contained in:
@@ -1,8 +1,14 @@
|
||||
package net.viper.status;
|
||||
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.api.config.ListenerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
import net.viper.status.module.ModuleManager;
|
||||
import net.viper.status.stats.PlayerStats;
|
||||
@@ -12,15 +18,15 @@ import net.viper.status.modules.globalchat.GlobalChatModule;
|
||||
import net.viper.status.modules.navigation.NavigationModule;
|
||||
import net.viper.status.modules.commandblocker.CommandBlockerModule;
|
||||
import net.viper.status.modules.broadcast.BroadcastModule;
|
||||
import net.viper.status.modules.AutoMessage.AutoMessageModule;
|
||||
import net.viper.status.modules.customcommands.CustomCommandModule;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringReader;
|
||||
import java.net.ServerSocket;
|
||||
@@ -29,24 +35,31 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
|
||||
/**
|
||||
* StatusAPI - zentraler Bungee HTTP-Status- und Broadcast-Endpunkt
|
||||
*/
|
||||
public class StatusAPI extends Plugin implements Runnable {
|
||||
public class StatusAPI extends Plugin implements Runnable, Listener {
|
||||
|
||||
private Thread thread;
|
||||
private int port = 9191;
|
||||
|
||||
private ModuleManager moduleManager;
|
||||
private UpdateChecker updateChecker;
|
||||
private FileDownloader fileDownloader;
|
||||
private Properties verifyProperties;
|
||||
|
||||
// Speicher für Updates beim Join
|
||||
private boolean updatePending = false;
|
||||
private String latestVersionString = "";
|
||||
private final Set<UUID> informedAdmins = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
getLogger().info("StatusAPI Core wird initialisiert...");
|
||||
|
||||
// Event Listener registrieren
|
||||
getProxy().getPluginManager().registerListener(this, this);
|
||||
|
||||
if (!getDataFolder().exists()) {
|
||||
getDataFolder().mkdirs();
|
||||
}
|
||||
@@ -63,6 +76,16 @@ public class StatusAPI extends Plugin implements Runnable {
|
||||
moduleManager.registerModule(new NavigationModule());
|
||||
moduleManager.registerModule(new BroadcastModule());
|
||||
moduleManager.registerModule(new CommandBlockerModule());
|
||||
moduleManager.registerModule(new AutoMessageModule());
|
||||
|
||||
// CustomCommandModule nur laden, wenn aktiviert
|
||||
boolean customCommandsEnabled = Boolean.parseBoolean(getVerifyProperties().getProperty("customcommands.enabled", "false"));
|
||||
if (customCommandsEnabled) {
|
||||
moduleManager.registerModule(new CustomCommandModule()); // Korrigiert: Kein Argument im Konstruktor
|
||||
getLogger().info("CustomCommandModule aktiviert.");
|
||||
} else {
|
||||
getLogger().info("CustomCommandModule deaktiviert (siehe verify.properties).");
|
||||
}
|
||||
|
||||
moduleManager.enableAll(this);
|
||||
|
||||
@@ -71,22 +94,114 @@ public class StatusAPI extends Plugin implements Runnable {
|
||||
thread = new Thread(this, "StatusAPI-HTTP-Server");
|
||||
thread.start();
|
||||
|
||||
// Update System
|
||||
String currentVersion = getDescription() != null ? getDescription().getVersion() : "0.0.0";
|
||||
updateChecker = new UpdateChecker(this, currentVersion, 6);
|
||||
fileDownloader = new FileDownloader(this);
|
||||
// Einfacher Update-Check (Nur Benachrichtigung für Admins beim Start oder beim Join)
|
||||
checkForUpdatesAndNotify();
|
||||
}
|
||||
|
||||
File pluginFile = getFile();
|
||||
File backupFile = new File(pluginFile.getParentFile(), "StatusAPI.jar.bak");
|
||||
|
||||
if (backupFile.exists()) {
|
||||
ProxyServer.getInstance().getScheduler().schedule(this, () -> {
|
||||
if (backupFile.exists()) backupFile.delete();
|
||||
},1, TimeUnit.MINUTES);
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PostLoginEvent event) {
|
||||
ProxiedPlayer player = event.getPlayer();
|
||||
|
||||
// Wir prüfen hier nur, ob ein Update aussteht. Der Rest wird im Scheduler verzögert geprüft.
|
||||
if (updatePending && isAdmin(player)) {
|
||||
// Verzögerung um 2 Sekunden
|
||||
getProxy().getScheduler().schedule(this, () -> {
|
||||
// Prüfen, ob Spieler noch online ist und noch nicht informiert wurde
|
||||
if (player.isConnected() && !informedAdmins.contains(player.getUniqueId()) && isAdmin(player)) {
|
||||
sendStyledUpdateMessage(player);
|
||||
informedAdmins.add(player.getUniqueId());
|
||||
getLogger().info("Admin " + player.getName() + " wurde über das neue Update informiert.");
|
||||
}
|
||||
}, 2, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
checkAndMaybeUpdate();
|
||||
ProxyServer.getInstance().getScheduler().schedule(this, this::checkAndMaybeUpdate, 6, 6, TimeUnit.HOURS);
|
||||
/**
|
||||
* Sendet eine formatierte Nachricht mit klickbarem Link.
|
||||
*/
|
||||
private void sendStyledUpdateMessage(ProxiedPlayer player) {
|
||||
String currentVersion = getDescription() != null ? getDescription().getVersion() : "Unbekannt";
|
||||
String downloadUrl = "https://git.viper.ipv64.net/M_Viper/StatusAPI/releases";
|
||||
|
||||
ComponentBuilder builder = new ComponentBuilder("");
|
||||
|
||||
// Zeile 1: Update Info
|
||||
// Wir konvertieren Legacy-Strings zu BaseComponents und fügen sie an den Builder an
|
||||
builder.append(TextComponent.fromLegacyText("§a[StatusAPI] "))
|
||||
.append(TextComponent.fromLegacyText("§eEine neue Version ist verfügbar: "))
|
||||
.append(TextComponent.fromLegacyText("§c" + latestVersionString))
|
||||
.append(TextComponent.fromLegacyText(" §7(Deine Version: "))
|
||||
.append(TextComponent.fromLegacyText("§c" + currentVersion))
|
||||
.append(TextComponent.fromLegacyText("§7)\n"));
|
||||
|
||||
// Zeile 2: Download
|
||||
builder.append(TextComponent.fromLegacyText("§7Download: "));
|
||||
|
||||
// Der Klickbare Teil
|
||||
TextComponent link = new TextComponent("§e§nLink");
|
||||
link.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, downloadUrl));
|
||||
link.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText("§aKlicke hier um die Release-Seite zu öffnen")));
|
||||
|
||||
builder.append(link);
|
||||
|
||||
// Korrektur: Nur die Components senden, nicht den Spieler als Argument
|
||||
player.sendMessage(builder.create());
|
||||
}
|
||||
|
||||
/**
|
||||
* Überprüft auf Updates und benachrichtigt Spieler mit Admin-Rechten (OP/Owner).
|
||||
*/
|
||||
private void checkForUpdatesAndNotify() {
|
||||
String currentVersion = getDescription() != null ? getDescription().getVersion() : "0.0.0";
|
||||
// Der UpdateChecker wird nur lokal instanziiert für den Check
|
||||
UpdateChecker checker = new UpdateChecker(this, currentVersion, 6);
|
||||
|
||||
try {
|
||||
checker.checkNow();
|
||||
|
||||
if (checker.isUpdateAvailable(currentVersion)) {
|
||||
String newVersion = checker.getLatestVersion();
|
||||
String url = checker.getLatestUrl();
|
||||
|
||||
getLogger().warning("------------------------------------------------");
|
||||
getLogger().warning("Neue Version verfügbar: " + newVersion);
|
||||
getLogger().warning("Aktuelle Version: " + currentVersion);
|
||||
getLogger().warning("Download: " + url);
|
||||
getLogger().warning("------------------------------------------------");
|
||||
|
||||
// Info speichern (nur Version, URL ist statisch für den Chat-Link)
|
||||
this.updatePending = true;
|
||||
this.latestVersionString = newVersion;
|
||||
|
||||
// Benachrichtigung an online Admins / OPs (mit Verzögerung, um konsistent mit Join zu sein)
|
||||
boolean notifiedSomeone = false;
|
||||
for (ProxiedPlayer p : ProxyServer.getInstance().getPlayers()) {
|
||||
if (isAdmin(p)) {
|
||||
final ProxiedPlayer player = p;
|
||||
getProxy().getScheduler().schedule(this, () -> {
|
||||
if (player.isConnected() && !informedAdmins.contains(player.getUniqueId())) {
|
||||
sendStyledUpdateMessage(player);
|
||||
informedAdmins.add(player.getUniqueId());
|
||||
}
|
||||
}, 2, TimeUnit.SECONDS);
|
||||
notifiedSomeone = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!notifiedSomeone) {
|
||||
getLogger().info("Keine Admins waren online, um benachrichtigt zu werden. Sie werden beim Join informiert.");
|
||||
}
|
||||
} else {
|
||||
getLogger().info("Keine Updates verfügbar.");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
getLogger().severe("Fehler beim Update-Check: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Hilfsmethode zum Prüfen von Admin-Rechten
|
||||
private boolean isAdmin(ProxiedPlayer player) {
|
||||
return player.hasPermission("statusapi.admin") || player.hasPermission("bungeecord.command.server");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -190,8 +305,6 @@ public class StatusAPI extends Plugin implements Runnable {
|
||||
"",
|
||||
"# Beispiel: Deinen UUID hier einfügen",
|
||||
"override.uuid-hier-einfügen = Owner",
|
||||
"override.uuid-hier-einfügen-2 = Admin",
|
||||
"override.uuid-hier-einfügen-3 = Developer",
|
||||
"",
|
||||
"# ===========================",
|
||||
"# Chat-Formate für Gruppen",
|
||||
@@ -209,10 +322,33 @@ public class StatusAPI extends Plugin implements Runnable {
|
||||
"groupformat.spieler=&f[Spieler] || &7 || &8",
|
||||
"",
|
||||
"# ===========================",
|
||||
"# AUTOMESSAGE",
|
||||
"# ===========================",
|
||||
"# Aktiviert den automatischen Nachrichten-Rundruf",
|
||||
"automessage.enabled=false",
|
||||
"",
|
||||
"# Zeitintervall in Sekunden (Standard: 300 = 5 Minuten)",
|
||||
"automessage.interval=300",
|
||||
"",
|
||||
"# Optional: Ein Prefix, das VOR jede Nachricht aus der Datei gesetzt wird.",
|
||||
"# Wenn du das Prefix bereits IN der messages.txt hast, lass dieses Feld einfach leer.",
|
||||
"automessage.prefix=",
|
||||
"",
|
||||
"# Der Name der Datei, in der die Nachrichten stehen (liegt im Plugin-Ordner)",
|
||||
"automessage.file=messages.txt",
|
||||
"",
|
||||
"# ===========================",
|
||||
"# COMMAND BLOCKER",
|
||||
"# ===========================",
|
||||
"commandblocker.enabled=true",
|
||||
"commandblocker.bypass.permission=commandblocker.bypass"
|
||||
"commandblocker.bypass.permission=commandblocker.bypass",
|
||||
"",
|
||||
"# ===========================",
|
||||
"# CUSTOM COMMANDS",
|
||||
"# ===========================",
|
||||
"# Aktiviert das Modul für benutzerdefinierte Befehle und Aliases.",
|
||||
"# Wenn aktiviert, wird die Datei 'customcommands.yml' geladen.",
|
||||
"customcommands.enabled=true"
|
||||
);
|
||||
|
||||
// 2. Existierende Werte einlesen
|
||||
@@ -321,69 +457,6 @@ public class StatusAPI extends Plugin implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
// --- Update Logik ---
|
||||
private void checkAndMaybeUpdate() {
|
||||
try {
|
||||
updateChecker.checkNow();
|
||||
String currentVersion = getDescription() != null ? getDescription().getVersion() : "0.0.0";
|
||||
|
||||
if (updateChecker.isUpdateAvailable(currentVersion)) {
|
||||
String newVersion = updateChecker.getLatestVersion();
|
||||
String url = updateChecker.getLatestUrl();
|
||||
getLogger().warning("----------------------------------------");
|
||||
getLogger().warning("Neue Version verfügbar: " + newVersion);
|
||||
getLogger().warning("Starte automatisches Update...");
|
||||
getLogger().warning("----------------------------------------");
|
||||
|
||||
File pluginFile = getFile();
|
||||
File newFile = new File(pluginFile.getParentFile(), "StatusAPI.jar.new");
|
||||
|
||||
fileDownloader.downloadFile(url, newFile, () -> triggerUpdateScript(pluginFile, newFile));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
getLogger().severe("Fehler beim Update-Check: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void triggerUpdateScript(File currentFile, File newFile) {
|
||||
try {
|
||||
File pluginsFolder = currentFile.getParentFile();
|
||||
File rootFolder = pluginsFolder.getParentFile();
|
||||
File batFile = new File(rootFolder, "StatusAPI_Update_" + System.currentTimeMillis() + ".bat");
|
||||
|
||||
String batContent = "@echo off\n" +
|
||||
"echo Bitte warten, der Server fährt herunter...\n" +
|
||||
"timeout /t 5 /nobreak >nul\n" +
|
||||
"cd /d \"" + pluginsFolder.getAbsolutePath().replace("\\", "/") + "\"\n" +
|
||||
"echo Fuehre Datei-Tausch durch...\n" +
|
||||
"if exist StatusAPI.jar.bak del StatusAPI.jar.bak\n" +
|
||||
"if exist StatusAPI.jar (\n" +
|
||||
" ren StatusAPI.jar StatusAPI.jar.bak\n" +
|
||||
")\n" +
|
||||
"if exist StatusAPI.new.jar (\n" +
|
||||
" ren StatusAPI.new.jar StatusAPI.jar\n" +
|
||||
" echo Update erfolgreich!\n" +
|
||||
") else (\n" +
|
||||
" echo FEHLER: StatusAPI.new.jar nicht gefunden!\n" +
|
||||
" pause\n" +
|
||||
")\n" +
|
||||
"del \"%~f0\"";
|
||||
|
||||
try (PrintWriter out = new PrintWriter(batFile)) { out.println(batContent); }
|
||||
|
||||
for (ProxiedPlayer p : ProxyServer.getInstance().getPlayers()) {
|
||||
p.disconnect("§cServer fährt für ein Update neu herunter. Bitte etwas warten.");
|
||||
}
|
||||
|
||||
getLogger().info("Starte Update-Skript...");
|
||||
Runtime.getRuntime().exec("cmd /c start \"Update_Proc\" \"" + batFile.getAbsolutePath() + "\"");
|
||||
ProxyServer.getInstance().stop();
|
||||
|
||||
} catch (Exception e) {
|
||||
getLogger().severe("Fehler beim Vorbereiten des Updates: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// --- WebServer & JSON ---
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
Reference in New Issue
Block a user