Unofficial site, not affiliated with modrinth.com.What is this?
Плагины/BackPackSSS

1.9

Release3 нед. назад

Список изменений

[1.9] - 2026-05-24

Fixed

  • 🔴 Critical — Race condition: async save after connection close saveSession() dispatches asynchronous write tasks. If one of those tasks was still in flight when syncSaveAll() returned and DatabaseManager.closeConnection() was called (during shutdown or /bp reload), the task would attempt to write to an already-closed connection, silently losing data. Fixed by introducing a volatile boolean shuttingDown flag in BackpackManager: syncSaveAll() sets the flag before entering, which causes saveSession() to no-op for any new attempts. syncSaveAll() then spin-waits (up to 5 seconds) for any already-running async tasks to land before proceeding with its own synchronous pass, ensuring the connection is only closed after all writes have completed.

  • 🔴 Critical — Memory leak: sessions map never evicted after close closeSession() removed a backpack from activeBackpacks and playerToBackpack but never called sessions.remove(). Every unique backpack UUID opened since the last restart accumulated indefinitely, causing unbounded memory growth on long-running servers. Fixed by adding sessions.remove(backpackUUID) in both closeSession() and closePlayerSession().

  • 🟡 Medium — DatabaseManager.init() could fail silently on first run createNewFile() throws IOException when its parent directory does not exist. On a fresh install, if saveDefaultConfig() had not yet been called, the database file could not be created, leaving the connection null and causing NPEs on any subsequent load. Fixed by calling plugin.getDataFolder().mkdirs() before attempting to create the file, and added a return-early path when createNewFile() returns false.

  • 🟡 Medium — BackpackSession.playerUUID was always null getBackpackSession() always passed null as the first constructor argument, making BackpackSession.getPlayerUUID() permanently useless. Fixed by threading the Player's UUID from openBackpack() through to getBackpackSession(), which now accepts UUID playerUUID as its first parameter.

  • 🟡 Medium — isForbiddenItem() used getMaxStackSize() == 1, which was too broad The heuristic blocked music discs, name tags, saddles, empty buckets, and any item from third-party plugins that happens to have a stack size of 1 for unrelated reasons. Replaced with an explicit category check using Material.name() suffixes (armor, swords, axes, pickaxes, shovels, hoes) and individual constants for bows, crossbows, tridents, shields, elytras, shears, flint-and-steel, enchanted books, and totems of undying — exactly the items documented in config.yml.

  • 🟡 Medium — onClick() marked session dirty before restriction checks session.setDirty(true) was called at the top of onClick(), before the nesting and item-filter checks that might cancel the event. A cancelled click does not modify the inventory, so marking it dirty caused unnecessary async saves. Fixed by moving setDirty(true) to execute only after all checks pass. Same fix applied to onDrag().

  • 🟡 Medium — PlayerInteractEvent fired for both hands, processing the backpack twice Without an EquipmentSlot.HAND guard, right-clicking with a backpack in the main hand generated two PlayerInteractEvent calls per click. The opening cooldown absorbed the second call, but both calls entered onInteract() and evaluated the PDC. Added if (event.getHand() != EquipmentSlot.HAND) return; as an early exit.

  • 🟡 Medium — InventorySerializer did not close streams on exception Both toBase64() and fromBase64() closed their BukkitObject*Stream only on the happy path. If serialization or deserialization threw mid-loop, the stream leaked. Replaced both methods with try-with-resources blocks.

  • 🟡 Medium — PrepareItemCraftEvent iterated player inventory unnecessarily countBackpacks() was called on every PrepareItemCraftEvent tick even when max-backpacks was 0 (unlimited). Added an early-return guard so the inventory scan only runs when a real limit is configured.

  • 🟢 Minor — BackpackCommand lacked explicit tier range validation A tier number outside [1, 3] was silently forwarded to createBackpack(), which returned null, producing a generic "invalid tier" message through an indirect path. Added upfront Integer.parseInt() + range check against TIER_MIN/TIER_MAX constants, returning the messages.invalid-tier config message immediately.


Метаданные

Канал релиза

Release

Номер версии

BackPackSSS

Загрузчики

Bukkit
Paper
Purpur
Spigot

Версии игры

1.21–1.21.11

Загрузок

40

Дата публикации

3 нед. назад

Загрузил

ID версии

Главная