diff --git a/pom.xml b/pom.xml index b0a85b4..39e5e60 100644 --- a/pom.xml +++ b/pom.xml @@ -66,7 +66,7 @@ -LOCAL - 1.14.0 + 1.14.1 BentoBoxWorld_addon-invSwitcher bentobox-world diff --git a/src/main/java/com/wasteofplastic/invswitcher/InvSwitcher.java b/src/main/java/com/wasteofplastic/invswitcher/InvSwitcher.java index c5f279a..8efe01e 100644 --- a/src/main/java/com/wasteofplastic/invswitcher/InvSwitcher.java +++ b/src/main/java/com/wasteofplastic/invswitcher/InvSwitcher.java @@ -1,12 +1,15 @@ package com.wasteofplastic.invswitcher; +import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; import org.bukkit.Bukkit; +import org.bukkit.Material; import org.bukkit.World; import com.wasteofplastic.invswitcher.listeners.PlayerListener; @@ -23,6 +26,9 @@ */ public class InvSwitcher extends Addon { + protected static final List MAT = Arrays.stream(Material.values()) + .filter(m -> !m.name().startsWith("LEGACY")).toList(); + private Store store; private Settings settings; @@ -90,7 +96,7 @@ public void onEnable() { public void onDisable() { // save cache if (store != null) { - getStore().saveOnlinePlayers(); + getStore().saveOnShutdown(); } } diff --git a/src/main/java/com/wasteofplastic/invswitcher/Store.java b/src/main/java/com/wasteofplastic/invswitcher/Store.java index 9c54365..255551f 100644 --- a/src/main/java/com/wasteofplastic/invswitcher/Store.java +++ b/src/main/java/com/wasteofplastic/invswitcher/Store.java @@ -57,7 +57,6 @@ * */ public class Store { - private static final Material[] MAT = Material.values(); private static final CharSequence THE_END = "_the_end"; private static final CharSequence NETHER = "_nether"; private final Database database; @@ -198,7 +197,7 @@ private InventoryStorage getInv(Player player) { * @param world - the world that is associated with these items/elements */ public void storeInventory(Player player, World world) { - storeAndSave(player, world); + storeAndSave(player, world, false); clearPlayer(player); // Done! } @@ -207,8 +206,9 @@ public void storeInventory(Player player, World world) { * Store and save the player to the database * @param player - player * @param world - world to save + * @param shutdown - true if this is a shutdown save */ - public void storeAndSave(Player player, World world) { + public void storeAndSave(Player player, World world, boolean shutdown) { // Get the player's store InventoryStorage store = getInv(player); // Do not differentiate between world environments @@ -249,57 +249,66 @@ public void storeAndSave(Player player, World world) { store.setEnderChest(overworldName, contents); } if (addon.getSettings().isStatistics()) { - saveStats(store, player, overworldName).thenAccept(database::saveObjectAsync); + saveStats(store, player, overworldName, shutdown).thenAccept(database::saveObjectAsync); return; } database.saveObjectAsync(store); } - private CompletableFuture saveStats(InventoryStorage store, Player player, String worldName) { + private CompletableFuture saveStats(InventoryStorage store, Player player, String worldName, + boolean shutdown) { CompletableFuture result = new CompletableFuture<>(); store.clearStats(worldName); + // Statistics - Bukkit.getScheduler().runTaskAsynchronously(addon.getPlugin(), () -> { - Arrays.stream(Statistic.values()).forEach(s -> { - Map map; - Map entMap; - switch (s.getType()) { - case BLOCK -> { - map = Arrays.stream(MAT).filter(Material::isBlock).filter(m -> !m.isLegacy()) - .filter(m -> player.getStatistic(s, m) > 0) - .collect(Collectors.toMap(k -> k, v -> player.getStatistic(s, v))); - if (!map.isEmpty()) { - store.getBlockStats(worldName).put(s, map); - } - } - case ITEM -> { - map = Arrays.stream(MAT).filter(Material::isItem).filter(m -> !m.isLegacy()) - .filter(m -> player.getStatistic(s, m) > 0) - .collect(Collectors.toMap(k -> k, v -> player.getStatistic(s, v))); - if (!map.isEmpty()) { - store.getItemStats(worldName).put(s, map); - } + if (shutdown) { + saveStatistics(result, store, player, worldName); + } else { + // Cannot schedule tasks on shutdown + Bukkit.getScheduler().runTaskAsynchronously(addon.getPlugin(), + () -> saveStatistics(result, store, player, worldName)); + } + return result; + + } + + private void saveStatistics(CompletableFuture result, InventoryStorage store, Player player, + String worldName) { + Arrays.stream(Statistic.values()).forEach(s -> { + Map map; + Map entMap; + switch (s.getType()) { + case BLOCK -> { + map = InvSwitcher.MAT.stream().filter(Material::isBlock).filter(m -> player.getStatistic(s, m) > 0) + .collect(Collectors.toMap(k -> k, v -> player.getStatistic(s, v))); + if (!map.isEmpty()) { + store.getBlockStats(worldName).put(s, map); } - case ENTITY -> { - entMap = Arrays.stream(EntityType.values()).filter(EntityType::isAlive) - .filter(m -> player.getStatistic(s, m) > 0) - .collect(Collectors.toMap(k -> k, v -> player.getStatistic(s, v))); - if (!entMap.isEmpty()) { - store.getEntityStats(worldName).put(s, entMap); - } + } + case ITEM -> { + map = InvSwitcher.MAT.stream().filter(Material::isItem).filter(m -> player.getStatistic(s, m) > 0) + .collect(Collectors.toMap(k -> k, v -> player.getStatistic(s, v))); + if (!map.isEmpty()) { + store.getItemStats(worldName).put(s, map); } - case UNTYPED -> { - int sc = player.getStatistic(s); - if (sc > 0) { - store.getUntypedStats(worldName).put(s, sc); - } + } + case ENTITY -> { + entMap = Arrays.stream(EntityType.values()).filter(EntityType::isAlive) + .filter(m -> player.getStatistic(s, m) > 0) + .collect(Collectors.toMap(k -> k, v -> player.getStatistic(s, v))); + if (!entMap.isEmpty()) { + store.getEntityStats(worldName).put(s, entMap); } + } + case UNTYPED -> { + int sc = player.getStatistic(s); + if (sc > 0) { + store.getUntypedStats(worldName).put(s, sc); } - }); - result.complete(store); + } + } }); - return result; - + result.complete(store); } /** @@ -461,7 +470,7 @@ private static void setTotalExperience(final Player player, final int exp) /** * Save all online players */ - public void saveOnlinePlayers() { - Bukkit.getOnlinePlayers().forEach(p -> this.storeAndSave(p, p.getWorld())); + public void saveOnShutdown() { + Bukkit.getOnlinePlayers().forEach(p -> this.storeAndSave(p, p.getWorld(), true)); } } diff --git a/src/main/java/com/wasteofplastic/invswitcher/listeners/PlayerListener.java b/src/main/java/com/wasteofplastic/invswitcher/listeners/PlayerListener.java index beccd52..2574209 100644 --- a/src/main/java/com/wasteofplastic/invswitcher/listeners/PlayerListener.java +++ b/src/main/java/com/wasteofplastic/invswitcher/listeners/PlayerListener.java @@ -71,7 +71,7 @@ public void onPlayerJoin(final PlayerJoinEvent event) { @EventHandler(priority = EventPriority.LOW, ignoreCancelled=true) public void onPlayerQuit(final PlayerQuitEvent event) { if (addon.getWorlds().contains(event.getPlayer().getWorld())) { - addon.getStore().storeAndSave(event.getPlayer(), event.getPlayer().getWorld()); + addon.getStore().storeAndSave(event.getPlayer(), event.getPlayer().getWorld(), false); } addon.getStore().removeFromCache(event.getPlayer()); } diff --git a/src/test/java/com/wasteofplastic/invswitcher/StoreTest.java b/src/test/java/com/wasteofplastic/invswitcher/StoreTest.java index 24b87f7..af2f4a1 100644 --- a/src/test/java/com/wasteofplastic/invswitcher/StoreTest.java +++ b/src/test/java/com/wasteofplastic/invswitcher/StoreTest.java @@ -262,14 +262,14 @@ public void testStoreInventoryAll() { } /** - * Test method for {@link com.wasteofplastic.invswitcher.Store#saveOnlinePlayers()}. + * Test method for {@link com.wasteofplastic.invswitcher.Store#saveOnShutdown()}. */ @Test public void testSaveOnlinePlayers() { // Mock the static method try (MockedStatic mockedBukkit = mockStatic(Bukkit.class)) { // Run the code under test - s.saveOnlinePlayers(); + s.saveOnShutdown(); // Verify that the static method was called mockedBukkit.verify(() -> Bukkit.getOnlinePlayers()); diff --git a/src/test/java/com/wasteofplastic/invswitcher/listeners/PlayerListenerTest.java b/src/test/java/com/wasteofplastic/invswitcher/listeners/PlayerListenerTest.java index 901a30f..36c67ea 100644 --- a/src/test/java/com/wasteofplastic/invswitcher/listeners/PlayerListenerTest.java +++ b/src/test/java/com/wasteofplastic/invswitcher/listeners/PlayerListenerTest.java @@ -141,7 +141,7 @@ public void testOnPlayerJoinWithStorage() { public void testOnPlayerQuit() { PlayerQuitEvent event = new PlayerQuitEvent(player, ""); pl.onPlayerQuit(event); - verify(store).storeAndSave(player, world); + verify(store).storeAndSave(player, world, false); verify(store).removeFromCache(player); } @@ -153,7 +153,7 @@ public void testOnPlayerQuitNotCoveredWorld() { when(player.getWorld()).thenReturn(notWorld); PlayerQuitEvent event = new PlayerQuitEvent(player, ""); pl.onPlayerQuit(event); - verify(store, never()).storeAndSave(player, world); + verify(store, never()).storeAndSave(player, world, false); verify(store).removeFromCache(player); }