diff --git a/src/main/java/de/ticketsystem/TicketPlaceholderExpansion.java b/src/main/java/de/ticketsystem/TicketPlaceholderExpansion.java new file mode 100644 index 0000000..389c130 --- /dev/null +++ b/src/main/java/de/ticketsystem/TicketPlaceholderExpansion.java @@ -0,0 +1,132 @@ +package de.ticketsystem; + +import de.ticketsystem.database.DatabaseManager; +import de.ticketsystem.model.Ticket; +import de.ticketsystem.model.TicketStatus; +import me.clip.placeholderapi.expansion.PlaceholderExpansion; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * PlaceholderAPI-Integration für das TicketSystem. + * + * Verfügbare Placeholder: + * + * ── Spieler ────────────────────────────────────────────────────────────────── + * %ticketsystem_my_open% + * Anzahl eigener aktiver Tickets (Status: OPEN + CLAIMED + FORWARDED) + * + * ── Admin ──────────────────────────────────────────────────────────────────── + * %ticketsystem_admin_open% + * Gesamtzahl aller Tickets mit Status OPEN + * + * %ticketsystem_admin_claimed% + * Gesamtzahl aller Tickets mit Status CLAIMED (in Bearbeitung) + * + * %ticketsystem_admin_rating_good% + * Gesamtzahl positiver Bewertungen (THUMBS_UP) + * + * %ticketsystem_admin_rating_bad% + * Gesamtzahl negativer Bewertungen (THUMBS_DOWN) + * + * %ticketsystem_admin_rating_total% + * Gesamtzahl aller abgegebenen Bewertungen + * + * %ticketsystem_admin_rating_percent% + * Prozentsatz positiver Bewertungen (0–100, gerundet), oder "-" wenn keine Bewertungen + */ +public class TicketPlaceholderExpansion extends PlaceholderExpansion { + + private final TicketPlugin plugin; + + public TicketPlaceholderExpansion(TicketPlugin plugin) { + this.plugin = plugin; + } + + // ── Pflichtfelder ───────────────────────────────────────────────────────── + + @Override + public @NotNull String getIdentifier() { + return "ticketsystem"; + } + + @Override + public @NotNull String getAuthor() { + return "M_Viper"; + } + + @Override + public @NotNull String getVersion() { + return plugin.getDescription().getVersion(); + } + + /** + * false = PlaceholderAPI registriert die Expansion nicht dauerhaft in der Cloud. + * true = die Expansion bleibt auch nach einem /papi reload aktiv, + * weil sie im Plugin-Ordner liegt. + */ + @Override + public boolean persist() { + return true; + } + + // ── Placeholder-Auflösung ───────────────────────────────────────────────── + + @Override + public String onPlaceholderRequest(Player player, @NotNull String identifier) { + + DatabaseManager db = plugin.getDatabaseManager(); + if (db == null) return "0"; + + // ── Spieler-Placeholder ────────────────────────────────────────────── + // Benötigen einen eingeloggten Spieler + if (identifier.equals("my_open")) { + if (player == null) return "0"; + return String.valueOf(db.countOpenTicketsByPlayer(player.getUniqueId())); + } + + // ── Admin-Placeholder (spielerunabhängig) ───────────────────────────── + // DB-Abfragen laufen synchron; bei sehr hoher Last kann ein + // async-Cache sinnvoll sein – für den normalen Scoreboard-Einsatz + // (Update alle 1–2 Sekunden) ist sync hier vertretbar. + + if (identifier.equals("admin_open")) { + return String.valueOf(countByStatus(db, TicketStatus.OPEN)); + } + + if (identifier.equals("admin_claimed")) { + return String.valueOf(countByStatus(db, TicketStatus.CLAIMED)); + } + + if (identifier.startsWith("admin_rating")) { + DatabaseManager.TicketStats stats = db.getTicketStats(); + + return switch (identifier) { + case "admin_rating_good" -> String.valueOf(stats.thumbsUp); + case "admin_rating_bad" -> String.valueOf(stats.thumbsDown); + case "admin_rating_total" -> String.valueOf(stats.thumbsUp + stats.thumbsDown); + case "admin_rating_percent" -> { + int total = stats.thumbsUp + stats.thumbsDown; + yield total == 0 ? "-" : String.valueOf(Math.round(stats.thumbsUp * 100.0 / total)); + } + default -> null; + }; + } + + // Unbekannter Placeholder + return null; + } + + // ── Hilfsmethoden ───────────────────────────────────────────────────────── + + /** + * Zählt Tickets eines einzelnen Status über getTicketsByStatus(). + * countOpenTickets() zählt nur OPEN – daher eigene Methode für CLAIMED. + */ + private int countByStatus(DatabaseManager db, TicketStatus status) { + List tickets = db.getTicketsByStatus(status); + return tickets == null ? 0 : tickets.size(); + } +} diff --git a/src/main/java/de/ticketsystem/TicketPlugin.java b/src/main/java/de/ticketsystem/TicketPlugin.java index 7836f4e..d0f019b 100644 --- a/src/main/java/de/ticketsystem/TicketPlugin.java +++ b/src/main/java/de/ticketsystem/TicketPlugin.java @@ -164,6 +164,14 @@ public class TicketPlugin extends JavaPlugin { webServer.start(); } + // ── PlaceholderAPI-Integration ──────────────────────────────────── + if (getServer().getPluginManager().getPlugin("PlaceholderAPI") != null) { + new TicketPlaceholderExpansion(this).register(); + getLogger().info("[PlaceholderAPI] Placeholder erfolgreich registriert."); + } else { + getLogger().warning("[PlaceholderAPI] PlaceholderAPI nicht gefunden – Placeholder nicht verfügbar."); + } + getLogger().info("TicketSystem v" + getDescription().getVersion() + " erfolgreich gestartet!"); } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index d578282..b374330 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ name: TicketSystem -version: 1.1.7 +version: 1.1.8 main: de.ticketsystem.TicketPlugin api-version: 1.20 author: M_Viper @@ -7,6 +7,9 @@ description: Ingame Support Ticket System with MySQL # ── BungeeCord Plugin-Messaging-Kanäle ─────────────────────────────────────── # PFLICHTFELD für Cross-Server-Benachrichtigungen! +softdepend: + - PlaceholderAPI + channels: - BungeeCord - ticketsystem:notify