Skip to content

Commit a28ce1c

Browse files
authored
fix: async DB operations, log deduplication, and build cleanup (#25)
- Move DB operations in ReportListeners to async (ID capture pattern) - Add messageHash column for efficient log deduplication (one-time migration) - Schedule ExpiresSync with batch delete in common plugin - Remove Log4j from libs module, add compileOnly where needed - Fix Velocity version token replacement with Blossom - Move BungeeCommand.java to correct package - Remove empty setupRunnables() from platform plugins - Fix Fabric to use own scheduler instead of BanManager's
1 parent c924ad0 commit a28ce1c

File tree

18 files changed

+162
-89
lines changed

18 files changed

+162
-89
lines changed

bukkit/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ dependencies {
3131
compileOnly("org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT") {
3232
exclude("junit", "junit")
3333
}
34+
compileOnly("org.apache.logging.log4j:log4j-core:2.17.0")
3435
"shadeOnly"("org.bstats:bstats-bukkit:2.2.1")
3536
}
3637

bukkit/src/main/java/me/confuser/banmanager/webenhancer/bukkit/BukkitPlugin.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ public void onEnable() {
5757

5858
setupListeners();
5959
setupCommands();
60-
setupRunnables();
6160
}
6261

6362
@Override
@@ -110,12 +109,6 @@ public void setupCommands() {
110109
}
111110
}
112111

113-
public void setupRunnables() {
114-
// Runner syncRunner = new Runner(new ExpiresSync(plugin));
115-
116-
// getServer().getScheduler().runTaskTimerAsynchronously(this, syncRunner, 10L, 10L);
117-
}
118-
119112
public void setupListeners() {
120113
appender = new LogServerAppender(plugin);
121114
((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).addAppender(appender);

bukkit/src/main/java/me/confuser/banmanager/webenhancer/bukkit/listeners/ReportListener.java

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
import org.bukkit.event.Listener;
1616

1717
import java.sql.SQLException;
18-
import java.util.Iterator;
18+
import java.util.ArrayList;
19+
import java.util.List;
1920
import java.util.Queue;
21+
import me.confuser.banmanager.common.BanManagerPlugin;
2022

2123
public class ReportListener implements Listener {
2224
private final BukkitPlugin plugin;
@@ -29,24 +31,29 @@ public ReportListener(BukkitPlugin plugin) {
2931

3032
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
3133
public void notifyOnReport(PlayerReportedEvent event) {
32-
PlayerReportData report = event.getReport();
34+
List<LogData> logs;
3335
Queue<LogData> queue = plugin.getAppender().getQueue();
34-
3536
synchronized (queue) {
36-
Iterator<LogData> iterator = queue.iterator();
37+
logs = new ArrayList<>(queue);
38+
}
39+
40+
final int reportId = event.getReport().getId();
3741

38-
// Create many-to-many relationship
39-
while (iterator.hasNext()) {
40-
LogData log = iterator.next();
42+
BanManagerPlugin.getInstance().getScheduler().runAsync(() -> {
43+
try {
44+
PlayerReportData report = BanManagerPlugin.getInstance()
45+
.getPlayerReportStorage().queryForId(reportId);
4146

42-
try {
47+
if (report == null) return;
48+
49+
for (LogData log : logs) {
4350
plugin.getPlugin().getLogStorage().createIfNotExists(log);
4451
plugin.getPlugin().getReportLogStorage().create(new ReportLogData(report, log));
45-
} catch (SQLException e) {
46-
e.printStackTrace();
4752
}
53+
} catch (SQLException e) {
54+
e.printStackTrace();
4855
}
49-
}
56+
});
5057
}
5158

5259
@EventHandler

bungee/src/main/java/me/confuser/banmanager/BungeeCommand.java renamed to bungee/src/main/java/me/confuser/banmanager/webenhancer/bungee/BungeeCommand.java

File renamed without changes.

bungee/src/main/java/me/confuser/banmanager/webenhancer/bungee/BungeePlugin.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ public void onEnable() {
4949

5050
setupListeners();
5151
setupCommands();
52-
setupRunnables();
5352
}
5453

5554
@Override
@@ -103,12 +102,6 @@ private void setupCommands() {
103102
getLogger().info("Registered commands");
104103
}
105104

106-
public void setupRunnables() {
107-
// Runner syncRunner = new Runner(new ExpiresSync(plugin));
108-
109-
// getServer().getScheduler().runTaskTimerAsynchronously(this, syncRunner, 10L, 10L);
110-
}
111-
112105
public void setupListeners() {
113106
registerEvent(new BanListener(this));
114107
}

common/src/main/java/me/confuser/banmanager/webenhancer/common/WebEnhancerPlugin.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
import me.confuser.banmanager.webenhancer.common.storage.LogStorage;
1212
import me.confuser.banmanager.webenhancer.common.storage.PlayerPinStorage;
1313
import me.confuser.banmanager.webenhancer.common.storage.ReportLogStorage;
14+
import me.confuser.banmanager.webenhancer.common.runnables.ExpiresSync;
1415

1516
import java.io.File;
1617
import java.sql.SQLException;
18+
import java.time.Duration;
1719

1820
public class WebEnhancerPlugin {
1921
private static WebEnhancerPlugin self;
@@ -58,6 +60,9 @@ public final void enable() throws Exception {
5860
e.printStackTrace();
5961
throw new Exception("An error occurred attempting to make a database connection, please see stack trace below");
6062
}
63+
64+
// Schedule pin cleanup every 60 seconds
65+
scheduler.runAsyncRepeating(new ExpiresSync(this), Duration.ofSeconds(60), Duration.ofSeconds(60));
6166
}
6267

6368
public void setupConfigs() {

common/src/main/java/me/confuser/banmanager/webenhancer/common/data/LogData.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
import lombok.Getter;
77
import lombok.Setter;
88

9+
import java.nio.charset.StandardCharsets;
10+
import java.security.MessageDigest;
11+
import java.security.NoSuchAlgorithmException;
12+
913
@DatabaseTable
1014
public class LogData {
1115

@@ -22,11 +26,31 @@ public class LogData {
2226
@Getter
2327
private long created = System.currentTimeMillis() / 1000L;
2428

29+
@DatabaseField(columnDefinition = "CHAR(64)")
30+
@Getter
31+
@Setter
32+
private String messageHash;
33+
2534
LogData() {
2635
}
2736

2837
public LogData(String message, long created) {
2938
this.message = message;
3039
this.created = created;
40+
this.messageHash = computeHash(message);
41+
}
42+
43+
public static String computeHash(String message) {
44+
try {
45+
MessageDigest digest = MessageDigest.getInstance("SHA-256");
46+
byte[] hash = digest.digest(message.getBytes(StandardCharsets.UTF_8));
47+
StringBuilder hex = new StringBuilder();
48+
for (byte b : hash) {
49+
hex.append(String.format("%02x", b));
50+
}
51+
return hex.toString();
52+
} catch (NoSuchAlgorithmException e) {
53+
throw new RuntimeException(e);
54+
}
3155
}
3256
}

common/src/main/java/me/confuser/banmanager/webenhancer/common/runnables/ExpiresSync.java

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package me.confuser.banmanager.webenhancer.common.runnables;
22

3-
import me.confuser.banmanager.common.ormlite.dao.CloseableIterator;
3+
import me.confuser.banmanager.common.ormlite.stmt.DeleteBuilder;
44
import me.confuser.banmanager.common.BanManagerPlugin;
55
import me.confuser.banmanager.common.runnables.BmRunnable;
66
import me.confuser.banmanager.common.util.DateUtils;
@@ -23,19 +23,12 @@ public ExpiresSync(WebEnhancerPlugin plugin) {
2323
public void run() {
2424
long now = (System.currentTimeMillis() / 1000L) + DateUtils.getTimeDiff();
2525

26-
CloseableIterator<PlayerPinData> pins = null;
2726
try {
28-
pins = pinStorage.queryBuilder().where().le("expires", now).iterator();
29-
30-
while (pins.hasNext()) {
31-
PlayerPinData pin = pins.next();
32-
33-
pinStorage.delete(pin);
34-
}
27+
DeleteBuilder<PlayerPinData, Integer> deleteBuilder = pinStorage.deleteBuilder();
28+
deleteBuilder.where().le("expires", now);
29+
deleteBuilder.delete();
3530
} catch (SQLException e) {
3631
e.printStackTrace();
37-
} finally {
38-
if (pins != null) pins.closeQuietly();
3932
}
4033
}
4134
}

common/src/main/java/me/confuser/banmanager/webenhancer/common/storage/LogStorage.java

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,50 @@ public LogStorage(ConnectionSource connection) throws SQLException {
2424
executeRawNoArgs("ALTER TABLE " + tableConfig.getTableName() + " CHANGE `created` `created` BIGINT UNSIGNED");
2525
} catch (SQLException e) {
2626
}
27+
28+
boolean columnAdded = false;
29+
try {
30+
executeRawNoArgs("ALTER TABLE " + tableConfig.getTableName() +
31+
" ADD COLUMN messageHash CHAR(64)");
32+
columnAdded = true;
33+
} catch (SQLException e) {
34+
}
35+
36+
try {
37+
executeRawNoArgs("CREATE INDEX idx_" + tableConfig.getTableName() +
38+
"_created_hash ON " + tableConfig.getTableName() + " (created, messageHash)");
39+
} catch (SQLException e) {
40+
}
41+
42+
if (columnAdded) {
43+
try {
44+
executeRawNoArgs(
45+
"UPDATE " + tableConfig.getTableName() +
46+
" SET messageHash = SHA2(message, 256)" +
47+
" WHERE messageHash IS NULL"
48+
);
49+
BanManagerPlugin.getInstance().getLogger().info("[WebEnhancer] Log hash migration completed");
50+
} catch (SQLException e) {
51+
BanManagerPlugin.getInstance().getLogger().info("[WebEnhancer] SQL hash migration skipped (SHA2 not available) - new logs will be indexed");
52+
}
53+
}
2754
}
2855
}
2956

3057
public LogData createIfNotExists(LogData data) throws SQLException {
3158
QueryBuilder<LogData, Integer> query = queryBuilder();
32-
//TODO Will require full table scan because of message, add index
33-
query.where().eq("message", data.getMessage()).and().eq("created", data.getCreated());
59+
60+
if (data.getMessageHash() != null) {
61+
query.where()
62+
.eq("created", data.getCreated())
63+
.and()
64+
.eq("messageHash", data.getMessageHash());
65+
} else {
66+
query.where()
67+
.eq("message", data.getMessage())
68+
.and()
69+
.eq("created", data.getCreated());
70+
}
3471

3572
List<LogData> results = query.query();
3673

fabric/src/main/java/me/confuser/banmanager/webenhancer/fabric/FabricPlugin.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
import org.apache.logging.log4j.LogManager;
1212

1313
import lombok.Getter;
14-
import me.confuser.banmanager.common.BanManagerPlugin;
1514
import me.confuser.banmanager.common.commands.CommonCommand;
1615
import me.confuser.banmanager.common.configs.PluginInfo;
16+
import me.confuser.banmanager.fabric.FabricScheduler;
1717
import me.confuser.banmanager.common.configuration.ConfigurationSection;
1818
import me.confuser.banmanager.common.configuration.file.YamlConfiguration;
1919
import me.confuser.banmanager.fabric.FabricCommand;
@@ -37,6 +37,7 @@ public class FabricPlugin implements DedicatedServerModInitializer {
3737
private PluginInfo pluginInfo;
3838
@Getter
3939
private LogServerAppender appender;
40+
private FabricScheduler scheduler;
4041

4142
@Override
4243
public void onInitializeServer() {
@@ -47,11 +48,13 @@ public void onInitializeServer() {
4748
return;
4849
}
4950

51+
scheduler = new FabricScheduler();
52+
5053
plugin = new WebEnhancerPlugin(
5154
pluginInfo,
5255
new PluginLogger(LogManager.getLogger("BanManager-WebEnhancer")),
5356
getDataFolder(),
54-
BanManagerPlugin.getInstance().getScheduler(),
57+
scheduler,
5558
new FabricMetrics()
5659
);
5760

@@ -69,6 +72,10 @@ public void onInitializeServer() {
6972
}
7073

7174
private void onServerStopping(MinecraftServer server) {
75+
if (scheduler != null) {
76+
scheduler.shutdown();
77+
}
78+
7279
if (appender != null) {
7380
((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).removeAppender(appender);
7481
}

0 commit comments

Comments
 (0)