No description
Find a file
2026-06-13 10:47:19 +02:00
src/main Minecraft Storage Plugin for PaperMC (works like a backpack) 2026-06-13 10:47:19 +02:00
.gitignore Minecraft Storage Plugin for PaperMC (works like a backpack) 2026-06-13 10:47:19 +02:00
pom.xml Minecraft Storage Plugin for PaperMC (works like a backpack) 2026-06-13 10:47:19 +02:00
README.md Minecraft Storage Plugin for PaperMC (works like a backpack) 2026-06-13 10:47:19 +02:00

ZalmikStorage

Ein mehrseitiges, datenbankgestütztes Lagersystem (ähnlich einer erweiterten Enderchest) für Paper/Spigot-Server ab Minecraft 1.20.

Spieler öffnen über /storage ein 54-Slot-Inventar mit 45 nutzbaren Slots pro Seite und können per Pfeil-Buttons zwischen Seiten blättern. Die Anzahl der verfügbaren Seiten wird über Permissions gesteuert. Items werden serialisiert in einer Datenbank gespeichert.

  • Author: Tronax
  • Version: 1.0
  • API: Paper 1.20

Features

  • Mehrseitiges Lager mit Navigation (Vorherige / Nächste Seite)
  • Pro-Spieler-Speicherung anhand der UUID
  • Seitenlimit konfigurierbar über Permissions
  • Unterstützt SQLite, MySQL/MariaDB und PostgreSQL (HikariCP Connection-Pool)
  • Asynchrones Laden/Speichern, um den Main-Thread zu entlasten

Befehle

Befehl Beschreibung Permission
/storage Öffnet das eigene Lager zalmikstorage.use

Permissions

Permission Beschreibung Default
zalmikstorage.use Erlaubt das Öffnen des Lagers false
zalmikstorage.pages.<n> Setzt das Seitenlimit auf <n> (z. B. .5 = 5)
zalmikstorage.pages.unlimited Hebt das Seitenlimit komplett auf

Das höchste zutreffende zalmikstorage.pages.<n> gewinnt. Ohne eine solche Permission steht 1 Seite zur Verfügung.

Konfiguration (config.yml)

database:
  type: sqlite          # sqlite | mysql | mariadb | postgresql
  host: "127.0.0.1"
  port: 3306
  database: "minecraft"
  username: "root"
  password: "password"
  pool_size: 10
  timeout: 30000

Bei type: sqlite wird eine lokale Datei storage.db im Plugin-Ordner verwendet (Host/Port/Zugangsdaten werden ignoriert).

Build

Voraussetzungen: JDK 21 und Maven.

mvn clean package

Das fertige Plugin liegt anschließend unter target/ZalmikStorage-1.0-SNAPSHOT.jar und kann in den plugins/-Ordner des Servers kopiert werden.

Datenbank-Schema

CREATE TABLE IF NOT EXISTS zalmik_storage (
    uuid  VARCHAR(36) NOT NULL,
    page  INT         NOT NULL,
    items TEXT,
    PRIMARY KEY (uuid, page)
);

Items werden als Base64-kodierter BukkitObjectStream in der Spalte items abgelegt.


Sicherheit & Stabilität

Das Plugin wurde einer Code-Prüfung unterzogen. Die dabei gefundenen Logik- und Sicherheitsprobleme sind behoben:

Kritisch — behoben

  1. Fehlende JDBC-Treiber im Buildsqlite-jdbc und mariadb-java-client wurden der pom.xml hinzugefügt. Die Standard-Konfiguration (type: sqlite) funktioniert jetzt out of the box.

  2. Datenverlust beim Server-StoponDisable() speichert alle offenen Lager nun synchron, bevor die Datenbankverbindung getrennt und die IO-Queues heruntergefahren werden.

  3. Race-Condition beim schnellen Öffnen/Schließen — Laden und Speichern laufen pro Spieler über eine serielle Single-Thread-Queue (ExecutorService). Dadurch ist FIFO-Reihenfolge garantiert: Ein Ladevorgang kann eine noch ausstehende Speicherung nicht mehr überholen.

Hoch — behoben

  1. Permission-Wert wird ignoriertgetMaxPages() überspringt nun Nodes mit getValue() == false. Eine auf false gesetzte zalmikstorage.pages.<n> gewährt keine Seiten mehr.

  2. Stiller Fehlerzustand bei DB-Verbindungsfehlerconnect() wirft jetzt eine Exception statt sie nur zu loggen; onEnable() fängt sie ab und deaktiviert das Plugin, statt in einem kaputten Zustand weiterzulaufen.

Mittel / Niedrig — behoben

  1. Unsichere Deserialisierung / DoSItemSerializer begrenzt die aus den Daten gelesene Array-Größe (MAX_ITEMS = 54) und lehnt ungültige Längen ab, bevor Speicher allokiert wird.

  2. Unbekannter database.type — wird jetzt mit einer klaren IllegalArgumentException abgewiesen, statt mit leerer JDBC-URL zu scheitern.

  3. getCommand("storage") ohne Null-Check — wird vor setExecutor auf null geprüft und sauber geloggt.

Bereits zuvor solide

  • Keine SQL-Injection: Alle Queries nutzen PreparedStatement, das Tabellen-Statement ist statisch.
  • Permission-Gate auf /storage (zalmikstorage.use, Default false).
  • Navigations-Slots (4553) sind klick-geschützt (event.setCancelled(true)), wodurch Item-Klau aus der GUI-Leiste verhindert wird.