Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a475cae54 | |||
| 366e0e9826 | |||
| 1aba2b7e1a | |||
| 91c13dea71 | |||
| fe255b6d26 | |||
| 40b21ca422 | |||
| d085ead6e9 | |||
| f99265a4eb |
343
README.md
343
README.md
@@ -1,192 +1,219 @@
|
|||||||
# AutoSortChest Benutzeranleitung
|
# AutoSortChest
|
||||||
|
|
||||||
Diese Anleitung erklärt, wie du das AutoSortChest-Plugin verwenden und einstellen kannst, um Items in Minecraft automatisch in Truhen zu sortieren.
|
*Intelligente Lagerverwaltung & automatisierte Sortiersysteme ohne Redstone-Chaos*
|
||||||
|
|
||||||
## Nutzung
|

|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
### Einrichtung einer Eingangstruhe
|
---
|
||||||
Eine Eingangstruhe nimmt Items auf und verteilt sie automatisch an Zieltruhen. So richtest du sie ein:
|
|
||||||
1. Platziere ein Schild an oder neben einer Truhe.
|
|
||||||
2. Schreibe Folgendes auf das Schild:
|
|
||||||
|
|
||||||
|
## Über AutoSortChest
|
||||||
|
|
||||||
|
Schluss mit unordentlichen Truhen und stundenlangem Sortieren! **AutoSortChest** ermöglicht es dir, komplexe Sortiersysteme für Farmen, Shops oder Lagerhäuser in Sekunden aufzubauen. Alles funktioniert über ein intuitives Schildersystem – keine komplizierten Befehle oder mühsame Redstone-Leitungen erforderlich.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✨ Features
|
||||||
|
|
||||||
|
- **Einfache Schild-Steuerung:** Erstelle Input-, Ziel- und Rest-Truhen durch das Platzieren eines Schildes.
|
||||||
|
- **Visuelles Status-System:** Schilder ändern ihre Farbe, wenn eine Truhe voll ist, und senden Warnungen im Chat.
|
||||||
|
- **Smart Rest-Truhe (Fallback):** Konfiguriere eine Auffangtruhe für alle Items ohne spezielles Ziel.
|
||||||
|
- **Dynamic Item Update:** Ändere das sortierte Item einer Truhe jederzeit per Rechtsklick – kein Abbauen nötig!
|
||||||
|
- **Privatsphäre-Modus:** Schalte Truhen per Shift-Rechtsklick zwischen Öffentlich und Privat um.
|
||||||
|
- **Server-übergreifend (CrossLink):** Mit MySQL können Zieltruhen auf anderen Servern des Netzwerks liegen. Items werden automatisch via Transfer-Tabelle weitergeleitet.
|
||||||
|
- **Import & Export:** Daten lassen sich bequem zwischen `players.yml` und MySQL hin- und herwechseln – per Admin-Befehl.
|
||||||
|
- **Multiplayer-Optimiert:** Jeder Spieler verwaltet sein eigenes System – kein gegenseitiges Stören.
|
||||||
|
- **Vollständig Anpassbar:** Alle Nachrichten, Farben und Limits lassen sich in der `config.yml` editieren.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📖 Einrichtung
|
||||||
|
|
||||||
|
### 1. Eingangstruhe (Input)
|
||||||
|
Hier wirfst du alle unsortierten Items hinein.
|
||||||
|
|
||||||
|
Schild an die Truhe platzieren und folgendes schreiben:
|
||||||
```
|
```
|
||||||
[asc]
|
[asc]
|
||||||
input
|
input
|
||||||
```
|
```
|
||||||
|
Dein Spielername wird automatisch in Zeile 4 eingetragen.
|
||||||
|
|
||||||
3. Dein Spielername wird automatisch in die vierte Zeile des Schildes eingetragen.
|
---
|
||||||
4. Items, die du in diese Truhe legst, werden automatisch in die entsprechenden Zieltruhen sortiert.
|
|
||||||
|
|
||||||
### Einrichtung einer Zieltruhe
|
### 2. Zieltruhe (Target)
|
||||||
Eine Zieltruhe speichert Items eines bestimmten Typs. So richtest du sie ein:
|
Hier landen die spezifisch sortierten Items.
|
||||||
1. Platziere ein Schild an oder neben einer Truhe.
|
|
||||||
2. Schreibe Folgendes auf das Schild:
|
|
||||||
|
|
||||||
|
Schild an die Truhe platzieren:
|
||||||
```
|
```
|
||||||
[asc]
|
[asc]
|
||||||
ziel
|
ziel
|
||||||
```
|
```
|
||||||
|
Danach mit dem gewünschten Item (z. B. Diamant) auf das Schild **Rechtsklicken** – der Item-Typ wird automatisch eingetragen.
|
||||||
3. Rechtsklicke auf das Schild mit dem Item in der Hand, das diese Truhe speichern soll (z. B. Diamanten).
|
|
||||||
4. Der Item-Typ (z. B. `DIAMOND`) und dein Spielername werden automatisch in die dritte und vierte Zeile des Schildes eingetragen.
|
|
||||||
|
|
||||||
**Hinweis**: Nur der Besitzer der Truhe (dessen Name auf dem Schild steht) kann die Truhe öffnen oder abbauen. Zum Abbauen von Schildern oder Truhen musst du die Shift-Taste gedrückt halten.
|
|
||||||
|
|
||||||
## 🔐 Zugriffrechte verwalten (Privat & Öffentlich)
|
|
||||||
|
|
||||||
Du kannst für jede Truhe (Eingang oder Ziel) festlegen, ob sie **privat** oder **öffentlich** genutzt werden darf.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 🔄 Modus ändern
|
### 3. Rest-Truhe (Fallback)
|
||||||
|
Das Auffangbecken für alle Items ohne Zieltruhe.
|
||||||
1. Halte **nichts** in der Hand (leere Hand).
|
```
|
||||||
2. Halte die **Shift-Taste** gedrückt.
|
[asc]
|
||||||
3. Mache einen **Rechtsklick** auf das **Schild** oder die **Truhe**.
|
rest
|
||||||
|
|
||||||
➡️ Das Schild wechselt anschließend automatisch den Modus.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 📦 Modi im Überblick
|
|
||||||
|
|
||||||
**🔒 Privat**
|
|
||||||
- Nur **du** kannst die Truhe nutzen oder Items einwerfen.
|
|
||||||
- Die Sortierung funktioniert **nur, wenn du online bist**.
|
|
||||||
|
|
||||||
**🌍 Öffentlich**
|
|
||||||
- **Alle Spieler** können Items in die Eingangstruhe werfen.
|
|
||||||
- Items werden **auch sortiert, wenn du offline bist**.
|
|
||||||
- Das Schild zeigt **`[Public]`** hinter deinem Namen an.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### ⚠️ Wichtige Regeln
|
|
||||||
|
|
||||||
- **Nur der Owner** (Name auf dem Schild) kann den Modus ändern.
|
|
||||||
- **Nur der Owner** kann das Schild oder die Truhe abbauen
|
|
||||||
(unabhängig davon, ob sie privat oder öffentlich ist).
|
|
||||||
- Zum Abbauen muss **immer die Shift-Taste gedrückt gehalten werden**.
|
|
||||||
|
|
||||||
|
|
||||||
### Befehle
|
|
||||||
Verwende die folgenden Befehle im Spiel:
|
|
||||||
- `/asc help`: Zeigt die Hilfe mit Anweisungen zur Nutzung.
|
|
||||||
- `/asc info`: Zeigt Informationen über das Plugin (Version, Autor, etc.).
|
|
||||||
- `/asc reload`: Lädt die Konfigurationsdateien neu. (Erfordert die Berechtigung `autosortchest.reload`, normalerweise nur für Server-Operatoren.)
|
|
||||||
|
|
||||||
## Konfiguration
|
|
||||||
|
|
||||||
### config.yml
|
|
||||||
Die `config.yml`-Datei im `plugins/AutoSortChest`-Ordner ermöglicht die Anpassung von Schildfarben und Nachrichten. Sie wird beim ersten Start des Plugins erstellt. Hier sind die wichtigsten Einstellungen:
|
|
||||||
|
|
||||||
- **Schildfarben**: Passe die Farben der Schilder für Eingangs-, Ziel- und volle Truhen an. Verwende Minecraft-Farbcodes (z. B. `&6` für Gold).
|
|
||||||
```yaml
|
|
||||||
sign-colors:
|
|
||||||
input:
|
|
||||||
line1: "&6" # Farbe für "[asc]" auf Eingangsschildern
|
|
||||||
line2: "&0" # Farbe für "input"
|
|
||||||
line4: "&f" # Farbe für den Spielernamen
|
|
||||||
target:
|
|
||||||
line1: "&6" # Farbe für "[asc]" auf Zieltruhen
|
|
||||||
line2: "&0" # Farbe für "ziel"
|
|
||||||
line3: "&f" # Farbe für den Item-Typ
|
|
||||||
line4: "&f" # Farbe für den Spielernamen
|
|
||||||
full:
|
|
||||||
line1: "&c" # Farbe für "[asc]" bei vollen Truhen
|
|
||||||
line2: "&4" # Farbe für "ziel" bei vollen Truhen
|
|
||||||
line3: "&e" # Farbe für den Item-Typ
|
|
||||||
line4: "&e" # Farbe für den Spielernamen
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Nachrichten: Passe die Nachrichten an, die Spielern im Spiel angezeigt werden.
|
---
|
||||||
|
|
||||||
|
## 🔐 Zugriff & Modi
|
||||||
|
|
||||||
|
| Aktion | Beschreibung |
|
||||||
|
|--------|-------------|
|
||||||
|
| **Shift + Rechtsklick** (leere Hand) auf Schild/Truhe | Wechselt zwischen Privat und Öffentlich |
|
||||||
|
| **Privat** | Nur der Besitzer kann die Truhe nutzen. Sortierung nur bei Online-Status. |
|
||||||
|
| **Öffentlich** | Alle Spieler dürfen Items einwerfen. Sortierung auch offline. Schild zeigt `[Public]`. |
|
||||||
|
|
||||||
|
> Nur der Besitzer (Name auf dem Schild) kann den Modus ändern oder die Truhe/das Schild abbauen.
|
||||||
|
> Zum Abbauen immer **Shift gedrückt halten**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🌐 Serverübergreifende Sortierung (CrossLink)
|
||||||
|
|
||||||
|
Wenn MySQL aktiviert und `server_crosslink: true` gesetzt ist, können Zieltruhen auf **anderen Servern desselben Netzwerks** liegen.
|
||||||
|
|
||||||
|
**Funktionsweise:**
|
||||||
|
1. Server A hat die Eingangstruhe und erkennt, dass die Zieltruhe für `OAK_LOG` auf Server B liegt.
|
||||||
|
2. Server A schreibt den Transfer in die gemeinsame Datenbank (`asc_transfers`).
|
||||||
|
3. Server B liest die Transfer-Tabelle und befüllt seine lokale Zieltruhe automatisch.
|
||||||
|
|
||||||
|
**Voraussetzung:** Alle Server müssen dieselbe MySQL-Datenbank nutzen.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💬 Befehle & Berechtigungen
|
||||||
|
|
||||||
|
| Befehl | Beschreibung | Berechtigung |
|
||||||
|
|--------|-------------|-------------|
|
||||||
|
| `/asc help` | Zeigt die Hilfe an | – |
|
||||||
|
| `/asc info` | Plugin-Informationen (Version, Autor) | `autosortchest.use` |
|
||||||
|
| `/asc reload` | Konfiguration neu laden | `autosortchest.reload` |
|
||||||
|
| `/asc import` | Importiert Daten aus `players.yml` → MySQL | `autosortchest.import` (OP) |
|
||||||
|
| `/asc export` | Exportiert Daten aus MySQL → `players.yml` | `autosortchest.export` (OP) |
|
||||||
|
|
||||||
|
### Import & Export – Details
|
||||||
|
|
||||||
|
**`/asc import`**
|
||||||
|
Überträgt alle Spielerdaten aus der `players.yml` in die MySQL-Datenbank. Sinnvoll beim erstmaligen Wechsel von YAML auf MySQL. Bestehende MySQL-Einträge werden dabei nicht gelöscht, sondern aktualisiert (`REPLACE INTO`).
|
||||||
|
|
||||||
|
**`/asc export`**
|
||||||
|
Exportiert alle Daten aus MySQL zurück in die `players.yml`. Enthält die `players.yml` noch Daten, wird vorher automatisch ein Backup erstellt (`players_backup_<timestamp>.yml`). Ist die Datei bereits leer, wird kein unnötiges Backup angelegt.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚙️ Konfiguration (config.yml)
|
||||||
```yaml
|
```yaml
|
||||||
|
# Version der Konfigurationsdatei
|
||||||
|
version: "2.0"
|
||||||
|
|
||||||
|
# Debug-Modus (nur für Entwicklung)
|
||||||
|
debug: false
|
||||||
|
|
||||||
|
# MySQL/MariaDB – für CrossLink und zentralen Datenspeicher
|
||||||
|
mysql:
|
||||||
|
enabled: false
|
||||||
|
host: "localhost"
|
||||||
|
port: 3306
|
||||||
|
database: "autosortchest"
|
||||||
|
user: "autosortchest"
|
||||||
|
password: "autosortchest"
|
||||||
|
|
||||||
|
# Serverübergreifende Sortierung (benötigt MySQL)
|
||||||
|
server_crosslink: true
|
||||||
|
|
||||||
|
# Sprache: 'de' oder 'en'
|
||||||
|
language: "de"
|
||||||
|
|
||||||
|
# Welten, in denen das Plugin deaktiviert ist
|
||||||
|
world_blacklist:
|
||||||
|
- "world_nether"
|
||||||
|
- "world_the_end"
|
||||||
|
|
||||||
|
# Sortier-Intervall in Ticks (1 Tick = 0,05s)
|
||||||
|
sort_interval_ticks: 5
|
||||||
|
|
||||||
|
# Maximale Anzahl Zieltruhen pro Spielergruppe
|
||||||
|
chest_limits:
|
||||||
|
default: 5
|
||||||
|
vip: 100
|
||||||
|
|
||||||
|
# Schildfarben (Minecraft-Farbcodes)
|
||||||
|
sign-colors:
|
||||||
|
input:
|
||||||
|
line1: "&6" # [asc]
|
||||||
|
line2: "&0" # input
|
||||||
|
line4: "&1" # Spielername
|
||||||
|
target:
|
||||||
|
line1: "&6" # [asc]
|
||||||
|
line2: "&0" # ziel
|
||||||
|
line3: "&f" # Item-Typ
|
||||||
|
line4: "&1" # Spielername
|
||||||
|
full:
|
||||||
|
line1: "&c"
|
||||||
|
line2: "&4"
|
||||||
|
line3: "&e"
|
||||||
|
line4: "&1"
|
||||||
|
rest:
|
||||||
|
line1: "&6"
|
||||||
|
line2: "&0"
|
||||||
|
line3: "&f"
|
||||||
|
line4: "&1"
|
||||||
|
|
||||||
|
# Nachrichten
|
||||||
messages:
|
messages:
|
||||||
no-chest-near-sign: "&cKeine Truhe in der Nähe des Schildes!"
|
no-chest-near-sign: "&cKeine Truhe in der Nähe des Schildes!"
|
||||||
no-item-in-hand: "&cDu musst ein Item in der Hand halten!"
|
no-item-in-hand: "&cDu musst ein Item in der Hand halten!"
|
||||||
not-your-chest: "&cDiese Truhe gehört dir nicht!"
|
not-your-chest: "&cDiese Truhe gehört dir nicht!"
|
||||||
input-chest-set: "&aEingangstruhe erfolgreich gesetzt!"
|
input-chest-set: "&aEingangstruhe erfolgreich gesetzt!"
|
||||||
target-chest-set: "&aZieltruhe für %item% erfolgreich gesetzt!"
|
target-chest-set: "&aZieltruhe erfolgreich für %item% eingerichtet!"
|
||||||
|
rest-chest-set: "&aRest-Truhe (Fallback) erfolgreich gesetzt!"
|
||||||
target-chest-missing: "&cZieltruhe für %item% fehlt!"
|
target-chest-missing: "&cZieltruhe für %item% fehlt!"
|
||||||
target-chest-full: "&cZieltruhe für %item% ist voll! Koordinaten: (%x%, %y%, %z%)"
|
target-chest-full: "&cZieltruhe für %item% ist voll! Koordinaten: (%x%, %y%, %z%)"
|
||||||
help: |-
|
sign-break-denied: "&cDu musst Shift gedrückt halten, um dieses Schild oder die Truhe abzubauen!"
|
||||||
&6&l=== AutoSortChest Hilfe ===
|
|
||||||
&eEingangstruhe erstellen:
|
|
||||||
&f1. Platziere ein Schild an einer Truhe.
|
|
||||||
&f2. Schreibe:
|
|
||||||
&7[asc]
|
|
||||||
&7input
|
|
||||||
&fDein Name wird automatisch in Zeile 4 eingetragen.
|
|
||||||
&eZieltruhe erstellen:
|
|
||||||
&f1. Platziere ein Schild an einer Truhe.
|
|
||||||
&f2. Schreibe:
|
|
||||||
&7[asc]
|
|
||||||
&7ziel
|
|
||||||
&f3. Rechtsklicke mit einem Item in der Hand.
|
|
||||||
&eBefehle:
|
|
||||||
&f- &b/asc help &f- Zeigt diese Hilfe.
|
|
||||||
&f- &b/asc info &f- Zeigt Plugin-Informationen.
|
|
||||||
&f- &b/asc reload &f- Lädt die Konfiguration neu (OP).
|
|
||||||
&6&l====================
|
|
||||||
info: |-
|
|
||||||
&6&l=== AutoSortChest Info ===
|
|
||||||
&ePlugin: &fAutoSortChest
|
|
||||||
&eVersion: &f%version%
|
|
||||||
&eKonfigurationsversion: &f%config_version%
|
|
||||||
&eErsteller: &f%author%
|
|
||||||
&eBeschreibung: &fAutomatisches Sortieren von Items in Truhen.
|
|
||||||
&6&l====================
|
|
||||||
no-permission: "&cDu hast keine Berechtigung für diesen Befehl!"
|
no-permission: "&cDu hast keine Berechtigung für diesen Befehl!"
|
||||||
reload-success: "&aKonfiguration erfolgreich neu geladen!"
|
reload-success: "&aKonfiguration erfolgreich neu geladen!"
|
||||||
sign-break-denied: "&cDu musst Shift gedrückt halten, um dieses Schild oder die Truhe abzubauen!
|
mode-changed: "&aModus gewechselt: &e%mode%"
|
||||||
```
|
mode-public: "&aÖffentlich"
|
||||||
|
mode-private: "&cPrivat"
|
||||||
### Anpassung:
|
|
||||||
|
|
||||||
Öffne config.yml mit einem Texteditor.
|
|
||||||
Ändere die Farbcodes oder Nachrichten nach deinen Wünschen.
|
|
||||||
Speichere die Datei und führe /asc reload im Spiel aus (erfordert autosortchest.reload-Berechtigung), um die Änderungen zu übernehmen.
|
|
||||||
|
|
||||||
### players.yml
|
|
||||||
Die players.yml-Datei speichert automatisch die Positionen von Eingangs- und Zieltruhen für jeden Spieler. Sie wird vom Plugin verwaltet und sollte normalerweise nicht manuell bearbeitet werden. Beispiel:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
players:
|
|
||||||
<player-uuid>:
|
|
||||||
input-chest:
|
|
||||||
world: world
|
|
||||||
x: 100
|
|
||||||
y: 64
|
|
||||||
z: 200
|
|
||||||
target-chests:
|
|
||||||
DIAMOND:
|
|
||||||
world: world
|
|
||||||
x: 102
|
|
||||||
y: 64
|
|
||||||
z: 202
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
<player-uuid> ist die eindeutige ID des Spielers.
|
|
||||||
input-chest speichert die Koordinaten der Eingangstruhe.
|
|
||||||
target-chests listet Zieltruhen für bestimmte Item-Typen (z. B. DIAMOND).
|
|
||||||
Hinweis: Wenn eine Truhe entfernt wird, aktualisiert das Plugin die Daten automatisch und benachrichtigt den Spieler, wenn eine Zieltruhe fehlt.
|
|
||||||
|
|
||||||
Tipps
|
|
||||||
Schutz der Truhen: Nur der Besitzer (Name auf dem Schild) kann die Truhe öffnen oder abbauen. Halte Shift gedrückt, um Schilder oder Truhen abzubauen.
|
|
||||||
Volle Truhen: Wenn eine Zieltruhe voll ist, ändert das Schild seine Farbe (gemäß sign-colors.full in config.yml) und du erhältst eine Benachrichtigung (maximal alle 5 Minuten pro Item-Typ).
|
|
||||||
Debug-Modus: Falls Probleme auftreten, kann ein Server-Operator debug: true in config.yml setzen, um detaillierte Logs zu erhalten.
|
|
||||||
Falls du Fragen hast oder Hilfe benötigst, verwende /asc help im Spiel!
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Erklärung
|
## 🗄️ Datenbank-Tabellen
|
||||||
- **Fokus**: Die Anleitung konzentriert sich ausschließlich auf die Nutzung (Einrichtung von Truhen, Befehle) und Konfiguration (`config.yml` und `players.yml`), wie von dir gewünscht.
|
|
||||||
- **Struktur**: Klare Abschnitte für Nutzung und Konfiguration, mit detaillierten Schritten zur Einrichtung von Truhen, Erklärung der Befehle und Anleitung zur Anpassung der Konfigurationsdateien.
|
|
||||||
- **Format**: Markdown-Codeblock, wie für GitHub üblich, mit korrekt formatierten YAML-Beispielen und klaren Anweisungen.
|
|
||||||
- **Sprache**: Komplett auf Deutsch, wie angefordert.
|
|
||||||
- **Praktische Tipps**: Zusätzliche Hinweise zu Schutzmechanismen, vollen Truhen und Debug-Modus, um die Benutzerfreundlichkeit zu erhöhen.
|
|
||||||
|
|
||||||
Falls du spezifische Änderungen, zusätzliche Details oder eine andere Struktur möchtest, lass es mich wissen!
|
Bei aktiviertem MySQL erstellt das Plugin folgende Tabellen automatisch:
|
||||||
|
|
||||||
|
| Tabelle | Inhalt |
|
||||||
|
|---------|--------|
|
||||||
|
| `asc_players` | Spieler-UUIDs und Namen |
|
||||||
|
| `asc_input_chests` | Registrierte Eingangstruhen |
|
||||||
|
| `asc_target_chests` | Zieltruhen mit Item-Zuordnung |
|
||||||
|
| `asc_rest_chests` | Rest-/Fallback-Truhen |
|
||||||
|
| `asc_transfers` | Ausstehende CrossLink-Transfers zwischen Servern |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 Technische Details
|
||||||
|
|
||||||
|
- **Kompatibilität:** Paper, Spigot, Purpur (1.18.x – 1.21.x)
|
||||||
|
- **Java:** 17+
|
||||||
|
- **Datenbank:** YAML (Standard) oder MySQL/MariaDB (optional)
|
||||||
|
- **Performance:** Ressourcenschonende Sortier-Algorithmen mit konfigurierbarem Intervall
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💬 Support
|
||||||
|
|
||||||
|
[](https://discord.com/invite/FdRs4BRd8D)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Viper Plugins © 2026 – Effizienz für deinen Server*
|
||||||
80
pom.xml
80
pom.xml
@@ -1,38 +1,44 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.viper</groupId>
|
<groupId>com.viper</groupId>
|
||||||
<artifactId>AutoSortChest</artifactId>
|
<artifactId>AutoSortChest</artifactId>
|
||||||
<version>1.8</version>
|
<version>2.0</version>
|
||||||
<name>AutoSortChest</name>
|
<name>AutoSortChest</name>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
<id>spigot-repo</id>
|
<id>spigot-repo</id>
|
||||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.spigotmc</groupId>
|
<groupId>org.spigotmc</groupId>
|
||||||
<artifactId>spigot-api</artifactId>
|
<artifactId>spigot-api</artifactId>
|
||||||
<version>1.21-R0.1-SNAPSHOT</version>
|
<version>1.21-R0.1-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
<!-- MySQL Connector -->
|
||||||
|
<dependency>
|
||||||
<build>
|
<groupId>mysql</groupId>
|
||||||
<plugins>
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
<plugin>
|
<version>8.0.33</version>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
</dependency>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
</dependencies>
|
||||||
<version>3.8.1</version>
|
|
||||||
<configuration>
|
<build>
|
||||||
<source>17</source>
|
<plugins>
|
||||||
<target>17</target>
|
<plugin>
|
||||||
</configuration>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
</plugin>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
</plugins>
|
<version>3.8.1</version>
|
||||||
</build>
|
<configuration>
|
||||||
|
<source>17</source>
|
||||||
|
<target>17</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
File diff suppressed because it is too large
Load Diff
412
src/main/java/com/viper/autosortchest/MySQLManager.java
Normal file
412
src/main/java/com/viper/autosortchest/MySQLManager.java
Normal file
@@ -0,0 +1,412 @@
|
|||||||
|
package com.viper.autosortchest;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class MySQLManager {
|
||||||
|
public Connection getConnection() {
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String host, database, user, password;
|
||||||
|
private final int port;
|
||||||
|
private Connection connection;
|
||||||
|
|
||||||
|
public MySQLManager(String host, int port, String database, String user, String password) {
|
||||||
|
this.host = host;
|
||||||
|
this.port = port;
|
||||||
|
this.database = database;
|
||||||
|
this.user = user;
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean connect() {
|
||||||
|
try {
|
||||||
|
if (connection != null && !connection.isClosed()) return true;
|
||||||
|
Class.forName("com.mysql.cj.jdbc.Driver");
|
||||||
|
connection = DriverManager.getConnection(
|
||||||
|
"jdbc:mysql://" + host + ":" + port + "/" + database
|
||||||
|
+ "?useSSL=false&autoReconnect=true&characterEncoding=UTF-8&serverTimezone=UTC",
|
||||||
|
user, password
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disconnect() {
|
||||||
|
try {
|
||||||
|
if (connection != null && !connection.isClosed()) connection.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setupTables() {
|
||||||
|
try (Statement st = connection.createStatement()) {
|
||||||
|
st.execute("CREATE TABLE IF NOT EXISTS asc_players (uuid VARCHAR(36) PRIMARY KEY, name VARCHAR(32));");
|
||||||
|
st.execute("CREATE TABLE IF NOT EXISTS asc_input_chests (uuid VARCHAR(36), chest_id VARCHAR(36), world VARCHAR(32), x INT, y INT, z INT, `public` BOOLEAN DEFAULT FALSE, PRIMARY KEY(uuid, chest_id));");
|
||||||
|
st.execute("CREATE TABLE IF NOT EXISTS asc_target_chests (uuid VARCHAR(36), item VARCHAR(64), world VARCHAR(32), x INT, y INT, z INT, `public` BOOLEAN DEFAULT FALSE, PRIMARY KEY(uuid, item));");
|
||||||
|
st.execute("CREATE TABLE IF NOT EXISTS asc_rest_chests (uuid VARCHAR(36), world VARCHAR(32), x INT, y INT, z INT, `public` BOOLEAN DEFAULT FALSE, PRIMARY KEY(uuid));");
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transfer-Tabelle für serverübergreifende Sortierung.
|
||||||
|
*/
|
||||||
|
public void setupTransferTable() {
|
||||||
|
try (Statement st = connection.createStatement()) {
|
||||||
|
st.execute(
|
||||||
|
"CREATE TABLE IF NOT EXISTS asc_transfers (" +
|
||||||
|
" id BIGINT AUTO_INCREMENT PRIMARY KEY," +
|
||||||
|
" uuid VARCHAR(36) NOT NULL," +
|
||||||
|
" item VARCHAR(64) NOT NULL," +
|
||||||
|
" amount INT NOT NULL," +
|
||||||
|
" target_world VARCHAR(32) NOT NULL," +
|
||||||
|
" created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP" +
|
||||||
|
");"
|
||||||
|
);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTransfer(String uuid, String item, int amount, String targetWorld) {
|
||||||
|
try (PreparedStatement ps = connection.prepareStatement(
|
||||||
|
"INSERT INTO asc_transfers (uuid, item, amount, target_world) VALUES (?, ?, ?, ?);")) {
|
||||||
|
ps.setString(1, uuid);
|
||||||
|
ps.setString(2, item);
|
||||||
|
ps.setInt(3, amount);
|
||||||
|
ps.setString(4, targetWorld);
|
||||||
|
ps.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Map<String, Object>> getPendingTransfers(String uuid) {
|
||||||
|
List<Map<String, Object>> list = new ArrayList<>();
|
||||||
|
try (PreparedStatement ps = connection.prepareStatement(
|
||||||
|
"SELECT id, item, amount, target_world FROM asc_transfers WHERE uuid=? ORDER BY created_at ASC;")) {
|
||||||
|
ps.setString(1, uuid);
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("id", rs.getLong("id"));
|
||||||
|
map.put("item", rs.getString("item"));
|
||||||
|
map.put("amount", rs.getInt("amount"));
|
||||||
|
map.put("target_world", rs.getString("target_world"));
|
||||||
|
list.add(map);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteTransfer(long id) {
|
||||||
|
try (PreparedStatement ps = connection.prepareStatement(
|
||||||
|
"DELETE FROM asc_transfers WHERE id=?;")) {
|
||||||
|
ps.setLong(1, id);
|
||||||
|
ps.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateTransferAmount(long id, int newAmount) {
|
||||||
|
try (PreparedStatement ps = connection.prepareStatement(
|
||||||
|
"UPDATE asc_transfers SET amount=? WHERE id=?;")) {
|
||||||
|
ps.setInt(1, newAmount);
|
||||||
|
ps.setLong(2, id);
|
||||||
|
ps.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Spieler ---
|
||||||
|
|
||||||
|
public void savePlayer(String uuid, String name) {
|
||||||
|
try (PreparedStatement ps = connection.prepareStatement(
|
||||||
|
"REPLACE INTO asc_players (uuid, name) VALUES (?, ?);")) {
|
||||||
|
ps.setString(1, uuid);
|
||||||
|
ps.setString(2, name);
|
||||||
|
ps.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt alle Spieler aus der asc_players-Tabelle zurück.
|
||||||
|
* Wird für den Export (MySQL → YAML) benötigt.
|
||||||
|
*
|
||||||
|
* @return Liste mit uuid und name je Spieler
|
||||||
|
*/
|
||||||
|
public List<Map<String, Object>> getAllPlayers() {
|
||||||
|
List<Map<String, Object>> list = new ArrayList<>();
|
||||||
|
try (Statement st = connection.createStatement();
|
||||||
|
ResultSet rs = st.executeQuery("SELECT uuid, name FROM asc_players;")) {
|
||||||
|
while (rs.next()) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("uuid", rs.getString("uuid"));
|
||||||
|
map.put("name", rs.getString("name"));
|
||||||
|
list.add(map);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Input-Chest ---
|
||||||
|
|
||||||
|
public void addInputChest(String uuid, String chestId, String world, int x, int y, int z) {
|
||||||
|
addInputChest(uuid, chestId, world, x, y, z, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addInputChest(String uuid, String chestId, String world, int x, int y, int z, boolean isPublic) {
|
||||||
|
try (PreparedStatement ps = connection.prepareStatement(
|
||||||
|
"REPLACE INTO asc_input_chests (uuid, chest_id, world, x, y, z, `public`) VALUES (?, ?, ?, ?, ?, ?, ?);")) {
|
||||||
|
ps.setString(1, uuid);
|
||||||
|
ps.setString(2, chestId);
|
||||||
|
ps.setString(3, world);
|
||||||
|
ps.setInt(4, x);
|
||||||
|
ps.setInt(5, y);
|
||||||
|
ps.setInt(6, z);
|
||||||
|
ps.setBoolean(7, isPublic);
|
||||||
|
ps.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeInputChest(String uuid, String chestId) {
|
||||||
|
try (PreparedStatement ps = connection.prepareStatement(
|
||||||
|
"DELETE FROM asc_input_chests WHERE uuid=? AND chest_id=?;")) {
|
||||||
|
ps.setString(1, uuid);
|
||||||
|
ps.setString(2, chestId);
|
||||||
|
ps.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Map<String, Object>> getInputChests(String uuid) {
|
||||||
|
List<Map<String, Object>> list = new ArrayList<>();
|
||||||
|
try (PreparedStatement ps = connection.prepareStatement(
|
||||||
|
"SELECT * FROM asc_input_chests WHERE uuid=?;")) {
|
||||||
|
ps.setString(1, uuid);
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("chest_id", rs.getString("chest_id"));
|
||||||
|
map.put("world", rs.getString("world"));
|
||||||
|
map.put("x", rs.getInt("x"));
|
||||||
|
map.put("y", rs.getInt("y"));
|
||||||
|
map.put("z", rs.getInt("z"));
|
||||||
|
map.put("public", rs.getBoolean("public"));
|
||||||
|
list.add(map);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Target-Chest ---
|
||||||
|
|
||||||
|
public void setTargetChest(String uuid, String item, String world, int x, int y, int z) {
|
||||||
|
setTargetChest(uuid, item, world, x, y, z, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTargetChest(String uuid, String item, String world, int x, int y, int z, boolean isPublic) {
|
||||||
|
try (PreparedStatement ps = connection.prepareStatement(
|
||||||
|
"REPLACE INTO asc_target_chests (uuid, item, world, x, y, z, `public`) VALUES (?, ?, ?, ?, ?, ?, ?);")) {
|
||||||
|
ps.setString(1, uuid);
|
||||||
|
ps.setString(2, item);
|
||||||
|
ps.setString(3, world);
|
||||||
|
ps.setInt(4, x);
|
||||||
|
ps.setInt(5, y);
|
||||||
|
ps.setInt(6, z);
|
||||||
|
ps.setBoolean(7, isPublic);
|
||||||
|
ps.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> getTargetChest(String uuid, String item) {
|
||||||
|
try (PreparedStatement ps = connection.prepareStatement(
|
||||||
|
"SELECT * FROM asc_target_chests WHERE uuid=? AND item=?;")) {
|
||||||
|
ps.setString(1, uuid);
|
||||||
|
ps.setString(2, item);
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
if (rs.next()) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("world", rs.getString("world"));
|
||||||
|
map.put("x", rs.getInt("x"));
|
||||||
|
map.put("y", rs.getInt("y"));
|
||||||
|
map.put("z", rs.getInt("z"));
|
||||||
|
map.put("public", rs.getBoolean("public"));
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeTargetChest(String uuid, String item) {
|
||||||
|
try (PreparedStatement ps = connection.prepareStatement(
|
||||||
|
"DELETE FROM asc_target_chests WHERE uuid=? AND item=?;")) {
|
||||||
|
ps.setString(1, uuid);
|
||||||
|
ps.setString(2, item);
|
||||||
|
ps.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Map<String, Object>> getTargetChests(String uuid) {
|
||||||
|
List<Map<String, Object>> list = new ArrayList<>();
|
||||||
|
try (PreparedStatement ps = connection.prepareStatement(
|
||||||
|
"SELECT * FROM asc_target_chests WHERE uuid=?;")) {
|
||||||
|
ps.setString(1, uuid);
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("item", rs.getString("item"));
|
||||||
|
map.put("world", rs.getString("world"));
|
||||||
|
map.put("x", rs.getInt("x"));
|
||||||
|
map.put("y", rs.getInt("y"));
|
||||||
|
map.put("z", rs.getInt("z"));
|
||||||
|
map.put("public", rs.getBoolean("public"));
|
||||||
|
list.add(map);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Rest-Chest ---
|
||||||
|
|
||||||
|
public void setRestChest(String uuid, String world, int x, int y, int z) {
|
||||||
|
setRestChest(uuid, world, x, y, z, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRestChest(String uuid, String world, int x, int y, int z, boolean isPublic) {
|
||||||
|
try (PreparedStatement ps = connection.prepareStatement(
|
||||||
|
"REPLACE INTO asc_rest_chests (uuid, world, x, y, z, `public`) VALUES (?, ?, ?, ?, ?, ?);")) {
|
||||||
|
ps.setString(1, uuid);
|
||||||
|
ps.setString(2, world);
|
||||||
|
ps.setInt(3, x);
|
||||||
|
ps.setInt(4, y);
|
||||||
|
ps.setInt(5, z);
|
||||||
|
ps.setBoolean(6, isPublic);
|
||||||
|
ps.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> getRestChest(String uuid) {
|
||||||
|
try (PreparedStatement ps = connection.prepareStatement(
|
||||||
|
"SELECT * FROM asc_rest_chests WHERE uuid=?;")) {
|
||||||
|
ps.setString(1, uuid);
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
if (rs.next()) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("world", rs.getString("world"));
|
||||||
|
map.put("x", rs.getInt("x"));
|
||||||
|
map.put("y", rs.getInt("y"));
|
||||||
|
map.put("z", rs.getInt("z"));
|
||||||
|
map.put("public", rs.getBoolean("public"));
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeRestChest(String uuid) {
|
||||||
|
try (PreparedStatement ps = connection.prepareStatement(
|
||||||
|
"DELETE FROM asc_rest_chests WHERE uuid=?;")) {
|
||||||
|
ps.setString(1, uuid);
|
||||||
|
ps.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Hilfsmethoden für serverCrosslink ---
|
||||||
|
|
||||||
|
public List<Map<String, Object>> getAllInputChests() {
|
||||||
|
List<Map<String, Object>> list = new ArrayList<>();
|
||||||
|
try (PreparedStatement ps = connection.prepareStatement("SELECT * FROM asc_input_chests;")) {
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("chest_id", rs.getString("chest_id"));
|
||||||
|
map.put("uuid", rs.getString("uuid"));
|
||||||
|
map.put("world", rs.getString("world"));
|
||||||
|
map.put("x", rs.getInt("x"));
|
||||||
|
map.put("y", rs.getInt("y"));
|
||||||
|
map.put("z", rs.getInt("z"));
|
||||||
|
map.put("public", rs.getBoolean("public"));
|
||||||
|
list.add(map);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Map<String, Object>> getAllTargetChests() {
|
||||||
|
List<Map<String, Object>> list = new ArrayList<>();
|
||||||
|
try (PreparedStatement ps = connection.prepareStatement("SELECT * FROM asc_target_chests;")) {
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("item", rs.getString("item"));
|
||||||
|
map.put("uuid", rs.getString("uuid"));
|
||||||
|
map.put("world", rs.getString("world"));
|
||||||
|
map.put("x", rs.getInt("x"));
|
||||||
|
map.put("y", rs.getInt("y"));
|
||||||
|
map.put("z", rs.getInt("z"));
|
||||||
|
map.put("public", rs.getBoolean("public"));
|
||||||
|
list.add(map);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> getAnyRestChest() {
|
||||||
|
try (PreparedStatement ps = connection.prepareStatement(
|
||||||
|
"SELECT * FROM asc_rest_chests WHERE public=1 LIMIT 1;")) {
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
if (rs.next()) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("uuid", rs.getString("uuid"));
|
||||||
|
map.put("world", rs.getString("world"));
|
||||||
|
map.put("x", rs.getInt("x"));
|
||||||
|
map.put("y", rs.getInt("y"));
|
||||||
|
map.put("z", rs.getInt("z"));
|
||||||
|
map.put("public", rs.getBoolean("public"));
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
77
src/main/java/com/viper/autosortchest/UpdateChecker.java
Normal file
77
src/main/java/com/viper/autosortchest/UpdateChecker.java
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
package com.viper.autosortchest;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Scanner;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class UpdateChecker {
|
||||||
|
|
||||||
|
private final JavaPlugin plugin;
|
||||||
|
private final int resourceId;
|
||||||
|
|
||||||
|
public UpdateChecker(JavaPlugin plugin, int resourceId) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.resourceId = resourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getVersion(final Consumer<String> consumer) {
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> {
|
||||||
|
try (InputStream is = new URL("https://api.spigotmc.org/legacy/update.php?resource=" + this.resourceId + "/~").openStream();
|
||||||
|
Scanner scann = new Scanner(is)) {
|
||||||
|
if (scann.hasNext()) {
|
||||||
|
consumer.accept(scann.next());
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
plugin.getLogger().info("Konnte nicht nach Updates suchen: " + e.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vergleicht zwei Versions-Strings semantisch (z.B. "2.0" vs "1.9").
|
||||||
|
* Gibt true zurück wenn currentVersion NEUER ODER GLEICH latestVersion ist.
|
||||||
|
* Gibt false zurück wenn latestVersion neuer ist (= Update verfügbar).
|
||||||
|
*
|
||||||
|
* Beispiele:
|
||||||
|
* isCurrentVersionUpToDate("2.0", "1.9") → true (wir sind neuer, kein Update nötig)
|
||||||
|
* isCurrentVersionUpToDate("1.9", "1.9") → true (gleich, kein Update nötig)
|
||||||
|
* isCurrentVersionUpToDate("1.8", "1.9") → false (Update verfügbar)
|
||||||
|
*/
|
||||||
|
public static boolean isCurrentVersionUpToDate(String currentVersion, String latestVersion) {
|
||||||
|
try {
|
||||||
|
String[] current = currentVersion.trim().split("[.\\-]");
|
||||||
|
String[] latest = latestVersion.trim().split("[.\\-]");
|
||||||
|
|
||||||
|
int length = Math.max(current.length, latest.length);
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
int c = i < current.length ? parseVersionPart(current[i]) : 0;
|
||||||
|
int l = i < latest.length ? parseVersionPart(latest[i]) : 0;
|
||||||
|
if (c > l) return true; // Aktuelle Version ist neuer → kein Update nötig
|
||||||
|
if (c < l) return false; // Veröffentlichte Version ist neuer → Update verfügbar
|
||||||
|
}
|
||||||
|
return true; // Versionen sind identisch
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Im Zweifel: kein Update anzeigen um false-positives zu vermeiden
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int parseVersionPart(String part) {
|
||||||
|
try {
|
||||||
|
// Nur die führenden Ziffern parsen (z.B. "1-SNAPSHOT" → 1)
|
||||||
|
StringBuilder digits = new StringBuilder();
|
||||||
|
for (char ch : part.toCharArray()) {
|
||||||
|
if (Character.isDigit(ch)) digits.append(ch);
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
return digits.length() > 0 ? Integer.parseInt(digits.toString()) : 0;
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,34 +1,161 @@
|
|||||||
version: "1.6"
|
# ============================================================
|
||||||
debug: false
|
# _ _ __ _ ___ _ _
|
||||||
|
# /_\ _ _| |_ ___ / _\ ___ _ __| |_ / __\ |__ ___ ___| |_
|
||||||
|
# //_\\| | | | __/ _ \\ \ / _ \| '__| __|/ / | '_ \ / _ \/ __| __|
|
||||||
|
# / _ \ |_| | || (_) |\ \ (_) | | | |_/ /___| | | | __/\__ \ |_
|
||||||
|
# \_/ \_/\__,_|\__\___/\__/\___/|_| \__\____/|_| |_|\___||___/\__|
|
||||||
|
#
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
# --- GRUNDLEGUNG ---
|
||||||
|
# Version der Konfigurationsdatei. Nicht ändern, um Fehler zu vermeiden!
|
||||||
|
|
||||||
|
version: "2.0"
|
||||||
|
|
||||||
|
# Debug-Modus (true = Ausführliche Logs in der Server-Konsole, nur zum Entwickeln nutzen)
|
||||||
|
|
||||||
|
debug: false
|
||||||
|
|
||||||
|
# ---------------------------------------------------
|
||||||
|
# DATENBANK (MySQL/MariaDB) - Optional
|
||||||
|
# ---------------------------------------------------
|
||||||
|
# Aktiviere MySQL/MariaDB Speicherung (true/false)
|
||||||
|
|
||||||
|
mysql:
|
||||||
|
enabled: false
|
||||||
|
host: "localhost"
|
||||||
|
port: 3306
|
||||||
|
database: "autosortchest"
|
||||||
|
user: "autosortchest"
|
||||||
|
password: "autosortchest"
|
||||||
|
|
||||||
|
# Soll serverübergreifendes Sortieren (mit MySQL) erlaubt sein?
|
||||||
|
server_crosslink: true
|
||||||
|
|
||||||
|
# ---------------------------------------------------
|
||||||
|
# SPRACHE (Language)
|
||||||
|
# ---------------------------------------------------
|
||||||
|
# Mögliche Werte: 'de' für Deutsch oder 'en' für Englisch
|
||||||
|
# Ändert den Text von /asc help und /asc info
|
||||||
|
language: "de"
|
||||||
|
|
||||||
|
# ---------------------------------------------------
|
||||||
|
# BLACKLIST FÜR WELTEN (Optional)
|
||||||
|
# ---------------------------------------------------
|
||||||
|
# Welten, in denen AutoSortChest NICHT funktioniert
|
||||||
|
|
||||||
|
world_blacklist:
|
||||||
|
- "world_nether"
|
||||||
|
- "world_the_end"
|
||||||
|
|
||||||
|
# ---------------------------------------------------
|
||||||
|
# VISUELLE EFFEKTE (PARTIKEL & TÖNE)
|
||||||
|
# ---------------------------------------------------
|
||||||
|
|
||||||
|
# Einstellungen für den Regenbogen-Effekt beim Sortieren
|
||||||
|
effects:
|
||||||
|
# Sollen Effekte angezeigt werden?
|
||||||
|
enabled: false
|
||||||
|
# Soll ein Ton gespielt werden, wenn Items ankommen?
|
||||||
|
sound: false
|
||||||
|
# Der Partikel-Typ.
|
||||||
|
# 'DUST' ist zwingend für den bunten Regenbogen-Effekt im aktuellen Code.
|
||||||
|
type: "DUST"
|
||||||
|
|
||||||
|
# ---------------------------------------------------
|
||||||
|
# SORTIER-INTERVALL (Ticks)
|
||||||
|
# ---------------------------------------------------
|
||||||
|
# Wie oft soll sortiert werden? (1 Tick = 0,05s)
|
||||||
|
#
|
||||||
|
# Wähle hier je nach Server-Leistung:
|
||||||
|
#
|
||||||
|
# 1 = SEHR SCHNELL (Items verschwinden sofort)
|
||||||
|
# WARNUNG: Kann bei vielen Truhen Lagg verursachen!
|
||||||
|
#
|
||||||
|
# 5 = SCHNELL (Sehr flüssig, gute Balance)
|
||||||
|
# Empfohlen für schnelle Server.
|
||||||
|
#
|
||||||
|
# 10 = FLÜSSIG (0,5s Verzögerung)
|
||||||
|
# Spart Ressourcen, fühlt sich noch schnell an.
|
||||||
|
#
|
||||||
|
# 20 = STANDARD (1 Sekunde)
|
||||||
|
# Standard-Wert, minimale Last.
|
||||||
|
#
|
||||||
|
# 30+ = SPARSAM (>1,5 Sekunden)
|
||||||
|
# Für sehr große Server mit schwacher Hardware.
|
||||||
|
#
|
||||||
|
sort_interval_ticks: 5
|
||||||
|
|
||||||
|
sort_interval_ticks: 5
|
||||||
|
|
||||||
|
# ---------------------------------------------------
|
||||||
|
# LIMITS FÜR SORTIERKISTEN (Optional)
|
||||||
|
# ---------------------------------------------------
|
||||||
|
# Maximale Anzahl an Sortierkisten pro Spielergruppe
|
||||||
|
|
||||||
|
chest_limits:
|
||||||
|
default: 50
|
||||||
|
vip: 100
|
||||||
|
# Beispiel für weitere Gruppen:
|
||||||
|
# supporter: 150
|
||||||
|
# admin: 200
|
||||||
|
|
||||||
|
# ---------------------------------------------------
|
||||||
|
# SCHILDFARBEN (Farbcodes wie im Chat)
|
||||||
|
# &c = Rot, &a = Grün, &e = Gelb, &6 = Gold, &f = Weiß, &0 = Schwarz
|
||||||
|
# ---------------------------------------------------
|
||||||
|
|
||||||
|
sign-colors:
|
||||||
|
# Farben für die Eingangstruhe ([asc] / input)
|
||||||
|
input:
|
||||||
|
line1: "&6" # Zeile 1: [asc]
|
||||||
|
line2: "&0" # Zeile 2: input
|
||||||
|
line4: "&1" # Zeile 4: Spielername
|
||||||
|
|
||||||
|
# Farben für die Zieltruhe ([asc] / ziel)
|
||||||
|
target:
|
||||||
|
line1: "&6" # Zeile 1: [asc]
|
||||||
|
line2: "&0" # Zeile 2: ziel
|
||||||
|
line3: "&f" # Zeile 3: Item-Name
|
||||||
|
line4: "&1" # Zeile 4: Spielername
|
||||||
|
|
||||||
|
# Farben für volle Truhen (Automatische Erkennung)
|
||||||
|
full:
|
||||||
|
line1: "&c" # Zeile 1: [asc]
|
||||||
|
line2: "&4" # Zeile 2: ziel / rest (Rot)
|
||||||
|
line3: "&e" # Zeile 3: Item-Name (Gelb)
|
||||||
|
line4: "&1" # Zeile 4: Spielername
|
||||||
|
|
||||||
|
# Farben für die Rest-Truhe ([asc] / rest)
|
||||||
|
rest:
|
||||||
|
line1: "&6" # Zeile 1: [asc]
|
||||||
|
line2: "&0" # Zeile 2: rest
|
||||||
|
line3: "&f" # Zeile 3: (Leer)
|
||||||
|
line4: "&1" # Zeile 4: Spielername
|
||||||
|
|
||||||
|
# ---------------------------------------------------
|
||||||
|
# SYSTEM NACHRICHTEN (Spieler-Feedback)
|
||||||
|
# Platzhalter: %player%, %item%, %x%, %y%, %z%, %mode%
|
||||||
|
# ---------------------------------------------------
|
||||||
|
|
||||||
messages:
|
messages:
|
||||||
|
# --- FEHLERMELDUNGEN ---
|
||||||
no-chest-near-sign: "&cKeine Truhe in der Nähe des Schildes!"
|
no-chest-near-sign: "&cKeine Truhe in der Nähe des Schildes!"
|
||||||
no-item-in-hand: "&cDu musst ein Item in der Hand halten!"
|
no-item-in-hand: "&cDu musst ein Item in der Hand halten!"
|
||||||
not-your-chest: "&cDiese Truhe gehört dir nicht!"
|
not-your-chest: "&cDiese Truhe gehört dir nicht!"
|
||||||
|
target-chest-missing: "&cZieltruhe für %item% fehlt!"
|
||||||
|
sign-break-denied: "&cDu musst Shift gedrückt halten, um dieses Schild oder die Truhe abzubauen!"
|
||||||
|
no-permission: "&cDu hast keine Berechtigung für diesen Befehl!"
|
||||||
|
|
||||||
|
# --- ERFOLGSMELDUNGEN ---
|
||||||
input-chest-set: "&aEingangstruhe erfolgreich gesetzt!"
|
input-chest-set: "&aEingangstruhe erfolgreich gesetzt!"
|
||||||
target-chest-set: "&aZieltruhe erfolgreich für %item% eingerichtet!"
|
target-chest-set: "&aZieltruhe erfolgreich für %item% eingerichtet!"
|
||||||
target-chest-missing: "&cZieltruhe für %item% fehlt!"
|
rest-chest-set: "&aRest-Truhe (Fallback) erfolgreich gesetzt!"
|
||||||
target-chest-full: "&cZieltruhe für %item% ist voll! Koordinaten: (%x%, %y%, %z%)"
|
|
||||||
help: "&6&l=== AutoSortChest Hilfe ===\n&eEingangstruhe erstellen:\n&f1. Platziere ein Schild an einer Truhe.\n&f2. Schreibe:\n &7[asc]\n &7input\n&fDein Name wird automatisch in Zeile 4 eingetragen.\n&eZieltruhe erstellen:\n&f1. Platziere ein Schild an einer Truhe.\n&f2. Schreibe:\n &7[asc]\n &7ziel\n&f3. Rechtsklicke mit einem Item in der Hand.\n&eBefehle:\n&f- &b/asc help &f- Zeigt diese Hilfe.\n&f- &b/asc info &f- Zeigt Plugin-Informationen.\n&f- &b/asc reload &f- Lädt die Konfiguration neu (OP).\n&6&l===================="
|
|
||||||
info: "&6&l=== AutoSortChest Info ===\n&ePlugin: &fAutoSortChest\n&eVersion: &f%version%\n&eKonfigurationsversion: &f%config_version%\n&eErsteller: &f%author%\n&eBeschreibung: &fAutomatisches Sortieren von Items in Truhen.\n&6&l===================="
|
|
||||||
no-permission: "&cDu hast keine Berechtigung für diesen Befehl!"
|
|
||||||
reload-success: "&aKonfiguration erfolgreich neu geladen!"
|
reload-success: "&aKonfiguration erfolgreich neu geladen!"
|
||||||
sign-break-denied: "&cDu musst Shift gedrückt halten, um dieses Schild oder die Truhe abzubauen!"
|
|
||||||
sign-colors:
|
# --- HINWEIS MELDUNGEN ---
|
||||||
input:
|
target-chest-full: "&cZieltruhe für %item% ist voll! Koordinaten: (%x%, %y%, %z%)"
|
||||||
line1: "&6" # [asc]
|
mode-changed: "&aModus gewechselt: &e%mode%"
|
||||||
line2: "&0" # input
|
mode-public: "&aÖffentlich"
|
||||||
line4: "&1" # Spielername
|
mode-private: "&cPrivat"
|
||||||
target:
|
|
||||||
line1: "&6" # [asc]
|
|
||||||
line2: "&0" # ziel
|
|
||||||
line3: "&f" # Item
|
|
||||||
line4: "&1" # Spielername
|
|
||||||
full:
|
|
||||||
line1: "&c" # [asc] für volle Truhe
|
|
||||||
line2: "&4" # ziel für volle Truhe
|
|
||||||
line3: "&e" # Item für volle Truhe
|
|
||||||
line4: "&1" # Spielername
|
|
||||||
rest:
|
|
||||||
line1: "&6" # Farbe für [asc] bei der Rest-Truhe
|
|
||||||
line2: "&0" # Farbe für 'rest'
|
|
||||||
line4: "&1" # Farbe für den Spielernamen
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: AutoSortChest
|
name: AutoSortChest
|
||||||
version: 1.9
|
version: 2.0
|
||||||
main: com.viper.autosortchest.Main
|
main: com.viper.autosortchest.Main
|
||||||
api-version: 1.21
|
api-version: 1.21
|
||||||
authors: [M_Viper]
|
authors: [M_Viper]
|
||||||
@@ -7,12 +7,18 @@ description: Ein Plugin zum automatischen Sortieren von Items in Truhen
|
|||||||
commands:
|
commands:
|
||||||
asc:
|
asc:
|
||||||
description: AutoSortChest Befehle
|
description: AutoSortChest Befehle
|
||||||
usage: /<command> [help|info|reload]
|
usage: /<command> [help|info|reload|import|export]
|
||||||
aliases: [autosortchest]
|
aliases: [autosortchest]
|
||||||
permissions:
|
permissions:
|
||||||
autosortchest.reload:
|
autosortchest.reload:
|
||||||
description: Erlaubt das Neuladen der Konfiguration mit /asc reload
|
description: Erlaubt das Neuladen der Konfiguration mit /asc reload
|
||||||
default: op
|
default: op
|
||||||
|
autosortchest.import:
|
||||||
|
description: Erlaubt den Import von players.yml nach MySQL mit /asc import
|
||||||
|
default: op
|
||||||
|
autosortchest.export:
|
||||||
|
description: Erlaubt den Export von MySQL nach players.yml mit /asc export
|
||||||
|
default: op
|
||||||
autosortchest.bypass:
|
autosortchest.bypass:
|
||||||
description: Erlaubt das Abbauen von ASC-Schildern ohne Shift-Taste und unabhängig vom Besitzer
|
description: Erlaubt das Abbauen von ASC-Schildern ohne Shift-Taste und unabhängig vom Besitzer
|
||||||
default: op
|
default: op
|
||||||
|
|||||||
Reference in New Issue
Block a user