Update from Git Manager GUI

This commit is contained in:
2026-02-21 18:41:15 +01:00
parent 7ede377c07
commit 301c0f1ce9
2 changed files with 154 additions and 7 deletions

View File

@@ -265,6 +265,20 @@ public class DatabaseManager {
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
""";
// Persistente Ersteller-Statistik zählt alle jemals erstellten Tickets pro Spieler.
// Überlebt das Löschen und Archivieren von Tickets vollständig.
// Wird bei jedem createTicket() inkrementiert (INSERT … ON DUPLICATE KEY UPDATE).
String creatorStatsSql = """
CREATE TABLE IF NOT EXISTS ticket_creator_stats (
creator_uuid VARCHAR(36) NOT NULL PRIMARY KEY,
creator_name VARCHAR(16) NOT NULL,
ticket_count INT NOT NULL DEFAULT 1,
last_updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_ticket_count (ticket_count)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
""";
try (Connection conn = getConnection(); Statement stmt = conn.createStatement()) {
stmt.execute(ticketsSql);
stmt.execute(commentsSql);
@@ -272,6 +286,7 @@ public class DatabaseManager {
stmt.execute(notifSql);
stmt.execute(statsSql);
stmt.execute(pendingTeleportSql);
stmt.execute(creatorStatsSql);
} catch (SQLException e) {
plugin.getLogger().log(Level.SEVERE, "Fehler beim Erstellen der Tabellen: " + e.getMessage(), e);
}
@@ -365,7 +380,11 @@ public class DatabaseManager {
ps.setString(12, ticket.getServerName()); // BungeeCord
ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
if (rs.next()) return rs.getInt(1);
if (rs.next()) {
int newId = rs.getInt(1);
incrementCreatorStats(ticket.getCreatorUUID(), ticket.getCreatorName());
return newId;
}
} catch (SQLException e) {
plugin.getLogger().log(Level.SEVERE, "Fehler beim Erstellen des Tickets: " + e.getMessage(), e);
}
@@ -375,11 +394,87 @@ public class DatabaseManager {
ticket.setId(id);
dataConfig.set("lastId", id);
dataConfig.set("tickets." + id, ticket);
// Datei-Modus: Zähler in dataConfig pflegen
String statsKey = "creator-stats." + ticket.getCreatorUUID().toString();
int current = dataConfig.getInt(statsKey + ".count", 0);
dataConfig.set(statsKey + ".count", current + 1);
dataConfig.set(statsKey + ".name", ticket.getCreatorName());
saveDataConfig();
return id;
}
}
// ─────────────────────────── Creator-Leaderboard ────────────────────────
/**
* Erhöht den Ticket-Zähler eines Erstellers um 1 (MySQL-Modus).
* Wird nach jedem erfolgreichen createTicket() aufgerufen.
* Die Tabelle ist unabhängig von tickets/archive Zahlen gehen nie verloren.
*/
private void incrementCreatorStats(UUID creatorUUID, String creatorName) {
if (!useMySQL) return;
String sql = """
INSERT INTO ticket_creator_stats (creator_uuid, creator_name, ticket_count)
VALUES (?, ?, 1)
ON DUPLICATE KEY UPDATE
ticket_count = ticket_count + 1,
creator_name = VALUES(creator_name)
""";
try (Connection conn = getConnection(); PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, creatorUUID.toString());
ps.setString(2, creatorName);
ps.executeUpdate();
} catch (SQLException e) {
plugin.getLogger().log(Level.SEVERE, "Fehler beim Aktualisieren der Creator-Stats: " + e.getMessage(), e);
}
}
/**
* Gibt die Top-{limit} Ticket-Ersteller zurück.
* Jeder Eintrag: [rank, playerName, ticketCount] (alle als String)
* Funktioniert in MySQL- und Datei-Modus.
*/
public List<String[]> getTopCreators(int limit) {
List<String[]> result = new ArrayList<>();
if (useMySQL) {
String sql = """
SELECT creator_name, ticket_count
FROM ticket_creator_stats
ORDER BY ticket_count DESC
LIMIT ?
""";
try (Connection conn = getConnection(); PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, limit);
ResultSet rs = ps.executeQuery();
int rank = 1;
while (rs.next()) {
result.add(new String[]{
String.valueOf(rank++),
rs.getString("creator_name"),
String.valueOf(rs.getInt("ticket_count"))
});
}
} catch (SQLException e) {
plugin.getLogger().log(Level.SEVERE, "Fehler beim Abrufen der Top-Creator: " + e.getMessage(), e);
}
} else if (dataConfig != null && dataConfig.contains("creator-stats")) {
// Datei-Modus: alle Einträge einlesen, nach count absteigend sortieren, begrenzen
record Entry(String name, int count) {}
List<Entry> entries = new ArrayList<>();
for (String uuid : dataConfig.getConfigurationSection("creator-stats").getKeys(false)) {
String name = dataConfig.getString("creator-stats." + uuid + ".name", uuid);
int count = dataConfig.getInt("creator-stats." + uuid + ".count", 0);
entries.add(new Entry(name, count));
}
entries.sort((a, b) -> Integer.compare(b.count(), a.count()));
int rank = 1;
for (Entry e : entries.subList(0, Math.min(limit, entries.size()))) {
result.add(new String[]{String.valueOf(rank++), e.name(), String.valueOf(e.count())});
}
}
return result;
}
// ── BUG FIX #1 ──────────────────────────────────────────────────────────
// Vorher: WHERE id = ? AND status = 'OPEN'
// Problem: Ein FORWARDED-Ticket konnte nicht geclaimed werden das UPDATE