Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 652372e191 | |||
| 2c8eb8fb70 | |||
| bff9b78408 | |||
| 5f8e0d3c05 | |||
| 201d1855fc | |||
| e19de4b638 | |||
| 90d66b6e96 |
@@ -94,4 +94,6 @@ visuals:
|
||||
|
||||
---
|
||||
|
||||
**Viper Plugins** © 2026 — Effiziente Systemlösungen für deinen Server.
|
||||
**Copyright © 2026 - M_Viper - Alle Rechte vorbehalten**
|
||||
|
||||
Die unbefugte Vervielfältigung, Verbreitung oder Weitergabe dieses Plugins ist strafbar und wird rechtlich verfolgt.
|
||||
2
pom.xml
2
pom.xml
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>de.mviper</groupId>
|
||||
<artifactId>Elevator</artifactId>
|
||||
<version>1.5</version>
|
||||
<version>1.8</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
|
||||
@@ -1,118 +1,283 @@
|
||||
package de.mviper.elevator;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class DatabaseManager {
|
||||
|
||||
// Maximaler Radius (in Blöcken, horizontal, gleiche Y-Ebene) für Auto-Gruppierung
|
||||
private static final int GROUP_SCAN_RADIUS = 4;
|
||||
|
||||
private File localFile;
|
||||
private FileConfiguration localConfig;
|
||||
|
||||
public DatabaseManager() { setupLocalFile(); }
|
||||
public DatabaseManager() {
|
||||
setupLocalFile();
|
||||
}
|
||||
|
||||
private void setupLocalFile() {
|
||||
localFile = new File(Elevator.getInstance().getDataFolder(), "elevators.yml");
|
||||
if (!localFile.exists()) {
|
||||
try {
|
||||
try {
|
||||
Elevator.getInstance().getDataFolder().mkdirs();
|
||||
localFile.createNewFile();
|
||||
} catch (IOException e) { e.printStackTrace(); }
|
||||
localFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
localConfig = YamlConfiguration.loadConfiguration(localFile);
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────
|
||||
// Basis-Operationen
|
||||
// ─────────────────────────────────────────────
|
||||
|
||||
public void addElevator(Location loc, UUID owner) {
|
||||
String key = locToKey(loc);
|
||||
localConfig.set(key + ".owner", owner.toString());
|
||||
localConfig.set(key + ".name", "Etage");
|
||||
localConfig.set(key + ".public", true);
|
||||
saveLocal();
|
||||
|
||||
// Debug-Ausgabe
|
||||
Elevator.getInstance().getLogger().info("Aufzug hinzugefügt: " + key + " | Public: true");
|
||||
|
||||
// Gruppe sofort zuweisen (Auto-Detect angrenzender Module)
|
||||
getOrAssignGroupId(loc);
|
||||
|
||||
if (Elevator.getInstance().isDebugMode()) {
|
||||
Elevator.getInstance().getLogger().info(
|
||||
"Aufzug registriert: " + key + " | Gruppe: " + getGroupId(loc));
|
||||
}
|
||||
}
|
||||
|
||||
public void removeElevator(Location loc) {
|
||||
localConfig.set(locToKey(loc), null);
|
||||
saveLocal();
|
||||
public void removeElevator(Location loc) {
|
||||
String key = locToKey(loc);
|
||||
String groupId = localConfig.getString(key + ".group");
|
||||
|
||||
localConfig.set(key, null);
|
||||
saveLocal();
|
||||
|
||||
// Gruppe aufräumen, wenn keine Mitglieder mehr
|
||||
if (groupId != null && getMembersOfGroup(groupId).isEmpty()) {
|
||||
localConfig.set("groups." + groupId, null);
|
||||
saveLocal();
|
||||
if (Elevator.getInstance().isDebugMode()) {
|
||||
Elevator.getInstance().getLogger().info("Gruppe " + groupId + " gelöscht (keine Mitglieder mehr).");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isElevator(Location loc) {
|
||||
return localConfig.contains(locToKey(loc));
|
||||
|
||||
public boolean isElevator(Location loc) {
|
||||
return localConfig.contains(locToKey(loc));
|
||||
}
|
||||
|
||||
public String getFloorCustomName(Location loc) {
|
||||
return localConfig.getString(locToKey(loc) + ".name", "Etage");
|
||||
|
||||
// ─────────────────────────────────────────────
|
||||
// Gruppen-System
|
||||
// ─────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Gibt die Gruppen-ID für ein Modul zurück.
|
||||
* Existiert noch keine, wird automatisch eine erstellt oder eine benachbarte übernommen.
|
||||
*/
|
||||
public String getOrAssignGroupId(Location loc) {
|
||||
String key = locToKey(loc);
|
||||
|
||||
// Existiert kein gültiger Aufzug → null
|
||||
if (!localConfig.contains(key)) return null;
|
||||
|
||||
// Gruppe schon gesetzt?
|
||||
if (localConfig.contains(key + ".group")) {
|
||||
return localConfig.getString(key + ".group");
|
||||
}
|
||||
|
||||
// Migration: ältere Einträge haben .name direkt gespeichert
|
||||
String oldName = localConfig.getString(key + ".name", null);
|
||||
|
||||
// Benachbartes Modul mit Gruppe suchen (gleiche Y-Ebene)
|
||||
String foundGroup = findAdjacentGroupId(loc);
|
||||
if (foundGroup != null) {
|
||||
localConfig.set(key + ".group", foundGroup);
|
||||
// Alten Namen übernehmen, falls Gruppe noch Default-Name hat
|
||||
if (oldName != null && !oldName.equals("Etage")
|
||||
&& "Etage".equals(localConfig.getString("groups." + foundGroup + ".name", "Etage"))) {
|
||||
localConfig.set("groups." + foundGroup + ".name", oldName);
|
||||
}
|
||||
localConfig.set(key + ".name", null); // Altes Feld entfernen
|
||||
saveLocal();
|
||||
return foundGroup;
|
||||
}
|
||||
|
||||
// Neue Gruppe erstellen
|
||||
String newGroupId = UUID.randomUUID().toString().substring(0, 8);
|
||||
String groupName = (oldName != null && !oldName.isEmpty()) ? oldName : "Etage";
|
||||
localConfig.set(key + ".group", newGroupId);
|
||||
localConfig.set("groups." + newGroupId + ".name", groupName);
|
||||
localConfig.set(key + ".name", null); // Altes Feld entfernen
|
||||
saveLocal();
|
||||
|
||||
if (Elevator.getInstance().isDebugMode()) {
|
||||
Elevator.getInstance().getLogger().info("Neue Gruppe erstellt: " + newGroupId + " | Name: " + groupName);
|
||||
}
|
||||
return newGroupId;
|
||||
}
|
||||
|
||||
public void setFloorName(Location loc, String name) {
|
||||
localConfig.set(locToKey(loc) + ".name", name);
|
||||
saveLocal();
|
||||
|
||||
/** Gibt die Gruppen-ID eines Moduls zurück (mit Lazy-Init). */
|
||||
public String getGroupId(Location loc) {
|
||||
return getOrAssignGroupId(loc);
|
||||
}
|
||||
|
||||
public UUID getOwner(Location loc) {
|
||||
|
||||
/**
|
||||
* Weist einem Modul manuell eine Gruppen-ID zu.
|
||||
* Wird vom /elevator group link Befehl genutzt.
|
||||
*/
|
||||
public void setGroupId(Location loc, String groupId) {
|
||||
String key = locToKey(loc);
|
||||
if (!localConfig.contains(key)) return;
|
||||
|
||||
localConfig.set(key + ".group", groupId);
|
||||
// Gruppe anlegen, falls noch nicht vorhanden
|
||||
if (!localConfig.contains("groups." + groupId + ".name")) {
|
||||
localConfig.set("groups." + groupId + ".name", "Etage");
|
||||
}
|
||||
saveLocal();
|
||||
}
|
||||
|
||||
/** Gibt den Anzeige-Namen der Gruppe zurück. */
|
||||
public String getGroupName(String groupId) {
|
||||
return localConfig.getString("groups." + groupId + ".name", "Etage");
|
||||
}
|
||||
|
||||
/** Setzt den Anzeige-Namen für eine Gruppe (benennt damit alle Mitglieder). */
|
||||
public void setGroupNameById(String groupId, String name) {
|
||||
localConfig.set("groups." + groupId + ".name", name);
|
||||
saveLocal();
|
||||
}
|
||||
|
||||
/** Alle Modul-Schlüssel (ohne "data." Prefix), die zur Gruppe gehören. */
|
||||
public List<String> getMembersOfGroup(String groupId) {
|
||||
List<String> members = new ArrayList<>();
|
||||
ConfigurationSection data = localConfig.getConfigurationSection("data");
|
||||
if (data == null) return members;
|
||||
for (String locKey : data.getKeys(false)) {
|
||||
if (groupId.equals(data.getString(locKey + ".group"))) {
|
||||
members.add(locKey);
|
||||
}
|
||||
}
|
||||
return members;
|
||||
}
|
||||
|
||||
/** Scannt benachbarte Module (horizontal, gleiche Y-Höhe) auf vorhandene Gruppen-IDs. */
|
||||
private String findAdjacentGroupId(Location loc) {
|
||||
for (int dx = -GROUP_SCAN_RADIUS; dx <= GROUP_SCAN_RADIUS; dx++) {
|
||||
for (int dz = -GROUP_SCAN_RADIUS; dz <= GROUP_SCAN_RADIUS; dz++) {
|
||||
if (dx == 0 && dz == 0) continue;
|
||||
Location adj = loc.clone().add(dx, 0, dz);
|
||||
String adjKey = locToKey(adj);
|
||||
if (localConfig.contains(adjKey) && localConfig.contains(adjKey + ".group")) {
|
||||
return localConfig.getString(adjKey + ".group");
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────
|
||||
// Namen (jetzt Gruppen-basiert)
|
||||
// ─────────────────────────────────────────────
|
||||
|
||||
/** Gibt den Etagen-Namen zurück — immer aus der Gruppe. */
|
||||
public String getFloorCustomName(Location loc) {
|
||||
String groupId = getGroupId(loc);
|
||||
if (groupId == null) return "Etage";
|
||||
return getGroupName(groupId);
|
||||
}
|
||||
|
||||
/** Setzt den Etagen-Namen für die gesamte Gruppe dieses Moduls. */
|
||||
public void setFloorName(Location loc, String name) {
|
||||
String groupId = getGroupId(loc);
|
||||
if (groupId == null) return;
|
||||
setGroupNameById(groupId, name);
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────
|
||||
// Besitzer & Sichtbarkeit
|
||||
// ─────────────────────────────────────────────
|
||||
|
||||
public UUID getOwner(Location loc) {
|
||||
String s = localConfig.getString(locToKey(loc) + ".owner");
|
||||
return s != null ? UUID.fromString(s) : UUID.randomUUID();
|
||||
return s != null ? UUID.fromString(s) : UUID.randomUUID();
|
||||
}
|
||||
|
||||
|
||||
public boolean isPublic(Location loc) {
|
||||
String key = locToKey(loc);
|
||||
String fullKey = key + ".public";
|
||||
|
||||
// Prüfe zuerst, ob der Aufzug überhaupt existiert
|
||||
|
||||
if (!localConfig.contains(key)) {
|
||||
Elevator.getInstance().getLogger().warning("isPublic: Aufzug existiert nicht: " + key);
|
||||
if (Elevator.getInstance().isDebugMode()) {
|
||||
Elevator.getInstance().getLogger().warning("isPublic: Aufzug existiert nicht: " + key);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Wenn der public-Schlüssel nicht existiert, setze ihn auf true (Standard)
|
||||
if (!localConfig.contains(fullKey)) {
|
||||
Elevator.getInstance().getLogger().info("isPublic: Schlüssel nicht gefunden, setze auf true: " + fullKey);
|
||||
localConfig.set(fullKey, true);
|
||||
saveLocal();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
boolean value = localConfig.getBoolean(fullKey, true);
|
||||
Elevator.getInstance().getLogger().info("isPublic: " + fullKey + " = " + value);
|
||||
if (Elevator.getInstance().isDebugMode()) {
|
||||
Elevator.getInstance().getLogger().info("isPublic: " + fullKey + " = " + value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
public void setPublic(Location loc, boolean status) {
|
||||
String key = locToKey(loc);
|
||||
String fullKey = key + ".public";
|
||||
|
||||
// Prüfe, ob der Aufzug existiert
|
||||
|
||||
if (!localConfig.contains(key)) {
|
||||
Elevator.getInstance().getLogger().warning("setPublic: Aufzug existiert nicht: " + key);
|
||||
if (Elevator.getInstance().isDebugMode()) {
|
||||
Elevator.getInstance().getLogger().warning("setPublic: Aufzug existiert nicht: " + key);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
localConfig.set(fullKey, status);
|
||||
saveLocal();
|
||||
|
||||
// Sofort nochmal laden um zu verifizieren
|
||||
|
||||
// Neu laden und verifizieren
|
||||
localConfig = YamlConfiguration.loadConfiguration(localFile);
|
||||
boolean verification = localConfig.getBoolean(fullKey, true);
|
||||
|
||||
Elevator.getInstance().getLogger().info("setPublic: " + fullKey + " auf " + status + " gesetzt (Verifiziert: " + verification + ")");
|
||||
|
||||
if (Elevator.getInstance().isDebugMode()) {
|
||||
Elevator.getInstance().getLogger().info(
|
||||
"setPublic: " + fullKey + " auf " + status + " gesetzt (Verifiziert: " + verification + ")");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ─────────────────────────────────────────────
|
||||
// Hilfsmethoden
|
||||
// ─────────────────────────────────────────────
|
||||
|
||||
private String locToKey(Location l) {
|
||||
// Wichtig: Nutze getBlockX/Y/Z für konsistente Koordinaten
|
||||
String key = "data." + l.getWorld().getName() + "_" + l.getBlockX() + "_" + l.getBlockY() + "_" + l.getBlockZ();
|
||||
return key;
|
||||
return "data." + l.getWorld().getName()
|
||||
+ "_" + l.getBlockX()
|
||||
+ "_" + l.getBlockY()
|
||||
+ "_" + l.getBlockZ();
|
||||
}
|
||||
|
||||
private void saveLocal() {
|
||||
try {
|
||||
|
||||
private void saveLocal() {
|
||||
try {
|
||||
localConfig.save(localFile);
|
||||
Elevator.getInstance().getLogger().info("Datenbank gespeichert: " + localFile.getName());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (Elevator.getInstance().isDebugMode()) {
|
||||
Elevator.getInstance().getLogger().info("Datenbank gespeichert: " + localFile.getName());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ public class Elevator extends JavaPlugin implements Listener {
|
||||
private DatabaseManager databaseManager;
|
||||
private HologramManager hologramManager;
|
||||
private String latestVersionFound;
|
||||
private boolean debugMode;
|
||||
|
||||
private final int RESOURCE_ID = 132220;
|
||||
private final String releaseUrl = "https://www.spigotmc.org/resources/" + RESOURCE_ID;
|
||||
@@ -34,7 +35,8 @@ public class Elevator extends JavaPlugin implements Listener {
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
saveDefaultConfig();
|
||||
|
||||
// Debug-Modus aus config laden
|
||||
this.debugMode = getConfig().getBoolean("settings.debug", false);
|
||||
this.databaseManager = new DatabaseManager();
|
||||
this.hologramManager = new HologramManager();
|
||||
hologramManager.purgeAllHolograms();
|
||||
@@ -43,6 +45,7 @@ public class Elevator extends JavaPlugin implements Listener {
|
||||
getServer().getPluginManager().registerEvents(new ElevatorListener(), this);
|
||||
getServer().getPluginManager().registerEvents(this, this);
|
||||
getCommand("elevator").setExecutor(new ElevatorCommand());
|
||||
getCommand("elevator").setTabCompleter(new ElevatorTabCompleter());
|
||||
|
||||
// Rezept laden
|
||||
registerElevatorRecipe();
|
||||
@@ -152,6 +155,7 @@ public class Elevator extends JavaPlugin implements Listener {
|
||||
public static Elevator getInstance() { return instance; }
|
||||
public DatabaseManager getDatabaseManager() { return databaseManager; }
|
||||
public HologramManager getHologramManager() { return hologramManager; }
|
||||
public boolean isDebugMode() { return debugMode; }
|
||||
|
||||
public ItemStack createElevatorModuleItem() {
|
||||
ItemStack item = new ItemStack(Material.DAYLIGHT_DETECTOR);
|
||||
|
||||
@@ -9,6 +9,8 @@ import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ElevatorCommand implements CommandExecutor {
|
||||
|
||||
@Override
|
||||
@@ -17,32 +19,7 @@ public class ElevatorCommand implements CommandExecutor {
|
||||
Player p = (Player) sender;
|
||||
|
||||
DatabaseManager db = Elevator.getInstance().getDatabaseManager();
|
||||
Block moduleBlock = null;
|
||||
|
||||
// VERBESSERTE ERKENNUNG: Prüfe direkt unter den Füßen und erweiterten Radius
|
||||
Location pLoc = p.getLocation();
|
||||
|
||||
// Erst direkt unter dem Spieler prüfen (häufigster Fall)
|
||||
Block directBelow = pLoc.clone().subtract(0, 1, 0).getBlock();
|
||||
if (directBelow.getType() == Material.DAYLIGHT_DETECTOR && db.isElevator(directBelow.getLocation())) {
|
||||
moduleBlock = directBelow;
|
||||
}
|
||||
|
||||
// Wenn nicht gefunden, erweiterte Suche
|
||||
if (moduleBlock == null) {
|
||||
outerLoop:
|
||||
for (double x = -1.0; x <= 1.0; x += 0.5) {
|
||||
for (double z = -1.0; z <= 1.0; z += 0.5) {
|
||||
for (double y = -2.0; y <= 0.5; y += 0.5) {
|
||||
Block check = pLoc.clone().add(x, y, z).getBlock();
|
||||
if (check.getType() == Material.DAYLIGHT_DETECTOR && db.isElevator(check.getLocation())) {
|
||||
moduleBlock = check;
|
||||
break outerLoop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Block moduleBlock = findNearbyModule(p, db);
|
||||
|
||||
if (moduleBlock == null) {
|
||||
p.sendMessage("§8[§bElevator§8] §cKein Aufzug-Modul in deiner Nähe gefunden!");
|
||||
@@ -50,66 +27,182 @@ public class ElevatorCommand implements CommandExecutor {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Debug-Ausgabe
|
||||
Location modLoc = moduleBlock.getLocation();
|
||||
Elevator.getInstance().getLogger().info("Command: Modul gefunden bei X:" + modLoc.getBlockX() + " Y:" + modLoc.getBlockY() + " Z:" + modLoc.getBlockZ());
|
||||
|
||||
// Berechtigungs-Check (Besitzer oder Admin)
|
||||
if (!db.getOwner(moduleBlock.getLocation()).equals(p.getUniqueId()) && !p.hasPermission("elevator.admin")) {
|
||||
if (Elevator.getInstance().isDebugMode()) {
|
||||
Elevator.getInstance().getLogger().info(
|
||||
"Command: Modul gefunden bei X:" + modLoc.getBlockX()
|
||||
+ " Y:" + modLoc.getBlockY()
|
||||
+ " Z:" + modLoc.getBlockZ());
|
||||
}
|
||||
|
||||
// Besitzer-Check (Besitzer oder Admin)
|
||||
if (!db.getOwner(modLoc).equals(p.getUniqueId()) && !p.hasPermission("elevator.admin")) {
|
||||
p.sendMessage("§8[§bElevator§8] §cDies ist nicht dein Aufzug!");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Befehl: /elevator name <Text>
|
||||
// ── /elevator name <Text> ──────────────────────────────────────────
|
||||
if (args.length >= 2 && args[0].equalsIgnoreCase("name")) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 1; i < args.length; i++) sb.append(args[i]).append(" ");
|
||||
String newName = ChatColor.translateAlternateColorCodes('&', sb.toString().trim());
|
||||
|
||||
db.setFloorName(moduleBlock.getLocation(), newName);
|
||||
p.sendMessage("§8[§bElevator§8] §aEtage benannt: " + newName);
|
||||
|
||||
db.setFloorName(modLoc, newName);
|
||||
|
||||
String groupId = db.getGroupId(modLoc);
|
||||
List<String> members = db.getMembersOfGroup(groupId);
|
||||
|
||||
p.sendMessage("§8[§bElevator§8] §aEtage benannt: §f" + newName);
|
||||
if (members.size() > 1) {
|
||||
p.sendMessage("§7(Name für §e" + members.size() + " §7verknüpfte Module gesetzt)");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Befehle: /elevator private | public
|
||||
if (args.length == 1) {
|
||||
Location modLocation = moduleBlock.getLocation();
|
||||
|
||||
if (args[0].equalsIgnoreCase("private")) {
|
||||
db.setPublic(modLocation, false);
|
||||
p.sendMessage("§8[§bElevator§8] §7Status: §cPrivat");
|
||||
p.sendMessage("§7Nur du kannst diesen Aufzug nun benutzen.");
|
||||
|
||||
// Verifizierung
|
||||
boolean currentStatus = db.isPublic(modLocation);
|
||||
p.sendMessage("§8[Debug] Aktueller Status nach Änderung: " + (currentStatus ? "§aÖffentlich" : "§cPrivat"));
|
||||
// ── /elevator group ────────────────────────────────────────────────
|
||||
if (args.length >= 1 && args[0].equalsIgnoreCase("group")) {
|
||||
|
||||
// /elevator group info
|
||||
if (args.length == 1 || args[1].equalsIgnoreCase("info")) {
|
||||
String groupId = db.getGroupId(modLoc);
|
||||
List<String> members = db.getMembersOfGroup(groupId);
|
||||
p.sendMessage("§b--- Gruppen-Info ---");
|
||||
p.sendMessage("§7Gruppen-ID: §e" + groupId);
|
||||
p.sendMessage("§7Gruppen-Name: §f" + db.getGroupName(groupId));
|
||||
p.sendMessage("§7Module in Gruppe: §e" + members.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args[0].equalsIgnoreCase("public")) {
|
||||
db.setPublic(modLocation, true);
|
||||
p.sendMessage("§8[§bElevator§8] §7Status: §aÖffentlich");
|
||||
p.sendMessage("§7Alle Spieler können diesen Aufzug nun benutzen.");
|
||||
|
||||
// Verifizierung
|
||||
boolean currentStatus = db.isPublic(modLocation);
|
||||
p.sendMessage("§8[Debug] Aktueller Status nach Änderung: " + (currentStatus ? "§aÖffentlich" : "§cPrivat"));
|
||||
|
||||
// /elevator group scan
|
||||
// Scannt benachbarte Module neu und verknüpft sie in eine Gruppe
|
||||
if (args[1].equalsIgnoreCase("scan")) {
|
||||
String myGroup = db.getGroupId(modLoc);
|
||||
int linked = 0;
|
||||
|
||||
// Radius 4 horizontal, gleiche Y-Ebene
|
||||
for (int dx = -4; dx <= 4; dx++) {
|
||||
for (int dz = -4; dz <= 4; dz++) {
|
||||
if (dx == 0 && dz == 0) continue;
|
||||
Location adj = modLoc.clone().add(dx, 0, dz);
|
||||
if (db.isElevator(adj)) {
|
||||
String adjGroup = db.getGroupId(adj);
|
||||
if (!adjGroup.equals(myGroup)) {
|
||||
db.setGroupId(adj, myGroup);
|
||||
linked++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p.sendMessage("§8[§bElevator§8] §aScan abgeschlossen.");
|
||||
p.sendMessage("§7" + linked + " Modul(e) mit dieser Gruppe verknüpft.");
|
||||
p.sendMessage("§7Gruppe §e" + myGroup + "§7 hat jetzt §e"
|
||||
+ db.getMembersOfGroup(myGroup).size() + "§7 Mitglieder.");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args[0].equalsIgnoreCase("status")) {
|
||||
boolean isPublic = db.isPublic(modLocation);
|
||||
p.sendMessage("§8[§bElevator§8] §7Aktueller Status: " + (isPublic ? "§aÖffentlich" : "§cPrivat"));
|
||||
|
||||
// /elevator group unlink
|
||||
// Trennt dieses Modul aus der Gruppe heraus (eigene Gruppe)
|
||||
if (args[1].equalsIgnoreCase("unlink")) {
|
||||
String oldGroup = db.getGroupId(modLoc);
|
||||
String oldName = db.getGroupName(oldGroup);
|
||||
|
||||
// Neue solo-Gruppe erstellen
|
||||
String newGroupId = java.util.UUID.randomUUID().toString().substring(0, 8);
|
||||
db.setGroupId(modLoc, newGroupId);
|
||||
db.setGroupNameById(newGroupId, oldName); // Namen behalten
|
||||
|
||||
p.sendMessage("§8[§bElevator§8] §eModul aus Gruppe getrennt.");
|
||||
p.sendMessage("§7Neue Gruppen-ID: §e" + newGroupId);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Unbekannter Unterbefehl → Hilfe
|
||||
sendGroupHelp(p);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Hilfe-Anzeige
|
||||
p.sendMessage("§b--- Elevator Hilfe ---");
|
||||
p.sendMessage("§e/elevator name <Text> §7- Namen der Etage ändern");
|
||||
p.sendMessage("§e/elevator private §7- Zugriff nur für dich");
|
||||
p.sendMessage("§e/elevator public §7- Zugriff für alle");
|
||||
p.sendMessage("§e/elevator status §7- Zeigt den aktuellen Status");
|
||||
// ── /elevator private ──────────────────────────────────────────────
|
||||
if (args.length == 1 && args[0].equalsIgnoreCase("private")) {
|
||||
db.setPublic(modLoc, false);
|
||||
p.sendMessage("§8[§bElevator§8] §7Status: §cPrivat");
|
||||
p.sendMessage("§7Nur du kannst diesen Aufzug nun benutzen.");
|
||||
if (Elevator.getInstance().isDebugMode()) {
|
||||
p.sendMessage("§8[Debug] Status nach Änderung: " + (db.isPublic(modLoc) ? "§aÖffentlich" : "§cPrivat"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ── /elevator public ───────────────────────────────────────────────
|
||||
if (args.length == 1 && args[0].equalsIgnoreCase("public")) {
|
||||
db.setPublic(modLoc, true);
|
||||
p.sendMessage("§8[§bElevator§8] §7Status: §aÖffentlich");
|
||||
p.sendMessage("§7Alle Spieler können diesen Aufzug nun benutzen.");
|
||||
if (Elevator.getInstance().isDebugMode()) {
|
||||
p.sendMessage("§8[Debug] Status nach Änderung: " + (db.isPublic(modLoc) ? "§aÖffentlich" : "§cPrivat"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ── /elevator status ───────────────────────────────────────────────
|
||||
if (args.length == 1 && args[0].equalsIgnoreCase("status")) {
|
||||
boolean isPublic = db.isPublic(modLoc);
|
||||
String groupId = db.getGroupId(modLoc);
|
||||
p.sendMessage("§b--- Aufzug-Status ---");
|
||||
p.sendMessage("§7Sichtbarkeit: " + (isPublic ? "§aÖffentlich" : "§cPrivat"));
|
||||
p.sendMessage("§7Etagen-Name: §f" + db.getGroupName(groupId));
|
||||
p.sendMessage("§7Gruppe: §e" + groupId
|
||||
+ " §7(§e" + db.getMembersOfGroup(groupId).size() + " §7Module)");
|
||||
return true;
|
||||
}
|
||||
|
||||
// ── Hilfe-Anzeige ──────────────────────────────────────────────────
|
||||
sendHelp(p);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
// Modul-Suche (identisch mit alter Logik)
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
private Block findNearbyModule(Player p, DatabaseManager db) {
|
||||
Location pLoc = p.getLocation();
|
||||
|
||||
// 1. Direkt unter den Füßen
|
||||
Block directBelow = pLoc.clone().subtract(0, 1, 0).getBlock();
|
||||
if (directBelow.getType() == Material.DAYLIGHT_DETECTOR
|
||||
&& db.isElevator(directBelow.getLocation())) {
|
||||
return directBelow;
|
||||
}
|
||||
|
||||
// 2. Erweiterter Radius
|
||||
for (double x = -1.0; x <= 1.0; x += 0.5) {
|
||||
for (double z = -1.0; z <= 1.0; z += 0.5) {
|
||||
for (double y = -2.0; y <= 0.5; y += 0.5) {
|
||||
Block check = pLoc.clone().add(x, y, z).getBlock();
|
||||
if (check.getType() == Material.DAYLIGHT_DETECTOR
|
||||
&& db.isElevator(check.getLocation())) {
|
||||
return check;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void sendHelp(Player p) {
|
||||
p.sendMessage("§b--- Elevator Hilfe ---");
|
||||
p.sendMessage("§e/elevator name <Text> §7- Etagen-Name setzen (für alle Module der Gruppe)");
|
||||
p.sendMessage("§e/elevator private §7- Zugriff nur für dich");
|
||||
p.sendMessage("§e/elevator public §7- Zugriff für alle");
|
||||
p.sendMessage("§e/elevator status §7- Aktuellen Status anzeigen");
|
||||
p.sendMessage("§e/elevator group §7- Gruppen-Info & Verwaltung");
|
||||
}
|
||||
|
||||
private void sendGroupHelp(Player p) {
|
||||
p.sendMessage("§b--- Gruppen-Befehle ---");
|
||||
p.sendMessage("§e/elevator group §7- Gruppen-Info anzeigen");
|
||||
p.sendMessage("§e/elevator group scan §7- Benachbarte Module automatisch verknüpfen");
|
||||
p.sendMessage("§e/elevator group unlink §7- Dieses Modul aus der Gruppe lösen");
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ public class ElevatorListener implements Listener {
|
||||
"http://textures.minecraft.net/texture/be8440e9d54ec7630b3e387f84e19e15f0b09d438a6bd784305df5d7608e6903";
|
||||
|
||||
private final Map<UUID, Long> cooldowns = new HashMap<>();
|
||||
private final Map<UUID, Long> deniedMessageCooldown = new HashMap<>(); // NEU: Für "Privat"-Meldungen
|
||||
private final Map<UUID, Long> deniedMessageCooldown = new HashMap<>();
|
||||
|
||||
|
||||
@EventHandler
|
||||
@@ -54,19 +54,20 @@ public class ElevatorListener implements Listener {
|
||||
boolean isPublic = db.isPublic(elevatorLoc);
|
||||
boolean isOwner = db.getOwner(elevatorLoc).equals(player.getUniqueId());
|
||||
boolean isAdmin = player.hasPermission("elevator.admin");
|
||||
|
||||
// Debug-Ausgabe
|
||||
Elevator.getInstance().getLogger().info("Spieler " + player.getName() + " interagiert mit Aufzug:");
|
||||
Elevator.getInstance().getLogger().info(" -> Public: " + isPublic);
|
||||
Elevator.getInstance().getLogger().info(" -> IsOwner: " + isOwner);
|
||||
Elevator.getInstance().getLogger().info(" -> IsAdmin: " + isAdmin);
|
||||
|
||||
|
||||
if (Elevator.getInstance().isDebugMode()) {
|
||||
Elevator.getInstance().getLogger().info("Spieler " + player.getName() + " interagiert mit Aufzug:");
|
||||
Elevator.getInstance().getLogger().info(" -> Public: " + isPublic);
|
||||
Elevator.getInstance().getLogger().info(" -> IsOwner: " + isOwner);
|
||||
Elevator.getInstance().getLogger().info(" -> IsAdmin: " + isAdmin);
|
||||
}
|
||||
|
||||
if (!isPublic && !isOwner && !isAdmin) {
|
||||
player.sendMessage("§8[§bElevator§8] §cDieser Aufzug ist privat!");
|
||||
e.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
e.setCancelled(true);
|
||||
openGUI(player, elevatorLoc.getBlock());
|
||||
}
|
||||
@@ -142,13 +143,12 @@ public class ElevatorListener implements Listener {
|
||||
String floorLabel = (i == 0) ? "Erdgeschoss" : "Etage " + i;
|
||||
meta.setDisplayName((isCurrent ? "§a● " : "§b○ ") + "§l" + floorLabel);
|
||||
|
||||
// Lore ohne sichtbare Koordinaten, aber mit versteckter ID am Ende
|
||||
String customName = db.getFloorCustomName(f.getLocation());
|
||||
meta.setLore(Arrays.asList(
|
||||
"§7Name: §f" + (customName != null ? customName : floorLabel),
|
||||
"",
|
||||
isCurrent ? "§7(Diese Etage)" : "§e➤ Klicken zum Reisen",
|
||||
"§0HIDDEN:" + f.getY() // Versteckte Zeile (Schwarz auf Schwarz/Unsichtbar)
|
||||
"§0HIDDEN:" + f.getY()
|
||||
));
|
||||
|
||||
item.setItemMeta(meta);
|
||||
@@ -170,11 +170,9 @@ public class ElevatorListener implements Listener {
|
||||
|
||||
try {
|
||||
List<String> lore = e.getCurrentItem().getItemMeta().getLore();
|
||||
// Die versteckte Koordinate steht in der letzten Zeile (Index 3)
|
||||
int targetY = Integer.parseInt(lore.get(3).replace("§0HIDDEN:", ""));
|
||||
p.closeInventory();
|
||||
|
||||
// Prüfe grob, ob der Spieler auf dem Modul steht
|
||||
Block module = findModuleUnderPlayer(p);
|
||||
|
||||
if (module != null) {
|
||||
@@ -219,21 +217,29 @@ public class ElevatorListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onJump(PlayerMoveEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
|
||||
// Nur bei echter Aufwärtsbewegung
|
||||
if (e.getTo().getY() <= e.getFrom().getY()) return;
|
||||
|
||||
// Cooldown prüfen
|
||||
if (cooldowns.containsKey(p.getUniqueId()) && System.currentTimeMillis() - cooldowns.get(p.getUniqueId()) < 300) return;
|
||||
|
||||
Block b = findModuleUnderPlayer(p);
|
||||
if (b != null) {
|
||||
// Prüfe Berechtigung
|
||||
if (!hasPermissionToUse(p, b)) {
|
||||
sendDeniedMessage(p);
|
||||
return;
|
||||
}
|
||||
|
||||
cooldowns.put(p.getUniqueId(), System.currentTimeMillis());
|
||||
handleQuickMove(p, 1);
|
||||
if (b == null) return;
|
||||
|
||||
// FIX: Prüfe, ob der Spieler in FROM wirklich AUF dem Elevator stand.
|
||||
// Steht er korrekt drauf: FROM.Y ≈ elevator.getY() + 1.0
|
||||
// Läuft er von einer Halbstufe drüber: FROM.Y ≈ elevator.getY() + 0.5
|
||||
// → Der Schritt von der Halbstufe wird dadurch zuverlässig ignoriert.
|
||||
double expectedStandingY = b.getY() + 1.0;
|
||||
if (e.getFrom().getY() < expectedStandingY - 0.1) return;
|
||||
|
||||
if (!hasPermissionToUse(p, b)) {
|
||||
sendDeniedMessage(p);
|
||||
return;
|
||||
}
|
||||
cooldowns.put(p.getUniqueId(), System.currentTimeMillis());
|
||||
handleQuickMove(p, 1);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
@@ -245,22 +251,28 @@ public class ElevatorListener implements Listener {
|
||||
|
||||
Block b = findModuleUnderPlayer(p);
|
||||
if (b != null) {
|
||||
// Prüfe Berechtigung
|
||||
if (!hasPermissionToUse(p, b)) {
|
||||
sendDeniedMessage(p);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
cooldowns.put(p.getUniqueId(), System.currentTimeMillis());
|
||||
handleQuickMove(p, -1);
|
||||
}
|
||||
}
|
||||
|
||||
// Hilfsmethode für grobe Erkennung (überall im Listener genutzt)
|
||||
// Prüft das Modul unter dem Spieler (aktuelle Position)
|
||||
private Block findModuleUnderPlayer(Player p) {
|
||||
return findModuleUnderLocation(p.getLocation());
|
||||
}
|
||||
|
||||
/**
|
||||
* FIX: Neue Hilfsmethode, die eine beliebige Location prüft.
|
||||
* Wird in onJump für die FROM-Position genutzt, um Halbstufen-Schritte
|
||||
* von echten Sprüngen zu unterscheiden.
|
||||
*/
|
||||
private Block findModuleUnderLocation(Location l) {
|
||||
DatabaseManager db = Elevator.getInstance().getDatabaseManager();
|
||||
Location l = p.getLocation();
|
||||
// Check Fußblock und Block darunter
|
||||
Block feet = l.getBlock();
|
||||
if (feet.getType() == Material.DAYLIGHT_DETECTOR && db.isElevator(feet.getLocation())) return feet;
|
||||
Block below = feet.getRelative(0, -1, 0);
|
||||
@@ -272,31 +284,24 @@ public class ElevatorListener implements Listener {
|
||||
private boolean hasPermissionToUse(Player p, Block elevatorBlock) {
|
||||
DatabaseManager db = Elevator.getInstance().getDatabaseManager();
|
||||
Location loc = elevatorBlock.getLocation();
|
||||
|
||||
|
||||
boolean isPublic = db.isPublic(loc);
|
||||
boolean isOwner = db.getOwner(loc).equals(p.getUniqueId());
|
||||
boolean isAdmin = p.hasPermission("elevator.admin");
|
||||
|
||||
// Debug
|
||||
Elevator.getInstance().getLogger().info("Permission-Check für " + p.getName() + ": Public=" + isPublic + ", Owner=" + isOwner + ", Admin=" + isAdmin);
|
||||
|
||||
|
||||
return isPublic || isOwner || isAdmin;
|
||||
}
|
||||
|
||||
|
||||
// Sendet "Privat"-Meldung nur, wenn Cooldown abgelaufen ist
|
||||
private void sendDeniedMessage(Player p) {
|
||||
UUID playerId = p.getUniqueId();
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
// Prüfe ob Cooldown aktiv ist (3 Sekunden)
|
||||
|
||||
if (deniedMessageCooldown.containsKey(playerId)) {
|
||||
long lastMessage = deniedMessageCooldown.get(playerId);
|
||||
if (now - lastMessage < 3000) {
|
||||
return; // Cooldown noch aktiv, keine Nachricht senden
|
||||
}
|
||||
if (now - lastMessage < 3000) return;
|
||||
}
|
||||
|
||||
// Sende Nachricht und setze Cooldown
|
||||
|
||||
p.sendMessage("§8[§bElevator§8] §cDieser Aufzug ist privat!");
|
||||
deniedMessageCooldown.put(playerId, now);
|
||||
}
|
||||
@@ -351,22 +356,13 @@ public class ElevatorListener implements Listener {
|
||||
|
||||
private void showVisualFeedback(Player p, Block targetBlock) {
|
||||
DatabaseManager db = Elevator.getInstance().getDatabaseManager();
|
||||
|
||||
// Hole benutzerdefinierten Namen
|
||||
|
||||
String customName = db.getFloorCustomName(targetBlock.getLocation());
|
||||
|
||||
// Falls ein Custom Name existiert, benutze diesen, sonst Fallback
|
||||
|
||||
if (customName != null && !customName.isEmpty() && !customName.equals("Etage")) {
|
||||
// Benutzer hat einen eigenen Namen vergeben
|
||||
p.sendTitle("", "§b" + customName, 5, 25, 5);
|
||||
|
||||
// Optional: Zeige auch ein Hologramm
|
||||
Elevator.getInstance().getHologramManager().spawnElevatorHolo(
|
||||
p.getLocation(),
|
||||
customName
|
||||
);
|
||||
Elevator.getInstance().getHologramManager().spawnElevatorHolo(p.getLocation(), customName);
|
||||
} else {
|
||||
// Standard: Etagen-Nummer anzeigen
|
||||
List<Block> floors = findFloorsInColumn(targetBlock);
|
||||
floors.sort(Comparator.comparingInt(Block::getY));
|
||||
|
||||
@@ -380,12 +376,7 @@ public class ElevatorListener implements Listener {
|
||||
|
||||
String label = (floorIndex <= 0) ? "Erdgeschoss" : "Etage " + floorIndex;
|
||||
p.sendTitle("", "§b" + label, 5, 25, 5);
|
||||
|
||||
// Optional: Zeige auch ein Hologramm
|
||||
Elevator.getInstance().getHologramManager().spawnElevatorHolo(
|
||||
p.getLocation(),
|
||||
label
|
||||
);
|
||||
Elevator.getInstance().getHologramManager().spawnElevatorHolo(p.getLocation(), label);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
129
src/main/java/de/mviper/elevator/ElevatorTabCompleter.java
Normal file
129
src/main/java/de/mviper/elevator/ElevatorTabCompleter.java
Normal file
@@ -0,0 +1,129 @@
|
||||
package de.mviper.elevator;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ElevatorTabCompleter implements TabCompleter {
|
||||
|
||||
// Alle Top-Level Unterbefehle
|
||||
private static final List<String> SUBCOMMANDS = Arrays.asList(
|
||||
"name", "group", "private", "public", "status"
|
||||
);
|
||||
|
||||
// Unterbefehle von /elevator group
|
||||
private static final List<String> GROUP_SUBCOMMANDS = Arrays.asList(
|
||||
"info", "scan", "unlink"
|
||||
);
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||
if (!(sender instanceof Player)) return Collections.emptyList();
|
||||
Player p = (Player) sender;
|
||||
|
||||
// args.length == 1 → Hauptbefehl-Vorschläge
|
||||
if (args.length == 1) {
|
||||
return filter(SUBCOMMANDS, args[0]);
|
||||
}
|
||||
|
||||
// args.length == 2 → zweite Ebene
|
||||
if (args.length == 2) {
|
||||
switch (args[0].toLowerCase()) {
|
||||
|
||||
case "group":
|
||||
return filter(GROUP_SUBCOMMANDS, args[1]);
|
||||
|
||||
case "name":
|
||||
// Vorschlag: aktueller Etagen-Name als Platzhalter
|
||||
String currentName = getCurrentFloorName(p);
|
||||
return currentName != null
|
||||
? filter(Collections.singletonList(currentName), args[1])
|
||||
: Collections.emptyList();
|
||||
|
||||
// private / public / status haben keine weiteren Argumente
|
||||
default:
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
// args.length >= 3 → drittes+ Argument
|
||||
if (args.length >= 3 && args[0].equalsIgnoreCase("name")) {
|
||||
// Wörter-Eingabe — aktuellen Namen als Gesamtvorschlag anbieten
|
||||
String currentName = getCurrentFloorName(p);
|
||||
if (currentName != null) {
|
||||
// Prüfen ob bisherige Eingabe zum Namen passt
|
||||
String typed = String.join(" ", Arrays.copyOfRange(args, 1, args.length));
|
||||
if (currentName.toLowerCase().startsWith(typed.toLowerCase())) {
|
||||
// Nur das nächste fehlende Wort vorschlagen
|
||||
String[] nameParts = currentName.split(" ");
|
||||
int wordIndex = args.length - 1;
|
||||
if (wordIndex < nameParts.length) {
|
||||
return Collections.singletonList(nameParts[wordIndex]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt den aktuellen Etagen-Namen des Moduls zurück, auf dem der Spieler steht.
|
||||
* Null, wenn kein Modul gefunden.
|
||||
*/
|
||||
private String getCurrentFloorName(Player p) {
|
||||
DatabaseManager db = Elevator.getInstance().getDatabaseManager();
|
||||
Block module = findModuleUnderPlayer(p, db);
|
||||
if (module == null) return null;
|
||||
|
||||
String groupId = db.getGroupId(module.getLocation());
|
||||
if (groupId == null) return null;
|
||||
|
||||
String name = db.getGroupName(groupId);
|
||||
return (name != null && !name.isEmpty() && !name.equals("Etage")) ? name : null;
|
||||
}
|
||||
|
||||
/** Modul direkt unter dem Spieler suchen (spiegelt Logik aus ElevatorCommand). */
|
||||
private Block findModuleUnderPlayer(Player p, DatabaseManager db) {
|
||||
org.bukkit.Location pLoc = p.getLocation();
|
||||
|
||||
Block directBelow = pLoc.clone().subtract(0, 1, 0).getBlock();
|
||||
if (directBelow.getType() == Material.DAYLIGHT_DETECTOR
|
||||
&& db.isElevator(directBelow.getLocation())) {
|
||||
return directBelow;
|
||||
}
|
||||
|
||||
for (double x = -1.0; x <= 1.0; x += 0.5) {
|
||||
for (double z = -1.0; z <= 1.0; z += 0.5) {
|
||||
for (double y = -2.0; y <= 0.5; y += 0.5) {
|
||||
Block check = pLoc.clone().add(x, y, z).getBlock();
|
||||
if (check.getType() == Material.DAYLIGHT_DETECTOR
|
||||
&& db.isElevator(check.getLocation())) {
|
||||
return check;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Filtert eine Liste nach dem bereits getippten Prefix (case-insensitive). */
|
||||
private List<String> filter(List<String> options, String typed) {
|
||||
if (typed == null || typed.isEmpty()) return new ArrayList<>(options);
|
||||
List<String> result = new ArrayList<>();
|
||||
String lower = typed.toLowerCase();
|
||||
for (String s : options) {
|
||||
if (s.toLowerCase().startsWith(lower)) result.add(s);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
# Elevator Config by M_Viper
|
||||
# =============================================================
|
||||
|
||||
debug: false # Debug-Modus (true = Debug-Ausgaben)
|
||||
|
||||
# Datenbank-Einstellungen (SQLite wird standardmäßig genutzt, falls false)
|
||||
mysql:
|
||||
enable: false
|
||||
@@ -17,6 +19,7 @@ settings:
|
||||
hologram-duration: 45 # Wie lange das Hologramm (in Ticks) sichtbar bleibt
|
||||
cooldown: 500 # Wartezeit zwischen Teleports (in Millisekunden)
|
||||
|
||||
|
||||
# Optische Effekte & Hologramme
|
||||
visuals:
|
||||
enable-particles: true
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: Elevator
|
||||
version: 1.5
|
||||
version: 1.8
|
||||
main: de.mviper.elevator.Elevator
|
||||
api-version: 1.20
|
||||
author: mviper
|
||||
|
||||
Reference in New Issue
Block a user