
Zenith-Mod
Advanced moderation plugin with ban/mute systems, escalation templates, offline support, and Web-API integration for professional server management.
Список изменений
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.ymlandmessages.ymlare 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
CompletableFuturechains - Created
getPlayerDataAsync()method that returnsCompletableFuture<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
escalationconfiguration before accessing it - Added null checks for
durationslist 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_timein 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-related operations (hidePlayer, setInvulnerable, setAllowFlight, etc.) now execute on the main thread
Impact: Vanish module no longer causes thread errors, providing a smoother experience for staff members using vanish.
Fixed Discord Unban Command Not Recognizing IP Bans
Issue: Discord /unban command incorrectly reported "Player is not banned" for IP-banned players, even when they were clearly banned in the database.
Problem: The command was only checking playerData.isBanned() (regular ban status) and not checking playerData.isIpBanned() (IP ban status), causing IP-banned players to be rejected.
Fix:
- Updated ban status check to include both
isBanned()andisIpBanned() - Players with either regular ban or IP ban can now be unbanned via Discord
- Consistent with in-game
/unbancommand which checks both ban types
Impact: Staff can now unban IP-banned players via Discord without receiving false "not banned" errors.
Fixed Disconnect Screen Showing Wrong Remaining Duration
Issue: Disconnect screen showed the original ban duration (e.g., "Unbanned in: 3 hours") instead of the actual remaining time (e.g., "Unbanned in: 20 minutes").
Problem: The code was using durationSeconds (original duration) instead of remainingDuration when creating the disconnect screen message.
Fix:
- Calculate remaining duration from
expiry_timeinadditional_dataJSON - Use remaining duration for both
durationDisplayanduntilMessage - Works for both IP bans and regular bans
- Works for both new bans and existing bans stored in the database
Impact: Banned players now see accurate remaining ban time on disconnect screen. For example, if they were banned for 3 hours 40 minutes ago, they'll see "Unbanned in: 20 minutes" instead of "Unbanned in: 3 hours". This fix applies to all bans, including existing ones in your database.
Fixed Vanish Module Not Hiding Players for New Joiners
Issue: When a normal player joins the server while a staff member is vanished, the normal player could see the vanished staff member in both the world and the tab list.
Problem: The handlePlayerJoin() method wasn't properly hiding already-vanished players from new joiners. It only handled the case when the joining player was vanished, not when other players were already vanished.
Fix:
- Added loop to hide all vanished players from new joiners without see permission
- Ensures vanished players are hidden in both world and tab list for new players
- Added proper tab name hiding with
playerListName(Component.empty()) - Runs on main thread with slight delay to ensure proper player loading
Impact: Vanished staff members are now completely invisible to normal players, both in the world and in the tab list. This applies to both newly vanished players and already-vanished players.
Fixed Discord Logging for All Ban Operations
Issue: Not all ban and unban operations were being logged to Discord channels.
Problem: The banOfflinePlayerWithCaseId() and ipBanOfflinePlayerWithCaseId() methods were missing Discord logging calls, causing offline bans to not appear in Discord.
Fix:
- Added Discord logging to
banOfflinePlayerWithCaseId()for offline player bans - Added Discord logging to
ipBanOfflinePlayerWithCaseId()for offline IP bans - All ban operations (online/offline, normal/IP) now log to Discord consistently
- All unban operations were already logging correctly
Impact: All ban and unban operations are now consistently logged to Discord channels, providing complete audit trails for staff.
Fixed IP_BAN / IPBAN Inconsistency
Issue: Sometimes "IPBAN" was stored instead of "IP_BAN", causing inconsistencies in database queries.
Problem:
- Inconsistent use of "IP_BAN" (with underscore) and "IPBAN" (without underscore)
- Some methods stored "IPBAN" while others searched for "IP_BAN"
- This caused queries to fail finding existing bans
Fix:
- Standardized to use "IP_BAN" (with underscore) throughout the codebase
- Added backward compatibility: queries now search for both "IP_BAN" and "IPBAN"
- Updated
getActiveBanOrMuteCaseId()to support both formats - Updated
deactivateIpBans()to support both formats - All new IP bans now consistently store "IP_BAN"
Impact: All IP ban queries now work correctly regardless of whether old entries use "IPBAN" or new entries use "IP_BAN".
📋 What You Need to Know
- Module configs are read-only: The plugin will never modify
modules/*.ymlfiles - Manual editing only: You can edit module configs directly in a file editor
- No auto-reformatting: Long strings won't be broken into multiple lines anymore
- Better async performance: Staff notifications no longer block the main thread
- No Discord timeouts: Discord slash commands respond instantly without blocking database queries
- No dropdown errors: History dropdown interactions complete successfully without "zip file closed" errors
- Accurate mute durations: Staff notifications now show correct remaining mute times
- Perfect vanish: Vanished players no longer reveal their presence through knockback
- Stable templates: Templates work even with incomplete configuration
- Correct ban durations: Staff join notifications show accurate remaining ban times
- Complete ban data: IP ban entries are properly stored with all information
- Working template escalation: Template bans now properly count offenses and escalate duration
- No vanish errors: Vanish module no longer causes thread errors on player join
- Discord unban works: Discord unban command now recognizes both regular and IP-banned players
- Accurate disconnect durations: Disconnect screen now shows actual remaining ban time, not original duration
- Complete vanish for new joiners: Vanished players are now properly hidden from players joining the server
- Complete Discord logging: All ban and unban operations are now logged to Discord channels
- IP ban consistency: All IP ban queries work correctly regardless of old or new format
Version: 1.1.9
