package net.cosmosmc.mcze.commands; import net.cosmosmc.mcze.core.constants.Messages; import net.cosmosmc.mcze.utils.GameFile; import net.cosmosmc.mcze.utils.Levenshtein; import net.cosmosmc.mcze.utils.Utils; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; public class Game implements CommandExecutor { /** * Represents a Game File to edit. We apply changes * here to assist map making and live debugging. * NOTE: Not final because this can change. */ private GameFile editedFile; /** * This is the ingame /game command. This is used to create, remove, modify * the Game File above. * NOTE: We run File I/O on the MAIN thread for convenience, and to keep our * code concise. */ @Override public boolean onCommand(CommandSender commandSender, Command command, String label, String[] args) { if (!(commandSender instanceof Player)) { return false; } Player player = (Player) commandSender; if (args.length == 1) { switch (args[0].toLowerCase()) { case "help": Messages.USAGE_GAME.send(player); case "addspawn": int spawn = editedFile.createListLocation(player, null, "Spawns"); Messages.CREATED_SPAWN.send(player, spawn); break; case "checkpoint": int checkpoint = editedFile.createListLocation(player, null, "Checkpoints"); Messages.CREATED_CHECKPOINT.send(player, checkpoint); break; case "nukeroom": editedFile.getConfig().set("Nukeroom", editedFile.serializeLocation(player.getLocation())); editedFile.saveFile(); Messages.CREATED_NUKEROOM.send(player); break; default: sendUnknownCommand(player); sendCorrection(player, args[0].toLowerCase(), new String[] { "addspawn", "checkpoint", "nukeroom" }); } } else if (args.length == 2) { switch (args[0].toLowerCase()) { case "load": load(player, args[1]); break; default: sendUnknownCommand(player); sendCorrection(player, args[0].toLowerCase(), new String[] { "load" }); } } else if (args.length == 3) { switch (args[0].toLowerCase()) { case "door": doorSubCommand(player, args); break; default: sendUnknownCommand(player); sendCorrection(player, args[0].toLowerCase(), new String[] { "door" }); } } else if (args.length == 4) { switch (args[0].toLowerCase()) { case "door": doorSubCommand(player, args); break; default: sendUnknownCommand(player); sendCorrection(player, args[0].toLowerCase(), new String[] { "door" }); } } else { sendUnknownCommand(player); } return false; } /** * Sends command usage for /game to the provided player * * @param player the player to send the usage to */ private void sendUnknownCommand(Player player) { Messages.UNKNOWN_COMMAND.send(player); } private void sendCorrection(Player player, String input, String[] options) { String closest = Levenshtein.getClosestString(input, options); if(closest.equals("")) return; Messages.CORRECTION.send(player, closest); } /** * Loads/Creates a new Game File for editing. * NOTE: The file is in the YAML format, and * should match the name of the arena. * * @param player the player who ran /game * @param input the confirmation message */ private void load(Player player, String input) { input += ".yml"; editedFile = new GameFile("plugins/ZombieEscape/", input); Messages.LOADING_FILE.send(player, input); } /** * Check if the current Game File is null or not. Will * send an error message if the file isn't loaded. * * @param player the player to send the message to * @return if the edited file is null */ private boolean isFileNull(Player player) { if (editedFile == null) { Messages.GAME_FILE_NULL.send(player); return true; } return false; } /** * Processes all subcommands of /door. Some arguments may * range from 3 to 4, but will never throw an exception. * * @param player the player to run the subcommand * @param args the /game command arguments */ private void doorSubCommand(Player player, String[] args) { switch (args[1].toLowerCase()) { case "add": if (!isFileNull(player)) { addDoor(player, args[2]); } break; case "timer": if (!isFileNull(player)) { timer(player, args); } break; case "view": if (!isFileNull(player)) { viewFile(player, args[2]); } break; case "delete": if (!isFileNull(player)) { deleteDoor(player, args[2]); } break; case "edge": if (!isFileNull(player)) { doorEdge(player, args[2], args[3]); } break; } } /** * Creates a door with a given time in seconds. * * @param player the player who is setting the arena up * @param input the time, in seconds, the door will take to open */ private void addDoor(Player player, String input) { Block block = player.getEyeLocation().getBlock(); Material material = block.getType(); if (material != Material.SIGN_POST && material != Material.WALL_SIGN) { Messages.BLOCK_NOT_SIGN.send(player); return; } int seconds = Utils.getNumber(player, input); if (seconds < 0) { Messages.BAD_SECONDS.send(player); return; } int signID = editedFile.createListLocation(player, block.getLocation(), "Doors"); editedFile.getConfig().set("Doors." + signID + ".Timer", seconds); editedFile.saveFile(); Messages.CREATED_SIGN.send(player, signID, seconds); } /** * Sets a timer for a given door. * * @param player the player who is setting the arena up * @param args the time, in seconds, the door will take to open */ private void timer(Player player, String[] args) { int id = Utils.getNumber(player, args[2]); int seconds = Utils.getNumber(player, args[3]); if (id < 0 || seconds < 0) { Messages.POSITIVE_VALUES.send(player); return; } editedFile.getConfig().set("Signs." + id + ".Timer", seconds); editedFile.saveFile(); } /** * Views current information for a provided Door. * * @param player the player to view the information * @param input the id of the door */ private void viewFile(Player player, String input) { // TODO: Load file and view it } /** * Removes a door from the game file. * * @param player the player who is setting the arena up * @param input the id of the door */ private void deleteDoor(Player player, String input) { // TODO: Delete door } /** * Creates a door edge. This is a location that will be used * to remove/fill in the blocks. * * @param player the player who is setting the arena up * @param inputId the id of the door to modify * @param corner the corner, 1 or 2 */ private void doorEdge(Player player, String inputId, String corner) { int id = Utils.getNumber(player, inputId); int input = Utils.getNumber(player, corner); if (id < 0) { Messages.POSITIVE_VALUES.send(player); return; } if (input < 1 || input > 2) { Messages.DOOR_EDGE_BAD.send(player); return; } Location lookingAt = player.getEyeLocation().getBlock().getLocation(); editedFile.getConfig().set("Doors." + id + ".Edge" + input, editedFile.serializeLocation(lookingAt)); editedFile.saveFile(); Messages.ADDED_CORNER.send(player, corner); } }