Spigot Plugin

RiftStatsPlugin

Create a premium-quality Minecraft Paper plugin called **RiftStats**. Requirements: - Java 21 - Support Paper 1.21.4–1.21.8 - Automatically detect and hook into Citizens if it is installed (no manual version configuration). - Clean, optimized, and asynchronous where possible. - Well-structured code with comments. - Full config.yml, messages.yml, and plugin.yml. /stats GUI When a player executes: /stats Open a modern, animated inventory GUI with a clean design. Display the player's statistics: ⚔ Kills ☠ Deaths ⏱ Playtime Each statistic should have: - Beautiful item icons

Read the full description

- Custom names using MiniMessage gradients - Clean lore - Premium-looking layout - Decorative glass panes around the GUI Example: ⚔ Your Statistics Kills: 154 Deaths: 29 Playtime: 18h 42m Leaderboard Button In the bottom-right corner of the GUI, place a button called: 🏆 Leaderboards Clicking it opens another GUI containing three categories: ⚔ Top Kills ☠ Top Deaths ⏱ Top Playtime Each category should display the Top 5 players. Example: ⚔ Top Kills 🥇 #1 Steve - 542 🥈 #2 Alex - 501 🥉 #3 Rift - 420 4️⃣ Notch - 388 5️⃣ Dream - 350 Example for Deaths: ☠ Top Deaths 🥇 #1 Steve - 230 🥈 #2 Alex - 211 🥉 #3 Rift - 185 4️⃣ Notch - 170 5️⃣ Dream - 165 Example for Playtime: ⏱ Top Playtime 🥇 #1 Steve - 312h 🥈 #2 Alex - 287h 🥉 #3 Rift - 260h 4️⃣ Notch - 244h 5️⃣ Dream - 229h NPC Integration Command: /stats create <name> Requirements: - Creates a Citizens NPC at the player's location. - NPC uses the provided name. - NPC automatically opens the /stats GUI when right-clicked. - No additional setup required. - Automatically hooks into Citizens if installed. - If Citizens is missing, display a friendly error message. Commands /stats Open your statistics GUI. /stats create <name> Create a Citizens NPC that opens the Stats GUI. /stats reload Reload plugin configuration. Permissions riftstats.use riftstats.create riftstats.reload Statistics Use Paper API statistics where possible. Track: - Player Kills - Deaths - Total Playtime Playtime should be displayed in: Days Hours Minutes Example: 1d 4h 37m Design Use MiniMessage gradients and modern colors. Theme: - Cyan - Blue - Purple - Gold accents Inventory should look premium with: - Animated title (optional) - Decorative borders - Clean spacing - High-quality icons - Professional lore formatting Performance - No memory leaks - Async leaderboard loading - Efficient caching - Optimized for servers with 500+ players - Minimal CPU usage Deliverables Generate the complete Maven project including: - src/ - pom.xml - plugin.yml - config.yml - messages.yml The project must compile without errors and produce a ready-to-use RiftStats.jar.

src/main/java/eu/codexe/riftstats/RiftStatsPlugin.java
package eu.codexe.riftstats;

import eu.codexe.riftstats.commands.StatsCommand;
import eu.codexe.riftstats.listeners.CitizensNpcListener;
import eu.codexe.riftstats.listeners.GuiListener;
import eu.codexe.riftstats.managers.ConfigManager;
import eu.codexe.riftstats.managers.GuiManager;
import eu.codexe.riftstats.managers.MessageManager;
import eu.codexe.riftstats.managers.StatsManager;
import eu.codexe.riftstats.storage.PlayerDataStorage;
import eu.codexe.riftstats.storage.YamlPlayerDataStorage;
import net.citizensnpcs.api.CitizensAPI;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;

public final class RiftStatsPlugin extends JavaPlugin {

    private ConfigManager configManager;
    private MessageManager messageManager;
    private PlayerDataStorage storage;
    private StatsManager statsManager;
    private GuiManager guiManager;
    private boolean citizensEnabled;

    @Override
    public void onEnable() {
        saveDefaultConfig();
        saveResource("messages.yml", false);

        this.configManager = new ConfigManager(this);
        this.messageManager = new MessageManager(this);
        this.storage = new YamlPlayerDataStorage(this);
        this.statsManager = new StatsManager(this, storage);
        this.guiManager = new GuiManager(this, statsManager, messageManager, configManager);

        this.citizensEnabled = Bukkit.getPluginManager().isPluginEnabled("Citizens") && CitizensAPI.getNPCRegistry() != null;

        getServer().getPluginManager().registerEvents(new GuiListener(guiManager), this);
        getServer().getPluginManager().registerEvents(new CitizensNpcListener(guiManager, messageManager), this);

        StatsCommand command = new StatsCommand(this, guiManager, messageManager, configManager, citizensEnabled);
        if (getCommand("stats") != null) {
            getCommand("stats").setExecutor(command);
            getCommand("stats").setTabCompleter(command);
        }

        statsManager.startTasks();
    }

    @Override
    public void onDisable() {
        if (statsManager != null) {
            statsManager.shutdown();
        }
    }

    public ConfigManager getConfigManager() {
        return configManager;
    }