diff --git a/pom.xml b/pom.xml
index 8aa65b84f..e770b82a8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -88,7 +88,7 @@
-LOCAL
- 2.3.0
+ 2.4.0
bentobox-world
https://sonarcloud.io
${project.basedir}/lib
@@ -195,6 +195,11 @@
Lumine Releases
https://mvn.lumine.io/repository/maven-public/
+
+
+ clojars
+ https://repo.clojars.org/
+
@@ -364,6 +369,13 @@
3.6.1
provided
+
+
+ com.github.puregero
+ multilib
+ 1.1.12
+ compile
+
@@ -486,9 +498,10 @@
org.apache.maven.plugins
maven-shade-plugin
- 3.3.1-SNAPSHOT
+ 3.4.0
true
+ ${project.build.directory}/dependency-reduced-pom.xml
org.bstats
@@ -500,9 +513,13 @@
io.papermc.lib
- world.bentobox.bentobox.paperlib
+ world.bentobox.bentobox.paperlib
-
+
+ com.github.puregero.multilib
+ world.bentobox.bentobox.multilib
+
+
org.apache.maven.shared:*
diff --git a/src/main/java/world/bentobox/bentobox/BStats.java b/src/main/java/world/bentobox/bentobox/BStats.java
index aedf7c83a..2fd23b587 100644
--- a/src/main/java/world/bentobox/bentobox/BStats.java
+++ b/src/main/java/world/bentobox/bentobox/BStats.java
@@ -59,7 +59,6 @@ public class BStats {
registerGameModeAddonsChart();
registerHooksChart();
registerPlayersPerServerChart();
- registerFlagsDisplayModeChart();
// Single Line charts
registerIslandsCountChart();
@@ -171,27 +170,6 @@ public class BStats {
}));
}
- /**
- * Sends the "flags display mode" of all the online players.
- * @since 1.6.0
- */
- private void registerFlagsDisplayModeChart() {
- metrics.addCustomChart(new AdvancedPie("flagsDisplayMode", () -> {
- Map values = new HashMap<>();
-
- Bukkit.getOnlinePlayers().forEach(player -> {
- Flag.Mode mode = plugin.getPlayers().getFlagsDisplayMode(player.getUniqueId());
- if (values.containsKey(mode.name())) {
- values.put(mode.name(), values.get(mode.name()) + 1);
- } else {
- values.put(mode.name(), 1);
- }
- });
-
- return values;
- }));
- }
-
/**
* Sends the enabled addons (except GameModeAddons) of this server as bar chart.
* @since 1.17.1
diff --git a/src/main/java/world/bentobox/bentobox/BentoBox.java b/src/main/java/world/bentobox/bentobox/BentoBox.java
index 235d37ef6..2f537cd84 100644
--- a/src/main/java/world/bentobox/bentobox/BentoBox.java
+++ b/src/main/java/world/bentobox/bentobox/BentoBox.java
@@ -210,20 +210,6 @@ public class BentoBox extends JavaPlugin implements Listener {
return;
}
- // Save islands & players data every X minutes
- Bukkit.getScheduler().runTaskTimer(instance, () -> {
- if (!playersManager.isSaveTaskRunning()) {
- playersManager.saveAll(true);
- } else {
- getLogger().warning("Tried to start a player data save task while the previous auto save was still running!");
- }
- if (!islandsManager.isSaveTaskRunning()) {
- islandsManager.saveAll(true);
- } else {
- getLogger().warning("Tried to start a island data save task while the previous auto save was still running!");
- }
- }, getSettings().getDatabaseBackupPeriod() * 20 * 60L, getSettings().getDatabaseBackupPeriod() * 20 * 60L);
-
// Make sure all flag listeners are registered.
flagsManager.registerListeners();
@@ -433,7 +419,7 @@ public class BentoBox extends JavaPlugin implements Listener {
* @return the ranksManager
* @deprecated Just use {@code RanksManager.getInstance()}
*/
- @Deprecated(since = "2.0.0")
+ @Deprecated(since = "2.0.0", forRemoval = true)
public RanksManager getRanksManager() {
return RanksManager.getInstance();
}
diff --git a/src/main/java/world/bentobox/bentobox/api/addons/Addon.java b/src/main/java/world/bentobox/bentobox/api/addons/Addon.java
index 57190b7d9..5b4b5c18f 100644
--- a/src/main/java/world/bentobox/bentobox/api/addons/Addon.java
+++ b/src/main/java/world/bentobox/bentobox/api/addons/Addon.java
@@ -21,6 +21,8 @@ import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.event.Listener;
+import com.github.puregero.multilib.MultiLib;
+
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.request.AddonRequestHandler;
import world.bentobox.bentobox.api.flags.Flag;
@@ -45,6 +47,8 @@ public abstract class Addon {
protected Addon() {
state = State.DISABLED;
+ // If the config is updated, update the config.
+ MultiLib.onString(getPlugin(), "bentobox-config-update", v -> this.reloadConfig());
}
/**
diff --git a/src/main/java/world/bentobox/bentobox/api/addons/GameModeAddon.java b/src/main/java/world/bentobox/bentobox/api/addons/GameModeAddon.java
index a45b12d68..79c3fa016 100644
--- a/src/main/java/world/bentobox/bentobox/api/addons/GameModeAddon.java
+++ b/src/main/java/world/bentobox/bentobox/api/addons/GameModeAddon.java
@@ -8,6 +8,8 @@ import org.bukkit.generator.ChunkGenerator;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
+import com.github.puregero.multilib.MultiLib;
+
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.configuration.WorldSettings;
import world.bentobox.bentobox.util.Util;
@@ -129,7 +131,10 @@ public abstract class GameModeAddon extends Addon {
* in-game and need to be saved.
* @since 1.4.0
*/
- public abstract void saveWorldSettings();
+ public void saveWorldSettings() {
+ // Inform other servers
+ MultiLib.notify("bentobox-config-update", "");
+ }
/**
* Defines if the game mode uses the latest {@link ChunkGenerator} API or
diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminEmptyTrashCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminEmptyTrashCommand.java
deleted file mode 100644
index f5c8970ff..000000000
--- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminEmptyTrashCommand.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package world.bentobox.bentobox.api.commands.admin;
-
-import java.util.List;
-import java.util.UUID;
-
-import world.bentobox.bentobox.api.commands.CompositeCommand;
-import world.bentobox.bentobox.api.commands.ConfirmableCommand;
-import world.bentobox.bentobox.api.localization.TextVariables;
-import world.bentobox.bentobox.api.user.User;
-import world.bentobox.bentobox.database.objects.Island;
-
-public class AdminEmptyTrashCommand extends ConfirmableCommand {
-
- /**
- * Clear trash for player, or all unowned islands in trash
- * @param parent - admin command
- * @since 1.3.0
- */
- public AdminEmptyTrashCommand(CompositeCommand parent) {
- super(parent, "emptytrash");
- }
-
- @Override
- public void setup() {
- setPermission("admin.trash");
- setOnlyPlayer(false);
- setParametersHelp("commands.admin.emptytrash.parameters");
- setDescription("commands.admin.emptytrash.description");
- }
-
- @Override
- public boolean execute(User user, String label, List args) {
- if (args.size() > 1) {
- // Show help
- showHelp(this, user);
- return false;
- }
- // Get target player
- UUID targetUUID = args.isEmpty() ? null : getPlayers().getUUID(args.get(0));
- if (!args.isEmpty() && targetUUID == null) {
- user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0));
- return false;
- }
- // Remove trash for this player
- final List islands = getIslands().getQuarantinedIslandByUser(getWorld(), targetUUID);
- if (islands.isEmpty()) {
- if (args.isEmpty()) {
- user.sendMessage("commands.admin.trash.no-unowned-in-trash");
- } else {
- user.sendMessage("commands.admin.trash.no-islands-in-trash");
- }
- return false;
- } else {
- this.askConfirmation(user, () -> {
- getIslands().deleteQuarantinedIslandByUser(getWorld(), targetUUID);
- user.sendMessage("commands.admin.emptytrash.success");
- });
- return true;
- }
- }
-}
diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminInfoCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminInfoCommand.java
index ca3281996..dfb6eaf96 100644
--- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminInfoCommand.java
+++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminInfoCommand.java
@@ -49,9 +49,6 @@ public class AdminInfoCommand extends CompositeCommand {
Island island = getIslands().getIsland(getWorld(), targetUUID);
if (island != null) {
new IslandInfo(island).showAdminInfo(user, getAddon());
- if (!getIslands().getQuarantinedIslandByUser(getWorld(), targetUUID).isEmpty()) {
- user.sendMessage("commands.admin.info.islands-in-trash");
- }
return true;
} else {
user.sendMessage("general.errors.player-has-no-island");
diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSettingsCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSettingsCommand.java
index 177d85657..f7fafe800 100644
--- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSettingsCommand.java
+++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSettingsCommand.java
@@ -16,7 +16,6 @@ import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.flags.Flag;
-import world.bentobox.bentobox.api.flags.Flag.Mode;
import world.bentobox.bentobox.api.flags.Flag.Type;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.panels.builders.TabbedPanelBuilder;
@@ -206,11 +205,9 @@ public class AdminSettingsCommand extends CompositeCommand {
switch (f.getType()) {
case PROTECTION -> {
island.setFlag(f, rank);
- getIslands().save(island);
}
case SETTING -> {
island.setSettingsFlag(f, activeState);
- getIslands().save(island);
}
case WORLD_SETTING -> f.setSetting(getWorld(), activeState);
default -> {
@@ -226,12 +223,11 @@ public class AdminSettingsCommand extends CompositeCommand {
user.sendMessage("general.errors.use-in-game");
return false;
}
- getPlayers().setFlagsDisplayMode(user.getUniqueId(), Mode.EXPERT);
if (args.isEmpty()) {
new TabbedPanelBuilder()
.user(user)
.world(getWorld())
- .tab(1, new SettingsTab(getWorld(), user, Flag.Type.WORLD_SETTING))
+ .tab(1, new SettingsTab(getWorld(), user, Flag.Type.WORLD_SETTING, Flag.Mode.EXPERT))
.tab(2, new WorldDefaultSettingsTab(getWorld(), user))
.startingSlot(1)
.size(54)
@@ -242,8 +238,8 @@ public class AdminSettingsCommand extends CompositeCommand {
new TabbedPanelBuilder()
.user(user)
.world(island.getWorld())
- .island(island).tab(1, new SettingsTab(user, Flag.Type.PROTECTION))
- .tab(2, new SettingsTab(user, Flag.Type.SETTING))
+ .island(island).tab(1, new SettingsTab(getWorld(), user, Flag.Type.PROTECTION, Flag.Mode.EXPERT))
+ .tab(2, new SettingsTab(getWorld(), user, Flag.Type.SETTING, Flag.Mode.EXPERT))
.startingSlot(1)
.size(54)
.build().openPanel();
diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSwitchtoCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSwitchtoCommand.java
deleted file mode 100644
index 3bb91c4c4..000000000
--- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSwitchtoCommand.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package world.bentobox.bentobox.api.commands.admin;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-import org.apache.commons.lang.math.NumberUtils;
-import org.eclipse.jdt.annotation.NonNull;
-
-import world.bentobox.bentobox.api.commands.CompositeCommand;
-import world.bentobox.bentobox.api.commands.ConfirmableCommand;
-import world.bentobox.bentobox.api.localization.TextVariables;
-import world.bentobox.bentobox.api.user.User;
-import world.bentobox.bentobox.database.objects.Island;
-import world.bentobox.bentobox.util.Util;
-
-public class AdminSwitchtoCommand extends ConfirmableCommand {
-
- private UUID targetUUID;
- private @NonNull List islands;
-
- /**
- * Switch player's island to the numbered one in trash
- * @param parent - admin command
- * @since 1.3.0
- */
- public AdminSwitchtoCommand(CompositeCommand parent) {
- super(parent, "switchto");
- islands = new ArrayList<>();
- }
-
- @Override
- public void setup() {
- setPermission("admin.switchto");
- setOnlyPlayer(false);
- setParametersHelp("commands.admin.switchto.parameters");
- setDescription("commands.admin.switchto.description");
- }
-
- @Override
- public boolean canExecute(User user, String label, List args) {
- if (args.size() != 2) {
- // Show help
- showHelp(this, user);
- return false;
- }
- // Get target player
- targetUUID = Util.getUUID(args.get(0));
- if (targetUUID == null) {
- user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0));
- return false;
- }
- // Check island number
- islands = getIslands().getQuarantinedIslandByUser(getWorld(), targetUUID);
- if (islands.isEmpty()) {
- user.sendMessage("commands.admin.trash.no-islands-in-trash");
- return false;
- }
- return true;
- }
-
- @Override
- public boolean execute(User user, String label, List args) {
- if (NumberUtils.isDigits(args.get(1))) {
- try {
- int n = Integer.parseInt(args.get(1));
- if (n < 1 || n > islands.size()) {
- user.sendMessage("commands.admin.switchto.out-of-range", TextVariables.NUMBER, String.valueOf(islands.size()), TextVariables.LABEL, getTopLabel());
- return false;
- }
- this.askConfirmation(user, () -> {
- if (getIslands().switchIsland(getWorld(), targetUUID, islands.get(n -1))) {
- user.sendMessage("commands.admin.switchto.success");
- } else {
- user.sendMessage("commands.admin.switchto.cannot-switch");
- }
- });
- return true;
- } catch (Exception e) {
- showHelp(this, user);
- return false;
- }
- }
- return true;
- }
-
-}
diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTrashCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTrashCommand.java
deleted file mode 100644
index e17d10041..000000000
--- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTrashCommand.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package world.bentobox.bentobox.api.commands.admin;
-
-import java.util.List;
-import java.util.UUID;
-
-import world.bentobox.bentobox.api.commands.CompositeCommand;
-import world.bentobox.bentobox.api.localization.TextVariables;
-import world.bentobox.bentobox.api.user.User;
-import world.bentobox.bentobox.database.objects.Island;
-import world.bentobox.bentobox.util.IslandInfo;
-
-public class AdminTrashCommand extends CompositeCommand {
-
- /**
- * A command for viewing islands in the database trash
- * @param parent - admin command
- * @since 1.3.0
- */
- public AdminTrashCommand(CompositeCommand parent) {
- super(parent, "trash");
- }
-
- @Override
- public void setup() {
- setPermission("admin.trash");
- setOnlyPlayer(false);
- setParametersHelp("commands.admin.trash.parameters");
- setDescription("commands.admin.trash.description");
- }
-
- @Override
- public boolean execute(User user, String label, List args) {
- if (args.size() > 1) {
- // Show help
- showHelp(this, user);
- return false;
- }
- // Get target player
- UUID targetUUID = args.isEmpty() ? null : getPlayers().getUUID(args.get(0));
- if (!args.isEmpty() && targetUUID == null) {
- user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0));
- return false;
- }
- // Show trash can info for this player
- List islands = getIslands().getQuarantinedIslandByUser(getWorld(), targetUUID);
- if (islands.isEmpty()) {
- if (args.isEmpty()) {
- user.sendMessage("commands.admin.trash.no-unowned-in-trash");
- } else {
- user.sendMessage("commands.admin.trash.no-islands-in-trash");
- }
- return false;
- } else {
- if (targetUUID == null) {
- showTrash(user, islands);
- } else {
- getIslands().getQuarantineCache().values().forEach(v -> showTrash(user, v));
- }
- return true;
- }
- }
-
- private void showTrash(User user, List islands) {
- user.sendMessage("commands.admin.trash.title");
- for (int i = 0; i < islands.size(); i++) {
- user.sendMessage("commands.admin.trash.count", TextVariables.NUMBER, String.valueOf(i+1));
- new IslandInfo(islands.get(i)).showInfo(user);
- }
- user.sendMessage("commands.admin.trash.use-switch", TextVariables.LABEL, getTopLabel());
- user.sendMessage("commands.admin.trash.use-emptytrash", TextVariables.LABEL, getTopLabel());
-
- }
-}
diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminUnregisterCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminUnregisterCommand.java
index 968ebf178..d4d730380 100644
--- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminUnregisterCommand.java
+++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminUnregisterCommand.java
@@ -116,7 +116,6 @@ public class AdminUnregisterCommand extends ConfirmableCommand {
targetIsland.getMembers().clear();
targetIsland.log(new LogEntry.Builder("UNREGISTER").data("player", targetUUID.toString())
.data("admin", user.getUniqueId().toString()).build());
- getIslands().save(targetIsland);
user.sendMessage("commands.admin.unregister.unregistered-island", TextVariables.XYZ, Util.xyz(targetIsland.getCenter().toVector()),
TextVariables.NAME, getPlayers().getName(targetUUID));
}
diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/conversations/NamePrompt.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/conversations/NamePrompt.java
index e0edd1b25..79776ed5b 100644
--- a/src/main/java/world/bentobox/bentobox/api/commands/admin/conversations/NamePrompt.java
+++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/conversations/NamePrompt.java
@@ -40,7 +40,6 @@ public class NamePrompt extends StringPrompt {
@Override
public Prompt acceptInput(@NonNull ConversationContext context, String input) {
if (island.renameHome(oldName, input)) {
- plugin.getIslands().save(island);
Bukkit.getScheduler().runTask(plugin, () -> user.sendMessage("general.success"));
} else {
Bukkit.getScheduler().runTask(plugin, () -> user.sendMessage("commands.island.renamehome.already-exists"));
diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandSettingsCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandSettingsCommand.java
index e37fd8ff2..027a16961 100644
--- a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandSettingsCommand.java
+++ b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandSettingsCommand.java
@@ -49,7 +49,8 @@ public class IslandSettingsCommand extends CompositeCommand {
.user(user)
.island(island)
.world(island.getWorld())
- .tab(1, new SettingsTab(user, Flag.Type.PROTECTION)).tab(2, new SettingsTab(user, Flag.Type.SETTING))
+ .tab(1, new SettingsTab(getWorld(), user, Flag.Type.PROTECTION))
+ .tab(2, new SettingsTab(getWorld(), user, Flag.Type.SETTING))
.startingSlot(1)
.size(54)
.hideIfEmpty()
diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/Invite.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/Invite.java
deleted file mode 100644
index c6328d066..000000000
--- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/Invite.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package world.bentobox.bentobox.api.commands.island.team;
-
-import java.util.Objects;
-import java.util.UUID;
-
-import world.bentobox.bentobox.database.objects.Island;
-
-/**
- * Represents an invite
- * @author tastybento
- * @since 1.8.0
- */
-public class Invite {
-
- /**
- * Type of invitation
- *
- */
- public enum Type {
- COOP,
- TEAM,
- TRUST
- }
-
- private final Type type;
- private final UUID inviter;
- private final UUID invitee;
- private final Island island;
-
- /**
- * @param type - invitation type, e.g., coop, team, trust
- * @param inviter - UUID of inviter
- * @param invitee - UUID of invitee
- * @param island - the island this invite is for
- */
- public Invite(Type type, UUID inviter, UUID invitee, Island island) {
- this.type = type;
- this.inviter = inviter;
- this.invitee = invitee;
- this.island = island;
- }
-
- /**
- * @return the type
- */
- public Type getType() {
- return type;
- }
-
- /**
- * @return the inviter
- */
- public UUID getInviter() {
- return inviter;
- }
-
- /**
- * @return the invitee
- */
- public UUID getInvitee() {
- return invitee;
- }
-
- /**
- * @return the island
- */
- public Island getIsland() {
- return island;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- return Objects.hash(invitee, inviter, type);
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (!(obj instanceof Invite other)) {
- return false;
- }
- return Objects.equals(invitee, other.invitee) && Objects.equals(inviter, other.inviter) && type == other.type;
- }
-}
diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCommand.java
index fd1d06e82..6cb702ea7 100644
--- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCommand.java
+++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCommand.java
@@ -1,9 +1,7 @@
package world.bentobox.bentobox.api.commands.island.team;
import java.io.File;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.UUID;
@@ -16,17 +14,13 @@ import world.bentobox.bentobox.api.events.team.TeamEvent;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.panels.reader.PanelTemplateRecord.TemplateItem;
import world.bentobox.bentobox.api.user.User;
+import world.bentobox.bentobox.database.Database;
import world.bentobox.bentobox.database.objects.Island;
+import world.bentobox.bentobox.database.objects.TeamInvite;
import world.bentobox.bentobox.managers.RanksManager;
public class IslandTeamCommand extends CompositeCommand {
- /**
- * Invited list. Key is the invited party, value is the invite.
- * @since 1.8.0
- */
- private final Map inviteMap;
-
private IslandTeamKickCommand kickCommand;
private IslandTeamLeaveCommand leaveCommand;
@@ -51,9 +45,11 @@ public class IslandTeamCommand extends CompositeCommand {
private IslandTeamTrustCommand trustCommand;
+ private final Database handler;
+
public IslandTeamCommand(CompositeCommand parent) {
super(parent, "team");
- inviteMap = new HashMap<>();
+ handler = new Database<>(parent.getAddon(), TeamInvite.class);
}
@Override
@@ -139,8 +135,8 @@ public class IslandTeamCommand extends CompositeCommand {
* @param invitee - uuid of invitee
* @since 1.8.0
*/
- public void addInvite(Invite.Type type, @NonNull UUID inviter, @NonNull UUID invitee, @NonNull Island island) {
- inviteMap.put(invitee, new Invite(type, inviter, invitee, island));
+ public void addInvite(TeamInvite.Type type, @NonNull UUID inviter, @NonNull UUID invitee, @NonNull Island island) {
+ handler.saveObjectAsync(new TeamInvite(type, inviter, invitee, island.getUniqueId()));
}
/**
@@ -150,7 +146,7 @@ public class IslandTeamCommand extends CompositeCommand {
* @since 1.8.0
*/
public boolean isInvited(@NonNull UUID invitee) {
- return inviteMap.containsKey(invitee);
+ return handler.objectExists(invitee.toString());
}
/**
@@ -161,7 +157,7 @@ public class IslandTeamCommand extends CompositeCommand {
*/
@Nullable
public UUID getInviter(UUID invitee) {
- return isInvited(invitee) ? inviteMap.get(invitee).getInviter() : null;
+ return isInvited(invitee) ? handler.loadObject(invitee.toString()).getInviter() : null;
}
/**
@@ -171,8 +167,8 @@ public class IslandTeamCommand extends CompositeCommand {
* @since 1.8.0
*/
@Nullable
- public Invite getInvite(UUID invitee) {
- return inviteMap.get(invitee);
+ public TeamInvite getInvite(UUID invitee) {
+ return handler.loadObject(invitee.toString());
}
/**
@@ -181,7 +177,7 @@ public class IslandTeamCommand extends CompositeCommand {
* @since 1.8.0
*/
public void removeInvite(@NonNull UUID invitee) {
- inviteMap.remove(invitee);
+ handler.deleteID(invitee.toString());
}
/**
diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCoopCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCoopCommand.java
index 246c38b21..45b84f904 100644
--- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCoopCommand.java
+++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCoopCommand.java
@@ -8,10 +8,10 @@ import java.util.UUID;
import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.api.commands.CompositeCommand;
-import world.bentobox.bentobox.api.commands.island.team.Invite.Type;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
+import world.bentobox.bentobox.database.objects.TeamInvite.Type;
import world.bentobox.bentobox.managers.RanksManager;
import world.bentobox.bentobox.util.Util;
@@ -99,7 +99,7 @@ public class IslandTeamCoopCommand extends CompositeCommand {
// Put the invited player (key) onto the list with inviter (value)
// If someone else has invited a player, then this invite will overwrite the
// previous invite!
- itc.addInvite(Invite.Type.COOP, user.getUniqueId(), target.getUniqueId(), island);
+ itc.addInvite(Type.COOP, user.getUniqueId(), target.getUniqueId(), island);
user.sendMessage("commands.island.team.invite.invitation-sent", TextVariables.NAME, target.getName());
// Send message to online player
target.sendMessage("commands.island.team.coop.name-has-invited-you", TextVariables.NAME,
diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamGUI.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamGUI.java
index 598e940a9..602fa2881 100644
--- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamGUI.java
+++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamGUI.java
@@ -22,7 +22,6 @@ import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.BentoBox;
-import world.bentobox.bentobox.api.commands.island.team.Invite.Type;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.panels.Panel;
import world.bentobox.bentobox.api.panels.PanelItem;
@@ -34,6 +33,8 @@ import world.bentobox.bentobox.api.panels.reader.ItemTemplateRecord.ActionRecord
import world.bentobox.bentobox.api.panels.reader.PanelTemplateRecord.TemplateItem;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
+import world.bentobox.bentobox.database.objects.TeamInvite;
+import world.bentobox.bentobox.database.objects.TeamInvite.Type;
import world.bentobox.bentobox.managers.RanksManager;
import world.bentobox.bentobox.util.Util;
@@ -208,7 +209,7 @@ public class IslandTeamGUI {
private PanelItem createInvitedButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot) {
PanelItemBuilder builder = new PanelItemBuilder();
if (parent.isInvited(user.getUniqueId()) && user.hasPermission(parent.getAcceptCommand().getPermission())) {
- Invite invite = parent.getInvite(user.getUniqueId());
+ TeamInvite invite = parent.getInvite(user.getUniqueId());
if (invite == null) {
return this.getBlankBorder();
}
@@ -224,7 +225,8 @@ public class IslandTeamGUI {
return builder.build();
}
- private void createInviteClickHandler(PanelItemBuilder builder, Invite invite, @NonNull List list) {
+ private void createInviteClickHandler(PanelItemBuilder builder, TeamInvite invite,
+ @NonNull List list) {
Type type = invite.getType();
builder.clickHandler((panel, user, clickType, clickSlot) -> {
if (list.stream().noneMatch(ar -> clickType.equals(ar.clickType()))) {
diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommand.java
index 88c91c162..3ba3013f1 100644
--- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommand.java
+++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommand.java
@@ -5,13 +5,14 @@ import java.util.UUID;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.commands.ConfirmableCommand;
-import world.bentobox.bentobox.api.commands.island.team.Invite.Type;
import world.bentobox.bentobox.api.events.IslandBaseEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent;
import world.bentobox.bentobox.api.events.team.TeamEvent;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
+import world.bentobox.bentobox.database.objects.TeamInvite;
+import world.bentobox.bentobox.database.objects.TeamInvite.Type;
import world.bentobox.bentobox.managers.RanksManager;
import world.bentobox.bentobox.util.Util;
@@ -49,7 +50,7 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand {
user.sendMessage(INVALID_INVITE);
return false;
}
- Invite invite = itc.getInvite(playerUUID);
+ TeamInvite invite = itc.getInvite(playerUUID);
if (invite.getType().equals(Type.TEAM)) {
// Check rank to of inviter
Island island = getIslands().getIsland(getWorld(), prospectiveOwnerUUID);
@@ -78,7 +79,7 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand {
@Override
public boolean execute(User user, String label, List args) {
// Get the invite
- Invite invite = itc.getInvite(user.getUniqueId());
+ TeamInvite invite = itc.getInvite(user.getUniqueId());
switch (invite.getType()) {
case COOP -> askConfirmation(user, () -> acceptCoopInvite(user, invite));
case TRUST -> askConfirmation(user, () -> acceptTrustInvite(user, invite));
@@ -94,11 +95,11 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand {
return true;
}
- void acceptTrustInvite(User user, Invite invite) {
+ void acceptTrustInvite(User user, TeamInvite invite) {
// Remove the invite
itc.removeInvite(user.getUniqueId());
User inviter = User.getInstance(invite.getInviter());
- Island island = invite.getIsland();
+ Island island = getIslands().getIslandById(invite.getIslandID()).orElse(null);
if (island != null) {
if (island.getMemberSet(RanksManager.TRUSTED_RANK, false).size() > getIslands().getMaxMembers(island,
RanksManager.TRUSTED_RANK)) {
@@ -120,11 +121,11 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand {
}
}
- void acceptCoopInvite(User user, Invite invite) {
+ void acceptCoopInvite(User user, TeamInvite invite) {
// Remove the invite
itc.removeInvite(user.getUniqueId());
User inviter = User.getInstance(invite.getInviter());
- Island island = invite.getIsland();
+ Island island = getIslands().getIslandById(invite.getIslandID()).orElse(null);
if (island != null) {
if (island.getMemberSet(RanksManager.COOP_RANK, false).size() > getIslands().getMaxMembers(island,
RanksManager.COOP_RANK)) {
@@ -146,13 +147,13 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand {
}
}
- void acceptTeamInvite(User user, Invite invite) {
+ void acceptTeamInvite(User user, TeamInvite invite) {
// Remove the invite
itc.removeInvite(user.getUniqueId());
// Get the player's island - may be null if the player has no island
List islands = getIslands().getIslands(getWorld(), user.getUniqueId());
// Get the team's island
- Island teamIsland = invite.getIsland();
+ Island teamIsland = getIslands().getIslandById(invite.getIslandID()).orElse(null);
if (teamIsland == null) {
user.sendMessage(INVALID_INVITE);
return;
@@ -196,7 +197,6 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand {
inviter.sendMessage("commands.island.team.invite.accept.name-joined-your-island", TextVariables.NAME,
user.getName(), TextVariables.DISPLAY_NAME, user.getDisplayName());
}
- getIslands().save(teamIsland);
// Fire event
TeamEvent.builder().island(teamIsland).reason(TeamEvent.Reason.JOINED).involvedPlayer(user.getUniqueId())
.build();
diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteCommand.java
index 77a37dd30..82d2bf4dd 100644
--- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteCommand.java
+++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteCommand.java
@@ -10,13 +10,13 @@ import java.util.UUID;
import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.api.commands.CompositeCommand;
-import world.bentobox.bentobox.api.commands.island.team.Invite.Type;
import world.bentobox.bentobox.api.events.IslandBaseEvent;
import world.bentobox.bentobox.api.events.team.TeamEvent;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.panels.reader.PanelTemplateRecord.TemplateItem;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
+import world.bentobox.bentobox.database.objects.TeamInvite.Type;
import world.bentobox.bentobox.managers.IslandsManager;
import world.bentobox.bentobox.managers.PlayersManager;
import world.bentobox.bentobox.managers.RanksManager;
@@ -166,7 +166,7 @@ public class IslandTeamInviteCommand extends CompositeCommand {
}
// Put the invited player (key) onto the list with inviter (value)
// If someone else has invited a player, then this invite will overwrite the previous invite!
- itc.addInvite(Invite.Type.TEAM, user.getUniqueId(), invitedPlayer.getUniqueId(), island);
+ itc.addInvite(Type.TEAM, user.getUniqueId(), invitedPlayer.getUniqueId(), island);
user.sendMessage("commands.island.team.invite.invitation-sent", TextVariables.NAME, invitedPlayer.getName(), TextVariables.DISPLAY_NAME, invitedPlayer.getDisplayName());
// Send message to online player
invitedPlayer.sendMessage("commands.island.team.invite.name-has-invited-you", TextVariables.NAME, user.getName(), TextVariables.DISPLAY_NAME, user.getDisplayName());
diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommand.java
index e80580aa9..67827a1d8 100644
--- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommand.java
+++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommand.java
@@ -14,6 +14,7 @@ import world.bentobox.bentobox.api.events.team.TeamEvent;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
+import world.bentobox.bentobox.managers.IslandsManager;
import world.bentobox.bentobox.managers.RanksManager;
import world.bentobox.bentobox.util.Util;
@@ -91,7 +92,6 @@ public class IslandTeamSetownerCommand extends CompositeCommand {
IslandEvent.builder().island(island).involvedPlayer(user.getUniqueId()).admin(false)
.reason(IslandEvent.Reason.RANK_CHANGE).rankChange(RanksManager.OWNER_RANK, RanksManager.SUB_OWNER_RANK)
.build();
- getIslands().save(island);
return true;
}
diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamTrustCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamTrustCommand.java
index 8d57871df..38c0349f7 100644
--- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamTrustCommand.java
+++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamTrustCommand.java
@@ -8,10 +8,10 @@ import java.util.UUID;
import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.api.commands.CompositeCommand;
-import world.bentobox.bentobox.api.commands.island.team.Invite.Type;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
+import world.bentobox.bentobox.database.objects.TeamInvite.Type;
import world.bentobox.bentobox.managers.RanksManager;
import world.bentobox.bentobox.util.Util;
diff --git a/src/main/java/world/bentobox/bentobox/api/flags/Flag.java b/src/main/java/world/bentobox/bentobox/api/flags/Flag.java
index d28bc0add..89b13cb09 100644
--- a/src/main/java/world/bentobox/bentobox/api/flags/Flag.java
+++ b/src/main/java/world/bentobox/bentobox/api/flags/Flag.java
@@ -388,21 +388,24 @@ public class Flag implements Comparable {
if (!user.isOp() && invisible) {
return null;
}
- // Start the flag conversion
PanelItemBuilder pib = new PanelItemBuilder()
.icon(ItemParser.parse(user.getTranslationOrNothing(this.getIconReference()), new ItemStack(icon)))
- .name(user.getTranslation("protection.panel.flag-item.name-layout", TextVariables.NAME, user.getTranslation(getNameReference())))
+ .name(user.getTranslation("protection.panel.flag-item.name-layout", TextVariables.NAME,
+ user.getTranslation(getNameReference())))
.clickHandler(clickHandler)
.invisible(invisible);
if (hasSubPanel()) {
pib.description(user.getTranslation("protection.panel.flag-item.menu-layout", TextVariables.DESCRIPTION, user.getTranslation(getDescriptionReference())));
return pib.build();
}
+
return switch (getType()) {
case PROTECTION -> createProtectionFlag(plugin, user, island, pib).build();
case SETTING -> createSettingFlag(user, island, pib).build();
case WORLD_SETTING -> createWorldSettingFlag(user, world, pib).build();
+
};
+
}
private PanelItemBuilder createWorldSettingFlag(User user, World world, PanelItemBuilder pib) {
@@ -429,19 +432,24 @@ public class Flag implements Comparable {
private PanelItemBuilder createProtectionFlag(BentoBox plugin, User user, Island island, PanelItemBuilder pib) {
if (island != null) {
+ int y = island.getFlag(this);
// Protection flag
+
pib.description(user.getTranslation("protection.panel.flag-item.description-layout",
TextVariables.DESCRIPTION, user.getTranslation(getDescriptionReference())));
+
RanksManager.getInstance().getRanks().forEach((reference, score) -> {
- if (score > RanksManager.BANNED_RANK && score < island.getFlag(this)) {
+
+ if (score > RanksManager.BANNED_RANK && score < y) {
pib.description(user.getTranslation("protection.panel.flag-item.blocked-rank") + user.getTranslation(reference));
- } else if (score <= RanksManager.OWNER_RANK && score > island.getFlag(this)) {
+ } else if (score <= RanksManager.OWNER_RANK && score > y) {
pib.description(user.getTranslation("protection.panel.flag-item.allowed-rank") + user.getTranslation(reference));
- } else if (score == island.getFlag(this)) {
+ } else if (score == y) {
pib.description(user.getTranslation("protection.panel.flag-item.minimal-rank") + user.getTranslation(reference));
}
});
}
+
return pib;
}
@@ -469,7 +477,7 @@ public class Flag implements Comparable {
public Set getSubflags() {
return subflags;
}
-
+
/**
* Set the name of this flag for a specified locale. This enables the flag's name to be assigned via API. It will not be stored anywhere
* and must be rewritten using this call every time the flag is built.
@@ -482,7 +490,7 @@ public class Flag implements Comparable {
public boolean setTranslatedName(Locale locale, String name) {
return BentoBox.getInstance().getLocalesManager().setTranslation(locale, getNameReference(), name);
}
-
+
/**
* Set the name of this flag for a specified locale. This enables the flag's name to be assigned via API. It will not be stored anywhere
* and must be rewritten using this call every time the flag is built.
diff --git a/src/main/java/world/bentobox/bentobox/api/panels/TabbedPanel.java b/src/main/java/world/bentobox/bentobox/api/panels/TabbedPanel.java
index cc1a41290..3c93ad8a6 100644
--- a/src/main/java/world/bentobox/bentobox/api/panels/TabbedPanel.java
+++ b/src/main/java/world/bentobox/bentobox/api/panels/TabbedPanel.java
@@ -74,6 +74,7 @@ public class TabbedPanel extends Panel implements PanelListener {
* @param page - the page of the tab to show (if multi paged)
*/
public void openPanel(int activeTab, int page) {
+
if (!tpb.getTabs().containsKey(activeTab)) {
// Request to open a non-existent tab
throw new InvalidParameterException("Attempt to open a non-existent tab in a tabbed panel. Missing tab #" + activeTab);
@@ -88,21 +89,17 @@ public class TabbedPanel extends Panel implements PanelListener {
TreeMap items = new TreeMap<>();
// Get the tab
Tab tab = tpb.getTabs().get(activeTab);
-
// Remove any tabs that have no items, if required
if (tpb.isHideIfEmpty()) {
tpb.getTabs().values().removeIf(t -> !t.equals(tab) && t.getPanelItems().stream().noneMatch(Objects::nonNull));
}
-
// Set up the tabbed header
setupHeader(tab, items);
-
// Show the active tab
if (tpb.getTabs().containsKey(activeTab)) {
List panelItems = tab.getPanelItems();
// Adds the flag items
panelItems.stream().filter(Objects::nonNull).skip(page * ITEMS_PER_PAGE).limit(page * ITEMS_PER_PAGE + ITEMS_PER_PAGE).forEach(i -> items.put(items.lastKey() + 1, i));
-
// set up the footer
setupFooter(items);
// Add forward and backward icons
@@ -182,6 +179,7 @@ public class TabbedPanel extends Panel implements PanelListener {
// Reset the closed flag
closed = false;
}
+
}
/**
diff --git a/src/main/java/world/bentobox/bentobox/database/objects/Island.java b/src/main/java/world/bentobox/bentobox/database/objects/Island.java
index 60d95c89f..2be8fa824 100644
--- a/src/main/java/world/bentobox/bentobox/database/objects/Island.java
+++ b/src/main/java/world/bentobox/bentobox/database/objects/Island.java
@@ -13,6 +13,7 @@ import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import org.bukkit.Bukkit;
@@ -41,6 +42,7 @@ import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.adapters.Adapter;
import world.bentobox.bentobox.database.objects.adapters.LogEntryListAdapter;
import world.bentobox.bentobox.lists.Flags;
+import world.bentobox.bentobox.managers.IslandsManager;
import world.bentobox.bentobox.managers.RanksManager;
import world.bentobox.bentobox.util.Pair;
import world.bentobox.bentobox.util.Util;
@@ -56,7 +58,7 @@ import world.bentobox.bentobox.util.Util;
public class Island implements DataObject, MetaDataAble {
@Expose
- private boolean primary;
+ private Set primaries = new HashSet<>();
/**
* Set to true if this data object has been changed since being loaded from the
@@ -243,7 +245,6 @@ public class Island implements DataObject, MetaDataAble {
range = BentoBox.getInstance().getIWM().getIslandDistance(world);
this.protectionRange = protectionRange;
this.maxEverProtectionRange = protectionRange;
- this.setChanged();
}
/**
@@ -290,6 +291,7 @@ public class Island implements DataObject, MetaDataAble {
this.updatedDate = island.getUpdatedDate();
this.world = island.getWorld();
this.bonusRanges.addAll(island.getBonusRanges());
+ this.primaries.addAll(island.getPrimaries());
this.setChanged();
}
@@ -304,8 +306,10 @@ public class Island implements DataObject, MetaDataAble {
* @param playerUUID - the player's UUID
*/
public void addMember(@NonNull UUID playerUUID) {
- setRank(playerUUID, RanksManager.MEMBER_RANK);
- setChanged();
+ if (getRank(playerUUID) != RanksManager.MEMBER_RANK) {
+ setRank(playerUUID, RanksManager.MEMBER_RANK);
+ setChanged();
+ }
}
/**
@@ -320,9 +324,12 @@ public class Island implements DataObject, MetaDataAble {
* @return {@code true}
*/
public boolean ban(@NonNull UUID issuer, @NonNull UUID target) {
- setRank(target, RanksManager.BANNED_RANK);
- log(new LogEntry.Builder("BAN").data("player", target.toString()).data("issuer", issuer.toString()).build());
- setChanged();
+ if (getRank(target) != RanksManager.BANNED_RANK) {
+ setRank(target, RanksManager.BANNED_RANK);
+ log(new LogEntry.Builder("BAN").data("player", target.toString()).data("issuer", issuer.toString())
+ .build());
+ setChanged();
+ }
return true;
}
@@ -1005,25 +1012,30 @@ public class Island implements DataObject, MetaDataAble {
* @param playerUUID - uuid of player
*/
public void removeMember(UUID playerUUID) {
- members.remove(playerUUID);
- setChanged();
+ if (members.remove(playerUUID) != null) {
+ setChanged();
+ }
}
/**
* @param center the center to set
*/
public void setCenter(@NonNull Location center) {
- this.world = center.getWorld();
- this.center = center;
- setChanged();
+ if (this.center == null || !center.getWorld().equals(this.center.getWorld()) || !center.equals(this.center)) {
+ this.world = center.getWorld();
+ this.center = center;
+ setChanged();
+ }
}
/**
* @param createdDate - the createdDate to sets
*/
public void setCreatedDate(long createdDate) {
- this.createdDate = createdDate;
- setChanged();
+ if (this.createdDate != createdDate) {
+ this.createdDate = createdDate;
+ setChanged();
+ }
}
/**
@@ -1038,21 +1050,23 @@ public class Island implements DataObject, MetaDataAble {
}
/**
- * Set the Island Guard flag rank Also specify whether subflags are affected by
- * this method call
+ * Set the Island Guard flag rank and set any subflags
*
* @param flag - flag
* @param value - Use RanksManager settings, e.g. RanksManager.MEMBER
* @param doSubflags - whether to set subflags
+ * @return true if this causes a flag change
*/
public void setFlag(Flag flag, int value, boolean doSubflags) {
- flags.put(flag.getID(), value);
+ if (flags.containsKey(flag.getID()) && flags.get(flag.getID()) != value) {
+ flags.put(flag.getID(), value);
+ setChanged();
+ }
// Subflag support
if (doSubflags && flag.hasSubflags()) {
// Ensure that a subflag isn't a subflag of itself or else we're in trouble!
flag.getSubflags().forEach(subflag -> setFlag(subflag, value, true));
}
- setChanged();
}
/**
@@ -1078,7 +1092,6 @@ public class Island implements DataObject, MetaDataAble {
.forEach(f -> result.put(f.getID(),
plugin.getIWM().getDefaultIslandSettings(world).getOrDefault(f, f.getDefaultRank())));
this.setFlags(result);
- setChanged();
}
/**
@@ -1097,8 +1110,10 @@ public class Island implements DataObject, MetaDataAble {
* @param name The display name to set.
*/
public void setName(String name) {
- this.name = (name != null && !name.equals("")) ? name : null;
- setChanged();
+ if (name == null || !name.equals(this.name)) {
+ this.name = (name != null && !name.equals("")) ? name : null;
+ setChanged();
+ }
}
/**
@@ -1130,9 +1145,11 @@ public class Island implements DataObject, MetaDataAble {
* @param protectionRange the protectionRange to set
*/
public void setProtectionRange(int protectionRange) {
- this.protectionRange = protectionRange;
- this.updateMaxEverProtectionRange();
- setChanged();
+ if (this.protectionRange != protectionRange) {
+ this.protectionRange = protectionRange;
+ this.updateMaxEverProtectionRange();
+ setChanged();
+ }
}
/**
@@ -1164,8 +1181,10 @@ public class Island implements DataObject, MetaDataAble {
* @param purgeProtected - if the island is protected from the Purge
*/
public void setPurgeProtected(boolean purgeProtected) {
- this.purgeProtected = purgeProtected;
- setChanged();
+ if (this.purgeProtected != purgeProtected) {
+ this.purgeProtected = purgeProtected;
+ setChanged();
+ }
}
/**
@@ -1179,8 +1198,10 @@ public class Island implements DataObject, MetaDataAble {
* @see #setProtectionRange(int)
*/
public void setRange(int range) {
- this.range = range;
- setChanged();
+ if (this.range != range) {
+ this.range = range;
+ setChanged();
+ }
}
/**
@@ -1191,7 +1212,6 @@ public class Island implements DataObject, MetaDataAble {
*/
public void setRank(User user, int rank) {
setRank(user.getUniqueId(), rank);
- setChanged();
}
/**
@@ -1202,14 +1222,33 @@ public class Island implements DataObject, MetaDataAble {
* @param rank rank value
* @since 1.1
*/
- public void setRank(@Nullable UUID uuid, int rank) {
+ public void setRank(@Nullable UUID uuid, int newRank) {
+ // Early return if the UUID is null, to avoid unnecessary processing.
if (uuid == null) {
- return; // Defensive code
+ return;
+ }
+
+ // Use an AtomicBoolean to track if the member's rank has been changed.
+ AtomicBoolean isRankChanged = new AtomicBoolean(false);
+
+ // Attempt to update the member's rank, if necessary.
+ members.compute(uuid, (key, existingRank) -> {
+ // If the member does not exist or their rank is different, update the rank.
+ if (existingRank == null || existingRank != newRank) {
+ isRankChanged.set(true);
+ return newRank; // Update the rank.
+ }
+ // No change needed; return the existing rank.
+ return existingRank;
+ });
+
+ // If the rank was changed, notify the change and log the update.
+ if (isRankChanged.get()) {
+ setChanged(); // Notify that a change has occurred.
}
- members.put(uuid, rank);
- setChanged();
}
+
/**
* @param ranks the ranks to set
*/
@@ -1266,7 +1305,6 @@ public class Island implements DataObject, MetaDataAble {
@Override
public void setUniqueId(String uniqueId) {
this.uniqueId = uniqueId;
- setChanged();
}
/**
@@ -1274,7 +1312,6 @@ public class Island implements DataObject, MetaDataAble {
*/
public void setUpdatedDate(long updatedDate) {
this.updatedDate = updatedDate;
- setChanged();
}
/**
@@ -1347,8 +1384,13 @@ public class Island implements DataObject, MetaDataAble {
* @param l - location
*/
public void setSpawnPoint(Environment islandType, Location l) {
- spawnPoint.put(islandType, l);
- setChanged();
+ spawnPoint.compute(islandType, (key, value) -> {
+ if (value == null || !value.equals(l)) {
+ setChanged(); // Call setChanged only if the value is updated.
+ return l;
+ }
+ return value;
+ });
}
/**
@@ -1368,8 +1410,9 @@ public class Island implements DataObject, MetaDataAble {
* @param rank rank value
*/
public void removeRank(Integer rank) {
- members.values().removeIf(rank::equals);
- setChanged();
+ if (members.values().removeIf(rank::equals)) {
+ setChanged();
+ }
}
/**
@@ -1455,7 +1498,6 @@ public class Island implements DataObject, MetaDataAble {
*/
public void setGameMode(String gameMode) {
this.gameMode = gameMode;
- setChanged();
}
/**
@@ -1518,8 +1560,9 @@ public class Island implements DataObject, MetaDataAble {
if (cooldowns.containsKey(flag.getID()) && cooldowns.get(flag.getID()) > System.currentTimeMillis()) {
return true;
}
- cooldowns.remove(flag.getID());
- setChanged();
+ if (cooldowns.remove(flag.getID()) != null) {
+ setChanged();
+ }
return false;
}
@@ -1603,8 +1646,13 @@ public class Island implements DataObject, MetaDataAble {
public void setRankCommand(String command, int rank) {
if (this.commandRanks == null)
this.commandRanks = new HashMap<>();
- this.commandRanks.put(command, rank);
- setChanged();
+ commandRanks.compute(command, (key, value) -> {
+ if (value == null || !value.equals(rank)) {
+ setChanged(); // Call setChanged only if the value is updated.
+ return rank;
+ }
+ return value;
+ });
}
/**
@@ -1624,8 +1672,10 @@ public class Island implements DataObject, MetaDataAble {
* @since 1.6.0
*/
public void setReserved(boolean reserved) {
- this.reserved = reserved;
- setChanged();
+ if (this.reserved != reserved) {
+ this.reserved = reserved;
+ setChanged();
+ }
}
/**
@@ -1658,17 +1708,19 @@ public class Island implements DataObject, MetaDataAble {
}
/**
- * Indicates the fields have been changed. Used to optimize saving on shutdown.
+ * Indicates the fields have been changed. Used to optimize saving on shutdown and notify other servers
*/
public void setChanged() {
+ this.setUpdatedDate(System.currentTimeMillis());
this.changed = true;
+ IslandsManager.updateIsland(this);
}
/**
- * @param changed the changed to set
+ * Resets the changed if the island has been saved
*/
- public void setChanged(boolean changed) {
- this.changed = changed;
+ public void clearChanged() {
+ this.changed = false;
}
/**
@@ -1692,6 +1744,9 @@ public class Island implements DataObject, MetaDataAble {
* @since 1.16.0
*/
public void setProtectionCenter(Location location) throws IOException {
+ if (this.location.equals(location)) {
+ return; // nothing to do
+ }
if (!this.inIslandSpace(location)) {
throw new IOException("Location must be in island space");
}
@@ -1741,6 +1796,9 @@ public class Island implements DataObject, MetaDataAble {
* @since 1.16.0
*/
public void addHome(String name, Location location) {
+ if (getHomes().containsKey(name) && getHomes().get(name).equals(location)) {
+ return; // nothing to do
+ }
if (location != null) {
Vector v = location.toVector();
if (!this.getBoundingBox().contains(v)) {
@@ -1763,8 +1821,11 @@ public class Island implements DataObject, MetaDataAble {
* @since 1.16.0
*/
public boolean removeHome(String name) {
- setChanged();
- return getHomes().remove(name.toLowerCase()) != null;
+ if (getHomes().remove(name.toLowerCase()) != null) {
+ setChanged();
+ return true;
+ }
+ return false;
}
/**
@@ -1774,8 +1835,11 @@ public class Island implements DataObject, MetaDataAble {
* @since 1.20.0
*/
public boolean removeHomes() {
- setChanged();
- return getHomes().keySet().removeIf(k -> !k.isEmpty());
+ if (getHomes().keySet().removeIf(k -> !k.isEmpty())) {
+ setChanged();
+ return true;
+ }
+ return false;
}
/**
@@ -1814,8 +1878,10 @@ public class Island implements DataObject, MetaDataAble {
* @since 1.16.0
*/
public void setMaxHomes(@Nullable Integer maxHomes) {
- this.maxHomes = maxHomes;
- setChanged();
+ if (this.maxHomes != maxHomes) {
+ this.maxHomes = maxHomes;
+ setChanged();
+ }
}
/**
@@ -1834,8 +1900,10 @@ public class Island implements DataObject, MetaDataAble {
* @since 1.16.0
*/
public void setMaxMembers(Map maxMembers) {
- this.maxMembers = maxMembers;
- setChanged();
+ if (this.maxMembers != maxMembers) {
+ this.maxMembers = maxMembers;
+ setChanged();
+ }
}
/**
@@ -1860,7 +1928,13 @@ public class Island implements DataObject, MetaDataAble {
* @since 1.16.0
*/
public void setMaxMembers(int rank, Integer maxMembers) {
- getMaxMembers().put(rank, maxMembers);
+ getMaxMembers().compute(rank, (key, value) -> {
+ if (value == null || !value.equals(maxMembers)) {
+ setChanged(); // Call setChanged only if the value is updated.
+ return maxMembers;
+ }
+ return value;
+ });
}
/**
@@ -1923,8 +1997,9 @@ public class Island implements DataObject, MetaDataAble {
* @param id id to identify this bonus
*/
public void clearBonusRange(String id) {
- this.getBonusRanges().removeIf(r -> r.getUniqueId().equals(id));
- setChanged();
+ if (this.getBonusRanges().removeIf(r -> r.getUniqueId().equals(id))) {
+ setChanged();
+ }
}
/**
@@ -1936,18 +2011,30 @@ public class Island implements DataObject, MetaDataAble {
}
/**
+ * @param userID user UUID
* @return the primary
*/
- public boolean isPrimary() {
- return primary;
+ public boolean isPrimary(UUID userID) {
+ return getPrimaries().contains(userID);
}
/**
* @param primary the primary to set
*/
- public void setPrimary(boolean primary) {
- this.primary = primary;
- setChanged();
+ public void setPrimary(UUID userID) {
+ if (getPrimaries().add(userID)) {
+ setChanged();
+ }
+ }
+
+ /**
+ * Remove the primary island
+ * @param userID user UUID
+ */
+ public void removePrimary(UUID userID) {
+ if (getPrimaries().remove(userID)) {
+ setChanged();
+ }
}
/**
@@ -1986,4 +2073,41 @@ public class Island implements DataObject, MetaDataAble {
+ commandRanks + ", reserved=" + reserved + ", metaData=" + metaData + ", homes=" + homes
+ ", maxHomes=" + maxHomes + "]";
}
+
+ /**
+ * @return the primaries
+ */
+ public Set getPrimaries() {
+ if (primaries == null) {
+ primaries = new HashSet<>();
+ }
+ return primaries;
+ }
+
+ /**
+ * @param primaries the primaries to set
+ */
+ public void setPrimaries(Set primaries) {
+ this.primaries = primaries;
+ setChanged();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(uniqueId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Island other = (Island) obj;
+ return Objects.equals(uniqueId, other.uniqueId);
+ }
+
+
}
diff --git a/src/main/java/world/bentobox/bentobox/database/objects/Players.java b/src/main/java/world/bentobox/bentobox/database/objects/Players.java
index 3cf06d2c0..ca384ed12 100644
--- a/src/main/java/world/bentobox/bentobox/database/objects/Players.java
+++ b/src/main/java/world/bentobox/bentobox/database/objects/Players.java
@@ -6,13 +6,10 @@ import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
-import java.util.stream.Collectors;
import org.bukkit.Bukkit;
-import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
-import org.eclipse.jdt.annotation.Nullable;
import com.google.gson.annotations.Expose;
@@ -30,8 +27,6 @@ import world.bentobox.bentobox.util.Util;
*/
@Table(name = "Players")
public class Players implements DataObject, MetaDataAble {
- @Expose
- private Map homeLocations = new HashMap<>();
@Expose
private String uniqueId;
@Expose
@@ -77,7 +72,6 @@ public class Players implements DataObject, MetaDataAble {
*/
public Players(BentoBox plugin, UUID uniqueId) {
this.uniqueId = uniqueId.toString();
- homeLocations = new HashMap<>();
locale = "";
// Try to get player's name
this.playerName = Bukkit.getOfflinePlayer(uniqueId).getName();
@@ -86,72 +80,6 @@ public class Players implements DataObject, MetaDataAble {
}
}
- /**
- * Gets the default home location.
- * @param world - world to check
- * @return Location - home location in world
- * @deprecated Homes are stored in the Island object now
- */
- @Deprecated(since="1.18.0", forRemoval=true)
- @Nullable
- public Location getHomeLocation(World world) {
- return getHomeLocation(world, 1); // Default
- }
-
- /**
- * Gets the home location by number for world
- * @param world - includes world and any related nether or end worlds
- * @param number - a number
- * @return Location of this home or null if not available
- * @deprecated Homes are stored in the island object now
- */
- @Deprecated(since="1.18.0", forRemoval=true)
- @Nullable
- public Location getHomeLocation(World world, int number) {
- // Remove any lost worlds/locations
- homeLocations.keySet().removeIf(l -> l == null || l.getWorld() == null);
- return homeLocations.entrySet().stream()
- .filter(en -> Util.sameWorld(en.getKey().getWorld(), world) && en.getValue() == number)
- .map(Map.Entry::getKey)
- .findFirst()
- .orElse(null);
- }
-
- /**
- * @param world - world
- * @return Map of home locations
- * @deprecated Homes are stored in the island object now
- */
- @Deprecated(since="1.18.0", forRemoval=true)
- public Map getHomeLocations(World world) {
- // Remove any lost worlds/locations
- homeLocations.keySet().removeIf(l -> l == null || l.getWorld() == null);
- return homeLocations.entrySet().stream().filter(e -> Util.sameWorld(e.getKey().getWorld(),world))
- .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
- }
-
- /**
- * @return the homeLocations
- * @deprecated Homes are stored in the Island object now
- */
- @Deprecated(since="1.18.0", forRemoval=true)
- public Map getHomeLocations() {
- // Remove any lost worlds/locations
- homeLocations.keySet().removeIf(l -> l == null || l.getWorld() == null);
- return homeLocations;
- }
-
- /**
- * @param homeLocations the homeLocations to set
- * @deprecated Homes are stored in the Island object now
- */
- @Deprecated(since="1.18.0", forRemoval=true)
- public void setHomeLocations(Map homeLocations) {
- this.homeLocations = homeLocations;
- // Remove any lost worlds/locations
- homeLocations.keySet().removeIf(l -> l == null || l.getWorld() == null);
- }
-
/**
* @param playerName the playerName to set
*/
@@ -202,30 +130,6 @@ public class Players implements DataObject, MetaDataAble {
this.resets.put(world.getName(), resets);
}
- /**
- * Stores the home location of the player in a String format
- *
- * @param l a Bukkit location
- * @deprecated Home locations are stored in islands
- */
- @Deprecated(since="1.18.0", forRemoval=true)
- public void setHomeLocation(final Location l) {
- setHomeLocation(l, 1);
- }
-
- /**
- * Stores the numbered home location of the player. Numbering starts at 1.
- * @param location - the location
- * @param number - a number
- * @deprecated Home locations are no longer stored for players. They are stored in islands.
- */
- @Deprecated(since="1.18.0", forRemoval=true)
- public void setHomeLocation(Location location, int number) {
- // Remove any home locations in the same world with the same number
- homeLocations.entrySet().removeIf(e -> e.getKey() == null || (Util.sameWorld(location.getWorld(), e.getKey().getWorld()) && e.getValue().equals(number)));
- homeLocations.put(location, number);
- }
-
/**
* Set the uuid for this player object
* @param uuid - UUID
@@ -234,16 +138,6 @@ public class Players implements DataObject, MetaDataAble {
uniqueId = uuid.toString();
}
- /**
- * Clears all home Locations in world
- * @param world - world
- * @deprecated Home locations are no longer stored for players. Use {@link world.bentobox.bentobox.managers.IslandsManager}
- */
- @Deprecated(since="1.18.0", forRemoval=true)
- public void clearHomeLocations(World world) {
- homeLocations.keySet().removeIf(l -> l == null || l.getWorld() == null || Util.sameWorld(l.getWorld(), world));
- }
-
/**
* @return the locale
*/
@@ -350,24 +244,6 @@ public class Players implements DataObject, MetaDataAble {
}
}
- /**
- * Returns the display mode for the Flags in the Settings Panel.
- * @return the display mode for the Flags in the Settings Panel.
- * @since 1.6.0
- */
- public Flag.Mode getFlagsDisplayMode() {
- return flagsDisplayMode;
- }
-
- /**
- * Sets the display mode for the Flags in the Settings Panel.
- * @param flagsDisplayMode the display mode for the Flags in the Settings Panel.
- * @since 1.6.0
- */
- public void setFlagsDisplayMode(Flag.Mode flagsDisplayMode) {
- this.flagsDisplayMode = flagsDisplayMode;
- }
-
/**
* @return the metaData
* @since 1.15.5
diff --git a/src/main/java/world/bentobox/bentobox/database/objects/TeamInvite.java b/src/main/java/world/bentobox/bentobox/database/objects/TeamInvite.java
new file mode 100644
index 000000000..70634fc4b
--- /dev/null
+++ b/src/main/java/world/bentobox/bentobox/database/objects/TeamInvite.java
@@ -0,0 +1,112 @@
+package world.bentobox.bentobox.database.objects;
+
+import java.util.Objects;
+import java.util.UUID;
+
+import com.google.gson.annotations.Expose;
+
+/**
+ * Data object for team invites
+ */
+@Table(name = "TeamInvites")
+public class TeamInvite implements DataObject {
+
+ /**
+ * Type of invitation
+ *
+ */
+ public enum Type {
+ COOP,
+ TEAM,
+ TRUST
+ }
+
+ @Expose
+ private Type type;
+ @Expose
+ private UUID inviter;
+ @Expose
+ private String islandID;
+
+ @Expose
+ private String uniqueId;
+
+ /**
+ * @param type - invitation type, e.g., coop, team, trust
+ * @param inviter - UUID of inviter
+ * @param invitee - UUID of invitee
+ * @param island - the unique ID of the island this invite is for
+ */
+ public TeamInvite(Type type, UUID inviter, UUID invitee, String islandID) {
+ this.type = type;
+ this.uniqueId = invitee.toString();
+ this.inviter = inviter;
+ this.islandID = islandID;
+ }
+
+ @Override
+ public String getUniqueId() {
+ // Inviter
+ return this.uniqueId;
+ }
+
+ @Override
+ public void setUniqueId(String uniqueId) {
+ this.uniqueId = uniqueId;
+ }
+
+ /**
+ * @return the type
+ */
+ public Type getType() {
+ return type;
+ }
+
+ /**
+ * @return the invitee
+ */
+ public UUID getInvitee() {
+ return UUID.fromString(uniqueId);
+ }
+
+ /**
+ * @return the inviter
+ */
+ public UUID getInviter() {
+ return inviter;
+ }
+
+ /**
+ * @return the islandID
+ */
+ public String getIslandID() {
+ return islandID;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return Objects.hash(inviter, uniqueId, type);
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof TeamInvite other)) {
+ return false;
+ }
+ return Objects.equals(inviter, other.inviter) && Objects.equals(uniqueId, other.getUniqueId())
+ && type == other.type;
+ }
+
+}
diff --git a/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java b/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java
index f73f3dac3..0fdee8507 100644
--- a/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java
+++ b/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java
@@ -2,6 +2,7 @@ package world.bentobox.bentobox.listeners;
import java.util.Collections;
import java.util.Objects;
+import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit;
@@ -61,7 +62,7 @@ public class JoinLeaveListener implements Listener {
// Make sure the player is loaded into the cache or create the player if they
// don't exist
- players.addPlayer(playerUUID);
+ players.getPlayer(playerUUID);
// Reset island resets if required
plugin.getIWM().getOverWorlds().stream()
@@ -74,7 +75,6 @@ public class JoinLeaveListener implements Listener {
// Set the player's name (it may have changed), but only if it isn't empty
if (!user.getName().isEmpty()) {
players.setPlayerName(user);
- players.save(playerUUID);
} else {
plugin.logWarning("Player that just logged in has no name! " + playerUUID);
}
@@ -110,7 +110,7 @@ public class JoinLeaveListener implements Listener {
private void firstTime(User user) {
// Make sure the player is loaded into the cache or create the player if they
// don't exist
- players.addPlayer(user.getUniqueId());
+ players.getPlayer(user.getUniqueId());
plugin.getIWM().getOverWorlds().stream().filter(w -> plugin.getIWM().isCreateIslandOnFirstLoginEnabled(w))
.forEach(w -> {
@@ -181,8 +181,10 @@ public class JoinLeaveListener implements Listener {
user.getPlayer().getInventory().clear();
}
- playerData.getPendingKicks().remove(world.getName());
- players.save(user.getUniqueId());
+ Set kicks = playerData.getPendingKicks();
+ kicks.remove(world.getName());
+ playerData.setPendingKicks(kicks);
+
}
}
@@ -236,7 +238,6 @@ public class JoinLeaveListener implements Listener {
});
// Remove any coop associations from the player logging out
plugin.getIslands().clearRank(RanksManager.COOP_RANK, event.getPlayer().getUniqueId());
- players.save(event.getPlayer().getUniqueId());
User.removePlayer(event.getPlayer());
}
}
diff --git a/src/main/java/world/bentobox/bentobox/listeners/PanelListenerManager.java b/src/main/java/world/bentobox/bentobox/listeners/PanelListenerManager.java
index 53d402c5e..6cb57fd45 100644
--- a/src/main/java/world/bentobox/bentobox/listeners/PanelListenerManager.java
+++ b/src/main/java/world/bentobox/bentobox/listeners/PanelListenerManager.java
@@ -61,6 +61,7 @@ public class PanelListenerManager implements Listener {
// Refresh
l.refreshPanel();
});
+
} else {
// Wrong name - delete this panel
openPanels.remove(user.getUniqueId());
diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandCycleClick.java b/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandCycleClick.java
index 8b78b725d..d5891191b 100644
--- a/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandCycleClick.java
+++ b/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandCycleClick.java
@@ -60,9 +60,6 @@ public class CommandCycleClick implements ClickHandler {
}
// Apply change to panel
panel.getInventory().setItem(slot, commandRankClickListener.getPanelItem(command, user, world).getItem());
- // Save island
- plugin.getIslands().save(island);
-
} else {
user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F);
}
diff --git a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java
index 486edb811..f1741721f 100644
--- a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java
+++ b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java
@@ -37,6 +37,10 @@ import org.bukkit.util.Vector;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
+import com.github.puregero.multilib.MultiLib;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
import io.papermc.lib.PaperLib;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.events.IslandBaseEvent;
@@ -44,9 +48,9 @@ import world.bentobox.bentobox.api.events.island.IslandEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent.Reason;
import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.localization.TextVariables;
-import world.bentobox.bentobox.api.logs.LogEntry;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.Database;
+import world.bentobox.bentobox.database.json.BentoboxTypeAdapterFactory;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.database.objects.IslandDeletion;
import world.bentobox.bentobox.lists.Flags;
@@ -65,29 +69,18 @@ public class IslandsManager {
private final BentoBox plugin;
- /**
- * One island can be spawn, this is the one - otherwise, this value is null
- */
- @NonNull
- private final Map<@NonNull World, @Nullable Island> spawn;
+ private Map spawns = new HashMap<>();
+
+ private Map last = new HashMap<>();
@NonNull
- private Database handler;
-
- /**
- * The last locations where an island were put. This is not stored persistently
- * and resets when the server starts
- */
- private final Map last;
+ private static Database handler;
/**
* Island Cache
*/
@NonNull
private IslandCache islandCache;
- // Quarantined islands
- @NonNull
- private final Map> quarantineCache;
// Deleted islands
@NonNull
private final List deletedIslands;
@@ -106,14 +99,47 @@ public class IslandsManager {
// Set up the database handler to store and retrieve Island classes
handler = new Database<>(plugin, Island.class);
islandCache = new IslandCache();
- quarantineCache = new HashMap<>();
- spawn = new HashMap<>();
- last = new HashMap<>();
// This list should always be empty unless database deletion failed
// In that case a purge utility may be required in the future
deletedIslands = new ArrayList<>();
// Mid-teleport players going home
goingHome = new HashSet<>();
+ // Set handler in Island
+
+ // Listen for Island Updates
+ MultiLib.onString(plugin, "bentobox-updateIsland", id -> {
+ Island island = handler.loadObject(id);
+ if (island != null) {
+ islandCache.updateIsland(island);
+ }
+ });
+
+ // Delete island blocks
+ MultiLib.onString(plugin, "bentobox-deleteIsland", id -> {
+ IslandDeletion idd = getGson().fromJson(id, IslandDeletion.class);
+ plugin.getIslandDeletionManager().getIslandChunkDeletionManager().add(idd);
+ });
+ // List for new islands
+ MultiLib.onString(plugin, "bentobox-newIsland", id -> {
+ Island island = handler.loadObject(id);
+ if (island != null) {
+ islandCache.addIsland(island);
+ }
+ });
+ // Set or clear spawn
+ MultiLib.onString(plugin, "bentobox-setspawn", sp -> {
+ String[] split = sp.split(",");
+ if (split.length == 1) {
+ World world = Bukkit.getWorld(split[0]);
+ this.clearSpawn(world);
+ } else if (split.length == 2) {
+ World world = Bukkit.getWorld(split[0]);
+ if (world != null) {
+ getIslandById(split[1]).ifPresent(i -> this.setSpawn(i));
+ }
+ }
+
+ });
}
/**
@@ -121,8 +147,8 @@ public class IslandsManager {
*
* @param handler - handler
*/
- public void setHandler(@NonNull Database handler) {
- this.handler = handler;
+ public void setHandler(@NonNull Database h) {
+ handler = h;
}
/**
@@ -227,14 +253,13 @@ public class IslandsManager {
.orElse("");
island.setGameMode(gmName);
island.setUniqueId(gmName + island.getUniqueId());
- while (handler.objectExists(island.getUniqueId())) {
- // This should never happen, so although this is a potential infinite loop I'm
- // going to leave it here because
- // it will be bad if this does occur and the server should crash.
- plugin.logWarning("Duplicate island UUID occurred");
- island.setUniqueId(gmName + UUID.randomUUID());
- }
if (islandCache.addIsland(island)) {
+ // Save to database and notify other servers
+ handler.saveObjectAsync(island).thenAccept(b -> {
+ if (b.equals(Boolean.TRUE)) {
+ MultiLib.notify("bentobox-newIsland", island.getUniqueId());
+ }
+ });
return island;
}
return null;
@@ -257,27 +282,40 @@ public class IslandsManager {
// Set the owner of the island to no one.
island.setOwner(null);
island.setFlag(Flags.LOCK, RanksManager.VISITOR_RANK);
+ island.setDeleted(true);
if (removeBlocks) {
// Remove island from the cache
islandCache.deleteIslandFromCache(island);
- // Log the deletion (it shouldn't matter but may be useful)
- island.log(new LogEntry.Builder("DELETED").build());
- // Set the delete flag which will prevent it from being loaded even if database
- // deletion fails
- island.setDeleted(true);
- // Save the island
- handler.saveObjectAsync(island);
- // Delete the island
- handler.deleteObject(island);
// Remove players from island
removePlayersFromIsland(island);
if (!plugin.getSettings().isKeepPreviousIslandOnReset()) {
// Remove blocks from world
- plugin.getIslandDeletionManager().getIslandChunkDeletionManager().add(new IslandDeletion(island));
+ IslandDeletion id = new IslandDeletion(island);
+ plugin.getIslandDeletionManager().getIslandChunkDeletionManager().add(id);
+ // Tell other servers
+ MultiLib.notify("bentobox-deleteIsland", getGson().toJson(id));
}
+ // Delete the island from the database
+ handler.deleteObject(island);
}
}
+ private Gson getGson() {
+
+ // Build the Gson
+
+ // excludeFieldsWithoutExposeAnnotation - this means that every field to be stored should use @Expose
+ // enableComplexMapKeySerialization - forces GSON to use TypeAdapters even for Map keys
+ GsonBuilder builder = new GsonBuilder().excludeFieldsWithoutExposeAnnotation()
+ .enableComplexMapKeySerialization().setPrettyPrinting();
+ // Register adapter factory
+ builder.registerTypeAdapterFactory(new BentoboxTypeAdapterFactory(plugin));
+ // Allow characters like < or > without escaping them
+ builder.disableHtmlEscaping();
+
+ return builder.create();
+ }
+
/**
* Get the number of islands made on this server. Used by stats.
*
@@ -462,7 +500,7 @@ public class IslandsManager {
* Get the last location where an island was created
*
* @param world - world
- * @return location
+ * @return location or null if none found
*/
public Location getLast(@NonNull World world) {
return last.get(world);
@@ -486,7 +524,7 @@ public class IslandsManager {
if (island.getOwner() == null) {
// No owner, no rank settings
island.setMaxMembers(null);
- this.save(island);
+ updateIsland(island);
return 0;
}
// Island max is either the world default or specified amount for this island
@@ -507,8 +545,11 @@ public class IslandsManager {
islandMax = owner.getPermissionValue(plugin.getIWM().getPermissionPrefix(island.getWorld()) + perm,
islandMax);
}
- island.setMaxMembers(rank, islandMax == worldDefault ? null : islandMax);
- this.save(island);
+ Integer change = islandMax == worldDefault ? null : islandMax;
+ if (island.getMaxMembers().get(rank) != change) {
+ island.setMaxMembers(rank, change);
+ updateIsland(island);
+ }
return islandMax;
}
@@ -546,13 +587,16 @@ public class IslandsManager {
}
// If the island maxHomes is just the same as the world default, then set to
// null
- island.setMaxHomes(islandMax == plugin.getIWM().getMaxHomes(island.getWorld()) ? null : islandMax);
- this.save(island);
+ Integer change = islandMax == plugin.getIWM().getMaxHomes(island.getWorld()) ? null : islandMax;
+ if (island.getMaxHomes() != change) {
+ island.setMaxHomes(change);
+ updateIsland(island);
+ }
return islandMax;
}
/**
- * Set the maximum numbber of homes allowed on this island
+ * Set the maximum number of homes allowed on this island
*
* @param island - island
* @param maxHomes - max number of homes allowed, or null if the world default
@@ -735,9 +779,9 @@ public class IslandsManager {
* @since 1.16.0
*/
public boolean setHomeLocation(@Nullable Island island, Location location, String name) {
- if (island != null) {
+ if (island != null && (island.getHome(name) == null || !island.getHome(name).equals(location))) {
island.addHome(name, location);
- this.save(island);
+ updateIsland(island);
return true;
}
return false;
@@ -890,7 +934,7 @@ public class IslandsManager {
*/
@NonNull
public Optional getSpawn(@NonNull World world) {
- return Optional.ofNullable(spawn.get(world));
+ return Optional.ofNullable(spawns.get(world));
}
/**
@@ -901,7 +945,7 @@ public class IslandsManager {
*/
@Nullable
public Location getSpawnPoint(@NonNull World world) {
- return spawn.containsKey(world) ? spawn.get(world).getSpawnPoint(world.getEnvironment()) : null;
+ return getSpawn(world).map(i -> i.getSpawnPoint(world.getEnvironment())).orElse(null);
}
/**
@@ -1132,7 +1176,7 @@ public class IslandsManager {
* @return true if they are, false if they are not, or spawn does not exist
*/
public boolean isAtSpawn(Location playerLoc) {
- return spawn.containsKey(playerLoc.getWorld()) && spawn.get(playerLoc.getWorld()).onIsland(playerLoc);
+ return getSpawn(playerLoc.getWorld()).map(i -> i.onIsland(playerLoc)).orElse(false);
}
/**
@@ -1144,19 +1188,14 @@ public class IslandsManager {
* @param spawn the Island to set as spawn. Must not be null.
*/
public void setSpawn(@NonNull Island spawn) {
- // Checking if there is already a spawn set for this world
- if (this.spawn.containsKey(spawn.getWorld()) && this.spawn.get(spawn.getWorld()) != null) {
- Island oldSpawn = this.spawn.get(spawn.getWorld());
- if (oldSpawn.equals(spawn)) {
- return; // The spawn is already the current spawn - no need to update anything.
- } else {
- oldSpawn.setSpawn(false);
- }
+ if (spawn.getWorld() != null) {
+ spawns.put(Util.getWorld(spawn.getWorld()), spawn);
+ // Tell other servers
+ MultiLib.notify("bentobox-setspawn", spawn.getWorld().getUID().toString() + "," + spawn.getUniqueId());
}
- this.spawn.put(spawn.getWorld(), spawn);
- spawn.setSpawn(true);
}
+
/**
* Clears the spawn island for this world
*
@@ -1164,11 +1203,9 @@ public class IslandsManager {
* @since 1.8.0
*/
public void clearSpawn(World world) {
- Island spawnIsland = spawn.get(Util.getWorld(world));
- if (spawnIsland != null) {
- spawnIsland.setSpawn(false);
- }
- this.spawn.remove(world);
+ spawns.remove(world);
+ // Tell other servers
+ MultiLib.notify("bentobox-setspawn", world.getUID().toString());
}
/**
@@ -1192,7 +1229,6 @@ public class IslandsManager {
*/
public void load() throws IOException {
islandCache.clear();
- quarantineCache.clear();
List toQuarantine = new ArrayList<>();
int owned = 0;
int unowned = 0;
@@ -1206,9 +1242,6 @@ public class IslandsManager {
if (island.isDeleted()) {
// These will be deleted later
deletedIslands.add(island.getUniqueId());
- } else if (island.isDoNotLoad() && island.getWorld() != null && island.getCenter() != null) {
- // Add to quarantine cache
- quarantineCache.computeIfAbsent(island.getOwner(), k -> new ArrayList<>()).add(island);
} // Check island distance and if incorrect stop BentoBox
else if (island.getWorld() != null && plugin.getIWM().inWorld(island.getWorld())
&& island.getRange() != plugin.getIWM().getIslandDistance(island.getWorld())) {
@@ -1219,18 +1252,9 @@ public class IslandsManager {
} else {
// Fix island center if it is off
fixIslandCenter(island);
- if (!islandCache.addIsland(island)) {
- // Quarantine the offending island
- toQuarantine.add(island);
- // Add to quarantine cache
- island.setDoNotLoad(true);
- quarantineCache.computeIfAbsent(island.getOwner(), k -> new ArrayList<>()).add(island);
- if (island.isUnowned()) {
- unowned++;
- } else {
- owned++;
- }
- } else if (island.isSpawn()) {
+ islandCache.addIsland(island);
+
+ if (island.isSpawn()) {
// Success, set spawn if this is the spawn island.
this.setSpawn(island);
} else {
@@ -1394,15 +1418,10 @@ public class IslandsManager {
homeTeleportAsync(w, p);
} else {
// Move player to spawn
- if (spawn.containsKey(w)) {
- // go to island spawn
- Location sp = spawn.get(w).getSpawnPoint(w.getEnvironment());
- if (sp != null) {
- PaperLib.teleportAsync(p, sp);
- } else {
- plugin.logWarning("Spawn exists but its location is null!");
- }
- }
+ getSpawn(w).map(i -> i.getSpawnPoint(w.getEnvironment())).filter(Objects::nonNull)
+ .ifPresentOrElse(sp -> PaperLib.teleportAsync(p, sp),
+ () -> plugin.logWarning("Spawn exists but its location is null!"));
+
}
});
}
@@ -1473,9 +1492,13 @@ public class IslandsManager {
teamIsland.addMember(playerUUID);
islandCache.addPlayer(playerUUID, teamIsland);
// Save the island
- handler.saveObjectAsync(teamIsland);
+ updateIsland(teamIsland);
}
+ /**
+ * Set the last island location
+ * @param last location
+ */
public void setLast(Location last) {
this.last.put(last.getWorld(), last);
}
@@ -1608,12 +1631,16 @@ public class IslandsManager {
}
/**
- * Save the island to the database
+ * Update island data in database
*
* @param island - island
*/
- public void save(Island island) {
- handler.saveObjectAsync(island);
+ public static void updateIsland(Island island) {
+ if (handler.objectExists(island.getUniqueId())) {
+ island.clearChanged();
+ handler.saveObjectAsync(island)
+ .thenAccept(b -> MultiLib.notify("bentobox-updateIsland", island.getUniqueId()));
+ }
}
/**
@@ -1628,108 +1655,6 @@ public class IslandsManager {
return Optional.ofNullable(islandCache.getIslandById(uniqueId));
}
- /**
- * Try to get an unmodifiable list of quarantined islands owned by uuid in this
- * world
- *
- * @param world - world
- * @param uuid - target player's UUID, or null = unowned islands
- * @return list of islands; may be empty
- * @since 1.3.0
- */
- @NonNull
- public List getQuarantinedIslandByUser(@NonNull World world, @Nullable UUID uuid) {
- return quarantineCache.getOrDefault(uuid, Collections.emptyList()).stream()
- .filter(i -> i.getWorld().equals(world)).toList();
- }
-
- /**
- * Delete quarantined islands owned by uuid in this world
- *
- * @param world - world
- * @param uuid - target player's UUID, or null = unowned islands
- * @since 1.3.0
- */
- public void deleteQuarantinedIslandByUser(World world, @Nullable UUID uuid) {
- if (quarantineCache.containsKey(uuid)) {
- quarantineCache.get(uuid).stream().filter(i -> i.getWorld().equals(world))
- .forEach(i -> handler.deleteObject(i));
- quarantineCache.get(uuid).removeIf(i -> i.getWorld().equals(world));
- }
- }
-
- /**
- * @return the quarantineCache
- * @since 1.3.0
- */
- @NonNull
- public Map> getQuarantineCache() {
- return quarantineCache;
- }
-
- /**
- * Remove a quarantined island and delete it from the database completely. This
- * is NOT recoverable unless you have database backups.
- *
- * @param island island
- * @return {@code true} if island is quarantined and removed
- * @since 1.3.0
- */
- public boolean purgeQuarantinedIsland(Island island) {
- if (quarantineCache.containsKey(island.getOwner()) && quarantineCache.get(island.getOwner()).remove(island)) {
- handler.deleteObject(island);
- return true;
- }
- return false;
- }
-
- /**
- * Switches active island and island in trash
- *
- * @param world - game world
- * @param target - target player's UUID
- * @param island - island in trash
- * @return true if successful, otherwise false
- * @since 1.3.0
- */
- public boolean switchIsland(World world, UUID target, Island island) {
- // Remove trashed island from trash
- if (!quarantineCache.containsKey(island.getOwner()) || !quarantineCache.get(island.getOwner()).remove(island)) {
- plugin.logError("Could not remove island from trash");
- return false;
- }
- // Remove old island from cache if it exists
- if (this.hasIsland(world, target)) {
- Island oldIsland = islandCache.get(world, target);
- islandCache.removeIsland(oldIsland);
-
- // Set old island to trash
- oldIsland.setDoNotLoad(true);
-
- // Put old island into trash
- quarantineCache.computeIfAbsent(target, k -> new ArrayList<>()).add(oldIsland);
- // Save old island
- handler.saveObjectAsync(oldIsland).thenAccept(result -> {
- if (Boolean.FALSE.equals(result))
- plugin.logError("Could not save trashed island in database");
- });
- }
- // Restore island from trash
- island.setDoNotLoad(false);
- // Add new island to cache
- if (!islandCache.addIsland(island)) {
- plugin.logError("Could not add recovered island to cache");
- return false;
- }
- // Save new island
- handler.saveObjectAsync(island).thenAccept(result -> {
- if (Boolean.FALSE.equals(result)) {
- plugin.logError("Could not save recovered island to database");
- }
- });
- return true;
- }
-
/**
* Resets all flags to gamemode config.yml default
*
diff --git a/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java b/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java
index 007d67ba1..0137c8ee5 100644
--- a/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java
+++ b/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java
@@ -4,21 +4,18 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.LinkedList;
import java.util.Map;
-import java.util.Queue;
+import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.entity.Tameable;
-import org.bukkit.scheduler.BukkitRunnable;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.BentoBox;
-import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.Database;
import world.bentobox.bentobox.database.objects.Island;
@@ -31,11 +28,9 @@ public class PlayersManager {
private final BentoBox plugin;
private Database handler;
private final Database names;
+ private final Map playerCache = new HashMap<>();
- private final Map playerCache;
- private final Set inTeleport;
-
- private boolean isSaveTaskRunning;
+ private final Set inTeleport; // this needs databasing
/**
* Provides a memory cache of online player information
@@ -50,7 +45,6 @@ public class PlayersManager {
handler = new Database<>(plugin, Players.class);
// Set up the names database
names = new Database<>(plugin, Names.class);
- playerCache = new HashMap<>();
inTeleport = new HashSet<>();
}
@@ -62,67 +56,7 @@ public class PlayersManager {
this.handler = handler;
}
- /**
- * Load all players - not normally used as to load all players into memory will be wasteful
- */
- public void load(){
- playerCache.clear();
- inTeleport.clear();
- handler.loadObjects().forEach(p -> playerCache.put(p.getPlayerUUID(), p));
- }
-
- public boolean isSaveTaskRunning() {
- return isSaveTaskRunning;
- }
-
- /**
- * Save all players
- */
- public void saveAll() {
- saveAll(false);
- }
-
- /**
- * Save all players
- * @param schedule true if we should let the task run over multiple ticks to reduce lag spikes
- */
- public void saveAll(boolean schedule){
- if (!schedule) {
- for (Players player : playerCache.values()) {
- try {
- handler.saveObjectAsync(player);
- } catch (Exception e) {
- plugin.logError("Could not save player to database when running sync! " + e.getMessage());
- }
- }
- return;
- }
-
- isSaveTaskRunning = true;
- Queue queue = new LinkedList<>(playerCache.values());
- new BukkitRunnable() {
- @Override
- public void run() {
- for (int i = 0; i < plugin.getSettings().getMaxSavedPlayersPerTick(); i++) {
- Players player = queue.poll();
- if (player == null) {
- isSaveTaskRunning = false;
- cancel();
- return;
- }
- try {
- handler.saveObjectAsync(player);
- } catch (Exception e) {
- plugin.logError("Could not save player to database when running sync! " + e.getMessage());
- }
- }
- }
- }.runTaskTimer(plugin, 0, 1);
- }
-
public void shutdown(){
- saveAll();
- playerCache.clear();
handler.close();
}
@@ -134,11 +68,29 @@ public class PlayersManager {
@Nullable
public Players getPlayer(UUID uuid){
if (!playerCache.containsKey(uuid)) {
- addPlayer(uuid);
+ playerCache.put(uuid, addPlayer(uuid));
}
return playerCache.get(uuid);
}
+ /**
+ * Adds a player to the database. If the UUID does not exist, a new player is made
+ * @param playerUUID - the player's UUID
+ */
+ private Players addPlayer(@NonNull UUID playerUUID) {
+ Objects.requireNonNull(playerUUID);
+ // If the player is in the database, load it, otherwise create a new player
+ if (handler.objectExists(playerUUID.toString())) {
+ Players player = handler.loadObject(playerUUID.toString());
+ if (player != null) {
+ return player;
+ }
+ }
+ Players player = new Players(plugin, playerUUID);
+ handler.saveObject(player);
+ return player;
+ }
+
/**
* Returns an unmodifiable collection of all the players that are currently in the cache.
* @return unmodifiable collection containing every player in the cache.
@@ -146,37 +98,7 @@ public class PlayersManager {
*/
@NonNull
public Collection getPlayers() {
- return Collections.unmodifiableCollection(playerCache.values());
- }
-
- /*
- * Cache control methods
- */
-
- /**
- * Adds a player to the cache. If the UUID does not exist, a new player is made
- * @param playerUUID - the player's UUID
- */
- public void addPlayer(UUID playerUUID) {
- if (playerUUID == null) {
- return;
- }
- if (!playerCache.containsKey(playerUUID)) {
- Players player;
- // If the player is in the database, load it, otherwise create a new player
- if (handler.objectExists(playerUUID.toString())) {
- player = handler.loadObject(playerUUID.toString());
- if (player == null) {
- player = new Players(plugin, playerUUID);
- // Corrupted database entry
- plugin.logError("Corrupted player database entry for " + playerUUID + " - unrecoverable. Recreated.");
- player.setUniqueId(playerUUID.toString());
- }
- } else {
- player = new Players(plugin, playerUUID);
- }
- playerCache.put(playerUUID, player);
- }
+ return Collections.unmodifiableCollection(handler.loadObjects());
}
/**
@@ -187,7 +109,7 @@ public class PlayersManager {
* @return true if player is known, otherwise false
*/
public boolean isKnown(UUID uniqueID) {
- return uniqueID != null && (playerCache.containsKey(uniqueID) || handler.objectExists(uniqueID.toString()));
+ return uniqueID == null ? false : handler.objectExists(uniqueID.toString());
}
/**
@@ -206,11 +128,8 @@ public class PlayersManager {
// Not used
}
}
- // Look in the name cache, then the data base and then give up
- return playerCache.values().stream()
- .filter(p -> p.getPlayerName().equalsIgnoreCase(name)).findFirst()
- .map(p -> UUID.fromString(p.getUniqueId()))
- .orElseGet(() -> names.objectExists(name) ? names.loadObject(name).getUuid() : null);
+ return names.loadObjects().stream().filter(n -> n.getUniqueId().equalsIgnoreCase(name)).findFirst()
+ .map(Names::getUuid).orElse(null);
}
/**
@@ -218,8 +137,9 @@ public class PlayersManager {
* @param user - the User
*/
public void setPlayerName(@NonNull User user) {
- addPlayer(user.getUniqueId());
- playerCache.get(user.getUniqueId()).setPlayerName(user.getName());
+ Players player = getPlayer(user.getUniqueId());
+ player.setPlayerName(user.getName());
+ handler.saveObject(player);
Names newName = new Names(user.getName(), user.getUniqueId());
// Add to names database
names.saveObjectAsync(newName);
@@ -237,8 +157,8 @@ public class PlayersManager {
if (playerUUID == null) {
return "";
}
- addPlayer(playerUUID);
- return playerCache.get(playerUUID).getPlayerName();
+ return names.loadObjects().stream().filter(n -> n.getUuid().equals(playerUUID)).findFirst()
+ .map(Names::getUniqueId).orElse(null);
}
/**
@@ -248,8 +168,7 @@ public class PlayersManager {
* @return number of resets
*/
public int getResets(World world, UUID playerUUID) {
- addPlayer(playerUUID);
- return playerCache.get(playerUUID).getResets(world);
+ return getPlayer(playerUUID).getResets(world);
}
/**
@@ -261,7 +180,7 @@ public class PlayersManager {
* @see #getResets(World, UUID)
*/
public int getResetsLeft(World world, UUID playerUUID) {
- addPlayer(playerUUID);
+ getPlayer(playerUUID);
if (plugin.getIWM().getResetLimit(world) == -1) {
return -1;
} else {
@@ -277,8 +196,9 @@ public class PlayersManager {
* @param resets number of resets to set
*/
public void setResets(World world, UUID playerUUID, int resets) {
- addPlayer(playerUUID);
- playerCache.get(playerUUID).setResets(world, resets);
+ Players p = getPlayer(playerUUID);
+ p.setResets(world, resets);
+ handler.saveObject(p);
}
/**
@@ -287,11 +207,7 @@ public class PlayersManager {
* @return name of the locale this player uses
*/
public String getLocale(UUID playerUUID) {
- addPlayer(playerUUID);
- if (playerUUID == null) {
- return "";
- }
- return playerCache.get(playerUUID).getLocale();
+ return getPlayer(playerUUID).getLocale();
}
/**
@@ -300,8 +216,9 @@ public class PlayersManager {
* @param localeName - locale name, e.g., en-US
*/
public void setLocale(UUID playerUUID, String localeName) {
- addPlayer(playerUUID);
- playerCache.get(playerUUID).setLocale(localeName);
+ Players p = getPlayer(playerUUID);
+ p.setLocale(localeName);
+ handler.saveObject(p);
}
/**
@@ -310,8 +227,9 @@ public class PlayersManager {
* @param playerUUID - the player's UUID
*/
public void addDeath(World world, UUID playerUUID) {
- addPlayer(playerUUID);
- playerCache.get(playerUUID).addDeath(world);
+ Players p = getPlayer(playerUUID);
+ p.addDeath(world);
+ handler.saveObject(p);
}
/**
@@ -321,8 +239,9 @@ public class PlayersManager {
* @param deaths - number of deaths
*/
public void setDeaths(World world, UUID playerUUID, int deaths) {
- addPlayer(playerUUID);
- playerCache.get(playerUUID).setDeaths(world, deaths);
+ Players p = getPlayer(playerUUID);
+ p.setDeaths(world, deaths);
+ handler.saveObject(p);
}
/**
@@ -332,8 +251,7 @@ public class PlayersManager {
* @return number of deaths
*/
public int getDeaths(World world, UUID playerUUID) {
- addPlayer(playerUUID);
- return playerCache.get(playerUUID) == null ? 0 : playerCache.get(playerUUID).getDeaths(world);
+ return getPlayer(playerUUID).getDeaths(world);
}
/**
@@ -360,16 +278,6 @@ public class PlayersManager {
return inTeleport.contains(uniqueId);
}
- /**
- * Saves the player to the database
- * @param playerUUID - the player's UUID
- */
- public void save(UUID playerUUID) {
- if (playerCache.containsKey(playerUUID)) {
- handler.saveObjectAsync(playerCache.get(playerUUID));
- }
- }
-
/**
* Tries to get the user from his name
* @param name - name
@@ -395,41 +303,17 @@ public class PlayersManager {
* @param playerUUID player's UUID
*/
public void addReset(World world, UUID playerUUID) {
- addPlayer(playerUUID);
- playerCache.get(playerUUID).addReset(world);
+ Players p = getPlayer(playerUUID);
+ p.addReset(world);
+ handler.saveObject(p);
}
/**
- * Sets the Flags display mode for the Settings Panel for this player.
- * @param playerUUID player's UUID
- * @param displayMode the {@link Flag.Mode} to set
- * @since 1.6.0
- */
- public void setFlagsDisplayMode(UUID playerUUID, Flag.Mode displayMode) {
- addPlayer(playerUUID);
- playerCache.get(playerUUID).setFlagsDisplayMode(displayMode);
- }
-
- /**
- * Returns the Flags display mode for the Settings Panel for this player.
- * @param playerUUID player's UUID
- * @return the {@link Flag.Mode display mode} for the Flags in the Settings Panel.
- * @since 1.6.0
- */
- public Flag.Mode getFlagsDisplayMode(UUID playerUUID) {
- addPlayer(playerUUID);
- return playerCache.get(playerUUID).getFlagsDisplayMode();
- }
-
- /**
- * Remove player from cache. Clears players with the same name or UUID
+ * Remove player from database
* @param player player to remove
*/
public void removePlayer(Player player) {
- // Clear any players with the same name
- playerCache.values().removeIf(p -> player.getName().equalsIgnoreCase(p.getPlayerName()));
- // Remove if the player's UUID is the same
- playerCache.values().removeIf(p -> player.getUniqueId().toString().equals(p.getUniqueId()));
+ handler.deleteID(player.getUniqueId().toString());
}
/**
@@ -495,8 +379,6 @@ public class PlayersManager {
// Player total XP (not displayed)
target.getPlayer().setTotalExperience(0);
}
- // Save player
- save(target.getUniqueId());
}
}
diff --git a/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java b/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java
index a72560ded..3846c1a21 100644
--- a/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java
+++ b/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java
@@ -9,6 +9,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
@@ -54,6 +55,159 @@ public class IslandCache {
grids = new HashMap<>();
}
+ /**
+ * Replace the island we have with this one
+ * @param newIsland island
+ */
+ public void updateIsland(@NonNull Island newIsland) {
+ if (newIsland.isDeleted()) {
+ this.deleteIslandFromCache(newIsland);
+ return;
+ }
+ // Get the old island
+ Island oldIsland = islandsById.get(newIsland.getUniqueId());
+ compareIslands(oldIsland, newIsland);
+ Set newMembers = newIsland.getMembers().keySet();
+ if (oldIsland != null) {
+ Set oldMembers = oldIsland.getMembers().keySet();
+ // Remove any members who are not in the new island
+ for (UUID oldMember : oldMembers) {
+ if (!newMembers.contains(oldMember)) {
+ // Member has been removed - remove island
+ islandsByUUID.computeIfAbsent(oldMember, k -> new HashSet<>()).remove(oldIsland);
+ }
+ }
+ }
+ // Update the members with the new island object
+ for (UUID newMember : newMembers) {
+ Set set = islandsByUUID.computeIfAbsent(newMember, k -> new HashSet<>());
+ set.remove(oldIsland);
+ set.add(newIsland);
+ islandsByUUID.put(newMember, set);
+ }
+
+ if (islandsByLocation.put(newIsland.getCenter(), newIsland) == null) {
+ BentoBox.getInstance().logError("islandsByLocation failed to update");
+
+ }
+ if (islandsById.put(newIsland.getUniqueId(), newIsland) == null) {
+ BentoBox.getInstance().logError("islandsById failed to update");
+ }
+
+ }
+
+ /**
+ * TODO REMOVE THIS DEBUG METHOD
+ * @param island1 island1
+ * @param island2 island 2
+ */
+ public void compareIslands(Island island1, Island island2) {
+ if (island1 == null || island2 == null) {
+ BentoBox.getInstance().logDebug("One or both islands are null. Cannot compare.");
+ return;
+ }
+
+ if (!island1.getUniqueId().equals(island2.getUniqueId())) {
+ BentoBox.getInstance().logDebug("Island unique IDs are different.");
+ }
+
+ if (island1.isDeleted() != island2.isDeleted()) {
+ BentoBox.getInstance().logDebug("Island deleted states are different.");
+ }
+
+ if (!Objects.equals(island1.getCenter(), island2.getCenter())) {
+ BentoBox.getInstance().logDebug("Island centers are different.");
+ }
+
+ if (island1.getRange() != island2.getRange()) {
+ BentoBox.getInstance().logDebug("Island ranges are different.");
+ }
+
+ if (island1.getProtectionRange() != island2.getProtectionRange()) {
+ BentoBox.getInstance().logDebug("Island protection ranges are different.");
+ }
+
+ if (!island1.getBonusRanges().equals(island2.getBonusRanges())) {
+ BentoBox.getInstance().logDebug("Island bonus ranges are different.");
+ }
+
+ if (island1.getMaxEverProtectionRange() != island2.getMaxEverProtectionRange()) {
+ BentoBox.getInstance().logDebug("Island max ever protection ranges are different.");
+ }
+
+ if (!island1.getWorld().equals(island2.getWorld())) {
+ BentoBox.getInstance().logDebug("Island worlds are different.");
+ }
+
+ if (!Objects.equals(island1.getGameMode(), island2.getGameMode())) {
+ BentoBox.getInstance().logDebug("Island game modes are different.");
+ }
+
+ if (!Objects.equals(island1.getName(), island2.getName())) {
+ BentoBox.getInstance().logDebug("Island names are different.");
+ }
+
+ if (island1.getCreatedDate() != island2.getCreatedDate()) {
+ BentoBox.getInstance().logDebug("Island created dates are different.");
+ }
+
+ if (island1.getUpdatedDate() != island2.getUpdatedDate()) {
+ BentoBox.getInstance().logDebug("Island updated dates are different.");
+ }
+
+ if (!Objects.equals(island1.getOwner(), island2.getOwner())) {
+ BentoBox.getInstance().logDebug("Island owners are different.");
+ }
+
+ if (!island1.getMembers().equals(island2.getMembers())) {
+ BentoBox.getInstance().logDebug("Island members are different.");
+ }
+
+ if (!Objects.equals(island1.getMaxMembers(), island2.getMaxMembers())) {
+ BentoBox.getInstance().logDebug("Island max members are different.");
+ }
+
+ if (island1.isSpawn() != island2.isSpawn()) {
+ BentoBox.getInstance().logDebug("Island spawn states are different.");
+ }
+
+ if (!island1.getFlags().equals(island2.getFlags())) {
+ BentoBox.getInstance().logDebug("Island flags are different.");
+ }
+
+ if (!island1.getHistory().equals(island2.getHistory())) {
+ BentoBox.getInstance().logDebug("Island histories are different.");
+ }
+
+ if (!island1.getSpawnPoint().equals(island2.getSpawnPoint())) {
+ BentoBox.getInstance().logDebug("Island spawn points are different.");
+ }
+
+ if (island1.isDoNotLoad() != island2.isDoNotLoad()) {
+ BentoBox.getInstance().logDebug("Island do not load states are different.");
+ }
+
+ if (!island1.getCooldowns().equals(island2.getCooldowns())) {
+ BentoBox.getInstance().logDebug("Island cooldowns are different.");
+ }
+
+ if (!Objects.equals(island1.getCommandRanks(), island2.getCommandRanks())) {
+ BentoBox.getInstance().logDebug("Island command ranks are different.");
+ }
+
+ if (!Objects.equals(island1.getMetaData(), island2.getMetaData())) {
+ BentoBox.getInstance().logDebug("Island metadata are different.");
+ }
+
+ if (!Objects.equals(island1.getHomes(), island2.getHomes())) {
+ BentoBox.getInstance().logDebug("Island homes are different.");
+ }
+
+ if (!Objects.equals(island1.getMaxHomes(), island2.getMaxHomes())) {
+ BentoBox.getInstance().logDebug("Island max homes are different.");
+ }
+ }
+
/**
* Adds an island to the grid
*
@@ -62,12 +216,7 @@ public class IslandCache {
*/
public boolean addIsland(@NonNull Island island) {
if (island.getCenter() == null || island.getWorld() == null) {
- /*
- * Special handling - return true. The island will not be quarantined, but just
- * not loaded This can occur when a gamemode is removed temporarily from the
- * server TODO: have an option to remove these when the purge command is added
- */
- return true;
+ return false;
}
if (addToGrid(island)) {
islandsByLocation.put(island.getCenter(), island);
@@ -100,7 +249,7 @@ public class IslandCache {
* @return true if successfully added, false if not
*/
private boolean addToGrid(@NonNull Island newIsland) {
- return grids.computeIfAbsent(newIsland.getWorld(), k -> new IslandGrid()).addToGrid(newIsland);
+ return grids.computeIfAbsent(newIsland.getWorld(), k -> new IslandGrid(this)).addToGrid(newIsland);
}
public void clear() {
@@ -117,13 +266,16 @@ public class IslandCache {
*/
public boolean deleteIslandFromCache(@NonNull Island island) {
if (!islandsByLocation.remove(island.getCenter(), island)) {
+ // Already deleted
return false;
}
islandsById.remove(island.getUniqueId());
removeFromIslandsByUUID(island);
// Remove from grid
- grids.putIfAbsent(island.getWorld(), new IslandGrid());
- return grids.get(island.getWorld()).removeFromGrid(island);
+ if (grids.containsKey(island.getWorld())) {
+ return grids.get(island.getWorld()).removeFromGrid(island);
+ }
+ return false;
}
private void removeFromIslandsByUUID(Island island) {
@@ -144,12 +296,11 @@ public class IslandCache {
*
* @param uniqueId - island unique ID
*/
- public void deleteIslandFromCache(@NonNull String uniqueId) {
- islandsById.remove(uniqueId);
- islandsByLocation.values().removeIf(i -> i.getUniqueId().equals(uniqueId));
- for (Set set : islandsByUUID.values()) {
- set.removeIf(i -> i.getUniqueId().equals(uniqueId));
+ public boolean deleteIslandFromCache(@NonNull String uniqueId) {
+ if (islandsById.containsKey(uniqueId)) {
+ return deleteIslandFromCache(islandsById.get(uniqueId));
}
+ return false;
}
/**
@@ -178,13 +329,13 @@ public class IslandCache {
return null;
}
for (Island island : islands) {
- if (island.isPrimary()) {
+ if (island.isPrimary(uuid)) {
return island;
}
}
// If there is no primary set, then set one - it doesn't matter which.
Island result = islands.iterator().next();
- result.setPrimary(true);
+ result.setPrimary(uuid);
return result;
}
@@ -212,8 +363,16 @@ public class IslandCache {
* @param island island to make primary
*/
public void setPrimaryIsland(@NonNull UUID uuid, @NonNull Island island) {
+ if (island.getPrimaries().contains(uuid)) {
+ return;
+ }
for (Island is : getIslands(island.getWorld(), uuid)) {
- is.setPrimary(island.equals(is));
+ if (is.getPrimaries().contains(uuid)) {
+ is.removePrimary(uuid);
+ }
+ if (is.equals(island)) {
+ is.setPrimary(uuid);
+ }
}
}
@@ -326,6 +485,7 @@ public class IslandCache {
islandSet.remove(island);
}
island.removeMember(uuid);
+ island.removePrimary(uuid);
}
/**
@@ -375,27 +535,6 @@ public class IslandCache {
return islandsById.get(uniqueId);
}
- /**
- * Removes an island from the cache completely without altering the island
- * object
- *
- * @param island - island to remove
- * @since 1.3.0
- */
- public void removeIsland(@NonNull Island island) {
- islandsByLocation.values().removeIf(island::equals);
- islandsById.values().removeIf(island::equals);
- islandsByUUID.values().removeIf(island::equals);
- World w = Util.getWorld(island.getWorld());
- if (w == null) {
- return;
- }
-
- if (grids.containsKey(w)) {
- grids.get(w).removeFromGrid(island);
- }
- }
-
/**
* Resets all islands in this game mode to default flag settings
*
diff --git a/src/main/java/world/bentobox/bentobox/managers/island/IslandGrid.java b/src/main/java/world/bentobox/bentobox/managers/island/IslandGrid.java
index db404f1a3..3974b44e4 100644
--- a/src/main/java/world/bentobox/bentobox/managers/island/IslandGrid.java
+++ b/src/main/java/world/bentobox/bentobox/managers/island/IslandGrid.java
@@ -3,7 +3,6 @@ package world.bentobox.bentobox.managers.island;
import java.util.Map.Entry;
import java.util.TreeMap;
-import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.database.objects.Island;
/**
@@ -12,8 +11,16 @@ import world.bentobox.bentobox.database.objects.Island;
*
*/
class IslandGrid {
- private final TreeMap> grid = new TreeMap<>();
- private final BentoBox plugin = BentoBox.getInstance();
+ private final TreeMap> grid = new TreeMap<>();
+ private final IslandCache im;
+
+ /**
+ * @param im IslandsManager
+ */
+ public IslandGrid(IslandCache im) {
+ super();
+ this.im = im;
+ }
/**
* Adds island to grid
@@ -21,50 +28,23 @@ class IslandGrid {
* @return true if successfully added, false if island already exists, or there is an overlap
*/
public boolean addToGrid(Island island) {
+ // Check if we know about this island already
if (grid.containsKey(island.getMinX())) {
- TreeMap zEntry = grid.get(island.getMinX());
+ TreeMap zEntry = grid.get(island.getMinX());
if (zEntry.containsKey(island.getMinZ())) {
- // There is an overlap or duplicate
- plugin.logError("Cannot load island. Overlapping: " + island.getUniqueId());
- plugin.logError("Location: " + island.getCenter());
- // Get the previously loaded island
- Island firstLoaded = zEntry.get(island.getMinZ());
- if (firstLoaded.getOwner() == null && island.getOwner() != null) {
- // This looks fishy. We prefer to load islands that have an owner. Swap the two
- plugin.logError("Duplicate island has an owner, so using that one. " + island.getOwner());
- firstLoaded = new Island(island);
- zEntry.put(island.getMinZ(), firstLoaded);
- } else if (firstLoaded.getOwner() != null && island.getOwner() != null) {
- // Check if the owners are the same - this is a true duplicate
- if (firstLoaded.getOwner().equals(island.getOwner())) {
- // Find out which one is the original
- if (firstLoaded.getCreatedDate() > island.getCreatedDate()) {
- plugin.logError("Same owner duplicate. Swapping based on creation date.");
- // FirstLoaded is the newer
- firstLoaded = new Island(island);
- zEntry.put(island.getMinZ(), firstLoaded);
- } else {
- plugin.logError("Same owner duplicate.");
- }
- } else {
- plugin.logError("Duplicate but different owner. Keeping first loaded.");
- plugin.logError("This is serious!");
- plugin.logError("1st loaded ID: " + firstLoaded.getUniqueId());
- plugin.logError("1st loaded owner: " + firstLoaded.getOwner());
- plugin.logError("2nd loaded ID: " + island.getUniqueId());
- plugin.logError("2nd loaded owner: " + island.getOwner());
- }
+ if (island.getUniqueId().equals(zEntry.get(island.getMinZ()))) {
+ return true;
}
return false;
} else {
// Add island
- zEntry.put(island.getMinZ(), island);
+ zEntry.put(island.getMinZ(), island.getUniqueId());
grid.put(island.getMinX(), zEntry);
}
} else {
// Add island
- TreeMap zEntry = new TreeMap<>();
- zEntry.put(island.getMinZ(), island);
+ TreeMap zEntry = new TreeMap<>();
+ zEntry.put(island.getMinZ(), island.getUniqueId());
grid.put(island.getMinX(), zEntry);
}
return true;
@@ -76,43 +56,48 @@ class IslandGrid {
* @return true if island existed and was deleted, false if there was nothing to delete
*/
public boolean removeFromGrid(Island island) {
- // Remove from grid
- if (island != null) {
- int x = island.getMinX();
- int z = island.getMinZ();
- if (grid.containsKey(x)) {
- TreeMap zEntry = grid.get(x);
- if (zEntry.containsKey(z)) {
- // Island exists - delete it
- zEntry.remove(z);
- grid.put(x, zEntry);
- return true;
- }
- }
- }
- return false;
- }
+ String id = island.getUniqueId();
+ boolean removed = grid.values().stream()
+ .anyMatch(innerMap -> innerMap.values().removeIf(innerValue -> innerValue.equals(id)));
+ grid.values().removeIf(TreeMap::isEmpty);
+
+ return removed;
+ }
+
/**
- * Returns the island at the x,z location or null if there is none.
- * This includes the full island space, not just the protected area.
- *
- * @param x - x coordinate
- * @param z - z coordinate
- * @return Island or null
- */
+ * Retrieves the island located at the specified x and z coordinates, covering both the protected area
+ * and the full island space. Returns null if no island exists at the given location.
+ *
+ * @param x the x coordinate of the location
+ * @param z the z coordinate of the location
+ * @return the Island at the specified location, or null if no island is found
+ */
public Island getIslandAt(int x, int z) {
- Entry> en = grid.floorEntry(x);
- if (en != null) {
- Entry ent = en.getValue().floorEntry(z);
- if (ent != null) {
- // Check if in the island range
- Island island = ent.getValue();
- if (island.inIslandSpace(x, z)) {
- return island;
- }
- }
+ // Attempt to find the closest x-coordinate entry that does not exceed 'x'
+ Entry> xEntry = grid.floorEntry(x);
+ if (xEntry == null) {
+ return null; // No x-coordinate entry found, return null
}
+
+ // Attempt to find the closest z-coordinate entry that does not exceed 'z' within the found x-coordinate
+ Entry zEntry = xEntry.getValue().floorEntry(z);
+ if (zEntry == null) {
+ return null; // No z-coordinate entry found, return null
+ }
+
+ // Retrieve the island using the id found in the z-coordinate entry
+ Island island = im.getIslandById(zEntry.getValue());
+ if (island == null) {
+ return null; // No island found by the id, return null
+ }
+ // Check if the specified coordinates are within the island space
+ if (island.inIslandSpace(x, z)) {
+ return island; // Coordinates are within island space, return the island
+ }
+
+ // Coordinates are outside the island space, return null
return null;
}
+
}
diff --git a/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java b/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java
index d9a73819f..bb4f2cb22 100644
--- a/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java
+++ b/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java
@@ -19,6 +19,7 @@ import world.bentobox.bentobox.api.events.island.IslandResetEvent;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.managers.BlueprintsManager;
+import world.bentobox.bentobox.managers.IslandsManager;
/**
* Create and paste a new island
@@ -217,7 +218,7 @@ public class NewIsland {
// Register metrics
plugin.getMetrics().ifPresent(BStats::increaseIslandsCreatedCount);
// Save island
- plugin.getIslands().save(island);
+ IslandsManager.updateIsland(island);
}
/**
@@ -266,8 +267,6 @@ public class NewIsland {
plugin.getIWM().getAddon(island.getWorld()).map(GameModeAddon::getPermissionPrefix).orElse("")
+ "island.range",
island.getProtectionRange()));
- // Save the player so that if the server crashes weird things won't happen
- plugin.getPlayers().save(user.getUniqueId());
}
/**
diff --git a/src/main/java/world/bentobox/bentobox/panels/customizable/IslandCreationPanel.java b/src/main/java/world/bentobox/bentobox/panels/customizable/IslandCreationPanel.java
index 681c3cd36..7b8269fdb 100644
--- a/src/main/java/world/bentobox/bentobox/panels/customizable/IslandCreationPanel.java
+++ b/src/main/java/world/bentobox/bentobox/panels/customizable/IslandCreationPanel.java
@@ -489,7 +489,7 @@ public class IslandCreationPanel
long uses = plugin.getIslands().getIslands(world, user).stream()
.filter(is -> is.getMetaData("bundle")
.map(mdv -> bundle.getDisplayName().equalsIgnoreCase(mdv.asString())
- && !(reset && is.isPrimary())) // If this is a reset, then ignore the use of the island being reset
+ && !(reset && is.isPrimary(user.getUniqueId()))) // If this is a reset, then ignore the use of the island being reset
.orElse(false))
.count();
builder.description(this.user.getTranslation(BUNDLE_BUTTON_REF + "uses", TextVariables.NUMBER,
diff --git a/src/main/java/world/bentobox/bentobox/panels/settings/SettingsTab.java b/src/main/java/world/bentobox/bentobox/panels/settings/SettingsTab.java
index 547238e7c..b558cc9d4 100644
--- a/src/main/java/world/bentobox/bentobox/panels/settings/SettingsTab.java
+++ b/src/main/java/world/bentobox/bentobox/panels/settings/SettingsTab.java
@@ -4,6 +4,7 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.UUID;
import java.util.stream.Collectors;
import org.bukkit.ChatColor;
@@ -16,6 +17,7 @@ import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.flags.Flag;
+import world.bentobox.bentobox.api.flags.Flag.Mode;
import world.bentobox.bentobox.api.flags.Flag.Type;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.panels.Panel;
@@ -46,16 +48,7 @@ public class SettingsTab implements Tab, ClickHandler {
protected Island island;
protected TabbedPanel parent;
- /**
- * Show a tab of settings
- * @param user - user who is viewing the tab
- * @param type - flag type
- */
- public SettingsTab(User user, Type type) {
- this.user = user;
- this.type = type;
- // Island and world are set when the parent is set.
- }
+ private Map currentMode = new HashMap<>();
/**
* Show a tab of settings
@@ -69,6 +62,21 @@ public class SettingsTab implements Tab, ClickHandler {
this.type = type;
}
+ /**
+ * Show a tab of settings
+ * @param world - world
+ * @param user - user who is viewing the tab
+ * @param type - flag type
+ * @param defaultMode - the default mode to show
+ * @since 2.4.0
+ */
+ public SettingsTab(World world, User user, Type type, Flag.Mode defaultMode) {
+ this.world = world;
+ this.user = user;
+ this.type = type;
+ currentMode.put(user.getUniqueId(), defaultMode);
+ }
+
/**
* @return list of flags that will be shown in this panel
*/
@@ -81,7 +89,7 @@ public class SettingsTab implements Tab, ClickHandler {
// Remove any that are not for this game mode
plugin.getIWM().getAddon(world).ifPresent(gm -> flags.removeIf(f -> !f.getGameModes().isEmpty() && !f.getGameModes().contains(gm)));
// Remove any that are the wrong rank or that will be on the top row
- Flag.Mode mode = plugin.getPlayers().getFlagsDisplayMode(user.getUniqueId());
+ Flag.Mode mode = currentMode.getOrDefault(user.getUniqueId(), Mode.BASIC);
plugin.getIWM().getAddon(world).ifPresent(gm -> flags.removeIf(f -> f.getMode().isGreaterThan(mode) ||
f.getMode().equals(Flag.Mode.TOP_ROW)));
return flags;
@@ -120,13 +128,14 @@ public class SettingsTab implements Tab, ClickHandler {
int i = 0;
// Jump past empty tabs
while (flags.isEmpty() && i++ < Flag.Mode.values().length) {
- plugin.getPlayers().setFlagsDisplayMode(user.getUniqueId(), plugin.getPlayers().getFlagsDisplayMode(user.getUniqueId()).getNext());
+ currentMode.put(user.getUniqueId(), currentMode.getOrDefault(user.getUniqueId(), Mode.BASIC).getNext());
flags = getFlags();
}
- return flags.stream().map(
+ List<@Nullable PanelItem> result = flags.stream().map(
(f -> f.toPanelItem(plugin, user, world, island,
plugin.getIWM().getHiddenFlags(world).contains(f.getID()))))
.toList();
+ return result;
}
@Override
@@ -137,8 +146,9 @@ public class SettingsTab implements Tab, ClickHandler {
icons.put(4, Flags.CHANGE_SETTINGS.toPanelItem(plugin, user, world, island, false));
icons.put(5, Flags.LOCK.toPanelItem(plugin, user, world, island, false));
}
+
// Add the mode icon
- switch (plugin.getPlayers().getFlagsDisplayMode(user.getUniqueId())) {
+ switch (currentMode.getOrDefault(user.getUniqueId(), Mode.BASIC)) {
case ADVANCED -> icons.put(7, new PanelItemBuilder().icon(Material.GOLD_INGOT)
.name(user.getTranslation(PROTECTION_PANEL + "mode.advanced.name"))
.description(user.getTranslation(PROTECTION_PANEL + "mode.advanced.description"), "",
@@ -161,7 +171,8 @@ public class SettingsTab implements Tab, ClickHandler {
.clickHandler(this)
.build());
}
- // Add the reset everything to default - it's only in the player's settings panel
+
+ // Add the reset everything to default - it's only in the player's settings panel
if (island != null && user.getUniqueId().equals(island.getOwner())) {
icons.put(8, new PanelItemBuilder().icon(Material.TNT)
.name(user.getTranslation(PROTECTION_PANEL + "reset-to-default.name"))
@@ -216,7 +227,7 @@ public class SettingsTab implements Tab, ClickHandler {
@Override
public boolean onClick(Panel panel, User user, ClickType clickType, int slot) {
// Cycle the mode
- plugin.getPlayers().setFlagsDisplayMode(user.getUniqueId(), plugin.getPlayers().getFlagsDisplayMode(user.getUniqueId()).getNext());
+ currentMode.put(user.getUniqueId(), currentMode.getOrDefault(user.getUniqueId(), Mode.BASIC).getNext());
if (panel instanceof TabbedPanel tp) {
tp.setActivePage(0);
tp.refreshPanel();
diff --git a/src/main/java/world/bentobox/bentobox/panels/settings/WorldDefaultSettingsTab.java b/src/main/java/world/bentobox/bentobox/panels/settings/WorldDefaultSettingsTab.java
index 38f2ebad8..d258eb9ab 100644
--- a/src/main/java/world/bentobox/bentobox/panels/settings/WorldDefaultSettingsTab.java
+++ b/src/main/java/world/bentobox/bentobox/panels/settings/WorldDefaultSettingsTab.java
@@ -7,6 +7,7 @@ import org.bukkit.Material;
import org.bukkit.World;
import org.eclipse.jdt.annotation.NonNull;
+import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.flags.Flag.Type;
import world.bentobox.bentobox.api.flags.clicklisteners.WorldToggleClick;
import world.bentobox.bentobox.api.localization.TextVariables;
diff --git a/src/test/java/world/bentobox/bentobox/TestBentoBox.java b/src/test/java/world/bentobox/bentobox/TestBentoBox.java
index fdfe61772..8b3005317 100644
--- a/src/test/java/world/bentobox/bentobox/TestBentoBox.java
+++ b/src/test/java/world/bentobox/bentobox/TestBentoBox.java
@@ -36,6 +36,8 @@ 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;
import org.powermock.modules.junit4.PowerMockRunner;
@@ -50,11 +52,12 @@ import world.bentobox.bentobox.listeners.flags.AbstractCommonSetup;
import world.bentobox.bentobox.lists.Flags;
import world.bentobox.bentobox.managers.CommandsManager;
import world.bentobox.bentobox.managers.FlagsManager;
+import world.bentobox.bentobox.managers.IslandsManager;
import world.bentobox.bentobox.managers.RanksManager;
import world.bentobox.bentobox.util.Util;
@RunWith(PowerMockRunner.class)
-@PrepareForTest({ BentoBox.class, Flags.class, Util.class, Bukkit.class})
+@PrepareForTest({ BentoBox.class, Flags.class, Util.class, Bukkit.class, IslandsManager.class })
public class TestBentoBox extends AbstractCommonSetup {
private static final UUID MEMBER_UUID = UUID.randomUUID();
private static final UUID VISITOR_UUID = UUID.randomUUID();
@@ -74,6 +77,9 @@ public class TestBentoBox extends AbstractCommonSetup {
public void setUp() throws Exception {
super.setUp();
+ // IslandsManager static
+ PowerMockito.mockStatic(IslandsManager.class, Mockito.RETURNS_MOCKS);
+
when(plugin.getCommandsManager()).thenReturn(cm);
SkullMeta skullMeta = mock(SkullMeta.class);
@@ -85,6 +91,7 @@ public class TestBentoBox extends AbstractCommonSetup {
when(player.hasPermission(anyString())).thenReturn(true);
+ when(location.getWorld()).thenReturn(world);
when(ownerOfIsland.getLocation()).thenReturn(location);
when(visitorToIsland.getLocation()).thenReturn(location);
when(location.clone()).thenReturn(location);
@@ -95,6 +102,7 @@ public class TestBentoBox extends AbstractCommonSetup {
island.setOwner(uuid);
island.setProtectionRange(100);
+ island.setCenter(location);
HashMap members = new HashMap<>();
members.put(uuid, RanksManager.OWNER_RANK);
members.put(MEMBER_UUID, RanksManager.MEMBER_RANK);
diff --git a/src/test/java/world/bentobox/bentobox/api/addons/AddonClassLoaderTest.java b/src/test/java/world/bentobox/bentobox/api/addons/AddonClassLoaderTest.java
index f3fb90554..fc5d42574 100644
--- a/src/test/java/world/bentobox/bentobox/api/addons/AddonClassLoaderTest.java
+++ b/src/test/java/world/bentobox/bentobox/api/addons/AddonClassLoaderTest.java
@@ -32,10 +32,13 @@ 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;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
+import com.github.puregero.multilib.MultiLib;
+
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.exceptions.InvalidAddonDescriptionException;
import world.bentobox.bentobox.managers.AddonsManager;
@@ -46,7 +49,7 @@ import world.bentobox.bentobox.managers.AddonsManager;
*
*/
@RunWith(PowerMockRunner.class)
-@PrepareForTest( { BentoBox.class, Bukkit.class })
+@PrepareForTest({ BentoBox.class, Bukkit.class, MultiLib.class })
public class AddonClassLoaderTest {
private enum mandatoryTags {
@@ -80,6 +83,7 @@ public class AddonClassLoaderTest {
*/
@Before
public void setUp() throws Exception {
+ PowerMockito.mockStatic(MultiLib.class, Mockito.RETURNS_MOCKS);
// Set up plugin
plugin = mock(BentoBox.class);
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
diff --git a/src/test/java/world/bentobox/bentobox/api/addons/AddonTest.java b/src/test/java/world/bentobox/bentobox/api/addons/AddonTest.java
index 6bb9c3e84..4921373b8 100644
--- a/src/test/java/world/bentobox/bentobox/api/addons/AddonTest.java
+++ b/src/test/java/world/bentobox/bentobox/api/addons/AddonTest.java
@@ -44,13 +44,15 @@ import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
+import com.github.puregero.multilib.MultiLib;
+
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.managers.AddonsManager;
import world.bentobox.bentobox.managers.IslandsManager;
import world.bentobox.bentobox.managers.PlayersManager;
@RunWith(PowerMockRunner.class)
-@PrepareForTest( { BentoBox.class, Bukkit.class })
+@PrepareForTest({ BentoBox.class, Bukkit.class, MultiLib.class })
public class AddonTest {
public static int BUFFER_SIZE = 10240;
@@ -90,6 +92,8 @@ public class AddonTest {
// Addons manager
when(plugin.getAddonsManager()).thenReturn(am);
+ // MultiLib
+ PowerMockito.mockStatic(MultiLib.class, Mockito.RETURNS_MOCKS);
// Mock item factory (for itemstacks)
ItemFactory itemFactory = mock(ItemFactory.class);
diff --git a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminInfoCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminInfoCommandTest.java
index 85830a653..67f01afb7 100644
--- a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminInfoCommandTest.java
+++ b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminInfoCommandTest.java
@@ -51,7 +51,7 @@ import world.bentobox.bentobox.util.Util;
*
*/
@RunWith(PowerMockRunner.class)
-@PrepareForTest({ Bukkit.class, BentoBox.class, Util.class })
+@PrepareForTest({ Bukkit.class, BentoBox.class, Util.class, IslandsManager.class })
public class AdminInfoCommandTest extends RanksManagerBeforeClassTest {
@Mock
@@ -84,6 +84,8 @@ public class AdminInfoCommandTest extends RanksManagerBeforeClassTest {
public void setUp() throws Exception {
super.setUp();
+ PowerMockito.mockStatic(IslandsManager.class, Mockito.RETURNS_MOCKS);
+
// IWM
when(plugin.getIWM()).thenReturn(iwm);
diff --git a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminSettingsCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminSettingsCommandTest.java
index c22fc6c60..10bdcaa12 100644
--- a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminSettingsCommandTest.java
+++ b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminSettingsCommandTest.java
@@ -144,7 +144,6 @@ public class AdminSettingsCommandTest extends RanksManagerBeforeClassTest {
when(plugin.getIWM()).thenReturn(iwm);
// Players manager
when(plugin.getPlayers()).thenReturn(pm);
- when(pm.getFlagsDisplayMode(any())).thenReturn(Mode.BASIC);
//Island Manager
when(plugin.getIslands()).thenReturn(im);
// Island - player has island
@@ -267,16 +266,6 @@ public class AdminSettingsCommandTest extends RanksManagerBeforeClassTest {
verify(user).sendMessage("general.errors.use-in-game");
}
- /**
- * Test method for {@link world.bentobox.bentobox.api.commands.admin.AdminSettingsCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
- */
- @Test
- public void testExecuteUserStringListOfStringNoArgs() {
- assertTrue(asc.execute(user, "", Collections.emptyList()));
- verify(pm).setFlagsDisplayMode(user.getUniqueId(), Mode.EXPERT);
- // Open panel
- }
-
/**
* Test method for {@link world.bentobox.bentobox.api.commands.admin.AdminSettingsCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}.
*/
diff --git a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminUnregisterCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminUnregisterCommandTest.java
index 8f4aaeb75..3dbdbe6ef 100644
--- a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminUnregisterCommandTest.java
+++ b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminUnregisterCommandTest.java
@@ -29,6 +29,7 @@ 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;
import org.powermock.modules.junit4.PowerMockRunner;
@@ -54,7 +55,7 @@ import world.bentobox.bentobox.util.Util;
*
*/
@RunWith(PowerMockRunner.class)
-@PrepareForTest({ Bukkit.class, BentoBox.class })
+@PrepareForTest({ Bukkit.class, BentoBox.class, IslandsManager.class })
public class AdminUnregisterCommandTest {
private UUID uuid = UUID.randomUUID();
@@ -83,6 +84,7 @@ public class AdminUnregisterCommandTest {
*/
@Before
public void setUp() throws Exception {
+ PowerMockito.mockStatic(IslandsManager.class, Mockito.RETURNS_MOCKS);
// Set up plugin
BentoBox plugin = mock(BentoBox.class);
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/DefaultPlayerCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/DefaultPlayerCommandTest.java
index 385da6c85..d703ef44a 100644
--- a/src/test/java/world/bentobox/bentobox/api/commands/island/DefaultPlayerCommandTest.java
+++ b/src/test/java/world/bentobox/bentobox/api/commands/island/DefaultPlayerCommandTest.java
@@ -39,7 +39,7 @@ import world.bentobox.bentobox.managers.RanksManagerBeforeClassTest;
*
*/
@RunWith(PowerMockRunner.class)
-@PrepareForTest({ Bukkit.class, BentoBox.class })
+@PrepareForTest({ Bukkit.class, BentoBox.class, IslandsManager.class })
public class DefaultPlayerCommandTest extends RanksManagerBeforeClassTest {
@Mock
@@ -68,6 +68,7 @@ public class DefaultPlayerCommandTest extends RanksManagerBeforeClassTest {
@Before
public void setUp() throws Exception {
super.setUp();
+ PowerMockito.mockStatic(IslandsManager.class, Mockito.RETURNS_MOCKS);
// User
when(user.getUniqueId()).thenReturn(UUID.randomUUID());
diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandInfoCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandInfoCommandTest.java
index 964d9fbea..1a3c383c4 100644
--- a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandInfoCommandTest.java
+++ b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandInfoCommandTest.java
@@ -51,7 +51,7 @@ import world.bentobox.bentobox.util.Util;
*
*/
@RunWith(PowerMockRunner.class)
-@PrepareForTest({Bukkit.class, BentoBox.class, Util.class})
+@PrepareForTest({ Bukkit.class, BentoBox.class, Util.class, IslandsManager.class })
public class IslandInfoCommandTest extends RanksManagerBeforeClassTest {
@Mock
@@ -84,6 +84,8 @@ public class IslandInfoCommandTest extends RanksManagerBeforeClassTest {
public void setUp() throws Exception {
super.setUp();
+ PowerMockito.mockStatic(IslandsManager.class, Mockito.RETURNS_MOCKS);
+
// IWM
when(plugin.getIWM()).thenReturn(iwm);
diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandResetCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandResetCommandTest.java
index da1505cd3..787f19dd8 100644
--- a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandResetCommandTest.java
+++ b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandResetCommandTest.java
@@ -62,7 +62,7 @@ import world.bentobox.bentobox.managers.island.NewIsland;
*
*/
@RunWith(PowerMockRunner.class)
-@PrepareForTest({ Bukkit.class, BentoBox.class, NewIsland.class })
+@PrepareForTest({ Bukkit.class, BentoBox.class, NewIsland.class, IslandsManager.class })
public class IslandResetCommandTest {
@Mock
@@ -97,6 +97,7 @@ public class IslandResetCommandTest {
*/
@Before
public void setUp() throws Exception {
+ PowerMockito.mockStatic(IslandsManager.class, Mockito.RETURNS_MOCKS);
// Set up plugin
BentoBox plugin = mock(BentoBox.class);
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCommandTest.java
index b0f360d80..8537a1f7e 100644
--- a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCommandTest.java
+++ b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCommandTest.java
@@ -7,10 +7,13 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import java.beans.IntrospectionException;
+import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.UUID;
@@ -29,10 +32,11 @@ import org.powermock.modules.junit4.PowerMockRunner;
import com.google.common.collect.ImmutableSet;
import world.bentobox.bentobox.BentoBox;
+import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.commands.CompositeCommand;
-import world.bentobox.bentobox.api.commands.island.team.Invite.Type;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
+import world.bentobox.bentobox.database.objects.TeamInvite.Type;
import world.bentobox.bentobox.managers.CommandsManager;
import world.bentobox.bentobox.managers.IslandWorldManager;
import world.bentobox.bentobox.managers.IslandsManager;
@@ -74,6 +78,9 @@ public class IslandTeamCommandTest extends RanksManagerBeforeClassTest {
@Mock
private @Nullable Island island;
+ @Mock
+ private GameModeAddon addon;
+
/**
*/
@Before
@@ -87,6 +94,7 @@ public class IslandTeamCommandTest extends RanksManagerBeforeClassTest {
// Parent command
when(ic.getPermissionPrefix()).thenReturn("bskyblock.");
when(ic.getWorld()).thenReturn(world);
+ when(ic.getAddon()).thenReturn(addon);
// user
uuid = UUID.randomUUID();
@@ -171,11 +179,14 @@ public class IslandTeamCommandTest extends RanksManagerBeforeClassTest {
/**
* Test method for
* {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamCommand#addInvite(world.bentobox.bentobox.api.commands.island.team.Invite.Type, java.util.UUID, java.util.UUID)}.
+ * @throws IntrospectionException
+ * @throws InvocationTargetException
+ * @throws IllegalAccessException
*/
@Test
- public void testAddInvite() {
- tc.addInvite(Invite.Type.TEAM, uuid, invitee, island);
- assertTrue(tc.isInvited(invitee));
+ public void testAddInvite() throws IllegalAccessException, InvocationTargetException, IntrospectionException {
+ tc.addInvite(Type.TEAM, uuid, invitee, island);
+ verify(h, atLeast(1)).saveObject(any());
}
/**
@@ -193,8 +204,7 @@ public class IslandTeamCommandTest extends RanksManagerBeforeClassTest {
*/
@Test
public void testGetInviter() {
- tc.addInvite(Invite.Type.TEAM, uuid, invitee, island);
- assertEquals(uuid, tc.getInviter(invitee));
+ assertNull(tc.getInviter(invitee));
}
/**
@@ -213,12 +223,6 @@ public class IslandTeamCommandTest extends RanksManagerBeforeClassTest {
@Test
public void testGetInvite() {
assertNull(tc.getInvite(invitee));
- tc.addInvite(Invite.Type.TEAM, uuid, invitee, island);
- @Nullable
- Invite invite = tc.getInvite(invitee);
- assertEquals(invitee, invite.getInvitee());
- assertEquals(Type.TEAM, invite.getType());
- assertEquals(uuid, invite.getInviter());
}
/**
@@ -228,7 +232,7 @@ public class IslandTeamCommandTest extends RanksManagerBeforeClassTest {
@Test
public void testRemoveInvite() {
assertNull(tc.getInvite(invitee));
- tc.addInvite(Invite.Type.TEAM, uuid, invitee, island);
+ tc.addInvite(Type.TEAM, uuid, invitee, island);
tc.removeInvite(invitee);
assertNull(tc.getInvite(invitee));
}
diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommandTest.java
index ca056a9ac..a10376f10 100644
--- a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommandTest.java
+++ b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommandTest.java
@@ -32,12 +32,13 @@ import org.powermock.reflect.Whitebox;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.Settings;
import world.bentobox.bentobox.TestWorldSettings;
-import world.bentobox.bentobox.api.commands.island.team.Invite.Type;
import world.bentobox.bentobox.api.events.IslandBaseEvent;
import world.bentobox.bentobox.api.events.team.TeamEvent;
import world.bentobox.bentobox.api.events.team.TeamEvent.TeamEventBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
+import world.bentobox.bentobox.database.objects.TeamInvite;
+import world.bentobox.bentobox.database.objects.TeamInvite.Type;
import world.bentobox.bentobox.managers.CommandsManager;
import world.bentobox.bentobox.managers.IslandWorldManager;
import world.bentobox.bentobox.managers.IslandsManager;
@@ -72,7 +73,7 @@ public class IslandTeamInviteAcceptCommandTest {
@Mock
private PluginManager pim;
@Mock
- private Invite invite;
+ private TeamInvite invite;
/**
*/
@@ -148,7 +149,7 @@ public class IslandTeamInviteAcceptCommandTest {
when(plugin.getIWM()).thenReturn(iwm);
// Invite
- when(invite.getType()).thenReturn(Invite.Type.TEAM);
+ when(invite.getType()).thenReturn(Type.TEAM);
// Team invite accept command
c = new IslandTeamInviteAcceptCommand(itc);
@@ -281,7 +282,7 @@ public class IslandTeamInviteAcceptCommandTest {
when(itc.isInvited(any())).thenReturn(true);
when(itc.getInviter(any())).thenReturn(notUUID);
when(itc.getInvite(any())).thenReturn(invite);
- when(invite.getType()).thenReturn(Invite.Type.COOP);
+ when(invite.getType()).thenReturn(Type.COOP);
when(im.inTeam(any(), any())).thenReturn(false);
assertTrue(c.canExecute(user, "accept", Collections.emptyList()));
verify(user, never()).sendMessage("commands.island.team.invite.errors.you-already-are-in-team");
@@ -332,7 +333,7 @@ public class IslandTeamInviteAcceptCommandTest {
@Test
public void testExecuteUserStringListOfStringCoop() {
// Coop
- when(invite.getType()).thenReturn(Invite.Type.COOP);
+ when(invite.getType()).thenReturn(Type.COOP);
assertTrue(c.execute(user, "accept", Collections.emptyList()));
verify(user).sendMessage("commands.confirmation.confirm", "[seconds]", "0");
}
@@ -343,7 +344,7 @@ public class IslandTeamInviteAcceptCommandTest {
@Test
public void testExecuteUserStringListOfStringTrust() {
// Trust
- when(invite.getType()).thenReturn(Invite.Type.TRUST);
+ when(invite.getType()).thenReturn(Type.TRUST);
assertTrue(c.execute(user, "accept", Collections.emptyList()));
verify(user).sendMessage("commands.confirmation.confirm", "[seconds]", "0");
}
diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteCommandTest.java
index 3a50c1445..cf8c263b6 100644
--- a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteCommandTest.java
+++ b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteCommandTest.java
@@ -40,12 +40,13 @@ import com.google.common.collect.ImmutableSet;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.Settings;
import world.bentobox.bentobox.TestWorldSettings;
-import world.bentobox.bentobox.api.commands.island.team.Invite.Type;
import world.bentobox.bentobox.api.configuration.WorldSettings;
import world.bentobox.bentobox.api.events.IslandBaseEvent;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
+import world.bentobox.bentobox.database.objects.TeamInvite;
+import world.bentobox.bentobox.database.objects.TeamInvite.Type;
import world.bentobox.bentobox.managers.CommandsManager;
import world.bentobox.bentobox.managers.IslandWorldManager;
import world.bentobox.bentobox.managers.IslandsManager;
@@ -319,7 +320,7 @@ public class IslandTeamInviteCommandTest extends RanksManagerBeforeClassTest {
assertTrue(itl.execute(user, itl.getLabel(), List.of("target")));
verify(pim).callEvent(any(IslandBaseEvent.class));
verify(user, never()).sendMessage(eq("commands.island.team.invite.removing-invite"));
- verify(ic).addInvite(Invite.Type.TEAM, uuid, notUUID, island);
+ verify(ic).addInvite(Type.TEAM, uuid, notUUID, island);
verify(user).sendMessage("commands.island.team.invite.invitation-sent", TextVariables.NAME, "target", TextVariables.DISPLAY_NAME, "&Ctarget");
verify(target).sendMessage("commands.island.team.invite.name-has-invited-you", TextVariables.NAME, "tastybento", TextVariables.DISPLAY_NAME, "&Ctastbento");
verify(target).sendMessage("commands.island.team.invite.to-accept-or-reject", TextVariables.LABEL, "island");
@@ -338,7 +339,7 @@ public class IslandTeamInviteCommandTest extends RanksManagerBeforeClassTest {
assertTrue(itl.execute(user, itl.getLabel(), List.of("target")));
verify(pim).callEvent(any(IslandBaseEvent.class));
verify(user, never()).sendMessage("commands.island.team.invite.removing-invite");
- verify(ic).addInvite(Invite.Type.TEAM, uuid, notUUID, island);
+ verify(ic).addInvite(Type.TEAM, uuid, notUUID, island);
verify(user).sendMessage("commands.island.team.invite.invitation-sent", TextVariables.NAME, "target",
TextVariables.DISPLAY_NAME, "&Ctarget");
verify(target).sendMessage("commands.island.team.invite.name-has-invited-you", TextVariables.NAME, "tastybento",
@@ -359,7 +360,7 @@ public class IslandTeamInviteCommandTest extends RanksManagerBeforeClassTest {
when(ic.isInvited(notUUID)).thenReturn(true);
// Set up invite
when(ic.getInviter(notUUID)).thenReturn(uuid);
- Invite invite = mock(Invite.class);
+ TeamInvite invite = mock(TeamInvite.class);
when(invite.getType()).thenReturn(Type.TEAM);
when(ic.getInvite(notUUID)).thenReturn(invite);
assertTrue(itl.execute(user, itl.getLabel(), List.of("target")));
diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommandTest.java
index 63d6f1bd8..7c89ff93c 100644
--- a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommandTest.java
+++ b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommandTest.java
@@ -54,7 +54,7 @@ import world.bentobox.bentobox.managers.PlayersManager;
*
*/
@RunWith(PowerMockRunner.class)
-@PrepareForTest({ Bukkit.class, BentoBox.class, User.class })
+@PrepareForTest({ Bukkit.class, BentoBox.class, User.class, IslandsManager.class })
public class IslandTeamSetownerCommandTest {
@Mock
@@ -84,6 +84,8 @@ public class IslandTeamSetownerCommandTest {
*/
@Before
public void setUp() throws Exception {
+ PowerMockito.mockStatic(IslandsManager.class, Mockito.RETURNS_MOCKS);
+
// Set up plugin
BentoBox plugin = mock(BentoBox.class);
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
@@ -276,7 +278,6 @@ public class IslandTeamSetownerCommandTest {
assertTrue(its.canExecute(user, "", List.of("tastybento")));
assertTrue(its.execute(user, "", List.of("tastybento")));
verify(im).setOwner(any(), eq(user), eq(target));
- verify(im).save(island);
}
/**
@@ -292,7 +293,6 @@ public class IslandTeamSetownerCommandTest {
assertTrue(its.canExecute(user, "", List.of("tastybento")));
assertTrue(its.execute(user, "", List.of("tastybento")));
verify(im).setOwner(any(), eq(user), eq(target));
- verify(im).save(island);
}
/**
diff --git a/src/test/java/world/bentobox/bentobox/api/events/island/IslandEventTest.java b/src/test/java/world/bentobox/bentobox/api/events/island/IslandEventTest.java
index 0677e8281..77bf06184 100644
--- a/src/test/java/world/bentobox/bentobox/api/events/island/IslandEventTest.java
+++ b/src/test/java/world/bentobox/bentobox/api/events/island/IslandEventTest.java
@@ -21,6 +21,7 @@ import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.reflect.Whitebox;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.events.IslandBaseEvent;
@@ -28,13 +29,14 @@ import world.bentobox.bentobox.api.events.island.IslandEvent.Reason;
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.database.objects.IslandDeletion;
+import world.bentobox.bentobox.managers.IslandsManager;
/**
* @author tastybento
*
*/
@RunWith(PowerMockRunner.class)
-@PrepareForTest({ BentoBox.class, Bukkit.class })
+@PrepareForTest({ BentoBox.class, Bukkit.class, IslandsManager.class })
public class IslandEventTest {
private Island island;
@@ -47,11 +49,18 @@ public class IslandEventTest {
private IslandDeletion deletedIslandInfo;
@Mock
private PluginManager pim;
+ @Mock
+ private BentoBox plugin;
/**
*/
@Before
public void setUp() throws Exception {
+ PowerMockito.mockStatic(IslandsManager.class, Mockito.RETURNS_MOCKS);
+
+ // Set up plugin
+ Whitebox.setInternalState(BentoBox.class, "instance", plugin);
+
uuid = UUID.randomUUID();
// Bukkit
PowerMockito.mockStatic(Bukkit.class);
diff --git a/src/test/java/world/bentobox/bentobox/database/objects/IslandTest.java b/src/test/java/world/bentobox/bentobox/database/objects/IslandTest.java
index 527eef8f4..b2b149abc 100644
--- a/src/test/java/world/bentobox/bentobox/database/objects/IslandTest.java
+++ b/src/test/java/world/bentobox/bentobox/database/objects/IslandTest.java
@@ -46,6 +46,7 @@ import world.bentobox.bentobox.lists.Flags;
import world.bentobox.bentobox.managers.CommandsManager;
import world.bentobox.bentobox.managers.FlagsManager;
import world.bentobox.bentobox.managers.IslandWorldManager;
+import world.bentobox.bentobox.managers.IslandsManager;
import world.bentobox.bentobox.managers.RanksManager;
import world.bentobox.bentobox.util.Pair;
@@ -54,7 +55,7 @@ import world.bentobox.bentobox.util.Pair;
*
*/
@RunWith(PowerMockRunner.class)
-@PrepareForTest({ Bukkit.class })
+@PrepareForTest({ Bukkit.class, IslandsManager.class })
public class IslandTest {
private static final int DISTANCE = 400;
@@ -105,6 +106,9 @@ public class IslandTest {
// Commands manager
when(plugin.getCommandsManager()).thenReturn(cm);
+ // Islands Manager
+ PowerMockito.mockStatic(IslandsManager.class, Mockito.RETURNS_MOCKS);
+
i = new Island(new Island(location, uuid, 100));
}
@@ -1105,15 +1109,6 @@ public class IslandTest {
assertTrue(ii.isChanged());
}
- /**
- * Test method for {@link world.bentobox.bentobox.database.objects.Island#setChanged(boolean)}.
- */
- @Test
- public void testSetChangedBoolean() {
- i.setChanged(false);
- assertFalse(i.isChanged());
- }
-
/**
* Test method for {@link world.bentobox.bentobox.database.objects.Island#getProtectionCenter()}.
*/
diff --git a/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java
index 3d1582420..d60092f74 100644
--- a/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java
+++ b/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java
@@ -65,7 +65,7 @@ import world.bentobox.bentobox.util.Util;
*
*/
@RunWith(PowerMockRunner.class)
-@PrepareForTest({ BentoBox.class, Util.class, Bukkit.class })
+@PrepareForTest({ BentoBox.class, Util.class, Bukkit.class, IslandsManager.class })
public class JoinLeaveListenerTest {
private static final String[] NAMES = { "adam", "ben", "cara", "dave", "ed", "frank", "freddy", "george", "harry",
@@ -111,6 +111,8 @@ public class JoinLeaveListenerTest {
*/
@Before
public void setUp() throws Exception {
+ PowerMockito.mockStatic(IslandsManager.class, Mockito.RETURNS_MOCKS);
+
// Set up plugin
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
@@ -218,8 +220,6 @@ public class JoinLeaveListenerTest {
jll = new JoinLeaveListener(plugin);
}
- /**
- */
@After
public void tearDown() {
User.clearUsers();
@@ -235,8 +235,7 @@ public class JoinLeaveListenerTest {
PlayerJoinEvent event = new PlayerJoinEvent(player, "");
jll.onPlayerJoin(event);
// Verify
- verify(pm, times(2)).addPlayer(any());
- verify(pm, times(2)).save(any());
+ verify(pm, times(3)).getPlayer(any());
verify(player, never()).sendMessage(anyString());
// Verify resets
verify(pm).setResets(eq(world), any(), eq(0));
@@ -245,7 +244,6 @@ public class JoinLeaveListenerTest {
verify(chest).clear();
verify(inv).clear();
assertTrue(set.isEmpty());
- verify(pm, times(2)).save(any());
}
/**
@@ -262,7 +260,6 @@ public class JoinLeaveListenerTest {
verify(chest, never()).clear();
verify(inv, never()).clear();
assertFalse(set.isEmpty());
- verify(pm).save(any());
}
/**
@@ -355,8 +352,7 @@ public class JoinLeaveListenerTest {
PlayerJoinEvent event = new PlayerJoinEvent(player, "");
jll.onPlayerJoin(event);
// Verify
- verify(pm, times(2)).addPlayer(any());
- verify(pm, times(2)).save(any());
+ verify(pm, times(3)).getPlayer(any());
verify(player).sendMessage(eq("commands.island.create.on-first-login"));
}
@@ -372,7 +368,6 @@ public class JoinLeaveListenerTest {
verify(chest).clear();
verify(inv).clear();
assertTrue(set.isEmpty());
- verify(pm).save(any());
}
/**
@@ -387,7 +382,6 @@ public class JoinLeaveListenerTest {
verify(chest, never()).clear();
verify(inv, never()).clear();
assertFalse(set.isEmpty());
- verify(pm, never()).save(any());
}
/**
diff --git a/src/test/java/world/bentobox/bentobox/managers/AddonsManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/AddonsManagerTest.java
index afb1a3bcc..260ef75d4 100644
--- a/src/test/java/world/bentobox/bentobox/managers/AddonsManagerTest.java
+++ b/src/test/java/world/bentobox/bentobox/managers/AddonsManagerTest.java
@@ -37,6 +37,8 @@ import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
+import com.github.puregero.multilib.MultiLib;
+
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.Settings;
import world.bentobox.bentobox.api.addons.Addon;
@@ -49,7 +51,7 @@ import world.bentobox.bentobox.database.DatabaseSetup.DatabaseType;
import world.bentobox.bentobox.database.objects.DataObject;
@RunWith(PowerMockRunner.class)
-@PrepareForTest( {Bukkit.class, BentoBox.class, DefaultPermissions.class} )
+@PrepareForTest({ Bukkit.class, BentoBox.class, DefaultPermissions.class, MultiLib.class })
public class AddonsManagerTest {
private BentoBox plugin;
@@ -81,6 +83,8 @@ public class AddonsManagerTest {
when(plugin.getSettings()).thenReturn(s);
PowerMockito.mockStatic(DefaultPermissions.class);
+
+ PowerMockito.mockStatic(MultiLib.class, Mockito.RETURNS_MOCKS);
}
/**
diff --git a/src/test/java/world/bentobox/bentobox/managers/BlueprintsManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/BlueprintsManagerTest.java
index b3b24ab42..ade8eda30 100644
--- a/src/test/java/world/bentobox/bentobox/managers/BlueprintsManagerTest.java
+++ b/src/test/java/world/bentobox/bentobox/managers/BlueprintsManagerTest.java
@@ -45,6 +45,8 @@ import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
+import com.github.puregero.multilib.MultiLib;
+
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.Addon;
import world.bentobox.bentobox.api.addons.AddonDescription;
@@ -62,7 +64,7 @@ import world.bentobox.bentobox.database.objects.Island;
*
*/
@RunWith(PowerMockRunner.class)
-@PrepareForTest( {Bukkit.class, BentoBox.class, BlueprintPaster.class} )
+@PrepareForTest({ Bukkit.class, BentoBox.class, BlueprintPaster.class, MultiLib.class })
public class BlueprintsManagerTest {
public static int BUFFER_SIZE = 10240;
@@ -95,10 +97,12 @@ public class BlueprintsManagerTest {
private int times;
@Mock
private Server server;
- /**
- */
+
@Before
public void setUp() throws Exception {
+ // Multilib
+ PowerMockito.mockStatic(MultiLib.class, Mockito.RETURNS_MOCKS);
+
// Make the addon
dataFolder = new File("dataFolder");
jarFile = new File("addon.jar");
diff --git a/src/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java
index 7931f9df7..dadfd87bf 100644
--- a/src/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java
+++ b/src/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java
@@ -65,6 +65,7 @@ import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
+import com.github.puregero.multilib.MultiLib;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
@@ -85,7 +86,7 @@ import world.bentobox.bentobox.managers.island.IslandCache;
import world.bentobox.bentobox.util.Util;
@RunWith(PowerMockRunner.class)
-@PrepareForTest({ Bukkit.class, BentoBox.class, Util.class, Location.class })
+@PrepareForTest({ Bukkit.class, BentoBox.class, Util.class, Location.class, MultiLib.class })
public class IslandsManagerTest extends AbstractCommonSetup {
@Mock
@@ -157,6 +158,9 @@ public class IslandsManagerTest extends AbstractCommonSetup {
plugin = mock(BentoBox.class);
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
+ // Mutilib
+ PowerMockito.mockStatic(MultiLib.class, Mockito.RETURNS_MOCKS);
+
// island world mgr
when(world.getName()).thenReturn("world");
when(world.getEnvironment()).thenReturn(World.Environment.NORMAL);
@@ -242,7 +246,7 @@ public class IslandsManagerTest extends AbstractCommonSetup {
// Island
when(island.getOwner()).thenReturn(uuid);
when(island.getWorld()).thenReturn(world);
- when(island.getMaxMembers()).thenReturn(null); // default
+ when(island.getMaxMembers()).thenReturn(new HashMap<>()); // default
when(island.getMaxMembers(Mockito.anyInt())).thenReturn(null); // default
when(island.getCenter()).thenReturn(location);
when(island.getProtectionCenter()).thenReturn(location);
@@ -329,6 +333,9 @@ public class IslandsManagerTest extends AbstractCommonSetup {
// Util strip spaces
when(Util.stripSpaceAfterColorCodes(anyString())).thenCallRealMethod();
+ // World UID
+ when(world.getUID()).thenReturn(uuid);
+
// Class under test
im = new IslandsManager(plugin);
// Set cache
@@ -970,7 +977,7 @@ public class IslandsManagerTest extends AbstractCommonSetup {
/**
* Test method for
- * {@link world.bentobox.bentobox.managers.IslandsManager#save(Island)}.
+ * {@link world.bentobox.bentobox.managers.IslandsManager#updateIsland(Island)}.
*/
@Test
public void testSave() {
@@ -1372,14 +1379,14 @@ public class IslandsManagerTest extends AbstractCommonSetup {
Island island = mock(Island.class);
when(island.getOwner()).thenReturn(uuid);
when(island.getWorld()).thenReturn(world);
- when(island.getMaxMembers()).thenReturn(null);
+ when(island.getMaxMembers()).thenReturn(new HashMap<>());
when(island.getMaxMembers(Mockito.anyInt())).thenReturn(null);
when(iwm.getMaxTeamSize(eq(world))).thenReturn(4);
// Offline owner
when(Bukkit.getPlayer(any(UUID.class))).thenReturn(null);
// Test
assertEquals(4, im.getMaxMembers(island, RanksManager.MEMBER_RANK));
- verify(island).setMaxMembers(eq(RanksManager.MEMBER_RANK), eq(null));
+ verify(island, never()).setMaxMembers(eq(RanksManager.MEMBER_RANK), eq(null)); // No change
}
/**
@@ -1391,14 +1398,14 @@ public class IslandsManagerTest extends AbstractCommonSetup {
Island island = mock(Island.class);
when(island.getOwner()).thenReturn(uuid);
when(island.getWorld()).thenReturn(world);
- when(island.getMaxMembers()).thenReturn(null);
+ when(island.getMaxMembers()).thenReturn(new HashMap<>());
when(island.getMaxMembers(Mockito.anyInt())).thenReturn(null);
when(iwm.getMaxTeamSize(eq(world))).thenReturn(4);
// Online owner
when(Bukkit.getPlayer(any(UUID.class))).thenReturn(player);
// Test
assertEquals(4, im.getMaxMembers(island, RanksManager.MEMBER_RANK));
- verify(island).setMaxMembers(eq(RanksManager.MEMBER_RANK), eq(null));
+ verify(island, never()).setMaxMembers(RanksManager.MEMBER_RANK, null);
}
/**
@@ -1410,7 +1417,7 @@ public class IslandsManagerTest extends AbstractCommonSetup {
Island island = mock(Island.class);
when(island.getOwner()).thenReturn(uuid);
when(island.getWorld()).thenReturn(world);
- when(island.getMaxMembers()).thenReturn(null);
+ when(island.getMaxMembers()).thenReturn(new HashMap<>());
when(island.getMaxMembers(Mockito.anyInt())).thenReturn(null);
when(iwm.getMaxTeamSize(eq(world))).thenReturn(4);
when(iwm.getMaxCoopSize(eq(world))).thenReturn(2);
@@ -1419,9 +1426,9 @@ public class IslandsManagerTest extends AbstractCommonSetup {
when(Bukkit.getPlayer(any(UUID.class))).thenReturn(player);
// Test
assertEquals(2, im.getMaxMembers(island, RanksManager.COOP_RANK));
- verify(island).setMaxMembers(eq(RanksManager.COOP_RANK), eq(null));
+ verify(island, never()).setMaxMembers(RanksManager.COOP_RANK, null); // No change
assertEquals(3, im.getMaxMembers(island, RanksManager.TRUSTED_RANK));
- verify(island).setMaxMembers(eq(RanksManager.TRUSTED_RANK), eq(null));
+ verify(island, never()).setMaxMembers(RanksManager.TRUSTED_RANK, null);
}
/**
@@ -1439,7 +1446,7 @@ public class IslandsManagerTest extends AbstractCommonSetup {
when(Bukkit.getPlayer(any(UUID.class))).thenReturn(player);
// Test
assertEquals(10, im.getMaxMembers(island, RanksManager.MEMBER_RANK));
- verify(island).setMaxMembers(eq(RanksManager.MEMBER_RANK), eq(10));
+ verify(island).setMaxMembers(RanksManager.MEMBER_RANK, 10);
}
/**
@@ -1457,7 +1464,7 @@ public class IslandsManagerTest extends AbstractCommonSetup {
when(Bukkit.getPlayer(any(UUID.class))).thenReturn(player);
// Test
assertEquals(10, im.getMaxMembers(island, RanksManager.MEMBER_RANK));
- verify(island).setMaxMembers(eq(RanksManager.MEMBER_RANK), eq(10));
+ verify(island).setMaxMembers(RanksManager.MEMBER_RANK, 10);
}
/**
@@ -1469,7 +1476,7 @@ public class IslandsManagerTest extends AbstractCommonSetup {
Island island = mock(Island.class);
when(island.getOwner()).thenReturn(uuid);
when(island.getWorld()).thenReturn(world);
- when(island.getMaxMembers()).thenReturn(null);
+ when(island.getMaxMembers()).thenReturn(new HashMap<>());
when(iwm.getMaxTeamSize(eq(world))).thenReturn(4);
// Permission
when(iwm.getPermissionPrefix(any())).thenReturn("bskyblock.");
@@ -1482,7 +1489,7 @@ public class IslandsManagerTest extends AbstractCommonSetup {
when(Bukkit.getPlayer(any(UUID.class))).thenReturn(player);
// Test
assertEquals(8, im.getMaxMembers(island, RanksManager.MEMBER_RANK));
- verify(island).setMaxMembers(eq(RanksManager.MEMBER_RANK), eq(8));
+ verify(island).setMaxMembers(RanksManager.MEMBER_RANK, 8);
}
/**
@@ -1494,7 +1501,7 @@ public class IslandsManagerTest extends AbstractCommonSetup {
Island island = mock(Island.class);
// Test
im.setMaxMembers(island, RanksManager.MEMBER_RANK, 40);
- verify(island).setMaxMembers(eq(RanksManager.MEMBER_RANK), eq(40));
+ verify(island).setMaxMembers(RanksManager.MEMBER_RANK, 40);
}
/**
@@ -1546,7 +1553,7 @@ public class IslandsManagerTest extends AbstractCommonSetup {
// Test
IslandsManager im = new IslandsManager(plugin);
assertEquals(4, im.getMaxHomes(island));
- verify(island).setMaxHomes(eq(null));
+ verify(island, never()).setMaxHomes(null);
}
/**
@@ -1572,7 +1579,7 @@ public class IslandsManagerTest extends AbstractCommonSetup {
// Test
IslandsManager im = new IslandsManager(plugin);
assertEquals(20, im.getMaxHomes(island));
- verify(island).setMaxHomes(eq(20));
+ verify(island, never()).setMaxHomes(20);
}
/**
@@ -1598,7 +1605,7 @@ public class IslandsManagerTest extends AbstractCommonSetup {
// Test
IslandsManager im = new IslandsManager(plugin);
assertEquals(8, im.getMaxHomes(island));
- verify(island).setMaxHomes(eq(8));
+ verify(island).setMaxHomes(8);
}
/**
diff --git a/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java
index 96790efba..8037ad671 100644
--- a/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java
+++ b/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java
@@ -6,7 +6,9 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -53,13 +55,13 @@ import org.powermock.reflect.Whitebox;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.Settings;
-import world.bentobox.bentobox.api.flags.Flag.Mode;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.AbstractDatabaseHandler;
import world.bentobox.bentobox.database.Database;
import world.bentobox.bentobox.database.DatabaseSetup;
import world.bentobox.bentobox.database.DatabaseSetup.DatabaseType;
import world.bentobox.bentobox.database.objects.Island;
+import world.bentobox.bentobox.database.objects.Names;
import world.bentobox.bentobox.database.objects.Players;
import world.bentobox.bentobox.hooks.VaultHook;
import world.bentobox.bentobox.util.Util;
@@ -240,6 +242,18 @@ public class PlayersManagerTest {
when(tamed.getOwner()).thenReturn(p);
when(world.getEntitiesByClass(Tameable.class)).thenReturn(list);
+ // Loading objects
+ Object players = new Players();
+ when(h.loadObject(anyString())).thenReturn(players);
+ // Set up names database
+ List