diff --git a/bukkit/src/main/java/co/aikar/commands/BukkitCommandContexts.java b/bukkit/src/main/java/co/aikar/commands/BukkitCommandContexts.java index c107f567..e842b63b 100644 --- a/bukkit/src/main/java/co/aikar/commands/BukkitCommandContexts.java +++ b/bukkit/src/main/java/co/aikar/commands/BukkitCommandContexts.java @@ -27,7 +27,9 @@ import co.aikar.commands.annotation.Optional; import co.aikar.commands.contexts.OnlinePlayer; import org.bukkit.Bukkit; import org.bukkit.ChatColor; +import org.bukkit.Location; import org.bukkit.World; +import org.bukkit.command.BlockCommandSender; import org.bukkit.command.CommandSender; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; @@ -121,6 +123,81 @@ public class BukkitCommandContexts extends CommandContexts { + String input = c.popFirstArg(); + CommandSender sender = c.getSender(); + String[] split = ACFPatterns.COLON.split(input, 2); + if (split.length == 0) { + throw new InvalidCommandArgument(true); + } + if (split.length < 2 && !(sender instanceof Player) && !(sender instanceof BlockCommandSender)) { + throw new InvalidCommandArgument(MinecraftMessageKeys.LOCATION_PLEASE_SPECIFY_WORLD); + } + final String world; + final String rest; + Location sourceLoc = null; + if (split.length == 2) { + world = split[0]; + rest = split[1]; + } else if (sender instanceof Player) { + sourceLoc = ((Player) sender).getLocation(); + world = sourceLoc.getWorld().getName(); + rest = split[0]; + } else if (sender instanceof BlockCommandSender) { + sourceLoc = ((BlockCommandSender) sender).getBlock().getLocation(); + world = sourceLoc.getWorld().getName(); + rest = split[0]; + } else { + throw new InvalidCommandArgument(true); + } + split = ACFPatterns.COMMA.split(rest); + if (split.length < 3) { + throw new InvalidCommandArgument(MinecraftMessageKeys.LOCATION_PLEASE_SPECIFY_XYZ); + } + + boolean relX = split[0].startsWith("~"); + boolean relY = split[1].startsWith("~"); + boolean relZ = split[2].startsWith("~"); + + Double x = ACFUtil.parseDouble(relX ? split[0].substring(1) : split[0]); + Double y = ACFUtil.parseDouble(relY ? split[1].substring(1) : split[1]); + Double z = ACFUtil.parseDouble(relZ ? split[2].substring(1) : split[2]); + + if (sourceLoc != null) { + if (relX) { + x += sourceLoc.getX(); + } + if (relX) { + y += sourceLoc.getY(); + } + if (relZ) { + z += sourceLoc.getZ(); + } + } else if (relX || relY || relZ) { + throw new InvalidCommandArgument(MinecraftMessageKeys.LOCATION_CONSOLE_NOT_RELATIVE); + } + + if (x == null || y == null || z == null) { + throw new InvalidCommandArgument(MinecraftMessageKeys.LOCATION_PLEASE_SPECIFY_XYZ); + } + + World worldObj = Bukkit.getWorld(world); + if (worldObj == null) { + throw new InvalidCommandArgument(MinecraftMessageKeys.INVALID_WORLD); + } + + if (split.length >= 5) { + Float yaw = ACFUtil.parseFloat(split[3]); + Float pitch = ACFUtil.parseFloat(split[4]); + + if (pitch == null || yaw == null) { + throw new InvalidCommandArgument(MinecraftMessageKeys.LOCATION_PLEASE_SPECIFY_XYZ); + } + return new Location(worldObj, x, y, z, yaw, pitch); + } else { + return new Location(worldObj, x, y, z); + } + }); Pattern versionPattern = Pattern.compile("\\(MC: (\\d)\\.(\\d+)\\.?.*?\\)"); Matcher matcher = versionPattern.matcher(Bukkit.getVersion()); if (matcher.find()) { diff --git a/bukkit/src/main/java/co/aikar/commands/MinecraftMessageKeys.java b/bukkit/src/main/java/co/aikar/commands/MinecraftMessageKeys.java index 5503a5be..4bddede0 100644 --- a/bukkit/src/main/java/co/aikar/commands/MinecraftMessageKeys.java +++ b/bukkit/src/main/java/co/aikar/commands/MinecraftMessageKeys.java @@ -34,8 +34,10 @@ public enum MinecraftMessageKeys implements MessageKeyProvider { IS_NOT_A_VALID_NAME, MULTIPLE_PLAYERS_MATCH, NO_PLAYER_FOUND_SERVER, - NO_PLAYER_FOUND - ; + NO_PLAYER_FOUND, + LOCATION_PLEASE_SPECIFY_WORLD, + LOCATION_PLEASE_SPECIFY_XYZ, + LOCATION_CONSOLE_NOT_RELATIVE; private final MessageKey key = MessageKey.of("acf-minecraft." + this.name().toLowerCase()); public MessageKey getMessageKey() { diff --git a/languages/minecraft/acf-minecraft_en.properties b/languages/minecraft/acf-minecraft_en.properties index 03b053cb..647083ef 100644 --- a/languages/minecraft/acf-minecraft_en.properties +++ b/languages/minecraft/acf-minecraft_en.properties @@ -32,3 +32,7 @@ acf-minecraft.is_not_a_valid_name = Error: {name} is not a valid userna acf-minecraft.multiple_players_match = Error: Multiple players matched {search} ({all}), please be more specific. acf-minecraft.no_player_found_server = No player matching {search} is connected to this server. acf-minecraft.no_player_found = No player matching {search} could be found. +acf-minecraft.location_please_specify_world = Error: Please specify world. Example: world:x,y,z. +acf-minecraft.location_please_specify_xyz = Error: Please x,y,z. Example: world:x,y,z. +acf-minecraft.location_console_not_relative = Error: Console may not use relative coordinates for location. +