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 com.google.gson.annotations.Expose;
/**
* Stores info on a warp sign
* @author tastybento
*
*/
public class SignCache {
public class SignCacheItem {
@Expose
private final List<String> signText;
@Expose
private final Material type;
/**
* @param signText
* @param type
*/
public SignCache(List<String> signText, Material type) {
public SignCacheItem(List<String> signText, Material type) {
this.signText = signText;
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
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;

View File

@ -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<World, Map<UUID, SignCache>> 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<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
* @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();
}
}

View File

@ -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<String> 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);
}
/**

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.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<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
@ -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);

View File

@ -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());
}