5 Commits
Author SHA1 Message Date
Git Manager GUI 47f35d77e8 Upload via GUI (43 Dateien) 2026-07-20 10:39:56 +02:00
Git Manager GUI f3f7afab4d Upload folder via GUI - src 2026-06-18 21:28:13 +02:00
Git Manager GUI a7bd93fd40 Upload via Git Manager GUI 2026-06-18 21:28:11 +02:00
Git Manager GUI bb5f93d23f Upload folder via GUI - src 2026-06-18 21:21:36 +02:00
Git Manager GUI 52ad98a643 Upload folder via GUI - src 2026-06-18 20:56:01 +02:00
11 changed files with 100 additions and 22 deletions
+39 -7
View File
@@ -6,20 +6,22 @@
<groupId>de.serverpulse</groupId> <groupId>de.serverpulse</groupId>
<artifactId>ServerPulse</artifactId> <artifactId>ServerPulse</artifactId>
<version>1.0.0</version> <version>1.0.2</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>ServerPulse</name> <name>ServerPulse</name>
<description>Monitoring &amp; Analytics Suite – Spigot + Paper + BungeeCord (unified JAR)</description> <description>Monitoring &amp; Analytics Suite – Spigot + Paper + BungeeCord (unified JAR)</description>
<properties> <properties>
<maven.compiler.source>17</maven.compiler.source> <!-- Bytecode bleibt auf 17 -> Jar läuft weiterhin auf älteren Servern (1.21.x).
<maven.compiler.target>17</maven.compiler.target> Zum Kompilieren wird aber JDK 25 benötigt, da die paper-api 26.2 Klassen
mit Class-File-Version 25 ausliefert (siehe PaperMC Project-Setup Docs). -->
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
<repositories> <repositories>
<!-- PaperMC: Paper API + BungeeCord API 26.1 --> <!-- PaperMC: Paper API (aktuell 26.2) + BungeeCord API -->
<repository> <repository>
<id>papermc</id> <id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url> <url>https://repo.papermc.io/repository/maven-public/</url>
@@ -35,16 +37,25 @@
<!-- ══════════════════════════════════════ <!-- ══════════════════════════════════════
SPIGOT / PAPER API (provided) SPIGOT / PAPER API (provided)
══════════════════════════════════════ --> ══════════════════════════════════════ -->
<!-- Ab 26.1 nutzt Paper ein neues Versionsschema (Jahr.Release statt 1.xx-R0.1-SNAPSHOT).
Der Range-Ausdruck holt sich automatisch den neuesten 26.2-Build.
Zum Fixieren auf einen konkreten Build stattdessen z.B. 26.2.build.60-beta eintragen. -->
<dependency> <dependency>
<groupId>io.papermc.paper</groupId> <groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId> <artifactId>paper-api</artifactId>
<version>1.21.4-R0.1-SNAPSHOT</version> <version>[26.2.build,)</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- ══════════════════════════════════════ <!-- ══════════════════════════════════════
BUNGEECORD API (provided) BUNGEECORD API (provided)
══════════════════════════════════════ --> ══════════════════════════════════════ -->
<!-- TODO prüfen: ob/wann net.md-5 eine bungeecord-api 26.2-R0.1-SNAPSHOT im
hub.spigotmc.org Snapshot-Repo veröffentlicht. Aktuell bleibt 26.1 eingetragen,
da ich das von hier aus nicht gegen das Repo verifizieren konnte (Netzwerkzugriff
auf hub.spigotmc.org ist mir nicht möglich). BungeeCord-Server laden Plugins auch
ohne exakt passende API-Version, das Bungee-Modul sollte also trotzdem auf einem
26.2-Proxy laufen - bitte einmal real testen. -->
<dependency> <dependency>
<groupId>net.md-5</groupId> <groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId> <artifactId>bungeecord-api</artifactId>
@@ -148,11 +159,32 @@
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version> <version>3.13.0</version>
<configuration> <configuration>
<source>17</source> <release>${maven.compiler.release}</release>
<target>17</target>
</configuration> </configuration>
</plugin> </plugin>
<!-- Bricht den Build sofort mit klarer Meldung ab, falls nicht mit JDK 25
gebaut wird (paper-api 26.2 Klassen haben Class-File-Version 69). -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>enforce-jdk-25</id>
<goals><goal>enforce</goal></goals>
<configuration>
<rules>
<requireJavaVersion>
<version>[25,26)</version>
<message>Dieses Projekt braucht JDK 25 zum Bauen (paper-api 26.2 Class-File-Version 69). JAVA_HOME auf JDK 25 setzen und erneut versuchen.</message>
</requireJavaVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins> </plugins>
</build> </build>
</project> </project>
@@ -25,6 +25,10 @@ public class AlertManager {
// Standard-Cooldown: 5 Minuten // Standard-Cooldown: 5 Minuten
private static final long DEFAULT_COOLDOWN_MS = 5 * 60 * 1000; private static final long DEFAULT_COOLDOWN_MS = 5 * 60 * 1000;
// Startup-Grace-Period
private final long pluginStartTimeMs = System.currentTimeMillis();
private final long startupGracePeriodMs;
// Zähler für kritische Ereignisse (für Auto-Diagnose) // Zähler für kritische Ereignisse (für Auto-Diagnose)
private int criticalEventCount = 0; private int criticalEventCount = 0;
@@ -33,6 +37,7 @@ public class AlertManager {
public AlertManager(ServerPulse plugin) { public AlertManager(ServerPulse plugin) {
this.plugin = plugin; this.plugin = plugin;
this.startupGracePeriodMs = plugin.getConfigManager().getStartupCheckDelayMinutes() * 60_000L;
} }
// ────────────────────────────────────────── // ──────────────────────────────────────────
@@ -44,6 +49,12 @@ public class AlertManager {
*/ */
public void triggerAlert(String alertType, AlertSeverity severity, String worldName, public void triggerAlert(String alertType, AlertSeverity severity, String worldName,
String message, Double currentValue, Double threshold) { String message, Double currentValue, Double threshold) {
// Startup-Grace-Period prüfen
if (isStartupGracePeriodActive()) {
plugin.debug("Startup-Delay aktiv: Alert unterdrückt (" + alertType + ")");
return;
}
// Cooldown prüfen // Cooldown prüfen
String cooldownKey = alertType + (worldName != null ? "_" + worldName : ""); String cooldownKey = alertType + (worldName != null ? "_" + worldName : "");
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
@@ -211,4 +222,8 @@ public class AlertManager {
public int getCriticalEventCount() { public int getCriticalEventCount() {
return criticalEventCount; return criticalEventCount;
} }
private boolean isStartupGracePeriodActive() {
return System.currentTimeMillis() - pluginStartTimeMs < startupGracePeriodMs;
}
} }
@@ -14,11 +14,15 @@ import java.util.concurrent.ConcurrentHashMap;
public class BungeeAlertManager { public class BungeeAlertManager {
private final BungeePlugin plugin; private final BungeePlugin plugin;
private final long pluginStartTimeMs;
private final long startupGracePeriodMs;
private final Map<String, Long> cooldowns = new ConcurrentHashMap<>(); private final Map<String, Long> cooldowns = new ConcurrentHashMap<>();
private static final long COOLDOWN_MS = 5 * 60 * 1000L; private static final long COOLDOWN_MS = 5 * 60 * 1000L;
public BungeeAlertManager(BungeePlugin plugin) { public BungeeAlertManager(BungeePlugin plugin) {
this.plugin = plugin; this.plugin = plugin;
this.pluginStartTimeMs = System.currentTimeMillis();
this.startupGracePeriodMs = plugin.getBungeeConfig().getStartupCheckDelayMinutes() * 60_000L;
} }
/** /**
@@ -71,6 +75,11 @@ public class BungeeAlertManager {
private void trigger(String cooldownKey, String severity, private void trigger(String cooldownKey, String severity,
String serverName, String alertType, String message) { String serverName, String alertType, String message) {
if (isStartupGracePeriodActive()) {
plugin.debug("Startup-Delay aktiv: Alert unterdrückt (" + alertType + ")");
return;
}
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
if (cooldowns.containsKey(cooldownKey) if (cooldowns.containsKey(cooldownKey)
&& now - cooldowns.get(cooldownKey) < COOLDOWN_MS) return; && now - cooldowns.get(cooldownKey) < COOLDOWN_MS) return;
@@ -82,4 +91,8 @@ public class BungeeAlertManager {
plugin.getDiscordWebhook().sendServerAlert(serverName, alertType, severity, message); plugin.getDiscordWebhook().sendServerAlert(serverName, alertType, severity, message);
} }
} }
private boolean isStartupGracePeriodActive() {
return System.currentTimeMillis() - pluginStartTimeMs < startupGracePeriodMs;
}
} }
@@ -41,6 +41,7 @@ public class BungeeConfig {
// ── General ────────────────────────────── // ── General ──────────────────────────────
public boolean isDebugMode() { return config.getBoolean("general.debug", false); } public boolean isDebugMode() { return config.getBoolean("general.debug", false); }
public int getPollInterval() { return config.getInt("general.poll-interval", 30); } public int getPollInterval() { return config.getInt("general.poll-interval", 30); }
public int getStartupCheckDelayMinutes() { return Math.max(0, config.getInt("general.startup-check-delay-minutes", 5)); }
// ── Discord ────────────────────────────── // ── Discord ──────────────────────────────
public boolean isDiscordEnabled() { return config.getBoolean("discord.enabled", false); } public boolean isDiscordEnabled() { return config.getBoolean("discord.enabled", false); }
@@ -19,6 +19,8 @@ import java.util.Map;
public class AlertManager { public class AlertManager {
private final SpigotPlugin plugin; private final SpigotPlugin plugin;
private final long pluginStartTimeMs;
private final long startupGracePeriodMs;
// Cooldown: alertType -> letzter Trigger-Zeitpunkt (ms) // Cooldown: alertType -> letzter Trigger-Zeitpunkt (ms)
private final Map<String, Long> alertCooldowns = new HashMap<>(); private final Map<String, Long> alertCooldowns = new HashMap<>();
@@ -33,6 +35,8 @@ public class AlertManager {
public AlertManager(SpigotPlugin plugin) { public AlertManager(SpigotPlugin plugin) {
this.plugin = plugin; this.plugin = plugin;
this.pluginStartTimeMs = System.currentTimeMillis();
this.startupGracePeriodMs = plugin.getSpigotConfig().getStartupCheckDelayMinutes() * 60_000L;
} }
// ────────────────────────────────────────── // ──────────────────────────────────────────
@@ -44,6 +48,11 @@ public class AlertManager {
*/ */
public void triggerAlert(String alertType, AlertSeverity severity, String worldName, public void triggerAlert(String alertType, AlertSeverity severity, String worldName,
String message, Double currentValue, Double threshold) { String message, Double currentValue, Double threshold) {
if (isStartupGracePeriodActive()) {
plugin.debug("Startup-Delay aktiv: Alert unterdrückt (" + alertType + ")");
return;
}
// Cooldown prüfen // Cooldown prüfen
String cooldownKey = alertType + (worldName != null ? "_" + worldName : ""); String cooldownKey = alertType + (worldName != null ? "_" + worldName : "");
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
@@ -216,4 +225,8 @@ public class AlertManager {
public int getCriticalEventCount() { public int getCriticalEventCount() {
return criticalEventCount; return criticalEventCount;
} }
private boolean isStartupGracePeriodActive() {
return System.currentTimeMillis() - pluginStartTimeMs < startupGracePeriodMs;
}
} }
@@ -15,8 +15,9 @@ public class MsgUtil {
// '─' (U+2500) ist in Minecraft's Standard-Schrift ca. 6px breit. // '─' (U+2500) ist in Minecraft's Standard-Schrift ca. 6px breit.
// Der Chat ist ~320px breit → ~53 Zeichen. // Der Chat ist ~320px breit → ~53 Zeichen.
// Mit Prefix "[ServerPulse] " (~14 Zeichen) bleiben ~39 Zeichen übrig. // Mit Prefix "[ServerPulse] " (~14 Zeichen) bleiben ~39 Zeichen übrig.
// Wir setzen LINE_LEN daher auf 38 damit es mit Prefix in eine Zeile passt. // In der Praxis wirkt die Zeile mit den Farbformatierungen etwas breiter.
private static final int LINE_LEN = 38; // 34 ergibt hier eine saubere Breite ohne Umbruch.
private static final int LINE_LEN = 34;
private static final char LINE_CHAR = '─'; private static final char LINE_CHAR = '─';
private MsgUtil() {} private MsgUtil() {}
@@ -78,22 +79,18 @@ public class MsgUtil {
} }
/** /**
* Zentrierter Header. * Zentrierter, symmetrischer Header.
* Beispiel: ───── ServerPulse Status ───── * Beispiel: ───── ServerPulse Status ─────
*
* Die Striche werden so berechnet, dass Titel + Striche = LINE_LEN ergibt.
* Wenn der Titel zu lang ist, werden mindestens 3 Striche pro Seite gesetzt.
*/ */
public static String header(String title) { public static String header(String title) {
int available = LINE_LEN - title.length() - 2; // -2 für Leerzeichen int available = Math.max(6, LINE_LEN - title.length() - 2); // -2 für Leerzeichen
int left = Math.max(3, available / 2); int side = Math.max(3, available / 2);
int right = Math.max(3, available - left);
String l = String.valueOf(LINE_CHAR); String l = String.valueOf(LINE_CHAR);
return colorize( return colorize(
"&8" + l.repeat(left) + "&8" + l.repeat(side) +
" &b&l" + title + " &b&l" + title +
" &8" + l.repeat(right) " &8" + l.repeat(side)
); );
} }
} }
@@ -14,6 +14,7 @@ public class SpigotConfig {
public boolean isDebugMode() { return cfg.getBoolean("general.debug", false); } public boolean isDebugMode() { return cfg.getBoolean("general.debug", false); }
public int getMetricsInterval() { return Math.max(10, cfg.getInt("general.metrics-interval", 30)); } public int getMetricsInterval() { return Math.max(10, cfg.getInt("general.metrics-interval", 30)); }
public int getEntityInterval() { return Math.max(10, cfg.getInt("general.entity-interval", 60)); } public int getEntityInterval() { return Math.max(10, cfg.getInt("general.entity-interval", 60)); }
public int getStartupCheckDelayMinutes() { return Math.max(0, cfg.getInt("general.startup-check-delay-minutes", 5)); }
public int getDataRetentionDays() { return cfg.getInt("general.data-retention-days", 90); } public int getDataRetentionDays() { return cfg.getInt("general.data-retention-days", 90); }
public boolean isDatabaseEnabled() { return cfg.getBoolean("database.enabled", true); } public boolean isDatabaseEnabled() { return cfg.getBoolean("database.enabled", true); }
public String getDbHost() { return cfg.getString("database.host", "localhost"); } public String getDbHost() { return cfg.getString("database.host", "localhost"); }
@@ -48,6 +48,10 @@ public class ConfigManager {
return config.getInt("general.data-retention-days", 90); return config.getInt("general.data-retention-days", 90);
} }
public int getStartupCheckDelayMinutes() {
return Math.max(0, config.getInt("general.startup-check-delay-minutes", 5));
}
// ────────────────────────────────────────── // ──────────────────────────────────────────
// DATENBANK // DATENBANK
// ────────────────────────────────────────── // ──────────────────────────────────────────
+1 -1
View File
@@ -1,5 +1,5 @@
name: ServerPulse name: ServerPulse
version: '1.0.0' version: '1.0.1'
main: de.serverpulse.bungee.BungeePlugin main: de.serverpulse.bungee.BungeePlugin
author: ServerPulse-Team author: ServerPulse-Team
description: ServerPulse BungeeCord Module (unified JAR) description: ServerPulse BungeeCord Module (unified JAR)
+2 -1
View File
@@ -1,5 +1,5 @@
# ╔══════════════════════════════════════════╗ # ╔══════════════════════════════════════════╗
# ║ ServerPulse v1.0.0 Configuration ║ # ║ ServerPulse v1.0.2 Configuration ║
# ║ Unified JAR – Spigot / Paper / Bungee ║ # ║ Unified JAR – Spigot / Paper / Bungee ║
# ╚══════════════════════════════════════════╝ # ╚══════════════════════════════════════════╝
# #
@@ -11,6 +11,7 @@
# ────────────────────────────────────────── # ──────────────────────────────────────────
general: general:
debug: false debug: false
startup-check-delay-minutes: 5 # Verzögerung nach Start, bevor Alerts/Prüfungen ausgelöst werden
metrics-interval: 30 # Sekunden (Spigot: Performance-Erfassung) metrics-interval: 30 # Sekunden (Spigot: Performance-Erfassung)
entity-interval: 60 # Sekunden (Spigot: Entity-Erfassung) entity-interval: 60 # Sekunden (Spigot: Entity-Erfassung)
poll-interval: 30 # Sekunden (BungeeCord: Daten-Weiterleitung) poll-interval: 30 # Sekunden (BungeeCord: Daten-Weiterleitung)
+3 -2
View File
@@ -1,7 +1,8 @@
name: ServerPulse name: ServerPulse
version: '1.0.0' version: '1.0.2'
main: de.serverpulse.spigot.SpigotPlugin main: de.serverpulse.spigot.SpigotPlugin
api-version: '1.21' api-version: '1.21' # bewusst niedrig gehalten (gültiger Bereich 1.13-26.2) -> Plugin lädt
# auf 1.21.x GENAUSO wie auf 26.1/26.2-Servern, kein separater Build nötig
description: Monitoring & Analytics Suite (Spigot/Paper/BungeeCord unified) description: Monitoring & Analytics Suite (Spigot/Paper/BungeeCord unified)
authors: [ M_Viper ] authors: [ M_Viper ]
prefix: ServerPulse prefix: ServerPulse