MC Data Bridge is a robust, high-performance hybrid plugin for PaperMC (Spigot), BungeeCord, and Velocity. It is designed to seamlessly synchronize player data across multiple Minecraft servers, ensuring that players have a consistent experience by retaining their health, hunger, experience, inventory, and more as they move between linked servers.
- Minecraft Version:
1.21.x - Server Platforms: PaperMC (or forks like Purpur), Spigot
- Proxy Platforms: BungeeCord, Velocity
This plugin is a hybrid build and the same JAR file works on all supported platforms.
- Hybrid Plugin: A single JAR file works on your PaperMC/Spigot servers and your BungeeCord/Velocity proxy, automatically activating the correct functionality for each platform.
- Proxy-Initiated Saves: The proxy (BungeeCord/Velocity) orchestrates the data saving process, ensuring that a player's data is saved from their source server before they connect to the destination server. This eliminates race conditions and ensures data is never lost during a server switch.
- Fully Asynchronous: All database operations are performed on a separate thread, ensuring that your server's main thread is never blocked. This means no lag, even if your database is slow to respond.
- Robust Locking Mechanism: A database-level locking mechanism with an automatic timeout prevents data corruption and ensures that only one server can write a player's data at a time.
- Version-Independent Item Serialization: Player inventories are serialized using Minecraft's built-in Base64 methods, which is highly robust and prevents data loss when you update your Minecraft server to a new version.
- Cross-Server Player Data Sync: Synchronizes core player data including:
- Health
- Food Level & Saturation
- Experience (Total XP, current XP, and Level)
- Inventory Contents
- Armor Contents
- Active Potion Effects
- Ender Chest Contents
- Advancements & Recipes
- Resilient Connection Pooling: Uses HikariCP with optimized settings to ensure that the database connection is resilient to network issues and database restarts.
- Granular Sync Control: Enable or disable synchronization for any specific data type via
config.yml. - Server/World Blacklist: Prevent synchronization on specific servers or worlds.
- Configurable Table Names: Set a custom prefix for database tables to avoid conflicts.
- Configurable & Flexible: Easily connect to your MySQL database and configure settings for your server environment.
- Build the Plugin:
- Navigate to the plugin's root directory in your terminal.
- Run
mvn clean packageto build the plugin. - The compiled JAR file (
mc-data-bridge-*.jar) will be located in thetarget/directory. - Note: Development builds will end in
-SNAPSHOT. Release builds (from themainbranch tags) will just be the version number.
- Deploy to Servers:
- Copy the single
mc-data-bridge-*.jarfile into theplugins/folder of each PaperMC server you wish to synchronize. - Copy the same JAR file into the
plugins/folder of your BungeeCord or Velocity proxy server.
- Copy the single
MC Data Bridge is built with a Security-First approach to player state. Unlike traditional sync plugins that rely on simple "Save-on-Quit," this plugin utilizes a Proxy-orchestrated handshake to eliminate data loss and duplication exploits.
The Proxy (Bungee/Velocity) acts as the coordinator. It ensures the Source Server has successfully committed data to the MySQL database and released its lock before the Destination Server is even allowed to request it.
sequenceDiagram
autonumber
actor User
participant P as Proxy (Velocity/Bungee)
participant S1 as Source Server
participant DB as MySQL Database
participant S2 as Destination Server
User->>P: /server survival
par Signal & Switch
P->>S1: Plugin Message: "SaveAndRelease"
P->>S2: Connect User
end
rect rgb(35, 35, 35)
Note over S1, DB: Async Save Process
S1->>DB: UPDATE data... (Save)
S1->>DB: UPDATE is_locked=0 (Release)
end
rect rgb(45, 20, 20)
Note over S2, DB: Pre-Login Guard
loop Polling Lock (Max 10s)
S2->>DB: Attempt Acquire Lock (UPDATE ...)
alt Lock Acquired
DB-->>S2: Success
Note over S2: Break Loop
else Locked by S1
DB-->>S2: Fail (Rows = 0)
S2-->>S2: Sleep 500ms
end
end
end
S2->>DB: SELECT data (Load)
DB-->>S2: Return Player Data
S2-->>User: Join Successful
By using a Database-Level Locking Mechanism, we prevent the "Double-Login" exploit. If a player somehow exists on two servers simultaneously, the second server will be denied access to the data until the first server safely disconnects.
sequenceDiagram
participant S1 as Server 1 (Survival)
participant DB as MySQL Database
participant S2 as Server 2 (Creative)
Note over S1: Active Session
S1->>DB: Heartbeat (Every 30s)
Note over S2: Malicious/Accidental Join
S2->>DB: Acquire Lock (UUID)
DB-->>S2: FAIL (Locked by 'Survival')
S2-->>S2: Kick Player: "Data still syncing..."
If a backend server crashes, the player's data lock might remain "Stuck." MC Data Bridge handles this gracefully via a configurable lock-timeout (Default: 60s). This ensures players aren't permanently locked out of the network while maintaining a safe window for the database to settle.
stateDiagram-v2
[*] --> Unlocked
state "Locked (Active)" as Locked {
[*] --> Valid
Valid --> Valid : Heartbeat (Every 30s)\nUPDATE lock_timestamp
Valid --> Expired : Server Crash\n(No Heartbeat > 60s)
}
Unlocked --> Locked : Player Pre-Login\n(Acquire Lock)
Locked --> Unlocked : Player Quit/Switch\n(Release Lock)
Expired --> Locked : New Server Claims Lock\n(Steal Lock)
A config.yml file will be generated in the plugins/mc-data-bridge/ folder on your PaperMC servers after the first run. You must update this file with your database credentials and a unique server ID.
# MySQL Database Configuration
database:
host: localhost
port: 3306
database: minecraft
username: user
password: password
# A list of JDBC properties to apply.
# This is where you would enable SSL (e.g., useSSL: true)
properties:
useSSL: false
allowPublicKeyRetrieval: true
# HikariCP Connection Pool Settings
pool-settings:
maximum-pool-size: 10
minimum-idle: 10
max-lifetime: 1800000 # 30 minutes
connection-timeout: 5000 # 5 seconds
idle-timeout: 600000 # 10 minutes
# MySQL JDBC Optimizations
optimizations:
cache-prep-stmts: true
prep-stmt-cache-size: 250
prep-stmt-cache-sql-limit: 2048
use-server-prep-stmts: true
use-local-session-state: true
rewrite-batched-statements: true
cache-result-set-metadata: true
cache-server-configuration: true
elide-set-auto-commits: true
maintain-time-stats: false
# Set to true to enable verbose debugging messages in the server console.
debug: false
# A unique name for this server. This is CRITICAL for data locking.
# Each server connected to the same database MUST have a unique name.
# Example: "survival-1", "creative", "lobby"
# Example: "survival-1", "creative", "lobby"
server-id: "default-server"
# Set to prefix the player_data table (e.g., 'mc_data_bridge_'). Leave empty for default.
table-prefix: ""
# The duration in milliseconds after which a player data lock is considered expired.
# This prevents players from being permanently locked out if a server crashes.
# Default: 60000 (1 minute)
lock-timeout: 60000
# Heartbeat interval for lock updates (seconds)
lock-heartbeat-seconds: 30
# Toggle specific data to sync
sync-data:
health: true
food-level: true
experience: true
inventory: true
armor: true
potion-effects: true
ender-chest: false
location: false # Logging only
advancements: false
# Blacklist servers/worlds from syncing
sync-blacklist:
servers:
- "example-server"
worlds:
- "example_nether"database.*: Standard configuration for your MySQL database connection.debug: Set totrueto enable verbose debugging messages in the server console. Set tofalsefor normal operation.server-id(Required): You must set a unique name for each of your PaperMC/Spigot servers. This is critical for the data locking system to work correctly. The proxy server does not need this configuration.lock-timeout: The time in milliseconds after which a data lock is considered expired. This prevents a player from being permanently locked if a server crashes while saving their data.sync-data: Toggle specific features on/off. New features likeender-chestandadvancementsare disabled by default.sync-blacklist: Define servers or worlds where synchronization should be skipped.
/databridge unlock <player>- Manually release a lock for a specific player (Permission:databridge.admin).
- Add the JAR: Place the single
mc-data-bridge-*.jarfile into theplugins/folder of all your PaperMC servers AND your BungeeCord/Velocity proxy. - Configure: Edit the
config.ymlin each PaperMC server'splugins/mc-data-bridge/folder. Set a uniqueserver-idfor each server. - Restart Servers: Restart your proxy and all backend Minecraft servers.
- Enjoy! Players can now seamlessly switch between your linked servers, and their data will be synchronized automatically and safely.
- Database Requirement: This plugin requires a MySQL or MariaDB database to function.
- Security Best Practice: For production servers, it is strongly recommended to create a dedicated MySQL user for this plugin with limited permissions. The user only needs
SELECT,INSERT,UPDATE,CREATE, andALTERon the specified database. - Connectivity & Firewalls: Ensure your Minecraft servers and proxy can open a network connection to your database's
hostandport. - Automatic Schema: The plugin will automatically create and update the
player_datatable in your database. The schema includesuuid,data,is_locked,locking_server,lock_timestamp, andlast_updated.