Storage backends¶
The plugin ships with two backends and you pick one in config.yml:
Changing type requires a server restart; /pv reload warns you if you do it at runtime.
YAML (default)¶
- One readable file per player:
plugins/JPPlayerVaults/data/<uuid>.yml. - Format:
vaults.<number>.items.<slot>: <Bukkit item>, plus the last known player name so administrators can identify the file. - Data is read from disk when a vault opens and dropped when the player quits, so a restart always starts from the real file.
- Lowering
vaults.sizenever deletes anything: items in hidden rows stay in the file and reappear when the size is raised again. - Bukkit converts material names that were renamed in 1.13+ while loading, so data survives Minecraft upgrades.
- Every save is written to a
.tmpfile and moved over the real one (atomic write).
If a file cannot be read (corrupted or hand-edited YAML), the plugin keeps a timestamped .bak copy
and refuses to open that vault until an administrator restores it. Showing an empty vault would
let the next save overwrite the real items. A single item that fails to deserialize does not prevent
the rest of the vault from loading.
Database over JDBC (MySQL / MariaDB)¶
storage:
type: mysql
mysql:
host: '127.0.0.1'
port: 3306
database: 'jpvaults'
username: 'root'
password: ''
table-prefix: 'jpvaults_'
properties: 'useSSL=false&characterEncoding=utf8'
pool-size: 4
connection-timeout-ms: 5000
| Key | Description | Default |
|---|---|---|
host, port, database |
Where the database lives. | 127.0.0.1, 3306, jpvaults |
username, password |
Credentials. | root, empty |
table-prefix |
Prefix of the two tables (letters, digits and _ only). |
jpvaults_ |
properties |
Extra JDBC URL parameters, MySQL syntax. | useSSL=false&characterEncoding=utf8 |
jdbc-url |
Full URL; overrides host/port/database. Use it for another engine. | empty |
driver-class |
JDBC driver to load. | empty (auto-detect) |
pool-size |
Connections the plugin keeps and reuses. | 4 |
connection-timeout-ms |
Connection timeout hint passed to the driver. | 5000 |
Schema¶
The plugin creates the tables on startup:
<prefix>players (uuid VARCHAR(36) PRIMARY KEY, last_name VARCHAR(16), updated_at BIGINT)
<prefix>vaults (uuid VARCHAR(36), vault INT, data BLOB, updated_at BIGINT,
PRIMARY KEY (uuid, vault))
One row per vault. Saving writes the player row and replaces that player's vault rows inside a single transaction (delete + insert), so a failure halfway cannot leave a vault half saved.
The driver¶
The plugin uses plain java.sql and takes the driver from the server: Spigot and Paper ship MySQL
Connector/J, so normally you do not have to do anything. It tries, in order:
storage.mysql.driver-class, if you set one.com.mysql.cj.jdbc.Drivercom.mysql.jdbc.Driverorg.mariadb.jdbc.Driver
For another engine, set driver-class and jdbc-url (for example
jdbc:postgresql://localhost:5432/jpvaults with org.postgresql.Driver), as long as that driver is
on the server's classpath. The driver is instantiated directly instead of going through
DriverManager, which is what lets drivers loaded by other plugins or by the server work.
Behaviour¶
- Reads happen on the server thread when a vault opens. Writes happen on a single plugin thread, in order, and closing a vault waits for its transaction (bounded to 5 seconds).
- If the database cannot be reached at startup, the plugin logs the error and keeps working with
YAML instead of leaving the server without vaults. Fix the settings, restart, and run
/pv admin migrateto copy those files into the database. /pv admin infoshows which backend is active and where it points.
Moving between backends¶
/pv admin migrate copies every YAML file of the configured folder into the active database:
- Without arguments it skips players that already have rows in the database.
/pv admin migrate forceoverwrites the players that are already stored.- It runs in batches (5 players per tick) on the server thread, with the database writes asynchronous, so it cannot freeze the server. Progress goes to whoever ran it and the console.
- The YAML files are never deleted: they remain as a backup. Delete them yourself once you are happy with the database.
The opposite direction is not automated. If you switch type back to yaml, the plugin starts
from the files it finds, and anything written to the database meanwhile would be missing. Keep the
YAML folder (or a database dump) until you are sure, and prefer migrating YAML → database.