diff --git a/src/main/java/net/viper/status/modules/chat/ChatLogger.java b/src/main/java/net/viper/status/modules/chat/ChatLogger.java deleted file mode 100644 index 8d679e7..0000000 --- a/src/main/java/net/viper/status/modules/chat/ChatLogger.java +++ /dev/null @@ -1,152 +0,0 @@ -package net.viper.status.modules.chat; - -import java.io.*; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.logging.Logger; - -/** - * Protokolliert alle Chat-Nachrichten in tagesweise rotierende Logdateien. - * - * Verzeichnis: plugins/StatusAPI/chatlogs/chatlog_YYYY-MM-DD.log - * Format: [HH:mm:ss] [MSG-XXXXXX] [SERVER] [CHANNEL] Spieler: Nachricht - * - * Alte Logs werden beim Start und täglich automatisch bereinigt. - * Die Aufbewahrungsdauer ist in der chat.yml konfigurierbar (7 oder 14 Tage). - */ -public class ChatLogger { - - private final File logDir; - private final Logger logger; - private final int retentionDays; - private final AtomicInteger counter = new AtomicInteger(0); - - private static final SimpleDateFormat DATE_FMT = new SimpleDateFormat("yyyy-MM-dd"); - private static final SimpleDateFormat TIME_FMT = new SimpleDateFormat("HH:mm:ss"); - - public ChatLogger(File dataFolder, Logger logger, int retentionDays) { - this.logDir = new File(dataFolder, "chatlogs"); - this.logger = logger; - this.retentionDays = Math.max(1, retentionDays); - this.logDir.mkdirs(); - cleanup(); - } - - // ===== Nachrichten-ID ===== - - /** - * Generiert eine eindeutige Nachrichten-ID (z.B. MSG-A3F2B1). - * Kombiniert Zeitstempel + inkrementellen Zähler für Eindeutigkeit. - */ - public String generateMessageId() { - int seq = counter.incrementAndGet(); - long ts = System.currentTimeMillis(); - int hash = (int)(ts ^ (ts >>> 32)) ^ (seq * 0x9E3779B9); - return "MSG-" + String.format("%06X", hash & 0xFFFFFF); - } - - // ===== Logging ===== - - /** - * Loggt eine Nachricht und gibt die generierte Nachrichten-ID zurück. - * - * @param msgId Vorher generierte ID (aus generateMessageId()) - * @param server Servername des Absenders - * @param channel Kanal-ID - * @param player Spielername - * @param message Nachrichtentext (Rohtext, ohne Farbcodes) - */ - public void log(String msgId, String server, String channel, String player, String message) { - String date = DATE_FMT.format(new Date()); - String time = TIME_FMT.format(new Date()); - - // Minecraft-Farbcodes aus dem Log entfernen - String cleanMsg = stripColor(message); - - String line = "[" + time + "] [" + msgId + "] [" + server + "] [" + channel + "] " - + player + ": " + cleanMsg; - - File logFile = new File(logDir, "chatlog_" + date + ".log"); - try (BufferedWriter bw = new BufferedWriter( - new OutputStreamWriter(new FileOutputStream(logFile, true), "UTF-8"))) { - bw.write(line); - bw.newLine(); - } catch (IOException e) { - logger.warning("[ChatLogger] Fehler beim Schreiben: " + e.getMessage()); - } - } - - // ===== Cleanup ===== - - /** - * Löscht Log-Dateien, die älter als retentionDays Tage sind. - * Wird beim Start und kann manuell aufgerufen werden. - */ - public void cleanup() { - if (!logDir.exists()) return; - long cutoff = System.currentTimeMillis() - ((long) retentionDays * 24L * 60L * 60L * 1000L); - File[] files = logDir.listFiles((dir, name) -> - name.startsWith("chatlog_") && name.endsWith(".log")); - if (files == null) return; - for (File f : files) { - if (f.lastModified() < cutoff) { - if (f.delete()) { - logger.info("[ChatLogger] Altes Log gelöscht: " + f.getName()); - } - } - } - } - - // ===== Hilfsmethoden ===== - - /** Entfernt §-Farbcodes aus dem Text. */ - private static String stripColor(String input) { - if (input == null) return ""; - return input.replaceAll("(?i)§[0-9A-FK-OR]", "") - .replaceAll("(?i)&[0-9A-FK-OR]", ""); - } - - public int getRetentionDays() { return retentionDays; } - public File getLogDir() { return logDir; } - - /** - * Liest die letzten `maxLines` Zeilen aus dem heutigen Chatlog. - * Wenn ein Spielername angegeben ist, werden nur seine Zeilen zurückgegeben. - * - * @param playerFilter Spielername (case-insensitiv) oder null für alle - * @param maxLines Maximale Anzahl zurückgegebener Zeilen - * @return Liste der Logzeilen (älteste zuerst) - */ - public List readLastLines(String playerFilter, int maxLines) { - String date = DATE_FMT.format(new Date()); - File logFile = new File(logDir, "chatlog_" + date + ".log"); - if (!logFile.exists()) return Collections.emptyList(); - - List allLines = new ArrayList<>(); - try (BufferedReader br = new BufferedReader( - new InputStreamReader(new FileInputStream(logFile), "UTF-8"))) { - String line; - while ((line = br.readLine()) != null) { - if (line.trim().isEmpty()) continue; - // Spieler-Filter: Format ist [...] [...] [...] [...] Spieler: Nachricht - if (playerFilter != null) { - // Spielername steht nach dem 4. [...]-Block - int lastBracket = line.indexOf("] ", line.lastIndexOf("[")); - if (lastBracket >= 0) { - String rest = line.substring(lastBracket + 2); - String name = rest.contains(":") ? rest.substring(0, rest.indexOf(":")).trim() : ""; - if (!name.equalsIgnoreCase(playerFilter)) continue; - } - } - allLines.add(line); - } - } catch (IOException e) { - logger.warning("[ChatLogger] Fehler beim Lesen: " + e.getMessage()); - } - - // Letzte maxLines zurückgeben - if (allLines.size() <= maxLines) return allLines; - return allLines.subList(allLines.size() - maxLines, allLines.size()); - } -} \ No newline at end of file