Dateien nach "src/main/java/de/nexuslobby/modules/armorstandtools" hochladen

This commit is contained in:
2026-01-22 14:56:11 +00:00
parent a3215ae3f3
commit dd5e65b707
9 changed files with 689 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
package de.nexuslobby.modules.armorstandtools;
import org.bukkit.entity.ArmorStand;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* Speicherklasse für temporäre Daten der Nexus ArmorStand Tools.
* Alle Daten werden per UUID des Spielers zugeordnet.
*/
public class AST {
// Speichert, welcher Spieler gerade welchen ArmorStand im Editor bearbeitet
public static Map<UUID, ArmorStand> selectedArmorStand = new HashMap<>();
// Speichert, welches Tool (z.B. für kontinuierliche Rotation) der Spieler gerade aktiviert hat
public static Map<UUID, ArmorStandTool> activeTool = new HashMap<>();
// Speichert, ob ein Spieler gerade im Modus ist, einen Text für ein Hologramm in den Chat zu schreiben
// Der zugeordnete ArmorStand erhält nach der Eingabe den Namen.
public static Map<UUID, ArmorStand> chatInputMode = new HashMap<>();
}

View File

@@ -0,0 +1,97 @@
package de.nexuslobby.modules.armorstandtools;
import de.nexuslobby.NexusLobby;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import java.util.Set;
public class ASTListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onInteract(PlayerInteractAtEntityEvent event) {
if (event.getHand() != EquipmentSlot.HAND) return;
if (!(event.getRightClicked() instanceof ArmorStand as)) return;
Player p = event.getPlayer();
// Sneak-Rechtsklick zum Bearbeiten
if (p.isSneaking()) {
if (p.hasPermission("nexuslobby.armorstand.use")) {
event.setCancelled(true);
AST.selectedArmorStand.put(p.getUniqueId(), as);
new ArmorStandGUI(as, p);
}
return;
}
// Normale Interaktion (Befehl ausführen)
Set<String> tags = as.getScoreboardTags();
for (String tag : tags) {
if (tag.startsWith("ascmd:")) {
event.setCancelled(true);
executeNexusCommand(p, tag);
break;
}
}
}
@EventHandler(priority = EventPriority.LOW)
public void onInventoryClick(InventoryClickEvent event) {
if (!event.getView().getTitle().equals("Nexus ArmorStand Editor")) return;
event.setCancelled(true);
if (!(event.getWhoClicked() instanceof Player p)) return;
ItemStack item = event.getCurrentItem();
if (item == null || item.getType() == Material.AIR) return;
ArmorStand as = AST.selectedArmorStand.get(p.getUniqueId());
if (as == null || !as.isValid()) {
p.closeInventory();
return;
}
ArmorStandTool tool = ArmorStandTool.get(item);
if (tool != null) {
tool.execute(as, p);
// GUI aktualisieren, falls noch offen (SET_NAME schließt es z.B.)
if (p.getOpenInventory().getTitle().equals("Nexus ArmorStand Editor")) {
new ArmorStandGUI(as, p);
}
}
}
private void executeNexusCommand(Player p, String tag) {
try {
String[] parts = tag.split(":", 3);
if (parts.length < 3) return;
String type = parts[1].toLowerCase();
String finalizedCommand = parts[2].replace("%player%", p.getName());
switch (type) {
case "player" -> p.performCommand(finalizedCommand);
case "console" -> Bukkit.dispatchCommand(Bukkit.getConsoleSender(), finalizedCommand);
case "bungee" -> sendToBungee(p, finalizedCommand);
}
} catch (Exception e) { e.printStackTrace(); }
}
private void sendToBungee(Player p, String server) {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("Connect");
out.writeUTF(server);
p.sendPluginMessage(NexusLobby.getInstance(), "BungeeCord", out.toByteArray());
}
}

View File

@@ -0,0 +1,116 @@
package de.nexuslobby.modules.armorstandtools;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Set;
public class ArmorStandCmdExecutor implements CommandExecutor {
private final String prefix = "§8[§6Nexus§8] ";
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (!(sender instanceof Player p)) return true;
if (!p.hasPermission("nexuslobby.armorstand.cmd")) {
p.sendMessage(prefix + "§cKeine Berechtigung!");
return true;
}
// 1. Priorität: Name setzen (verwendet den in der Map gespeicherten AS aus der GUI)
if (args.length >= 2 && args[0].equalsIgnoreCase("name")) {
ArmorStand target = AST.selectedArmorStand.get(p.getUniqueId());
if (target == null || !target.isValid()) {
p.sendMessage(prefix + "§cBitte wähle zuerst einen ArmorStand im GUI (Sneak-Rechtsklick) aus!");
return true;
}
String nameInput = buildString(args, 1);
if (nameInput.equalsIgnoreCase("none")) {
target.setCustomName("");
target.setCustomNameVisible(false);
p.sendMessage(prefix + "§eName entfernt.");
} else {
String colored = ChatColor.translateAlternateColorCodes('&', nameInput);
target.setCustomName(colored);
target.setCustomNameVisible(true);
p.sendMessage(prefix + "§7Name gesetzt: " + colored);
}
return true;
}
// 2. Priorität: Action-Commands (verwendet Nearby-Suche für /nexuscmd add...)
ArmorStand target = getNearbyArmorStand(p);
if (target == null) {
p.sendMessage(prefix + "§cKein ArmorStand in der Nähe (4 Blöcke) gefunden!");
return true;
}
if (args.length >= 5 && args[0].equalsIgnoreCase("add")) {
String type = args[3].toLowerCase();
String cmd = buildString(args, 4);
if (!type.equals("player") && !type.equals("console") && !type.equals("bungee")) {
p.sendMessage(prefix + "§cTypen: §eplayer, console, bungee");
return true;
}
target.addScoreboardTag("ascmd:" + type + ":" + cmd);
p.sendMessage(prefix + "§aBefehl an ArmorStand gebunden!");
return true;
}
if (args.length >= 1 && args[0].equalsIgnoreCase("list")) {
p.sendMessage("§6§lBefehle auf diesem ArmorStand:");
for (String tag : target.getScoreboardTags()) {
if (tag.startsWith("ascmd:")) {
p.sendMessage(" §8» §e" + tag.replace("ascmd:", ""));
}
}
return true;
}
if (args.length >= 1 && args[0].equalsIgnoreCase("remove")) {
Set<String> tags = target.getScoreboardTags();
for (String tag : new ArrayList<>(tags)) {
if (tag.startsWith("ascmd:")) target.removeScoreboardTag(tag);
}
p.sendMessage(prefix + "§eAlle Befehle entfernt.");
return true;
}
return sendHelp(p);
}
private ArmorStand getNearbyArmorStand(Player p) {
for (Entity e : p.getNearbyEntities(4, 4, 4)) {
if (e instanceof ArmorStand as) return as;
}
return null;
}
private String buildString(String[] args, int start) {
StringBuilder sb = new StringBuilder();
for (int i = start; i < args.length; i++) {
sb.append(args[i]).append(i == args.length - 1 ? "" : " ");
}
return sb.toString();
}
private boolean sendHelp(Player p) {
p.sendMessage("§6§lNexus Command-Binder Hilfe:");
p.sendMessage("§e/nexuscmd name <Text> §7- Namen setzen (AS vorher anklicken)");
p.sendMessage("§e/nexuscmd add 0 0 <type> <cmd> §7- Befehl binden");
p.sendMessage("§e/nexuscmd list §7- Befehle anzeigen");
p.sendMessage("§e/nexuscmd remove §7- Befehle löschen");
return true;
}
}

View File

@@ -0,0 +1,113 @@
package de.nexuslobby.modules.armorstandtools;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
public class ArmorStandCommand implements CommandExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (!(sender instanceof Player p)) return true;
if (!p.hasPermission("nexuslobby.armorstand.use")) {
p.sendMessage(Config.prefix() + ChatColor.RED + Config.generalNoPerm);
return true;
}
// Suche ArmorStand im Umkreis von 5 Blöcken
ArmorStand target = getNearbyArmorStand(p);
// Fall 1: Nur /astools -> GUI öffnen
if (args.length == 0) {
if (target != null) {
AST.selectedArmorStand.put(p.getUniqueId(), target);
new ArmorStandGUI(target, p);
} else {
p.sendMessage(Config.prefix() + ChatColor.RED + "Kein ArmorStand in der Nähe gefunden!");
}
return true;
}
// Fall 2: Unterbefehle (add, remove, list)
String sub = args[0].toLowerCase();
if (target == null) {
p.sendMessage(Config.prefix() + ChatColor.RED + "Du musst nah an einem ArmorStand stehen!");
return true;
}
switch (sub) {
case "addplayer": // /astools addplayer <command>
if (args.length < 2) return sendHelp(p);
String pCmd = buildString(args, 1);
target.addScoreboardTag("ascmd:player:" + pCmd);
p.sendMessage(Config.prefix() + "§aBefehl (Player) hinzugefügt: §e" + pCmd);
break;
case "addconsole": // /astools addconsole <command>
if (args.length < 2) return sendHelp(p);
String cCmd = buildString(args, 1);
target.addScoreboardTag("ascmd:console:" + cCmd);
p.sendMessage(Config.prefix() + "§aBefehl (Konsole) hinzugefügt: §e" + cCmd);
break;
case "addbungee": // /astools addbungee <server>
if (args.length < 2) return sendHelp(p);
String server = args[1];
target.addScoreboardTag("ascmd:bungee:" + server);
p.sendMessage(Config.prefix() + "§aBefehl (Bungee) hinzugefügt: §eConnect zu " + server);
break;
case "remove": // /astools remove (Löscht alle ascmd Tags)
Set<String> tags = target.getScoreboardTags();
tags.removeIf(tag -> tag.startsWith("ascmd:"));
p.sendMessage(Config.prefix() + "§cAlle Befehle von diesem ArmorStand entfernt.");
break;
case "reload":
Config.load();
p.sendMessage(Config.prefix() + "§aKonfiguration neu geladen.");
break;
default:
sendHelp(p);
break;
}
return true;
}
private ArmorStand getNearbyArmorStand(Player p) {
for (Entity e : p.getNearbyEntities(5, 5, 5)) {
if (e instanceof ArmorStand as) return as;
}
return null;
}
private String buildString(String[] args, int start) {
StringBuilder sb = new StringBuilder();
for (int i = start; i < args.length; i++) {
sb.append(args[i]).append(i == args.length - 1 ? "" : " ");
}
return sb.toString();
}
private boolean sendHelp(Player p) {
p.sendMessage("§6§lArmorStandTools Hilfe:");
p.sendMessage("§e/astools §7- Öffnet Editor");
p.sendMessage("§e/astools addplayer <cmd> §7- Befehl als Spieler ausführen");
p.sendMessage("§e/astools addconsole <cmd> §7- Befehl als Konsole ausführen");
p.sendMessage("§e/astools addbungee <server> §7- Serverwechsel");
p.sendMessage("§e/astools remove §7- Entfernt alle Befehle");
p.sendMessage("§e/astools reload §7- Lädt Config neu");
return true;
}
}

View File

@@ -0,0 +1,49 @@
package de.nexuslobby.modules.armorstandtools;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.List;
public class ArmorStandGUI {
private final Inventory inv;
private final ArmorStand as;
public ArmorStandGUI(ArmorStand as, Player p) {
this.as = as;
// Titel auf Nexus-Branding geändert
this.inv = Bukkit.createInventory(null, 45, "Nexus ArmorStand Editor");
initializeItems();
p.openInventory(inv);
}
private void initializeItems() {
ItemStack filler = new ItemStack(Material.GRAY_STAINED_GLASS_PANE);
ItemMeta fillerMeta = filler.getItemMeta();
if (fillerMeta != null) {
fillerMeta.setDisplayName(" ");
filler.setItemMeta(fillerMeta);
}
for (int i = 0; i < inv.getSize(); i++) {
inv.setItem(i, filler);
}
for (ArmorStandTool tool : ArmorStandTool.values()) {
if (tool.isForGui()) {
inv.setItem(tool.getSlot(), tool.updateLore(as));
}
}
}
public static void init() {
// Statische Initialisierung bleibt erhalten
}
}

View File

@@ -0,0 +1,121 @@
package de.nexuslobby.modules.armorstandtools;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.List;
public enum ArmorStandTool {
// Sichtbarkeit & Basis-Attribute
INVIS(Material.GLASS_PANE, 10) {
@Override public void execute(ArmorStand as, Player p) { as.setVisible(!as.isVisible()); }
},
ARMS(Material.STICK, 11) {
@Override public void execute(ArmorStand as, Player p) { as.setArms(!as.hasArms()); }
},
BASE(Material.STONE_SLAB, 12) {
@Override public void execute(ArmorStand as, Player p) { as.setBasePlate(!as.hasBasePlate()); }
},
SIZE(Material.PUMPKIN_SEEDS, 13) {
@Override public void execute(ArmorStand as, Player p) { as.setSmall(!as.isSmall()); }
},
GRAV(Material.ANVIL, 14) {
@Override public void execute(ArmorStand as, Player p) { as.setGravity(!as.hasGravity()); }
},
INVUL(Material.BEDROCK, 15) {
@Override public void execute(ArmorStand as, Player p) { as.setInvulnerable(!as.isInvulnerable()); }
},
// Hologramm / Name setzen
SET_NAME(Material.NAME_TAG, 16) {
@Override public void execute(ArmorStand as, Player p) {
p.closeInventory();
p.sendMessage(" ");
p.sendMessage("§8§m--------------------------------------");
p.sendMessage("§6§lHologramm-Editor");
p.sendMessage("§7Nutze: §e/nexuscmd name <Text> §7um den Namen zu setzen.");
p.sendMessage("§7Nutze: §e/nexuscmd name none §7um den Namen zu entfernen.");
p.sendMessage("§7Farbcodes mit §6& §7werden unterstützt.");
p.sendMessage("§8§m--------------------------------------");
AST.selectedArmorStand.put(p.getUniqueId(), as);
}
},
// KÖRPERGESTALTUNG (Rotationen)
HEAD_ROT(Material.PLAYER_HEAD, 28) {
@Override public void execute(ArmorStand as, Player p) {
as.setHeadPose(as.getHeadPose().add(Math.toRadians(15), 0, 0));
}
},
BODY_ROT(Material.IRON_CHESTPLATE, 29) {
@Override public void execute(ArmorStand as, Player p) {
as.setBodyPose(as.getBodyPose().add(0, Math.toRadians(15), 0));
}
},
L_ARM_ROT(Material.STICK, 30) {
@Override public void execute(ArmorStand as, Player p) {
as.setLeftArmPose(as.getLeftArmPose().add(Math.toRadians(15), 0, 0));
}
},
R_ARM_ROT(Material.STICK, 31) {
@Override public void execute(ArmorStand as, Player p) {
as.setRightArmPose(as.getRightArmPose().add(Math.toRadians(15), 0, 0));
}
},
L_LEG_ROT(Material.LEATHER_BOOTS, 32) {
@Override public void execute(ArmorStand as, Player p) {
as.setLeftLegPose(as.getLeftLegPose().add(Math.toRadians(15), 0, 0));
}
},
R_LEG_ROT(Material.LEATHER_BOOTS, 33) {
@Override public void execute(ArmorStand as, Player p) {
as.setRightLegPose(as.getRightLegPose().add(Math.toRadians(15), 0, 0));
}
},
REMOVE(Material.BARRIER, 40) {
@Override public void execute(ArmorStand as, Player p) {
as.remove();
p.closeInventory();
p.sendMessage("§cNexus ArmorStand entfernt.");
}
};
private final Material material;
private final int slot;
ArmorStandTool(Material material, int slot) {
this.material = material;
this.slot = slot;
}
public abstract void execute(ArmorStand as, Player p);
public int getSlot() { return slot; }
// Diese Methode hat im letzten Code gefehlt:
public boolean isForGui() { return true; }
public ItemStack updateLore(ArmorStand as) {
ItemStack item = new ItemStack(material);
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.setDisplayName("§6" + this.name().replace("_", " "));
List<String> lore = new ArrayList<>();
lore.add("§7Klicken zum Bearbeiten");
meta.setLore(lore);
item.setItemMeta(meta);
}
return item;
}
public static ArmorStandTool get(ItemStack item) {
if (item == null || !item.hasItemMeta() || !item.getItemMeta().hasDisplayName()) return null;
String name = ChatColor.stripColor(item.getItemMeta().getDisplayName()).replace(" ", "_");
try { return valueOf(name); } catch (Exception e) { return null; }
}
}

View File

@@ -0,0 +1,26 @@
package de.nexuslobby.modules.armorstandtools;
public enum CommandType {
PLAYER("pl:"),
CONSOLE("co:"),
BUNGEE("bu:");
private final String tag;
CommandType(String tag) {
this.tag = tag;
}
public String getTag() {
return tag;
}
public static CommandType fromTag(String tag) {
for (CommandType type : values()) {
if (type.tag.equalsIgnoreCase(tag) || type.name().equalsIgnoreCase(tag)) {
return type;
}
}
return null;
}
}

View File

@@ -0,0 +1,80 @@
package de.nexuslobby.modules.armorstandtools;
import de.nexuslobby.NexusLobby;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
public class Config {
// Vorhandene Variablen (Standardwerte)
public static String guiInUse = "Dieser ArmorStand wird gerade bearbeitet!";
public static String armorStand = "Armor Stand";
public static String wgNoPerm = "Du hast hier keine Baurechte!";
public static String generalNoPerm = "Keine Berechtigung!";
public static String isTrue = "An";
public static String isFalse = "Aus";
public static String isOn = "An";
public static String isOff = "Aus";
public static String small = "Klein";
public static String normal = "Normal";
public static String locked = "Gesperrt";
public static String unLocked = "Offen";
public static String carrying = "Du trägst nun den Armor Stand";
public static String cbCreated = "Command-Block erstellt!";
public static String creativeRequired = "Kreativmodus erforderlich!";
public static String asVisible = "Sichtbarkeit";
public static String size = "Größe";
public static String basePlate = "Bodenplatte";
public static String gravity = "Schwerkraft";
public static String arms = "Arme";
public static String invul = "Unverwundbar";
public static String equip = "Ausrüstung";
public static String glow = "Leuchten";
public static String cmdOnCooldown = "Befehl hat noch Cooldown!";
public static String errorExecutingCmd = "Fehler beim Ausführen von Befehl";
public static boolean saveToolCreatesCommandBlock = true;
public static boolean requireCreative = false;
public static boolean logGeneratedSummonCommands = false;
public static int defaultASCmdCooldownTicks = 0;
// Neue Config-Verwaltung
private static FileConfiguration armorStandConfig;
// Diese Methode wurde vom ASTListener benötigt
public static String prefix() {
return "§8[§6ArmorStand§8] §7";
}
public static void load() {
NexusLobby plugin = NexusLobby.getInstance();
File file = new File(plugin.getDataFolder(), "armorstands.yml");
if (!file.exists()) {
plugin.saveResource("armorstands.yml", false);
}
armorStandConfig = YamlConfiguration.loadConfiguration(file);
// Werte aus der Config laden, falls vorhanden
guiInUse = getString("messages.guiInUse", guiInUse);
wgNoPerm = getString("messages.noPermission", wgNoPerm);
generalNoPerm = getString("messages.generalNoPerm", generalNoPerm);
requireCreative = armorStandConfig.getBoolean("settings.requireCreative", requireCreative);
logGeneratedSummonCommands = armorStandConfig.getBoolean("settings.logCommands", logGeneratedSummonCommands);
}
private static String getString(String path, String def) {
if (armorStandConfig == null) return def;
String value = armorStandConfig.getString(path, def);
return ChatColor.translateAlternateColorCodes('&', value);
}
public static void logSummonCommand(String name, String cmd) {
Bukkit.getLogger().info(name + " generierte: " + cmd);
}
}

View File

@@ -0,0 +1,64 @@
package de.nexuslobby.modules.armorstandtools;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.CommandBlock;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EntityEquipment;
public class Utils {
public static void title(Player p, String msg) {
p.sendTitle("", msg, 10, 40, 10);
}
public static ArmorStand cloneArmorStand(ArmorStand as) {
ArmorStand clone = as.getWorld().spawn(as.getLocation(), ArmorStand.class);
clone.setArms(as.hasArms());
clone.setBasePlate(as.hasBasePlate());
clone.setGravity(as.hasGravity());
clone.setSmall(as.isSmall());
clone.setVisible(as.isVisible());
clone.setCustomName(as.getCustomName());
clone.setCustomNameVisible(as.isCustomNameVisible());
clone.setInvulnerable(as.isInvulnerable());
clone.setGlowing(as.isGlowing());
EntityEquipment e1 = as.getEquipment();
EntityEquipment e2 = clone.getEquipment();
if(e1 != null && e2 != null) {
e2.setHelmet(e1.getHelmet());
e2.setChestplate(e1.getChestplate());
e2.setLeggings(e1.getLeggings());
e2.setBoots(e1.getBoots());
e2.setItemInMainHand(e1.getItemInMainHand());
e2.setItemInOffHand(e1.getItemInOffHand());
}
return clone;
}
public static String createSummonCommand(ArmorStand as) {
return "/summon armor_stand " + as.getLocation().getX() + " " + as.getLocation().getY() + " " + as.getLocation().getZ() + " {ShowArms:1b}";
}
public static String createGiveCommand(ArmorStand as, Player p) {
return "give " + p.getName() + " armor_stand";
}
public static void generateCmdBlock(Location l, String command) {
Block b = l.getBlock();
b.setType(Material.COMMAND_BLOCK);
if (b.getState() instanceof CommandBlock cb) {
cb.setCommand(command);
cb.update();
}
}
public static boolean toggleSlotsDisabled(ArmorStand as) {
// Logik für ArmorStand-Locking (NBT Manipulation wäre hier nötig)
return true;
}
}