Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8693ef41af | |||
| 52f00f9b93 | |||
| fb05868e65 | |||
| 6943022cd3 | |||
| da5adc8034 | |||
| 197acc6750 | |||
| 40295f3711 | |||
| 1638ad4e8a | |||
| e5251933e1 | |||
| 08b05167d8 |
27
pom.xml
27
pom.xml
@@ -1,13 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>de.viper</groupId>
|
<groupId>de.viper</groupId>
|
||||||
<artifactId>SurvivalPlus</artifactId>
|
<artifactId>SurvivalPlus</artifactId>
|
||||||
<version>1.1.1-Beta</version>
|
<version>1.1.2-Beta</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<name>SurvivalPlus</name>
|
<name>SurvivalPlus</name>
|
||||||
|
|
||||||
@@ -26,6 +25,10 @@
|
|||||||
<id>codemc-repo</id>
|
<id>codemc-repo</id>
|
||||||
<url>https://repo.codemc.io/repository/maven-public/</url>
|
<url>https://repo.codemc.io/repository/maven-public/</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>jitpack.io</id>
|
||||||
|
<url>https://jitpack.io</url>
|
||||||
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@@ -61,13 +64,21 @@
|
|||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- ProtocolLib 4.8.0 (für WrapperPlayServerScoreboardTeam) -->
|
<!-- ProtocolLib 4.8.0 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.comphenix.protocol</groupId>
|
<groupId>com.comphenix.protocol</groupId>
|
||||||
<artifactId>ProtocolLib</artifactId>
|
<artifactId>ProtocolLib</artifactId>
|
||||||
<version>4.8.0</version>
|
<version>4.8.0</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Vault API -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.milkbowl.vault</groupId>
|
||||||
|
<artifactId>VaultAPI</artifactId>
|
||||||
|
<version>1.7</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@@ -78,8 +89,8 @@
|
|||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.8.1</version>
|
<version>3.8.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>17</source>
|
<!-- Hier KEINE expliziten source/target Werte setzen. -->
|
||||||
<target>17</target>
|
<!-- Maven nutzt jetzt automatisch die 21 aus den Properties oben. -->
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
@@ -87,7 +98,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>3.4.1</version>
|
<version>3.5.0</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>package</phase>
|
<phase>package</phase>
|
||||||
@@ -130,6 +141,8 @@
|
|||||||
<include>lootchests.yml</include>
|
<include>lootchests.yml</include>
|
||||||
<include>blocks.yml</include>
|
<include>blocks.yml</include>
|
||||||
<include>nicknames.yml</include>
|
<include>nicknames.yml</include>
|
||||||
|
<include>mobadapt.yml</include>
|
||||||
|
<include>heads.yml</include>
|
||||||
</includes>
|
</includes>
|
||||||
</resource>
|
</resource>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
305
readme.md
305
readme.md
@@ -1,174 +1,265 @@
|
|||||||
|
<div align="center">
|
||||||
|
|
||||||
# SurvivalPlus
|
# SurvivalPlus
|
||||||
|
|
||||||

|
### Das ultimative Survival-Plugin für deinen Minecraft Server
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
**SurvivalPlus** ist ein Minecraft-Plugin zur Verbesserung des Survival-Erlebnisses.
|
[](https://github.com/username/SurvivalPlus)
|
||||||
Es bietet Homes, Teleports, Inventar-/Enderchest-Verwaltung, Claims (Anti-Grief), Freundeslisten, Shop-System, Loot-Kisten, Tablist-Anpassungen und viele Komfort-Utilities.
|
[](https://www.minecraft.net/)
|
||||||
|
[](https://openjdk.org/)
|
||||||
|
[](https://www.spigotmc.org/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**SurvivalPlus** erweitert dein Minecraft Survival-Erlebnis mit uber 50 Befehlen, umfangreichen Schutzsystemen und zahlreichen Quality-of-Life Features. Entwickelt fur Performance und einfache Konfiguration.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📦 Beschreibung
|
||||||
|
|
||||||
|
**SurvivalPlus** ist ein umfangreiches Minecraft-Plugin zur Verbesserung des klassischen Survival-Erlebnisses.
|
||||||
|
Es kombiniert Komfort-Features für Spieler mit leistungsstarken Verwaltungs- und Schutzmechanismen für Serverbetreiber.
|
||||||
|
|
||||||
|
Enthalten sind unter anderem:
|
||||||
|
Homes, Teleports, Inventar- & Enderchest-Verwaltung, Claims (Anti-Grief), Freundeslisten, Shop-System, Loot-Kisten, Tablist-Anpassungen, Player Heads, erweiterte Vanish-Funktionen sowie zahlreiche Server-Utilities.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ⚡ Highlights / Features
|
## ⚡ Highlights / Features
|
||||||
|
|
||||||
- Homes & Warps (persönliche Warps, Home-Management)
|
- **Homes & Warps**
|
||||||
- Teleportation & Anfrage-System (`/tpa`, `/tpaccept`, `/tpdeny`)
|
Persönliche Warps, Home-Management, GUI-Übersichten
|
||||||
- Claim-System zur Land-Sicherung (trust/untrust, create/delete, info, list)
|
|
||||||
- Inventar- & Enderchest-Verwaltung (öffnen von Fremd-Inventaren, Admin-Tools)
|
- **Teleportation & Anfrage-System**
|
||||||
- Shop-System & Lootchests (Verwaltung, Teleport zu Lootchests)
|
`/tpa`, `/tpaccept`, `/tpdeny`, `/back`, `/spawn`
|
||||||
- CommandBlocker & Server-Utilities (clearchat, clearitems, closedoors, lock)
|
|
||||||
- Debug-Logging (optionale `debug-logging` in config, Debug/debug.log & Debug/console.log)
|
- **Claim-System (Anti-Grief)**
|
||||||
- Tablist (animiert / konfigurierbar über `tablist.yml`)
|
Land sichern, Trust/Untrust, Ban/Kick, Claim-Infos
|
||||||
- bStats Unterstützung (Statistiken)
|
|
||||||
|
- **Inventar- & Enderchest-Verwaltung**
|
||||||
|
Admin-Zugriff auf Fremd-Inventare
|
||||||
|
|
||||||
|
- **Neu: Player Heads**
|
||||||
|
Köpfe bei Tod oder per `/head` Befehl
|
||||||
|
|
||||||
|
- **Neu: Erweiterte Vanish-Funktionen**
|
||||||
|
Silent Join, keine Item-Aufnahme
|
||||||
|
|
||||||
|
- **Neu: Sign Shops**
|
||||||
|
Schilder-Shops mit Vault-Integration
|
||||||
|
|
||||||
|
- **Shop-System & Lootchests**
|
||||||
|
Verwaltung & Teleport zu Loot-Kisten
|
||||||
|
|
||||||
|
- **CommandBlocker & Server-Utilities**
|
||||||
|
Clearchat, Clearitems, Closedoors, Lock-System
|
||||||
|
|
||||||
|
- **Debug-Logging**
|
||||||
|
Optionales Logging in `debug.log` & `console.log`
|
||||||
|
|
||||||
|
- **Tablist**
|
||||||
|
Animiert & konfigurierbar über `tablist.yml`
|
||||||
|
|
||||||
|
- **bStats Unterstützung**
|
||||||
|
Anonyme Statistiken
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🛠 Komplette Befehlsübersicht
|
## Befehlsübersicht
|
||||||
|
|
||||||
> Hinweis: In `plugin.yml` sind alle Commands definiert — hier die Übersicht gruppiert nach Kategorie.
|
> **Hinweis:**
|
||||||
|
> Alle Commands sind vollständig in der `plugin.yml` definiert.
|
||||||
|
> Nachfolgend eine Übersicht nach Kategorien.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Allgemein / Haupt
|
### Allgemein / Haupt
|
||||||
|
|
||||||
| Befehl | Nutzung | Permission |
|
| Befehl | Nutzung | Permission |
|
||||||
|---|---:|:---|
|
|------|------|-----------|
|
||||||
| `/sp` | Hauptbefehl (CommandBlocker, reload, info, share, help u.v.m.) | `survivalplus.sp` |
|
| `/sp` | Hauptbefehl (Reload, Info, Help, Share, CommandBlocker u.v.m.) | `survivalplus.sp` |
|
||||||
| `/help` (alias über `/sp help`) | Hilfe / Übersicht | `survivalplus.sp` |
|
| `/help` | Hilfe / Übersicht (Alias: `/sp help`) | `survivalplus.sp` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Item & Utility
|
### Item & Utility
|
||||||
| Befehl | Usage | Permission |
|
|
||||||
|---|---:|:---|
|
| Befehl | Nutzung | Permission |
|
||||||
| `/ir <neuer_name>` | Item umbenennen (Item in Hand) | `survivalplus.itemrename` |
|
|------|------|-----------|
|
||||||
|
| `/ir <name>` | Item umbenennen (Item in Hand) | `survivalplus.itemrename` |
|
||||||
| `/workbench` | Öffnet Werkbank-GUI | `survivalplus.workbench` |
|
| `/workbench` | Öffnet Werkbank-GUI | `survivalplus.workbench` |
|
||||||
| `/anvil` | Öffnet Amboss-GUI | `survivalplus.anvil` |
|
| `/anvil` | Öffnet Amboss-GUI | `survivalplus.anvil` |
|
||||||
| `/trash` | Öffnet Mülleimer | `survivalplus.trash` |
|
| `/trash` | Öffnet Mülleimer | `survivalplus.trash` |
|
||||||
| `/showarmorstands` | Alle (debug) ArmorStands sichtbar machen | `survivalplus.showarmorstands` |
|
| `/showarmorstands` | Debug: ArmorStands sichtbar | `survivalplus.showarmorstands` |
|
||||||
| `/cleardebugarmorstands` | Entfernt Debug-ArmorStands | `survivalplus.cleardebugarmorstands` |
|
| `/cleardebugarmorstands` | Entfernt Debug-ArmorStands | `survivalplus.cleardebugarmorstands` |
|
||||||
| `/leashcount` | Anzahl geleinter Tiere anzeigen | `survivalplus.leashcount` |
|
| `/leashcount` | Zeigt geleinte Tiere | `survivalplus.leashcount` |
|
||||||
| `/nick <Name>` | Nickname ändern (Farben/Hex möglich) | `survivalplus.nick` |
|
| `/nick <Name>` | Nickname setzen (Farben/Hex) | `survivalplus.nick` |
|
||||||
| `/nick off` | Entfernt den Nickname wieder (Zurücksetzen zum echten Namen). | `survivalplus.nick` |
|
| `/nick off` | Nickname entfernen | `survivalplus.nick` |
|
||||||
| `/nick reset` | Alias für /nick off | `survivalplus.nick` |
|
| `/head <Spieler>` | Spieler-Kopf erhalten | `survivalplus.head` |
|
||||||
| `/nick remove` | Alias für /nick off | `survivalplus.nick` |
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Admin & Tools
|
||||||
|
|
||||||
|
| Befehl | Nutzung | Permission |
|
||||||
|
|------|------|-----------|
|
||||||
|
| `/vanish` | Unsichtbar (Silent, No-Pickup optional) | `survivalplus.vanish` |
|
||||||
|
| `/freeze <Spieler>` | Spieler einfrieren | `survivalplus.freeze` |
|
||||||
|
| `/ride [Spieler]` | Reite einen Spieler | `survivalplus.ride` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Teleportation
|
### Teleportation
|
||||||
| Befehl | Usage | Permission |
|
|
||||||
|---|---:|:---|
|
| Befehl | Nutzung | Permission |
|
||||||
|
|------|------|-----------|
|
||||||
| `/tp <Spieler>` | Teleport zu Spieler | `survivalplus.tp` |
|
| `/tp <Spieler>` | Teleport zu Spieler | `survivalplus.tp` |
|
||||||
| `/tphere <Spieler>` | Teleportiert Spieler zu dir | `survivalplus.tphere` |
|
| `/tphere <Spieler>` | Spieler zu dir teleportieren | `survivalplus.tphere` |
|
||||||
| `/tpa <Spieler>` | Teleportanfrage senden | `survivalplus.tpa` |
|
| `/tpa <Spieler>` | Teleportanfrage senden | `survivalplus.tpa` |
|
||||||
| `/tpaccept` | Teleportanfrage annehmen | `survivalplus.tpaccept` |
|
| `/tpaccept` | Anfrage akzeptieren | `survivalplus.tpaccept` |
|
||||||
| `/tpdeny` | Teleportanfrage ablehnen | `survivalplus.tpdeny` |
|
| `/tpdeny` | Anfrage ablehnen | `survivalplus.tpdeny` |
|
||||||
| `/back` | Zum letzten Todespunkt teleportieren | `survivalplus.back` |
|
| `/back` | Zum letzten Todespunkt | `survivalplus.back` |
|
||||||
| `/spawn` | Teleport zum Weltspawn | `survivalplus.spawn` |
|
| `/spawn` | Zum Weltspawn | `survivalplus.spawn` |
|
||||||
| `/setspawn` | Setzt Server-Spawn | `survivalplus.setspawn` |
|
| `/setspawn` | Server-Spawn setzen | `survivalplus.setspawn` |
|
||||||
| `/setworldspawn` | Setzt Weltspawn (aktuelle Welt) | `survivalplus.setworldspawn` |
|
| `/setworldspawn` | Welt-Spawn setzen | `survivalplus.setworldspawn` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Homes & Warps
|
### Homes & Warps
|
||||||
| Befehl | Usage | Permission |
|
|
||||||
|---|---:|:---|
|
| Befehl | Nutzung | Permission |
|
||||||
| `/sethome <name>` | Setzt Home | `survivalplus.homes.set` |
|
|------|------|-----------|
|
||||||
| `/delhome <name>` | Löscht Home | `survivalplus.homes.delete` |
|
| `/sethome <name>` | Home setzen | `survivalplus.homes.set` |
|
||||||
| `/home <name>` | Teleport zu Home | `survivalplus.homes` |
|
| `/delhome <name>` | Home löschen | `survivalplus.homes.delete` |
|
||||||
| `/homelist` | GUI mit Homes öffnen | `survivalplus.homes.list` |
|
| `/home <name>` | Zu Home teleportieren | `survivalplus.homes` |
|
||||||
| `/setwarp <name>` | Persönlichen Warp setzen (Item in Hand) | `survivalplus.setwarp` |
|
| `/homelist` | GUI mit allen Homes | `survivalplus.homes.list` |
|
||||||
| `/delwarp <name>` | Persönlichen Warp löschen | `survivalplus.delwarp` |
|
| `/setwarp <name>` | Persönlichen Warp setzen | `survivalplus.setwarp` |
|
||||||
| `/warps` | GUI aller Warps öffnen | `survivalplus.warps` |
|
| `/delwarp <name>` | Warp löschen | `survivalplus.delwarp` |
|
||||||
|
| `/warps` | Warp-GUI öffnen | `survivalplus.warps` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Claim (Anti-Grief)
|
### Claim (Anti-Grief)
|
||||||
| Befehl | Usage | Permission |
|
|
||||||
|---|---:|:---|
|
| Befehl | Nutzung | Permission |
|
||||||
| `/claim [unclaim / trust <player> / untrust <player>]` | Claim-Management (Trust/Untrust/Unclaim) | `survivalplus.claim.use` |
|
|------|------|-----------|
|
||||||
| `/claim create <name>` (falls implementiert) | Neues Claim anlegen | `survivalplus.claim.use` |
|
| `/claim mark 1|2` | Auswahlpunkt setzen | — |
|
||||||
| `/claim delete <name>` (falls implementiert) | Claim löschen | `survivalplus.claim.use` |
|
| `/claim` | Gebiet claimen | `survivalplus.claim.use` |
|
||||||
| `/claim addmember <player>` | Spieler zum Claim hinzufügen | `survivalplus.claim.trust` |
|
| `/claim unclaim` | Claim löschen | `survivalplus.claim.use` |
|
||||||
| `/claim removemember <player>` | Spieler entfernen | `survivalplus.claim.trust` |
|
| `/claim unclaim <Spieler>` | Alle Claims löschen (Admin) | `survivalplus.claim.admin` |
|
||||||
| `/claim info` | Claim-Informationen anzeigen | `survivalplus.claim.use` |
|
| `/claim trust <Spieler>` | Spieler hinzufügen | `survivalplus.claim.trust` |
|
||||||
| `/claim list` | Eigene Claims auflisten | `survivalplus.claim.use` |
|
| `/claim untrust <Spieler>` | Spieler entfernen | `survivalplus.claim.trust` |
|
||||||
|
| `/claim ban <Spieler>` | Spieler bannen | `survivalplus.claim.ban` |
|
||||||
|
| `/claim kick <Spieler>` | Spieler kicken | `survivalplus.claim.kick` |
|
||||||
|
| `/claim info` | Claim-Infos anzeigen | `survivalplus.claim.use` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### CommandBlocker / Server-Management
|
### CommandBlocker / Server-Management
|
||||||
| Befehl | Usage | Permission |
|
|
||||||
|---|---:|:---|
|
| Befehl | Nutzung | Permission |
|
||||||
| `/sp cb add <cmd>` | Befehl zur Blockliste hinzufügen | `survivalplus.commandblocker.add` |
|
|------|------|-----------|
|
||||||
| `/sp cb remove <cmd>` | Befehl entfernen | `survivalplus.commandblocker.remove` |
|
| `/sp cb add <cmd>` | Befehl blockieren | `survivalplus.commandblocker.add` |
|
||||||
| `/sp cb list` | Blockierte Befehle anzeigen | `survivalplus.commandblocker.list` |
|
| `/sp cb remove <cmd>` | Blockierung entfernen | `survivalplus.commandblocker.remove` |
|
||||||
| `/clearchat` | Chat löschen | `survivalplus.clearchat` |
|
| `/sp cb list` | Blockierte Befehle | `survivalplus.commandblocker.list` |
|
||||||
| `/clearitems` | Items aufsammeln/entfernen | `survivalplus.clearitems` |
|
| `/clearchat` | Chat leeren | `survivalplus.clearchat` |
|
||||||
| `/closedoors <radius>` | Türen in Radius schließen | `survivalplus.closedoors` |
|
| `/clearitems` | Items entfernen | `survivalplus.clearitems` |
|
||||||
| `/sp lock /unlock/friendadd/friendremove [player]` | Kisten/Türen sperren / freigeben | `survivalplus.lock` |
|
| `/closedoors <radius>` | Türen schließen | `survivalplus.closedoors` |
|
||||||
|
| `/sp lock` | Kisten/Türen sperren | `survivalplus.lock` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Shop, Loot & Trade
|
### Shop, Loot & Trade
|
||||||
| Befehl | Usage | Permission |
|
|
||||||
|---|---:|:---|
|
| Befehl | Nutzung | Permission |
|
||||||
| `/shop add <item> <basispreis> <lagerbestand>` | Shop verwalten | `survivalplus.shop` |
|
|------|------|-----------|
|
||||||
| `/lootchests` | Listet Loot-Kisten auf (Admins teleportieren) | `survivalplus.lootchests` |
|
| **Sign Shops** | `[Buy] Menge Item Preis` | automatisch |
|
||||||
| `/tploot <welt> <x> <y> <z>` | Teleportiere zu Loot-Kiste (Admin) | `survivalplus.lootchests` |
|
| `/shop add <item> <preis> <bestand>` | Shop verwalten | `survivalplus.shop` |
|
||||||
| `/trade <Spieler>` | Startet Handel | `survivalplus.trade` |
|
| `/lootchests` | Loot-Kisten auflisten | `survivalplus.lootchests` |
|
||||||
| `/tradeaccept <Spieler>` | Akzeptiert Handel | `survivalplus.tradeaccept` |
|
| `/tploot <welt> <x> <y> <z>` | Zu Loot-Kiste teleportieren | `survivalplus.lootchests` |
|
||||||
|
| `/trade <Spieler>` | Handel starten | `survivalplus.trade` |
|
||||||
|
| `/tradeaccept <Spieler>` | Handel annehmen | `survivalplus.tradeaccept` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Zeit, Gamemode & Admin
|
### Zeit, Gamemode & Admin
|
||||||
| Befehl | Usage | Permission |
|
|
||||||
|---|---:|:---|
|
| Befehl | Nutzung | Permission |
|
||||||
| `/day` | Setzt Zeit auf Tag | `survivalplus.day` |
|
|------|------|-----------|
|
||||||
| `/night` | Setzt Zeit auf Nacht | `survivalplus.night` |
|
| `/day` | Tag setzen | `survivalplus.day` |
|
||||||
| `/gm <modus> [spieler]` (alias `gamemode`) | Spielmodus ändern | `survivalplus.gamemode` |
|
| `/night` | Nacht setzen | `survivalplus.night` |
|
||||||
| `/heal [spieler]` | Heilt Spieler (oder andere) | `survivalplus.heal`, `survivalplus.heal.others` |
|
| `/gm <modus>` | Gamemode ändern | `survivalplus.gamemode` |
|
||||||
|
| `/heal [Spieler]` | Spieler heilen | `survivalplus.heal` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Freundes-, Block- & Report-System
|
### Freundes-, Block- & Report-System
|
||||||
| Befehl | Usage | Permission |
|
|
||||||
|---|---:|:---|
|
| Befehl | Nutzung | Permission |
|
||||||
| `/friend [add/accept/deny/list/del/tp] [Spieler]` | Freundschaften verwalten | `survivalplus.friend` |
|
|------|------|-----------|
|
||||||
|
| `/friend add|accept|deny` | Freundesverwaltung | — |
|
||||||
| `/block <Spieler>` | Spieler blockieren | `survivalplus.block` |
|
| `/block <Spieler>` | Spieler blockieren | `survivalplus.block` |
|
||||||
| `/unblock <Spieler>` | Unblock | `survivalplus.unblock` |
|
| `/unblock <Spieler>` | Blockierung aufheben | `survivalplus.unblock` |
|
||||||
| `/blocklist` | Blockierte Spieler anzeigen | `survivalplus.blocklist` |
|
| `/blocklist` | Blockliste anzeigen | `survivalplus.blocklist` |
|
||||||
| `/report <Spieler> [Grund]` | Spieler melden | `survivalplus.report` |
|
| `/report <Spieler> [Grund]` | Spieler melden | `survivalplus.report` |
|
||||||
| `/showreport <Spieler>` | Reports anzeigen | `survivalplus.report.show` |
|
| `/showreport <Spieler>` | Reports anzeigen | `survivalplus.report.show` |
|
||||||
| `/clearreport <Spieler>` | Reports löschen | `survivalplus.report.clear` |
|
| `/clearreport <Spieler>` | Reports löschen | `survivalplus.report.clear` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Sonstiges
|
### Sonstiges
|
||||||
| Befehl | Usage | Permission |
|
|
||||||
|---|---:|:---|
|
| Befehl | Nutzung | Permission |
|
||||||
| `/stats` | Spielerstatistiken anzeigen | `survivalplus.stats` |
|
|------|------|-----------|
|
||||||
| `/kit` | Starterkit erhalten | `survivalplus.kit` |
|
| `/stats` | Spielerstatistiken | `survivalplus.stats` |
|
||||||
|
| `/kit` | Starterkit | `survivalplus.kit` |
|
||||||
| `/startchallenge <name>` | Fun-Challenge starten | `survivalplus.startchallenge` |
|
| `/startchallenge <name>` | Fun-Challenge starten | `survivalplus.startchallenge` |
|
||||||
| `/lootchests` | Übersicht über Lootkisten | `survivalplus.lootchests` |
|
|
||||||
| `/sit` | Hinsetzen | `survivalplus.sit` |
|
| `/sit` | Hinsetzen | `survivalplus.sit` |
|
||||||
| `/ride` | Auf spieler Reiten | `survivalplus.ride` |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔐 Permissions (Kurzüberblick)
|
## 🔐 Permissions (Kurzüberblick)
|
||||||
Vollständige Permission-Deklaration findest du in `plugin.yml`.
|
|
||||||
Wichtige Permissions:
|
|
||||||
|
|
||||||
- `survivalplus.*` — Vollzugriff (OP)
|
- `survivalplus.*` — Vollzugriff (OP)
|
||||||
- `survivalplus.sp` — Zugriff auf `/sp` (Hauptbefehl)
|
- `survivalplus.sp` — Zugriff auf Hauptbefehl
|
||||||
- `survivalplus.homes.*` — Homes verwalten
|
- `survivalplus.claim.use / trust / admin` — Claim-System
|
||||||
- `survivalplus.claim.use` / `survivalplus.claim.trust` — Claim-Management & Trust
|
- `survivalplus.vanish.silent` — Silent Join
|
||||||
- `survivalplus.shop` — Shopverwaltung
|
- `survivalplus.vanish.no-pickup` — Keine Item-Aufnahme
|
||||||
- `survivalplus.lootchests` — Lootchest-Adminrechte
|
- `survivalplus.head` — `/head` nutzen
|
||||||
- `survivalplus.notify` — Admin-Benachrichtigung bei Besitz von Command/Structure-Blocks
|
- `survivalplus.notify` — Admin-Benachrichtigungen
|
||||||
- uvm. — siehe `plugin.yml` für die vollständige Liste
|
|
||||||
|
➡ Vollständige Liste: **plugin.yml**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ⚙ Installation
|
## ⚙ Installation
|
||||||
|
|
||||||
1. Lade die aktuelle `.jar` Datei herunter.
|
1. Aktuelle `.jar` herunterladen
|
||||||
2. Kopiere sie in den `plugins`-Ordner deines Servers.
|
2. In den `plugins/` Ordner legen
|
||||||
3. Starte den Server neu oder nutze `/reload`.
|
3. **LuckPerms** und **Vault** installieren
|
||||||
4. Stelle sicher, dass **LuckPerms** und **PlaceholderAPI** installiert sind.
|
4. Server neu starten oder `/reload`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🐞 Debug & Fehlerberichte
|
## 🐞 Debug & Fehlerberichte
|
||||||
|
|
||||||
- Aktiviere in `config.yml` `debug-logging: true` wenn du Probleme hast.
|
- In `config.yml` setzen:
|
||||||
- `Debug/debug.log` — enthält Plugin-Fehler/Stacktraces (nur wenn aktiviert).
|
```yml
|
||||||
- `Debug/console.log` — dupliziert den Konsolenoutput (komplette Ausgabe), damit du diesen als Datei an Entwickler schicken kannst.
|
debug-logging: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🐞 Debug & Logs
|
||||||
|
|
||||||
|
- `Debug/debug.log` — Enthält Plugin-Fehler und Stacktraces (nur bei aktiviertem Debug-Logging)
|
||||||
|
- `Debug/console.log` — Kompletter Konsolenoutput zur Weitergabe an Entwickler
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📜 Lizenz & Kontakt
|
## 📜 Lizenz & Kontakt
|
||||||
Dieses Projekt ist frei für den privaten Gebrauch. Für Fragen, Bug-Reports oder Feature-Wünsche: **M_Viper** (Repo-Owner / Gitea).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
|
Dieses Projekt ist frei für den **privaten Gebrauch**.
|
||||||
|
|
||||||
|
**Kontakt / Support / Feature-Wünsche:**
|
||||||
|
**M_Viper** (Repo-Owner / GitHub)
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ public class ShopManager {
|
|||||||
private final File shopFile;
|
private final File shopFile;
|
||||||
private final FileConfiguration shopConfig;
|
private final FileConfiguration shopConfig;
|
||||||
|
|
||||||
|
// Multiplikatoren für dynamische Preise
|
||||||
|
private double buyMultiplier;
|
||||||
|
private double sellMultiplier;
|
||||||
|
|
||||||
public ShopManager(SurvivalPlus plugin) {
|
public ShopManager(SurvivalPlus plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.shopFile = new File(plugin.getDataFolder(), "shop.yml");
|
this.shopFile = new File(plugin.getDataFolder(), "shop.yml");
|
||||||
@@ -20,8 +24,16 @@ public class ShopManager {
|
|||||||
if (!shopFile.exists()) {
|
if (!shopFile.exists()) {
|
||||||
plugin.saveResource("shop.yml", false);
|
plugin.saveResource("shop.yml", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.shopConfig = YamlConfiguration.loadConfiguration(shopFile);
|
this.shopConfig = YamlConfiguration.loadConfiguration(shopFile);
|
||||||
|
|
||||||
|
// Multiplikatoren laden
|
||||||
|
loadMultipliers();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadMultipliers() {
|
||||||
|
this.buyMultiplier = plugin.getConfig().getDouble("economy.buy-multiplier", 1.05);
|
||||||
|
this.sellMultiplier = plugin.getConfig().getDouble("economy.sell-multiplier", 0.95);
|
||||||
|
plugin.getLogger().info("Shop-Multiplikatoren geladen: Buy=" + buyMultiplier + ", Sell=" + sellMultiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getCurrentPrice(String itemKey) {
|
public double getCurrentPrice(String itemKey) {
|
||||||
@@ -33,22 +45,22 @@ public class ShopManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spieler kauft Item: Lager sinkt, Preis steigt (Verknappung)
|
* Spieler kauft Item: Preis steigt
|
||||||
*/
|
*/
|
||||||
public boolean buyItem(String itemKey, int amount) {
|
public boolean buyItem(String itemKey, int amount) {
|
||||||
int stock = shopConfig.getInt("items." + itemKey + ".stock", 0);
|
int stock = shopConfig.getInt("items." + itemKey + ".stock", 0);
|
||||||
|
|
||||||
if (stock < amount) {
|
// Fallback auf Base-Price wenn noch keine Transaktion stattfand (sonst wird 1.05 auf 0 gerechnet)
|
||||||
return false;
|
double currentPrice = shopConfig.getDouble("items." + itemKey + ".current-price", 0);
|
||||||
|
if (currentPrice == 0) {
|
||||||
|
currentPrice = shopConfig.getDouble("items." + itemKey + ".base-price", 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
double price = shopConfig.getDouble("items." + itemKey + ".current-price", 0);
|
// Lager aktualisieren (optional, oder unendlich)
|
||||||
|
// shopConfig.set("items." + itemKey + ".stock", stock - amount);
|
||||||
|
|
||||||
// Lager aktualisieren
|
// Preis erhöhen (Dynamisch)
|
||||||
shopConfig.set("items." + itemKey + ".stock", stock - amount);
|
double newPrice = currentPrice * buyMultiplier;
|
||||||
|
|
||||||
// Preis erhöhen (Faktor 1.05 = +5%)
|
|
||||||
double newPrice = price * 1.05;
|
|
||||||
shopConfig.set("items." + itemKey + ".current-price", newPrice);
|
shopConfig.set("items." + itemKey + ".current-price", newPrice);
|
||||||
|
|
||||||
saveShop();
|
saveShop();
|
||||||
@@ -56,19 +68,20 @@ public class ShopManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spieler verkauft Item: Lager steigt, Preis sinkt (Überfluss)
|
* Spieler verkauft Item: Preis sinkt
|
||||||
*/
|
*/
|
||||||
public boolean sellItem(String itemKey, int amount) {
|
public boolean sellItem(String itemKey, int amount) {
|
||||||
// Hier könnte man prüfen, ob der Shop genügend Geld hat (falls nötig)
|
// Fallback auf Base-Price
|
||||||
|
double currentPrice = shopConfig.getDouble("items." + itemKey + ".current-price", 0);
|
||||||
|
if (currentPrice == 0) {
|
||||||
|
currentPrice = shopConfig.getDouble("items." + itemKey + ".base-price", 100);
|
||||||
|
}
|
||||||
|
|
||||||
double price = shopConfig.getDouble("items." + itemKey + ".current-price", 0);
|
// Lager aktualisieren (optional)
|
||||||
int stock = shopConfig.getInt("items." + itemKey + ".stock", 0);
|
// shopConfig.set("items." + itemKey + ".stock", stock + amount);
|
||||||
|
|
||||||
// Lager aktualisieren
|
// Preis senken (Dynamisch)
|
||||||
shopConfig.set("items." + itemKey + ".stock", stock + amount);
|
double newPrice = currentPrice * sellMultiplier;
|
||||||
|
|
||||||
// Preis senken (Faktor 0.95 = -5%)
|
|
||||||
double newPrice = price * 0.95;
|
|
||||||
shopConfig.set("items." + itemKey + ".current-price", newPrice);
|
shopConfig.set("items." + itemKey + ".current-price", newPrice);
|
||||||
|
|
||||||
saveShop();
|
saveShop();
|
||||||
@@ -78,7 +91,10 @@ public class ShopManager {
|
|||||||
public void addOrUpdateItem(String itemKey, double basePrice, int stock) {
|
public void addOrUpdateItem(String itemKey, double basePrice, int stock) {
|
||||||
shopConfig.set("items." + itemKey + ".base-price", basePrice);
|
shopConfig.set("items." + itemKey + ".base-price", basePrice);
|
||||||
shopConfig.set("items." + itemKey + ".stock", stock);
|
shopConfig.set("items." + itemKey + ".stock", stock);
|
||||||
|
// Wenn der Preis noch nicht existiert (neues Item), setze ihn auf Base-Preis
|
||||||
|
if (!shopConfig.contains("items." + itemKey + ".current-price")) {
|
||||||
shopConfig.set("items." + itemKey + ".current-price", basePrice);
|
shopConfig.set("items." + itemKey + ".current-price", basePrice);
|
||||||
|
}
|
||||||
saveShop();
|
saveShop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import de.viper.survivalplus.commands.NightCommand;
|
|||||||
import de.viper.survivalplus.commands.TradeCommand;
|
import de.viper.survivalplus.commands.TradeCommand;
|
||||||
import de.viper.survivalplus.commands.ReportCommand;
|
import de.viper.survivalplus.commands.ReportCommand;
|
||||||
import de.viper.survivalplus.Manager.ShopManager;
|
import de.viper.survivalplus.Manager.ShopManager;
|
||||||
|
import de.viper.survivalplus.commands.ShopCommand;
|
||||||
import de.viper.survivalplus.commands.HealCommand;
|
import de.viper.survivalplus.commands.HealCommand;
|
||||||
import de.viper.survivalplus.Manager.TablistManager;
|
import de.viper.survivalplus.Manager.TablistManager;
|
||||||
import de.viper.survivalplus.Manager.CommandBlocker;
|
import de.viper.survivalplus.Manager.CommandBlocker;
|
||||||
@@ -42,6 +43,19 @@ import de.viper.survivalplus.commands.WarpsCommand;
|
|||||||
import de.viper.survivalplus.fun.FunChallengeManager;
|
import de.viper.survivalplus.fun.FunChallengeManager;
|
||||||
import de.viper.survivalplus.listeners.ChallengeCollectListener;
|
import de.viper.survivalplus.listeners.ChallengeCollectListener;
|
||||||
import de.viper.survivalplus.commands.StartFunChallengeCommand;
|
import de.viper.survivalplus.commands.StartFunChallengeCommand;
|
||||||
|
|
||||||
|
// --- NEU: Imports für Heads, Vanish & Shops ---
|
||||||
|
import de.viper.survivalplus.commands.HeadCommand;
|
||||||
|
import de.viper.survivalplus.listeners.HeadDropListener;
|
||||||
|
import de.viper.survivalplus.listeners.VanishListener;
|
||||||
|
import de.viper.survivalplus.listeners.SignShopListener;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.ProtocolLibrary;
|
||||||
|
import com.comphenix.protocol.ProtocolManager;
|
||||||
|
|
||||||
|
import net.milkbowl.vault.economy.Economy;
|
||||||
|
import net.milkbowl.vault.economy.EconomyResponse;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -71,8 +85,9 @@ import java.io.FileWriter;
|
|||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import org.bukkit.metadata.MetadataValue;
|
||||||
|
import org.bukkit.metadata.FixedMetadataValue;
|
||||||
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||||
|
|
||||||
public class SurvivalPlus extends JavaPlugin {
|
public class SurvivalPlus extends JavaPlugin {
|
||||||
|
|
||||||
@@ -136,6 +151,12 @@ public class SurvivalPlus extends JavaPlugin {
|
|||||||
private File consoleFile;
|
private File consoleFile;
|
||||||
private PrintWriter consoleWriter;
|
private PrintWriter consoleWriter;
|
||||||
|
|
||||||
|
// --- NEU: Vanish & Economy Support ---
|
||||||
|
private Map<UUID, Boolean> vanishedPlayers = new HashMap<>();
|
||||||
|
private Economy economy = null;
|
||||||
|
private final String VANISH_META_KEY = "vanished";
|
||||||
|
// ---------------------------------------
|
||||||
|
|
||||||
public void reloadTablistConfig() {
|
public void reloadTablistConfig() {
|
||||||
if (tablistFile == null) tablistFile = new File(getDataFolder(), "tablist.yml");
|
if (tablistFile == null) tablistFile = new File(getDataFolder(), "tablist.yml");
|
||||||
if (!tablistFile.exists()) {
|
if (!tablistFile.exists()) {
|
||||||
@@ -251,6 +272,19 @@ public class SurvivalPlus extends JavaPlugin {
|
|||||||
createNicknamesFile();
|
createNicknamesFile();
|
||||||
reloadBlockedCommandsConfig();
|
reloadBlockedCommandsConfig();
|
||||||
loadClaims();
|
loadClaims();
|
||||||
|
|
||||||
|
// --- NEU: Vault Economy Setup ---
|
||||||
|
if (Bukkit.getPluginManager().getPlugin("Vault") != null) {
|
||||||
|
RegisteredServiceProvider<Economy> rsp = getServer().getServicesManager().getRegistration(Economy.class);
|
||||||
|
if (rsp != null) {
|
||||||
|
economy = rsp.getProvider();
|
||||||
|
getLogger().info("Vault Economy erfolgreich verbunden.");
|
||||||
|
} else {
|
||||||
|
getLogger().warning("Vault Plugin gefunden, aber kein Economy Provider!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// -------------------------------------------------
|
||||||
|
|
||||||
PluginManager pluginManager = getServer().getPluginManager();
|
PluginManager pluginManager = getServer().getPluginManager();
|
||||||
try {
|
try {
|
||||||
Permission notifyPerm = new Permission("survivalplus.notify", PermissionDefault.OP);
|
Permission notifyPerm = new Permission("survivalplus.notify", PermissionDefault.OP);
|
||||||
@@ -342,9 +376,11 @@ public class SurvivalPlus extends JavaPlugin {
|
|||||||
pluginManager.registerEvents(lootChestManager, this);
|
pluginManager.registerEvents(lootChestManager, this);
|
||||||
getCommand("lootchests").setExecutor(lootChestManager);
|
getCommand("lootchests").setExecutor(lootChestManager);
|
||||||
getCommand("tploot").setExecutor(lootChestManager);
|
getCommand("tploot").setExecutor(lootChestManager);
|
||||||
|
getCommand("vanish").setExecutor(new AdminToolsCommand(this));
|
||||||
|
getCommand("freeze").setExecutor(new AdminToolsCommand(this));
|
||||||
getCommand("ride").setExecutor(new RideCommand(this));
|
getCommand("ride").setExecutor(new RideCommand(this));
|
||||||
getCommand("claim").setExecutor(new ClaimCommand(this));
|
getCommand("claim").setExecutor(new ClaimCommand(this));
|
||||||
// HIER: (this) hinzugefügt, damit der BlockManager die Datei speichern kann
|
|
||||||
BlockManager blockManager = new BlockManager(this);
|
BlockManager blockManager = new BlockManager(this);
|
||||||
FileConfiguration config = getConfig();
|
FileConfiguration config = getConfig();
|
||||||
BackpackRecipe.register(this, langConfig);
|
BackpackRecipe.register(this, langConfig);
|
||||||
@@ -354,6 +390,12 @@ public class SurvivalPlus extends JavaPlugin {
|
|||||||
getCommand("unblock").setExecutor(new UnblockCommand(blockManager, getConfig()));
|
getCommand("unblock").setExecutor(new UnblockCommand(blockManager, getConfig()));
|
||||||
getCommand("blocklist").setExecutor(new BlockListCommand(blockManager, getConfig()));
|
getCommand("blocklist").setExecutor(new BlockListCommand(blockManager, getConfig()));
|
||||||
|
|
||||||
|
// --- NEU: NEUE LISTENER & COMMANDS ---
|
||||||
|
getCommand("head").setExecutor(new HeadCommand(this));
|
||||||
|
pluginManager.registerEvents(new HeadDropListener(this), this);
|
||||||
|
pluginManager.registerEvents(new VanishListener(this), this);
|
||||||
|
// ------------------------------------
|
||||||
|
|
||||||
pluginManager.registerEvents(new ChatBlockListener(blockManager), this);
|
pluginManager.registerEvents(new ChatBlockListener(blockManager), this);
|
||||||
pluginManager.registerEvents(new InventoryClickListener(this), this);
|
pluginManager.registerEvents(new InventoryClickListener(this), this);
|
||||||
pluginManager.registerEvents(sitListener, this);
|
pluginManager.registerEvents(sitListener, this);
|
||||||
@@ -367,6 +409,7 @@ public class SurvivalPlus extends JavaPlugin {
|
|||||||
pluginManager.registerEvents(new FirstJoinListener(), this);
|
pluginManager.registerEvents(new FirstJoinListener(), this);
|
||||||
pluginManager.registerEvents(playerJoinListener, this);
|
pluginManager.registerEvents(playerJoinListener, this);
|
||||||
pluginManager.registerEvents(new SignColorListener(this), this);
|
pluginManager.registerEvents(new SignColorListener(this), this);
|
||||||
|
pluginManager.registerEvents(new SignShopListener(this), this);
|
||||||
pluginManager.registerEvents(new SleepListener(this), this);
|
pluginManager.registerEvents(new SleepListener(this), this);
|
||||||
pluginManager.registerEvents(new OreAlarmListener(this), this);
|
pluginManager.registerEvents(new OreAlarmListener(this), this);
|
||||||
pluginManager.registerEvents(new MobLeashLimitListener(this, getConfig()), this);
|
pluginManager.registerEvents(new MobLeashLimitListener(this, getConfig()), this);
|
||||||
@@ -526,7 +569,6 @@ private void ensureConfigVersion(FileConfiguration config, File file, String ver
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void removeForbiddenBlocksFromInventories(boolean cmdAllowed, boolean structAllowed) {
|
private void removeForbiddenBlocksFromInventories(boolean cmdAllowed, boolean structAllowed) {
|
||||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||||
if (p.hasPermission("survivalplus.notify")) {
|
if (p.hasPermission("survivalplus.notify")) {
|
||||||
@@ -567,6 +609,7 @@ private void ensureConfigVersion(FileConfiguration config, File file, String ver
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// === Claims.yml ===
|
||||||
private void createClaimsFile() {
|
private void createClaimsFile() {
|
||||||
claimsFile = new File(getDataFolder(), "claims.yml");
|
claimsFile = new File(getDataFolder(), "claims.yml");
|
||||||
if (!claimsFile.exists()) {
|
if (!claimsFile.exists()) {
|
||||||
@@ -700,6 +743,30 @@ private void ensureConfigVersion(FileConfiguration config, File file, String ver
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- NEU: Delete Claim Methode ---
|
||||||
|
public void deleteClaim(Claim claim) {
|
||||||
|
String key = getClaimKey(claim);
|
||||||
|
if (key != null) {
|
||||||
|
claims.remove(key);
|
||||||
|
playerClaimCounts.merge(claim.getOwner(), -1, Integer::sum);
|
||||||
|
saveClaims();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getClaimKey(Claim claim) {
|
||||||
|
for (Map.Entry<String, Claim> entry : claims.entrySet()) {
|
||||||
|
if (entry.getValue() == claim) {
|
||||||
|
return entry.getKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// -----------------------------
|
||||||
|
|
||||||
|
// WICHTIG: Getter für Claim Config für Ban-System
|
||||||
|
public FileConfiguration getClaimsConfig() {
|
||||||
|
return claimsConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Methoden für nicknames.yml
|
// Methoden für nicknames.yml
|
||||||
@@ -768,7 +835,6 @@ private void ensureConfigVersion(FileConfiguration config, File file, String ver
|
|||||||
getLogger().info(getMessage("plugin.disabled"));
|
getLogger().info(getMessage("plugin.disabled"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void saveStats() {
|
public void saveStats() {
|
||||||
if (statsManager != null) {
|
if (statsManager != null) {
|
||||||
statsManager.saveStats();
|
statsManager.saveStats();
|
||||||
@@ -1228,6 +1294,7 @@ private void ensureConfigVersion(FileConfiguration config, File file, String ver
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BannerManager getBannerManager() {
|
public BannerManager getBannerManager() {
|
||||||
return bannerManager;
|
return bannerManager;
|
||||||
}
|
}
|
||||||
@@ -1258,4 +1325,33 @@ private void ensureConfigVersion(FileConfiguration config, File file, String ver
|
|||||||
getLogger().info(msg); // Optional: zusätzlich Konsole ausgeben
|
getLogger().info(msg); // Optional: zusätzlich Konsole ausgeben
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- NEU: HELFERMETHODEN FÜR NEUE FEATURES ---
|
||||||
|
|
||||||
|
// Vanish
|
||||||
|
public void setVanished(UUID uuid, boolean vanished) {
|
||||||
|
if (vanished) {
|
||||||
|
vanishedPlayers.put(uuid, true);
|
||||||
|
} else {
|
||||||
|
vanishedPlayers.remove(uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isVanished(UUID uuid) {
|
||||||
|
return vanishedPlayers.containsKey(uuid) && vanishedPlayers.get(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<UUID, Boolean> getVanishedPlayers() {
|
||||||
|
return vanishedPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Economy
|
||||||
|
public Economy getEconomy() {
|
||||||
|
return economy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProtocolLib Bridge (für Silent Vanish)
|
||||||
|
public ProtocolManager getProtocolManager() {
|
||||||
|
return ProtocolLibrary.getProtocolManager();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
package de.viper.survivalplus.commands;
|
||||||
|
|
||||||
|
import de.viper.survivalplus.SurvivalPlus;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Location; // <--- WICHTIG: Das war der Fehler
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class AdminToolsCommand implements CommandExecutor, Listener {
|
||||||
|
|
||||||
|
private final SurvivalPlus plugin;
|
||||||
|
private final Set<UUID> vanishedPlayers = new HashSet<>();
|
||||||
|
private final Set<UUID> frozenPlayers = new HashSet<>();
|
||||||
|
|
||||||
|
public AdminToolsCommand(SurvivalPlus plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||||
|
if (!(sender instanceof Player)) {
|
||||||
|
sender.sendMessage("Nur Spieler können diesen Befehl nutzen!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player player = (Player) sender;
|
||||||
|
FileConfiguration lang = plugin.getLangConfig();
|
||||||
|
|
||||||
|
// --- VANISH ---
|
||||||
|
if (command.getName().equalsIgnoreCase("vanish")) {
|
||||||
|
if (!player.hasPermission("survivalplus.vanish")) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Keine Berechtigung!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vanishedPlayers.contains(player.getUniqueId())) {
|
||||||
|
// Ent-vanish
|
||||||
|
for (Player all : Bukkit.getOnlinePlayers()) {
|
||||||
|
all.showPlayer(plugin, player);
|
||||||
|
}
|
||||||
|
player.setPlayerListName(player.getName()); // Name wieder in Tab-Liste anzeigen
|
||||||
|
vanishedPlayers.remove(player.getUniqueId());
|
||||||
|
player.sendMessage(ChatColor.GREEN + "Du bist nun sichtbar.");
|
||||||
|
} else {
|
||||||
|
// Vanish
|
||||||
|
for (Player all : Bukkit.getOnlinePlayers()) {
|
||||||
|
all.hidePlayer(plugin, player);
|
||||||
|
}
|
||||||
|
vanishedPlayers.add(player.getUniqueId());
|
||||||
|
player.sendMessage(ChatColor.GREEN + "Du bist nun unsichtbar.");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- FREEZE ---
|
||||||
|
if (command.getName().equalsIgnoreCase("freeze")) {
|
||||||
|
if (!player.hasPermission("survivalplus.freeze")) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Keine Berechtigung!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.length == 0) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Verwendung: /freeze <Spieler>");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player target = Bukkit.getPlayer(args[0]);
|
||||||
|
if (target == null) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Spieler nicht gefunden!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frozenPlayers.contains(target.getUniqueId())) {
|
||||||
|
// Ent-freezen
|
||||||
|
frozenPlayers.remove(target.getUniqueId());
|
||||||
|
player.sendMessage(ChatColor.GREEN + target.getName() + " wurde aufgetaut.");
|
||||||
|
target.sendMessage(ChatColor.GREEN + "Du bist nicht mehr eingefroren.");
|
||||||
|
} else {
|
||||||
|
// Einfrieren
|
||||||
|
frozenPlayers.add(target.getUniqueId());
|
||||||
|
player.sendMessage(ChatColor.GREEN + target.getName() + " wurde eingefroren.");
|
||||||
|
target.sendMessage(ChatColor.RED + "Du wurdest von einem Admin eingefroren! " + ChatColor.BOLD + "Keine Bewegung möglich!");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- EVENTS ---
|
||||||
|
|
||||||
|
// Verhindert Bewegung wenn eingefroren
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerMove(PlayerMoveEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
// Kopf drehen (YAW/PITCH) ist okay, Blocken wenn Position (X/Y/Z) ändert
|
||||||
|
if (frozenPlayers.contains(player.getUniqueId())) {
|
||||||
|
Location from = event.getFrom();
|
||||||
|
Location to = event.getTo();
|
||||||
|
// Wenn die Koordinaten sich ändern
|
||||||
|
if (to.getX() != from.getX() || to.getY() != from.getY() || to.getZ() != from.getZ()) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
// Optional: Kleine Meldung beim Versuch zu laufen
|
||||||
|
// player.sendMessage(ChatColor.RED + "Du bist eingefroren!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wenn ein Spieler joint: Hide vanished players for him
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
|
Player joiner = event.getPlayer();
|
||||||
|
for (UUID vanishedUUID : vanishedPlayers) {
|
||||||
|
Player vanishedPlayer = Bukkit.getPlayer(vanishedUUID);
|
||||||
|
if (vanishedPlayer != null && vanishedPlayer.isOnline()) {
|
||||||
|
joiner.hidePlayer(plugin, vanishedPlayer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup wenn ein Spieler geht
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||||
|
vanishedPlayers.remove(event.getPlayer().getUniqueId());
|
||||||
|
frozenPlayers.remove(event.getPlayer().getUniqueId());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,15 +3,19 @@ package de.viper.survivalplus.commands;
|
|||||||
import de.viper.survivalplus.SurvivalPlus;
|
import de.viper.survivalplus.SurvivalPlus;
|
||||||
import de.viper.survivalplus.util.Claim;
|
import de.viper.survivalplus.util.Claim;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandExecutor;
|
import org.bukkit.command.CommandExecutor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class ClaimCommand implements CommandExecutor {
|
public class ClaimCommand implements CommandExecutor {
|
||||||
private SurvivalPlus plugin;
|
private SurvivalPlus plugin;
|
||||||
@@ -71,7 +75,7 @@ public class ClaimCommand implements CommandExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (args[0].toLowerCase()) {
|
switch (args[0].toLowerCase()) {
|
||||||
case "mark":
|
case "mark": {
|
||||||
if (!player.hasPermission("survivalplus.claim.use")) {
|
if (!player.hasPermission("survivalplus.claim.use")) {
|
||||||
player.sendMessage(plugin.getMessage("commands.no-permission"));
|
player.sendMessage(plugin.getMessage("commands.no-permission"));
|
||||||
return true;
|
return true;
|
||||||
@@ -89,22 +93,13 @@ public class ClaimCommand implements CommandExecutor {
|
|||||||
player.sendMessage(plugin.getMessage("claim.point2-set").replace("%x%", String.valueOf(location.getBlockX())).replace("%z%", String.valueOf(location.getBlockZ())));
|
player.sendMessage(plugin.getMessage("claim.point2-set").replace("%x%", String.valueOf(location.getBlockX())).replace("%z%", String.valueOf(location.getBlockZ())));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
case "unclaim":
|
case "unclaim":
|
||||||
if (args.length == 1) {
|
case "del":
|
||||||
if (!player.hasPermission("survivalplus.claim.use")) {
|
case "delete": {
|
||||||
player.sendMessage(plugin.getMessage("commands.no-permission"));
|
// 1. Mass Delete (Admin): /claim unclaim <Spieler> (oder del/delete)
|
||||||
return true;
|
if (args.length == 2 && player.isOp()) {
|
||||||
}
|
|
||||||
Claim claim = plugin.getClaim(player.getLocation());
|
|
||||||
if (claim == null || !claim.getOwner().equals(player.getUniqueId())) {
|
|
||||||
player.sendMessage(plugin.getMessage("claim.not-owner"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
plugin.removeClaim(player.getLocation(), player);
|
|
||||||
player.sendMessage(plugin.getMessage("claim.unclaimed"));
|
|
||||||
return true;
|
|
||||||
} else if (args.length == 2 && player.isOp()) {
|
|
||||||
Player target = Bukkit.getPlayer(args[1]);
|
Player target = Bukkit.getPlayer(args[1]);
|
||||||
UUID targetUUID;
|
UUID targetUUID;
|
||||||
if (target != null) {
|
if (target != null) {
|
||||||
@@ -127,12 +122,38 @@ public class ClaimCommand implements CommandExecutor {
|
|||||||
.replace("%player%", args[1]));
|
.replace("%player%", args[1]));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
player.sendMessage(plugin.getMessage("claim.usage"));
|
|
||||||
|
// 2. Normaler oder Admin Targeted Delete
|
||||||
|
Claim claim = plugin.getClaim(player.getLocation());
|
||||||
|
if (claim == null) {
|
||||||
|
player.sendMessage(plugin.getMessage("claim.no-claim-at-location"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case "trust":
|
// Prüfen, ob Spieler Owner ist (oder OP)
|
||||||
|
if (!claim.getOwner().equals(player.getUniqueId())) {
|
||||||
|
// NICHT Owner -> Aber Admin?
|
||||||
|
if (player.isOp()) {
|
||||||
|
plugin.deleteClaim(claim);
|
||||||
|
String ownerName = Bukkit.getOfflinePlayer(claim.getOwner()).getName();
|
||||||
|
if (ownerName == null) ownerName = "Unbekannt";
|
||||||
|
player.sendMessage(ChatColor.GREEN + "Claim wurde entfernt. (Besitzer war: " + ChatColor.YELLOW + ownerName + ChatColor.GREEN + ")");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// Nicht Owner und kein Admin -> Abbruch
|
||||||
|
player.sendMessage(plugin.getMessage("claim.not-owner"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Owner löscht eigenen Claim
|
||||||
|
plugin.deleteClaim(claim);
|
||||||
|
player.sendMessage(plugin.getMessage("claim.unclaimed"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "trust": {
|
||||||
if (!player.hasPermission("survivalplus.claim.trust")) {
|
if (!player.hasPermission("survivalplus.claim.trust")) {
|
||||||
player.sendMessage(plugin.getMessage("commands.no-permission"));
|
player.sendMessage(plugin.getMessage("commands.no-permission"));
|
||||||
return true;
|
return true;
|
||||||
@@ -146,17 +167,18 @@ public class ClaimCommand implements CommandExecutor {
|
|||||||
player.sendMessage(plugin.getMessage("commands.player-not-found"));
|
player.sendMessage(plugin.getMessage("commands.player-not-found"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Claim claim = plugin.getClaim(player.getLocation());
|
Claim trustClaim = plugin.getClaim(player.getLocation());
|
||||||
if (claim == null || !claim.getOwner().equals(player.getUniqueId())) {
|
if (trustClaim == null || !trustClaim.getOwner().equals(player.getUniqueId())) {
|
||||||
player.sendMessage(plugin.getMessage("claim.not-owner"));
|
player.sendMessage(plugin.getMessage("claim.not-owner"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
claim.addTrusted(target.getUniqueId());
|
trustClaim.addTrusted(target.getUniqueId());
|
||||||
player.sendMessage(plugin.getMessage("claim.trusted").replace("%player%", args[1]));
|
player.sendMessage(plugin.getMessage("claim.trusted").replace("%player%", args[1]));
|
||||||
plugin.saveClaims();
|
plugin.saveClaims();
|
||||||
break;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
case "untrust":
|
case "untrust": {
|
||||||
if (!player.hasPermission("survivalplus.claim.trust")) {
|
if (!player.hasPermission("survivalplus.claim.trust")) {
|
||||||
player.sendMessage(plugin.getMessage("commands.no-permission"));
|
player.sendMessage(plugin.getMessage("commands.no-permission"));
|
||||||
return true;
|
return true;
|
||||||
@@ -165,43 +187,145 @@ public class ClaimCommand implements CommandExecutor {
|
|||||||
player.sendMessage(plugin.getMessage("claim.usage-untrust"));
|
player.sendMessage(plugin.getMessage("claim.usage-untrust"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
target = Bukkit.getPlayer(args[1]);
|
Player target = Bukkit.getPlayer(args[1]);
|
||||||
if (target == null) {
|
if (target == null) {
|
||||||
player.sendMessage(plugin.getMessage("commands.player-not-found"));
|
player.sendMessage(plugin.getMessage("commands.player-not-found"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
claim = plugin.getClaim(player.getLocation());
|
Claim trustClaim = plugin.getClaim(player.getLocation());
|
||||||
if (claim == null || !claim.getOwner().equals(player.getUniqueId())) {
|
if (trustClaim == null || !trustClaim.getOwner().equals(player.getUniqueId())) {
|
||||||
player.sendMessage(plugin.getMessage("claim.not-owner"));
|
player.sendMessage(plugin.getMessage("claim.not-owner"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
claim.removeTrusted(target.getUniqueId());
|
trustClaim.removeTrusted(target.getUniqueId());
|
||||||
player.sendMessage(plugin.getMessage("claim.untrusted").replace("%player%", args[1]));
|
player.sendMessage(plugin.getMessage("claim.untrusted").replace("%player%", args[1]));
|
||||||
plugin.saveClaims();
|
plugin.saveClaims();
|
||||||
break;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
case "info":
|
// --- NEU: KICK ---
|
||||||
|
case "kick": {
|
||||||
|
if (!player.hasPermission("survivalplus.claim.kick")) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Keine Berechtigung!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (args.length < 2) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Verwendung: /claim kick <Spieler>");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Player kickTarget = Bukkit.getPlayer(args[1]);
|
||||||
|
if (kickTarget == null) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Spieler nicht gefunden oder offline!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Claim currentClaim = plugin.getClaim(kickTarget.getLocation());
|
||||||
|
if (currentClaim == null || !currentClaim.getOwner().equals(player.getUniqueId())) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Du bist hier nicht Besitzer oder kein Claim.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
kickPlayerFromClaim(kickTarget, currentClaim);
|
||||||
|
player.sendMessage(ChatColor.GREEN + "Spieler " + kickTarget.getName() + " wurde aus dem Claim gekickt!");
|
||||||
|
kickTarget.sendMessage(ChatColor.RED + "Du wurdest aus dem Claim geworfen!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- NEU: BAN ---
|
||||||
|
case "ban": {
|
||||||
|
if (!player.hasPermission("survivalplus.claim.ban")) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Keine Berechtigung!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (args.length < 2) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Verwendung: /claim ban <Spieler>");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String claimKey = getClaimKeyAtLocation(player.getLocation());
|
||||||
|
if (claimKey == null) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Du stehst in keinem Claim.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player banTarget = Bukkit.getPlayer(args[1]);
|
||||||
|
UUID banUUID;
|
||||||
|
if (banTarget != null) {
|
||||||
|
banUUID = banTarget.getUniqueId();
|
||||||
|
Claim banCheck = plugin.getClaim(player.getLocation());
|
||||||
|
if (banCheck != null && banCheck.isInside(banTarget.getLocation())) {
|
||||||
|
kickPlayerFromClaim(banTarget, banCheck);
|
||||||
|
banTarget.sendMessage(ChatColor.RED + "Du wurdest aus dem Claim geworfen und gebannt!");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
banUUID = UUID.fromString(args[1]);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Ungültige UUID oder Spieler nicht online.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
banPlayerInClaim(banUUID, claimKey);
|
||||||
|
player.sendMessage(ChatColor.GREEN + "Spieler wurde von diesem Claim gebannt.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- NEU: UNBAN ---
|
||||||
|
case "unban": {
|
||||||
|
if (!player.hasPermission("survivalplus.claim.ban")) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Keine Berechtigung!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (args.length < 2) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Verwendung: /claim unban <Spieler>");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Player unbanTarget = Bukkit.getPlayer(args[1]);
|
||||||
|
UUID unbanUUID;
|
||||||
|
if (unbanTarget != null) {
|
||||||
|
unbanUUID = unbanTarget.getUniqueId();
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
unbanUUID = UUID.fromString(args[1]);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Ungültige UUID.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String claimKeyUnban = getClaimKeyAtLocation(player.getLocation());
|
||||||
|
if (claimKeyUnban == null) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Du stehst in keinem Claim.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unbanPlayerInClaim(unbanUUID, claimKeyUnban);
|
||||||
|
player.sendMessage(ChatColor.GREEN + "Spieler wurde für diesen Claim entbannt.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "info": {
|
||||||
if (!player.hasPermission("survivalplus.claim.use")) {
|
if (!player.hasPermission("survivalplus.claim.use")) {
|
||||||
player.sendMessage(plugin.getMessage("commands.no-permission"));
|
player.sendMessage(plugin.getMessage("commands.no-permission"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
claim = plugin.getClaim(player.getLocation());
|
Claim infoClaim = plugin.getClaim(player.getLocation());
|
||||||
if (claim == null) {
|
if (infoClaim == null) {
|
||||||
player.sendMessage(plugin.getMessage("claim.no-claim-at-location"));
|
player.sendMessage(plugin.getMessage("claim.no-claim-at-location"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
String ownerName = Bukkit.getOfflinePlayer(claim.getOwner()).getName();
|
String ownerName = Bukkit.getOfflinePlayer(infoClaim.getOwner()).getName();
|
||||||
if (ownerName == null) {
|
if (ownerName == null) {
|
||||||
ownerName = claim.getOwner().toString(); // Fallback to UUID if name not found
|
ownerName = infoClaim.getOwner().toString();
|
||||||
}
|
}
|
||||||
player.sendMessage(plugin.getMessage("claim.info")
|
player.sendMessage(plugin.getMessage("claim.info")
|
||||||
.replace("%owner%", ownerName)
|
.replace("%owner%", ownerName)
|
||||||
.replace("%world%", claim.getWorldName())
|
.replace("%world%", infoClaim.getWorldName())
|
||||||
.replace("%x1%", String.valueOf(claim.getX1()))
|
.replace("%x1%", String.valueOf(infoClaim.getX1()))
|
||||||
.replace("%z1%", String.valueOf(claim.getZ1()))
|
.replace("%z1%", String.valueOf(infoClaim.getZ1()))
|
||||||
.replace("%x2%", String.valueOf(claim.getX2()))
|
.replace("%x2%", String.valueOf(infoClaim.getX2()))
|
||||||
.replace("%z2%", String.valueOf(claim.getZ2())));
|
.replace("%z2%", String.valueOf(infoClaim.getZ2())));
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
player.sendMessage(plugin.getMessage("claim.usage"));
|
player.sendMessage(plugin.getMessage("claim.usage"));
|
||||||
@@ -223,4 +347,62 @@ public class ClaimCommand implements CommandExecutor {
|
|||||||
}
|
}
|
||||||
return removedCount;
|
return removedCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- HILFSMETHODEN ---
|
||||||
|
private void kickPlayerFromClaim(Player player, Claim claim) {
|
||||||
|
Location loc = player.getLocation();
|
||||||
|
int x = loc.getBlockX();
|
||||||
|
int z = loc.getBlockZ();
|
||||||
|
int minX = Math.min(claim.getX1(), claim.getX2());
|
||||||
|
int maxX = Math.max(claim.getX1(), claim.getX2());
|
||||||
|
int minZ = Math.min(claim.getZ1(), claim.getZ2());
|
||||||
|
int maxZ = Math.max(claim.getZ1(), claim.getZ2());
|
||||||
|
|
||||||
|
int distX1 = Math.abs(x - minX);
|
||||||
|
int distX2 = Math.abs(x - maxX);
|
||||||
|
int distZ1 = Math.abs(z - minZ);
|
||||||
|
int distZ2 = Math.abs(z - maxZ);
|
||||||
|
|
||||||
|
int minDist = Math.min(Math.min(distX1, distX2), Math.min(distZ1, distZ2));
|
||||||
|
|
||||||
|
Location newLoc = loc.clone();
|
||||||
|
if (minDist == distX1) {
|
||||||
|
newLoc.setX(minX - 1);
|
||||||
|
} else if (minDist == distX2) {
|
||||||
|
newLoc.setX(maxX + 1);
|
||||||
|
} else if (minDist == distZ1) {
|
||||||
|
newLoc.setZ(minZ - 1);
|
||||||
|
} else {
|
||||||
|
newLoc.setZ(maxZ + 1);
|
||||||
|
}
|
||||||
|
newLoc.setY(newLoc.getY() + 1);
|
||||||
|
player.teleport(newLoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getClaimKeyAtLocation(Location loc) {
|
||||||
|
for (String key : plugin.getClaims().keySet()) {
|
||||||
|
if (plugin.getClaims().get(key).isInside(loc)) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void banPlayerInClaim(UUID uuid, String claimKey) {
|
||||||
|
FileConfiguration config = plugin.getClaimsConfig();
|
||||||
|
List<String> banned = config.getStringList(claimKey + ".banned");
|
||||||
|
if (!banned.contains(uuid.toString())) {
|
||||||
|
banned.add(uuid.toString());
|
||||||
|
config.set(claimKey + ".banned", banned);
|
||||||
|
plugin.saveClaims();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unbanPlayerInClaim(UUID uuid, String claimKey) {
|
||||||
|
FileConfiguration config = plugin.getClaimsConfig();
|
||||||
|
List<String> banned = config.getStringList(claimKey + ".banned");
|
||||||
|
banned.remove(uuid.toString());
|
||||||
|
config.set(claimKey + ".banned", banned);
|
||||||
|
plugin.saveClaims();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package de.viper.survivalplus.commands;
|
||||||
|
|
||||||
|
import de.viper.survivalplus.SurvivalPlus;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.SkullMeta;
|
||||||
|
|
||||||
|
public class HeadCommand implements CommandExecutor {
|
||||||
|
private SurvivalPlus plugin;
|
||||||
|
|
||||||
|
public HeadCommand(SurvivalPlus plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
|
||||||
|
if (!(sender instanceof Player)) {
|
||||||
|
sender.sendMessage("Nur Spieler können diesen Befehl nutzen.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Player player = (Player) sender;
|
||||||
|
|
||||||
|
if (args.length == 0) {
|
||||||
|
player.sendMessage(plugin.getMessage("commands.player-only"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!player.hasPermission("survivalplus.head")) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Keine Berechtigung!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String targetName = args[0];
|
||||||
|
OfflinePlayer target = Bukkit.getOfflinePlayer(targetName);
|
||||||
|
|
||||||
|
if (target == null) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Spieler '" + targetName + "' wurde nie gefunden.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack head = new ItemStack(Material.PLAYER_HEAD);
|
||||||
|
SkullMeta meta = (SkullMeta) head.getItemMeta();
|
||||||
|
meta.setOwningPlayer(target);
|
||||||
|
meta.setDisplayName(ChatColor.YELLOW + "Kopf von " + targetName);
|
||||||
|
head.setItemMeta(meta);
|
||||||
|
|
||||||
|
player.getInventory().addItem(head);
|
||||||
|
player.sendMessage(ChatColor.GREEN + "Du hast den Kopf von " + targetName + " erhalten!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ package de.viper.survivalplus.commands;
|
|||||||
|
|
||||||
import de.viper.survivalplus.Manager.ShopManager;
|
import de.viper.survivalplus.Manager.ShopManager;
|
||||||
import de.viper.survivalplus.SurvivalPlus;
|
import de.viper.survivalplus.SurvivalPlus;
|
||||||
import de.viper.survivalplus.gui.ShopGui; // <--- WICHTIG: Dieser Import fehlte dir
|
import de.viper.survivalplus.gui.ShopGui;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@@ -11,15 +11,33 @@ import org.bukkit.command.CommandExecutor;
|
|||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.PlayerInventory;
|
||||||
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||||
|
import net.milkbowl.vault.economy.Economy;
|
||||||
|
import net.milkbowl.vault.economy.EconomyResponse;
|
||||||
|
|
||||||
public class ShopCommand implements CommandExecutor {
|
public class ShopCommand implements CommandExecutor {
|
||||||
|
|
||||||
private final ShopManager shopManager;
|
private final ShopManager shopManager;
|
||||||
private final SurvivalPlus plugin;
|
private final SurvivalPlus plugin;
|
||||||
|
private Economy economy;
|
||||||
|
|
||||||
public ShopCommand(SurvivalPlus plugin) {
|
public ShopCommand(SurvivalPlus plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.shopManager = new ShopManager(plugin);
|
this.shopManager = new ShopManager(plugin);
|
||||||
|
|
||||||
|
// Economy laden (für Admin-Verkauf an Server)
|
||||||
|
try {
|
||||||
|
if (Bukkit.getPluginManager().isPluginEnabled("Vault")) {
|
||||||
|
RegisteredServiceProvider<Economy> rsp = Bukkit.getServicesManager().getRegistration(Economy.class);
|
||||||
|
if (rsp != null) {
|
||||||
|
this.economy = rsp.getProvider();
|
||||||
|
plugin.getLogger().info("Vault Economy für ShopCommand gefunden.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Ignorieren wenn Vault fehlt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getMessage(String key) {
|
private String getMessage(String key) {
|
||||||
@@ -35,78 +53,102 @@ public class ShopCommand implements CommandExecutor {
|
|||||||
Player player = (Player) sender;
|
Player player = (Player) sender;
|
||||||
|
|
||||||
// Shop-GUI öffnen
|
// Shop-GUI öffnen
|
||||||
if (args.length == 0 || (args.length > 0 && args[0].toLowerCase().equals("gui"))) {
|
if (args.length == 0 || (args.length > 0 && args[0].equalsIgnoreCase("gui"))) {
|
||||||
ShopGui shopGui = new ShopGui(plugin, player, shopManager);
|
ShopGui shopGui = new ShopGui(plugin, player, shopManager);
|
||||||
Bukkit.getPluginManager().registerEvents(shopGui, plugin);
|
Bukkit.getPluginManager().registerEvents(shopGui, plugin);
|
||||||
player.openInventory(shopGui.getInventory());
|
player.openInventory(shopGui.getInventory());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args[0].toLowerCase().equals("add")) {
|
// --- SHOP ADD LOGIK ---
|
||||||
sender.sendMessage(getMessage("unknown-subcommand"));
|
if (args.length >= 4 && args[0].equalsIgnoreCase("add")) {
|
||||||
|
|
||||||
|
// Economy-Check
|
||||||
|
if (economy == null) {
|
||||||
|
sender.sendMessage(ChatColor.RED + "Vault Economy ist nicht verfügbar!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Neue Logik für /shop add ---
|
|
||||||
|
|
||||||
String itemKey;
|
|
||||||
double basePrice;
|
|
||||||
int stock;
|
|
||||||
|
|
||||||
// Fall 1: /shop add <Material> <Preis> <Stock> (4 Argumente)
|
|
||||||
if (args.length >= 4) {
|
|
||||||
String materialName = args[1];
|
String materialName = args[1];
|
||||||
|
String priceStr = args[2];
|
||||||
|
String amountStr = args[3];
|
||||||
|
|
||||||
Material mat = Material.matchMaterial(materialName);
|
Material mat = Material.matchMaterial(materialName);
|
||||||
|
|
||||||
if (mat == null) {
|
if (mat == null) {
|
||||||
sender.sendMessage(ChatColor.RED + "Das Material '" + materialName + "' wurde nicht gefunden!");
|
sender.sendMessage(ChatColor.RED + "Das Material '" + materialName + "' wurde nicht gefunden!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
itemKey = mat.name().toLowerCase();
|
|
||||||
|
double price;
|
||||||
|
int amount;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
basePrice = Double.parseDouble(args[2]);
|
price = Double.parseDouble(priceStr);
|
||||||
stock = Integer.parseInt(args[3]);
|
amount = Integer.parseInt(amountStr);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
sender.sendMessage(ChatColor.RED + "Ungültige Preis oder Bestandszahl! Beispiel: /shop add Diamond 20 64");
|
sender.sendMessage(ChatColor.RED + "Ungültige Preis oder Bestandszahl! Beispiel: /shop add Diamond 20 64");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
if (amount <= 0 || price < 0) {
|
||||||
// Fall 2: /shop add <Preis> <Stock> (3 Argumente) -> Nimmt Item in der Hand
|
sender.sendMessage(ChatColor.RED + "Menge und Preis müssen positiv sein.");
|
||||||
else if (args.length == 3) {
|
|
||||||
ItemStack itemInHand = player.getInventory().getItemInMainHand();
|
|
||||||
if (itemInHand == null || itemInHand.getType() == Material.AIR) {
|
|
||||||
sender.sendMessage(ChatColor.RED + "Du musst das Item, das du hinzufügen willst, in der Hand halten!");
|
|
||||||
sender.sendMessage(ChatColor.GRAY + "Oder benutze: /shop add <Material> <Preis> <Bestand>");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
itemKey = itemInHand.getType().name().toLowerCase();
|
|
||||||
|
|
||||||
try {
|
// 1. Prüfen: Hat der Spieler die Items?
|
||||||
basePrice = Double.parseDouble(args[1]);
|
int hasAmount = countItems(player.getInventory(), mat);
|
||||||
stock = Integer.parseInt(args[2]);
|
|
||||||
} catch (NumberFormatException e) {
|
if (hasAmount < amount) {
|
||||||
sender.sendMessage(getMessage("number-error"));
|
sender.sendMessage(ChatColor.RED + "Du hast nicht genug Items! (Benötigt: " + amount + ", Vorhanden: " + hasAmount + ")");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2. Items aus Inventar entfernen
|
||||||
|
player.getInventory().removeItem(new ItemStack(mat, amount));
|
||||||
|
player.updateInventory(); // Wichtig für Client-Update
|
||||||
|
|
||||||
|
// 3. Spieler Geld geben (Verkauf an Server)
|
||||||
|
double totalCost = price * amount;
|
||||||
|
EconomyResponse response = economy.depositPlayer(player, totalCost);
|
||||||
|
|
||||||
|
if (response.transactionSuccess()) {
|
||||||
|
sender.sendMessage(ChatColor.GREEN + "Du hast " + amount + " " + mat.name() + " für " + totalCost + " Coins an den Server verkauft!");
|
||||||
|
|
||||||
|
// 4. Shop-Config aktualisieren (Lagerbestand erhöhen)
|
||||||
|
String itemKey = mat.name().toLowerCase();
|
||||||
|
shopManager.addOrUpdateItem(itemKey, price, shopManager.getStock(itemKey) + amount);
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(ChatColor.RED + "Fehler bei der Auszahlung!");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
// Falsche Anzahl an Argumenten
|
|
||||||
else {
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback für falsche Argumente
|
||||||
|
if (args.length > 0 && args[0].equalsIgnoreCase("add")) {
|
||||||
sender.sendMessage(ChatColor.RED + "Falsche Benutzung!");
|
sender.sendMessage(ChatColor.RED + "Falsche Benutzung!");
|
||||||
sender.sendMessage(ChatColor.GRAY + "Mit Item in Hand: /shop add <Preis> <Bestand>");
|
sender.sendMessage(ChatColor.GRAY + "Mit Item in Hand: /shop add <Preis> <Bestand>");
|
||||||
sender.sendMessage(ChatColor.GRAY + "Mit Namen: /shop add <Material> <Preis> <Bestand>");
|
sender.sendMessage(ChatColor.GRAY + "Mit Namen: /shop add <Material> <Preis> <Bestand>");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
shopManager.addOrUpdateItem(itemKey, basePrice, stock);
|
sender.sendMessage(ChatColor.RED + "Unbekannter Befehl! Benutze /shop [add|gui]");
|
||||||
|
|
||||||
String msg = getMessage("item-added")
|
|
||||||
.replace("{item}", itemKey)
|
|
||||||
.replace("{price}", String.valueOf(basePrice))
|
|
||||||
.replace("{stock}", String.valueOf(stock));
|
|
||||||
sender.sendMessage(msg);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zählt die Anzahl der Items eines bestimmten Materials im Inventar.
|
||||||
|
* Nutzt StorageContents, um auch Rüstung/Shulker-Slots zu prüfen.
|
||||||
|
*/
|
||||||
|
private int countItems(PlayerInventory inv, Material mat) {
|
||||||
|
int count = 0;
|
||||||
|
for (ItemStack item : inv.getStorageContents()) {
|
||||||
|
if (item != null && item.getType().equals(mat)) {
|
||||||
|
count += item.getAmount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,9 @@ package de.viper.survivalplus.listeners;
|
|||||||
|
|
||||||
import de.viper.survivalplus.SurvivalPlus;
|
import de.viper.survivalplus.SurvivalPlus;
|
||||||
import de.viper.survivalplus.util.Claim;
|
import de.viper.survivalplus.util.Claim;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.entity.Monster;
|
import org.bukkit.entity.Monster;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
@@ -51,6 +53,25 @@ public class ClaimListener implements Listener {
|
|||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
UUID playerId = player.getUniqueId();
|
UUID playerId = player.getUniqueId();
|
||||||
Claim currentClaim = plugin.getClaim(event.getTo());
|
Claim currentClaim = plugin.getClaim(event.getTo());
|
||||||
|
Location to = event.getTo();
|
||||||
|
|
||||||
|
// --- NEU: BAN CHECK ---
|
||||||
|
if (currentClaim != null) {
|
||||||
|
// Checken ob Spieler in der Ban-Liste der Claims Config steht
|
||||||
|
String claimKey = getClaimKeyFromLocation(to);
|
||||||
|
if (claimKey != null) {
|
||||||
|
FileConfiguration config = plugin.getClaimsConfig();
|
||||||
|
if (config.contains(claimKey + ".banned")) {
|
||||||
|
if (config.getStringList(claimKey + ".banned").contains(playerId.toString())) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
player.sendMessage(ChatColor.RED + "Du bist aus diesem Gebiet verbannt!");
|
||||||
|
// Optional: Knockback effect
|
||||||
|
player.teleport(event.getFrom().add(0, 0.2, 0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Prüfe, ob sich der Claim-Status geändert hat
|
// Prüfe, ob sich der Claim-Status geändert hat
|
||||||
Claim previousClaim = lastClaim.getOrDefault(playerId, null);
|
Claim previousClaim = lastClaim.getOrDefault(playerId, null);
|
||||||
@@ -97,4 +118,15 @@ public class ClaimListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper für ClaimListener (Kopiert, da wir die Methode in Command nicht sehen können)
|
||||||
|
private String getClaimKeyFromLocation(Location loc) {
|
||||||
|
// Da wir hier keinen direkten Zugriff auf den Key haben, iterieren wir kurz
|
||||||
|
for (String key : plugin.getClaims().keySet()) {
|
||||||
|
if (plugin.getClaims().get(key).isInside(loc)) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package de.viper.survivalplus.listeners;
|
||||||
|
|
||||||
|
import de.viper.survivalplus.SurvivalPlus;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.SkullMeta;
|
||||||
|
|
||||||
|
public class HeadDropListener implements Listener {
|
||||||
|
private SurvivalPlus plugin;
|
||||||
|
|
||||||
|
public HeadDropListener(SurvivalPlus plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerDeath(PlayerDeathEvent event) {
|
||||||
|
if (!plugin.getConfig().getBoolean("heads.drop-on-death", true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player player = event.getEntity();
|
||||||
|
ItemStack head = new ItemStack(Material.PLAYER_HEAD);
|
||||||
|
SkullMeta meta = (SkullMeta) head.getItemMeta();
|
||||||
|
meta.setOwningPlayer(player);
|
||||||
|
meta.setDisplayName(ChatColor.YELLOW + "Kopf von " + player.getName());
|
||||||
|
head.setItemMeta(meta);
|
||||||
|
|
||||||
|
event.getDrops().add(head);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,324 @@
|
|||||||
|
package de.viper.survivalplus.listeners;
|
||||||
|
|
||||||
|
import de.viper.survivalplus.SurvivalPlus;
|
||||||
|
import net.milkbowl.vault.economy.Economy;
|
||||||
|
import net.milkbowl.vault.economy.EconomyResponse;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.Sign;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.SignChangeEvent;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||||
|
|
||||||
|
public class SignShopListener implements Listener {
|
||||||
|
private final SurvivalPlus plugin;
|
||||||
|
private Economy economy;
|
||||||
|
|
||||||
|
public SignShopListener(SurvivalPlus plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
try {
|
||||||
|
if (plugin.getServer().getPluginManager().isPluginEnabled("Vault")) {
|
||||||
|
RegisteredServiceProvider<Economy> rsp = plugin.getServer().getServicesManager().getRegistration(Economy.class);
|
||||||
|
if (rsp != null) {
|
||||||
|
this.economy = rsp.getProvider();
|
||||||
|
plugin.getLogger().info("Vault Economy für Sign Shops gefunden.");
|
||||||
|
} else {
|
||||||
|
plugin.getLogger().warning("Vault Economy Service nicht gefunden!");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
plugin.getLogger().warning("Vault Plugin nicht installiert! Sign Shops funktionieren nicht.");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
plugin.getLogger().warning("Fehler beim Laden der Vault API.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Schild erstellung ---
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
public void onSignChange(SignChangeEvent event) {
|
||||||
|
String line0Raw = event.getLine(0);
|
||||||
|
if (!line0Raw.equalsIgnoreCase("[buy]") && !line0Raw.equalsIgnoreCase("[sell]")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
if (!player.hasPermission("survivalplus.shop.create")) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Keine Berechtigung, Shops zu erstellen.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String line2 = event.getLine(1);
|
||||||
|
String line3 = event.getLine(2);
|
||||||
|
|
||||||
|
String[] parts = line2.split(" ");
|
||||||
|
if (parts.length < 2) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Format in Zeile 2 falsch! Beispiel: 64 Diamond");
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Integer.parseInt(parts[0]);
|
||||||
|
if (Material.matchMaterial(parts[1]) == null) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Das Item '" + parts[1] + "' existiert nicht.");
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Double.parseDouble(line3);
|
||||||
|
} catch (Exception e) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Fehler im Format! Benutze: [Buy] \n 64 Diamond \n 500");
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- NEU: Schild farbig machen ---
|
||||||
|
if (line0Raw.equalsIgnoreCase("[buy]")) {
|
||||||
|
event.setLine(0, ChatColor.GREEN + "[BUY]");
|
||||||
|
event.setLine(1, ChatColor.WHITE + parts[0] + " " + ChatColor.AQUA + parts[1]);
|
||||||
|
event.setLine(2, ChatColor.GOLD + line3 + " Coins");
|
||||||
|
} else if (line0Raw.equalsIgnoreCase("[sell]")) {
|
||||||
|
event.setLine(0, ChatColor.RED + "[SELL]");
|
||||||
|
event.setLine(1, ChatColor.WHITE + parts[0] + " " + ChatColor.AQUA + parts[1]);
|
||||||
|
event.setLine(2, ChatColor.GOLD + line3 + " Coins");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.getLine(3) != null && !event.getLine(3).isEmpty()) {
|
||||||
|
event.setLine(3, ChatColor.GRAY + event.getLine(3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Interaktion ---
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||||
|
Block block = event.getClickedBlock();
|
||||||
|
if (block == null || !(block.getState() instanceof Sign)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sign sign = (Sign) block.getState();
|
||||||
|
String line0 = ChatColor.stripColor(sign.getLine(0));
|
||||||
|
|
||||||
|
if (!line0.equalsIgnoreCase("[buy]") && !line0.equalsIgnoreCase("[sell]")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (economy == null) {
|
||||||
|
event.getPlayer().sendMessage(ChatColor.RED + "Shop System offline (Vault fehlt).");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- FEATURE: SHIFT+KLICK LOGIK (LÖSCHEN) ---
|
||||||
|
if (event.getPlayer().isSneaking()) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
if (!player.hasPermission("survivalplus.shop.create")) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Keine Berechtigung, Shops zu entfernen.");
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
block.breakNaturally();
|
||||||
|
player.sendMessage(ChatColor.GREEN + "Shop entfernt.");
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- ROUTING ---
|
||||||
|
if (line0.equalsIgnoreCase("[buy]")) {
|
||||||
|
handleBuy(event, sign);
|
||||||
|
} else if (line0.equalsIgnoreCase("[sell]")) {
|
||||||
|
handleSell(event, sign);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- KAUFS LOGIK (ROBUST) ---
|
||||||
|
private void handleBuy(PlayerInteractEvent event, Sign sign) {
|
||||||
|
event.setCancelled(true); // Interaktion stoppen
|
||||||
|
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
String line1Raw = ChatColor.stripColor(sign.getLine(1)); // "64 Diamond"
|
||||||
|
String line2Raw = ChatColor.stripColor(sign.getLine(2)); // "500" oder "500 Coins"
|
||||||
|
|
||||||
|
// 1. Validierung: Zeilen leer?
|
||||||
|
if (line1Raw == null || line1Raw.isEmpty()) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Zeile 1 des Schildes ist leer! (Format: 64 Diamond)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (line2Raw == null || line2Raw.isEmpty()) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Preiszeile ist leer! (Format: 500)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Parsing: Zeile 1 "64 Diamond"
|
||||||
|
String[] partsRaw = line1Raw.split(" ");
|
||||||
|
if (partsRaw.length < 2) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Falsches Format! Benutze: [Buy] \n 64 Diamond");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String amountStr = partsRaw[0].trim(); // "64"
|
||||||
|
String itemNameStr = partsRaw[1].trim(); // "Diamond"
|
||||||
|
|
||||||
|
if (amountStr.isEmpty() || itemNameStr.isEmpty()) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Format Fehler!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int amount;
|
||||||
|
Material material;
|
||||||
|
try {
|
||||||
|
amount = Integer.parseInt(amountStr);
|
||||||
|
material = Material.matchMaterial(itemNameStr);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Angebot '" + amountStr + "' ist keine Zahl! (Beispiel: 64)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (material == null) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Item '" + itemNameStr + "' existiert nicht!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Parsing: Zeile 2 "500 Coins" (Hier passierte der Fehler!)
|
||||||
|
String[] priceParts = line2Raw.split(" ");
|
||||||
|
if (priceParts.length == 0) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Preiszeile ist leer! (Beispiel: 500)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String priceStr = priceParts[0].trim();
|
||||||
|
if (priceStr.isEmpty()) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Kein Preis gefunden! (Beispiel: 500)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double price;
|
||||||
|
try {
|
||||||
|
price = Double.parseDouble(priceStr);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Preis '" + priceStr + "' ist keine Zahl! (Beispiel: 500)");
|
||||||
|
return;
|
||||||
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Fehlerhafter Preis! (Beispiel: 500)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (amount <= 0 || price < 0) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Negative Werte sind nicht erlaubt.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Transaktion
|
||||||
|
try {
|
||||||
|
ItemStack item = new ItemStack(material, amount);
|
||||||
|
|
||||||
|
if (economy.getBalance(player) >= price) {
|
||||||
|
EconomyResponse response = economy.withdrawPlayer(player, price);
|
||||||
|
if (response.transactionSuccess()) {
|
||||||
|
player.getInventory().addItem(item);
|
||||||
|
player.sendMessage(ChatColor.GREEN + "Du hast " + amount + " " + material.name().toLowerCase() + " für " + price + " gekauft!");
|
||||||
|
} else {
|
||||||
|
player.sendMessage(ChatColor.RED + "Fehler bei der Transaktion.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
player.sendMessage(ChatColor.RED + "Du hast nicht genug Geld! Du brauchst " + price + ".");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Ein Fehler ist beim Lesen des Shops aufgetreten.");
|
||||||
|
// Loggen für Debugging, falls Vault spinnt
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- VERKAUFS LOGIK ---
|
||||||
|
private void handleSell(PlayerInteractEvent event, Sign sign) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
String line1Raw = ChatColor.stripColor(sign.getLine(1));
|
||||||
|
String line2Raw = ChatColor.stripColor(sign.getLine(2));
|
||||||
|
|
||||||
|
if (line1Raw == null || line1Raw.isEmpty()) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Zeile 1 ist leer!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (line2Raw == null || line2Raw.isEmpty()) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Zeile 2 ist leer!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] partsRaw = line1Raw.split(" ");
|
||||||
|
if (partsRaw.length < 2) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Format falsch! Benutze: [Sell] \n 64 Diamond");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String amountStr = partsRaw[0].trim();
|
||||||
|
String itemNameStr = partsRaw[1].trim();
|
||||||
|
|
||||||
|
int amount;
|
||||||
|
Material material;
|
||||||
|
try {
|
||||||
|
amount = Integer.parseInt(amountStr);
|
||||||
|
material = Material.matchMaterial(itemNameStr);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Menge ist keine Zahl!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (material == null) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Item existiert nicht!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preis Parsing (wie im Kauf, nur sicherer)
|
||||||
|
String[] priceParts = line2Raw.split(" ");
|
||||||
|
if (priceParts.length == 0) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Preiszeile ist leer!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String priceStr = priceParts[0].trim();
|
||||||
|
if (priceStr.isEmpty()) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Kein Preis!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double price;
|
||||||
|
try {
|
||||||
|
price = Double.parseDouble(priceStr);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Preis '" + priceStr + "' ist keine Zahl!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (amount <= 0 || price < 0) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Negativer Wert!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack tempItem = new ItemStack(material, amount);
|
||||||
|
int hasAmount = 0;
|
||||||
|
|
||||||
|
for (ItemStack item : player.getInventory().getStorageContents()) {
|
||||||
|
if (item != null && item.isSimilar(tempItem)) {
|
||||||
|
hasAmount += item.getAmount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasAmount < amount) {
|
||||||
|
player.sendMessage(ChatColor.RED + "Du hast nicht genug Items!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verkauf durchführen
|
||||||
|
player.getInventory().removeItem(new ItemStack(material, amount));
|
||||||
|
economy.depositPlayer(player, price);
|
||||||
|
player.updateInventory();
|
||||||
|
|
||||||
|
player.sendMessage(ChatColor.GREEN + "Du hast " + amount + " " + material.name().toLowerCase() + " für " + price + " Coins verkauft!");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
package de.viper.survivalplus.listeners;
|
||||||
|
|
||||||
|
import de.viper.survivalplus.SurvivalPlus;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.EntityPickupItemEvent; // NEU: EntityPickupItemEvent
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||||
|
import com.comphenix.protocol.ProtocolLibrary;
|
||||||
|
import com.comphenix.protocol.ProtocolManager;
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
|
|
||||||
|
public class VanishListener implements Listener {
|
||||||
|
private final SurvivalPlus plugin;
|
||||||
|
|
||||||
|
public VanishListener(SurvivalPlus plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
if (plugin.isVanished(player.getUniqueId())) {
|
||||||
|
// Join Message ausblenden
|
||||||
|
event.setJoinMessage(null);
|
||||||
|
|
||||||
|
// Silent Join (Teleport-Effekt) via ProtocolLib
|
||||||
|
if (player.hasPermission("survivalplus.vanish.silent")) {
|
||||||
|
hideJoinParticles(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
if (plugin.isVanished(player.getUniqueId())) {
|
||||||
|
// Quit Message ausblenden
|
||||||
|
event.setQuitMessage(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onTeleport(PlayerTeleportEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
// Silent Teleport verhindert den Endermann-Teleportations-Effekt
|
||||||
|
if (plugin.isVanished(player.getUniqueId()) && player.hasPermission("survivalplus.vanish.silent")) {
|
||||||
|
// In 4.8.0 ist das stumme Teleportieren komplex.
|
||||||
|
// Wir lassen es hier beim Abschalten der Join-Partikel bewenden.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPickup(EntityPickupItemEvent event) {
|
||||||
|
if (!(event.getEntity() instanceof Player)) return; // Vorsichtshalber prüfen
|
||||||
|
|
||||||
|
Player player = (Player) event.getEntity();
|
||||||
|
if (plugin.isVanished(player.getUniqueId()) && player.hasPermission("survivalplus.vanish.no-pickup")) {
|
||||||
|
event.setCancelled(true); // Item nicht aufheben
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hideJoinParticles(Player player) {
|
||||||
|
if (!plugin.getServer().getPluginManager().isPluginEnabled("ProtocolLib")) return;
|
||||||
|
try {
|
||||||
|
// Direkter Cast auf ProtocolManager ist in 4.8.0 sicherer
|
||||||
|
ProtocolManager manager = (ProtocolManager) plugin.getServer().getPluginManager().getPlugin("ProtocolLib");
|
||||||
|
if (manager == null) return;
|
||||||
|
|
||||||
|
// Packet Container erstellen
|
||||||
|
PacketContainer packet = manager.createPacket(PacketType.Play.Server.ENTITY_STATUS);
|
||||||
|
packet.getIntegers().write(0, player.getEntityId());
|
||||||
|
packet.getBytes().write(0, (byte) 0x20); // 32 = Invisibel/Unsichtbar Status Client-Side
|
||||||
|
|
||||||
|
for (Player online : plugin.getServer().getOnlinePlayers()) {
|
||||||
|
if (online.equals(player)) continue;
|
||||||
|
manager.sendServerPacket(online, packet);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Ignorieren Fehler bei ProtocolLib
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,10 @@ version: 1.1.0
|
|||||||
# Debug-Option
|
# Debug-Option
|
||||||
debug-logging: false
|
debug-logging: false
|
||||||
|
|
||||||
|
# Spieler Kopf bei Tod
|
||||||
|
heads:
|
||||||
|
drop-on-death: true
|
||||||
|
|
||||||
# Neulings Schutz
|
# Neulings Schutz
|
||||||
newbie-protection:
|
newbie-protection:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|||||||
@@ -137,6 +137,10 @@ commands:
|
|||||||
description: "&eTeleportiert dich zu einem Freund."
|
description: "&eTeleportiert dich zu einem Freund."
|
||||||
usage: "&b/friend tp <Spieler>"
|
usage: "&b/friend tp <Spieler>"
|
||||||
|
|
||||||
|
freeze:
|
||||||
|
description: "&eFriert einen Spieler ein (Bewegung unmöglich)."
|
||||||
|
usage: "&b/freeze <Spieler>"
|
||||||
|
|
||||||
ir:
|
ir:
|
||||||
description: "&eBenennt das Item in der Hand um."
|
description: "&eBenennt das Item in der Hand um."
|
||||||
usage: "&b/ir <neuer_name>"
|
usage: "&b/ir <neuer_name>"
|
||||||
@@ -201,6 +205,10 @@ commands:
|
|||||||
description: "&eZeigt eine Liste der blockierten Spieler."
|
description: "&eZeigt eine Liste der blockierten Spieler."
|
||||||
usage: "&b/blocklist"
|
usage: "&b/blocklist"
|
||||||
|
|
||||||
|
vanish:
|
||||||
|
description: "&eMacht dich für andere Spieler unsichtbar."
|
||||||
|
usage: "&b/vanish"
|
||||||
|
|
||||||
kit:
|
kit:
|
||||||
description: "&eHolt das Starterkit."
|
description: "&eHolt das Starterkit."
|
||||||
usage: "&b/kit"
|
usage: "&b/kit"
|
||||||
@@ -213,6 +221,10 @@ commands:
|
|||||||
description: "&eÄndert deinen Nicknamen mit Farb- und Hex-Support."
|
description: "&eÄndert deinen Nicknamen mit Farb- und Hex-Support."
|
||||||
usage: "&b/nick <Name>"
|
usage: "&b/nick <Name>"
|
||||||
|
|
||||||
|
ride:
|
||||||
|
description: "&eReite einen Spieler oder Mob."
|
||||||
|
usage: "&b/ride [spieler]"
|
||||||
|
|
||||||
lootchests:
|
lootchests:
|
||||||
description: "&eZeigt eine Liste aller aktiven Loot-Kisten an. Admins können per Klick teleportieren."
|
description: "&eZeigt eine Liste aller aktiven Loot-Kisten an. Admins können per Klick teleportieren."
|
||||||
usage: "&b/lootchests"
|
usage: "&b/lootchests"
|
||||||
@@ -275,7 +287,7 @@ commands:
|
|||||||
|
|
||||||
claim:
|
claim:
|
||||||
description: "&eVerwaltet Claims für den Anti-Grief-Schutz."
|
description: "&eVerwaltet Claims für den Anti-Grief-Schutz."
|
||||||
usage: "&b/claim [mark <1|2>| unclaim | trust <spieler> | untrust <spieler>]"
|
usage: "&b/claim [mark <1|2>| unclaim | trust <spieler> | untrust <spieler> | info | kick <spieler> | ban <spieler> | unban <spieler>]"
|
||||||
subcommands:
|
subcommands:
|
||||||
mark:
|
mark:
|
||||||
description: "&eMarkiert die erste oder zweite Ecke eines zu schützenden Bereichs."
|
description: "&eMarkiert die erste oder zweite Ecke eines zu schützenden Bereichs."
|
||||||
@@ -289,6 +301,18 @@ commands:
|
|||||||
untrust:
|
untrust:
|
||||||
description: "&eEntfernt die Vertrauensberechtigung eines Spielers für den Bereich."
|
description: "&eEntfernt die Vertrauensberechtigung eines Spielers für den Bereich."
|
||||||
usage: "&b/claim untrust <spieler>"
|
usage: "&b/claim untrust <spieler>"
|
||||||
|
info:
|
||||||
|
description: "&eZeigt Informationen über den aktuellen Claim an."
|
||||||
|
usage: "&b/claim info"
|
||||||
|
kick:
|
||||||
|
description: "&eWirft einen Spieler aus dem Claim."
|
||||||
|
usage: "&b/claim kick <Spieler>"
|
||||||
|
ban:
|
||||||
|
description: "&eVerbannt einen Spieler permanent aus dem Claim."
|
||||||
|
usage: "&b/claim ban <Spieler>"
|
||||||
|
unban:
|
||||||
|
description: "&eEntbannt einen Spieler aus dem Claim."
|
||||||
|
usage: "&b/claim unban <Spieler>"
|
||||||
|
|
||||||
messages:
|
messages:
|
||||||
header: "&6=== Befehle ==="
|
header: "&6=== Befehle ==="
|
||||||
@@ -309,7 +333,7 @@ messages:
|
|||||||
name: "&ePlugin-Name: &f"
|
name: "&ePlugin-Name: &f"
|
||||||
version: "&eVersion: &f"
|
version: "&eVersion: &f"
|
||||||
author: "&eErsteller: &f"
|
author: "&eErsteller: &f"
|
||||||
description: "&eBeschreibung:\\n&f"
|
description: "&eBeschreibung:\n&f"
|
||||||
footer: "&7=========================="
|
footer: "&7=========================="
|
||||||
share:
|
share:
|
||||||
preview-title: "&aDeine aktuellen Koordinaten wären:"
|
preview-title: "&aDeine aktuellen Koordinaten wären:"
|
||||||
@@ -321,3 +345,18 @@ messages:
|
|||||||
sent: "&aKoordinaten gesendet."
|
sent: "&aKoordinaten gesendet."
|
||||||
cancelled: "&eSenden der Koordinaten abgebrochen."
|
cancelled: "&eSenden der Koordinaten abgebrochen."
|
||||||
help-not-found: "&cHilfedatei (help.yml) konnte nicht geladen werden!"
|
help-not-found: "&cHilfedatei (help.yml) konnte nicht geladen werden!"
|
||||||
|
vanish:
|
||||||
|
activated: "&aDu bist nun unsichtbar."
|
||||||
|
deactivated: "&cDu bist nun sichtbar."
|
||||||
|
freeze:
|
||||||
|
frozen: "&cDu wurdest von einem Admin eingefroren! &lKeine Bewegung möglich!"
|
||||||
|
unfrozen: "&aDu bist nicht mehr eingefroren."
|
||||||
|
player-frozen: "&a%player% wurde eingefroren."
|
||||||
|
player-unfrozen: "&a%player% wurde aufgetaut."
|
||||||
|
claim:
|
||||||
|
kicked: "&cDu wurdest aus dem Claim geworfen!"
|
||||||
|
kicked-target: "&aSpieler wurde aus dem Claim geworfen."
|
||||||
|
banned: "&cDu bist aus diesem Gebiet verbannt!"
|
||||||
|
unbanned: "&aDu bist für dieses Gebiet entbannt."
|
||||||
|
admin-banned: "&aSpieler wurde von diesem Claim gebannt."
|
||||||
|
admin-unbanned: "&aSpieler wurde für diesen Claim entbannt."
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
name: SurvivalPlus
|
name: SurvivalPlus
|
||||||
version: 1.1.1
|
version: 1.1.2
|
||||||
|
|
||||||
main: de.viper.survivalplus.SurvivalPlus
|
main: de.viper.survivalplus.SurvivalPlus
|
||||||
api-version: 1.21
|
api-version: 1.21
|
||||||
softdepend: [LuckPerms, PlaceholderAPI, ProtocolLib]
|
softdepend: [LuckPerms, PlaceholderAPI, ProtocolLib, Vault]
|
||||||
author: Viper
|
author: Viper
|
||||||
description: A plugin for enhancing survival gameplay in Minecraft.
|
description: A plugin for enhancing survival gameplay in Minecraft.
|
||||||
|
|
||||||
@@ -188,6 +188,16 @@ commands:
|
|||||||
usage: /<command> [spieler]
|
usage: /<command> [spieler]
|
||||||
permission: survivalplus.ride
|
permission: survivalplus.ride
|
||||||
permission-message: "§cDu hast keine Berechtigung, Spieler zu reiten!"
|
permission-message: "§cDu hast keine Berechtigung, Spieler zu reiten!"
|
||||||
|
vanish:
|
||||||
|
description: Macht dich unsichtbar
|
||||||
|
usage: /<command>
|
||||||
|
permission: survivalplus.vanish
|
||||||
|
permission-message: "§cDu hast keine Berechtigung für diesen Befehl."
|
||||||
|
freeze:
|
||||||
|
description: Friert einen Spieler ein
|
||||||
|
usage: /<command> <Spieler>
|
||||||
|
permission: survivalplus.freeze
|
||||||
|
permission-message: "§cDu hast keine Berechtigung für diesen Befehl."
|
||||||
lootchests:
|
lootchests:
|
||||||
description: Zeigt eine Liste aller aktiven Loot-Kisten an. Admins können per Klick zu einer Kiste teleportieren.
|
description: Zeigt eine Liste aller aktiven Loot-Kisten an. Admins können per Klick zu einer Kiste teleportieren.
|
||||||
usage: /<command>
|
usage: /<command>
|
||||||
@@ -268,11 +278,19 @@ commands:
|
|||||||
usage: /<command> [spieler]
|
usage: /<command> [spieler]
|
||||||
permission: survivalplus.heal
|
permission: survivalplus.heal
|
||||||
permission-message: "§cDu hast keine Berechtigung, Spieler zu heilen!"
|
permission-message: "§cDu hast keine Berechtigung, Spieler zu heilen!"
|
||||||
|
|
||||||
claim:
|
claim:
|
||||||
description: Manages claims for anti-griefing
|
description: Manages claims for anti-griefing
|
||||||
usage: /<command> [unclaim | trust <player> | untrust <player>]
|
usage: /<command> [mark|unclaim|del|delete|trust|untrust|info|kick|ban|unban]
|
||||||
aliases: [cl]
|
aliases: [cl]
|
||||||
|
permission: survivalplus.claim.use
|
||||||
|
permission-message: "§cDu hast keine Berechtigung für diesen Befehl."
|
||||||
|
|
||||||
|
# --- NEU: HEAD COMMAND ---
|
||||||
|
head:
|
||||||
|
description: Hol dir den Kopf eines Spielers.
|
||||||
|
usage: /<command> <name>
|
||||||
|
permission: survivalplus.head
|
||||||
|
permission-message: "§cDu hast keine Berechtigung für diesen Befehl."
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
survivalplus.*:
|
survivalplus.*:
|
||||||
@@ -326,6 +344,8 @@ permissions:
|
|||||||
survivalplus.nick: true
|
survivalplus.nick: true
|
||||||
survivalplus.ride: true
|
survivalplus.ride: true
|
||||||
survivalplus.ride.exempt: true
|
survivalplus.ride.exempt: true
|
||||||
|
survivalplus.vanish: true
|
||||||
|
survivalplus.freeze: true
|
||||||
survivalplus.lootchests: true
|
survivalplus.lootchests: true
|
||||||
survivalplus.day: true
|
survivalplus.day: true
|
||||||
survivalplus.night: true
|
survivalplus.night: true
|
||||||
@@ -346,6 +366,12 @@ permissions:
|
|||||||
survivalplus.chunkanimals: true
|
survivalplus.chunkanimals: true
|
||||||
survivalplus.claim.use: true
|
survivalplus.claim.use: true
|
||||||
survivalplus.claim.trust: true
|
survivalplus.claim.trust: true
|
||||||
|
survivalplus.claim.kick: true
|
||||||
|
survivalplus.claim.ban: true
|
||||||
|
survivalplus.head: true
|
||||||
|
survivalplus.claim.admin: true
|
||||||
|
survivalplus.vanish.silent: true
|
||||||
|
survivalplus.vanish.no-pickup: true
|
||||||
survivalplus.commandblocker.add:
|
survivalplus.commandblocker.add:
|
||||||
description: Erlaubt das Hinzufügen von Befehlen zur Blockierliste
|
description: Erlaubt das Hinzufügen von Befehlen zur Blockierliste
|
||||||
default: op
|
default: op
|
||||||
@@ -487,6 +513,12 @@ permissions:
|
|||||||
survivalplus.ride.exempt:
|
survivalplus.ride.exempt:
|
||||||
description: Spieler mit dieser Permission können nicht geritten werden
|
description: Spieler mit dieser Permission können nicht geritten werden
|
||||||
default: op
|
default: op
|
||||||
|
survivalplus.vanish:
|
||||||
|
description: Erlaubt das Unsichtbar werden
|
||||||
|
default: op
|
||||||
|
survivalplus.freeze:
|
||||||
|
description: Erlaubt das Einfrieren von Spielern
|
||||||
|
default: op
|
||||||
survivalplus.lootchests:
|
survivalplus.lootchests:
|
||||||
description: Erlaubt das Verwalten und Teleportieren zu Loot-Kisten
|
description: Erlaubt das Verwalten und Teleportieren zu Loot-Kisten
|
||||||
default: op
|
default: op
|
||||||
@@ -541,3 +573,27 @@ permissions:
|
|||||||
survivalplus.chunkanimals:
|
survivalplus.chunkanimals:
|
||||||
description: Erlaubt das Anzeigen der Anzahl der Tiere im aktuellen Chunk
|
description: Erlaubt das Anzeigen der Anzahl der Tiere im aktuellen Chunk
|
||||||
default: op
|
default: op
|
||||||
|
survivalplus.claim.use:
|
||||||
|
description: Erlaubt das Erstellen von Claims
|
||||||
|
default: true
|
||||||
|
survivalplus.claim.trust:
|
||||||
|
description: Erlaubt das Verwalten von Trusted-Spielern in Claims
|
||||||
|
default: true
|
||||||
|
survivalplus.claim.kick:
|
||||||
|
description: Erlaubt das Kicken von Spielern aus Claims
|
||||||
|
default: op
|
||||||
|
survivalplus.claim.ban:
|
||||||
|
description: Erlaubt das Bannen von Spielern aus Claims
|
||||||
|
default: op
|
||||||
|
survivalplus.claim.admin:
|
||||||
|
description: Erlaubt das Löschen von fremden Claims (Admin Feature)
|
||||||
|
default: op
|
||||||
|
survivalplus.vanish.silent:
|
||||||
|
description: Erlaubt stummes Einloggen
|
||||||
|
default: op
|
||||||
|
survivalplus.vanish.no-pickup:
|
||||||
|
description: Kein Items aufheben im Vanish-Modus
|
||||||
|
default: op
|
||||||
|
survivalplus.head:
|
||||||
|
description: Erlaubt das Holen von Spielerköpfen
|
||||||
|
default: true
|
||||||
Reference in New Issue
Block a user