diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs index f28c61f..93a53a2 100644 --- a/.settings/org.eclipse.core.resources.prefs +++ b/.settings/org.eclipse.core.resources.prefs @@ -1,3 +1,2 @@ eclipse.preferences.version=1 encoding//src/dev/heliosares/auxprotect/bungee/Results.java=UTF-8 -encoding//src/dev/heliosares/auxprotect/command/APCommand.java=UTF-8 diff --git a/plugin.yml b/plugin.yml index 1d80358..7aa6356 100644 --- a/plugin.yml +++ b/plugin.yml @@ -1,5 +1,5 @@ name: AuxProtect -version: 1.0.4 +version: 1.0.5 main: dev.heliosares.auxprotect.AuxProtect description: A plugin designed to suplement CoreProtect in a few ways. api-version: 1.13 diff --git a/pom.xml b/pom.xml index 56d7a29..df6bdbe 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 AuxProtect AuxProtect - 1.0.4 + 1.0.5 AuxProtect ${myPath}/plugins @@ -39,21 +39,20 @@ chestshop-repo https://repo.minebench.de/ - - playpro-repo - https://maven.playpro.com/ - jitpack.io https://jitpack.io + + playpro-repo + https://maven.playpro.com + org.spigotmc - spigot + spigot-api 1.18.1-R0.1-SNAPSHOT - remapped-mojang provided diff --git a/src/dev/heliosares/auxprotect/AuxProtect.java b/src/dev/heliosares/auxprotect/AuxProtect.java index 52447c0..d970b8d 100644 --- a/src/dev/heliosares/auxprotect/AuxProtect.java +++ b/src/dev/heliosares/auxprotect/AuxProtect.java @@ -171,7 +171,9 @@ public class AuxProtect extends JavaPlugin implements IAuxProtect { debug("Checking for updates..."); String newVersion = UpdateChecker.getVersion(AuxProtect.this, 99147); if (newVersion != null) { - if (AuxProtect.this.getDescription().getVersion().equals(newVersion)) { + int compare = UpdateChecker.compareVersions(AuxProtect.this.getDescription().getVersion(), + newVersion); + if (compare <= 0) { update = null; } else { boolean newUpdate = update == null; diff --git a/src/dev/heliosares/auxprotect/bungee/Results.java b/src/dev/heliosares/auxprotect/bungee/Results.java index 3fa0ba7..619ac8f 100644 --- a/src/dev/heliosares/auxprotect/bungee/Results.java +++ b/src/dev/heliosares/auxprotect/bungee/Results.java @@ -8,6 +8,9 @@ import java.util.ArrayList; import dev.heliosares.auxprotect.AuxProtect; import dev.heliosares.auxprotect.IAuxProtect; import dev.heliosares.auxprotect.database.DbEntry; +import dev.heliosares.auxprotect.database.EntryAction; +import dev.heliosares.auxprotect.utils.InvSerialization; +import dev.heliosares.auxprotect.utils.MyPermission; import dev.heliosares.auxprotect.utils.TimeUtil; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.chat.ClickEvent; @@ -19,76 +22,106 @@ public class Results { protected final ArrayList entries; protected final CommandSender player; - protected final boolean showTime; protected final DateTimeFormatter formatter; private final IAuxProtect plugin; + public int perpage = 4; + public int prevpage = 0; - public Results(IAuxProtect plugin, ArrayList entries, CommandSender player, boolean showTime) { + public Results(IAuxProtect plugin, ArrayList entries, CommandSender player) { this.entries = entries; this.player = player; - this.showTime = showTime; this.formatter = DateTimeFormatter.ofPattern("ddMMMYY HH:mm.ss"); this.plugin = plugin; } - public void showPage(int page, int perpage) { - int lastpage = lastPage(perpage); - if (page > lastpage) { + public void showPage(int page, int perpage_) { + int lastpage = getLastPage(perpage_); + if (page > lastpage || page < 1) { AuxProtectBungee.tell(player, AuxProtect.getInstance().translate("lookup-nopage")); return; } + perpage = perpage_; + prevpage = page; AuxProtectBungee.tell(player, "§f------ §9AuxProtect Results§7 ------"); for (int i = (page - 1) * perpage; i < (page) * perpage && i < entries.size(); i++) { DbEntry en = entries.get(i); - String line1 = ""; - if (showTime) { - line1 += "§7" + Instant.ofEpochMilli(en.getTime()).atZone(ZoneId.systemDefault()).format(formatter); - } else { - line1 += String.format("§7%s ago", TimeUtil.millisToString(System.currentTimeMillis() - en.getTime()), - en.getUser(plugin.getSqlManager())); + ComponentBuilder message = new ComponentBuilder(); + + message.append(String.format("§7%s ago", TimeUtil.millisToString(System.currentTimeMillis() - en.getTime()), + en.getUser(plugin.getSqlManager()))) + .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, + new Text(Instant.ofEpochMilli(en.getTime()).atZone(ZoneId.systemDefault()).format(formatter) + + "\n§7Click to copy epoch time."))) + .event(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, en.getTime() + "e")); + + message.append(String.format(" §f- §9%s §f%s §9%s§f", en.getUser(plugin.getSqlManager()), + plugin.translate(en.getAction().getLang(en.getState())), en.getTarget())).event((HoverEvent) null); + String data = en.getData(); + if (data != null && data.contains(InvSerialization.itemSeparator)) { + data = data.split(InvSerialization.itemSeparator)[0]; + if (MyPermission.INV.hasPermission(player)) { + message.append(" §a[View]") + .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/ap inv %d", i))) + .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("§fClick to view!"))); + } + } + if (en.getAction() == EntryAction.INVENTORY) { + if (MyPermission.INV.hasPermission(player)) { + message.append(" §a[View]") + .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/ap inv %d", i))) + .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("§fClick to view!"))); + } + } else if (en.getAction() == EntryAction.KILL) { + if (MyPermission.INV.hasPermission(player) && !en.getTarget().startsWith("#")) { + message.append(" §a[View Inv]") + .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + String.format("/ap l u:%s a:inventory target:death before:%de after:%de", + en.getTarget(), en.getTime() + 50L, en.getTime() - 50L))) + .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("§fClick to view!"))); + } + message.append(" §7(" + data + ")"); + } else if (data != null && data.length() > 0) { + message.append(" §7(" + data + ")"); } - line1 += String.format(" §f- §9%s §f%s §9%s§f §7%s", en.getUser(plugin.getSqlManager()), - plugin.translate(en.getAction().getLang(en.getState())), en.getTarget(), - (en.getData() != null && en.getData().length() > 0) ? "(" + en.getData() + ")" : ""); - AuxProtectBungee.tell(player, line1); if (en.world != null && !en.world.equals("$null")) { - ComponentBuilder message = new ComponentBuilder(); - message.append(String.format(" §7§l^ §7(x%d/y%d/z%d/%s)", en.x, en.y, en.z, en.world)) + message.append(String.format("\n §7§l^ §7(x%d/y%d/z%d/%s)", en.x, en.y, en.z, en.world)) .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, - String.format("/apb tp %d %d %d %s", en.x, en.y, en.z, en.world))) + String.format("/ap tp %d %d %d %s", en.x, en.y, en.z, en.world))) .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("§fClick to Teleport!"))); - player.sendMessage(message.create()); } + player.sendMessage(message.create()); } - // â—„â–º + ComponentBuilder message = new ComponentBuilder(); message.append("§7("); if (page > 1) { - message.append("§9§lâ—„â—„").event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/apb l 1:" + perpage)) + message.append("§9§l" + AuxProtect.LEFT_ARROW + AuxProtect.LEFT_ARROW) + .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/ap l 1:" + perpage)) .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("§9Jump to First Page"))); message.append(" ").event((ClickEvent) null).event((HoverEvent) null); - message.append("§9§lâ—„") - .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/apb l " + (page - 1) + ":" + perpage)) + message.append("§9§l" + AuxProtect.LEFT_ARROW) + .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/ap l " + (page - 1) + ":" + perpage)) .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("Last Page"))); } else { message.event(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "")); - message.append("§8§lâ—„â—„").event((ClickEvent) null).event((HoverEvent) null); + message.append("§8§l" + AuxProtect.LEFT_ARROW + AuxProtect.LEFT_ARROW).event((ClickEvent) null) + .event((HoverEvent) null); message.append(" "); - message.append("§8§lâ—„"); + message.append("§8§l" + AuxProtect.LEFT_ARROW); } message.append(" ").event((ClickEvent) null).event((HoverEvent) null); if (page < lastpage) { - message.append("§9§lâ–º") - .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/apb l " + (page + 1) + ":" + perpage)) + message.append("§9§l" + AuxProtect.RIGHT_ARROW) + .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/ap l " + (page + 1) + ":" + perpage)) .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("Next Page"))); message.append(" ").event((ClickEvent) null).event((HoverEvent) null); - message.append("§9§l►►") - .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/apb l " + lastpage + ":" + perpage)) + message.append("§9§l" + AuxProtect.RIGHT_ARROW + AuxProtect.RIGHT_ARROW) + .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/ap l " + lastpage + ":" + perpage)) .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("Jump to Last Page"))); } else { - message.append("§8§lâ–º").event((ClickEvent) null).event((HoverEvent) null); + message.append("§8§l" + AuxProtect.RIGHT_ARROW).event((ClickEvent) null).event((HoverEvent) null); message.append(" "); - message.append("§8§l►►"); + message.append("§8§l" + AuxProtect.RIGHT_ARROW + AuxProtect.RIGHT_ARROW); } message.append("§7) ").event((ClickEvent) null).event((HoverEvent) null); message.append(String.format(plugin.translate("lookup-page-footer"), page, @@ -97,7 +130,7 @@ public class Results { return; } - int lastPage(int perpage) { + public int getLastPage(int perpage) { return (int) Math.ceil(entries.size() / (double) perpage); } } \ No newline at end of file diff --git a/src/dev/heliosares/auxprotect/bungee/command/LookupCommand.java b/src/dev/heliosares/auxprotect/bungee/command/LookupCommand.java index 7ba1d57..13676fa 100644 --- a/src/dev/heliosares/auxprotect/bungee/command/LookupCommand.java +++ b/src/dev/heliosares/auxprotect/bungee/command/LookupCommand.java @@ -4,11 +4,15 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import org.bukkit.entity.Player; + import dev.heliosares.auxprotect.bungee.AuxProtectBungee; import dev.heliosares.auxprotect.bungee.Results; import dev.heliosares.auxprotect.database.DbEntry; import dev.heliosares.auxprotect.database.EntryAction; import dev.heliosares.auxprotect.database.SQLiteManager.LookupException; +import dev.heliosares.auxprotect.utils.MyPermission; +import dev.heliosares.auxprotect.utils.PlayTimeSolver; import dev.heliosares.auxprotect.utils.TimeUtil; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.ProxyServer; @@ -41,56 +45,90 @@ public class LookupCommand { AuxProtectBungee.tell(sender, plugin.lang.translate("lookup-invalid-syntax")); return true; } + Player player_ = null; + if (sender instanceof Player) { + player_ = (Player) sender; + } + final Player player = player_; if (args.length == 2) { int page = -1; - int perpage = 4; - if (args[1].contains(":")) { - String[] split = args[1].split(":"); - - try { - page = Integer.parseInt(split[0]); - perpage = Integer.parseInt(split[1]); - } catch (NumberFormatException e) { - - } - } else { - try { - page = Integer.parseInt(args[1]); - } catch (NumberFormatException e) { - + int perpage = -1; + boolean isPageLookup = false; + boolean next = args[1].equalsIgnoreCase("next"); + boolean prev = args[1].equalsIgnoreCase("prev"); + boolean first = args[1].equalsIgnoreCase("first"); + boolean last = args[1].equalsIgnoreCase("last"); + if (!next && !prev && !first && !last) { + if (args[1].contains(":")) { + String[] split = args[1].split(":"); + try { + page = Integer.parseInt(split[0]); + perpage = Integer.parseInt(split[1]); + isPageLookup = true; + } catch (NumberFormatException e) { + } + } else { + try { + page = Integer.parseInt(args[1]); + isPageLookup = true; + } catch (NumberFormatException e) { + } } } - if (page > 0) { - if (perpage > 99) - perpage = 99; + if (isPageLookup || first || last || next || prev) { + Results result = null; String uuid = "nonplayer"; - if (sender instanceof ProxiedPlayer) { - uuid = ((ProxiedPlayer) sender).getUniqueId().toString(); + if (sender instanceof Player) { + uuid = ((Player) sender).getUniqueId().toString(); } if (results.containsKey(uuid)) { - results.get(uuid).showPage(page, perpage); - return true; - } else { + result = results.get(uuid); + } + if (result == null) { AuxProtectBungee.tell(sender, plugin.lang.translate("lookup-no-results-selected")); return true; } + if (perpage == -1) { + perpage = result.perpage; + } + if (first) { + page = 1; + } else if (last) { + page = result.getLastPage(result.perpage); + } else if (next) { + page = result.prevpage + 1; + } else if (prev) { + page = result.prevpage - 1; + } + if (perpage > 0) { + if (perpage > 100) { + perpage = 100; + } + result.showPage(page, perpage); + return true; + } } } + HashMap params = new HashMap<>(); boolean count = false; - boolean showTime = false; + boolean playtime = false; boolean bw = false; long startTime = 0; for (int i = 1; i < args.length; i++) { if (args[i].equalsIgnoreCase("#count")) { count = true; continue; - } else if (args[i].equalsIgnoreCase("#time")) { - showTime = true; - continue; } else if (args[i].equalsIgnoreCase("#bw")) { bw = true; continue; + } else if (args[i].equalsIgnoreCase("#pt")) { + if (!MyPermission.LOOKUP_PLAYTIME.hasPermission(sender)) { + AuxProtectBungee.tell(sender, plugin.translate("no-permission-flag")); + return true; + } + playtime = true; + continue; } String[] split = args[i].split(":"); @@ -112,9 +150,14 @@ public class LookupCommand { token = "world"; break; } + if (token.equalsIgnoreCase("db")) { + if (!MyPermission.ADMIN.hasPermission(sender)) { + AuxProtectBungee.tell(sender, plugin.translate("no-permission")); + return true; + } + } if (split.length != 2 || !validParams.contains(token)) { - AuxProtectBungee.tell(sender, - String.format(plugin.lang.translate("lookup-invalid-parameter"), args[i])); + AuxProtectBungee.tell(sender, String.format(plugin.translate("lookup-invalid-parameter"), args[i])); return true; } String param = split[1]; @@ -127,7 +170,7 @@ public class LookupCommand { } if (time < 0) { AuxProtectBungee.tell(sender, - String.format(plugin.lang.translate("lookup-invalid-parameter"), args[i])); + String.format(plugin.translate("lookup-invalid-parameter"), args[i])); return true; } param = time + ""; @@ -176,38 +219,67 @@ public class LookupCommand { params.put("target", target); } } + if (playtime) { + if (params.containsKey("user")) { + if (params.get("user").split(",").length > 1) { + AuxProtectBungee.tell(sender, plugin.translate("lookup-playtime-toomanyusers")); + return true; + } + } else { + AuxProtectBungee.tell(sender, plugin.translate("lookup-playtime-nouser")); + return true; + } + if (params.containsKey("action")) { + params.remove("action"); + params.put("action", "session"); + } + } final boolean count_ = count; - final boolean showTime_ = showTime; - AuxProtectBungee.tell(sender, plugin.lang.translate("lookup-looking")); + final boolean playtime_ = playtime; + final long startTime_ = startTime; + AuxProtectBungee.tell(sender, plugin.translate("lookup-looking")); Runnable runnable = new Runnable() { @Override public void run() { - // TODO: Sender compatibility ArrayList results = null; try { - results = plugin.getSqlManager().lookup(params, null, false); + results = plugin.getSqlManager().lookup(params, player != null ? player.getLocation() : null, + false); } catch (LookupException e) { AuxProtectBungee.tell(sender, e.errorMessage); return; } if (results == null || results.size() == 0) { - AuxProtectBungee.tell(sender, plugin.lang.translate("lookup-noresults")); + AuxProtectBungee.tell(sender, plugin.translate("lookup-noresults")); return; } if (count_) { - AuxProtectBungee.tell(sender, String.format(plugin.lang.translate("lookup-count"), results.size())); + AuxProtectBungee.tell(sender, String.format(plugin.translate("lookup-count"), results.size())); + } else if (playtime_) { + String users = params.get("user"); + if (users == null) { + AuxProtectBungee.tell(sender, plugin.translate("playtime-nouser")); + return; + } + if (users.contains(",")) { + AuxProtectBungee.tell(sender, plugin.translate("playtime-toomanyusers")); + return; + } + sender.sendMessage( + PlayTimeSolver.solvePlaytime(results, (int) Math.round(startTime_ / (1000 * 3600)), users)); } else { String uuid = "nonplayer"; - if (sender instanceof ProxiedPlayer) { - uuid = ((ProxiedPlayer) sender).getUniqueId().toString(); + if (player != null) { + uuid = player.getUniqueId().toString(); } - Results result = new Results(plugin, results, sender, showTime_); + Results result = new Results(plugin, results, sender); result.showPage(1, 4); LookupCommand.this.results.put(uuid, result); } } }; + // plugin.dbRunnable.scheduleLookup(runnable); plugin.dbRunnable.scheduleLookup(runnable); return true; } diff --git a/src/dev/heliosares/auxprotect/command/APCommand.java b/src/dev/heliosares/auxprotect/command/APCommand.java index c059411..a5bfafe 100644 --- a/src/dev/heliosares/auxprotect/command/APCommand.java +++ b/src/dev/heliosares/auxprotect/command/APCommand.java @@ -4,6 +4,7 @@ import java.sql.SQLException; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -61,7 +62,8 @@ public class APCommand implements CommandExecutor { return true; } return moneyCommand.onCommand(sender, command, label, args); - } else if ((args[0].equalsIgnoreCase("x") || args[0].equalsIgnoreCase("xray")) && plugin.config.isPrivate()) { + } else if ((args[0].equalsIgnoreCase("x") || args[0].equalsIgnoreCase("xray")) + && plugin.config.isPrivate()) { if (!MyPermission.LOOKUP_XRAY.hasPermission(sender)) { sender.sendMessage(plugin.translate("no-permission")); return true; @@ -91,7 +93,7 @@ public class APCommand implements CommandExecutor { } catch (NumberFormatException e) { } if (verbosity < 0 || verbosity > 5) { - sender.sendMessage("§cInvalid verbosity level. /ap debug [0-5]"); + sender.sendMessage("§cInvalid verbosity level. /ap debug [0-5]"); return true; } } else { @@ -104,7 +106,7 @@ public class APCommand implements CommandExecutor { plugin.debug = verbosity; plugin.getConfig().set("debug", plugin.debug); plugin.saveConfig(); - sender.sendMessage("Debug " + (verbosity > 0 ? "§aenabled. §7Level: " + verbosity : "§cdisabled.")); + sender.sendMessage("Debug " + (verbosity > 0 ? "§aenabled. §7Level: " + verbosity : "§cdisabled.")); return true; } else if (args[0].equalsIgnoreCase("help")) { if (!MyPermission.HELP.hasPermission(sender)) { @@ -127,8 +129,8 @@ public class APCommand implements CommandExecutor { } DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMMYY HH:mm.ss"); if (args.length == 1) { - sender.sendMessage("§9Server time:"); - sender.sendMessage("§7" + LocalDateTime.now().format(formatter)); + sender.sendMessage("§9Server time:"); + sender.sendMessage("§7" + LocalDateTime.now().format(formatter)); return true; } else if (args.length == 2) { if (args[1].startsWith("+") || args[1].startsWith("-")) { @@ -139,8 +141,8 @@ public class APCommand implements CommandExecutor { return true; } sender.sendMessage( - "§9Server time " + (add ? "plus" : "minus") + " " + args[1].substring(1) + ":"); - sender.sendMessage("§7" + "§9Server time " + (add ? "plus" : "minus") + " " + args[1].substring(1) + ":"); + sender.sendMessage("§7" + LocalDateTime.now().plusSeconds((add ? 1 : -1) * (time / 1000)).format(formatter)); return true; } @@ -156,15 +158,25 @@ public class APCommand implements CommandExecutor { // plugin.saveConfig(); plugin.reloadConfig(); plugin.config.load(); - sender.sendMessage("§aConfig reloaded"); + sender.sendMessage("§aConfig reloaded"); return true; - } else if (args[0].equalsIgnoreCase("sql")) { - if (!MyPermission.SQL.hasPermission(sender)) { + } else if (args[0].equalsIgnoreCase("stats")) { + if (!MyPermission.ADMIN.hasPermission(sender)) { sender.sendMessage(plugin.translate("no-permission")); return true; } - if (plugin.debug == 0) { - sender.sendMessage("§cDebug mode must be enabled to use this command."); + + sender.sendMessage("§7Rows: §9" + plugin.getSqlManager().getCount()); + sender.sendMessage("§7Average lookup time: §9" + + Math.round(plugin.getSqlManager().lookupTime.getMean() / 1000.0) / 1000.0 + "§7ms"); + sender.sendMessage("§7Average record time per entry: §9" + + Math.round(plugin.getSqlManager().putTimePerEntry.getMean() / 1000.0) / 1000.0 + "§7ms"); + sender.sendMessage("§7Average lookup time per execution: §9" + + Math.round(plugin.getSqlManager().putTimePerExec.getMean() / 1000.0) / 1000.0 + "§7ms"); + return true; + } else if (args[0].equalsIgnoreCase("sql")) { + if (!MyPermission.SQL.hasPermission(sender) || !sender.equals(Bukkit.getConsoleSender())) { + sender.sendMessage(plugin.translate("no-permission")); return true; } String msg = ""; @@ -174,11 +186,11 @@ public class APCommand implements CommandExecutor { try { plugin.getSqlManager().execute(msg.trim()); } catch (SQLException e) { - sender.sendMessage("§cAn error occured."); + sender.sendMessage("§cAn error occured."); e.printStackTrace(); return true; } - sender.sendMessage("§aSQL statement executed successfully."); + sender.sendMessage("§aSQL statement executed successfully."); return true; } else { sender.sendMessage(plugin.translate("unknown-subcommand")); @@ -187,17 +199,17 @@ public class APCommand implements CommandExecutor { } sendInfo(sender); if (MyPermission.HELP.hasPermission(sender)) { - sender.sendMessage("§7Do §9/ap help§7 for more info."); + sender.sendMessage("§7Do §9/ap help§7 for more info."); } return true; } private void sendInfo(CommandSender sender) { - sender.sendMessage("§9AuxProtect" - + (MyPermission.ADMIN.hasPermission(sender) ? (" §7v" + plugin.getDescription().getVersion()) : "")); - sender.sendMessage("§7Developed by §9Heliosares"); + sender.sendMessage("§9AuxProtect" + + (MyPermission.ADMIN.hasPermission(sender) ? (" §7v" + plugin.getDescription().getVersion()) : "")); + sender.sendMessage("§7Developed by §9Heliosares"); if (MyPermission.ADMIN.hasPermission(sender)) { - sender.sendMessage("§7§ohttps://www.spigotmc.org/resources/auxprotect.99147/"); + sender.sendMessage("§7§ohttps://www.spigotmc.org/resources/auxprotect.99147/"); } } diff --git a/src/dev/heliosares/auxprotect/command/APCommandTab.java b/src/dev/heliosares/auxprotect/command/APCommandTab.java index 6fc7b4a..fcd0aed 100644 --- a/src/dev/heliosares/auxprotect/command/APCommandTab.java +++ b/src/dev/heliosares/auxprotect/command/APCommandTab.java @@ -16,12 +16,14 @@ public class APCommandTab implements TabCompleter { private final LookupCommandTab lookupCommandTab; private final PurgeCommandTab purgeCommandTab; private final PlaytimeCommandTab playtimeCommandTab; + private final MoneyCommandTab moneyCommandTab; public APCommandTab(AuxProtect plugin) { // this.plugin = plugin; this.lookupCommandTab = new LookupCommandTab(plugin); this.purgeCommandTab = new PurgeCommandTab(plugin); this.playtimeCommandTab = new PlaytimeCommandTab(plugin); + this.moneyCommandTab = new MoneyCommandTab(plugin); } @Override @@ -32,10 +34,16 @@ public class APCommandTab implements TabCompleter { if (args.length == 1) { if (MyPermission.LOOKUP.hasPermission(sender)) { possible.add("lookup"); - possible.add("playtime"); + if (MyPermission.LOOKUP_PLAYTIME.hasPermission(sender)) { + possible.add("playtime"); + } } if (MyPermission.ADMIN.hasPermission(sender)) { possible.add("debug"); + possible.add("stats"); + } + if (MyPermission.LOOKUP_MONEY.hasPermission(sender)) { + possible.add("money"); } if (MyPermission.HELP.hasPermission(sender)) { possible.add("help"); @@ -49,9 +57,10 @@ public class APCommandTab implements TabCompleter { if ((args[0].equalsIgnoreCase("lookup") || args[0].equalsIgnoreCase("l")) && MyPermission.LOOKUP.hasPermission(sender)) { possible.addAll(lookupCommandTab.onTabComplete(sender, cmd, label, args)); - } else if (((args[0].equalsIgnoreCase("playtime") || args[0].equalsIgnoreCase("pt")) - && MyPermission.LOOKUP_PLAYTIME.hasPermission(sender)) - || (args[0].equalsIgnoreCase("money") && MyPermission.LOOKUP_MONEY.hasPermission(sender))) { + } else if (args[0].equalsIgnoreCase("money") && MyPermission.LOOKUP_MONEY.hasPermission(sender)) { + possible.addAll(moneyCommandTab.onTabComplete(sender, cmd, label, args)); + } else if ((args[0].equalsIgnoreCase("playtime") || args[0].equalsIgnoreCase("pt")) + && MyPermission.LOOKUP_PLAYTIME.hasPermission(sender)) { possible.addAll(playtimeCommandTab.onTabComplete(sender, cmd, label, args)); } else if ((args[0].equalsIgnoreCase("purge")) && MyPermission.PURGE.hasPermission(sender)) { possible.addAll(purgeCommandTab.onTabComplete(sender, cmd, label, args)); diff --git a/src/dev/heliosares/auxprotect/command/MoneyCommandTab.java b/src/dev/heliosares/auxprotect/command/MoneyCommandTab.java new file mode 100644 index 0000000..6ecf7b0 --- /dev/null +++ b/src/dev/heliosares/auxprotect/command/MoneyCommandTab.java @@ -0,0 +1,35 @@ +package dev.heliosares.auxprotect.command; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; +import org.bukkit.util.StringUtil; + +import dev.heliosares.auxprotect.AuxProtect; + +public class MoneyCommandTab implements TabCompleter { + // private final AuxProtect plugin; + + public MoneyCommandTab(AuxProtect plugin) { + // this.plugin = plugin; + } + + @Override + public List onTabComplete(CommandSender sender, Command cmd, String label, String[] args) { + List possible = new ArrayList<>(); + String currentArg = args[args.length - 1]; + + for (Player player : Bukkit.getOnlinePlayers()) { + possible.add(player.getName()); + } + + List output = new ArrayList<>(); + StringUtil.copyPartialMatches(currentArg, possible, output); + return output; + } +} diff --git a/src/dev/heliosares/auxprotect/command/XrayCommand.java b/src/dev/heliosares/auxprotect/command/XrayCommand.java index 5d97b76..9e652de 100644 --- a/src/dev/heliosares/auxprotect/command/XrayCommand.java +++ b/src/dev/heliosares/auxprotect/command/XrayCommand.java @@ -1,5 +1,6 @@ package dev.heliosares.auxprotect.command; +import java.lang.reflect.Method; import java.sql.Statement; import java.time.LocalDateTime; import java.util.ArrayList; @@ -250,6 +251,7 @@ public class XrayCommand implements CommandExecutor { sender.sendMessage(plugin.translate("lookup-looking")); new BukkitRunnable() { + @SuppressWarnings("unchecked") @Override public void run() { ArrayList entries = new ArrayList<>(); @@ -270,12 +272,25 @@ public class XrayCommand implements CommandExecutor { List lookup = null; try { Statement statement = Database.getConnection(true).createStatement(); - lookup = Lookup.performLookup(statement, Bukkit.getConsoleSender(), new ArrayList(), - new ArrayList(), blocks, new ArrayList<>(), new ArrayList(), - actions/* actions */, null, null, - (int) ((System.currentTimeMillis() - time) / 1000), false, true); + /* + * lookup = Lookup.performLookup(statement, Bukkit.getConsoleSender(), new + * ArrayList(), new ArrayList(), blocks, new + * ArrayList(), new ArrayList(), actions, null, null, + * ((System.currentTimeMillis() - time) / 1000), false, true); + */ + Method method = null; + for (Method method_ : Lookup.class.getMethods()) { + if (method_.getName().equals("performLookup")) { + method = method_; + break; + } + } + lookup = (List) method.invoke(null, statement, Bukkit.getConsoleSender(), + new ArrayList(), new ArrayList(), blocks, new ArrayList(), + new ArrayList(), actions/* actions */, null, null, + ((System.currentTimeMillis() - time) / 1000), false, true); - } catch (Exception e) { + } catch (Throwable e) { e.printStackTrace(); sender.sendMessage("§cAn error occured."); return; diff --git a/src/dev/heliosares/auxprotect/database/SQLiteManager.java b/src/dev/heliosares/auxprotect/database/SQLiteManager.java index ef30ade..e3cdd8f 100644 --- a/src/dev/heliosares/auxprotect/database/SQLiteManager.java +++ b/src/dev/heliosares/auxprotect/database/SQLiteManager.java @@ -18,6 +18,7 @@ import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import dev.heliosares.auxprotect.IAuxProtect; +import dev.heliosares.auxprotect.utils.MovingAverage; public class SQLiteManager { private Connection connection; @@ -31,8 +32,6 @@ public class SQLiteManager { private int version; - private int count; - public int getCount() { return count; } @@ -45,6 +44,11 @@ public class SQLiteManager { return version; } + public MovingAverage putTimePerEntry = new MovingAverage(100); + public MovingAverage putTimePerExec = new MovingAverage(100); + public MovingAverage lookupTime = new MovingAverage(100); + private int count; + public static enum TABLE { AUXPROTECT, AUXPROTECT_SPAM, AUXPROTECT_LONGTERM, AUXPROTECT_ABANDONED, AUXPROTECT_INVENTORY, WORLDS; @@ -252,6 +256,7 @@ public class SQLiteManager { protected long put(TABLE table, ArrayList entries) throws SQLException { if (!isConnected) return -1; + long start = System.nanoTime(); synchronized (connection) { holdingConnectionSince = System.currentTimeMillis(); holdingConnection = "put"; @@ -322,6 +327,8 @@ public class SQLiteManager { statement.close(); count += entries.size(); holdingConnectionSince = 0; + this.putTimePerEntry.addData((System.nanoTime() - start) / (double) entries.size()); + this.putTimePerExec.addData(System.nanoTime() - start); return serialized_id; } } @@ -350,6 +357,7 @@ public class SQLiteManager { public ArrayList lookup(HashMap params, Location location, boolean exact) throws LookupException { + long start = System.nanoTime(); if (!isConnected) return null; @@ -649,6 +657,7 @@ public class SQLiteManager { 1); holdingConnectionSince = 0; + this.lookupTime.addData(System.nanoTime() - start); return output; } } catch (Exception e) { diff --git a/src/dev/heliosares/auxprotect/utils/Experience.java b/src/dev/heliosares/auxprotect/utils/Experience.java index 2bf6ae7..f892fc6 100644 --- a/src/dev/heliosares/auxprotect/utils/Experience.java +++ b/src/dev/heliosares/auxprotect/utils/Experience.java @@ -13,7 +13,7 @@ public class Experience { * href=http://minecraft.gamepedia.com/Experience#Leveling_up>Experience#Leveling_up */ public static int getTotalExp(Player player) { - return getExpFromLevel(player.getLevel()) + player.getExpToLevel(); + return getExpFromLevel(player.getLevel()) + (int) player.getExp(); } /** diff --git a/src/dev/heliosares/auxprotect/utils/MovingAverage.java b/src/dev/heliosares/auxprotect/utils/MovingAverage.java new file mode 100644 index 0000000..ad412b5 --- /dev/null +++ b/src/dev/heliosares/auxprotect/utils/MovingAverage.java @@ -0,0 +1,75 @@ +package dev.heliosares.auxprotect.utils; + +import java.util.Arrays; + +public class MovingAverage { + public double[] data; + private int index = -1; + private long age; + + public MovingAverage(int datapoints) { + data = new double[datapoints]; + } + + public void reset() { + for (int i = 0; i < data.length; i++) { + data[i] = 0; + } + age = 0; + } + + public int getIndex() { + return index; + } + + public void addData(double value) { + index++; + age++; + if (index >= data.length) { + index = 0; + } + data[index] = value; + } + + public long getAge() { + return age; + } + + public double getMean() { + double total = 0; + int count = 0; + for (int i = 0; i < data.length && i < age; i++) { + total += data[i]; + count++; + } + return total / (double) count; + } + + public double getMedian() { + double[] data1 = Arrays.copyOf(data, data.length); + Arrays.sort(data1); + + return data1[data1.length / 2]; + } + + public double getPk() { + double max = 0; + for (double part : data) { + if (part > max) { + max = part; + } + } + return max; + } + + public double getLast() { + if (index < 0) { + return 0; + } + return data[index]; + } + + public int getSize() { + return data.length; + } +} diff --git a/src/dev/heliosares/auxprotect/utils/Telemetry.java b/src/dev/heliosares/auxprotect/utils/Telemetry.java index b6ad457..05fd8ae 100644 --- a/src/dev/heliosares/auxprotect/utils/Telemetry.java +++ b/src/dev/heliosares/auxprotect/utils/Telemetry.java @@ -18,5 +18,12 @@ public class Telemetry { return count; } })); + + metrics.addCustomChart(new Metrics.SimplePie("private", new Callable() { + @Override + public String call() throws Exception { + return plugin.config.isPrivate() ? "Private" : "Public"; + } + })); } } diff --git a/src/dev/heliosares/auxprotect/utils/UpdateChecker.java b/src/dev/heliosares/auxprotect/utils/UpdateChecker.java index 9995a61..a43a82f 100644 --- a/src/dev/heliosares/auxprotect/utils/UpdateChecker.java +++ b/src/dev/heliosares/auxprotect/utils/UpdateChecker.java @@ -21,4 +21,56 @@ public class UpdateChecker { } return null; } + + private static int[] versionAsIntArray(String version) { + String[] parts = version.split("\\."); + if (version.startsWith("v")) { + version = version.substring(1); + } + int array[] = new int[parts.length]; + for (int i = 0; i < parts.length; i++) { + try { + array[i] = Integer.parseInt(parts[i]); + } catch (NumberFormatException ignored) { + + } + } + return array; + } + + public static String getHigherVersion(String ver1, String ver2) { + int compare = compareVersions(ver1, ver2); + if (compare == -1) { + return ver1; + } + if (compare == 1) { + return ver2; + } + return "equal"; + } + + /** + * @returns -1 if ver1 is greater, 0 if equal, 1 if ver2 i greater + */ + public static int compareVersions(String ver1, String ver2) { + int[] ver1int = versionAsIntArray(ver1); + int[] ver2int = versionAsIntArray(ver2); + for (int i = 0; i < ver1int.length && i < ver2int.length; i++) { + int ver1part = ver1int[i]; + int ver2part = ver2int[i]; + if (ver1part > ver2part) { + return -1; + } + if (ver1part < ver2part) { + return 1; + } + } + if (ver1int.length > ver2int.length) { + return -1; + } + if (ver1int.length < ver2int.length) { + return 1; + } + return 0; + } } \ No newline at end of file