3
0
Mirror von https://github.com/St3venAU/ArmorStandTools.git synchronisiert 2024-12-27 12:00:07 +01:00
Dieser Commit ist enthalten in:
Steven 2021-10-07 17:26:10 +08:00
Ursprung 74df5da36a
Commit b2a098741f
16 geänderte Dateien mit 894 neuen und 377 gelöschten Zeilen

Datei anzeigen

@ -3,8 +3,8 @@ A full suite of Armor Stand tools for CraftBukkit/Spigot
Spigot resource page with plugin download: http://www.spigotmc.org/resources/armor-stand-tools.2237/
Inspiration
-----------
About
-----
I wanted to create an armor stand for each kit in my mini-game, and I quickly became frustrated with trying to use commands and numeric values to position the legs, arms, body and head of each armor stand, so I created this plugin which allows you to do all of this with ease. Among other features you can create any pose you wish just by holding right click on the tools and moving your cursor up and down on the armor stand. The plugin can also generate a summon command that will re-create the armor stand at any time.
Compatibility
@ -17,37 +17,59 @@ Features
--------
- Summon armor stands.
- Name armor stands.
- Toggle: Gravity, Visibility, Arms, Base, Size, Invulnerability, Equipment Lock.
- Toggle: Gravity, Visibility, Arms, Base, Size, Invulnerability, Equipment Lock, Glow.
- Manipulate the x/y/z rotations of the Head, Body, Arms and Legs. The value depends on how high up the armor stand's body you click with the tool (i.e. click near the feet is one extreme, near the top of the head is the other extreme).
- Full control over armor stand's inventory (armor & items in hands).
- Pick up and move armor stands.
- Armor stand cloning tool.
- Save tool: Automatically generate a command block with the command to summon that armor stand in its current state.
- Save tool: Automatically generate a summon command to summon the armor stand in its current state. This can be saved to a command block or logged.
- Pick up as item: Convert an armor stand into an inventory item that when placed like a normal armor stand retains its inventory, pose and settings.
- Player head tool: Give an armor stand the head of a specific player.
- WorldGuard region support, including a custom WorldGuard flag. Set the 'ast' flag for a region to deny to turn off AST use in that region.
- WorldGuard region support, including a custom WorldGuard flag. Setting the 'ast' flag for a region to deny turns off AST use in that region.
- Customizable language config file.
- Assign commands to armor stands that are run when a player right clicks that armor stand (see below).
Assigning Commands
------------------
- Use /ascmd to assign a command to an armor stand (see usage and permissions below)
- When using /ascmd assign player <command>, the command will be run by the player
- When using /ascmd assign console <command>, the command will be run by the console (see Warning below!)
- When a player with the astools.ascmd.execute permission right-clicks on an armor stand, it's command is run.
- If a player is crouching when they right-click the armor stand, the command will not be run.
- Warning: Make sure you are careful when assigning console commands. Any player with the astools.ascmd.execute permission will be able to execute the command.
- By default, any command assigned to an armor stand will use the default cooldown set in config.yml. This can be set on an individual basis using the /ascmd cooldown <ticks> command.
Commands
--------
- /astools or /ast : Give yourself all the armor stand tools (Note: Saves & clears your inventory which is restored by running this command again)
- /astools reload : Reload the config file
- /ascmd assign console <command> : Assign a console command to the nearest armor stand (within 4 blocks)
- /ascmd assign player <command> : Assign a player command to the nearest armor stand
- /ascmd remove : Remove the command assigned to the nearest armor stand
- /ascmd view : View the command assigned to the nearest armor stand
- /ascmd add \<priority\> \<delay\> \<player/console/bungee\> \<command/bungee_server_name\> : Add an assigned command to the nearest armor stand. See the assigning commands section below for more info.
- /ascmd remove \<command_number\> : Remove a command from to the nearest armor stand (use /ascmd list to find the command number)
- /ascmd list : List the commands assigned to the nearest armor stand
- /ascmd cooldown <ticks> : Sets the cooldown (in ticks) for the command on nearest armor stand (Setting this overrides the default cooldown from config.yml)
- /ascmd cooldown remove : Removes the cooldown for the command on nearest armor stand (Default cooldown set in config.yml will be used)
Permissions
-----------
- astools.use : Permission for using any of the tools
- astools.command : Permission for the /astools command
- astools.reload : Permission to reload the plugin with /astools reload
- astools.clone: Permission to use the clone tool
- astools.head: Permission to use the player head tool (Ability to specify a player head for an armor stand)
- astools.summon: Permission to use the summon tool (Summons an armor stand without requiring the materials)
- astools.cmdblock: Permission to use the save tool (Create a summon command)
- astools.glow: Permission to use the glow tool (Glow effect on armor stands)
- astools.ascmd.add.console: Permission to add a console command to an armor stand (Previously astools.ascmd.assign.console)
- astools.ascmd.add.player: Permission to add a player command to an armor stand (Previously astools.ascmd.assign.player)
- astools.ascmd.add.bungee: Permission to add a bungee command to an armor stand (See below for details)
- astools.ascmd.remove: Permission to remove a command from an armor stand
- astools.ascmd.list: Permission to list the commands assigned to an armor stand (Previously astools.ascmd.view)
- astools.ascmd.cooldown: Permission to add/remove a cooldown to commands assigned to an armor stand
- astools.ascmd.execute: Permission to execute commands assigned to an armor stand by (on right click)
- astools.bypass-wg-flag: Permission to bypass the WorldGuard ast flag, allowing the player to use AST even in regions that ast flag is set to deny.
Assigning Commands to Armor Stands
----------------------------------
- Stand close to the armor stand (The nearest armor stand within 4 blocks is selected) and use the command: /ascmd add \<priority\> \<delay\> \<player/console/bungee\> \<command/bungee_server_name\>
- \<priority\>: When multiple commands are assigned, commands with the lowest priority number are executed first. Command with the same priority can be executed in any order.
- \<delay\>: Delay in ticks before the command is executed.
- \<player/console/bungee\>: Player commands are executed as if they were typed by the player. Console commands are executed by the console. Bungee commands are a special case (see below).
- \<command/bungee_server_name\>: The command to be executed. To use the executing player's name in the command, use the placeholder %player% - it will be replaced with the players name at time of execution.
- When a player with the astools.ascmd.execute permission right-clicks on an armor stand, commands assigned to that armor stand are executed.
- Warning: Make sure you are careful when assigning console commands. Any player with the astools.ascmd.execute permission will be able to execute the command.
- By default, any command assigned to an armor stand will use the default cooldown set in config.yml. This can be set on an individual basis using the /ascmd cooldown <ticks> command.
- Bungee commands: These are used to send the player to a different BungeeCord server. E.g. This will add a command to send the player to a server called server1: /ascmd add 0 0 bungee server1
WorldGuard Integration
----------------------
- If a player does not have build permission for the region, that player will also be denied the use of AST in that region.
@ -55,23 +77,6 @@ WorldGuard Integration
- The ast worldguard flag is ignored for any player with the permission node 'astools.bypass-wg-flag'. This means that a player with this permission can use AST in worldguard regions even if the ast flag for that region is set to Deny.
- The ast worldguard flag is also ignored for players that have op.
Permissions
-----------
- astools.command : Permission for the /astools command
- astools.reload : Permission to reload the plugin with /astools reload
- astools.use : Permission for using any of the tools
- astools.clone: Permission to use the clone tool
- astools.head: Permission to use the player head tool (Ability to specify a player head for an armor stand)
- astools.summon: Permission to use the summon tool (Summons an armor stand without requiring the materials)
- astools.cmdblock: Permission to use the save tool (Creates a command block)
- astools.ascmd.assign.console: Permission to assign a console command to an armor stand
- astools.ascmd.assign.player: Permission to assign a player command to an armor stand
- astools.ascmd.remove: Permission to remove a command from an armor stand
- astools.ascmd.view: Permission to view the command assigned to an armor stand
- astools.ascmd.cooldown: Permission to add a cooldown to commands assigned to an armor stand
- astools.ascmd.execute: Permission to execute a command assigned to an armor stand by (on right click)
- astools.bypass-wg-flag: Permission to bypass the WorldGuard ast flag, allowing the player to use AST even in regions that ast flag is set to deny.
Config
------
- config.yml - The main config file allows you to set the default starting settings for newly summoned armor stands. This is useful if you plan on creating a lot of armor stands with similar equipment.

Datei anzeigen

@ -3,9 +3,9 @@
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gmail.St3venAU.plugins</groupId>
<groupId>com.gmail.st3venau.plugins</groupId>
<artifactId>ArmorStandTools</artifactId>
<version>4.2.0</version>
<version>4.3.0</version>
<name>ArmorStandTools</name>
<repositories>

Datei anzeigen

@ -35,6 +35,7 @@ public class AST extends JavaPlugin {
public static final HashMap<UUID, ItemStack[]> savedInventories = new HashMap<>();
static AST plugin;
static String nmsVersion;
@Override
public void onLoad() {
@ -56,7 +57,7 @@ public class AST extends JavaPlugin {
@Override
public void onEnable() {
plugin = this;
String nmsVersion = getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
nmsVersion = getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
if( nmsVersion.startsWith("v1_4") ||
nmsVersion.startsWith("v1_5") ||
nmsVersion.startsWith("v1_6") ||
@ -75,6 +76,7 @@ public class AST extends JavaPlugin {
return;
}
getServer().getPluginManager().registerEvents(new MainListener(), this);
getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
Commands cmds = new Commands();
PluginCommand command = getCommand("astools");
if(command != null) {
@ -103,6 +105,7 @@ public class AST extends JavaPlugin {
@Override
public void onDisable() {
getServer().getMessenger().unregisterOutgoingPluginChannel(this);
for(UUID uuid : activeTool.keySet()) {
if(ArmorStandTool.MOVE != activeTool.get(uuid)) continue;
ArmorStand as = selectedArmorStand.get(uuid);
@ -237,7 +240,9 @@ public class AST extends JavaPlugin {
if(!Utils.hasPermissionNode(p, "astools.bypass-wg-flag") && !getWorldGuardAstFlag(b.getLocation())) {
return false;
}
return Config.worldGuardPlugin.createProtectionQuery().testBlockBreak(p, b);
if(!Config.worldGuardPlugin.createProtectionQuery().testBlockBreak(p, b)) {
return false;
}
}
BlockBreakEvent breakEvent = new BlockBreakEvent(b, p);
Bukkit.getServer().getPluginManager().callEvent(breakEvent);

Datei anzeigen

@ -1,164 +1,109 @@
package com.gmail.st3venau.plugins.armorstandtools;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandException;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Player;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.io.Serializable;
class ArmorStandCmd {
public record ArmorStandCmd(String command, CommandType type, Integer priority, Integer delay) implements Comparable<ArmorStandCmd>, Serializable {
private final ArmorStand armorStand;
private String command;
private boolean console;
ArmorStandCmd(ArmorStand as, String command, boolean console) {
this.armorStand = as;
this.command = command;
this.console = console;
String getTag() {
return "ascmd::v2::" + priority + "::" + delay + "::" + type.getTag() + "::" + command;
}
ArmorStandCmd(ArmorStand as) {
this.armorStand = as;
this.command = null;
for(String tag : armorStand.getScoreboardTags()) {
if(tag.startsWith("ast-cmd-")) {
String cmd = tag.substring(8);
if(cmd.startsWith("con:")) {
cmd = cmd.substring(4);
if(cmd.charAt(0) == '/') {
cmd = cmd.substring(1);
}
if(cmd.length() == 0) return;
this.command = cmd;
this.console = true;
return;
} else if(cmd.startsWith("plr:")) {
cmd = cmd.substring(4);
if(cmd.charAt(0) == '/') {
cmd = cmd.substring(1);
}
if(cmd.length() == 0) return;
this.command = cmd;
this.console = false;
return;
}
}
}
void saveTo(ArmorStand as) {
as.addScoreboardTag(getTag());
}
private String getTag() {
return "ast-cmd-" + (console ? "con" : "plr") + ":" + command;
}
String getCommand() {
return this.command;
void removeFrom(ArmorStand as) {
as.removeScoreboardTag(getTag());
}
boolean execute(Player p) {
if(command == null) return true;
if(isOnCooldown()) {
p.sendMessage(ChatColor.RED + Config.cmdOnCooldown);
return true;
}
setOnCooldown();
String cmd = command.contains("%player%") ? command.replaceAll("%player%", p.getName()) : command;
if(console) {
return Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd);
} else {
if (command == null) return true;
String cmd = command.replaceAll("%player%", p.getName());
switch (type) {
case PLAYER -> {
return p.performCommand(cmd);
}
}
private void cleanUpCommand() {
if(command.charAt(0) == '/') {
command = command.substring(1);
}
}
boolean save() {
removeAssignedCommand(armorStand);
if (command == null) return false;
cleanUpCommand();
return command.length() != 0 && armorStand.addScoreboardTag(getTag());
}
void cloneTo(ArmorStand clone) {
if(command == null) return;
ArmorStandCmd asCmd = new ArmorStandCmd(clone, command, console);
asCmd.save();
}
String getType() {
return console ? "Console" : "Player";
}
static boolean removeAssignedCommand(ArmorStand as) {
List<String> tags = new ArrayList<>();
for(String tag : as.getScoreboardTags()) {
if(tag.startsWith("ast-cmd-")) {
tags.add(tag);
}
}
for(String tag : tags) {
as.removeScoreboardTag(tag);
}
return tags.size() > 0;
}
private void setOnCooldown() {
int cooldownTime = getCooldownTime();
if(cooldownTime == -1) {
cooldownTime = Config.defaultASCmdCooldownTicks;
}
if(cooldownTime < 1) return;
armorStand.setMetadata("ast-cmd-cooldown", new FixedMetadataValue(AST.plugin, true));
new BukkitRunnable() {
@Override
public void run() {
armorStand.removeMetadata("ast-cmd-cooldown", AST.plugin);
}
}.runTaskLater(AST.plugin, cooldownTime);
}
private boolean isOnCooldown() {
return armorStand.hasMetadata("ast-cmd-cooldown");
}
// Positive cooldown: Set cooldown time, Negative cooldown: Remove cooldown time
void setCooldownTime(int cooldown) {
if(armorStand == null) return;
List<String> tags = new ArrayList<>();
for(String tag : armorStand.getScoreboardTags()) {
if(tag.startsWith("ast-cdn-")) {
tags.add(tag);
}
}
for(String tag : tags) {
armorStand.removeScoreboardTag(tag);
}
if(cooldown < 0) return;
armorStand.addScoreboardTag("ast-cdn-" + cooldown);
}
private int getCooldownTime() {
if(armorStand == null) return -1;
for(String tag : armorStand.getScoreboardTags()) {
if(tag.startsWith("ast-cdn-")) {
String[] split = tag.split("ast-cdn-");
if(split.length < 2 || split[1].length() < 1) return -1;
case CONSOLE -> {
boolean ok;
try {
return Integer.parseInt(split[1]);
} catch (NumberFormatException e) {
return -1;
ok = Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd);
} catch (CommandException e) {
return false;
}
return ok;
}
case BUNGEE -> {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("Connect");
out.writeUTF(cmd);
p.sendPluginMessage(AST.plugin, "BungeeCord", out.toByteArray());
return true;
}
}
}
return -1;
return true;
}
static ArmorStandCmd fromTag(String tag) {
//[0] [1] [2] [3] [4] [5 - ...]
//ascmd::v2::priority::delay::type::command
String[] split = tag.split("::");
if (split.length < 6) return null;
if (!split[0].equals("ascmd")) return null;
int priority;
try {
priority = Integer.parseInt(split[2]);
} catch (NumberFormatException e) {
return null;
}
int delay;
try {
delay = Integer.parseInt(split[3]);
} catch (NumberFormatException e) {
return null;
}
if(delay < 0) return null;
CommandType type = CommandType.fromTag(split[4]);
if (type == null) return null;
String cmd;
if (split.length == 6) {
cmd = split[5];
} else {
StringBuilder sb = new StringBuilder();
for (int i = 5; i < split.length; i++) {
sb.append(split[i]).append("::");
}
cmd = sb.substring(0, sb.length() - 2);
}
if (cmd.charAt(0) == '/') {
cmd = cmd.substring(1);
}
if (cmd.length() == 0) return null;
return new ArmorStandCmd(cmd, type, priority, delay);
}
static ArmorStandCmd fromLegacyTag(String tag) {
//ast-cmd-type-command
if (!tag.startsWith("ast-cmd-")) return null;
CommandType type = CommandType.fromTag(tag.substring(8, 11));
if (type == null) return null;
String cmd = tag.substring(12);
if (cmd.charAt(0) == '/') {
cmd = cmd.substring(1);
}
if (cmd.length() == 0) return null;
return new ArmorStandCmd(cmd, type, 0, 0);
}
@Override
public int compareTo(@NotNull ArmorStandCmd o) {
return Integer.compare(priority, o.priority);
}
}

Datei anzeigen

@ -0,0 +1,147 @@
package com.gmail.st3venau.plugins.armorstandtools;
import org.bukkit.ChatColor;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Player;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
class ArmorStandCmdManager {
static private final String ON_COOLDOWN_TAG = "AstCmdCooldown";
private final ArmorStand armorStand;
private final List<ArmorStandCmd> commands = new ArrayList<>();
ArmorStandCmdManager(ArmorStand as) {
this.armorStand = as;
getCommandsFromScoreboardTags();
commands.sort(null);
}
private void getCommandsFromScoreboardTags() {
Set<String> tags = new HashSet<>(armorStand.getScoreboardTags());
for(String tag : tags) {
if(tag.startsWith("ast-cmd-")) {
ArmorStandCmd command = ArmorStandCmd.fromLegacyTag(tag);
armorStand.removeScoreboardTag(tag);
if(command != null) {
addCommand(command, true);
}
} else if (tag.startsWith("ascmd::v2::")) {
ArmorStandCmd command = ArmorStandCmd.fromTag(tag);
if(command != null) {
addCommand(command, false);
}
}
}
}
public List<ArmorStandCmd> getCommands() {
commands.sort(null);
return commands;
}
boolean hasCommands() {
return !commands.isEmpty();
}
void addCommand(ArmorStandCmd command, boolean saveToArmorStand) {
commands.add(command);
if(saveToArmorStand) {
command.saveTo(armorStand);
}
}
boolean removeCommand(int index) {
ArmorStandCmd cmd;
try {
cmd = commands.get(index);
} catch (IndexOutOfBoundsException e) {
return false;
}
cmd.removeFrom(armorStand);
commands.remove(index);
return true;
}
void executeCommands(Player p) {
if(isOnCooldown()) {
p.sendMessage(ChatColor.RED + Config.cmdOnCooldown);
return;
}
setOnCooldown();
long cumulativeDelay = 0;
for(int n = 0; n < commands.size(); n++) {
ArmorStandCmd asCmd = commands.get(n);
cumulativeDelay += asCmd.delay();
final int num = n + 1;
new BukkitRunnable() {
@Override
public void run() {
if(!p.isOnline()) return;
if(!asCmd.execute(p)) {
p.sendMessage(ChatColor.RED + Config.errorExecutingCmd + " #" + num);
}
}
}.runTaskLater(AST.plugin, cumulativeDelay);
}
}
private void setOnCooldown() {
int cooldownTime = getCooldownTime();
if(cooldownTime == -1) {
cooldownTime = Config.defaultASCmdCooldownTicks;
}
if(cooldownTime < 1) return;
armorStand.setMetadata(ON_COOLDOWN_TAG, new FixedMetadataValue(AST.plugin, true));
new BukkitRunnable() {
@Override
public void run() {
armorStand.removeMetadata(ON_COOLDOWN_TAG, AST.plugin);
}
}.runTaskLater(AST.plugin, cooldownTime);
}
private boolean isOnCooldown() {
return armorStand.hasMetadata(ON_COOLDOWN_TAG);
}
// Positive cooldown: Set cooldown time, Negative cooldown: Remove cooldown time
void setCooldownTime(int cooldown) {
if(armorStand == null) return;
List<String> tags = new ArrayList<>();
for(String tag : armorStand.getScoreboardTags()) {
if(tag.startsWith("ast-cdn-")) {
tags.add(tag);
}
}
for(String tag : tags) {
armorStand.removeScoreboardTag(tag);
}
if(cooldown < 0) return;
armorStand.addScoreboardTag("ast-cdn-" + cooldown);
}
private int getCooldownTime() {
if(armorStand == null) return -1;
for(String tag : armorStand.getScoreboardTags()) {
if(tag.startsWith("ast-cdn-")) {
String[] split = tag.split("ast-cdn-");
if(split.length < 2 || split[1].length() < 1) return -1;
try {
return Integer.parseInt(split[1]);
} catch (NumberFormatException e) {
return -1;
}
}
}
return -1;
}
}

Datei anzeigen

@ -6,6 +6,7 @@ import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
@ -18,6 +19,7 @@ import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.HashSet;
@ -197,7 +199,10 @@ class ArmorStandGUI implements Listener {
break;
case CLONE:
p.closeInventory();
AST.pickUpArmorStand(Utils.cloneArmorStand(as), p, true);
ArmorStand clone = (ArmorStand) as.getWorld().spawnEntity(as.getLocation().add(1, 0, 0), EntityType.ARMOR_STAND);
(new ArmorStandMeta(as)).applyToArmorStand(clone);
clone.setMetadata("clone", new FixedMetadataValue(AST.plugin, true));
AST.pickUpArmorStand(clone, p, true);
Utils.title(p, Config.carrying);
break;
case GEN_CMD:
@ -258,6 +263,18 @@ class ArmorStandGUI implements Listener {
as.setGlowing(glowing);
Utils.title(p, Config.glow + ": " + (glowing ? Config.isOn : Config.isOff));
break;
case ITEM:
ArmorStandMeta asm = new ArmorStandMeta(as);
ItemStack item = asm.convertToItem();
if(item != null) {
p.closeInventory();
if(p.getInventory().addItem(item).size() > 0) {
p.sendMessage(ChatColor.RED + Config.inventoryFull);
} else if(p.getGameMode() != GameMode.CREATIVE) {
as.remove();
}
}
break;
default:
return;
}

Datei anzeigen

@ -0,0 +1,259 @@
package com.gmail.st3venau.plugins.armorstandtools;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.ArmorStand;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.EulerAngle;
import org.bukkit.util.io.BukkitObjectInputStream;
import org.bukkit.util.io.BukkitObjectOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class ArmorStandMeta implements Serializable {
final String name;
final float yaw;
ItemStack helmet, chest, leggings, boots, mainHand, offHand;
final double[] headPose, bodyPose, leftArmPose, rightArmPose, leftLegPose, rightLegPose;
final boolean gravity, visible, basePlate, arms, small, invulnerable, glowing, nameVisible, marker;
final HashMap<EquipmentSlot, ArrayList<ArmorStand.LockType>> equipmentLocks;
final List<String> commandTags = new ArrayList<>();
String cooldownTag;
ArmorStandMeta(ArmorStand as) {
name = as.getCustomName();
yaw = as.getLocation().getYaw();
EntityEquipment equipment = as.getEquipment();
if(equipment != null) {
helmet = equipment.getHelmet();
chest = equipment.getChestplate();
leggings = equipment.getLeggings();
boots = equipment.getBoots();
mainHand = equipment.getItemInMainHand();
offHand = equipment.getItemInOffHand();
}
headPose = new double[3];
headPose[0] = as.getHeadPose().getX();
headPose[1] = as.getHeadPose().getY();
headPose[2] = as.getHeadPose().getZ();
bodyPose = new double[3];
bodyPose[0] = as.getBodyPose().getX();
bodyPose[1] = as.getBodyPose().getY();
bodyPose[2] = as.getBodyPose().getZ();
leftArmPose = new double[3];
leftArmPose[0] = as.getLeftArmPose().getX();
leftArmPose[1] = as.getLeftArmPose().getY();
leftArmPose[2] = as.getLeftArmPose().getZ();
rightArmPose = new double[3];
rightArmPose[0] = as.getRightArmPose().getX();
rightArmPose[1] = as.getRightArmPose().getY();
rightArmPose[2] = as.getRightArmPose().getZ();
leftLegPose = new double[3];
leftLegPose[0] = as.getLeftLegPose().getX();
leftLegPose[1] = as.getLeftLegPose().getX();
leftLegPose[2] = as.getLeftLegPose().getZ();
rightLegPose = new double[3];
rightLegPose[0] = as.getRightLegPose().getX();
rightLegPose[1] = as.getRightLegPose().getY();
rightLegPose[2] = as.getRightLegPose().getZ();
gravity = as.hasGravity();
visible = as.isVisible();
basePlate = as.hasBasePlate();
arms = as.hasArms();
small = as.isSmall();
invulnerable = as.isInvulnerable();
glowing = as.isGlowing();
nameVisible = as.isCustomNameVisible();
marker = as.isMarker();
equipmentLocks = new HashMap<>();
for (EquipmentSlot slot : EquipmentSlot.values()) {
ArrayList<ArmorStand.LockType> lockTypes = new ArrayList<>();
for (ArmorStand.LockType lockType : ArmorStand.LockType.values()) {
if (as.hasEquipmentLock(slot, lockType)) {
lockTypes.add(lockType);
}
}
equipmentLocks.put(slot, lockTypes);
}
for(ArmorStandCmd cmd : new ArmorStandCmdManager(as).getCommands()) {
commandTags.add(cmd.getTag());
}
for(String tag : as.getScoreboardTags()) {
if(tag.startsWith("ast-cdn-")) {
cooldownTag = tag;
}
}
}
void applyToArmorStand(ArmorStand as) {
as.setCustomName(name);
EntityEquipment equipment = as.getEquipment();
if(equipment != null) {
equipment.setHelmet(helmet);
equipment.setChestplate(chest);
equipment.setLeggings(leggings);
equipment.setBoots(boots);
equipment.setItemInMainHand(mainHand);
equipment.setItemInOffHand(offHand);
}
as.setHeadPose( new EulerAngle( headPose[0], headPose[1], headPose[2]));
as.setBodyPose( new EulerAngle( bodyPose[0], bodyPose[1], bodyPose[2]));
as.setLeftArmPose( new EulerAngle( leftArmPose[0], leftArmPose[1], leftArmPose[2]));
as.setRightArmPose(new EulerAngle(rightArmPose[0], rightArmPose[1], rightArmPose[2]));
as.setLeftLegPose( new EulerAngle( leftLegPose[0], leftLegPose[1], leftLegPose[2]));
as.setRightLegPose(new EulerAngle(rightLegPose[0], rightLegPose[1], rightLegPose[2]));
as.setGravity(gravity);
as.setVisible(visible);
as.setBasePlate(basePlate);
as.setArms(arms);
as.setSmall(small);
as.setInvulnerable(invulnerable);
as.setGlowing(glowing);
as.setCustomNameVisible(nameVisible);
as.setMarker(marker);
for (EquipmentSlot slot : equipmentLocks.keySet()) {
for (ArmorStand.LockType lockType : equipmentLocks.get(slot)) {
as.addEquipmentLock(slot, lockType);
}
}
for(String tag : commandTags) {
as.addScoreboardTag(tag);
}
if(cooldownTag != null) {
as.addScoreboardTag(cooldownTag);
}
new BukkitRunnable() {
@Override
public void run() {
Location l = as.getLocation();
l.setYaw(yaw);
as.teleport(l);
}
}.runTaskLater(AST.plugin, 2L);
}
ItemStack convertToItem() {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
BukkitObjectOutputStream objectStream = new BukkitObjectOutputStream(outputStream);
objectStream.writeObject(this);
objectStream.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
ItemStack is = new ItemStack(Material.ARMOR_STAND, 1);
is.addUnsafeEnchantment(Enchantment.DURABILITY, 1);
ItemMeta meta = is.getItemMeta();
if(meta != null) {
meta.setDisplayName(ChatColor.AQUA + Config.configuredArmorStand);
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
meta.setLore(createLore());
is.setItemMeta(meta);
}
try {
Class<?> craftItemStackClass = Class.forName("org.bukkit.craftbukkit." + AST.nmsVersion + ".inventory.CraftItemStack");
Object nmsStack = craftItemStackClass.getMethod("asNMSCopy", ItemStack.class)
.invoke(null, is);
Object tag = nmsStack.getClass().getMethod("getTag")
.invoke(nmsStack);
Object nbtArray = Class.forName("net.minecraft.nbt.NBTTagByteArray")
.getConstructor(byte[].class)
.newInstance((Object) outputStream.toByteArray());
tag.getClass().getMethod("set", String.class, Class.forName("net.minecraft.nbt.NBTBase"))
.invoke(tag, "ArmorStandMeta", nbtArray);
nmsStack.getClass().getMethod("setTag", tag.getClass())
.invoke(nmsStack, tag);
return (ItemStack) craftItemStackClass.getMethod("asBukkitCopy", nmsStack.getClass())
.invoke(null, nmsStack);
} catch (Exception e) {
if(Config.showDebugMessages) {
e.printStackTrace();
AST.debug("Failed to convert armor stand into an item");
}
return null;
}
}
static ArmorStandMeta fromItem(ItemStack is) {
if(is == null) return null;
Object armorStandMetaObject;
try {
Class<?> craftItemStackClass = Class.forName("org.bukkit.craftbukkit." + AST.nmsVersion + ".inventory.CraftItemStack");
Object nmsStack = craftItemStackClass.getMethod("asNMSCopy", ItemStack.class)
.invoke(null, is);
Object tag = nmsStack.getClass().getMethod("getTag")
.invoke(nmsStack);
if(tag == null) return null;
byte[] byteArray = (byte[]) tag.getClass().getMethod("getByteArray", String.class)
.invoke(tag, "ArmorStandMeta");
if(byteArray == null) return null;
ByteArrayInputStream inputStream = new ByteArrayInputStream(byteArray);
BukkitObjectInputStream objectStream = new BukkitObjectInputStream(inputStream);
armorStandMetaObject = objectStream.readObject();
objectStream.close();
} catch (Exception e) {
return null;
}
return armorStandMetaObject instanceof ArmorStandMeta ? (ArmorStandMeta) armorStandMetaObject : null;
}
List<String> createLore() {
List<String> lore = new ArrayList<>();
if(name != null && name.length() > 0) {
lore.add(Config.name + ": " + ChatColor.YELLOW + name);
}
int stacks = 0;
int items = 0;
if(helmet != null) { stacks++; items += helmet.getAmount(); }
if(chest != null) { stacks++; items += chest.getAmount(); }
if(leggings != null) { stacks++; items += leggings.getAmount(); }
if(boots != null) { stacks++; items += boots.getAmount(); }
if(mainHand != null) { stacks++; items += mainHand.getAmount(); }
if(offHand != null) { stacks++; items += offHand.getAmount(); }
if(stacks > 0) {
lore.add(Config.inventory + ": " + ChatColor.YELLOW + items + " " + Config.items + " (" + stacks + " " + Config.stacks + ")");
}
List<String> attribs = new ArrayList<>();
if(commandTags.size() > 0) attribs.add(commandTags.size() + " " + Config.cmdsAssigned);
if(equipmentLocks.size() > 0) attribs.add(Config.equip + " " + Config.locked);
if(!gravity) attribs.add(Config.gravity + " " + Config.isOff);
if(!visible) attribs.add(Config.invisible);
if(arms) attribs.add(Config.arms);
if(small) attribs.add(Config.small);
if(invulnerable) attribs.add(Config.invuln);
if(glowing) attribs.add(Config.glowing);
if(attribs.size() > 0) {
StringBuilder sb = new StringBuilder(Config.attributes + ": " + ChatColor.YELLOW);
for (String attrib : attribs) {
sb.append(attrib).append(", ");
if (sb.length() >= 40) {
lore.add(sb.toString());
sb = new StringBuilder("" + ChatColor.YELLOW);
}
}
if (sb.length() < 3) {
String last = lore.get(lore.size() - 1);
lore.add(last.substring(0, last.length() - 2));
} else {
lore.add(sb.substring(0, sb.length() - 2));
}
}
return lore;
}
}

Datei anzeigen

@ -6,6 +6,7 @@ import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
@ -59,7 +60,8 @@ public enum ArmorStandTool {
RARM ("gui_rarm", Material.REDSTONE_TORCH, 15, true, "astools.use", true),
LARM ("gui_larm", Material.TORCH, 17, true, "astools.use", true),
RLEG ("gui_rleg", Material.BLAZE_ROD, 24, true, "astools.use", true),
LLEG ("gui_lleg", Material.BONE, 26, true, "astools.use", true);
LLEG ("gui_lleg", Material.BONE, 26, true, "astools.use", true),
ITEM ("gui_item", Material.ARMOR_STAND, 34, true, "astools.use", false);
private final ItemStack item;
private final String config_id;
@ -73,6 +75,12 @@ public enum ArmorStandTool {
ArmorStandTool(String config_id, Material m, int slot, boolean forGui, String permission, boolean reverseSneaking) {
item = new ItemStack(m);
ItemMeta meta = item.getItemMeta();
if(meta != null) {
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
item.setItemMeta(meta);
}
this.config_id = config_id;
this.slot = slot;
this.forGui = forGui;

Datei anzeigen

@ -0,0 +1,49 @@
package com.gmail.st3venau.plugins.armorstandtools;
enum CommandType {
PLAYER ("Player", "plr", "astools.ascmd.add.player"),
CONSOLE("Console", "con", "astools.ascmd.add.console"),
BUNGEE ("Bungee", "bun", "astools.ascmd.add.bungee");
private final String name;
private final String tag;
private final String addPermission;
CommandType(String name, String tag, String addPermission) {
this.name = name;
this.tag = tag;
this.addPermission = addPermission;
}
String getTag() {
return tag;
}
String getName() {
return name;
}
String getAddPermission() {
return addPermission;
}
static CommandType fromTag(String tag) {
for(CommandType type : values()) {
if(type.tag.equalsIgnoreCase(tag)) {
return type;
}
}
return null;
}
static CommandType fromName(String name) {
for(CommandType type : values()) {
if(type.name.equalsIgnoreCase(name)) {
return type;
}
}
return null;
}
}

Datei anzeigen

@ -59,61 +59,71 @@ class Commands implements CommandExecutor, TabCompleter {
}
String name = " ";
if(as.getName().length() > 0 && !as.getName().equalsIgnoreCase("armor stand")) {
name = " (" + ChatColor.AQUA + as.getName() + ChatColor.RESET + ") ";
name = ChatColor.RESET + " (" + ChatColor.AQUA + as.getName() + ChatColor.RESET + ") ";
}
if(args.length > 0 && args[0].equalsIgnoreCase("view")) {
// ascmd view
if (!Utils.hasPermissionNode(p, "astools.ascmd.view")) {
ArmorStandCmdManager asCmdManager = new ArmorStandCmdManager(as);
if(args.length >= 1 && args[0].equalsIgnoreCase("list")) {
// [0]
// ascmd list
if (!Utils.hasPermissionNode(p, "astools.ascmd.list")) {
p.sendMessage(ChatColor.RED + Config.noCommandPerm);
return true;
}
ArmorStandCmd asCmd = new ArmorStandCmd(as);
if(asCmd.getCommand() == null) {
p.sendMessage("\n" + Config.closestAS + name + Config.hasNoCmd);
} else {
p.sendMessage("\n" + Config.closestAS + name + Config.hasCmd);
p.sendMessage(Config.type + ": " + ChatColor.YELLOW + asCmd.getType());
p.sendMessage(Config.command + ": " + ChatColor.YELLOW + asCmd.getCommand());
}
} else if(args.length > 0 && args[0].equalsIgnoreCase("remove")) {
// ascmd remove
listAssignedCommands(asCmdManager, name, p);
return true;
} else if(args.length >= 2 && args[0].equalsIgnoreCase("remove")) {
// [0] [1]
// ascmd remove <command_number>
if (!Utils.hasPermissionNode(p, "astools.ascmd.remove")) {
p.sendMessage(ChatColor.RED + Config.noCommandPerm);
return true;
}
if(ArmorStandCmd.removeAssignedCommand(as)) {
p.sendMessage("\n" + Config.unassignedCmd + name);
int n;
try {
n = Integer.parseInt(args[1]);
} catch (NumberFormatException e) {
p.sendMessage(ChatColor.RED + args[1] + " " + Config.isNotValidNumber);
return true;
}
if(asCmdManager.removeCommand(n - 1)) {
p.sendMessage("\n" + Config.command + ChatColor.GREEN + " #" + n + ChatColor.RESET + " " + Config.removedFromAs + name);
} else {
p.sendMessage("\n" + Config.closestAS + name + Config.hasNoCmd);
p.sendMessage(ChatColor.RED + args[1] + " " + Config.isNotValidNumber);
}
} else if(args.length >= 3 && args[0].equalsIgnoreCase("assign")) {
// ascmd assign <player/console> (command)
ArmorStandCmd asCmd = new ArmorStandCmd(as);
if(asCmd.getCommand() != null) {
p.sendMessage("\n" + Config.closestAS + name + Config.hasCmd);
p.sendMessage(Config.removeCmd + ": " + ChatColor.YELLOW + " /ascmd remove");
listAssignedCommands(asCmdManager, name, p);
return true;
}
Boolean isConsole = null;
if(args[1].equalsIgnoreCase("console")) {
isConsole = true;
if (!Utils.hasPermissionNode(p, "astools.ascmd.assign.console")) {
p.sendMessage(ChatColor.RED + Config.noCommandPerm);
return true;
}
} else if(args[1].equalsIgnoreCase("player")) {
isConsole = false;
if (!Utils.hasPermissionNode(p, "astools.ascmd.assign.player")) {
p.sendMessage(ChatColor.RED + Config.noCommandPerm);
return true;
}
}
if(isConsole == null) {
} else if(args.length >= 5 && args[0].equalsIgnoreCase("add")) {
// [0] [1] [2] [3] [4 - ...]
// ascmd add <priority> <delay> <player/console/bungee> <command/bungee_server_name>
CommandType type = CommandType.fromName(args[3]);
if(type == null) {
ascmdHelp(p);
return true;
}
if (!Utils.hasPermissionNode(p, type.getAddPermission())) {
p.sendMessage(ChatColor.RED + Config.noCommandPerm);
return true;
}
int priority;
try {
priority = Integer.parseInt(args[1]);
} catch (NumberFormatException e) {
p.sendMessage(ChatColor.RED + args[1] + " " + Config.isNotValidNumber);
return true;
}
int delay;
try {
delay = Integer.parseInt(args[2]);
} catch (NumberFormatException e) {
p.sendMessage(ChatColor.RED + args[2] + " " + Config.isNotValidNumber);
return true;
}
if(delay < 0) {
p.sendMessage(ChatColor.RED + args[2] + " " + Config.isNotValidNumber);
return true;
}
StringBuilder sb = new StringBuilder();
for(int i = 2; i < args.length; i++) {
for(int i = 4; i < args.length; i++) {
sb.append(args[i]).append(" ");
}
int startAt = sb.charAt(0) == '/' ? 1 : 0;
@ -122,26 +132,20 @@ class Commands implements CommandExecutor, TabCompleter {
ascmdHelp(p);
return true;
}
asCmd = new ArmorStandCmd(as, c, isConsole);
if(asCmd.save()) {
p.sendMessage("\n" + Config.assignedCmdToAS + name);
p.sendMessage(Config.type + ": " + ChatColor.YELLOW + asCmd.getType());
p.sendMessage(Config.command + ": " + ChatColor.YELLOW + asCmd.getCommand());
} else {
p.sendMessage("\n" + Config.assignCmdError + name);
}
asCmdManager.addCommand(new ArmorStandCmd(c, type, priority, delay), true);
listAssignedCommands(asCmdManager, name, p);
return true;
} else if(args.length >= 2 && args[0].equalsIgnoreCase("cooldown")) { //ascmd cooldown <ticks>/remove
if (!Utils.hasPermissionNode(p, "astools.ascmd.cooldown")) {
p.sendMessage(ChatColor.RED + Config.noCommandPerm);
return true;
}
ArmorStandCmd asCmd = new ArmorStandCmd(as);
if(asCmd.getCommand() == null) {
p.sendMessage(Config.closestAS + name + Config.hasNoCmd);
if(!asCmdManager.hasCommands()) {
p.sendMessage(Config.closestAS + name + Config.hasNoCmds);
return true;
}
if(args[1].equalsIgnoreCase("remove")) {
asCmd.setCooldownTime(-1);
asCmdManager.setCooldownTime(-1);
p.sendMessage(Config.cooldownRemovedFrom + " " + Config.closestAS + name);
} else {
int ticks;
@ -155,7 +159,7 @@ class Commands implements CommandExecutor, TabCompleter {
p.sendMessage(args[1] + " " + Config.isAnInvalidCooldown);
return true;
}
asCmd.setCooldownTime(ticks);
asCmdManager.setCooldownTime(ticks);
p.sendMessage(Config.cooldownSetTo + " " + ticks + " " + Config.ticksFor + " " + Config.closestAS + name);
}
return true;
@ -163,19 +167,35 @@ class Commands implements CommandExecutor, TabCompleter {
ascmdHelp(p);
return true;
}
return true;
}
return false;
}
private void listAssignedCommands(ArmorStandCmdManager asCmdManager, String name, Player p) {
if(asCmdManager.hasCommands()) {
p.sendMessage("\n" + Config.closestAS + name + Config.hasTheseCmdsAssigned);
List<ArmorStandCmd> list = asCmdManager.getCommands();
for(int n = 0; n < list.size(); n++) {
ArmorStandCmd asCmd = list.get(n);
// #1 Priority:0 Delay:0 Type:Player Command:cmd
p.sendMessage(
ChatColor.GREEN + "#" + (n + 1) + " " +
ChatColor.LIGHT_PURPLE + Config.priority + ":" + ChatColor.RESET + asCmd.priority() + " " +
ChatColor.YELLOW + Config.delay + ":" + ChatColor.RESET + asCmd.delay() + " " +
ChatColor.GOLD + Config.type + ":" + ChatColor.RESET + asCmd.type().getName() + " " +
ChatColor.AQUA + Config.command + ":" + ChatColor.RESET + asCmd.command()
);
}
} else {
p.sendMessage("\n" + Config.closestAS + name + Config.hasNoCmds);
}
}
private void ascmdHelp(Player p) {
p.sendMessage("\n" + ChatColor.AQUA + Config.ascmdHelp);
p.sendMessage(Config.viewCmd + ": " + ChatColor.YELLOW + "/ascmd view");
p.sendMessage(Config.removeCmd + ": " + ChatColor.YELLOW + "/ascmd remove");
p.sendMessage(Config.assignConsole + ":");
p.sendMessage(ChatColor.YELLOW + "/ascmd assign console <command>");
p.sendMessage(Config.assignPlayer + ":");
p.sendMessage(ChatColor.YELLOW + "/ascmd assign player <command>");
p.sendMessage("\n" + ChatColor.AQUA + Config.cmdHelp);
p.sendMessage(Config.listAssignedCmds + ": " + ChatColor.YELLOW + "/ascmd list");
p.sendMessage(Config.addACmd + ":" + ChatColor.YELLOW + "/ascmd add <priority> <delay> <player/console/bungee> <command/bungee_server_name>");
p.sendMessage(Config.removeACmd + ": " + ChatColor.YELLOW + "/ascmd remove <command_number>");
p.sendMessage(Config.setCooldown + ":");
p.sendMessage(ChatColor.YELLOW + "/ascmd cooldown <ticks>");
p.sendMessage(Config.removeCooldown + ":");
@ -183,14 +203,17 @@ class Commands implements CommandExecutor, TabCompleter {
}
private ArmorStand getNearbyArmorStand(Player p) {
ArmorStand closest = null;
double dist = 1000000;
ArmorStand closestAs = null;
double closestDist = 1000000;
for(Entity e : p.getNearbyEntities(4, 4, 4)) {
if(e instanceof ArmorStand && e.getLocation().distanceSquared(p.getLocation()) < dist) {
closest = (ArmorStand) e;
if(!(e instanceof ArmorStand)) continue;
double dist = e.getLocation().distanceSquared(p.getLocation());
if(dist < closestDist) {
closestDist = dist;
closestAs = (ArmorStand) e;
}
}
return closest;
return closestAs;
}
public List<String> onTabComplete(@NotNull CommandSender sender, Command command, @NotNull String alias, String[] args) {
@ -202,17 +225,23 @@ class Commands implements CommandExecutor, TabCompleter {
}
if (cmd.equals("ascmd")) {
if (args.length == 1) {
for(String s : Arrays.asList("view", "remove", "assign", "cooldown")) {
for(String s : Arrays.asList("list", "remove", "add", "cooldown")) {
if(s.startsWith(typed)) {
list.add(s);
}
}
} else if (args.length == 2 && args[0].equalsIgnoreCase("assign")) {
for(String s : Arrays.asList("player", "console")) {
if(s.startsWith(typed)) {
} else if (args[0].equalsIgnoreCase("add")) {
if(args.length == 2 && typed.length() == 0) {
list.add("priority");
} if(args.length == 3 && typed.length() == 0) {
list.add("delay");
} else if(args.length == 4) {
for (String s : Arrays.asList("player", "console", "bungee")) {
if (s.startsWith(typed)) {
list.add(s);
}
}
}
} else if (args.length == 2 && args[0].equalsIgnoreCase("cooldown")) {
String s = "remove";
if(s.startsWith(typed)) {

Datei anzeigen

@ -51,6 +51,7 @@ class Config {
static boolean ignoreWGForASCmdExecution = false;
static boolean saveToolCreatesCommandBlock = true;
static boolean logGeneratedSummonCommands = false;
static boolean crouchRightClickOpensGUI = false;
static final ArrayList<String> deniedCommands = new ArrayList<>();
@ -60,14 +61,16 @@ class Config {
isOn, isOff, gravity, arms, invul, equip, locked,
unLocked, notConsole, giveMsg1, giveMsg2, conReload,
noRelPerm, noAirError, invalidName, wgNoPerm, currently,
noCommandPerm, generalNoPerm, armorStand, none,
guiInUse, noASNearBy, closestAS, creativeRequired,
hasNoCmd, hasCmd, type, command, unassignedCmd,
assignedCmdToAS, assignCmdError, ascmdHelp, viewCmd,
removeCmd, assignConsole, assignPlayer, executeCmdError,
noCommandPerm, generalNoPerm, armorStand, none, guiInUse,
noASNearBy, closestAS, creativeRequired, type, command,
cmdOnCooldown, cooldownRemovedFrom, isAnInvalidCooldown,
cooldownSetTo, ticksFor, setCooldown, removeCooldown,
cmdNotAllowed, glow, crouch, click, finish;
cmdNotAllowed, glow, crouch, click, finish, inventoryFull,
configuredArmorStand, name, inventory, cmdsAssigned,
invisible, invuln, glowing, attributes, items, stacks,
hasTheseCmdsAssigned, hasNoCmds, priority, delay,
errorExecutingCmd, isNotValidNumber, removedFromAs,
listAssignedCmds, addACmd, removeACmd, cmdHelp;
static void reload() {
reloadMainConfig();
@ -103,6 +106,7 @@ class Config {
showDebugMessages = config.getBoolean("showDebugMessages", false);
saveToolCreatesCommandBlock = config.getBoolean("saveToolCreatesCommandBlock", true);
logGeneratedSummonCommands = config.getBoolean("logGeneratedSummonCommands", false);
crouchRightClickOpensGUI = config.getBoolean("crouchRightClickOpensGUI", false);
AST.activeTool.clear();
AST.selectedArmorStand.clear();
@ -207,19 +211,8 @@ class Config {
guiInUse = languageConfig.getString("guiInUse");
noASNearBy = languageConfig.getString("noASNearBy");
closestAS = languageConfig.getString("closestAS");
hasNoCmd = languageConfig.getString("hasNoCmd");
hasCmd = languageConfig.getString("hasCmd");
type = languageConfig.getString("type");
command = languageConfig.getString("command");
unassignedCmd = languageConfig.getString("unassignedCmd");
assignedCmdToAS = languageConfig.getString("assignedCmdToAS");
assignCmdError = languageConfig.getString("assignCmdError");
ascmdHelp = languageConfig.getString("ascmdHelp");
viewCmd = languageConfig.getString("viewCmd");
removeCmd = languageConfig.getString("removeCmd");
assignConsole = languageConfig.getString("assignConsole");
assignPlayer = languageConfig.getString("assignPlayer");
executeCmdError = languageConfig.getString("executeCmdError");
creativeRequired = languageConfig.getString("creativeRequired");
cmdOnCooldown = languageConfig.getString("cmdOnCooldown");
cooldownRemovedFrom = languageConfig.getString("cooldownRemovedFrom");
@ -234,6 +227,28 @@ class Config {
crouch = languageConfig.getString("crouch");
click = languageConfig.getString("click");
finish = languageConfig.getString("finish");
inventoryFull = languageConfig.getString("inventoryFull");
configuredArmorStand = languageConfig.getString("configuredArmorStand");
name = languageConfig.getString("name");
inventory = languageConfig.getString("inventory");
cmdsAssigned = languageConfig.getString("cmdsAssigned");
invisible = languageConfig.getString("invisible");
invuln = languageConfig.getString("invuln");
glowing = languageConfig.getString("glowing");
attributes = languageConfig.getString("attributes");
items = languageConfig.getString("items");
stacks = languageConfig.getString("stacks");
hasTheseCmdsAssigned = languageConfig.getString("hasTheseCmdsAssigned");
hasNoCmds = languageConfig.getString("hasNoCmds");
priority = languageConfig.getString("priority");
delay = languageConfig.getString("delay");
errorExecutingCmd = languageConfig.getString("errorExecutingCmd");
isNotValidNumber = languageConfig.getString("isNotValidNumber");
removedFromAs = languageConfig.getString("removedFromAs");
listAssignedCmds = languageConfig.getString("listAssignedCmds");
addACmd = languageConfig.getString("addACmd");
removeACmd = languageConfig.getString("removeACmd");
cmdHelp = languageConfig.getString("cmdHelp");
}
private static ItemStack toItemStack(String s) {

Datei anzeigen

@ -2,12 +2,14 @@ package com.gmail.st3venau.plugins.armorstandtools;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.GameRule;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.ItemFrame;
@ -56,12 +58,21 @@ public class MainListener implements Listener {
public void onPlayerInteractAtEntity(PlayerInteractAtEntityEvent event) {
if(!(event.getRightClicked() instanceof ArmorStand as)) return;
Player p = event.getPlayer();
if(!event.isCancelled() && ArmorStandGUI.isInUse(as)) {
if (ArmorStandGUI.isInUse(as)) {
Utils.title(p, Config.guiInUse);
event.setCancelled(true);
return;
}
if(!event.isCancelled() && stopEditing(p, false)) {
if(stopEditing(p, false)) {
event.setCancelled(true);
return;
}
if(Config.crouchRightClickOpensGUI && p.isSneaking() && Utils.hasPermissionNode(p, "astools.use")) {
if (!AST.playerHasPermission(p, as.getLocation().getBlock(), null)) {
p.sendMessage(ChatColor.RED + Config.generalNoPerm);
return;
}
new ArmorStandGUI(as, p);
event.setCancelled(true);
return;
}
@ -116,14 +127,10 @@ public class MainListener implements Listener {
return;
}
if((Config.ignoreWGForASCmdExecution || !event.isCancelled()) && !p.isSneaking()) {
ArmorStandCmd asCmd = new ArmorStandCmd(as);
if (asCmd.getCommand() != null) {
ArmorStandCmdManager asCmdManager = new ArmorStandCmdManager(as);
if (asCmdManager.hasCommands() && Utils.hasPermissionNode(p, "astools.ascmd.execute")) {
event.setCancelled(true);
if (Utils.hasPermissionNode(p, "astools.ascmd.execute")) {
if (!asCmd.execute(p)) {
p.sendMessage(Config.executeCmdError);
}
}
asCmdManager.executeCommands(p);
}
}
}
@ -267,10 +274,36 @@ public class MainListener implements Listener {
event.setCancelled(true);
return;
}
ArmorStandTool tool = ArmorStandTool.get(event.getItem());
Action action = event.getAction();
BlockFace blockFace = event.getBlockFace();
ItemStack inHand = event.getItem();
Block b = event.getClickedBlock();
ArmorStandTool tool = ArmorStandTool.get(inHand);
if(inHand != null && tool == null && b != null && action == Action.RIGHT_CLICK_BLOCK && blockFace != BlockFace.DOWN && inHand.getType() == Material.ARMOR_STAND) {
b = b.getRelative(blockFace);
if (!AST.playerHasPermission(p, b, ArmorStandTool.ITEM)) {
p.sendMessage(ChatColor.RED + Config.generalNoPerm);
return;
}
ArmorStandMeta asm = ArmorStandMeta.fromItem(inHand);
if(asm != null) {
event.setCancelled(true);
Location l = b.getLocation().add(0.5, 0, 0.5);
ArmorStand as = (ArmorStand) b.getWorld().spawnEntity(l, EntityType.ARMOR_STAND);
asm.applyToArmorStand(as);
if(p.getGameMode() != GameMode.CREATIVE) {
if(inHand.getAmount() == 1) {
p.getInventory().setItemInMainHand(null);
} else {
inHand.setAmount(inHand.getAmount() - 1);
p.getInventory().setItemInMainHand(inHand);
}
}
return;
}
}
if(tool == null) return;
event.setCancelled(true);
Action action = event.getAction();
if(action == Action.LEFT_CLICK_AIR || action == Action.LEFT_CLICK_BLOCK) {
Utils.cycleInventory(p);
} else if((action == Action.RIGHT_CLICK_BLOCK || action == Action.RIGHT_CLICK_AIR) && tool == ArmorStandTool.SUMMON) {
@ -453,10 +486,10 @@ public class MainListener implements Listener {
attachment.setPermission("astools.head", true);
attachment.setPermission("astools.reload", true);
attachment.setPermission("astools.cmdblock", true);
attachment.setPermission("astools.ascmd.view", true);
attachment.setPermission("astools.ascmd.list", true);
attachment.setPermission("astools.ascmd.remove", true);
attachment.setPermission("astools.ascmd.assign.player", true);
attachment.setPermission("astools.ascmd.assign.console", true);
attachment.setPermission("astools.ascmd.add.player", true);
attachment.setPermission("astools.ascmd.add.console", true);
attachment.setPermission("astools.ascmd.execute", true);
attachment.setPermission("astools.ascmd.cooldown", true);
//attachment.setPermission("astools.bypass-wg-flag", true);

Datei anzeigen

@ -7,7 +7,6 @@ import org.bukkit.block.CommandBlock;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.EquipmentSlot;
@ -99,48 +98,6 @@ class Utils {
return slotsDisabled;
}
static ArmorStand cloneArmorStand(ArmorStand as) {
ArmorStand clone = (ArmorStand) as.getWorld().spawnEntity(as.getLocation().add(1, 0, 0), EntityType.ARMOR_STAND);
EntityEquipment asEquipment = as.getEquipment();
EntityEquipment cloneEquipment = clone.getEquipment();
if(asEquipment != null && cloneEquipment != null) {
cloneEquipment.setHelmet(asEquipment.getHelmet());
cloneEquipment.setChestplate(asEquipment.getChestplate());
cloneEquipment.setLeggings(asEquipment.getLeggings());
cloneEquipment.setBoots(asEquipment.getBoots());
cloneEquipment.setItemInMainHand(asEquipment.getItemInMainHand());
cloneEquipment.setItemInOffHand(asEquipment.getItemInOffHand());
}
clone.setHeadPose(as.getHeadPose());
clone.setBodyPose(as.getBodyPose());
clone.setLeftArmPose(as.getLeftArmPose());
clone.setRightArmPose(as.getRightArmPose());
clone.setLeftLegPose(as.getLeftLegPose());
clone.setRightLegPose(as.getRightLegPose());
clone.setGravity(as.hasGravity());
clone.setVisible(as.isVisible());
clone.setBasePlate(as.hasBasePlate());
clone.setArms(as.hasArms());
clone.setCustomName(as.getCustomName());
clone.setCustomNameVisible(as.isCustomNameVisible());
clone.setSmall(as.isSmall());
clone.setInvulnerable(as.isInvulnerable());
clone.setGlowing(as.isGlowing());
for(EquipmentSlot slot : EquipmentSlot.values()) {
for(ArmorStand.LockType lockType : ArmorStand.LockType.values()) {
if(as.hasEquipmentLock(slot, lockType)) {
clone.addEquipmentLock(slot, lockType);
}
}
}
ArmorStandCmd asCmd = new ArmorStandCmd(as);
if(asCmd.getCommand() != null) {
asCmd.cloneTo(clone);
}
clone.setMetadata("clone", new FixedMetadataValue(AST.plugin, true));
return clone;
}
static boolean hasPermissionNode(Player p, String perm) {
if ((p == null) || p.isOp()) {
return true;

Datei anzeigen

@ -25,10 +25,10 @@
# /astools Give yourself all of the armor stand tools (Note: Clears your inventory)
# /astools reload Reload the armor stand tools plugin config file
# /ast Alias for the /astools
# /ascmd assign console <command> Assign a console command to the nearest armor stand (within 4 blocks)
# /ascmd assign player <command> Assign a player command to the nearest armor stand
# /ascmd remove Remove the command assigned to the nearest armor stand
# /ascmd view View the command assigned to the nearest armor stand
# /ascmd add <priority> <delay> <player/console/bungee> <command/bungee_server_name>
# Add an assigned command to the nearest armor stand. See the assigning commands section below for more info.
# /ascmd remove <command_number> Remove the command assigned to the nearest armor stand
# /ascmd list List the commands assigned to the nearest armor stand
# /ascmd cooldown <ticks> Set the cooldown for the command on nearest armor stand (Setting this overrides the default cooldown from config.yml)
# /ascmd cooldown remove Remove the cooldown for the command on nearest armor stand (Default cooldown set in config.yml will be used)
# Note: Commands may include a %player% placeholder, which will get replaced by the executing player's name at time of execution.
@ -41,20 +41,42 @@
# astools.summon Permission to use the summon tool (Summons an armor stand without requiring the materials)
# astools.head Permission to use the player head tool (Ability to specify a player head for an armor stand)
# astools.cmdblock Permission to use the save tool (Creates a command block)
# astools.ascmd.assign.console Permission to assign a console command to an armor stand
# astools.ascmd.assign.player Permission to assign a player command to an armor stand
# astools.glow Permission to use the glow tool (Glow effect on armor stands)
# astools.ascmd.add.console Permission to add a console command to an armor stand (Previously astools.ascmd.assign.console)
# astools.ascmd.add.player Permission to add a player command to an armor stand (Previously astools.ascmd.assign.player)
# astools.ascmd.add.bungee Permission to add a bungee command to an armor stand (See below for details)
# astools.ascmd.remove Permission to remove a command from an armor stand
# astools.ascmd.view Permission to view the command assigned to an armor stand
# astools.ascmd.execute Permission to execute a command assigned to an armor stand by (on right click)
# astools.ascmd.cooldown Permission to add a cooldown to commands assigned to an armor stand
# astools.ascmd.list Permission to list the commands assigned to an armor stand (Previously astools.ascmd.view)
# astools.ascmd.cooldown Permission to add/remove a cooldown to commands assigned to an armor stand
# astools.ascmd.execute Permission to execute commands assigned to an armor stand by (on right click)
# astools.bypass-wg-flag Permission to bypass AST's custom worldguard flag (see below for more details)
#
# Assigning Commands to Armor Stands:
# - Stand close to the armor stand (The nearest armor stand within 4 blocks is selected) and use the command:
# /ascmd add <priority> <delay> <player/console/bungee> <command/bungee_server_name>
# - <priority>: When multiple commands are assigned, commands with the lowest priority number are executed first.
# Command with the same priority can be executed in any order.
# - <delay>: Delay in ticks before the command is executed.
# - <player\console\bungee>: Player commands are executed as if they were typed by the player.
# Console commands are executed by the console.
# Bungee commands are a special case (see below).
# - <command/bungee_server_name>: The command to be executed. To use the executing player's name in the command, use the
# placeholder %player% - it will be replaced with the players name at time of execution.
# - When a player with the astools.ascmd.execute permission right-clicks on an armor stand, commands assigned to that
# armor stand are executed.
# - Warning: Make sure you are careful when assigning console commands. Any player with the astools.ascmd.execute
# permission will be able to execute the command.
# - By default, any command assigned to an armor stand will use the default cooldown set in config.yml. This can be
# set on an individual basis using the /ascmd cooldown <ticks> command.
# - Bungee commands: These are used to send the player to a different BungeeCord server. E.g. This will add a command
# to send the player to a server called server1: /ascmd add 0 0 bungee server1
#
# WorldGuard Integration:
# - If a player does not have build permission for the region, that player will also be denied the use of AST in that region.
# - Additionally, there is a custom region flag named 'ast' which defaults to Allow, this can be changed to Deny if you wish to have a
# region in which players have build permission, but not permission to use AST.
# - The ast worldguard flag is ignored for any player with the permission node 'astools.bypass-wg-flag'. This means that a player with
# this permission can use AST in worldguard regions even if the ast flag for that region is set to Deny.
# - Additionally, there is a custom region flag named 'ast' which defaults to Allow, this can be changed to Deny if you wish
# to have a region in which players have build permission, but not permission to use AST.
# - The ast worldguard flag is ignored for any player with the permission node 'astools.bypass-wg-flag'. This means that a
# player with this permission can use AST in worldguard regions even if the ast flag for that region is set to Deny.
# - The ast worldguard flag is also ignored for players that have op.
#
@ -63,6 +85,7 @@ integrateWithWorldGuard: true
allowMovingStandsBetweenWorlds: false
deactivateToolsOnWorldChange: true
requireCreativeForSaveAsCmdBlock: false
crouchRightClickOpensGUI: false
defaultASCmdCooldownTicks: 0
bypassWorldguardForASCmdExecution: false
saveToolCreatesCommandBlock: true
@ -136,3 +159,4 @@ enableTool:
gui_rarm: true
gui_lleg: true
gui_rleg: true
gui_item: true

Datei anzeigen

@ -63,19 +63,8 @@ guiInUse: 'This armor stands GUI is in use'
# New since v2.4.0:
noASNearBy: 'No armor stand found near by'
closestAS: 'Closest armor stand'
hasNoCmd: 'has no command assigned'
hasCmd: 'has an assigned a command'
type: 'Type'
command: 'Command'
unassignedCmd: 'Unassigned command from armor stand'
assignedCmdToAS: 'Assigned command to closest armor stand'
assignCmdError: 'An error occured while assigning command to closest armor stand'
ascmdHelp: 'This command is used to assign a command to the nearest armor stand (within 4 blocks). The command is executed when the armor stand is right clicked.'
viewCmd: 'View assigned command'
removeCmd: 'Remove assigned command'
assignConsole: 'Assign a command to be executed by the console'
assignPlayer: 'Assign a command to be executed by the player'
executeCmdError: 'An error occured executing the command assigned to this armor stand'
# New since v3.2.0
creativeRequired: 'Creative mode is required to save an armor stand as a command block'
# New since v3.3.0
@ -93,7 +82,30 @@ cmdNotAllowed: 'That command is not allowed while using Armor Stand Tools'
crouch: 'Crouch'
click: 'Click'
finish: 'Finish'
#
#New since v4.3.0
configuredArmorStand: 'Configured Armor Stand'
inventoryFull: 'Inventory full. Try again.'
name: 'Name'
inventory: 'Inventory'
items: 'Items'
stacks: 'Stacks'
cmdsAssigned: 'commands assigned'
invisible: 'Invisible'
invuln: 'Invulnerable'
glowing: 'Glowing'
attributes: 'Attributes'
hasTheseCmdsAssigned: 'has these commands assigned'
hasNoCmds: 'has no commands assigned'
priority: 'Priority'
delay: 'Delay'
errorExecutingCmd: 'An error occured executing command'
isNotValidNumber: 'is not a valid number'
removedFromAs: 'removed from armor stand'
listAssignedCmds: 'List assigned commands'
addACmd: 'Add a command'
removeACmd: 'Remove a command'
cmdHelp: 'This command is used to add/remove commands to the nearest armor stand (within 4 blocks). The commands are executed when the armor stand is right clicked, lowest priority first.'
#############################
# Tool names & descriptions #
#############################
@ -264,19 +276,31 @@ tool:
lore:
gui_head:
name: 'Move Head'
lore: 'Change the head position'
lore:
- 'Change the head position'
gui_body:
name: 'Move Body'
lore: 'Change the body position'
lore:
- 'Change the body position'
gui_larm:
name: 'Move Left Arm'
lore: 'Change the left arm position'
lore:
- 'Change the left arm position'
gui_rarm:
name: 'Move Right Arm'
lore: 'Change the right arm position'
lore:
- 'Change the right arm position'
gui_lleg:
name: 'Move Left Leg'
lore: 'Change the left leg position'
lore:
- 'Change the left leg position'
gui_rleg:
name: 'Move Right Leg'
lore: 'Change the right leg position'
lore:
- 'Change the right leg position'
gui_item:
name: 'Pick Up As Item'
lore:
- 'Create armor stand item for this armor stand'
- 'Creative mode: Armor stand stays'
- 'Survival mode: Armor stand is deleted'

Datei anzeigen

@ -11,5 +11,5 @@ commands:
aliases: ast
usage: Usage /astools or /astools reload
ascmd:
description: View/Remove/Assign the command assigned to the nearest armor stand
usage: Usage /ascmd view, /ascmd remove, /ascmd assign <player/console> <command>
description: List/Add/Remove commands assigned to the nearest armor stand
usage: Usage /ascmd list, /ascmd remove <command_number>, /ascmd add <priority> <delay> <player/console/bungee> <command/bungee_server_name>