Upload folder via GUI - src

This commit is contained in:
Git Manager GUI
2026-04-21 17:49:01 +02:00
parent 31c3496519
commit 03b484eac5
7 changed files with 140 additions and 127 deletions

View File

@@ -120,15 +120,8 @@ public class TicketCommand implements CommandExecutor, TabCompleter {
}
// ── /ticket create (Konsole) ──────────────────────────────────────────
//
// Syntax: /ticket create <Spielername> [Kategorie] [Priorität] <Beschreibung>
//
// Das Ticket wird im Namen des angegebenen Spielers erstellt.
// Als Erstell-Position wird die aktuelle Spieler-Location verwendet
// (oder eine Default-Location wenn der Spieler offline ist).
private void handleCreateConsole(CommandSender console, String[] args) {
// args[0] = "create", args[1] = Spielername, args[2..] = [Kategorie] [Priorität] Text
if (args.length < 3) {
console.sendMessage("[TicketSystem] Verwendung: /ticket create <Spielername> [Kategorie] [Priorität] <Beschreibung>");
console.sendMessage("[TicketSystem] Beispiel: /ticket create Notch bug high Spieler fällt durch den Boden");
@@ -137,7 +130,6 @@ public class TicketCommand implements CommandExecutor, TabCompleter {
String targetName = args[1];
// Spieler suchen (online bevorzugt, sonst OfflinePlayer)
@SuppressWarnings("deprecation")
OfflinePlayer offlineTarget = Bukkit.getOfflinePlayer(targetName);
UUID targetUUID = offlineTarget.getUniqueId();
@@ -146,12 +138,11 @@ public class TicketCommand implements CommandExecutor, TabCompleter {
CategoryManager cm = plugin.getCategoryManager();
ConfigCategory category = cm.getDefault();
TicketPriority priority = TicketPriority.NORMAL;
int msgStart = 2; // Index ab dem die Beschreibung beginnt (relativ zu args[2..])
int msgStart = 2;
boolean categoriesOn = plugin.getConfig().getBoolean("categories-enabled", true);
boolean prioritiesOn = plugin.getConfig().getBoolean("priorities-enabled", true);
// args[2] = optional Kategorie, args[3] = optional Priorität, Rest = Text
if (args.length >= 4 && categoriesOn) {
ConfigCategory parsedCat = cm.resolve(args[2]);
if (parsedCat != null) {
@@ -170,15 +161,15 @@ public class TicketCommand implements CommandExecutor, TabCompleter {
if (parsedPrio != null) { priority = parsedPrio; msgStart = 3; }
}
// Beschreibung zusammensetzen (args[msgStart+1] weil args[1]=Spielername)
int absoluteStart = msgStart + 1; // +1 für den Spielernamen in args[1]
if (absoluteStart >= args.length) {
// msgStart ist der absolute Index in args[] ab dem die Beschreibung beginnt.
// Kein +1 nötig msgStart zeigt bereits auf das erste Beschreibungs-Wort.
if (msgStart >= args.length) {
console.sendMessage("[TicketSystem] Fehler: Keine Beschreibung angegeben.");
console.sendMessage("[TicketSystem] Verwendung: /ticket create <Spielername> [Kategorie] [Priorität] <Beschreibung>");
return;
}
String message = String.join(" ", Arrays.copyOfRange(args, absoluteStart, args.length));
String message = String.join(" ", Arrays.copyOfRange(args, msgStart, args.length));
int maxLen = plugin.getConfig().getInt("max-description-length", 100);
if (message.isEmpty()) {
@@ -190,7 +181,6 @@ public class TicketCommand implements CommandExecutor, TabCompleter {
return;
}
// Location: online-Spieler → aktuelle Pos; offline → Spawn der Default-Welt
Location location;
Player onlineTarget = Bukkit.getPlayer(targetUUID);
if (onlineTarget != null) {
@@ -233,7 +223,6 @@ public class TicketCommand implements CommandExecutor, TabCompleter {
+ "' erstellt." + catInfo + prioInfo);
console.sendMessage("[TicketSystem] Nachricht: " + fMessage);
// Team benachrichtigen (gleich wie bei normalem /ticket create)
plugin.getTicketManager().notifyTeam(ticket);
});
});
@@ -247,9 +236,10 @@ public class TicketCommand implements CommandExecutor, TabCompleter {
plugin.reloadSettings();
plugin.getTicketGUI().reloadConfig();
plugin.getTicketGUI().reloadTitles();
plugin.getFaqGUI().reloadConfig();
// FaqGUI ist null wenn faq-enabled: false → Null-Check erforderlich
if (plugin.getFaqGUI() != null) plugin.getFaqGUI().reloadConfig();
plugin.getCategoryManager().reload();
plugin.getFaqManager().reload();
if (plugin.getFaqManager() != null) plugin.getFaqManager().reload();
plugin.getTicketCache().clear();
console.sendMessage("[TicketSystem] Konfiguration erfolgreich neu geladen.");
}
@@ -729,9 +719,10 @@ public class TicketCommand implements CommandExecutor, TabCompleter {
plugin.reloadSettings();
plugin.getTicketGUI().reloadConfig();
plugin.getTicketGUI().reloadTitles();
plugin.getFaqGUI().reloadConfig();
// FaqGUI ist null wenn faq-enabled: false → Null-Check erforderlich
if (plugin.getFaqGUI() != null) plugin.getFaqGUI().reloadConfig();
plugin.getCategoryManager().reload();
plugin.getFaqManager().reload();
if (plugin.getFaqManager() != null) plugin.getFaqManager().reload();
plugin.getTicketCache().clear();
player.sendMessage(plugin.lang().get("reload.success"));
if (plugin.isBungeeCordEnabled())
@@ -944,14 +935,13 @@ public class TicketCommand implements CommandExecutor, TabCompleter {
// ── /ticket faq ───────────────────────────────────────────────────────
private void handleFaq(Player player, String[] args) {
// FAQ-System global deaktiviert?
if (!plugin.getConfig().getBoolean("faq-enabled", true)) {
plugin.lang().send(player, "faq.disabled");
return;
}
if (args.length == 1) {
plugin.getFaqGUI().openFaqGUI(player);
if (plugin.getFaqGUI() != null) plugin.getFaqGUI().openFaqGUI(player);
return;
}
@@ -1122,7 +1112,6 @@ public class TicketCommand implements CommandExecutor, TabCompleter {
if (!player.hasPermission("ticket.admin")) {
plugin.lang().send(player, "general.no-permission"); return;
}
// FAQ-System deaktiviert?
if (!plugin.getConfig().getBoolean("faq-enabled", true)) {
plugin.lang().send(player, "faq.disabled"); return;
}
@@ -1218,6 +1207,7 @@ public class TicketCommand implements CommandExecutor, TabCompleter {
}
private List<String> getFaqCategoryKeysForTab(String input) {
if (plugin.getFaqManager() == null) return new ArrayList<>();
String lower = input == null ? "" : input.toLowerCase();
List<String> result = new ArrayList<>();
for (FaqCategory cat : plugin.getFaqManager().getAllCategories())
@@ -1257,11 +1247,9 @@ public class TicketCommand implements CommandExecutor, TabCompleter {
for (String s : List.of("create", "reload", "archive", "stats"))
if (s.startsWith(args[0].toLowerCase())) completions.add(s);
} else if (args.length == 2 && normalize(args[0]).equals("create")) {
// Spielernamen vorschlagen
for (Player p : Bukkit.getOnlinePlayers())
if (p.getName().toLowerCase().startsWith(args[1].toLowerCase())) completions.add(p.getName());
} else if (args.length == 3 && normalize(args[0]).equals("create")) {
// Kategorien vorschlagen
completions.addAll(plugin.getCategoryManager().getDisplayNamesForTabComplete(args[2]));
}
return completions;
@@ -1321,8 +1309,9 @@ public class TicketCommand implements CommandExecutor, TabCompleter {
&& (args[1].equalsIgnoreCase("edit") || args[1].equalsIgnoreCase("delete")
|| args[1].equalsIgnoreCase("bearbeiten") || args[1].equalsIgnoreCase("löschen"))
&& player.hasPermission("ticket.admin")) {
for (FaqEntry e : plugin.getFaqManager().getAll())
completions.add(String.valueOf(e.getId()));
if (plugin.getFaqManager() != null)
for (FaqEntry e : plugin.getFaqManager().getAll())
completions.add(String.valueOf(e.getId()));
} else if (args.length == 2 && (normalize(args[0]).equals("category")
|| args[0].equalsIgnoreCase("kategorie"))

View File

@@ -32,9 +32,12 @@ public class PlayerJoinListener implements Listener {
int count = plugin.getDatabaseManager().countOpenTickets();
if (count > 0) {
Bukkit.getScheduler().runTaskLater(plugin, () -> {
player.sendMessage(plugin.lang().format("join.open-tickets",
"{count}", String.valueOf(count)));
player.sendMessage(plugin.lang().get("join.open-tickets-hint"));
// Anzahl als normaler Text kein MiniMessage nötig
plugin.lang().send(player, "join.open-tickets",
"{count}", String.valueOf(count));
// Hint über send() routen → MiniMessage greift wenn
// <click:run_command:...> in der lang.yml steht
plugin.lang().send(player, "join.open-tickets-hint");
}, 40L);
}
});
@@ -54,14 +57,14 @@ public class PlayerJoinListener implements Listener {
if (!player.isOnline()) return;
World world = Bukkit.getWorld(pt.world());
if (world == null) {
player.sendMessage(plugin.lang().format("join.teleport-world-missing",
"{world}", pt.world()));
plugin.lang().send(player, "join.teleport-world-missing",
"{world}", pt.world());
return;
}
Location loc = new Location(world, pt.x(), pt.y(), pt.z(), pt.yaw(), pt.pitch());
player.teleport(loc);
String coords = String.format("%.0f, %.0f, %.0f", pt.x(), pt.y(), pt.z());
player.sendMessage(plugin.lang().format("join.teleport-success", "{coords}", coords));
plugin.lang().send(player, "join.teleport-success", "{coords}", coords);
});
});
}, 40L);
@@ -78,7 +81,9 @@ public class PlayerJoinListener implements Listener {
player.sendMessage(plugin.lang().get("general.separator"));
player.sendMessage(plugin.lang().get("join.pending-header"));
for (String msg : pending) {
player.sendMessage(plugin.lang().color(msg));
// Pending-Nachrichten können MiniMessage-Tags enthalten
// → sendRaw() statt color()
plugin.lang().sendRaw(player, msg);
}
player.sendMessage(plugin.lang().get("general.separator"));
});
@@ -94,7 +99,6 @@ public class PlayerJoinListener implements Listener {
// ── Spieler: über geschlossene Tickets informieren ────────────────
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
// Nur Tickets dieses Spielers laden (nicht ALLE closed Tickets)
List<Ticket> closed = plugin.getDatabaseManager()
.getUnnotifiedClosedTicketsByPlayer(player.getUniqueId());
@@ -111,7 +115,7 @@ public class PlayerJoinListener implements Listener {
new de.ticketsystem.UpdateChecker(plugin, resourceId).getVersion(version -> {
String current = plugin.getDescription().getVersion();
if (!current.equals(version)) {
String bar = plugin.lang().get("update.available-bar");
String bar = plugin.lang().get("update.available-bar");
String line1 = plugin.lang().format("update.available-line1", "{version}", version);
String line2 = plugin.lang().get("update.available-line2");
player.sendMessage(ChatColor.GOLD + bar);

View File

@@ -293,7 +293,7 @@ public class LanguageManager {
}
/**
* Sendet eine Nachricht an einen CommandSender.
* Sendet eine Nachricht an einen CommandSender (aus einem lang-Key).
*
* Enthält der Rohtext MiniMessage-Tags mit interaktiven Elementen
* (click, hover, insertion), wird die Nachricht als Adventure-Component
@@ -312,6 +312,38 @@ public class LanguageManager {
for (int i = 0; i + 1 < replacements.length; i += 2)
raw = raw.replace(replacements[i], replacements[i + 1]);
sendProcessed(sender, raw, needsPrefix(key));
}
/**
* Sendet einen bereits zusammengebauten Roh-String (KEIN lang-Key) durch
* die vollständige MiniMessage-Pipeline inkl. Legacy-Konvertierung.
*
* Verwende diese Methode wenn du Strings programmatisch zusammenbaust
* (z.B. Rating-Prompt aus mehreren Keys) und trotzdem klickbare
* run_command-Tags benötigst.
*
* Prefix wird NICHT automatisch vorangestellt.
*/
public void sendRaw(CommandSender sender, String rawText) {
if (rawText == null || rawText.isEmpty()) return;
sendProcessed(sender, rawText, false);
}
/**
* Sendet einen bereits zusammengebauten Roh-String mit optionalem Prefix
* durch die vollständige MiniMessage-Pipeline.
*/
public void sendRaw(CommandSender sender, String rawText, boolean withPrefix) {
if (rawText == null || rawText.isEmpty()) return;
sendProcessed(sender, rawText, withPrefix);
}
/**
* Interne Kernmethode: Verarbeitet einen vorbereiteten String und sendet ihn.
* Entscheidet automatisch zwischen MiniMessage-Component und Legacy-String.
*/
private void sendProcessed(CommandSender sender, String raw, boolean addPrefix) {
if (hasMiniMessageInteractiveTags(raw)) {
// MiniMessage-Pfad: interaktive Komponenten (click/hover)
// Legacy-&-Farbcodes in MiniMessage-Äquivalente umwandeln damit
@@ -320,7 +352,7 @@ public class LanguageManager {
Component component = MINI.deserialize(mm);
// Prefix als Component voranstellen wenn nötig
if (needsPrefix(key)) {
if (addPrefix) {
Component prefixComp = MINI.deserialize(legacyToMiniMessage(
color("&8[&6Ticket&8] &r")));
component = prefixComp.append(component);
@@ -332,7 +364,7 @@ public class LanguageManager {
} else {
// Legacy-Pfad: §-Codes, kein Adventure nötig
String text = color(raw);
sender.sendMessage(needsPrefix(key) ? prefix + text : text);
sender.sendMessage(addPrefix ? prefix + text : text);
}
}
@@ -454,37 +486,6 @@ public class LanguageManager {
return sb.toString();
}
/**
* Sendet eine Adventure-Component an einen CommandSender.
*
* Der Cast auf net.kyori.adventure.audience.Audience umgeht das compile-time
* Problem, dass Spigots CommandSender-Interface sendMessage(Component) nicht
* direkt exponiert zur Laufzeit implementiert jeder CommandSender auf
* Paper/Spigot 1.18+ das Audience-Interface.
*/
private void sendComponent(CommandSender sender, Component component) {
if (sender instanceof net.kyori.adventure.audience.Audience audience) {
try {
audience.sendMessage(component);
} catch (NoSuchMethodError | AbstractMethodError e) {
// Fallback für reines Spigot ohne Adventure-Patch:
// Component in Legacy-String serialisieren (click/hover gehen verloren,
// aber der Text bleibt lesbar)
String legacy = LegacyComponentSerializer.legacySection().serialize(component);
sender.sendMessage(legacy);
if (plugin.isDebug()) {
plugin.getLogger().info("[LanguageManager] Adventure-API nicht verfügbar "
+ "interaktive Tags werden als Plain-Text gesendet. "
+ "Wechsel auf Paper für volle MiniMessage-Unterstützung.");
}
}
} else {
// Kein Audience (z. B. alte Konsole) → Legacy-Fallback
String legacy = LegacyComponentSerializer.legacySection().serialize(component);
sender.sendMessage(legacy);
}
}
// ── Intern ───────────────────────────────────────────────────────────────
private boolean needsPrefix(String key) {

View File

@@ -45,6 +45,9 @@ public class TicketManager {
/**
* Benachrichtigt alle Supporter/Admins über ein neues Ticket.
* Bei BungeeCord wird die Nachricht an alle Server weitergeleitet.
*
* Die gui-hint-Nachricht wird über lang().send() geroutet, damit
* ein <click:run_command:...>-Tag in der lang.yml funktioniert.
*/
public void notifyTeam(Ticket ticket) {
String creatorName = ticket.getCreatorName() != null ? ticket.getCreatorName() : "Unbekannt";
@@ -66,21 +69,24 @@ public class TicketManager {
serverInfo = plugin.lang().format("notify.team-server", "{server}", ticket.getServerName());
}
// Haupt-Benachrichtigung (plain Legacy-String, kein MiniMessage nötig)
String msg = plugin.lang().format("ticket.new-notify",
"{player}", creatorName,
"{message}", message,
"{id}", String.valueOf(ticket.getId()))
+ categoryInfo + priorityInfo + serverInfo;
String guiHint = plugin.lang().get("notify.gui-hint");
if (plugin.isBungeeCordEnabled()) {
plugin.getBungeeMessenger().broadcastTeamNotification(msg + "\n" + guiHint);
// BungeeCord: Roh-String broadcasten (gui-hint separat per sendRaw)
plugin.getBungeeMessenger().broadcastTeamNotification(msg);
plugin.getBungeeMessenger().broadcastTeamNotification(
plugin.lang().get("notify.gui-hint"));
} else {
for (Player p : Bukkit.getOnlinePlayers()) {
if (p.hasPermission("ticket.support") || p.hasPermission("ticket.admin")) {
p.sendMessage(msg);
p.sendMessage(guiHint);
// gui-hint über send() routen → MiniMessage greift wenn Tags vorhanden
plugin.lang().send(p, "notify.gui-hint");
}
}
}
@@ -120,14 +126,13 @@ public class TicketManager {
Bukkit.getScheduler().runTask(plugin, () -> {
if (!player.isOnline()) return;
if (t.getStatus() == TicketStatus.CLAIMED) {
player.sendMessage(plugin.lang().format("ticket.claimed-notify",
"{id}", String.valueOf(t.getId()), "{claimer}", name));
plugin.lang().send(player, "ticket.claimed-notify",
"{id}", String.valueOf(t.getId()), "{claimer}", name);
} else {
String forwardedTo = t.getForwardedToName() != null ? t.getForwardedToName() : "einen Supporter";
player.sendMessage(plugin.lang().format("ticket.forwarded-creator",
"{id}", String.valueOf(t.getId()), "{supporter}", forwardedTo));
plugin.lang().send(player, "ticket.forwarded-creator",
"{id}", String.valueOf(t.getId()), "{supporter}", forwardedTo);
}
// Flag NACH der Nachricht setzen sicher im Hauptthread
Bukkit.getScheduler().runTaskAsynchronously(plugin,
() -> plugin.getDatabaseManager().markClaimerNotified(t.getId()));
});
@@ -163,6 +168,14 @@ public class TicketManager {
notifyCreatorClosed(ticket, null);
}
/**
* Benachrichtigt den Ersteller über die Schließung seines Tickets.
*
* Der Rating-Prompt wird über lang().sendRaw() gesendet, damit
* <click:run_command:...>-Tags in der lang.yml tatsächlich funktionieren.
* Dazu werden die einzelnen Keys zusammengebaut und als ein String
* durch die MiniMessage-Pipeline geschickt.
*/
public void notifyCreatorClosed(Ticket ticket, String closerName) {
Bukkit.getScheduler().runTaskAsynchronously(plugin, () ->
plugin.getDatabaseManager().markCloseNotified(ticket.getId()));
@@ -170,36 +183,50 @@ public class TicketManager {
String comment = (ticket.getCloseComment() != null && !ticket.getCloseComment().isEmpty())
? ticket.getCloseComment() : "";
String msg = plugin.lang().format("ticket.closed-notify", "{id}", String.valueOf(ticket.getId()));
// Schließ-Nachricht (normaler send()-Pfad reicht)
String closedKey = "ticket.closed-notify";
// Bewertungsaufforderung aufbauen
String ratingMsg = null;
// Rating-Prompt: Keys einzeln holen und zu einem String zusammenbauen,
// damit Platzhalter korrekt ersetzt werden, BEVOR sendRaw() aufgerufen wird.
String ratingRaw = null;
if (plugin.getConfig().getBoolean("rating-enabled", true)) {
String id = String.valueOf(ticket.getId());
ratingMsg = plugin.lang().get("rating.prompt-header") + "\n"
+ plugin.lang().get("rating.prompt-title") + "\n"
+ plugin.lang().format("rating.prompt-good", "{id}", id) + "\n"
+ plugin.lang().format("rating.prompt-bad", "{id}", id) + "\n"
+ plugin.lang().get("rating.prompt-footer");
ratingRaw = plugin.lang().getRaw("rating.prompt-header") + "\n"
+ plugin.lang().getRaw("rating.prompt-title") + "\n"
+ plugin.lang().getRaw("rating.prompt-good").replace("{id}", id) + "\n"
+ plugin.lang().getRaw("rating.prompt-bad").replace("{id}", id) + "\n"
+ plugin.lang().getRaw("rating.prompt-footer");
// {cmd_rate}-Platzhalter ebenfalls ersetzen
ratingRaw = ratingRaw.replace("{cmd_rate}", plugin.lang().getCmdName("rate"));
}
final String finalRatingRaw = ratingRaw;
Player creator = Bukkit.getPlayer(ticket.getCreatorUUID());
if (creator != null && creator.isOnline()) {
creator.sendMessage(msg);
// Schließ-Nachricht
plugin.lang().send(creator, closedKey, "{id}", String.valueOf(ticket.getId()));
// Kommentar des Supports
if (!comment.isEmpty())
creator.sendMessage(plugin.lang().format("ticket.close-comment-label", "{comment}", comment));
if (ratingMsg != null)
creator.sendMessage(ratingMsg);
// Rating-Prompt: über sendRaw() damit MiniMessage-Tags greifen
if (finalRatingRaw != null)
plugin.lang().sendRaw(creator, finalRatingRaw);
} else if (plugin.isBungeeCordEnabled()) {
plugin.getBungeeMessenger().sendMessageToPlayer(ticket.getCreatorUUID(), ticket.getCreatorName(), msg);
String closedMsg = plugin.lang().format(closedKey, "{id}", String.valueOf(ticket.getId()));
plugin.getBungeeMessenger().sendMessageToPlayer(ticket.getCreatorUUID(), ticket.getCreatorName(), closedMsg);
if (!comment.isEmpty())
plugin.getBungeeMessenger().sendMessageToPlayer(
ticket.getCreatorUUID(), ticket.getCreatorName(),
plugin.lang().format("ticket.close-comment-label", "{comment}", comment));
if (ratingMsg != null)
// Im BungeeCord-Modus: Rating-Prompt als plain Text (click-Events
// funktionieren nur lokal über Adventure BungeeCord-Messaging
// überträgt keine Component-Events, nur Text)
if (finalRatingRaw != null)
plugin.getBungeeMessenger().sendMessageToPlayer(
ticket.getCreatorUUID(), ticket.getCreatorName(), ratingMsg);
ticket.getCreatorUUID(), ticket.getCreatorName(),
plugin.lang().color(finalRatingRaw));
} else {
savePendingClosedNotification(ticket, comment);
@@ -230,42 +257,34 @@ public class TicketManager {
/**
* Sendet die Hilfe-Nachricht an den Spieler.
*
* Die Befehlsnamen in den lang.yml-Schlüsseln (z.B. help.create) enthalten
* {cmd_X}-Platzhalter. Der LanguageManager ersetzt diese automatisch
* anhand von language in config.yml:
*
* language: de → /ticket erstellen
* language: en → /ticket create
* language: both → /ticket create (erstellen)
*
* Hier muss kein manueller Sprachcode gelesen werden.
* Jede Zeile wird über lang().send() geroutet damit
* eventuelle MiniMessage-Tags funktionieren.
*/
public void sendHelpMessage(Player player) {
player.sendMessage(plugin.lang().get("general.separator"));
player.sendMessage(plugin.lang().get("help.header"));
player.sendMessage(plugin.lang().get("general.separator"));
player.sendMessage(plugin.lang().get("help.create"));
player.sendMessage(plugin.lang().get("help.list"));
player.sendMessage(plugin.lang().get("help.comment"));
plugin.lang().send(player, "general.separator");
plugin.lang().send(player, "help.header");
plugin.lang().send(player, "general.separator");
plugin.lang().send(player, "help.create");
plugin.lang().send(player, "help.list");
plugin.lang().send(player, "help.comment");
if (plugin.getConfig().getBoolean("rating-enabled", true))
player.sendMessage(plugin.lang().get("help.rate"));
plugin.lang().send(player, "help.rate");
if (player.hasPermission("ticket.support") || player.hasPermission("ticket.admin")) {
player.sendMessage(plugin.lang().get("help.claim"));
player.sendMessage(plugin.lang().get("help.close"));
plugin.lang().send(player, "help.claim");
plugin.lang().send(player, "help.close");
}
if (player.hasPermission("ticket.admin")) {
player.sendMessage(plugin.lang().get("help.forward"));
player.sendMessage(plugin.lang().get("help.blacklist"));
player.sendMessage(plugin.lang().get("help.reload"));
player.sendMessage(plugin.lang().get("help.stats"));
plugin.lang().send(player, "help.forward");
plugin.lang().send(player, "help.blacklist");
plugin.lang().send(player, "help.reload");
plugin.lang().send(player, "help.stats");
}
player.sendMessage(plugin.lang().get("general.separator"));
plugin.lang().send(player, "general.separator");
if (player.hasPermission("ticket.admin") && plugin.isBungeeCordEnabled())
player.sendMessage(plugin.lang().format("help.bungee-status", "{server}", plugin.getServerName()));
plugin.lang().send(player, "help.bungee-status", "{server}", plugin.getServerName());
}
// ── Interne Hilfsmethoden ─────────────────────────────────────────────

View File

@@ -80,7 +80,7 @@ ticket:
# BENACHRICHTIGUNGEN (Team / GUI-Hinweis)
# ============================================================
notify:
gui-hint: "&7» Klicke &e{cmd_list} &7um die Übersicht zu öffnen."
gui-hint: "&7» <click:run_command:/ticket liste><yellow>Klicke hier</yellow></click> &7um die Übersicht zu öffnen."
team-category: " §7[§r{category}§7]"
team-priority: " §7Priorität: §r{priority}"
team-server: " §7Server: §b{server}"
@@ -139,8 +139,8 @@ rating:
invalid: "&cUngültige Bewertung! Benutze &egood &coder &ebad&c."
prompt-header: "&#555555&m "
prompt-title: "&6Wie zufrieden bist du mit dem Support?"
prompt-good: "&a{cmd_rate} {id} good &7 👍 Gut"
prompt-bad: "&c{cmd_rate} {id} bad &7 👎 Schlecht"
prompt-good: "<green><click:run_command:/ticket bewerten {id} good>&a👍 Gut bewerten</click></green>"
prompt-bad: "<red><click:run_command:/ticket bewerten {id} bad>&c👎 Schlecht bewerten</click></red>"
prompt-footer: "&#555555&m "
# ============================================================
@@ -538,7 +538,7 @@ gui:
# ============================================================
join:
open-tickets: "&eEs gibt noch &6{count} &eoffene Ticket(s)!"
open-tickets-hint: "&7» Tippe &e{cmd_list} &7für die Übersicht."
open-tickets-hint: "&7» <click:run_command:/ticket liste><yellow>Klicke hier</yellow></click> &7für die Ticket-Übersicht."
teleport-world-missing: "&cTeleport-Zielwelt &e{world} &cnicht gefunden!"
teleport-success: "&7Du wurdest zur Ticket-Position teleportiert. &8({coords})"
pending-header: "&6Ticket-Benachrichtigungen &7(während du offline warst):"

View File

@@ -80,7 +80,7 @@ ticket:
# NOTIFICATIONS (Team / GUI hint)
# ============================================================
notify:
gui-hint: "&7» Click &e{cmd_list} &7to open the overview."
gui-hint: "&7» <click:run_command:/ticket list><yellow>Click here</yellow></click> &7to open the overview."
team-category: " §7[§r{category}§7]"
team-priority: " §7Priority: §r{priority}"
team-server: " §7Server: §b{server}"
@@ -139,8 +139,8 @@ rating:
invalid: "&cInvalid rating! Use &egood &cor &ebad&c."
prompt-header: "&#777777&m "
prompt-title: "&6How satisfied are you with the support?"
prompt-good: "&a{cmd_rate} {id} good &7 👍 Good"
prompt-bad: "&c{cmd_rate} {id} bad &7 👎 Bad"
prompt-good: "<green><click:run_command:/ticket rate {id} good>&a👍 Rate Good</click></green>"
prompt-bad: "<red><click:run_command:/ticket rate {id} bad>&c👎 Rate Bad</click></red>"
prompt-footer: "&#777777&m "
# ============================================================
@@ -538,7 +538,7 @@ gui:
# ============================================================
join:
open-tickets: "&eThere are still &6{count} &eopen ticket(s)!"
open-tickets-hint: "&7» Type &e{cmd_list} &7for the overview."
open-tickets-hint: "&7» <click:run_command:/ticket list><yellow>Click here</yellow></click> &7for the ticket overview."
teleport-world-missing: "&cTeleport target world &e{world} &cnot found!"
teleport-success: "&7You have been teleported to the ticket location. &8({coords})"
pending-header: "&6Ticket notifications &7(while you were offline):"

View File

@@ -1,5 +1,5 @@
name: TicketSystem
version: 1.1.5
version: 1.1.6
main: de.ticketsystem.TicketPlugin
api-version: 1.20
author: M_Viper