Sueta

Zenith-Mod

1.2.7

Advanced moderation plugin with ban/mute systems, escalation templates, offline support, and Web-API integration for professional server management.

·Plugin
  1. 1.2.7latestZenith-Mod 1.2.7Mar 15, 2026

    Changelog

    Ban GUI - Completely remade the Ban GUI, fixing several bugs from the previous version - Added a Case-ID search feature — simply click the magnifying glass and type the ID in chat - Active bans now show in red, expired/unbanned players in green - Added a filter button to toggle between all bans, active only, or inactive only AutoMod - Added an AutoMod system that automatically detects and removes messages containing blacklisted words - Leetspeak detection included — things like 1d10t or i.d.i.o.t are caught automatically, you only need to add the base word to the list - Added an AntiSpam system that detects duplicate messages and message flooding - Staff alerts are sent in-game and to Discord when a message is blocked - Staff can toggle their own alerts with /automod alerts
    176 downloads
  2. 1.2.6Zenith-Mod 1.2.6Jan 30, 2026

    Zenith-Mod v1.2.6 Update

    🐛 Bug Fixes

    BanList GUI Critical Fixes
    This update fixes several critical issues in the BanList GUI module that could cause server crashes. #### Fixed Issues - Fixed: Critical crash when opening Ban Details GUI caused by invalid material name (HOURGLASS) - The material HOURGLASS does not exist in Minecraft/Bukkit API - Changed to CLOCK (the correct material name) - Added fallback handling for invalid material names throughout the module - Fixed: Material validation errors - All Material.valueOf() calls now include proper try-catch error handling - Invalid material names from configuration now fallback to safe defaults (PAPER, RED_CONCRETE) - Prevents IllegalArgumentException crashes when configuration contains invalid materials - Fixed: Pagination bounds checking - Improved index validation when clicking on ban items - Prevents IndexOutOfBoundsException when navigating between pages - Better handling of edge cases in pagination logic #### Technical Improvements - Added: Safe material name validation with fallback handling for all GUI items - Filter buttons, navigation buttons, action buttons, and info items all have fallback materials - Configuration errors no longer cause server crashes - Server continues to function even with invalid material names in config - Added: Enhanced slot bounds checking throughout the BanList module - All slot assignments now validate bounds before setting items - Prevents ArrayIndexOutOfBoundsException errors - Better error logging for configuration issues - Improved: Better error handling for invalid configuration values - Invalid slot numbers are safely ignored - Invalid material names use fallback materials - Configuration errors are logged but don't crash the server

    🚀 Velocity Plugin Available

    Zenith-Mod Velocity v1.2.5 is now also available! The Velocity version includes all the same features and bug fixes as the Bukkit version.

    📋 Compatibility

    - Fully backward compatible - No breaking changes - No configuration changes needed - Existing configs work as-is - No database migrations needed - Automatic database handling - Works with all database types - H2, SQLite, MySQL, MariaDB

    🔧 Technical Details

    Material Name Validation
    All GUI item creation now includes safe material validation:
    Material material;
    try {
        material = Material.valueOf(materialName);
    } catch (IllegalArgumentException e) {
        // Fallback to safe default
        material = Material.PAPER; // or appropriate fallback
    }
    This ensures that even if the configuration contains invalid material names (like HOURGLASS), the server will not crash and will use a safe fallback material instead.
    Slot Bounds Checking
    All slot assignments now validate bounds:
    if (slot >= 0 && slot < gui.getSize()) {
        gui.setItem(slot, item);
    }
    This prevents ArrayIndexOutOfBoundsException errors when configuration contains invalid slot numbers.

    📝 Configuration Notes

    If you're using custom material names in modules/banlist.yml, please ensure they are valid Minecraft material names. Common mistakes: - ❌ HOURGLASS → ✅ CLOCK - ❌ WOOL → ✅ WHITE_WOOL (or specific color) - ❌ STAINED_GLASS → ✅ WHITE_STAINED_GLASS (or specific color) For a complete list of valid material names, refer to the [Bukkit Material API documentation](https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/Mater…

    ⚠️ Important Notes

    - This update is highly recommended - Fixes critical crashes in the BanList GUI - No data loss - All existing bans and history entries remain intact - Automatic fallback - Invalid configurations are automatically handled with safe defaults - Error logging - Configuration errors are logged to help identify issues

    🔗 Links

    - Bukkit Version: [Download on Modrinth](https://modrinth.com/plugin/z-mod/versions) - Documentation: [Plugin Documentation](https://docs.zenith-studios.org/zenith-mod/introduction/) - API Documentation: [Java API Docs](http://javadocs.zenith-studios.org/) --- ⚠️ Recommendation: If you're using the BanList GUI feature, we strongly recommend updating to this version to prevent potential server crashes. Developed by Zenith-Studios
    56 downloads
  3. 1.2.5Zenith-Mod 1.2.5Jan 24, 2026

    Zenith-Mod v1.2.5 Update

    🎨 New: Ban List GUI (/banlist)

    - GUI-based ban overview with player heads - Click a ban to open a detail view - Unban directly from the GUI (permission-based) - Pagination + filters (Active/Expired, Player/IP, All)

    🛠️ Fixed

    - Fixed: A crash (ArrayIndexOutOfBoundsException) when opening the Ban Details GUI caused by invalid slot handling / config path mismatch.

    🌐 Velocity Plugin Available

    - The Zenith-Mod Velocity plugin is now available for proxy/network setups. Download on our Discord

    🔐 Permissions

    - zenith.banlist — Access /banlist - zenith.banlist.unban — Unban from the GUI --- Developed by Zenith-Studios
    46 downloads
  4. 1.2.4Zenith-Mod 1.2.4Jan 22, 2026

    Zenith-Mod v1.2.4 Update

    🎨 New Feature: Ban List GUI

    A powerful, interactive GUI system for managing bans! Zenith-Mod now includes a comprehensive ban list interface that makes it easier than ever to view, filter, and manage player bans directly from an in-game GUI.
    ✨ Key Features
    #### Interactive Ban List GUI - Visual Ban Overview: Browse all bans in a beautiful, organized GUI - Player Heads: See player avatars for each banned player - Detailed Information: View ban reason, staff member, case ID, date, duration, and status at a glance - Click to View Details: Click on any ban to see full information #### Advanced Filtering System - Active Bans: Filter to show only currently active bans - Expired Bans: View bans that have expired or been lifted - Player Bans: Filter to show only player-specific bans - IP Bans: Filter to show only IP-based bans - All Bans: View complete ban history #### Pagination Support - Navigate through large ban lists with ease - Page indicators show your current position - Smooth navigation between pages #### Quick Actions - Unban Directly from GUI: Unban players with a single click (requires permission) - Detailed View: Click any ban to see complete information including: - Player UUID and IP address - Full ban reason - Staff member details - Case ID - Ban date and duration - Current status (Active/Expired/Unbanned)
    🎯 Configuration
    The ban list GUI is fully configurable via modules/banlist.yml: - Customizable GUI Titles: Use hex colors and small caps formatting - Configurable Item Lore: Customize what information is displayed - Filter Button Positions: Arrange filter buttons as you prefer - Material Customization: Choose different materials for active/expired/IP bans - Variable Support: Use placeholders like {player_name}, {reason}, {case_id}, etc. - Color Utils Support: Full support for %smcaps% and hex colors (&#RRGGBB)
    🔐 Permissions
    - zenith.banlist - Access to /banlist command - zenith.banlist.unban - Unban players from the GUI
    📋 Usage
    Simply use the /banlist command to open the ban list GUI. From there, you can: 1. Browse all bans with pagination 2. Apply filters to narrow down results 3. Click on any ban to view detailed information 4. Unban players directly from the detail view (if you have permission)
    🎨 Customization Examples
    The ban list GUI supports extensive customization through the configuration file:
    gui:
      title: '&#00FFAA%smcaps%BAN LIST%smreset%'
      ban_item:
        name: '&#FF5555{player_name}'
        lore:
          - '&#AAAAAAReason: &#FFFFFF{reason}'
          - '&#AAAAAAStaff: &#FFFFFF{staff_name}'
          - '&#AAAAAACase ID: &#FFFFFF{case_id}'
    All text supports: - Hex colors (&#RRGGBB) - Small caps formatting (%smcaps%...%smreset%) - Variable placeholders ({player_name}, {reason}, etc.) - Standard Minecraft color codes
    🔧 Technical Details
    - Asynchronous Loading: Ban data is loaded asynchronously to prevent server lag - Session Management: Player sessions track current filter and page state - Efficient Filtering: Smart filtering system handles large ban lists efficiently - Thread-Safe: All GUI operations are properly synchronized
    📊 Integration
    The ban list GUI integrates seamlessly with: - Existing ban system - History tracking - Case ID system - Unban functionality - Staff notification system
    ⚠️ Breaking Changes
    None - This update is fully backward compatible. All existing commands and functionality work exactly as before.
    🔄 Migration Notes
    - No configuration changes required - The ban list module is enabled by default - New configuration file modules/banlist.yml will be created automatically - All existing bans are immediately visible in the GUI
    📝 Files Changed
    #### New Classes - me.kzlyth.modules.banlist.BanListModule - me.kzlyth.modules.banlist.BanListConfig - me.kzlyth.modules.banlist.gui.BanListGUI - me.kzlyth.modules.banlist.gui.BanDetailGUI - me.kzlyth.modules.banlist.gui.BanListGUIHandler - me.kzlyth.commands.admin.BanListCommand #### New Configuration - modules/banlist.yml - Complete GUI configuration #### Enhanced - ZenithMod - Added ban list module initialization - plugin.yml - Added /banlist command and permissions --- 🎉 Enjoy the new ban list GUI! This feature makes ban management more intuitive and efficient than ever before. 📢 Note: The ban list GUI requires players to have the zenith.banlist permission. Make sure to grant this permission to your staff members.
    50 downloads
  5. 1.2.3Zenith-Mod 1.2.3Oct 31, 2025

    Zenith-Mod v1.2.3 Update

    ⚠️ Beta Notice

    This update includes significant API additions that are currently in Beta. While we've thoroughly tested all features, please be aware that: - In very rare cases, API methods may behave unexpectedly - In very rare cases, events may not fire or fire incorrectly - API structure may undergo changes in future versions - We do not provide any warranty or guarantee regarding the API's functionality Use of the new API features is at your own risk. However, all core plugin functionality (commands, moderation, etc.) remains stable and fully supported.

    🚨 CRITICAL: Database Fix

    ⚠️ THIS UPDATE IS HIGHLY RECOMMENDED - CRITICAL DATABASE ISSUE FIXED This version fixes a critical database problem that could cause data inconsistency issues. We strongly recommend updating immediately, especially if you're using MySQL or MariaDB databases.
    What Was Fixed?
    - Fixed: Critical database transaction issue that could cause history entries to be incomplete - Fixed: Potential race condition in database operations that could lead to missing case IDs - Improved: Database connection handling and error recovery - Result: More reliable database operations and complete history tracking Note: If you experience any issues after updating, please check your database logs and ensure all migrations completed successfully.

    🎯 New API System (Beta)

    Zenith-Mod now includes a comprehensive Java API for developers to integrate with other plugins and extend functionality!
    📦 New API Modules
    #### FreezeAPI (me.kzlyth.api.freeze) - freeze(UUID, UUID, String) - Freeze a player with reason - unfreeze(UUID, UUID, String) - Unfreeze a player - isFrozen(UUID) - Check if player is frozen - getFrozenPlayers() - Get list of all frozen players - Automatic history logging with case IDs - Staff notifications for all freeze actions #### ChatFreezeAPI (me.kzlyth.api.chatfreeze) - freezeChat(UUID, String) - Freeze the server chat - unfreezeChat(UUID, String) - Unfreeze the server chat - isChatFrozen() - Check if chat is currently frozen - Server-wide chat control with history tracking - Automatic staff notifications #### EssentialsAPI (me.kzlyth.api.essentials) - God Mode: setGodMode(UUID, UUID, boolean), isGodMode(UUID) - Fly Mode: setFlyMode(UUID, UUID, boolean), isFlying(UUID) - Heal: heal(UUID, UUID) - Restore player health - Feed: feed(UUID, UUID) - Restore player hunger - Clear Inventory: clearInventory(UUID, UUID) - Clear player inventory - Teleport: teleport(UUID, UUID), teleportHere(UUID, UUID) - Teleport players - All methods include staff notifications #### VanishAPI (me.kzlyth.api.vanish) - vanish(UUID) - Make player invisible - unvanish(UUID) - Make player visible - toggleVanish(UUID) - Toggle vanish status - isVanished(UUID) - Check if player is vanished - getVanishedPlayers() - Get list of all vanished players - Automatic staff notifications
    🎪 Event System (Beta)
    A powerful event bus system for listening to moderation actions in real-time! #### Available Events - Ban Events: PlayerBanEvent, PlayerUnbanEvent - Mute Events: PlayerMuteEvent, PlayerUnmuteEvent - Warn Events: PlayerWarnEvent - Kick Events: PlayerKickEvent #### Event Packages - me.kzlyth.api.events.ban.* - Ban and unban events - me.kzlyth.api.events.mute.* - Mute and unmute events - me.kzlyth.api.events.warn.* - Warn events - me.kzlyth.api.events.kick.* - Kick events #### Features - Events fired after actions complete (for integrations and logging) - Complete event data (player info, staff info, reason, case ID, duration, etc.) - Automatic main-thread handling for safe Bukkit API access - Simple subscription/unsubscription system - Perfect for Discord webhooks, external databases, analytics, and plugin integrations
    📚 API Integration
    All new APIs are accessible through the main ZenithAPI class:
    ZenithAPI api = ZenithAPI.getInstance();
    if (api != null && api.isAvailable()) {
        FreezeAPI freezeAPI = api.getFreezeAPI();
        ChatFreezeAPI chatFreezeAPI = api.getChatFreezeAPI();
        EssentialsAPI essentialsAPI = api.getEssentialsAPI();
        VanishAPI vanishAPI = api.getVanishAPI();
        
        ZenithEventBus eventBus = ZenithEventBus.getInstance();
        eventBus.subscribe(PlayerBanEvent.class, event -> {
            // Handle ban event
        });
    }
    📖 Complete API Documentation
    For detailed API documentation, method signatures, parameters, and usage examples, visit: [http://javadocs.zenith-studios.org/](http://javadocs.zenith-studios.org/) The Javadoc includes: - Complete class and method documentation - Parameter descriptions and return types - Usage examples and best practices - Exception handling guides - Event system documentation

    ✅ Enhanced Existing APIs

    BanAPI Improvements
    - Fixed: Players are now automatically kicked when banned via API - Added: Staff notifications for all ban API calls - Improved: Better error handling and validation
    MuteAPI Improvements
    - Added: Staff notifications for all mute API calls - Improved: Better offline player handling
    WarnAPI Improvements
    - Added: Staff notifications for all warn API calls - Fixed: Auto-escalation now works correctly with API calls
    KickAPI Improvements
    - Added: Staff notifications for all kick API calls - Improved: Better integration with history system

    📊 Analytics Integration

    bStats Integration
    - Added: Integrated bStats metrics system for plugin analytics - Anonymous usage statistics to help us improve the plugin - Respects server privacy settings - Can be disabled via bStats configuration

    🔧 Technical Details

    API Architecture
    - Asynchronous Operations: All API methods use CompletableFuture for non-blocking operations - Thread Safety: Event bus automatically handles thread synchronization - Error Handling: Comprehensive exception handling with APIUnavailableException - History Integration: All API actions automatically create history entries with case IDs - Notification System: Automatic staff notifications for all moderation actions
    Database Improvements
    - Fixed critical transaction issues - Improved connection handling - Better error recovery mechanisms - Enhanced history entry consistency
    Performance
    - Asynchronous API calls prevent server lag - Event system optimized for high-throughput scenarios - Efficient database operations

    📋 Setup Instructions

    For Plugin Developers
    1. Add Zenith-Mod as a dependency in your plugin.yml:
    depend: [Zenith-Mod]
    2. Get the API instance:
    ZenithAPI api = ZenithAPI.getInstance();
    if (api != null && api.isAvailable()) {
        // Use API...
    }
    3. Subscribe to events:
    ZenithEventBus bus = ZenithEventBus.getInstance();
    bus.subscribe(PlayerBanEvent.class, event -> {
        // Handle event...
    });
    For complete setup instructions and examples, see the [API Documentation](http://javadocs.zenith-studios.org/).

    ⚠️ Breaking Changes

    None - This update is fully backward compatible. All existing commands and functionality work exactly as before.

    🔄 Migration Notes

    - No configuration changes required - No database migrations needed (automatic) - All existing bans, mutes, warns, and history entries remain intact - API is opt-in - existing plugins continue to work without changes

    📝 Files Changed

    New API Classes
    - me.kzlyth.api.freeze.FreezeAPI - me.kzlyth.api.chatfreeze.ChatFreezeAPI - me.kzlyth.api.essentials.EssentialsAPI - me.kzlyth.api.vanish.VanishAPI - me.kzlyth.api.events.ZenithEvent - me.kzlyth.api.events.ZenithEventBus - Event classes in me.kzlyth.api.events.* packages
    Enhanced Existing Classes
    - ZenithAPI - Added getters for new APIs - BanAPI - Added notifications and auto-kick - MuteAPI - Added
    138 downloads
  6. 1.2.2Zenith-Mod 1.2.2Oct 28, 2025

    Zenith-Mod v1.2.2 Release Notes

    Update Notification System & Critical Bug Fixes

    🔔 Update Notification System
    - Added: Automatic update checking for new plugin versions - Added: Players with zenith.update.notify permission get notified when a new version is available - Added: Clickable green "Modrinth" link that opens the download page - Features: - Async version checking via Modrinth API - Non-blocking update checks - Clean notification message with clickable link - Permission-based notification system (default: OP only) - Result: Staff members are automatically notified of new versions when joining the server
    🔓 Unmute System Fix
    - Fixed: active_case now correctly set to null after unmute (instead of unmute case ID) - Fixed: ip_muted status now properly cleared when unmuting IP-muted players - Fixed: IPMUTE recognition (without underscore) in unmute operations - Added: Support for both IP_MUTE and IPMUTE punishment types in unmute logic - Changed: updatePlayerMuteStatus now sets active_case to null instead of unmute case ID - Result: Unmuted players have correct status flags, allowing them to be muted again if needed
    ⏱️ IP-Mute Duration Display Fix
    - Fixed: "Unknown" or "Permanent" duration display for IP-muted players - Fixed: Correct remaining duration calculation for IP_MUTE and IPMUTE types - Changed: JSON parsing now supports both "expiry_time" and "expiryTime" formats - Changed: Staff notifications now show accurate remaining mute time for IP-muted players - Result: Staff see correct remaining time (e.g., "45 minutes") instead of "Unknown" or "Permanent"
    🎯 Offense Counter Fix
    - Fixed: Offense counting now works per template/reason instead of globally - Fixed: Different templates (e.g., "Doxx Threats", "Cheating") are counted separately - Changed: SQL query now filters by reason base (e.g., "Doxx Threats%") instead of all offenses - Changed: Template-based offense tracking prevents cross-template contamination - Result: Correct escalation levels per template (1st/2nd/3rd offense per specific reason)
    🚀 Player Join Optimization & Mute Command Fix
    - Fixed: "Player not found in database" error when muting freshly joined players - Fixed: Race condition between player join and mute commands - Changed: Intelligent player database handling on join (existing vs new players) - Changed: Synchronous database creation for new players to prevent race conditions - Changed: Asynchronous updates for existing players (last_seen, IP) for performance - Added: Fallback mechanism for database errors during player join - Result: Mute commands work immediately after player join, no more "not found" errors

    What Changed?

    Before:
    - ❌ No automatic update notifications for staff - ❌ Players had to manually check for new versions - ❌ active_case set to unmute case ID prevented re-muting players - ❌ ip_muted status not cleared after unmuting IP-muted players - ❌ Staff notifications showed "Unknown" or "Permanent" for IP-muted players - ❌ Duration calculation failed for IP_MUTE and IPMUTE types - ❌ JSON parsing only checked for "expiryTime" format - ❌ Offense counting was global across all templates - ❌ Different templates contaminated each other's offense counts - ❌ Players got wrong escalation levels (e.g., "2nd Offense" when it was their first) - ❌ "Player not found in database" error when muting freshly joined players - ❌ Race condition between player join and mute commands - ❌ All player joins used asynchronous database operations
    After:
    - ✅ Automatic update notifications when joining server - ✅ Clickable Modrinth link for easy download access - ✅ Permission-based notification system - ✅ active_case correctly set to null after unmute - ✅ ip_muted status properly cleared after unmuting IP-muted players - ✅ Both IP_MUTE and IPMUTE supported in unmute operations (I dont even know why I did IP_MUTE and IPMUTE in the first place 😭) - ✅ Accurate remaining duration shown in staff notifications - ✅ Supports both "expiry_time" and "expiryTime" JSON formats - ✅ Correct duration calculation for all mute types - ✅ Offense counting works per template/reason - ✅ Each template tracks offenses independently - ✅ Correct escalation levels per specific reason - ✅ Mute commands work immediately after player join - ✅ No more "Player not found in database" errors - ✅ Intelligent player database handling (existing vs new players) - ✅ Synchronous database creation for new players prevents race conditions

    Technical Details

    Update Notification System
    - UpdateChecker.java: New utility class for checking Modrinth API for updates - UpdateCheckListener.java: Event listener that checks for updates on player join - API Integration: Fetches version list from https://api.modrinth.com/v2/project/z-mod/version - Version Comparison: Semantic versioning comparison (MAJOR.MINOR.PATCH) - Notification: Adventure API message with clickable link using ClickEvent.OPEN_URL - Permission: zenith.update.notify (default: OP only) - Thread Safety: Async operations prevent blocking server thread
    Unmute System Fix
    - MuteManager.unmutePlayerWithCaseId(): Now checks for MUTE, IP_MUTE, and IPMUTE types - MuteManager.unmuteOfflinePlayerWithCaseId(): Same fixes for offline unmute operations - PlayerRepository.updatePlayerMuteStatus(): Sets active_case to null instead of unmute case ID - PlayerRepository.setIpMuted(): Clears ip_muted status when unmuting IP-muted players - Case ID Tracking: Original mute case ID stored in additional_data for audit trail - Discord Logging: Original case ID displayed in unmute embeds
    IP-Mute Duration Display Fix
    - MuteHandler.sendStaffNotificationForIpMutedChat(): Fixed JSON parsing for expiry time - JSON Parsing: Supports both "expiry_time" (underscore) and "expiryTime" (no underscore) - String Parsing: Proper extraction of expiry_time value from JSON strings - Duration Calculation: remainingSeconds = (expiryTime - currentTime) / 1000 - Format Display: Uses DurationParser.formatDuration() for readable time display - Punishment Type Support: Recognizes both IP_MUTE and IPMUTE types
    Offense Counter Fix
    - HistoryRepository.getOffenseCountByType(): Now filters by reason base instead of all offenses - Template Integration: Loads BanTemplate to get correct default reason for filtering - SQL Query: reason LIKE baseReason + "%" instead of reason LIKE "%(%" - Cross-Template Prevention: Different templates (e.g., "Doxx Threats", "Cheating") counted separately - Escalation Accuracy: Each template maintains independent offense counts - Backward Compatibility: Existing history entries remain unchanged
    Player Join Optimization & Mute Command Fix
    - PlayerJoinHandler.continueNormalJoinProcess(): Intelligent player database handling - PlayerRepository.updatePlayerLastSeenAndIp(): New method for updating existing players - Synchronous Database Creation: New players created synchronously to prevent race conditions - Asynchronous Updates: Existing players updated asynchronously for performance - MuteCommand.handleOfflineManualMute(): Online player detection prevents database lookup errors - Race Condition Prevention: Eliminates timing issues between join and mute commands - Fallback Mechanism: Graceful error handling with async fallback

    Compatibility

    Update Notification System
    - ✅ Fully backward compatible - ✅ No configuration required - ✅ Permission-based access control - ✅ Works with all server types (Paper/Purpur) - ✅ Graceful handling of API failures
    Unmute System
    - ✅ Fully backward compatible with existing unmutes - ✅ No database migration required - ✅ Works with all mute types (MUTE, IP_
    54 downloads
  7. 1.2.1Zenith-Mod 1.2.1Oct 27, 2025

    Zenith-Mod v1.2.1 Release Notes

    CRITICAL Bug Fixes

    🎭 Vanish Module - Fly State Preservation
    - Fixed: Fly mode is now properly restored when exiting vanish - Changed: Previous fly state (from EssentialsX /fly or Creative gamemode) is now saved and restored automatically - Result: Players can now fly again after exiting vanish if they had fly enabled before entering vanish - Technical: Added previousAllowFlight and previousFlying Maps to store and restore player fly states
    🔨 Ban/Mute Duration Fixes
    - Fixed: Permanent ban/mute now uses 0 duration instead of -1 for consistency - Fixed: Commands /ban player perm reason and /ban player 0 reason now correctly create permanent bans - Fixed: Player is no longer instantly unbanned when using duration "0" - Changed: Internal logic now treats 0 as permanent ban/mute across all systems - Result: Permanent bans now work correctly without instant unbans
    🔇 Mute Already Muted Player Error
    - Fixed: Better error messages when trying to mute already muted players - Changed: Now shows "Player is already muted!" instead of "Failed to mute offline player" - Result: Staff members get clear feedback when attempting to mute already muted players
    🔓 Unban Discord Logging & Case ID Display
    - Fixed: Unban actions now properly log to Discord channel when executed ingame - Fixed: Original case ID from ban is now displayed in Discord embed for unbans - Changed: Discord embed now shows the original ban case ID in "Original Case" field - Result: Staff can now track which ban was undone by each unban action
    🔓 Unmute Discord Logging & Case ID Display
    - Fixed: Unmute actions now properly log to Discord channel for both online and offline players - Fixed: Original case ID from mute is now displayed in Discord embed for unmutes - Changed: UnmuteCommand now properly waits for Discord logging to complete before showing success message - Result: Staff can now track which mute was undone by each unmute action, complete audit trail for mute/unmute workflow
    🚫 Ban Check Race Condition Fix
    - Fixed: Banned players can no longer join server during async ban check - Changed: Ban checking is now synchronous in AsyncPlayerPreLoginHandler to prevent race conditions - Result: Banned players are instantly blocked before they can join, no matter how fast they connect
    🔌 Discord Plugin Reload Fix
    - Fixed: "zip file closed" errors during plugin reloads no longer spam console - Changed: Added global exception handler in DiscordBot to catch and ignore expected "zip file closed" errors - Result: Clean console during Discord interactions after plugin updates, no error spam
    ⏰ Auto-Unban Expired Bans Fix
    - Fixed: Players with expired bans can now connect, ban status is automatically updated - Changed: Added automatic expiry check in AsyncPlayerPreLoginHandler for both regular and IP bans - Result: Expired bans are automatically deactivated when players try to join, no manual unban required
    📊 JSON Parsing Fix for Expired Bans
    - Fixed: Better JSON parsing for expiry_time in additional_data to correctly extract expiry timestamps - Changed: Now properly finds the end of the number value (either comma or closing brace) in JSON strings - Result: Expired bans are now correctly detected and auto-unbanned, no more parsing errors
    🖥️ Disconnect Screen - Real Ban Data Display
    - Fixed: Disconnect screen now shows real ban data instead of placeholders - Changed: Added handleIpBanWithData() and handlePlayerBanWithData() methods that load real ban information before disconnecting - Result: Players now see correct staff name, reason, remaining time, and case ID on disconnect screen
    ⏱️ Remaining Ban Time Calculation
    - Fixed: Disconnect screen now shows remaining ban time instead of original duration - Changed: Calculates remaining time from expiry_time in additional_data for both IP bans and regular bans - Result: Players see "2h 30m" instead of original "6h" ban duration on disconnect screen
    🔍 Orphaned IP Ban Fix
    - Fixed: Players with ip_banned=true but no active history entry are now allowed to connect - Changed: Added check for caseId <= 0 to detect orphaned ban status in players table - Result: Removes incorrect ip_banned flag when no active history entry exists, prevents false positives

    What Changed?

    Before:
    - ❌ Players lost ability to fly after exiting vanish - ❌ Creative mode flight disappeared after vanish - ❌ [EssentialsX](https://essentialsx.net/) /fly no longer worked after vanish - ❌ Permanent bans using "perm" or "0" didn't work correctly - ❌ Player was instantly unbanned when using duration "0" - ❌ Unclear error messages when trying to mute already muted players - ❌ Unban actions didn't log to Discord when executed ingame - ❌ Discord embeds didn't show which ban was undone - ❌ No way to track which case was reversed by an unban - ❌ Unmute actions didn't log to Discord for offline players - ❌ Original case ID not displayed in unmute embeds - ❌ Banned players could join server during async ban check (race condition) - ❌ "zip file closed" errors flooded console after plugin updates - ❌ Expired bans kept players blocked, required manual unban - ❌ ip_banned flag stayed true even after ban expiration - ❌ JSON parsing errors when checking expired ban expiry times - ❌ Disconnect screen showed "Admin", "N/A", "No expiration" instead of real ban data - ❌ Disconnect screen showed original ban duration instead of remaining time - ❌ Players with orphaned ip_banned=true flag couldn't connect
    After:
    - ✅ Players keep their original fly state after exiting vanish - ✅ Creative mode flight is preserved - ✅ [EssentialsX](https://essentialsx.net/) /fly continues working after vanish - ✅ Fly speed returns to normal (0.1f) - ✅ Permanent bans work correctly with both "perm" and "0" durations - ✅ Players stay banned when using permanent ban durations - ✅ Clear error messages when attempting to mute already muted players - ✅ All unban actions log to Discord (both ingame and Discord bot) - ✅ Discord embed shows original ban case ID - ✅ Complete audit trail for ban/unban workflow - ✅ Staff can see which specific ban was reversed - ✅ All unmute actions log to Discord (both online and offline players) - ✅ Discord embed shows original mute case ID for unmutes - ✅ Complete audit trail for mute/unmute workflow - ✅ Banned players are instantly blocked, no race condition possible - ✅ Clean console during plugin reloads, no "zip file closed" spam - ✅ Expired bans are automatically removed, players can reconnect - ✅ Ban status flags are updated when bans expire - ✅ JSON expiry time parsing works correctly, no more parsing errors - ✅ Disconnect screen shows real staff name, reason, remaining time, and case ID - ✅ Disconnect screen shows remaining ban time instead of original duration - ✅ Orphaned ban statuses are automatically cleaned up

    Technical Details

    Vanish Module
    - Vanish Entry: System now stores current allowFlight and isFlying state before enabling vanish flying - Vanish Exit: System restores the exact previous fly state (including EssentialsX /fly or Creative mode) - Storage: Uses HashMap<UUID, Boolean> to track previous fly states per player
    Duration System
    - DurationParser: Changed permanent ban/mute from -1 to 0 for consistency - BanManager/MuteManager: Updated all -1 checks to use 0 for permanent bans - Validation: Both "perm" and "0" are now treated as permanent ban/mute durations - Expiry Time: Changed from expiryTime = -1 to expiryTime = 0 for permanent punishments
    Error Handling
    - MuteCommand: Added check for caseId == -1 to detect already muted players - Error Messages: Improved messaging to distinguish between "
    36 downloads
  8. 1.2.0Zenith-Mod 1.2.0Oct 27, 2025

    Zenith-Mod v1.2.0 Release Notes

    Performance & UX Improvements

    ⚡ Instant Ban Disconnect
    - Fixed: Players are now instantly kicked during login without waiting for database queries - Improved: Disconnect screen shows immediately for banned players - Changes: Ban checks now happen in AsyncPlayerPreLoginEvent with instant kick, while history details load asynchronously in background - Result: No more delays when banned players try to join - connection is rejected immediately
    ⚡ Instant Kick Command
    - Fixed: /kick command now executes immediately without any delay - Removed: 20-tick (1 second) delay that was previously added - Improved: Kick disconnect screen appears instantly for kicked players - Changes: History entry is now created asynchronously after the kick, not blocking the kick execution - Result: Staff can instantly kick players without waiting for database operations
    🗄️ Full Database Compatibility
    - Fixed: SQLite syntax errors in all repository files - Added: Proper SQL syntax for all database types (SQLite, MySQL, MariaDB, H2) - Changed: All repository files now use database-specific AUTO_INCREMENT syntax - Changed: UPSERT operations now use database-specific syntax (ON DUPLICATE KEY UPDATE for MySQL/MariaDB, INSERT OR REPLACE for SQLite/H2) - Result: Plugin now works seamlessly with SQLite, MySQL, MariaDB, and H2 databases
    ⚙️ Configuration Improvements
    - Fixed: config.yml is now truly read-only and never overwritten by the system - Changed: Plugin now stops immediately if database connection fails (no automatic fallback) - Result: User database settings are preserved exactly as configured

    What Changed?

    Before:
    - ❌ Banned players could briefly connect before being kicked - ❌ Kick command had a 1-second delay - ❌ Server had to wait for database queries before kicking - ❌ SQLite databases caused syntax errors - ❌ config.yml was sometimes overwritten by the system - ❌ Plugin tried to fallback to different databases when connection failed
    After:
    - ✅ Banned players are rejected immediately at login - ✅ Kick command executes instantly - ✅ Database operations happen in background without affecting user experience - ✅ SQLite works perfectly with proper syntax - ✅ config.yml is truly read-only - ✅ Plugin stops gracefully on database connection failure (respects user configuration)

    Technical Details

    - Ban Handler: Optimized AsyncPlayerPreLoginHandler to kick players instantly with default message, then load actual ban details asynchronously - Kick Manager: Removed blocking .join() calls and runTaskLater delay, now kicks immediately - Database Operations: All history entries and Discord logs now happen asynchronously without blocking user operations - SQLite Support: Fixed AUTO_INCREMENT syntax in all 6 repository files (History, Player, AltLimit, Notes, Warn, RequestLog) - UPSERT Operations: Database-specific syntax for insert-or-update operations - Config Protection: config.yml is now read-only at save time to prevent system overwrites - Database Failures: Plugin stops gracefully when connection fails instead of automatic fallback

    Compatibility

    - ✅ Fully backward compatible - ✅ No configuration changes required - ✅ All existing bans/kicks continue to work normally - ✅ Works with all database types (H2, SQLite, MySQL, MariaDB) --- Note: This version focuses on performance and user experience improvements, ensuring instant feedback for moderation actions.
    32 downloads
  9. 1.1.9Zenith-Mod 1.1.9Oct 27, 2025

    Zenith-Mod v1.1.9 - Bug Fixes & Improvements

    🐛 Critical Fixes

    Fixed YAML Configuration Auto-Formatting
    Issue: Module configuration files (ban.yml, mutes.yml, etc.) were being auto-formatted by the plugin, causing line breaks in long strings and breaking the YAML syntax. Problem: The plugin was loading module configs into a global map and then saving them during saveAllConfigs(), which triggered Bukkit's YAML formatter to add unwanted line breaks for strings longer than ~80 characters. Fix: - Module configuration files are now read-only - Only config.yml and messages.yml are saved by the plugin - Module configs are loaded fresh from disk each time they're accessed - Prevents automatic formatting and preserves your custom YAML structure Impact: Your module configuration files will no longer be modified by the plugin, preserving their original formatting and structure.
    Fixed Staff Notification Duration Display
    Issue: Staff notifications for muted players showed "Unknown" as duration instead of the actual remaining mute time. Problem: The code was using blocking .get() calls and only checking for "MUTE" punishment type, missing "IP_MUTE" entries. Fix: - Converted blocking calls to async thenAcceptAsync() handlers - Added support for both "MUTE" and "IP_MUTE" punishment types in notification checks - Proper async handling prevents thread blocking and ensures duration is calculated correctly - Staff notifications now display accurate remaining mute times Impact: Staff will now see correct mute durations in chat attempt notifications for both regular and IP mutes.
    Fixed Discord Command Interaction Timeouts
    Issue: Discord slash commands were timing out with "Unknown interaction" errors after 3 seconds. Problem: The /getinfo command was using blocking .get() calls on database queries, preventing Discord from receiving an immediate acknowledgment. Fix: - Converted blocking database calls to async CompletableFuture chains - Created getPlayerDataAsync() method that returns CompletableFuture<PlayerData> - Removed all blocking .get() calls from Discord command handlers - Discord interactions now respond within the required 3-second window Impact: Discord commands will no longer timeout, providing a smoother experience for staff members using the Discord bot.
    Fixed Discord Dropdown Interaction Timeouts
    Issue: History dropdown interactions in Discord were timing out with "zip file closed" errors. Problem: The HistoryDropdownHandler was using .thenAccept() instead of .thenAcceptAsync(), which could cause thread blocking during database operations. Fix: - Converted .thenAccept() to .thenAcceptAsync() in both outer and inner chains - Ensures proper async handling for all database queries - Prevents "zip file closed" errors during plugin reloads - All Discord dropdown interactions now complete without timing out Impact: Discord dropdown menus for history entries will no longer timeout or cause errors, providing a seamless experience for staff.
    Fixed Mute Duration Display in Staff Notifications
    Issue: Staff notifications for muted players showed "0 seconds" instead of the actual remaining mute time. Problem: The code was checking for "expiryTime" in JSON data, but the database stores it as "expiry_time" (with underscore). Fix: - Updated code to check for both "expiry_time" and "expiryTime" for backward compatibility - Added debug logging to track duration calculations - Proper JSON parsing now retrieves the correct expiry time - Duration is now calculated and displayed accurately Impact: Staff will see correct mute durations like "2 hours, 15 minutes" instead of "0 seconds".
    Added Knockback Prevention for Vanished Players
    Issue: Vanished players still received knockback when hit, making their vanished status obvious to others. Solution: Implemented knockback prevention using Paper's native EntityKnockbackEvent API. Features: - Vanished players no longer receive knockback when damaged - Uses Paper's native event system for optimal performance - Simple event cancellation - no workarounds needed - All sources of knockback are blocked (melee, ranged, explosions, etc.) Impact: Vanished players remain completely invisible, making staff investigations undetectable.
    Fixed Template Escalation NullPointerException
    Issue: Using ban/mute templates without proper configuration caused crashes with NullPointerException. Problem: Templates could be missing escalation or durations fields in configuration, causing crashes when the code tried to access them. Fix: - Added null checks for escalation configuration before accessing it - Added null checks for durations list before accessing it - Templates with missing fields now use sensible defaults instead of crashing - Added warning logs when default values are used Impact: The plugin will no longer crash when using templates with incomplete configuration, improving stability.
    Fixed IP Ban JSON Format
    Issue: IP ban entries in database had incomplete JSON in additional_data field (missing closing brace). Problem: When creating IP ban history entries for offline players, the JSON string was incomplete, causing parsing errors. Fix: - Added missing "ip" field to IP ban JSON for offline players - Ensured all JSON objects are properly formatted with closing braces - Both online and offline IP bans now store complete JSON data Impact: IP ban data is now properly stored and can be correctly parsed for duration calculations and case management.
    Fixed Ban Join Notification Duration Display
    Issue: Staff notifications for banned players trying to join showed "Permanent" even for temporary bans. Problem: The code was not calculating the remaining ban duration correctly from the expiry time stored in additional_data JSON. Fix: - Implemented proper remaining duration calculation from expiry_time in JSON - Added fallback to original duration if expiry time parsing fails - Properly handles permanent bans (duration <= 0) - Both IP bans and normal bans now show correct remaining time Impact: Staff will now see accurate ban durations in join attempt notifications, making it easier to track when players can return.
    Fixed Template Escalation and Disconnect Screen Duration Display
    Issue: Template bans showed incorrect escalation levels and disconnect screen showed "Permanent" instead of actual duration. Problem: - Template escalation was looking for wrong reason pattern in database - Disconnect screen was parsing already-formatted duration strings (e.g., "3 hours") instead of using them directly - Template name was being passed instead of template key/identifier - OR clause in offense count query was preventing proper offense counting Fix: - Simplified offense count query to search for offense suffix pattern %(% in reason field - Removed unnecessary duration parsing in disconnect screen (duration is already formatted) - Changed template processing to use template key instead of display name - Added debug logging to track offense counts - Disconnect screen now displays correct ban duration (e.g., "Unbanned in: 3 hours") Impact: Template bans now properly escalate (1st offense → 2nd offense) and show correct duration on disconnect screen.
    Fixed Vanish Module AsyncCatcher Error
    Issue: Vanish module caused "Thread ForkJoinPool.commonPool-worker-5 failed main thread check" errors when applying vanish effects during player join. Problem: The handlePlayerJoin() method in VanishModule was applying vanish effects (hiding players) from an async thread, but Bukkit's hidePlayer() operation must run on the main thread. Fix: - Wrapped vanish effect application in Bukkit.getScheduler().runTask() to ensure it runs on main thread - All vanish-r
    33 downloads
  10. 1.1.8Zenith-Mod 1.1.8Oct 26, 2025

    Zenith-Mod v1.1.8 - Critical Bug Fixes

    🐛 Critical Fix

    Fixed Offense Counting Bug
    Issue: Players were incorrectly getting "2nd offense" when they should have gotten "1st offense", even though another player from a different IP was banned. Fix: The offense counting now properly tracks by IP address or player UUID based on the template's track_by_ip setting: - IP-based tracking: All players from the same IP share the same offense count - UUID-based tracking: Each player has their own separate offense count - Result: Escalation levels now correctly apply per player/IP group Impact: Ban durations now correctly reflect the actual offense count for each player or IP address.

    🚀 Database Improvements

    Auto-Increment ID Support
    - All database tables now have AUTO_INCREMENT IDs - Works for MySQL, MariaDB, H2, and SQLite - Automatic migration for existing databases

    🔧 Technical Details

    History Repository Fix
    - Fixed offense counting to use proper WHERE clauses - Now filters by target_ip or target_uuid based on tracking key - Properly tracks escalation levels per player/IP group --- Version: 1.1.8
    40 downloads
  11. 1.1.7Zenith-Mod 1.1.7Oct 26, 2025

    Zenith-Mod v1.1.7 - Template Identifier Validation

    🚀 What's Changed

    Templates now require the identifier (YAML key) instead of display names.
    ✅ Before & After
    ❌ Before: /ban Player "Bug Abuse" ✅ Now: /ban Player bug-abuse
    🎯 What You Need to Know
    When using a display name, you'll get a helpful error message:
    You entered the display name 'Bug Abuse' instead of the identifier!
    Please use the identifier: bug-abuse
    This applies to both Ban and Mute templates.
    ⚙️ Configuration
    Display names can now include spaces in the name field:
    bug-abuse:
      name: "Bug Abuse"  # ← Spaces allowed!
      description: "Ban template for bug abuse"
      auto_ip_ban: true
      # ...
    Use the YAML key (bug-abuse) in commands, not the display name. --- Version: 1.1.7 | Date: January 15, 2025
    30 downloads
  12. 1.1.6Zenith-Mod 1.1.6Oct 26, 2025

    Zenith-Mod v1.1.6 - First Release

    A comprehensive and professional moderation plugin for Paper servers with advanced player management tools, database persistence, and modern architecture.

    🚀 What is Zenith-Mod?

    Zenith-Mod is a complete moderation solution designed for modern Paper servers. Built with performance and scalability in mind, it provides everything you need to manage your community professionally.

    ✨ Features

    🎯 Core Moderation Systems
    - Advanced Ban System - Complete ban management with IP bans, temporary/permanent bans, and escalation templates - Mute System - Chat muting with command blocking, offline player support, and template-based escalation - Warning System - Comprehensive warning management with escalation levels and automatic punishments - Freeze System - Player freezing with configurable restrictions and notifications
    🔧 Template System
    - Pre-configured punishment templates with automatic escalation - Track offenses by player UUID or IP address - Customizable duration levels and reason suffixes - Template-specific permissions for staff members
    💻 Offline Player Support
    - Mute, ban, and warn players even when they're offline - Automatic player creation in database for offline operations - Complete audit trail with case IDs for all actions
    📊 Advanced Player Management
    - Alt Detection & Limiting - Automatic detection of alt accounts and configurable limits per IP - History System - Complete moderation history with case IDs and audit trails - Note System - Staff notes for players, invisible to players - Player Info System - Real-time player information and status checks
    🎨 Vanish System
    - Complete invisibility from other players - Hides from tab list, player list, and nametags - Prevents damage, block interactions, and item pickup - Auto god-mode and flight for vanished players - Permission-based visibility control
    ⚡ Performance Optimized
    - Zero thread blocking with async operations - Async database queries throughout - Hot-reload configuration without server restart - Custom logging system with colored console output
    🚨 Staff Notifications
    - Real-time notifications for moderation events - Banned player join attempts - Muted player chat attempts - Permission-based notification system
    🔗 Web-API Integration (Premium)
    - RESTful API for external integrations and web panels - Token-based authentication system - Real-time server statistics and player management - License validation for premium features
    🎮 Discord Integration (Beta)
    - Discord slash commands for moderation - Ban, mute, and player management via Discord - Real-time moderation from Discord - Discord embed notifications - ⚠️ Currently in BETA - use with caution

    📁 Modular Configuration

    The plugin uses a modular configuration system for easy customization:
    Core Configuration
    - config.yml - Main plugin configuration, database settings, and general options - messages.yml - Customizable messages, notifications, and placeholder support
    Module Configurations
    - modules/ban.yml - Ban system with templates and escalation - modules/mutes.yml - Mute system with chat blocking - modules/warn.yml - Warning system - modules/freeze.yml - Player freeze system - modules/kick.yml - Kick system - modules/notes.yml - Staff notes system - modules/essentials.yml - Essential commands - modules/gamemodes.yml - Gamemode management - modules/vanish.yml - Vanish system - modules/limiter.yml - Alt detection and limiting - modules/client-detector.yml - Client detection - modules/chat-freeze.yml - Chat freeze system - modules/history.yml - History tracking - modules/check.yml - Player check system - modules/web-api.yml - Web-API configuration - modules/discord/discord-bot.yml - Discord bot configuration (BETA)

    🛠️ Requirements & Compatibility

    ✅ Tested On
    - Paper 1.21.4 (Primary development and testing version)
    ⚠️ Compatibility Rating
    - Paper 1.21.4+: ✅ Fully supported and tested - Paper 1.21.0-1.21.3: ✅ Very likely compatible - Paper 1.20.x: ✅ Very likely compatible - Paper 1.19.4: ⚠️ Probably compatible - Paper 1.19.0-1.19.3: ⚠️ May work with minor issues - Paper 1.18.x and older: ❌ Unlikely to work - Spigot: ⚠️ Partially supported (some features may not work)
    🚀 Future-Proof Design
    - No Deprecated APIs: This plugin uses only current, non-deprecated Bukkit/Paper APIs - Modern Architecture: Built with latest Paper Plugin system and async operations - Stable Dependencies: Uses only stable, long-term supported features - Forward Compatible: Designed to work with future Paper versions - Clean Code: No legacy code or deprecated methods that could break in future updates
    🚫 Not Supported
    - Custom Paper Forks - Use at your own risk, no support provided - PlugMan - Do not use PlugMan to load this plugin (Paper plugins not supported) - Bukkit - Requires Paper/Spigot API features

    📦 Database Support

    Supported Databases
    - H2 (Embedded - Default, perfect for single-server setups) - SQLite (File-based, great for small servers) - MySQL (Network database, ideal for multi-server setups) - MariaDB (Network database, MySQL alternative)
    Features
    - HikariCP connection pooling for optimal performance - Automatic database initialization - Async database operations throughout - Migration support for future updates

    📝 Changelog (v1.1.6)

    Fixed
    - Alt Limit System: Fixed critical bug where players could bypass alt limits - Proxy Support: Added Velocity/BungeeCord IP forwarding support - Performance: Removed thread blocking in CommandBlocker and Discord commands
    Added
    - Proxy Detection: Automatic IP detection from proxy servers - Debug Logging: Enhanced IP detection with detailed logging - Performance Optimizations: Async operations throughout
    Changed
    - CommandBlocker: Now uses async operations, no more thread blocking - MuteSlashCommand: Optimized async handling to prevent "zip file closed" errors - IPUtils: Added Velocity proxy support with reflection-based IP detection

    🎯 Getting Started

    1. Download the latest version from Modrinth 2. Place the JAR file in your plugins/ folder 3. Restart your server 4. Configure the plugin in plugins/Zenith-Mod/ 5. Set up your database in config.yml 6. Customize messages in messages.yml 7. Configure modules in modules/ directory

    📞 Support & Resources

    - Discord: [Zenith Studios Discord](https://discord.gg/2qCMn6KHj4) - Documentation: [Zenith-Mod](https://docs.zenith-studios.org/docs/zenith-mod/)

    ⚠️ Important Notes

    Discord Integration (BETA)
    - Discord slash commands are currently in BETA - Use with caution in production environments - Report any issues on Discord - Configuration available in modules/discord/discord-bot.yml
    Permissions
    - All permissions are documented in plugin.yml - Use LuckPerms or your preferred permission manager - Template permissions follow pattern: zenith.[action].template.[name]
    Performance
    - All database operations are async - No thread blocking in moderation commands - Built-in connection pooling for optimal performance - Hot-reload with /zenith reload command

    🎉 Ready to Get Started?

    Zenith-Mod is the complete moderation solution you've been waiting for. Download now and revolutionize your server's moderation system! --- Version: 1.1.6 Release Date: January 14, 2025 Platform: Paper 1.21.4+ --- Made with ❤️ by Zenith Studios
    53 downloads

Similar projects

Plugin →