Files
Fussball/src/main/java/de/fussball/plugin/stats/StatsManager.java
2026-03-17 16:15:01 +01:00

188 lines
7.1 KiB
Java

package de.fussball.plugin.stats;
import de.fussball.plugin.Fussball;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
import java.util.*;
/**
* Verwaltet persistente Spielerstatistiken in stats.yml.
* Gespeichert werden: Tore, Schüsse, Siege, Niederlagen, Unentschieden, gespielte Spiele.
*/
public class StatsManager {
private final Fussball plugin;
private final File statsFile;
private FileConfiguration statsConfig;
// In-Memory-Cache für schnellen Zugriff
private final Map<UUID, PlayerStats> cache = new HashMap<>();
public StatsManager(Fussball plugin) {
this.plugin = plugin;
this.statsFile = new File(plugin.getDataFolder(), "stats.yml");
load();
}
// ── Persistenz ──────────────────────────────────────────────────────────
private void load() {
if (!statsFile.exists()) {
try { statsFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); }
}
statsConfig = YamlConfiguration.loadConfiguration(statsFile);
cache.clear();
if (statsConfig.contains("players")) {
for (String uuidStr : statsConfig.getConfigurationSection("players").getKeys(false)) {
try {
UUID uuid = UUID.fromString(uuidStr);
String path = "players." + uuidStr;
PlayerStats stats = new PlayerStats(
statsConfig.getString(path + ".name", "Unbekannt"),
statsConfig.getInt(path + ".goals", 0),
statsConfig.getInt(path + ".kicks", 0),
statsConfig.getInt(path + ".wins", 0),
statsConfig.getInt(path + ".losses", 0),
statsConfig.getInt(path + ".draws", 0),
statsConfig.getInt(path + ".games", 0),
statsConfig.getInt(path + ".assists", 0),
statsConfig.getInt(path + ".ownGoals", 0)
);
cache.put(uuid, stats);
} catch (IllegalArgumentException ignored) {}
}
}
plugin.getLogger().info("[Fussball] Statistiken geladen: " + cache.size() + " Spieler.");
}
public void save() {
statsConfig.set("players", null);
for (Map.Entry<UUID, PlayerStats> entry : cache.entrySet()) {
String path = "players." + entry.getKey();
PlayerStats s = entry.getValue();
statsConfig.set(path + ".name", s.name);
statsConfig.set(path + ".goals", s.goals);
statsConfig.set(path + ".kicks", s.kicks);
statsConfig.set(path + ".wins", s.wins);
statsConfig.set(path + ".losses", s.losses);
statsConfig.set(path + ".draws", s.draws);
statsConfig.set(path + ".games", s.games);
statsConfig.set(path + ".assists", s.assists);
statsConfig.set(path + ".ownGoals", s.ownGoals);
}
try { statsConfig.save(statsFile); } catch (IOException e) { e.printStackTrace(); }
}
// ── Datenzugriff ────────────────────────────────────────────────────────
public PlayerStats getStats(UUID uuid) {
return cache.computeIfAbsent(uuid, k -> new PlayerStats("Unbekannt", 0, 0, 0, 0, 0, 0, 0, 0));
}
public void addGoal(UUID uuid, String name) {
PlayerStats s = getStats(uuid);
s.name = name;
s.goals++;
save();
}
public void addOwnGoal(UUID uuid, String name) {
PlayerStats s = getStats(uuid);
s.name = name;
s.ownGoals++;
save();
}
public void addAssist(UUID uuid, String name) {
PlayerStats s = getStats(uuid);
s.name = name;
s.assists++;
save();
}
public void addGameResult(UUID uuid, String name, GameResult result) {
PlayerStats s = getStats(uuid);
s.name = name;
s.games++;
switch (result) {
case WIN -> s.wins++;
case LOSS -> s.losses++;
case DRAW -> s.draws++;
}
save();
}
public void flushKicks(Map<UUID, Integer> kicks, Map<UUID, String> names) {
for (Map.Entry<UUID, Integer> entry : kicks.entrySet()) {
PlayerStats s = getStats(entry.getKey());
if (names.containsKey(entry.getKey())) s.name = names.get(entry.getKey());
s.kicks += entry.getValue();
}
save();
}
public boolean resetStats(UUID uuid) {
boolean removed = cache.remove(uuid) != null;
if (!removed) {
return false;
}
save();
return true;
}
public int resetAllStats() {
int count = cache.size();
if (count == 0) {
return 0;
}
cache.clear();
save();
return count;
}
public UUID findPlayerUuidByName(String playerName) {
for (Map.Entry<UUID, PlayerStats> entry : cache.entrySet()) {
if (entry.getValue().name != null && entry.getValue().name.equalsIgnoreCase(playerName)) {
return entry.getKey();
}
}
return null;
}
/** Gibt die Top-N-Torschützen zurück, sortiert nach Toren */
public List<Map.Entry<UUID, PlayerStats>> getTopScorers(int limit) {
List<Map.Entry<UUID, PlayerStats>> list = new ArrayList<>(cache.entrySet());
list.sort((a, b) -> b.getValue().goals - a.getValue().goals);
return list.subList(0, Math.min(limit, list.size()));
}
/** Gibt die Top-N-Spieler nach Siegen zurück */
public List<Map.Entry<UUID, PlayerStats>> getTopWins(int limit) {
List<Map.Entry<UUID, PlayerStats>> list = new ArrayList<>(cache.entrySet());
list.sort((a, b) -> b.getValue().wins - a.getValue().wins);
return list.subList(0, Math.min(limit, list.size()));
}
// ── Innere Klassen ───────────────────────────────────────────────────────
public static class PlayerStats {
public String name;
public int goals, kicks, wins, losses, draws, games, assists, ownGoals;
public PlayerStats(String name, int goals, int kicks, int wins, int losses, int draws, int games, int assists, int ownGoals) {
this.name = name; this.goals = goals; this.kicks = kicks;
this.wins = wins; this.losses = losses; this.draws = draws; this.games = games;
this.assists = assists; this.ownGoals = ownGoals;
}
public double getWinRate() {
if (games == 0) return 0.0;
return (double) wins / games * 100.0;
}
}
public enum GameResult { WIN, LOSS, DRAW }
}