Dateien nach "src/main/java/net/viper/status/stats" hochladen
This commit is contained in:
70
src/main/java/net/viper/status/stats/PlayerStats.java
Normal file
70
src/main/java/net/viper/status/stats/PlayerStats.java
Normal file
@@ -0,0 +1,70 @@
|
||||
package net.viper.status.stats;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerStats {
|
||||
public final UUID uuid;
|
||||
public String name;
|
||||
public long firstSeen;
|
||||
public long lastSeen;
|
||||
public long totalPlaytime;
|
||||
public long currentSessionStart;
|
||||
public int joins;
|
||||
|
||||
public PlayerStats(UUID uuid, String name) {
|
||||
this.uuid = uuid;
|
||||
this.name = name;
|
||||
long now = System.currentTimeMillis() / 1000L;
|
||||
this.firstSeen = now;
|
||||
this.lastSeen = now;
|
||||
this.totalPlaytime = 0;
|
||||
this.currentSessionStart = 0;
|
||||
this.joins = 0;
|
||||
}
|
||||
|
||||
public synchronized void onJoin() {
|
||||
long now = System.currentTimeMillis() / 1000L;
|
||||
if (this.currentSessionStart == 0) this.currentSessionStart = now;
|
||||
this.lastSeen = now;
|
||||
this.joins++;
|
||||
if (this.firstSeen == 0) this.firstSeen = now;
|
||||
}
|
||||
|
||||
public synchronized void onQuit() {
|
||||
long now = System.currentTimeMillis() / 1000L;
|
||||
if (this.currentSessionStart > 0) {
|
||||
long session = now - this.currentSessionStart;
|
||||
if (session > 0) this.totalPlaytime += session;
|
||||
this.currentSessionStart = 0;
|
||||
}
|
||||
this.lastSeen = now;
|
||||
}
|
||||
|
||||
public synchronized long getPlaytimeWithCurrentSession() {
|
||||
long now = System.currentTimeMillis() / 1000L;
|
||||
if (this.currentSessionStart > 0) return totalPlaytime + (now - currentSessionStart);
|
||||
return totalPlaytime;
|
||||
}
|
||||
|
||||
public synchronized String toLine() {
|
||||
return uuid + "|" + name.replace("|", "_") + "|" + firstSeen + "|" + lastSeen + "|" + totalPlaytime + "|" + currentSessionStart + "|" + joins;
|
||||
}
|
||||
|
||||
public static PlayerStats fromLine(String line) {
|
||||
String[] parts = line.split("\\|", -1);
|
||||
if (parts.length < 7) return null;
|
||||
try {
|
||||
UUID uuid = UUID.fromString(parts[0]);
|
||||
String name = parts[1];
|
||||
PlayerStats ps = new PlayerStats(uuid, name);
|
||||
ps.firstSeen = Long.parseLong(parts[2]);
|
||||
ps.lastSeen = Long.parseLong(parts[3]);
|
||||
ps.totalPlaytime = Long.parseLong(parts[4]);
|
||||
ps.currentSessionStart = Long.parseLong(parts[5]);
|
||||
ps.joins = Integer.parseInt(parts[6]);
|
||||
return ps;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
35
src/main/java/net/viper/status/stats/StatsManager.java
Normal file
35
src/main/java/net/viper/status/stats/StatsManager.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package net.viper.status.stats;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class StatsManager {
|
||||
private final ConcurrentHashMap<UUID, PlayerStats> map = new ConcurrentHashMap<>();
|
||||
|
||||
public PlayerStats get(UUID uuid, String name) {
|
||||
return map.compute(uuid, (k, v) -> {
|
||||
if (v == null) {
|
||||
return new PlayerStats(uuid, name != null ? name : "");
|
||||
} else {
|
||||
if (name != null && !name.isEmpty()) v.name = name;
|
||||
return v;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public PlayerStats getIfPresent(UUID uuid) {
|
||||
return map.get(uuid);
|
||||
}
|
||||
|
||||
public Iterable<PlayerStats> all() {
|
||||
return map.values();
|
||||
}
|
||||
|
||||
public void put(PlayerStats ps) {
|
||||
map.put(ps.uuid, ps);
|
||||
}
|
||||
|
||||
public void remove(UUID uuid) {
|
||||
map.remove(uuid);
|
||||
}
|
||||
}
|
||||
100
src/main/java/net/viper/status/stats/StatsModule.java
Normal file
100
src/main/java/net/viper/status/stats/StatsModule.java
Normal file
@@ -0,0 +1,100 @@
|
||||
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: Kümmert sich eigenständig um das Tracking der Spielerdaten.
|
||||
* Implementiert Module (für das Lifecycle) und Listener (für die Events).
|
||||
*/
|
||||
public class StatsModule implements Module, Listener {
|
||||
|
||||
private StatsManager manager;
|
||||
private StatsStorage storage;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "StatsModule";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable(Plugin plugin) {
|
||||
// Initialisierung
|
||||
manager = new StatsManager();
|
||||
storage = new StatsStorage(plugin.getDataFolder());
|
||||
|
||||
// Laden
|
||||
try {
|
||||
storage.load(manager);
|
||||
plugin.getLogger().info("Player-Stats wurden erfolgreich geladen.");
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().warning("Fehler beim Laden der Stats: " + e.getMessage());
|
||||
}
|
||||
|
||||
// Event Listener registrieren
|
||||
plugin.getProxy().getPluginManager().registerListener(plugin, this);
|
||||
|
||||
// Auto-Save Task (alle 5 Minuten)
|
||||
plugin.getProxy().getScheduler().schedule(plugin, () -> {
|
||||
try {
|
||||
storage.save(manager);
|
||||
plugin.getLogger().info("Auto-Save: Player-Stats gespeichert.");
|
||||
} 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) {
|
||||
// Laufende Sessions beenden vor dem Speichern
|
||||
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; // Session beenden
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
storage.save(manager);
|
||||
plugin.getLogger().info("Player-Stats beim Shutdown gespeichert.");
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().warning("Fehler beim Speichern (Shutdown): " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Öffentlicher Zugriff für den WebServer
|
||||
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) {}
|
||||
}
|
||||
}
|
||||
37
src/main/java/net/viper/status/stats/StatsStorage.java
Normal file
37
src/main/java/net/viper/status/stats/StatsStorage.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package net.viper.status.stats;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class StatsStorage {
|
||||
private final File file;
|
||||
|
||||
public StatsStorage(File pluginFolder) {
|
||||
if (!pluginFolder.exists()) pluginFolder.mkdirs();
|
||||
this.file = new File(pluginFolder, "stats.dat");
|
||||
}
|
||||
|
||||
public void save(StatsManager manager) {
|
||||
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
|
||||
for (PlayerStats ps : manager.all()) {
|
||||
bw.write(ps.toLine());
|
||||
bw.newLine();
|
||||
}
|
||||
bw.flush();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void load(StatsManager manager) {
|
||||
if (!file.exists()) return;
|
||||
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
PlayerStats ps = PlayerStats.fromLine(line);
|
||||
if (ps != null) manager.put(ps);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user