3
0
Mirror von https://github.com/St3venAU/ArmorStandTools.git synchronisiert 2024-12-27 12:00:07 +01:00

Added armor stand command cooldown

Dieser Commit ist enthalten in:
Steven 2019-03-15 15:33:34 +08:00
Ursprung 2bad136ebe
Commit 42d13d4e20
13 geänderte Dateien mit 246 neuen und 118 gelöschten Zeilen

Datei anzeigen

@ -9,7 +9,7 @@ I wanted to create an armor stand for each kit in my mini-game, and I quickly be
Compatibility
-------------
- Armor Stand Tools v3.2.0 - Spigot/CraftBukkit 1.13 only
- Armor Stand Tools v3.x.x - Spigot/CraftBukkit 1.13.x only
- Armor Stand Tools v2.4.3 - Spigot/CraftBukkit 1.8, 1.9, 1.10, 1.11, 1.12 (https://www.spigotmc.org/resources/armor-stand-tools.2237/download?version=175162)
Features
@ -35,6 +35,7 @@ Assigning Commands
- 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 armor stands command will use the cooldown set in config.yml. This can be set on an individual basis using the /ascmd cooldown <ticks> command.
Commands
--------
@ -45,6 +46,8 @@ Commands
- /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 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
-----------

Datei anzeigen

@ -1,24 +1,31 @@
package com.gmail.St3venAU.plugins.ArmorStandTools;
import org.bukkit.Bukkit;
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.List;
class ArmorStandCmd {
private final ArmorStand armorStand;
private String command;
private final boolean console;
private boolean console;
ArmorStandCmd(String command, boolean console) {
ArmorStandCmd(ArmorStand as, String command, boolean console) {
this.armorStand = as;
this.command = command;
this.console = console;
}
static ArmorStandCmd fromAS(ArmorStand as) {
for(String tag : as.getScoreboardTags()) {
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:")) {
@ -26,19 +33,22 @@ class ArmorStandCmd {
if(cmd.charAt(0) == '/') {
cmd = cmd.substring(1);
}
if(cmd.length() == 0) return null;
return new ArmorStandCmd(cmd, true);
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 null;
return new ArmorStandCmd(cmd, false);
if(cmd.length() == 0) return;
this.command = cmd;
this.console = false;
return;
}
}
}
return null;
}
private String getTag() {
@ -50,6 +60,12 @@ class ArmorStandCmd {
}
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);
@ -64,17 +80,17 @@ class ArmorStandCmd {
}
}
boolean assignTo(ArmorStand as) {
removeAssignedCommand(as);
boolean save() {
removeAssignedCommand(armorStand);
if (command == null) return false;
cleanUpCommand();
return command.length() != 0 && as.addScoreboardTag(getTag());
return command.length() != 0 && armorStand.addScoreboardTag(getTag());
}
static void cloneASCommand(ArmorStand original, ArmorStand clone) {
ArmorStandCmd asCmd = fromAS(original);
if(asCmd == null) return;
asCmd.assignTo(clone);
void cloneTo(ArmorStand clone) {
if(command == null) return;
ArmorStandCmd asCmd = new ArmorStandCmd(clone, command, console);
asCmd.save();
}
String getType() {
@ -94,5 +110,55 @@ class ArmorStandCmd {
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(Main.plugin, true));
new BukkitRunnable() {
@Override
public void run() {
armorStand.removeMetadata("ast-cmd-cooldown", Main.plugin);
}
}.runTaskLater(Main.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<String>();
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

@ -66,7 +66,7 @@ public enum ArmorStandTool {
return item;
}
boolean is(ItemStack is) {
private boolean is(ItemStack is) {
return is != null && is.getType() == item.getType() && is.hasItemMeta() &&
is.getItemMeta().hasDisplayName() &&
is.getItemMeta().getDisplayName().equals(item.getItemMeta().getDisplayName());

Datei anzeigen

@ -74,8 +74,8 @@ class Commands implements CommandExecutor, TabCompleter {
p.sendMessage(ChatColor.RED + Config.noCommandPerm);
return true;
}
ArmorStandCmd asCmd = ArmorStandCmd.fromAS(as);
if(asCmd == null) {
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);
@ -95,8 +95,8 @@ class Commands implements CommandExecutor, TabCompleter {
}
} else if(args.length >= 3 && args[0].equalsIgnoreCase("assign")) {
// ascmd assign <player/console> (command)
ArmorStandCmd asCmd = ArmorStandCmd.fromAS(as);
if(asCmd != null) {
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");
return true;
@ -129,14 +129,40 @@ class Commands implements CommandExecutor, TabCompleter {
ascmdHelp(p);
return true;
}
asCmd = new ArmorStandCmd(c, isConsole);
if(asCmd.assignTo(as)) {
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);
}
} else if(args.length >= 2 && args[0].equalsIgnoreCase("cooldown")) { //ascmd cooldown <ticks>/remove
ArmorStandCmd asCmd = new ArmorStandCmd(as);
if(asCmd.getCommand() == null) {
p.sendMessage(Config.closestAS + name + Config.hasNoCmd);
return true;
}
if(args[1].equalsIgnoreCase("remove")) {
asCmd.setCooldownTime(-1);
p.sendMessage(Config.cooldownRemovedFrom + " " + Config.closestAS + name);
return true;
} else {
int ticks;
try {
ticks = Integer.parseInt(args[1]);
} catch (NumberFormatException e) {
p.sendMessage(args[1] + " " + Config.isAnInvalidCooldown);
return true;
}
if(ticks < 0) {
p.sendMessage(args[1] + " " + Config.isAnInvalidCooldown);
return true;
}
asCmd.setCooldownTime(ticks);
p.sendMessage(Config.cooldownSetTo + " " + ticks + " " + Config.ticksFor + " " + Config.closestAS + name);
return true;
}
} else {
ascmdHelp(p);
return true;
@ -154,6 +180,10 @@ class Commands implements CommandExecutor, TabCompleter {
p.sendMessage(ChatColor.YELLOW + "/ascmd assign console <command>");
p.sendMessage(Config.assignPlayer + ":");
p.sendMessage(ChatColor.YELLOW + "/ascmd assign player <command>");
p.sendMessage(Config.setCooldown + ":");
p.sendMessage(ChatColor.YELLOW + "/ascmd cooldown <ticks>");
p.sendMessage(Config.removeCooldown + ":");
p.sendMessage(ChatColor.YELLOW + "/ascmd cooldown remove");
}
private ArmorStand getNearbyArmorStand(Player p) {
@ -176,17 +206,22 @@ class Commands implements CommandExecutor, TabCompleter {
}
if (cmd.equals("ascmd")) {
if (args.length == 1) {
for(String s : Arrays.asList("view", "remove", "assign")) {
for(String s : Arrays.asList("view", "remove", "assign", "cooldown")) {
if(s.startsWith(typed)) {
list.add(s);
}
}
} else if (args.length == 2 && args[0].toLowerCase().equals("assign")) {
} else if (args.length == 2 && args[0].equalsIgnoreCase("assign")) {
for(String s : Arrays.asList("player", "console")) {
if(s.startsWith(typed)) {
list.add(s);
}
}
} else if (args.length == 2 && args[0].equalsIgnoreCase("cooldown")) {
String s = "remove";
if(s.startsWith(typed)) {
list.add(s);
}
}
}
return list;

Datei anzeigen

@ -10,7 +10,7 @@ import org.bukkit.plugin.Plugin;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.charset.Charset;
import java.util.logging.Level;
class Config {
@ -19,23 +19,25 @@ class Config {
private static File languageConfigFile;
private static FileConfiguration languageConfig;
public static WorldGuardPlugin worldGuardPlugin;
static WorldGuardPlugin worldGuardPlugin;
public static ItemStack helmet, chest, pants, boots, itemInHand, itemInOffHand;
public static boolean isVisible = true;
public static boolean isSmall = false;
public static boolean hasArms = true;
public static boolean hasBasePlate = false;
public static boolean hasGravity = false;
public static String defaultName = "";
public static boolean invulnerable = false;
public static boolean equipmentLock = false;
public static boolean allowMoveWorld = false;
public static boolean deactivateOnWorldChange = true;
public static boolean debug = false;
public static boolean requireCreative = false;
static ItemStack helmet, chest, pants, boots, itemInHand, itemInOffHand;
public static String
static boolean isVisible = true;
static boolean isSmall = false;
static boolean hasArms = true;
static boolean hasBasePlate = false;
static boolean hasGravity = false;
static String defaultName = "";
static boolean invulnerable = false;
static boolean equipmentLock = false;
static boolean allowMoveWorld = false;
static boolean deactivateOnWorldChange = true;
static boolean debug = false;
static boolean requireCreative = false;
static int defaultASCmdCooldownTicks = 0;
static String
invReturned, asDropped, asVisible, isTrue, isFalse,
carrying, cbCreated, size, small, normal, basePlate,
isOn, isOff, gravity, arms, invul, equip, locked,
@ -46,14 +48,16 @@ class Config {
guiInUse, noASNearBy, closestAS, creativeRequired,
hasNoCmd, hasCmd, type, command, unassignedCmd,
assignedCmdToAS, assignCmdError, ascmdHelp, viewCmd,
removeCmd, assignConsole, assignPlayer, executeCmdError;
removeCmd, assignConsole, assignPlayer, executeCmdError,
cmdOnCooldown, cooldownRemovedFrom, isAnInvalidCooldown,
cooldownSetTo, ticksFor, setCooldown, removeCooldown;
public static void reload(Main main) {
static void reload(Main main) {
plugin = main;
reload();
}
public static void reload() {
static void reload() {
reloadMainConfig();
saveDefaultLanguageConfig();
reloadLanguageConfig();
@ -110,30 +114,38 @@ class Config {
assignPlayer = languageConfig.getString("assignPlayer");
executeCmdError = languageConfig.getString("executeCmdError");
creativeRequired = languageConfig.getString("creativeRequired");
cmdOnCooldown = languageConfig.getString("cmdOnCooldown");
cooldownRemovedFrom = languageConfig.getString("cooldownRemovedFrom");
isAnInvalidCooldown = languageConfig.getString("isAnInvalidCooldown");
cooldownSetTo = languageConfig.getString("cooldownSetTo");
ticksFor = languageConfig.getString("ticksFor");
setCooldown = languageConfig.getString("setCooldown");
ticksFor = languageConfig.getString("ticksFor");
}
private static void reloadMainConfig() {
plugin.saveDefaultConfig();
plugin.reloadConfig();
FileConfiguration config= plugin.getConfig();
helmet = toItemStack(config.getString("helmet"));
chest = toItemStack(config.getString("chest"));
pants = toItemStack(config.getString("pants"));
boots = toItemStack(config.getString("boots"));
itemInHand = toItemStack(config.getString("inHand"));
itemInOffHand = toItemStack(config.getString("inOffHand"));
isVisible = config.getBoolean("isVisible");
isSmall = config.getBoolean("isSmall");
hasArms = config.getBoolean("hasArms");
hasBasePlate = config.getBoolean("hasBasePlate");
hasGravity = config.getBoolean("hasGravity");
defaultName = config.getString("name");
invulnerable = config.getBoolean("invulnerable");
equipmentLock = config.getBoolean("equipmentLock");
allowMoveWorld = config.getBoolean("allowMovingStandsBetweenWorlds");
deactivateOnWorldChange = config.getBoolean("deactivateToolsOnWorldChange");
requireCreative = config.getBoolean("requireCreativeForSaveAsCmdBlock");
debug = config.getBoolean("debug", false);
FileConfiguration config = plugin.getConfig();
helmet = toItemStack(config.getString("helmet"));
chest = toItemStack(config.getString("chest"));
pants = toItemStack(config.getString("pants"));
boots = toItemStack(config.getString("boots"));
itemInHand = toItemStack(config.getString("inHand"));
itemInOffHand = toItemStack(config.getString("inOffHand"));
isVisible = config.getBoolean("isVisible");
isSmall = config.getBoolean("isSmall");
hasArms = config.getBoolean("hasArms");
hasBasePlate = config.getBoolean("hasBasePlate");
hasGravity = config.getBoolean("hasGravity");
defaultName = config.getString("name");
invulnerable = config.getBoolean("invulnerable");
equipmentLock = config.getBoolean("equipmentLock");
allowMoveWorld = config.getBoolean("allowMovingStandsBetweenWorlds");
deactivateOnWorldChange = config.getBoolean("deactivateToolsOnWorldChange");
requireCreative = config.getBoolean("requireCreativeForSaveAsCmdBlock");
defaultASCmdCooldownTicks = config.getInt("defaultASCmdCooldownTicks");
debug = config.getBoolean("debug", false);
plugin.carryingArmorStand.clear();
for(ArmorStandTool tool : ArmorStandTool.values()) {
@ -148,7 +160,7 @@ class Config {
}
catch (Throwable e) {
e.printStackTrace();
plugin.getLogger().log(Level.WARNING, "PlotSquared plugin was found, but there was an error initializing PlotSquared support enabled.");
plugin.getLogger().log(Level.WARNING, "PlotSquared plugin was found, but there was an error initializing PlotSquared support.");
}
} else {
plugin.getLogger().log(Level.INFO, "PlotSquared plugin not found. Continuing without PlotSquared support.");
@ -171,7 +183,7 @@ class Config {
languageConfig = YamlConfiguration.loadConfiguration(languageConfigFile);
InputStream defConfigStream = plugin.getResource("language.yml");
if (defConfigStream != null) {
languageConfig.setDefaults(YamlConfiguration.loadConfiguration(new InputStreamReader(defConfigStream, StandardCharsets.UTF_8)));
languageConfig.setDefaults(YamlConfiguration.loadConfiguration(new InputStreamReader(defConfigStream, Charset.forName("UTF-8"))));
}
}

Datei anzeigen

@ -27,8 +27,11 @@ public class Main extends JavaPlugin {
final HashMap<UUID, ArmorStand> carryingArmorStand = new HashMap<UUID, ArmorStand>();
final HashMap<UUID, ItemStack[]> savedInventories = new HashMap<UUID, ItemStack[]>();
static Main plugin;
@Override
public void onEnable() {
plugin = this;
if(!loadSpigotVersionSupport()) {
setEnabled(false);
return;
@ -79,7 +82,7 @@ public class Main extends JavaPlugin {
getLogger().warning("Support for " + nmsVersion + " not found, trying " + usingVersion + ". Please check for possible updates to the plugin.");
}
try {
nms = (NMS) Class.forName("com.gmail.St3venAU.plugins.ArmorStandTools.NMS_" + usingVersion).getConstructor(Main.class, String.class).newInstance(this, nmsVersion);
nms = (NMS) Class.forName("com.gmail.St3venAU.plugins.ArmorStandTools.NMS_" + usingVersion).getConstructor(String.class).newInstance(nmsVersion);
} catch (Exception e) {
e.printStackTrace();
getLogger().warning("An error occurred while attempting to load support for this version of Craftbukkit/Spigot. Loading plugin failed.");

Datei anzeigen

@ -168,8 +168,8 @@ public class MainListener implements Listener {
return;
}
if(!p.isSneaking()) {
ArmorStandCmd asCmd = ArmorStandCmd.fromAS(as);
if (asCmd != null) {
ArmorStandCmd asCmd = new ArmorStandCmd(as);
if (asCmd.getCommand() != null) {
event.setCancelled(true);
if (Utils.hasPermissionNode(p, "astools.ascmd.execute")) {
if (!asCmd.execute(p)) {

Datei anzeigen

@ -18,14 +18,11 @@ import java.util.Map;
abstract class NMS {
private Main plugin;
private final String
nmsVersion,
disabledSlotsFieldName;
NMS(Main plugin, String nmsVersion, String disabledSlotsFieldName) {
this.plugin = plugin;
NMS(String nmsVersion, String disabledSlotsFieldName) {
this.nmsVersion = nmsVersion;
this.disabledSlotsFieldName = disabledSlotsFieldName;
}
@ -57,7 +54,7 @@ abstract class NMS {
e.printStackTrace();
}
}
}.runTaskLater(plugin, 2L);
}.runTaskLater(Main.plugin, 2L);
}
boolean toggleSlotsDisabled(ArmorStand as) {
@ -212,7 +209,10 @@ abstract class NMS {
clone.setSmall(as.isSmall());
clone.setInvulnerable(as.isInvulnerable());
setSlotsDisabled(clone, getDisabledSlots(as) == 0xFFFFFF);
ArmorStandCmd.cloneASCommand(as, clone);
ArmorStandCmd asCmd = new ArmorStandCmd(as);
if(asCmd.getCommand() != null) {
asCmd.cloneTo(clone);
}
return clone;
}

Datei anzeigen

@ -3,9 +3,8 @@ package com.gmail.St3venAU.plugins.ArmorStandTools;
@SuppressWarnings("unused")
class NMS_v1_13_R1 extends NMS {
public NMS_v1_13_R1(Main plugin, String nmsVersion) {
public NMS_v1_13_R1(String nmsVersion) {
super(
plugin,
nmsVersion,
"bH"
);

Datei anzeigen

@ -3,9 +3,8 @@ package com.gmail.St3venAU.plugins.ArmorStandTools;
@SuppressWarnings("unused")
class NMS_v1_13_R2 extends NMS {
public NMS_v1_13_R2(Main plugin, String nmsVersion) {
public NMS_v1_13_R2(String nmsVersion) {
super(
plugin,
nmsVersion,
"bH"
);

Datei anzeigen

@ -4,7 +4,7 @@
#
# Main Config
#
# File generated by: v3.2.0
# File generated by: v3.3.0
# (If this is not the version you are running, consider deleting this
# config to allow it to be re-created. There may be new config options)
#
@ -29,6 +29,8 @@
# /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 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.
#
# Permissions:
@ -53,6 +55,7 @@ integrateWithWorldGuard: true
allowMovingStandsBetweenWorlds: false
deactivateToolsOnWorldChange: true
requireCreativeForSaveAsCmdBlock: false
defaultASCmdCooldownTicks: 0
helmet: AIR 0
chest: AIR 0
pants: AIR 0
@ -68,39 +71,39 @@ name: ''
invulnerable: false
equipmentLock: false
enableTool:
headX: true
headY: true
headZ: true
lArmX: true
lArmY: true
lArmZ: true
rArmX: true
rArmY: true
rArmZ: true
moveX: true
moveY: true
moveZ: true
lLegX: true
lLegY: true
lLegZ: true
rLegX: true
rLegY: true
rLegZ: true
bodyX: true
bodyY: true
bodyZ: true
summon: true
gui: true
rotat: true
gui_clone: true
gui_save: true
gui_invis: true
gui_size: true
gui_base: true
gui_grav: true
gui_arms: true
gui_name: true
gui_slots: true
gui_pHead: true
gui_invul: true
gui_move: true
headX: true
headY: true
headZ: true
lArmX: true
lArmY: true
lArmZ: true
rArmX: true
rArmY: true
rArmZ: true
moveX: true
moveY: true
moveZ: true
lLegX: true
lLegY: true
lLegZ: true
rLegX: true
rLegY: true
rLegZ: true
bodyX: true
bodyY: true
bodyZ: true
summon: true
gui: true
rotat: true
gui_clone: true
gui_save: true
gui_invis: true
gui_size: true
gui_base: true
gui_grav: true
gui_arms: true
gui_name: true
gui_slots: true
gui_pHead: true
gui_invul: true
gui_move: true

Datei anzeigen

@ -4,7 +4,7 @@
#
# Language Config
#
# File generated by: v3.2.0
# File generated by: v3.3.0
# (If this is not the version you are running, consider deleting this
# config to allow it to be re-created. There may be new config options)
#
@ -81,6 +81,14 @@ 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
cmdOnCooldown: 'This command is on cooldown'
cooldownRemovedFrom: 'Cooldown removed from'
isAnInvalidCooldown: 'is an invalid cooldown time'
cooldownSetTo: 'Cooldown set to'
ticksFor: 'ticks for'
setCooldown: 'Set the cooldown for the command'
removeCooldown: 'Remove the cooldown for the command'
#
#############################
# Tool names & descriptions #

Datei anzeigen

@ -1,6 +1,6 @@
main: com.gmail.St3venAU.plugins.ArmorStandTools.Main
name: ArmorStandTools
version: 3.2.0
version: 3.3.0
api-version: 1.13
author: St3venAU
description: Armor stand manipulation tools