3.2.0latestZoneRental v3.2.0Jan 14, 2026 Changed
- Complete migration from ChatColor to Adventure API - Migrated 548 ChatColor usages across 21 source files to use Paper's native Adventure Component API with MiniMessage format - All commands now usesendMiniMessage()extension for inline messages - ConfigManager now returnsComponentfromgetMessage()instead of legacy strings - Sign formats updated to use MiniMessage tags (<red>,<green>,<gold>, etc.) - All config.yml messages migrated from&color codes to MiniMessage format - Deprecated Bukkit API fixes - Updated 5 deprecated API usages: -player.sendTitle()→player.showTitle()with Adventure Title -itemMeta.setDisplayName()→itemMeta.displayName(Component)-itemMeta.lore = List<String>→itemMeta.lore(List<Component>)Added
- AdventureExtensions.kt - New extension functions for Adventure API: -String.toComponent()- Parse MiniMessage format -String.legacyToComponent()- Convert legacy&codes to Component -String.toMiniMessage()- Convert legacy codes to MiniMessage tags -CommandSender.sendMiniMessage()- Send MiniMessage-formatted textBreaking Changes
- Config format change -config.ymlnow uses MiniMessage format instead of&color codes - Old:prefix: '&8[&6ZoneRental&8]&r '- New:prefix: '<dark_gray>[<gold>ZoneRental<dark_gray>]<reset> '- Existing configs will need to be updated or regenerated3.1.3ZoneRental v3.1.3Jan 14, 2026 Removed
- Unused Rental factory methods - RemovedfromLegacyStorage()andfromMigration()from Rental.kt (never called, migration handled inline) - Deprecated non-world-aware methods - Removed 7 methods that were replaced by world-aware versions: -SignManager.updateSign(String)-WorldEditManager.captureRegion(String)-WorldEditManager.restoreRegion(String)-WorldEditManager.hasCapture(String)-WorldEditManager.deleteCapture(String)-StorageManager.collectItemsFromRegion(String)-EzChestShopManager.removeShopsInRegion(String)- Deprecated permission - Removedzonerental.admin.retime(replaced byzonerental.admin.duration)Fixed
- Dead code conditions - Removed 3 conditions that were always true/false: -CreateSignCommand.kt: Redundant null check (getTargetBlock never returns null) -SignManager.kt: Two null checks in for loops (List<String> elements cannot be null)Changed
- Documentation - Updated CLAUDE.md WorldEdit Integration examples to use world-aware method signatures3.1.2ZoneRental v3.1.2Jan 3, 2026 Fixed
- Regions not removed from groups when using `/zrremove` - Fixed bug where removing a rental region did not remove it from any groups it belonged to - When/zrremove <region>is executed, the region is now automatically removed from its group (if any) - Prevents orphaned group memberships that could cause conflicts when re-adding regions - Individual region overrides are only removed if the region was NOT in a group (groups already clear individual overrides when joining) - Success message now shows group removal confirmation3.1.1ZoneRental v3.1.1Dec 31, 2025 Fixed
- Storage retrieval GUI pagination broken on pages 2 and above - Fixed critical bug where navigation buttons became moveable objects after navigating past page 1 - Root cause: When opening a new page,player.openInventory()automatically closes the previous inventory, triggeringonInventoryClosewhich removed the session fromactiveGUISessionsbefore the new page could use it - Fix: AddedisTransitioningflag toStorageGUISessionthat prevents the close handler from removing the session during page transitions - Navigation buttons now work correctly on all pages - Close button and item retrieval work on all pages - Items on pages 2+ lost when closing GUI - Fixed critical bug where only items from the currently visible page were saved on close - Root cause:getRemainingItemsFromGUI()only read the 45 visible slots of the current page, ignoring items on other pages stored insession.items- Fix: AddedsyncCurrentPageToSession()method that syncs GUI state back to session before page transitions and on close - All remaining items across all pages now persist correctly when GUI is closed - Items consolidate automatically into fewer pages as items are takenChanged
- StorageGUISession.kt - AddedisTransitioning: Booleanproperty for page transition tracking - AddedoriginalItemCount: Intproperty for accurate "items taken" messaging - StorageManager.kt - AddedsyncCurrentPageToSession()method to sync GUI state back to session - Updated navigation handlers to sync current page before changing pages - UpdatedonInventoryClose()to sync and save all items from session - Removed localITEMS_PER_PAGEconstant, now usesStorageGUISession.ITEMS_PER_PAGEas single source of truth - Removed unusedgetRemainingItemsFromGUI()method3.1.0ZoneRental v3.1.0Dec 31, 2025 Major performance update implementing async chunk-based region scanning for improved server performance during rental expiration.New Features
- MCCoroutine 2.21.0 Integration - Added Kotlin coroutine support for Bukkit - Plugin now extendsSuspendingJavaPluginfor automatic coroutine lifecycle management - Enables non-blocking async operations during item/block scanning - TPS-aware throttling to prevent lag during large region scans - ChunkSnapshot Pre-filtering - ~99% reduction in main threadgetBlock()calls - Phase A: ScanChunkSnapshotfor container block types (async, off main thread) - Phase B: Access actual blocks only for found containers (main thread, minimal) - Dramatically reduces server impact for large rental regions - Dynamic Chunk Batching - Batch size scales with region size - Tiny (<50 chunks): 15 chunks/batch, no delay - Small (<200 chunks): 10 chunks/batch, 25ms delay - Medium (<500 chunks): 8 chunks/batch, 50ms delay - Large (<1000 chunks): 4 chunks/batch, 100ms delay - Very Large (<2000 chunks): 2 chunks/batch, 150ms delay - Extreme (2000+ chunks): 1 chunk/batch, 200ms delay - Y-Level Aware Scanning - Only scans actual region Y-bounds - Uses WorldGuard region min/max Y coordinates - Avoids scanning full world height (Y -64 to 320) - Significant performance improvement for regions with limited vertical extent - TPS Monitoring with Auto-Throttling - Adaptive performance management - HEALTHY (TPS ≥ 19.5): Full speed scanning - WARNING (TPS ≥ 18.5): Reduced concurrency, doubled delays - CRITICAL (TPS < 18.5): Single chunk, 200ms delays, pause if TPS drops further - Region Size Limits - Block rentals for excessively large regions - Configurablemax-rental-chunkslimit (default: 2000) - Prevents performance issues from extremely large regions - Clear error message when region exceeds limitNew Files
-src/main/kotlin/com/zonerental/async/ScanModels.kt- Data classes for async scanning -ScanRegion,ChunkCoord,BlockCoord,ChunkBatch-ScanStrategysealed class (Tiny/Small/Medium/Large/VeryLarge/Extreme) -TpsLevelenum andAdjustedStrategyfor TPS-based throttling -src/main/kotlin/com/zonerental/async/TpsMonitor.kt- TPS monitoring utility - Uses Paper'sBukkit.getTPS()API - Provides strategy adjustment based on current server load - Estimates scan time for large regions -src/main/kotlin/com/zonerental/async/AsyncScanService.kt- Core async scan service -createScanRegion()- Creates scan region from WorldGuard bounds -calculateChunkBatches()- Splits region into TPS-friendly batches -scanSnapshotForContainers()- Finds container blocks in ChunkSnapshot -scanSnapshotForChangedBlocks()- Detects player-placed blocksModified Files
- ZoneRental.java - Now extendsSuspendingJavaPluginfor MCCoroutine - StorageManager.kt - Added async ChunkSnapshot-based scanning methods - WorldEditManager.kt - Added async file I/O for schematic operations - RentalManager.kt - AddedexpireRentalAsync()suspend function - ExpirationManager.kt - Usesplugin.launch {}for async expiration - ConfigManager.kt - Added async-scanning configuration propertiesNew Configuration
async-scanning: enabled: true # Enable async scanning for large regions min-chunks-for-async: 10 # Minimum chunks before using async tps-healthy-threshold: 19.5 tps-warning-threshold: 18.5 debug-async: false # Enable debug logging for async operations max-rental-chunks: 2000 # Block rentals for regions larger than thisTechnical Details
- Dependencies added: -mccoroutine-bukkit-api:2.21.0-mccoroutine-bukkit-core:2.21.0-kotlinx-coroutines-core:1.9.0- All new dependencies are relocated via ShadowJar to avoid conflicts - Backward compatible - small regions still use synchronous scanning - No changes to data formats or API3.0.5ZoneRental v3.0.5Dec 30, 2025 Fixed
- Retrieval GUI missing navigation elements - Close button and page indicator are now always visible - Previously, navigation buttons only appeared when there were more than 45 items (multiple pages) - Single-page GUIs now show page indicator (slot 49) and close button (slot 50) - Navigation arrows still only appear when there are multiple pages to navigateChanged
- Consolidated StorageGUISession classes - Removed duplicate inner class - ReplacedStorageManager.StorageGUISessioninner class with external model - Now usescom.zonerental.models.StorageGUISessionfor session tracking - Improved code organization and maintainability3.0.4ZoneRental v3.0.4Dec 28, 2025 Internal refactoring: Migrated the final four Java command classes to Kotlin.Kotlin Conversions
- RRCommand.kt - Migrated from Java (467 → 444 lines, 5% reduction) - Multi-page help system withwhenexpressions - String templates for dynamic prefix interpolation - Tab completion with filtered list operations - RetrieveCommand.kt - Migrated from Java (37 → 28 lines, 24% reduction) - Kotlin smart cast for Player type check - Property access for plugin managers - RemoveCommand.kt - Migrated from Java (132 → 124 lines, 6% reduction) -buildString {}instead of StringBuilder - Null-safe property access with?.let {}- World-aware region parsing preserved - ReloadCommand.kt - Migrated from Java (27 → 20 lines, 26% reduction) - Simple command with idiomatic Kotlin patterns - Property access for config managerTechnical Notes
- All commands now in Kotlin - Zero Java command classes remain - Total line reduction: 663 lines Java → 616 lines Kotlin (7% reduction) - No user-facing changes - all commands work identically -src/main/java/com/zonerental/commands/directory is now empty3.0.3ZoneRental v3.0.3Dec 27, 2025 Changed
- Consolidated `/zrmembers` into `/zrmember list` - Reduced command redundancy -/zrmember add <region> <username>- Add a member (unchanged) -/zrmember remove <region> <username>- Remove a member (unchanged) -/zrmember list <region>- View members (previously/zrmembers <region>)Kotlin Migration
- MemberCommand.kt - Migrated from Java and merged with MembersCommand - Combined MemberCommand.java (204 lines) + MembersCommand.java (142 lines) → MemberCommand.kt (268 lines) - World-aware parser support for all subcommands - Unified tab completion for all subcommandsRemoved
- MemberCommand.java - Replaced by Kotlin implementation - MembersCommand.java - Merged into/zrmember listsubcommand - `/zrmembers` command - Use/zrmember listinsteadNotes
- Both permissions preserved for backward compatibility: -zonerental.member- Foraddandremovesubcommands -zonerental.members- Forlistsubcommand3.0.2ZoneRental v3.0.2Dec 27, 2025 Fixed
- Command Registration Bug - Fixed issue where/zrcommand was being registered twice - Plugin's own PluginCommand from plugin.yml was incorrectly detected as a conflict - This caused fallback to/zr1prefix instead of/zr-checkPrefixConflicts()now recognizes the plugin's own PluginCommand and skips it -registerCommandWithPrefix()now uses existing PluginCommand for main/zrcommand - Missing Subcommands in Conflict Check - Addedmember,members,tp,groupto the subcommands array in conflict detection3.0.1ZoneRental v3.0.1Dec 26, 2025 Internal refactoring: Migrated four command classes from Java to Kotlin.Kotlin Conversions
- CreateSignCommand.kt - Migrated from Java (65 → 53 lines, 18% reduction) - Player validation usingasPlayerOrNull()extension - String templates for messages - Property access for plugin managers - InfoCommand.kt - Migrated from Java (76 → 70 lines, 8% reduction) - String templates for cleaner output formatting - Property access for Rental fields - Elvis operator for null handling - ResetCommand.kt - Migrated from Java (87 → 77 lines, 11% reduction) - Map indexing with type casting for refund details - String templates for messages and logging - Conditional logging with string interpolation - ExtendCommand.kt - Migrated from Java (107 → 98 lines, 8% reduction) - Player validation usingasPlayerOrNull()extension - Property access for Rental fields and config values - Vault economy integration preserved with null safety3.0.0ZoneRental v3.0.0Dec 25, 2025 Major version bump marking the complete rename of the project from RegionRental to ZoneRental.Breaking Changes
- Plugin Renamed - RegionRental is now ZoneRental - Commands Renamed - All commands now use/zrprefix instead of/rr-/rrcreatesign->/zrcreatesign-/rrreset->/zrreset-/rrremove->/zrremove-/rrinfo->/zrinfo-/rrlist->/zrlist-/rrextend->/zrextend-/rrretrieve->/zrretrieve-/rrmember->/zrmember-/rrmembers->/zrmembers-/rrtp->/zrtp-/rrduration->/zrduration-/rroverride->/zroverride-/rrgroup->/zrgroup-/rrverify->/zrverify-/rrreload->/zrreload-/rrrefundhistory->/zrrefundhistory- Permissions Renamed - All permissions now usezonerental.prefix instead ofregionrental.-regionrental.rent->zonerental.rent-regionrental.extend->zonerental.extend-regionrental.admin.*->zonerental.admin.*- (and all other permissions) - Data Folder Renamed - Plugin data folder changed fromplugins/RegionRental/toplugins/ZoneRental/- JAR File Renamed - Output JAR is nowZoneRental-3.0.0.jar- Package Renamed - Java/Kotlin package changed fromcom.regionrentaltocom.zonerentalMigration Notes
- Manual Migration Required - Move your data folder fromplugins/RegionRental/toplugins/ZoneRental/- Permission Updates Required - Update all permissions in your permissions plugin fromregionrental.*tozonerental.*- Command Aliases - Update any command aliases or scripts that reference/rr*commands to use/zr*- Configuration Files - Configuration files (config.yml, regions.yml, etc.) are compatible and do not need modification2.9.3RegionRental v2.9.3Dec 25, 2025 Internal refactoring: Migrated three additional command classes from Java to Kotlin.Kotlin Conversions
- RefundHistoryCommand.kt - Migrated from Java (130 → 109 lines, 16% reduction) - Switch statement → Kotlin when expression - Loop with index → forEachIndexed - String templates for cleaner formatting - ListCommand.kt - Migrated from Java (79 → 76 lines, 4% reduction) - Complex if/else chain → when expression with destructuring - Smart cast for Player type checking - Nullable handling with Pair returns - VerifyCommand.kt - Migrated from Java (94 → 83 lines, 12% reduction) - Unchecked casts → safe casts with filterIsInstance - For loops → forEach - Type-safe map access with null defaultsTechnical Notes
- No user-facing changes - all commands work identically - Total line reduction: ~12% across migrated commands - Improved null safety and type handling2.9.2RegionRental v2.9.2Dec 23, 2025 Internal refactoring: Migrated the three largest command classes from Java to Kotlin.Kotlin Conversions
- DurationCommand.kt - Migrated from Java (439 → 329 lines, 25% reduction) - Leverages existing DurationAction/DurationResult sealed classes - When expressions for action handling - TimeUtils integration for duration parsing - GroupCommand.kt - Migrated from Java (777 → 599 lines, 23% reduction) - Data classes for PendingGroupAction and ParseResult - Collection functions for region parsing - Simplified tab completion with caching - TpCommand.kt - Migrated from Java (463 → 310 lines, 33% reduction) - Smart casts for block data types - Companion object with material sets for block checks - Streamlined 3D safe location algorithmTechnical Notes
- No user-facing changes - all commands work identically - Total line reduction: ~26% across migrated commands - Improved type safety and null handling2.9.1RegionRental 2.9.1Dec 21, 2025 [2.9.1] - Schematic Deletion Bug Fix
Fixed
- Schematic deletion bug in /rrremove command - Fixed issue where schematic files were not being deleted when removing rental setup from a region. ThedeleteCapture()method now correctly uses the composite key format for schematic file lookup. ---[2.9.0] - Tier 2 Kotlin Migration
Major update completing the Kotlin migration by converting all remaining manager classes and utilities to Kotlin.Kotlin Conversions (Tier 2)
Phase 1 - Utilities: - WorldRegionParser.kt - Migrated from Java - Idiomatic Kotlin with data classes and sealed results - Pattern matching for region parsing - ExpirationManager.kt - Migrated from Java - Kotlin coroutine-style task scheduling - Safe operators for null handling - WorldGuardManager.kt - Migrated from Java - Properties for region queries - Extension functions for WorldGuard API Phase 2 - Plugin Managers: - EzChestShopManager.kt - Migrated from Java - Reflection API wrapped with Kotlin safe calls - Cleaner API with extension functions - SignManager.kt - Migrated from Java - Functional operations for sign updates - Support block handling with sealed classes Phase 3 - Storage Managers: - WorldEditManager.kt - Migrated from Java - Schematic operations with safe file handling - LRU cache implementation in Kotlin - StorageManager.kt - Migrated from Java - Container scanning with functional operations - GUI session management with data classes Phase 4 - Core Manager: - RentalManager.kt - Migrated from Java - Central rental lifecycle in idiomatic Kotlin - ConcurrentHashMap with Kotlin extensions - Computed properties for rental queriesBug Fixes
- Fixed nullable World in chargeDurationAdd method - Proper null handling for world parameter - Fixed StorageGUIHolder getInventory return type - Corrected interface implementation - Fixed SignManager Kotlin compilation errors - Resolved type mismatches - Fixed ParsedRegion Java field access - Added@JvmFieldannotations for Java interop - Fixed JVM signature clash in WorldGuardManager - Resolved overload conflicts - Fixed WorldGuardManager property access - Added proper Kotlin accessorsTechnical Details
- 10 manager classes migrated from Java to Kotlin - Full Java interoperability maintained via JVM annotations - Zero breaking changes to API or data formats - Build verified with Kotlin stdlib verification in CI ---[2.8.2] - Kotlin Runtime Fix (Complete)
Fixed
- Kotlin stdlib not bundled in JAR - Fixed shadowJar configuration to explicitly include runtime dependencies. Addedconfigurations = listOf(project.configurations.runtimeClasspath.get())to ensure Kotlin stdlib is properly shaded. Also disabled the default jar task to prevent conflicts. ---[2.8.1] - Kotlin Runtime Fix (Incomplete)
Fixed
- Attempted fix for Kotlin stdlib bundling withrelocate- insufficient on its own. ---[2.8.0] - Tier 1 Kotlin Migration
Continues the Kotlin migration by converting all configuration managers and the teleport cooldown manager.Kotlin Conversions (Tier 1)
- ConfigManager.kt - Migrated from Java (394 lines → 387 lines) - Properties with private setters replacing getter methods - Kotlin string templates for config paths - TeleportCooldownManager.kt - Migrated from Java (129 lines → 81 lines, 37% reduction) -mutableMapOf<UUID, Long>()for cooldowns - Simplified with Elvis operator and safe calls - SignsConfig.kt - Migrated from Java (367 lines → 301 lines, 18% reduction) - String templates for YAML paths - Safe operators for null handling - RegionsConfig.kt - Migrated from Java (818 lines → 509 lines, 38% reduction) - Properties for query methods (allRegions,allGroupsWithOverrides) - Functional operations (filter,associateWith) - GroupsConfig.kt - Migrated from Java (442 lines → 276 lines, 38% reduction) - Companion object for constants - KotlinRegexinstead ofPattern-whenexpression for validation - StorageConfig.kt - Migrated from Java (208 lines → 169 lines, 19% reduction) - Safe cast with@Suppressfor generic lists -emptyList()instead ofArrayList()Summary
- 6 files migrated from Java to Kotlin - Total reduction: 2,358 lines → 1,723 lines (27% reduction) - Full Java interoperability maintained via generated getters ---[2.7.0] - Kotlin Migration
Major update introducing Kotlin for improved code quality, type safety, and reduced boilerplate.Kotlin Conversions
- Rental.kt - Full conversion from Java (300 lines → ~170 lines) - Data class with computed properties replacing 10+ getter methods - Factory methods (Rental.create(),Rental.fromStorage()) replacing 5 Java constructors -@JvmStaticand@JvmOverloadsannotations for full Java interoperability - NestedRefundRecorddata class for audit trail - OverrideCommand.kt - Full rewrite with sealed classes (863 lines → ~350 lines, 60% reduction) -OverrideSetting<T>sealed class with 6 type-safe setting variants - Single generic handler replaces 6 nearly identical Java methods -ParseResult<T>sealed class for type-safe parsing resultsNew Kotlin Files
Extensions (5 files): -StringExtensions.kt-color(),withPlaceholders(),parseCompositeKey()-LocationExtensions.kt-Location.toKey(),String.toLocation(),String.toWorld()-PlayerExtensions.kt-asPlayerOrNull(),requirePlayer(),requirePermission()-CollectionExtensions.kt- Filtering and mapping helpers Utilities: -TimeUtils.kt- Duration formatting, time parsing,Int.days/Int.hoursextensions Data Models (4 files): -RefundRecord.kt- Standalone refund transaction model -ParsedRegion.kt- World:region parsing with composite key support -StorageGUISession.kt- Paginated GUI session for item retrieval -SupportBlockData.kt- Sign support block capture/restore Configuration (2 files): -RegionOverride.kt- Type-safe override container withmerge()andwithDefaults()-MessageFormatter.kt- DSL for message formatting with fluent API Commands: -DurationAction.kt- Sealed class for duration command actions Manager Extensions: -ManagerExtensions.kt- Collection extensions for rental operationsDeleted Java Files
-src/main/java/com/regionrental/managers/Rental.java(replaced by Kotlin) -src/main/java/com/regionrental/commands/OverrideCommand.java(replaced by Kotlin)Technical Details
- 15 Kotlin files created across extensions, models, config, commands, and managers - 2 Java files replaced (Rental.java, OverrideCommand.java) - ~1,100 lines of Java removed, ~800 lines of Kotlin added (net reduction) - Full Java interoperability maintained via@JvmStatic,@JvmOverloads,@JvmField- Zero breaking changes to API or data formats - Build verified on GitHub ActionsMigration Notes
- Java code callingnew Rental(...)should useRental.create()orRental.fromStorage()-rental.getExtensionCost()→rental.extensionCost(Kotlin property) -rental.isExpired()→rental.isExpired(Kotlin property) - All existing data files (rentals.yml, etc.) remain compatible ---[2.6.0] - Schematic Format Migration
Major update fixing critical WorldEdit schematic serialization bug and migrating to industry-standard Sponge format.Critical Bug Fix
- Fixed Schematic Serialization - Replaced broken Java serialization with Sponge Schematic format - Previous Bug:SerializableClipboardclass hadtransientclipboard field, resulting in empty .dat files - Impact: All .dat schematics from v2.5.1 and earlier contain NO block data - Restoration only worked if clipboard remained in memory cache - Server restarts caused silent data lossChanges
Similar projects
Plugin →WorldEdit
A Minecraft Map Editor... that runs in-game! With selections, schematics, copy and paste, brushes, and scripting. Use it in creative, or use it temporarily in survival.
11.6MSueta
LuckPerms
A permissions plugin/mod for Minecraft servers.
2.8MSueta
ItemSwapper
Inventory update concept for hotswapping items.
2.1MSueta
SkinsRestorer
🎨 Ability to restore/change skins on servers! (Offline and Online Mode)
1.6MSueta
Universal TierTagger
Displays a players Tiers across the following Networks: MCTiers PVPTiers SubTiers TiersMC PVPHQ
1.1MSueta
WorldGuard
WorldGuard lets you and players guard areas of land against griefers and undesirables as well as tweak and disable various gameplay features of Minecraft.
960.5KSueta