Root cause of backpack duplication: Sophisticated Backpacks' setBackpackContents merges shallowly when the UUID exists, so stale sub-tags survived every restore. doBackPackRestore now calls removeBackpackContents before setBackpackContents for a clean replace. Curios cosmetic stacks (getCosmeticStacks) are now snapshotted, applied, restored and cached on all paths. Old-format rows without the "cos:" prefix still parse unchanged, so existing DB data is preserved on upgrade. closeContainer no longer matches by class-name substring (was closing unrelated mod menus containing "curio"/"accessor"). Only menus whose slots reference the disconnecting player's inventory/ender-chest are closed. Thread-safety: Sophisticated Storage contents are now snapshotted on the main thread (snapshotSSData + saveSSSnapshots) instead of read from a background thread racing with world ticks. Event priority / defensive guards: - onPlayerDeath is now EventPriority.LOW and skips cancelled events so Revive Me / Corail Tombstone's cancel runs first. - onServerStarting short-circuits on integrated (single-player) servers to avoid noisy MySQL connection attempts. Observability: - executeBatchTransaction now returns per-statement row counts. - writeSnapshotToDB calls SyncLogger.guardBlocked when the core UPDATE silently no-ops (another server claimed last_server). - SyncLogger uses a daemon scheduler that flushes every 500 ms; shutdown happens after parallel saves so final save logs are no longer dropped. - Rollback failures inside executeBatchTransaction and refreshInventoryForInputOutput are now logged instead of swallowed. HikariCP retuned: maxPoolSize 25->15, connectionTimeout 30->10s, idleTimeout 600->300s, leakDetectionThreshold 10->25s (covers worst-case join polling without log spam). New table_prefix config option (Tables helper) lets a user share one MySQL database with other mods without table-name collisions. Default is empty to preserve backward compatibility. Reflection Methods for NeoForge AttachmentHolder are resolved once in a static initializer and cached. Chat sync and Cobblemon integration removed: - Chat sync: 319 LoC of socket/thread code guarded by a config flag that defaulted to false; orphaned config keys are silently ignored by the NeoForge ModConfig loader, so no crash on upgrade. - Cobblemon: 297 LoC of mixins that ran synchronous JDBC on the main thread and built SQL with raw UUID concatenation. The existing cobblemon table in the DB is left untouched on upgrade. Also fixes cobblemon ALTER TABLE running blindly on every boot (alterColumnIfNeeded helper checks INFORMATION_SCHEMA first). Author: vyrriox |
||
|---|---|---|
| .github | ||
| gradle/wrapper | ||
| src/main | ||
| .gitattributes | ||
| .gitignore | ||
| build.gradle | ||
| docker-compose.yml | ||
| gradle.properties | ||
| gradlew | ||
| gradlew.bat | ||
| LICENSE | ||
| README.md | ||
| settings.gradle | ||
PlayerSync
PlayerSync is a Minecraft Forge mod that synchronizes player data across multiple servers using a MySQL backend. It allows players to maintain their inventory, equipment, experience, advancements, and more when moving between servers in a network.
Mod Support
Any other mods support is also possible.
Development Setup
Database Setup (Docker)
A docker-compose.yml file is provided for easily setting up a MariaDB database instance for development testing.
- Make sure Docker is installed.
- Inside your work directory run:
This will download the MariaDB image (if not already present) and start a database container in the background.docker compose up -d - Stoppinng the Database
docker compose down
Data Persistence: The database uses a Docker volume, ensuring your data persists even if you stop and restart the containers.
Database Management Tool
The docker-compose.yml also includes an Adminer service, a lightweight database management tool.
- Access Adminer in your web browser at http://localhost:8080.
- Log in using the server with
- username:
playersync - database:
playersync - password: see docker-compose.yml
- username:
For debugging purposes, you can enable use_legacy_serialization to have readable database fields. This can cause crashes and unintended side-effects. Do not enable this on a production server if not absolutely necessary!
Running the Mod
The project uses Gradle for building and running. Use the provided Gradle wrapper (gradlew for Linux/macOS, gradlew.bat for Windows).
- Make sure that the MySQL database you configured is running.
- Run the Server
or on Windows:./gradlew runServer
This task compiles the mod and starts a dedicated Minecraft server instance with the mod loaded in the.\gradlew.bat runServerrundirectory. - Run the Client
or on Windows:./gradlew runClient.\gradlew.bat runClient