- Add Accessories API sync for Aether mod accessory slots (pendant, cape,
gloves, rings, shield, misc). Uses same pattern as Curios: validate data
before clearing slots, PreparedStatements for DB operations
- Add Cosmetic Armor Reworked sync for 4 cosmetic armor slots via
InventoryManager/CosArmorAPI
- Add Apotheosis + Placebo as compileOnly deps. Apotheosis item data
(affixes, gems, sockets, rarity) travels with items via DataComponents
and is already synced by the inventory sync
- New generic mod_player_data DB table with composite key (uuid, mod_id)
for extensible mod-specific data storage
- Integrated save/restore in join, logout, and auto-save pipelines
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix advancements disappearing: use PreparedStatements for all SQL with
user data (advancement JSON contains chars that broke string-concat SQL),
add null safety for advancement file
- Fix multi-server kick: run doPlayerConnect synchronously instead of async
(players could join before the duplicate check completed)
- Fix Curios disappearing: clear slots AFTER validating data exists (not
before), use CuriosCache for dead players on logout instead of empty API
- Fix Sophisticated Storage items: add storeSophisticatedStorageItems() and
restoreSophisticatedStorageItems() to sync packed barrels/shulkers/chests
- Anti-duplication: clear all inventories before restoring from DB on join
- Fix tick counter: remove LevelTickEvent (fired per dimension = 3x too
fast), merge heartbeat into ServerTickEvent
- Fix connection leaks: use try-with-resources for all QueryResult
- Fix logout order: save data BEFORE marking player offline
- Skip auto-save for dead/unsynced players to prevent saving empty data
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This allows using PlayerSync with different minecraft versions and
even different sets of mods.
All unknown items are replaced by Paper with its original NBT data
encoded into the paper item.
reading CHAT_SYNC immediately within FMLCommonSetupEvent can lead to
timing issues that the default value instead of the real config value is
being returned.
Moving them within event.enqueueWork() fixes the timing issue.
Previously, the json was written too late and never reloaded.
This commit moves the advancement restoration from the PlayerLoggedInEvent
to the earlier onDatapackSyncEvent.
At the same time, it forces a reload of the json files, making sure the
client is informed about the update advancements.