A Minecraft Forge mod that synchronizes player data across multiple servers using a MySQL backend.
Go to file
laforetbrut be816cb359 Phase 19: wire save_on_death + save_on_respawn (dead config) to fix keep-charm edge cases
User report: Twilight Forest 'Charm of Keeping' + ReviveMe interaction loses
inventory over multiple deaths. Analysis concludes this is a Twilight/ReviveMe
event-priority interaction, not a PlayerSync bug — but two dead config options
hid admin-facing levers that help mitigate the case.

(1) save_on_death was declared in JdbcConfig but NEVER read in code. The death
    snapshot ran unconditionally. Now gated: setting save_on_death=false
    disables the LivingDeathEvent-driven pre-drop snapshot. The normal
    onPlayerLogout save still fires on disconnect, so nothing is lost — but
    admins diagnosing a keeping-charm interaction can quickly turn off the
    aggressive death snapshot to rule PlayerSync in or out.

(2) save_on_respawn was also declared but never read. Added a new
    @SubscribeEvent PlayerEvent.PlayerRespawnEvent handler that calls
    snapshotAndQueueSave(player, 'RESPAWN') after the respawn completes.
    This captures the post-death state AFTER keeping-charms / Corail
    Tombstone / similar mods have restored their preserved items, so
    PlayerSync's DB row reflects the actual post-respawn inventory rather
    than the pre-drop snapshot from onPlayerDeath.

    Excludes end-portal exit (isEndConquered) since that's not a death
    respawn — no need to overwrite.

Combined effect: if a player dies, charm-keeps items, respawns, the DB
ends up with:
  t=0  death snapshot (pre-drop, full inventory)
  t=X  respawn snapshot (post-drop, kept items + whatever charm restored)
The respawn snapshot overwrites the death one by virtue of running later.
A disconnect between t=0 and t=X still saves via onPlayerLogout anyway,
so no loss window opens.

No change to the duplication-safety guarantees from Phases 15-18:
onPlayerDeath still checks event.isCanceled() for ReviveMe, the RESPAWN
snapshot goes through the normal snapshotAndQueueSave pipeline with all
the P0-a/b/c guards and the 2-phase-commit logout_started_at tracking.

Answer to the user's question: the keep-charm inventory loss is
overwhelmingly likely to be a ReviveMe x Twilight Forest event-priority
bug outside PlayerSync's control, but this commit exposes two levers
(save_on_death, save_on_respawn) that let admins test whether PlayerSync
is contributing — setting save_on_death=false should make the symptom
unchanged if the root cause is external.
2026-04-22 20:15:30 +02:00
.github Bump gradle/actions from 4 to 5 2025-10-14 16:55:21 +08:00
compat-mods Add compat-mods staging folder for mod compatibility analysis 2026-04-22 03:33:11 +02:00
gradle/wrapper migrate from ForgeGradle to ModDevGradle legacy 2025-05-02 22:40:39 +00:00
src/main Phase 19: wire save_on_death + save_on_respawn (dead config) to fix keep-charm edge cases 2026-04-22 20:15:30 +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 jarJar: declare version ranges for MySQL + HikariCP 2026-04-22 06:46:24 +02:00
CHANGELOG.md Phase 8: 20+ new config keys + 14 admin commands (/playersync) 2026-04-22 06:34:02 +02:00
docker-compose.yml use volume for docker-compose db to persist data 2025-05-01 18:42:58 +00:00
ERROR_LOG.md Phase 6: docs (CHANGELOG, ERROR_LOG, TEST_PROCEDURE) 2026-04-22 06:09:08 +02: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
TEST_PROCEDURE_v2.1.5.html Phase 6: docs (CHANGELOG, ERROR_LOG, TEST_PROCEDURE) 2026-04-22 06:09:08 +02: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