package de.ticketsystem; import de.ticketsystem.bungee.BungeeMessenger; import de.ticketsystem.cache.TicketCache; import de.ticketsystem.commands.TicketCommand; import de.ticketsystem.database.DatabaseManager; import de.ticketsystem.discord.DiscordWebhook; import de.ticketsystem.gui.FaqGUI; import de.ticketsystem.gui.TicketGUI; import de.ticketsystem.listeners.PlayerJoinListener; import de.ticketsystem.manager.CategoryManager; import de.ticketsystem.manager.FaqManager; import de.ticketsystem.manager.TicketManager; import de.ticketsystem.model.Ticket; import org.bukkit.ChatColor; import org.bukkit.plugin.java.JavaPlugin; import java.util.Objects; public class TicketPlugin extends JavaPlugin { private static TicketPlugin instance; private boolean debug; /** * Name dieses Servers im BungeeCord-Netzwerk. * Konfigurierbar in config.yml → server-name */ private String serverName; private DatabaseManager databaseManager; private TicketManager ticketManager; private CategoryManager categoryManager; private FaqManager faqManager; private TicketGUI ticketGUI; private FaqGUI faqGUI; private DiscordWebhook discordWebhook; private BungeeMessenger bungeeMessenger; private TicketCache ticketCache; @Override public void onEnable() { instance = this; saveDefaultConfig(); // Ticket-Klasse für YAML-Serialisierung registrieren Ticket.register(); // ── BungeeCord Plugin-Messaging-Kanäle registrieren ─────────────── getServer().getMessenger().registerOutgoingPluginChannel(this, BungeeMessenger.BUNGEE_CHANNEL); getServer().getMessenger().registerOutgoingPluginChannel(this, BungeeMessenger.CUSTOM_CHANNEL); bungeeMessenger = new BungeeMessenger(this); getServer().getMessenger().registerIncomingPluginChannel(this, BungeeMessenger.CUSTOM_CHANNEL, bungeeMessenger); // Server-Name aus Config lesen serverName = getConfig().getString("server-name", "unknown"); if ("unknown".equals(serverName)) { getLogger().warning("[BungeeCord] Kein 'server-name' in der config.yml definiert!"); } // BungeeCord-Hinweis nur bei deaktiviertem Feature ausgeben if (!getConfig().getBoolean("bungeecord", false)) { getLogger().info("[BungeeCord] Cross-Server-Features deaktiviert. Setze 'bungeecord: true' um sie zu aktivieren."); } // Update-Checker (nur Warnung wenn Update verfügbar – kein API-Raw-Log) int resourceId = 132757; new UpdateChecker(this, resourceId).getVersion(version -> { String current = getDescription().getVersion(); if (!current.equals(version)) { String msg = ChatColor.translateAlternateColorCodes('&', "&6[TicketSystem] &eNeue Version verfügbar: &a" + version + " &7(aktuell: " + current + ")"); getLogger().warning("Neue Version verfügbar: " + version + " (aktuell: " + current + ")"); getServer().getScheduler().runTaskLater(this, () -> getServer().getOnlinePlayers().stream() .filter(p -> p.hasPermission("ticket.admin")) .forEach(p -> p.sendMessage(msg)), 20L); } }); // Versionsprüfung der config.yml String configVersion = getConfig().getString("version", ""); String expectedVersion = "2.0"; if (!expectedVersion.equals(configVersion)) { getLogger().warning("[WARNUNG] config.yml-Version (" + configVersion + ") stimmt nicht mit der erwarteten Version (" + expectedVersion + ") überein!"); } debug = getConfig().getBoolean("debug", false); // ── Performance: Ticket-Cache ────────────────────────────────────── long cacheTtl = getConfig().getLong("cache-ttl-seconds", 60) * 1000L; ticketCache = new TicketCache(cacheTtl); // Regelmäßige Cache-Bereinigung alle 5 Minuten getServer().getScheduler().runTaskTimerAsynchronously(this, () -> ticketCache.evictExpired(), 6000L, 6000L); // Datenbankverbindung databaseManager = new DatabaseManager(this); if (!databaseManager.connect()) { getLogger().severe("Konnte keine Datenbankverbindung herstellen! Plugin läuft im Datei-Modus weiter."); } // Manager, GUI, FAQ & Discord-Webhook initialisieren categoryManager = new CategoryManager(this); ticketManager = new TicketManager(this); faqManager = new FaqManager(this); ticketGUI = new TicketGUI(this); faqGUI = new FaqGUI(this); discordWebhook = new DiscordWebhook(this); if (getConfig().getBoolean("discord.enabled", false)) { String url = getConfig().getString("discord.webhook-url", ""); if (url.isEmpty()) { getLogger().warning("[DiscordWebhook] Aktiviert, aber keine Webhook-URL in config.yml eingetragen!"); } } // Commands & Events TicketCommand ticketCommand = new TicketCommand(this); Objects.requireNonNull(getCommand("ticket")).setExecutor(ticketCommand); Objects.requireNonNull(getCommand("ticket")).setTabCompleter(ticketCommand); getServer().getPluginManager().registerEvents(new PlayerJoinListener(this), this); getServer().getPluginManager().registerEvents(ticketGUI, this); getServer().getPluginManager().registerEvents(faqGUI, this); // Automatische Archivierung int archiveIntervalH = getConfig().getInt("auto-archive-interval-hours", 24); if (archiveIntervalH > 0) { long ticks = archiveIntervalH * 60L * 60L * 20L; getServer().getScheduler().runTaskTimer(this, () -> { int archived = databaseManager.archiveClosedTickets(); if (archived > 0) { getLogger().info("Automatische Archivierung: " + archived + " Tickets archiviert."); } }, ticks, ticks); } getLogger().info("TicketSystem v" + getDescription().getVersion() + " erfolgreich gestartet!"); } @Override public void onDisable() { getServer().getMessenger().unregisterOutgoingPluginChannel(this); getServer().getMessenger().unregisterIncomingPluginChannel(this); if (ticketCache != null) ticketCache.clear(); if (databaseManager != null) databaseManager.disconnect(); getLogger().info("TicketSystem wurde deaktiviert."); } // ─────────────────────────── Hilfsmethoden ───────────────────────────── public String formatMessage(String path) { String prefix = color(getConfig().getString("prefix", "&8[&6Ticket&8] &r")); String message = getConfig().getString(path, "&cNachricht nicht gefunden: " + path); return prefix + color(message); } public String color(String text) { return ChatColor.translateAlternateColorCodes('&', text); } // ─────────────────────────── Getter ──────────────────────────────────── public static TicketPlugin getInstance() { return instance; } public DatabaseManager getDatabaseManager() { return databaseManager; } public TicketManager getTicketManager() { return ticketManager; } public CategoryManager getCategoryManager() { return categoryManager; } public FaqManager getFaqManager() { return faqManager; } public TicketGUI getTicketGUI() { return ticketGUI; } public FaqGUI getFaqGUI() { return faqGUI; } public DiscordWebhook getDiscordWebhook() { return discordWebhook; } public BungeeMessenger getBungeeMessenger() { return bungeeMessenger; } public TicketCache getTicketCache() { return ticketCache; } public boolean isDebug() { return debug; } public String getServerName() { return serverName; } public boolean isBungeeCordEnabled() { return getConfig().getBoolean("bungeecord", false); } }