tastybento 2021-01-09 15:33:27 -08:00
parent 82bd4c8b31
commit 7fbe4b5b88
8 changed files with 146 additions and 122 deletions

View File

@ -9,7 +9,6 @@ import org.bukkit.Material;
import org.bukkit.World;
import org.eclipse.jdt.annotation.NonNull;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.database.Database;
import world.bentobox.warps.objects.SignCache;
@ -27,6 +26,7 @@ public class SignCacheManager {
}
private void loadCache() {
cachedSigns.clear();
handler.loadObjects().forEach(w -> {
World world = Bukkit.getWorld(w.getUniqueId());
if (world != null) {
@ -57,12 +57,9 @@ public class SignCacheManager {
// Generate and add to cache
SignCacheItem result = addon.getWarpSignsManager().getSignInfo(world, warpOwner);
if (result.isReal()) {
BentoBox.getInstance().logDebug("Warp is real - caching");
cachedSigns.get(world).put(warpOwner, result);
} else {
BentoBox.getInstance().logDebug("Warp is not real - removing");
cachedSigns.get(world).remove(warpOwner);
addon.getWarpSignsManager().removeWarp(world, warpOwner);
}
return result;
}

View File

@ -104,7 +104,7 @@ public class Warp extends Addon {
this.warpSignsManager.saveWarpList();
this.loadSettings();
this.getLogger().info("WelcomeWarp addon reloaded.");
this.getLogger().info("Warps addon reloaded.");
}
}
@ -149,10 +149,9 @@ public class Warp extends Addon {
@Override
public void onDisable(){
// Save the warps
if (warpSignsManager != null)
if (warpSignsManager != null) {
warpSignsManager.saveWarpList();
if (warpPanelManager != null)
warpPanelManager.saveCache();
}
}

View File

@ -1,5 +1,6 @@
package world.bentobox.warps;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.UUID;
@ -10,7 +11,6 @@ import org.bukkit.World;
import org.bukkit.inventory.ItemStack;
import org.eclipse.jdt.annotation.NonNull;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
@ -52,7 +52,6 @@ public class WarpPanelManager {
}
private PanelItem getRandomButton(World world, User user, UUID warpOwner) {
///give @p minecraft:player_head{display:{Name:"{\"text\":\"Question Mark\"}"},SkullOwner:"MHF_Question"} 1
return new PanelItemBuilder()
.name(addon.getSettings().getNameFormat() + user.getTranslation("warps.random"))
.clickHandler((panel, clicker, click, slot) -> hander(world, clicker, warpOwner))
@ -82,40 +81,27 @@ public class WarpPanelManager {
void processSigns(CompletableFuture<Void> r, PanelBuilder panelBuilder, User user, int index, World world) {
addon.getWarpSignsManager().getSortedWarps(world).thenAccept(warps -> {
// Cache and clean the signs
Iterator<UUID> it = warps.iterator();
while(it.hasNext()) {
UUID warpOwner = it.next();
@NonNull
SignCacheItem sign = signCacheManager.getSignItem(world, warpOwner);
if (!sign.isReal()) {
it.remove();
addon.getWarpSignsManager().removeWarpFromMap(world, warpOwner);
}
}
// Add random warp
getRandomWarp(warps);
// Build the main body
int i = buildMainBody(panelBuilder, user, index, world, warps, getRandomWarp(warps));
int i = buildMainBody(panelBuilder, user, index, world, warps);
// Add navigation
addNavigation(panelBuilder, user, world, i, index, warps.size());
r.complete(null);
});
}
int buildMainBody(PanelBuilder panelBuilder, User user, int index, World world, List<UUID> warps, boolean randomWarp) {
if (index < 0) {
index = 0;
} else if (index > (warps.size() / PANEL_MAX_SIZE)) {
index = warps.size() / PANEL_MAX_SIZE;
}
int i = index * PANEL_MAX_SIZE;
for (; panelBuilder.getItems().size() < PANEL_MAX_SIZE && i < warps.size(); i++) {
UUID warpOwner = warps.get(i);
if (randomWarp && i == 0) {
panelBuilder.item(getRandomButton(world, user, warpOwner));
} else {
@NonNull
SignCacheItem sign = signCacheManager.getSignItem(world, warpOwner);
if (sign.isReal()) {
BentoBox.getInstance().logDebug("Sign is real - adding to panel");
panelBuilder.item(getPanelItem(world, warpOwner, sign));
} else {
BentoBox.getInstance().logDebug("Sign is not real - not adding to panel");
}
}
}
return i;
}
private boolean getRandomWarp(List<UUID> warps) {
// Add random warp
if (!warps.isEmpty() && addon.getSettings().isRandomAllowed()) {
@ -125,6 +111,31 @@ public class WarpPanelManager {
return false;
}
int buildMainBody(PanelBuilder panelBuilder, User user, int index, World world, List<UUID> warps) {
if (index < 0) {
index = 0;
} else if (index > (warps.size() / PANEL_MAX_SIZE)) {
index = warps.size() / PANEL_MAX_SIZE;
}
int i = index * PANEL_MAX_SIZE;
for (; panelBuilder.getItems().size() < PANEL_MAX_SIZE && i < warps.size(); i++) {
UUID warpOwner = warps.get(i);
if (addon.getSettings().isRandomAllowed() && i == 0) {
panelBuilder.item(getRandomButton(world, user, warpOwner));
} else {
@NonNull
SignCacheItem sign = signCacheManager.getSignItem(world, warpOwner);
if (sign.isReal()) {
panelBuilder.item(getPanelItem(world, warpOwner, sign));
} else {
addon.getWarpSignsManager().removeWarpFromMap(world, warpOwner);
}
}
}
return i;
}
/**
* Add Next and Previous icons to navigate
* @param panelBuilder - the panel builder
@ -135,18 +146,7 @@ public class WarpPanelManager {
* @param totalNum - total number of items in the list
*/
void addNavigation(PanelBuilder panelBuilder, User user, World world, int numOfItems, int panelNum, int totalNum) {
BentoBox.getInstance().logDebug("numOfItlems = " + numOfItems + " panel Num " + panelNum + " total Num " + totalNum);
if (numOfItems < totalNum) {
// Next
panelBuilder.item(new PanelItemBuilder()
.name(user.getTranslation("warps.next"))
.icon(new ItemStack(Material.STONE))
.clickHandler((panel, clicker, click, slot) -> {
user.closeInventory();
showWarpPanel(world, user, panelNum+1);
return true;
}).build());
}
// Previous
if (panelNum > 0 && numOfItems > PANEL_MAX_SIZE) {
// Previous
panelBuilder.item(new PanelItemBuilder()
@ -158,7 +158,18 @@ public class WarpPanelManager {
return true;
}).build());
}
// Next
if (numOfItems < totalNum) {
// Next
panelBuilder.item(new PanelItemBuilder()
.name(user.getTranslation("warps.next"))
.icon(new ItemStack(Material.STONE))
.clickHandler((panel, clicker, click, slot) -> {
user.closeInventory();
showWarpPanel(world, user, panelNum+1);
return true;
}).build());
}
}
/**

View File

@ -75,6 +75,7 @@ public class WarpSignsManager {
public WarpSignsManager(Warp addon, BentoBox plugin) {
this.addon = addon;
this.plugin = plugin;
this.worldsWarpList = new HashMap<>();
// Set up the database handler
// Note that these are saved by the BentoBox database
handler = new Database<>(addon, WarpsData.class);
@ -149,7 +150,7 @@ public class WarpSignsManager {
return r;
}
private void processWarpMap(CompletableFuture<List<UUID>> r, @NonNull World world) {
List<UUID> processWarpMap(CompletableFuture<List<UUID>> r, @NonNull World world) {
// Remove any null locations - this can happen if an admin changes the name of the world and signs point to old locations
getWarpMap(world).values().removeIf(Objects::isNull);
// Bigger value of time means a more recent login
@ -171,7 +172,7 @@ public class WarpSignsManager {
}
// Return to main thread
Bukkit.getScheduler().runTask(plugin, () -> r.complete(list));
return list;
}
/**
@ -270,6 +271,15 @@ public class WarpSignsManager {
saveWarpList();
}
/**
* Remove the warp from the warp map
* @param world - world
* @param uuid - uuid of owner
*/
public void removeWarpFromMap(World world, UUID uuid) {
getWarpMap(world).remove(uuid);
}
/**
* Saves the warp lists to the database
*/
@ -290,15 +300,9 @@ public class WarpSignsManager {
List<String> result = new ArrayList<>();
//get the sign info
Location signLocation = getWarp(world, uuid);
if (signLocation == null) {
plugin.logDebug("Null warp found");
if (signLocation == null || !signLocation.getBlock().getType().name().contains("SIGN")) {
return new SignCacheItem();
}
if (!signLocation.getBlock().getType().name().contains("SIGN")) {
plugin.logDebug("Sign block is not");
return new SignCacheItem();
}
plugin.logDebug("Sign block is a sign");
Sign sign = (Sign)signLocation.getBlock().getState();
result.addAll(Arrays.asList(sign.getLines()));
// Clean up - remove the [WELCOME] line

View File

@ -4,9 +4,9 @@ import java.util.List;
import org.bukkit.World;
import world.bentobox.warps.Warp;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.warps.Warp;
/**
* Handles the warps command

View File

@ -50,6 +50,7 @@ public class WarpsData implements DataObject {
* @return this class filled with data
*/
public WarpsData save(Map<World, Map<UUID, Location>> worldsWarpList) {
getWarpSigns().clear();
worldsWarpList.values().forEach(world -> world.forEach((uuid,location) -> warpSigns.put(location, uuid)));
return this;
}

View File

@ -15,6 +15,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -105,7 +106,7 @@ public class WarpPanelManagerTest {
uuid = UUID.randomUUID();
list.add(uuid);
when(wsm.getSortedWarps(any())).thenReturn(list);
when(wsm.getSortedWarps(any())).thenReturn(CompletableFuture.completedFuture(list));
// User and player
when(user.getPlayer()).thenReturn(player);
@ -142,21 +143,20 @@ public class WarpPanelManagerTest {
Location location = mock(Location.class);
Block block = mock(Block.class);
Material sign_type;
Material signType;
try {
sign_type = Material.valueOf("SIGN");
signType = Material.valueOf("SIGN");
} catch (Exception e) {
sign_type = Material.valueOf("OAK_SIGN");
signType = Material.valueOf("OAK_SIGN");
}
when(block.getType()).thenReturn(sign_type);
when(block.getType()).thenReturn(signType);
when(location.getBlock()).thenReturn(block);
// Sign block
when(wsm.getWarp(any(), any())).thenReturn(location);
// Sign cache
SignCacheItem sc = mock(SignCacheItem.class);
when(sc.getSignText()).thenReturn(Collections.singletonList("[welcome]"));
when(sc.getType()).thenReturn(sign_type);
SignCacheItem sc = new SignCacheItem(Collections.singletonList("[welcome]"), signType);
when(wsm.getSignInfo(any(), any())).thenReturn(sc);
// Class under test
@ -164,18 +164,17 @@ public class WarpPanelManagerTest {
}
/**
* Test method for {@link WarpPanelManager#showWarpPanel(org.bukkit.World, world.bentobox.bbox.api.user.User, int)}.
* Test method for {@link WarpPanelManager#processSigns(CompletableFuture, PanelBuilder, User, int, World)}.
*/
@Test
public void testShowWarpPanelTestCache() {
PanelBuilder pb = mock(PanelBuilder.class);
// Do 45 initial lookups of sign text
wpm.buildPanel(pb, user, 3, world);
// Do initial lookups of sign text
wpm.processSigns(new CompletableFuture<>(), pb, user, 3, world);
// Get the panel again
wpm.buildPanel(pb, user, 3, world);
// Should only check this 45 times because the sign text is cached
verify(wsm, times(45)).getSignInfo(any(), any());
wpm.processSigns(new CompletableFuture<>(), pb, user, 3, world);
// Should only check this 201 times in total because the sign text is cached
verify(wsm, times(201)).getSignInfo(any(), any());
}
@ -194,8 +193,8 @@ public class WarpPanelManagerTest {
public void testBuildPanel() {
PanelBuilder pb = mock(PanelBuilder.class);
wpm.buildPanel(pb, user, 3, world);
// Removing the UUID should force a refresh and therefore 46 lookups
verify(wsm, times(45)).getSignInfo(any(), any());
// Removing the UUID should force a refresh and therefore 201 lookups
verify(wsm, times(201)).getSignInfo(any(), any());
}
@ -245,8 +244,9 @@ public class WarpPanelManagerTest {
private int mainBod(int page, int j, boolean random) {
when(settings.isRandomAllowed()).thenReturn(random);
PanelBuilder pb = mock(PanelBuilder.class);
int r = wpm.buildMainBody(pb, user, page, world, list, random);
int r = wpm.buildMainBody(pb, user, page, world, list);
verify(pb, times(j)).item(any());
if (random && page <= 0) {
verify(user).getTranslation(eq("warps.random"));
@ -261,7 +261,7 @@ public class WarpPanelManagerTest {
*/
@Test
public void testBuildMainBodyNoRandomPage0() {
assertEquals(52, mainBod(0, 52, false));
assertEquals(201, mainBod(0, 201, false));
}
/**
@ -269,7 +269,7 @@ public class WarpPanelManagerTest {
*/
@Test
public void testBuildMainBodyNoRandomPage1() {
assertEquals(104, mainBod(1, 52, false));
assertEquals(201, mainBod(1, 149, false));
}
/**
@ -277,7 +277,7 @@ public class WarpPanelManagerTest {
*/
@Test
public void testBuildMainBodyNoRandomPage2() {
assertEquals(156, mainBod(2, 52, false));
assertEquals(201, mainBod(2, 97, false));
}
/**
@ -293,7 +293,7 @@ public class WarpPanelManagerTest {
*/
@Test
public void testBuildMainBodyNoRandomPageMinus1() {
assertEquals(52, mainBod(-1, 52, false));
assertEquals(201, mainBod(-1, 201, false));
}
/**
@ -301,7 +301,7 @@ public class WarpPanelManagerTest {
*/
@Test
public void testBuildMainBodyRandomPage0() {
assertEquals(52, mainBod(0, 52, true));
assertEquals(201, mainBod(0, 201, true));
}
/**
@ -309,7 +309,7 @@ public class WarpPanelManagerTest {
*/
@Test
public void testBuildMainBodyRandomPage1() {
assertEquals(104, mainBod(1, 52, true));
assertEquals(201, mainBod(1, 149, true));
}
/**
@ -317,7 +317,7 @@ public class WarpPanelManagerTest {
*/
@Test
public void testBuildMainBodyRandomPage2() {
assertEquals(156, mainBod(2, 52, true));
assertEquals(201, mainBod(2, 97, true));
}
/**
@ -333,6 +333,6 @@ public class WarpPanelManagerTest {
*/
@Test
public void testBuildMainBodyRandomPageMinus1() {
assertEquals(52, mainBod(-1, 52, true));
assertEquals(201, mainBod(-1, 201, true));
}
}

View File

@ -16,11 +16,20 @@ import static org.mockito.Mockito.when;
import java.beans.IntrospectionException;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.logging.Logger;
import org.bukkit.*;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
@ -74,7 +83,7 @@ public class WarpSignsManagerTest {
@Mock
private static AbstractDatabaseHandler<Object> handler;
private WarpSignsManager wsm;
@Mock
private Logger logger;
@ -106,7 +115,7 @@ public class WarpSignsManagerTest {
@Mock
private Island island;
@SuppressWarnings("unchecked")
@BeforeClass
public static void beforeClass() {
@ -118,7 +127,7 @@ public class WarpSignsManagerTest {
when(DatabaseSetup.getDatabase()).thenReturn(dbSetup);
when(dbSetup.getHandler(any())).thenReturn(handler);
}
/**
* @throws java.lang.Exception
*/
@ -127,12 +136,12 @@ public class WarpSignsManagerTest {
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
when(addon.getPlugin()).thenReturn(plugin);
when(addon.getLogger()).thenReturn(logger);
// Player
when(player.getUniqueId()).thenReturn(uuid);
User.setPlugin(plugin);
User.getInstance(player);
// Locales
LocalesManager lm = mock(LocalesManager.class);
when(lm.get(Mockito.any(), Mockito.any())).thenReturn(null);
@ -142,16 +151,16 @@ public class WarpSignsManagerTest {
when(phm.replacePlaceholders(any(), anyString())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(1, String.class));
when(plugin.getPlaceholdersManager()).thenReturn(phm);
// Server
when(addon.getServer()).thenReturn(server);
when(server.getPlayer(any(UUID.class))).thenReturn(player);
// Util
PowerMockito.mockStatic(Util.class);
when(Util.getWorld(any())).thenAnswer((Answer<World>) invocation -> invocation.getArgument(0, World.class));
when(Util.sameWorld(any(), any())).thenReturn(true);
// Location
when(location.getWorld()).thenReturn(world);
when(location.getBlock()).thenReturn(block);
@ -174,27 +183,27 @@ public class WarpSignsManagerTest {
when(signBd.getRotation()).thenReturn(BlockFace.EAST);
when(block.getBlockData()).thenReturn(signBd);
when(block.getRelative(any())).thenReturn(block);
// Handler
when(handler.objectExists(eq("warps"))).thenReturn(true);
Map<Location, UUID> warpMap = Collections.singletonMap(location, uuid);
when(load.getWarpSigns()).thenReturn(warpMap);
when(handler.loadObject(anyString())).thenReturn(load);
// Settings
when(addon.getSettings()).thenReturn(settings);
when(settings.getWelcomeLine()).thenReturn("[Welcome]");
when(settings.getLoreFormat()).thenReturn("&f");
when(settings.getIcon()).thenReturn("SIGN");
// Bukkit
PowerMockito.mockStatic(Bukkit.class);
// Bukkit
PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
when(Bukkit.getPluginManager()).thenReturn(pim);
// Players Manager
when(plugin.getPlayers()).thenReturn(pm);
when(pm.getName(eq(uuid))).thenReturn("tastybento");
// Offline player
when(server.getOfflinePlayer(any(UUID.class))).thenReturn(offlinePlayer);
when(offlinePlayer.getLastPlayed()).thenReturn(System.currentTimeMillis());
@ -202,15 +211,15 @@ public class WarpSignsManagerTest {
// IWM
when(plugin.getIWM()).thenReturn(iwm);
when(iwm.getPermissionPrefix(any())).thenReturn("bskyblock.");
// Island Manager
when(addon.getIslands()).thenReturn(im);
when(im.getIsland(any(), any(UUID.class))).thenReturn(island);
when(im.isSafeLocation(any())).thenReturn(true);
// WarpPanelManager
when(addon.getWarpPanelManager()).thenReturn(wpm);
wsm = new WarpSignsManager(addon, plugin);
}
@ -260,10 +269,10 @@ public class WarpSignsManagerTest {
wsm = new WarpSignsManager(addon, plugin);
assertTrue("Map is not empty", wsm.getWarpMap(world).isEmpty());
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#getWarpMap(org.bukkit.World)}.
* @throws Exception
* @throws Exception
*/
@Test
public void testGetWarpMapNullDatabaseObject() throws Exception {
@ -271,7 +280,7 @@ public class WarpSignsManagerTest {
wsm = new WarpSignsManager(addon, plugin);
assertTrue("Map is not empty", wsm.getWarpMap(world).isEmpty());
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#getWarpMap(org.bukkit.World)}.
*/
@ -281,10 +290,10 @@ public class WarpSignsManagerTest {
wsm = new WarpSignsManager(addon, plugin);
assertTrue("Map is not empty", wsm.getWarpMap(world).isEmpty());
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#WarpSignsManager(world.bentobox.warps.Warp, world.bentobox.bentobox.BentoBox)}.
* @throws Exception
* @throws Exception
*/
@Test
public void testWarpSignsManager() throws Exception {
@ -300,7 +309,7 @@ public class WarpSignsManagerTest {
public void testAddWarpNullPlayer() {
assertFalse(wsm.addWarp(null, null));
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#addWarp(java.util.UUID, org.bukkit.Location)}.
*/
@ -308,7 +317,7 @@ public class WarpSignsManagerTest {
public void testAddWarpNullLocation() {
assertFalse(wsm.addWarp(uuid, null));
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#addWarp(java.util.UUID, org.bukkit.Location)}.
*/
@ -317,7 +326,7 @@ public class WarpSignsManagerTest {
assertTrue(wsm.addWarp(uuid, location));
verify(player).sendMessage("warps.sign-removed");
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#addWarp(java.util.UUID, org.bukkit.Location)}.
*/
@ -326,7 +335,7 @@ public class WarpSignsManagerTest {
assertTrue(wsm.addWarp(UUID.randomUUID(), location));
verify(player).sendMessage("warps.sign-removed");
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#addWarp(java.util.UUID, org.bukkit.Location)}.
*/
@ -358,15 +367,18 @@ public class WarpSignsManagerTest {
*/
@Test
public void testGetWarpOwner() {
assertEquals("tastybento", wsm.getWarpOwner(location));
assertEquals("tastybento", wsm.getWarpOwner(location));
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#getSortedWarps(org.bukkit.World)}.
* @throws ExecutionException
* @throws InterruptedException
*/
@Test
public void testGetSortedWarps() {
assertEquals(1, wsm.getSortedWarps(world).size());
public void testGetSortedWarps() throws InterruptedException, ExecutionException {
CompletableFuture<List<UUID>> r = new CompletableFuture<>();
assertEquals(1, wsm.processWarpMap(r, world).size());
}
/**
@ -398,9 +410,9 @@ public class WarpSignsManagerTest {
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#saveWarpList()}.
* @throws IntrospectionException
* @throws InvocationTargetException
* @throws Exception
* @throws IntrospectionException
* @throws InvocationTargetException
* @throws Exception
*/
@Test
public void testSaveWarpList() throws Exception {
@ -458,10 +470,10 @@ public class WarpSignsManagerTest {
verify(addon, times(2)).log(eq("Loading warps..."));
assertTrue(wsm.getWarpMap(world).isEmpty());
}
/**
* Test method for {@link world.bentobox.warps.WarpSignsManager#loadWarpList()}.
* @throws Exception
* @throws Exception
*/
@Test
public void testLoadWarpListEmptyWarpTable() throws Exception {