
Список изменений
[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. The
deleteCapture()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 queries
Bug 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 accessors
Technical 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. Added
configurations = 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 with
relocate- 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)
- Properties for query methods (
-
GroupsConfig.kt - Migrated from Java (442 lines → 276 lines, 38% reduction)
- Companion object for constants
- Kotlin
Regexinstead ofPattern whenexpression for validation
-
StorageConfig.kt - Migrated from Java (208 lines → 169 lines, 19% reduction)
- Safe cast with
@Suppressfor generic lists emptyList()instead ofArrayList()
- Safe cast with
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- Nested
RefundRecorddata 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 results
New 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 modelParsedRegion.kt- World:region parsing with composite key supportStorageGUISession.kt- Paginated GUI session for item retrievalSupportBlockData.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 operations
Deleted 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 Actions
Migration Notes
- Java code calling
new 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 loss
- Previous Bug:
Changes
- Sponge Schematic Format - Now uses WorldEdit's official
.schemformat- Industry-standard format used by WorldEdit, FastAsyncWorldEdit, and other tools
- Properly persists blocks, entities, and metadata across server restarts
- Files can be imported/exported to other WorldEdit-compatible tools
- Better compression and smaller file sizes
Migration
- Automatic Migration - Handles legacy .dat files gracefully
- Detects and warns about empty .dat files at startup
- Auto-deletes legacy files if
restoration.auto-delete-schematics: true - Clear logging explains the bug and migration process
- Regions will be automatically re-captured on next rental
Technical Details
- Added imports:
ClipboardFormat,ClipboardFormats,ClipboardReader,ClipboardWriter,BuiltInClipboardFormat - Removed: Broken
SerializableClipboardwrapper class - Updated methods:
saveSchematic(),loadSchematic(),indexSchematics(),deleteSchematic() - File extension:
.dat→.schem
Upgrade Notes
- Existing Installations:
- All existing .dat files are empty and will be ignored
- Regions will be re-captured automatically when next rented
- Set
restoration.auto-delete-schematics: trueto clean up legacy .dat files
- No Config Changes Required: Migration is automatic
- No Data Loss: The .dat files were already empty, so nothing is lost
[2.5.1] - PR Review Fixes
Patch release addressing code review feedback with bug fixes, thread safety improvements, and code quality enhancements.
Bug Fixes
- Cache Invalidation - Fixed
invalidateGroupCache()never being called after group modifications- Added calls to:
processCreateGroup,handleDelete,processAddRegions,processRemoveRegions - Tab completion now immediately reflects group changes
- Added calls to:
Thread Safety Improvements
- WorldEditManager - Made collections thread-safe for potential concurrent access
knownSchematics: Changed fromHashSettoConcurrentHashMap.newKeySet()clipboardCache: WrappedLinkedHashMapwithCollections.synchronizedMap()
Code Quality
- Cleaner Save Pattern - Refactored save methods across 5 files
- Moved
isDirty = falseoutside try block with early return on failure - More explicit success-only flag reset
- Files: StorageConfig, RegionsConfig, SignsConfig, GroupsConfig, RentalManager
- Moved
Technical Details
- Files modified: 7 files
- ~43 lines changed (+31/-12)
- Backward compatible
[2.5.0] - Performance Optimization
Minor update with comprehensive performance optimizations to reduce disk I/O, memory usage, and CPU overhead.
Optimizations
- Dirty Tracking - Saves only happen when data actually changes (80-90% disk I/O reduction)
- Applied to: RentalManager, SignsConfig, StorageConfig, RegionsConfig, GroupsConfig
markDirty()replaces immediatesave()callssaveIfDirty()called during auto-save task
- Lazy Schematic Loading - Schematics loaded on-demand with LRU cache (major RAM reduction)
- Startup only indexes schematic files, doesn't load them
- LRU cache evicts least-recently-used schematics when full
- Configurable cache size:
restoration.schematic-cache-size: 20
- O(1) Support Block Lookups - HashMap index instead of O(n) scan on block breaks
supportBlockIndexmaps "world:x:y:z" → "world:region"- Rebuilt on sign config load
- O(1) Player/Member Lookups - Secondary indexes for rental queries
playerRentalIndex: UUID → Set of composite keysmemberRentalIndex: UUID → Set of composite keysgetPlayerRentals()andgetRentalsWhereMember()now O(1)
- Memory Leak Fixes - GUI sessions cleaned on disconnect, cooldown cleanup task
PlayerQuitEventhandler removes GUI sessions- Periodic task cleans expired teleport cooldowns (every 10 minutes)
- EnumSet for Container Types - O(1) contains() instead of O(n) ArrayList
- Tab Completion Caching - 5-second TTL cache for group names in commands
New Configuration
restoration:
schematic-cache-size: 20 # Max schematics in memory (LRU eviction)
Technical Summary
- Files modified: 10+ files across managers, configs, and commands
- ~500 lines of optimization code
- Backward compatible with existing data
- Zero breaking changes
[2.4.1] - Teleportation Safe Location Bug Fix
Patch release fixing critical teleportation bugs with enhanced 3D search algorithm.
Bug Fixes
- Wall Sign Teleportation - Fixed "no safe location found" error for wall-mounted signs
- Original algorithm only searched upward from sign level
- New 3D search algorithm searches forward, down, and up
- Standing Sign Direction - Fixed standing signs using player's facing instead of sign rotation
Enhanced 3D Search Algorithm
- Forward Search - Searches 1-20 blocks in front of sign (configurable)
- Downward Floor Search - Searches up to 20 blocks down for solid floor
- Upward Floor Search - Searches up to 20 blocks up as fallback
New Configuration
teleport:
forward-search-distance: 5 # How many blocks forward to search
floor-search-down: 20 # How many blocks down to search for floor
floor-search-up: 20 # How many blocks up to search for floor
[2.4.0] - Teleportation System
Minor update adding teleportation feature for rental owners and members.
New Features
- Teleport Command -
/rrtp <region>allows teleporting to rented regions- Works for rental owners and members
- Cross-world teleportation support
- Safe location detection algorithm
- Cooldown System - Prevents spam teleporting (configurable, default: 30s)
- Effects & Feedback - Enderman teleport sound and portal particles (configurable)
Configuration
teleport:
enabled: true
max-search-distance: 20
cooldown: 30
cross-world-warning: true
sound-enabled: true
particle-enabled: true
[2.3.0] - Member Management System
Minor update adding complete member management for rented regions.
New Features
- Member Management Commands
/rrmember add <region> <username>- Add member to rented region/rrmember remove <region> <username>- Remove member from rented region/rrmembers <region>- List all members of a region
- WorldGuard Integration - Members added to WorldGuard region members
- Configurable Limits -
members.max-members: 5(-1 for unlimited) - Access Control - Only renter can add/remove members
Configuration
members:
enabled: true
max-members: 5 # -1 for unlimited
[2.2.1] - Sign Update Bug Fix
Patch release fixing missing sign updates when regions are removed from groups.
Bug Fixes
- Sign Update Edge Cases - Signs now update immediately when group membership changes
- Fixed: Signs not updating when regions are removed from groups (
/rrgroup edit <name> remove) - Fixed: Signs not updating when groups are deleted (
/rrgroup delete <name>) - Fixed: Signs not updating when regions are added to groups with existing overrides
- Added:
bulkMarkSignsDirty()calls in 4 group command methods
- Fixed: Signs not updating when regions are removed from groups (
Technical Details
- Modified
GroupCommand.javato mark signs as dirty after group membership changes - Signs now update within 30 seconds (next update cycle) instead of showing stale data
- No performance impact (dirty tracking uses efficient HashSet operations)
- Ensures override lookup priority works correctly: Group → Region → Default
[2.2.0] - Region Grouping System
Minor update adding comprehensive region grouping and mass override management.
New Features
-
Region Grouping System - Group multiple regions together for unified configuration
/rrgroup create <name> [regions]- Create region groups/rrgroup edit <name> add/remove [regions]- Modify group membership/rrgroup delete <name>- Delete groups with confirmation/rrgroup listand/rrgroup view <name>- Browse groups- Multi-world support (regions from different worlds in same group)
- Hybrid command interface (inline arguments OR chat prompts with 60s timeout)
-
Mass Override Operations - Set overrides once for entire group
group:prefix parser resolves naming conflicts (/rroverride price group:shops 1000)- Override lookup priority: Group → Region → Default
- Bulk sign updates (all group signs update together)
- Automatic individual override cleanup when adding to groups
-
Enhanced Tab Completion - Smart suggestions for all commands
group:prefix suggestions in override commands- Region name completion from WorldGuard
- World prefix completion (
world:,world_nether:) - Context-aware suggestions (player's world vs explicit world)
Validation & Edge Cases
- Exclusive group membership (regions can only be in one group)
- Duplicate prevention (cannot add if already in another group)
- Group name validation (2-30 chars, alphanumeric + underscore, reserved names blocked)
- Region/world existence checks before adding
- Automatic cleanup on group deletion (removes group overrides from regions.yml)
Technical Summary
- Files created: 3 (GroupsConfig.java, GroupCommand.java, GroupChatListener.java)
- Files modified: 5 (RegionRental.java, OverrideCommand.java, SignManager.java, RegionsConfig.java, CLAUDE.md)
- Lines added: ~2000+ lines across 5 implementation phases
- Data files: groups.yml (new), regions.yml (extended with group section)
- Documentation: Comprehensive grouping system docs added to CLAUDE.md
[2.1.0] - Command Prefix Registration Cleanup
Minor update cleaning up command prefix registration behavior.
Changes
- Command Prefix Fix - Removed duplicate /rr command registration when custom prefix is configured
- Custom prefix users will only have their configured prefix registered (no more /rr fallback)
- Default prefix users (
prefix: 'rr') are unaffected - Conflict resolution still works (falls back to 'rr' or auto-generated suffix)
- Console Message Cleanup - Removed misleading log messages about fallback /rr registration
- Removed: "Fallback 'rr' prefix also registered for backward compatibility" (line 352)
- Removed: "Fallback 'rr' will be registered when conflicts resolve" (line 360)
Technical Summary
- Files modified: 1 file (RegionRental.java)
- Lines removed: 20 lines (18 from registration block + 2 misleading messages)
- Breaking change: Users who configured custom prefix but used /rr commands must switch to custom prefix
- Benefits: Cleaner command registration, less namespace pollution, more intuitive behavior
[2.0.1] - Critical Bug Fixes and Performance Optimizations
Bug Fixes
- Fixed rental sign interaction error: Resolved "region world:shop1 not found" bug
- Properly parses composite keys to extract region names
- Sign interactions now work correctly across all worlds
- Prevented IndexOutOfBoundsException crashes: Added comprehensive bounds checking
- WorldRegionParser null and bounds validation
- Command argument validation (RRCommand, DurationCommand)
- Storage manager GUI pagination bounds checking
- Prevented NullPointerException errors: Added null safety checks
- Sign format list validation before iteration
- Individual format line null checks
Performance Improvements
- WorldGuard operations: 3x-10x faster
- Removed 9 deprecated methods with multi-world iteration (133 lines)
- Direct world-specific lookups instead of scanning all worlds
- Rental lookups: 100x-1000x faster
- Removed 8 deprecated O(n) search methods (82 lines)
- Direct hash map access using composite keys for O(1) performance
- Sign updates: 90%+ overhead reduction
- Dirty tracking system updates only changed signs
- No longer updates all signs every 30 seconds
- Thread safety improvements
- Synchronized storage manager GUI pagination
- Prevents concurrent modification exceptions
Technical Details
- Total: ~215+ lines of deprecated code removed
- 15 potential crash/error scenarios eliminated
- 7 commits with comprehensive testing
- All optimizations maintain backward compatibility
- Zero breaking changes to API or data formats
[2.0.0] - Multi-World Support
Complete Multi-World System
- World-Aware Rentals: Each rental now tracks and operates in its specific world
- Fixed Critical Bug: WorldEdit operations now use correct world instead of hardcoded first world
- Composite Key System: Rentals identified by
worldName:regionNameformat for uniqueness - Automatic Migration: Existing rentals seamlessly upgraded to multi-world format on first load
- Performance Improvements: Direct world-specific lookups eliminate inefficient world scanning
- Zero Breaking Changes: Fully backward compatible with existing rental data
Updated Components
- Rental Class: Added
worldNamefield and composite key support - RentalManager: All CRUD operations now world-aware with deprecated fallback methods
- WorldEditManager: Fixed hardcoded world bug, now captures/restores in correct world
- WorldGuardManager: Added direct world-specific methods for O(1) performance
- SignManager: Sign updates now world-aware based on rental's world
- SignInteractListener: Player interactions use player's current world automatically
- CreateSignCommand: Validates regions in player's current world
Data Migration
- Existing
rentals.ymlautomatically detected and migrated - Old rentals default to first world (usually "world")
- Migration count logged on startup for transparency
- Data immediately re-saved in new composite key format
- No manual intervention or downtime required
Example Use Cases
- Set up identical rental shops in overworld and nether
- Different rental regions per dimension (mining claims in end, shops in overworld)
- WorldEdit captures/restores blocks in correct world
- No more world collisions or unexpected behavior
[1.3.3] - EzChestShop Integration
EzChestShop Plugin Support
- Automatic shop removal on rental expiration for seamless cleanup
- Runtime detection using reflection-based API (no compile-time dependency required)
- Smart cleanup approach using block break/replace for reliable shop and hologram removal
- Conditional restoration - Only restores chest blocks if WorldEdit restoration is disabled
- Configurable notifications - Optional player notifications when shops are removed
- Perfect timing - Shops removed after storage scan but before WorldEdit restoration
- Compatible with EzChestShop 1.9.2+ with automatic version detection
Technical Implementation
- Reflection API for accessing EzChestShop's internal ShopContainer class
- Block break/replace pattern triggers EzChestShop's BlockBreakEvent for automatic cleanup
- No hologram glitches - EzChestShop's event handler removes all holograms automatically
- Inventory protection - Clears chest inventory before breaking (items already saved)
- 3-tick delay for chest restoration when WorldEdit is disabled
- Configuration options in config.yml under
integration.ezchestshop
Configuration Options
integration:
ezchestshop:
enabled: true # Enable/disable integration
notify-on-removal: true # Notify player when shops removed
removal-message: '&eChest shops in &6{region}&e have been removed.'
[1.1.0] - Command-Based Override System
Region Override Command System
- New command
/rroverridefor setting per-region custom rental settings - 8 subcommands: price, duration, maxextensions, extensionprice, allowextensions, extensionduration, remove, list
- In-game configuration - No manual file editing required
- Defaults-first approach - Regions not in regions.yml use config.yml defaults
- Immediate updates - Signs automatically update when overrides are changed
- Tab completion - Full tab completion support for all subcommands and region names
- WorldGuard validation - Prevents setting overrides for non-existent regions
Updated Verification System
- Enhanced
/rrverifynow shows breakdown of defaults vs custom overrides - Reports orphaned configs - Configs without signs (can be cleaned up)
- No longer auto-repairs - Only reports status, admins manage via commands
Removed Auto-Population
- Simplified workflow -
/rrcreatesignno longer auto-populates regions.yml - Cleaner files - regions.yml only contains intentional overrides
- Better clarity - Clear which regions use defaults vs custom settings
[1.0.0] - Initial Release
Per-Region Configuration System (regions.yml)
- Config file
regions.ymlfor managing per-region override settings - Migration system automatically moves old
regions:data from config.yml - Partial overrides - Only specify settings you want to change
Command Consolidation - Duration Management
- Removed
RetimeCommand- functionality merged intoDurationCommand - Enhanced
/rrdurationcommand now supports:add- Add time to rentalremove- Remove time from rentalset- Set absolute durationreset- Reset to default duration with optional extension refund
- Extension refund system - Optionally refunds extension costs when resetting duration
- Config option
extension.refund-on-duration-resetcontrols refund behavior - Simplified interface - No longer requires player name, only region name
Refund History Tracking
- New command
/rrrefundhistory <region>to view complete refund transaction history - Automatic tracking of all refunds (resets, duration changes, removals)
- Detailed logging with timestamps, amounts, and reasons
- Double-refund prevention system tracks what has been refunded
Enhanced Support Block Protection
- Auto-migration of existing signs to include support block protection
- Improved data storage for original block type and orientation
- Restoration system properly restores support blocks when using
/rrremove
