package org.mctourney.autoreferee.commands; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Set; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.command.CommandSender; import org.bukkit.entity.Entity; import org.bukkit.entity.NPC; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; import org.bukkit.scoreboard.Scoreboard; import org.mctourney.autoreferee.AutoRefMap; import org.mctourney.autoreferee.AutoRefMatch; import org.mctourney.autoreferee.AutoRefTeam; import org.mctourney.autoreferee.AutoReferee; import org.mctourney.autoreferee.AutoRefMatch.MatchStatus; import org.mctourney.autoreferee.goals.CoreGoal; import org.mctourney.autoreferee.listeners.SpectatorListener; import org.mctourney.autoreferee.regions.AutoRefRegion; import org.mctourney.autoreferee.regions.CuboidRegion; import org.mctourney.autoreferee.util.BlockData; import org.mctourney.autoreferee.util.LocationUtil; import org.mctourney.autoreferee.util.commands.AutoRefCommand; import org.mctourney.autoreferee.util.commands.AutoRefPermission; import org.mctourney.autoreferee.util.commands.CommandHandler; import org.apache.commons.cli.CommandLine; import org.apache.commons.lang.StringUtils; import com.google.common.collect.Sets; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdom2.output.Format; import org.jdom2.output.XMLOutputter; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.selections.CuboidSelection; import com.sk89q.worldedit.bukkit.selections.Selection; public class ConfigurationCommands implements CommandHandler { AutoReferee plugin; public ConfigurationCommands(Plugin plugin) { this.plugin = (AutoReferee) plugin; } @AutoRefCommand(name={"autoref", "archive"}, argmax=0, description="Package the map and configuration into the maps/ directory.") @AutoRefPermission(console=true, nodes={"autoreferee.configure"}) public boolean archive(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) throws IOException { if (match == null) return false; File zipfile = match.distributeMap(); String resp = String.format("%s %s", match.getVersionString(), zipfile == null ? "failed to archive." : "archived!"); sender.sendMessage(ChatColor.GREEN + resp); AutoReferee.log(resp); return true; } @AutoRefCommand(name={"autoref", "tool", "wincond"}, argmax=0, description="Get the tool used to configure win conditions.") @AutoRefPermission(console=false, nodes={"autoreferee.configure"}) public boolean toolWinCondition(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) { if (match == null) return false; // get the tool used to set the win conditions Material tooltype = SpectatorListener.ToolAction.TOOL_WINCOND.tooltype; ItemStack toolitem = new ItemStack(tooltype); // add to the inventory and switch to holding it ((Player) sender).getInventory().addItem(toolitem); // let the player know what the tool is and how to use it sender.sendMessage("Given win condition tool: " + toolitem.getType().name()); sender.sendMessage("Right-click on a block to set it as a win-condition."); return true; } @AutoRefCommand(name={"autoref", "tool", "startmech"}, argmax=0, description="Get the tool used to configure start mechanisms.") @AutoRefPermission(console=false, nodes={"autoreferee.configure"}) public boolean toolStartMechanism(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) { if (match == null) return false; // get the tool used to set the starting mechanisms Material tooltype = SpectatorListener.ToolAction.TOOL_STARTMECH.tooltype; ItemStack toolitem = new ItemStack(tooltype); // add to the inventory and switch to holding it ((Player) sender).getInventory().addItem(toolitem); // let the player know what the tool is and how to use it sender.sendMessage("Given start mechanism tool: " + toolitem.getType().name()); sender.sendMessage("Right-click on a device to set it as a starting mechanism."); return true; } @AutoRefCommand(name={"autoref", "tool", "protect"}, argmax=0, description="Get the tool used to configure protected entities (will not be butchered before match).") @AutoRefPermission(console=false, nodes={"autoreferee.configure"}) public boolean toolProtectEntities(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) { if (match == null) return false; // get the tool used to set the starting mechanisms Material tooltype = SpectatorListener.ToolAction.TOOL_PROTECT.tooltype; ItemStack toolitem = new ItemStack(tooltype); // add to the inventory and switch to holding it ((Player) sender).getInventory().addItem(toolitem); // let the player know what the tool is and how to use it sender.sendMessage("Given entity protection tool: " + toolitem.getType().name()); sender.sendMessage("Right-click on an entity to protect it from butchering."); return true; } @AutoRefCommand(name={"autoref", "protectall"}, argmax=0, description="Protect all entities currently on the map.") @AutoRefPermission(console=false, nodes={"autoreferee.configure"}) public boolean protectAll(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) { if (match == null) return false; for (Entity e : match.getWorld().getEntitiesByClasses(NPC.class)) { match.protect(e.getUniqueId()); match.broadcast(ChatColor.DARK_GRAY + "Protecting " + e.getType().name() + " @ " + LocationUtil.toBlockCoords(e.getLocation())); } return true; } @AutoRefCommand(name={"autoref", "nocraft"}, argmax=0, description="Prohibit the item in hand from being crafted during a match.") @AutoRefPermission(console=false, nodes={"autoreferee.configure"}) public boolean setNoCraft(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) { if (match == null) return false; ItemStack item = ((Player) sender).getItemInHand(); if (item != null) match.addIllegalCraft(BlockData.fromItemStack(item)); return true; } @AutoRefCommand(name={"autoref", "setspawn"}, argmin=0, argmax=1, options="as", description="Set the current location as the global spawn. If a team name is provided, sets team spawn.", usage="<command> [<team name>]", opthelp= { "a", "add an additional spawn location", "s", "set spectator spawn", }) @AutoRefPermission(console=false, nodes={"autoreferee.configure"}) public boolean setSpawn(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) { if (match == null) return false; Player player = (Player) sender; if (args.length == 0) { if (options.hasOption('s')) { match.setSpectatorSpawn(player.getLocation()); sender.sendMessage(ChatColor.GRAY + "Spectator spawn set!"); } else { match.setWorldSpawn(player.getLocation()); String coords = LocationUtil.toBlockCoords(match.getWorldSpawn()); sender.sendMessage(ChatColor.GRAY + "Global spawn set to " + coords); } return true; } AutoRefTeam team = match.getTeam(args[0]); if (team == null) { // team name is invalid. let the player know sender.sendMessage(ChatColor.DARK_GRAY + args[1] + ChatColor.RESET + " is not a valid team."); sender.sendMessage("Teams are " + match.getTeamList()); } else { boolean append = options.hasOption('a'); if (!append) team.clearSpawnRegions(); team.addSpawnRegion(player.getLocation()); sender.sendMessage(ChatColor.GRAY + String.format("%s set as spawn for %s", LocationUtil.toBlockCoords(player.getLocation()), team.getDisplayName())); if (append) sender.sendMessage(ChatColor.GRAY + "Appended."); } return true; } @AutoRefCommand(name={"zones"}, argmax=1, description="List all configured regions on the map.", usage="<command> [<team name>]") @AutoRefPermission(console=true, nodes={"autoreferee.configure"}) public boolean getZones(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) { if (match == null) return false; Set<AutoRefTeam> teams = null; // if a team has been specified as an argument if (args.length > 0) { AutoRefTeam t = match.getTeam(args[0]); teams = Sets.newHashSet(t); if (t == null) { // team name is invalid. let the player know sender.sendMessage(ChatColor.DARK_GRAY + args[0] + ChatColor.RESET + " is not a valid team."); return true; } } // otherwise, just print all the teams else teams = match.getTeams(); // sanity check... if (teams == null) return false; // print all the start regions sender.sendMessage("Start Regions:"); if (match.getStartRegions().size() > 0) for (AutoRefRegion reg : match.getStartRegions()) sender.sendMessage(" " + reg.toString()); // if there are no regions, print None else sender.sendMessage(" <None>"); // for all the teams being looked up for (AutoRefTeam team : teams) { // print team-name header sender.sendMessage(team.getDisplayName() + "'s Regions:"); // print all the regions owned by this team if (team.getRegions().size() > 0) for (AutoRefRegion reg : team.getRegions()) sender.sendMessage(" " + reg.toString()); // if there are no regions, print None else sender.sendMessage(" <None>"); } return true; } @AutoRefCommand(name={"zone"}, argmin=0, options=AutoRefRegion.Flag.OPTIONS + "XSN+", description="Set the currently selected WorldEdit region to be a team's zone.", usage="<command> [<team names...>]", opthelp= { // TODO Need data automatically from AutoRefRegion.Flag }) @AutoRefPermission(console=false, nodes={"autoreferee.configure"}) public boolean setupZone(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) { if (match == null) return false; Player player = (Player) sender; WorldEditPlugin worldEdit = AutoReferee.getWorldEdit(); if (worldEdit == null) { // world edit not installed sender.sendMessage("This method requires WorldEdit installed and running."); return true; } Set<AutoRefTeam> teams = Sets.newHashSet(); for (String arg : args) { AutoRefTeam team = match.getTeam(arg); if (team != null) teams.add(team); } boolean isStartRegion = options.hasOption('S'); if (teams.isEmpty() && !isStartRegion) { // team name is invalid. let the player know sender.sendMessage(ChatColor.DARK_GRAY + "No valid team names given."); sender.sendMessage("Teams are " + match.getTeamList()); return true; } Selection sel = worldEdit.getSelection(player); AutoRefRegion reg = null; if ((sel instanceof CuboidSelection)) { CuboidSelection csel = (CuboidSelection) sel; reg = new CuboidRegion(csel.getMinimumPoint(), csel.getMaximumPoint()); } // if we couldn't get a region from WorldEdit if (reg == null) return false; // add the selection to the start regions if (isStartRegion) { match.addStartRegion(reg); sender.sendMessage("Region now marked as a start region!"); return true; } // name this region if it has a name if (options.hasOption('N')) reg.setName(options.getOptionValue('N', null)); for (AutoRefRegion.Flag flag : AutoRefRegion.Flag.values()) if (options.hasOption(flag.getMark())) reg.toggle(flag); for (AutoRefTeam team : teams) if (team.addRegion(reg)) sender.sendMessage(reg.toString() + " set as " + team.getDisplayName() + "'s region."); return true; } @AutoRefCommand(name={"autoref", "core"}, argmin=1, argmax=1, options="r+", description="Set the currently selected WorldEdit region to be a team's core.", usage="<command> <team name>", opthelp= { "r", "specify the range of the core", }) @AutoRefPermission(console=false, nodes={"autoreferee.configure"}) public boolean setupCore(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) { if (match == null) return false; Player player = (Player) sender; WorldEditPlugin worldEdit = AutoReferee.getWorldEdit(); if (worldEdit == null) { // world edit not installed sender.sendMessage("This method requires WorldEdit installed and running."); return true; } AutoRefTeam team = match.getTeam(args[0]); Selection sel = worldEdit.getSelection(player); AutoRefRegion reg = null; if ((sel instanceof CuboidSelection)) { CuboidSelection csel = (CuboidSelection) sel; reg = new CuboidRegion(csel.getMinimumPoint(), csel.getMaximumPoint()); } else { sender.sendMessage("You must have a selection with WorldEdit already to run this method."); return true; } CoreGoal core = new CoreGoal(team, reg); if (options.hasOption('r')) try { core.setRange(Long.parseLong(options.getOptionValue('r'))); } catch (NumberFormatException e) { sender.sendMessage(ChatColor.RED + options.getOptionValue('r') + " is not a valid range."); } team.addGoal(core); sender.sendMessage(reg.toString() + " set as " + team.getDisplayName() + "'s TARGET core."); sender.sendMessage(team.getDisplayName() + " will be attacking this core, not defending it."); return true; } @AutoRefCommand(name={"autoref", "setheight"}, argmin=1, argmax=1, description="Restrict all team zones to be within a given height.", usage="<command> <height>") @AutoRefPermission(console=true, nodes={"autoreferee.configure"}) public boolean setHeight(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) { try { double newHeight = Double.parseDouble(args[0]); for (CuboidRegion creg : match.getRegions(CuboidRegion.class)) if (creg.y2 > newHeight) creg.y2 = newHeight; } catch (NumberFormatException e) { sender.sendMessage(ChatColor.RED + args[0] + " is not a valid height."); } return true; } @AutoRefCommand(name={"autoref", "cfg", "init"}, argmax=0, description="Initialize a blank configuration file for this map.") @AutoRefPermission(console=true, nodes={"autoreferee.configure"}) public boolean configInit(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) { // if there is a match object for this map if (match != null) sender.sendMessage(plugin.getName() + " already initialized for " + match.getMapName() + "."); else { World world = plugin.getSenderWorld(sender); plugin.addMatch(match = new AutoRefMatch(world, false)); match.saveWorldConfiguration(); match.setCurrentState(MatchStatus.NONE); sender.sendMessage(ChatColor.GREEN + AutoReferee.CFG_FILENAME + " generated."); } return true; } @AutoRefCommand(name={"autoref", "cfg", "save"}, argmax=0, description="Save the configuration file for this map.") @AutoRefPermission(console=true, nodes={"autoreferee.configure"}) public boolean configSave(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) { match.saveWorldConfiguration(); sender.sendMessage(ChatColor.GREEN + AutoReferee.CFG_FILENAME + " saved."); return true; } @AutoRefCommand(name={"autoref", "cfg", "reload"}, argmax=0, description="Reload the configuration file from disk for this map.") @AutoRefPermission(console=true, nodes={"autoreferee.configure"}) public boolean configReload(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) { match.reload(); sender.sendMessage(ChatColor.GREEN + AutoReferee.CFG_FILENAME + " reload complete!"); return true; } @AutoRefCommand(name={"autoref", "cfg", "apply"}, argmin=1, options="v+", description="Apply a known map configuration file to the current map.", usage="<command> <map name>", opthelp= { "v", "new map version number", }) @AutoRefPermission(console=true, nodes={"autoreferee.configure"}) public boolean configApply(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) { // generate a map name from the args String mapName = StringUtils.join(args, " "); AutoRefMap map = AutoRefMap.getMap(mapName); World world = plugin.getSenderWorld(sender); if (map == null) { sender.sendMessage(ChatColor.RED + "Unknown map: " + mapName); return true; } else sender.sendMessage(ChatColor.RED + "Applying " + map.getVersionString()); Element worldConfig = null; try { worldConfig = AutoRefMap.getConfigFileData(map.getZip()); } catch (IOException e) { e.printStackTrace(); return true; } catch (JDOMException e) { e.printStackTrace(); return true; } // set a new version string if one is specified if (options.hasOption('v')) { Element version = worldConfig.getChild("meta").getChild("version"); version.setText(options.getOptionValue('v')); } try { XMLOutputter xmlout = new XMLOutputter(Format.getPrettyFormat()); File localconfig = new File(world.getWorldFolder(), AutoReferee.CFG_FILENAME); xmlout.output(worldConfig, new FileOutputStream(localconfig)); } catch (java.io.IOException e) { AutoReferee.log("Could not save world config: " + world.getName()); return true; } AutoRefMatch.setupWorld(world, false); return true; } @AutoRefCommand(name={"autoref", "scoreboard", "save"}, argmax=0, options="m", description="Save the current world's scoreboard to file.", opthelp= { "m", "save the main server scoreboard", }) @AutoRefPermission(console=true, nodes={"autoreferee.configure"}) public boolean scoreboardSave(CommandSender sender, AutoRefMatch match, String[] args, CommandLine options) { if (match == null || !match.getCurrentState().isBeforeMatch()) return false; Scoreboard scoreboard = match.getScoreboard(); if (options.hasOption('m')) scoreboard = Bukkit.getScoreboardManager().getMainScoreboard(); match.saveScoreboardData(scoreboard); sender.sendMessage(ChatColor.GREEN + "Scoreboard saved to file."); return true; } }