All versions
4.5-beta
Beta
Optimizations lol6 months ago 19
Compatibility
Minecraft: Java Edition
26.1.x
1.21.x
1.20.x
1.19.x
1.18.x
1.17.x
1.16.x
1.15.x
1.14.x
1.13.x
1.12.x
1.11.x
1.10.x
1.9.x
1.8.x
1.7.10
Platforms
Bukkit
Folia
Paper
Purpur
Spigot
Changes
Added
- Added database connection retry mechanism with
MAX_RETRY_ATTEMPTS(3) andRETRY_DELAY_MS(1000ms) for MySQL/SQLite. - Added
ensureConnection()andreconnect()methods for automatic database connection recovery. - Added
executeWithRetry(),executeUuidQueryWithRetry(), andexecuteVoidWithRetry()helper methods to wrap SQL operations with retry logic. - Added cross-server compatibility for offline player targeting: When a player name is not found in the local memory cache (
nameToUUIDs), the plugin now queries the database directly viaqueryUuidByName(). - Added
-offline,-online, and-allflags to batch target processing. - Added
PlayerQuitEventhandler to clean upplayerLockswhen a player disconnects, preventing potential memory leaks. - Added proper index creation handling (
createIndexSafe) with fallback checks for MySQL vs SQLite metadata differences. - Added
GamemodeChangeEventcustom event that is called when a player's gamemode is changed by the plugin.
Fixed
- Fixed database index creation to check for existing indexes before attempting
CREATE INDEXto prevent SQL errors on MySQL. - Fixed
onPlayerJoinevent to useOptionalforloadPlayerModeand properly handle null stored gamemodes without triggering unnecessary errors. - Fixed
savePlayerModeto ensure player name is correctly updated in the database when saving gamemode. - Fixed
setPlayerModeAPI method to handle exceptions and returnfalseon failure rather than always returningtrue. - Fixed YAML caching to properly wrap saves in
synchronizedblocks to prevent concurrent modification issues. - Fixed
loadDatato properly populatenameToUUIDsanduuidToNamemappings from both YAML and SQL storage. - Fixed
handleSinglePlayerto check for player name in database when local cache misses, improving cross-server or bungeecord network support. - Fixed
processOfflinePlayersDatato use database batch operations for SQL storage instead of locking each player individually, greatly improving performance.
Changed
- Refactored database initialization to use a dedicated
dbUrl,dbUser, anddbPassfields instead of constructing the connection string inline. - Updated
loadPlayerModeto useexecuteWithRetryfor robust SQL error handling andOptional<GameMode>return type. - Improved
setPlayerGamemodeLockedlogic to checkplayer.isOnline()before scheduling tasks. - Enhanced
handleGamemodeTargetto useasync()for both batch and single player operations to avoid blocking the main thread. - Replaced explicit
try-catchblocks withexecuteWithRetrywrappers in database operations for cleaner code. - Changed
handleBatchPlayersandhandleSinglePlayerto usesync()for sending messages to ensure thread safety. - Improved
migrateFromYamlIfNeededto handleON DUPLICATE KEY UPDATEproperly on MySQL. - Optimized
processOfflinePlayersDatato use batch SQL execution (executeBatch()) withBATCH_SIZEinstead of individual updates.
Removed
- Removed
tryReadLock(),unlockRead(), andwithReadLock()methods as they were unused in the new version. - Removed
saveAllSync()method as it was unused. - Removed direct
Statementusage ininitDatabase()in favor of try-with-resources and prepared statements. - Removed redundant player mode saving in
onPlayerJoin(no longer forces save if gamemode didn't change). - Removed manual thread sleeping in
processOfflinePlayersDatafor SQL storage, as batch processing handles this efficiently.
Optional dependencies
Any compatible version
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:J0B80Y0Q:KlnY2vWi"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:J0B80Y0Q:KlnY2vWi"
}

