7 Commits
1.0.8 ... main

Author SHA1 Message Date
39cf666bf4 readme.md aktualisiert 2025-08-27 18:58:51 +00:00
24c551fb5c readme.md aktualisiert 2025-08-27 18:48:33 +00:00
790980a5ac readme.md aktualisiert 2025-08-27 18:24:02 +00:00
779f031fdc readme.md aktualisiert 2025-08-27 18:18:29 +00:00
7fb9afa9d3 Update: Versionierung in config/lang/help/tablist.yml + Debug-System 2025-08-27 20:07:30 +02:00
a69200ee17 src/main/resources/plugin.yml aktualisiert 2025-08-25 13:25:51 +00:00
73fed5acc5 pom.xml aktualisiert 2025-08-25 06:33:32 +00:00
10 changed files with 417 additions and 109 deletions

View File

@@ -6,7 +6,8 @@
<groupId>de.viper</groupId> <groupId>de.viper</groupId>
<artifactId>SurvivalPlus</artifactId> <artifactId>SurvivalPlus</artifactId>
<version>1.0.8-Beta</version> <version>1.0.9-Beta</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>SurvivalPlus</name> <name>SurvivalPlus</name>

189
readme.md
View File

@@ -1,87 +1,146 @@
# SurvivalPlus # SurvivalPlus
![Minecraft Plugin](https://img.shields.io/badge/Minecraft-Plugin-green) ![Minecraft Plugin](https://img.shields.io/badge/Minecraft-Plugin-green)
![Version](https://img.shields.io/badge/version-1.0.5-blue) ![Version](https://img.shields.io/badge/version-1.0.9-blue)
![Author](https://img.shields.io/badge/author-M_Viper-yellow) ![Author](https://img.shields.io/badge/author-M_Viper-yellow)
**SurvivalPlus** ist ein Minecraft-Plugin zur Verbesserung des Survival-Erlebnisses. **SurvivalPlus** ist ein Minecraft-Plugin zur Verbesserung des Survival-Erlebnisses.
Es bietet Homes, Teleportation, Inventarverwaltung, Freundeslisten, Shops, Loot-Kisten und weitere Komfortbefehle. Es bietet Homes, Teleports, Inventar-/Enderchest-Verwaltung, Claims (Anti-Grief), Freundeslisten, Shop-System, Loot-Kisten, Tablist-Anpassungen und viele Komfort-Utilities.
--- ---
## ⚡ Features ## ⚡ Highlights / Features
- **Homes & Warps** Homepunkte setzen, löschen, Teleportation, persönliche Warps - Homes & Warps (persönliche Warps, Home-Management)
- **Teleportation & Spielerinteraktion** `/tp`, `/tphere`, `/tpa`, `/back`, `/spawn` - Teleportation & Anfrage-System (`/tpa`, `/tpaccept`, `/tpdeny`)
- **Inventar & Endertruhe** Öffnen eigener und fremder Inventare/Endertruhen - Claim-System zur Land-Sicherung (trust/untrust, create/delete, info, list)
- **Spielmodus & Zeit** `/gm`, `/day`, `/night` - Inventar- & Enderchest-Verwaltung (öffnen von Fremd-Inventaren, Admin-Tools)
- **Freundes- und Kommunikationssystem** `/friend`, `/block`, `/blocklist` - Shop-System & Lootchests (Verwaltung, Teleport zu Lootchests)
- **Koordinaten teilen** `/sp share`, `/sp shareconfirm`, `/sp sharecancel` - CommandBlocker & Server-Utilities (clearchat, clearitems, closedoors, lock)
- **Items & Werkzeuge** `/ir`, `/workbench`, `/anvil`, `/kit` - Debug-Logging (optionale `debug-logging` in config, Debug/debug.log & Debug/console.log)
- **Server-Management** `/clearchat`, `/clearitems`, `/closedoors`, `/lock`, `/shop` - Tablist (animiert / konfigurierbar über `tablist.yml`)
- **Statistiken & Reporting** `/stats`, `/report`, `/showreport`, `/clearreport` - bStats Unterstützung (Statistiken)
- **Fun & Challenges** `/sit`, `/startchallenge`, `/trade`, `/lootchests`
--- ---
## 🛠 Commands Übersicht ## 🛠 Komplette Befehlsübersicht
> Hinweis: In `plugin.yml` sind alle Commands definiert — hier die Übersicht gruppiert nach Kategorie.
### Allgemein / Haupt
| Befehl | Nutzung | Permission |
|---|---:|:---|
| `/sp` | Hauptbefehl (CommandBlocker, reload, info, share, help u.v.m.) | `survivalplus.sp` |
| `/help` (alias über `/sp help`) | Hilfe / Übersicht | `survivalplus.sp` |
### Item & Utility
| Befehl | Usage | Permission |
|---|---:|:---|
| `/ir <neuer_name>` | Item umbenennen (Item in Hand) | `survivalplus.itemrename` |
| `/workbench` | Öffnet Werkbank-GUI | `survivalplus.workbench` |
| `/anvil` | Öffnet Amboss-GUI | `survivalplus.anvil` |
| `/trash` | Öffnet Mülleimer | `survivalplus.trash` |
| `/showarmorstands` | Alle (debug) ArmorStands sichtbar machen | `survivalplus.showarmorstands` |
| `/cleardebugarmorstands` | Entfernt Debug-ArmorStands | `survivalplus.cleardebugarmorstands` |
| `/leashcount` | Anzahl geleinter Tiere anzeigen | `survivalplus.leashcount` |
| `/nick <Name>` | Nickname ändern (Farben/Hex möglich) | `survivalplus.nick` |
### Teleportation ### Teleportation
| Befehl | Nutzung | Permission | | Befehl | Usage | Permission |
|--------|---------|------------| |---|---:|:---|
| `/tp` | Teleport zu Spieler | `survivalplus.tp` | | `/tp <Spieler>` | Teleport zu Spieler | `survivalplus.tp` |
| `/tphere` | Spieler zu dir teleportieren | `survivalplus.tphere` | | `/tphere <Spieler>` | Teleportiert Spieler zu dir | `survivalplus.tphere` |
| `/tpa` | Teleportanfrage senden | `survivalplus.tpa` | | `/tpa <Spieler>` | Teleportanfrage senden | `survivalplus.tpa` |
| `/tpaccept` | Teleportanfrage annehmen | `survivalplus.tpaccept` | | `/tpaccept` | Teleportanfrage annehmen | `survivalplus.tpaccept` |
| `/tpdeny` | Teleportanfrage ablehnen | `survivalplus.tpdeny` | | `/tpdeny` | Teleportanfrage ablehnen | `survivalplus.tpdeny` |
| `/back` | Zum letzten Todespunkt | `survivalplus.back` | | `/back` | Zum letzten Todespunkt teleportieren | `survivalplus.back` |
| `/spawn` | Weltspawn teleport | `survivalplus.spawn` | | `/spawn` | Teleport zum Weltspawn | `survivalplus.spawn` |
| `/setspawn` | Setzt Server-Spawn | `survivalplus.setspawn` |
| `/setworldspawn` | Setzt Weltspawn (aktuelle Welt) | `survivalplus.setworldspawn` |
### Homes & Warps ### Homes & Warps
| Befehl | Nutzung | Permission | | Befehl | Usage | Permission |
|--------|---------|------------| |---|---:|:---|
| `/sethome <name>` | Home setzen | `survivalplus.homes.set` | | `/sethome <name>` | Setzt Home | `survivalplus.homes.set` |
| `/delhome <name>` | Home löschen | `survivalplus.homes.delete` | | `/delhome <name>` | Löscht Home | `survivalplus.homes.delete` |
| `/home <name>` | Teleport zu Home | `survivalplus.homes` | | `/home <name>` | Teleport zu Home | `survivalplus.homes` |
| `/homelist` | Liste aller Homes | `survivalplus.homes.list` | | `/homelist` | GUI mit Homes öffnen | `survivalplus.homes.list` |
| `/setwarp <name>` | Persönlichen Warp setzen | `survivalplus.setwarp` | | `/setwarp <name>` | Persönlichen Warp setzen (Item in Hand) | `survivalplus.setwarp` |
| `/delwarp <name>` | Persönlichen Warp löschen | `survivalplus.delwarp` | | `/delwarp <name>` | Persönlichen Warp löschen | `survivalplus.delwarp` |
| `/warps` | GUI aller Warps öffnen | `survivalplus.warps` | | `/warps` | GUI aller Warps öffnen | `survivalplus.warps` |
### Spieler & Kommunikation ### Claim (Anti-Grief)
| Befehl | Nutzung | Permission | | Befehl | Usage | Permission |
|--------|---------|------------| |---|---:|:---|
| `/friend` | Freundesliste verwalten | `survivalplus.friend` | | `/claim [unclaim / trust <player> / untrust <player>]` | Claim-Management (Trust/Untrust/Unclaim) | `survivalplus.claim.use` |
| `/block` | Spieler blockieren | `survivalplus.block` | | `/claim create <name>` (falls implementiert) | Neues Claim anlegen | `survivalplus.claim.use` |
| `/unblock` | Blockierung aufheben | `survivalplus.unlock` | | `/claim delete <name>` (falls implementiert) | Claim löschen | `survivalplus.claim.use` |
| `/blocklist` | Liste blockierter Spieler | `survivalplus.blocklist` | | `/claim addmember <player>` | Spieler zum Claim hinzufügen | `survivalplus.claim.trust` |
| `/claim removemember <player>` | Spieler entfernen | `survivalplus.claim.trust` |
| `/claim info` | Claim-Informationen anzeigen | `survivalplus.claim.use` |
| `/claim list` | Eigene Claims auflisten | `survivalplus.claim.use` |
### Items & Werkzeuge ### CommandBlocker / Server-Management
| Befehl | Nutzung | Permission | | Befehl | Usage | Permission |
|--------|---------|------------| |---|---:|:---|
| `/ir <neuer_name>` | Item umbenennen | `survivalplus.itemrename` | | `/sp cb add <cmd>` | Befehl zur Blockliste hinzufügen | `survivalplus.commandblocker.add` |
| `/workbench` | Werkbank GUI öffnen | `survivalplus.workbench` | | `/sp cb remove <cmd>` | Befehl entfernen | `survivalplus.commandblocker.remove` |
| `/anvil` | Amboss GUI öffnen | `survivalplus.anvil` | | `/sp cb list` | Blockierte Befehle anzeigen | `survivalplus.commandblocker.list` |
| `/kit` | Starterkit erhalten | `survivalplus.kit` |
| `/leashcount` | Anzahl geleinter Tiere | `survivalplus.leashcount` |
| `/nick <Name>` | Nickname ändern | `survivalplus.nick` |
### Server-Management
| Befehl | Nutzung | Permission |
|--------|---------|------------|
| `/clearchat` | Chat löschen | `survivalplus.clearchat` | | `/clearchat` | Chat löschen | `survivalplus.clearchat` |
| `/clearitems` | Items entfernen | `survivalplus.clearitems` | | `/clearitems` | Items aufsammeln/entfernen | `survivalplus.clearitems` |
| `/closedoors <radius>` | Türen schließen | `survivalplus.closedoors` | | `/closedoors <radius>` | Türen in Radius schließen | `survivalplus.closedoors` |
| `/lock` | Container schützen | `survivalplus.lock` | | `/splock lock|unlock|friendadd|friendremove [player]` | Kisten/Türen sperren / freigeben | `survivalplus.lock` |
| `/shop add <item> <preis> <bestand>` | Server-Shop verwalten | `survivalplus.shop` |
### Statistiken & Reporting ### Shop, Loot & Trade
| Befehl | Nutzung | Permission | | Befehl | Usage | Permission |
|--------|---------|------------| |---|---:|:---|
| `/stats` | Spielerstatistiken | `survivalplus.stats` | | `/shop add <item> <basispreis> <lagerbestand>` | Shop verwalten | `survivalplus.shop` |
| `/report <spieler> [grund]` | Spieler melden | `survivalplus.report` | | `/lootchests` | Listet Loot-Kisten auf (Admins teleportieren) | `survivalplus.lootchests` |
| `/showreport <spieler>` | Reports anzeigen | `survivalplus.report.show` | | `/tploot <welt> <x> <y> <z>` | Teleportiere zu Loot-Kiste (Admin) | `survivalplus.lootchests` |
| `/clearreport <spieler>` | Reports löschen | `survivalplus.report.clear` | | `/trade <Spieler>` | Startet Handel | `survivalplus.trade` |
| `/tradeaccept <Spieler>` | Akzeptiert Handel | `survivalplus.tradeaccept` |
### Zeit, Gamemode & Admin
| Befehl | Usage | Permission |
|---|---:|:---|
| `/day` | Setzt Zeit auf Tag | `survivalplus.day` |
| `/night` | Setzt Zeit auf Nacht | `survivalplus.night` |
| `/gm <modus> [spieler]` (alias `gamemode`) | Spielmodus ändern | `survivalplus.gamemode` |
| `/heal [spieler]` | Heilt Spieler (oder andere) | `survivalplus.heal`, `survivalplus.heal.others` |
### Freundes-, Block- & Report-System
| Befehl | Usage | Permission |
|---|---:|:---|
| `/friend [add/accept/deny/list/del/tp] [Spieler]` | Freundschaften verwalten | `survivalplus.friend` |
| `/block <Spieler>` | Spieler blockieren | `survivalplus.block` |
| `/unblock <Spieler>` | Unblock | `survivalplus.unblock` |
| `/blocklist` | Blockierte Spieler anzeigen | `survivalplus.blocklist` |
| `/report <Spieler> [Grund]` | Spieler melden | `survivalplus.report` |
| `/showreport <Spieler>` | Reports anzeigen | `survivalplus.report.show` |
| `/clearreport <Spieler>` | Reports löschen | `survivalplus.report.clear` |
### Sonstiges
| Befehl | Usage | Permission |
|---|---:|:---|
| `/stats` | Spielerstatistiken anzeigen | `survivalplus.stats` |
| `/kit` | Starterkit erhalten | `survivalplus.kit` |
| `/startchallenge <name>` | Fun-Challenge starten | `survivalplus.startchallenge` |
| `/lootchests` | Übersicht über Lootkisten | `survivalplus.lootchests` |
---
## 🔐 Permissions (Kurzüberblick)
Vollständige Permission-Deklaration findest du in `plugin.yml`.
Wichtige Permissions:
- `survivalplus.*` — Vollzugriff (OP)
- `survivalplus.sp` — Zugriff auf `/sp` (Hauptbefehl)
- `survivalplus.homes.*` — Homes verwalten
- `survivalplus.claim.use` / `survivalplus.claim.trust` — Claim-Management & Trust
- `survivalplus.shop` — Shopverwaltung
- `survivalplus.lootchests` — Lootchest-Adminrechte
- `survivalplus.notify` — Admin-Benachrichtigung bei Besitz von Command/Structure-Blocks
- uvm. — siehe `plugin.yml` für die vollständige Liste
--- ---
@@ -94,13 +153,17 @@ Es bietet Homes, Teleportation, Inventarverwaltung, Freundeslisten, Shops, Loot-
--- ---
## 🔐 Permissions ## 🐞 Debug & Fehlerberichte
- **Vollzugriff:** `survivalplus.*` (OP) - Aktiviere in `config.yml` `debug-logging: true` wenn du Probleme hast.
- Alle Befehle können über LuckPerms angepasst werden. - `Debug/debug.log` — enthält Plugin-Fehler/Stacktraces (nur wenn aktiviert).
- `Debug/console.log` — dupliziert den Konsolenoutput (komplette Ausgabe), damit du diesen als Datei an Entwickler schicken kannst.
---
## 📜 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).
--- ---
## 📜 Lizenz
Dieses Projekt ist frei für den privaten Gebrauch. Kontakt: **M_Viper**

View File

@@ -58,13 +58,19 @@ public class TablistManager implements Listener {
// Resource sicherstellen, Config laden // Resource sicherstellen, Config laden
try { try {
plugin.saveResource("tablist.yml", false); File tablistFile = new File(plugin.getDataFolder(), "tablist.yml");
if (!tablistFile.exists()) {
plugin.saveResource("tablist.yml", false);
}
} catch (Exception ignored) {} } catch (Exception ignored) {}
try { try {
plugin.reloadTablistConfig(); plugin.reloadTablistConfig();
} catch (Exception ignored) {} } catch (Exception ignored) {}
FileConfiguration config = plugin.getTablistConfig(); FileConfiguration config = plugin.getTablistConfig();
// Nicknames.yml laden // Nicknames.yml laden
try { try {
File nicknameFile = new File(plugin.getDataFolder(), "nicknames.yml"); File nicknameFile = new File(plugin.getDataFolder(), "nicknames.yml");

View File

@@ -66,6 +66,13 @@ import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import de.viper.survivalplus.util.BannerManager;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.charset.StandardCharsets;
public class SurvivalPlus extends JavaPlugin { public class SurvivalPlus extends JavaPlugin {
@@ -116,6 +123,11 @@ public class SurvivalPlus extends JavaPlugin {
private Map<UUID, Integer> playerClaimCounts = new HashMap<>(); private Map<UUID, Integer> playerClaimCounts = new HashMap<>();
private Map<UUID, Location> point1Selections = new HashMap<>(); private Map<UUID, Location> point1Selections = new HashMap<>();
private Map<UUID, Location> point2Selections = new HashMap<>(); private Map<UUID, Location> point2Selections = new HashMap<>();
private BannerManager bannerManager;
private File debugFile;
private PrintWriter debugWriter;
private File consoleFile;
private PrintWriter consoleWriter;
public void reloadTablistConfig() { public void reloadTablistConfig() {
if (tablistFile == null) tablistFile = new File(getDataFolder(), "tablist.yml"); if (tablistFile == null) tablistFile = new File(getDataFolder(), "tablist.yml");
@@ -168,6 +180,41 @@ public class SurvivalPlus extends JavaPlugin {
@Override @Override
public void onEnable() { public void onEnable() {
saveDefaultConfig(); saveDefaultConfig();
// Version aus plugin.yml
String pluginVersion = getDescription().getVersion();
// Sicherstellen, dass 'version:' ganz oben steht
ensureConfigVersion(getConfig(), new File(getDataFolder(), "config.yml"), pluginVersion);
ensureVersionAtTop(new File(getDataFolder(), "lang.yml"), pluginVersion);
ensureVersionAtTop(new File(getDataFolder(), "help.yml"), pluginVersion);
ensureVersionAtTop(new File(getDataFolder(), "tablist.yml"), pluginVersion);
// Debug-Logging initialisieren
if (getConfig().getBoolean("debug-logging", false)) {
try {
// Ordner erstellen
File debugFolder = new File(getDataFolder(), "Debug");
if (!debugFolder.exists()) {
debugFolder.mkdirs();
}
// debug.log für Fehler
debugFile = new File(debugFolder, "debug.log");
if (!debugFile.exists()) debugFile.createNewFile();
debugWriter = new PrintWriter(new FileWriter(debugFile, true), true);
// console.log für komplette Plugin-Infos
consoleFile = new File(debugFolder, "console.log");
if (!consoleFile.exists()) consoleFile.createNewFile();
consoleWriter = new PrintWriter(new FileWriter(consoleFile, true), true);
logConsole("Debug-Logging ist aktiviert. Alle Plugin-Logs werden in Debug/console.log gespeichert.");
} catch (IOException e) {
getLogger().warning("Konnte Debug-Dateien nicht erstellen: " + e.getMessage());
}
}
int pluginId = 26886; int pluginId = 26886;
Metrics metrics = new Metrics(this, pluginId); Metrics metrics = new Metrics(this, pluginId);
metrics.addCustomChart(new SimplePie( metrics.addCustomChart(new SimplePie(
@@ -182,6 +229,10 @@ public class SurvivalPlus extends JavaPlugin {
"plugin_language", "plugin_language",
() -> getConfig().getString("language", "default") () -> getConfig().getString("language", "default")
)); ));
bannerManager = new BannerManager(this);
bannerManager.displayConsoleBanner(); // Banner beim Serverstart
updateConfigFiles(); updateConfigFiles();
createHomesFile(); createHomesFile();
createGravesFile(); createGravesFile();
@@ -383,6 +434,77 @@ public class SurvivalPlus extends JavaPlugin {
getLogger().info("Block-Regeln angewendet: CommandBlocks erlaubt=" + cmdAllowed + ", StructureBlocks erlaubt=" + structAllowed); getLogger().info("Block-Regeln angewendet: CommandBlocks erlaubt=" + cmdAllowed + ", StructureBlocks erlaubt=" + structAllowed);
} }
private void ensureVersionAtTop(File file, String version) {
try {
if (!file.exists()) return; // Datei existiert nicht
List<String> lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
if (!lines.isEmpty() && lines.get(0).startsWith("version:")) {
// Alte Versionsnummer ersetzen
lines.set(0, "version: " + version);
} else {
// Version an den Anfang setzen
lines.add(0, "version: " + version);
}
Files.write(file.toPath(), lines, StandardCharsets.UTF_8);
} catch (IOException e) {
getLogger().warning("Konnte Version in " + file.getName() + " nicht setzen: " + e.getMessage());
}
}
/**
* Speziell für config.yml:
* - Setzt die Version in der geladenen FileConfiguration (getConfig()) und speichert sie,
* - und sorgt anschließend dafür, dass die 'version:'-Zeile ganz oben in der Datei steht.
*/
private void ensureConfigVersion(FileConfiguration config, File file, String version) {
try {
if (!file.exists()) return; // nichts zu tun, Datei existiert nicht
// 1) Version in der geladenen Config setzen und speichern (Bukkit nutzt diese Config im Speicher)
String current = config.getString("version", "");
if (!version.equals(current)) {
config.set("version", version);
try {
config.save(file);
} catch (IOException e) {
getLogger().warning("Konnte config.yml nicht speichern: " + e.getMessage());
}
}
// 2) Text-Nachbearbeitung: sicherstellen, dass 'version:' als erste Zeile steht
List<String> lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
// Entferne alle vorhandenen version:-Zeilen (falls irgendwo)
int foundIndex = -1;
for (int i = 0; i < lines.size(); i++) {
if (lines.get(i).trim().startsWith("version:")) {
foundIndex = i;
break;
}
}
if (foundIndex == 0) {
// bereits oben -> ersetzen
lines.set(0, "version: " + version);
} else {
// entferne alte Stelle (wenn vorhanden)
if (foundIndex > 0) {
lines.remove(foundIndex);
}
// füge neue version ganz oben ein
lines.add(0, "version: " + version);
}
Files.write(file.toPath(), lines, StandardCharsets.UTF_8);
getLogger().info("config.yml: Version oben gesetzt auf " + version);
} catch (IOException e) {
getLogger().warning("Konnte Version in config.yml nicht setzen: " + e.getMessage());
}
}
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")) {
@@ -558,19 +680,6 @@ public class SurvivalPlus extends JavaPlugin {
// Methoden für nicknames.yml // Methoden für nicknames.yml
public void createNicknamesFile() { public void createNicknamesFile() {
nicknamesFile = new File(getDataFolder(), "nicknames.yml"); nicknamesFile = new File(getDataFolder(), "nicknames.yml");
@@ -618,6 +727,9 @@ public class SurvivalPlus extends JavaPlugin {
@Override @Override
public void onDisable() { public void onDisable() {
if (debugWriter != null) {
debugWriter.close();
}
if (autoClearTaskId != -1) { if (autoClearTaskId != -1) {
Bukkit.getScheduler().cancelTask(autoClearTaskId); Bukkit.getScheduler().cancelTask(autoClearTaskId);
} }
@@ -1066,4 +1178,34 @@ public class SurvivalPlus extends JavaPlugin {
e.printStackTrace(); e.printStackTrace();
} }
} }
public BannerManager getBannerManager() {
return bannerManager;
}
// Nur Fehler/Exceptions
public void log(String msg) {
if (getConfig().getBoolean("debug-logging", false) && debugWriter != null) {
debugWriter.println("[" + new java.util.Date() + "] " + msg);
} else {
getLogger().info(msg);
}
}
public void logError(String msg, Throwable t) {
if (getConfig().getBoolean("debug-logging", false) && debugWriter != null) {
debugWriter.println("[" + new java.util.Date() + "] ERROR: " + msg);
t.printStackTrace(debugWriter);
} else {
getLogger().log(Level.SEVERE, msg, t);
}
}
// Komplette Plugin-Logs in console.log
public void logConsole(String msg) {
if (getConfig().getBoolean("debug-logging", false) && consoleWriter != null) {
consoleWriter.println("[" + new java.util.Date() + "] " + msg);
}
getLogger().info(msg); // Optional: zusätzlich Konsole ausgeben
}
} }

View File

@@ -2,13 +2,20 @@ 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.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class ClaimListener implements Listener { public class ClaimListener implements Listener {
private SurvivalPlus plugin; private final SurvivalPlus plugin;
private final Map<UUID, Claim> lastClaim = new HashMap<>();
public ClaimListener(SurvivalPlus plugin) { public ClaimListener(SurvivalPlus plugin) {
this.plugin = plugin; this.plugin = plugin;
@@ -16,19 +23,51 @@ public class ClaimListener implements Listener {
@EventHandler @EventHandler
public void onBlockBreak(BlockBreakEvent event) { public void onBlockBreak(BlockBreakEvent event) {
Player player = event.getPlayer();
if (player.isOp()) return;
Claim claim = plugin.getClaim(event.getBlock().getLocation()); Claim claim = plugin.getClaim(event.getBlock().getLocation());
if (claim != null && !claim.canInteract(event.getPlayer().getUniqueId()) && !event.getPlayer().isOp()) { if (claim != null && !claim.getOwner().equals(player.getUniqueId()) && !claim.getTrusted().contains(player.getUniqueId())) {
event.setCancelled(true); event.setCancelled(true);
event.getPlayer().sendMessage(plugin.getMessage("claim.no-break")); player.sendMessage(plugin.getMessage("claim.no-break"));
} }
} }
@EventHandler @EventHandler
public void onBlockPlace(BlockPlaceEvent event) { public void onBlockPlace(BlockPlaceEvent event) {
Player player = event.getPlayer();
if (player.isOp()) return;
Claim claim = plugin.getClaim(event.getBlock().getLocation()); Claim claim = plugin.getClaim(event.getBlock().getLocation());
if (claim != null && !claim.canInteract(event.getPlayer().getUniqueId()) && !event.getPlayer().isOp()) { if (claim != null && !claim.getOwner().equals(player.getUniqueId()) && !claim.getTrusted().contains(player.getUniqueId())) {
event.setCancelled(true); event.setCancelled(true);
event.getPlayer().sendMessage(plugin.getMessage("claim.no-place")); player.sendMessage(plugin.getMessage("claim.no-place"));
}
}
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
Player player = event.getPlayer();
UUID playerId = player.getUniqueId();
Claim currentClaim = plugin.getClaim(event.getTo());
// Prüfe, ob sich der Claim-Status geändert hat
Claim previousClaim = lastClaim.getOrDefault(playerId, null);
if (currentClaim != previousClaim) {
if (currentClaim != null) {
// Spieler betritt einen Claim
String ownerName = plugin.getServer().getOfflinePlayer(currentClaim.getOwner()).getName();
if (ownerName == null) {
ownerName = currentClaim.getOwner().toString(); // Fallback auf UUID
}
player.sendMessage(plugin.getMessage("claim.enter").replace("%owner%", ownerName));
} else if (previousClaim != null) {
// Spieler verlässt einen Claim
String ownerName = plugin.getServer().getOfflinePlayer(previousClaim.getOwner()).getName();
if (ownerName == null) {
ownerName = previousClaim.getOwner().toString(); // Fallback auf UUID
}
player.sendMessage(plugin.getMessage("claim.leave").replace("%owner%", ownerName));
}
lastClaim.put(playerId, currentClaim);
} }
} }
} }

View File

@@ -26,10 +26,12 @@ public class NewbieProtectionListener implements Listener {
private final SurvivalPlus plugin; private final SurvivalPlus plugin;
private final boolean enabled; private final boolean enabled;
private final int durationMinutes; private final int durationMinutes;
private final int COOLDOWN_SECONDS = 60; // Abklingzeit für Nachrichten in Sekunden (1 Minute)
// Maps für Zeiten und BossBars // Maps für Zeiten, BossBars und Nachrichten-Abklingzeit
private final Map<UUID, Integer> remainingSeconds = new HashMap<>(); private final Map<UUID, Integer> remainingSeconds = new HashMap<>();
private final Map<UUID, BossBar> bossBars = new HashMap<>(); private final Map<UUID, BossBar> bossBars = new HashMap<>();
private final Map<UUID, Long> messageCooldowns = new HashMap<>();
// YAML Datei // YAML Datei
private File dataFile; private File dataFile;
@@ -89,14 +91,29 @@ public class NewbieProtectionListener implements Listener {
if (!(event.getEntity() instanceof Player)) return; if (!(event.getEntity() instanceof Player)) return;
Player victim = (Player) event.getEntity(); Player victim = (Player) event.getEntity();
UUID vid = victim.getUniqueId(); UUID victimId = victim.getUniqueId();
Integer timeLeft = remainingSeconds.get(vid); Integer timeLeft = remainingSeconds.get(victimId);
if (timeLeft != null && timeLeft > 0) { if (timeLeft != null && timeLeft > 0) {
event.setCancelled(true); event.setCancelled(true);
victim.sendMessage(ChatColor.GREEN + "Du bist noch im Neulingsschutz!");
// Prüfe Abklingzeit für Opfer
long currentTime = System.currentTimeMillis() / 1000;
long lastMessageTimeVictim = messageCooldowns.getOrDefault(victimId, 0L);
if (currentTime >= lastMessageTimeVictim + COOLDOWN_SECONDS) {
victim.sendMessage(ChatColor.GREEN + "Du bist noch im Neulingsschutz!");
messageCooldowns.put(victimId, currentTime);
}
// Prüfe Abklingzeit für Angreifer, falls es ein Spieler ist
if (event.getDamager() instanceof Player) { if (event.getDamager() instanceof Player) {
((Player) event.getDamager()).sendMessage(ChatColor.RED + victim.getName() + " ist noch geschützt!"); Player damager = (Player) event.getDamager();
UUID damagerId = damager.getUniqueId();
long lastMessageTimeDamager = messageCooldowns.getOrDefault(damagerId, 0L);
if (currentTime >= lastMessageTimeDamager + COOLDOWN_SECONDS) {
damager.sendMessage(ChatColor.RED + victim.getName() + " ist noch geschützt!");
messageCooldowns.put(damagerId, currentTime);
}
} }
} }
} }
@@ -158,7 +175,6 @@ public class NewbieProtectionListener implements Listener {
} }
} }
// WICHTIG: Public gemacht, damit von SurvivalPlus.java aufrufbar
public void saveData() { public void saveData() {
if (dataConfig == null) return; if (dataConfig == null) return;
for (Map.Entry<UUID, Integer> entry : remainingSeconds.entrySet()) { for (Map.Entry<UUID, Integer> entry : remainingSeconds.entrySet()) {
@@ -176,4 +192,4 @@ public class NewbieProtectionListener implements Listener {
int sec = totalSec % 60; int sec = totalSec % 60;
return String.format("%02d:%02d", min, sec); return String.format("%02d:%02d", min, sec);
} }
} }

View File

@@ -0,0 +1,28 @@
package de.viper.survivalplus.util;
import de.viper.survivalplus.SurvivalPlus;
import java.util.Arrays;
import java.util.List;
public class BannerManager {
private final SurvivalPlus plugin;
public BannerManager(SurvivalPlus plugin) {
this.plugin = plugin;
}
public void displayConsoleBanner() {
String version = plugin.getDescription().getVersion();
List<String> banner = Arrays.asList(
"******************************",
"* SurvivalPlus " + version + " *",
"* *",
"* M_Viper *",
"******************************"
);
for (String line : banner) {
plugin.getLogger().info(line);
}
}
}

View File

@@ -1,3 +1,9 @@
# Version (Nicht Ändern!)
version: 1.0.9
# Debug-Option
debug-logging: false
# Neulings Schutz # Neulings Schutz
newbie-protection: newbie-protection:
enabled: true enabled: true

View File

@@ -403,24 +403,30 @@ inventory:
player-only: "§cDieser Befehl ist nur für Spieler!" player-only: "§cDieser Befehl ist nur für Spieler!"
claim: claim:
points-not-set: "&cDu musst zuerst zwei Punkte markieren! Verwende /claim mark <1|2>." points-not-set: "&cDu musst zuerst zwei Punkte markieren! Verwende /claim mark <1|2>."
different-worlds: "&cDie markierten Punkte müssen in derselben Welt liegen!" different-worlds: "&cDie markierten Punkte müssen in derselben Welt liegen!"
too-large: "&cDer Bereich ist zu groß! Maximal erlaubt: %max% Blöcke²." too-large: "&cDer Bereich ist zu groß! Maximal erlaubt: %max% Blöcke²."
overlap: "&cDieser Bereich überschneidet sich mit einem bestehenden Claim!" overlap: "&cDieser Bereich überschneidet sich mit einem bestehenden Claim!"
max-reached: "&cDu hast das Maximum von %max% Claims erreicht!" max-reached: "&cDu hast das Maximum von %max% Claims erreicht!"
success: "&aBereich beansprucht! (%count%/%max%)" success: "&aBereich beansprucht! (%count%/%max%)"
unclaimed: "&aBereich freigegeben!" unclaimed: "&aBereich freigegeben!"
not-owner: "&cDies ist nicht dein Claim!" not-owner: "&cDies ist nicht dein Claim!"
point1-set: "&aPunkt 1 gesetzt bei x=%x%, z=%z%." point1-set: "&aPunkt 1 gesetzt bei x=%x%, z=%z%."
point2-set: "&aPunkt 2 gesetzt bei x=%x%, z=%z%." point2-set: "&aPunkt 2 gesetzt bei x=%x%, z=%z%."
trusted: "&a%player% ist jetzt in diesem Claim vertraut!" trusted: "&a%player% ist jetzt in diesem Claim vertraut!"
untrusted: "&a%player% ist in diesem Claim nicht mehr vertraut!" untrusted: "&a%player% ist in diesem Claim nicht mehr vertraut!"
no-break: "&cDu kannst in diesem beanspruchten Bereich keine Blöcke abbauen!" no-break: "&cDu kannst in diesem beanspruchten Bereich keine Blöcke abbauen!"
no-place: "&cDu kannst in diesem beanspruchten Bereich keine Blöcke platzieren!" no-place: "&cDu kannst in diesem beanspruchten Bereich keine Blöcke platzieren!"
op-unclaimed: "&a%count% Claims von %player% wurden entfernt!" op-unclaimed: "&a%count% Claims von %player% wurden entfernt!"
no-claims-found: "&cKeine Claims für %player% gefunden!" no-claims-found: "&cKeine Claims für %player% gefunden!"
no-claim-at-location: "&cKein Claim an dieser Position!" no-claim-at-location: "&cKein Claim an dieser Position!"
info: "&eClaim-Info:\n&7Besitzer: &e%owner%\n&7Welt: &e%world%\n&7Koordinaten: &eX1: %x1%, Z1: %z1% bis X2: %x2%, Z2: %z2%" info:
- "&eClaim-Info:"
- "&7Besitzer: &e%owner%"
- "&7Welt: &e%world%"
- "&7Koordinaten: &eX1: %x1%, Z1: %z1% bis X2: %x2%, Z2: %z2%"
enter: "&aDu hast das Gebiet von %owner% betreten."
leave: "&eDu hast das Gebiet von %owner% verlassen."
force-survival: force-survival:
join-message: "§aDu wurdest in den Survivalmodus gesetzt!" join-message: "§aDu wurdest in den Survivalmodus gesetzt!"

View File

@@ -1,5 +1,6 @@
name: SurvivalPlus name: SurvivalPlus
version: 1.0.8 version: 1.0.9
main: de.viper.survivalplus.SurvivalPlus main: de.viper.survivalplus.SurvivalPlus
api-version: 1.21 api-version: 1.21