diff --git a/locales/en-US.yml b/locales/en-US.yml index 85a507999..f7762762a 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -77,6 +77,7 @@ commands: description: "register player to unowned island you are on" registered-island: "&aRegistered player to island at [xyz]." already-owned: "&cIsland is already owned by another player!" + no-island-here: "&cThere is no island here. Confirm to make one." unregister: parameters: "" description: "unregister owner from island, but keep island blocks" @@ -100,6 +101,7 @@ commands: is-spawn: "Island is a spawn island" banned-players: "Banned players:" banned-format: "&c[name]" + unowned: "&cUnonwed" version: description: "display %bsb_plugin_name% and addons versions" setrange: diff --git a/src/main/java/us/tastybento/bskyblock/commands/admin/AdminInfoCommand.java b/src/main/java/us/tastybento/bskyblock/commands/admin/AdminInfoCommand.java index 7719169f9..87feb2406 100644 --- a/src/main/java/us/tastybento/bskyblock/commands/admin/AdminInfoCommand.java +++ b/src/main/java/us/tastybento/bskyblock/commands/admin/AdminInfoCommand.java @@ -30,7 +30,7 @@ public class AdminInfoCommand extends CompositeCommand { // If there are no args, then the player wants info on the island at this location if (args.isEmpty()) { getPlugin().log("DEBUG: getting info - no args"); - if (!getIslands().getIslandAt(user.getLocation()).map(i -> i.showInfo(getPlugin(), user)).orElse(false)) { + if (!getIslands().getIslandAt(user.getLocation()).map(i -> i.showInfo(getPlugin(), user, getWorld())).orElse(false)) { user.sendMessage("commands.admin.info.no-island"); return false; } @@ -47,7 +47,7 @@ public class AdminInfoCommand extends CompositeCommand { return false; } // Show info for this player - getIslands().getIsland(getWorld(), targetUUID).showInfo(getPlugin(), user); + getIslands().getIsland(getWorld(), targetUUID).showInfo(getPlugin(), user, getWorld()); return true; } } diff --git a/src/main/java/us/tastybento/bskyblock/commands/admin/AdminRegisterCommand.java b/src/main/java/us/tastybento/bskyblock/commands/admin/AdminRegisterCommand.java index 2428513ee..b65ced1d4 100644 --- a/src/main/java/us/tastybento/bskyblock/commands/admin/AdminRegisterCommand.java +++ b/src/main/java/us/tastybento/bskyblock/commands/admin/AdminRegisterCommand.java @@ -1,9 +1,13 @@ package us.tastybento.bskyblock.commands.admin; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.UUID; +import org.bukkit.Location; +import org.bukkit.Material; + import us.tastybento.bskyblock.api.commands.CompositeCommand; import us.tastybento.bskyblock.api.user.User; import us.tastybento.bskyblock.database.objects.Island; @@ -43,9 +47,7 @@ public class AdminRegisterCommand extends CompositeCommand { if (getIslands().inTeam(getWorld(), targetUUID)) { user.sendMessage("commands.admin.register.cannot-register-team-player"); return false; - } - getIslands().getIslandAt(user.getLocation()).ifPresent(i -> getPlugin().log("DEBUG: island at this location is " + i.getCenter())); - + } // Check if island is owned Optional island = getIslands().getIslandAt(user.getLocation()); @@ -54,13 +56,51 @@ public class AdminRegisterCommand extends CompositeCommand { return false; } // Register island if it exists - return island.map(i -> { + if (!island.map(i -> { // Island exists getIslands().makeLeader(user, targetUUID, i, getPermissionPrefix()); user.sendMessage("commands.admin.register.registered-island", "[xyz]", Util.xyz(i.getCenter().toVector())); user.sendMessage("general.success"); return true; - }).orElse(false); // Island does not exist - + }).orElse(false)) { + // Island does not exist + user.sendMessage("commands.admin.register.no-island-here"); + this.askConfirmation(user, () -> { + // Make island here + Island i = getIslands().createIsland(getClosestIsland(user.getLocation()), targetUUID); + getIslands().makeLeader(user, targetUUID, i, getPermissionPrefix()); + getWorld().getBlockAt(i.getCenter()).setType(Material.BEDROCK); + user.sendMessage("commands.admin.register.registered-island", "[xyz]", Util.xyz(i.getCenter().toVector())); + user.sendMessage("general.success"); + }); + return false; + } + return true; } + + @Override + public Optional> tabComplete(User user, String alias, List args) { + String lastArg = !args.isEmpty() ? args.get(args.size()-1) : ""; + if (args.isEmpty()) { + // Don't show every player on the server. Require at least the first letter + return Optional.empty(); + } + List options = new ArrayList<>(Util.getOnlinePlayerList(user)); + return Optional.of(Util.tabLimit(options, lastArg)); + } + + /** + * This returns the coordinate of where an island should be on the grid. + * + * @param location + * @return Location of where an island should be on a grid in this world + */ + public Location getClosestIsland(Location location) { + int dist = getIWM().getIslandDistance(getWorld()) * 2; + long x = Math.round((double) location.getBlockX() / dist) * dist + getIWM().getIslandXOffset(getWorld()); + long z = Math.round((double) location.getBlockZ() / dist) * dist + getIWM().getIslandZOffset(getWorld()); + long y = getIWM().getIslandHeight(getWorld()); + return new Location(location.getWorld(), x, y, z); + } + } \ No newline at end of file diff --git a/src/main/java/us/tastybento/bskyblock/commands/admin/AdminUnregisterCommand.java b/src/main/java/us/tastybento/bskyblock/commands/admin/AdminUnregisterCommand.java index 0cb5b5833..893a17bc1 100644 --- a/src/main/java/us/tastybento/bskyblock/commands/admin/AdminUnregisterCommand.java +++ b/src/main/java/us/tastybento/bskyblock/commands/admin/AdminUnregisterCommand.java @@ -1,6 +1,8 @@ package us.tastybento.bskyblock.commands.admin; +import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.UUID; import us.tastybento.bskyblock.api.commands.CompositeCommand; @@ -44,7 +46,19 @@ public class AdminUnregisterCommand extends CompositeCommand { // Unregister island user.sendMessage("commands.admin.unregister.unregistered-island", "[xyz]", Util.xyz(getIslands().getIsland(getWorld(), targetUUID).getCenter().toVector())); getIslands().removePlayer(getWorld(), targetUUID); + getPlayers().clearHomeLocations(getWorld(), targetUUID); user.sendMessage("general.success"); return true; } + + @Override + public Optional> tabComplete(User user, String alias, List args) { + String lastArg = !args.isEmpty() ? args.get(args.size()-1) : ""; + if (args.isEmpty()) { + // Don't show every player on the server. Require at least the first letter + return Optional.empty(); + } + List options = new ArrayList<>(Util.getOnlinePlayerList(user)); + return Optional.of(Util.tabLimit(options, lastArg)); + } } \ No newline at end of file diff --git a/src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamAddCommand.java b/src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamAddCommand.java index 0de40a676..3efa41bd0 100644 --- a/src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamAddCommand.java +++ b/src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamAddCommand.java @@ -45,7 +45,7 @@ public class AdminTeamAddCommand extends CompositeCommand { } if (getIslands().inTeam(getWorld(), leaderUUID) && !getIslands().getTeamLeader(getWorld(), leaderUUID).equals(leaderUUID)) { user.sendMessage("commands.admin.team.add.name-not-leader", TextVariables.NAME, args.get(0)); - getIslands().getIsland(getWorld(), leaderUUID).showMembers(getPlugin(), user); + getIslands().getIsland(getWorld(), leaderUUID).showMembers(getPlugin(), user, getWorld()); return false; } if (getIslands().inTeam(getWorld(), targetUUID)) { diff --git a/src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamKickCommand.java b/src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamKickCommand.java index 7848b56b7..559d258c7 100644 --- a/src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamKickCommand.java +++ b/src/main/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamKickCommand.java @@ -43,7 +43,7 @@ public class AdminTeamKickCommand extends CompositeCommand { } if (getIslands().getTeamLeader(getWorld(), targetUUID).equals(targetUUID)) { user.sendMessage("commands.admin.team.kick.cannot-kick-leader"); - getIslands().getIsland(getWorld(), targetUUID).showMembers(getPlugin(), user); + getIslands().getIsland(getWorld(), targetUUID).showMembers(getPlugin(), user, getWorld()); return false; } User.getInstance(targetUUID).sendMessage("commands.admin.team.kick.admin-kicked"); diff --git a/src/main/java/us/tastybento/bskyblock/commands/island/teams/IslandTeamCommand.java b/src/main/java/us/tastybento/bskyblock/commands/island/teams/IslandTeamCommand.java index bda91bbd4..a30abfe19 100644 --- a/src/main/java/us/tastybento/bskyblock/commands/island/teams/IslandTeamCommand.java +++ b/src/main/java/us/tastybento/bskyblock/commands/island/teams/IslandTeamCommand.java @@ -57,7 +57,7 @@ public class IslandTeamCommand extends CompositeCommand { } } // Show members of island - getIslands().getIsland(getWorld(), playerUUID).showMembers(getPlugin(), user); + getIslands().getIsland(getWorld(), playerUUID).showMembers(getPlugin(), user, getWorld()); return true; } diff --git a/src/main/java/us/tastybento/bskyblock/database/objects/Island.java b/src/main/java/us/tastybento/bskyblock/database/objects/Island.java index 8b70a9052..66876f421 100755 --- a/src/main/java/us/tastybento/bskyblock/database/objects/Island.java +++ b/src/main/java/us/tastybento/bskyblock/database/objects/Island.java @@ -8,7 +8,6 @@ import java.util.Map.Entry; import java.util.Set; import java.util.UUID; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; @@ -110,7 +109,8 @@ public class Island implements DataObject { createdDate = System.currentTimeMillis(); updatedDate = System.currentTimeMillis(); world = location.getWorld(); - center = location; + // Make a copy of the location + center = new Location(location.getWorld(), location.getX(), location.getY(), location.getZ()); range = BSkyBlock.getInstance().getIWM().getIslandDistance(world); minX = center.getBlockX() - range; minZ = center.getBlockZ() - range; @@ -378,7 +378,6 @@ public class Island implements DataObject { * @return true if in the island space */ public boolean inIslandSpace(int x, int z) { - Bukkit.getLogger().info("DEBUG: minX = " + minX + " range = " + range + " minZ = " + minZ); return x >= minX && x < minX + range*2 && z >= minZ && z < minZ + range*2; } @@ -649,9 +648,10 @@ public class Island implements DataObject { * Show info on the island * @param plugin - plugin * @param user - the user who is receiving the info + * @param world * @return true always */ - public boolean showInfo(BSkyBlock plugin, User user) { + public boolean showInfo(BSkyBlock plugin, User user, World world) { user.sendMessage("commands.admin.info.title"); if (owner == null) { user.sendMessage("commands.admin.info.unowned"); @@ -665,7 +665,7 @@ public class Island implements DataObject { String total = plugin.getSettings().getResetLimit() < 0 ? "Unlimited" : String.valueOf(plugin.getSettings().getResetLimit()); user.sendMessage("commands.admin.info.resets-left", "[number]", resets, "[total]", total); // Show team members - showMembers(plugin, user); + showMembers(plugin, user, world); } Vector location = center.toVector(); user.sendMessage("commands.admin.info.island-location", "[xyz]", Util.xyz(location)); @@ -691,9 +691,10 @@ public class Island implements DataObject { * Shows the members of this island * @param plugin - plugin * @param user - user who is requesting + * @param world */ - public void showMembers(BSkyBlock plugin, User user) { - if (plugin.getIslands().inTeam(user.getWorld(), user.getUniqueId())) { + public void showMembers(BSkyBlock plugin, User user, World world) { + if (plugin.getIslands().inTeam(world, user.getUniqueId())) { user.sendMessage("commands.admin.info.team-members-title"); members.forEach((u, i) -> { if (owner.equals(u)) { diff --git a/src/main/java/us/tastybento/bskyblock/managers/IslandsManager.java b/src/main/java/us/tastybento/bskyblock/managers/IslandsManager.java index 8e2f88ef5..739d22328 100644 --- a/src/main/java/us/tastybento/bskyblock/managers/IslandsManager.java +++ b/src/main/java/us/tastybento/bskyblock/managers/IslandsManager.java @@ -710,7 +710,7 @@ public class IslandsManager { } } }; - plugin.getServer().getScheduler().runTaskAsynchronously(plugin, save); + Bukkit.getScheduler().runTaskAsynchronously(plugin, save); } else { for(Island island : collection){ try { diff --git a/src/main/java/us/tastybento/bskyblock/managers/island/IslandCache.java b/src/main/java/us/tastybento/bskyblock/managers/island/IslandCache.java index fbb07e3e2..840d208ad 100644 --- a/src/main/java/us/tastybento/bskyblock/managers/island/IslandCache.java +++ b/src/main/java/us/tastybento/bskyblock/managers/island/IslandCache.java @@ -8,18 +8,14 @@ import java.util.Map; import java.util.Set; import java.util.UUID; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; - import us.tastybento.bskyblock.database.objects.Island; import us.tastybento.bskyblock.util.Util; public class IslandCache { - private BiMap islandsByLocation; + private Map islandsByLocation; /** * Every player who is associated with an island is in this map. */ @@ -27,7 +23,7 @@ public class IslandCache { private Map grids; public IslandCache() { - islandsByLocation = HashBiMap.create(); + islandsByLocation = new HashMap<>(); islandsByUUID = new HashMap<>(); grids = new HashMap<>(); } @@ -38,10 +34,17 @@ public class IslandCache { * @return true if successfully added, false if not */ public boolean addIsland(Island island) { - islandsByLocation.put(island.getCenter(), island); + if (island.getCenter() == null || island.getWorld() == null) { + return false; + } + islandsByLocation.put(island.getCenter(), island); + // Make world islandsByUUID.putIfAbsent(island.getWorld(), new HashMap<>()); - islandsByUUID.get(island.getWorld()).put(island.getOwner(), island); - island.getMemberSet().forEach(member -> islandsByUUID.get(island.getWorld()).put(member, island)); + // Only add islands to this map if they are owned + if (island.getOwner() != null) { + islandsByUUID.get(island.getWorld()).put(island.getOwner(), island); + island.getMemberSet().forEach(member -> islandsByUUID.get(island.getWorld()).put(member, island)); + } return addToGrid(island); } @@ -117,7 +120,7 @@ public class IslandCache { } return grids.get(Util.getWorld(location.getWorld())).getIslandAt(location.getBlockX(), location.getBlockZ()); } - + public Collection getIslands() { return Collections.unmodifiableCollection(islandsByLocation.values()); } @@ -168,19 +171,16 @@ public class IslandCache { * @param uuid - player's UUID */ public void removePlayer(World world, UUID uuid) { - Bukkit.getLogger().info("DEBUG: removing " + uuid + " in " + world.getName()); world = Util.getWorld(world); islandsByUUID.putIfAbsent(world, new HashMap<>()); Island island = islandsByUUID.get(world).get(uuid); if (island != null) { - Bukkit.getLogger().info("DEBUG: island found"); if (island.getOwner() != null && island.getOwner().equals(uuid)) { - Bukkit.getLogger().info("DEBUG: owner is not null and uuid is owner"); // Clear ownership and members island.getMembers().clear(); island.setOwner(null); + //islandsByLocation.put(island.getCenter(), island); } else { - Bukkit.getLogger().info("DEBUG: owner is not uuid - just remove member"); // Remove player from the island membership island.removeMember(uuid); } @@ -207,5 +207,5 @@ public class IslandCache { islandsByUUID.get(Util.getWorld(island.getWorld())).put(newOwnerUUID, island); islandsByLocation.put(island.getCenter(), island); } - + } diff --git a/src/main/java/us/tastybento/bskyblock/managers/island/IslandGrid.java b/src/main/java/us/tastybento/bskyblock/managers/island/IslandGrid.java index 53d2c5451..f2124ff76 100644 --- a/src/main/java/us/tastybento/bskyblock/managers/island/IslandGrid.java +++ b/src/main/java/us/tastybento/bskyblock/managers/island/IslandGrid.java @@ -1,9 +1,6 @@ package us.tastybento.bskyblock.managers.island; import java.util.Map.Entry; - -import org.bukkit.Bukkit; - import java.util.TreeMap; import us.tastybento.bskyblock.database.objects.Island; @@ -72,17 +69,13 @@ public class IslandGrid { * @return Island or null */ public Island getIslandAt(int x, int z) { - Bukkit.getLogger().info("DEBUG: x and z = " + x + " " + z); Entry> en = grid.floorEntry(x); if (en != null) { Entry ent = en.getValue().floorEntry(z); if (ent != null) { - Bukkit.getLogger().info("DEBUG: found island"); // Check if in the island range Island island = ent.getValue(); - Bukkit.getLogger().info("DEBUG: island center = " + island.getCenter()); if (island.inIslandSpace(x, z)) { - Bukkit.getLogger().info("DEBUG: in island space"); return island; } } diff --git a/src/main/java/us/tastybento/bskyblock/util/Util.java b/src/main/java/us/tastybento/bskyblock/util/Util.java index e2cabae59..2e2c27e8a 100755 --- a/src/main/java/us/tastybento/bskyblock/util/Util.java +++ b/src/main/java/us/tastybento/bskyblock/util/Util.java @@ -6,6 +6,8 @@ import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; import org.apache.commons.lang.math.NumberUtils; import org.bukkit.Bukkit; @@ -151,13 +153,12 @@ public class Util { * @return a list of online players this player can see */ public static List getOnlinePlayerList(User user) { - final List returned = new ArrayList<>(); - for (Player p : Bukkit.getServer().getOnlinePlayers()) { - if (user == null || user.getPlayer().canSee(p)) { - returned.add(p.getName()); - } + if (user == null || !user.isPlayer()) { + // Console and null get to see every player + return Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList()); } - return returned; + // Otherwise prevent invisible players from seeing + return Bukkit.getOnlinePlayers().stream().filter(p -> user.getPlayer().canSee(p)).map(Player::getName).collect(Collectors.toList()); } /** diff --git a/src/test/java/us/tastybento/bskyblock/commands/admin/AdminInfoCommandTest.java b/src/test/java/us/tastybento/bskyblock/commands/admin/AdminInfoCommandTest.java index e3456bed0..e24c02541 100644 --- a/src/test/java/us/tastybento/bskyblock/commands/admin/AdminInfoCommandTest.java +++ b/src/test/java/us/tastybento/bskyblock/commands/admin/AdminInfoCommandTest.java @@ -175,7 +175,7 @@ public class AdminInfoCommandTest { Island is = mock(Island.class); when(im.getIsland(Mockito.any(), Mockito.eq(notUUID))).thenReturn(is); assertTrue(itl.execute(user, Arrays.asList(name))); - Mockito.verify(is).showInfo(Mockito.eq(plugin), Mockito.eq(user)); + Mockito.verify(is).showInfo(Mockito.eq(plugin), Mockito.eq(user), Mockito.any()); } /** @@ -204,7 +204,7 @@ public class AdminInfoCommandTest { // Island has owner Island is = mock(Island.class); when(is.getOwner()).thenReturn(uuid); - when(is.showInfo(Mockito.any(), Mockito.any())).thenReturn(true); + when(is.showInfo(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(true); Optional opi = Optional.of(is); when(im.getIslandAt(Mockito.any())).thenReturn(opi); when(user.getLocation()).thenReturn(loc); @@ -212,6 +212,6 @@ public class AdminInfoCommandTest { assertTrue(itl.execute(user, new ArrayList<>())); // Confirm other verifications - Mockito.verify(is).showInfo(Mockito.eq(plugin), Mockito.eq(user)); + Mockito.verify(is).showInfo(Mockito.eq(plugin), Mockito.eq(user), Mockito.any()); } } \ No newline at end of file diff --git a/src/test/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamAddCommandTest.java b/src/test/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamAddCommandTest.java index cfa29c162..5b8363631 100644 --- a/src/test/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamAddCommandTest.java +++ b/src/test/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamAddCommandTest.java @@ -221,7 +221,7 @@ public class AdminTeamAddCommandTest { assertFalse(itl.execute(user, Arrays.asList(name))); Mockito.verify(user).sendMessage("commands.admin.team.add.name-not-leader", "[name]", "tastybento"); - Mockito.verify(island).showMembers(Mockito.eq(plugin), Mockito.any()); + Mockito.verify(island).showMembers(Mockito.eq(plugin), Mockito.any(), Mockito.any()); } /** diff --git a/src/test/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamKickCommandTest.java b/src/test/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamKickCommandTest.java index 121c0b44c..fb986347e 100644 --- a/src/test/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamKickCommandTest.java +++ b/src/test/java/us/tastybento/bskyblock/commands/admin/teams/AdminTeamKickCommandTest.java @@ -176,7 +176,7 @@ public class AdminTeamKickCommandTest { AdminTeamKickCommand itl = new AdminTeamKickCommand(ac); assertFalse(itl.execute(user, Arrays.asList(name))); Mockito.verify(user).sendMessage(Mockito.eq("commands.admin.team.kick.cannot-kick-leader")); - Mockito.verify(is).showMembers(plugin, user); + Mockito.verify(is).showMembers(Mockito.any(), Mockito.any(), Mockito.any()); } /** diff --git a/src/test/java/us/tastybento/bskyblock/managers/IslandsManagerTest.java b/src/test/java/us/tastybento/bskyblock/managers/IslandsManagerTest.java index ac6e1c7dd..593d87143 100644 --- a/src/test/java/us/tastybento/bskyblock/managers/IslandsManagerTest.java +++ b/src/test/java/us/tastybento/bskyblock/managers/IslandsManagerTest.java @@ -159,6 +159,9 @@ public class IslandsManagerTest { PowerMockito.mockStatic(Util.class); when(Util.getWorld(Mockito.any())).thenReturn(world); + + // Scheduler + when(Bukkit.getScheduler()).thenReturn(mock(BukkitScheduler.class)); } @@ -426,7 +429,7 @@ public class IslandsManagerTest { IslandsManager im = new IslandsManager(plugin); Island island = im.createIsland(location); assertNotNull(island); - assertEquals(island.getCenter(), location); + assertEquals(island.getCenter().getWorld(), location.getWorld()); } /** @@ -438,7 +441,7 @@ public class IslandsManagerTest { IslandsManager im = new IslandsManager(plugin); Island island = im.createIsland(location, owner); assertNotNull(island); - assertEquals(location, island.getCenter()); + assertEquals(island.getCenter().getWorld(), location.getWorld()); assertEquals(owner, island.getOwner()); } @@ -517,7 +520,7 @@ public class IslandsManagerTest { public void testGetIslandLocation() { IslandsManager im = new IslandsManager(plugin); im.createIsland(location, uuid); - assertEquals(location, im.getIslandLocation(world, uuid)); + assertEquals(world, im.getIslandLocation(world, uuid).getWorld()); assertNull(im.getIslandLocation(world, UUID.randomUUID())); }