From fee62529f2a24f296b3f8da435d98606d4abe409 Mon Sep 17 00:00:00 2001 From: Internal-Exception Date: Fri, 8 Apr 2022 23:36:43 -0400 Subject: [PATCH] 1.1-pre1 --- .settings/org.eclipse.core.resources.prefs | 2 - bungee.yml | 2 +- en-us.yml | 3 +- plugin.yml | 2 +- pom.xml | 2 +- src/dev/heliosares/auxprotect/AuxProtect.java | 69 +- .../heliosares/auxprotect/IAuxProtect.java | 10 +- .../{APListener.java => APBListener.java} | 86 +- .../auxprotect/bungee/AuxProtectBungee.java | 147 +- .../auxprotect/bungee/Language.java | 1 + .../heliosares/auxprotect/bungee/Results.java | 136 -- .../auxprotect/bungee/YMLManager.java | 4 +- .../{APCommand.java => APBCommand.java} | 75 +- .../bungee/command/LookupCommand.java | 353 ---- .../auxprotect/command/APCommand.java | 13 +- .../auxprotect/command/InvCommand.java | 10 +- .../auxprotect/command/LookupCommand.java | 509 +++--- .../auxprotect/command/PurgeCommand.java | 51 +- .../auxprotect/command/XrayCommand.java | 13 +- .../auxprotect/database/DatabaseRunnable.java | 24 +- .../auxprotect/database/DbEntry.java | 118 +- .../auxprotect/database/EntryAction.java | 23 +- .../auxprotect/database/Results.java | 66 +- .../auxprotect/database/SQLManager.java | 1417 ++++++++++++----- .../auxprotect/database/XrayResults.java | 7 +- .../auxprotect/listeners/PlayerListener.java | 45 +- .../heliosares/auxprotect/utils/BidiMap.java | 46 + .../auxprotect/utils/BidiMapCache.java | 110 ++ .../auxprotect/utils/EntryFormatter.java | 10 +- .../auxprotect/utils/InvSerialization.java | 26 +- .../auxprotect/utils/MoneySolver.java | 12 +- .../auxprotect/utils/MyPermission.java | 4 + .../heliosares/auxprotect/utils/MySender.java | 78 + .../auxprotect/utils/UpdateChecker.java | 50 +- .../auxprotect/utils/XraySolver.java | 6 +- .../auxprotect/utils/YMLManager.java | 2 +- 36 files changed, 2026 insertions(+), 1506 deletions(-) delete mode 100644 .settings/org.eclipse.core.resources.prefs rename src/dev/heliosares/auxprotect/bungee/{APListener.java => APBListener.java} (57%) delete mode 100644 src/dev/heliosares/auxprotect/bungee/Results.java rename src/dev/heliosares/auxprotect/bungee/command/{APCommand.java => APBCommand.java} (70%) delete mode 100644 src/dev/heliosares/auxprotect/bungee/command/LookupCommand.java create mode 100644 src/dev/heliosares/auxprotect/utils/BidiMap.java create mode 100644 src/dev/heliosares/auxprotect/utils/BidiMapCache.java create mode 100644 src/dev/heliosares/auxprotect/utils/MySender.java diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 93a53a2..0000000 --- a/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/dev/heliosares/auxprotect/bungee/Results.java=UTF-8 diff --git a/bungee.yml b/bungee.yml index 6396780..e970de2 100644 --- a/bungee.yml +++ b/bungee.yml @@ -1,4 +1,4 @@ name: AuxProtectBungee main: dev.heliosares.auxprotect.bungee.AuxProtectBungee -version: 1.0.10.2 +version: 1.1-pre1 author: Heliosares \ No newline at end of file diff --git a/en-us.yml b/en-us.yml index 35e56a1..df4a96b 100644 --- a/en-us.yml +++ b/en-us.yml @@ -17,10 +17,11 @@ lookup-incompatible-tables: '&cThose actions are incompatible.' lookup-action-negate: '&cYou cannot negate actions.' lookup-action-perm: '&cYou do not have permission to lookup that action.' command-help-1: '&cYou don''t have a lookup to page through.' -purge-purging: '&9Purge in progress..' +purge-purging: '&9Purging ''%s''...' purge-complete: '&9Purge complete.' purge-error: '&cAn error occured while purging.' purge-time: '&cThat purge is too short. Try a longer amount of time.' +purge-table: '&cThat table is invalid or does not exist.' unknown-subcommand: 'Unknown subcommand. Do ''/ap help'' for more info.' command-help-unknown-subcommand: '&cUnknown subcommand.' command-help-header: '&f----- &9AuxProtect Help &f-----' diff --git a/plugin.yml b/plugin.yml index 6998f1a..03ff232 100644 --- a/plugin.yml +++ b/plugin.yml @@ -1,5 +1,5 @@ name: AuxProtect -version: 1.0.11 +version: 1.1-pre1 main: dev.heliosares.auxprotect.AuxProtect description: A plugin designed to supplement CoreProtect in a few ways. api-version: 1.13 diff --git a/pom.xml b/pom.xml index 5af7b84..15b0a15 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 AuxProtect AuxProtect - 1.0.11 + 1.1-pre1 AuxProtect ${testserver}/plugins diff --git a/src/dev/heliosares/auxprotect/AuxProtect.java b/src/dev/heliosares/auxprotect/AuxProtect.java index d7f8342..b7480e9 100644 --- a/src/dev/heliosares/auxprotect/AuxProtect.java +++ b/src/dev/heliosares/auxprotect/AuxProtect.java @@ -2,7 +2,9 @@ package dev.heliosares.auxprotect; import java.io.File; import java.io.IOException; +import java.sql.SQLException; import java.util.HashMap; +import java.util.logging.Level; import org.bukkit.Bukkit; import org.bukkit.block.Container; @@ -29,6 +31,7 @@ import dev.heliosares.auxprotect.listeners.*; import dev.heliosares.auxprotect.utils.InvSerialization; import dev.heliosares.auxprotect.utils.Language; import dev.heliosares.auxprotect.utils.MyPermission; +import dev.heliosares.auxprotect.utils.MySender; import dev.heliosares.auxprotect.utils.Telemetry; import dev.heliosares.auxprotect.utils.UpdateChecker; import dev.heliosares.auxprotect.utils.YMLManager; @@ -60,7 +63,7 @@ public class AuxProtect extends JavaPlugin implements IAuxProtect { private Economy econ; private static AuxProtect instance; - SQLManager sqlManager; + private static SQLManager sqlManager; public String update; long lastCheckedForUpdate; @@ -101,7 +104,7 @@ public class AuxProtect extends JavaPlugin implements IAuxProtect { } catch (Exception e) { warning("Failed to parse version string: \"" + Bukkit.getBukkitVersion() + "\". Defaulting to 1.16"); SERVER_VERSION = 16; - e.printStackTrace(); + print(e); } debug("Compatability version: " + SERVER_VERSION, 1); @@ -143,13 +146,15 @@ public class AuxProtect extends JavaPlugin implements IAuxProtect { @Override public void run() { - boolean success = false; - if (mysql) { - success = sqlManager.connect(user, pass); - } else { - success = sqlManager.connect(); - } - if (!success) { + try { + if (mysql) { + sqlManager.connect(user, pass); + } else { + sqlManager.connect(); + } + sqlManager.count(); + } catch (SQLException e) { + print(e); getLogger().severe("Failed to connect to SQL database. Disabling."); setEnabled(false); return; @@ -157,16 +162,22 @@ public class AuxProtect extends JavaPlugin implements IAuxProtect { for (Object command : getConfig().getList("purge-cmds")) { String cmd = (String) command; - PurgeCommand purge = new PurgeCommand(AuxProtect.this); String[] argsOld = cmd.split(" "); String[] args = new String[argsOld.length + 1]; args[0] = "purge"; for (int i = 0; i < argsOld.length; i++) { args[i + 1] = argsOld[i]; } - purge.purge(Bukkit.getConsoleSender(), args); + PurgeCommand.purge(AuxProtect.this, new MySender(Bukkit.getConsoleSender()), args); + } + + sqlManager.purgeUIDs(); + + try { + sqlManager.vacuum(); + } catch (SQLException e) { + print(e); } - sqlManager.count(); } }.runTaskAsynchronously(this); @@ -239,7 +250,7 @@ public class AuxProtect extends JavaPlugin implements IAuxProtect { } } } - }.runTaskTimerAsynchronously(this, 10 * 20, 10 * 20); + }.runTaskTimerAsynchronously(this, 1 * 20, 10 * 20); getServer().getPluginManager().registerEvents(new ProjectileListener(this), this); getServer().getPluginManager().registerEvents(new EntityListener(this), this); @@ -288,7 +299,7 @@ public class AuxProtect extends JavaPlugin implements IAuxProtect { } } catch (Exception e) { warning("Exception while hooking other plugins"); - e.printStackTrace(); + print(e); } this.getCommand("claiminv").setExecutor(new ClaimInvCommand(this)); @@ -325,9 +336,12 @@ public class AuxProtect extends JavaPlugin implements IAuxProtect { @Override public void onDisable() { - dbRunnable.run(); - if (sqlManager != null) + if (dbRunnable != null) { + dbRunnable.run(); + } + if (sqlManager != null) { sqlManager.close(); + } dbRunnable = null; sqlManager = null; } @@ -370,6 +384,9 @@ public class AuxProtect extends JavaPlugin implements IAuxProtect { } public String formatMoney(double d) { + if (d <= 0) { + return "$0"; + } if (econ == null) { return "$" + (Math.round(d * 100) / 100.0); } @@ -401,6 +418,11 @@ public class AuxProtect extends JavaPlugin implements IAuxProtect { getLogger().warning(message); } + @Override + public void print(Throwable t) { + getLogger().log(Level.WARNING, t.getMessage(), t); + } + @Override public boolean isBungee() { return false; @@ -414,4 +436,19 @@ public class AuxProtect extends JavaPlugin implements IAuxProtect { public APConfig getAPConfig() { return config; } + + @Override + public void add(DbEntry dbEntry) { + dbRunnable.add(dbEntry); + } + + @Override + public void runAsync(Runnable run) { + getServer().getScheduler().runTaskAsynchronously(this, run); + } + + @Override + public void runSync(Runnable run) { + getServer().getScheduler().runTask(this, run); + } } diff --git a/src/dev/heliosares/auxprotect/IAuxProtect.java b/src/dev/heliosares/auxprotect/IAuxProtect.java index e1c3ff4..11eed0c 100644 --- a/src/dev/heliosares/auxprotect/IAuxProtect.java +++ b/src/dev/heliosares/auxprotect/IAuxProtect.java @@ -3,6 +3,7 @@ package dev.heliosares.auxprotect; import java.io.File; import java.io.InputStream; +import dev.heliosares.auxprotect.database.DbEntry; import dev.heliosares.auxprotect.database.SQLManager; public interface IAuxProtect { @@ -20,6 +21,8 @@ public interface IAuxProtect { void debug(String msg, int verb); void warning(String msg); + + void print(Throwable t); boolean isBungee(); @@ -28,5 +31,10 @@ public interface IAuxProtect { int getDebug(); APConfig getAPConfig(); - + + void add(DbEntry dbEntry); + + public void runAsync(Runnable run); + + public void runSync(Runnable runnable); } diff --git a/src/dev/heliosares/auxprotect/bungee/APListener.java b/src/dev/heliosares/auxprotect/bungee/APBListener.java similarity index 57% rename from src/dev/heliosares/auxprotect/bungee/APListener.java rename to src/dev/heliosares/auxprotect/bungee/APBListener.java index f46c1de..07f825d 100644 --- a/src/dev/heliosares/auxprotect/bungee/APListener.java +++ b/src/dev/heliosares/auxprotect/bungee/APBListener.java @@ -1,26 +1,26 @@ package dev.heliosares.auxprotect.bungee; -import java.util.ArrayList; -import java.util.HashMap; +import java.net.InetSocketAddress; import java.util.UUID; import dev.heliosares.auxprotect.database.DbEntry; import dev.heliosares.auxprotect.database.EntryAction; -import dev.heliosares.auxprotect.database.SQLManager.LookupException; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.event.ChatEvent; -import net.md_5.bungee.api.event.ServerConnectEvent; +import net.md_5.bungee.api.event.LoginEvent; +import net.md_5.bungee.api.event.PlayerDisconnectEvent; import net.md_5.bungee.api.plugin.Listener; import net.md_5.bungee.event.EventHandler; +import net.md_5.bungee.event.EventPriority; import xyz.olivermartin.multichat.bungee.Events; import xyz.olivermartin.multichat.bungee.MultiChat; import xyz.olivermartin.multichat.bungee.MultiChatUtil; -public class APListener implements Listener { +public class APBListener implements Listener { private final AuxProtectBungee plugin; - public APListener(AuxProtectBungee plugin) { + public APBListener(AuxProtectBungee plugin) { this.plugin = plugin; } @@ -29,8 +29,8 @@ public class APListener implements Listener { if (e.getSender() instanceof ProxiedPlayer) { ProxiedPlayer player = (ProxiedPlayer) e.getSender(); if (e.isCommand()) { - DbEntry entry = new DbEntry(player.getName(), EntryAction.COMMAND, false, "$null", 0, 0, 0, - e.getMessage(), player.getUniqueId().toString()); + DbEntry entry = new DbEntry(AuxProtectBungee.getLabel(player), EntryAction.COMMAND, false, + e.getMessage(), ""); plugin.dbRunnable.add(entry); if (e.getMessage().toLowerCase().startsWith("/msg ") || e.getMessage().toLowerCase().startsWith("/message ") @@ -54,8 +54,8 @@ public class APListener implements Listener { ProxiedPlayer target = ProxyServer.getInstance() .getPlayer((UUID) Events.PMToggle.get(player.getUniqueId())); - DbEntry entry = new DbEntry((player).getName(), EntryAction.MSG, false, "$null", 0, 0, 0, - target.getName(), message); + DbEntry entry = new DbEntry(AuxProtectBungee.getLabel(player), EntryAction.MSG, false, + AuxProtectBungee.getLabel(target), message); plugin.dbRunnable.add(entry); } @@ -70,8 +70,8 @@ public class APListener implements Listener { if (ProxyServer.getInstance().getPlayer(args[0]) != null) { ProxiedPlayer target = ProxyServer.getInstance().getPlayer(args[0]); - DbEntry entry = new DbEntry((player).getName(), EntryAction.MSG, false, "$null", 0, 0, 0, - target.getName(), message); + DbEntry entry = new DbEntry(AuxProtectBungee.getLabel(player), EntryAction.MSG, false, + AuxProtectBungee.getLabel(target), message); plugin.dbRunnable.add(entry); } } @@ -85,50 +85,42 @@ public class APListener implements Listener { ProxiedPlayer target = ProxyServer.getInstance() .getPlayer((UUID) MultiChat.lastmsg.get(player.getUniqueId())); - DbEntry entry = new DbEntry(player.getName(), EntryAction.MSG, false, "$null", 0, 0, 0, - target.getName(), message); + DbEntry entry = new DbEntry(AuxProtectBungee.getLabel(player), EntryAction.MSG, false, + AuxProtectBungee.getLabel(target), message); plugin.dbRunnable.add(entry); } } } } - @EventHandler - public void serverConnectEvent(ServerConnectEvent e) { - plugin.getSqlManager().updateUsername(e.getPlayer().getUniqueId().toString(), e.getPlayer().getName()); - Runnable run = new Runnable() { + @EventHandler(priority = EventPriority.HIGHEST) + public void serverConnectEvent(LoginEvent e) { + if (e.isCancelled()) { + return; + } + String ip_ = ((InetSocketAddress) e.getConnection().getSocketAddress()).getAddress().toString(); + if (ip_.startsWith("/")) { + ip_ = ip_.substring(1); + } + + final String ip = ip_; + + plugin.runAsync(new Runnable() { @Override public void run() { - HashMap params = new HashMap<>(); - params.put("user", "$" + e.getPlayer().getUniqueId()); - params.put("action", "username"); - - ArrayList results = null; - try { - results = plugin.getSqlManager().lookup(params, null, false); - } catch (LookupException e1) { - plugin.warning(e1.toString()); - return; - } - if (results == null) - return; - String newestusername = ""; - long highestusername = 0; - for (DbEntry entry : results) { - if (entry.getAction() == EntryAction.USERNAME) { - if (entry.getTime() > highestusername) { - highestusername = entry.getTime(); - newestusername = entry.getTarget(); - } - } - } - if (!e.getPlayer().getName().equals(newestusername)) { - plugin.dbRunnable.add(new DbEntry("$"+e.getPlayer().getUniqueId().toString(), EntryAction.USERNAME, false, - "", 0, 0, 0, e.getPlayer().getName(), "")); - } + plugin.getSqlManager().updateUsernameAndIP(e.getConnection().getUniqueId().toString(), + e.getConnection().getName(), ip); } - }; - plugin.getProxy().getScheduler().runAsync(plugin, run); + }); + plugin.dbRunnable.add(new DbEntry("$" + e.getConnection().getUniqueId().toString(), EntryAction.SESSION, true, + "", "IP: " + ip)); } + + @EventHandler + public void onDisconnect(PlayerDisconnectEvent e) { + plugin.dbRunnable + .add(new DbEntry(AuxProtectBungee.getLabel(e.getPlayer()), EntryAction.SESSION, false, "", "")); + } + } diff --git a/src/dev/heliosares/auxprotect/bungee/AuxProtectBungee.java b/src/dev/heliosares/auxprotect/bungee/AuxProtectBungee.java index a1a9526..66b7d63 100644 --- a/src/dev/heliosares/auxprotect/bungee/AuxProtectBungee.java +++ b/src/dev/heliosares/auxprotect/bungee/AuxProtectBungee.java @@ -4,25 +4,35 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; +import java.sql.SQLException; import java.util.concurrent.TimeUnit; +import java.util.logging.Level; + +import org.bukkit.block.Container; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; import com.Acrobot.ChestShop.ChestShop; import dev.heliosares.auxprotect.APConfig; import dev.heliosares.auxprotect.AuxProtect; import dev.heliosares.auxprotect.IAuxProtect; -import dev.heliosares.auxprotect.bungee.command.APCommand; +import dev.heliosares.auxprotect.bungee.command.APBCommand; +import dev.heliosares.auxprotect.command.PurgeCommand; import dev.heliosares.auxprotect.database.DatabaseRunnable; +import dev.heliosares.auxprotect.database.DbEntry; import dev.heliosares.auxprotect.database.SQLManager; import dev.heliosares.auxprotect.listeners.ChestShopListener; import dev.heliosares.auxprotect.listeners.EntityListener; import dev.heliosares.auxprotect.listeners.ShopGUIPlusListener; +import dev.heliosares.auxprotect.utils.MySender; import dev.heliosares.auxprotect.listeners.InventoryListener; import dev.heliosares.auxprotect.listeners.ProjectileListener; import net.brcdev.shopgui.ShopGuiPlugin; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.plugin.Listener; import net.md_5.bungee.api.plugin.Plugin; import net.md_5.bungee.config.Configuration; @@ -44,39 +54,85 @@ public class AuxProtectBungee extends Plugin implements Listener, IAuxProtect { @Override public void onEnable() { - getProxy().getPluginManager().registerCommand(this, new APCommand(this)); - getProxy().getPluginManager().registerListener(this, new APListener(this)); + getProxy().getPluginManager().registerCommand(this, new APBCommand(this)); + getProxy().getPluginManager().registerListener(this, new APBListener(this)); loadConfig(); YMLManager langManager = new YMLManager("en-us.yml", this); langManager.load(); lang = new Language(langManager.getData()); - File sqliteFile = new File(getDataFolder(), "database/auxprotect.db"); - if (!sqliteFile.getParentFile().exists()) { - if (!sqliteFile.getParentFile().mkdirs()) { - this.getLogger().severe("Failed to create database directory."); - this.onDisable(); - return; - } - } - if (!sqliteFile.exists()) { - try { - if (!sqliteFile.createNewFile()) { - throw new IOException(); + boolean mysql = config.getBoolean("MySQL.use", false); + String user = config.getString("MySQL.username", ""); + String pass = config.getString("MySQL.password", ""); + String uri = ""; + if (mysql) { + String host = config.getString("MySQL.host", "localhost"); + String port = config.getString("MySQL.port", "3306"); + String database = config.getString("MySQL.database", "database"); + uri = String.format("jdbc:mysql://%s:%s/%s", host, port, database); + } else { + File sqliteFile = new File(getDataFolder(), "database/auxprotect.db"); + if (!sqliteFile.getParentFile().exists()) { + if (!sqliteFile.getParentFile().mkdirs()) { + this.getLogger().severe("Failed to create database directory."); + this.onDisable(); + return; } - } catch (IOException e) { - this.getLogger().severe("Failed to create database file."); - this.onDisable(); - return; } + if (!sqliteFile.exists()) { + try { + if (!sqliteFile.createNewFile()) { + throw new IOException(); + } + } catch (IOException e) { + this.getLogger().severe("Failed to create database file."); + this.onDisable(); + return; + } + } + uri = "jdbc:sqlite:" + sqliteFile.getAbsolutePath(); } - sqlManager = new SQLManager(this, "jdbc:sqlite:" + sqliteFile.getAbsolutePath(), null); - if (!sqlManager.connect()) { - this.getLogger().severe("Failed to connect to SQL database. Disabling."); - this.onDisable(); - return; - } + sqlManager = new SQLManager(this, uri, config.getString("MySQL.table-prefix")); + + runAsync(new Runnable() { + + @Override + public void run() { + try { + if (mysql) { + sqlManager.connect(user, pass); + } else { + sqlManager.connect(); + } + sqlManager.count(); + } catch (SQLException e) { + print(e); + getLogger().severe("Failed to connect to SQL database. Disabling."); + onDisable(); + return; + } + + for (Object command : config.getList("purge-cmds")) { + String cmd = (String) command; + String[] argsOld = cmd.split(" "); + String[] args = new String[argsOld.length + 1]; + args[0] = "purge"; + for (int i = 0; i < argsOld.length; i++) { + args[i + 1] = argsOld[i]; + } + PurgeCommand.purge(AuxProtectBungee.this, new MySender(getProxy().getConsole()), args); + } + sqlManager.purgeUIDs(); + + try { + sqlManager.vacuum(); + } catch (SQLException e) { + print(e); + } + } + }); + dbRunnable = new DatabaseRunnable(this, sqlManager); getProxy().getScheduler().schedule(this, dbRunnable, 250, 250, TimeUnit.MILLISECONDS); @@ -86,8 +142,12 @@ public class AuxProtectBungee extends Plugin implements Listener, IAuxProtect { public void onDisable() { getProxy().getPluginManager().unregisterListeners(this); getProxy().getPluginManager().unregisterCommands(this); - if (sqlManager != null) + if (dbRunnable != null) { + dbRunnable.run(); + } + if (sqlManager != null) { sqlManager.close(); + } } public static void tell(CommandSender to, String message) { @@ -105,14 +165,14 @@ public class AuxProtectBungee extends Plugin implements Listener, IAuxProtect { try (InputStream in = getResourceAsStream("config.yml")) { Files.copy(in, file.toPath()); } catch (IOException e) { - e.printStackTrace(); + print(e); } } try { config = ConfigurationProvider.getProvider(YamlConfiguration.class) .load(new File(getDataFolder(), "config.yml")); } catch (IOException e) { - e.printStackTrace(); + print(e); } } @@ -154,6 +214,11 @@ public class AuxProtectBungee extends Plugin implements Listener, IAuxProtect { getLogger().warning(message); } + @Override + public void print(Throwable t) { + getLogger().log(Level.WARNING, t.getMessage(), t); + } + @Override public boolean isBungee() { return true; @@ -173,4 +238,30 @@ public class AuxProtectBungee extends Plugin implements Listener, IAuxProtect { // TODO Implement APConfig return null; } + + @Override + public void add(DbEntry dbEntry) { + dbRunnable.add(dbEntry); + } + + @Override + public void runAsync(Runnable run) { + getProxy().getScheduler().runAsync(this, run); + } + + @Override + public void runSync(Runnable run) { + runAsync(run); + } + + public static String getLabel(Object o) { + if (o == null) { + return "#null"; + } + if (o instanceof ProxiedPlayer) { + return "$" + ((ProxiedPlayer) o).getUniqueId().toString(); + } + return "#null"; + } + } diff --git a/src/dev/heliosares/auxprotect/bungee/Language.java b/src/dev/heliosares/auxprotect/bungee/Language.java index 0c2da6d..0a449c3 100644 --- a/src/dev/heliosares/auxprotect/bungee/Language.java +++ b/src/dev/heliosares/auxprotect/bungee/Language.java @@ -7,6 +7,7 @@ import net.md_5.bungee.config.Configuration; public class Language { private Configuration lang; + HashMap langMap; public Language(Configuration lang) { diff --git a/src/dev/heliosares/auxprotect/bungee/Results.java b/src/dev/heliosares/auxprotect/bungee/Results.java deleted file mode 100644 index 619ac8f..0000000 --- a/src/dev/heliosares/auxprotect/bungee/Results.java +++ /dev/null @@ -1,136 +0,0 @@ -package dev.heliosares.auxprotect.bungee; - -import java.time.Instant; -import java.time.ZoneId; -import java.time.format.DateTimeFormatter; -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; -import net.md_5.bungee.api.chat.ComponentBuilder; -import net.md_5.bungee.api.chat.HoverEvent; -import net.md_5.bungee.api.chat.hover.content.Text; - -public class Results { - - protected final ArrayList entries; - protected final CommandSender player; - protected final DateTimeFormatter formatter; - private final IAuxProtect plugin; - public int perpage = 4; - public int prevpage = 0; - - public Results(IAuxProtect plugin, ArrayList entries, CommandSender player) { - this.entries = entries; - this.player = player; - this.formatter = DateTimeFormatter.ofPattern("ddMMMYY HH:mm.ss"); - this.plugin = plugin; - } - - 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); - 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 + ")"); - } - if (en.world != null && !en.world.equals("$null")) { - 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("/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()); - } - - ComponentBuilder message = new ComponentBuilder(); - message.append("§7("); - if (page > 1) { - 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" + 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" + AuxProtect.LEFT_ARROW + AuxProtect.LEFT_ARROW).event((ClickEvent) null) - .event((HoverEvent) null); - message.append(" "); - message.append("§8§l" + AuxProtect.LEFT_ARROW); - } - message.append(" ").event((ClickEvent) null).event((HoverEvent) null); - if (page < lastpage) { - 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" + 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" + AuxProtect.RIGHT_ARROW).event((ClickEvent) null).event((HoverEvent) null); - message.append(" "); - 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, - (int) Math.ceil(entries.size() / (double) perpage), entries.size())); - player.sendMessage(message.create()); - return; - } - - 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/YMLManager.java b/src/dev/heliosares/auxprotect/bungee/YMLManager.java index e1b333a..3822781 100644 --- a/src/dev/heliosares/auxprotect/bungee/YMLManager.java +++ b/src/dev/heliosares/auxprotect/bungee/YMLManager.java @@ -31,7 +31,7 @@ public class YMLManager { try (InputStream in = plugin.getResourceAsStream(fileName)) { Files.copy(in, file.toPath()); } catch (IOException e) { - e.printStackTrace(); + plugin.print(e); } } reload(); @@ -56,7 +56,7 @@ public class YMLManager { this.data = ConfigurationProvider.getProvider(YamlConfiguration.class) .load(new File(plugin.getDataFolder(), fileName)); } catch (IOException e) { - e.printStackTrace(); + plugin.print(e); } } } diff --git a/src/dev/heliosares/auxprotect/bungee/command/APCommand.java b/src/dev/heliosares/auxprotect/bungee/command/APBCommand.java similarity index 70% rename from src/dev/heliosares/auxprotect/bungee/command/APCommand.java rename to src/dev/heliosares/auxprotect/bungee/command/APBCommand.java index f42eddb..7f5e714 100644 --- a/src/dev/heliosares/auxprotect/bungee/command/APCommand.java +++ b/src/dev/heliosares/auxprotect/bungee/command/APBCommand.java @@ -5,20 +5,24 @@ import java.util.ArrayList; import java.util.List; import dev.heliosares.auxprotect.bungee.AuxProtectBungee; +import dev.heliosares.auxprotect.command.LookupCommand; +import dev.heliosares.auxprotect.command.PurgeCommand; +import dev.heliosares.auxprotect.database.EntryAction; import dev.heliosares.auxprotect.utils.MyPermission; +import dev.heliosares.auxprotect.utils.MySender; import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.plugin.Command; import net.md_5.bungee.api.plugin.TabExecutor; -public class APCommand extends Command implements TabExecutor { +public class APBCommand extends Command implements TabExecutor { private AuxProtectBungee plugin; - private LookupCommand lookupCommand; - public APCommand(AuxProtectBungee plugin) { + public APBCommand(AuxProtectBungee plugin) { super("apb"); this.plugin = plugin; - lookupCommand = new LookupCommand(plugin); } private void sendHelpMessage(CommandSender sender, String subcommand) { @@ -53,7 +57,7 @@ public class APCommand extends Command implements TabExecutor { AuxProtectBungee.tell(sender, plugin.lang.translate("no-permission")); return; } - lookupCommand.onCommand(sender, args); + LookupCommand.onCommand(plugin, new MySender(sender), args); return; } else if (args[0].equalsIgnoreCase("help")) { if (!MyPermission.HELP.hasPermission(sender)) { @@ -117,11 +121,18 @@ public class APCommand extends Command implements TabExecutor { plugin.getSqlManager().execute(msg.trim()); } catch (SQLException e) { AuxProtectBungee.tell(sender, "§cAn error occured."); - e.printStackTrace(); + plugin.print(e); return; } AuxProtectBungee.tell(sender, "§aSQL statement executed successfully."); return; + } else if (args[0].equalsIgnoreCase("purge")) { + if (!MyPermission.PURGE.hasPermission(sender)) { + AuxProtectBungee.tell(sender, plugin.lang.translate("no-permission")); + return; + } + PurgeCommand.purge(plugin, new MySender(sender), args); + return; } else { AuxProtectBungee.tell(sender, plugin.lang.translate("unknown-subcommand")); return; @@ -138,7 +149,6 @@ public class APCommand extends Command implements TabExecutor { if (args.length == 1) { if (MyPermission.LOOKUP.hasPermission(sender)) { possible.add("lookup"); - possible.add("playtime"); } if (MyPermission.ADMIN.hasPermission(sender)) { possible.add("debug"); @@ -154,7 +164,56 @@ public class APCommand extends Command implements TabExecutor { if (args.length >= 2) { if ((args[0].equalsIgnoreCase("lookup") || args[0].equalsIgnoreCase("l")) && MyPermission.LOOKUP.hasPermission(sender)) { - possible.addAll(lookupCommand.onTabComplete(sender, args)); + possible.add("time:"); + possible.add("target:"); + possible.add("action:"); + possible.add("user:"); + if (currentArg.startsWith("action:") || currentArg.startsWith("a:")) { + String action = currentArg.split(":")[0] + ":"; + for (EntryAction eaction : EntryAction.values()) { + if (eaction.isBungee() && eaction.isEnabled()) { + String actString = eaction.toString().toLowerCase(); + if (eaction.hasDual) { + possible.add(action + "+" + actString); + possible.add(action + "-" + actString); + + } + possible.add(action + actString); + } + } + } + if (currentArg.startsWith("user:") || currentArg.startsWith("u:") || currentArg.startsWith("target:")) { + String user = currentArg.split(":")[0] + ":"; + for (ProxiedPlayer player : ProxyServer.getInstance().getPlayers()) { + possible.add(user + player.getName()); + } + } + if (currentArg.startsWith("time:") || currentArg.startsWith("t:")) { + if (currentArg.matches("t(ime)?:\\d+")) { + possible.add(currentArg + "s"); + possible.add(currentArg + "m"); + possible.add(currentArg + "h"); + possible.add(currentArg + "d"); + possible.add(currentArg + "w"); + } + } + if (currentArg.startsWith("b")) + possible.add("before:"); + if (currentArg.startsWith("a")) + possible.add("after:"); + + if (currentArg.startsWith("#")) { + possible.add("#bw"); + possible.add("#count"); + } + + for (int i = 1; i < args.length - 1; i++) { + String arg = args[i]; + if (!arg.contains(":")) + continue; + arg = arg.substring(0, arg.indexOf(":") + 1); + possible.remove(arg); + } } else if ((args[0].equalsIgnoreCase("help")) && MyPermission.HELP.hasPermission(sender)) { possible.add("lookup"); possible.add("purge"); diff --git a/src/dev/heliosares/auxprotect/bungee/command/LookupCommand.java b/src/dev/heliosares/auxprotect/bungee/command/LookupCommand.java deleted file mode 100644 index 893971f..0000000 --- a/src/dev/heliosares/auxprotect/bungee/command/LookupCommand.java +++ /dev/null @@ -1,353 +0,0 @@ -package dev.heliosares.auxprotect.bungee.command; - -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.SQLManager.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; -import net.md_5.bungee.api.connection.ProxiedPlayer; - -public class LookupCommand { - - private AuxProtectBungee plugin; - - private ArrayList validParams; - - public LookupCommand(AuxProtectBungee plugin) { - this.plugin = plugin; - results = new HashMap<>(); - validParams = new ArrayList<>(); - validParams.add("action"); - validParams.add("after"); - validParams.add("before"); - validParams.add("target"); - validParams.add("time"); - validParams.add("world"); - validParams.add("user"); - validParams.add("radius"); - } - - HashMap results; - - public boolean onCommand(final CommandSender sender, String[] args) { - if (args.length < 2) { - 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 = -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 (isPageLookup || first || last || next || prev) { - Results result = null; - String uuid = "nonplayer"; - if (sender instanceof Player) { - uuid = ((Player) sender).getUniqueId().toString(); - } - if (results.containsKey(uuid)) { - 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 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("#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(":"); - - String token = split[0]; - switch (token.toLowerCase()) { - case "a": - token = "action"; - break; - case "u": - token = "user"; - break; - case "t": - token = "time"; - break; - case "r": - token = "radius"; - break; - case "w": - 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.translate("lookup-invalid-parameter"), args[i])); - return true; - } - String param = split[1]; - if (token.equalsIgnoreCase("time") || token.equalsIgnoreCase("before") || token.equalsIgnoreCase("after")) { - if (param.endsWith("e")) { - long time = -1; - try { - time = Long.parseLong(param.substring(0, param.length() - 1)); - } catch (NumberFormatException e) { - } - if (time < 0) { - AuxProtectBungee.tell(sender, - String.format(plugin.translate("lookup-invalid-parameter"), args[i])); - return true; - } - param = time + ""; - } else { - startTime = TimeUtil.convertTime(param); - if (startTime < 0) { - AuxProtectBungee.tell(sender, - String.format(plugin.lang.translate("lookup-invalid-parameter"), args[i])); - return true; - } - param = (System.currentTimeMillis() - startTime) + ""; - } - } - params.put(token, param.toLowerCase()); - } - if (params.size() < 1) { - AuxProtectBungee.tell(sender, plugin.lang.translate("purge-error-notenough")); - return true; - } - if (bw) { - String user = params.get("user"); - final String targetOld = params.get("target"); - String target = params.get("target"); - if (user == null) { - user = ""; - } - if (target == null) { - target = ""; - } - if (user.length() > 0) { - if (targetOld != null && targetOld.length() > 0) { - target += ","; - } - target += user; - } - if (targetOld != null && targetOld.length() > 0) { - if (user.length() > 0) { - user += ","; - } - user += targetOld; - } - if (user.length() > 0) { - params.put("user", user); - } - if (target.length() > 0) { - 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 playtime_ = playtime; - final long startTime_ = startTime; - AuxProtectBungee.tell(sender, plugin.translate("lookup-looking")); - Runnable runnable = new Runnable() { - - @Override - public void run() { - ArrayList results = null; - try { - 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.translate("lookup-noresults")); - return; - } - if (count_) { - 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 (player != null) { - uuid = player.getUniqueId().toString(); - } - 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; - } - - public List onTabComplete(CommandSender sender, String[] args) { - List possible = new ArrayList<>(); - String currentArg = args[args.length - 1]; - - possible.add("radius:"); - possible.add("time:"); - possible.add("target:"); - possible.add("action:"); - possible.add("world:"); - possible.add("user:"); - if (currentArg.startsWith("action:") || currentArg.startsWith("a:")) { - String action = currentArg.split(":")[0] + ":"; - for (EntryAction eaction : EntryAction.values()) { - if (eaction.isBungee() && eaction.isEnabled()) { - String actString = eaction.toString().toLowerCase(); - if (eaction.hasDual) { - possible.add(action + "+" + actString); - possible.add(action + "-" + actString); - - } - possible.add(action + actString); - } - } - } - if (currentArg.startsWith("user:") || currentArg.startsWith("u:") || currentArg.startsWith("target:")) { - String user = currentArg.split(":")[0] + ":"; - for (ProxiedPlayer player : ProxyServer.getInstance().getPlayers()) { - possible.add(user + player.getName()); - } - } - if (currentArg.startsWith("time:") || currentArg.startsWith("t:")) { - if (currentArg.matches("t(ime)?:\\d+")) { - possible.add(currentArg + "s"); - possible.add(currentArg + "m"); - possible.add(currentArg + "h"); - possible.add(currentArg + "d"); - possible.add(currentArg + "w"); - } - } - if (currentArg.startsWith("b")) - possible.add("before:"); - if (currentArg.startsWith("a")) - possible.add("after:"); - - if (currentArg.startsWith("#")) { - /* - * if (MyPermission.LOOKUP_PLAYTIME.hasPermission(sender)) { - * possible.add("#pt"); } - */ - possible.add("#bw"); - possible.add("#time"); - possible.add("#count"); - } - - for (int i = 1; i < args.length - 1; i++) { - String arg = args[i]; - if (!arg.contains(":")) - continue; - arg = arg.substring(0, arg.indexOf(":") + 1); - possible.remove(arg); - } - - List output = new ArrayList<>(); - APCommand.copyPartialMatches(currentArg, possible, output); - return output; - } -} diff --git a/src/dev/heliosares/auxprotect/command/APCommand.java b/src/dev/heliosares/auxprotect/command/APCommand.java index 3f8f368..e41eb7d 100644 --- a/src/dev/heliosares/auxprotect/command/APCommand.java +++ b/src/dev/heliosares/auxprotect/command/APCommand.java @@ -12,13 +12,13 @@ import org.bukkit.command.CommandSender; import dev.heliosares.auxprotect.AuxProtect; import dev.heliosares.auxprotect.utils.MyPermission; +import dev.heliosares.auxprotect.utils.MySender; import dev.heliosares.auxprotect.utils.TimeUtil; public class APCommand implements CommandExecutor { private AuxProtect plugin; public LookupCommand lookupCommand; - private PurgeCommand purgeCommand; private TpCommand tpCommand; private InvCommand invCommand; private PlaytimeCommand playtimeCommand; @@ -28,7 +28,6 @@ public class APCommand implements CommandExecutor { public APCommand(AuxProtect plugin) { this.plugin = plugin; lookupCommand = new LookupCommand(plugin); - purgeCommand = new PurgeCommand(plugin); tpCommand = new TpCommand(plugin); invCommand = new InvCommand(plugin, this); playtimeCommand = new PlaytimeCommand(plugin); @@ -44,13 +43,14 @@ public class APCommand implements CommandExecutor { sender.sendMessage(plugin.translate("no-permission")); return true; } - return lookupCommand.onCommand(sender, command, label, args); + return lookupCommand.onCommand(sender, args); } else if (args[0].equalsIgnoreCase("purge")) { if (!MyPermission.PURGE.hasPermission(sender)) { sender.sendMessage(plugin.translate("no-permission")); return true; } - return purgeCommand.onCommand(sender, command, label, args); + PurgeCommand.purge(plugin, new MySender(sender), args); + return true; } else if (args[0].equalsIgnoreCase("pt") || args[0].equalsIgnoreCase("playtime")) { if (!MyPermission.LOOKUP_PLAYTIME.hasPermission(sender)) { sender.sendMessage(plugin.translate("no-permission")); @@ -167,7 +167,8 @@ public class APCommand implements CommandExecutor { return true; } - sender.sendMessage("§7Rows: §9" + plugin.getSqlManager().getCount()); + sender.sendMessage("§7Rows: §9" + plugin.getSqlManager().getCount() + " §7DB Version: §9" + + plugin.getSqlManager().getVersion()); 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" @@ -201,7 +202,7 @@ public class APCommand implements CommandExecutor { } } catch (SQLException e) { sender.sendMessage("§cAn error occured."); - e.printStackTrace(); + plugin.print(e); return true; } sender.sendMessage("§aSQL statement executed successfully."); diff --git a/src/dev/heliosares/auxprotect/command/InvCommand.java b/src/dev/heliosares/auxprotect/command/InvCommand.java index 96b1df9..071e8de 100644 --- a/src/dev/heliosares/auxprotect/command/InvCommand.java +++ b/src/dev/heliosares/auxprotect/command/InvCommand.java @@ -1,6 +1,5 @@ package dev.heliosares.auxprotect.command; -import java.util.HashMap; import java.util.UUID; import org.bukkit.Bukkit; @@ -32,16 +31,11 @@ import net.md_5.bungee.api.chat.hover.content.Text; public class InvCommand implements CommandExecutor { private AuxProtect plugin; - private APCommand command; public InvCommand(AuxProtect plugin, APCommand command) { this.plugin = plugin; - results = new HashMap<>(); - this.command = command; } - HashMap results; - @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { if (args.length < 2) { @@ -60,7 +54,7 @@ public class InvCommand implements CommandExecutor { if (idnex < 0) { return true; } - Results results = this.command.lookupCommand.results.get(player.getUniqueId().toString()); + Results results = LookupCommand.results.get(player.getUniqueId().toString()); if (results == null || idnex >= results.getSize()) { return true; } @@ -75,7 +69,7 @@ public class InvCommand implements CommandExecutor { final ItemStack[] storage = InvSerialization.toItemStackArray(data[0]); final ItemStack[] armor = InvSerialization.toItemStackArray(data[1]); final ItemStack[] extra = InvSerialization.toItemStackArray(data[2]); - OfflinePlayer target = Bukkit.getOfflinePlayer(UUID.fromString(entry.userUuid.substring(1))); + OfflinePlayer target = Bukkit.getOfflinePlayer(UUID.fromString(entry.getUserUUID().substring(1))); final Player targetO = target.getPlayer(); Pane enderpane = new Pane(Type.SHOW); final Inventory ender = InvSerialization.toInventory(data[3], enderpane, diff --git a/src/dev/heliosares/auxprotect/command/LookupCommand.java b/src/dev/heliosares/auxprotect/command/LookupCommand.java index fe4320a..f0bb5e7 100644 --- a/src/dev/heliosares/auxprotect/command/LookupCommand.java +++ b/src/dev/heliosares/auxprotect/command/LookupCommand.java @@ -3,34 +3,30 @@ package dev.heliosares.auxprotect.command; import java.util.ArrayList; import java.util.HashMap; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; +import org.bukkit.Location; import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; 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.database.Results; import dev.heliosares.auxprotect.database.SQLManager.LookupException; import dev.heliosares.auxprotect.utils.MoneySolver; import dev.heliosares.auxprotect.utils.MyPermission; +import dev.heliosares.auxprotect.utils.MySender; import dev.heliosares.auxprotect.utils.PlayTimeSolver; import dev.heliosares.auxprotect.utils.TimeUtil; import dev.heliosares.auxprotect.utils.XraySolver; -public class LookupCommand implements CommandExecutor { +public class LookupCommand { - private AuxProtect plugin; + private final IAuxProtect plugin; - private ArrayList validParams; + private static final ArrayList validParams; + static final HashMap results; - public LookupCommand(AuxProtect plugin) { - this.plugin = plugin; - results = new HashMap<>(); + static { validParams = new ArrayList<>(); validParams.add("action"); validParams.add("after"); @@ -41,246 +37,251 @@ public class LookupCommand implements CommandExecutor { validParams.add("user"); validParams.add("radius"); validParams.add("db"); + results = new HashMap<>(); } - HashMap results; + public LookupCommand(IAuxProtect plugin) { + this.plugin = plugin; + } - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + public boolean onCommand(org.bukkit.command.CommandSender sender1, String[] args) { + MySender sender = new MySender(sender1); + onCommand(plugin, sender, args); + return true; + } + + public static void onCommand(IAuxProtect plugin, MySender sender, String[] args) { if (args.length < 2) { sender.sendMessage(plugin.translate("lookup-invalid-syntax")); - return true; + return; } - Player player_ = null; - if (sender instanceof Player) { - player_ = (Player) sender; - } - final Player player = player_; - if (args.length == 2) { - int page = -1; - 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 (isPageLookup || first || last || next || prev) { - Results result = null; - String uuid = "nonplayer"; - if (sender instanceof Player) { - uuid = ((Player) sender).getUniqueId().toString(); - } - if (results.containsKey(uuid)) { - result = results.get(uuid); - } - if (result == null) { - sender.sendMessage(plugin.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; - } else { - result.showPage(page); - return true; - } - } - } - - HashMap params = new HashMap<>(); - boolean count = false; - boolean playtime = false; - boolean xray = false; - boolean bw = false; - boolean money = 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("#xray")) { - xray = true; - continue; - } else if (args[i].equalsIgnoreCase("#bw")) { - bw = true; - continue; - } else if (args[i].equalsIgnoreCase("#pt")) { - if (!MyPermission.LOOKUP_PLAYTIME.hasPermission(sender)) { - sender.sendMessage(plugin.translate("no-permission-flag")); - return true; - } - playtime = true; - continue; - } else if (args[i].equalsIgnoreCase("#money")) { - if (!MyPermission.LOOKUP_MONEY.hasPermission(sender)) { - sender.sendMessage(plugin.translate("no-permission-flag")); - return true; - } - money = true; - continue; - } - String[] split = args[i].split(":"); - - String token = split[0]; - switch (token.toLowerCase()) { - case "a": - token = "action"; - break; - case "u": - token = "user"; - break; - case "t": - token = "time"; - break; - case "r": - token = "radius"; - break; - case "w": - token = "world"; - break; - } - if (token.equalsIgnoreCase("db")) { - if (!MyPermission.ADMIN.hasPermission(sender)) { - sender.sendMessage(plugin.translate("no-permission")); - return true; - } - } - if (split.length != 2 || !validParams.contains(token)) { - sender.sendMessage(String.format(plugin.translate("lookup-invalid-parameter"), args[i])); - return true; - } - String param = split[1]; - if (token.equalsIgnoreCase("time") || token.equalsIgnoreCase("before") || token.equalsIgnoreCase("after")) { - if (param.endsWith("e")) { - long time = -1; - try { - time = Long.parseLong(param.substring(0, param.length() - 1)); - } catch (NumberFormatException e) { - } - if (time < 0) { - sender.sendMessage(String.format(plugin.translate("lookup-invalid-parameter"), args[i])); - return true; - } - param = time + ""; - } else { - startTime = TimeUtil.convertTime(param); - if (startTime < 0) { - sender.sendMessage(String.format(plugin.translate("lookup-invalid-parameter"), args[i])); - return true; - } - param = (System.currentTimeMillis() - startTime) + ""; - } - } - params.put(token, param.toLowerCase()); - } - if (params.size() < 1) { - sender.sendMessage(plugin.translate("purge-error-notenough")); - return true; - } - if (bw) { - String user = params.get("user"); - final String targetOld = params.get("target"); - String target = params.get("target"); - if (user == null) { - user = ""; - } - if (target == null) { - target = ""; - } - if (user.length() > 0) { - if (targetOld != null && targetOld.length() > 0) { - target += ","; - } - target += user; - } - if (targetOld != null && targetOld.length() > 0) { - if (user.length() > 0) { - user += ","; - } - user += targetOld; - } - if (user.length() > 0) { - params.put("user", user); - } - if (target.length() > 0) { - params.put("target", target); - } - } - if (playtime) { - if (params.containsKey("user")) { - if (params.get("user").split(",").length > 1) { - sender.sendMessage(plugin.translate("lookup-playtime-toomanyusers")); - return true; - } - } else { - sender.sendMessage(plugin.translate("lookup-playtime-nouser")); - return true; - } - if (params.containsKey("action")) { - params.remove("action"); - params.put("action", "session"); - } - } - final boolean count_ = count; - final boolean playtime_ = playtime; - final boolean xray_ = xray; - final long startTime_ = startTime; - final boolean money_ = money; - sender.sendMessage(plugin.translate("lookup-looking")); - BukkitRunnable runnable = new BukkitRunnable() { + Runnable run = new Runnable() { @Override public void run() { - ArrayList results = null; + if (args.length == 2) { + int page = -1; + 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 (isPageLookup || first || last || next || prev) { + Results result = null; + String uuid = sender.getUniqueId().toString(); + if (results.containsKey(uuid)) { + result = results.get(uuid); + } + if (result == null) { + sender.sendMessage(plugin.translate("lookup-no-results-selected")); + return; + } + 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; + } else { + result.showPage(page); + return; + } + } + } + + HashMap params = new HashMap<>(); + boolean count = false; + boolean playtime = false; + boolean xray = false; + boolean bw = false; + boolean money = 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("#xray")) { + xray = true; + continue; + } else if (args[i].equalsIgnoreCase("#bw")) { + bw = true; + continue; + } else if (args[i].equalsIgnoreCase("#pt")) { + if (!MyPermission.LOOKUP_PLAYTIME.hasPermission(sender)) { + sender.sendMessage(plugin.translate("no-permission-flag")); + return; + } + playtime = true; + continue; + } else if (args[i].equalsIgnoreCase("#money")) { + if (!MyPermission.LOOKUP_MONEY.hasPermission(sender)) { + sender.sendMessage(plugin.translate("no-permission-flag")); + return; + } + money = true; + continue; + } + String[] split = args[i].split(":"); + + String token = split[0]; + switch (token.toLowerCase()) { + case "a": + token = "action"; + break; + case "u": + token = "user"; + break; + case "t": + token = "time"; + break; + case "r": + token = "radius"; + break; + case "w": + token = "world"; + break; + } + if (token.equalsIgnoreCase("db")) { + if (!MyPermission.ADMIN.hasPermission(sender)) { + sender.sendMessage(plugin.translate("no-permission")); + return; + } + } + if (split.length != 2 || !validParams.contains(token)) { + sender.sendMessage(String.format(plugin.translate("lookup-invalid-parameter"), args[i])); + return; + } + String param = split[1]; + if (token.equalsIgnoreCase("time") || token.equalsIgnoreCase("before") + || token.equalsIgnoreCase("after")) { + if (param.endsWith("e")) { + long time = -1; + try { + time = Long.parseLong(param.substring(0, param.length() - 1)); + } catch (NumberFormatException e) { + } + if (time < 0) { + sender.sendMessage( + String.format(plugin.translate("lookup-invalid-parameter"), args[i])); + return; + } + param = time + ""; + } else { + startTime = TimeUtil.convertTime(param); + if (startTime < 0) { + sender.sendMessage( + String.format(plugin.translate("lookup-invalid-parameter"), args[i])); + return; + } + param = (System.currentTimeMillis() - startTime) + ""; + } + } + params.put(token, param.toLowerCase()); + } + if (params.size() < 1) { + sender.sendMessage(plugin.translate("purge-error-notenough")); + return; + } + if (bw) { + String user = params.get("user"); + final String targetOld = params.get("target"); + String target = params.get("target"); + if (user == null) { + user = ""; + } + if (target == null) { + target = ""; + } + if (user.length() > 0) { + if (targetOld != null && targetOld.length() > 0) { + target += ","; + } + target += user; + } + if (targetOld != null && targetOld.length() > 0) { + if (user.length() > 0) { + user += ","; + } + user += targetOld; + } + if (user.length() > 0) { + params.put("user", user); + } + if (target.length() > 0) { + params.put("target", target); + } + } + if (playtime) { + if (params.containsKey("user")) { + if (params.get("user").split(",").length > 1) { + sender.sendMessage(plugin.translate("lookup-playtime-toomanyusers")); + return; + } + } else { + sender.sendMessage(plugin.translate("lookup-playtime-nouser")); + return; + } + if (params.containsKey("action")) { + params.remove("action"); + params.put("action", "session"); + } + } + sender.sendMessage(plugin.translate("lookup-looking")); + ArrayList rs = null; try { - results = plugin.getSqlManager().lookup(params, player != null ? player.getLocation() : null, - false); + if (sender.isBungee()) { + rs = plugin.getSqlManager().lookup(params, null, false); + } else { + Location location = null; + if (sender.getSender() instanceof Player) { + location = ((Player) sender.getSender()).getLocation(); + } + rs = plugin.getSqlManager().lookup(params, location, false); + } } catch (LookupException e) { sender.sendMessage(e.errorMessage); return; } - if (results == null || results.size() == 0) { + if (rs == null || rs.size() == 0) { sender.sendMessage(plugin.translate("lookup-noresults")); return; } - if (count_) { - sender.sendMessage(String.format(plugin.translate("lookup-count"), results.size())); + if (count) { + sender.sendMessage(String.format(plugin.translate("lookup-count"), rs.size())); double totalMoney = 0; int dropcount = 0; int pickupcount = 0; - for (DbEntry entry : results) { + for (DbEntry entry : rs) { if (entry.getAction() == EntryAction.SHOP) { String[] parts = entry.getData().split(", "); if (parts.length >= 3) { @@ -294,9 +295,6 @@ public class LookupCommand implements CommandExecutor { totalMoney += each * qty; } } catch (Exception ignored) { - if (plugin.debug >= 3) { - ignored.printStackTrace(); - } } } } @@ -306,9 +304,6 @@ public class LookupCommand implements CommandExecutor { double each = Double.parseDouble(parts[parts.length - 1].substring(1)); totalMoney += each; } catch (Exception ignored) { - if (plugin.debug >= 3) { - ignored.printStackTrace(); - } } } if (entry.getAction() == EntryAction.DROP || entry.getAction() == EntryAction.PICKUP) { @@ -327,8 +322,8 @@ public class LookupCommand implements CommandExecutor { } } } - if (totalMoney != 0) { - sender.sendMessage("§9" + plugin.formatMoney(totalMoney)); + if (totalMoney != 0 && plugin instanceof AuxProtect) { + sender.sendMessage("§9" + ((AuxProtect) plugin).formatMoney(totalMoney)); } String msg = ""; if (pickupcount > 0) { @@ -343,7 +338,7 @@ public class LookupCommand implements CommandExecutor { if (msg.length() > 0) { sender.sendMessage(msg); } - } else if (playtime_) { + } else if (playtime) { String users = params.get("user"); if (users == null) { sender.sendMessage(plugin.translate("playtime-nouser")); @@ -353,11 +348,11 @@ public class LookupCommand implements CommandExecutor { sender.sendMessage(plugin.translate("playtime-toomanyusers")); return; } - sender.spigot().sendMessage( - PlayTimeSolver.solvePlaytime(results, (int) Math.round(startTime_ / (1000 * 3600)), users)); - } else if (xray_) { - sender.spigot().sendMessage(XraySolver.solvePlaytime(results, plugin)); - } else if (money_) { + sender.sendMessage( + PlayTimeSolver.solvePlaytime(rs, (int) Math.round(startTime / (1000 * 3600)), users)); + } else if (xray) { + sender.sendMessage(XraySolver.solvePlaytime(rs, plugin)); + } else if (money && !sender.isBungee()) { String users = params.get("user"); if (users == null) { sender.sendMessage(plugin.translate("playtime-nouser")); @@ -367,27 +362,21 @@ public class LookupCommand implements CommandExecutor { sender.sendMessage(plugin.translate("playtime-toomanyusers")); return; } - @SuppressWarnings("deprecation") - OfflinePlayer targetUser = Bukkit.getOfflinePlayer(users); - if (targetUser == null) { - sender.sendMessage(plugin.translate("playtime-nouser")); + if (sender.getSender() instanceof Player) { + MoneySolver.showMoney(plugin, (Player) sender.getSender(), rs, + (int) Math.round(startTime / (1000 * 3600)), users); + } else { return; } - MoneySolver.showMoney(plugin, player, results, (int) Math.round(startTime_ / (1000 * 3600)), - targetUser.getName()); } else { - String uuid = "nonplayer"; - if (player != null) { - uuid = player.getUniqueId().toString(); - } - Results result = new Results(plugin, results, sender); + String uuid = sender.getUniqueId().toString(); + Results result = new Results(plugin, rs, sender, sender.isBungee() ? "apb" : "ap"); result.showPage(1, 4); - LookupCommand.this.results.put(uuid, result); + results.put(uuid, result); } } }; - runnable.runTaskAsynchronously(plugin); - return true; + plugin.runAsync(run); } } diff --git a/src/dev/heliosares/auxprotect/command/PurgeCommand.java b/src/dev/heliosares/auxprotect/command/PurgeCommand.java index b63b9ad..906c831 100644 --- a/src/dev/heliosares/auxprotect/command/PurgeCommand.java +++ b/src/dev/heliosares/auxprotect/command/PurgeCommand.java @@ -1,47 +1,14 @@ package dev.heliosares.auxprotect.command; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.HashMap; - -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; - -import dev.heliosares.auxprotect.AuxProtect; -import dev.heliosares.auxprotect.database.Results; +import dev.heliosares.auxprotect.IAuxProtect; import dev.heliosares.auxprotect.database.SQLManager.TABLE; +import dev.heliosares.auxprotect.utils.MySender; import dev.heliosares.auxprotect.utils.TimeUtil; -public class PurgeCommand implements CommandExecutor { +public class PurgeCommand { - private AuxProtect plugin; - - private ArrayList validParams; - - public PurgeCommand(AuxProtect plugin) { - this.plugin = plugin; - results = new HashMap<>(); - validParams = new ArrayList<>(); - validParams.add("time"); - validParams.add("world"); - validParams.add("action"); - } - - HashMap results; - - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() { - @Override - public void run() { - purge(sender, args); - } - }); - return true; - } - - public void purge(CommandSender sender, String[] args) { + public static void purge(IAuxProtect plugin, MySender sender, String[] args) { if (args.length != 3) { sender.sendMessage(plugin.translate("lookup-invalid-syntax")); return; @@ -51,7 +18,11 @@ public class PurgeCommand implements CommandExecutor { try { table = TABLE.valueOf(args[1].toUpperCase()); } catch (IllegalArgumentException e) { - sender.sendMessage(plugin.translate("lookup-invalid-syntax")); + sender.sendMessage(plugin.translate("purge-table")); + return; + } + if (sender.isBungee() && !table.isOnBungee()) { + sender.sendMessage(plugin.translate("purge-table")); return; } long time = TimeUtil.convertTime(args[2]); @@ -61,12 +32,12 @@ public class PurgeCommand implements CommandExecutor { return; } - sender.sendMessage(plugin.translate("purge-purging")); + sender.sendMessage(String.format(plugin.translate("purge-purging"), table.toString())); boolean success = false; try { success = plugin.getSqlManager().purge(sender, table, time); } catch (SQLException e) { - e.printStackTrace(); + plugin.print(e); } if (success) { sender.sendMessage(plugin.translate("purge-complete")); diff --git a/src/dev/heliosares/auxprotect/command/XrayCommand.java b/src/dev/heliosares/auxprotect/command/XrayCommand.java index 645f561..44fcaa4 100644 --- a/src/dev/heliosares/auxprotect/command/XrayCommand.java +++ b/src/dev/heliosares/auxprotect/command/XrayCommand.java @@ -26,6 +26,7 @@ import dev.heliosares.auxprotect.database.SQLManager.LookupException; import dev.heliosares.auxprotect.database.SQLManager.TABLE; import dev.heliosares.auxprotect.utils.EntryFormatter; import dev.heliosares.auxprotect.utils.MyPermission; +import dev.heliosares.auxprotect.utils.MySender; import dev.heliosares.auxprotect.utils.TimeUtil; import net.coreprotect.CoreProtect; import net.coreprotect.CoreProtectAPI.ParseResult; @@ -189,8 +190,8 @@ public class XrayCommand implements CommandExecutor { sender.sendMessage(plugin.translate("xray-rate-conflic")); boolean validWarning = false; for (DbEntry warn : localHits) { - if (warn.userUuid.equals(en.userUuid)) { - EntryFormatter.sendEntry(plugin, warn, sender); + if (warn.getUserUUID().equals(en.getUserUUID())) { + EntryFormatter.sendEntry(plugin, warn, new MySender(sender)); validWarning = true; } } @@ -227,8 +228,7 @@ public class XrayCommand implements CommandExecutor { } } plugin.dbRunnable.add(new DbEntry(en.getTime(), - "$" + Bukkit.getOfflinePlayer(en.getUser(plugin.getSqlManager())).getUniqueId() - .toString(), + "$" + Bukkit.getOfflinePlayer(en.getUser()).getUniqueId().toString(), EntryAction.XRAYCHECK, false, en.world, en.x, en.y, en.z, rating_ + "", "Rated by " + sender.getName() + " on " + LocalDateTime.now().format(EntryFormatter.formatter))); @@ -312,7 +312,7 @@ public class XrayCommand implements CommandExecutor { true);// boolean lookup } catch (Throwable e) { - e.printStackTrace(); + plugin.print(e); sender.sendMessage("§cAn error occured."); return; } @@ -372,8 +372,7 @@ public class XrayCommand implements CommandExecutor { if (player != null) { uuid = player.getUniqueId().toString(); } - entries.sort((o1, o2) -> o1.getUser(plugin.getSqlManager()) - .compareTo(o2.getUser(plugin.getSqlManager()))); + entries.sort((o1, o2) -> o1.getUser().compareTo(o2.getUser())); entries.sort((o1, o2) -> o1.getLocation().getWorld().getName() .compareTo(o2.getLocation().getWorld().getName())); XrayResults result = new XrayResults(plugin, entries, sender); diff --git a/src/dev/heliosares/auxprotect/database/DatabaseRunnable.java b/src/dev/heliosares/auxprotect/database/DatabaseRunnable.java index bb5debf..550f55c 100644 --- a/src/dev/heliosares/auxprotect/database/DatabaseRunnable.java +++ b/src/dev/heliosares/auxprotect/database/DatabaseRunnable.java @@ -84,12 +84,13 @@ public class DatabaseRunnable implements Runnable { ArrayList entriesLongterm = new ArrayList<>(); ArrayList entriesAbandoned = new ArrayList<>(); ArrayList entriesInventory = new ArrayList<>(); + ArrayList entriesCommands = new ArrayList<>(); ArrayList entriesSpam = new ArrayList<>(); lastPolled = System.currentTimeMillis(); while ((entry = queue.poll()) != null) { if (plugin.getDebug() >= 2) { - String debug = String.format("§9%s §f%s§7(%d) §9%s §7", entry.getUser(sqlManager), + String debug = String.format("§9%s §f%s§7(%d) §9%s §7", entry.getUser(), plugin.translate(entry.getAction().getLang(entry.getState())), entry.getAction().getId(entry.getState()), entry.getTarget()); if (entry.getData() != null && entry.getData().length() > 0) { @@ -103,7 +104,7 @@ public class DatabaseRunnable implements Runnable { plugin.debug(debug, 2); } - switch (entry.getAction().getTable(plugin.isBungee())) { + switch (entry.getAction().getTable()) { case AUXPROTECT_ABANDONED: entriesAbandoned.add(entry); break; @@ -116,11 +117,14 @@ public class DatabaseRunnable implements Runnable { case AUXPROTECT_LONGTERM: entriesLongterm.add(entry); break; + case AUXPROTECT_COMMANDS: + entriesCommands.add(entry); + break; case AUXPROTECT: entries.add(entry); break; default: - plugin.warning("Unknown table " + entry.getAction().getTable(plugin.isBungee()).toString() + plugin.warning("Unknown table " + entry.getAction().getTable().toString() + ". This is bad. (DatabaseRunnable)"); continue; } @@ -152,13 +156,19 @@ public class DatabaseRunnable implements Runnable { plugin.debug(debugLogStatement(start, entriesLongterm.size(), TABLE.AUXPROTECT_LONGTERM), 1); start = System.nanoTime(); } + if (entriesCommands.size() > 0) { + sqlManager.put(TABLE.AUXPROTECT_COMMANDS, entriesCommands); + plugin.debug(debugLogStatement(start, entriesCommands.size(), TABLE.AUXPROTECT_COMMANDS), 1); + start = System.nanoTime(); + } } catch (SQLException e) { - e.printStackTrace(); + plugin.print(e); } } } catch (Exception e) { - e.printStackTrace(); + plugin.print(e); } + sqlManager.cleanup(); running = 0; } @@ -199,8 +209,8 @@ public class DatabaseRunnable implements Runnable { if (next.getAction() != entry.getAction()) { continue; } - if (next.userUuid.equals(entry.userUuid)) { - if (next.targetUuid.equals(entry.targetUuid)) { + if (next.getUserUUID().equals(entry.getUserUUID())) { + if (next.getTargetUUID().equals(entry.getTargetUUID())) { if (next.world.equals(entry.world)) { if (next.getDistance(entry) <= 3) { next.add(entry); diff --git a/src/dev/heliosares/auxprotect/database/DbEntry.java b/src/dev/heliosares/auxprotect/database/DbEntry.java index 8d4f175..67582a7 100644 --- a/src/dev/heliosares/auxprotect/database/DbEntry.java +++ b/src/dev/heliosares/auxprotect/database/DbEntry.java @@ -1,7 +1,5 @@ package dev.heliosares.auxprotect.database; -import java.util.UUID; - import org.bukkit.Bukkit; import org.bukkit.Location; @@ -34,10 +32,13 @@ public class DbEntry { public final int y; public final int z; - public final String userUuid; + private String userUuid; private String user; - public final String targetUuid; + private int uid; + + private String targetUuid; private String target; + private int target_id; public DbEntry(String userUuid, EntryAction action, boolean state, String world, int x, int y, int z, String target, String data) { @@ -53,6 +54,19 @@ public class DbEntry { this.data = data; } + public DbEntry(String userUuid, EntryAction action, boolean state, String target, String data) { + this.time = DatabaseRunnable.getTime(); + this.userUuid = userUuid; + this.action = action; + this.state = state; + this.world = null; + this.x = 0; + this.y = 0; + this.z = 0; + this.targetUuid = target; + this.data = data; + } + public DbEntry(String userUuid, EntryAction action, boolean state, Location location, String target, String suplmemental) { this(userUuid, action, state, location.getWorld().getName(), location.getBlockX(), location.getBlockY(), @@ -73,35 +87,109 @@ public class DbEntry { this.data = data; } - public String getUser(SQLManager sqlManager) { + public DbEntry(long time, int uid, EntryAction action, boolean state, String world, int x, int y, int z, + String target, String data) { + this.time = time; + this.uid = uid; + this.action = action; + this.state = state; + this.world = world; + this.x = x; + this.y = y; + this.z = z; + this.targetUuid = target; + this.data = data; + } + + public DbEntry(long time, int uid, EntryAction action, boolean state, String world, int x, int y, int z, + int target_id, String data) { + this.time = time; + this.uid = uid; + this.action = action; + this.state = state; + this.world = world; + this.x = x; + this.y = y; + this.z = z; + this.target_id = target_id; + this.data = data; + } + + public String getUser() { if (user != null) { return user; } - if (!userUuid.startsWith("$") || userUuid.length() != 37) { - return user = userUuid; + if (!getUserUUID().startsWith("$") || getUserUUID().length() != 37) { + return user = getUserUUID(); } - user = sqlManager.getUsernameFromUUID(userUuid); + user = SQLManager.getInstance().getUsernameFromUID(getUid()); if (user == null) { - user = userUuid; + user = getUserUUID(); } return user; } + public int getUid() { + if (uid > 0) { + return uid; + } + return uid = SQLManager.getInstance().getUIDFromUUID(getUserUUID(), true); + } + + public int getTargetId() { + if (action.getTable().hasStringTarget()) { + return -1; + } + if (target_id > 0) { + return target_id; + } + return target_id = SQLManager.getInstance().getUIDFromUUID(getTargetUUID(), true); + } + public String getTarget() { if (target != null) { return target; } - if (!targetUuid.startsWith("$") || targetUuid.length() != 37) { - return target = targetUuid; + if (action.getTable().hasStringTarget() || !getTargetUUID().startsWith("$") || getTargetUUID().length() != 37) { + return target = getTargetUUID(); } - try { - target = Bukkit.getServer().getOfflinePlayer(UUID.fromString(targetUuid.substring(1))).getName(); - } catch (NoClassDefFoundError e) { - target = targetUuid; + target = SQLManager.getInstance().getUsernameFromUID(getTargetId()); + if (target == null) { + target = getTargetUUID(); } return target; } + public String getTargetUUID() { + if (targetUuid != null) { + return targetUuid; + } + if (target_id > 0) { + targetUuid = SQLManager.getInstance().getUUIDFromUID(target_id); + } else if (target_id == 0) { + return targetUuid = ""; + } + if (targetUuid == null) { + targetUuid = "#null"; + } + return targetUuid; + } + + public String getUserUUID() { + if (userUuid != null) { + return userUuid; + } + if (uid > 0) { + userUuid = SQLManager.getInstance().getUUIDFromUID(uid); + } else if (uid == 0) { + return userUuid = ""; + } + if (userUuid == null) { + userUuid = "#null"; + } + return userUuid; + } + public double getBoxDistance(DbEntry entry) { if (!entry.world.equals(world)) { return -1; diff --git a/src/dev/heliosares/auxprotect/database/EntryAction.java b/src/dev/heliosares/auxprotect/database/EntryAction.java index e20fdeb..8b6751c 100644 --- a/src/dev/heliosares/auxprotect/database/EntryAction.java +++ b/src/dev/heliosares/auxprotect/database/EntryAction.java @@ -17,7 +17,7 @@ public enum EntryAction { // END DEFAULT (255) // START SPAM(256) - POS(256), HURT(257), INV(258, 259), COMMAND(260), KILL(261), LAND(262), ELYTRA(263, 264), + POS(256), HURT(257), INV(258, 259), KILL(261), LAND(262), ELYTRA(263, 264), // END SPAM(511) // START IGNOREABANDONED(512) @@ -31,8 +31,12 @@ public enum EntryAction { // START INVENTORY (1024) INVENTORY(1024), LAUNCH(1025), GRAB(1026), DROP(1027), PICKUP(1028), AHLIST(1029), AHBUY(1030), // inventory doubles - ITEMFRAME(1152, 1153) - // END INVENTORY(1280) + ITEMFRAME(1152, 1153), + // END INVENTORY(1279) + + // START COMMANDS (1280) + COMMAND(1280) + // END COMMANDS(1289) ; public final boolean hasDual; @@ -75,8 +79,10 @@ public enum EntryAction { public boolean isBungee() { switch (this) { case MSG: - return true; case COMMAND: + case IP: + case USERNAME: + case SESSION: return true; default: break; @@ -94,13 +100,13 @@ public enum EntryAction { return true; } - public TABLE getTable(boolean bungee) { - if (bungee) { + public TABLE getTable() { + /*if (bungee) { if (this == USERNAME || this == IP) { return TABLE.AUXPROTECT_LONGTERM; } return TABLE.AUXPROTECT; - } + }*/ if (id < 256) { return TABLE.AUXPROTECT; } @@ -116,6 +122,9 @@ public enum EntryAction { if (id < 1280) { return TABLE.AUXPROTECT_INVENTORY; } + if (id < 1290) { + return TABLE.AUXPROTECT_COMMANDS; + } return null; } diff --git a/src/dev/heliosares/auxprotect/database/Results.java b/src/dev/heliosares/auxprotect/database/Results.java index da18865..011e77b 100644 --- a/src/dev/heliosares/auxprotect/database/Results.java +++ b/src/dev/heliosares/auxprotect/database/Results.java @@ -5,12 +5,11 @@ import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; -import org.bukkit.command.CommandSender; - import dev.heliosares.auxprotect.AuxProtect; import dev.heliosares.auxprotect.IAuxProtect; import dev.heliosares.auxprotect.utils.InvSerialization; import dev.heliosares.auxprotect.utils.MyPermission; +import dev.heliosares.auxprotect.utils.MySender; import dev.heliosares.auxprotect.utils.TimeUtil; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.ComponentBuilder; @@ -20,17 +19,37 @@ import net.md_5.bungee.api.chat.hover.content.Text; public class Results { protected final ArrayList entries; - protected final CommandSender player; + protected final MySender player; protected final DateTimeFormatter formatter; private final IAuxProtect plugin; public int perpage = 4; public int prevpage = 0; + final String commandPrefix; - public Results(IAuxProtect plugin, ArrayList entries, CommandSender player) { + public Results(IAuxProtect plugin, ArrayList entries, MySender player, String commandPrefix) { this.entries = entries; this.player = player; this.formatter = DateTimeFormatter.ofPattern("ddMMMYY HH:mm:ss.SSS"); this.plugin = plugin; + if (!commandPrefix.startsWith("/")) { + commandPrefix = "/" + commandPrefix; + } + this.commandPrefix = commandPrefix; + + boolean allNullWorld = true; + int count = 0; + for (DbEntry entry : entries) { + if (entry.world != null && !entry.world.equals("#null")) { + allNullWorld = false; + break; + } + if (count++ > 1000) { + break; + } + } + if (allNullWorld) { + perpage = 10; + } } public DbEntry get(int i) { @@ -53,37 +72,39 @@ public class Results { for (int i = (page - 1) * perpage; i < (page) * perpage && i < entries.size(); i++) { DbEntry en = entries.get(i); ComponentBuilder message = new ComponentBuilder(); + plugin.debug(en.getTarget() + "(" + en.getTargetId() + "): " + en.getTargetUUID()); message.append(String.format("§7%s ago", TimeUtil.millisToString(System.currentTimeMillis() - en.getTime()), - en.getUser(plugin.getSqlManager()))) + en.getUser())) .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()), + message.append(String.format(" §f- §9%s §f%s §9%s§f", en.getUser(), 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 ClickEvent(ClickEvent.Action.RUN_COMMAND, + String.format(commandPrefix + " 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 ClickEvent(ClickEvent.Action.RUN_COMMAND, + String.format(commandPrefix + " 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))) + message.append(" §a[View Inv]").event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + String.format(commandPrefix + " 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 + ")"); @@ -91,23 +112,24 @@ public class Results { message.append(" §7(" + data + ")"); } if (en.world != null && !en.world.equals("$null")) { + String tpCommand = String.format(commandPrefix + " tp %d %d %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("/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!"))); + .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, tpCommand)) + .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("§7" + tpCommand))); } - player.spigot().sendMessage(message.create()); + player.sendMessage(message.create()); } ComponentBuilder message = new ComponentBuilder(); message.append("§7("); if (page > 1) { message.append("§9§l" + AuxProtect.LEFT_ARROW + AuxProtect.LEFT_ARROW) - .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/ap l 1:" + perpage)) + .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, commandPrefix + " 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" + AuxProtect.LEFT_ARROW) - .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/ap l " + (page - 1) + ":" + perpage)) + .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + commandPrefix + " l " + (page - 1) + ":" + perpage)) .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("Last Page"))); } else { message.event(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "")); @@ -119,11 +141,13 @@ public class Results { message.append(" ").event((ClickEvent) null).event((HoverEvent) null); if (page < lastpage) { message.append("§9§l" + AuxProtect.RIGHT_ARROW) - .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/ap l " + (page + 1) + ":" + perpage)) + .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + commandPrefix + " 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" + AuxProtect.RIGHT_ARROW + AuxProtect.RIGHT_ARROW) - .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/ap l " + lastpage + ":" + perpage)) + .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + commandPrefix + " l " + lastpage + ":" + perpage)) .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("Jump to Last Page"))); } else { message.append("§8§l" + AuxProtect.RIGHT_ARROW).event((ClickEvent) null).event((HoverEvent) null); @@ -133,7 +157,7 @@ public class Results { message.append("§7) ").event((ClickEvent) null).event((HoverEvent) null); message.append(String.format(plugin.translate("lookup-page-footer"), page, (int) Math.ceil(entries.size() / (double) perpage), entries.size())); - player.spigot().sendMessage(message.create()); + player.sendMessage(message.create()); return; } diff --git a/src/dev/heliosares/auxprotect/database/SQLManager.java b/src/dev/heliosares/auxprotect/database/SQLManager.java index 885ef86..9b30cb1 100644 --- a/src/dev/heliosares/auxprotect/database/SQLManager.java +++ b/src/dev/heliosares/auxprotect/database/SQLManager.java @@ -9,19 +9,19 @@ import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map.Entry; -import java.util.UUID; +import java.util.Set; import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.OfflinePlayer; -//import org.bukkit.World; -import org.bukkit.command.CommandSender; import dev.heliosares.auxprotect.IAuxProtect; +import dev.heliosares.auxprotect.utils.BidiMapCache; import dev.heliosares.auxprotect.utils.MovingAverage; +import dev.heliosares.auxprotect.utils.MySender; public class SQLManager { private Connection connection; @@ -35,9 +35,18 @@ public class SQLManager { private HashMap worlds = new HashMap<>(); private int nextWid; + private BidiMapCache uuids = new BidiMapCache<>(10000L, 10000L, true); + private BidiMapCache usernames = new BidiMapCache<>(10000L, 10000L, true); + private int version; - public static final int DBVERSION = 2; + private static SQLManager instance; + + public static SQLManager getInstance() { + return instance; + } + + public static final int DBVERSION = 3; public int getCount() { return count; @@ -61,31 +70,126 @@ public class SQLManager { private int count; public static enum TABLE { - AUXPROTECT, AUXPROTECT_SPAM, AUXPROTECT_LONGTERM, AUXPROTECT_ABANDONED, AUXPROTECT_INVENTORY, AUXPROTECT_WORLDS; + AUXPROTECT, AUXPROTECT_SPAM, AUXPROTECT_LONGTERM, AUXPROTECT_ABANDONED, AUXPROTECT_INVENTORY, AUXPROTECT_WORLDS, + AUXPROTECT_UIDS, AUXPROTECT_COMMANDS; @Override public String toString() { return tablePrefix + super.toString().toLowerCase(); } + + public boolean hasData() { + switch (this) { + case AUXPROTECT: + case AUXPROTECT_INVENTORY: + case AUXPROTECT_SPAM: + return true; + default: + return false; + } + } + + public boolean isOnBungee() { + switch (this) { + case AUXPROTECT: + case AUXPROTECT_COMMANDS: + case AUXPROTECT_LONGTERM: + return true; + default: + return false; + } + } + + public boolean hasLocation() { + switch (this) { + case AUXPROTECT: + case AUXPROTECT_ABANDONED: + case AUXPROTECT_INVENTORY: + case AUXPROTECT_SPAM: + case AUXPROTECT_COMMANDS: + return true; + default: + return false; + } + } + + public boolean hasActionId() { + switch (this) { + case AUXPROTECT_COMMANDS: + return false; + default: + return true; + } + } + + public boolean hasStringTarget() { + switch (this) { + case AUXPROTECT_COMMANDS: + case AUXPROTECT_LONGTERM: + return true; + default: + return false; + } + } + + public String getValuesHeader(boolean bungee) { + if (this == TABLE.AUXPROTECT_LONGTERM) { + return "(time, uid, action_id, target)"; + } else if (this == TABLE.AUXPROTECT_COMMANDS) { + if (bungee) { + return "(time, uid, target)"; + } + return "(time, uid, world_id, x, y, z, target)"; + } else if (bungee) { + return "(time, uid, action_id, target_id, data)"; + } else if (this == TABLE.AUXPROTECT || this == TABLE.AUXPROTECT_SPAM + || this == TABLE.AUXPROTECT_INVENTORY) { + return "(time, uid, action_id, world_id, x, y, z, target_id, data)"; + } else if (this == TABLE.AUXPROTECT_ABANDONED) { + return "(time, uid, action_id, world_id, x, y, z, target_id)"; + } + return null; + } + + public String getValuesTemplate(boolean bungee) { + if (this == TABLE.AUXPROTECT_LONGTERM) { + return "(?, ?, ?, ?)"; + } else if (this == TABLE.AUXPROTECT_COMMANDS) { + if (bungee) { + return "(?, ?, ?)"; + } + return "(?, ?, ?, ?, ?, ?, ?)"; + } else if (bungee) { + return "(?, ?, ?, ?, ?)"; + } else if (this == TABLE.AUXPROTECT || this == TABLE.AUXPROTECT_SPAM + || this == TABLE.AUXPROTECT_INVENTORY) { + return "(?, ?, ?, ?, ?, ?, ?, ?, ?)"; + } else if (this == TABLE.AUXPROTECT_ABANDONED) { + return "(?, ?, ?, ?, ?, ?, ?, ?)"; + } + return null; + } + } public String holdingConnection; public long holdingConnectionSince; public SQLManager(IAuxProtect plugin, String target, String prefix) { + instance = this; this.plugin = plugin; this.targetString = target; if (prefix == null) { tablePrefix = ""; } else { - tablePrefix = prefix; + tablePrefix = prefix.replaceAll(" ", "_"); if (tablePrefix.length() > 0 && !tablePrefix.endsWith("_")) { tablePrefix += "_"; } } } - public boolean connect(String user, String pass) { + public void connect(String user, String pass) throws SQLException { boolean driver = false; if (!driver) try { @@ -107,40 +211,36 @@ public class SQLManager { } if (!driver) { System.err.println("SQL DRIVER NOT FOUND"); - return false; } - try { - if (user != null && pass != null) { - mysql = true; - connection = DriverManager.getConnection(targetString, user, pass); - } else { - mysql = false; - connection = DriverManager.getConnection(targetString); - } - init(); - - isConnected = true; - return true; - } catch (SQLException e) { - e.printStackTrace(); + if (user != null && pass != null) { + mysql = true; + connection = DriverManager.getConnection(targetString, user, pass); + } else { + mysql = false; + connection = DriverManager.getConnection(targetString); } - return false; + init(); + + isConnected = true; + } - public boolean connect() { - return connect(null, null); + public void connect() throws SQLException { + connect(null, null); } public void close() { + isConnected = false; if (connection != null) { + checkAsync(); synchronized (connection) { holdingConnectionSince = System.currentTimeMillis(); holdingConnection = "close"; try { connection.close(); } catch (SQLException e) { - e.printStackTrace(); + plugin.print(e); } holdingConnectionSince = 0; } @@ -148,58 +248,63 @@ public class SQLManager { } private void init() throws SQLException { + checkAsync(); synchronized (connection) { holdingConnectionSince = System.currentTimeMillis(); holdingConnection = "init"; - Statement statement = connection.createStatement(); - String stmt = "CREATE TABLE IF NOT EXISTS version (time BIGINT,version INTEGER);"; - plugin.debug(stmt, 3); - statement.execute(stmt); + execute("CREATE TABLE IF NOT EXISTS version (time BIGINT,version INTEGER);"); - stmt = "SELECT * FROM version;"; + String stmt = "SELECT * FROM version;"; plugin.debug(stmt, 3); - ResultSet results = statement.executeQuery(stmt); - long versionTime = 0; - while (results.next()) { - long versionTime_ = results.getLong("time"); - int version_ = results.getInt("version"); - if (versionTime_ > versionTime) { - version = version_; - versionTime = versionTime_; + try (Statement statement = connection.createStatement()) { + try (ResultSet results = statement.executeQuery(stmt)) { + long versionTime = 0; + while (results.next()) { + long versionTime_ = results.getLong("time"); + int version_ = results.getInt("version"); + if (versionTime_ > versionTime) { + version = version_; + versionTime = versionTime_; + } + plugin.debug("Version at " + versionTime_ + " was v" + version_ + ".", 1); + } } - plugin.debug("Version at " + versionTime_ + " was v" + version_ + ".", 1); } - results.close(); if (version < 1) { - PreparedStatement pstmt = connection - .prepareStatement("INSERT INTO version (time,version) VALUES (?,?)"); - pstmt.setLong(1, System.currentTimeMillis()); - pstmt.setInt(2, DBVERSION); - plugin.debug("Setting database to v" + DBVERSION, 1); - pstmt.execute(); - pstmt.close(); - } else { - // This is inside an else so that it's only done if this isn't the first time - // running the plugin. - if (version < 2) { - plugin.info("Migrating database to v2"); - execute("ALTER TABLE worlds RENAME TO auxprotect_worlds;"); + execute("INSERT INTO version (time,version) VALUES (" + System.currentTimeMillis() + "," + + (version = DBVERSION) + ")"); + } - PreparedStatement pstmt = connection - .prepareStatement("INSERT INTO version (time,version) VALUES (?,?)"); - pstmt.setLong(1, System.currentTimeMillis()); - pstmt.setInt(2, 2); - pstmt.execute(); - pstmt.close(); - plugin.info("Done migrating."); + if (version < 2 && !plugin.isBungee()) { + plugin.info("Migrating database to v2"); + execute("ALTER TABLE worlds RENAME TO auxprotect_worlds;"); + + execute("\"INSERT INTO version (time,version) VALUES (" + System.currentTimeMillis() + "," + + (version = 2) + ")"); + plugin.info("Done migrating."); + } + int rowcountformerge = 0; + TABLE[] migrateTablesV3 = new TABLE[] { TABLE.AUXPROTECT, TABLE.AUXPROTECT_SPAM, TABLE.AUXPROTECT_LONGTERM, + TABLE.AUXPROTECT_ABANDONED, TABLE.AUXPROTECT_INVENTORY }; + if (plugin.isBungee()) { + migrateTablesV3 = new TABLE[] { TABLE.AUXPROTECT, TABLE.AUXPROTECT_LONGTERM }; + } + + if (version < 3) { + plugin.info("Migrating database to v3. DO NOT INTERRUPT"); + for (TABLE table : migrateTablesV3) { + rowcountformerge += count(table);// TODO: Lock error maybe? + execute("ALTER TABLE " + table.toString() + " RENAME TO " + table.toString() + "_temp;"); + plugin.info("."); } + plugin.info("Tables renamed"); } stmt = "CREATE TABLE IF NOT EXISTS " + TABLE.AUXPROTECT.toString() + " (\n"; stmt += " time BIGINT(255),\n"; - stmt += " user varchar(255),\n"; + stmt += " uid integer,\n"; stmt += " action_id SMALLINT,\n"; if (!plugin.isBungee()) { stmt += " world_id SMALLINT,\n"; @@ -207,207 +312,450 @@ public class SQLManager { stmt += " y SMALLINT,\n"; stmt += " z INTEGER,\n"; } - stmt += " target varchar(255),\n"; + stmt += " target_id integer,\n"; stmt += " data LONGTEXT\n"; stmt += ");"; - plugin.debug(stmt, 3); - statement.execute(stmt); + execute(stmt); stmt = "CREATE TABLE IF NOT EXISTS " + TABLE.AUXPROTECT_LONGTERM.toString() + " (\n"; stmt += " time BIGINT(255),\n"; - stmt += " user varchar(255),\n"; + stmt += " uid integer,\n"; stmt += " action_id SMALLINT,\n"; stmt += " target varchar(255)\n"; stmt += ");"; - plugin.debug(stmt, 3); - statement.execute(stmt); + execute(stmt); + + stmt = "CREATE TABLE IF NOT EXISTS " + TABLE.AUXPROTECT_COMMANDS.toString() + " (\n"; + stmt += " time BIGINT(255),\n"; + stmt += " uid integer,\n"; + if (!plugin.isBungee()) { + stmt += " world_id SMALLINT,\n"; + stmt += " x INTEGER,\n"; + stmt += " y SMALLINT,\n"; + stmt += " z INTEGER,\n"; + } + stmt += " target LONGTEXT\n"; + stmt += ");"; + execute(stmt); if (!plugin.isBungee()) { stmt = "CREATE TABLE IF NOT EXISTS " + TABLE.AUXPROTECT_INVENTORY.toString() + " (\n"; stmt += " time BIGINT(255),\n"; - stmt += " user varchar(255),\n"; + stmt += " uid integer,\n"; stmt += " action_id SMALLINT,\n"; stmt += " world_id SMALLINT,\n"; stmt += " x INTEGER,\n"; stmt += " y SMALLINT,\n"; stmt += " z INTEGER,\n"; - stmt += " target varchar(255),\n"; + stmt += " target_id integer,\n"; stmt += " data LONGTEXT\n"; stmt += ");"; plugin.debug(stmt, 3); - statement.execute(stmt); + execute(stmt); stmt = "CREATE TABLE IF NOT EXISTS " + TABLE.AUXPROTECT_SPAM.toString() + " (\n"; stmt += " time BIGINT(255),\n"; - stmt += " user varchar(255),\n"; + stmt += " uid integer,\n"; stmt += " action_id SMALLINT,\n"; stmt += " world_id SMALLINT,\n"; stmt += " x INTEGER,\n"; stmt += " y SMALLINT,\n"; stmt += " z INTEGER,\n"; - stmt += " target varchar(255),\n"; + stmt += " target_id integer,\n"; stmt += " data LONGTEXT\n"; stmt += ");"; plugin.debug(stmt, 3); - statement.execute(stmt); + execute(stmt); if (plugin.getAPConfig().isPrivate()) { stmt = "CREATE TABLE IF NOT EXISTS " + TABLE.AUXPROTECT_ABANDONED.toString() + " (\n"; stmt += " time BIGINT(255),\n"; - stmt += " user varchar(255),\n"; + stmt += " uid integer,\n"; stmt += " action_id SMALLINT,\n"; stmt += " world_id SMALLINT,\n"; stmt += " x INTEGER,\n"; stmt += " y SMALLINT,\n"; stmt += " z INTEGER,\n"; - stmt += " target varchar(255)\n"; + stmt += " target_id integer\n"; stmt += ");"; plugin.debug(stmt, 3); - statement.execute(stmt); + execute(stmt); } stmt = "CREATE TABLE IF NOT EXISTS " + TABLE.AUXPROTECT_WORLDS.toString() + " (name varchar(255), wid SMALLINT);"; plugin.debug(stmt, 3); - statement.execute(stmt); + execute(stmt); stmt = "SELECT * FROM " + TABLE.AUXPROTECT_WORLDS.toString() + ";"; plugin.debug(stmt, 3); - results = statement.executeQuery(stmt); - while (results.next()) { - String world = results.getString("name"); - int wid = results.getInt("wid"); - worlds.put(world, wid); - if (wid >= nextWid) { - nextWid = wid + 1; + try (Statement statement = connection.createStatement()) { + try (ResultSet results = statement.executeQuery(stmt)) { + while (results.next()) { + String world = results.getString("name"); + int wid = results.getInt("wid"); + worlds.put(world, wid); + if (wid >= nextWid) { + nextWid = wid + 1; + } + } } } - results.close(); + + } + + stmt = "CREATE TABLE IF NOT EXISTS " + TABLE.AUXPROTECT_UIDS.toString() + + " (uuid varchar(255), uid INTEGER PRIMARY KEY AUTOINCREMENT);"; + plugin.debug(stmt, 3); + execute(stmt); + + if (version < 3) { + plugin.info("Merging data into new tables..."); + int progress = 0; + int count = 0; + + for (TABLE table : migrateTablesV3) { + ArrayList output = new ArrayList<>(); + ArrayList commands = new ArrayList<>(); + final boolean hasLocation = plugin.isBungee() ? false : table.hasLocation(); + final boolean hasData = table.hasData(); + final boolean hasStringTarget = table.hasStringTarget(); + plugin.info("Merging table: " + table.toString()); + stmt = "SELECT * FROM " + table.toString() + "_temp;"; + plugin.debug(stmt, 3); + try (PreparedStatement pstmt = connection.prepareStatement(stmt)) { + pstmt.setFetchSize(500); + try (ResultSet results = pstmt.executeQuery()) { + while (results.next()) { + ArrayList entry = new ArrayList<>(); + entry.add(results.getLong("time")); + entry.add(this.getUIDFromUUID(results.getString("user"), true)); + int action_id = results.getInt("action_id"); + if (action_id != 260) { + entry.add(action_id); + } + if (hasLocation) { + entry.add(results.getInt("world_id")); + entry.add(results.getInt("x")); + entry.add(results.getInt("y")); + entry.add(results.getInt("z")); + } + String target = results.getString("target"); + if (hasStringTarget || action_id == 260) { + entry.add(target); + } else { + entry.add(this.getUIDFromUUID(target, true)); + } + if (hasData) { + entry.add(results.getString("data")); + } + + if (action_id == 260) { + commands.add(entry.toArray(new Object[0])); + } else { + output.add(entry.toArray(new Object[0])); + } + if (output.size() >= 5000) { + this.putRaw(table, output); + output.clear(); + } + if (commands.size() >= 5000) { + this.putRaw(TABLE.AUXPROTECT_COMMANDS, commands); + commands.clear(); + } + count++; + int progressPercentage = (int) Math.floor((double) count / rowcountformerge * 100); + if (progressPercentage / 5 > progress) { + progress = progressPercentage / 5; + plugin.info("Migration " + progress * 5 + "% complete. (" + count + "/" + + rowcountformerge + "). DO NOT INTERRUPT"); + } + } + } + } + if (output.size() > 0) { + this.putRaw(table, output); + } + if (commands.size() > 0) { + this.putRaw(TABLE.AUXPROTECT_COMMANDS, commands); + } + } + + execute("INSERT INTO version (time,version) VALUES (" + System.currentTimeMillis() + "," + (version = 3) + + ")"); + plugin.info("Done migrating."); + } + plugin.debug("Purging temporary tables"); + for (TABLE table : TABLE.values()) { + execute("DROP TABLE IF EXISTS " + table.toString() + "temp;"); + execute("DROP TABLE IF EXISTS " + table.toString() + "_temp;"); } - statement.close(); plugin.debug("init done.", 1); holdingConnectionSince = 0; } } + public void purgeUIDs() { + plugin.info("Performing UID purge"); + Set inUseUids = new HashSet<>(); + Set savedUids = new HashSet<>(); + + synchronized (connection) { + for (TABLE table : new TABLE[] { TABLE.AUXPROTECT, TABLE.AUXPROTECT_SPAM, TABLE.AUXPROTECT_LONGTERM, + TABLE.AUXPROTECT_ABANDONED, TABLE.AUXPROTECT_INVENTORY, TABLE.AUXPROTECT_UIDS }) { + try { + + boolean hasTargetId = !table.hasStringTarget() && table != TABLE.AUXPROTECT_UIDS; + String stmt = "SELECT uid" + (hasTargetId ? ", target_id" : "") + " FROM " + table.toString() + ";"; + plugin.debug(stmt, 3); + try (PreparedStatement pstmt = connection.prepareStatement(stmt)) { + pstmt.setFetchSize(500); + try (ResultSet results = pstmt.executeQuery()) { + while (results.next()) { + int uid = results.getInt("uid"); + if (table == TABLE.AUXPROTECT_UIDS) { + savedUids.add(uid); + continue; + } + inUseUids.add(uid); + if (hasTargetId) { + int target_id = results.getInt("target_id"); + inUseUids.add(target_id); + } + } + } + } + } catch (SQLException ignored) { + } + } + plugin.debug(savedUids.size() + " saved UIDS"); + plugin.debug(inUseUids.size() + " in use UIDS"); + int i = 0; + final String hdr = "DELETE FROM " + TABLE.AUXPROTECT_UIDS.toString() + " WHERE "; + String stmt = ""; + try { + for (int uid : savedUids) { + if (inUseUids.contains(uid)) { + continue; + } + if (!stmt.isEmpty()) { + stmt += " OR "; + } + plugin.debug("Purging UID " + uid, 5); + stmt += "uid=" + uid; + if (++i >= 1000) { + execute(hdr + stmt); + stmt = ""; + i = 0; + } + } + if (!stmt.isEmpty()) + execute(hdr + stmt); + } catch (SQLException e) { + + } + } + plugin.info("UID purge complete."); + } + + public void vacuum() throws SQLException { + synchronized (connection) { + execute("CREATE TABLE IF NOT EXISTS " + tablePrefix + "last_vacuum (time BIGINT);"); + + String stmt = "SELECT * FROM " + tablePrefix + "last_vacuum;"; + plugin.debug(stmt, 3); + long lastvacuum = 0; + int vacuumcount = 0; + try (Statement statement = connection.createStatement()) { + try (ResultSet results = statement.executeQuery(stmt)) { + while (results.next()) { + long time = results.getLong("time"); + if (time > lastvacuum) { + lastvacuum = time; + } + vacuumcount++; + } + } + } + + if (System.currentTimeMillis() - lastvacuum > 1000L * 3600L * 24L * 30L) { + plugin.info( + "Performing vacuum operation. Please do not shutdown your server or unload the plugin. This may take a while..."); + execute("VACUUM;"); + if (vacuumcount == 0) { + execute("INSERT INTO " + tablePrefix + "last_vacuum (time) VALUES (" + System.currentTimeMillis() + + ");"); + } else { + execute("UPDATE " + tablePrefix + "last_vacuum SET time=" + System.currentTimeMillis() + ";"); + } + plugin.info("Vacuum complete."); + } + } + } + public void execute(String stmt) throws SQLException { plugin.debug(stmt, 2); - Statement statement = connection.createStatement(); - statement.execute(stmt); - statement.close(); + checkAsync(); + synchronized (connection) { + try (Statement statement = connection.createStatement()) { + statement.execute(stmt); + } + } } public List> executeUpdate(String string) throws SQLException { plugin.debug(string, 2); - Statement statement = connection.createStatement(); - ResultSet rs = statement.executeQuery(string); - - if (rs == null) { - statement.close(); - return null; - } - final ResultSetMetaData meta = rs.getMetaData(); - final int columnCount = meta.getColumnCount(); final List> rowList = new LinkedList>(); - while (rs.next()) { - final List columnList = new LinkedList(); - rowList.add(columnList); + checkAsync(); + synchronized (connection) { + try (Statement statement = connection.createStatement()) { + try (ResultSet rs = statement.executeQuery(string)) { + final ResultSetMetaData meta = rs.getMetaData(); + final int columnCount = meta.getColumnCount(); + while (rs.next()) { + final List columnList = new LinkedList(); + rowList.add(columnList); - for (int column = 1; column <= columnCount; ++column) { - final Object value = rs.getObject(column); - columnList.add(String.valueOf(value)); + for (int column = 1; column <= columnCount; ++column) { + final Object value = rs.getObject(column); + columnList.add(String.valueOf(value)); + } + } + } } } - rs.close(); - statement.close(); return rowList; } - protected long put(TABLE table, ArrayList entries) throws SQLException { - if (!isConnected) - return -1; - long start = System.nanoTime(); + private void putRaw(TABLE table, ArrayList datas) + throws SQLException, ClassCastException, IndexOutOfBoundsException { + checkAsync(); synchronized (connection) { holdingConnectionSince = System.currentTimeMillis(); holdingConnection = "put"; String stmt = "INSERT INTO " + table.toString() + " "; - String inc = "\n (?, ?, ?, ?, ?, ?, ?, ?, ?)"; - boolean hasLocation = true; - boolean hasData = true; - if (table == TABLE.AUXPROTECT_LONGTERM) { - stmt += "(time, user, action_id, target)"; - inc = "\n (?, ?, ?, ?)"; - hasData = false; - hasLocation = false; - } else if (plugin.isBungee()) { - stmt += "(time, user, action_id, target, data)"; - inc = "\n (?, ?, ?, ?, ?)"; - hasLocation = false; - } else if (table == TABLE.AUXPROTECT || table == TABLE.AUXPROTECT_SPAM - || table == TABLE.AUXPROTECT_INVENTORY) { - stmt += "(time, user, action_id, world_id, x, y, z, target, data)"; - } else if (table == TABLE.AUXPROTECT_ABANDONED) { - stmt += "(time, user, action_id, world_id, x, y, z, target)"; - inc = "\n (?, ?, ?, ?, ?, ?, ?, ?)"; - hasData = false; - } else { - plugin.warning("Unknown table " + table.toString() + ". This is bad. (put)"); - return -1; + final boolean hasLocation = plugin.isBungee() ? false : table.hasLocation(); + final boolean hasData = table.hasData(); + final boolean hasAction = table.hasActionId(); + stmt += table.getValuesHeader(plugin.isBungee()); + String inc = table.getValuesTemplate(plugin.isBungee()); + stmt += " VALUES"; + for (int i = 0; i < datas.size(); i++) { + stmt += "\n" + inc; + if (i + 1 == datas.size()) { + stmt += ";"; + } else { + stmt += ","; + } } + try (PreparedStatement statement = connection.prepareStatement(stmt)) { + + int i = 1; + for (Object[] data : datas) { + int y = 0; + try { + // statement.setString(i++, table); + statement.setLong(i++, (long) data[y++]); + statement.setInt(i++, (int) data[y++]); + + if (hasAction) { + statement.setInt(i++, (int) data[y++]); + } + if (hasLocation) { + statement.setInt(i++, (int) data[y++]); + statement.setInt(i++, (int) data[y++]); + statement.setInt(i++, (int) data[y++]); + statement.setInt(i++, (int) data[y++]); + } + if (table.hasStringTarget()) { + statement.setString(i++, (String) data[y++]); + } else { + statement.setInt(i++, (int) data[y++]); + } + if (hasData) { + statement.setString(i++, (String) data[y++]); + } + } catch (Exception e) { + String error = ""; + for (Object o : data) { + error += o + ", "; + } + plugin.warning(error + "\nError at index " + y); + throw e; + } + } + + statement.executeUpdate(); + } + count += datas.size(); + holdingConnectionSince = 0; + } + } + + protected void put(TABLE table, ArrayList entries) throws SQLException { + long start = System.nanoTime(); + checkAsync(); + synchronized (connection) { + holdingConnectionSince = System.currentTimeMillis(); + holdingConnection = "put"; + String stmt = "INSERT INTO " + table.toString() + " "; + String inc = table.getValuesTemplate(plugin.isBungee()); + final boolean hasLocation = plugin.isBungee() ? false : table.hasLocation(); + final boolean hasData = table.hasData(); + final boolean hasAction = table.hasActionId(); + stmt += table.getValuesHeader(plugin.isBungee()); stmt += " VALUES"; for (int i = 0; i < entries.size(); i++) { - stmt += inc; + stmt += "\n" + inc; if (i + 1 == entries.size()) { stmt += ";"; } else { stmt += ","; } } - PreparedStatement statement = connection.prepareStatement(stmt, Statement.RETURN_GENERATED_KEYS); + try (PreparedStatement statement = connection.prepareStatement(stmt)) { - int i = 1; - for (DbEntry dbEntry : entries) { - // statement.setString(i++, table); - statement.setLong(i++, dbEntry.getTime()); - statement.setString(i++, dbEntry.userUuid.toLowerCase()); - int action = dbEntry.getState() ? dbEntry.getAction().idPos : dbEntry.getAction().id; + int i = 1; + for (DbEntry dbEntry : entries) { + // statement.setString(i++, table); + statement.setLong(i++, dbEntry.getTime()); + statement.setInt(i++, getUIDFromUUID(dbEntry.getUserUUID(), true)); + int action = dbEntry.getState() ? dbEntry.getAction().idPos : dbEntry.getAction().id; - statement.setInt(i++, action); - if (hasLocation) { - statement.setInt(i++, getWid(dbEntry.world)); - statement.setInt(i++, dbEntry.x); - int y = dbEntry.y; - if (y > 32767) { - y = 32767; + if (hasAction) { + statement.setInt(i++, action); } - if (y < -32768) { - y = -32768; + if (hasLocation) { + statement.setInt(i++, getWID(dbEntry.world)); + statement.setInt(i++, dbEntry.x); + int y = dbEntry.y; + if (y > 32767) { + y = 32767; + } + if (y < -32768) { + y = -32768; + } + statement.setInt(i++, y); + statement.setInt(i++, dbEntry.z); + } + if (table.hasStringTarget()) { + statement.setString(i++, dbEntry.getTargetUUID()); + } else { + statement.setInt(i++, getUIDFromUUID(dbEntry.getTargetUUID(), true)); + } + if (hasData) { + statement.setString(i++, dbEntry.getData()); } - statement.setInt(i++, y); - statement.setInt(i++, dbEntry.z); - } - statement.setString(i++, dbEntry.targetUuid); - if (hasData) { - statement.setString(i++, dbEntry.getData()); } + + statement.executeUpdate(); } - statement.executeUpdate(); - ResultSet result = statement.getGeneratedKeys(); - int serialized_id = -1; - - if (result.next()) { - serialized_id = result.getInt(1); - } - - result.close(); - 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; } } @@ -443,9 +791,11 @@ public class SQLManager { TABLE table = null; TABLE forcedTable = null; - String stmt = "\nWHERE ("; HashMap> dos = new HashMap<>(); HashMap> donts = new HashMap<>(); + ArrayList writeParams = new ArrayList<>(); + ArrayList targets = new ArrayList<>(); + boolean targetNot = false; if (exact && !params.containsKey("radius")) { if (location == null) { return null; @@ -491,34 +841,25 @@ public class SQLManager { } for (String param : value.split(",")) { String theStmt = ""; - if (key.equalsIgnoreCase("target") && param.contains("*")) { - theStmt = "target LIKE '" + param.replaceAll("-", " ").replaceAll("\\*", "%") - + "' OR target LIKE '" + param.replaceAll("\\*", "%") + "'"; - } else if (key.equalsIgnoreCase("user") || key.equalsIgnoreCase("target")) { - if (param.startsWith("@")) { - theStmt = "lower(" + key + ") = '" + param.substring(1).toLowerCase() + "'"; - } else if (!param.startsWith("#") && !param.startsWith("$")) { - String targetUuid = this.getUuidFromUsername(param); - if (targetUuid == null && !plugin.isBungee()) { - @SuppressWarnings("deprecation") - OfflinePlayer player = Bukkit.getOfflinePlayer(param); - if (player != null) { - targetUuid = "$" + player.getUniqueId().toString(); - } - } - if (targetUuid != null) { - theStmt = key + " = '" + targetUuid + "'"; - } else if (key.equals("user")) { - throw new LookupException(LookupExceptionType.PLAYER_NOT_FOUND, - String.format(plugin.translate("lookup-playernotfound"), param)); - } + if (key.equalsIgnoreCase("target")) { + if (not) { + targetNot = true; } - if (theStmt.length() > 0) { - theStmt += " OR "; - } - theStmt += "lower(" + key + ") = '" + param.toLowerCase() + "' OR "; - theStmt += "lower(" + key + ") = '" + param.toLowerCase().replaceAll("-", " ") + "'"; + targets.add(param); + } else if (key.equalsIgnoreCase("user")) { + int uid = this.getUIDFromUsername(param); + int altuid = this.getUIDFromUUID(param); + if (uid > 0 && altuid > 0) { + theStmt = "(uid = '" + uid + "' OR uid = '" + altuid + "')"; + } else if (uid > 0) { + theStmt = "uid = '" + uid + "'"; + } else if (altuid > 0) { + theStmt = "uid = '" + altuid + "'"; + } else { + throw new LookupException(LookupExceptionType.PLAYER_NOT_FOUND, + String.format(plugin.translate("lookup-playernotfound"), param)); + } } else if (key.equalsIgnoreCase("radius")) { String rStatement = stmtForRadius(location, param, !params.containsKey("world"), exact); if (rStatement != null) { @@ -542,9 +883,9 @@ public class SQLManager { * param)); return null; } } */ if (table == null) { - table = action.getTable(plugin.isBungee()); + table = action.getTable(); } else { - if (table != action.getTable(plugin.isBungee())) { + if (table != action.getTable()) { throw new LookupException(LookupExceptionType.ACTION_INCOMPATIBLE, plugin.translate("lookup-incompatible-tables")); } @@ -560,15 +901,17 @@ public class SQLManager { } } } else if (key.equalsIgnoreCase("world")) { - int wid = getWid(param); + int wid = getWID(param); if (wid == -1) { throw new LookupException(LookupExceptionType.UNKNOWN_WORLD, String.format(plugin.translate("lookup-unknown-world"), param)); } - theStmt = "world_id = " + getWid(param); + theStmt = "world_id = " + getWID(param); } else { - theStmt = key + " = '" + param + "'"; + theStmt = key + " = ?"; + writeParams.add(param); } + if (theStmt.length() > 0) { if (not) { ArrayList donts_ = donts.get(key); @@ -588,10 +931,62 @@ public class SQLManager { } } } + if (forcedTable != null) { + table = forcedTable; + } else if (table == null) { + table = TABLE.AUXPROTECT; + } + ArrayList targetArray = new ArrayList<>(); + for (String target : targets) { + String theStmt = ""; + if (table.hasStringTarget()) { + if (target.contains("*")) { + theStmt = "target LIKE ? OR target LIKE ?"; + writeParams.add(target.replaceAll("-", " ").replaceAll("\\*", "%")); + writeParams.add(target.replaceAll("\\*", "%")); + } else { + if (theStmt.length() > 0) { + theStmt += " OR "; + } + theStmt += "lower(target) = ? OR lower(target) = ?"; + writeParams.add(target.toLowerCase()); + writeParams.add(target.toLowerCase().replaceAll("-", " ")); + + } + } else { + int uid = this.getUIDFromUsername(target); + int altuid = this.getUIDFromUUID(target); + if (uid > 0 && altuid > 0) { + theStmt = "(target_id = '" + uid + "' OR target_id = '" + altuid + "')"; + } else if (uid > 0) { + theStmt = "target_id = '" + uid + "'"; + } else if (altuid > 0) { + theStmt = "target_id = '" + altuid + "'"; + } else { + throw new LookupException(LookupExceptionType.PLAYER_NOT_FOUND, + String.format(plugin.translate("lookup-playernotfound"), target)); + } + } + if (theStmt.length() > 0) { + targetArray.add(theStmt); + } + } + if (targetArray.size() > 0) { + if (targetNot) { + donts.put("target", targetArray); + } else { + dos.put("target", targetArray); + } + } + String stmt = "\nWHERE ("; + int conditions = 0; int i = 0; if (dos.size() > 0) { stmt += "("; for (String key : dos.keySet()) { + if (key.equalsIgnoreCase("action") && !table.hasActionId()) { + continue; + } if (i > 0) { stmt += ") AND ("; } @@ -603,6 +998,7 @@ public class SQLManager { stmt += values.get(i1); } i++; + conditions++; } stmt += ")"; } @@ -613,6 +1009,9 @@ public class SQLManager { } stmt += "NOT ("; for (String key : donts.keySet()) { + if (key.equalsIgnoreCase("action") && !table.hasActionId()) { + continue; + } if (i > 0) { stmt += " OR "; } @@ -624,109 +1023,96 @@ public class SQLManager { stmt += values.get(i1); } i++; + conditions++; } stmt += ")"; } - - stmt += ")\nORDER BY time DESC\nLIMIT 100001;"; - if (forcedTable != null) { - table = forcedTable; - } else if (table == null) { - table = TABLE.AUXPROTECT; + if (conditions == 0) { + stmt = ""; + } else { + stmt += ")"; } - boolean hasLocation = true; - boolean hasData = true; - if (table == TABLE.AUXPROTECT_LONGTERM) { - stmt = "SELECT time, user, action_id, target FROM " + table.toString() + stmt; - hasLocation = false; - hasData = false; - } else if (plugin.isBungee()) { - stmt = "SELECT time, user, action_id, target, data FROM auxprotect " + stmt; - hasLocation = false; - } else if (table == TABLE.AUXPROTECT || table == TABLE.AUXPROTECT_SPAM - || table == TABLE.AUXPROTECT_INVENTORY) { - stmt = "SELECT time, user, action_id, world_id, x, y, z, target, data FROM " + table.toString() + stmt; - } else if (table == TABLE.AUXPROTECT_ABANDONED) { - stmt = "SELECT time, user, action_id, world_id, x, y, z, target FROM " + table.toString() + stmt; - hasData = false; - } else if (table == TABLE.AUXPROTECT_WORLDS && plugin.getDebug() > 0) { - stmt = "SELECT * FROM " + table.toString(); - plugin.debug(stmt, 3); - try { - PreparedStatement pstmt = connection.prepareStatement(stmt); - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { - String name = rs.getString("name"); - int wid = rs.getInt("wid"); - plugin.debug("§9" + wid + ": §f" + name, 1); - } - } catch (SQLException e) { - - } + final boolean hasLocation = plugin.isBungee() ? false : table.hasLocation(); + final boolean hasData = table.hasData(); + final boolean hasAction = table.hasActionId(); + if (table == TABLE.AUXPROTECT_WORLDS) { return null; } else { - plugin.warning("Unknown table " + table.toString() + ". This is bad. (Lookup)"); - throw new LookupException(LookupExceptionType.UNKNOWN_TABLE, "Unknown Table"); + stmt = "SELECT * FROM " + table.toString() + stmt; } + stmt += "\nORDER BY time DESC\nLIMIT 100001;"; plugin.debug(stmt, 3); - PreparedStatement pstmt = null; - ResultSet rs = null; ArrayList output = new ArrayList<>(); long parseStart; + checkAsync(); synchronized (connection) { holdingConnectionSince = System.currentTimeMillis(); holdingConnection = "lookup"; long lookupStart = System.currentTimeMillis(); - try { - pstmt = connection.prepareStatement(stmt); + try (PreparedStatement pstmt = connection.prepareStatement(stmt)) { + pstmt.setFetchSize(500); - rs = pstmt.executeQuery(); + for (int i1 = 0; i1 < writeParams.size(); i1++) { + String param = writeParams.get(i1); + pstmt.setString(i1 + 1, param); + } + try (ResultSet rs = pstmt.executeQuery()) { - int count = 0; - parseStart = System.currentTimeMillis(); - while (rs.next()) { - long time = rs.getLong("time"); - String user = rs.getString("user"); - int action_id = rs.getInt("action_id"); - String world = null; - int x = 0, y = 0, z = 0; - if (hasLocation) { - world = this.getWorld(rs.getInt("world_id")); - x = rs.getInt("x"); - y = rs.getInt("y"); - z = rs.getInt("z"); - } - String target = rs.getString("target"); - String data = null; - if (hasData) { - data = rs.getString("data"); - } - EntryAction entryAction = EntryAction.fromId(action_id); - if (entryAction == null) { - plugin.debug("Unknown action_id: " + action_id, 1); - continue; - } - boolean state = false; - if (entryAction.hasDual && entryAction.id != action_id) { - state = true; - } - DbEntry entry = new DbEntry(time, user, entryAction, state, world, x, y, z, target, data); + int count = 0; + parseStart = System.currentTimeMillis(); + while (rs.next()) { + long time = rs.getLong("time"); + int uid = rs.getInt("uid"); + int action_id = -1; + if (hasAction) { + action_id = rs.getInt("action_id"); + } else if (table == TABLE.AUXPROTECT_COMMANDS) { + action_id = EntryAction.COMMAND.id; + } + String world = null; + int x = 0, y = 0, z = 0; + if (hasLocation) { + world = this.getWorld(rs.getInt("world_id")); + x = rs.getInt("x"); + y = rs.getInt("y"); + z = rs.getInt("z"); + } + String target = null; - output.add(entry); - if (++count >= 100000) { - throw new LookupException(LookupExceptionType.TOO_MANY, - String.format(plugin.translate("lookup-toomany"), count)); + String data = null; + if (hasData) { + data = rs.getString("data"); + } + EntryAction entryAction = EntryAction.fromId(action_id); + if (entryAction == null) { + plugin.debug("Unknown action_id: " + action_id, 1); + continue; + } + boolean state = false; + if (entryAction.hasDual && entryAction.id != action_id) { + state = true; + } + DbEntry entry = null; + if (table.hasStringTarget()) { + target = rs.getString("target"); + entry = new DbEntry(time, uid, entryAction, state, world, x, y, z, target, data); + } else { + int target_id = rs.getInt("target_id"); + entry = new DbEntry(time, uid, entryAction, state, world, x, y, z, target_id, data); + } + + output.add(entry); + if (++count >= 100000) { + throw new LookupException(LookupExceptionType.TOO_MANY, + String.format(plugin.translate("lookup-toomany"), count)); + } } } - - rs.close(); - pstmt.close(); - } catch (SQLException e) { plugin.warning("Error while executing command"); plugin.warning("SQL Code: " + stmt); - e.printStackTrace(); + plugin.print(e); holdingConnectionSince = 0; throw new LookupException(LookupExceptionType.GENERAL, plugin.translate("lookup-error")); } @@ -743,18 +1129,19 @@ public class SQLManager { throw e; } plugin.warning("Error while executing command"); - e.printStackTrace(); + plugin.print(e); holdingConnectionSince = 0; throw new LookupException(LookupExceptionType.GENERAL, plugin.translate("lookup-error")); } } - public boolean purge(CommandSender sender, TABLE table, long time) throws SQLException { + public boolean purge(MySender sender, TABLE table, long time) throws SQLException { if (!isConnected) return false; if (time < 1000 * 3600 * 24 * 14) { return false; } + checkAsync(); synchronized (connection) { holdingConnectionSince = System.currentTimeMillis(); holdingConnection = "purge"; @@ -763,19 +1150,12 @@ public class SQLManager { stmt += (System.currentTimeMillis() - time); stmt += ");"; plugin.debug(stmt, 1); - PreparedStatement pstmt = null; - try { - pstmt = connection.prepareStatement(stmt); + try (PreparedStatement pstmt = connection.prepareStatement(stmt)) { pstmt.setFetchSize(500); pstmt.execute(); - } catch (SQLException e) { - e.printStackTrace(); + plugin.print(e); return false; - } finally { - if (pstmt != null) { - pstmt.close(); - } } holdingConnectionSince = 0; } @@ -786,24 +1166,26 @@ public class SQLManager { if (!isConnected) return; String stmt = "DELETE FROM " + table.toString() - + "\nWHERE time = ? AND user = ? AND action_id = ? AND world_id = ? AND x = ? AND y = ? AND z = ? AND target = ?;"; + + "\nWHERE time = ? AND uid = ? AND action_id = ? AND world_id = ? AND x = ? AND y = ? AND z = ?;"; plugin.debug(stmt, 3); - try { - PreparedStatement statement = connection.prepareStatement(stmt); + checkAsync(); + synchronized (connection) { + try { + PreparedStatement statement = connection.prepareStatement(stmt); - int i = 1; - statement.setLong(i++, entry.getTime()); - statement.setString(i++, entry.userUuid.toLowerCase()); - statement.setInt(i++, entry.getAction().getId(entry.getState())); - statement.setInt(i++, getWid(entry.world)); - statement.setInt(i++, entry.x); - statement.setInt(i++, entry.y); - statement.setInt(i++, entry.z); - statement.setString(i++, entry.targetUuid); - statement.executeUpdate(); - } catch (SQLException e) { - e.printStackTrace(); + int i = 1; + statement.setLong(i++, entry.getTime()); + statement.setInt(i++, entry.getUid()); + statement.setInt(i++, entry.getAction().getId(entry.getState())); + statement.setInt(i++, getWID(entry.world)); + statement.setInt(i++, entry.x); + statement.setInt(i++, entry.y); + statement.setInt(i++, entry.z); + statement.executeUpdate(); + } catch (SQLException e) { + plugin.print(e); + } } } @@ -828,13 +1210,177 @@ public class SQLManager { stmt += "z BETWEEN " + (location.getBlockZ() - radius) + " AND " + (location.getBlockZ() + radius); if (specifyWorld) { stmt += " AND "; - stmt += "world_id = " + getWid(location.getWorld().getName()); + stmt += "world_id = " + getWID(location.getWorld().getName()); } } stmt += ")"; return stmt; } + public void updateUsernameAndIP(String uuid, String name, String ip) { + if (!uuid.startsWith("$")) { + uuid = "$" + uuid; + } + final int uid = this.getUIDFromUUID(uuid, true); + if (uid <= 0) { + return; + } + usernames.put(uid, name); + + checkAsync(); + synchronized (connection) { + String newestusername = null; + long newestusernametime = 0; + boolean newip = true; + String stmt = "SELECT * FROM " + TABLE.AUXPROTECT_LONGTERM.toString() + " WHERE uid=?;"; + plugin.debug(stmt, 3); + try (PreparedStatement pstmt = connection.prepareStatement(stmt)) { + pstmt.setInt(1, uid); + try (ResultSet results = pstmt.executeQuery()) { + while (results.next()) { + String target = results.getString("target"); + if (target == null) { + continue; + } + long time = results.getLong("time"); + int action_id = results.getInt("action_id"); + if (action_id == EntryAction.IP.id) { + if (target.equals(ip)) { + newip = false; + } + } else if (action_id == EntryAction.USERNAME.id) { + if (time > newestusernametime) { + newestusername = target; + newestusernametime = time; + } + } + } + } catch (SQLException e) { + plugin.print(e); + } + } catch (SQLException e) { + plugin.print(e); + } + if (newip) { + plugin.add(new DbEntry(uuid, EntryAction.IP, false, "", 0, 0, 0, ip, "")); + } + if (!name.equalsIgnoreCase(newestusername)) { + plugin.debug("New username: " + name + " for " + newestusername); + plugin.add(new DbEntry(uuid, EntryAction.USERNAME, false, "", 0, 0, 0, name, "")); + } + } + + } + + public String getUsernameFromUID(int uid) { + if (uid < 0) { + return null; + } + if (uid == 0) { + return ""; + } + if (usernames.containsKey(uid)) { + return usernames.get(uid); + } + /* + * if (plugin.isBungee()) { return uuid; } else { OfflinePlayer player = + * Bukkit.getOfflinePlayer(UUID.fromString(uuid.substring(1))); if (player != + * null) { usernames.put(uuid, player.getName()); return player.getName + */ + + String stmt = "SELECT * FROM " + TABLE.AUXPROTECT_LONGTERM.toString() + + " WHERE action_id=? AND uid=?\nORDER BY time DESC\nLIMIT 1;"; + plugin.debug(stmt, 3); + checkAsync(); + synchronized (connection) { + try (PreparedStatement pstmt = connection.prepareStatement(stmt)) { + pstmt.setInt(1, EntryAction.USERNAME.id); + pstmt.setInt(2, uid); + try (ResultSet results = pstmt.executeQuery()) { + if (results.next()) { + String username = results.getString("target"); + plugin.debug("Resolved UID " + uid + " to " + username, 5); + if (username != null) { + usernames.put(uid, username); + return username; + } + } + } catch (SQLException e) { + plugin.print(e); + } + } catch (SQLException e) { + plugin.print(e); + } + } + return null; + } + + public int getUIDFromUsername(String username) { + if (username == null) { + return -1; + } + if (usernames.containsValue(username)) { + return usernames.getKey(username); + } + String stmt = "SELECT * FROM " + TABLE.AUXPROTECT_LONGTERM.toString() + + " WHERE action_id=? AND lower(target)=?\nORDER BY time DESC\nLIMIT 1;"; + plugin.debug(stmt, 3); + + checkAsync(); + synchronized (connection) { + try (PreparedStatement pstmt = connection.prepareStatement(stmt)) { + pstmt.setInt(1, EntryAction.USERNAME.id); + pstmt.setString(2, username.toLowerCase()); + try (ResultSet results = pstmt.executeQuery()) { + if (results.next()) { + int uid = results.getInt("uid"); + String username_ = results.getString("target"); + plugin.debug("Resolved username " + username_ + " to UID " + uid, 5); + if (username_ != null && uid > 0) { + usernames.put(uid, username_); + return uid; + } + } + } catch (SQLException e) { + plugin.print(e); + } + } catch (SQLException e) { + plugin.print(e); + } + } + plugin.debug("Unknown UID for " + username, 3); + return -1; + } + + public int getWID(String world) { + if (worlds.containsKey(world)) { + return worlds.get(world); + } + if (Bukkit.getWorld(world) == null) { + return -1; + } + checkAsync(); + synchronized (connection) { + try { + + String stmt = "INSERT INTO " + TABLE.AUXPROTECT_WORLDS.toString() + " (name, wid)"; + stmt += "\nVALUES (?,?)"; + PreparedStatement pstmt = connection.prepareStatement(stmt); + pstmt.setString(1, world); + pstmt.setInt(2, nextWid); + plugin.debug(stmt + "\n" + world + ":" + nextWid, 3); + pstmt.execute(); + worlds.put(world, nextWid); + count++; + return nextWid++; + } catch (SQLException e) { + plugin.print(e); + } + } + + return -1; + } + public String getWorld(int wid) { for (Entry entry : worlds.entrySet()) { if (entry.getValue() == wid) { @@ -844,153 +1390,152 @@ public class SQLManager { return null; } - public void updateUsername(String uuid, String name) { - if (!uuid.startsWith("$")) - uuid = "$" + uuid; - usernames.put(uuid, name); + public int getUIDFromUUID(String uuid) { + return getUIDFromUUID(uuid, false); } - HashMap usernames = new HashMap<>(); - - public String getUsernameFromUUID(String uuid) { - if (!uuid.startsWith("$")) - uuid = "$" + uuid; - if (usernames.containsKey(uuid)) { - return usernames.get(uuid); - } - if (plugin.isBungee()) { - return uuid; - } else { - OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(uuid.substring(1))); - if (player != null) { - usernames.put(uuid, player.getName()); - return player.getName(); - } - } - HashMap params = new HashMap<>(); - params.put("user", uuid); - params.put("action", "username"); - - ArrayList results = null; - try { - results = plugin.getSqlManager().lookup(params, null, false); - } catch (LookupException e) { - plugin.warning(e.toString()); - } - if (results == null) - return null; - String newestusername = null; - long highestusername = 0; - for (DbEntry entry : results) { - if (entry.getTime() > highestusername) { - highestusername = entry.getTime(); - newestusername = entry.getTarget(); - } - } - usernames.put(uuid, newestusername); - return newestusername; - } - - public String getUuidFromUsername(String username) { - if (username == null) { - return null; - } - if (usernames.containsValue(username)) { - return usernames.get(username); - } - String username_ = username.toLowerCase(); - for (Entry entry : usernames.entrySet()) { - if (entry.getValue().toLowerCase().equals(username_)) { - return entry.getKey(); - } - } - HashMap params = new HashMap<>(); - params.put("target", "@" + username); - params.put("action", "username"); - - ArrayList results = null; - try { - results = plugin.getSqlManager().lookup(params, null, false); - } catch (LookupException e) { - plugin.warning(e.toString()); - } - if (results == null) - return null; - String newestUuid = null; - long highestusername = 0; - for (DbEntry entry : results) { - if (entry.getTime() > highestusername) { - highestusername = entry.getTime(); - newestUuid = entry.userUuid; - } - } - if (newestUuid != null) { - usernames.put(newestUuid, username); - } - return newestUuid; - } - - public int getWid(String world) { - if (worlds.containsKey(world)) { - return worlds.get(world); - } - if (Bukkit.getWorld(world) == null) { + public int getUIDFromUUID(String uuid, boolean insert) { + if (uuid == null || uuid.equalsIgnoreCase("#null")) { return -1; } - try { + if (uuid.length() == 0) { + return 0; + } + uuid = uuid.toLowerCase(); + if (uuids.containsValue(uuid)) { + return uuids.getKey(uuid); + } + checkAsync(); + synchronized (connection) { + String stmt = "SELECT * FROM " + TABLE.AUXPROTECT_UIDS.toString() + " WHERE uuid=?;"; + plugin.debug(stmt, 3); + try (PreparedStatement pstmt = connection.prepareStatement(stmt)) { + pstmt.setString(1, uuid); + try (ResultSet results = pstmt.executeQuery()) { + if (results.next()) { + int uid = results.getInt("uid"); + uuids.put(uid, uuid); + return uid; + } + } catch (SQLException e) { + plugin.print(e); + } + } catch (SQLException e) { + plugin.print(e); + } + if (insert) { + stmt = "INSERT INTO " + TABLE.AUXPROTECT_UIDS.toString() + " (uuid)\nVALUES (?)"; + try (PreparedStatement pstmt = connection.prepareStatement(stmt)) { + pstmt.setString(1, uuid); + pstmt.execute(); - String stmt = "INSERT INTO " + TABLE.AUXPROTECT_WORLDS.toString() + " (name, wid)"; - stmt += "\nVALUES (?,?)"; - PreparedStatement pstmt = connection.prepareStatement(stmt); - pstmt.setString(1, world); - pstmt.setInt(2, nextWid); - plugin.debug(stmt + "\n" + world + ":" + nextWid, 3); - pstmt.execute(); - worlds.put(world, nextWid); - count++; - return nextWid++; - } catch (SQLException e) { - e.printStackTrace(); + try (ResultSet result = pstmt.getGeneratedKeys()) { + if (result.next()) { + int uid = result.getInt(1); + uuids.put(uid, uuid); + plugin.debug("New UUID: " + uuid + ":" + uid, 3); + count++; + return uid++; + } + } + } catch (SQLException e) { + plugin.print(e); + } + } } return -1; } - public void count() { + public String getUUIDFromUID(int uid) { + if (uid < 0) { + return "#null"; + } + if (uid == 0) { + return ""; + } + if (uuids.containsKey(uid)) { + return uuids.get(uid); + } + + checkAsync(); + synchronized (connection) { + try (Statement statement = connection.createStatement()) { + String stmt = "SELECT * FROM " + TABLE.AUXPROTECT_UIDS.toString() + " WHERE uid='" + uid + "';"; + plugin.debug(stmt, 3); + try (ResultSet results = statement.executeQuery(stmt)) { + if (results.next()) { + String uuid = results.getString("uuid"); + uuids.put(uid, uuid); + return uuid; + } + } catch (SQLException e) { + plugin.print(e); + } + } catch (SQLException e) { + plugin.print(e); + } + } + return null; + } + + public void count() throws SQLException { int total = 0; plugin.debug("Counting rows.."); for (TABLE table : TABLE.values()) { + if (plugin.isBungee() && !table.isOnBungee()) { + continue; + } if (table == TABLE.AUXPROTECT_ABANDONED && !plugin.getAPConfig().isPrivate()) { continue; } - synchronized (connection) { - holdingConnectionSince = System.currentTimeMillis(); - holdingConnection = "count"; - try { - String stmtStr = ""; - if (mysql) { - stmtStr = "SELECT COUNT(*) FROM " + table.toString(); - } else { - stmtStr = "SELECT COUNT(1) FROM " + table.toString(); - } - plugin.debug(stmtStr, 5); - PreparedStatement pstmt = connection.prepareStatement(stmtStr); - ResultSet rs = pstmt.executeQuery(); - int count = 0; - if (rs.next()) { - count = rs.getInt(1); - } - total += count; - plugin.debug(table.toString() + ": " + count + " rows."); - rs.close(); - pstmt.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - holdingConnectionSince = 0; - } + total += count(table); } plugin.debug("Counted all tables. " + total + " rows."); count = total; } + + public int count(TABLE table) throws SQLException { + String stmtStr = ""; + if (mysql) { + stmtStr = "SELECT COUNT(*) FROM " + table.toString(); + } else { + stmtStr = "SELECT COUNT(1) FROM " + table.toString(); + } + plugin.debug(stmtStr, 5); + checkAsync(); + synchronized (connection) { + holdingConnectionSince = System.currentTimeMillis(); + holdingConnection = "count"; + try (PreparedStatement pstmt = connection.prepareStatement(stmtStr)) { + try (ResultSet rs = pstmt.executeQuery()) { + if (rs.next()) { + return rs.getInt(1); + } + } + } + holdingConnectionSince = 0; + } + + return -1; + } + + public void cleanup() { + usernames.cleanup(); + uuids.cleanup(); + } + + private boolean checkAsync() { + if (plugin.isBungee()) { + return true; + } + boolean sync = Bukkit.isPrimaryThread(); + if (sync) { + plugin.warning("Synchronous call to database. This may cause lag."); + if (plugin.getDebug() > 0) { + Thread.dumpStack(); + } + } + return !sync; + } } diff --git a/src/dev/heliosares/auxprotect/database/XrayResults.java b/src/dev/heliosares/auxprotect/database/XrayResults.java index 08540da..dcb0ed4 100644 --- a/src/dev/heliosares/auxprotect/database/XrayResults.java +++ b/src/dev/heliosares/auxprotect/database/XrayResults.java @@ -7,6 +7,7 @@ import org.bukkit.command.CommandSender; import dev.heliosares.auxprotect.AuxProtect; import dev.heliosares.auxprotect.IAuxProtect; import dev.heliosares.auxprotect.utils.EntryFormatter; +import dev.heliosares.auxprotect.utils.MySender; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.ComponentBuilder; import net.md_5.bungee.api.chat.HoverEvent; @@ -16,7 +17,7 @@ public class XrayResults extends Results { private IAuxProtect plugin; public XrayResults(IAuxProtect plugin, ArrayList entries, CommandSender player) { - super(plugin, entries, player); + super(plugin, entries, new MySender(player), "ap"); this.plugin = plugin; } @@ -63,7 +64,7 @@ public class XrayResults extends Results { message.append("§4§l[3]").event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format(xraycmd, 3, i))) .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("§4Rate this vein a 3/3 (almost certain or entirely certain)"))); - player.spigot().sendMessage(message.create()); + player.sendMessage(message.create()); } ComponentBuilder message = new ComponentBuilder(); message.append("§7("); @@ -99,7 +100,7 @@ public class XrayResults extends Results { message.append("§7) ").event((ClickEvent) null).event((HoverEvent) null); message.append(String.format(AuxProtect.getInstance().translate("lookup-page-footer"), page, (int) Math.ceil(entries.size() / (double) perpage), entries.size())); - player.spigot().sendMessage(message.create()); + player.sendMessage(message.create()); return; } diff --git a/src/dev/heliosares/auxprotect/listeners/PlayerListener.java b/src/dev/heliosares/auxprotect/listeners/PlayerListener.java index 00756ea..ff28927 100644 --- a/src/dev/heliosares/auxprotect/listeners/PlayerListener.java +++ b/src/dev/heliosares/auxprotect/listeners/PlayerListener.java @@ -1,7 +1,6 @@ package dev.heliosares.auxprotect.listeners; import java.util.ArrayList; -import java.util.HashMap; import org.bukkit.Location; import org.bukkit.Material; @@ -38,7 +37,6 @@ import dev.heliosares.auxprotect.AuxProtect; import dev.heliosares.auxprotect.database.DbEntry; import dev.heliosares.auxprotect.database.EntryAction; import dev.heliosares.auxprotect.database.PickupEntry; -import dev.heliosares.auxprotect.database.SQLManager.LookupException; import dev.heliosares.auxprotect.utils.ChartRenderer; import dev.heliosares.auxprotect.utils.InvSerialization; import dev.heliosares.auxprotect.utils.MyPermission; @@ -149,51 +147,12 @@ public class PlayerListener implements Listener { logMoney(plugin, e.getPlayer(), "join"); String ip = e.getPlayer().getAddress().getHostString(); logSession(e.getPlayer(), true, "IP: " + ip); - plugin.getSqlManager().updateUsername(e.getPlayer().getUniqueId().toString(), e.getPlayer().getName()); new BukkitRunnable() { @Override public void run() { - HashMap params = new HashMap<>(); - params.put("user", "$" + e.getPlayer().getUniqueId()); - params.put("action", "ip,username"); - - ArrayList results = null; - try { - results = plugin.getSqlManager().lookup(params, null, false); - } catch (LookupException e1) { - plugin.warning(e1.toString()); - return; - } - if (results == null) - return; - boolean newip = true; - String newestusername = ""; - long highestusername = 0; - for (DbEntry entry : results) { - if (entry.getAction() == EntryAction.IP) { - if (!newip) { - continue; - } - if (entry.getTarget().equals(ip)) { - newip = false; - } - } - if (entry.getAction() == EntryAction.USERNAME) { - if (entry.getTime() > highestusername) { - highestusername = entry.getTime(); - newestusername = entry.getTarget(); - } - } - } - if (newip) { - plugin.dbRunnable.add(new DbEntry(AuxProtect.getLabel(e.getPlayer()), EntryAction.IP, false, "", 0, - 0, 0, ip, "")); - } - if (!e.getPlayer().getName().equals(newestusername)) { - plugin.dbRunnable.add(new DbEntry(AuxProtect.getLabel(e.getPlayer()), EntryAction.USERNAME, false, - "", 0, 0, 0, e.getPlayer().getName(), "")); - } + plugin.getSqlManager().updateUsernameAndIP(e.getPlayer().getUniqueId().toString(), + e.getPlayer().getName(), ip); } }.runTaskAsynchronously(plugin); diff --git a/src/dev/heliosares/auxprotect/utils/BidiMap.java b/src/dev/heliosares/auxprotect/utils/BidiMap.java new file mode 100644 index 0000000..e521441 --- /dev/null +++ b/src/dev/heliosares/auxprotect/utils/BidiMap.java @@ -0,0 +1,46 @@ +package dev.heliosares.auxprotect.utils; + +import java.util.HashMap; +import java.util.Map.Entry; +import java.util.Set; + +public class BidiMap { + + public BidiMap() { + set = new HashMap<>(); + reverse = new HashMap<>(); + } + + private HashMap set; + private HashMap reverse; + + public void clear() { + set.clear(); + reverse.clear(); + } + + public boolean containsKey(K key) { + return set.containsKey(key); + } + + public boolean containsValue(V value) { + return reverse.containsKey(value); + } + + public V get(K key) { + return set.get(key); + } + + public K getKey(V value) { + return reverse.get(value); + } + + public void put(K key, V value) { + set.put(key, value); + reverse.put(value, key); + } + + public Set> entrySet() { + return set.entrySet(); + } +} diff --git a/src/dev/heliosares/auxprotect/utils/BidiMapCache.java b/src/dev/heliosares/auxprotect/utils/BidiMapCache.java new file mode 100644 index 0000000..e83f809 --- /dev/null +++ b/src/dev/heliosares/auxprotect/utils/BidiMapCache.java @@ -0,0 +1,110 @@ +package dev.heliosares.auxprotect.utils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Set; +import java.util.Map.Entry; + +public class BidiMapCache { + + public BidiMapCache(long timeToLive, long cleanupInterval, boolean updateWhenAccessed) { + set = new HashMap<>(); + reverse = new HashMap<>(); + timeAdded = new HashMap<>(); + this.timeToLive = timeToLive; + this.cleanupInterval = cleanupInterval; + this.lastCleanup = System.currentTimeMillis(); + this.updateWhenAccessed = updateWhenAccessed; + } + + private HashMap set; + private HashMap reverse; + private HashMap timeAdded; + private long lastCleanup; + private final long timeToLive; + private final long cleanupInterval; + private final boolean updateWhenAccessed; + + public void clear() { + set.clear(); + reverse.clear(); + timeAdded.clear(); + this.lastCleanup = System.currentTimeMillis(); + } + + public boolean containsKey(K key) { + synchronized (set) { + return set.containsKey(key); + } + } + + public boolean containsValue(V value) { + synchronized (set) { + return reverse.containsKey(value); + } + } + + public V get(K key) { + synchronized (set) { + V value = set.get(key); + if (value == null) { + return null; + } + if (updateWhenAccessed) { + timeAdded.put(key, System.currentTimeMillis()); + } + return value; + } + } + + public K getKey(V value) { + synchronized (set) { + K key = reverse.get(value); + if (key == null) { + return null; + } + if (updateWhenAccessed) { + timeAdded.put(key, System.currentTimeMillis()); + } + return key; + } + } + + public void put(K key, V value) { + synchronized (set) { + set.put(key, value); + reverse.put(value, key); + timeAdded.put(key, System.currentTimeMillis()); + } + } + + public Set> entrySet() { + return set.entrySet(); + } + + public void cleanup() { + if (System.currentTimeMillis() - lastCleanup > cleanupInterval) { + actuallyCleanup(); + lastCleanup = System.currentTimeMillis(); + } + } + + private void actuallyCleanup() { + final long cutoff = System.currentTimeMillis() - timeToLive; + synchronized (set) { + ArrayList cleanup = new ArrayList<>(); + for (Entry entry : timeAdded.entrySet()) { + if (entry.getValue().longValue() < cutoff) { + cleanup.add(entry.getKey()); + } + } + for (K key : cleanup) { + timeAdded.remove(key); + V value = set.remove(key); + if (value != null) { + reverse.remove(value); + } + } + } + } +} diff --git a/src/dev/heliosares/auxprotect/utils/EntryFormatter.java b/src/dev/heliosares/auxprotect/utils/EntryFormatter.java index ce4cf2f..3527f18 100644 --- a/src/dev/heliosares/auxprotect/utils/EntryFormatter.java +++ b/src/dev/heliosares/auxprotect/utils/EntryFormatter.java @@ -4,8 +4,6 @@ import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; -import org.bukkit.command.CommandSender; - import dev.heliosares.auxprotect.IAuxProtect; import dev.heliosares.auxprotect.database.DbEntry; import net.md_5.bungee.api.chat.ClickEvent; @@ -20,15 +18,15 @@ public class EntryFormatter { formatter = DateTimeFormatter.ofPattern("ddMMMYY HH:mm.ss"); } - public static void sendEntry(IAuxProtect plugin, DbEntry en, CommandSender sender) { + public static void sendEntry(IAuxProtect plugin, DbEntry en, MySender sender) { ComponentBuilder message = new ComponentBuilder(); message.append(String.format("§7%s ago", TimeUtil.millisToString(System.currentTimeMillis() - en.getTime()), - en.getUser(plugin.getSqlManager()))) + en.getUser())) .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text( "§7" + Instant.ofEpochMilli(en.getTime()).atZone(ZoneId.systemDefault()).format(formatter)))); - message.append(String.format(" §f- §9%s §f%s §9%s§f §7%s", en.getUser(plugin.getSqlManager()), + message.append(String.format(" §f- §9%s §f%s §9%s§f §7%s", en.getUser(), plugin.translate(en.getAction().getLang(en.getState())), en.getTarget(), (en.getData() != null && en.getData().length() > 0) ? "(" + en.getData() + ")" : "") + "\n") .event((HoverEvent) null); @@ -37,6 +35,6 @@ public class EntryFormatter { .event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, 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!"))); - sender.spigot().sendMessage(message.create()); + sender.sendMessage(message.create()); } } diff --git a/src/dev/heliosares/auxprotect/utils/InvSerialization.java b/src/dev/heliosares/auxprotect/utils/InvSerialization.java index 1b33b07..3648bfc 100644 --- a/src/dev/heliosares/auxprotect/utils/InvSerialization.java +++ b/src/dev/heliosares/auxprotect/utils/InvSerialization.java @@ -13,6 +13,8 @@ import org.bukkit.util.io.BukkitObjectInputStream; import org.bukkit.util.io.BukkitObjectOutputStream; import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder; +import dev.heliosares.auxprotect.AuxProtect; + public class InvSerialization { public static String playerToBase64(Player player) { String str1 = toBase64(player.getInventory().getStorageContents()); @@ -36,8 +38,8 @@ public class InvSerialization { bukkitObjectOutputStream.close(); return Base64Coder.encodeLines(byteArrayOutputStream.toByteArray()); - } catch (IOException exception) { - exception.printStackTrace(); + } catch (IOException e) { + AuxProtect.getInstance().print(e); } return null; } @@ -51,8 +53,8 @@ public class InvSerialization { bukkitObjectOutputStream.close(); return itemSeparator + Base64Coder.encodeLines(byteArrayOutputStream.toByteArray()); - } catch (IOException exception) { - exception.printStackTrace(); + } catch (IOException e) { + AuxProtect.getInstance().print(e); } return null; } @@ -84,8 +86,8 @@ public class InvSerialization { bukkitObjectOutputStream.close(); return Base64Coder.encodeLines(byteArrayOutputStream.toByteArray()); - } catch (IOException exception) { - exception.printStackTrace(); + } catch (IOException e) { + AuxProtect.getInstance().print(e); } return null; } @@ -104,8 +106,8 @@ public class InvSerialization { bukkitObjectInputStream.close(); return inventory; - } catch (Exception exc) { - exc.printStackTrace(); + } catch (Exception e) { + AuxProtect.getInstance().print(e); } return null; } @@ -126,8 +128,8 @@ public class InvSerialization { bukkitObjectInputStream.close(); return arrayOfItemStack; - } catch (Exception exc) { - exc.printStackTrace(); + } catch (Exception e) { + AuxProtect.getInstance().print(e); } return null; } @@ -146,8 +148,8 @@ public class InvSerialization { bukkitObjectInputStream.close(); return itemStack; - } catch (Exception exc) { - exc.printStackTrace(); + } catch (Exception e) { + AuxProtect.getInstance().print(e); } return null; } diff --git a/src/dev/heliosares/auxprotect/utils/MoneySolver.java b/src/dev/heliosares/auxprotect/utils/MoneySolver.java index 8756fc6..9c98bb3 100644 --- a/src/dev/heliosares/auxprotect/utils/MoneySolver.java +++ b/src/dev/heliosares/auxprotect/utils/MoneySolver.java @@ -13,9 +13,7 @@ import org.bukkit.entity.Player; import org.bukkit.map.MapCanvas; import org.bukkit.map.MapView; import org.bukkit.map.MinecraftFont; -import org.bukkit.scheduler.BukkitRunnable; - -import dev.heliosares.auxprotect.AuxProtect; +import dev.heliosares.auxprotect.IAuxProtect; import dev.heliosares.auxprotect.database.DbEntry; public class MoneySolver extends ChartRenderer { @@ -47,7 +45,7 @@ public class MoneySolver extends ChartRenderer { currentMoney = Double.parseDouble(result.getData().substring(1).replaceAll(",", "")); } catch (Exception e) { try { - currentMoney = Double.parseDouble(result.targetUuid.substring(1).replaceAll(",", "")); + currentMoney = Double.parseDouble(result.getTargetUUID().substring(1).replaceAll(",", "")); } catch (Exception e1) { e1.printStackTrace(); return; @@ -115,13 +113,13 @@ public class MoneySolver extends ChartRenderer { } } - public static void showMoney(AuxProtect plugin, Player player, ArrayList results, int time, String users) { - new BukkitRunnable() { + public static void showMoney(IAuxProtect plugin, Player player, ArrayList results, int time, String users) { + plugin.runSync(new Runnable() { @Override public void run() { MoneySolver solver = new MoneySolver(player, results, time, users); player.getInventory().addItem(solver.asItem(player)); } - }.runTask(plugin); + }); } } diff --git a/src/dev/heliosares/auxprotect/utils/MyPermission.java b/src/dev/heliosares/auxprotect/utils/MyPermission.java index 1167355..2bd4804 100644 --- a/src/dev/heliosares/auxprotect/utils/MyPermission.java +++ b/src/dev/heliosares/auxprotect/utils/MyPermission.java @@ -21,6 +21,10 @@ public enum MyPermission { return player.hasPermission(node); } + public boolean hasPermission(MySender player) { + return player.hasPermission(node); + } + public boolean hasPermission(net.md_5.bungee.api.CommandSender player) { return player.hasPermission(node); } diff --git a/src/dev/heliosares/auxprotect/utils/MySender.java b/src/dev/heliosares/auxprotect/utils/MySender.java new file mode 100644 index 0000000..00f7e9f --- /dev/null +++ b/src/dev/heliosares/auxprotect/utils/MySender.java @@ -0,0 +1,78 @@ +package dev.heliosares.auxprotect.utils; + +import java.util.UUID; + +import org.bukkit.entity.Player; + +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +public class MySender { + + private final Object sender; + private final boolean bungee; + + public MySender(org.bukkit.command.CommandSender sender) { + this.sender = sender; + this.bungee = false; + } + + public MySender(net.md_5.bungee.api.CommandSender sender) { + this.sender = sender; + this.bungee = true; + } + + public Object getSender() { + return sender; + } + + public boolean isBungee() { + return bungee; + } + + public void sendMessage(String message) { + if (bungee) { + ((net.md_5.bungee.api.CommandSender) sender).sendMessage(TextComponent.fromLegacyText(message)); + } else { + ((org.bukkit.command.CommandSender) sender).sendMessage(message); + } + } + + public void sendMessage(BaseComponent... message) { + if (bungee) { + ((net.md_5.bungee.api.CommandSender) sender).sendMessage(message); + } else { + ((org.bukkit.command.CommandSender) sender).spigot().sendMessage(message); + } + } + + public boolean hasPermission(String node) { + if (bungee) { + return ((net.md_5.bungee.api.CommandSender) sender).hasPermission(node); + } else { + return ((org.bukkit.command.CommandSender) sender).hasPermission(node); + } + } + + public String getName() { + if (bungee) { + return ((net.md_5.bungee.api.CommandSender) sender).getName(); + } else { + return ((org.bukkit.command.CommandSender) sender).getName(); + } + } + + public UUID getUniqueId() { + if (bungee) { + if (sender instanceof ProxiedPlayer) { + return ((ProxiedPlayer) sender).getUniqueId(); + } + } else { + if (sender instanceof Player) { + return ((Player) sender).getUniqueId(); + } + } + return UUID.fromString("00000000-0000-0000-0000-000000000000"); + } +} diff --git a/src/dev/heliosares/auxprotect/utils/UpdateChecker.java b/src/dev/heliosares/auxprotect/utils/UpdateChecker.java index a43a82f..c2d0571 100644 --- a/src/dev/heliosares/auxprotect/utils/UpdateChecker.java +++ b/src/dev/heliosares/auxprotect/utils/UpdateChecker.java @@ -5,6 +5,7 @@ import org.bukkit.plugin.java.JavaPlugin; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.util.ArrayList; import java.util.Scanner; // From: https://www.spigotmc.org/wiki/creating-an-update-checker-that-checks-for-updates @@ -22,42 +23,43 @@ public class UpdateChecker { return null; } - private static int[] versionAsIntArray(String version) { - String[] parts = version.split("\\."); + public static Integer[] versionAsIntArray(String version) { + String[] parts = version.split("[\\.|\\-]+"); if (version.startsWith("v")) { version = version.substring(1); } - int array[] = new int[parts.length]; + ArrayList array = new ArrayList<>(); for (int i = 0; i < parts.length; i++) { try { - array[i] = Integer.parseInt(parts[i]); + int part = 0; + if (parts[i].startsWith("pre")) { + part = Integer.parseInt(parts[i].substring(3)) - 1000000; + } else { + part = Integer.parseInt(parts[i]); + } + array.add(part); } 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"; + return array.toArray(new Integer[0]); } /** * @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]; + Integer[] ver1int = versionAsIntArray(ver1); + Integer[] ver2int = versionAsIntArray(ver2); + for (int i = 0; i < ver1int.length || i < ver2int.length; i++) { + int ver1part = 0; + int ver2part = 0; + if (i < ver1int.length) { + ver1part = ver1int[i]; + } + if (i < ver2int.length) { + ver2part = ver2int[i]; + } if (ver1part > ver2part) { return -1; } @@ -65,12 +67,6 @@ public class UpdateChecker { return 1; } } - if (ver1int.length > ver2int.length) { - return -1; - } - if (ver1int.length < ver2int.length) { - return 1; - } return 0; } } \ No newline at end of file diff --git a/src/dev/heliosares/auxprotect/utils/XraySolver.java b/src/dev/heliosares/auxprotect/utils/XraySolver.java index 28bac28..9a04f7e 100644 --- a/src/dev/heliosares/auxprotect/utils/XraySolver.java +++ b/src/dev/heliosares/auxprotect/utils/XraySolver.java @@ -20,9 +20,9 @@ public class XraySolver { HashMap> hash = new HashMap<>(); for (int i = entries.size() - 1; i >= 0; i--) { DbEntry entry = entries.get(i); - ArrayList hits = hash.get(entry.userUuid); + ArrayList hits = hash.get(entry.getUserUUID()); if (hits == null) { - hash.put(entry.userUuid, hits = new ArrayList<>()); + hash.put(entry.getUserUUID(), hits = new ArrayList<>()); } if (entry.getAction() == EntryAction.XRAYCHECK) { hits.add(entry); @@ -41,7 +41,7 @@ public class XraySolver { } } if (score >= 6) { - String user = entries1.get(0).getUser(plugin.getSqlManager()); + String user = entries1.get(0).getUser(); String tooltip = "§4Hits for '" + user + "':\n"; for (DbEntry entry : entries1) { switch (entry.getTarget()) { diff --git a/src/dev/heliosares/auxprotect/utils/YMLManager.java b/src/dev/heliosares/auxprotect/utils/YMLManager.java index 61b5c2f..7aa7389 100644 --- a/src/dev/heliosares/auxprotect/utils/YMLManager.java +++ b/src/dev/heliosares/auxprotect/utils/YMLManager.java @@ -48,7 +48,7 @@ public class YMLManager { Files.copy(plugin.getResource(fileName + ".yml"), dfile.toPath()); reload(); } catch (IOException e) { - e.printStackTrace(); + plugin.print(e); } } save();