public void moreHelp() { Util.sendMessage(sender, "&cPreviews a rollback to only you"); Util.sendMessage(sender, "&cThis type of rollback does not affect the actual world in any way"); Util.sendMessage( sender, "&cThe effects can be applied after using &7/hawk preview apply&c or cancelled using &7/hawk preview cancel"); Util.sendMessage(sender, "&cThe parameters are the same as &7/hawk rollback"); }
/** * Handler for sending a result. Converts to multiple lines if it is too long, or if the next word * cannot fit on the line * * @param sender {@link CommandSender} to send result to * @param line text to send wordWrap */ public static void sendLine(CommandSender sender, String input) { int n = 65; String s = ""; String[] splitInput = input .replaceAll("\\s+", " ") .replaceAll(String.format(" *(.{1,%d})(?=$| ) *", n), "$1\n") .split("\n"); for (String line : splitInput) { Util.sendMessage(sender, "&8| " + Util.getLastColor(s) + line); s = line; } }
@Override public boolean execute() { // Check if player already has a rollback processing if (!session.isInPreview()) { Util.sendMessage(sender, "&cNo preview to apply!"); return true; } // Undo local changes to the player Util.sendMessage(sender, "&cAttempting to apply rollback to world..."); new Rollback(RollbackType.GLOBAL, session); session.setInPreview(false); return true; }
/** * Closes database result set and logs if an error is encountered * * @param aResultSet the result set to be closed */ public static void closeJDBCResultSet(ResultSet aResultSet) { try { if (aResultSet != null) { aResultSet.close(); } } catch (SQLException ex) { Util.severe("Unable to close JDBCResulset: " + ex); } }
@Override public boolean execute() { // Check if player already has a rollback processing if (session.doingRollback()) { Util.sendMessage(sender, "&cYou already have a rollback command processing!"); return true; } // Parse arguments SearchParser parser = null; try { parser = new SearchParser(player, args); parser.loc = null; // Check that supplied actions can rollback if (parser.actions.size() > 0) { for (DataType type : parser.actions) if (!type.canRollback()) throw new IllegalArgumentException( "You cannot rollback that action type: &7" + type.getConfigName()); } // If none supplied, add in all rollback types else { for (DataType type : DataType.values()) if (type.canRollback()) parser.actions.add(type); } } catch (IllegalArgumentException e) { Util.sendMessage(sender, "&c" + e.getMessage()); return true; } // Create new SearchQuery with data new SearchQuery(new RollbackCallback(session, RollbackType.LOCAL), parser, SearchDir.DESC); session.setInPreview(true); return true; }
@Override public boolean execute() { Util.sendMessage(sender, "&c-----------&8[ &7Reload Process Started &8]&c-----------"); HawkEye hawk = HawkEye.instance; hawk.reloadConfig(); hawk.config = new Config(hawk); for (DataType dt : DataType.values()) { dt.reload(); } Util.sendMessage(sender, "&8| &7- &cConfig has been reloaded.."); HandlerList.unregisterAll(hawk); // Unregisters all listeners registered to hawkeye hawk.registerListeners(Bukkit.getPluginManager()); Util.sendMessage(sender, "&8| &7- &cListeners have been reloaded.."); Util.sendMessage(sender, "&c-----------&8[ &7Reload Process Finished &8]&c-----------"); return true; }
@Override public void moreHelp() { Util.sendMessage(sender, "&cReloads Hawkeye's configuration"); }
public SearchParser(CommandSender player, List<String> args) throws IllegalArgumentException { this.player = player; String lastParam = ""; boolean paramSet = false; boolean worldedit = false; for (int i = 0; i < args.size(); i++) { String arg = args.get(i); if (arg.isEmpty()) continue; if (!paramSet) { if (arg.length() < 2) throw new IllegalArgumentException("Invalid argument format: &7" + arg); if (!arg.substring(1, 2).equals(":")) { if (arg.contains(":")) throw new IllegalArgumentException("Invalid argument format: &7" + arg); // No arg specified, treat as player players.add(arg); continue; } lastParam = arg.substring(0, 1).toLowerCase(); paramSet = true; if (arg.length() == 2) { if (i == (args.size() - 1)) // No values specified throw new IllegalArgumentException("Invalid argument format: &7" + arg); else // User put a space between the colon and value continue; } // Get values out of argument arg = arg.substring(2); } if (paramSet) { if (arg.isEmpty()) { throw new IllegalArgumentException("Invalid argument format: &7" + lastParam + ":"); } String[] values = arg.split(","); // Players if (lastParam.equals("p")) for (String p : values) players.add(p); // Worlds else if (lastParam.equals("w")) worlds = values; // Filters else if (lastParam.equals("f")) { if (filters != null) filters = Util.concat(filters, values); else filters = values; } // Blocks else if (lastParam.equals("b")) { for (int j = 0; j < values.length; j++) { if (Material.getMaterial(values[j]) != null) values[j] = Integer.toString(Material.getMaterial(values[j]).getId()); } } // Actions else if (lastParam.equals("a")) { for (String value : values) { DataType type = DataType.fromName(value); if (type == null) throw new IllegalArgumentException("Invalid action supplied: &7" + value); if (!Util.hasPerm(player, "search." + type.getConfigName().toLowerCase())) throw new IllegalArgumentException( "You do not have permission to search for: &7" + type.getConfigName()); actions.add(type); } } // Location else if (lastParam.equals("l") && player instanceof Player) { if (values[0].equalsIgnoreCase("here")) loc = ((Player) player).getLocation().toVector(); else { loc = new Vector(); loc.setX(Integer.parseInt(values[0])); loc.setY(Integer.parseInt(values[1])); loc.setZ(Integer.parseInt(values[2])); } } // Radius else if (lastParam.equals("r") && player instanceof Player) { if (!Util.isInteger(values[0])) { if ((values[0].equalsIgnoreCase("we") || values[0].equalsIgnoreCase("worldedit")) && HawkEye.worldEdit != null) { Selection sel = HawkEye.worldEdit.getSelection((Player) player); double lRadius = Math.ceil(sel.getLength() / 2); double wRadius = Math.ceil(sel.getWidth() / 2); double hRadius = Math.ceil(sel.getHeight() / 2); if (Config.MaxRadius != 0 && (lRadius > Config.MaxRadius || wRadius > Config.MaxRadius || hRadius > Config.MaxRadius)) throw new IllegalArgumentException( "Selection too large, max radius: &7" + Config.MaxRadius); worldedit = true; minLoc = new Vector( sel.getMinimumPoint().getX(), sel.getMinimumPoint().getY(), sel.getMinimumPoint().getZ()); maxLoc = new Vector( sel.getMaximumPoint().getX(), sel.getMaximumPoint().getY(), sel.getMaximumPoint().getZ()); } else { throw new IllegalArgumentException("Invalid radius supplied: &7" + values[0]); } } else { radius = Integer.parseInt(values[0]); if (Config.MaxRadius != 0 && radius > Config.MaxRadius) throw new IllegalArgumentException( "Radius too large, max allowed: &7" + Config.MaxRadius); } } // Time else if (lastParam.equals("t")) { int type = 2; boolean isTo = false; for (int j = 0; j < arg.length(); j++) { String c = arg.substring(j, j + 1); if (!Util.isInteger(c)) { if (c.equals("m") || c.equals("s") || c.equals("h") || c.equals("d") || c.equals("w")) { type = 0; } if (c.equals("-") || c.equals(":")) type = 1; } } // If the time is in the format '0w0d0h0m0s' if (type == 0) { int weeks = 0; int days = 0; int hours = 0; int mins = 0; int secs = 0; String nums = ""; for (int j = 0; j < values[0].length(); j++) { String c = values[0].substring(j, j + 1); if (c.equals("!")) { // If the number has a ! infront of it the time inverts c = values[0].substring(j, j + 2).replace("!", ""); isTo = true; } else { if (Util.isInteger(c)) { nums += c; continue; } int num = Integer.parseInt(nums); if (c.equals("w")) weeks = num; else if (c.equals("d")) days = num; else if (c.equals("h")) hours = num; else if (c.equals("m")) mins = num; else if (c.equals("s")) secs = num; else throw new IllegalArgumentException("Invalid time measurement: &7" + c); nums = ""; } } Calendar cal = Calendar.getInstance(); cal.add(Calendar.WEEK_OF_YEAR, -1 * weeks); cal.add(Calendar.DAY_OF_MONTH, -1 * days); cal.add(Calendar.HOUR, -1 * hours); cal.add(Calendar.MINUTE, -1 * mins); cal.add(Calendar.SECOND, -1 * secs); SimpleDateFormat form = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); if (isTo) dateTo = form.format(cal.getTime()); else dateFrom = form.format(cal.getTime()); } // If the time is in the format 'yyyy-MM-dd HH:mm:ss' else if (type == 1) { if (values.length == 1) { SimpleDateFormat form = new SimpleDateFormat("yyyy-MM-dd"); dateFrom = form.format(Calendar.getInstance().getTime()) + " " + values[0]; } if (values.length >= 2) dateFrom = values[0] + " " + values[1]; if (values.length == 4) dateTo = values[2] + " " + values[3]; } // Invalid time format else if (type == 2) throw new IllegalArgumentException("Invalid time format!"); } else throw new IllegalArgumentException("Invalid parameter supplied: &7" + lastParam); paramSet = false; } } // Sort out locations if (!worldedit) parseLocations(); }
/** Run the search query */ @Override public void run() { Util.debug("Beginning search query"); String sql; if (delete) sql = "DELETE FROM "; else sql = "SELECT * FROM "; sql += "`" + Config.DbHawkEyeTable + "` WHERE "; List<String> args = new LinkedList<String>(); List<Object> binds = new LinkedList<Object>(); // Match players from database list Util.debug("Building players"); if (parser.players.size() >= 1) { List<Integer> pids = new ArrayList<Integer>(); List<Integer> npids = new ArrayList<Integer>(); for (String player : parser.players) { for (Map.Entry<String, Integer> entry : DataManager.dbPlayers.entrySet()) { String name = entry.getKey().toLowerCase(); if (name.equals(player.replace("*", ""))) pids.add(entry.getValue()); else if (name.contains(player)) pids.add(entry.getValue()); else if (name.contains(player.replace("!", ""))) npids.add(entry.getValue()); } } // Include players if (pids.size() > 0) args.add("player_id IN (" + Util.join(pids, ",") + ")"); // Exclude players if (npids.size() > 0) args.add("player_id NOT IN (" + Util.join(npids, ",") + ")"); if (npids.size() + pids.size() < 1) { callBack.error(SearchError.NO_PLAYERS, "No players found matching your specifications"); return; } } // Match worlds from database list Util.debug("Building worlds"); if (parser.worlds != null) { List<Integer> wids = new ArrayList<Integer>(); List<Integer> nwids = new ArrayList<Integer>(); for (String world : parser.worlds) { for (Map.Entry<String, Integer> entry : DataManager.dbWorlds.entrySet()) { if (entry.getKey().toLowerCase().contains(world.toLowerCase())) wids.add(entry.getValue()); else if (entry.getKey().toLowerCase().contains(world.replace("!", "").toLowerCase())) nwids.add(entry.getValue()); } } // Include worlds if (wids.size() > 0) args.add("world_id IN (" + Util.join(wids, ",") + ")"); // Exclude worlds if (nwids.size() > 0) args.add("world_id NOT IN (" + Util.join(nwids, ",") + ")"); if (nwids.size() + wids.size() < 1) { callBack.error(SearchError.NO_WORLDS, "No worlds found matching your specifications"); return; } } // Compile actions into SQL form Util.debug("Building actions"); if (parser.actions != null && parser.actions.size() > 0) { List<Integer> acs = new ArrayList<Integer>(); for (DataType act : parser.actions) acs.add(act.getId()); args.add("action IN (" + Util.join(acs, ",") + ")"); } // Add dates Util.debug("Building dates"); if (parser.dateFrom != null) { args.add("timestamp >= ?"); binds.add(parser.dateFrom); } if (parser.dateTo != null) { args.add("timestamp <= ?"); binds.add(parser.dateTo); } // Check if location is exact or a range Util.debug("Building location"); if (parser.minLoc != null) { args.add( "(x BETWEEN " + parser.minLoc.getBlockX() + " AND " + parser.maxLoc.getBlockX() + ")"); args.add( "(y BETWEEN " + parser.minLoc.getBlockY() + " AND " + parser.maxLoc.getBlockY() + ")"); args.add( "(z BETWEEN " + parser.minLoc.getBlockZ() + " AND " + parser.maxLoc.getBlockZ() + ")"); } else if (parser.loc != null) { args.add("x = " + parser.loc.getX()); args.add("y = " + parser.loc.getY()); args.add("z = " + parser.loc.getZ()); } // Build the filters into SQL form Util.debug("Building filters"); if (parser.filters != null) { for (String filter : parser.filters) { args.add("data LIKE ?"); binds.add("%" + filter + "%"); } } // Build WHERE clause sql += Util.join(args, " AND "); // Add order by Util.debug("Ordering by data_id"); sql += " ORDER BY `data_id` " + (dir == SearchDir.DESC ? "DESC" : "ASC"); // Check the limits Util.debug("Building limits"); if (Config.MaxLines > 0) sql += " LIMIT " + Config.MaxLines; // Util.debug("Searching: " + sql); // Set up some stuff for the search ResultSet res = null; List<DataEntry> results = new ArrayList<DataEntry>(); JDCConnection conn = DataManager.getConnection(); PreparedStatement stmnt = null; int deleted = 0; try { conn.setAutoCommit(false); // Execute query stmnt = conn.prepareStatement(sql); Util.debug("Preparing statement"); for (int i = 0; i < binds.size(); i++) stmnt.setObject(i + 1, binds.get(i)); Util.debug("Searching: " + stmnt.toString()); if (delete) { Util.debug("Deleting entries"); deleted = stmnt.executeUpdate(); } else { res = stmnt.executeQuery(); Util.debug("Getting results"); DataType type = null; DataEntry entry = null; // Retrieve results while (res.next()) { type = DataType.fromId(res.getInt(4)); entry = (DataEntry) type.getEntryConstructor() .newInstance( res.getInt(3), res.getTimestamp(2), res.getInt(1), res.getInt(4), res.getString(9), res.getString(10), res.getInt(5), res.getInt(6), res.getInt(7), res.getInt(8)); results.add(entry); } } conn.commit(); conn.setAutoCommit(true); } catch (Exception ex) { Util.severe("Error executing MySQL query: " + ex); ex.printStackTrace(); callBack.error(SearchError.MYSQL_ERROR, "Error executing MySQL query: " + ex); return; } finally { try { if (res != null) res.close(); if (stmnt != null) stmnt.close(); conn.close(); } catch (SQLException ex) { Util.severe("Unable to close SQL connection: " + ex); callBack.error(SearchError.MYSQL_ERROR, "Unable to close SQL connection: " + ex); } } Util.debug(results.size() + " results found"); // Run callback if (delete) ((DeleteCallback) callBack).deleted = deleted; else callBack.results = results; callBack.execute(); Util.debug("Search complete"); }
/** * Displays a page of data from the specified {@link PlayerSession} search results. Contains * appropriate methods for detecing errors e.g. no results * * @param session {@link PlayerSession} * @param page page number to display */ public static void displayPage(PlayerSession session, int page) { // Check if any results are found List<DataEntry> results = session.getSearchResults(); if (results == null || results.size() == 0) { Util.sendMessage(session.getSender(), "&cNo results found"); return; } // Work out max pages. Return if page is higher than max pages int maxLines = 6; int maxPages = (int) Math.ceil((double) results.size() / 6); if (page > maxPages || page < 1) { return; } // Fix the line to properly fit the screen int len = String.valueOf(maxPages).length(); if (len > 3) { len = (len - (len / 2)) + 1; } String l = "----------------------".substring(len); // Begin displaying page Util.sendMessage( session.getSender(), "&8" + l + " &7Page (&c" + page + "&7/&c" + maxPages + "&7) &8" + l + (len > 1 ? "-" : "")); for (int i = (page - 1) * maxLines; i < ((page - 1) * maxLines) + maxLines; i++) { if (i == results.size()) { break; } DataEntry entry = results.get(i); String time = Util.getTime(entry.getTimestamp()); DisplayManager.sendLine( session.getSender(), "&cID:" + entry.getDataId() + " &7" + time + "&c" + entry.getPlayerName() + " &7" + entry.getType().getConfigName()); DisplayManager.sendLine( session.getSender(), "&cLoc: &7" + entry.getWorld() + "-" + entry.getX() + "," + entry.getY() + "," + entry.getZ() + " &cData: &7" + entry.getStringData()); } Util.sendMessage( session.getSender(), "&8-----------------------------------------------------"); return; }
@Override public void moreHelp() { Util.sendMessage(sender, "&cApplies the results of a &7/hawk preview&c globally"); Util.sendMessage(sender, "&cUntil this command is called, the preview is only visible to you"); }