1.8
Compatibility
Changes
[1.8] - 2026-04-21
Fixed
-
🔴 Critical —
onDropnever fired:getSessions()returns aMap<BackpackUUID, Session>but the old code checkedgetSessions().containsKey(playerUUID). Because the key is a backpack UUID, the check was always false — players could freely drop items while a backpack was open. Fixed by addingBackpackManager.isPlayerHasOpenBackpack(playerUUID)which queries the correctplayerToBackpackmap. -
🔴 Critical —
isBackpack()missed freshly crafted items:isBackpack()previously checked forBP_ID_KEY, which is only assigned on the first right-click of a backpack item. Brand-new crafted backpacks had no ID yet, so they were invisible to the pickup/max-backpack limit check. Fixed by checkingBP_TIER_KEYinstead, which is always present fromcreateBackpack(). -
🔴 Critical — Data loss race condition in
saveAll(): The oldsaveAll()dispatched async save tasks and then immediately calledsessions.clear(). The async lambdas could still be running when the map was cleared, leading to NPE or lost saves on server shutdown/reload. Replaced with a newsyncSaveAll()that blocks on the main thread during disable/reload, ensuring all data is written before the connection is closed. -
🟡 Task leak on
/bp reload:reloadPlugin()created a newBackpackManager(and calledstartAutoSaveTask()on it) without ever cancelling the previous manager's repeating task. Each reload stacked another permanent 2-minute timer. Fixed by callingcancelAutoSaveTask()before tearing down the old manager. -
🟡 Auto-save not restarted after reload:
reloadPlugin()built a newBackpackManagerbut forgot to callstartAutoSaveTask()on it — the replacement manager ran with no auto-save at all. Fixed. -
🟡 Hardcoded version string in startup log:
onEnable()printed"version 1.0"regardless of the actual version. Changed togetDescription().getVersion(). -
🟢 Config typo — "Week Backpack": Tier-1 display name was
"Week Backpack"(a day of the week) instead of"Weak Backpack". Fixed inconfig.yml.
Improved
-
BackpackCommandnow usesbackpack.adminpermission instead ofplayer.isOp(), allowing server admins to grant give/reload access via any permissions plugin (LuckPerms, etc.). -
/backpack give <tier> [player]: Admin can now give a backpack directly to another online player:/bp give 2 Steve. Tab-completion lists online player names. -
Recipe deduplication on reload:
registerRecipes()now removes old recipes before re-adding them, preventing "duplicate recipe" warnings in the console on each/bp reload. -
Safe inventory size mismatch handling: If a backpack's stored item count exceeds the configured
size(e.g. after an admin reduces the tier size), the plugin now logs a warning and truncates gracefully instead of throwing anArrayIndexOutOfBoundsException. -
plugin.yml: Addedbackpack.adminpermission entry withdefault: op. Updated description and usage string for thebackpackcommand.
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:T8kyE5QU:DqMJ0eF1"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:T8kyE5QU:DqMJ0eF1"
}

