A Minecraft Forge mod that synchronizes player data across multiple servers using a MySQL backend.
Go to file
laforetbrut 1d30184aba Fix critical data loss, backpack duplication, and ender chest sync
CRITICAL - New player data loss (players lose everything):
- store() INSERT now includes last_server column. Without it, last_server
  stayed NULL, causing ALL subsequent writes (AND last_server=?) to fail
  silently — new players' data was never saved after initial INSERT.
- writeSnapshotToDB now handles legacy NULL last_server with
  (last_server=? OR last_server IS NULL) and auto-claims ownership.
- Same NULL handling in writeGuardedModData for mod_player_data table.

CRITICAL - online=0 stuck at 1 (players unable to connect):
- Removed AND last_server=? from deadPlayerWhileLogging and
  syncNotCompletedPlayer logout paths. These fire before doPlayerJoin
  sets last_server, so the guard always failed → online stayed 1.

CRITICAL - Backpack duplication via viewer race:
- snapshotBackpackData() now captures backpack NBT on the MAIN THREAD
  (not just UUIDs). Previously saveBackpacksByUuids read BackpackStorage
  on an async thread — another player viewing the backpack could take
  items between the main-thread refresh and the async read.
- .copy() freezes the NBT state at snapshot time.

CRITICAL - Backpacks in ender chest not synced:
- snapshotBackpackData() and doBackPackRestore now scan the ender chest
  in addition to main inventory. PlayerInventoryProvider.runOnBackpacks
  only scans equipment/inventory, missing ender chest backpacks entirely.

Anti-duplication - Container closing on disconnect:
- Owner's container menu is force-closed before snapshot to prevent
  post-snapshot modifications by viewers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 11:00:18 +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 critical data loss, backpack duplication, and ender chest sync 2026-04-15 11:00:18 +02:00
.gitattributes Initial commit 2022-12-08 16:59:20 +08:00
.gitignore add support for Minecraft 1.20.4 with ModDevGradle 2025-05-04 18:43:11 +00: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