diff --git a/bukkit/build.gradle.kts b/bukkit/build.gradle.kts index 14c326f..5081b0e 100644 --- a/bukkit/build.gradle.kts +++ b/bukkit/build.gradle.kts @@ -31,6 +31,7 @@ dependencies { compileOnly("org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT") { exclude("junit", "junit") } + compileOnly("org.apache.logging.log4j:log4j-core:2.17.0") "shadeOnly"("org.bstats:bstats-bukkit:2.2.1") } diff --git a/bukkit/src/main/java/me/confuser/banmanager/webenhancer/bukkit/BukkitPlugin.java b/bukkit/src/main/java/me/confuser/banmanager/webenhancer/bukkit/BukkitPlugin.java index c672168..1575722 100644 --- a/bukkit/src/main/java/me/confuser/banmanager/webenhancer/bukkit/BukkitPlugin.java +++ b/bukkit/src/main/java/me/confuser/banmanager/webenhancer/bukkit/BukkitPlugin.java @@ -57,7 +57,6 @@ public void onEnable() { setupListeners(); setupCommands(); - setupRunnables(); } @Override @@ -110,12 +109,6 @@ public void setupCommands() { } } - public void setupRunnables() { -// Runner syncRunner = new Runner(new ExpiresSync(plugin)); - -// getServer().getScheduler().runTaskTimerAsynchronously(this, syncRunner, 10L, 10L); - } - public void setupListeners() { appender = new LogServerAppender(plugin); ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).addAppender(appender); diff --git a/bukkit/src/main/java/me/confuser/banmanager/webenhancer/bukkit/listeners/ReportListener.java b/bukkit/src/main/java/me/confuser/banmanager/webenhancer/bukkit/listeners/ReportListener.java index 1f58828..600af19 100644 --- a/bukkit/src/main/java/me/confuser/banmanager/webenhancer/bukkit/listeners/ReportListener.java +++ b/bukkit/src/main/java/me/confuser/banmanager/webenhancer/bukkit/listeners/ReportListener.java @@ -15,8 +15,10 @@ import org.bukkit.event.Listener; import java.sql.SQLException; -import java.util.Iterator; +import java.util.ArrayList; +import java.util.List; import java.util.Queue; +import me.confuser.banmanager.common.BanManagerPlugin; public class ReportListener implements Listener { private final BukkitPlugin plugin; @@ -29,24 +31,29 @@ public ReportListener(BukkitPlugin plugin) { @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) public void notifyOnReport(PlayerReportedEvent event) { - PlayerReportData report = event.getReport(); + List logs; Queue queue = plugin.getAppender().getQueue(); - synchronized (queue) { - Iterator iterator = queue.iterator(); + logs = new ArrayList<>(queue); + } + + final int reportId = event.getReport().getId(); - // Create many-to-many relationship - while (iterator.hasNext()) { - LogData log = iterator.next(); + BanManagerPlugin.getInstance().getScheduler().runAsync(() -> { + try { + PlayerReportData report = BanManagerPlugin.getInstance() + .getPlayerReportStorage().queryForId(reportId); - try { + if (report == null) return; + + for (LogData log : logs) { plugin.getPlugin().getLogStorage().createIfNotExists(log); plugin.getPlugin().getReportLogStorage().create(new ReportLogData(report, log)); - } catch (SQLException e) { - e.printStackTrace(); } + } catch (SQLException e) { + e.printStackTrace(); } - } + }); } @EventHandler diff --git a/bungee/src/main/java/me/confuser/banmanager/BungeeCommand.java b/bungee/src/main/java/me/confuser/banmanager/webenhancer/bungee/BungeeCommand.java similarity index 100% rename from bungee/src/main/java/me/confuser/banmanager/BungeeCommand.java rename to bungee/src/main/java/me/confuser/banmanager/webenhancer/bungee/BungeeCommand.java diff --git a/bungee/src/main/java/me/confuser/banmanager/webenhancer/bungee/BungeePlugin.java b/bungee/src/main/java/me/confuser/banmanager/webenhancer/bungee/BungeePlugin.java index edc0e88..6e2a7ca 100644 --- a/bungee/src/main/java/me/confuser/banmanager/webenhancer/bungee/BungeePlugin.java +++ b/bungee/src/main/java/me/confuser/banmanager/webenhancer/bungee/BungeePlugin.java @@ -49,7 +49,6 @@ public void onEnable() { setupListeners(); setupCommands(); - setupRunnables(); } @Override @@ -103,12 +102,6 @@ private void setupCommands() { getLogger().info("Registered commands"); } - public void setupRunnables() { -// Runner syncRunner = new Runner(new ExpiresSync(plugin)); - -// getServer().getScheduler().runTaskTimerAsynchronously(this, syncRunner, 10L, 10L); - } - public void setupListeners() { registerEvent(new BanListener(this)); } diff --git a/common/src/main/java/me/confuser/banmanager/webenhancer/common/WebEnhancerPlugin.java b/common/src/main/java/me/confuser/banmanager/webenhancer/common/WebEnhancerPlugin.java index 89dd103..5a4922b 100644 --- a/common/src/main/java/me/confuser/banmanager/webenhancer/common/WebEnhancerPlugin.java +++ b/common/src/main/java/me/confuser/banmanager/webenhancer/common/WebEnhancerPlugin.java @@ -11,9 +11,11 @@ import me.confuser.banmanager.webenhancer.common.storage.LogStorage; import me.confuser.banmanager.webenhancer.common.storage.PlayerPinStorage; import me.confuser.banmanager.webenhancer.common.storage.ReportLogStorage; +import me.confuser.banmanager.webenhancer.common.runnables.ExpiresSync; import java.io.File; import java.sql.SQLException; +import java.time.Duration; public class WebEnhancerPlugin { private static WebEnhancerPlugin self; @@ -58,6 +60,9 @@ public final void enable() throws Exception { e.printStackTrace(); throw new Exception("An error occurred attempting to make a database connection, please see stack trace below"); } + + // Schedule pin cleanup every 60 seconds + scheduler.runAsyncRepeating(new ExpiresSync(this), Duration.ofSeconds(60), Duration.ofSeconds(60)); } public void setupConfigs() { diff --git a/common/src/main/java/me/confuser/banmanager/webenhancer/common/data/LogData.java b/common/src/main/java/me/confuser/banmanager/webenhancer/common/data/LogData.java index c23a306..32dcefd 100644 --- a/common/src/main/java/me/confuser/banmanager/webenhancer/common/data/LogData.java +++ b/common/src/main/java/me/confuser/banmanager/webenhancer/common/data/LogData.java @@ -6,6 +6,10 @@ import lombok.Getter; import lombok.Setter; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + @DatabaseTable public class LogData { @@ -22,11 +26,31 @@ public class LogData { @Getter private long created = System.currentTimeMillis() / 1000L; + @DatabaseField(columnDefinition = "CHAR(64)") + @Getter + @Setter + private String messageHash; + LogData() { } public LogData(String message, long created) { this.message = message; this.created = created; + this.messageHash = computeHash(message); + } + + public static String computeHash(String message) { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + byte[] hash = digest.digest(message.getBytes(StandardCharsets.UTF_8)); + StringBuilder hex = new StringBuilder(); + for (byte b : hash) { + hex.append(String.format("%02x", b)); + } + return hex.toString(); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } } } diff --git a/common/src/main/java/me/confuser/banmanager/webenhancer/common/runnables/ExpiresSync.java b/common/src/main/java/me/confuser/banmanager/webenhancer/common/runnables/ExpiresSync.java index 2cff61e..849865a 100644 --- a/common/src/main/java/me/confuser/banmanager/webenhancer/common/runnables/ExpiresSync.java +++ b/common/src/main/java/me/confuser/banmanager/webenhancer/common/runnables/ExpiresSync.java @@ -1,6 +1,6 @@ package me.confuser.banmanager.webenhancer.common.runnables; -import me.confuser.banmanager.common.ormlite.dao.CloseableIterator; +import me.confuser.banmanager.common.ormlite.stmt.DeleteBuilder; import me.confuser.banmanager.common.BanManagerPlugin; import me.confuser.banmanager.common.runnables.BmRunnable; import me.confuser.banmanager.common.util.DateUtils; @@ -23,19 +23,12 @@ public ExpiresSync(WebEnhancerPlugin plugin) { public void run() { long now = (System.currentTimeMillis() / 1000L) + DateUtils.getTimeDiff(); - CloseableIterator pins = null; try { - pins = pinStorage.queryBuilder().where().le("expires", now).iterator(); - - while (pins.hasNext()) { - PlayerPinData pin = pins.next(); - - pinStorage.delete(pin); - } + DeleteBuilder deleteBuilder = pinStorage.deleteBuilder(); + deleteBuilder.where().le("expires", now); + deleteBuilder.delete(); } catch (SQLException e) { e.printStackTrace(); - } finally { - if (pins != null) pins.closeQuietly(); } } } diff --git a/common/src/main/java/me/confuser/banmanager/webenhancer/common/storage/LogStorage.java b/common/src/main/java/me/confuser/banmanager/webenhancer/common/storage/LogStorage.java index a7622ad..90c1870 100644 --- a/common/src/main/java/me/confuser/banmanager/webenhancer/common/storage/LogStorage.java +++ b/common/src/main/java/me/confuser/banmanager/webenhancer/common/storage/LogStorage.java @@ -24,13 +24,50 @@ public LogStorage(ConnectionSource connection) throws SQLException { executeRawNoArgs("ALTER TABLE " + tableConfig.getTableName() + " CHANGE `created` `created` BIGINT UNSIGNED"); } catch (SQLException e) { } + + boolean columnAdded = false; + try { + executeRawNoArgs("ALTER TABLE " + tableConfig.getTableName() + + " ADD COLUMN messageHash CHAR(64)"); + columnAdded = true; + } catch (SQLException e) { + } + + try { + executeRawNoArgs("CREATE INDEX idx_" + tableConfig.getTableName() + + "_created_hash ON " + tableConfig.getTableName() + " (created, messageHash)"); + } catch (SQLException e) { + } + + if (columnAdded) { + try { + executeRawNoArgs( + "UPDATE " + tableConfig.getTableName() + + " SET messageHash = SHA2(message, 256)" + + " WHERE messageHash IS NULL" + ); + BanManagerPlugin.getInstance().getLogger().info("[WebEnhancer] Log hash migration completed"); + } catch (SQLException e) { + BanManagerPlugin.getInstance().getLogger().info("[WebEnhancer] SQL hash migration skipped (SHA2 not available) - new logs will be indexed"); + } + } } } public LogData createIfNotExists(LogData data) throws SQLException { QueryBuilder query = queryBuilder(); - //TODO Will require full table scan because of message, add index - query.where().eq("message", data.getMessage()).and().eq("created", data.getCreated()); + + if (data.getMessageHash() != null) { + query.where() + .eq("created", data.getCreated()) + .and() + .eq("messageHash", data.getMessageHash()); + } else { + query.where() + .eq("message", data.getMessage()) + .and() + .eq("created", data.getCreated()); + } List results = query.query(); diff --git a/fabric/src/main/java/me/confuser/banmanager/webenhancer/fabric/FabricPlugin.java b/fabric/src/main/java/me/confuser/banmanager/webenhancer/fabric/FabricPlugin.java index ed4a951..60ad833 100644 --- a/fabric/src/main/java/me/confuser/banmanager/webenhancer/fabric/FabricPlugin.java +++ b/fabric/src/main/java/me/confuser/banmanager/webenhancer/fabric/FabricPlugin.java @@ -11,9 +11,9 @@ import org.apache.logging.log4j.LogManager; import lombok.Getter; -import me.confuser.banmanager.common.BanManagerPlugin; import me.confuser.banmanager.common.commands.CommonCommand; import me.confuser.banmanager.common.configs.PluginInfo; +import me.confuser.banmanager.fabric.FabricScheduler; import me.confuser.banmanager.common.configuration.ConfigurationSection; import me.confuser.banmanager.common.configuration.file.YamlConfiguration; import me.confuser.banmanager.fabric.FabricCommand; @@ -37,6 +37,7 @@ public class FabricPlugin implements DedicatedServerModInitializer { private PluginInfo pluginInfo; @Getter private LogServerAppender appender; + private FabricScheduler scheduler; @Override public void onInitializeServer() { @@ -47,11 +48,13 @@ public void onInitializeServer() { return; } + scheduler = new FabricScheduler(); + plugin = new WebEnhancerPlugin( pluginInfo, new PluginLogger(LogManager.getLogger("BanManager-WebEnhancer")), getDataFolder(), - BanManagerPlugin.getInstance().getScheduler(), + scheduler, new FabricMetrics() ); @@ -69,6 +72,10 @@ public void onInitializeServer() { } private void onServerStopping(MinecraftServer server) { + if (scheduler != null) { + scheduler.shutdown(); + } + if (appender != null) { ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).removeAppender(appender); } diff --git a/fabric/src/main/java/me/confuser/banmanager/webenhancer/fabric/listeners/ReportListener.java b/fabric/src/main/java/me/confuser/banmanager/webenhancer/fabric/listeners/ReportListener.java index 86a725e..208d0a3 100644 --- a/fabric/src/main/java/me/confuser/banmanager/webenhancer/fabric/listeners/ReportListener.java +++ b/fabric/src/main/java/me/confuser/banmanager/webenhancer/fabric/listeners/ReportListener.java @@ -1,8 +1,10 @@ package me.confuser.banmanager.webenhancer.fabric.listeners; import java.sql.SQLException; -import java.util.Iterator; +import java.util.ArrayList; +import java.util.List; import java.util.Queue; +import me.confuser.banmanager.common.BanManagerPlugin; import me.confuser.banmanager.common.data.PlayerReportData; import me.confuser.banmanager.common.ormlite.stmt.DeleteBuilder; @@ -24,23 +26,29 @@ public ReportListener(FabricPlugin fabricPlugin) { } private void notifyOnReport(PlayerReportData report, boolean silent) { + List logs; Queue queue = fabricPlugin.getAppender().getQueue(); - synchronized (queue) { - Iterator iterator = queue.iterator(); + logs = new ArrayList<>(queue); + } + + final int reportId = report.getId(); - // Create many-to-many relationship - while (iterator.hasNext()) { - LogData log = iterator.next(); + BanManagerPlugin.getInstance().getScheduler().runAsync(() -> { + try { + PlayerReportData reportReloaded = BanManagerPlugin.getInstance() + .getPlayerReportStorage().queryForId(reportId); - try { + if (reportReloaded == null) return; + + for (LogData log : logs) { fabricPlugin.getPlugin().getLogStorage().createIfNotExists(log); - fabricPlugin.getPlugin().getReportLogStorage().create(new ReportLogData(report, log)); - } catch (SQLException e) { - e.printStackTrace(); + fabricPlugin.getPlugin().getReportLogStorage().create(new ReportLogData(reportReloaded, log)); } + } catch (SQLException e) { + e.printStackTrace(); } - } + }); } private void reportDeleted(PlayerReportData report) { diff --git a/libs/build.gradle.kts b/libs/build.gradle.kts index 473b554..d512a4a 100644 --- a/libs/build.gradle.kts +++ b/libs/build.gradle.kts @@ -6,8 +6,6 @@ dependencies { "shade"("org.bouncycastle:bcprov-jdk15on:1.70") "shade"("org.bouncycastle:bcpkix-jdk15on:1.70") "shade"("com.google.guava:guava:17.0") - "shade"("org.apache.logging.log4j:log4j-core:2.17.0") - "shade"("org.apache.logging.log4j:log4j-api:2.17.0") } tasks.withType() { @@ -27,8 +25,6 @@ tasks.named("jar") { include(dependency("com.google.guava:guava")) } - include(dependency("org.apache.logging.log4j:log4j-core")) - include(dependency("org.apache.logging.log4j:log4j-api")) include(dependency("org.bouncycastle:bcpkix-jdk15on")) } diff --git a/sponge-api7/build.gradle.kts b/sponge-api7/build.gradle.kts index df2d503..0c3496c 100644 --- a/sponge-api7/build.gradle.kts +++ b/sponge-api7/build.gradle.kts @@ -64,6 +64,7 @@ configurations { dependencies { compileOnly("org.spongepowered:spongeapi:7.2.0") compileOnly("me.confuser.banmanager:BanManagerSponge7:7.10.0-SNAPSHOT") + compileOnly("org.apache.logging.log4j:log4j-core:2.17.0") api(project(":BanManagerWebEnhancerCommon")) { isTransitive = true diff --git a/sponge-api7/src/main/java/me/confuser/banmanager/webenhancer/sponge/SpongePlugin.java b/sponge-api7/src/main/java/me/confuser/banmanager/webenhancer/sponge/SpongePlugin.java index dee3e1d..b5e19d2 100644 --- a/sponge-api7/src/main/java/me/confuser/banmanager/webenhancer/sponge/SpongePlugin.java +++ b/sponge-api7/src/main/java/me/confuser/banmanager/webenhancer/sponge/SpongePlugin.java @@ -101,7 +101,6 @@ public void onEnable(GameInitializationEvent event) { setupListeners(); setupCommands(); - setupRunnables(); } public CommonLogger getLogger() { @@ -146,9 +145,6 @@ public void setupCommands() { } } - public void setupRunnables() { - } - public void setupListeners() { appender = new LogServerAppender(plugin); ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).addAppender(appender); diff --git a/sponge-api7/src/main/java/me/confuser/banmanager/webenhancer/sponge/listeners/ReportListener.java b/sponge-api7/src/main/java/me/confuser/banmanager/webenhancer/sponge/listeners/ReportListener.java index 8821836..29cb6fb 100644 --- a/sponge-api7/src/main/java/me/confuser/banmanager/webenhancer/sponge/listeners/ReportListener.java +++ b/sponge-api7/src/main/java/me/confuser/banmanager/webenhancer/sponge/listeners/ReportListener.java @@ -16,8 +16,10 @@ import org.spongepowered.api.util.Tristate; import java.sql.SQLException; -import java.util.Iterator; +import java.util.ArrayList; +import java.util.List; import java.util.Queue; +import me.confuser.banmanager.common.BanManagerPlugin; public class ReportListener { private final SpongePlugin plugin; @@ -31,24 +33,29 @@ public ReportListener(SpongePlugin plugin) { @IsCancelled(Tristate.UNDEFINED) @Listener(order = Order.POST) public void notifyOnReport(PlayerReportedEvent event) { - PlayerReportData report = event.getReport(); + List logs; Queue queue = plugin.getAppender().getQueue(); - synchronized (queue) { - Iterator iterator = queue.iterator(); + logs = new ArrayList<>(queue); + } + + final int reportId = event.getReport().getId(); - // Create many-to-many relationship - while (iterator.hasNext()) { - LogData log = iterator.next(); + BanManagerPlugin.getInstance().getScheduler().runAsync(() -> { + try { + PlayerReportData report = BanManagerPlugin.getInstance() + .getPlayerReportStorage().queryForId(reportId); - try { + if (report == null) return; + + for (LogData log : logs) { plugin.getPlugin().getLogStorage().createIfNotExists(log); plugin.getPlugin().getReportLogStorage().create(new ReportLogData(report, log)); - } catch (SQLException e) { - e.printStackTrace(); } + } catch (SQLException e) { + e.printStackTrace(); } - } + }); } @IsCancelled(Tristate.UNDEFINED) diff --git a/sponge/src/main/java/me/confuser/banmanager/webenhancer/sponge/listeners/ReportListener.java b/sponge/src/main/java/me/confuser/banmanager/webenhancer/sponge/listeners/ReportListener.java index 9ccfeb3..cf048ce 100644 --- a/sponge/src/main/java/me/confuser/banmanager/webenhancer/sponge/listeners/ReportListener.java +++ b/sponge/src/main/java/me/confuser/banmanager/webenhancer/sponge/listeners/ReportListener.java @@ -14,8 +14,10 @@ import org.spongepowered.api.event.Order; import java.sql.SQLException; -import java.util.Iterator; +import java.util.ArrayList; +import java.util.List; import java.util.Queue; +import me.confuser.banmanager.common.BanManagerPlugin; public class ReportListener { private final SpongePlugin plugin; @@ -30,24 +32,29 @@ public ReportListener(SpongePlugin plugin) { public void notifyOnReport(PlayerReportedEvent event) { plugin.getFileLogReader().readNewEntries(); - PlayerReportData report = event.getReport(); + List logs; Queue queue = plugin.getLogQueue(); - synchronized (queue) { - Iterator iterator = queue.iterator(); + logs = new ArrayList<>(queue); + } + + final int reportId = event.getReport().getId(); - // Create many-to-many relationship - while (iterator.hasNext()) { - LogData log = iterator.next(); + BanManagerPlugin.getInstance().getScheduler().runAsync(() -> { + try { + PlayerReportData report = BanManagerPlugin.getInstance() + .getPlayerReportStorage().queryForId(reportId); - try { + if (report == null) return; + + for (LogData log : logs) { plugin.getPlugin().getLogStorage().createIfNotExists(log); plugin.getPlugin().getReportLogStorage().create(new ReportLogData(report, log)); - } catch (SQLException e) { - e.printStackTrace(); } + } catch (SQLException e) { + e.printStackTrace(); } - } + }); } @Listener(order = Order.POST) diff --git a/velocity/build.gradle.kts b/velocity/build.gradle.kts index f9564d7..bf8be7e 100644 --- a/velocity/build.gradle.kts +++ b/velocity/build.gradle.kts @@ -2,11 +2,16 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { `java-library` + id("net.kyori.blossom") version "1.2.0" } applyPlatformAndCoreConfiguration() applyShadowConfiguration() +blossom { + replaceToken("@projectVersion@", project.ext["internalVersion"]) +} + repositories { maven { name = "papermc" diff --git a/velocity/src/main/java/me/confuser/banmanager/webenhancer/velocity/VelocityPlugin.java b/velocity/src/main/java/me/confuser/banmanager/webenhancer/velocity/VelocityPlugin.java index e32f18d..85832dd 100644 --- a/velocity/src/main/java/me/confuser/banmanager/webenhancer/velocity/VelocityPlugin.java +++ b/velocity/src/main/java/me/confuser/banmanager/webenhancer/velocity/VelocityPlugin.java @@ -33,7 +33,7 @@ @Plugin( id = "banmanagerwebenhancer", name = "BanManagerWebEnhancer", - version = "${projectVersion}", + version = "@projectVersion@", url = "https://banmanagement.com", description = "A suite of moderation plugins & apps for Minecraft servers",dependencies = { @Dependency(id = "banmanager")}, @@ -84,7 +84,6 @@ public void onProxyInitialisation(ProxyInitializeEvent event) { return; } - setupRunnables(); setupListeners(); setupCommands(); @@ -145,12 +144,6 @@ private void setupCommands() { logger.info("Registered commands"); } - public void setupRunnables() { -// Runner syncRunner = new Runner(new ExpiresSync(plugin)); - -// getServer().getScheduler().runTaskTimerAsynchronously(this, syncRunner, 10L, 10L); - } - public void setupListeners() { registerEvent(new BanListener(this)); }