From 79b8c0cd87bae26181883f96877e8edf6666ce2b Mon Sep 17 00:00:00 2001 From: tastybento Date: Tue, 28 Jan 2020 17:11:23 -0800 Subject: [PATCH] Added saving of the warp sign cache to database. Relates to https://github.com/BentoBoxWorld/Warps/issues/68 --- .../{SignCache.java => SignCacheItem.java} | 8 +- .../bentobox/warps/SignCacheManager.java | 79 +++++++++++++++++++ src/main/java/world/bentobox/warps/Warp.java | 4 +- .../bentobox/warps/WarpPanelManager.java | 50 +++--------- .../bentobox/warps/WarpSignsManager.java | 10 +-- .../bentobox/warps/objects/SignCache.java | 54 +++++++++++++ .../bentobox/warps/WarpPanelManagerTest.java | 21 ++++- .../bentobox/warps/WarpSignsManagerTest.java | 7 +- 8 files changed, 179 insertions(+), 54 deletions(-) rename src/main/java/world/bentobox/warps/{SignCache.java => SignCacheItem.java} (77%) create mode 100644 src/main/java/world/bentobox/warps/SignCacheManager.java create mode 100644 src/main/java/world/bentobox/warps/objects/SignCache.java diff --git a/src/main/java/world/bentobox/warps/SignCache.java b/src/main/java/world/bentobox/warps/SignCacheItem.java similarity index 77% rename from src/main/java/world/bentobox/warps/SignCache.java rename to src/main/java/world/bentobox/warps/SignCacheItem.java index 33d0224..fb938bb 100644 --- a/src/main/java/world/bentobox/warps/SignCache.java +++ b/src/main/java/world/bentobox/warps/SignCacheItem.java @@ -4,19 +4,23 @@ import java.util.List; import org.bukkit.Material; +import com.google.gson.annotations.Expose; + /** * Stores info on a warp sign * @author tastybento * */ -public class SignCache { +public class SignCacheItem { + @Expose private final List signText; + @Expose private final Material type; /** * @param signText * @param type */ - public SignCache(List signText, Material type) { + public SignCacheItem(List signText, Material type) { this.signText = signText; this.type = type; } diff --git a/src/main/java/world/bentobox/warps/SignCacheManager.java b/src/main/java/world/bentobox/warps/SignCacheManager.java new file mode 100644 index 0000000..b0611f8 --- /dev/null +++ b/src/main/java/world/bentobox/warps/SignCacheManager.java @@ -0,0 +1,79 @@ +package world.bentobox.warps; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.World; + +import world.bentobox.bentobox.database.Database; +import world.bentobox.warps.objects.SignCache; + +public class SignCacheManager { + private Map> cachedSigns = new HashMap<>(); + private Warp addon; + // Database handler for level data + private Database handler; + + public SignCacheManager(Warp addon) { + this.addon = addon; + handler = new Database<>(addon, SignCache.class); + // Load the sign caches + loadCache(); + } + + private void loadCache() { + handler.loadObjects().forEach(w -> { + World world = Bukkit.getWorld(w.getUniqueId()); + if (world != null) { + cachedSigns.put(world, w.getSigns()); + } + }); + } + + void saveCache() { + cachedSigns.forEach((w, m) -> handler.saveObject(new SignCache(w, m))); + } + + Material getSignIcon(World world, UUID warpOwner) { + // Add the worlds if we haven't seen this before + cachedSigns.putIfAbsent(world, new HashMap<>()); + if (cachedSigns.get(world).containsKey(warpOwner)) { + return cachedSigns.get(world).get(warpOwner).getType(); + } + // Not in cache + SignCacheItem sc = addon.getWarpSignsManager().getSignInfo(world, warpOwner); + cachedSigns.get(world).put(warpOwner, sc); + return sc.getType(); + } + + /** + * Gets sign text and cache it + * @param playerUUID + * @return sign text in a list + */ + List getSign(World world, UUID playerUUID) { + // Add the worlds if we haven't seen this before + cachedSigns.putIfAbsent(world, new HashMap<>()); + if (cachedSigns.get(world).containsKey(playerUUID)) { + return cachedSigns.get(world).get(playerUUID).getSignText(); + } + SignCacheItem result = addon.getWarpSignsManager().getSignInfo(world, playerUUID); + cachedSigns.get(world).put(playerUUID, result); + return result.getSignText(); + } + + /** + * Removes sign text from the cache + * @param world - world + * @param key - uuid of owner + */ + void removeWarp(World world, UUID key) { + cachedSigns.putIfAbsent(world, new HashMap<>()); + cachedSigns.get(world).remove(key); + } + +} diff --git a/src/main/java/world/bentobox/warps/Warp.java b/src/main/java/world/bentobox/warps/Warp.java index 3e29cba..ff0a0c5 100644 --- a/src/main/java/world/bentobox/warps/Warp.java +++ b/src/main/java/world/bentobox/warps/Warp.java @@ -148,6 +148,8 @@ public class Warp extends Addon { // Save the warps if (warpSignsManager != null) warpSignsManager.saveWarpList(); + if (warpPanelManager != null) + warpPanelManager.saveCache(); } @@ -172,7 +174,7 @@ public class Warp extends Addon { /** * Get warp panel manager - * @return + * @return Warp Panel Manager */ public WarpPanelManager getWarpPanelManager() { return warpPanelManager; diff --git a/src/main/java/world/bentobox/warps/WarpPanelManager.java b/src/main/java/world/bentobox/warps/WarpPanelManager.java index ba3ed0a..95984c7 100644 --- a/src/main/java/world/bentobox/warps/WarpPanelManager.java +++ b/src/main/java/world/bentobox/warps/WarpPanelManager.java @@ -1,9 +1,7 @@ package world.bentobox.warps; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Random; import java.util.UUID; @@ -21,20 +19,19 @@ public class WarpPanelManager { private static final int PANEL_MAX_SIZE = 52; private Warp addon; // This is a cache of signs - private Map> cachedSigns = new HashMap<>(); - - + private SignCacheManager signCacheManager; public WarpPanelManager(Warp addon) { this.addon = addon; + signCacheManager = new SignCacheManager(addon); } private PanelItem getPanelItem(World world, UUID warpOwner) { PanelItemBuilder pib = new PanelItemBuilder() .name(addon.getSettings().getNameFormat() + addon.getPlugin().getPlayers().getName(warpOwner)) - .description(getSign(world, warpOwner)) + .description(signCacheManager.getSign(world, warpOwner)) .clickHandler((panel, clicker, click, slot) -> hander(world, clicker, warpOwner)); - Material icon = getSignIcon(world, warpOwner); + Material icon = signCacheManager.getSignIcon(world, warpOwner); if (icon.equals(Material.PLAYER_HEAD)) { return pib.icon(addon.getPlayers().getName(warpOwner)).build(); } else { @@ -59,35 +56,6 @@ public class WarpPanelManager { .icon(Material.END_CRYSTAL).build(); } - private Material getSignIcon(World world, UUID warpOwner) { - // Add the worlds if we haven't seen this before - cachedSigns.putIfAbsent(world, new HashMap<>()); - if (cachedSigns.get(world).containsKey(warpOwner)) { - return cachedSigns.get(world).get(warpOwner).getType(); - } - // Not in cache - SignCache sc = addon.getWarpSignsManager().getSignInfo(world, warpOwner); - cachedSigns.get(world).put(warpOwner, sc); - return sc.getType(); - } - - - /** - * Gets sign text and cache it - * @param playerUUID - * @return sign text in a list - */ - private List getSign(World world, UUID playerUUID) { - // Add the worlds if we haven't seen this before - cachedSigns.putIfAbsent(world, new HashMap<>()); - if (cachedSigns.get(world).containsKey(playerUUID)) { - return cachedSigns.get(world).get(playerUUID).getSignText(); - } - SignCache result = addon.getWarpSignsManager().getSignInfo(world, playerUUID); - cachedSigns.get(world).put(playerUUID, result); - return result.getSignText(); - } - /** * Show the warp panel for the user * @param world - world @@ -148,11 +116,15 @@ public class WarpPanelManager { /** * Removes sign text from the cache - * @param key + * @param world - world + * @param key - uuid of owner */ public void removeWarp(World world, UUID key) { - cachedSigns.putIfAbsent(world, new HashMap<>()); - cachedSigns.get(world).remove(key); + signCacheManager.removeWarp(world, key); + } + + public void saveCache() { + signCacheManager.saveCache(); } } diff --git a/src/main/java/world/bentobox/warps/WarpSignsManager.java b/src/main/java/world/bentobox/warps/WarpSignsManager.java index b3adb62..9fda886 100644 --- a/src/main/java/world/bentobox/warps/WarpSignsManager.java +++ b/src/main/java/world/bentobox/warps/WarpSignsManager.java @@ -74,7 +74,7 @@ public class WarpSignsManager { this.addon = addon; this.plugin = plugin; // Set up the database handler - // Note that these are saved by the BSkyBlock database + // Note that these are saved by the BentoBox database handler = new Database<>(addon, WarpsData.class); // Load the warps loadWarpList(); @@ -263,7 +263,7 @@ public class WarpSignsManager { * @return Sign's content and type */ @NonNull - public SignCache getSignInfo(@NonNull World world, @NonNull UUID uuid) { + public SignCacheItem getSignInfo(@NonNull World world, @NonNull UUID uuid) { List result = new ArrayList<>(); //get the sign info Location signLocation = getWarp(world, uuid); @@ -297,14 +297,14 @@ public class WarpSignsManager { } if (icon == null || icon.name().contains("SIGN")) { - return new SignCache(result, Material.valueOf(sign.getType().name().replace("WALL_", ""))); + return new SignCacheItem(result, Material.valueOf(sign.getType().name().replace("WALL_", ""))); } else { - return new SignCache(result, icon); + return new SignCacheItem(result, icon); } } else { addon.getWarpSignsManager().removeWarp(world, uuid); } - return new SignCache(Collections.emptyList(), Material.AIR); + return new SignCacheItem(Collections.emptyList(), Material.AIR); } /** diff --git a/src/main/java/world/bentobox/warps/objects/SignCache.java b/src/main/java/world/bentobox/warps/objects/SignCache.java new file mode 100644 index 0000000..042a1b2 --- /dev/null +++ b/src/main/java/world/bentobox/warps/objects/SignCache.java @@ -0,0 +1,54 @@ +package world.bentobox.warps.objects; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.bukkit.World; + +import com.google.gson.annotations.Expose; + +import world.bentobox.bentobox.database.objects.DataObject; +import world.bentobox.warps.SignCacheItem; + +public class SignCache implements DataObject { + + @Expose + private String uniqueId = ""; + @Expose + private Map signs = new HashMap<>(); + + public SignCache() { + // Required by YAML database + } + + public SignCache(World w, Map m) { + this.uniqueId = w.getName(); + this.signs = m; + } + + @Override + public String getUniqueId() { + return uniqueId; + } + + @Override + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + /** + * @return the signs + */ + public Map getSigns() { + return signs; + } + + /** + * @param signs the signs to set + */ + public void setSigns(Map signs) { + this.signs = signs; + } + +} diff --git a/src/test/java/world/bentobox/warps/WarpPanelManagerTest.java b/src/test/java/world/bentobox/warps/WarpPanelManagerTest.java index 3e3e584..0521627 100644 --- a/src/test/java/world/bentobox/warps/WarpPanelManagerTest.java +++ b/src/test/java/world/bentobox/warps/WarpPanelManagerTest.java @@ -24,6 +24,7 @@ import org.bukkit.inventory.ItemFactory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -37,6 +38,8 @@ import org.powermock.modules.junit4.PowerMockRunner; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.database.AbstractDatabaseHandler; +import world.bentobox.bentobox.database.DatabaseSetup; import world.bentobox.bentobox.managers.PlayersManager; import world.bentobox.warps.config.Settings; @@ -45,7 +48,7 @@ import world.bentobox.warps.config.Settings; * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({Bukkit.class}) +@PrepareForTest({Bukkit.class, DatabaseSetup.class}) public class WarpPanelManagerTest { @Mock @@ -63,6 +66,20 @@ public class WarpPanelManagerTest { private UUID uuid; @Mock private Settings settings; + @Mock + private static AbstractDatabaseHandler handler; + + @SuppressWarnings("unchecked") + @BeforeClass + public static void beforeClass() { + // This has to be done beforeClass otherwise the tests will interfere with each other + handler = mock(AbstractDatabaseHandler.class); + // Database + PowerMockito.mockStatic(DatabaseSetup.class); + DatabaseSetup dbSetup = mock(DatabaseSetup.class); + when(DatabaseSetup.getDatabase()).thenReturn(dbSetup); + when(dbSetup.getHandler(any())).thenReturn(handler); + } /** * @throws java.lang.Exception @@ -127,7 +144,7 @@ public class WarpPanelManagerTest { when(wsm.getWarp(any(), any())).thenReturn(location); // Sign cache - SignCache sc = mock(SignCache.class); + SignCacheItem sc = mock(SignCacheItem.class); when(sc.getSignText()).thenReturn(Collections.singletonList("[welcome]")); when(sc.getType()).thenReturn(sign_type); when(wsm.getSignInfo(any(), any())).thenReturn(sc); diff --git a/src/test/java/world/bentobox/warps/WarpSignsManagerTest.java b/src/test/java/world/bentobox/warps/WarpSignsManagerTest.java index 37c3456..2a6b290 100644 --- a/src/test/java/world/bentobox/warps/WarpSignsManagerTest.java +++ b/src/test/java/world/bentobox/warps/WarpSignsManagerTest.java @@ -211,10 +211,7 @@ public class WarpSignsManagerTest { // WarpPanelManager when(addon.getWarpPanelManager()).thenReturn(wpm); - - // User - - + wsm = new WarpSignsManager(addon, plugin); } @@ -417,7 +414,7 @@ public class WarpSignsManagerTest { */ @Test public void testGetSignInfo() { - SignCache sc = wsm.getSignInfo(world, uuid); + SignCacheItem sc = wsm.getSignInfo(world, uuid); assertEquals(Material.ACACIA_SIGN, sc.getType()); }