Tags
Creators
Details
Licensed Apache-2.0
Published last year
Updated 7 months ago
All versions
1.2.1
Release
Zenith-Mod 1.2.1last year 36
Uploaded by
Compatibility
Minecraft: Java Edition
1.21–1.21.10
1.20.x
1.19.4
Platforms
Paper
Purpur
Changes
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
/flyor 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
previousAllowFlightandpreviousFlyingMaps to store and restore player fly states
🔨 Ban/Mute Duration Fixes
- Fixed: Permanent ban/mute now uses
0duration instead of-1for consistency - Fixed: Commands
/ban player perm reasonand/ban player 0 reasonnow correctly create permanent bans - Fixed: Player is no longer instantly unbanned when using duration "0"
- Changed: Internal logic now treats
0as 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
AsyncPlayerPreLoginHandlerto 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
DiscordBotto 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
AsyncPlayerPreLoginHandlerfor 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_timeinadditional_datato 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()andhandlePlayerBanWithData()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_timeinadditional_datafor 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=truebut no active history entry are now allowed to connect - Changed: Added check for
caseId <= 0to detect orphaned ban status in players table - Result: Removes incorrect
ip_bannedflag 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
/flyno 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_bannedflag stayedtrueeven 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=trueflag couldn't connect
After:
- ✅ Players keep their original fly state after exiting vanish
- ✅ Creative mode flight is preserved
- ✅ EssentialsX
/flycontinues 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
allowFlightandisFlyingstate before enabling vanish flying - Vanish Exit: System restores the exact previous fly state (including EssentialsX
/flyor Creative mode) - Storage: Uses
HashMap<UUID, Boolean>to track previous fly states per player
Duration System
- DurationParser: Changed permanent ban/mute from
-1to0for consistency - BanManager/MuteManager: Updated all
-1checks to use0for permanent bans - Validation: Both "perm" and "0" are now treated as permanent ban/mute durations
- Expiry Time: Changed from
expiryTime = -1toexpiryTime = 0for permanent punishments
Error Handling
- MuteCommand: Added check for
caseId == -1to detect already muted players - Error Messages: Improved messaging to distinguish between "already muted" and "player not found" errors
Discord Logging
- UnbanCommand: Added Discord logging after successful unban history creation
- UnmuteCommand: Fixed to properly wait for async unmute operations and Discord logging
- MuteManager: Added Discord logging for offline unmute operations
- Embed Display: Added regex parsing to extract
original_case_idfromadditional_data - Field Display: Shows "Original Case: #123" in Discord embed for unbans and unmutes
- Case ID Tracking:
additional_dataJSON now includesoriginal_case_idfield for complete audit trail
Ban Check Race Condition
- AsyncPlayerPreLoginHandler: Changed from async
.thenAccept()to synchronous.get()calls - IP Ban Check: Now uses
playerRepository.isIpBanned(playerIp).get()for synchronous check - Player Ban Check: Now uses
playerRepository.getPlayerByUuid(uuid).get()for synchronous check - Result: Banned players are blocked immediately, preventing them from joining during database query
Discord Plugin Reload Handler
- DiscordBot.onException(): Added global exception handler to catch
IllegalStateExceptionwith "zip file closed" message - Error Filtering: Only ignores expected "zip file closed" errors during plugin reloads, logs other exceptions normally
- Result: Clean console output during Discord interactions after plugin updates
Auto-Unban Expired Bans
- AsyncPlayerPreLoginHandler: Added expiry check for both regular bans and IP bans before blocking connection
- Expiry Detection: Parses
expiry_timefromadditional_datato determine if ban has expired - Active Status Check: First checks if history entry exists and is
active = truein history table - Automatic Cleanup: Updates
banned/ip_bannedflags tofalseand deactivates history entry when ban expires or is not active - deactivateCase(): New method in
HistoryRepositoryto deactivate history entries by case ID - Result: Expired bans are automatically removed when players try to join, eliminating need for manual unban
JSON Parsing for Expiry Time
- AsyncPlayerPreLoginHandler: Improved JSON parsing logic to correctly extract
expiry_timefromadditional_data - Parsing Logic: Now finds the end of the number value by looking for comma
,or closing brace} - String Extraction: Properly extracts just the timestamp number without extra JSON content
- Error Handling: Catches parsing errors and logs them without blocking ban checks
- Result: Expired bans are now correctly detected and auto-unbanned without parsing errors
Disconnect Screen Improvements
- handleIpBanWithData(): New method that loads real IP ban data synchronously before disconnecting
- handlePlayerBanWithData(): New method that loads real player ban data synchronously before disconnecting
- Real Data Display: Shows actual staff name, reason, and case ID from history entry instead of placeholders
- Remaining Time: Calculates remaining ban time from
expiry_timeinadditional_datafor accurate duration display - Data Sources: Uses
historyEntry.getStaffName(),historyEntry.getReason(), and formatted remaining seconds - Result: Players see accurate ban information on disconnect screen, not "Admin" or "N/A"
Orphaned Ban Cleanup
- AsyncPlayerPreLoginHandler: Added check for
caseId <= 0to detect orphaned ban status - Detection: When
ip_banned=truein players table but no active history entry exists - Automatic Removal: Sets
ip_bannedtofalseand allows connection if no case found - Prevention: Prevents false positives from database inconsistencies
- Result: Players with orphaned ban status can now connect, system auto-cleans inconsistent data
Compatibility
Vanish Module
- ✅ Fully backward compatible
- ✅ Works with EssentialsX
/flycommand - ✅ Works with Creative mode flying
- ✅ Works with any other plugin that modifies allowFlight/flying
- ✅ No configuration changes required
Ban/Mute System
- ✅ Fully backward compatible with existing permanent bans (converts
-1to0internally) - ✅ Supports both "perm" and "0" as permanent ban/mute durations
- ✅ Clear error messages for staff when attempting to mute already muted players
- ✅ No database migration required
Unban/Unmute System
- ✅ Fully backward compatible with existing unbans and unmutes
- ✅ Works with both regular bans and IP bans
- ✅ Works with both regular mutes and IP mutes
- ✅ Complete audit trail for ban/unban and mute/unmute workflows
- ✅ Discord embeds show historical case IDs for both unbans and unmutes
Discord Reload Handling
- ✅ Gracefully handles plugin reloads without error spam
- ✅ Old Discord interactions silently fail during reload
- ✅ No console spam from expected "zip file closed" errors
- ✅ New plugin instances work seamlessly after reload
Expired Ban Handling
- ✅ Expired regular bans are automatically removed on connection attempt
- ✅ Expired IP bans are automatically removed on connection attempt
- ✅ Ban status flags (
banned,ip_banned) are updated when bans expire - ✅ History entries are properly deactivated when bans expire
- ✅ No manual intervention required for expired bans
- ✅ JSON parsing for expiry times works correctly for all ban types
Disconnect Screen Display
- ✅ Real staff names displayed instead of "Admin"
- ✅ Actual ban reasons displayed instead of "IP Banned"
- ✅ Remaining ban time calculated and displayed correctly
- ✅ Real case IDs displayed instead of "N/A"
- ✅ Both IP bans and regular bans show accurate information
Database Consistency
- ✅ Orphaned ban statuses automatically detected and cleaned
- ✅ Players with
ip_banned=truebut no history entry can connect - ✅ System prevents false positives from database inconsistencies
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle. To learn more about the Modrinth Maven API, click here.
Note: When available, you should use the creator's maven repo instead as it will have transitive dependency information that the Modrinth Maven API does not. You may also end up with duplicate dependencies if you use a mix of Modrinth and non-Modrinth Maven repositories for your dependencies, because the group identifier will be different when served through the Modrinth Maven API.
Maven coordinates:
Version ID:
build.gradle:
repositories {
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
// forRepositories(fg.repository) // Uncomment when using ForgeGradle
filter {
includeGroup "maven.modrinth"
}
}
}
// Standard Gradle dependency
dependencies {
implementation "maven.modrinth:TY8FR9Ml:DKq3pdCs"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:TY8FR9Ml:DKq3pdCs"
}

