/** * BetonQuest - advanced quests for Bukkit * Copyright (C) 2016 Jakub "Co0sh" Sapalski * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package pl.betoncraft.betonquest.commands; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.scheduler.BukkitRunnable; import pl.betoncraft.betonquest.BetonQuest; import pl.betoncraft.betonquest.ConditionID; import pl.betoncraft.betonquest.EventID; import pl.betoncraft.betonquest.InstructionParseException; import pl.betoncraft.betonquest.ItemID; import pl.betoncraft.betonquest.Journal; import pl.betoncraft.betonquest.ObjectNotFoundException; import pl.betoncraft.betonquest.ObjectiveID; import pl.betoncraft.betonquest.Point; import pl.betoncraft.betonquest.Pointer; import pl.betoncraft.betonquest.api.Objective; import pl.betoncraft.betonquest.config.Config; import pl.betoncraft.betonquest.config.ConfigAccessor; import pl.betoncraft.betonquest.config.ConfigPackage; import pl.betoncraft.betonquest.database.Connector.UpdateType; import pl.betoncraft.betonquest.database.PlayerData; import pl.betoncraft.betonquest.database.Saver.Record; import pl.betoncraft.betonquest.item.QuestItem; import pl.betoncraft.betonquest.utils.Debug; import pl.betoncraft.betonquest.utils.PlayerConverter; import pl.betoncraft.betonquest.utils.Updater; import pl.betoncraft.betonquest.utils.Utils; /** * Main admin command for quest editing. * * @author Jakub Sapalski */ public class QuestCommand implements CommandExecutor { private BetonQuest instance = BetonQuest.getInstance(); private String defaultPack = Config.getString("config.default_package"); /** * Registers a new executor of the /betonquest command */ public QuestCommand() { BetonQuest.getInstance().getCommand("betonquest").setExecutor(this); } @Override public boolean onCommand(CommandSender sender, Command cmd, String alias, String[] args) { if (cmd.getName().equalsIgnoreCase("betonquest")) { Debug.info("Executing /betonquest command for user " + sender.getName() + " with arguments: " + Arrays.toString(args)); // if the command is empty, display help message if (args.length < 1) { displayHelp(sender, alias); return true; } // if there are arguments handle them // toLowerCase makes switch case-insensitive switch (args[0].toLowerCase()) { case "conditions": case "condition": case "c": // conditions are only possible for online players, so no // MySQL async // access is required handleConditions(sender, args); break; case "events": case "event": case "e": // the same goes for events handleEvents(sender, args); break; case "items": case "item": case "i": // and items, which only use configuration files (they // should be sync) handleItems(sender, args); break; case "give": case "g": giveItem(sender, args); break; case "config": // config is also only synchronous handleConfig(sender, args); break; case "objectives": case "objective": case "o": Debug.info("Loading data asynchronously"); final CommandSender finalSender1 = sender; final String[] finalArgs1 = args; new BukkitRunnable() { @Override public void run() { handleObjectives(finalSender1, finalArgs1); } }.runTaskAsynchronously(instance); break; case "tags": case "tag": case "t": Debug.info("Loading data asynchronously"); final CommandSender finalSender2 = sender; final String[] finalArgs2 = args; new BukkitRunnable() { @Override public void run() { handleTags(finalSender2, finalArgs2); } }.runTaskAsynchronously(instance); break; case "points": case "point": case "p": Debug.info("Loading data asynchronously"); final CommandSender finalSender3 = sender; final String[] finalArgs3 = args; new BukkitRunnable() { @Override public void run() { handlePoints(finalSender3, finalArgs3); } }.runTaskAsynchronously(instance); break; case "journals": case "journal": case "j": Debug.info("Loading data asynchronously"); final CommandSender finalSender4 = sender; final String[] finalArgs4 = args; new BukkitRunnable() { @Override public void run() { handleJournals(finalSender4, finalArgs4); } }.runTaskAsynchronously(instance); break; case "delete": case "del": case "d": Debug.info("Loading data asynchronously"); final CommandSender finalSender5 = sender; final String[] finalArgs5 = args; new BukkitRunnable() { @Override public void run() { handleDeleting(finalSender5, finalArgs5); } }.runTaskAsynchronously(instance); break; case "rename": case "r": Debug.info("Loading data asynchronously"); final CommandSender finalSender6 = sender; final String[] finalArgs6 = args; new BukkitRunnable() { @Override public void run() { handleRenaming(finalSender6, finalArgs6); } }.runTaskAsynchronously(instance); break; case "vector": case "vec": case "v": handleVector(sender, args); break; case "purge": Debug.info("Loading data asynchronously"); final CommandSender finalSender7 = sender; final String[] finalArgs7 = args; new BukkitRunnable() { @Override public void run() { purgePlayer(finalSender7, finalArgs7); } }.runTaskAsynchronously(instance); break; case "update": Updater upd = BetonQuest.getInstance().getUpdater(); if (args.length > 1 && args[1].equalsIgnoreCase("--dev")) { if (upd.updateDevBuild(sender)) { sender.sendMessage("§2Downloading development version " + upd.getRemoteDevBuild()); } else { sender.sendMessage("§cThere is no new development version available."); } } else { if (upd.updateNewRelease(sender)) { sender.sendMessage("§2Downloading new release " + upd.getRemoteRelease()); } else { sender.sendMessage("§cThere is no new release available."); } } break; case "reload": // just reloading defaultPack = Config.getString("config.default_package"); instance.reload(); sendMessage(sender, "reloaded"); break; case "backup": // do a full plugin backup if (sender instanceof Player || Bukkit.getOnlinePlayers().size() > 0) { sendMessage(sender, "offline"); break; } Utils.backup(); break; case "create": case "package": createNewPackage(sender, args); break; default: // there was an unknown argument, so handle this sendMessage(sender, "unknown_argument"); break; } Debug.info("Command executing done"); return true; } return false; } /** * Gives an item to the player */ private void giveItem(CommandSender sender, String[] args) { // sender must be a player if (!(sender instanceof Player)) { Debug.info("Cannot continue, sender must be player"); return; } // and the item name must be specified if (args.length < 2) { Debug.info("Cannot continue, item's name must be supplied"); sendMessage(sender, "specify_item"); return; } try { ItemID itemID = new ItemID(null, args[1]); QuestItem item = new QuestItem(itemID); ((Player) sender).getInventory().addItem(item.generate(1)); } catch (InstructionParseException | ObjectNotFoundException e) { sendMessage(sender, "error", new String[]{e.getMessage()}); Debug.error("Error while creating an item: " + e.getMessage()); } } /** * Creates new package */ private void createNewPackage(CommandSender sender, String[] args) { if (args.length < 2) { Debug.info("Package name is missing"); sendMessage(sender, "specify_package"); return; } if (Config.createPackage(args[1])) { sendMessage(sender, "package_created"); } else { sendMessage(sender, "package_exists"); } } /** * Purges player's data */ private void purgePlayer(CommandSender sender, String[] args) { // playerID is required if (args.length < 2) { Debug.info("Player's name is missing"); sendMessage(sender, "specify_player"); return; } String playerID = PlayerConverter.getID(args[1]); PlayerData playerData = instance.getPlayerData(playerID); // if the player is offline then get his PlayerData outside of the // list if (playerData == null) { Debug.info("Player is offline, loading his data"); playerData = new PlayerData(playerID); } // purge the player Debug.info("Purging player " + args[1]); playerData.purgePlayer(); // done sendMessage(sender, "purged", new String[] { args[1] }); } /** * Reads, sets or appends strings from/to config files */ private void handleConfig(CommandSender sender, String[] args) { if (args.length < 3) { Debug.info("No action specified!"); sendMessage(sender, "specify_action"); return; } String action = args[1]; String path = args[2]; switch (action) { case "read": case "r": Debug.info("Displaying variable at path " + path); String message = Config.getString(path); sender.sendMessage(message == null ? "null" : message); break; case "set": case "s": if (args.length < 4) { sendMessage(sender, "config_set_error"); return; } StringBuilder strBldr = new StringBuilder(); for (int i = 3; i < args.length; i++) { strBldr.append(args[i] + " "); } if (strBldr.length() < 2) { Debug.info("Wrong path!"); sendMessage(sender, "specify_path"); return; } boolean set = Config.setString(path, (args[3].equalsIgnoreCase("null")) ? null : strBldr.toString().trim()); if (set) { Debug.info("Displaying variable at path " + path); String message1 = Config.getString(path); sender.sendMessage(message1 == null ? "null" : message1); } else { sendMessage(sender, "config_set_error"); } break; case "add": case "a": if (args.length < 4) { sendMessage(sender, "config_set_error"); return; } StringBuilder strBldr2 = new StringBuilder(); for (int i = 3; i < args.length; i++) { strBldr2.append(args[i] + " "); } if (strBldr2.length() < 2) { Debug.info("Wrong path!"); sendMessage(sender, "specify_path"); return; } String finalString = strBldr2.toString().trim(); boolean space = false; if (finalString.startsWith("_")) { finalString = finalString.substring(1); space = true; } String oldString = Config.getString(path); if (oldString == null) { oldString = ""; } boolean set2 = Config.setString(path, oldString + ((space) ? " " : "") + finalString); if (set2) { Debug.info("Displaying variable at path " + path); String message2 = Config.getString(path); sender.sendMessage(message2 == null ? "null" : message2); } else { sendMessage(sender, "config_set_error"); } break; default: // if there was something else, display error message Debug.info("The argument was unknown"); sendMessage(sender, "unknown_argument"); break; } } /** * Lists, adds or removes journal entries of certain players */ private void handleJournals(CommandSender sender, String[] args) { // playerID is required if (args.length < 2) { Debug.info("Player's name is missing"); sendMessage(sender, "specify_player"); return; } String playerID = PlayerConverter.getID(args[1]); PlayerData playerData = instance.getPlayerData(playerID); // if the player is offline then get his PlayerData outside of the // list if (playerData == null) { Debug.info("Player is offline, loading his data"); playerData = new PlayerData(playerID); } Journal journal = playerData.getJournal(); // if there are no arguments then list player's pointers if (args.length < 3 || args[2].equalsIgnoreCase("list") || args[2].equalsIgnoreCase("l")) { Debug.info("Listing journal pointers"); sendMessage(sender, "player_journal"); for (Pointer pointer : journal.getPointers()) { String date = new SimpleDateFormat(Config.getString("config.date_format")) .format(new Date(pointer.getTimestamp())); sender.sendMessage("§b- " + pointer.getPointer() + " §c(§2" + date + "§c)"); } return; } // if there is not enough arguments, display warning if (args.length < 4) { Debug.info("Missing pointer"); sendMessage(sender, "specify_pointer"); return; } String pointerName = (args[3].contains(".")) ? args[3] : defaultPack + "." + args[3]; // if there are arguments, handle them switch (args[2].toLowerCase()) { case "add": case "a": Pointer pointer; if (args.length < 5) { long timestamp = new Date().getTime(); Debug.info("Adding pointer with current date: " + timestamp); pointer = new Pointer(pointerName, timestamp); } else { Debug.info("Adding pointer with date " + args[4].replaceAll("_", " ")); try { pointer = new Pointer(pointerName, new SimpleDateFormat(Config.getString("config.date_format")) .parse(args[4].replaceAll("_", " ")).getTime()); } catch (ParseException e) { Debug.info("Date was in the wrong format"); sendMessage(sender, "specify_date"); return; } } // add the pointer journal.addPointer(pointer); journal.update(); sendMessage(sender, "pointer_added"); break; case "remove": case "delete": case "del": case "r": case "d": // remove the pointer Debug.info("Removing pointer"); journal.removePointer(pointerName); journal.update(); sendMessage(sender, "pointer_removed"); break; default: // if there was something else, display error message Debug.info("The argument was unknown"); sendMessage(sender, "unknown_argument"); break; } } /** * Lists, adds or removes points of certain player */ private void handlePoints(CommandSender sender, String[] args) { // playerID is required if (args.length < 2) { Debug.info("Player's name is missing"); sendMessage(sender, "specify_player"); return; } String playerID = PlayerConverter.getID(args[1]); PlayerData playerData = instance.getPlayerData(playerID); // if the player is offline then get his PlayerData outside of the // list if (playerData == null) { Debug.info("Player is offline, loading his data"); playerData = new PlayerData(playerID); } // if there are no arguments then list player's points if (args.length < 3 || args[2].equalsIgnoreCase("list") || args[2].equalsIgnoreCase("l")) { List<Point> points = playerData.getPoints(); Debug.info("Listing points"); sendMessage(sender, "player_points"); for (Point point : points) { sender.sendMessage("§b- " + point.getCategory() + "§e: §a" + point.getCount()); } return; } // if there is not enough arguments, display warning if (args.length < 4) { Debug.info("Missing category"); sendMessage(sender, "specify_category"); return; } String category = args[3].contains(".") ? args[3] : defaultPack + "." + args[3]; // if there are arguments, handle them switch (args[2].toLowerCase()) { case "add": case "a": if (args.length < 5 || !args[4].matches("-?\\d+")) { Debug.info("Missing amount"); sendMessage(sender, "specify_amount"); return; } // add the point Debug.info("Adding points"); playerData.modifyPoints(category, Integer.parseInt(args[4])); sendMessage(sender, "points_added"); break; case "remove": case "delete": case "del": case "r": case "d": // remove the point (this is unnecessary as adding negative amounts // subtracts points, but for the sake of users let's leave it here) Debug.info("Removing points"); playerData.removePointsCategory(category); sendMessage(sender, "points_removed"); break; default: // if there was something else, display error message Debug.info("The argument was unknown"); sendMessage(sender, "unknown_argument"); break; } } /** * Adds item held in hand to items.yml file */ private void handleItems(CommandSender sender, String[] args) { // sender must be a player if (!(sender instanceof Player)) { Debug.info("Cannot continue, sender must be player"); return; } // and the item name must be specified if (args.length < 2) { Debug.info("Cannot continue, item's name must be supplied"); sendMessage(sender, "specify_item"); return; } String itemID = args[1]; String pack; String name; if (itemID.contains(".")) { String[] parts = itemID.split("\\."); pack = parts[0]; name = parts[1]; } else { pack = defaultPack; name = itemID; } Player player = (Player) sender; ItemStack item = player.getInventory().getItemInMainHand(); // if item is air then there is nothing to add to items.yml if (item == null || item.getType() == Material.AIR) { Debug.info("Cannot continue, item must not be air"); sendMessage(sender, "no_item"); return; } // define parts of the final string ConfigPackage configPack = Config.getPackages().get(pack); if (configPack == null) { Debug.info("Cannot continue, package does not exist"); sendMessage(sender, "specify_package"); return; } ConfigAccessor config = configPack.getItems(); String instructions = QuestItem.itemToString(item); // save it in items.yml Debug.info("Saving item to configuration as " + args[1]); config.getConfig().set(name, instructions.trim()); config.saveConfig(); // done sendMessage(sender, "item_created", new String[] { args[1] }); } /** * Fires an event for an online player. It cannot work for offline players! */ private void handleEvents(CommandSender sender, String[] args) { // the player has to be specified every time if (args.length < 2 || (Bukkit.getPlayer(args[1]) == null && !args[1].equals("-"))) { Debug.info("Player's name is missing or he's offline"); sendMessage(sender, "specify_player"); return; } String playerID = (args[1].equals("-")) ? null : PlayerConverter.getID(args[1]); if (args.length < 3) { Debug.info("Event's ID is missing"); sendMessage(sender, "specify_event"); return; } EventID eventID; try { eventID = new EventID(null, args[2]); } catch (ObjectNotFoundException e) { sendMessage(sender, "error", new String[]{ e.getMessage() }); return; } // fire the event BetonQuest.event(playerID, eventID); sendMessage(sender, "player_event", new String[] { eventID.generateInstruction().getInstruction() }); } /** * Checks if specified player meets condition described by ID */ private void handleConditions(CommandSender sender, String[] args) { // the player has to be specified every time if (args.length < 2 || Bukkit.getPlayer(args[1]) == null) { Debug.info("Player's name is missing or he's offline"); sendMessage(sender, "specify_player"); return; } String playerID = PlayerConverter.getID(args[1]); // the condition ID if (args.length < 3) { Debug.info("Condition's ID is missing"); sendMessage(sender, "specify_condition"); return; } ConditionID conditionID; try { conditionID = new ConditionID(null, args[2]); } catch (ObjectNotFoundException e) { sendMessage(sender, "error", new String[]{ e.getMessage() }); return; } // display message about condition sendMessage(sender, "player_condition", new String[] { (conditionID.inverted() ? "! " : "") + conditionID.generateInstruction().getInstruction(), Boolean.toString(BetonQuest.condition(playerID, conditionID)) }); } /** * Lists, adds or removes tags */ private void handleTags(CommandSender sender, String[] args) { // playerID is required if (args.length < 2) { Debug.info("Player's name is missing"); sendMessage(sender, "specify_player"); return; } String playerID = PlayerConverter.getID(args[1]); PlayerData playerData = instance.getPlayerData(playerID); // if the player is offline then get his PlayerData outside of the // list if (playerData == null) { Debug.info("Player is offline, loading his data"); playerData = new PlayerData(playerID); } // if there are no arguments then list player's tags if (args.length < 3 || args[2].equalsIgnoreCase("list") || args[2].equalsIgnoreCase("l")) { List<String> tags = playerData.getTags(); Debug.info("Listing tags"); sendMessage(sender, "player_tags"); for (String tag : tags) { sender.sendMessage("§b- " + tag); } return; } // if there is not enough arguments, display warning if (args.length < 4) { Debug.info("Missing tag name"); sendMessage(sender, "specify_tag"); return; } String tag = args[3].contains(".") ? args[3] : defaultPack + "." + args[3]; // if there are arguments, handle them switch (args[2].toLowerCase()) { case "add": case "a": // add the tag Debug.info("Adding tag " + tag + " for player " + PlayerConverter.getName(playerID)); playerData.addTag(tag); sendMessage(sender, "tag_added"); break; case "remove": case "delete": case "del": case "r": case "d": // remove the tag Debug.info("Removing tag " + tag + " for player " + PlayerConverter.getName(playerID)); playerData.removeTag(tag); sendMessage(sender, "tag_removed"); break; default: // if there was something else, display error message Debug.info("The argument was unknown"); sendMessage(sender, "unknown_argument"); break; } } /** * Lists, adds or removes objectives. */ private void handleObjectives(CommandSender sender, String[] args) { // playerID is required if (args.length < 2) { Debug.info("Player's name is missing"); sendMessage(sender, "specify_player"); return; } String playerID = PlayerConverter.getID(args[1]); boolean isOnline = !(PlayerConverter.getPlayer(playerID) == null); PlayerData playerData = instance.getPlayerData(playerID); // if the player is offline then get his PlayerData outside of the // list if (playerData == null) { Debug.info("Player is offline, loading his data"); playerData = new PlayerData(playerID); } // if there are no arguments then list player's objectives if (args.length < 3 || args[2].equalsIgnoreCase("list") || args[2].equalsIgnoreCase("l")) { List<String> tags; if (!isOnline) { // if player is offline then convert his raw objective strings // to tags tags = new ArrayList<>(); for (String string : playerData.getRawObjectives().keySet()) { tags.add(string); } } else { // if the player is online then just retrieve tags from his // active // objectives tags = new ArrayList<>(); for (Objective objective : BetonQuest.getInstance().getPlayerObjectives(playerID)) { tags.add(objective.getLabel()); } } // display objectives Debug.info("Listing objectives"); sendMessage(sender, "player_objectives"); for (String tag : tags) { sender.sendMessage("§b- " + tag); } return; } // if there is not enough arguments, display warning if (args.length < 4) { Debug.info("Missing objective instruction string"); sendMessage(sender, "specify_objective"); return; } // get the objective ObjectiveID objectiveID; try { objectiveID = new ObjectiveID(null, args[3]); } catch (ObjectNotFoundException e) { sendMessage(sender, "error", new String[]{ e.getMessage() }); return; } Objective objective = BetonQuest.getInstance().getObjective(objectiveID); if (objective == null) { sendMessage(sender, "specify_objective"); return; } switch (args[2].toLowerCase()) { case "start": case "s": case "add": case "a": Debug.info("Adding new objective " + objectiveID + " for player " + PlayerConverter.getName(playerID)); // add the objective if (isOnline) { BetonQuest.newObjective(playerID, objectiveID); } else { playerData.addNewRawObjective(objectiveID); } sendMessage(sender, "objective_added"); break; case "remove": case "delete": case "del": case "r": case "d": Debug.info("Deleting objective " + objectiveID + " for player " + PlayerConverter.getName(playerID)); objective.removePlayer(playerID); playerData.removeRawObjective(objectiveID); sendMessage(sender, "objective_removed"); break; case "complete": case "c": Debug.info("Completing objective " + objectiveID + " for player " + PlayerConverter.getName(playerID)); if (isOnline) { objective.completeObjective(playerID); } else { playerData.removeRawObjective(objectiveID); } sendMessage(sender, "objective_completed"); break; default: // if there was something else, display error message Debug.info("The argument was unknown"); sendMessage(sender, "unknown_argument"); break; } } /** * Creates a vector variable * * @param sender * @param args */ private void handleVector(CommandSender sender, String[] args) { if (!(sender instanceof Player)) return; Player player = ((Player) sender); if (args.length != 3) { player.sendMessage("§4ERROR"); return; } String pack = null, name = null; if (args[1].contains(".")) { String[] parts = args[1].split("\\."); pack = parts[0]; name = parts[1]; } else { pack = defaultPack; name = args[1]; } String origin = Config.getString(pack + ".main.variables." + name); if (origin == null) { player.sendMessage("§4ERROR"); return; } String[] parts = origin.split(";"); if (parts.length < 3) { player.sendMessage("§4ERROR"); return; } double x, y, z; try { x = Double.parseDouble(parts[0]); y = Double.parseDouble(parts[1]); z = Double.parseDouble(parts[2]); } catch (NumberFormatException e) { player.sendMessage("§4ERROR"); return; } Location loc = player.getLocation(); x = loc.getX() - x; y = loc.getY() - y; z = loc.getZ() - z; Config.setString(pack + ".main.variables.vectors." + args[2], String.format("$%s$->(%.2f,%.2f,%.2f)", name, x, y, z)); player.sendMessage("§2OK"); } /** * Renames stuff. */ private void handleRenaming(CommandSender sender, String[] args) { if (args.length < 4) { sendMessage(sender, "arguments"); return; } String type = args[1].toLowerCase(), name = args[2], rename = args[3]; if (!name.contains(".")) { name = defaultPack + "." + name; } if (!rename.contains(".")) { rename = defaultPack + "." + rename; } UpdateType updateType; switch (type) { case "tags": case "tag": case "t": updateType = UpdateType.RENAME_ALL_TAGS; for (Player player : Bukkit.getOnlinePlayers()) { PlayerData playerData = BetonQuest.getInstance().getPlayerData(PlayerConverter.getID(player)); playerData.removeTag(name); playerData.addTag(rename); } break; case "points": case "point": case "p": updateType = UpdateType.RENAME_ALL_POINTS; for (Player player : Bukkit.getOnlinePlayers()) { PlayerData playerData = BetonQuest.getInstance().getPlayerData(PlayerConverter.getID(player)); int points = 0; for (Point point : playerData.getPoints()) { if (point.getCategory().equals(name)) { points = point.getCount(); break; } } playerData.removePointsCategory(name); playerData.modifyPoints(rename, points); } break; case "objectives": case "objective": case "o": updateType = UpdateType.RENAME_ALL_OBJECTIVES; // get ID and package ObjectiveID nameID; try { nameID = new ObjectiveID(null, name); } catch (ObjectNotFoundException e) { sendMessage(sender, "error", new String[]{ e.getMessage() }); return; } // rename objective in the file nameID.getPackage().getObjectives().getConfig().set(rename.split("\\.")[1], nameID.generateInstruction().getInstruction()); nameID.getPackage().getObjectives().saveConfig(); // rename objective instance ObjectiveID renameID; try { renameID = new ObjectiveID(null, rename); } catch (ObjectNotFoundException e) { // this should not happen e.printStackTrace(); return; } BetonQuest.getInstance().renameObjective(nameID, renameID); BetonQuest.getInstance().getObjective(renameID).setLabel(renameID); // renaming an active objective probably isn't needed for (Player player : Bukkit.getOnlinePlayers()) { String playerID = PlayerConverter.getID(player); boolean found = false; String data = null; for (Objective obj : BetonQuest.getInstance().getPlayerObjectives(playerID)) { if (obj.getLabel().equals(name)) { found = true; data = obj.getData(PlayerConverter.getID(player)); break; } } // skip the player if he does not have this objective if (found == false) continue; if (data == null) data = ""; BetonQuest.getInstance().getObjective(nameID).removePlayer(playerID); BetonQuest.getInstance().getPlayerData(playerID).removeRawObjective(nameID); BetonQuest.resumeObjective(PlayerConverter.getID(player), renameID, data); } nameID.getPackage().getObjectives().getConfig().set(nameID.getBaseID(), null); nameID.getPackage().getObjectives().saveConfig(); break; case "journals": case "journal": case "j": case "entries": case "entry": case "e": updateType = UpdateType.RENAME_ALL_ENTRIES; for (Player player : Bukkit.getOnlinePlayers()) { Journal journal = BetonQuest.getInstance().getPlayerData(PlayerConverter.getID(player)).getJournal(); Pointer p = null; for (Pointer pointer : journal.getPointers()) { if (pointer.getPointer().equals(name)) { p = pointer; } } // skip the player if he does not have this entry if (p == null) continue; journal.removePointer(name); journal.addPointer(new Pointer(rename, p.getTimestamp())); journal.update(); } break; default: sendMessage(sender, "unknown_argument"); return; } BetonQuest.getInstance().getSaver().add(new Record(updateType, new String[] { rename, name })); sendMessage(sender, "everything_renamed"); } /** * Deleted stuff. */ private void handleDeleting(CommandSender sender, String[] args) { if (args.length < 3) { sendMessage(sender, "arguments"); return; } String type = args[1].toLowerCase(), name = args[2]; if (!name.contains(".")) { name = defaultPack + "." + name; } UpdateType updateType; switch (type) { case "tags": case "tag": case "t": updateType = UpdateType.REMOVE_ALL_TAGS; for (Player player : Bukkit.getOnlinePlayers()) { PlayerData playerData = BetonQuest.getInstance().getPlayerData(PlayerConverter.getID(player)); playerData.removeTag(name); } break; case "points": case "point": case "p": updateType = UpdateType.REMOVE_ALL_POINTS; for (Player player : Bukkit.getOnlinePlayers()) { PlayerData playerData = BetonQuest.getInstance().getPlayerData(PlayerConverter.getID(player)); playerData.removePointsCategory(name); } break; case "objectives": case "objective": case "o": updateType = UpdateType.REMOVE_ALL_OBJECTIVES; ObjectiveID objectiveID; try { objectiveID = new ObjectiveID(null, name); } catch (ObjectNotFoundException e) { sendMessage(sender, "error", new String[]{ e.getMessage() }); return; } for (Player player : Bukkit.getOnlinePlayers()) { String playerID = PlayerConverter.getID(player); BetonQuest.getInstance().getObjective(objectiveID).removePlayer(playerID); BetonQuest.getInstance().getPlayerData(playerID).removeRawObjective(objectiveID); } break; case "journals": case "journal": case "j": case "entries": case "entry": case "e": updateType = UpdateType.REMOVE_ALL_ENTRIES; for (Player player : Bukkit.getOnlinePlayers()) { Journal journal = BetonQuest.getInstance().getPlayerData(PlayerConverter.getID(player)).getJournal(); journal.removePointer(name); journal.update(); } break; default: sendMessage(sender, "unknown_argument"); return; } BetonQuest.getInstance().getSaver().add(new Record(updateType, new String[] { name })); sendMessage(sender, "everything_removed"); } /** * Displays help to the user. */ private void displayHelp(CommandSender sender, String alias) { Debug.info("Just displaying help"); // specify all commands HashMap<String, String> cmds = new HashMap<>(); cmds.put("reload", "reload"); cmds.put("objectives", "objective <player> [list/add/del] [objective]"); cmds.put("tags", "tag <player> [list/add/del] [tag]"); cmds.put("points", "point <player> [list/add/del] [category] [amount]"); cmds.put("journal", "journal <player> [list/add/del] [entry] [date]"); cmds.put("condition", "condition <player> <condition>"); cmds.put("event", "event <player> <event>"); cmds.put("item", "item <name>"); cmds.put("give", "give <name>"); cmds.put("rename", "rename <tag/point/objective/journal> <old> <new>"); cmds.put("delete", "delete <tag/point/objective/journal> <name>"); cmds.put("config", "config <read/set/add> <path> [string]"); cmds.put("vector", "vector <pack.varname> <vectorname>"); cmds.put("purge", "purge <player>"); if (!(sender instanceof Player)) cmds.put("backup", "backup"); // display them sender.sendMessage("§e----- §aBetonQuest §e-----"); if (sender instanceof Player) { String lang = BetonQuest.getInstance().getPlayerData(PlayerConverter.getID((Player) sender)).getLanguage(); for (String command : cmds.keySet()) { Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender.getName() + " {\"text\":\"\",\"extra\":[{\"text\":\"§c/" + alias + " " + cmds.get(command) + "\",\"hoverEvent\":{\"action\":\"show_text\",\"value\":\"§b" + Config.getMessage(lang, "command_" + command) + "\"}}]}"); } } else { for (String command : cmds.keySet()) { sender.sendMessage("§c/" + alias + " " + cmds.get(command)); sender.sendMessage("§b- " + Config.getMessage(Config.getLanguage(), "command_" + command)); } } } private void sendMessage(CommandSender sender, String messageName) { sendMessage(sender, messageName, null); } private void sendMessage(CommandSender sender, String messageName, String[] variables) { if (sender instanceof Player) { Config.sendMessage(PlayerConverter.getID((Player) sender), messageName, variables); } else { String message = Config.getMessage(Config.getLanguage(), messageName, variables); sender.sendMessage(message); } } }