{"id":34253559,"url":"https://github.com/westkevin12/mc-data-bridge","last_synced_at":"2025-12-25T14:05:37.174Z","repository":{"id":319524954,"uuid":"1051481283","full_name":"westkevin12/mc-data-bridge","owner":"westkevin12","description":"MC Data Bridge is a robust, hybrid Minecraft plugin designed to synchronize player data (inventory, health, experience, etc.) across multiple servers within a BungeeCord or Velocity network.","archived":false,"fork":false,"pushed_at":"2025-12-19T09:15:13.000Z","size":124,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-19T21:59:16.413Z","etag":null,"topics":["bungeecord","bungeecord-plugin","minecraft-plugin","papermc","papermc-plugin","spigot","spigot-plugin","velocity","velocity-plugin"],"latest_commit_sha":null,"homepage":"https://www.spigotmc.org/resources/mc-data-bridge.128642/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/westkevin12.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-06T04:48:56.000Z","updated_at":"2025-12-19T09:16:25.000Z","dependencies_parsed_at":null,"dependency_job_id":"ffc79c40-0505-47f2-a349-dc4b261a6be2","html_url":"https://github.com/westkevin12/mc-data-bridge","commit_stats":null,"previous_names":["westkevin12/mc-data-bridge"],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/westkevin12/mc-data-bridge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/westkevin12%2Fmc-data-bridge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/westkevin12%2Fmc-data-bridge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/westkevin12%2Fmc-data-bridge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/westkevin12%2Fmc-data-bridge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/westkevin12","download_url":"https://codeload.github.com/westkevin12/mc-data-bridge/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/westkevin12%2Fmc-data-bridge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28030909,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-25T02:00:05.988Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bungeecord","bungeecord-plugin","minecraft-plugin","papermc","papermc-plugin","spigot","spigot-plugin","velocity","velocity-plugin"],"created_at":"2025-12-16T11:04:25.219Z","updated_at":"2025-12-25T14:05:37.169Z","avatar_url":"https://github.com/westkevin12.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MC Data Bridge\n\n![Minecraft Version](https://img.shields.io/badge/Minecraft-1.21.x-blue?style=for-the-badge\u0026logo=minecraft)\n![Platform](https://img.shields.io/badge/Platform-Paper%20%7C%20Bungee%20%7C%20Velocity-brightgreen?style=for-the-badge)\n[![Modrinth Downloads](https://img.shields.io/modrinth/dt/mc-data-bridge?style=for-the-badge\u0026logo=modrinth\u0026label=Modrinth)](https://modrinth.com/plugin/mc-data-bridge)\n[![Spigot Downloads](https://img.shields.io/spiget/downloads/128642?style=for-the-badge\u0026logo=spigotmc\u0026label=Spigot\u0026color=orange)](https://www.spigotmc.org/resources/128642)\n\nMC 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.\n\n## Compatibility\n\n- **Minecraft Version:** `1.21.x`\n- **Server Platforms:** PaperMC (or forks like Purpur), Spigot\n- **Proxy Platforms:** BungeeCord, Velocity\n\nThis plugin is a hybrid build and the same JAR file works on all supported platforms.\n\n## Features\n\n- **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.\n- **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.\n- **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.\n- **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.\n- **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.\n- **Cross-Server Player Data Sync:** Synchronizes core player data including:\n  - Health\n  - Food Level \u0026 Saturation\n  - Experience (Total XP, current XP, and Level)\n  - Inventory Contents\n  - Armor Contents\n  - Active Potion Effects\n  - **Ender Chest Contents**\n  - **Advancements \u0026 Recipes**\n- **Resilient Connection Pooling:** Uses HikariCP with optimized settings to ensure that the database connection is resilient to network issues and database restarts.\n- **Granular Sync Control**: Enable or disable synchronization for any specific data type via `config.yml`.\n- **Server/World Blacklist**: Prevent synchronization on specific servers or worlds.\n- **Configurable Table Names**: Set a custom prefix for database tables to avoid conflicts.\n- **Configurable \u0026 Flexible:** Easily connect to your MySQL database and configure settings for your server environment.\n\n## Installation\n\n1.  **Build the Plugin:**\n    - Navigate to the plugin's root directory in your terminal.\n    - Run `mvn clean package` to build the plugin.\n    - The compiled JAR file (`mc-data-bridge-*.jar`) will be located in the `target/` directory.\n    - **Note**: Development builds will end in `-SNAPSHOT`. Release builds (from the `main` branch tags) will just be the version number.\n2.  **Deploy to Servers:**\n    - Copy the single `mc-data-bridge-*.jar` file into the `plugins/` folder of **each PaperMC server** you wish to synchronize.\n    - Copy the **same JAR file** into the `plugins/` folder of your **BungeeCord or Velocity proxy server**.\n\n---\n\n## 🛠 Technical Deep Dive\n\nMC 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.\n\n### 1. The Secure Handshake (Happy Path)\n\nThe 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.\n\n```mermaid\nsequenceDiagram\n    autonumber\n    actor User\n    participant P as Proxy (Velocity/Bungee)\n    participant S1 as Source Server\n    participant DB as MySQL Database\n    participant S2 as Destination Server\n\n    User-\u003e\u003eP: /server survival\n    par Signal \u0026 Switch\n        P-\u003e\u003eS1: Plugin Message: \"SaveAndRelease\"\n        P-\u003e\u003eS2: Connect User\n    end\n\n    rect rgb(35, 35, 35)\n        Note over S1, DB: Async Save Process\n        S1-\u003e\u003eDB: UPDATE data... (Save)\n        S1-\u003e\u003eDB: UPDATE is_locked=0 (Release)\n    end\n\n    rect rgb(45, 20, 20)\n        Note over S2, DB: Pre-Login Guard\n        loop Polling Lock (Max 10s)\n            S2-\u003e\u003eDB: Attempt Acquire Lock (UPDATE ...)\n            alt Lock Acquired\n                DB--\u003e\u003eS2: Success\n                Note over S2: Break Loop\n            else Locked by S1\n                DB--\u003e\u003eS2: Fail (Rows = 0)\n                S2--\u003e\u003eS2: Sleep 500ms\n            end\n        end\n    end\n\n    S2-\u003e\u003eDB: SELECT data (Load)\n    DB--\u003e\u003eS2: Return Player Data\n    S2--\u003e\u003eUser: Join Successful\n```\n\n### 2. Anti-Duplication \u0026 Race Condition Protection\n\nBy 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.\n\n```mermaid\nsequenceDiagram\n    participant S1 as Server 1 (Survival)\n    participant DB as MySQL Database\n    participant S2 as Server 2 (Creative)\n\n    Note over S1: Active Session\n    S1-\u003e\u003eDB: Heartbeat (Every 30s)\n\n    Note over S2: Malicious/Accidental Join\n    S2-\u003e\u003eDB: Acquire Lock (UUID)\n    DB--\u003e\u003eS2: FAIL (Locked by 'Survival')\n    S2--\u003e\u003eS2: Kick Player: \"Data still syncing...\"\n```\n\n### 3. Crash Resilience \u0026 Auto-Recovery\n\nIf 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.\n\n```mermaid\nstateDiagram-v2\n    [*] --\u003e Unlocked\n\n    state \"Locked (Active)\" as Locked {\n        [*] --\u003e Valid\n        Valid --\u003e Valid : Heartbeat (Every 30s)\\nUPDATE lock_timestamp\n        Valid --\u003e Expired : Server Crash\\n(No Heartbeat \u003e 60s)\n    }\n\n    Unlocked --\u003e Locked : Player Pre-Login\\n(Acquire Lock)\n    Locked --\u003e Unlocked : Player Quit/Switch\\n(Release Lock)\n\n    Expired --\u003e Locked : New Server Claims Lock\\n(Steal Lock)\n```\n\n## Configuration\n\nA `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.\n\n```yaml\n# MySQL Database Configuration\ndatabase:\n  host: localhost\n  port: 3306\n  database: minecraft\n  username: user\n  password: password\n\n  # A list of JDBC properties to apply.\n  # This is where you would enable SSL (e.g., useSSL: true)\n  properties:\n    useSSL: false\n    allowPublicKeyRetrieval: true\n\n  # HikariCP Connection Pool Settings\n  pool-settings:\n    maximum-pool-size: 10\n    minimum-idle: 10\n    max-lifetime: 1800000 # 30 minutes\n    connection-timeout: 5000 # 5 seconds\n    idle-timeout: 600000 # 10 minutes\n\n  # MySQL JDBC Optimizations\n  optimizations:\n    cache-prep-stmts: true\n    prep-stmt-cache-size: 250\n    prep-stmt-cache-sql-limit: 2048\n    use-server-prep-stmts: true\n    use-local-session-state: true\n    rewrite-batched-statements: true\n    cache-result-set-metadata: true\n    cache-server-configuration: true\n    elide-set-auto-commits: true\n    maintain-time-stats: false\n\n# Set to true to enable verbose debugging messages in the server console.\ndebug: false\n\n# A unique name for this server. This is CRITICAL for data locking.\n# Each server connected to the same database MUST have a unique name.\n# Example: \"survival-1\", \"creative\", \"lobby\"\n# Example: \"survival-1\", \"creative\", \"lobby\"\nserver-id: \"default-server\"\n\n# Set to prefix the player_data table (e.g., 'mc_data_bridge_'). Leave empty for default.\ntable-prefix: \"\"\n\n# The duration in milliseconds after which a player data lock is considered expired.\n# This prevents players from being permanently locked out if a server crashes.\n# Default: 60000 (1 minute)\nlock-timeout: 60000\n\n# Heartbeat interval for lock updates (seconds)\nlock-heartbeat-seconds: 30\n\n# Toggle specific data to sync\nsync-data:\n  health: true\n  food-level: true\n  experience: true\n  inventory: true\n  armor: true\n  potion-effects: true\n  ender-chest: false\n  location: false # Logging only\n  advancements: false\n\n# Blacklist servers/worlds from syncing\nsync-blacklist:\n  servers:\n    - \"example-server\"\n  worlds:\n    - \"example_nether\"\n```\n\n- **`database.*`**: Standard configuration for your MySQL database connection.\n- **`debug`**: Set to `true` to enable verbose debugging messages in the server console. Set to `false` for normal operation.\n- **`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.\n- **`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.\n- **`sync-data`**: Toggle specific features on/off. New features like `ender-chest` and `advancements` are disabled by default.\n- **`sync-blacklist`**: Define servers or worlds where synchronization should be skipped.\n\n## Commands\n\n- `/databridge unlock \u003cplayer\u003e` - Manually release a lock for a specific player (Permission: `databridge.admin`).\n\n## Usage\n\n1.  **Add the JAR:** Place the single `mc-data-bridge-*.jar` file into the `plugins/` folder of all your PaperMC servers AND your BungeeCord/Velocity proxy.\n2.  **Configure:** Edit the `config.yml` in each PaperMC server's `plugins/mc-data-bridge/` folder. **Set a unique `server-id` for each server.**\n3.  **Restart Servers:** Restart your proxy and all backend Minecraft servers.\n4.  **Enjoy!** Players can now seamlessly switch between your linked servers, and their data will be synchronized automatically and safely.\n\n## Important Notes\n\n- **Database Requirement:** This plugin requires a **MySQL or MariaDB database** to function.\n- **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`, and `ALTER` on the specified database.\n- **Connectivity \u0026 Firewalls:** Ensure your Minecraft servers and proxy can open a network connection to your database's `host` and `port`.\n- **Automatic Schema:** The plugin will automatically create and update the `player_data` table in your database. The schema includes `uuid`, `data`, `is_locked`, `locking_server`, `lock_timestamp`, and `last_updated`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwestkevin12%2Fmc-data-bridge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwestkevin12%2Fmc-data-bridge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwestkevin12%2Fmc-data-bridge/lists"}