1
0
mirror of https://github.com/BentoBoxWorld/Warps.git synced 2024-11-22 10:35:52 +01:00

Added saving of the warp sign cache to database.

Relates to https://github.com/BentoBoxWorld/Warps/issues/68
This commit is contained in:
tastybento 2020-01-28 17:11:23 -08:00
parent ef523d4332
commit 79b8c0cd87
8 changed files with 179 additions and 54 deletions

View File

@ -4,19 +4,23 @@ import java.util.List;
import org.bukkit.Material; import org.bukkit.Material;
import com.google.gson.annotations.Expose;
/** /**
* Stores info on a warp sign * Stores info on a warp sign
* @author tastybento * @author tastybento
* *
*/ */
public class SignCache { public class SignCacheItem {
@Expose
private final List<String> signText; private final List<String> signText;
@Expose
private final Material type; private final Material type;
/** /**
* @param signText * @param signText
* @param type * @param type
*/ */
public SignCache(List<String> signText, Material type) { public SignCacheItem(List<String> signText, Material type) {
this.signText = signText; this.signText = signText;
this.type = type; this.type = type;
} }

View File

@ -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<World, Map<UUID, SignCacheItem>> cachedSigns = new HashMap<>();
private Warp addon;
// Database handler for level data
private Database<SignCache> 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<String> 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);
}
}

View File

@ -148,6 +148,8 @@ public class Warp extends Addon {
// Save the warps // Save the warps
if (warpSignsManager != null) if (warpSignsManager != null)
warpSignsManager.saveWarpList(); warpSignsManager.saveWarpList();
if (warpPanelManager != null)
warpPanelManager.saveCache();
} }
@ -172,7 +174,7 @@ public class Warp extends Addon {
/** /**
* Get warp panel manager * Get warp panel manager
* @return * @return Warp Panel Manager
*/ */
public WarpPanelManager getWarpPanelManager() { public WarpPanelManager getWarpPanelManager() {
return warpPanelManager; return warpPanelManager;

View File

@ -1,9 +1,7 @@
package world.bentobox.warps; package world.bentobox.warps;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.UUID; import java.util.UUID;
@ -21,20 +19,19 @@ public class WarpPanelManager {
private static final int PANEL_MAX_SIZE = 52; private static final int PANEL_MAX_SIZE = 52;
private Warp addon; private Warp addon;
// This is a cache of signs // This is a cache of signs
private Map<World, Map<UUID, SignCache>> cachedSigns = new HashMap<>(); private SignCacheManager signCacheManager;
public WarpPanelManager(Warp addon) { public WarpPanelManager(Warp addon) {
this.addon = addon; this.addon = addon;
signCacheManager = new SignCacheManager(addon);
} }
private PanelItem getPanelItem(World world, UUID warpOwner) { private PanelItem getPanelItem(World world, UUID warpOwner) {
PanelItemBuilder pib = new PanelItemBuilder() PanelItemBuilder pib = new PanelItemBuilder()
.name(addon.getSettings().getNameFormat() + addon.getPlugin().getPlayers().getName(warpOwner)) .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)); .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)) { if (icon.equals(Material.PLAYER_HEAD)) {
return pib.icon(addon.getPlayers().getName(warpOwner)).build(); return pib.icon(addon.getPlayers().getName(warpOwner)).build();
} else { } else {
@ -59,35 +56,6 @@ public class WarpPanelManager {
.icon(Material.END_CRYSTAL).build(); .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<String> 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 * Show the warp panel for the user
* @param world - world * @param world - world
@ -148,11 +116,15 @@ public class WarpPanelManager {
/** /**
* Removes sign text from the cache * Removes sign text from the cache
* @param key * @param world - world
* @param key - uuid of owner
*/ */
public void removeWarp(World world, UUID key) { public void removeWarp(World world, UUID key) {
cachedSigns.putIfAbsent(world, new HashMap<>()); signCacheManager.removeWarp(world, key);
cachedSigns.get(world).remove(key); }
public void saveCache() {
signCacheManager.saveCache();
} }
} }

View File

@ -74,7 +74,7 @@ public class WarpSignsManager {
this.addon = addon; this.addon = addon;
this.plugin = plugin; this.plugin = plugin;
// Set up the database handler // 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); handler = new Database<>(addon, WarpsData.class);
// Load the warps // Load the warps
loadWarpList(); loadWarpList();
@ -263,7 +263,7 @@ public class WarpSignsManager {
* @return Sign's content and type * @return Sign's content and type
*/ */
@NonNull @NonNull
public SignCache getSignInfo(@NonNull World world, @NonNull UUID uuid) { public SignCacheItem getSignInfo(@NonNull World world, @NonNull UUID uuid) {
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();
//get the sign info //get the sign info
Location signLocation = getWarp(world, uuid); Location signLocation = getWarp(world, uuid);
@ -297,14 +297,14 @@ public class WarpSignsManager {
} }
if (icon == null || icon.name().contains("SIGN")) { 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 { } else {
return new SignCache(result, icon); return new SignCacheItem(result, icon);
} }
} else { } else {
addon.getWarpSignsManager().removeWarp(world, uuid); addon.getWarpSignsManager().removeWarp(world, uuid);
} }
return new SignCache(Collections.emptyList(), Material.AIR); return new SignCacheItem(Collections.emptyList(), Material.AIR);
} }
/** /**

View File

@ -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<UUID, SignCacheItem> signs = new HashMap<>();
public SignCache() {
// Required by YAML database
}
public SignCache(World w, Map<UUID, SignCacheItem> 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<UUID, SignCacheItem> getSigns() {
return signs;
}
/**
* @param signs the signs to set
*/
public void setSigns(Map<UUID, SignCacheItem> signs) {
this.signs = signs;
}
}

View File

@ -24,6 +24,7 @@ import org.bukkit.inventory.ItemFactory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
@ -37,6 +38,8 @@ import org.powermock.modules.junit4.PowerMockRunner;
import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.user.User; 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.bentobox.managers.PlayersManager;
import world.bentobox.warps.config.Settings; import world.bentobox.warps.config.Settings;
@ -45,7 +48,7 @@ import world.bentobox.warps.config.Settings;
* *
*/ */
@RunWith(PowerMockRunner.class) @RunWith(PowerMockRunner.class)
@PrepareForTest({Bukkit.class}) @PrepareForTest({Bukkit.class, DatabaseSetup.class})
public class WarpPanelManagerTest { public class WarpPanelManagerTest {
@Mock @Mock
@ -63,6 +66,20 @@ public class WarpPanelManagerTest {
private UUID uuid; private UUID uuid;
@Mock @Mock
private Settings settings; private Settings settings;
@Mock
private static AbstractDatabaseHandler<Object> 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 * @throws java.lang.Exception
@ -127,7 +144,7 @@ public class WarpPanelManagerTest {
when(wsm.getWarp(any(), any())).thenReturn(location); when(wsm.getWarp(any(), any())).thenReturn(location);
// Sign cache // Sign cache
SignCache sc = mock(SignCache.class); SignCacheItem sc = mock(SignCacheItem.class);
when(sc.getSignText()).thenReturn(Collections.singletonList("[welcome]")); when(sc.getSignText()).thenReturn(Collections.singletonList("[welcome]"));
when(sc.getType()).thenReturn(sign_type); when(sc.getType()).thenReturn(sign_type);
when(wsm.getSignInfo(any(), any())).thenReturn(sc); when(wsm.getSignInfo(any(), any())).thenReturn(sc);

View File

@ -212,9 +212,6 @@ public class WarpSignsManagerTest {
// WarpPanelManager // WarpPanelManager
when(addon.getWarpPanelManager()).thenReturn(wpm); when(addon.getWarpPanelManager()).thenReturn(wpm);
// User
wsm = new WarpSignsManager(addon, plugin); wsm = new WarpSignsManager(addon, plugin);
} }
@ -417,7 +414,7 @@ public class WarpSignsManagerTest {
*/ */
@Test @Test
public void testGetSignInfo() { public void testGetSignInfo() {
SignCache sc = wsm.getSignInfo(world, uuid); SignCacheItem sc = wsm.getSignInfo(world, uuid);
assertEquals(Material.ACACIA_SIGN, sc.getType()); assertEquals(Material.ACACIA_SIGN, sc.getType());
} }