From 86cbdd41c295b3693db5700f02c6031bb07d6b60 Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Sun, 25 Aug 2024 17:48:18 -0500 Subject: [PATCH] Fix trackers not being created on BattleArena reload --- .../battleplugins/tracker/BattleTracker.java | 16 +++- .../feature/battlearena/ArenaTracker.java | 1 + .../battlearena/BattleArenaListener.java | 88 +++++++++++++++---- .../tracker/sql/SqlSerializer.java | 16 ++-- 4 files changed, 94 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/battleplugins/tracker/BattleTracker.java b/src/main/java/org/battleplugins/tracker/BattleTracker.java index 6c3fc29..071dd17 100644 --- a/src/main/java/org/battleplugins/tracker/BattleTracker.java +++ b/src/main/java/org/battleplugins/tracker/BattleTracker.java @@ -260,10 +260,24 @@ public void registerCalculator(RatingCalculator calculator) { this.ratingCalculators.put(calculator.getName(), calculator); } - void registerTracker(Tracker tracker) { + /** + * Registers a {@link Tracker}. + * + * @param tracker the tracker to register + */ + public void registerTracker(Tracker tracker) { this.trackers.put(tracker.getName(), tracker); } + /** + * Unregisters a {@link Tracker}. + * + * @param tracker the tracker to unregister + */ + public void unregisterTracker(Tracker tracker) { + this.trackers.remove(tracker.getName()); + } + /** * Registers a {@link Listener} to a {@link Tracker}. * diff --git a/src/main/java/org/battleplugins/tracker/feature/battlearena/ArenaTracker.java b/src/main/java/org/battleplugins/tracker/feature/battlearena/ArenaTracker.java index 7dccad7..17a2e99 100644 --- a/src/main/java/org/battleplugins/tracker/feature/battlearena/ArenaTracker.java +++ b/src/main/java/org/battleplugins/tracker/feature/battlearena/ArenaTracker.java @@ -26,6 +26,7 @@ protected TrackerSqlSerializer createSerializer() { StatType.MAX_STREAK, StatType.MAX_RANKING, StatType.RATING, StatType.MAX_RATING, StatType.MAX_KD_RATIO ); + return new TrackerSqlSerializer( this, generalStats, diff --git a/src/main/java/org/battleplugins/tracker/feature/battlearena/BattleArenaListener.java b/src/main/java/org/battleplugins/tracker/feature/battlearena/BattleArenaListener.java index 7d55550..cf7e485 100644 --- a/src/main/java/org/battleplugins/tracker/feature/battlearena/BattleArenaListener.java +++ b/src/main/java/org/battleplugins/tracker/feature/battlearena/BattleArenaListener.java @@ -1,10 +1,13 @@ package org.battleplugins.tracker.feature.battlearena; +import com.google.common.base.Supplier; import org.battleplugins.arena.Arena; import org.battleplugins.arena.ArenaPlayer; import org.battleplugins.arena.competition.JoinResult; import org.battleplugins.arena.competition.LiveCompetition; import org.battleplugins.arena.competition.phase.CompetitionPhaseType; +import org.battleplugins.arena.event.BattleArenaReloadEvent; +import org.battleplugins.arena.event.BattleArenaReloadedEvent; import org.battleplugins.arena.event.arena.ArenaCreateExecutorEvent; import org.battleplugins.arena.event.arena.ArenaDrawEvent; import org.battleplugins.arena.event.arena.ArenaInitializeEvent; @@ -14,10 +17,13 @@ import org.battleplugins.arena.event.player.ArenaPreJoinEvent; import org.battleplugins.arena.options.types.BooleanArenaOption; import org.battleplugins.tracker.BattleTracker; +import org.battleplugins.tracker.SqlTracker; import org.battleplugins.tracker.TrackedDataType; import org.battleplugins.tracker.Tracker; import org.battleplugins.tracker.stat.Record; import org.battleplugins.tracker.stat.StatType; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -34,10 +40,54 @@ public class BattleArenaListener implements Listener { private final BattleTracker battleTracker; private final Map> pendingExecutors = new HashMap<>(); + private boolean reloaded; + public BattleArenaListener(BattleTracker battleTracker) { this.battleTracker = battleTracker; } + @EventHandler + public void onBattleArenaReload(BattleArenaReloadEvent event) { + this.reloaded = true; + + for (Arena arena : event.getBattleArena().getArenas()) { + Tracker tracker = this.battleTracker.getTracker(arena.getName().toLowerCase(Locale.ROOT)); + if (tracker == null) { + continue; + } + + tracker.saveAll().whenComplete((aVoid, e) -> { + if (e != null) { + this.battleTracker.error("Failed to save tracker data for Arena: {}.", arena.getName()); + e.printStackTrace(); + } + + tracker.destroy(); + }); + + this.battleTracker.unregisterTracker(tracker); + } + } + + @EventHandler + public void onBattleArenaReloaded(BattleArenaReloadedEvent event) { + for (Arena arena : event.getBattleArena().getArenas()) { + Tracker tracker = this.battleTracker.getTracker(arena.getName().toLowerCase(Locale.ROOT)); + if (tracker == null) { + continue; + } + + // Ensure records are created for online players + for (Player player : Bukkit.getOnlinePlayers()) { + tracker.getOrCreateRecord((OfflinePlayer) player).whenComplete((record, e) -> { + if (tracker instanceof SqlTracker sqlTracker) { + sqlTracker.getRecords().lock(player.getUniqueId()); + } + }); + } + } + } + @EventHandler public void onArenaInitialize(ArenaInitializeEvent event) { Arena arena = event.getArena(); @@ -48,25 +98,33 @@ public void onArenaInitialize(ArenaInitializeEvent event) { } Consumer pendingExecutor = this.pendingExecutors.remove(arena); + Supplier supplier = () -> { + Tracker tracker = new ArenaTracker( + this.battleTracker, + arena.getName(), + this.battleTracker.getCalculator("elo"), + Set.of(TrackedDataType.PVP), + List.of() + ); + + if (pendingExecutor != null) { + pendingExecutor.accept(tracker); + } + + return tracker; + }; + this.battleTracker.registerTracker( event.getArena().getName().toLowerCase(Locale.ROOT), - () -> { - Tracker tracker = new ArenaTracker( - this.battleTracker, - arena.getName(), - this.battleTracker.getCalculator("elo"), - Set.of(TrackedDataType.PVP), - List.of() - ); - - if (pendingExecutor != null) { - pendingExecutor.accept(tracker); - } - - return tracker; - } + supplier ); + // This is kind of silly, but in the event that the plugin is reloaded, + // we want to ensure our tracker instance gets updated. + if (this.reloaded) { + this.battleTracker.registerTracker(supplier.get()); + } + this.battleTracker.info("Enabled tracking for arena: {}.", arena.getName()); } diff --git a/src/main/java/org/battleplugins/tracker/sql/SqlSerializer.java b/src/main/java/org/battleplugins/tracker/sql/SqlSerializer.java index c86f892..d1efde6 100644 --- a/src/main/java/org/battleplugins/tracker/sql/SqlSerializer.java +++ b/src/main/java/org/battleplugins/tracker/sql/SqlSerializer.java @@ -393,13 +393,13 @@ protected ResultSetConnection executeQuery(Connection con, boolean displayErrors protected void executeUpdate(boolean async, String strRawStmt, Object... varArgs) { if (async) { - new Thread(() -> { + CompletableFuture.runAsync(() -> { try { this.executeUpdate(strRawStmt, varArgs); } catch (Exception e) { e.printStackTrace(); } - }).start(); + }); } else { try { this.executeUpdate(strRawStmt, varArgs); @@ -433,17 +433,11 @@ protected int executeUpdate(String strRawStmt, Object... varArgs) { } protected CompletableFuture executeBatch(boolean async, String updateStatement, List> batch) { - CompletableFuture future = new CompletableFuture<>(); + CompletableFuture future; if (async) { - new Thread(() -> { - try { - this.executeBatch(updateStatement, batch); - future.complete(null); - } catch (Exception e) { - future.completeExceptionally(e); - } - }).start(); + future = CompletableFuture.runAsync(() -> this.executeBatch(updateStatement, batch)); } else { + future = new CompletableFuture<>(); try { this.executeBatch(updateStatement, batch); future.complete(null);