Delete _trash/2026-05-07T19-39-23-130Z/src/main/java/net/viper/status/modules/chat/ChatLogger.java via Git Manager GUI
This commit is contained in:
@@ -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<String> 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<String> 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());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user