1.3.1
Compatibility
Changes
[1.3.1] — Bug Fix Release
🐛 Fixed
-
[CRITICAL] FOLLOW_RANGE stuck at 0 after mob returns near player Mobs whose
FOLLOW_RANGEwas zeroed by the pathfinding-distance optimiser were never restored when they re-entered a player's chunk radius. They would remain AI-enabled but permanently unable to pathfind, appearing frozen. Fix: restoreFOLLOW_RANGEtodefaultValue × multiplierinside thenearPlayer || hotRegionbranch ofapplyAiBatched(). -
[CRITICAL] ConcurrentModificationException on
tpsHistorybetween main thread and HTTP threadtpsHistorywas anArrayDeque— not thread-safe. The Bukkit main thread writes to it every tick while the Web Dashboard HTTP thread pool iterates it on every/api/statusrequest, causing intermittent exceptions. Fix: replaced withConcurrentLinkedDeque. AddedvolatiletotpsSum,tpsCount,criticalActivations, andmediumActivationsfor JMM visibility. -
[CRITICAL] MySQL connection silently dies after DB restart or idle timeout A single
Connectionwas reused indefinitely. When MySQL restarted or timed out, all subsequent sync calls threwSQLExceptionsilently, leaving multi-server sync permanently broken with no visible warning. Fix: addedensureConnected()that checksisClosed()and reconnects automatically before eachupsertMysql()/readPeersMysql()call. -
[MEDIUM] autoRestoreOnError never works on first plugin startup The backup-restore safety net checked for existing backups before any had been created, so it could never restore on a fresh install. Fix:
doBackup()is now called immediately at startup before the check. -
[MEDIUM] StressTestManager.finish() could run twice, emitting duplicate audit reports If the Bukkit scheduler fired the deferred
finish()in the same tick as an earlystop()call, both executions would complete and emit an audit report. Fix:finish()returns immediately ifrunningis alreadyfalse. -
[MEDIUM] Web API /api/cmd whitelist bypassable via prefix matching
body.startsWith(a)allowed inputs like"reloadEvil"to pass the filter. Fix: the first token is extracted and matched exactly against the allowlist.
🔒 Security
- Web auth token warned when passed via URL query param
?token=xxxleaks into browser history and proxy logs.Authorization: Bearerheader is now the primary path; query-param auth logs a one-time warning.
⚡ Performance
- Redis publisher now uses JedisPool
A fresh TCP connection was opened and closed every 5 seconds. A bounded
JedisPool(max 8 / idle 2) is created at startup and shared by publisher and subscriber, eliminating per-publish connection overhead.
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:NQv4Mv8q:tQUpEmGa"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:NQv4Mv8q:tQUpEmGa"
}

