From c34d6ff8685993a8865cbe1a04741d1de7391af2 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 6 Apr 2024 21:19:20 -0700 Subject: [PATCH 01/19] Switch to use database for team invites. --- .../island/team/IslandTeamCommand.java | 28 ++++---- .../island/team/IslandTeamCoopCommand.java | 4 +- .../commands/island/team/IslandTeamGUI.java | 8 ++- .../team/IslandTeamInviteAcceptCommand.java | 13 ++-- .../island/team/IslandTeamInviteCommand.java | 4 +- .../island/team/IslandTeamTrustCommand.java | 2 +- .../objects/TeamInvite.java} | 64 ++++++++++++------- .../island/team/IslandTeamCommandTest.java | 13 ++-- .../IslandTeamInviteAcceptCommandTest.java | 13 ++-- .../team/IslandTeamInviteCommandTest.java | 9 +-- 10 files changed, 88 insertions(+), 70 deletions(-) rename src/main/java/world/bentobox/bentobox/{api/commands/island/team/Invite.java => database/objects/TeamInvite.java} (56%) 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..19d8c2515 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)); } /** @@ -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..25cceac63 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,7 +95,7 @@ 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()); @@ -120,7 +121,7 @@ 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()); @@ -146,7 +147,7 @@ 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 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/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/commands/island/team/Invite.java b/src/main/java/world/bentobox/bentobox/database/objects/TeamInvite.java similarity index 56% rename from src/main/java/world/bentobox/bentobox/api/commands/island/team/Invite.java rename to src/main/java/world/bentobox/bentobox/database/objects/TeamInvite.java index c6328d066..72d5b960a 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/Invite.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/TeamInvite.java @@ -1,17 +1,16 @@ -package world.bentobox.bentobox.api.commands.island.team; +package world.bentobox.bentobox.database.objects; import java.util.Objects; import java.util.UUID; -import world.bentobox.bentobox.database.objects.Island; +import com.google.gson.annotations.Expose; /** - * Represents an invite - * @author tastybento - * @since 1.8.0 + * Data object for team invites */ -public class Invite { - +@Table(name = "TeamInvites") +public class TeamInvite implements DataObject { + /** * Type of invitation * @@ -22,24 +21,40 @@ public class Invite { TRUST } - private final Type type; - private final UUID inviter; - private final UUID invitee; - private final Island island; - + @Expose + private Type type; + @Expose + private UUID inviter; + @Expose + private Island island; + + @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 island this invite is for */ - public Invite(Type type, UUID inviter, UUID invitee, Island island) { + public TeamInvite(Type type, UUID inviter, UUID invitee, Island island) { this.type = type; + this.uniqueId = invitee.toString(); this.inviter = inviter; - this.invitee = invitee; this.island = island; } + @Override + public String getUniqueId() { + // Inviter + return this.uniqueId; + } + + @Override + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + /** * @return the type */ @@ -47,6 +62,13 @@ public class Invite { return type; } + /** + * @return the invitee + */ + public UUID getInvitee() { + return UUID.fromString(uniqueId); + } + /** * @return the inviter */ @@ -54,13 +76,6 @@ public class Invite { return inviter; } - /** - * @return the invitee - */ - public UUID getInvitee() { - return invitee; - } - /** * @return the island */ @@ -73,7 +88,7 @@ public class Invite { */ @Override public int hashCode() { - return Objects.hash(invitee, inviter, type); + return Objects.hash(inviter, uniqueId, type); } /* (non-Javadoc) @@ -87,9 +102,10 @@ public class Invite { if (obj == null) { return false; } - if (!(obj instanceof Invite other)) { + if (!(obj instanceof TeamInvite other)) { return false; } - return Objects.equals(invitee, other.invitee) && Objects.equals(inviter, other.inviter) && type == other.type; + return Objects.equals(inviter, other.inviter) && Objects.equals(uniqueId, other.getUniqueId()) + && type == other.type; } } 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..09d21b8ac 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 @@ -30,9 +30,10 @@ import com.google.common.collect.ImmutableSet; import world.bentobox.bentobox.BentoBox; 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; +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; @@ -174,7 +175,7 @@ public class IslandTeamCommandTest extends RanksManagerBeforeClassTest { */ @Test public void testAddInvite() { - tc.addInvite(Invite.Type.TEAM, uuid, invitee, island); + tc.addInvite(Type.TEAM, uuid, invitee, island); assertTrue(tc.isInvited(invitee)); } @@ -193,7 +194,7 @@ public class IslandTeamCommandTest extends RanksManagerBeforeClassTest { */ @Test public void testGetInviter() { - tc.addInvite(Invite.Type.TEAM, uuid, invitee, island); + tc.addInvite(Type.TEAM, uuid, invitee, island); assertEquals(uuid, tc.getInviter(invitee)); } @@ -213,9 +214,9 @@ public class IslandTeamCommandTest extends RanksManagerBeforeClassTest { @Test public void testGetInvite() { assertNull(tc.getInvite(invitee)); - tc.addInvite(Invite.Type.TEAM, uuid, invitee, island); + tc.addInvite(Type.TEAM, uuid, invitee, island); @Nullable - Invite invite = tc.getInvite(invitee); + TeamInvite invite = tc.getInvite(invitee); assertEquals(invitee, invite.getInvitee()); assertEquals(Type.TEAM, invite.getType()); assertEquals(uuid, invite.getInviter()); @@ -228,7 +229,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"))); From aaa1504dc6057582e5ce6d970bc9137c0109aae4 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 7 Apr 2024 17:05:21 -0700 Subject: [PATCH 02/19] WIP multipaper --- pom.xml | 23 +- .../world/bentobox/bentobox/BentoBox.java | 14 - .../admin/AdminEmptyTrashCommand.java | 61 ---- .../api/commands/admin/AdminInfoCommand.java | 3 - .../commands/admin/AdminSettingsCommand.java | 4 +- .../commands/admin/AdminSwitchtoCommand.java | 87 ------ .../api/commands/admin/AdminTrashCommand.java | 73 ----- .../admin/AdminUnregisterCommand.java | 2 +- .../admin/conversations/NamePrompt.java | 2 +- .../team/IslandTeamInviteAcceptCommand.java | 3 +- .../team/IslandTeamSetownerCommand.java | 2 +- .../bentobox/database/objects/Island.java | 177 +++++++---- .../bentobox/listeners/JoinLeaveListener.java | 9 +- .../clicklisteners/CommandCycleClick.java | 2 +- .../bentobox/managers/IslandsManager.java | 284 ++++++------------ .../bentobox/managers/PlayersManager.java | 172 +++-------- .../bentobox/managers/island/IslandCache.java | 34 ++- .../bentobox/managers/island/IslandGrid.java | 37 +-- .../bentobox/managers/island/NewIsland.java | 4 +- .../team/IslandTeamSetownerCommandTest.java | 4 +- .../bentobox/database/objects/IslandTest.java | 9 - .../listeners/JoinLeaveListenerTest.java | 6 - .../bentobox/managers/IslandsManagerTest.java | 2 +- .../bentobox/managers/PlayersManagerTest.java | 37 --- .../managers/island/NewIslandTest.java | 16 +- 25 files changed, 327 insertions(+), 740 deletions(-) delete mode 100644 src/main/java/world/bentobox/bentobox/api/commands/admin/AdminEmptyTrashCommand.java delete mode 100644 src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSwitchtoCommand.java delete mode 100644 src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTrashCommand.java diff --git a/pom.xml b/pom.xml index 8aa65b84f..1d0d56251 100644 --- a/pom.xml +++ b/pom.xml @@ -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/BentoBox.java b/src/main/java/world/bentobox/bentobox/BentoBox.java index 235d37ef6..567c2eceb 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(); 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..1fa50c1a7 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 @@ -206,11 +206,11 @@ public class AdminSettingsCommand extends CompositeCommand { switch (f.getType()) { case PROTECTION -> { island.setFlag(f, rank); - getIslands().save(island); + getIslands().updateIsland(island); } case SETTING -> { island.setSettingsFlag(f, activeState); - getIslands().save(island); + getIslands().updateIsland(island); } case WORLD_SETTING -> f.setSetting(getWorld(), activeState); default -> { 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..d0b319aee 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,7 @@ 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); + getIslands().updateIsland(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..645be62b2 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,7 @@ public class NamePrompt extends StringPrompt { @Override public Prompt acceptInput(@NonNull ConversationContext context, String input) { if (island.renameHome(oldName, input)) { - plugin.getIslands().save(island); + plugin.getIslands().updateIsland(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/team/IslandTeamInviteAcceptCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommand.java index 25cceac63..ed08f2394 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 @@ -13,6 +13,7 @@ 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.IslandsManager; import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.util.Util; @@ -197,7 +198,7 @@ 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); + IslandsManager.updateIsland(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/IslandTeamSetownerCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommand.java index e80580aa9..e9f1e5eae 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 @@ -91,7 +91,7 @@ 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); + getIslands().updateIsland(island); return true; } 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..50e38334e 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/Island.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/Island.java @@ -41,6 +41,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; @@ -243,7 +244,6 @@ public class Island implements DataObject, MetaDataAble { range = BentoBox.getInstance().getIWM().getIslandDistance(world); this.protectionRange = protectionRange; this.maxEverProtectionRange = protectionRange; - this.setChanged(); } /** @@ -290,6 +290,7 @@ public class Island implements DataObject, MetaDataAble { this.updatedDate = island.getUpdatedDate(); this.world = island.getWorld(); this.bonusRanges.addAll(island.getBonusRanges()); + this.primary = island.primary; this.setChanged(); } @@ -304,8 +305,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 +323,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 +1011,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 (!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 +1049,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(); } /** @@ -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(); } /** @@ -1206,8 +1226,14 @@ public class Island implements DataObject, MetaDataAble { if (uuid == null) { return; // Defensive code } - members.put(uuid, rank); - setChanged(); + members.compute(uuid, (key, value) -> { + if (value == null || !value.equals(rank)) { + setChanged(); // Call setChanged only if the value is updated. + BentoBox.getInstance().logDebug("Set rank for " + uuid + " to " + rank); + return rank; + } + return value; + }); } /** @@ -1266,7 +1292,6 @@ public class Island implements DataObject, MetaDataAble { @Override public void setUniqueId(String uniqueId) { this.uniqueId = uniqueId; - setChanged(); } /** @@ -1274,7 +1299,6 @@ public class Island implements DataObject, MetaDataAble { */ public void setUpdatedDate(long updatedDate) { this.updatedDate = updatedDate; - setChanged(); } /** @@ -1347,8 +1371,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 +1397,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 +1485,6 @@ public class Island implements DataObject, MetaDataAble { */ public void setGameMode(String gameMode) { this.gameMode = gameMode; - setChanged(); } /** @@ -1603,8 +1632,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 +1658,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 +1694,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 +1730,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 +1782,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 +1807,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 +1821,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 +1864,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 +1886,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 +1914,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 +1983,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(); + } } /** @@ -1946,8 +2007,10 @@ public class Island implements DataObject, MetaDataAble { * @param primary the primary to set */ public void setPrimary(boolean primary) { - this.primary = primary; - setChanged(); + if (this.primary != primary) { + this.primary = primary; + setChanged(); + } } /** diff --git a/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java b/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java index f73f3dac3..7cac25a0c 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; @@ -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); } @@ -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/flags/clicklisteners/CommandCycleClick.java b/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandCycleClick.java index 8b78b725d..922c82dcd 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 @@ -61,7 +61,7 @@ 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); + plugin.getIslands().updateIsland(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..4dcd898f7 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java @@ -37,6 +37,8 @@ import org.bukkit.util.Vector; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; +import com.github.puregero.multilib.MultiLib; + import io.papermc.lib.PaperLib; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.events.IslandBaseEvent; @@ -44,7 +46,6 @@ 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.objects.Island; @@ -65,29 +66,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 +96,52 @@ 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 -> { + BentoBox.getInstance().logDebug("Updating island " + id); + Island island = handler.loadObject(id); + if (island != null) { + islandCache.updateIsland(island); + } + }); + // List for new islands + MultiLib.onString(plugin, "bentobox-newIsland", id -> { + BentoBox.getInstance().logDebug("New island " + id); + Island island = handler.loadObject(id); + if (island != null) { + islandCache.addIsland(island); + } + }); + // Remove islands + MultiLib.onString(plugin, "bentobox-deleteIsland", id -> { + BentoBox.getInstance().logDebug("Delete island " + id); + Island island = handler.loadObject(id); + if (island != null) { + islandCache.removeIsland(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)); + BentoBox.getInstance().logDebug("Setting spawn for world " + world); + } + } + + }); } /** @@ -121,8 +149,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 +255,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; @@ -260,15 +287,10 @@ public class IslandsManager { 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); + // Inform other servers + MultiLib.notify("bentobox-deletedIsland", island.getUniqueId()); // Remove players from island removePlayersFromIsland(island); if (!plugin.getSettings().isKeepPreviousIslandOnReset()) { @@ -462,7 +484,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 +508,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 @@ -508,7 +530,7 @@ public class IslandsManager { islandMax); } island.setMaxMembers(rank, islandMax == worldDefault ? null : islandMax); - this.save(island); + updateIsland(island); return islandMax; } @@ -547,12 +569,12 @@ 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); + 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 @@ -737,7 +759,7 @@ public class IslandsManager { public boolean setHomeLocation(@Nullable Island island, Location location, String name) { if (island != null) { island.addHome(name, location); - this.save(island); + updateIsland(island); return true; } return false; @@ -890,7 +912,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 +923,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 +1154,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 +1166,12 @@ 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); - } - } - this.spawn.put(spawn.getWorld(), spawn); - spawn.setSpawn(true); + spawns.put(Util.getWorld(spawn.getWorld()), spawn); + // Tell other servers + MultiLib.notify("bentobox-setspawn", spawn.getWorld().getUID().toString() + "," + spawn.getUniqueId()); } + /** * Clears the spawn island for this world * @@ -1164,11 +1179,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 +1205,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 +1218,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 +1228,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 +1394,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 +1468,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 +1607,17 @@ 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())); + BentoBox.getInstance().logDebug("Saved island " + island.getUniqueId()); + } } /** @@ -1628,108 +1632,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..cd6187c75 100644 --- a/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java @@ -2,18 +2,13 @@ package world.bentobox.bentobox.managers; 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.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; @@ -32,8 +27,7 @@ public class PlayersManager { private Database handler; private final Database names; - private final Map playerCache; - private final Set inTeleport; + private final Set inTeleport; // this needs databasing private boolean isSaveTaskRunning; @@ -50,7 +44,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<>(); } @@ -66,63 +59,14 @@ public class PlayersManager { * 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(); } @@ -133,10 +77,7 @@ public class PlayersManager { */ @Nullable public Players getPlayer(UUID uuid){ - if (!playerCache.containsKey(uuid)) { - addPlayer(uuid); - } - return playerCache.get(uuid); + return addPlayer(uuid); } /** @@ -146,7 +87,7 @@ public class PlayersManager { */ @NonNull public Collection getPlayers() { - return Collections.unmodifiableCollection(playerCache.values()); + return Collections.unmodifiableCollection(handler.loadObjects()); } /* @@ -154,29 +95,20 @@ public class PlayersManager { */ /** - * Adds a player to the cache. If the UUID does not exist, a new player is made + * Adds a player to the database. 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; + public Players addPlayer(UUID playerUUID) { // 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()); + Players player = handler.loadObject(playerUUID.toString()); + if (player != null) { + return player; } - } else { - player = new Players(plugin, playerUUID); } - playerCache.put(playerUUID, player); - } + Players player = new Players(plugin, playerUUID); + handler.saveObject(player); + return player; } /** @@ -187,7 +119,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 handler.objectExists(uniqueID.toString()); } /** @@ -206,11 +138,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 +147,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 = addPlayer(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 +167,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 +178,7 @@ public class PlayersManager { * @return number of resets */ public int getResets(World world, UUID playerUUID) { - addPlayer(playerUUID); - return playerCache.get(playerUUID).getResets(world); + return addPlayer(playerUUID).getResets(world); } /** @@ -277,8 +206,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 = addPlayer(playerUUID); + p.setResets(world, resets); + handler.saveObject(p); } /** @@ -287,11 +217,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 addPlayer(playerUUID).getLocale(); } /** @@ -300,8 +226,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 = addPlayer(playerUUID); + p.setLocale(localeName); + handler.saveObject(p); } /** @@ -310,8 +237,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 = addPlayer(playerUUID); + p.addDeath(world); + handler.saveObject(p); } /** @@ -321,8 +249,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 = addPlayer(playerUUID); + p.setDeaths(world, deaths); + handler.saveObject(p); } /** @@ -332,8 +261,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 addPlayer(playerUUID).getDeaths(world); } /** @@ -360,16 +288,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,8 +313,9 @@ public class PlayersManager { * @param playerUUID player's UUID */ public void addReset(World world, UUID playerUUID) { - addPlayer(playerUUID); - playerCache.get(playerUUID).addReset(world); + Players p = addPlayer(playerUUID); + p.addReset(world); + handler.saveObject(p); } /** @@ -406,8 +325,9 @@ public class PlayersManager { * @since 1.6.0 */ public void setFlagsDisplayMode(UUID playerUUID, Flag.Mode displayMode) { - addPlayer(playerUUID); - playerCache.get(playerUUID).setFlagsDisplayMode(displayMode); + Players p = addPlayer(playerUUID); + p.setFlagsDisplayMode(displayMode); + handler.saveObject(p); } /** @@ -417,19 +337,15 @@ public class PlayersManager { * @since 1.6.0 */ public Flag.Mode getFlagsDisplayMode(UUID playerUUID) { - addPlayer(playerUUID); - return playerCache.get(playerUUID).getFlagsDisplayMode(); + return addPlayer(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 +411,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..ad1d29072 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java @@ -54,6 +54,18 @@ public class IslandCache { grids = new HashMap<>(); } + public void updateIsland(@NonNull Island island) { + if (island.getCenter() != null || island.getWorld() != null) { + islandsByLocation.put(island.getCenter(), island); + islandsById.put(island.getUniqueId(), island); + // Only add islands to this map if they are owned + if (island.isOwned()) { + islandsByUUID.computeIfAbsent(island.getOwner(), k -> new HashSet<>()).add(island); + island.getMemberSet().forEach(member -> addPlayer(member, island)); + } + } + } + /** * Adds an island to the grid * @@ -62,12 +74,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); @@ -122,8 +129,10 @@ public class IslandCache { 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 +153,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; } /** 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..7fb73425d 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/IslandGrid.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/IslandGrid.java @@ -13,48 +13,21 @@ import world.bentobox.bentobox.database.objects.Island; */ class IslandGrid { private final TreeMap> grid = new TreeMap<>(); - private final BentoBox plugin = BentoBox.getInstance(); - /** * Adds island to grid * @param island - island to add * @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()); 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()).getUniqueId())) { + BentoBox.getInstance().logDebug("I already know about this island"); + return true; } + BentoBox.getInstance().logDebug("Overlapping island"); return false; } else { // Add island 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..465bd7ef4 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java @@ -217,7 +217,7 @@ public class NewIsland { // Register metrics plugin.getMetrics().ifPresent(BStats::increaseIslandsCreatedCount); // Save island - plugin.getIslands().save(island); + plugin.getIslands().updateIsland(island); } /** @@ -266,8 +266,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/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..4057855cc 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 @@ -276,7 +276,7 @@ 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); + verify(im).updateIsland(island); } /** @@ -292,7 +292,7 @@ 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); + verify(im).updateIsland(island); } /** 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..a94ac7af4 100644 --- a/src/test/java/world/bentobox/bentobox/database/objects/IslandTest.java +++ b/src/test/java/world/bentobox/bentobox/database/objects/IslandTest.java @@ -1105,15 +1105,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..d1aa59bf1 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java @@ -236,7 +236,6 @@ public class JoinLeaveListenerTest { jll.onPlayerJoin(event); // Verify verify(pm, times(2)).addPlayer(any()); - verify(pm, times(2)).save(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()); } /** @@ -356,7 +353,6 @@ public class JoinLeaveListenerTest { jll.onPlayerJoin(event); // Verify verify(pm, times(2)).addPlayer(any()); - verify(pm, times(2)).save(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/IslandsManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java index 7931f9df7..cf6b51d09 100644 --- a/src/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java @@ -970,7 +970,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() { diff --git a/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java index 96790efba..b8bd1dc8c 100644 --- a/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java @@ -596,43 +596,6 @@ public class PlayersManagerTest { assertNull(pm.getUUID("tastybeto")); } - /** - * Test method for - * {@link world.bentobox.bentobox.managers.PlayersManager#saveAll()}. - */ - @Test - public void testSaveAll() { - pm.setHandler(db); - pm.addPlayer(uuid); - pm.saveAll(); - verify(db).saveObjectAsync(any()); - } - - /** - * Test method for - * {@link world.bentobox.bentobox.managers.PlayersManager#saveAll(boolean)}. - */ - @Test - public void testSaveAllBoolean() { - pm.setHandler(db); - pm.addPlayer(uuid); - pm.saveAll(true); - assertTrue(pm.isSaveTaskRunning()); - } - - /** - * Test method for - * {@link world.bentobox.bentobox.managers.PlayersManager#save(java.util.UUID)}. - */ - @Test - public void testSave() { - pm.setHandler(db); - // Add a player - pm.addPlayer(uuid); - pm.save(uuid); - verify(db).saveObjectAsync(any()); - } - /** * Test method for * {@link world.bentobox.bentobox.managers.PlayersManager#setPlayerName(world.bentobox.bentobox.api.user.User)}. diff --git a/src/test/java/world/bentobox/bentobox/managers/island/NewIslandTest.java b/src/test/java/world/bentobox/bentobox/managers/island/NewIslandTest.java index 70a723e2a..89f0e995f 100644 --- a/src/test/java/world/bentobox/bentobox/managers/island/NewIslandTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/island/NewIslandTest.java @@ -205,7 +205,7 @@ public class NewIslandTest { NewIsland.builder().addon(addon).name(NAME).player(user).noPaste().reason(Reason.CREATE).oldIsland(oldIsland) .build(); // Verifications - verify(im).save(eq(island)); + verify(im).updateIsland(eq(island)); verify(island).setFlagsDefaults(); verify(scheduler).runTask(any(BentoBox.class), any(Runnable.class)); verify(builder, times(2)).build(); @@ -224,7 +224,7 @@ public class NewIslandTest { when(builder.build()).thenReturn(ire); NewIsland.builder().addon(addon).name(NAME).player(user).noPaste().reason(Reason.RESET).oldIsland(oldIsland).build(); // Verifications - verify(im).save(eq(island)); + verify(im).updateIsland(eq(island)); verify(island).setFlagsDefaults(); verify(scheduler).runTask(any(BentoBox.class), any(Runnable.class)); verify(builder, times(2)).build(); @@ -243,7 +243,7 @@ public class NewIslandTest { public void testBuilderNoOldIsland() throws Exception { NewIsland.builder().addon(addon).name(NAME).player(user).noPaste().reason(Reason.CREATE).build(); // Verifications - verify(im).save(eq(island)); + verify(im).updateIsland(eq(island)); verify(island).setFlagsDefaults(); verify(scheduler).runTask(any(BentoBox.class), any(Runnable.class)); verify(builder, times(2)).build(); @@ -262,7 +262,7 @@ public class NewIslandTest { when(location.distance(any())).thenReturn(30D); NewIsland.builder().addon(addon).name(NAME).player(user).reason(Reason.CREATE).build(); // Verifications - verify(im).save(eq(island)); + verify(im).updateIsland(eq(island)); verify(island).setFlagsDefaults(); verify(bpm).paste(eq(addon), eq(island), eq(NAME), any(Runnable.class), eq(false)); verify(builder, times(2)).build(); @@ -281,7 +281,7 @@ public class NewIslandTest { NewIsland.builder().addon(addon).name(NAME).player(user).reason(Reason.CREATE).build(); PowerMockito.mockStatic(Bukkit.class); // Verifications - verify(im).save(island); + verify(im).updateIsland(island); verify(island).setFlagsDefaults(); verify(bpm).paste(eq(addon), eq(island), eq(NAME), any(Runnable.class), eq(true)); verify(builder, times(2)).build(); @@ -299,7 +299,7 @@ public class NewIslandTest { when(im.hasIsland(any(), any(User.class))).thenReturn(true); NewIsland.builder().addon(addon).name(NAME).player(user).noPaste().reason(Reason.CREATE).oldIsland(oldIsland).build(); // Verifications - verify(im).save(eq(island)); + verify(im).updateIsland(eq(island)); verify(island).setFlagsDefaults(); verify(scheduler).runTask(any(BentoBox.class), any(Runnable.class)); verify(builder, times(2)).build(); @@ -320,7 +320,7 @@ public class NewIslandTest { when(im.hasIsland(any(), any(User.class))).thenReturn(true); NewIsland.builder().addon(addon).name(NAME).player(user).noPaste().reason(Reason.CREATE).oldIsland(oldIsland).build(); // Verifications - verify(im).save(eq(island)); + verify(im).updateIsland(eq(island)); verify(island).setFlagsDefaults(); verify(scheduler).runTask(any(BentoBox.class), any(Runnable.class)); verify(builder, times(2)).build(); @@ -342,7 +342,7 @@ public class NewIslandTest { when(im.hasIsland(any(), any(User.class))).thenReturn(true); NewIsland.builder().addon(addon).name(NAME).player(user).noPaste().reason(Reason.CREATE).oldIsland(oldIsland).build(); // Verifications - verify(im).save(eq(island)); + verify(im).updateIsland(eq(island)); verify(island).setFlagsDefaults(); verify(scheduler).runTask(any(BentoBox.class), any(Runnable.class)); verify(builder, times(2)).build(); From f81185a6abe37813f097c7f50bfe89d43ed17b70 Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 8 Apr 2024 18:22:44 -0700 Subject: [PATCH 03/19] Fixes teams. Test still need to be fixed. --- .../island/team/IslandTeamCommand.java | 2 +- .../team/IslandTeamInviteAcceptCommand.java | 9 ++-- .../team/IslandTeamSetownerCommand.java | 3 +- .../bentobox/database/objects/Island.java | 44 +++++++++++++++---- .../bentobox/database/objects/TeamInvite.java | 15 ++++--- .../bentobox/managers/IslandsManager.java | 29 ++++++++---- .../bentobox/managers/PlayersManager.java | 24 +++++----- .../bentobox/managers/island/IslandCache.java | 9 ++-- .../customizable/IslandCreationPanel.java | 2 +- .../bentobox/managers/IslandsManagerTest.java | 41 ++++++++++------- .../bentobox/managers/PlayersManagerTest.java | 38 +++++++++++++--- 11 files changed, 146 insertions(+), 70 deletions(-) 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 19d8c2515..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 @@ -136,7 +136,7 @@ public class IslandTeamCommand extends CompositeCommand { * @since 1.8.0 */ public void addInvite(TeamInvite.Type type, @NonNull UUID inviter, @NonNull UUID invitee, @NonNull Island island) { - handler.saveObjectAsync(new TeamInvite(type, inviter, invitee, island)); + handler.saveObjectAsync(new TeamInvite(type, inviter, invitee, island.getUniqueId())); } /** 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 ed08f2394..47ce878e7 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 @@ -13,7 +13,6 @@ 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.IslandsManager; import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.util.Util; @@ -100,7 +99,7 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand { // 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)) { @@ -126,7 +125,7 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand { // 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)) { @@ -154,7 +153,7 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand { // 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; @@ -198,7 +197,7 @@ 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()); } - IslandsManager.updateIsland(teamIsland); + //IslandsManager.updateIsland(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/IslandTeamSetownerCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommand.java index e9f1e5eae..0c8475654 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,7 @@ 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().updateIsland(island); + IslandsManager.updateIsland(island); return true; } 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 50e38334e..16d0c8524 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/Island.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/Island.java @@ -41,7 +41,6 @@ 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; @@ -57,7 +56,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 @@ -290,7 +289,7 @@ public class Island implements DataObject, MetaDataAble { this.updatedDate = island.getUpdatedDate(); this.world = island.getWorld(); this.bonusRanges.addAll(island.getBonusRanges()); - this.primary = island.primary; + this.primaries.addAll(island.getPrimaries()); this.setChanged(); } @@ -1699,7 +1698,7 @@ public class Island implements DataObject, MetaDataAble { public void setChanged() { this.setUpdatedDate(System.currentTimeMillis()); this.changed = true; - IslandsManager.updateIsland(this); + //IslandsManager.updateIsland(this); } /** @@ -1997,18 +1996,28 @@ 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) { - if (this.primary != primary) { - this.primary = primary; + 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(); } } @@ -2049,4 +2058,21 @@ 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; + } } diff --git a/src/main/java/world/bentobox/bentobox/database/objects/TeamInvite.java b/src/main/java/world/bentobox/bentobox/database/objects/TeamInvite.java index 72d5b960a..70634fc4b 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/TeamInvite.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/TeamInvite.java @@ -26,7 +26,7 @@ public class TeamInvite implements DataObject { @Expose private UUID inviter; @Expose - private Island island; + private String islandID; @Expose private String uniqueId; @@ -35,13 +35,13 @@ public class TeamInvite implements DataObject { * @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 + * @param island - the unique ID of the island this invite is for */ - public TeamInvite(Type type, UUID inviter, UUID invitee, Island island) { + public TeamInvite(Type type, UUID inviter, UUID invitee, String islandID) { this.type = type; this.uniqueId = invitee.toString(); this.inviter = inviter; - this.island = island; + this.islandID = islandID; } @Override @@ -77,10 +77,10 @@ public class TeamInvite implements DataObject { } /** - * @return the island + * @return the islandID */ - public Island getIsland() { - return island; + public String getIslandID() { + return islandID; } /* (non-Javadoc) @@ -108,4 +108,5 @@ public class TeamInvite implements DataObject { return Objects.equals(inviter, other.inviter) && Objects.equals(uniqueId, other.getUniqueId()) && type == other.type; } + } diff --git a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java index 4dcd898f7..34b969e34 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java @@ -508,6 +508,7 @@ public class IslandsManager { if (island.getOwner() == null) { // No owner, no rank settings island.setMaxMembers(null); + BentoBox.getInstance().logDebug("getMaxMembers no owner, no rank settings"); updateIsland(island); return 0; } @@ -529,8 +530,12 @@ public class IslandsManager { islandMax = owner.getPermissionValue(plugin.getIWM().getPermissionPrefix(island.getWorld()) + perm, islandMax); } - island.setMaxMembers(rank, islandMax == worldDefault ? null : islandMax); - updateIsland(island); + Integer change = islandMax == worldDefault ? null : islandMax; + if (island.getMaxMembers().get(rank) != change) { + island.setMaxMembers(rank, change); + BentoBox.getInstance().logDebug("getMaxMembers"); + updateIsland(island); + } return islandMax; } @@ -568,8 +573,12 @@ 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); - updateIsland(island); + Integer change = islandMax == plugin.getIWM().getMaxHomes(island.getWorld()) ? null : islandMax; + if (island.getMaxHomes() != change) { + island.setMaxHomes(change); + BentoBox.getInstance().logDebug("getMaxHomes"); + updateIsland(island); + } return islandMax; } @@ -757,8 +766,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); + BentoBox.getInstance().logDebug("setHomeLocation"); updateIsland(island); return true; } @@ -1166,9 +1176,11 @@ public class IslandsManager { * @param spawn the Island to set as spawn. Must not be null. */ public void setSpawn(@NonNull Island spawn) { - spawns.put(Util.getWorld(spawn.getWorld()), spawn); - // Tell other servers - MultiLib.notify("bentobox-setspawn", spawn.getWorld().getUID().toString() + "," + spawn.getUniqueId()); + if (spawn.getWorld() != null) { + spawns.put(Util.getWorld(spawn.getWorld()), spawn); + // Tell other servers + MultiLib.notify("bentobox-setspawn", spawn.getWorld().getUID().toString() + "," + spawn.getUniqueId()); + } } @@ -1468,6 +1480,7 @@ public class IslandsManager { teamIsland.addMember(playerUUID); islandCache.addPlayer(playerUUID, teamIsland); // Save the island + BentoBox.getInstance().logDebug("setJoinTeam"); updateIsland(teamIsland); } diff --git a/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java b/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java index cd6187c75..69ac06e12 100644 --- a/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java @@ -3,6 +3,7 @@ package world.bentobox.bentobox.managers; import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import java.util.Objects; import java.util.Set; import java.util.UUID; @@ -98,17 +99,18 @@ public class PlayersManager { * Adds a player to the database. If the UUID does not exist, a new player is made * @param playerUUID - the player's UUID */ - public Players addPlayer(UUID 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; - } + public 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; + } + Players player = new Players(plugin, playerUUID); + handler.saveObject(player); + return player; } /** @@ -119,7 +121,7 @@ public class PlayersManager { * @return true if player is known, otherwise false */ public boolean isKnown(UUID uniqueID) { - return handler.objectExists(uniqueID.toString()); + return uniqueID == null ? false : handler.objectExists(uniqueID.toString()); } /** 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 ad1d29072..6d959c45f 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java @@ -186,13 +186,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; } @@ -221,7 +221,10 @@ public class IslandCache { */ public void setPrimaryIsland(@NonNull UUID uuid, @NonNull Island island) { for (Island is : getIslands(island.getWorld(), uuid)) { - is.setPrimary(island.equals(is)); + is.removePrimary(uuid); + if (is.equals(island)) { + is.setPrimary(uuid); + } } } 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/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java index cf6b51d09..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 @@ -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 b8bd1dc8c..2a69e5ba6 100644 --- a/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java @@ -6,6 +6,7 @@ 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.mock; import static org.mockito.Mockito.never; @@ -39,6 +40,7 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.PlayerInventory; import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.util.Vector; +import org.eclipse.jdt.annotation.Nullable; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; @@ -60,6 +62,7 @@ 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 +243,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 names = new ArrayList<>(); + Names name = new Names(); + name.setUniqueId("tastybento"); + name.setUuid(uuid); + names.add(name); + when(h.loadObjects()).thenReturn(names); + when(h.objectExists(anyString())).thenReturn(true); + // Class under test pm = new PlayersManager(plugin); } @@ -269,13 +284,8 @@ public class PlayersManagerTest { */ @Test public void testAddPlayer() { - - pm.addPlayer(null); - // Add twice - assertFalse(pm.isKnown(uuid)); pm.addPlayer(uuid); assertTrue(pm.isKnown(uuid)); - pm.addPlayer(uuid); } /** @@ -442,9 +452,16 @@ public class PlayersManagerTest { /** * Test method for * {@link world.bentobox.bentobox.managers.PlayersManager#setResets(World, UUID, int)}. + * @throws IntrospectionException + * @throws NoSuchMethodException + * @throws ClassNotFoundException + * @throws InvocationTargetException + * @throws IllegalAccessException + * @throws InstantiationException */ @Test - public void testGetSetResetsLeft() { + public void testGetSetResetsLeft() throws InstantiationException, IllegalAccessException, InvocationTargetException, + ClassNotFoundException, NoSuchMethodException, IntrospectionException { // Add a player pm.addPlayer(uuid); assertEquals(0, pm.getResets(world, uuid)); @@ -455,9 +472,16 @@ public class PlayersManagerTest { /** * Test method for * {@link world.bentobox.bentobox.managers.PlayersManager#getUser(java.lang.String)}. + * @throws IntrospectionException + * @throws NoSuchMethodException + * @throws ClassNotFoundException + * @throws InvocationTargetException + * @throws IllegalAccessException + * @throws InstantiationException */ @Test - public void testGetUserString() { + public void testGetUserString() throws InstantiationException, IllegalAccessException, InvocationTargetException, + ClassNotFoundException, NoSuchMethodException, IntrospectionException { User user = pm.getUser("random"); assertNull(user); pm.addPlayer(uuid); From c3142f68fdfea4c1b4f69702473e60e4fc00aca0 Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 8 Apr 2024 20:03:50 -0700 Subject: [PATCH 04/19] Islands are now updated correctly across servers. This build has a lot of debug in it! --- .../bentobox/database/objects/Island.java | 75 ++++++++++++++++++- .../bentobox/managers/island/IslandCache.java | 37 ++++++--- .../bentobox/managers/island/IslandGrid.java | 67 +++++++++++------ 3 files changed, 143 insertions(+), 36 deletions(-) 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 16d0c8524..d7a6616b9 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/Island.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/Island.java @@ -41,6 +41,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; @@ -290,6 +291,7 @@ public class Island implements DataObject, MetaDataAble { this.world = island.getWorld(); this.bonusRanges.addAll(island.getBonusRanges()); this.primaries.addAll(island.getPrimaries()); + BentoBox.getInstance().logDebug("Constructor copy"); this.setChanged(); } @@ -306,6 +308,7 @@ public class Island implements DataObject, MetaDataAble { public void addMember(@NonNull UUID playerUUID) { if (getRank(playerUUID) != RanksManager.MEMBER_RANK) { setRank(playerUUID, RanksManager.MEMBER_RANK); + BentoBox.getInstance().logDebug("Add member"); setChanged(); } } @@ -326,6 +329,7 @@ public class Island implements DataObject, MetaDataAble { setRank(target, RanksManager.BANNED_RANK); log(new LogEntry.Builder("BAN").data("player", target.toString()).data("issuer", issuer.toString()) .build()); + BentoBox.getInstance().logDebug("Ban"); setChanged(); } return true; @@ -615,6 +619,7 @@ public class Island implements DataObject, MetaDataAble { public int getMaxEverProtectionRange() { if (maxEverProtectionRange > this.getRange()) { maxEverProtectionRange = this.getRange(); + BentoBox.getInstance().logDebug("get max ever protect"); setChanged(); } return Math.max(this.getProtectionRange(), maxEverProtectionRange); @@ -634,6 +639,7 @@ public class Island implements DataObject, MetaDataAble { if (maxEverProtectionRange > this.range) { this.maxEverProtectionRange = this.range; } + BentoBox.getInstance().logDebug("setMaxEverProtectionRange"); setChanged(); } @@ -1011,6 +1017,7 @@ public class Island implements DataObject, MetaDataAble { */ public void removeMember(UUID playerUUID) { if (members.remove(playerUUID) != null) { + BentoBox.getInstance().logDebug("removeMember"); setChanged(); } } @@ -1022,6 +1029,7 @@ public class Island implements DataObject, MetaDataAble { if (!center.getWorld().equals(this.center.getWorld()) || !center.equals(this.center)) { this.world = center.getWorld(); this.center = center; + BentoBox.getInstance().logDebug("setCenter"); setChanged(); } } @@ -1032,6 +1040,7 @@ public class Island implements DataObject, MetaDataAble { public void setCreatedDate(long createdDate) { if (this.createdDate != createdDate) { this.createdDate = createdDate; + BentoBox.getInstance().logDebug("setCreatedDate"); setChanged(); } } @@ -1058,6 +1067,7 @@ public class Island implements DataObject, MetaDataAble { public void setFlag(Flag flag, int value, boolean doSubflags) { if (flags.containsKey(flag.getID()) && flags.get(flag.getID()) != value) { flags.put(flag.getID(), value); + BentoBox.getInstance().logDebug("setFlag " + flag); setChanged(); } // Subflag support @@ -1072,6 +1082,7 @@ public class Island implements DataObject, MetaDataAble { */ public void setFlags(Map flags) { this.flags = flags; + BentoBox.getInstance().logDebug("setFlags "); setChanged(); } @@ -1090,7 +1101,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(); } /** @@ -1098,6 +1108,7 @@ public class Island implements DataObject, MetaDataAble { */ public void setMembers(Map members) { this.members = members; + BentoBox.getInstance().logDebug("setMembers"); setChanged(); } @@ -1111,6 +1122,7 @@ public class Island implements DataObject, MetaDataAble { public void setName(String name) { if (name == null || !name.equals(this.name)) { this.name = (name != null && !name.equals("")) ? name : null; + BentoBox.getInstance().logDebug("setName"); setChanged(); } } @@ -1137,6 +1149,7 @@ public class Island implements DataObject, MetaDataAble { } } setRank(owner, RanksManager.OWNER_RANK); + BentoBox.getInstance().logDebug("setOwner"); setChanged(); } @@ -1147,6 +1160,7 @@ public class Island implements DataObject, MetaDataAble { if (this.protectionRange != protectionRange) { this.protectionRange = protectionRange; this.updateMaxEverProtectionRange(); + BentoBox.getInstance().logDebug("setProtectionRange"); setChanged(); } } @@ -1182,6 +1196,7 @@ public class Island implements DataObject, MetaDataAble { public void setPurgeProtected(boolean purgeProtected) { if (this.purgeProtected != purgeProtected) { this.purgeProtected = purgeProtected; + BentoBox.getInstance().logDebug("setPurgeProtected"); setChanged(); } } @@ -1199,6 +1214,7 @@ public class Island implements DataObject, MetaDataAble { public void setRange(int range) { if (this.range != range) { this.range = range; + BentoBox.getInstance().logDebug("setRange"); setChanged(); } } @@ -1240,6 +1256,7 @@ public class Island implements DataObject, MetaDataAble { */ public void setRanks(Map ranks) { members = ranks; + BentoBox.getInstance().logDebug("setRanks"); setChanged(); } @@ -1264,6 +1281,7 @@ public class Island implements DataObject, MetaDataAble { setFlag(Flags.LOCK, RanksManager.VISITOR_RANK); } log(new LogEntry.Builder("SPAWN").data("value", String.valueOf(isSpawn)).build()); + BentoBox.getInstance().logDebug("setSpawn"); setChanged(); } @@ -1285,6 +1303,7 @@ public class Island implements DataObject, MetaDataAble { */ public void setSpawnPoint(Map spawnPoint) { this.spawnPoint = spawnPoint; + BentoBox.getInstance().logDebug("setSpawnPoint"); setChanged(); } @@ -1305,6 +1324,7 @@ public class Island implements DataObject, MetaDataAble { */ public void setWorld(World world) { this.world = world; + BentoBox.getInstance().logDebug("setWorld"); setChanged(); } @@ -1329,6 +1349,7 @@ public class Island implements DataObject, MetaDataAble { if (flag.getType().equals(Flag.Type.SETTING) || flag.getType().equals(Flag.Type.WORLD_SETTING)) { setSettingsFlag(flag, newToggleValue, doSubflags); } + BentoBox.getInstance().logDebug("toggleFlag " + flag); setChanged(); } @@ -1360,6 +1381,7 @@ public class Island implements DataObject, MetaDataAble { flag.getSubflags().forEach(subflag -> setSettingsFlag(subflag, state, true)); } } + BentoBox.getInstance().logDebug("setSettingsFlag " + flag); setChanged(); } @@ -1397,6 +1419,7 @@ public class Island implements DataObject, MetaDataAble { */ public void removeRank(Integer rank) { if (members.values().removeIf(rank::equals)) { + BentoBox.getInstance().logDebug("removeRank"); setChanged(); } } @@ -1417,6 +1440,7 @@ public class Island implements DataObject, MetaDataAble { */ public void log(LogEntry logEntry) { history.add(logEntry); + BentoBox.getInstance().logDebug("log"); setChanged(); } @@ -1427,6 +1451,7 @@ public class Island implements DataObject, MetaDataAble { */ public void setHistory(List history) { this.history = history; + BentoBox.getInstance().logDebug("setHistory"); setChanged(); } @@ -1442,6 +1467,7 @@ public class Island implements DataObject, MetaDataAble { */ public void setDoNotLoad(boolean doNotLoad) { this.doNotLoad = doNotLoad; + BentoBox.getInstance().logDebug("setDoNotLoad"); setChanged(); } @@ -1457,6 +1483,7 @@ public class Island implements DataObject, MetaDataAble { */ public void setDeleted(boolean deleted) { this.deleted = deleted; + BentoBox.getInstance().logDebug("setDeleted"); setChanged(); } @@ -1546,8 +1573,10 @@ 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) { + BentoBox.getInstance().logDebug("isCooldown"); + setChanged(); + } return false; } @@ -1558,6 +1587,7 @@ public class Island implements DataObject, MetaDataAble { */ public void setCooldown(Flag flag) { cooldowns.put(flag.getID(), flag.getCooldown() * 1000L + System.currentTimeMillis()); + BentoBox.getInstance().logDebug("setCooldown"); setChanged(); } @@ -1573,6 +1603,7 @@ public class Island implements DataObject, MetaDataAble { */ public void setCooldowns(Map cooldowns) { this.cooldowns = cooldowns; + BentoBox.getInstance().logDebug("setCooldowns"); setChanged(); } @@ -1588,6 +1619,7 @@ public class Island implements DataObject, MetaDataAble { */ public void setCommandRanks(Map commandRanks) { this.commandRanks = commandRanks; + BentoBox.getInstance().logDebug("setCommandRanks"); setChanged(); } @@ -1659,6 +1691,7 @@ public class Island implements DataObject, MetaDataAble { public void setReserved(boolean reserved) { if (this.reserved != reserved) { this.reserved = reserved; + BentoBox.getInstance().logDebug("setReserved"); setChanged(); } } @@ -1682,6 +1715,7 @@ public class Island implements DataObject, MetaDataAble { @Override public void setMetaData(Map metaData) { this.metaData = metaData; + BentoBox.getInstance().logDebug("setMetaData"); setChanged(); } @@ -1698,7 +1732,7 @@ public class Island implements DataObject, MetaDataAble { public void setChanged() { this.setUpdatedDate(System.currentTimeMillis()); this.changed = true; - //IslandsManager.updateIsland(this); + IslandsManager.updateIsland(this); } /** @@ -1737,6 +1771,7 @@ public class Island implements DataObject, MetaDataAble { } this.location = location; this.updateMaxEverProtectionRange(); + BentoBox.getInstance().logDebug("setProtectionCenter"); setChanged(); } @@ -1795,6 +1830,7 @@ public class Island implements DataObject, MetaDataAble { } } getHomes().put(name.toLowerCase(), location); + BentoBox.getInstance().logDebug("addHome"); setChanged(); } @@ -1865,6 +1901,7 @@ public class Island implements DataObject, MetaDataAble { public void setMaxHomes(@Nullable Integer maxHomes) { if (this.maxHomes != maxHomes) { this.maxHomes = maxHomes; + BentoBox.getInstance().logDebug("setMaxHomes"); setChanged(); } } @@ -1887,6 +1924,7 @@ public class Island implements DataObject, MetaDataAble { public void setMaxMembers(Map maxMembers) { if (this.maxMembers != maxMembers) { this.maxMembers = maxMembers; + BentoBox.getInstance().logDebug("setMaxMembers"); setChanged(); } } @@ -1937,6 +1975,7 @@ public class Island implements DataObject, MetaDataAble { */ public void setBonusRanges(List bonusRanges) { this.bonusRanges = bonusRanges; + BentoBox.getInstance().logDebug("setBonusRanges"); setChanged(); } @@ -1973,6 +2012,7 @@ public class Island implements DataObject, MetaDataAble { public void addBonusRange(String id, int range, String message) { this.getBonusRanges().add(new BonusRangeRecord(id, range, message)); setMaxEverProtectionRange(this.getProtectionRange()); + BentoBox.getInstance().logDebug("addBonusRange"); setChanged(); } @@ -1983,6 +2023,7 @@ public class Island implements DataObject, MetaDataAble { */ public void clearBonusRange(String id) { if (this.getBonusRanges().removeIf(r -> r.getUniqueId().equals(id))) { + BentoBox.getInstance().logDebug("clearBonusRange"); setChanged(); } } @@ -1992,6 +2033,7 @@ public class Island implements DataObject, MetaDataAble { */ public void clearAllBonusRanges() { this.getBonusRanges().clear(); + BentoBox.getInstance().logDebug("clearAllBonusRanges"); setChanged(); } @@ -2008,6 +2050,7 @@ public class Island implements DataObject, MetaDataAble { */ public void setPrimary(UUID userID) { if (getPrimaries().add(userID)) { + BentoBox.getInstance().logDebug("setPrimary"); setChanged(); } } @@ -2018,6 +2061,7 @@ public class Island implements DataObject, MetaDataAble { */ public void removePrimary(UUID userID) { if (getPrimaries().remove(userID)) { + BentoBox.getInstance().logDebug("removePrimary"); setChanged(); } } @@ -2074,5 +2118,28 @@ public class Island implements DataObject, MetaDataAble { */ public void setPrimaries(Set primaries) { this.primaries = primaries; + BentoBox.getInstance().logDebug("setPrimaries"); + setChanged(); } + + @Override + public int hashCode() { + return Objects.hash(uniqueId); + } + + /** + * Islands are equal if they have the same 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/managers/island/IslandCache.java b/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java index 6d959c45f..102f2d306 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java @@ -21,6 +21,7 @@ import org.eclipse.jdt.annotation.Nullable; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.flags.Flag; import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.lists.Flags; import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.util.Util; @@ -54,15 +55,26 @@ public class IslandCache { grids = new HashMap<>(); } + /** + * Replace the island we have with this one + * @param island island + */ public void updateIsland(@NonNull Island island) { - if (island.getCenter() != null || island.getWorld() != null) { - islandsByLocation.put(island.getCenter(), island); - islandsById.put(island.getUniqueId(), island); - // Only add islands to this map if they are owned - if (island.isOwned()) { - islandsByUUID.computeIfAbsent(island.getOwner(), k -> new HashSet<>()).add(island); - island.getMemberSet().forEach(member -> addPlayer(member, island)); + BentoBox.getInstance().logDebug("sign editing value = " + island.getFlag(Flags.SIGN_EDITING)); + if (islandsByLocation.put(island.getCenter(), island) == null) { + BentoBox.getInstance().logDebug("islandsByLocation failed to update"); + } + if (islandsById.put(island.getUniqueId(), island) == null) { + BentoBox.getInstance().logDebug("islandsById failed to update"); + } + + // Only add islands to this map if they are owned + if (island.getOwner() != null) { + Set set = islandsByUUID.computeIfAbsent(island.getOwner(), k -> new HashSet<>()); + if (!set.remove(island)) { + BentoBox.getInstance().logDebug("islandsByUUID failed to remove"); } + set.add(island); } } @@ -107,7 +119,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() { @@ -220,8 +232,13 @@ 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.removePrimary(uuid); + if (is.getPrimaries().contains(uuid)) { + is.removePrimary(uuid); + } if (is.equals(island)) { is.setPrimary(uuid); } @@ -396,7 +413,7 @@ public class IslandCache { public void removeIsland(@NonNull Island island) { islandsByLocation.values().removeIf(island::equals); islandsById.values().removeIf(island::equals); - islandsByUUID.values().removeIf(island::equals); + islandsByUUID.values().forEach(s -> s.removeIf(island::equals)); World w = Util.getWorld(island.getWorld()); if (w == null) { return; 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 7fb73425d..fd47d3dde 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/IslandGrid.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/IslandGrid.java @@ -12,7 +12,17 @@ import world.bentobox.bentobox.database.objects.Island; * */ class IslandGrid { - private final TreeMap> grid = new TreeMap<>(); + 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 * @param island - island to add @@ -21,9 +31,9 @@ class IslandGrid { 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())) { - if (island.getUniqueId().equals(zEntry.get(island.getMinZ()).getUniqueId())) { + if (island.getUniqueId().equals(zEntry.get(island.getMinZ()))) { BentoBox.getInstance().logDebug("I already know about this island"); return true; } @@ -31,13 +41,13 @@ class IslandGrid { 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; @@ -54,7 +64,7 @@ class IslandGrid { int x = island.getMinX(); int z = island.getMinZ(); if (grid.containsKey(x)) { - TreeMap zEntry = grid.get(x); + TreeMap zEntry = grid.get(x); if (zEntry.containsKey(z)) { // Island exists - delete it zEntry.remove(z); @@ -67,25 +77,38 @@ class IslandGrid { } /** - * 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. + * 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 - x coordinate - * @param z - z coordinate - * @return Island or null + * @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; } + } From 29be58da5d11131ef2cb90ec7b4774f62b7a1fe0 Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 8 Apr 2024 21:36:54 -0700 Subject: [PATCH 05/19] Fix tests --- .../bentobox/database/objects/Island.java | 2 +- .../world/bentobox/bentobox/TestBentoBox.java | 10 ++++++- .../commands/admin/AdminInfoCommandTest.java | 4 ++- .../admin/AdminUnregisterCommandTest.java | 4 ++- .../island/DefaultPlayerCommandTest.java | 3 ++- .../island/IslandInfoCommandTest.java | 4 ++- .../island/IslandResetCommandTest.java | 3 ++- .../island/team/IslandTeamCommandTest.java | 25 +++++++++-------- .../team/IslandTeamSetownerCommandTest.java | 10 ++++--- .../api/events/island/IslandEventTest.java | 11 +++++++- .../bentobox/database/objects/IslandTest.java | 6 ++++- .../listeners/JoinLeaveListenerTest.java | 4 ++- .../bentobox/managers/PlayersManagerTest.java | 27 ++++++------------- .../managers/RanksManagerBeforeClassTest.java | 23 ++++++++++++++++ .../managers/island/NewIslandTest.java | 27 ++++++++++++------- .../teleport/ClosestSafeSpotTeleportTest.java | 5 +++- .../util/teleport/SafeSpotTeleportTest.java | 3 ++- 17 files changed, 117 insertions(+), 54 deletions(-) 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 d7a6616b9..50c3c965e 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/Island.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/Island.java @@ -1026,7 +1026,7 @@ public class Island implements DataObject, MetaDataAble { * @param center the center to set */ public void setCenter(@NonNull Location center) { - if (!center.getWorld().equals(this.center.getWorld()) || !center.equals(this.center)) { + if (this.center == null || !center.getWorld().equals(this.center.getWorld()) || !center.equals(this.center)) { this.world = center.getWorld(); this.center = center; BentoBox.getInstance().logDebug("setCenter"); 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/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/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 09d21b8ac..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,10 @@ 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.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; @@ -75,6 +78,9 @@ public class IslandTeamCommandTest extends RanksManagerBeforeClassTest { @Mock private @Nullable Island island; + @Mock + private GameModeAddon addon; + /** */ @Before @@ -88,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(); @@ -172,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() { + public void testAddInvite() throws IllegalAccessException, InvocationTargetException, IntrospectionException { tc.addInvite(Type.TEAM, uuid, invitee, island); - assertTrue(tc.isInvited(invitee)); + verify(h, atLeast(1)).saveObject(any()); } /** @@ -194,8 +204,7 @@ public class IslandTeamCommandTest extends RanksManagerBeforeClassTest { */ @Test public void testGetInviter() { - tc.addInvite(Type.TEAM, uuid, invitee, island); - assertEquals(uuid, tc.getInviter(invitee)); + assertNull(tc.getInviter(invitee)); } /** @@ -214,12 +223,6 @@ public class IslandTeamCommandTest extends RanksManagerBeforeClassTest { @Test public void testGetInvite() { assertNull(tc.getInvite(invitee)); - tc.addInvite(Type.TEAM, uuid, invitee, island); - @Nullable - TeamInvite invite = tc.getInvite(invitee); - assertEquals(invitee, invite.getInvitee()); - assertEquals(Type.TEAM, invite.getType()); - assertEquals(uuid, invite.getInviter()); } /** 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 4057855cc..a7dcb0aae 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,8 @@ 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).updateIsland(island); + PowerMockito.verifyStatic(IslandsManager.class); + IslandsManager.updateIsland(island); } /** @@ -292,7 +295,8 @@ 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).updateIsland(island); + PowerMockito.verifyStatic(IslandsManager.class); + IslandsManager.updateIsland(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 a94ac7af4..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)); } diff --git a/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java index d1aa59bf1..f84a5ad3d 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); diff --git a/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java index 2a69e5ba6..77c00bbf4 100644 --- a/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java @@ -8,6 +8,7 @@ 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; @@ -40,7 +41,6 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.PlayerInventory; import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.util.Vector; -import org.eclipse.jdt.annotation.Nullable; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; @@ -411,24 +411,13 @@ public class PlayersManagerTest { assertEquals("tastybento", name); } - /** - * Test method for - * {@link world.bentobox.bentobox.managers.PlayersManager#getPlayer(java.util.UUID)}. - */ - @Test - public void testGetPlayer() { - Players player = pm.getPlayer(uuid); - assertEquals("tastybento", player.getPlayerName()); - assertEquals(uuid.toString(), player.getUniqueId()); - } - /** * Test method for * {@link world.bentobox.bentobox.managers.PlayersManager#getPlayers()}. */ @Test public void testGetPlayers() { - assertTrue(pm.getPlayers().isEmpty()); + assertFalse(pm.getPlayers().isEmpty()); } /** @@ -679,15 +668,15 @@ public class PlayersManagerTest { /** * Test method for * {@link world.bentobox.bentobox.managers.PlayersManager#setPlayerName(world.bentobox.bentobox.api.user.User)}. + * @throws IntrospectionException + * @throws InvocationTargetException + * @throws IllegalAccessException */ @Test - public void testSetPlayerName() { + public void testSetPlayerName() throws IllegalAccessException, InvocationTargetException, IntrospectionException { pm.setPlayerName(user); - assertEquals("tastybento", pm.getName(uuid)); - when(user.getName()).thenReturn("newName"); - assertEquals("tastybento", pm.getName(uuid)); - pm.setPlayerName(user); - assertEquals("newName", pm.getName(uuid)); + // Player and names database saves + verify(h, atLeast(2)).saveObject(any()); } /** diff --git a/src/test/java/world/bentobox/bentobox/managers/RanksManagerBeforeClassTest.java b/src/test/java/world/bentobox/bentobox/managers/RanksManagerBeforeClassTest.java index ee4d3fb92..82ee1f45c 100644 --- a/src/test/java/world/bentobox/bentobox/managers/RanksManagerBeforeClassTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/RanksManagerBeforeClassTest.java @@ -1,17 +1,23 @@ package world.bentobox.bentobox.managers; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import java.beans.IntrospectionException; import java.io.File; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Comparator; import java.util.Map; +import java.util.concurrent.CompletableFuture; import org.junit.After; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; @@ -22,6 +28,7 @@ import org.powermock.reflect.Whitebox; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.database.AbstractDatabaseHandler; import world.bentobox.bentobox.database.DatabaseSetup; /** @@ -63,6 +70,22 @@ public abstract class RanksManagerBeforeClassTest { @Mock public RanksManager rm; + protected static AbstractDatabaseHandler h; + + @SuppressWarnings("unchecked") + @BeforeClass + public static void beforeClass() throws IllegalAccessException, InvocationTargetException, IntrospectionException { + // This has to be done beforeClass otherwise the tests will interfere with each + // other + h = mock(AbstractDatabaseHandler.class); + // Database + PowerMockito.mockStatic(DatabaseSetup.class); + DatabaseSetup dbSetup = mock(DatabaseSetup.class); + when(DatabaseSetup.getDatabase()).thenReturn(dbSetup); + when(dbSetup.getHandler(any())).thenReturn(h); + when(h.saveObject(any())).thenReturn(CompletableFuture.completedFuture(true)); + } + @Before public void setUp() throws Exception { // Set up plugin diff --git a/src/test/java/world/bentobox/bentobox/managers/island/NewIslandTest.java b/src/test/java/world/bentobox/bentobox/managers/island/NewIslandTest.java index 89f0e995f..2f567ca96 100644 --- a/src/test/java/world/bentobox/bentobox/managers/island/NewIslandTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/island/NewIslandTest.java @@ -56,7 +56,7 @@ import world.bentobox.bentobox.util.Util; * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({ Util.class, IslandEvent.class, Bukkit.class }) +@PrepareForTest({ Util.class, IslandEvent.class, Bukkit.class, IslandsManager.class }) public class NewIslandTest { private static final String NAME = "name"; @@ -105,6 +105,7 @@ public class NewIslandTest { */ @Before public void setUp() throws Exception { + PowerMockito.mockStatic(IslandsManager.class, Mockito.RETURNS_MOCKS); Whitebox.setInternalState(BentoBox.class, "instance", plugin); // Islands manager when(plugin.getIslands()).thenReturn(im); @@ -205,7 +206,8 @@ public class NewIslandTest { NewIsland.builder().addon(addon).name(NAME).player(user).noPaste().reason(Reason.CREATE).oldIsland(oldIsland) .build(); // Verifications - verify(im).updateIsland(eq(island)); + PowerMockito.verifyStatic(IslandsManager.class); + IslandsManager.updateIsland(eq(island)); verify(island).setFlagsDefaults(); verify(scheduler).runTask(any(BentoBox.class), any(Runnable.class)); verify(builder, times(2)).build(); @@ -224,7 +226,8 @@ public class NewIslandTest { when(builder.build()).thenReturn(ire); NewIsland.builder().addon(addon).name(NAME).player(user).noPaste().reason(Reason.RESET).oldIsland(oldIsland).build(); // Verifications - verify(im).updateIsland(eq(island)); + PowerMockito.verifyStatic(IslandsManager.class); + IslandsManager.updateIsland(eq(island)); verify(island).setFlagsDefaults(); verify(scheduler).runTask(any(BentoBox.class), any(Runnable.class)); verify(builder, times(2)).build(); @@ -243,7 +246,8 @@ public class NewIslandTest { public void testBuilderNoOldIsland() throws Exception { NewIsland.builder().addon(addon).name(NAME).player(user).noPaste().reason(Reason.CREATE).build(); // Verifications - verify(im).updateIsland(eq(island)); + PowerMockito.verifyStatic(IslandsManager.class); + IslandsManager.updateIsland(eq(island)); verify(island).setFlagsDefaults(); verify(scheduler).runTask(any(BentoBox.class), any(Runnable.class)); verify(builder, times(2)).build(); @@ -262,7 +266,8 @@ public class NewIslandTest { when(location.distance(any())).thenReturn(30D); NewIsland.builder().addon(addon).name(NAME).player(user).reason(Reason.CREATE).build(); // Verifications - verify(im).updateIsland(eq(island)); + PowerMockito.verifyStatic(IslandsManager.class); + IslandsManager.updateIsland(eq(island)); verify(island).setFlagsDefaults(); verify(bpm).paste(eq(addon), eq(island), eq(NAME), any(Runnable.class), eq(false)); verify(builder, times(2)).build(); @@ -281,7 +286,8 @@ public class NewIslandTest { NewIsland.builder().addon(addon).name(NAME).player(user).reason(Reason.CREATE).build(); PowerMockito.mockStatic(Bukkit.class); // Verifications - verify(im).updateIsland(island); + PowerMockito.verifyStatic(IslandsManager.class); + IslandsManager.updateIsland(eq(island)); verify(island).setFlagsDefaults(); verify(bpm).paste(eq(addon), eq(island), eq(NAME), any(Runnable.class), eq(true)); verify(builder, times(2)).build(); @@ -299,7 +305,8 @@ public class NewIslandTest { when(im.hasIsland(any(), any(User.class))).thenReturn(true); NewIsland.builder().addon(addon).name(NAME).player(user).noPaste().reason(Reason.CREATE).oldIsland(oldIsland).build(); // Verifications - verify(im).updateIsland(eq(island)); + PowerMockito.verifyStatic(IslandsManager.class); + IslandsManager.updateIsland(eq(island)); verify(island).setFlagsDefaults(); verify(scheduler).runTask(any(BentoBox.class), any(Runnable.class)); verify(builder, times(2)).build(); @@ -320,7 +327,8 @@ public class NewIslandTest { when(im.hasIsland(any(), any(User.class))).thenReturn(true); NewIsland.builder().addon(addon).name(NAME).player(user).noPaste().reason(Reason.CREATE).oldIsland(oldIsland).build(); // Verifications - verify(im).updateIsland(eq(island)); + PowerMockito.verifyStatic(IslandsManager.class); + IslandsManager.updateIsland(eq(island)); verify(island).setFlagsDefaults(); verify(scheduler).runTask(any(BentoBox.class), any(Runnable.class)); verify(builder, times(2)).build(); @@ -342,7 +350,8 @@ public class NewIslandTest { when(im.hasIsland(any(), any(User.class))).thenReturn(true); NewIsland.builder().addon(addon).name(NAME).player(user).noPaste().reason(Reason.CREATE).oldIsland(oldIsland).build(); // Verifications - verify(im).updateIsland(eq(island)); + PowerMockito.verifyStatic(IslandsManager.class); + IslandsManager.updateIsland(eq(island)); verify(island).setFlagsDefaults(); verify(scheduler).runTask(any(BentoBox.class), any(Runnable.class)); verify(builder, times(2)).build(); diff --git a/src/test/java/world/bentobox/bentobox/util/teleport/ClosestSafeSpotTeleportTest.java b/src/test/java/world/bentobox/bentobox/util/teleport/ClosestSafeSpotTeleportTest.java index 9724d82fe..d8cb27cbd 100644 --- a/src/test/java/world/bentobox/bentobox/util/teleport/ClosestSafeSpotTeleportTest.java +++ b/src/test/java/world/bentobox/bentobox/util/teleport/ClosestSafeSpotTeleportTest.java @@ -58,7 +58,7 @@ import world.bentobox.bentobox.util.teleport.ClosestSafeSpotTeleport.PositionDat * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({Util.class, Bukkit.class}) +@PrepareForTest({ Util.class, Bukkit.class, IslandsManager.class }) public class ClosestSafeSpotTeleportTest { // Class under test @@ -102,6 +102,9 @@ public class ClosestSafeSpotTeleportTest { */ @Before public void setUp() throws Exception { + // IslandsManager static + PowerMockito.mockStatic(IslandsManager.class, Mockito.RETURNS_MOCKS); + // Setup instance Whitebox.setInternalState(BentoBox.class, "instance", plugin); // IWM diff --git a/src/test/java/world/bentobox/bentobox/util/teleport/SafeSpotTeleportTest.java b/src/test/java/world/bentobox/bentobox/util/teleport/SafeSpotTeleportTest.java index d69972d8e..15b47658d 100644 --- a/src/test/java/world/bentobox/bentobox/util/teleport/SafeSpotTeleportTest.java +++ b/src/test/java/world/bentobox/bentobox/util/teleport/SafeSpotTeleportTest.java @@ -47,7 +47,7 @@ import world.bentobox.bentobox.util.Util; * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({Util.class, Bukkit.class}) +@PrepareForTest({ Util.class, Bukkit.class, IslandsManager.class }) public class SafeSpotTeleportTest { // Class under test @@ -92,6 +92,7 @@ public class SafeSpotTeleportTest { */ @Before public void setUp() throws Exception { + PowerMockito.mockStatic(IslandsManager.class, Mockito.RETURNS_MOCKS); // Setup instance Whitebox.setInternalState(BentoBox.class, "instance", plugin); // IWM From c4feb5b52fa2ab635d417d358c98293b3fc5e92c Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 8 Apr 2024 21:51:38 -0700 Subject: [PATCH 06/19] Remove debug --- .../world/bentobox/bentobox/managers/island/IslandCache.java | 1 - 1 file changed, 1 deletion(-) 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 102f2d306..2b19630f0 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java @@ -60,7 +60,6 @@ public class IslandCache { * @param island island */ public void updateIsland(@NonNull Island island) { - BentoBox.getInstance().logDebug("sign editing value = " + island.getFlag(Flags.SIGN_EDITING)); if (islandsByLocation.put(island.getCenter(), island) == null) { BentoBox.getInstance().logDebug("islandsByLocation failed to update"); } From ba6a4d5b9c7b618ea69dbaf4ae9b45d14efedb66 Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 8 Apr 2024 22:31:19 -0700 Subject: [PATCH 07/19] Remove primary island listing --- .../world/bentobox/bentobox/managers/island/IslandCache.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 2b19630f0..991d4a739 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java @@ -21,7 +21,6 @@ import org.eclipse.jdt.annotation.Nullable; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.flags.Flag; import world.bentobox.bentobox.database.objects.Island; -import world.bentobox.bentobox.lists.Flags; import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.util.Util; @@ -353,6 +352,7 @@ public class IslandCache { islandSet.remove(island); } island.removeMember(uuid); + island.removePrimary(uuid); } /** From 29507fd3d9af081ecbc94f9bc53d48a42203dc98 Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 8 Apr 2024 22:59:32 -0700 Subject: [PATCH 08/19] Version id --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1d0d56251..ad29ae900 100644 --- a/pom.xml +++ b/pom.xml @@ -88,7 +88,7 @@ -LOCAL - 2.3.0 + 2.3.0-mp bentobox-world https://sonarcloud.io ${project.basedir}/lib From 37b43b6cc1cd09946a1837b65a8746194f3bd742 Mon Sep 17 00:00:00 2001 From: tastybento Date: Wed, 10 Apr 2024 21:32:11 -0700 Subject: [PATCH 09/19] Fix team management and ranks --- .../bentobox/database/objects/Island.java | 41 +++++++++---- .../bentobox/managers/IslandsManager.java | 4 -- .../bentobox/managers/island/IslandCache.java | 59 +++++++++++++++---- 3 files changed, 74 insertions(+), 30 deletions(-) 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 50c3c965e..5946b0aec 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; @@ -1016,8 +1017,9 @@ public class Island implements DataObject, MetaDataAble { * @param playerUUID - uuid of player */ public void removeMember(UUID playerUUID) { + BentoBox.getInstance().logDebug("removeMember - island "); if (members.remove(playerUUID) != null) { - BentoBox.getInstance().logDebug("removeMember"); + BentoBox.getInstance().logDebug("removeMember done"); setChanged(); } } @@ -1237,20 +1239,34 @@ 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; } - members.compute(uuid, (key, value) -> { - if (value == null || !value.equals(rank)) { - setChanged(); // Call setChanged only if the value is updated. - BentoBox.getInstance().logDebug("Set rank for " + uuid + " to " + rank); - return rank; + + // 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. } - return value; + // 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. + BentoBox.getInstance().logDebug("Set rank for UUID " + uuid + " to " + newRank); + } } + /** * @param ranks the ranks to set */ @@ -2060,8 +2076,9 @@ public class Island implements DataObject, MetaDataAble { * @param userID user UUID */ public void removePrimary(UUID userID) { + BentoBox.getInstance().logDebug("Removing primary "); if (getPrimaries().remove(userID)) { - BentoBox.getInstance().logDebug("removePrimary"); + BentoBox.getInstance().logDebug("removePrimary done"); setChanged(); } } @@ -2127,9 +2144,6 @@ public class Island implements DataObject, MetaDataAble { return Objects.hash(uniqueId); } - /** - * Islands are equal if they have the same uniqueId - */ @Override public boolean equals(Object obj) { if (this == obj) @@ -2142,4 +2156,5 @@ public class Island implements DataObject, MetaDataAble { return Objects.equals(uniqueId, other.uniqueId); } + } diff --git a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java index 34b969e34..d34c3f64b 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java @@ -508,7 +508,6 @@ public class IslandsManager { if (island.getOwner() == null) { // No owner, no rank settings island.setMaxMembers(null); - BentoBox.getInstance().logDebug("getMaxMembers no owner, no rank settings"); updateIsland(island); return 0; } @@ -533,7 +532,6 @@ public class IslandsManager { Integer change = islandMax == worldDefault ? null : islandMax; if (island.getMaxMembers().get(rank) != change) { island.setMaxMembers(rank, change); - BentoBox.getInstance().logDebug("getMaxMembers"); updateIsland(island); } return islandMax; @@ -576,7 +574,6 @@ public class IslandsManager { Integer change = islandMax == plugin.getIWM().getMaxHomes(island.getWorld()) ? null : islandMax; if (island.getMaxHomes() != change) { island.setMaxHomes(change); - BentoBox.getInstance().logDebug("getMaxHomes"); updateIsland(island); } return islandMax; @@ -768,7 +765,6 @@ public class IslandsManager { public boolean setHomeLocation(@Nullable Island island, Location location, String name) { if (island != null && (island.getHome(name) == null || !island.getHome(name).equals(location))) { island.addHome(name, location); - BentoBox.getInstance().logDebug("setHomeLocation"); updateIsland(island); return true; } 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 991d4a739..6b6df076e 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java @@ -56,24 +56,51 @@ public class IslandCache { /** * Replace the island we have with this one - * @param island island + * @param newIsland island */ - public void updateIsland(@NonNull Island island) { - if (islandsByLocation.put(island.getCenter(), island) == null) { - BentoBox.getInstance().logDebug("islandsByLocation failed to update"); + public void updateIsland(@NonNull Island newIsland) { + // Get the old island + Island oldIsland = islandsById.get(newIsland.getUniqueId()); + 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)) { + BentoBox.getInstance().logDebug("Removing a member from the team " + oldMember); + // Member has been removed - remove island + if (islandsByUUID.computeIfAbsent(oldMember, k -> new HashSet<>()).remove(oldIsland)) { + BentoBox.getInstance().logDebug("removed"); + } else { + BentoBox.getInstance().logDebug("not removed!"); + } + ; + } + } } - if (islandsById.put(island.getUniqueId(), island) == null) { + // Update the members with the new island object + BentoBox.getInstance().logDebug("Updating island. New members are:"); + newMembers.forEach(BentoBox.getInstance()::logDebug); + for (UUID newMember : newMembers) { + Set set = islandsByUUID.computeIfAbsent(newMember, k -> new HashSet<>()); + if (set.remove(oldIsland)) { + BentoBox.getInstance().logDebug("removed old island for " + newMember); + } else { + BentoBox.getInstance().logDebug("Did not remove old island for " + newMember); + } + set.add(newIsland); + BentoBox.getInstance().logDebug("Added island to set"); + islandsByUUID.put(newMember, set); + } + + if (islandsByLocation.put(newIsland.getCenter(), newIsland) == null) { + BentoBox.getInstance().logDebug("islandsByLocation failed to update"); + + } + if (islandsById.put(newIsland.getUniqueId(), newIsland) == null) { BentoBox.getInstance().logDebug("islandsById failed to update"); } - // Only add islands to this map if they are owned - if (island.getOwner() != null) { - Set set = islandsByUUID.computeIfAbsent(island.getOwner(), k -> new HashSet<>()); - if (!set.remove(island)) { - BentoBox.getInstance().logDebug("islandsByUUID failed to remove"); - } - set.add(island); - } } /** @@ -192,17 +219,22 @@ public class IslandCache { @Nullable public Island get(@NonNull World world, @NonNull UUID uuid) { List islands = getIslands(world, uuid); + BentoBox.getInstance().logDebug("Getting islands for " + uuid + " and there are " + islands.size()); if (islands.isEmpty()) { return null; } for (Island island : islands) { if (island.isPrimary(uuid)) { + BentoBox.getInstance().logDebug("Primary island found"); + island.getMembers().keySet().forEach(BentoBox.getInstance()::logDebug); return island; } } + BentoBox.getInstance().logDebug("No Primary island set"); // If there is no primary set, then set one - it doesn't matter which. Island result = islands.iterator().next(); result.setPrimary(uuid); + result.getMembers().keySet().forEach(BentoBox.getInstance()::logDebug); return result; } @@ -347,6 +379,7 @@ public class IslandCache { * @param uuid uuid of member to remove */ public void removePlayer(@NonNull Island island, @NonNull UUID uuid) { + BentoBox.getInstance().logDebug("Removing the player " + uuid); Set islandSet = islandsByUUID.get(uuid); if (islandSet != null) { islandSet.remove(island); From 12b08aacc6bbcedeb5132947c5c9ff8f22adc197 Mon Sep 17 00:00:00 2001 From: tastybento Date: Wed, 10 Apr 2024 21:40:00 -0700 Subject: [PATCH 10/19] Removed debug --- .../bentobox/database/objects/Island.java | 47 ------------------- .../bentobox/managers/IslandsManager.java | 2 - .../bentobox/managers/island/IslandCache.java | 27 ++--------- .../bentobox/managers/island/IslandGrid.java | 2 - 4 files changed, 4 insertions(+), 74 deletions(-) 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 5946b0aec..2be8fa824 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/Island.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/Island.java @@ -292,7 +292,6 @@ public class Island implements DataObject, MetaDataAble { this.world = island.getWorld(); this.bonusRanges.addAll(island.getBonusRanges()); this.primaries.addAll(island.getPrimaries()); - BentoBox.getInstance().logDebug("Constructor copy"); this.setChanged(); } @@ -309,7 +308,6 @@ public class Island implements DataObject, MetaDataAble { public void addMember(@NonNull UUID playerUUID) { if (getRank(playerUUID) != RanksManager.MEMBER_RANK) { setRank(playerUUID, RanksManager.MEMBER_RANK); - BentoBox.getInstance().logDebug("Add member"); setChanged(); } } @@ -330,7 +328,6 @@ public class Island implements DataObject, MetaDataAble { setRank(target, RanksManager.BANNED_RANK); log(new LogEntry.Builder("BAN").data("player", target.toString()).data("issuer", issuer.toString()) .build()); - BentoBox.getInstance().logDebug("Ban"); setChanged(); } return true; @@ -620,7 +617,6 @@ public class Island implements DataObject, MetaDataAble { public int getMaxEverProtectionRange() { if (maxEverProtectionRange > this.getRange()) { maxEverProtectionRange = this.getRange(); - BentoBox.getInstance().logDebug("get max ever protect"); setChanged(); } return Math.max(this.getProtectionRange(), maxEverProtectionRange); @@ -640,7 +636,6 @@ public class Island implements DataObject, MetaDataAble { if (maxEverProtectionRange > this.range) { this.maxEverProtectionRange = this.range; } - BentoBox.getInstance().logDebug("setMaxEverProtectionRange"); setChanged(); } @@ -1017,9 +1012,7 @@ public class Island implements DataObject, MetaDataAble { * @param playerUUID - uuid of player */ public void removeMember(UUID playerUUID) { - BentoBox.getInstance().logDebug("removeMember - island "); if (members.remove(playerUUID) != null) { - BentoBox.getInstance().logDebug("removeMember done"); setChanged(); } } @@ -1031,7 +1024,6 @@ public class Island implements DataObject, MetaDataAble { if (this.center == null || !center.getWorld().equals(this.center.getWorld()) || !center.equals(this.center)) { this.world = center.getWorld(); this.center = center; - BentoBox.getInstance().logDebug("setCenter"); setChanged(); } } @@ -1042,7 +1034,6 @@ public class Island implements DataObject, MetaDataAble { public void setCreatedDate(long createdDate) { if (this.createdDate != createdDate) { this.createdDate = createdDate; - BentoBox.getInstance().logDebug("setCreatedDate"); setChanged(); } } @@ -1069,7 +1060,6 @@ public class Island implements DataObject, MetaDataAble { public void setFlag(Flag flag, int value, boolean doSubflags) { if (flags.containsKey(flag.getID()) && flags.get(flag.getID()) != value) { flags.put(flag.getID(), value); - BentoBox.getInstance().logDebug("setFlag " + flag); setChanged(); } // Subflag support @@ -1084,7 +1074,6 @@ public class Island implements DataObject, MetaDataAble { */ public void setFlags(Map flags) { this.flags = flags; - BentoBox.getInstance().logDebug("setFlags "); setChanged(); } @@ -1110,7 +1099,6 @@ public class Island implements DataObject, MetaDataAble { */ public void setMembers(Map members) { this.members = members; - BentoBox.getInstance().logDebug("setMembers"); setChanged(); } @@ -1124,7 +1112,6 @@ public class Island implements DataObject, MetaDataAble { public void setName(String name) { if (name == null || !name.equals(this.name)) { this.name = (name != null && !name.equals("")) ? name : null; - BentoBox.getInstance().logDebug("setName"); setChanged(); } } @@ -1151,7 +1138,6 @@ public class Island implements DataObject, MetaDataAble { } } setRank(owner, RanksManager.OWNER_RANK); - BentoBox.getInstance().logDebug("setOwner"); setChanged(); } @@ -1162,7 +1148,6 @@ public class Island implements DataObject, MetaDataAble { if (this.protectionRange != protectionRange) { this.protectionRange = protectionRange; this.updateMaxEverProtectionRange(); - BentoBox.getInstance().logDebug("setProtectionRange"); setChanged(); } } @@ -1198,7 +1183,6 @@ public class Island implements DataObject, MetaDataAble { public void setPurgeProtected(boolean purgeProtected) { if (this.purgeProtected != purgeProtected) { this.purgeProtected = purgeProtected; - BentoBox.getInstance().logDebug("setPurgeProtected"); setChanged(); } } @@ -1216,7 +1200,6 @@ public class Island implements DataObject, MetaDataAble { public void setRange(int range) { if (this.range != range) { this.range = range; - BentoBox.getInstance().logDebug("setRange"); setChanged(); } } @@ -1262,7 +1245,6 @@ public class Island implements DataObject, MetaDataAble { // If the rank was changed, notify the change and log the update. if (isRankChanged.get()) { setChanged(); // Notify that a change has occurred. - BentoBox.getInstance().logDebug("Set rank for UUID " + uuid + " to " + newRank); } } @@ -1272,7 +1254,6 @@ public class Island implements DataObject, MetaDataAble { */ public void setRanks(Map ranks) { members = ranks; - BentoBox.getInstance().logDebug("setRanks"); setChanged(); } @@ -1297,7 +1278,6 @@ public class Island implements DataObject, MetaDataAble { setFlag(Flags.LOCK, RanksManager.VISITOR_RANK); } log(new LogEntry.Builder("SPAWN").data("value", String.valueOf(isSpawn)).build()); - BentoBox.getInstance().logDebug("setSpawn"); setChanged(); } @@ -1319,7 +1299,6 @@ public class Island implements DataObject, MetaDataAble { */ public void setSpawnPoint(Map spawnPoint) { this.spawnPoint = spawnPoint; - BentoBox.getInstance().logDebug("setSpawnPoint"); setChanged(); } @@ -1340,7 +1319,6 @@ public class Island implements DataObject, MetaDataAble { */ public void setWorld(World world) { this.world = world; - BentoBox.getInstance().logDebug("setWorld"); setChanged(); } @@ -1365,7 +1343,6 @@ public class Island implements DataObject, MetaDataAble { if (flag.getType().equals(Flag.Type.SETTING) || flag.getType().equals(Flag.Type.WORLD_SETTING)) { setSettingsFlag(flag, newToggleValue, doSubflags); } - BentoBox.getInstance().logDebug("toggleFlag " + flag); setChanged(); } @@ -1397,7 +1374,6 @@ public class Island implements DataObject, MetaDataAble { flag.getSubflags().forEach(subflag -> setSettingsFlag(subflag, state, true)); } } - BentoBox.getInstance().logDebug("setSettingsFlag " + flag); setChanged(); } @@ -1435,7 +1411,6 @@ public class Island implements DataObject, MetaDataAble { */ public void removeRank(Integer rank) { if (members.values().removeIf(rank::equals)) { - BentoBox.getInstance().logDebug("removeRank"); setChanged(); } } @@ -1456,7 +1431,6 @@ public class Island implements DataObject, MetaDataAble { */ public void log(LogEntry logEntry) { history.add(logEntry); - BentoBox.getInstance().logDebug("log"); setChanged(); } @@ -1467,7 +1441,6 @@ public class Island implements DataObject, MetaDataAble { */ public void setHistory(List history) { this.history = history; - BentoBox.getInstance().logDebug("setHistory"); setChanged(); } @@ -1483,7 +1456,6 @@ public class Island implements DataObject, MetaDataAble { */ public void setDoNotLoad(boolean doNotLoad) { this.doNotLoad = doNotLoad; - BentoBox.getInstance().logDebug("setDoNotLoad"); setChanged(); } @@ -1499,7 +1471,6 @@ public class Island implements DataObject, MetaDataAble { */ public void setDeleted(boolean deleted) { this.deleted = deleted; - BentoBox.getInstance().logDebug("setDeleted"); setChanged(); } @@ -1590,7 +1561,6 @@ public class Island implements DataObject, MetaDataAble { return true; } if (cooldowns.remove(flag.getID()) != null) { - BentoBox.getInstance().logDebug("isCooldown"); setChanged(); } return false; @@ -1603,7 +1573,6 @@ public class Island implements DataObject, MetaDataAble { */ public void setCooldown(Flag flag) { cooldowns.put(flag.getID(), flag.getCooldown() * 1000L + System.currentTimeMillis()); - BentoBox.getInstance().logDebug("setCooldown"); setChanged(); } @@ -1619,7 +1588,6 @@ public class Island implements DataObject, MetaDataAble { */ public void setCooldowns(Map cooldowns) { this.cooldowns = cooldowns; - BentoBox.getInstance().logDebug("setCooldowns"); setChanged(); } @@ -1635,7 +1603,6 @@ public class Island implements DataObject, MetaDataAble { */ public void setCommandRanks(Map commandRanks) { this.commandRanks = commandRanks; - BentoBox.getInstance().logDebug("setCommandRanks"); setChanged(); } @@ -1707,7 +1674,6 @@ public class Island implements DataObject, MetaDataAble { public void setReserved(boolean reserved) { if (this.reserved != reserved) { this.reserved = reserved; - BentoBox.getInstance().logDebug("setReserved"); setChanged(); } } @@ -1731,7 +1697,6 @@ public class Island implements DataObject, MetaDataAble { @Override public void setMetaData(Map metaData) { this.metaData = metaData; - BentoBox.getInstance().logDebug("setMetaData"); setChanged(); } @@ -1787,7 +1752,6 @@ public class Island implements DataObject, MetaDataAble { } this.location = location; this.updateMaxEverProtectionRange(); - BentoBox.getInstance().logDebug("setProtectionCenter"); setChanged(); } @@ -1846,7 +1810,6 @@ public class Island implements DataObject, MetaDataAble { } } getHomes().put(name.toLowerCase(), location); - BentoBox.getInstance().logDebug("addHome"); setChanged(); } @@ -1917,7 +1880,6 @@ public class Island implements DataObject, MetaDataAble { public void setMaxHomes(@Nullable Integer maxHomes) { if (this.maxHomes != maxHomes) { this.maxHomes = maxHomes; - BentoBox.getInstance().logDebug("setMaxHomes"); setChanged(); } } @@ -1940,7 +1902,6 @@ public class Island implements DataObject, MetaDataAble { public void setMaxMembers(Map maxMembers) { if (this.maxMembers != maxMembers) { this.maxMembers = maxMembers; - BentoBox.getInstance().logDebug("setMaxMembers"); setChanged(); } } @@ -1991,7 +1952,6 @@ public class Island implements DataObject, MetaDataAble { */ public void setBonusRanges(List bonusRanges) { this.bonusRanges = bonusRanges; - BentoBox.getInstance().logDebug("setBonusRanges"); setChanged(); } @@ -2028,7 +1988,6 @@ public class Island implements DataObject, MetaDataAble { public void addBonusRange(String id, int range, String message) { this.getBonusRanges().add(new BonusRangeRecord(id, range, message)); setMaxEverProtectionRange(this.getProtectionRange()); - BentoBox.getInstance().logDebug("addBonusRange"); setChanged(); } @@ -2039,7 +1998,6 @@ public class Island implements DataObject, MetaDataAble { */ public void clearBonusRange(String id) { if (this.getBonusRanges().removeIf(r -> r.getUniqueId().equals(id))) { - BentoBox.getInstance().logDebug("clearBonusRange"); setChanged(); } } @@ -2049,7 +2007,6 @@ public class Island implements DataObject, MetaDataAble { */ public void clearAllBonusRanges() { this.getBonusRanges().clear(); - BentoBox.getInstance().logDebug("clearAllBonusRanges"); setChanged(); } @@ -2066,7 +2023,6 @@ public class Island implements DataObject, MetaDataAble { */ public void setPrimary(UUID userID) { if (getPrimaries().add(userID)) { - BentoBox.getInstance().logDebug("setPrimary"); setChanged(); } } @@ -2076,9 +2032,7 @@ public class Island implements DataObject, MetaDataAble { * @param userID user UUID */ public void removePrimary(UUID userID) { - BentoBox.getInstance().logDebug("Removing primary "); if (getPrimaries().remove(userID)) { - BentoBox.getInstance().logDebug("removePrimary done"); setChanged(); } } @@ -2135,7 +2089,6 @@ public class Island implements DataObject, MetaDataAble { */ public void setPrimaries(Set primaries) { this.primaries = primaries; - BentoBox.getInstance().logDebug("setPrimaries"); setChanged(); } diff --git a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java index d34c3f64b..027c925f7 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java @@ -1476,7 +1476,6 @@ public class IslandsManager { teamIsland.addMember(playerUUID); islandCache.addPlayer(playerUUID, teamIsland); // Save the island - BentoBox.getInstance().logDebug("setJoinTeam"); updateIsland(teamIsland); } @@ -1625,7 +1624,6 @@ public class IslandsManager { island.clearChanged(); handler.saveObjectAsync(island) .thenAccept(b -> MultiLib.notify("bentobox-updateIsland", island.getUniqueId())); - BentoBox.getInstance().logDebug("Saved island " + island.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 6b6df076e..f496d7ed6 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java @@ -67,38 +67,25 @@ public class IslandCache { // Remove any members who are not in the new island for (UUID oldMember : oldMembers) { if (!newMembers.contains(oldMember)) { - BentoBox.getInstance().logDebug("Removing a member from the team " + oldMember); // Member has been removed - remove island - if (islandsByUUID.computeIfAbsent(oldMember, k -> new HashSet<>()).remove(oldIsland)) { - BentoBox.getInstance().logDebug("removed"); - } else { - BentoBox.getInstance().logDebug("not removed!"); - } - ; + islandsByUUID.computeIfAbsent(oldMember, k -> new HashSet<>()).remove(oldIsland); } } } // Update the members with the new island object - BentoBox.getInstance().logDebug("Updating island. New members are:"); - newMembers.forEach(BentoBox.getInstance()::logDebug); for (UUID newMember : newMembers) { Set set = islandsByUUID.computeIfAbsent(newMember, k -> new HashSet<>()); - if (set.remove(oldIsland)) { - BentoBox.getInstance().logDebug("removed old island for " + newMember); - } else { - BentoBox.getInstance().logDebug("Did not remove old island for " + newMember); - } + set.remove(oldIsland); set.add(newIsland); - BentoBox.getInstance().logDebug("Added island to set"); islandsByUUID.put(newMember, set); } if (islandsByLocation.put(newIsland.getCenter(), newIsland) == null) { - BentoBox.getInstance().logDebug("islandsByLocation failed to update"); + BentoBox.getInstance().logError("islandsByLocation failed to update"); } if (islandsById.put(newIsland.getUniqueId(), newIsland) == null) { - BentoBox.getInstance().logDebug("islandsById failed to update"); + BentoBox.getInstance().logError("islandsById failed to update"); } } @@ -219,22 +206,17 @@ public class IslandCache { @Nullable public Island get(@NonNull World world, @NonNull UUID uuid) { List islands = getIslands(world, uuid); - BentoBox.getInstance().logDebug("Getting islands for " + uuid + " and there are " + islands.size()); if (islands.isEmpty()) { return null; } for (Island island : islands) { if (island.isPrimary(uuid)) { - BentoBox.getInstance().logDebug("Primary island found"); - island.getMembers().keySet().forEach(BentoBox.getInstance()::logDebug); return island; } } - BentoBox.getInstance().logDebug("No Primary island set"); // If there is no primary set, then set one - it doesn't matter which. Island result = islands.iterator().next(); result.setPrimary(uuid); - result.getMembers().keySet().forEach(BentoBox.getInstance()::logDebug); return result; } @@ -379,7 +361,6 @@ public class IslandCache { * @param uuid uuid of member to remove */ public void removePlayer(@NonNull Island island, @NonNull UUID uuid) { - BentoBox.getInstance().logDebug("Removing the player " + uuid); Set islandSet = islandsByUUID.get(uuid); if (islandSet != null) { islandSet.remove(island); 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 fd47d3dde..920cf9e71 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/IslandGrid.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/IslandGrid.java @@ -34,10 +34,8 @@ class IslandGrid { TreeMap zEntry = grid.get(island.getMinX()); if (zEntry.containsKey(island.getMinZ())) { if (island.getUniqueId().equals(zEntry.get(island.getMinZ()))) { - BentoBox.getInstance().logDebug("I already know about this island"); return true; } - BentoBox.getInstance().logDebug("Overlapping island"); return false; } else { // Add island From 8b15888968474bfcf06f240662f93170906e3d45 Mon Sep 17 00:00:00 2001 From: tastybento Date: Wed, 10 Apr 2024 23:00:20 -0700 Subject: [PATCH 11/19] Handle island deletion better --- .../bentobox/managers/IslandsManager.java | 16 +-- .../bentobox/managers/island/IslandCache.java | 135 +++++++++++++++--- .../bentobox/managers/island/IslandGrid.java | 39 ++--- .../bentobox/managers/island/NewIsland.java | 4 +- 4 files changed, 136 insertions(+), 58 deletions(-) diff --git a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java index 027c925f7..e503e06eb 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java @@ -119,14 +119,6 @@ public class IslandsManager { islandCache.addIsland(island); } }); - // Remove islands - MultiLib.onString(plugin, "bentobox-deleteIsland", id -> { - BentoBox.getInstance().logDebug("Delete island " + id); - Island island = handler.loadObject(id); - if (island != null) { - islandCache.removeIsland(island); - } - }); // Set or clear spawn MultiLib.onString(plugin, "bentobox-setspawn", sp -> { String[] split = sp.split(","); @@ -275,6 +267,7 @@ public class IslandsManager { * @param involvedPlayer - player related to the island deletion, if any */ public void deleteIsland(@NonNull Island island, boolean removeBlocks, @Nullable UUID involvedPlayer) { + BentoBox.getInstance().logDebug("Deleting island " + island.getUniqueId() + " remove blocks = " + removeBlocks); // Fire event IslandBaseEvent event = IslandEvent.builder().island(island).involvedPlayer(involvedPlayer) .reason(Reason.DELETE).build(); @@ -284,19 +277,18 @@ 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); - // Delete the island - handler.deleteObject(island); - // Inform other servers - MultiLib.notify("bentobox-deletedIsland", island.getUniqueId()); // Remove players from island removePlayersFromIsland(island); if (!plugin.getSettings().isKeepPreviousIslandOnReset()) { // Remove blocks from world plugin.getIslandDeletionManager().getIslandChunkDeletionManager().add(new IslandDeletion(island)); } + // Delete the island from the database + handler.deleteObject(island); } } 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 f496d7ed6..954972afa 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; @@ -59,8 +60,13 @@ public class IslandCache { * @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(); @@ -90,6 +96,113 @@ public class IslandCache { } + 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 * @@ -148,6 +261,7 @@ public class IslandCache { */ public boolean deleteIslandFromCache(@NonNull Island island) { if (!islandsByLocation.remove(island.getCenter(), island)) { + // Already deleted return false; } islandsById.remove(island.getUniqueId()); @@ -416,27 +530,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().forEach(s -> s.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 920cf9e71..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; /** @@ -57,31 +56,23 @@ 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; + } + /** - * 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 - */ + * 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) { // Attempt to find the closest x-coordinate entry that does not exceed 'x' Entry> xEntry = grid.floorEntry(x); 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 465bd7ef4..0f6b09467 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 @@ -216,8 +217,9 @@ public class NewIsland { island.setFlagsDefaults(); // Register metrics plugin.getMetrics().ifPresent(BStats::increaseIslandsCreatedCount); + plugin.getIslands(); // Save island - plugin.getIslands().updateIsland(island); + IslandsManager.updateIsland(island); } /** From 2fe85ec9b029123bc13f93952d4e33f2f692bbc4 Mon Sep 17 00:00:00 2001 From: tastybento Date: Thu, 11 Apr 2024 19:17:47 -0700 Subject: [PATCH 12/19] Island deletion across servers. --- .../bentobox/managers/IslandsManager.java | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java index e503e06eb..38090056d 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java @@ -38,6 +38,8 @@ 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; @@ -48,6 +50,7 @@ import world.bentobox.bentobox.api.flags.Flag; import world.bentobox.bentobox.api.localization.TextVariables; 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; @@ -111,6 +114,13 @@ public class IslandsManager { islandCache.updateIsland(island); } }); + + // Delete island blocks + MultiLib.onString(plugin, "bentobox-deleteIsland", id -> { + BentoBox.getInstance().logDebug("Delete island blocks"); + IslandDeletion idd = getGson().fromJson(id, IslandDeletion.class); + plugin.getIslandDeletionManager().getIslandChunkDeletionManager().add(idd); + }); // List for new islands MultiLib.onString(plugin, "bentobox-newIsland", id -> { BentoBox.getInstance().logDebug("New island " + id); @@ -285,13 +295,32 @@ public class IslandsManager { 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. * From b756d06c0e42fbc639febf689899fef0a50c9efe Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 14 Apr 2024 14:37:44 -0700 Subject: [PATCH 13/19] Fix bug with MythicMobs changes #2340 --- .../bentobox/blueprints/dataobjects/BlueprintEntity.java | 3 +++ .../java/world/bentobox/bentobox/hooks/MythicMobsHook.java | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintEntity.java b/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintEntity.java index bf6257d59..4c4eb1de1 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintEntity.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintEntity.java @@ -286,6 +286,9 @@ public class BlueprintEntity { * @return the mythicMobsRecord */ public MythicMobRecord getMythicMobsRecord() { + if (this.MMtype == null || this.MMLevel == null || this.MMpower == null || this.MMStance == null) { + return null; + } return new MythicMobRecord(this.MMtype, this.getCustomName(), this.MMLevel, this.MMpower, this.MMStance); } diff --git a/src/main/java/world/bentobox/bentobox/hooks/MythicMobsHook.java b/src/main/java/world/bentobox/bentobox/hooks/MythicMobsHook.java index 5db726a27..616ea0622 100644 --- a/src/main/java/world/bentobox/bentobox/hooks/MythicMobsHook.java +++ b/src/main/java/world/bentobox/bentobox/hooks/MythicMobsHook.java @@ -55,6 +55,9 @@ public class MythicMobsHook extends Hook { * @return true if spawn is successful */ public boolean spawnMythicMob(MythicMobRecord mmr, Location spawnLocation) { + if (!this.isPluginAvailable()) { + return false; + } return MythicBukkit.inst().getMobManager().getMythicMob(mmr.type()).map(mob -> { // A delay is required before spawning, I assume because the blocks are pasted using NMS Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { From 9b8540a8edfabebfe0af07fdec1e36fd516911ec Mon Sep 17 00:00:00 2001 From: tastybento Date: Fri, 19 Apr 2024 21:43:30 -0700 Subject: [PATCH 14/19] 2.4.0 --- pom.xml | 2 +- .../java/world/bentobox/bentobox/managers/island/NewIsland.java | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index ad29ae900..e770b82a8 100644 --- a/pom.xml +++ b/pom.xml @@ -88,7 +88,7 @@ -LOCAL - 2.3.0-mp + 2.4.0 bentobox-world https://sonarcloud.io ${project.basedir}/lib 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 0f6b09467..bb4f2cb22 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/NewIsland.java @@ -217,7 +217,6 @@ public class NewIsland { island.setFlagsDefaults(); // Register metrics plugin.getMetrics().ifPresent(BStats::increaseIslandsCreatedCount); - plugin.getIslands(); // Save island IslandsManager.updateIsland(island); } From fd12ef9fe793cfaf614f75738d9904b3acf3ff1a Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 21 Apr 2024 13:12:52 -0700 Subject: [PATCH 15/19] Load of debug - trying to solve the settings slowness --- .../java/world/bentobox/bentobox/BStats.java | 22 ---- .../bentobox/bentobox/api/addons/Addon.java | 5 + .../bentobox/api/addons/GameModeAddon.java | 7 +- .../commands/admin/AdminSettingsCommand.java | 3 - .../admin/AdminUnregisterCommand.java | 1 - .../admin/conversations/NamePrompt.java | 1 - .../team/IslandTeamInviteAcceptCommand.java | 1 - .../team/IslandTeamSetownerCommand.java | 1 - .../bentobox/bentobox/api/flags/Flag.java | 13 +- .../bentobox/api/panels/TabbedPanel.java | 13 +- .../bentobox/database/objects/Island.java | 1 + .../bentobox/database/objects/Players.java | 124 ------------------ .../bentobox/listeners/JoinLeaveListener.java | 4 +- .../clicklisteners/CommandCycleClick.java | 3 - .../bentobox/managers/IslandsManager.java | 3 + .../bentobox/managers/PlayersManager.java | 71 +++------- .../bentobox/panels/settings/SettingsTab.java | 35 ++++- .../settings/WorldDefaultSettingsTab.java | 2 + .../admin/AdminSettingsCommandTest.java | 1 - .../bentobox/managers/PlayersManagerTest.java | 19 --- 20 files changed, 88 insertions(+), 242 deletions(-) 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/api/addons/Addon.java b/src/main/java/world/bentobox/bentobox/api/addons/Addon.java index 57190b7d9..32f656ac4 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()); } /** @@ -220,6 +224,7 @@ public abstract class Addon { * @since 1.13.0 */ public void reloadConfig() { + BentoBox.getInstance().logDebug("Config reloaded"); config = loadYamlFile(); } 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/AdminSettingsCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSettingsCommand.java index 1fa50c1a7..f3192369b 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 @@ -206,11 +206,9 @@ public class AdminSettingsCommand extends CompositeCommand { switch (f.getType()) { case PROTECTION -> { island.setFlag(f, rank); - getIslands().updateIsland(island); } case SETTING -> { island.setSettingsFlag(f, activeState); - getIslands().updateIsland(island); } case WORLD_SETTING -> f.setSetting(getWorld(), activeState); default -> { @@ -226,7 +224,6 @@ 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) 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 d0b319aee..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().updateIsland(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 645be62b2..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().updateIsland(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/team/IslandTeamInviteAcceptCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteAcceptCommand.java index 47ce878e7..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 @@ -197,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()); } - //IslandsManager.updateIsland(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/IslandTeamSetownerCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommand.java index 0c8475654..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 @@ -92,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(); - IslandsManager.updateIsland(island); return true; } 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..4acca3cd1 100644 --- a/src/main/java/world/bentobox/bentobox/api/flags/Flag.java +++ b/src/main/java/world/bentobox/bentobox/api/flags/Flag.java @@ -384,6 +384,7 @@ public class Flag implements Comparable { */ @Nullable public PanelItem toPanelItem(BentoBox plugin, User user, World world, @Nullable Island island, boolean invisible) { + long m = System.currentTimeMillis(); // Invisibility if (!user.isOp() && invisible) { return null; @@ -394,10 +395,12 @@ public class Flag implements Comparable { .name(user.getTranslation("protection.panel.flag-item.name-layout", TextVariables.NAME, user.getTranslation(getNameReference()))) .clickHandler(clickHandler) .invisible(invisible); + BentoBox.getInstance().logDebug("Time for pib = " + (System.currentTimeMillis() - m)); if (hasSubPanel()) { pib.description(user.getTranslation("protection.panel.flag-item.menu-layout", TextVariables.DESCRIPTION, user.getTranslation(getDescriptionReference()))); return pib.build(); } + BentoBox.getInstance().logDebug("Type = " + getType()); return switch (getType()) { case PROTECTION -> createProtectionFlag(plugin, user, island, pib).build(); case SETTING -> createSettingFlag(user, island, pib).build(); @@ -428,20 +431,24 @@ public class Flag implements Comparable { } private PanelItemBuilder createProtectionFlag(BentoBox plugin, User user, Island island, PanelItemBuilder pib) { + long m = System.currentTimeMillis(); + BentoBox.getInstance().logDebug("Protection flag"); 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)); } }); } + BentoBox.getInstance().logDebug("Protection flag " + (System.currentTimeMillis() - m)); return pib; } 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..91abe4a0d 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) { + long m = System.currentTimeMillis(); 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); @@ -84,11 +85,12 @@ public class TabbedPanel extends Panel implements PanelListener { } this.activeTab = activeTab; this.activePage = page; + BentoBox.getInstance().logDebug("Time 1 " + (System.currentTimeMillis() - m)); // The items in the panel TreeMap items = new TreeMap<>(); // Get the tab Tab tab = tpb.getTabs().get(activeTab); - + BentoBox.getInstance().logDebug("Time 2 " + (System.currentTimeMillis() - m)); // 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)); @@ -96,15 +98,16 @@ public class TabbedPanel extends Panel implements PanelListener { // Set up the tabbed header setupHeader(tab, items); - + BentoBox.getInstance().logDebug("Time 3 " + (System.currentTimeMillis() - m)); // 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)); - + BentoBox.getInstance().logDebug("Time 4 " + (System.currentTimeMillis() - m)); // set up the footer setupFooter(items); + BentoBox.getInstance().logDebug("Time 5 " + (System.currentTimeMillis() - m)); // Add forward and backward icons if (page > 0) { // Previous page icon @@ -114,6 +117,7 @@ public class TabbedPanel extends Panel implements PanelListener { return true; }).build()); } + BentoBox.getInstance().logDebug("Time 6 " + (System.currentTimeMillis() - m)); if ((page + 1) * ITEMS_PER_PAGE < panelItems.stream().filter(Objects::nonNull).count()) { // Next page icon items.put(52, new PanelItemBuilder().icon(Material.ARROW).name(tpb.getUser().getTranslation(PROTECTION_PANEL + "next")).clickHandler((panel, user1, clickType, slot1) -> { @@ -122,11 +126,14 @@ public class TabbedPanel extends Panel implements PanelListener { return true; }).build()); } + BentoBox.getInstance().logDebug("Time 7 " + (System.currentTimeMillis() - m)); } else { throw new InvalidParameterException("Unknown tab slot number " + activeTab); } + BentoBox.getInstance().logDebug("Time 8 " + (System.currentTimeMillis() - m)); // Show it to the player this.makePanel(tab.getName(), items, tpb.getSize(), tpb.getUser(), this); + BentoBox.getInstance().logDebug("Time 9 " + (System.currentTimeMillis() - m)); } /** 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 2be8fa824..fb8f7b0c8 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/Island.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/Island.java @@ -1711,6 +1711,7 @@ public class Island implements DataObject, MetaDataAble { * Indicates the fields have been changed. Used to optimize saving on shutdown and notify other servers */ public void setChanged() { + BentoBox.getInstance().logDebug("Island changed"); this.setUpdatedDate(System.currentTimeMillis()); this.changed = true; IslandsManager.updateIsland(this); 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/listeners/JoinLeaveListener.java b/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java index 7cac25a0c..0fdee8507 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/JoinLeaveListener.java @@ -62,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() @@ -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 -> { 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 922c82dcd..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().updateIsland(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 38090056d..5c9426bee 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java @@ -1641,11 +1641,14 @@ public class IslandsManager { * @param island - island */ public static void updateIsland(Island island) { + long m = System.currentTimeMillis(); + if (handler.objectExists(island.getUniqueId())) { island.clearChanged(); handler.saveObjectAsync(island) .thenAccept(b -> MultiLib.notify("bentobox-updateIsland", island.getUniqueId())); } + BentoBox.getInstance().logDebug("Island update " + (System.currentTimeMillis() - m)); } /** diff --git a/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java b/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java index 69ac06e12..b3303f738 100644 --- a/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java @@ -2,7 +2,9 @@ package world.bentobox.bentobox.managers; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.UUID; @@ -14,7 +16,6 @@ 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; @@ -27,11 +28,10 @@ public class PlayersManager { private final BentoBox plugin; private Database handler; private final Database names; + private final Map playerCache = new HashMap<>(); private final Set inTeleport; // this needs databasing - private boolean isSaveTaskRunning; - /** * Provides a memory cache of online player information * This is the one-stop-shop of player info @@ -56,17 +56,6 @@ 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(){ - inTeleport.clear(); - } - - public boolean isSaveTaskRunning() { - return isSaveTaskRunning; - } - public void shutdown(){ handler.close(); } @@ -78,28 +67,18 @@ public class PlayersManager { */ @Nullable public Players getPlayer(UUID uuid){ - return addPlayer(uuid); + if (!playerCache.containsKey(uuid)) { + playerCache.put(uuid, addPlayer(uuid)); + BentoBox.getInstance().logDebug("Not in cache"); + } + return playerCache.get(uuid); } - /** - * Returns an unmodifiable collection of all the players that are currently in the cache. - * @return unmodifiable collection containing every player in the cache. - * @since 1.1 - */ - @NonNull - public Collection getPlayers() { - return Collections.unmodifiableCollection(handler.loadObjects()); - } - - /* - * Cache control methods - */ - /** * Adds a player to the database. If the UUID does not exist, a new player is made * @param playerUUID - the player's UUID */ - public Players addPlayer(@NonNull UUID playerUUID) { + 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())) { @@ -113,6 +92,16 @@ public class PlayersManager { 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. + * @since 1.1 + */ + @NonNull + public Collection getPlayers() { + return Collections.unmodifiableCollection(handler.loadObjects()); + } + /** * Checks if the player is known or not. * Will check not just the cache but if the object but in the database too. @@ -320,28 +309,6 @@ public class PlayersManager { 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) { - Players p = addPlayer(playerUUID); - p.setFlagsDisplayMode(displayMode); - handler.saveObject(p); - } - - /** - * 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) { - return addPlayer(playerUUID).getFlagsDisplayMode(); - } - /** * Remove player from database * @param player player to remove 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..738c0c9ff 100644 --- a/src/main/java/world/bentobox/bentobox/panels/settings/SettingsTab.java +++ b/src/main/java/world/bentobox/bentobox/panels/settings/SettingsTab.java @@ -1,9 +1,11 @@ package world.bentobox.bentobox.panels.settings; +import java.util.ArrayList; 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 +18,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,6 +49,8 @@ public class SettingsTab implements Tab, ClickHandler { protected Island island; protected TabbedPanel parent; + private Map currentMode = new HashMap<>(); + /** * Show a tab of settings * @param user - user who is viewing the tab @@ -73,6 +78,7 @@ public class SettingsTab implements Tab, ClickHandler { * @return list of flags that will be shown in this panel */ protected List getFlags() { + long m = System.currentTimeMillis(); // Get a list of flags of the correct type and sort by the translated names List flags = plugin.getFlagsManager().getFlags().stream().filter(f -> f.getType().equals(type)) // We're stripping colors to avoid weird sorting issues @@ -81,9 +87,10 @@ 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))); + BentoBox.getInstance().logDebug("Time to get flags = " + (System.currentTimeMillis() - m)); return flags; } @@ -116,17 +123,33 @@ public class SettingsTab implements Tab, ClickHandler { @Override @NonNull public List<@Nullable PanelItem> getPanelItems() { + long m = System.currentTimeMillis(); + BentoBox.getInstance().logDebug("Get panel items"); List flags = getFlags(); + BentoBox.getInstance().logDebug("Time for getFlags = " + (System.currentTimeMillis() - m)); 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 = new ArrayList<>(); + for (Flag f : flags) { + boolean x = plugin.getIWM().getHiddenFlags(world).contains(f.getID()); + //BentoBox.getInstance().logDebug("Time for x = " + (System.currentTimeMillis() - m)); + PanelItem pi = f.toPanelItem(plugin, user, world, island, x); + ///BentoBox.getInstance().logDebug("Time for pi = " + (System.currentTimeMillis() - m)); + result.add(pi); + } + /* + List<@Nullable PanelItem> result = flags.stream().map( (f -> f.toPanelItem(plugin, user, world, island, plugin.getIWM().getHiddenFlags(world).contains(f.getID())))) .toList(); + */ + BentoBox.getInstance().logDebug("Time for getpanelitems end = " + (System.currentTimeMillis() - m)); + return result; } @Override @@ -138,7 +161,7 @@ public class SettingsTab implements Tab, ClickHandler { 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"), "", @@ -215,13 +238,15 @@ public class SettingsTab implements Tab, ClickHandler { @Override public boolean onClick(Panel panel, User user, ClickType clickType, int slot) { + long m = System.currentTimeMillis(); // 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(); user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_STONE_BUTTON_CLICK_OFF, 1F, 1F); } + BentoBox.getInstance().logDebug("Time for onClick = " + (System.currentTimeMillis() - m)); return true; } 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..752d9d9c3 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; @@ -69,6 +70,7 @@ public class WorldDefaultSettingsTab extends SettingsTab implements Tab { */ @Override public @NonNull List getPanelItems() { + BentoBox.getInstance().logDebug("Get world default settings"); // Different description and click handlers return getFlags().stream().map(f -> { PanelItem i = f.toPanelItem(plugin, user, world, island, false); 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..603522044 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 diff --git a/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java index 77c00bbf4..d89ed0379 100644 --- a/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java @@ -382,15 +382,6 @@ public class PlayersManagerTest { assertEquals(0, pm.getDeaths(world, uuid)); } - /** - * Test method for - * {@link world.bentobox.bentobox.managers.PlayersManager#getFlagsDisplayMode(java.util.UUID)}. - */ - @Test - public void testGetFlagsDisplayMode() { - assertEquals(Mode.BASIC, pm.getFlagsDisplayMode(uuid)); - } - /** * Test method for * {@link world.bentobox.bentobox.managers.PlayersManager#getLocale(java.util.UUID)}. @@ -634,16 +625,6 @@ public class PlayersManagerTest { } - /** - * Test method for - * {@link world.bentobox.bentobox.managers.PlayersManager#setFlagsDisplayMode(java.util.UUID, world.bentobox.bentobox.api.flags.Flag.Mode)}. - */ - @Test - public void testSetFlagsDisplayMode() { - pm.setFlagsDisplayMode(uuid, Mode.ADVANCED); - assertEquals(Mode.ADVANCED, pm.getFlagsDisplayMode(uuid)); - } - /** * Test method for * {@link world.bentobox.bentobox.managers.PlayersManager#setInTeleport(java.util.UUID)}. From 5b4ecd52933d00da397a95a0786232110b26407a Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 21 Apr 2024 13:30:03 -0700 Subject: [PATCH 16/19] Debug debug --- src/main/java/world/bentobox/bentobox/api/flags/Flag.java | 5 ++++- .../bentobox/bentobox/panels/settings/SettingsTab.java | 6 ++++-- 2 files changed, 8 insertions(+), 3 deletions(-) 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 4acca3cd1..938d0dc6b 100644 --- a/src/main/java/world/bentobox/bentobox/api/flags/Flag.java +++ b/src/main/java/world/bentobox/bentobox/api/flags/Flag.java @@ -384,6 +384,7 @@ public class Flag implements Comparable { */ @Nullable public PanelItem toPanelItem(BentoBox plugin, User user, World world, @Nullable Island island, boolean invisible) { + // TODO: Why is this taking long long m = System.currentTimeMillis(); // Invisibility if (!user.isOp() && invisible) { @@ -435,9 +436,11 @@ public class Flag implements Comparable { BentoBox.getInstance().logDebug("Protection flag"); if (island != null) { int y = island.getFlag(this); + BentoBox.getInstance().logDebug("Protection flag getFlag time " + (System.currentTimeMillis() - m)); // Protection flag pib.description(user.getTranslation("protection.panel.flag-item.description-layout", TextVariables.DESCRIPTION, user.getTranslation(getDescriptionReference()))); + BentoBox.getInstance().logDebug("Protection flag description time " + (System.currentTimeMillis() - m)); RanksManager.getInstance().getRanks().forEach((reference, score) -> { if (score > RanksManager.BANNED_RANK && score < y) { pib.description(user.getTranslation("protection.panel.flag-item.blocked-rank") + user.getTranslation(reference)); @@ -448,7 +451,7 @@ public class Flag implements Comparable { } }); } - BentoBox.getInstance().logDebug("Protection flag " + (System.currentTimeMillis() - m)); + BentoBox.getInstance().logDebug("Protection flag time " + (System.currentTimeMillis() - m)); return pib; } 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 738c0c9ff..85486d6a1 100644 --- a/src/main/java/world/bentobox/bentobox/panels/settings/SettingsTab.java +++ b/src/main/java/world/bentobox/bentobox/panels/settings/SettingsTab.java @@ -123,16 +123,18 @@ public class SettingsTab implements Tab, ClickHandler { @Override @NonNull public List<@Nullable PanelItem> getPanelItems() { - long m = System.currentTimeMillis(); + BentoBox.getInstance().logDebug("Get panel items"); List flags = getFlags(); - BentoBox.getInstance().logDebug("Time for getFlags = " + (System.currentTimeMillis() - m)); int i = 0; // Jump past empty tabs while (flags.isEmpty() && i++ < Flag.Mode.values().length) { currentMode.put(user.getUniqueId(), currentMode.getOrDefault(user.getUniqueId(), Mode.BASIC).getNext()); flags = getFlags(); } + long m = System.currentTimeMillis(); + + // TODO This is taking too long!!! List<@Nullable PanelItem> result = new ArrayList<>(); for (Flag f : flags) { From cf0bdbc3904c4a2889218597c24071008b93ecf7 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 28 Apr 2024 08:00:03 -0700 Subject: [PATCH 17/19] Bug found - addPlayer being called instead of getPlayer --- .../world/bentobox/bentobox/BentoBox.java | 2 +- .../bentobox/bentobox/api/addons/Addon.java | 1 - .../bentobox/bentobox/api/flags/Flag.java | 24 +++++------ .../bentobox/api/panels/TabbedPanel.java | 13 +----- .../bentobox/database/objects/Island.java | 1 - .../listeners/PanelListenerManager.java | 1 + .../bentobox/managers/IslandsManager.java | 8 ---- .../bentobox/managers/PlayersManager.java | 21 +++++----- .../bentobox/managers/island/IslandCache.java | 5 +++ .../bentobox/panels/settings/SettingsTab.java | 33 +++------------ .../settings/WorldDefaultSettingsTab.java | 1 - .../admin/AdminSettingsCommandTest.java | 10 ----- .../listeners/JoinLeaveListenerTest.java | 4 +- .../bentobox/managers/PlayersManagerTest.java | 40 +++++-------------- 14 files changed, 48 insertions(+), 116 deletions(-) diff --git a/src/main/java/world/bentobox/bentobox/BentoBox.java b/src/main/java/world/bentobox/bentobox/BentoBox.java index 567c2eceb..2f537cd84 100644 --- a/src/main/java/world/bentobox/bentobox/BentoBox.java +++ b/src/main/java/world/bentobox/bentobox/BentoBox.java @@ -419,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 32f656ac4..5b4b5c18f 100644 --- a/src/main/java/world/bentobox/bentobox/api/addons/Addon.java +++ b/src/main/java/world/bentobox/bentobox/api/addons/Addon.java @@ -224,7 +224,6 @@ public abstract class Addon { * @since 1.13.0 */ public void reloadConfig() { - BentoBox.getInstance().logDebug("Config reloaded"); config = loadYamlFile(); } 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 938d0dc6b..89b13cb09 100644 --- a/src/main/java/world/bentobox/bentobox/api/flags/Flag.java +++ b/src/main/java/world/bentobox/bentobox/api/flags/Flag.java @@ -384,29 +384,28 @@ public class Flag implements Comparable { */ @Nullable public PanelItem toPanelItem(BentoBox plugin, User user, World world, @Nullable Island island, boolean invisible) { - // TODO: Why is this taking long - long m = System.currentTimeMillis(); // Invisibility 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); - BentoBox.getInstance().logDebug("Time for pib = " + (System.currentTimeMillis() - m)); if (hasSubPanel()) { pib.description(user.getTranslation("protection.panel.flag-item.menu-layout", TextVariables.DESCRIPTION, user.getTranslation(getDescriptionReference()))); return pib.build(); } - BentoBox.getInstance().logDebug("Type = " + getType()); + 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) { @@ -432,16 +431,15 @@ public class Flag implements Comparable { } private PanelItemBuilder createProtectionFlag(BentoBox plugin, User user, Island island, PanelItemBuilder pib) { - long m = System.currentTimeMillis(); - BentoBox.getInstance().logDebug("Protection flag"); if (island != null) { int y = island.getFlag(this); - BentoBox.getInstance().logDebug("Protection flag getFlag time " + (System.currentTimeMillis() - m)); // Protection flag + pib.description(user.getTranslation("protection.panel.flag-item.description-layout", TextVariables.DESCRIPTION, user.getTranslation(getDescriptionReference()))); - BentoBox.getInstance().logDebug("Protection flag description time " + (System.currentTimeMillis() - m)); + RanksManager.getInstance().getRanks().forEach((reference, score) -> { + 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 > y) { @@ -451,7 +449,7 @@ public class Flag implements Comparable { } }); } - BentoBox.getInstance().logDebug("Protection flag time " + (System.currentTimeMillis() - m)); + return pib; } @@ -479,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. @@ -492,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 91abe4a0d..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,7 +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) { - long m = System.currentTimeMillis(); + 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); @@ -85,29 +85,23 @@ public class TabbedPanel extends Panel implements PanelListener { } this.activeTab = activeTab; this.activePage = page; - BentoBox.getInstance().logDebug("Time 1 " + (System.currentTimeMillis() - m)); // The items in the panel TreeMap items = new TreeMap<>(); // Get the tab Tab tab = tpb.getTabs().get(activeTab); - BentoBox.getInstance().logDebug("Time 2 " + (System.currentTimeMillis() - m)); // 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); - BentoBox.getInstance().logDebug("Time 3 " + (System.currentTimeMillis() - m)); // 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)); - BentoBox.getInstance().logDebug("Time 4 " + (System.currentTimeMillis() - m)); // set up the footer setupFooter(items); - BentoBox.getInstance().logDebug("Time 5 " + (System.currentTimeMillis() - m)); // Add forward and backward icons if (page > 0) { // Previous page icon @@ -117,7 +111,6 @@ public class TabbedPanel extends Panel implements PanelListener { return true; }).build()); } - BentoBox.getInstance().logDebug("Time 6 " + (System.currentTimeMillis() - m)); if ((page + 1) * ITEMS_PER_PAGE < panelItems.stream().filter(Objects::nonNull).count()) { // Next page icon items.put(52, new PanelItemBuilder().icon(Material.ARROW).name(tpb.getUser().getTranslation(PROTECTION_PANEL + "next")).clickHandler((panel, user1, clickType, slot1) -> { @@ -126,14 +119,11 @@ public class TabbedPanel extends Panel implements PanelListener { return true; }).build()); } - BentoBox.getInstance().logDebug("Time 7 " + (System.currentTimeMillis() - m)); } else { throw new InvalidParameterException("Unknown tab slot number " + activeTab); } - BentoBox.getInstance().logDebug("Time 8 " + (System.currentTimeMillis() - m)); // Show it to the player this.makePanel(tab.getName(), items, tpb.getSize(), tpb.getUser(), this); - BentoBox.getInstance().logDebug("Time 9 " + (System.currentTimeMillis() - m)); } /** @@ -189,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 fb8f7b0c8..2be8fa824 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/Island.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/Island.java @@ -1711,7 +1711,6 @@ public class Island implements DataObject, MetaDataAble { * Indicates the fields have been changed. Used to optimize saving on shutdown and notify other servers */ public void setChanged() { - BentoBox.getInstance().logDebug("Island changed"); this.setUpdatedDate(System.currentTimeMillis()); this.changed = true; IslandsManager.updateIsland(this); 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/managers/IslandsManager.java b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java index 5c9426bee..f1741721f 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java @@ -108,7 +108,6 @@ public class IslandsManager { // Listen for Island Updates MultiLib.onString(plugin, "bentobox-updateIsland", id -> { - BentoBox.getInstance().logDebug("Updating island " + id); Island island = handler.loadObject(id); if (island != null) { islandCache.updateIsland(island); @@ -117,13 +116,11 @@ public class IslandsManager { // Delete island blocks MultiLib.onString(plugin, "bentobox-deleteIsland", id -> { - BentoBox.getInstance().logDebug("Delete island blocks"); IslandDeletion idd = getGson().fromJson(id, IslandDeletion.class); plugin.getIslandDeletionManager().getIslandChunkDeletionManager().add(idd); }); // List for new islands MultiLib.onString(plugin, "bentobox-newIsland", id -> { - BentoBox.getInstance().logDebug("New island " + id); Island island = handler.loadObject(id); if (island != null) { islandCache.addIsland(island); @@ -139,7 +136,6 @@ public class IslandsManager { World world = Bukkit.getWorld(split[0]); if (world != null) { getIslandById(split[1]).ifPresent(i -> this.setSpawn(i)); - BentoBox.getInstance().logDebug("Setting spawn for world " + world); } } @@ -277,7 +273,6 @@ public class IslandsManager { * @param involvedPlayer - player related to the island deletion, if any */ public void deleteIsland(@NonNull Island island, boolean removeBlocks, @Nullable UUID involvedPlayer) { - BentoBox.getInstance().logDebug("Deleting island " + island.getUniqueId() + " remove blocks = " + removeBlocks); // Fire event IslandBaseEvent event = IslandEvent.builder().island(island).involvedPlayer(involvedPlayer) .reason(Reason.DELETE).build(); @@ -1641,14 +1636,11 @@ public class IslandsManager { * @param island - island */ public static void updateIsland(Island island) { - long m = System.currentTimeMillis(); - if (handler.objectExists(island.getUniqueId())) { island.clearChanged(); handler.saveObjectAsync(island) .thenAccept(b -> MultiLib.notify("bentobox-updateIsland", island.getUniqueId())); } - BentoBox.getInstance().logDebug("Island update " + (System.currentTimeMillis() - m)); } /** diff --git a/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java b/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java index b3303f738..0137c8ee5 100644 --- a/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/PlayersManager.java @@ -69,7 +69,6 @@ public class PlayersManager { public Players getPlayer(UUID uuid){ if (!playerCache.containsKey(uuid)) { playerCache.put(uuid, addPlayer(uuid)); - BentoBox.getInstance().logDebug("Not in cache"); } return playerCache.get(uuid); } @@ -138,7 +137,7 @@ public class PlayersManager { * @param user - the User */ public void setPlayerName(@NonNull User user) { - Players player = addPlayer(user.getUniqueId()); + Players player = getPlayer(user.getUniqueId()); player.setPlayerName(user.getName()); handler.saveObject(player); Names newName = new Names(user.getName(), user.getUniqueId()); @@ -169,7 +168,7 @@ public class PlayersManager { * @return number of resets */ public int getResets(World world, UUID playerUUID) { - return addPlayer(playerUUID).getResets(world); + return getPlayer(playerUUID).getResets(world); } /** @@ -181,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 { @@ -197,7 +196,7 @@ public class PlayersManager { * @param resets number of resets to set */ public void setResets(World world, UUID playerUUID, int resets) { - Players p = addPlayer(playerUUID); + Players p = getPlayer(playerUUID); p.setResets(world, resets); handler.saveObject(p); } @@ -208,7 +207,7 @@ public class PlayersManager { * @return name of the locale this player uses */ public String getLocale(UUID playerUUID) { - return addPlayer(playerUUID).getLocale(); + return getPlayer(playerUUID).getLocale(); } /** @@ -217,7 +216,7 @@ public class PlayersManager { * @param localeName - locale name, e.g., en-US */ public void setLocale(UUID playerUUID, String localeName) { - Players p = addPlayer(playerUUID); + Players p = getPlayer(playerUUID); p.setLocale(localeName); handler.saveObject(p); } @@ -228,7 +227,7 @@ public class PlayersManager { * @param playerUUID - the player's UUID */ public void addDeath(World world, UUID playerUUID) { - Players p = addPlayer(playerUUID); + Players p = getPlayer(playerUUID); p.addDeath(world); handler.saveObject(p); } @@ -240,7 +239,7 @@ public class PlayersManager { * @param deaths - number of deaths */ public void setDeaths(World world, UUID playerUUID, int deaths) { - Players p = addPlayer(playerUUID); + Players p = getPlayer(playerUUID); p.setDeaths(world, deaths); handler.saveObject(p); } @@ -252,7 +251,7 @@ public class PlayersManager { * @return number of deaths */ public int getDeaths(World world, UUID playerUUID) { - return addPlayer(playerUUID).getDeaths(world); + return getPlayer(playerUUID).getDeaths(world); } /** @@ -304,7 +303,7 @@ public class PlayersManager { * @param playerUUID player's UUID */ public void addReset(World world, UUID playerUUID) { - Players p = addPlayer(playerUUID); + Players p = getPlayer(playerUUID); p.addReset(world); handler.saveObject(p); } 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 954972afa..3846c1a21 100644 --- a/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java +++ b/src/main/java/world/bentobox/bentobox/managers/island/IslandCache.java @@ -96,6 +96,11 @@ public class IslandCache { } + /** + * 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."); 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 85486d6a1..0bf39d470 100644 --- a/src/main/java/world/bentobox/bentobox/panels/settings/SettingsTab.java +++ b/src/main/java/world/bentobox/bentobox/panels/settings/SettingsTab.java @@ -1,14 +1,10 @@ package world.bentobox.bentobox.panels.settings; -import java.util.ArrayList; -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; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.World; @@ -78,7 +74,8 @@ public class SettingsTab implements Tab, ClickHandler { * @return list of flags that will be shown in this panel */ protected List getFlags() { - long m = System.currentTimeMillis(); + return plugin.getFlagsManager().getFlags(); + /* // Get a list of flags of the correct type and sort by the translated names List flags = plugin.getFlagsManager().getFlags().stream().filter(f -> f.getType().equals(type)) // We're stripping colors to avoid weird sorting issues @@ -90,8 +87,7 @@ public class SettingsTab implements Tab, ClickHandler { 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))); - BentoBox.getInstance().logDebug("Time to get flags = " + (System.currentTimeMillis() - m)); - return flags; + return flags;*/ } /** @@ -123,8 +119,6 @@ public class SettingsTab implements Tab, ClickHandler { @Override @NonNull public List<@Nullable PanelItem> getPanelItems() { - - BentoBox.getInstance().logDebug("Get panel items"); List flags = getFlags(); int i = 0; // Jump past empty tabs @@ -132,25 +126,10 @@ public class SettingsTab implements Tab, ClickHandler { currentMode.put(user.getUniqueId(), currentMode.getOrDefault(user.getUniqueId(), Mode.BASIC).getNext()); flags = getFlags(); } - long m = System.currentTimeMillis(); - - // TODO This is taking too long!!! - - List<@Nullable PanelItem> result = new ArrayList<>(); - for (Flag f : flags) { - boolean x = plugin.getIWM().getHiddenFlags(world).contains(f.getID()); - //BentoBox.getInstance().logDebug("Time for x = " + (System.currentTimeMillis() - m)); - PanelItem pi = f.toPanelItem(plugin, user, world, island, x); - ///BentoBox.getInstance().logDebug("Time for pi = " + (System.currentTimeMillis() - m)); - result.add(pi); - } - /* List<@Nullable PanelItem> result = flags.stream().map( (f -> f.toPanelItem(plugin, user, world, island, plugin.getIWM().getHiddenFlags(world).contains(f.getID())))) .toList(); - */ - BentoBox.getInstance().logDebug("Time for getpanelitems end = " + (System.currentTimeMillis() - m)); return result; } @@ -162,6 +141,7 @@ 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 (currentMode.getOrDefault(user.getUniqueId(), Mode.BASIC)) { case ADVANCED -> icons.put(7, new PanelItemBuilder().icon(Material.GOLD_INGOT) @@ -186,7 +166,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")) @@ -240,7 +221,6 @@ public class SettingsTab implements Tab, ClickHandler { @Override public boolean onClick(Panel panel, User user, ClickType clickType, int slot) { - long m = System.currentTimeMillis(); // Cycle the mode currentMode.put(user.getUniqueId(), currentMode.getOrDefault(user.getUniqueId(), Mode.BASIC).getNext()); if (panel instanceof TabbedPanel tp) { @@ -248,7 +228,6 @@ public class SettingsTab implements Tab, ClickHandler { tp.refreshPanel(); user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_STONE_BUTTON_CLICK_OFF, 1F, 1F); } - BentoBox.getInstance().logDebug("Time for onClick = " + (System.currentTimeMillis() - m)); return true; } 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 752d9d9c3..d258eb9ab 100644 --- a/src/main/java/world/bentobox/bentobox/panels/settings/WorldDefaultSettingsTab.java +++ b/src/main/java/world/bentobox/bentobox/panels/settings/WorldDefaultSettingsTab.java @@ -70,7 +70,6 @@ public class WorldDefaultSettingsTab extends SettingsTab implements Tab { */ @Override public @NonNull List getPanelItems() { - BentoBox.getInstance().logDebug("Get world default settings"); // Different description and click handlers return getFlags().stream().map(f -> { PanelItem i = f.toPanelItem(plugin, user, world, island, false); 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 603522044..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 @@ -266,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/listeners/JoinLeaveListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java index f84a5ad3d..1bc40b1bc 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java @@ -237,7 +237,7 @@ public class JoinLeaveListenerTest { PlayerJoinEvent event = new PlayerJoinEvent(player, ""); jll.onPlayerJoin(event); // Verify - verify(pm, times(2)).addPlayer(any()); + verify(pm, times(2)).getPlayer(any()); verify(player, never()).sendMessage(anyString()); // Verify resets verify(pm).setResets(eq(world), any(), eq(0)); @@ -354,7 +354,7 @@ public class JoinLeaveListenerTest { PlayerJoinEvent event = new PlayerJoinEvent(player, ""); jll.onPlayerJoin(event); // Verify - verify(pm, times(2)).addPlayer(any()); + verify(pm, times(2)).getPlayer(any()); verify(player).sendMessage(eq("commands.island.create.on-first-login")); } diff --git a/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java index d89ed0379..3c6bcaa86 100644 --- a/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java @@ -278,16 +278,6 @@ public class PlayersManagerTest { assertEquals(deaths + 1, pm.getDeaths(world, uuid)); } - /** - * Test method for - * {@link world.bentobox.bentobox.managers.PlayersManager#addPlayer(java.util.UUID)}. - */ - @Test - public void testAddPlayer() { - pm.addPlayer(uuid); - assertTrue(pm.isKnown(uuid)); - } - /** * Test method for * {@link world.bentobox.bentobox.managers.PlayersManager#addReset(org.bukkit.World, java.util.UUID)}. @@ -443,7 +433,7 @@ public class PlayersManagerTest { public void testGetSetResetsLeft() throws InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException, NoSuchMethodException, IntrospectionException { // Add a player - pm.addPlayer(uuid); + pm.getPlayer(uuid); assertEquals(0, pm.getResets(world, uuid)); pm.setResets(world, uuid, 20); assertEquals(20, pm.getResets(world, uuid)); @@ -464,7 +454,7 @@ public class PlayersManagerTest { ClassNotFoundException, NoSuchMethodException, IntrospectionException { User user = pm.getUser("random"); assertNull(user); - pm.addPlayer(uuid); + pm.getPlayer(uuid); user = pm.getUser("tastybento"); assertEquals("tastybento", user.getName()); } @@ -485,7 +475,7 @@ public class PlayersManagerTest { */ @Test public void testGetUUID() { - pm.addPlayer(uuid); + pm.getPlayer(uuid); assertEquals(uuid, pm.getUUID("tastybento")); assertNull(pm.getUUID("unknown")); } @@ -498,7 +488,7 @@ public class PlayersManagerTest { public void testGetUUIDOfflinePlayer() { pm.setHandler(db); // Add a player to the cache - pm.addPlayer(uuid); + pm.getPlayer(uuid); UUID uuidResult = pm.getUUID("tastybento"); assertEquals(uuid, uuidResult); } @@ -511,7 +501,7 @@ public class PlayersManagerTest { public void testGetUUIDUnknownPlayer() { pm.setHandler(db); // Add a player to the cache - pm.addPlayer(uuid); + pm.getPlayer(uuid); // Unknown player should return null assertNull(pm.getUUID("tastybento123")); } @@ -541,8 +531,8 @@ public class PlayersManagerTest { @Test public void testIsKnown() { - pm.addPlayer(uuid); - pm.addPlayer(notUUID); + pm.getPlayer(uuid); + pm.getPlayer(notUUID); assertFalse(pm.isKnown(null)); assertTrue(pm.isKnown(uuid)); @@ -551,21 +541,11 @@ public class PlayersManagerTest { /** * Test method for - * {@link world.bentobox.bentobox.managers.PlayersManager#isSaveTaskRunning()}. + * {@link world.bentobox.bentobox.managers.PlayersManager#setHandler(Database)} */ @Test - public void testIsSaveTaskRunning() { - assertFalse(pm.isSaveTaskRunning()); - } - - /** - * Test method for - * {@link world.bentobox.bentobox.managers.PlayersManager#load()}. - */ - @Test - public void testLoad() { + public void testSetHandler() { pm.setHandler(db); - pm.load(); } /** @@ -608,7 +588,7 @@ public class PlayersManagerTest { public void testSetandGetPlayerName() { pm.setHandler(db); // Add a player - pm.addPlayer(uuid); + pm.getPlayer(uuid); assertEquals("tastybento", pm.getName(user.getUniqueId())); pm.setPlayerName(user); assertEquals(user.getName(), pm.getName(user.getUniqueId())); From 901295b0eaaa3a7fde77077ea94bb9e7e2eca43b Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 28 Apr 2024 08:13:01 -0700 Subject: [PATCH 18/19] Uncomment code after debug --- .../bentobox/bentobox/panels/settings/SettingsTab.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) 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 0bf39d470..43359ed2e 100644 --- a/src/main/java/world/bentobox/bentobox/panels/settings/SettingsTab.java +++ b/src/main/java/world/bentobox/bentobox/panels/settings/SettingsTab.java @@ -1,10 +1,13 @@ package world.bentobox.bentobox.panels.settings; +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; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.World; @@ -74,8 +77,6 @@ public class SettingsTab implements Tab, ClickHandler { * @return list of flags that will be shown in this panel */ protected List getFlags() { - return plugin.getFlagsManager().getFlags(); - /* // Get a list of flags of the correct type and sort by the translated names List flags = plugin.getFlagsManager().getFlags().stream().filter(f -> f.getType().equals(type)) // We're stripping colors to avoid weird sorting issues @@ -87,7 +88,7 @@ public class SettingsTab implements Tab, ClickHandler { 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;*/ + return flags; } /** From 64ccfaa37ff46d9e0085f61f0110001014b6d6cb Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 28 Apr 2024 09:20:53 -0700 Subject: [PATCH 19/19] Fix tests --- .../commands/admin/AdminSettingsCommand.java | 7 +++-- .../island/IslandSettingsCommand.java | 3 ++- .../bentobox/panels/settings/SettingsTab.java | 26 +++++++++++-------- .../api/addons/AddonClassLoaderTest.java | 6 ++++- .../bentobox/api/addons/AddonTest.java | 6 ++++- .../team/IslandTeamSetownerCommandTest.java | 4 --- .../listeners/JoinLeaveListenerTest.java | 6 ++--- .../bentobox/managers/AddonsManagerTest.java | 6 ++++- .../managers/BlueprintsManagerTest.java | 10 ++++--- .../bentobox/managers/PlayersManagerTest.java | 1 - 10 files changed, 44 insertions(+), 31 deletions(-) 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 f3192369b..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; @@ -228,7 +227,7 @@ public class AdminSettingsCommand extends CompositeCommand { 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) @@ -239,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/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/panels/settings/SettingsTab.java b/src/main/java/world/bentobox/bentobox/panels/settings/SettingsTab.java index 43359ed2e..b558cc9d4 100644 --- a/src/main/java/world/bentobox/bentobox/panels/settings/SettingsTab.java +++ b/src/main/java/world/bentobox/bentobox/panels/settings/SettingsTab.java @@ -50,17 +50,6 @@ public class SettingsTab implements Tab, ClickHandler { private Map currentMode = new HashMap<>(); - /** - * 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. - } - /** * Show a tab of settings * @param world - world @@ -73,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 */ 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/island/team/IslandTeamSetownerCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamSetownerCommandTest.java index a7dcb0aae..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 @@ -278,8 +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)); - PowerMockito.verifyStatic(IslandsManager.class); - IslandsManager.updateIsland(island); } /** @@ -295,8 +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)); - PowerMockito.verifyStatic(IslandsManager.class); - IslandsManager.updateIsland(island); } /** diff --git a/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java index 1bc40b1bc..d60092f74 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/JoinLeaveListenerTest.java @@ -220,8 +220,6 @@ public class JoinLeaveListenerTest { jll = new JoinLeaveListener(plugin); } - /** - */ @After public void tearDown() { User.clearUsers(); @@ -237,7 +235,7 @@ public class JoinLeaveListenerTest { PlayerJoinEvent event = new PlayerJoinEvent(player, ""); jll.onPlayerJoin(event); // Verify - verify(pm, times(2)).getPlayer(any()); + verify(pm, times(3)).getPlayer(any()); verify(player, never()).sendMessage(anyString()); // Verify resets verify(pm).setResets(eq(world), any(), eq(0)); @@ -354,7 +352,7 @@ public class JoinLeaveListenerTest { PlayerJoinEvent event = new PlayerJoinEvent(player, ""); jll.onPlayerJoin(event); // Verify - verify(pm, times(2)).getPlayer(any()); + verify(pm, times(3)).getPlayer(any()); verify(player).sendMessage(eq("commands.island.create.on-first-login")); } 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/PlayersManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java index 3c6bcaa86..8037ad671 100644 --- a/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/PlayersManagerTest.java @@ -55,7 +55,6 @@ 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;