A Minecraft Forge mod that synchronizes player data across multiple servers using a MySQL backend.
Go to file
laforetbrut 13de5b65c0 Fix backpack/curios dup, perf overhaul, drop chat+cobblemon
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
2026-04-22 02:50:26 +02:00
.github Bump gradle/actions from 4 to 5 2025-10-14 16:55:21 +08:00
gradle/wrapper migrate from ForgeGradle to ModDevGradle legacy 2025-05-02 22:40:39 +00:00
src/main Fix backpack/curios dup, perf overhaul, drop chat+cobblemon 2026-04-22 02:50:26 +02:00
.gitattributes Initial commit 2022-12-08 16:59:20 +08:00
.gitignore Fix backpack/curios dup, perf overhaul, drop chat+cobblemon 2026-04-22 02:50:26 +02:00
build.gradle perf: zero JDBC on server thread + HikariCP + parallel shutdown + audit fixes 2026-03-29 18:58:27 +02:00
docker-compose.yml use volume for docker-compose db to persist data 2025-05-01 18:42:58 +00:00
gradle.properties perf: zero JDBC on server thread + HikariCP + parallel shutdown + audit fixes 2026-03-29 18:58:27 +02:00
gradlew migrate from ForgeGradle to ModDevGradle legacy 2025-05-02 22:40:39 +00:00
gradlew.bat migrate from ForgeGradle to ModDevGradle legacy 2025-05-02 22:40:39 +00:00
LICENSE Create LICENSE 2022-12-08 17:11:47 +08:00
README.md readme: add section on how to setup a dev env 2025-05-01 16:59:05 +00:00
settings.gradle half done, noticed about advancement can't store normally 2025-06-07 00:55:30 +08:00

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.

  1. Make sure Docker is installed.
  2. Inside your work directory run:
    docker compose up -d
    
    This will download the MariaDB image (if not already present) and start a database container in the background.
  3. 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.

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).

  1. Make sure that the MySQL database you configured is running.
  2. Run the Server
    ./gradlew runServer
    
    or on Windows:
    .\gradlew.bat runServer
    
    This task compiles the mod and starts a dedicated Minecraft server instance with the mod loaded in the run directory.
  3. Run the Client
    ./gradlew runClient
    
    or on Windows:
    .\gradlew.bat runClient