Files
TicketSystem/src/main/java/de/ticketsystem/commands/TicketCommand.java
2026-02-21 00:55:27 +01:00

696 lines
39 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package de.ticketsystem.commands;
import de.ticketsystem.TicketPlugin;
import de.ticketsystem.model.Ticket;
import de.ticketsystem.manager.CategoryManager;
import de.ticketsystem.model.ConfigCategory;
import de.ticketsystem.model.TicketComment;
import de.ticketsystem.model.TicketPriority;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
public class TicketCommand implements CommandExecutor, TabCompleter {
private final TicketPlugin plugin;
public TicketCommand(TicketPlugin plugin) { this.plugin = plugin; }
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player player)) {
sender.sendMessage("Dieser Befehl kann nur von Spielern ausgeführt werden.");
return true;
}
if (args.length == 0) { plugin.getTicketManager().sendHelpMessage(player); return true; }
switch (args[0].toLowerCase()) {
case "create" -> handleCreate(player, args);
case "list" -> handleList(player);
case "claim" -> handleClaim(player, args);
case "close" -> handleClose(player, args);
case "forward" -> handleForward(player, args);
case "reload" -> handleReload(player);
case "migrate" -> handleMigrate(player, args);
case "export" -> handleExport(player, args);
case "import" -> handleImport(player, args);
case "stats" -> handleStats(player);
case "archive" -> handleArchive(player);
case "comment" -> handleComment(player, args);
case "blacklist" -> handleBlacklist(player, args);
case "rate" -> handleRate(player, args);
case "setpriority" -> handleSetPriority(player, args);
default -> plugin.getTicketManager().sendHelpMessage(player);
}
return true;
}
// ─────────────────────────── /ticket create ────────────────────────────
private void handleCreate(Player player, String[] args) {
if (!player.hasPermission("ticket.create")) {
player.sendMessage(plugin.formatMessage("messages.no-permission")); return;
}
// Blacklist-Check
if (plugin.getDatabaseManager().isBlacklisted(player.getUniqueId())) {
player.sendMessage(plugin.color("&cDu wurdest vom Ticket-System gesperrt und kannst keine Tickets erstellen."));
return;
}
if (args.length < 2) {
player.sendMessage(plugin.color("&cBenutzung: /ticket create [Kategorie] [Priorität] <Beschreibung>"));
if (plugin.getConfig().getBoolean("categories-enabled", true)) {
player.sendMessage(plugin.color("&7Kategorien: &ebug&7, &efrage&7, &ebeschwerde&7, &esonstiges&7, &eallgemein"));
}
if (plugin.getConfig().getBoolean("priorities-enabled", true)) {
player.sendMessage(plugin.color("&7Prioritäten: &alow&7, &enormal&7, &6high&7, &curgent"));
}
return;
}
if (plugin.getTicketManager().hasCooldown(player.getUniqueId())) {
long remaining = plugin.getTicketManager().getRemainingCooldown(player.getUniqueId());
player.sendMessage(plugin.formatMessage("messages.cooldown").replace("{seconds}", String.valueOf(remaining)));
return;
}
if (plugin.getTicketManager().hasReachedTicketLimit(player.getUniqueId())) {
int max = plugin.getConfig().getInt("max-open-tickets-per-player", 2);
player.sendMessage(plugin.color("&cDu hast bereits &e" + max + " &coffene Ticket(s). Bitte warte, bis dein Ticket bearbeitet wurde."));
return;
}
// Kategorie und Priorität optional parsen
CategoryManager cm = plugin.getCategoryManager();
ConfigCategory category = cm.getDefault();
TicketPriority priority = TicketPriority.NORMAL;
int messageStartIndex = 1;
boolean categoriesOn = plugin.getConfig().getBoolean("categories-enabled", true);
boolean prioritiesOn = plugin.getConfig().getBoolean("priorities-enabled", true);
if (args.length >= 3) {
// args[1]: erst als Kategorie prüfen, dann als Priorität
if (categoriesOn) {
ConfigCategory parsedCat = cm.resolve(args[1]);
if (parsedCat != null) {
category = parsedCat;
messageStartIndex = 2;
// args[2]: Priorität prüfen (nur wenn danach noch Text kommt)
if (prioritiesOn && args.length >= 4) {
TicketPriority parsedPrio = parsePriority(args[2]);
if (parsedPrio != null) {
priority = parsedPrio;
messageStartIndex = 3;
}
}
} else {
// Keine Kategorie erkannt → args[1] als Priorität prüfen
if (prioritiesOn) {
TicketPriority parsedPrio = parsePriority(args[1]);
if (parsedPrio != null) {
priority = parsedPrio;
messageStartIndex = 2;
}
}
}
} else if (prioritiesOn) {
// Kategorien aus → args[1] direkt als Priorität prüfen
TicketPriority parsedPrio = parsePriority(args[1]);
if (parsedPrio != null) {
priority = parsedPrio;
messageStartIndex = 2;
}
}
} else if (args.length == 2) {
// Nur ein Argument: könnte Kategorie oder Priorität sein, aber kein Text danach
// → einfach als Beschreibung behandeln, nichts parsen
}
String message = String.join(" ", Arrays.copyOfRange(args, messageStartIndex, args.length));
int maxLen = plugin.getConfig().getInt("max-description-length", 100);
if (message.isEmpty()) {
player.sendMessage(plugin.color("&cBitte gib eine Beschreibung für dein Ticket an."));
return;
}
if (message.length() > maxLen) {
player.sendMessage(plugin.color("&cDeine Beschreibung ist zu lang! Maximal " + maxLen + " Zeichen."));
return;
}
final ConfigCategory finalCategory = category;
final TicketPriority finalPriority = priority;
Ticket ticket = new Ticket(player.getUniqueId(), player.getName(), message, player.getLocation());
ticket.setCategoryKey(finalCategory.getKey());
ticket.setPriority(finalPriority);
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
int id = plugin.getDatabaseManager().createTicket(ticket);
if (id == -1) { player.sendMessage(plugin.color("&cFehler beim Erstellen des Tickets!")); return; }
ticket.setId(id);
plugin.getTicketManager().setCooldown(player.getUniqueId());
Bukkit.getScheduler().runTask(plugin, () -> {
String catInfo = plugin.getConfig().getBoolean("categories-enabled", true)
? " §7[" + finalCategory.getColored() + "§7]" : "";
String prioInfo = plugin.getConfig().getBoolean("priorities-enabled", true)
? " §7[" + finalPriority.getColored() + "§7]" : "";
player.sendMessage(plugin.formatMessage("messages.ticket-created").replace("{id}", String.valueOf(id)) + catInfo + prioInfo);
plugin.getTicketManager().notifyTeam(ticket);
});
});
}
// ─────────────────────────── /ticket list ──────────────────────────────
private void handleList(Player player) {
if (player.hasPermission("ticket.support") || player.hasPermission("ticket.admin")) {
Bukkit.getScheduler().runTaskAsynchronously(plugin, () ->
Bukkit.getScheduler().runTask(plugin, () -> plugin.getTicketGUI().openGUI(player)));
} else {
Bukkit.getScheduler().runTaskAsynchronously(plugin, () ->
Bukkit.getScheduler().runTask(plugin, () -> plugin.getTicketGUI().openPlayerGUI(player)));
}
}
// ─────────────────────────── /ticket claim ─────────────────────────────
private void handleClaim(Player player, String[] args) {
if (!player.hasPermission("ticket.support") && !player.hasPermission("ticket.admin")) {
player.sendMessage(plugin.formatMessage("messages.no-permission")); return;
}
if (args.length < 2) { player.sendMessage(plugin.color("&cBenutzung: /ticket claim <ID>")); return; }
int id;
try { id = Integer.parseInt(args[1]); }
catch (NumberFormatException e) { player.sendMessage(plugin.color("&cUngültige ID!")); return; }
final int ticketId = id;
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
boolean success = plugin.getDatabaseManager().claimTicket(ticketId, player.getUniqueId(), player.getName());
Bukkit.getScheduler().runTask(plugin, () -> {
if (!success) { player.sendMessage(plugin.formatMessage("messages.already-claimed")); return; }
Ticket ticket = plugin.getDatabaseManager().getTicketById(ticketId);
if (ticket == null) return;
player.sendMessage(plugin.formatMessage("messages.ticket-claimed")
.replace("{id}", String.valueOf(ticketId))
.replace("{player}", ticket.getCreatorName()));
plugin.getTicketManager().notifyCreatorClaimed(ticket);
if (ticket.getLocation() != null) player.teleport(ticket.getLocation());
});
});
}
// ─────────────────────────── /ticket close ─────────────────────────────
private void handleClose(Player player, String[] args) {
if (!player.hasPermission("ticket.support") && !player.hasPermission("ticket.admin")) {
player.sendMessage(plugin.formatMessage("messages.no-permission")); return;
}
if (args.length < 2) { player.sendMessage(plugin.color("&cBenutzung: /ticket close <ID> [Kommentar]")); return; }
int id;
try { id = Integer.parseInt(args[1]); }
catch (NumberFormatException e) { player.sendMessage(plugin.color("&cUngültige ID!")); return; }
String closeComment = args.length > 2 ? String.join(" ", Arrays.copyOfRange(args, 2, args.length)) : "";
final int ticketId = id;
final String comment = closeComment;
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
boolean success = plugin.getDatabaseManager().closeTicket(ticketId, comment);
if (success) {
Ticket ticket = plugin.getDatabaseManager().getTicketById(ticketId);
Bukkit.getScheduler().runTask(plugin, () -> {
player.sendMessage(plugin.formatMessage("messages.ticket-closed").replace("{id}", String.valueOf(ticketId)));
if (ticket != null) {
ticket.setCloseComment(comment);
plugin.getTicketManager().notifyCreatorClosed(ticket, player.getName());
}
});
} else {
Bukkit.getScheduler().runTask(plugin, () -> player.sendMessage(plugin.formatMessage("messages.ticket-not-found")));
}
});
}
// ─────────────────────────── /ticket forward ───────────────────────────
private void handleForward(Player player, String[] args) {
if (!player.hasPermission("ticket.admin")) {
player.sendMessage(plugin.formatMessage("messages.no-permission")); return;
}
if (args.length < 3) { player.sendMessage(plugin.color("&cBenutzung: /ticket forward <ID> <Spieler>")); return; }
int id;
try { id = Integer.parseInt(args[1]); }
catch (NumberFormatException e) { player.sendMessage(plugin.color("&cUngültige ID!")); return; }
Player target = Bukkit.getPlayer(args[2]);
if (target == null) { player.sendMessage(plugin.color("&cSpieler nicht gefunden!")); return; }
final int ticketId = id;
final String fromName = player.getName();
final Player t = target;
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
boolean success = plugin.getDatabaseManager().forwardTicket(ticketId, t.getUniqueId(), t.getName());
Bukkit.getScheduler().runTask(plugin, () -> {
if (!success) { player.sendMessage(plugin.formatMessage("messages.ticket-not-found")); return; }
Ticket ticket = plugin.getDatabaseManager().getTicketById(ticketId);
if (ticket == null) return;
player.sendMessage(plugin.color("&aTicket &e#" + ticketId + " &awurde an &e" + t.getName() + " &aweitergeleitet."));
plugin.getTicketManager().notifyForwardedTo(ticket, fromName);
plugin.getTicketManager().notifyCreatorForwarded(ticket);
});
});
}
// ─────────────────────────── /ticket comment ───────────────────────────
private void handleComment(Player player, String[] args) {
if (!player.hasPermission("ticket.create") && !player.hasPermission("ticket.support") && !player.hasPermission("ticket.admin")) {
player.sendMessage(plugin.formatMessage("messages.no-permission")); return;
}
if (args.length < 3) { player.sendMessage(plugin.color("&cBenutzung: /ticket comment <ID> <Nachricht>")); return; }
int id;
try { id = Integer.parseInt(args[1]); }
catch (NumberFormatException e) { player.sendMessage(plugin.color("&cUngültige ID!")); return; }
String msg = String.join(" ", Arrays.copyOfRange(args, 2, args.length));
if (msg.length() > 500) { player.sendMessage(plugin.color("&cNachricht zu lang! Maximal 500 Zeichen.")); return; }
final int ticketId = id;
final String message = msg;
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
Ticket ticket = plugin.getDatabaseManager().getTicketById(ticketId);
if (ticket == null) {
Bukkit.getScheduler().runTask(plugin, () -> player.sendMessage(plugin.formatMessage("messages.ticket-not-found")));
return;
}
// Spieler darf nur auf eigene Tickets kommentieren (Supporter/Admin: alle)
boolean isOwner = ticket.getCreatorUUID().equals(player.getUniqueId());
boolean isStaff = player.hasPermission("ticket.support") || player.hasPermission("ticket.admin");
if (!isOwner && !isStaff) {
Bukkit.getScheduler().runTask(plugin, () -> player.sendMessage(plugin.color("&cDu kannst nur deine eigenen Tickets kommentieren.")));
return;
}
TicketComment comment = new TicketComment(ticketId, player.getUniqueId(), player.getName(), message);
boolean success = plugin.getDatabaseManager().addComment(comment);
Bukkit.getScheduler().runTask(plugin, () -> {
if (success) {
player.sendMessage(plugin.color("&aDein Kommentar zu Ticket &e#" + ticketId + " &awurde gespeichert."));
// Supporter/Admin und Ticket-Ersteller benachrichtigen
notifyCommentReceivers(player, ticket, message);
} else {
player.sendMessage(plugin.color("&cFehler beim Speichern des Kommentars."));
}
});
});
}
private void notifyCommentReceivers(Player author, Ticket ticket, String message) {
String onlineMsg = plugin.color("&e[Ticket #" + ticket.getId() + "] &f" + author.getName() + " &7hat kommentiert: &f" + message);
String offlineMsg = "&e[Ticket #" + ticket.getId() + "] &f" + author.getName() + " &7hat kommentiert (während du offline warst): &f" + message;
// Ticket-Ersteller benachrichtigen (wenn nicht der Autor selbst)
if (!ticket.getCreatorUUID().equals(author.getUniqueId())) {
Player creator = Bukkit.getPlayer(ticket.getCreatorUUID());
if (creator != null && creator.isOnline()) {
creator.sendMessage(onlineMsg);
} else {
// Offline → für nächsten Login speichern
Bukkit.getScheduler().runTaskAsynchronously(plugin, () ->
plugin.getDatabaseManager().addPendingNotification(ticket.getCreatorUUID(), offlineMsg));
}
}
// Supporter/Admin benachrichtigen (wenn Autor kein Supporter ist)
if (!author.hasPermission("ticket.support") && !author.hasPermission("ticket.admin")) {
// Claimer des Tickets bevorzugt benachrichtigen
UUID claimerUUID = ticket.getClaimerUUID();
if (claimerUUID != null && !claimerUUID.equals(author.getUniqueId())) {
Player claimer = Bukkit.getPlayer(claimerUUID);
if (claimer != null && claimer.isOnline()) {
claimer.sendMessage(onlineMsg);
} else {
String claimerOffline = "&e[Ticket #" + ticket.getId() + "] &f" + author.getName() + " &7hat auf dein bearbeitetes Ticket kommentiert (offline): &f" + message;
Bukkit.getScheduler().runTaskAsynchronously(plugin, () ->
plugin.getDatabaseManager().addPendingNotification(claimerUUID, claimerOffline));
}
}
// Alle anderen Online-Supporter zusätzlich informieren
for (Player p : Bukkit.getOnlinePlayers()) {
if (p.getUniqueId().equals(author.getUniqueId())) continue;
if (claimerUUID != null && p.getUniqueId().equals(claimerUUID)) continue; // schon oben
if (p.hasPermission("ticket.support") || p.hasPermission("ticket.admin")) {
p.sendMessage(onlineMsg);
}
}
}
}
// ─────────────────────────── /ticket rate ──────────────────────────────
private void handleRate(Player player, String[] args) {
if (!plugin.getConfig().getBoolean("rating-enabled", true)) {
player.sendMessage(plugin.color("&cBewertungen sind deaktiviert.")); return;
}
if (args.length < 3) { player.sendMessage(plugin.color("&cBenutzung: /ticket rate <ID> <good|bad>")); return; }
int id;
try { id = Integer.parseInt(args[1]); }
catch (NumberFormatException e) { player.sendMessage(plugin.color("&cUngültige ID!")); return; }
String ratingArg = args[2].toLowerCase();
String rating;
if (ratingArg.equals("good") || ratingArg.equals("gut") || ratingArg.equals("thumbsup")) {
rating = "THUMBS_UP";
} else if (ratingArg.equals("bad") || ratingArg.equals("schlecht") || ratingArg.equals("thumbsdown")) {
rating = "THUMBS_DOWN";
} else {
player.sendMessage(plugin.color("&cUngültige Bewertung! Benutze &egood &coder &ebad&c."));
return;
}
final int ticketId = id;
final String finalRating = rating;
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
Ticket ticket = plugin.getDatabaseManager().getTicketById(ticketId);
if (ticket == null) {
Bukkit.getScheduler().runTask(plugin, () -> player.sendMessage(plugin.formatMessage("messages.ticket-not-found")));
return;
}
if (!ticket.getCreatorUUID().equals(player.getUniqueId())) {
Bukkit.getScheduler().runTask(plugin, () -> player.sendMessage(plugin.color("&cDu kannst nur deine eigenen Tickets bewerten.")));
return;
}
if (ticket.hasRating()) {
Bukkit.getScheduler().runTask(plugin, () -> player.sendMessage(plugin.color("&cDu hast dieses Ticket bereits bewertet.")));
return;
}
boolean success = plugin.getDatabaseManager().rateTicket(ticketId, finalRating);
Bukkit.getScheduler().runTask(plugin, () -> {
if (success) {
String emoji = "THUMBS_UP".equals(finalRating) ? "§a👍 Positiv" : "§c👎 Negativ";
player.sendMessage(plugin.color("&aDanke für deine Bewertung! (" + emoji + "§a)"));
} else {
player.sendMessage(plugin.color("&cBewertung konnte nicht gespeichert werden. Ticket geschlossen?"));
}
});
});
}
// ─────────────────────────── /ticket blacklist ─────────────────────────
private void handleBlacklist(Player player, String[] args) {
if (!player.hasPermission("ticket.admin")) {
player.sendMessage(plugin.formatMessage("messages.no-permission")); return;
}
if (args.length < 2) {
player.sendMessage(plugin.color("&cBenutzung: /ticket blacklist <add|remove|list> [Spieler] [Grund]"));
return;
}
switch (args[1].toLowerCase()) {
case "add" -> {
if (args.length < 3) { player.sendMessage(plugin.color("&cBenutzung: /ticket blacklist add <Spieler> [Grund]")); return; }
String targetName = args[2];
String reason = args.length > 3 ? String.join(" ", Arrays.copyOfRange(args, 3, args.length)) : "Missbrauch";
@SuppressWarnings("deprecation")
OfflinePlayer target = Bukkit.getOfflinePlayer(targetName);
if (target.getUniqueId() == null) { player.sendMessage(plugin.color("&cSpieler nicht gefunden.")); return; }
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
boolean success = plugin.getDatabaseManager().addBlacklist(
target.getUniqueId(), targetName, reason, player.getName());
Bukkit.getScheduler().runTask(plugin, () -> {
if (success)
player.sendMessage(plugin.color("&a" + targetName + " &awurde zur Ticket-Blacklist hinzugefügt. &7Grund: &e" + reason));
else
player.sendMessage(plugin.color("&cSpieler ist bereits auf der Blacklist."));
});
});
}
case "remove" -> {
if (args.length < 3) { player.sendMessage(plugin.color("&cBenutzung: /ticket blacklist remove <Spieler>")); return; }
String targetName = args[2];
@SuppressWarnings("deprecation")
OfflinePlayer target = Bukkit.getOfflinePlayer(targetName);
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
boolean success = plugin.getDatabaseManager().removeBlacklist(target.getUniqueId());
Bukkit.getScheduler().runTask(plugin, () -> {
if (success) player.sendMessage(plugin.color("&a" + targetName + " &awurde von der Blacklist entfernt."));
else player.sendMessage(plugin.color("&cSpieler war nicht auf der Blacklist."));
});
});
}
case "list" -> {
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
var list = plugin.getDatabaseManager().getBlacklist();
Bukkit.getScheduler().runTask(plugin, () -> {
player.sendMessage(plugin.color("&8&m "));
player.sendMessage(plugin.color("&6Ticket-Blacklist &7(" + list.size() + " Einträge)"));
player.sendMessage(plugin.color("&8&m "));
if (list.isEmpty()) {
player.sendMessage(plugin.color("&7Keine gesperrten Spieler."));
} else {
for (String[] entry : list) {
// {uuid, name, reason, bannedBy, bannedAt}
player.sendMessage(plugin.color("&e" + entry[1] + " &7 &f" + entry[2]
+ " &7(gesperrt von &e" + entry[3] + "&7)"));
}
}
player.sendMessage(plugin.color("&8&m "));
});
});
}
default -> player.sendMessage(plugin.color("&cBenutzung: /ticket blacklist <add|remove|list> [Spieler] [Grund]"));
}
}
// ─────────────────────────── /ticket reload ────────────────────────────
private void handleReload(Player player) {
if (!player.hasPermission("ticket.admin")) { player.sendMessage(plugin.formatMessage("messages.no-permission")); return; }
plugin.reloadConfig();
plugin.getCategoryManager().reload();
player.sendMessage(plugin.color("&aKonfiguration wurde neu geladen. &7(inkl. Kategorien)"));
}
// ─────────────────────────── /ticket archive ───────────────────────────
private void handleArchive(Player player) {
if (!player.hasPermission("ticket.admin")) { player.sendMessage(plugin.formatMessage("messages.no-permission")); return; }
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
int count = plugin.getDatabaseManager().archiveClosedTickets();
Bukkit.getScheduler().runTask(plugin, () -> {
if (count > 0) player.sendMessage(plugin.formatMessage("messages.archive-success").replace("{count}", String.valueOf(count)));
else player.sendMessage(plugin.formatMessage("messages.archive-fail"));
});
});
}
// ─────────────────────────── /ticket stats ─────────────────────────────
private void handleStats(Player player) {
if (!player.hasPermission("ticket.admin")) { player.sendMessage(plugin.formatMessage("messages.no-permission")); return; }
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
var stats = plugin.getDatabaseManager().getTicketStats();
Bukkit.getScheduler().runTask(plugin, () -> {
player.sendMessage(plugin.color("&8&m "));
player.sendMessage(plugin.color("&6Ticket Statistik"));
player.sendMessage(plugin.color("&8&m "));
player.sendMessage(plugin.color("&eGesamt: &a" + stats.total));
player.sendMessage(plugin.color("&eOffen: &a" + stats.open));
player.sendMessage(plugin.color("&eGeschlossen: &a" + stats.closed));
player.sendMessage(plugin.color("&eWeitergeleitet: &a" + stats.forwarded));
if (plugin.getConfig().getBoolean("rating-enabled", true)) {
player.sendMessage(plugin.color("&8&m "));
player.sendMessage(plugin.color("&6Support-Bewertungen"));
player.sendMessage(plugin.color("&a👍 Positiv: &f" + stats.thumbsUp
+ " &c👎 Negativ: &f" + stats.thumbsDown));
int total = stats.thumbsUp + stats.thumbsDown;
if (total > 0) {
int percent = (int) Math.round(stats.thumbsUp * 100.0 / total);
player.sendMessage(plugin.color("&7Zufriedenheit: &e" + percent + "%"));
}
}
player.sendMessage(plugin.color("&8&m "));
player.sendMessage(plugin.color("&6Top Ersteller:"));
stats.byPlayer.entrySet().stream()
.sorted((a, b) -> b.getValue() - a.getValue())
.limit(5)
.forEach(e -> player.sendMessage(plugin.color("&e " + e.getKey() + ": &a" + e.getValue())));
player.sendMessage(plugin.color("&8&m "));
});
});
}
// ─────────────────────────── /ticket migrate ───────────────────────────
private void handleMigrate(Player player, String[] args) {
if (!player.hasPermission("ticket.admin")) { player.sendMessage(plugin.formatMessage("messages.no-permission")); return; }
if (args.length < 2) { player.sendMessage(plugin.color("&cBenutzung: /ticket migrate <tomysql|tofile>")); return; }
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
int migrated = 0;
String mode = args[1].toLowerCase();
if (mode.equals("tomysql")) migrated = plugin.getDatabaseManager().migrateToMySQL();
else if (mode.equals("tofile")) migrated = plugin.getDatabaseManager().migrateToFile();
else { player.sendMessage(plugin.formatMessage("messages.unknown-mode")); return; }
int f = migrated;
Bukkit.getScheduler().runTask(plugin, () -> {
if (f > 0) player.sendMessage(plugin.formatMessage("messages.migration-success").replace("{count}", String.valueOf(f)));
else player.sendMessage(plugin.formatMessage("messages.migration-fail"));
});
});
}
// ─────────────────────────── /ticket export ────────────────────────────
private void handleExport(Player player, String[] args) {
if (!player.hasPermission("ticket.admin")) { player.sendMessage(plugin.formatMessage("messages.no-permission")); return; }
if (args.length < 2) { player.sendMessage(plugin.color("&cBenutzung: /ticket export <Dateiname>")); return; }
String filename = args[1];
File exportFile = new File(plugin.getDataFolder(), filename);
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
int count = plugin.getDatabaseManager().exportTickets(exportFile);
Bukkit.getScheduler().runTask(plugin, () -> {
if (count > 0) player.sendMessage(plugin.formatMessage("messages.export-success").replace("{count}", String.valueOf(count)).replace("{file}", filename));
else player.sendMessage(plugin.formatMessage("messages.export-fail"));
});
});
}
// ─────────────────────────── /ticket import ────────────────────────────
private void handleImport(Player player, String[] args) {
if (!player.hasPermission("ticket.admin")) { player.sendMessage(plugin.formatMessage("messages.no-permission")); return; }
if (args.length < 2) { player.sendMessage(plugin.color("&cBenutzung: /ticket import <Dateiname>")); return; }
String filename = args[1];
File importFile = new File(plugin.getDataFolder(), filename);
if (!importFile.exists()) { player.sendMessage(plugin.formatMessage("messages.file-not-found").replace("{file}", filename)); return; }
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
int count = plugin.getDatabaseManager().importTickets(importFile);
Bukkit.getScheduler().runTask(plugin, () -> {
if (count > 0) player.sendMessage(plugin.formatMessage("messages.import-success").replace("{count}", String.valueOf(count)));
else player.sendMessage(plugin.formatMessage("messages.import-fail"));
});
});
}
// ─────────────────────────── /ticket setpriority ──────────────────────
private void handleSetPriority(Player player, String[] args) {
if (!player.hasPermission("ticket.support") && !player.hasPermission("ticket.admin")) {
player.sendMessage(plugin.formatMessage("messages.no-permission")); return;
}
if (!plugin.getConfig().getBoolean("priorities-enabled", true)) {
player.sendMessage(plugin.color("&cDas Prioritäten-System ist deaktiviert.")); return;
}
if (args.length < 3) {
player.sendMessage(plugin.color("&cBenutzung: /ticket setpriority <ID> <low|normal|high|urgent>")); return;
}
int ticketId;
try { ticketId = Integer.parseInt(args[1]); }
catch (NumberFormatException e) {
player.sendMessage(plugin.color("&cUngültige Ticket-ID: &e" + args[1])); return;
}
TicketPriority priority = parsePriority(args[2]);
if (priority == null) {
player.sendMessage(plugin.color("&cUngültige Priorität! Gültig: &alow&7, &enormal&7, &6high&7, &curgent")); return;
}
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
boolean success = plugin.getDatabaseManager().setTicketPriority(ticketId, priority);
Bukkit.getScheduler().runTask(plugin, () -> {
if (success) {
player.sendMessage(plugin.color("&aPriorität von Ticket &e#" + ticketId
+ " &awurde auf " + priority.getColored() + " &agesetzt."));
} else {
player.sendMessage(plugin.color("&cTicket &e#" + ticketId + " &cwurde nicht gefunden."));
}
});
});
}
/** Parst Benutzer-Eingaben wie "high", "hoch", "urgent", "dringend" etc. zu TicketPriority.
* Gibt null zurück wenn keine Übereinstimmung. */
private TicketPriority parsePriority(String input) {
if (input == null) return null;
return switch (input.toLowerCase()) {
case "low", "niedrig" -> TicketPriority.LOW;
case "normal" -> TicketPriority.NORMAL;
case "high", "hoch" -> TicketPriority.HIGH;
case "urgent", "dringend" -> TicketPriority.URGENT;
default -> null;
};
}
// ─────────────────────────── Tab-Completion ────────────────────────────
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String label, String[] args) {
List<String> completions = new ArrayList<>();
if (!(sender instanceof Player player)) return completions;
if (args.length == 1) {
List<String> subs = new ArrayList<>(List.of("create", "list", "comment"));
if (player.hasPermission("ticket.support") || player.hasPermission("ticket.admin"))
subs.addAll(List.of("claim", "close"));
if (plugin.getConfig().getBoolean("rating-enabled", true)) subs.add("rate");
if (player.hasPermission("ticket.admin"))
subs.addAll(List.of("forward", "reload", "stats", "archive", "migrate", "export", "import", "blacklist"));
if ((player.hasPermission("ticket.support") || player.hasPermission("ticket.admin"))
&& plugin.getConfig().getBoolean("priorities-enabled", true))
subs.add("setpriority");
for (String s : subs) if (s.startsWith(args[0].toLowerCase())) completions.add(s);
} else if (args.length == 2 && args[0].equalsIgnoreCase("create")
&& plugin.getConfig().getBoolean("categories-enabled", true)) {
for (ConfigCategory c : plugin.getCategoryManager().getAll())
if (c.getKey().startsWith(args[1].toLowerCase())) completions.add(c.getKey());
// auch Priorität direkt ohne Kategorie anbieten
if (plugin.getConfig().getBoolean("priorities-enabled", true))
for (String p : List.of("low", "normal", "high", "urgent"))
if (p.startsWith(args[1].toLowerCase())) completions.add(p);
} else if (args.length == 3 && args[0].equalsIgnoreCase("create")
&& plugin.getConfig().getBoolean("priorities-enabled", true)) {
// Priorität nach Kategorie
for (String p : List.of("low", "normal", "high", "urgent"))
if (p.startsWith(args[2].toLowerCase())) completions.add(p);
} else if (args.length == 3 && args[0].equalsIgnoreCase("setpriority")) {
for (String p : List.of("low", "normal", "high", "urgent"))
if (p.startsWith(args[2].toLowerCase())) completions.add(p);
} else if (args.length == 3 && args[0].equalsIgnoreCase("forward")) {
for (Player p : Bukkit.getOnlinePlayers())
if (p.getName().toLowerCase().startsWith(args[2].toLowerCase())) completions.add(p.getName());
} else if (args.length == 2 && args[0].equalsIgnoreCase("blacklist")) {
completions.addAll(List.of("add", "remove", "list"));
} else if (args.length == 3 && args[0].equalsIgnoreCase("blacklist")
&& (args[1].equalsIgnoreCase("add") || args[1].equalsIgnoreCase("remove"))) {
for (Player p : Bukkit.getOnlinePlayers())
if (p.getName().toLowerCase().startsWith(args[2].toLowerCase())) completions.add(p.getName());
} else if (args.length == 3 && args[0].equalsIgnoreCase("rate")) {
completions.addAll(List.of("good", "bad"));
}
return completions;
}
}