More work on multi island. Fixed tests so clean compile.
This commit is contained in:
parent
3fdbb014c7
commit
6cae448efb
2
pom.xml
2
pom.xml
|
@ -88,7 +88,7 @@
|
|||
<!-- Do not change unless you want different name for local builds. -->
|
||||
<build.number>-LOCAL</build.number>
|
||||
<!-- This allows to change between versions. -->
|
||||
<build.version>1.24.2</build.version>
|
||||
<build.version>2.0.0</build.version>
|
||||
<sonar.organization>bentobox-world</sonar.organization>
|
||||
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
|
||||
<server.jars>${project.basedir}/lib</server.jars>
|
||||
|
|
|
@ -31,6 +31,7 @@ import world.bentobox.bentobox.listeners.BlockEndDragon;
|
|||
import world.bentobox.bentobox.listeners.DeathListener;
|
||||
import world.bentobox.bentobox.listeners.JoinLeaveListener;
|
||||
import world.bentobox.bentobox.listeners.PanelListenerManager;
|
||||
import world.bentobox.bentobox.listeners.PrimaryIslandListener;
|
||||
import world.bentobox.bentobox.listeners.StandardSpawnProtectionListener;
|
||||
import world.bentobox.bentobox.listeners.teleports.EntityTeleportListener;
|
||||
import world.bentobox.bentobox.listeners.teleports.PlayerTeleportListener;
|
||||
|
@ -306,6 +307,8 @@ public class BentoBox extends JavaPlugin implements Listener {
|
|||
// Island Delete Manager
|
||||
islandDeletionManager = new IslandDeletionManager(this);
|
||||
manager.registerEvents(islandDeletionManager, this);
|
||||
// Primary Island Listener
|
||||
manager.registerEvents(new PrimaryIslandListener(this), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -215,33 +215,30 @@ public class JoinLeaveListener implements Listener {
|
|||
}
|
||||
|
||||
private void updateIslandRange(User user) {
|
||||
plugin.getIWM().getOverWorlds().stream()
|
||||
.filter(world -> plugin.getIslands().isOwner(world, user.getUniqueId()))
|
||||
.forEach(world -> {
|
||||
Island island = plugin.getIslands().getIsland(world, user);
|
||||
if (island != null) {
|
||||
// Check if new owner has a different range permission than the island size
|
||||
int range = user.getPermissionValue(plugin.getIWM().getAddon(island.getWorld()).map(GameModeAddon::getPermissionPrefix).orElse("") + "island.range", island.getRawProtectionRange());
|
||||
// Range cannot be greater than the island distance
|
||||
range = Math.min(range, plugin.getIWM().getIslandDistance(island.getWorld()));
|
||||
// Range can go up or down
|
||||
if (range != island.getRawProtectionRange()) {
|
||||
user.sendMessage("commands.admin.setrange.range-updated", TextVariables.NUMBER, String.valueOf(range));
|
||||
int oldRange = island.getProtectionRange();
|
||||
island.setProtectionRange(range);
|
||||
plugin.getIslands().getIslands().stream()
|
||||
.filter(island -> island.getOwner() != null && island.getOwner().equals(user.getUniqueId()))
|
||||
.forEach(island -> {
|
||||
// Check if new owner has a different range permission than the island size
|
||||
int range = user.getPermissionValue(plugin.getIWM().getAddon(island.getWorld()).map(GameModeAddon::getPermissionPrefix).orElse("") + "island.range", island.getRawProtectionRange());
|
||||
// Range cannot be greater than the island distance
|
||||
range = Math.min(range, plugin.getIWM().getIslandDistance(island.getWorld()));
|
||||
// Range can go up or down
|
||||
if (range != island.getRawProtectionRange()) {
|
||||
user.sendMessage("commands.admin.setrange.range-updated", TextVariables.NUMBER, String.valueOf(range));
|
||||
int oldRange = island.getProtectionRange();
|
||||
island.setProtectionRange(range);
|
||||
|
||||
plugin.log("Island protection range changed from " + oldRange + " to "
|
||||
+ island.getProtectionRange() + " for " + user.getName() + " due to permission.");
|
||||
// Call Protection Range Change event. Does not support canceling.
|
||||
IslandEvent.builder()
|
||||
.island(island)
|
||||
.location(island.getProtectionCenter())
|
||||
.reason(IslandEvent.Reason.RANGE_CHANGE)
|
||||
.involvedPlayer(user.getUniqueId())
|
||||
.admin(true)
|
||||
.protectionRange(island.getProtectionRange(), oldRange)
|
||||
.build();
|
||||
}
|
||||
plugin.log("Island protection range changed from " + oldRange + " to "
|
||||
+ island.getProtectionRange() + " for " + user.getName() + " due to permission.");
|
||||
// Call Protection Range Change event. Does not support canceling.
|
||||
IslandEvent.builder()
|
||||
.island(island)
|
||||
.location(island.getProtectionCenter())
|
||||
.reason(IslandEvent.Reason.RANGE_CHANGE)
|
||||
.involvedPlayer(user.getUniqueId())
|
||||
.admin(true)
|
||||
.protectionRange(island.getProtectionRange(), oldRange)
|
||||
.build();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
package world.bentobox.bentobox.listeners;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.managers.IslandsManager;
|
||||
|
||||
/**
|
||||
* Sets the player's primary island based on where they teleported or moved to
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
public class PrimaryIslandListener implements Listener {
|
||||
|
||||
private final IslandsManager im;
|
||||
|
||||
/**
|
||||
* @param plugin - plugin object
|
||||
*/
|
||||
public PrimaryIslandListener(@NonNull BentoBox plugin) {
|
||||
this.im = plugin.getIslands();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void onPlayerJoin(final PlayerJoinEvent event) {
|
||||
setIsland(event.getPlayer(), event.getPlayer().getLocation());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void onPlayerMove(final PlayerMoveEvent event) {
|
||||
if (event.getTo() != null && !event.getFrom().toVector().equals(event.getTo().toVector())) {
|
||||
setIsland(event.getPlayer(), event.getTo());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void onPlayerMove(final PlayerTeleportEvent event) {
|
||||
if (event.getTo() != null) {
|
||||
setIsland(event.getPlayer(), event.getTo());
|
||||
}
|
||||
}
|
||||
|
||||
private void setIsland(Player player, Location location) {
|
||||
im.getIslandAt(location)
|
||||
.filter(i -> i.getOwner() != null && i.getOwner().equals(player.getUniqueId()))
|
||||
.ifPresent(i -> im.setPrimaryIsland(player.getUniqueId(), i));
|
||||
}
|
||||
|
||||
}
|
|
@ -1901,4 +1901,13 @@ public class IslandsManager {
|
|||
return islandCache.getAllIslands(world, uuid).size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the user's primary island
|
||||
* @param uuid user's uuid
|
||||
* @param i island
|
||||
*/
|
||||
public void setPrimaryIsland(UUID uuid, Island i) {
|
||||
this.getIslandCache().setPrimaryIsland(uuid, i);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -274,9 +274,10 @@ public class IslandCache {
|
|||
}*/
|
||||
|
||||
/**
|
||||
* Get the UUID of the owner of the island of the player, which may be their UUID
|
||||
* @param world the world to check
|
||||
* @param uuid the player's UUID
|
||||
* @return island owner's UUID, the player UUID if they are not in a team, or null if there is no island
|
||||
* @return island owner's UUID or null if there is no island
|
||||
*/
|
||||
@Nullable
|
||||
public UUID getOwner(@NonNull World world, @NonNull UUID uuid) {
|
||||
|
@ -285,11 +286,11 @@ public class IslandCache {
|
|||
return null;
|
||||
}
|
||||
List<Island> islands = islandsByUUID.computeIfAbsent(w, k -> new HashMap<>()).get(uuid);
|
||||
return islands != null ? islands.get(0).getOwner() : null;
|
||||
|
||||
return islands == null ? null : islands.get(0).getOwner();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks is a player has an island and owns it
|
||||
* @param world the world to check
|
||||
* @param uuid the player
|
||||
* @return true if player has island and owns it
|
||||
|
@ -299,8 +300,9 @@ public class IslandCache {
|
|||
if (w == null) {
|
||||
return false;
|
||||
}
|
||||
Island island = islandsByUUID.computeIfAbsent(w, k -> new HashMap<>()).get(uuid).get(0);
|
||||
return island != null && uuid.equals(island.getOwner());
|
||||
List<Island> island = islandsByUUID.computeIfAbsent(w, k -> new HashMap<>()).get(uuid);
|
||||
if (island == null) return false;
|
||||
return !island.isEmpty() && uuid.equals(island.get(0).getOwner());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -297,9 +297,6 @@ public class NewIsland {
|
|||
// Clear the reservation
|
||||
island.setReserved(false);
|
||||
return l;
|
||||
} else {
|
||||
// This should never happen unless we allow another way to paste over islands without reserving
|
||||
plugin.logError("New island for user " + user.getName() + " was not reserved!");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -11,18 +11,22 @@ import static org.mockito.Mockito.when;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
|
@ -49,12 +53,20 @@ import world.bentobox.bentobox.util.Util;
|
|||
@PrepareForTest({Bukkit.class, BentoBox.class, User.class })
|
||||
public class AdminDeleteCommandTest {
|
||||
|
||||
@Mock
|
||||
private CompositeCommand ac;
|
||||
@Mock
|
||||
private User user;
|
||||
@Mock
|
||||
private IslandsManager im;
|
||||
@Mock
|
||||
private PlayersManager pm;
|
||||
private UUID notUUID;
|
||||
private UUID uuid;
|
||||
@Mock
|
||||
private World world;
|
||||
@Mock
|
||||
private @Nullable Island island;
|
||||
|
||||
/**
|
||||
*/
|
||||
|
@ -79,7 +91,6 @@ public class AdminDeleteCommandTest {
|
|||
// Player
|
||||
Player p = mock(Player.class);
|
||||
// Sometimes use Mockito.withSettings().verboseLogging()
|
||||
user = mock(User.class);
|
||||
when(user.isOp()).thenReturn(false);
|
||||
uuid = UUID.randomUUID();
|
||||
notUUID = UUID.randomUUID();
|
||||
|
@ -92,9 +103,9 @@ public class AdminDeleteCommandTest {
|
|||
User.setPlugin(plugin);
|
||||
|
||||
// Parent command has no aliases
|
||||
ac = mock(CompositeCommand.class);
|
||||
when(ac.getSubCommandAliases()).thenReturn(new HashMap<>());
|
||||
when(ac.getTopLabel()).thenReturn("admin");
|
||||
when(ac.getWorld()).thenReturn(world);
|
||||
|
||||
// Island World Manager
|
||||
IslandWorldManager iwm = mock(IslandWorldManager.class);
|
||||
|
@ -102,15 +113,17 @@ public class AdminDeleteCommandTest {
|
|||
|
||||
|
||||
// Player has island to begin with
|
||||
im = mock(IslandsManager.class);
|
||||
when(im.hasIsland(any(), any(UUID.class))).thenReturn(true);
|
||||
when(im.hasIsland(any(), any(User.class))).thenReturn(true);
|
||||
when(im.isOwner(any(),any())).thenReturn(true);
|
||||
when(im.getOwner(any(),any())).thenReturn(uuid);
|
||||
when(im.getIsland(world, user)).thenReturn(island);
|
||||
when(plugin.getIslands()).thenReturn(im);
|
||||
|
||||
// Island
|
||||
when(island.getOwner()).thenReturn(uuid);
|
||||
|
||||
// Has team
|
||||
pm = mock(PlayersManager.class);
|
||||
when(im.inTeam(any(), eq(uuid))).thenReturn(true);
|
||||
|
||||
when(plugin.getPlayers()).thenReturn(pm);
|
||||
|
@ -162,10 +175,9 @@ public class AdminDeleteCommandTest {
|
|||
@Test
|
||||
public void testExecutePlayerNoIsland() {
|
||||
AdminDeleteCommand itl = new AdminDeleteCommand(ac);
|
||||
String[] name = {"tastybento"};
|
||||
when(pm.getUUID(any())).thenReturn(notUUID);
|
||||
when(im.getOwner(any(), any())).thenReturn(null);
|
||||
assertFalse(itl.canExecute(user, itl.getLabel(), Arrays.asList(name)));
|
||||
when(im.getIsland(world, user)).thenReturn(null);
|
||||
assertFalse(itl.canExecute(user, "", List.of("tastybento")));
|
||||
verify(user).sendMessage(eq("general.errors.player-has-no-island"));
|
||||
}
|
||||
|
||||
|
@ -174,6 +186,7 @@ public class AdminDeleteCommandTest {
|
|||
*/
|
||||
@Test
|
||||
public void testExecuteOwner() {
|
||||
|
||||
when(im.inTeam(any(),any())).thenReturn(true);
|
||||
when(im.getOwner(any(), any())).thenReturn(notUUID);
|
||||
String[] name = {"tastybento"};
|
||||
|
|
|
@ -18,8 +18,10 @@ import java.util.Optional;
|
|||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
@ -37,6 +39,7 @@ import world.bentobox.bentobox.BentoBox;
|
|||
import world.bentobox.bentobox.Settings;
|
||||
import world.bentobox.bentobox.api.addons.GameModeAddon;
|
||||
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||
import world.bentobox.bentobox.api.configuration.WorldSettings;
|
||||
import world.bentobox.bentobox.api.events.island.IslandEvent.Reason;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle;
|
||||
|
@ -75,6 +78,10 @@ public class IslandCreateCommandTest {
|
|||
private CompositeCommand ic;
|
||||
@Mock
|
||||
private BlueprintsManager bpm;
|
||||
@Mock
|
||||
private World world;
|
||||
@Mock
|
||||
private @NonNull WorldSettings ws;
|
||||
|
||||
/**
|
||||
*/
|
||||
|
@ -115,6 +122,7 @@ public class IslandCreateCommandTest {
|
|||
when(ic.getUsage()).thenReturn("");
|
||||
when(ic.getSubCommand(Mockito.anyString())).thenReturn(Optional.empty());
|
||||
when(ic.getAddon()).thenReturn(addon);
|
||||
when(ic.getWorld()).thenReturn(world);
|
||||
|
||||
|
||||
// No island for player to begin with (set it later in the tests)
|
||||
|
@ -136,6 +144,8 @@ public class IslandCreateCommandTest {
|
|||
|
||||
// IWM friendly name
|
||||
when(iwm.getFriendlyName(any())).thenReturn("BSkyBlock");
|
||||
when(ws.getConcurrentIslands()).thenReturn(1); // One island allowed
|
||||
when(iwm.getWorldSettings(world)).thenReturn(ws);
|
||||
when(plugin.getIWM()).thenReturn(iwm);
|
||||
|
||||
// NewIsland
|
||||
|
@ -190,9 +200,12 @@ public class IslandCreateCommandTest {
|
|||
*/
|
||||
@Test
|
||||
public void testCanExecuteUserStringListOfStringHasIsland() {
|
||||
// Currently user has two islands
|
||||
when(im.getNumberOfConcurrentIslands(user.getUniqueId(), world)).thenReturn(2);
|
||||
// Player has an island
|
||||
@Nullable
|
||||
Island island = mock(Island.class);
|
||||
when(im.getIsland(any(), Mockito.any(User.class))).thenReturn(island);
|
||||
when(im.getIsland(any(), any(User.class))).thenReturn(island);
|
||||
assertFalse(cc.canExecute(user, "", Collections.emptyList()));
|
||||
verify(user).sendMessage(eq("general.errors.already-have-island"));
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import static org.mockito.Mockito.times;
|
|||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
@ -46,6 +47,8 @@ import org.powermock.core.classloader.annotations.PrepareForTest;
|
|||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.powermock.reflect.Whitebox;
|
||||
|
||||
import com.mysql.cj.x.protobuf.MysqlxCrud.CollectionOrBuilder;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.Settings;
|
||||
import world.bentobox.bentobox.api.addons.GameModeAddon;
|
||||
|
@ -162,6 +165,7 @@ public class JoinLeaveListenerTest {
|
|||
|
||||
when(im.getIsland(any(), any(User.class))).thenReturn(island);
|
||||
when(im.getIsland(any(), any(UUID.class))).thenReturn(island);
|
||||
when(im.getIslands()).thenReturn(Collections.singletonList(island));
|
||||
Map<UUID, Integer> memberMap = new HashMap<>();
|
||||
|
||||
memberMap.put(uuid, RanksManager.OWNER_RANK);
|
||||
|
|
|
@ -16,7 +16,6 @@ import java.util.UUID;
|
|||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.plugin.PluginAwareness.Flags;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
@ -253,7 +252,7 @@ public class IslandCacheTest {
|
|||
@Test
|
||||
public void testGetOwner() {
|
||||
ic.addIsland(island);
|
||||
|
||||
// Should be no owner, so null
|
||||
assertEquals(owner, ic.getOwner(world, owner));
|
||||
assertNull(ic.getOwner(world, UUID.randomUUID()));
|
||||
}
|
||||
|
|
|
@ -275,46 +275,4 @@ public class NewIslandTest {
|
|||
verify(island).setReserved(eq(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.island.NewIsland#builder()}.
|
||||
*/
|
||||
@Test
|
||||
public void testBuilderHasIslandFail() throws Exception {
|
||||
when(im.getIsland(any(), any(User.class))).thenReturn(null);
|
||||
when(im.hasIsland(any(), any(User.class))).thenReturn(true);
|
||||
NewIsland.builder().addon(addon).name(NAME).player(user).noPaste().reason(Reason.CREATE).oldIsland(oldIsland).build();
|
||||
// Verifications
|
||||
verify(im).save(eq(island));
|
||||
verify(island).setFlagsDefaults();
|
||||
verify(scheduler).runTask(any(BentoBox.class), any(Runnable.class));
|
||||
verify(builder, times(2)).build();
|
||||
verify(bpb).getUniqueId();
|
||||
verify(ice).getBlueprintBundle();
|
||||
verify(pm).setDeaths(eq(world), eq(uuid), eq(0));
|
||||
verify(im).setHomeLocation(eq(user), any());
|
||||
verify(island).setProtectionRange(eq(20));
|
||||
verify(plugin).logError("New island for user tastybento was not reserved!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link world.bentobox.bentobox.managers.island.NewIsland#builder()}.
|
||||
*/
|
||||
@Test
|
||||
public void testBuilderHasIslandFailnoReserve() throws Exception {
|
||||
when(island.isReserved()).thenReturn(false);
|
||||
when(im.hasIsland(any(), any(User.class))).thenReturn(true);
|
||||
NewIsland.builder().addon(addon).name(NAME).player(user).noPaste().reason(Reason.CREATE).oldIsland(oldIsland).build();
|
||||
// Verifications
|
||||
verify(im).save(eq(island));
|
||||
verify(island).setFlagsDefaults();
|
||||
verify(scheduler).runTask(any(BentoBox.class), any(Runnable.class));
|
||||
verify(builder, times(2)).build();
|
||||
verify(bpb).getUniqueId();
|
||||
verify(ice).getBlueprintBundle();
|
||||
verify(pm).setDeaths(eq(world), eq(uuid), eq(0));
|
||||
verify(im).setHomeLocation(eq(user), any());
|
||||
verify(island).setProtectionRange(eq(20));
|
||||
verify(plugin).logError("New island for user tastybento was not reserved!");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue