Delete src/main/java/net/viper/status/stats/StatsModule.java via Git Manager GUI
This commit is contained in:
@@ -1,145 +0,0 @@
|
||||
package net.viper.status.stats;
|
||||
|
||||
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
|
||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
import net.viper.status.module.Module;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* StatsModule: Tracking von Spielerdaten (Playtime, Joins, Kills, Deaths).
|
||||
*
|
||||
* Fixes:
|
||||
* - BUG-1: Crash-Recovery für currentSessionStart (verhindert falsche Spielzeit nach Absturz)
|
||||
* - BUG-2: kills / deaths werden jetzt getrackt und per POST /stats/update aktualisiert
|
||||
*/
|
||||
public class StatsModule implements Module, Listener {
|
||||
|
||||
/**
|
||||
* Maximale Sessionlänge nach einem Crash noch gutschreiben (24 Stunden).
|
||||
* Längere Differenzen sind unrealistisch → werden ignoriert, currentSessionStart = 0 gesetzt.
|
||||
*/
|
||||
private static final long MAX_SESSION_SECONDS = 86_400L;
|
||||
|
||||
private StatsManager manager;
|
||||
private StatsStorage storage;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "StatsModule";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable(Plugin plugin) {
|
||||
manager = new StatsManager();
|
||||
storage = new StatsStorage(plugin.getDataFolder());
|
||||
|
||||
try {
|
||||
storage.load(manager);
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().warning("Fehler beim Laden der Stats: " + e.getMessage());
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// FIX BUG-1: Crash-Recovery – offene Sessions bereinigen.
|
||||
//
|
||||
// Bei normalem Shutdown setzt onDisable() currentSessionStart = 0 und speichert.
|
||||
// Bei einem Crash (kill -9, OOM, etc.) passiert das nicht. Beim nächsten Start
|
||||
// sind alle Spieler offline, aber currentSessionStart enthält noch den alten
|
||||
// Timestamp. getPlaytimeWithCurrentSession() würde dann fälschlicherweise
|
||||
// (now - alter_crash_timestamp) zur Spielzeit addieren → massiv falscher Wert.
|
||||
//
|
||||
// Fix: Nach dem Laden jeden Eintrag prüfen. Falls currentSessionStart > 0:
|
||||
// - Plausible Differenz (≤ MAX_SESSION_SECONDS) → als echte Zeit gutschreiben
|
||||
// - Unplausibel (> MAX_SESSION_SECONDS) → verwerfen, nur zurücksetzen
|
||||
// - In beiden Fällen: currentSessionStart = 0 setzen
|
||||
// -----------------------------------------------------------------------
|
||||
long now = System.currentTimeMillis() / 1000L;
|
||||
int recovered = 0;
|
||||
for (PlayerStats ps : manager.all()) {
|
||||
synchronized (ps) {
|
||||
if (ps.currentSessionStart > 0) {
|
||||
long delta = now - ps.currentSessionStart;
|
||||
if (delta > 0 && delta <= MAX_SESSION_SECONDS) {
|
||||
ps.totalPlaytime += delta;
|
||||
recovered++;
|
||||
} else if (delta > MAX_SESSION_SECONDS) {
|
||||
plugin.getLogger().warning(
|
||||
"[StatsModule] Unplausibler currentSessionStart für " + ps.name
|
||||
+ " (delta=" + delta + "s > " + MAX_SESSION_SECONDS + "s). "
|
||||
+ "Session wird ohne Gutschrift zurückgesetzt."
|
||||
);
|
||||
}
|
||||
ps.currentSessionStart = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (recovered > 0) {
|
||||
plugin.getLogger().info(
|
||||
"[StatsModule] Crash-Recovery: " + recovered + " offene Session(en) bereinigt und gespeichert."
|
||||
);
|
||||
try {
|
||||
storage.save(manager);
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().warning("Fehler beim Speichern nach Crash-Recovery: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
plugin.getProxy().getPluginManager().registerListener(plugin, this);
|
||||
|
||||
// Auto-Save alle 5 Minuten
|
||||
plugin.getProxy().getScheduler().schedule(plugin, () -> {
|
||||
try {
|
||||
storage.save(manager);
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().warning("Fehler beim Auto-Save: " + e.getMessage());
|
||||
}
|
||||
}, 5, 5, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable(Plugin plugin) {
|
||||
if (manager != null && storage != null) {
|
||||
long now = System.currentTimeMillis() / 1000L;
|
||||
for (PlayerStats ps : manager.all()) {
|
||||
synchronized (ps) {
|
||||
if (ps.currentSessionStart > 0) {
|
||||
long delta = now - ps.currentSessionStart;
|
||||
if (delta > 0) ps.totalPlaytime += delta;
|
||||
ps.currentSessionStart = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
storage.save(manager);
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().warning("Fehler beim Speichern (Shutdown): " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public StatsManager getManager() {
|
||||
return manager;
|
||||
}
|
||||
|
||||
// --- Events ---
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PostLoginEvent e) {
|
||||
try {
|
||||
manager.get(e.getPlayer().getUniqueId(), e.getPlayer().getName()).onJoin();
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerDisconnectEvent e) {
|
||||
try {
|
||||
PlayerStats ps = manager.getIfPresent(e.getPlayer().getUniqueId());
|
||||
if (ps != null) ps.onQuit();
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user