diff --git a/pom.xml b/pom.xml index 3b5372fd0..ce7f409d7 100644 --- a/pom.xml +++ b/pom.xml @@ -217,7 +217,7 @@ 3.11.1 test - + org.spigotmc spigot-api diff --git a/src/main/java/world/bentobox/bentobox/BentoBox.java b/src/main/java/world/bentobox/bentobox/BentoBox.java index 70140b94d..1ee3cfb1e 100644 --- a/src/main/java/world/bentobox/bentobox/BentoBox.java +++ b/src/main/java/world/bentobox/bentobox/BentoBox.java @@ -73,7 +73,6 @@ public class BentoBox extends JavaPlugin implements Listener { private AddonsManager addonsManager; private FlagsManager flagsManager; private IslandWorldManager islandWorldManager; - private RanksManager ranksManager; private BlueprintsManager blueprintsManager; private HooksManager hooksManager; private PlaceholdersManager placeholdersManager; @@ -141,7 +140,6 @@ public class BentoBox extends JavaPlugin implements Listener { return; } islandsManager = new IslandsManager(this); - ranksManager = new RanksManager(); // Start head getter headGetter = new HeadGetter(this); @@ -429,9 +427,11 @@ public class BentoBox extends JavaPlugin implements Listener { /** * @return the ranksManager + * @deprecated Just use {@code RanksManager.getInstance()} */ + @Deprecated(since = "2.0.0") public RanksManager getRanksManager() { - return ranksManager; + return RanksManager.getInstance(); } /** @@ -466,6 +466,7 @@ public class BentoBox extends JavaPlugin implements Listener { return false; } + log("Saving default panels..."); if (!Files.exists(Path.of(this.getDataFolder().getPath(), "panels", "island_creation_panel.yml"))) { log("Saving default island_creation_panel..."); this.saveResource("panels/island_creation_panel.yml", false); @@ -475,7 +476,6 @@ public class BentoBox extends JavaPlugin implements Listener { log("Saving default language_panel..."); this.saveResource("panels/language_panel.yml", false); } - return true; } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminGetrankCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminGetrankCommand.java index 1c9b10b2e..e6bb28905 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminGetrankCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminGetrankCommand.java @@ -83,10 +83,10 @@ public class AdminGetrankCommand extends CompositeCommand { @Override public boolean execute(User user, String label, List args) { // Get rank - RanksManager rm = getPlugin().getRanksManager(); User target = User.getInstance(targetUUID); int currentRank = island.getRank(target); - user.sendMessage("commands.admin.getrank.rank-is", TextVariables.RANK, user.getTranslation(rm.getRank(currentRank)), + user.sendMessage("commands.admin.getrank.rank-is", TextVariables.RANK, + user.getTranslation(RanksManager.getInstance().getRank(currentRank)), TextVariables.NAME, getPlayers().getName(island.getOwner())); return true; } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSetrankCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSetrankCommand.java index d0ff2d416..71f5cde6b 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSetrankCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSetrankCommand.java @@ -24,7 +24,6 @@ public class AdminSetrankCommand extends CompositeCommand { private int rankValue; private @Nullable UUID targetUUID; private @Nullable UUID ownerUUID; - private RanksManager rm; public AdminSetrankCommand(CompositeCommand adminCommand) { super(adminCommand, "setrank"); @@ -36,7 +35,6 @@ public class AdminSetrankCommand extends CompositeCommand { setOnlyPlayer(false); setParametersHelp("commands.admin.setrank.parameters"); setDescription("commands.admin.setrank.description"); - rm = getPlugin().getRanksManager(); } @Override @@ -53,7 +51,7 @@ public class AdminSetrankCommand extends CompositeCommand { return false; } // Get rank - rankValue = rm.getRanks().entrySet().stream() + rankValue = RanksManager.getInstance().getRanks().entrySet().stream() .filter(r -> user.getTranslation(r.getKey()).equalsIgnoreCase(args.get(1))).findFirst() .map(Map.Entry::getValue).orElse(-999); if (rankValue < RanksManager.BANNED_RANK) { @@ -121,8 +119,8 @@ public class AdminSetrankCommand extends CompositeCommand { ownerName = target.getName(); } user.sendMessage("commands.admin.setrank.rank-set", - "[from]", user.getTranslation(rm.getRank(currentRank)), - "[to]", user.getTranslation(rm.getRank(rankValue)), + "[from]", user.getTranslation(RanksManager.getInstance().getRank(currentRank)), "[to]", + user.getTranslation(RanksManager.getInstance().getRank(rankValue)), TextVariables.NAME, ownerName); return true; } @@ -136,7 +134,7 @@ public class AdminSetrankCommand extends CompositeCommand { // Return the ranks if (args.size() == 3) { - return Optional.of(getPlugin().getRanksManager().getRanks() + return Optional.of(RanksManager.getInstance().getRanks() .entrySet().stream() .filter(entry -> entry.getValue() > RanksManager.VISITOR_RANK) .map(entry -> user.getTranslation(entry.getKey())).toList()); 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 80dbc9d0a..177d85657 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 @@ -175,7 +175,7 @@ public class AdminSettingsCommand extends CompositeCommand { * @return true if rank is valid */ private boolean checkRank(User user, String string) { - for (Entry en : getPlugin().getRanksManager().getRanks().entrySet()) { + for (Entry en : RanksManager.getInstance().getRanks().entrySet()) { if (en.getValue() > RanksManager.BANNED_RANK && en.getValue() <= RanksManager.OWNER_RANK && string.equalsIgnoreCase(ChatColor.stripColor(user.getTranslation(en.getKey())))) { // We have a winner @@ -277,8 +277,7 @@ public class AdminSettingsCommand extends CompositeCommand { } else if (args.size() == 4) { // Get flag in previous argument options = getPlugin().getFlagsManager().getFlag(args.get(2).toUpperCase(Locale.ENGLISH)).map(f -> switch (f.getType()) { - case PROTECTION -> getPlugin().getRanksManager() - .getRanks().entrySet().stream() + case PROTECTION -> RanksManager.getInstance().getRanks().entrySet().stream() .filter(en -> en.getValue() > RanksManager.BANNED_RANK && en.getValue() <= RanksManager.OWNER_RANK) .map(Entry::getKey) .map(user::getTranslation).toList(); diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommand.java index bb98b9ab4..74dfe764e 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminTeleportCommand.java @@ -118,12 +118,10 @@ public class AdminTeleportCommand extends CompositeCommand { private Location getSpot(World world) { Island island = getIslands().getIsland(world, targetUUID); - if (island != null && island.getSpawnPoint(world.getEnvironment()) != null) { - // Return the defined spawn point - return island.getSpawnPoint(world.getEnvironment()); + if (island == null) { + return null; } - // Return the default island protection center - return island.getProtectionCenter().toVector().toLocation(world); + return island.getSpawnPoint(world.getEnvironment()) != null ? island.getSpawnPoint(world.getEnvironment()) : island.getProtectionCenter().toVector().toLocation(world); } @Override diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandBanCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandBanCommand.java index 8e0465673..403eecc88 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandBanCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandBanCommand.java @@ -17,6 +17,7 @@ import world.bentobox.bentobox.api.events.island.IslandEvent; 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.RanksManager; import world.bentobox.bentobox.util.Util; public class IslandBanCommand extends CompositeCommand { @@ -55,7 +56,7 @@ public class IslandBanCommand extends CompositeCommand { int rank = island.getRank(user); if (rank < island.getRankCommand(getUsage())) { user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, - user.getTranslation(getPlugin().getRanksManager().getRank(rank))); + user.getTranslation(RanksManager.getInstance().getRank(rank))); return false; } // Get target player diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandBanlistCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandBanlistCommand.java index 7d19f5c81..754c345bf 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandBanlistCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandBanlistCommand.java @@ -8,6 +8,7 @@ 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.managers.RanksManager; public class IslandBanlistCommand extends CompositeCommand { @@ -40,7 +41,8 @@ public class IslandBanlistCommand extends CompositeCommand { island = getIslands().getIsland(getWorld(), user.getUniqueId()); int rank = Objects.requireNonNull(island).getRank(user); if (rank < island.getRankCommand(getUsage())) { - user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, user.getTranslation(getPlugin().getRanksManager().getRank(rank))); + user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, + user.getTranslation(RanksManager.getInstance().getRank(rank))); return false; } return true; diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandDeletehomeCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandDeletehomeCommand.java index d2b1ccd15..d11947399 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandDeletehomeCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandDeletehomeCommand.java @@ -57,7 +57,7 @@ public class IslandDeletehomeCommand extends ConfirmableCommand { int rank = Objects.requireNonNull(island).getRank(user); if (rank < island.getRankCommand(getUsage())) { user.sendMessage("general.errors.insufficient-rank", - TextVariables.RANK, user.getTranslation(getPlugin().getRanksManager().getRank(rank))); + TextVariables.RANK, user.getTranslation(RanksManager.getInstance().getRank(rank))); return false; } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandExpelCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandExpelCommand.java index d8759a987..6d9de5fc4 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandExpelCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandExpelCommand.java @@ -16,6 +16,7 @@ import world.bentobox.bentobox.api.events.island.IslandEvent; 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.RanksManager; import world.bentobox.bentobox.util.Util; /** @@ -60,7 +61,7 @@ public class IslandExpelCommand extends CompositeCommand { int rank = Objects.requireNonNull(island).getRank(user); if (rank < island.getRankCommand(getUsage())) { user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, - user.getTranslation(getPlugin().getRanksManager().getRank(rank))); + user.getTranslation(RanksManager.getInstance().getRank(rank))); return false; } // Get target player diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandRenamehomeCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandRenamehomeCommand.java index 591fbbafb..80a06fc30 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandRenamehomeCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandRenamehomeCommand.java @@ -65,7 +65,8 @@ public class IslandRenamehomeCommand extends ConfirmableCommand { // check command permission int rank = Objects.requireNonNull(island).getRank(user); if (rank < island.getRankCommand(getUsage())) { - user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, user.getTranslation(getPlugin().getRanksManager().getRank(rank))); + user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, + user.getTranslation(RanksManager.getInstance().getRank(rank))); return false; } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandResetnameCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandResetnameCommand.java index 063553214..d797ed458 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandResetnameCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandResetnameCommand.java @@ -7,6 +7,7 @@ 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.managers.RanksManager; /** @@ -41,7 +42,7 @@ public class IslandResetnameCommand extends CompositeCommand { int rank = Objects.requireNonNull(island).getRank(user); if (rank < island.getRankCommand(getUsage())) { user.sendMessage("general.errors.insufficient-rank", - TextVariables.RANK, user.getTranslation(getPlugin().getRanksManager().getRank(rank))); + TextVariables.RANK, user.getTranslation(RanksManager.getInstance().getRank(rank))); return false; } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandSethomeCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandSethomeCommand.java index 7b50b3c52..9ccde2194 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandSethomeCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandSethomeCommand.java @@ -46,7 +46,8 @@ public class IslandSethomeCommand extends ConfirmableCommand { int rank = Objects.requireNonNull(island).getRank(user); if (rank < island.getRankCommand(getUsage())) { - user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, user.getTranslation(getPlugin().getRanksManager().getRank(rank))); + user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, + user.getTranslation(RanksManager.getInstance().getRank(rank))); return false; } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandSetnameCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandSetnameCommand.java index f8b66f38e..d0582e787 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandSetnameCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandSetnameCommand.java @@ -10,6 +10,7 @@ import world.bentobox.bentobox.api.events.island.IslandEvent; 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.RanksManager; /** @@ -51,7 +52,8 @@ public class IslandSetnameCommand extends CompositeCommand { // Check command rank. int rank = Objects.requireNonNull(island).getRank(user); if (rank < island.getRankCommand(getUsage())) { - user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, user.getTranslation(getPlugin().getRanksManager().getRank(rank))); + user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, + user.getTranslation(RanksManager.getInstance().getRank(rank))); return false; } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandUnbanCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandUnbanCommand.java index 041636e0f..dfaab3dd4 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandUnbanCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandUnbanCommand.java @@ -13,6 +13,7 @@ import world.bentobox.bentobox.api.events.island.IslandEvent; 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.RanksManager; import world.bentobox.bentobox.util.Util; /** @@ -54,7 +55,8 @@ public class IslandUnbanCommand extends CompositeCommand { Island island = getIslands().getIsland(getWorld(), user); int rank = Objects.requireNonNull(island).getRank(user); if (rank < island.getRankCommand(getUsage())) { - user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, user.getTranslation(getPlugin().getRanksManager().getRank(rank))); + user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, + user.getTranslation(RanksManager.getInstance().getRank(rank))); return false; } // Get target player diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/InviteNamePrompt.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/InviteNamePrompt.java new file mode 100644 index 000000000..d9fde3cda --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/InviteNamePrompt.java @@ -0,0 +1,53 @@ +package world.bentobox.bentobox.api.commands.island.team; + +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.conversations.ConversationContext; +import org.bukkit.conversations.Prompt; +import org.bukkit.conversations.StringPrompt; +import org.eclipse.jdt.annotation.NonNull; + +import world.bentobox.bentobox.BentoBox; +import world.bentobox.bentobox.api.user.User; + +/** + * Invites a player by search + * @author tastybento + * + */ +public class InviteNamePrompt extends StringPrompt { + + @NonNull + private final User user; + @NonNull + private final IslandTeamInviteCommand itic; + + public InviteNamePrompt(@NonNull User user, IslandTeamInviteCommand islandTeamInviteCommand) { + this.user = user; + this.itic = islandTeamInviteCommand; + } + + @Override + @NonNull + public String getPromptText(@NonNull ConversationContext context) { + return user.getTranslation("commands.island.team.invite.gui.enter-name"); + } + + @Override + public Prompt acceptInput(@NonNull ConversationContext context, String input) { + // TODO remove this and pass the options back to the GUI + if (itic.canExecute(user, itic.getLabel(), List.of(input))) { + if (itic.execute(user, itic.getLabel(), List.of(input))) { + return Prompt.END_OF_CONVERSATION; + } + } + // Set the search item to what was entered + itic.setSearchName(input); + // Return to the GUI but give a second for the error to show + // TODO: return the failed input and display the options in the GUI. + Bukkit.getScheduler().runTaskLater(BentoBox.getInstance(), () -> itic.build(user), 20L); + return Prompt.END_OF_CONVERSATION; + } + +} 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 b8a12affe..90120ba68 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,15 +1,24 @@ package world.bentobox.bentobox.api.commands.island.team; +import java.io.File; import java.time.Duration; import java.time.Instant; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; +import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.UUID; import org.bukkit.Bukkit; +import org.bukkit.Material; import org.bukkit.OfflinePlayer; +import org.bukkit.Sound; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; @@ -17,6 +26,15 @@ import world.bentobox.bentobox.api.commands.CompositeCommand; 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.Panel; +import world.bentobox.bentobox.api.panels.PanelItem; +import world.bentobox.bentobox.api.panels.TemplatedPanel; +import world.bentobox.bentobox.api.panels.TemplatedPanel.ItemSlot; +import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; +import world.bentobox.bentobox.api.panels.builders.TemplatedPanelBuilder; +import world.bentobox.bentobox.api.panels.reader.ItemTemplateRecord; +import world.bentobox.bentobox.api.panels.reader.ItemTemplateRecord.ActionRecords; +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.managers.RanksManager; @@ -24,12 +42,48 @@ import world.bentobox.bentobox.util.Util; public class IslandTeamCommand extends CompositeCommand { + /** + * List of ranks that we will loop through in order + */ + private static final List RANKS = List.of(RanksManager.OWNER_RANK, RanksManager.SUB_OWNER_RANK, + RanksManager.MEMBER_RANK, RanksManager.TRUSTED_RANK, RanksManager.COOP_RANK); + /** * Invited list. Key is the invited party, value is the invite. * @since 1.8.0 */ private final Map inviteMap; + private User user; + + private Island island; + + private int rank = RanksManager.OWNER_RANK; + + private IslandTeamKickCommand kickCommand; + + private IslandTeamLeaveCommand leaveCommand; + + private IslandTeamSetownerCommand setOwnerCommand; + + private IslandTeamUncoopCommand uncoopCommand; + + private IslandTeamUntrustCommand unTrustCommand; + + private @Nullable TemplateItem border; + + private @Nullable TemplateItem background; + + private IslandTeamInviteAcceptCommand acceptCommand; + + private IslandTeamInviteRejectCommand rejectCommand; + + private IslandTeamInviteCommand inviteCommand; + + private IslandTeamCoopCommand coopCommand; + + private IslandTeamTrustCommand trustCommand; + public IslandTeamCommand(CompositeCommand parent) { super(parent, "team"); inviteMap = new HashMap<>(); @@ -41,29 +95,40 @@ public class IslandTeamCommand extends CompositeCommand { setOnlyPlayer(true); setDescription("commands.island.team.description"); // Register commands - new IslandTeamInviteCommand(this); - new IslandTeamLeaveCommand(this); - new IslandTeamSetownerCommand(this); - new IslandTeamKickCommand(this); - new IslandTeamInviteAcceptCommand(this); - new IslandTeamInviteRejectCommand(this); - if (getPlugin().getRanksManager().rankExists(RanksManager.COOP_RANK_REF)) { - new IslandTeamCoopCommand(this); - new IslandTeamUncoopCommand(this); + inviteCommand = new IslandTeamInviteCommand(this); + leaveCommand = new IslandTeamLeaveCommand(this); + setOwnerCommand = new IslandTeamSetownerCommand(this); + kickCommand = new IslandTeamKickCommand(this); + acceptCommand = new IslandTeamInviteAcceptCommand(this); + rejectCommand = new IslandTeamInviteRejectCommand(this); + if (RanksManager.getInstance().rankExists(RanksManager.COOP_RANK_REF)) { + coopCommand = new IslandTeamCoopCommand(this); + uncoopCommand = new IslandTeamUncoopCommand(this); } - if (getPlugin().getRanksManager().rankExists(RanksManager.TRUSTED_RANK_REF)) { - new IslandTeamTrustCommand(this); - new IslandTeamUntrustCommand(this); + if (RanksManager.getInstance().rankExists(RanksManager.TRUSTED_RANK_REF)) { + trustCommand = new IslandTeamTrustCommand(this); + unTrustCommand = new IslandTeamUntrustCommand(this); } new IslandTeamPromoteCommand(this, "promote"); new IslandTeamPromoteCommand(this, "demote"); + + // Panels + if (!new File(getPlugin().getDataFolder() + File.separator + "panels", "team_panel.yml").exists()) { + getPlugin().saveResource("panels/team_panel.yml", false); + } } @Override - public boolean execute(User user, String label, List args) { + public boolean canExecute(User user, String label, List args) { + this.user = user; // Player issuing the command must have an island - Island island = getIslands().getPrimaryIsland(getWorld(), user.getUniqueId()); + island = getIslands().getPrimaryIsland(getWorld(), user.getUniqueId()); if (island == null) { + if (isInvited(user.getUniqueId())) { + // Player has an invite, so show the invite + build(); + return true; + } user.sendMessage("general.errors.no-island"); return false; } @@ -84,86 +149,499 @@ public class IslandTeamCommand extends CompositeCommand { user.sendMessage("commands.island.team.invite.errors.island-is-full"); } } - // Show members of island - showMembers(island, user); return true; } - private void showMembers(Island island, User user) { + @Override + public boolean execute(User user, String label, List args) { + // Show the panel + build(); + return true; + } + + /** + * This method builds this GUI. + */ + void build() { + // Start building panel. + TemplatedPanelBuilder panelBuilder = new TemplatedPanelBuilder(); + panelBuilder.user(user); + panelBuilder.world(user.getWorld()); + + panelBuilder.template("team_panel", new File(getPlugin().getDataFolder(), "panels")); + + panelBuilder.parameters("[name]", user.getName(), "[display_name]", user.getDisplayName()); + + panelBuilder.registerTypeBuilder("STATUS", this::createStatusButton); + panelBuilder.registerTypeBuilder("MEMBER", this::createMemberButton); + panelBuilder.registerTypeBuilder("INVITED", this::createInvitedButton); + panelBuilder.registerTypeBuilder("RANK", this::createRankButton); + panelBuilder.registerTypeBuilder("INVITE", this::createInviteButton); + border = panelBuilder.getPanelTemplate().border(); + background = panelBuilder.getPanelTemplate().background(); + // Register unknown type builder. + panelBuilder.build(); + } + + private PanelItem createInviteButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot) { + if (island == null || !user.hasPermission(this.inviteCommand.getPermission()) + || island.getRank(user) < island.getRankCommand(this.getLabel() + " invite")) { + return this.getBlankBorder(); + } + PanelItemBuilder builder = new PanelItemBuilder(); + builder.icon(Material.PLAYER_HEAD); + builder.name(user.getTranslation("commands.island.team.gui.buttons.invite.name")); + builder.description(user.getTranslation("commands.island.team.gui.buttons.invite.description")); + builder.clickHandler((panel, user, clickType, clickSlot) -> { + if (clickType.equals(ClickType.LEFT)) { + user.closeInventory(); + this.inviteCommand.build(user); + } + return true; + }); + return builder.build(); + } + + private PanelItem createRankButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot) { + // If there is no island, the do not show this icon + if (island == null) { + return this.getBlankBorder(); + } + PanelItemBuilder builder = new PanelItemBuilder(); + builder.name(user.getTranslation("commands.island.team.gui.buttons.rank-filter.name")); + builder.icon(Material.AMETHYST_SHARD); + // Create description + RanksManager.getInstance().getRanks().forEach((reference, score) -> { + if (rank == RanksManager.OWNER_RANK && score > RanksManager.VISITOR_RANK + && score <= RanksManager.OWNER_RANK) { + builder.description(user.getTranslation("protection.panel.flag-item.allowed-rank") + + user.getTranslation(reference)); + } else if (score > RanksManager.VISITOR_RANK && score < rank) { + builder.description(user.getTranslation("protection.panel.flag-item.blocked-rank") + + user.getTranslation(reference)); + } else if (score <= RanksManager.OWNER_RANK && score > rank) { + builder.description(user.getTranslation("protection.panel.flag-item.blocked-rank") + + user.getTranslation(reference)); + } else if (score == rank) { + builder.description(user.getTranslation("protection.panel.flag-item.allowed-rank") + + user.getTranslation(reference)); + } + }); + builder.description(user.getTranslation("commands.island.team.gui.buttons.rank-filter.description")); + builder.clickHandler((panel, user, clickType, clickSlot) -> { + if (clickType.equals(ClickType.LEFT)) { + rank = RanksManager.getInstance().getRankDownValue(rank); + if (rank <= RanksManager.VISITOR_RANK) { + rank = RanksManager.OWNER_RANK; + user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F); + } else { + user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1F, 1F); + } + } + if (clickType.equals(ClickType.RIGHT)) { + rank = RanksManager.getInstance().getRankUpValue(rank); + if (rank >= RanksManager.OWNER_RANK) { + rank = RanksManager.getInstance().getRankUpValue(RanksManager.VISITOR_RANK); + user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F); + } else { + user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1F, 1F); + } + } + + // Update panel after click + build(); + return true; + }); + + return builder.build(); + } + + /** + * Create invited button panel item. + * + * @param template the template + * @param slot the slot + * @return the panel item + */ + private PanelItem createInvitedButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot) { + PanelItemBuilder builder = new PanelItemBuilder(); + if (isInvited(user.getUniqueId()) && user.hasPermission(this.acceptCommand.getPermission())) { + Invite invite = getInvite(user.getUniqueId()); + User inviter = User.getInstance(invite.getInviter()); + String name = inviter.getName(); + builder.icon(inviter.getName()); + builder.name(user.getTranslation("commands.island.team.gui.buttons.invitation")); + builder.description(switch (invite.getType()) { + case COOP -> + List.of(user.getTranslation("commands.island.team.invite.name-has-invited-you.coop", TextVariables.NAME, + name)); + case TRUST -> + List.of(user.getTranslation("commands.island.team.invite.name-has-invited-you.trust", + TextVariables.NAME, name)); + default -> + List.of(user.getTranslation("commands.island.team.invite.name-has-invited-you", TextVariables.NAME, + name), user.getTranslation("commands.island.team.invite.accept.confirmation")); + }); + // Add all the tool tips + builder.description(template.actions().stream() + .map(ar -> user.getTranslation("commands.island.team.gui.tips." + ar.clickType().name() + ".name") + + " " + + user.getTranslation(ar.tooltip())) + .toList()); + builder.clickHandler((panel, user, clickType, clickSlot) -> { + if (clickType.equals(ClickType.SHIFT_LEFT) && user.hasPermission(this.acceptCommand.getPermission())) { + getPlugin().log("Invite accepted: " + user.getName() + " accepted " + invite.getType() + + " invite to island at " + island.getCenter()); + // Accept + switch (invite.getType()) { + case COOP -> this.acceptCommand.acceptCoopInvite(user, invite); + case TRUST -> this.acceptCommand.acceptTrustInvite(user, invite); + default -> this.acceptCommand.acceptTeamInvite(user, invite); + } + user.closeInventory(); + } + if (clickType.equals(ClickType.SHIFT_RIGHT) && user.hasPermission(this.rejectCommand.getPermission())) { + // Reject + getPlugin().log("Invite rejected: " + user.getName() + " rejected " + invite.getType() + + " invite."); + this.rejectCommand.execute(user, "", List.of()); + user.closeInventory(); + } + return true; + }); + } else { + return this.getBlankBorder(); + } + return builder.build(); + } + + /** + * Create status button panel item. + * + * @param template the template + * @param slot the slot + * @return the panel item + */ + private PanelItem createStatusButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot) { + PanelItemBuilder builder = new PanelItemBuilder(); + // Player issuing the command must have an island + Island island = getIslands().getPrimaryIsland(getWorld(), user.getUniqueId()); + if (island == null) { + return getBlankBorder(); + } + + return builder.icon(user.getName()).name(user.getTranslation("commands.island.team.gui.buttons.status.name")) + .description(showMembers()).build(); + } + + private PanelItem getBlankBorder() { + return new PanelItemBuilder().icon(Objects.requireNonNullElse(border.icon(), new ItemStack(Material.BARRIER))) + .name((Objects.requireNonNullElse(border.title(), ""))).build(); + } + + private PanelItem getBlankBackground() { + return new PanelItemBuilder() + .icon(Objects.requireNonNullElse(background.icon(), new ItemStack(Material.BARRIER))) + .name((Objects.requireNonNullElse(background.title(), ""))).build(); + } + + /** + * Create member button panel item. + * + * @param template the template + * @param slot the slot + * @return the panel item + */ + private PanelItem createMemberButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot) { + // Player issuing the command must have an island + Island island = getIslands().getPrimaryIsland(getWorld(), user.getUniqueId()); + if (island == null) { + return this.getBlankBackground(); + } + return switch (rank) { + case RanksManager.OWNER_RANK -> ownerView(template, slot); + default -> getMemberButton(rank, slot.slot(), template.actions()); + }; + } + + /** + * The owner view shows all the ranks, in order + * @param template template reference + * @param slot slot to show + * @return panel item + */ + private PanelItem ownerView(ItemTemplateRecord template, ItemSlot slot) { + if (slot.slot() == 0 && island.getOwner() != null) { + // Owner + PanelItem item = getMemberButton(RanksManager.OWNER_RANK, 1, template.actions()); + if (item != null) { + return item; + } + } + long subOwnerCount = island.getMemberSet(RanksManager.SUB_OWNER_RANK, false).stream().count(); + long memberCount = island.getMemberSet(RanksManager.MEMBER_RANK, false).stream().count(); + long coopCount = island.getMemberSet(RanksManager.COOP_RANK, false).stream().count(); + long trustedCount = island.getMemberSet(RanksManager.TRUSTED_RANK, false).stream().count(); + + if (slot.slot() > 0 && slot.slot() < subOwnerCount + 1) { + // Show sub owners + PanelItem item = getMemberButton(RanksManager.SUB_OWNER_RANK, slot.slot(), template.actions()); + if (item != null) { + return item; + } + + } + if (slot.slot() > subOwnerCount && slot.slot() < subOwnerCount + memberCount + 1) { + // Show members + PanelItem item = getMemberButton(RanksManager.MEMBER_RANK, slot.slot(), template.actions()); + if (item != null) { + return item; + } + } + if (slot.slot() > subOwnerCount + memberCount && slot.slot() < subOwnerCount + memberCount + trustedCount + 1) { + // Show trusted + PanelItem item = getMemberButton(RanksManager.TRUSTED_RANK, slot.slot(), template.actions()); + if (item != null) { + return item; + } + + } + if (slot.slot() > subOwnerCount + memberCount + trustedCount + && slot.slot() < subOwnerCount + memberCount + trustedCount + coopCount + 1) { + // Show coops + return getMemberButton(RanksManager.COOP_RANK, slot.slot(), template.actions()); + } + return this.getBlankBackground(); + + } + + /** + * Shows a member's head. The clicks available will depend on who is viewing. + * @param targetRank - the rank to show + * @param slot - the slot number + * @param actions - actions that need to apply to this member button as provided by the template + * @return panel item + */ + private PanelItem getMemberButton(int targetRank, int slot, List actions) { + if (slot == 0 && island.getOwner() != null) { + // Owner + return getMemberButton(RanksManager.OWNER_RANK, 1, actions); + } + String ref = RanksManager.getInstance().getRank(targetRank); + Optional opMember = island.getMemberSet(targetRank, false).stream().sorted().skip(slot - 1L).limit(1L) + .map(User::getInstance).findFirst(); + if (opMember.isEmpty()) { + return this.getBlankBackground(); + } + User member = opMember.get(); + // Make button description depending on viewer + List desc = new ArrayList<>(); + int userRank = Objects.requireNonNull(island).getRank(user); + // Add the tooltip for kicking + if (user.hasPermission(this.kickCommand.getPermission()) + && userRank >= island.getRankCommand(this.getLabel() + " kick") && !user.equals(member)) { + actions.stream().filter(ar -> ar.actionType().equalsIgnoreCase("kick")) + .map(ar -> user.getTranslation("commands.island.team.gui.tips." + ar.clickType().name() + ".name") + + " " + user.getTranslation(ar.tooltip())) + .findFirst().ifPresent(desc::add); + } + // Set Owner + if (user.hasPermission(this.setOwnerCommand.getPermission()) && !user.equals(member) + && userRank >= RanksManager.OWNER_RANK && targetRank >= RanksManager.MEMBER_RANK) { + // Add the tooltip for setowner + actions.stream().filter(ar -> ar.actionType().equalsIgnoreCase("setowner")) + .map(ar -> user.getTranslation("commands.island.team.gui.tips." + ar.clickType().name() + ".name") + + " " + user.getTranslation(ar.tooltip())) + .findFirst().ifPresent(desc::add); + } + // Leave + if (user.hasPermission(this.leaveCommand.getPermission()) && user.equals(member) + && userRank < RanksManager.OWNER_RANK) { + // Add the tooltip for leave + actions.stream().filter(ar -> ar.actionType().equalsIgnoreCase("leave")) + .map(ar -> user.getTranslation("commands.island.team.gui.tips." + ar.clickType().name() + ".name") + + " " + user.getTranslation(ar.tooltip())) + .findFirst().ifPresent(desc::add); + } + if (member.isOnline()) { + desc.add(0, user.getTranslation(ref)); + return new PanelItemBuilder().icon(member.getName()).name(member.getDisplayName()).description(desc) + .clickHandler( + (panel, user, clickType, i) -> clickListener(panel, user, clickType, i, member, actions)) + .build(); + } else { + // Offline player + desc.add(0, user.getTranslation(ref)); + return new PanelItemBuilder().icon(member.getName()) + .name(offlinePlayerStatus(user, Bukkit.getOfflinePlayer(member.getUniqueId()))).description(desc) + .clickHandler( + (panel, user, clickType, i) -> clickListener(panel, user, clickType, i, member, actions)) + .build(); + } + } + + private boolean clickListener(Panel panel, User clickingUser, ClickType clickType, int i, User target, + List actions) { + int rank = Objects.requireNonNull(island).getRank(clickingUser); + for (ItemTemplateRecord.ActionRecords action : actions) { + if (clickType.equals(action.clickType())) { + switch (action.actionType().toUpperCase(Locale.ENGLISH)) { + case "KICK" -> { + // Kick the player, or uncoop, or untrust + if (clickingUser.hasPermission(this.kickCommand.getPermission()) && !target.equals(clickingUser) + && rank >= island.getRankCommand(this.getLabel() + " kick")) { + getPlugin().log("Kick: " + clickingUser.getName() + " kicked " + target.getName() + + " from island at " + island.getCenter()); + clickingUser.closeInventory(); + if (removePlayer(clickingUser, target)) { + clickingUser.getPlayer().playSound(clickingUser.getLocation(), Sound.BLOCK_GLASS_BREAK, 1F, + 1F); + getPlugin().log("Kick: success"); + } else { + getPlugin().log("Kick: failed"); + } + } + } + case "SETOWNER" -> { + // Make the player the leader of the island + if (clickingUser.hasPermission(this.setOwnerCommand.getPermission()) && !target.equals(clickingUser) + && clickingUser.getUniqueId().equals(island.getOwner())) { + getPlugin().log("Set Owner: " + clickingUser.getName() + " trying to make " + target.getName() + + " owner of island at " + island.getCenter()); + clickingUser.closeInventory(); + if (this.setOwnerCommand.setOwner(clickingUser, target.getUniqueId())) { + getPlugin().log("Set Owner: success"); + } else { + getPlugin().log("Set Owner: failed"); + } + } + } + case "LEAVE" -> { + if (clickingUser.hasPermission(this.leaveCommand.getPermission()) && target.equals(clickingUser) + && !clickingUser.getUniqueId().equals(island.getOwner())) { + getPlugin().log("Leave: " + clickingUser.getName() + " trying to leave island at " + + island.getCenter()); + clickingUser.closeInventory(); + if (leaveCommand.leave(clickingUser)) { + getPlugin().log("Leave: success"); + } else { + getPlugin().log("Leave: failed"); + } + } + } + } + } + } + return true; + } + + private boolean removePlayer(User clicker, User member) { + // If member then kick, if coop, uncoop, if trusted, then untrust + return switch (island.getRank(member)) { + case RanksManager.COOP_RANK -> this.uncoopCommand.unCoopCmd(user, member.getUniqueId()); + case RanksManager.TRUSTED_RANK -> this.unTrustCommand.unTrustCmd(user, member.getUniqueId()); + default -> { + if (kickCommand.canExecute(user, kickCommand.getLabel(), List.of(member.getName()))) { + yield kickCommand.execute(user, kickCommand.getLabel(), List.of(member.getName())); + } else { + yield false; + } + } + }; + + } + + private List showMembers() { + List message = new ArrayList<>(); // Gather online members - long count = island.getMemberSet(RanksManager.MEMBER_RANK).stream() + long onlineMemberCount = island.getMemberSet(RanksManager.MEMBER_RANK).stream() .filter(uuid -> Util.getOnlinePlayerList(user).contains(Bukkit.getOfflinePlayer(uuid).getName())) .count(); - // List of ranks that we will loop through - Integer[] ranks = new Integer[] { RanksManager.OWNER_RANK, RanksManager.SUB_OWNER_RANK, - RanksManager.MEMBER_RANK, RanksManager.TRUSTED_RANK, RanksManager.COOP_RANK }; - // Show header: - user.sendMessage("commands.island.team.info.header", "[max]", + message.add(user.getTranslation("commands.island.team.info.header", "[max]", String.valueOf(getIslands().getMaxMembers(island, RanksManager.MEMBER_RANK)), "[total]", - String.valueOf(island.getMemberSet().size()), "[online]", String.valueOf(count)); + String.valueOf(island.getMemberSet().size()), "[online]", String.valueOf(onlineMemberCount))); // We now need to get all online "members" of the island - incl. Trusted and coop List onlineMembers = island.getMemberSet(RanksManager.COOP_RANK).stream() .filter(uuid -> Util.getOnlinePlayerList(user).contains(Bukkit.getOfflinePlayer(uuid).getName())) .toList(); - for (int rank : ranks) { + for (int rank : RANKS) { Set players = island.getMemberSet(rank, false); if (!players.isEmpty()) { if (rank == RanksManager.OWNER_RANK) { // Slightly special handling for the owner rank - user.sendMessage("commands.island.team.info.rank-layout.owner", TextVariables.RANK, - user.getTranslation(RanksManager.OWNER_RANK_REF)); + message.add(user.getTranslation("commands.island.team.info.rank-layout.owner", TextVariables.RANK, + user.getTranslation(RanksManager.OWNER_RANK_REF))); } else { - user.sendMessage("commands.island.team.info.rank-layout.generic", TextVariables.RANK, - user.getTranslation(getPlugin().getRanksManager().getRank(rank)), TextVariables.NUMBER, - String.valueOf(island.getMemberSet(rank, false).size())); + message.add(user.getTranslation("commands.island.team.info.rank-layout.generic", TextVariables.RANK, + user.getTranslation(RanksManager.getInstance().getRank(rank)), TextVariables.NUMBER, + String.valueOf(island.getMemberSet(rank, false).size()))); } - displayOnOffline(user, rank, island, onlineMembers); + message.addAll(displayOnOffline(user, rank, island, onlineMembers)); } } + return message; + } + + private List displayOnOffline(User user, int rank, Island island, List onlineMembers) { + List message = new ArrayList<>(); + for (UUID member : island.getMemberSet(rank, false)) { + message.add(getMemberStatus(user, member, onlineMembers.contains(member))); + + } + return message; + } + + private String getMemberStatus(User user2, UUID member, boolean online) { + OfflinePlayer offlineMember = Bukkit.getOfflinePlayer(member); + if (online) { + return user.getTranslation("commands.island.team.info.member-layout.online", TextVariables.NAME, + offlineMember.getName()); + } else { + return offlinePlayerStatus(user, offlineMember); + } } - private void displayOnOffline(User user, int rank, Island island, List onlineMembers) { - for (UUID member : island.getMemberSet(rank, false)) { - OfflinePlayer offlineMember = Bukkit.getOfflinePlayer(member); - if (onlineMembers.contains(member)) { - // the player is online - user.sendMessage("commands.island.team.info.member-layout.online", TextVariables.NAME, - offlineMember.getName()); - } else { - // A bit of handling for the last joined date - Instant lastJoined = Instant.ofEpochMilli(offlineMember.getLastPlayed()); - Instant now = Instant.now(); - - Duration duration = Duration.between(lastJoined, now); - String lastSeen; - final String reference = "commands.island.team.info.last-seen.layout"; - if (duration.toMinutes() < 60L) { - lastSeen = user.getTranslation(reference, TextVariables.NUMBER, - String.valueOf(duration.toMinutes()), TextVariables.UNIT, - user.getTranslation("commands.island.team.info.last-seen.minutes")); - } else if (duration.toHours() < 24L) { - lastSeen = user.getTranslation(reference, TextVariables.NUMBER, String.valueOf(duration.toHours()), - TextVariables.UNIT, user.getTranslation("commands.island.team.info.last-seen.hours")); - } else { - lastSeen = user.getTranslation(reference, TextVariables.NUMBER, String.valueOf(duration.toDays()), - TextVariables.UNIT, user.getTranslation("commands.island.team.info.last-seen.days")); - } - - if (island.getMemberSet(RanksManager.MEMBER_RANK, true).contains(member)) { - user.sendMessage("commands.island.team.info.member-layout.offline", TextVariables.NAME, - offlineMember.getName(), "[last_seen]", lastSeen); - } else { - // This will prevent anyone that is trusted or below to not have a last-seen status - user.sendMessage("commands.island.team.info.member-layout.offline-not-last-seen", - TextVariables.NAME, offlineMember.getName()); - } - } + /** + * Creates text to describe the status of the player + * @param user2 user asking to see the status + * @param offlineMember member of the team + * @return string + */ + private String offlinePlayerStatus(User user2, OfflinePlayer offlineMember) { + String lastSeen = lastSeen(offlineMember); + if (island.getMemberSet(RanksManager.MEMBER_RANK, true).contains(offlineMember.getUniqueId())) { + return user.getTranslation("commands.island.team.info.member-layout.offline", TextVariables.NAME, + offlineMember.getName(), "[last_seen]", lastSeen); + } else { + // This will prevent anyone that is trusted or below to not have a last-seen status + return user.getTranslation("commands.island.team.info.member-layout.offline-not-last-seen", + TextVariables.NAME, offlineMember.getName()); } + } + private String lastSeen(OfflinePlayer offlineMember) { + // A bit of handling for the last joined date + Instant lastJoined = Instant.ofEpochMilli(offlineMember.getLastPlayed()); + Instant now = Instant.now(); + + Duration duration = Duration.between(lastJoined, now); + String lastSeen; + final String reference = "commands.island.team.info.last-seen.layout"; + if (duration.toMinutes() < 60L) { + lastSeen = user.getTranslation(reference, TextVariables.NUMBER, String.valueOf(duration.toMinutes()), + TextVariables.UNIT, user.getTranslation("commands.island.team.info.last-seen.minutes")); + } else if (duration.toHours() < 24L) { + lastSeen = user.getTranslation(reference, TextVariables.NUMBER, String.valueOf(duration.toHours()), + TextVariables.UNIT, user.getTranslation("commands.island.team.info.last-seen.hours")); + } else { + lastSeen = user.getTranslation(reference, TextVariables.NUMBER, String.valueOf(duration.toDays()), + TextVariables.UNIT, user.getTranslation("commands.island.team.info.last-seen.days")); + } + return lastSeen; } private boolean fireEvent(User user, Island island) { @@ -223,4 +701,18 @@ public class IslandTeamCommand extends CompositeCommand { public void removeInvite(@NonNull UUID invitee) { inviteMap.remove(invitee); } + + /** + * @return the coopCommand + */ + protected IslandTeamCoopCommand getCoopCommand() { + return coopCommand; + } + + /** + * @return the trustCommand + */ + protected IslandTeamTrustCommand getTrustCommand() { + return trustCommand; + } } 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 19a039b69..246c38b21 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 @@ -58,7 +58,7 @@ public class IslandTeamCoopCommand extends CompositeCommand { int rank = Objects.requireNonNull(island).getRank(user); if (rank < island.getRankCommand(getUsage())) { user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, - user.getTranslation(getPlugin().getRanksManager().getRank(rank))); + user.getTranslation(RanksManager.getInstance().getRank(rank))); return false; } // Get target player 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 b93d52b8c..576956b63 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 @@ -23,7 +23,6 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand { private static final String INVALID_INVITE = "commands.island.team.invite.errors.invalid-invite"; private final IslandTeamCommand itc; - private UUID playerUUID; public IslandTeamInviteAcceptCommand(IslandTeamCommand islandTeamCommand) { super(islandTeamCommand, "accept"); @@ -39,7 +38,7 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand { @Override public boolean canExecute(User user, String label, List args) { - playerUUID = user.getUniqueId(); + UUID playerUUID = user.getUniqueId(); // Check if player has been invited if (!itc.isInvited(playerUUID)) { user.sendMessage("commands.island.team.invite.errors.none-invited-you"); @@ -79,7 +78,7 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand { @Override public boolean execute(User user, String label, List args) { // Get the invite - Invite invite = itc.getInvite(playerUUID); + Invite invite = itc.getInvite(user.getUniqueId()); switch (invite.getType()) { case COOP -> askConfirmation(user, () -> acceptCoopInvite(user, invite)); case TRUST -> askConfirmation(user, () -> acceptTrustInvite(user, invite)); @@ -89,9 +88,9 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand { return true; } - private void acceptTrustInvite(User user, Invite invite) { + void acceptTrustInvite(User user, Invite invite) { // Remove the invite - itc.removeInvite(playerUUID); + itc.removeInvite(user.getUniqueId()); User inviter = User.getInstance(invite.getInviter()); Island island = invite.getIsland(); if (island != null) { @@ -115,9 +114,9 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand { } } - private void acceptCoopInvite(User user, Invite invite) { + void acceptCoopInvite(User user, Invite invite) { // Remove the invite - itc.removeInvite(playerUUID); + itc.removeInvite(user.getUniqueId()); User inviter = User.getInstance(invite.getInviter()); Island island = invite.getIsland(); if (island != null) { @@ -141,11 +140,11 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand { } } - private void acceptTeamInvite(User user, Invite invite) { + void acceptTeamInvite(User user, Invite invite) { // Remove the invite - itc.removeInvite(playerUUID); + itc.removeInvite(user.getUniqueId()); // Get the player's island - may be null if the player has no island - Set islands = getIslands().getIslands(getWorld(), playerUUID); + Set islands = getIslands().getIslands(getWorld(), user.getUniqueId()); // Get the team's island Island teamIsland = invite.getIsland(); if (teamIsland == null) { @@ -158,11 +157,11 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand { return; } // Remove player as owner of the old island - getIslands().removePlayer(getWorld(), playerUUID); + getIslands().removePlayer(getWorld(), user.getUniqueId()); // Remove money inventory etc. for leaving cleanPlayer(user); // Add the player as a team member of the new island - getIslands().setJoinTeam(teamIsland, playerUUID); + getIslands().setJoinTeam(teamIsland, user.getUniqueId()); // Move player to team's island getIslands().homeTeleportAsync(getWorld(), user.getPlayer()).thenRun(() -> { // Delete the old islands @@ -178,7 +177,7 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand { }); // Reset deaths if (getIWM().isTeamJoinDeathReset(getWorld())) { - getPlayers().setDeaths(getWorld(), playerUUID, 0); + getPlayers().setDeaths(getWorld(), user.getUniqueId(), 0); } user.sendMessage("commands.island.team.invite.accept.you-joined-island", TextVariables.LABEL, getTopLabel()); User inviter = User.getInstance(invite.getInviter()); @@ -188,7 +187,8 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand { } getIslands().save(teamIsland); // Fire event - TeamEvent.builder().island(teamIsland).reason(TeamEvent.Reason.JOINED).involvedPlayer(playerUUID).build(); + TeamEvent.builder().island(teamIsland).reason(TeamEvent.Reason.JOINED).involvedPlayer(user.getUniqueId()) + .build(); IslandEvent.builder().island(teamIsland).involvedPlayer(user.getUniqueId()).admin(false) .reason(IslandEvent.Reason.RANK_CHANGE).rankChange(teamIsland.getRank(user), RanksManager.MEMBER_RANK) .build(); diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamInviteCommand.java index 2f054e1d4..c80c6df8b 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 @@ -1,18 +1,33 @@ package world.bentobox.bentobox.api.commands.island.team; +import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.UUID; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.conversations.ConversationFactory; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; import org.eclipse.jdt.annotation.Nullable; +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.events.IslandBaseEvent; import world.bentobox.bentobox.api.events.team.TeamEvent; import world.bentobox.bentobox.api.localization.TextVariables; +import world.bentobox.bentobox.api.panels.Panel; +import world.bentobox.bentobox.api.panels.PanelItem; +import world.bentobox.bentobox.api.panels.TemplatedPanel; +import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; +import world.bentobox.bentobox.api.panels.builders.TemplatedPanelBuilder; +import world.bentobox.bentobox.api.panels.reader.ItemTemplateRecord; +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.managers.IslandsManager; @@ -24,6 +39,13 @@ public class IslandTeamInviteCommand extends CompositeCommand { private final IslandTeamCommand itc; private @Nullable User invitedPlayer; + private @Nullable TemplateItem border; + private @Nullable TemplateItem background; + private User user; + private long page = 0; // This number by 35 + private boolean inviteCmd; + private static final long PER_PAGE = 35; + private String searchName = ""; public IslandTeamInviteCommand(IslandTeamCommand parent) { super(parent, "invite"); @@ -36,6 +58,10 @@ public class IslandTeamInviteCommand extends CompositeCommand { setOnlyPlayer(true); setDescription("commands.island.team.invite.description"); setConfigurableRankCommand(); + // Panels + if (!new File(getPlugin().getDataFolder() + File.separator + "panels", "team_invite_panel.yml").exists()) { + getPlugin().saveResource("panels/team_invite_panel.yml", false); + } } @@ -51,7 +77,9 @@ public class IslandTeamInviteCommand extends CompositeCommand { } if (args.size() != 1) { - return handleCommandWithNoArgs(user); + this.inviteCmd = true; + build(user); + return true; } Island island = islandsManager.getIsland(getWorld(), user); @@ -60,33 +88,15 @@ public class IslandTeamInviteCommand extends CompositeCommand { return checkRankAndInvitePlayer(user, island, rank, args.get(0)); } - private boolean handleCommandWithNoArgs(User user) { - UUID playerUUID = user.getUniqueId(); - Type inviteType = getInviteType(playerUUID); - - if (inviteType != null) { - String name = getPlayers().getName(playerUUID); - switch (inviteType) { - case COOP -> user.sendMessage("commands.island.team.invite.name-has-invited-you.coop", TextVariables.NAME, name); - case TRUST -> user.sendMessage("commands.island.team.invite.name-has-invited-you.trust", TextVariables.NAME, name); - default -> user.sendMessage("commands.island.team.invite.name-has-invited-you", TextVariables.NAME, name); - } - return true; - } - - showHelp(this, user); - return false; - } - private boolean checkRankAndInvitePlayer(User user, Island island, int rank, String playerName) { - RanksManager ranksManager = getPlugin().getRanksManager(); PlayersManager playersManager = getPlayers(); UUID playerUUID = user.getUniqueId(); // Check rank to use command int requiredRank = island.getRankCommand(getUsage()); if (rank < requiredRank) { - user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, user.getTranslation(ranksManager.getRank(rank))); + user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, + user.getTranslation(RanksManager.getInstance().getRank(rank))); return false; } @@ -127,14 +137,6 @@ public class IslandTeamInviteCommand extends CompositeCommand { return true; } - private Type getInviteType(UUID playerUUID) { - if (itc.isInvited(playerUUID)) { - Invite invite = itc.getInvite(playerUUID); - return invite.getType(); - } - return null; - } - private boolean canInvitePlayer(User user, User invitedPlayer) { UUID playerUUID = user.getUniqueId(); if (!invitedPlayer.isOnline() || !user.getPlayer().canSee(invitedPlayer.getPlayer())) { @@ -204,4 +206,198 @@ public class IslandTeamInviteCommand extends CompositeCommand { return Optional.of(Util.tabLimit(options, lastArg)); } + /** + * Build the invite panel + * @param user use of the panel + */ + void build(User user) { + this.user = user; + // Start building panel. + TemplatedPanelBuilder panelBuilder = new TemplatedPanelBuilder(); + panelBuilder.user(user); + panelBuilder.world(user.getWorld()); + + panelBuilder.template("team_invite_panel", new File(getPlugin().getDataFolder(), "panels")); + + panelBuilder.parameters("[name]", user.getName(), "[display_name]", user.getDisplayName()); + + panelBuilder.registerTypeBuilder("PROSPECT", this::createProspectButton); + panelBuilder.registerTypeBuilder("PREVIOUS", this::createPreviousButton); + panelBuilder.registerTypeBuilder("NEXT", this::createNextButton); + panelBuilder.registerTypeBuilder("SEARCH", this::createSearchButton); + panelBuilder.registerTypeBuilder("BACK", this::createBackButton); + // Stash the backgrounds for later use + border = panelBuilder.getPanelTemplate().border(); + background = panelBuilder.getPanelTemplate().background(); + // Register unknown type builder. + panelBuilder.build(); + + } + + private PanelItem createBackButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot) { + checkTemplate(template); + return new PanelItemBuilder().name(user.getTranslation(template.title())).icon(template.icon()) + .clickHandler((panel, user, clickType, clickSlot) -> { + user.closeInventory(); + if (!inviteCmd) { + this.itc.build(); + } + return true; + }).build(); + } + + private PanelItem createSearchButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot) { + checkTemplate(template); + PanelItemBuilder pib = new PanelItemBuilder().name(user.getTranslation(template.title())).icon(template.icon()) + .clickHandler((panel, user, clickType, clickSlot) -> { + user.closeInventory(); + new ConversationFactory(BentoBox.getInstance()).withLocalEcho(false).withTimeout(90) + .withModality(false).withFirstPrompt(new InviteNamePrompt(user, this)) + .buildConversation(user.getPlayer()).begin(); + return true; + }); + if (!this.searchName.isBlank()) { + pib.description(user.getTranslation(Objects + .requireNonNullElse(template.description(), + "commands.island.team.invite.gui.button.searching"), + TextVariables.NAME, searchName)); + } + return pib.build(); + } + + private PanelItem createNextButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot) { + checkTemplate(template); + long count = getWorld().getPlayers().stream().filter(player -> user.getPlayer().canSee(player)) + .filter(player -> !player.equals(user.getPlayer())).count(); + if (count > page * PER_PAGE) { + // We need to show a next button + return new PanelItemBuilder().name(user.getTranslation(template.title())).icon(template.icon()) + .clickHandler((panel, user, clickType, clickSlot) -> { + user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1F, 1F); + page++; + build(user); + return true; + }).build(); + } + return getBlankBorder(); + } + + private void checkTemplate(ItemTemplateRecord template) { + if (template.icon() == null) { + getPlugin().logError("Icon in template is missing or unknown! " + template.toString()); + } + if (template.title() == null) { + getPlugin().logError("Title in template is missing! " + template.toString()); + } + + } + + private PanelItem createPreviousButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot) { + checkTemplate(template); + if (page > 0) { + // We need to show a next button + return new PanelItemBuilder().name(user.getTranslation(template.title())).icon(template.icon()) + .clickHandler((panel, user, clickType, clickSlot) -> { + user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1F, 1F); + page--; + build(user); + return true; + }).build(); + } + return getBlankBorder(); + } + + private PanelItem getBlankBorder() { + return new PanelItemBuilder().icon(Objects.requireNonNullElse(border.icon(), new ItemStack(Material.BARRIER))) + .name((Objects.requireNonNullElse(border.title(), ""))).build(); + } + + /** + * Create member button panel item. + * + * @param template the template + * @param slot the slot + * @return the panel item + */ + private PanelItem createProspectButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot) { + // Player issuing the command must have an island + Island island = getIslands().getPrimaryIsland(getWorld(), user.getUniqueId()); + if (island == null) { + return this.getBlankBackground(); + } + if (page < 0) { + page = 0; + } + return getWorld().getPlayers().stream().filter(player -> user.getPlayer().canSee(player)) + .filter(player -> this.searchName.isBlank() ? true + : player.getName().toLowerCase().contains(searchName.toLowerCase())) + .filter(player -> !player.equals(user.getPlayer())).skip(slot.slot() + page * PER_PAGE).findFirst() + .map(player -> getProspect(player, template)).orElse(this.getBlankBackground()); + } + + private PanelItem getProspect(Player player, ItemTemplateRecord template) { + // Check if the prospect has already been invited + if (this.itc.isInvited(player.getUniqueId()) + && user.getUniqueId().equals(this.itc.getInvite(player.getUniqueId()).getInviter())) { + return new PanelItemBuilder().icon(player.getName()).name(player.getDisplayName()) + .description(user.getTranslation("commands.island.team.invite.gui.button.already-invited")).build(); + } + List desc = template.actions().stream().map(ar -> user + .getTranslation("commands.island.team.invite.gui.tips." + ar.clickType().name() + ".name") + + " " + user.getTranslation(ar.tooltip())).toList(); + return new PanelItemBuilder().icon(player.getName()).name(player.getDisplayName()).description(desc) + .clickHandler( + (panel, user, clickType, clickSlot) -> clickHandler(panel, user, clickType, clickSlot, player)) + .build(); + } + + private boolean clickHandler(Panel panel, User user, ClickType clickType, int clickSlot, Player player) { + if (clickType.equals(ClickType.LEFT)) { + user.closeInventory(); + if (this.canExecute(user, this.getLabel(), List.of(player.getName()))) { + getPlugin().log("Invite sent to: " + player.getName() + " by " + user.getName() + " to join island in " + + getWorld().getName()); + this.execute(user, getLabel(), List.of(player.getName())); + } else { + getPlugin().log("Invite failed: " + player.getName() + " by " + user.getName() + " to join island in " + + getWorld().getName()); + } + } else if (clickType.equals(ClickType.RIGHT)) { + user.closeInventory(); + if (this.itc.getCoopCommand().canExecute(user, this.getLabel(), List.of(player.getName()))) { + getPlugin().log("Coop: " + player.getName() + " cooped " + user.getName() + " to island in " + + getWorld().getName()); + this.itc.getCoopCommand().execute(user, getLabel(), List.of(player.getName())); + } else { + getPlugin().log( + "Coop failed: " + player.getName() + "'s coop to " + user.getName() + " failed for island in " + + getWorld().getName()); + } + } else if (clickType.equals(ClickType.SHIFT_LEFT)) { + user.closeInventory(); + if (this.itc.getTrustCommand().canExecute(user, this.getLabel(), List.of(player.getName()))) { + getPlugin().log("Trust: " + player.getName() + " trusted " + user.getName() + " to island in " + + getWorld().getName()); + this.itc.getTrustCommand().execute(user, getLabel(), List.of(player.getName())); + } else { + getPlugin().log("Trust failed: " + player.getName() + "'s trust failed for " + user.getName() + + " for island in " + + getWorld().getName()); + } + } + return true; + } + + private PanelItem getBlankBackground() { + return new PanelItemBuilder() + .icon(Objects.requireNonNullElse(background.icon(), new ItemStack(Material.BARRIER))) + .name((Objects.requireNonNullElse(background.title(), ""))).build(); + } + + /** + * @param searchName the searchName to set + */ + void setSearchName(String searchName) { + this.searchName = searchName; + } } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommand.java index 6266edb4f..38989a433 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommand.java @@ -35,7 +35,7 @@ public class IslandTeamKickCommand extends ConfirmableCommand { } @Override - public boolean execute(User user, String label, List args) { + public boolean canExecute(User user, String label, List args) { if (!getIslands().inTeam(getWorld(), user.getUniqueId())) { user.sendMessage("general.errors.no-team"); return false; @@ -45,7 +45,7 @@ public class IslandTeamKickCommand extends ConfirmableCommand { int rank = Objects.requireNonNull(island).getRank(user); if (rank < island.getRankCommand(getUsage())) { user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, - user.getTranslation(getPlugin().getRanksManager().getRank(rank))); + user.getTranslation(RanksManager.getInstance().getRank(rank))); return false; } // If args are not right, show help @@ -74,7 +74,13 @@ public class IslandTeamKickCommand extends ConfirmableCommand { getPlayers().getName(targetUUID)); return false; } + return true; + } + @Override + public boolean execute(User user, String label, List args) { + // Get target + UUID targetUUID = getPlayers().getUUID(args.get(0)); if (!getSettings().isKickConfirmation()) { kick(user, targetUUID); return true; @@ -84,7 +90,7 @@ public class IslandTeamKickCommand extends ConfirmableCommand { } } - private void kick(User user, UUID targetUUID) { + protected void kick(User user, UUID targetUUID) { User target = User.getInstance(targetUUID); Island oldIsland = Objects.requireNonNull(getIslands().getIsland(getWorld(), targetUUID)); // Should never be // null because of diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamLeaveCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamLeaveCommand.java index fc39559f0..882f19719 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamLeaveCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamLeaveCommand.java @@ -65,17 +65,17 @@ public class IslandTeamLeaveCommand extends ConfirmableCommand { } - private void leave(User user) { + protected boolean leave(User user) { Island island = getIslands().getIsland(getWorld(), user); if (island == null) { user.sendMessage("general.errors.no-island"); - return; + return false; } // Fire event IslandBaseEvent event = TeamEvent.builder().island(island).reason(TeamEvent.Reason.LEAVE) .involvedPlayer(user.getUniqueId()).build(); if (event.isCancelled()) { - return; + return false; } UUID ownerUUID = island.getOwner(); if (ownerUUID != null) { @@ -103,5 +103,6 @@ public class IslandTeamLeaveCommand extends ConfirmableCommand { IslandEvent.builder().island(island).involvedPlayer(user.getUniqueId()).admin(false) .reason(IslandEvent.Reason.RANK_CHANGE).rankChange(island.getRank(user), RanksManager.VISITOR_RANK) .build(); + return true; } } \ No newline at end of file diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamPromoteCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamPromoteCommand.java index 988f74201..eab48723a 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamPromoteCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamPromoteCommand.java @@ -54,7 +54,8 @@ public class IslandTeamPromoteCommand extends CompositeCommand { Island island = getIslands().getIsland(getWorld(), user); int rank = Objects.requireNonNull(island).getRank(user); if (rank < island.getRankCommand(getUsage())) { - user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, user.getTranslation(getPlugin().getRanksManager().getRank(rank))); + user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, + user.getTranslation(RanksManager.getInstance().getRank(rank))); return false; } @@ -97,11 +98,11 @@ public class IslandTeamPromoteCommand extends CompositeCommand { Island island = getIslands().getIsland(getWorld(), user); int currentRank = island.getRank(target); if (this.getLabel().equals("promote")) { - int nextRank = getPlugin().getRanksManager().getRankUpValue(currentRank); + int nextRank = RanksManager.getInstance().getRankUpValue(currentRank); // Stop short of owner if (nextRank != RanksManager.OWNER_RANK && nextRank > currentRank) { island.setRank(target, nextRank); - String rankName = user.getTranslation(getPlugin().getRanksManager().getRank(nextRank)); + String rankName = user.getTranslation(RanksManager.getInstance().getRank(nextRank)); user.sendMessage("commands.island.team.promote.success", TextVariables.NAME, target.getName(), TextVariables.RANK, rankName, TextVariables.DISPLAY_NAME, target.getDisplayName()); IslandEvent.builder() .island(island) @@ -117,11 +118,11 @@ public class IslandTeamPromoteCommand extends CompositeCommand { } } else { // Demote - int prevRank = getPlugin().getRanksManager().getRankDownValue(currentRank); + int prevRank = RanksManager.getInstance().getRankDownValue(currentRank); // Lowest is Member if (prevRank >= RanksManager.MEMBER_RANK && prevRank < currentRank) { island.setRank(target, prevRank); - String rankName = user.getTranslation(getPlugin().getRanksManager().getRank(prevRank)); + String rankName = user.getTranslation(RanksManager.getInstance().getRank(prevRank)); user.sendMessage("commands.island.team.demote.success", TextVariables.NAME, target.getName(), TextVariables.RANK, rankName, TextVariables.DISPLAY_NAME, target.getDisplayName()); IslandEvent.builder() .island(island) 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 842a2134f..24f10557b 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 @@ -4,6 +4,7 @@ import java.util.List; import java.util.Optional; import java.util.UUID; +import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import world.bentobox.bentobox.api.commands.CompositeCommand; @@ -69,19 +70,24 @@ public class IslandTeamSetownerCommand extends CompositeCommand { @Override public boolean execute(User user, String label, List args) { + return setOwner(user, targetUUID); + + } + + protected boolean setOwner(User user, @NonNull UUID targetUUID2) { // Fire event so add-ons can run commands, etc. Island island = getIslands().getPrimaryIsland(getWorld(), user.getUniqueId()); // Fire event so add-ons can run commands, etc. IslandBaseEvent e = TeamEvent.builder().island(island).reason(TeamEvent.Reason.SETOWNER) - .involvedPlayer(targetUUID).build(); + .involvedPlayer(targetUUID2).build(); if (e.isCancelled()) { return false; } - getIslands().setOwner(getWorld(), user, targetUUID); + getIslands().setOwner(getWorld(), user, targetUUID2); // Call the event for the new owner - IslandEvent.builder().island(island).involvedPlayer(targetUUID).admin(false) + IslandEvent.builder().island(island).involvedPlayer(targetUUID2).admin(false) .reason(IslandEvent.Reason.RANK_CHANGE) - .rankChange(island.getRank(User.getInstance(targetUUID)), RanksManager.OWNER_RANK).build(); + .rankChange(island.getRank(User.getInstance(targetUUID2)), RanksManager.OWNER_RANK).build(); // Call the event for the previous owner IslandEvent.builder().island(island).involvedPlayer(user.getUniqueId()).admin(false) .reason(IslandEvent.Reason.RANK_CHANGE).rankChange(RanksManager.OWNER_RANK, RanksManager.SUB_OWNER_RANK) 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 633223bb3..8d57871df 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 @@ -55,7 +55,8 @@ public class IslandTeamTrustCommand extends CompositeCommand { Island island = getIslands().getIsland(getWorld(), user); int rank = Objects.requireNonNull(island).getRank(user); if (rank < island.getRankCommand(getUsage())) { - user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, user.getTranslation(getPlugin().getRanksManager().getRank(rank))); + user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, + user.getTranslation(RanksManager.getInstance().getRank(rank))); return false; } // Get target player diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamUncoopCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamUncoopCommand.java index c60bde5d3..c79b3e219 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamUncoopCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamUncoopCommand.java @@ -55,7 +55,7 @@ public class IslandTeamUncoopCommand extends CompositeCommand { int rank = Objects.requireNonNull(island).getRank(user); if (rank < island.getRankCommand(getUsage())) { user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, - user.getTranslation(getPlugin().getRanksManager().getRank(rank))); + user.getTranslation(RanksManager.getInstance().getRank(rank))); return false; } // Get target player @@ -68,7 +68,7 @@ public class IslandTeamUncoopCommand extends CompositeCommand { return unCoopCmd(user, targetUUID); } - private boolean unCoopCmd(User user, UUID targetUUID) { + protected boolean unCoopCmd(User user, UUID targetUUID) { // Player cannot uncoop themselves if (user.getUniqueId().equals(targetUUID)) { user.sendMessage("commands.island.team.uncoop.cannot-uncoop-yourself"); diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamUntrustCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamUntrustCommand.java index ca2f3d408..11bdb82aa 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamUntrustCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamUntrustCommand.java @@ -55,7 +55,7 @@ public class IslandTeamUntrustCommand extends CompositeCommand { int rank = Objects.requireNonNull(island).getRank(user); if (rank < island.getRankCommand(getUsage())) { user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, - user.getTranslation(getPlugin().getRanksManager().getRank(rank))); + user.getTranslation(RanksManager.getInstance().getRank(rank))); return false; } // Get target player @@ -68,7 +68,7 @@ public class IslandTeamUntrustCommand extends CompositeCommand { return unTrustCmd(user, targetUUID); } - private boolean unTrustCmd(User user, UUID targetUUID) { + protected boolean unTrustCmd(User user, UUID targetUUID) { // Player cannot untrust themselves if (user.getUniqueId().equals(targetUUID)) { user.sendMessage("commands.island.team.untrust.cannot-untrust-yourself"); 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 409296228..cac99e562 100644 --- a/src/main/java/world/bentobox/bentobox/api/flags/Flag.java +++ b/src/main/java/world/bentobox/bentobox/api/flags/Flag.java @@ -430,7 +430,7 @@ public class Flag implements Comparable { // Protection flag pib.description(user.getTranslation("protection.panel.flag-item.description-layout", TextVariables.DESCRIPTION, user.getTranslation(getDescriptionReference()))); - plugin.getRanksManager().getRanks().forEach((reference, score) -> { + RanksManager.getInstance().getRanks().forEach((reference, score) -> { if (score > RanksManager.BANNED_RANK && score < island.getFlag(this)) { pib.description(user.getTranslation("protection.panel.flag-item.blocked-rank") + user.getTranslation(reference)); } else if (score <= RanksManager.OWNER_RANK && score > island.getFlag(this)) { diff --git a/src/main/java/world/bentobox/bentobox/api/flags/clicklisteners/CycleClick.java b/src/main/java/world/bentobox/bentobox/api/flags/clicklisteners/CycleClick.java index c1a281e37..296a79fed 100644 --- a/src/main/java/world/bentobox/bentobox/api/flags/clicklisteners/CycleClick.java +++ b/src/main/java/world/bentobox/bentobox/api/flags/clicklisteners/CycleClick.java @@ -81,15 +81,14 @@ public class CycleClick implements PanelItem.ClickHandler { // Shift Left Click toggles player visibility if (island != null && (user.isOp() || island.isAllowed(user, Flags.CHANGE_SETTINGS) || user.hasPermission(prefix + "admin.settings"))) { changeOccurred = true; - RanksManager rm = plugin.getRanksManager(); plugin.getFlagsManager().getFlag(id).ifPresent(flag -> { // Rank int currentRank = island.getFlag(flag); if (click.equals(ClickType.LEFT)) { - leftClick(flag, rm, currentRank); + leftClick(flag, currentRank); } else if (click.equals(ClickType.RIGHT)) { - rightClick(flag, rm, currentRank); + rightClick(flag, currentRank); } else if (click.equals(ClickType.SHIFT_LEFT) && user2.isOp()) { leftShiftClick(flag); @@ -109,16 +108,16 @@ public class CycleClick implements PanelItem.ClickHandler { // Player is not the allowed to change settings. user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, - user.getTranslation(plugin.getRanksManager().getRank(Objects.requireNonNull(island).getRank(user)))); + user.getTranslation(RanksManager.getInstance().getRank(Objects.requireNonNull(island).getRank(user)))); } user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F); } - private void leftClick(Flag flag, RanksManager rm, int currentRank) { + private void leftClick(Flag flag, int currentRank) { if (currentRank >= maxRank) { island.setFlag(flag, minRank); } else { - island.setFlag(flag, rm.getRankUpValue(currentRank)); + island.setFlag(flag, RanksManager.getInstance().getRankUpValue(currentRank)); } user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_STONE_BUTTON_CLICK_OFF, 1F, 1F); // Fire event @@ -132,11 +131,11 @@ public class CycleClick implements PanelItem.ClickHandler { } - private void rightClick(Flag flag, RanksManager rm, int currentRank) { + private void rightClick(Flag flag, int currentRank) { if (currentRank <= minRank) { island.setFlag(flag, maxRank); } else { - island.setFlag(flag, rm.getRankDownValue(currentRank)); + island.setFlag(flag, RanksManager.getInstance().getRankDownValue(currentRank)); } user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1F, 1F); // Fire event diff --git a/src/main/java/world/bentobox/bentobox/api/flags/clicklisteners/IslandToggleClick.java b/src/main/java/world/bentobox/bentobox/api/flags/clicklisteners/IslandToggleClick.java index 056af998c..76949cd6e 100644 --- a/src/main/java/world/bentobox/bentobox/api/flags/clicklisteners/IslandToggleClick.java +++ b/src/main/java/world/bentobox/bentobox/api/flags/clicklisteners/IslandToggleClick.java @@ -17,6 +17,7 @@ import world.bentobox.bentobox.api.panels.TabbedPanel; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.lists.Flags; +import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.panels.settings.SettingsTab; import world.bentobox.bentobox.util.Util; @@ -112,7 +113,7 @@ public class IslandToggleClick implements ClickHandler { // Player is not the allowed to change settings. user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, - user.getTranslation(plugin.getRanksManager().getRank(Objects.requireNonNull(island).getRank(user)))); + user.getTranslation(RanksManager.getInstance().getRank(Objects.requireNonNull(island).getRank(user)))); } user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F); diff --git a/src/main/java/world/bentobox/bentobox/api/panels/Panel.java b/src/main/java/world/bentobox/bentobox/api/panels/Panel.java index 48aef7d6f..ce2b7963d 100644 --- a/src/main/java/world/bentobox/bentobox/api/panels/Panel.java +++ b/src/main/java/world/bentobox/bentobox/api/panels/Panel.java @@ -38,8 +38,8 @@ public class Panel implements HeadRequester, InventoryHolder { *
* The current list of inventories that cannot be created are:
*
- * {@link Type#INVENTORY}, {@link Type#HOPPER} and - * {@link Type#DROPPER} + * {@link Type#INVENTORY}, {@link Type#HOPPER}, + * {@link Type#DROPPER}, {@link Type#ANVIL} *
* * These relate to the Bukkit inventories with INVENTORY being the standard CHEST inventory. @@ -47,7 +47,7 @@ public class Panel implements HeadRequester, InventoryHolder { * @since 1.7.0 */ public enum Type { - INVENTORY, HOPPER, DROPPER + INVENTORY, HOPPER, DROPPER, ANVIL } public Panel() { @@ -92,6 +92,7 @@ public class Panel implements HeadRequester, InventoryHolder { case INVENTORY -> inventory = Bukkit.createInventory(null, fixSize(size), name); case HOPPER -> inventory = Bukkit.createInventory(null, InventoryType.HOPPER, name); case DROPPER -> inventory = Bukkit.createInventory(null, InventoryType.DROPPER, name); + case ANVIL -> inventory = Bukkit.createInventory(null, InventoryType.ANVIL, name); } // Fill the inventory and return diff --git a/src/main/java/world/bentobox/bentobox/api/panels/TemplatedPanel.java b/src/main/java/world/bentobox/bentobox/api/panels/TemplatedPanel.java index 866473e2d..6310fa144 100644 --- a/src/main/java/world/bentobox/bentobox/api/panels/TemplatedPanel.java +++ b/src/main/java/world/bentobox/bentobox/api/panels/TemplatedPanel.java @@ -61,6 +61,7 @@ public class TemplatedPanel extends Panel { case INVENTORY -> this.populateInventoryPanel(new PanelItem[6][9]); case HOPPER -> this.populateInventoryPanel(new PanelItem[1][5]); case DROPPER -> this.populateInventoryPanel(new PanelItem[3][3]); + case ANVIL -> this.populateInventoryPanel(new PanelItem[4][9]); }; super.makePanel(this.user.getTranslation(this.panelTemplate.title(), this.parameters), items, diff --git a/src/main/java/world/bentobox/bentobox/api/panels/reader/ItemTemplateRecord.java b/src/main/java/world/bentobox/bentobox/api/panels/reader/ItemTemplateRecord.java index c1c157124..85b1ef2fd 100644 --- a/src/main/java/world/bentobox/bentobox/api/panels/reader/ItemTemplateRecord.java +++ b/src/main/java/world/bentobox/bentobox/api/panels/reader/ItemTemplateRecord.java @@ -3,10 +3,8 @@ // Copyright - 2021 // - package world.bentobox.bentobox.api.panels.reader; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -17,8 +15,6 @@ import org.bukkit.inventory.ItemStack; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; -import world.bentobox.bentobox.api.panels.reader.ItemTemplateRecord.ActionRecords; - /** * This Record contains all necessary information about Item Template that can be used to craft panel item. * @@ -31,13 +27,32 @@ import world.bentobox.bentobox.api.panels.reader.ItemTemplateRecord.ActionRecord * * @since 1.17.3 */ -public record ItemTemplateRecord(@Nullable ItemStack icon, +public record ItemTemplateRecord( + /** + * ItemStack of the Item + */ + @Nullable ItemStack icon, + /** + * Title of the item + */ @Nullable String title, + /** + * Lore message of the item + */ @Nullable String description, + /** + * List of Actions for a button + */ @NonNull List actions, + /** + * DataMap that links additional objects for a button. + */ @NonNull Map dataMap, - @Nullable ItemTemplateRecord fallback) -{ + /** + * FallBack item if current one is not possible to generate. + */ + @Nullable ItemTemplateRecord fallback) { + /** * Instantiates a new Item template record without actions and data map. * @@ -46,39 +61,32 @@ public record ItemTemplateRecord(@Nullable ItemStack icon, * @param description the description * @param fallback the fallback */ - public ItemTemplateRecord(ItemStack icon, String title, String description, ItemTemplateRecord fallback) - { + public ItemTemplateRecord(ItemStack icon, String title, String description, ItemTemplateRecord fallback) { this(icon, title, description, new ArrayList<>(6), new HashMap<>(0), fallback); } - /** * This method adds given object associated with key into data map. * @param key Key value of object. * @param data Data that is associated with a key. */ - public void addData(String key, Object data) - { + public void addData(String key, Object data) { this.dataMap.put(key, data); } - /** * Add action to the actions list. * * @param actionData the action data */ - public void addAction(ActionRecords actionData) - { + public void addAction(ActionRecords actionData) { this.actions.add(actionData); } - // --------------------------------------------------------------------- // Section: Classes // --------------------------------------------------------------------- - /** * The Action Records holds data about each action. * @@ -87,5 +95,22 @@ public record ItemTemplateRecord(@Nullable ItemStack icon, * @param content the content of the action * @param tooltip the tooltip of action */ - public record ActionRecords(ClickType clickType, String actionType, String content, String tooltip) {} + public record ActionRecords( + /** + * the click type + */ + ClickType clickType, + /** + * the string that represents action type + */ + String actionType, + /** + * the content of the action + */ + String content, + /** + * the tooltip of action + */ + String tooltip) { + } } diff --git a/src/main/java/world/bentobox/bentobox/api/panels/reader/PanelTemplateRecord.java b/src/main/java/world/bentobox/bentobox/api/panels/reader/PanelTemplateRecord.java index 18d5506f1..f260fb564 100644 --- a/src/main/java/world/bentobox/bentobox/api/panels/reader/PanelTemplateRecord.java +++ b/src/main/java/world/bentobox/bentobox/api/panels/reader/PanelTemplateRecord.java @@ -15,7 +15,6 @@ import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import world.bentobox.bentobox.api.panels.Panel; -import world.bentobox.bentobox.api.panels.reader.PanelTemplateRecord.TemplateItem; /** * This is template object for the panel reader. It contains data that can exist in the panel. diff --git a/src/main/java/world/bentobox/bentobox/api/panels/reader/TemplateReader.java b/src/main/java/world/bentobox/bentobox/api/panels/reader/TemplateReader.java index 9d8158b1b..524f0f260 100644 --- a/src/main/java/world/bentobox/bentobox/api/panels/reader/TemplateReader.java +++ b/src/main/java/world/bentobox/bentobox/api/panels/reader/TemplateReader.java @@ -22,6 +22,7 @@ import org.eclipse.jdt.annotation.Nullable; import com.google.common.base.Enums; +import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.panels.Panel; import world.bentobox.bentobox.util.ItemParser; @@ -83,6 +84,7 @@ public class TemplateReader { if (!panelLocation.exists()) { + BentoBox.getInstance().logError("Panel Template reader: Folder does not exist"); // Return null because folder does not exist. return null; } @@ -91,6 +93,7 @@ public class TemplateReader if (!file.exists()) { + BentoBox.getInstance().logError(file.getAbsolutePath() + " does not exist for panel template"); // Return as file does not exist. return null; } @@ -117,6 +120,8 @@ public class TemplateReader } catch (IOException | InvalidConfigurationException e) { + BentoBox.getInstance().logError("Error loading template"); + BentoBox.getInstance().logStacktrace(e); rec = null; } @@ -133,6 +138,7 @@ public class TemplateReader { if (configurationSection == null) { + BentoBox.getInstance().logError("No configuration section!"); // No data to return. return null; } 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 6a5927ddb..a06c11932 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintEntity.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintEntity.java @@ -78,7 +78,8 @@ public class BlueprintEntity { if (e instanceof AbstractHorse horse) { if (domestication != null) horse.setDomestication(domestication); if (inventory != null) { - inventory.forEach(horse.getInventory()::setItem); + inventory.forEach((index, item) -> horse.getInventory().setItem(index.intValue(), item)); + } } if (style != null && e instanceof Horse horse) { diff --git a/src/main/java/world/bentobox/bentobox/commands/BentoBoxRankCommand.java b/src/main/java/world/bentobox/bentobox/commands/BentoBoxRankCommand.java index a666cddde..3c5b9b4f5 100644 --- a/src/main/java/world/bentobox/bentobox/commands/BentoBoxRankCommand.java +++ b/src/main/java/world/bentobox/bentobox/commands/BentoBoxRankCommand.java @@ -20,7 +20,6 @@ public class BentoBoxRankCommand extends CompositeCommand { private static final String REMOVE = "remove"; private int rankValue; private String firstElement; - private final RanksManager rm; /** * Rank management. Add and remove @@ -29,7 +28,6 @@ public class BentoBoxRankCommand extends CompositeCommand { */ public BentoBoxRankCommand(CompositeCommand parent) { super(parent, "rank"); - rm = getPlugin().getRanksManager(); } @Override @@ -93,7 +91,7 @@ public class BentoBoxRankCommand extends CompositeCommand { return true; } if ("add".equals(firstElement)) { - if (rm.addRank(args.get(1), rankValue)) { + if (RanksManager.getInstance().addRank(args.get(1), rankValue)) { user.sendMessage("commands.bentobox.rank.add.success", TextVariables.RANK, args.get(1), TextVariables.NUMBER, String.valueOf(rankValue)); showRanks(user); @@ -103,7 +101,7 @@ public class BentoBoxRankCommand extends CompositeCommand { return false; } } else { - if (rm.removeRank(args.get(1))) { + if (RanksManager.getInstance().removeRank(args.get(1))) { user.sendMessage("commands.bentobox.rank.remove.success", TextVariables.RANK, args.get(1)); showRanks(user); } else { @@ -116,7 +114,7 @@ public class BentoBoxRankCommand extends CompositeCommand { private void showRanks(User user) { user.sendMessage("commands.bentobox.rank.list"); - rm.getRanks().forEach((ref, rank) -> { + RanksManager.getInstance().getRanks().forEach((ref, rank) -> { user.sendRawMessage(user.getTranslation(ref) + ": " + ref + " " + String.valueOf(rank)); }); @@ -133,11 +131,11 @@ public class BentoBoxRankCommand extends CompositeCommand { } if (args.size() > 1 && "add".equals(firstElement)) { List options = new ArrayList<>(RanksManager.DEFAULT_RANKS.keySet()); - options.removeIf(rm.getRanks().keySet()::contains); + options.removeIf(RanksManager.getInstance().getRanks().keySet()::contains); return Optional.of(options); } if (args.size() > 1 && REMOVE.equals(firstElement)) { - return Optional.of(new ArrayList<>(rm.getRanks().keySet())); + return Optional.of(new ArrayList<>(RanksManager.getInstance().getRanks().keySet())); } return Optional.empty(); 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 528e5c433..09f79feb8 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/Island.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/Island.java @@ -658,9 +658,6 @@ public class Island implements DataObject, MetaDataAble { * @return rank integer */ public int getRank(User user) { - if (user.isOp()) { - return RanksManager.ADMIN_RANK; - } return members.getOrDefault(user.getUniqueId(), RanksManager.VISITOR_RANK); } 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 5e64c9f5d..3cf06d2c0 100644 --- a/src/main/java/world/bentobox/bentobox/database/objects/Players.java +++ b/src/main/java/world/bentobox/bentobox/database/objects/Players.java @@ -298,7 +298,7 @@ public class Players implements DataObject, MetaDataAble { * @param world - world */ public void addReset(World world) { - resets.merge(world.getName(), 1, Integer::sum); + resets.merge(world.getName(), 1, (oldValue, newValue) -> Integer.valueOf(oldValue + newValue)); } /** 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 0668f4a3b..2368c62f7 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 @@ -38,20 +38,19 @@ public class CommandCycleClick implements ClickHandler { World world = panel.getWorld().orElse(user.getWorld()); Island island = plugin.getIslands().getIsland(world, user.getUniqueId()); if (island != null && island.getOwner() != null && island.isAllowed(user, Flags.CHANGE_SETTINGS)) { - RanksManager rm = plugin.getRanksManager(); int currentRank = island.getRankCommand(command); if (click.equals(ClickType.LEFT)) { if (currentRank == RanksManager.OWNER_RANK) { island.setRankCommand(command, RanksManager.MEMBER_RANK); } else { - island.setRankCommand(command, rm.getRankUpValue(currentRank)); + island.setRankCommand(command, RanksManager.getInstance().getRankUpValue(currentRank)); } user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1F, 1F); } else if (click.equals(ClickType.RIGHT)) { if (currentRank == RanksManager.MEMBER_RANK) { island.setRankCommand(command, RanksManager.OWNER_RANK); } else { - island.setRankCommand(command, rm.getRankDownValue(currentRank)); + island.setRankCommand(command, RanksManager.getInstance().getRankDownValue(currentRank)); } user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1F, 1F); } diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandRankClickListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandRankClickListener.java index 766d3ce68..352b31370 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandRankClickListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandRankClickListener.java @@ -66,7 +66,7 @@ public class CommandRankClickListener implements ClickHandler { // Check if user has rank enough on the island //Island island = plugin.getIslands().getIsland(panel.getWorld().orElse(user.getWorld()), user.getUniqueId()); if (!island.isAllowed(user, Flags.CHANGE_SETTINGS)) { - String rank = user.getTranslation(plugin.getRanksManager().getRank(Objects.requireNonNull(island).getRank(user))); + String rank = user.getTranslation(RanksManager.getInstance().getRank(Objects.requireNonNull(island).getRank(user))); user.sendMessage("general.errors.insufficient-rank", TextVariables.RANK, rank); user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F); return true; @@ -114,7 +114,7 @@ public class CommandRankClickListener implements ClickHandler { // TODO: use specific layout String d = user.getTranslation("protection.panel.flag-item.description-layout", TextVariables.DESCRIPTION, ""); pib.description(d); - plugin.getRanksManager().getRanks().forEach((reference, score) -> { + RanksManager.getInstance().getRanks().forEach((reference, score) -> { if (score >= RanksManager.MEMBER_RANK && score < island.getRankCommand(c)) { pib.description(user.getTranslation("protection.panel.flag-item.blocked-rank") + user.getTranslation(reference)); } else if (score <= RanksManager.OWNER_RANK && score > island.getRankCommand(c)) { diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/LockAndBanListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/LockAndBanListener.java index ad20ba54b..6a41cb2ca 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/LockAndBanListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/LockAndBanListener.java @@ -162,7 +162,10 @@ public class LockAndBanListener extends FlagListener { } else { // There's nothing much we can do. // We'll try to teleport him to the spawn... - PaperLib.teleportAsync(player, player.getWorld().getSpawnLocation()); + Location l = player.getWorld().getSpawnLocation(); + if (l != null) { + PaperLib.teleportAsync(player, l); + } // Switch him back to the default gamemode. He may die, sorry :( player.setGameMode(getIWM().getDefaultGameMode(player.getWorld())); diff --git a/src/main/java/world/bentobox/bentobox/lists/GameModePlaceholder.java b/src/main/java/world/bentobox/bentobox/lists/GameModePlaceholder.java index 54e91288c..06662819f 100644 --- a/src/main/java/world/bentobox/bentobox/lists/GameModePlaceholder.java +++ b/src/main/java/world/bentobox/bentobox/lists/GameModePlaceholder.java @@ -289,7 +289,9 @@ public enum GameModePlaceholder { * Returns the rank this player has on his island. * @since 1.5.0 */ - RANK("rank", (addon, user, island) -> (island == null || user == null) ? "" : user.getTranslation(addon.getPlugin().getRanksManager().getRank(island.getRank(user)))), + RANK("rank", + (addon, user, island) -> (island == null || user == null) ? "" + : user.getTranslation(RanksManager.getInstance().getRank(island.getRank(user)))), /** * Returns how many times this player reset his island. * @since 1.5.0 diff --git a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java index 595b7f54c..55ad2d68b 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java @@ -1116,7 +1116,7 @@ public class IslandsManager { .ifFail(() -> goingHome.remove(user.getUniqueId())).buildFuture().thenAccept(result::complete); return; } - PaperLib.teleportAsync(player, home).thenAccept(b -> { + PaperLib.teleportAsync(Objects.requireNonNull(player), home).thenAccept(b -> { // Only run the commands if the player is successfully teleported if (Boolean.TRUE.equals(b)) { teleported(world, user, name, newIsland, island); @@ -1512,7 +1512,12 @@ public class IslandsManager { // Move player to spawn if (spawn.containsKey(w)) { // go to island spawn - PaperLib.teleportAsync(p, spawn.get(w).getSpawnPoint(w.getEnvironment())); + 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!"); + } } } }); @@ -1925,7 +1930,7 @@ public class IslandsManager { Island highestIsland = null; for (Island i : en.getValue()) { int rankValue = i.getRank(en.getKey()); - String rank = plugin.getRanksManager().getRank(rankValue); + String rank = RanksManager.getInstance().getRank(rankValue); if (rankValue > highestRank || highestIsland == null) { highestRank = rankValue; highestIsland = i; @@ -1937,7 +1942,7 @@ public class IslandsManager { } // Fix island ownership in cache // Correct island cache - if (highestRank == RanksManager.OWNER_RANK + if (highestRank == RanksManager.OWNER_RANK && highestIsland != null && islandCache.getIslandById(highestIsland.getUniqueId()) != null) { islandCache.setOwner(islandCache.getIslandById(highestIsland.getUniqueId()), en.getKey()); } diff --git a/src/main/java/world/bentobox/bentobox/managers/PlaceholdersManager.java b/src/main/java/world/bentobox/bentobox/managers/PlaceholdersManager.java index 20e9ad2b5..8917e61e2 100644 --- a/src/main/java/world/bentobox/bentobox/managers/PlaceholdersManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/PlaceholdersManager.java @@ -95,7 +95,7 @@ public class PlaceholdersManager { int j = 1; for (UUID uuid : island.getMemberSet(RanksManager.MEMBER_RANK)) { if (j++ == count) { - return user.getTranslationOrNothing(plugin.getRanksManager().getRank(island.getRank(uuid))); + return user.getTranslationOrNothing(RanksManager.getInstance().getRank(island.getRank(uuid))); } } } @@ -140,7 +140,7 @@ public class PlaceholdersManager { int j = 1; for (UUID uuid : island.getMemberSet(RanksManager.MEMBER_RANK)) { if (j++ == count) { - return user.getTranslationOrNothing(plugin.getRanksManager().getRank(island.getRank(uuid))); + return user.getTranslationOrNothing(RanksManager.getInstance().getRank(island.getRank(uuid))); } } return ""; diff --git a/src/main/java/world/bentobox/bentobox/managers/RanksManager.java b/src/main/java/world/bentobox/bentobox/managers/RanksManager.java index fe5009f37..002569326 100644 --- a/src/main/java/world/bentobox/bentobox/managers/RanksManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/RanksManager.java @@ -41,16 +41,32 @@ public class RanksManager { public static final int BANNED_RANK = -1; // The store of ranks - private LinkedHashMap ranks = new LinkedHashMap<>(); + private static LinkedHashMap ranks = new LinkedHashMap<>(); public static final Map DEFAULT_RANKS = Map.of(ADMIN_RANK_REF, ADMIN_RANK, MOD_RANK_REF, MOD_RANK, OWNER_RANK_REF, OWNER_RANK, SUB_OWNER_RANK_REF, SUB_OWNER_RANK, MEMBER_RANK_REF, MEMBER_RANK, TRUSTED_RANK_REF, TRUSTED_RANK, COOP_RANK_REF, COOP_RANK, VISITOR_RANK_REF, VISITOR_RANK, BANNED_RANK_REF, BANNED_RANK); @NonNull - private Database handler; + private static Database handler; + private static RanksManager instance; - public RanksManager() { + // Private constructor for singleton + private RanksManager() { + handler = new Database<>(BentoBox.getInstance(), Ranks.class); + ranks = new LinkedHashMap<>(); + loadRanksFromDatabase(); + } + + // Public method to get the singleton instance + public static synchronized RanksManager getInstance() { + if (instance == null) { + instance = new RanksManager(); + } + return instance; + } + + public void loadRanksFromDatabase() { // Set up the database handler to store and retrieve Island classes handler = new Database<>(BentoBox.getInstance(), Ranks.class); if (!handler.objectExists(Ranks.ID)) { @@ -59,7 +75,8 @@ public class RanksManager { handler.saveObject(new Ranks(ranks)); } else { // Load the ranks from the database - Objects.requireNonNull(handler.loadObject(Ranks.ID)).getRankReference().forEach(this::ranksPut); + Objects.requireNonNull(handler.loadObject(Ranks.ID)).getRankReference() + .forEach((rankRef, rankValue) -> ranksPut(rankRef, rankValue)); } } diff --git a/src/main/java/world/bentobox/bentobox/util/DefaultPasteUtil.java b/src/main/java/world/bentobox/bentobox/util/DefaultPasteUtil.java index 85f7c78c1..e616e35a3 100644 --- a/src/main/java/world/bentobox/bentobox/util/DefaultPasteUtil.java +++ b/src/main/java/world/bentobox/bentobox/util/DefaultPasteUtil.java @@ -131,7 +131,7 @@ public class DefaultPasteUtil { Inventory ih = holder.getInventory(); // Double chests are pasted as two blocks so inventory is filled twice. // This code stops over-filling for the first block. - bpBlock.getInventory().forEach(ih::setItem); + bpBlock.getInventory().forEach((slot, item) -> ih.setItem(slot, item)); } // Mob spawners else if (bs instanceof CreatureSpawner spawner) { diff --git a/src/main/java/world/bentobox/bentobox/util/IslandInfo.java b/src/main/java/world/bentobox/bentobox/util/IslandInfo.java index d59d63638..cb5e4e4e8 100644 --- a/src/main/java/world/bentobox/bentobox/util/IslandInfo.java +++ b/src/main/java/world/bentobox/bentobox/util/IslandInfo.java @@ -169,11 +169,11 @@ public class IslandInfo { if (owner.equals(u)) { user.sendMessage("commands.admin.info.team-owner-format", TextVariables.NAME, plugin.getPlayers().getName(u), "[rank]", - user.getTranslation(plugin.getRanksManager().getRank(i))); + user.getTranslation(RanksManager.getInstance().getRank(i))); } else if (i > RanksManager.VISITOR_RANK) { user.sendMessage("commands.admin.info.team-member-format", TextVariables.NAME, plugin.getPlayers().getName(u), "[rank]", - user.getTranslation(plugin.getRanksManager().getRank(i))); + user.getTranslation(RanksManager.getInstance().getRank(i))); } }); } diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index f8bca0808..2a0bb2db4 100644 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -108,8 +108,7 @@ commands: status: description: displays the status of the purge status: '&b [purged] &a islands purged out of &b [purgeable] &7(&b[percentage] - %&7)&a.' - + %&7)&a.' team: description: manage teams add: @@ -612,7 +611,41 @@ commands: description: reset your island name success: '&a Successfully reset your island name.' team: - description: manage your team + description: "manage your team" + gui: + titles: + team-panel: "Team Management" + buttons: + status: + name: "Status" + description: "The status of the team" + rank-filter: + name: "Rank Filter" + description: "&a Click to cycle ranks" + invitation: "Invitation" + invite: + name: "Invite player" + description: | + &a Players must be in the + &a same world as you to be + &a shown in the list. + tips: + LEFT: + name: "&b Left Click" + invite: "&a to invite a player" + RIGHT: + name: "&b Right Click" + SHIFT_RIGHT: + name: "&b Shift Right Click" + reject: "&a to reject" + kick: "&a to kick player" + leave: "&a to leave team" + SHIFT_LEFT: + name: "&b Shift Left Click" + accept: "&a to accept " + setowner: | + &a to set owner + &a to this player info: description: display detailed info about your team member-layout: @@ -678,6 +711,30 @@ commands: to-accept-or-reject: '&a Do /[label] team accept to accept, or /[label] team reject to reject' you-will-lose-your-island: '&c WARNING! You will lose your island if you accept!' + gui: + titles: + team-invite-panel: "Invite Players" + button: + already-invited: "&c Invited already" + search: "&a Search for a player" + searching: | + &b Searching for + &c [name] + enter-name: "&a Enter name:" + tips: + LEFT: + name: "&b Left Click" + search: "&a Enter the player's name" + back: "&a Back" + invite: | + &a to invite a player + &a to join your team + RIGHT: + name: "&b Right Click" + coop: "&a to coop player" + SHIFT_LEFT: + name: "&b Shift Left Click" + trust: "&a to trust a player" errors: cannot-invite-self: '&c You cannot invite yourself!' cooldown: '&c You cannot invite that person for another [number] seconds.' diff --git a/src/main/resources/panels/team_invite_panel.yml b/src/main/resources/panels/team_invite_panel.yml new file mode 100644 index 000000000..7be5de6a0 --- /dev/null +++ b/src/main/resources/panels/team_invite_panel.yml @@ -0,0 +1,144 @@ +# Name of panel used for indentification in the code - must be the same name as the filename. +team_invite_panel: + # Title of the panel shown to the user. This is a reference and the reference will be translatable in the locale file + title: commands.island.team.invite.gui.titles.team-invite-panel + # The type of panel to show. Options are INVENTORY, HOPPER, DROPPER. INVENTORY is that standard chest inventory and + # the others refer to the inventories shown for those items. + type: INVENTORY + # The background of the panel. These items will be shown if other items are not there. STAINED_GLASS_PANEs give a good effect. + background: + icon: BLACK_STAINED_GLASS_PANE + # Each item may have text applied to it, but usually for background items, nothing is shown. + title: "&b&r" # Empty text. This is using the Bukkit chat color coding with &'s. + border: + # The border of each panel may be shown as a different item. + # It can be used to provide a contrast to items in the panel. + icon: BLUE_STAINED_GLASS_PANE + title: "&b&r" # Empty text + # This tag indicates which rows in the panel must be shown. The panel will be sized vertically accordingly. This does not include the borders. + # This can be a list and rows must be between 1 and 6, if used. + force-shown: [] + # The content section contains details of each item/button in the panel. The numbers indicate the rows and then then columns of each item. + content: + # Row number + 1: + 2: + title: "protection.panel.previous" + icon: ARROW + data: + type: PREVIOUS + # Actions cover what happens if the button is clicked or the mouse is moved over it. There can be multiple actions possible for different + # click-types. + actions: + # Each action has an arbitrary descriptive name to define it. + view: + # The click-type is the same as the bukkit {@link org.bukkit.event.inventory.ClickType}. UNKNOWN is the default. + click-type: LEFT + # tooltip is a locale reference that will be translated for the user and shown when they hover over the button. + tooltip: commands.island.team.invite.gui.tips.previous + 5: + title: "commands.island.team.invite.gui.button.search" + description: "commands.island.team.invite.gui.button.searching" + icon: PLAYER_HEAD + data: + type: SEARCH + actions: + search: + click-type: LEFT + tooltip: commands.island.team.invite.gui.tips.search + 8: + title: "protection.panel.next" + icon: ARROW + data: + type: NEXT + # Actions cover what happens if the button is clicked or the mouse is moved over it. There can be multiple actions possible for different + # click-types. + actions: + # Each action has an arbitrary descriptive name to define it. + view: + # The click-type is the same as the bukkit {@link org.bukkit.event.inventory.ClickType}. UNKNOWN is the default. + click-type: LEFT + # tooltip is a locale reference that will be translated for the user and shown when they hover over the button. + tooltip: commands.island.team.invite.gui.tips.next + 2: + 2: prospect_button + 3: prospect_button + 4: prospect_button + 5: prospect_button + 6: prospect_button + 7: prospect_button + 8: prospect_button + 3: + 2: prospect_button + 3: prospect_button + 4: prospect_button + 5: prospect_button + 6: prospect_button + 7: prospect_button + 8: prospect_button + 4: + 2: prospect_button + 3: prospect_button + 4: prospect_button + 5: prospect_button + 6: prospect_button + 7: prospect_button + 8: prospect_button + 5: + 2: prospect_button + 3: prospect_button + 4: prospect_button + 5: prospect_button + 6: prospect_button + 7: prospect_button + 8: prospect_button + 6: + 2: prospect_button + 3: prospect_button + 4: prospect_button + 5: prospect_button + 6: prospect_button + 7: prospect_button + 8: prospect_button + 9: + title: "commands.island.team.invite.gui.tips.LEFT.back" + icon: OAK_DOOR + data: + type: BACK + # Actions cover what happens if the button is clicked or the mouse is moved over it. There can be multiple actions possible for different + # click-types. + actions: + # Each action has an arbitrary descriptive name to define it. + back: + # The click-type is the same as the bukkit {@link org.bukkit.event.inventory.ClickType}. UNKNOWN is the default. + click-type: LEFT + # tooltip is a locale reference that will be translated for the user and shown when they hover over the button. + tooltip: commands.island.team.invite.gui.tips.LEFT.back + + # This is where reusable buttons are defined. + reusable: + # This is the name of the button that is referenced + prospect_button: + # If the icon for a button is not defined, it defaults to AIR and so effectively will not be shown. + # icons are usually not defined if the icon is going to be dynamically set in the panel, e.g. in this case the material will vary + #icon: STONE + title: commands.island.team.invite.gui.buttons.member.name + description: commands.island.team.invite.gui.buttons.member.description + data: + type: PROSPECT + # Actions cover what happens if the button is clicked or the mouse is moved over it. There can be multiple actions possible for different + # click-types. + actions: + # Each action has an arbitrary descriptive name to define it. + invite: + # The click-type is the same as the bukkit {@link org.bukkit.event.inventory.ClickType}. UNKNOWN is the default. + click-type: LEFT + # tooltip is a locale reference that will be translated for the user and shown when they hover over the button. + tooltip: commands.island.team.invite.gui.tips.LEFT.invite + coop: + click-type: RIGHT + tooltip: commands.island.team.invite.gui.tips.RIGHT.coop + trust: + click-type: SHIFT_LEFT + tooltip: commands.island.team.invite.gui.tips.SHIFT_LEFT.trust + \ No newline at end of file diff --git a/src/main/resources/panels/team_panel.yml b/src/main/resources/panels/team_panel.yml new file mode 100644 index 000000000..c34deb8d4 --- /dev/null +++ b/src/main/resources/panels/team_panel.yml @@ -0,0 +1,139 @@ +# Name of panel used for indentification in the code - must be the same name as the filename. +team_panel: + # Title of the panel shown to the user. This is a reference and the reference will be translatable in the locale file + title: commands.island.team.gui.titles.team-panel + # The type of panel to show. Options are INVENTORY, HOPPER, DROPPER. INVENTORY is that standard chest inventory and + # the others refer to the inventories shown for those items. + type: INVENTORY + # The background of the panel. These items will be shown if other items are not there. STAINED_GLASS_PANEs give a good effect. + background: + icon: BLACK_STAINED_GLASS_PANE + # Each item may have text applied to it, but usually for background items, nothing is shown. + title: "&b&r" # Empty text. This is using the Bukkit chat color coding with &'s. + border: + # The border of each panel may be shown as a different item. + # It can be used to provide a contrast to items in the panel. + icon: BLUE_STAINED_GLASS_PANE + title: "&b&r" # Empty text + # This tag indicates which rows in the panel must be shown. The panel will be sized vertically accordingly. This does not include the borders. + # This can be a list and rows must be between 1 and 6, if used. + force-shown: [] + # The content section contains details of each item/button in the panel. The numbers indicate the rows and then then columns of each item. + content: + # Row number + 1: + # Column number + 1: + # The data section is a key-value list of data relavent for this button. It is interpreted by the code implemented the panel. + # The convention is to specify the type and the panel tab that will open if pressed. These are Enums in the code. + data: + type: STATUS + # Actions cover what happens if the button is clicked or the mouse is moved over it. There can be multiple actions possible for different + # click-types. + actions: + # Each action has an arbitrary descriptive name to define it. + view: + # The click-type is the same as the bukkit {@link org.bukkit.event.inventory.ClickType}. UNKNOWN is the default. + click-type: UNKNOWN + # tooltip is a locale reference that will be translated for the user and shown when they hover over the button. + tooltip: commands.island.team.gui.tips.click-to-view + 3: + # Rank filter + data: + type: RANK + name: commands.island.team.gui.buttons.rank-filter + actions: + cycle-up: + click-type: LEFT + tooltip: commands.island.team.gui.tips.right-click.rank + cycle-down: + click-type: RIGHT + tooltip: commands.island.team.gui.tips.right-click.rank + 5: + # Invited button - this appears if you have been invited to join a team + data: + type: INVITED + name: commands.island.team.gui.buttons.invited + actions: + accept: + click-type: SHIFT_LEFT + tooltip: commands.island.team.gui.tips.SHIFT_LEFT.accept + reject: + click-type: SHIFT_RIGHT + tooltip: commands.island.team.gui.tips.SHIFT_RIGHT.reject + 7: + # Invite button + data: + type: INVITE + name: commands.island.team.gui.buttons.invite + actions: + invite: + click-type: LEFT + tooltip: commands.island.team.gui.tips.LEFT.invite + 2: + 2: member_button + 3: member_button + 4: member_button + 5: member_button + 6: member_button + 7: member_button + 8: member_button + 3: + 2: member_button + 3: member_button + 4: member_button + 5: member_button + 6: member_button + 7: member_button + 8: member_button + 4: + 2: member_button + 3: member_button + 4: member_button + 5: member_button + 6: member_button + 7: member_button + 8: member_button + 5: + 2: member_button + 3: member_button + 4: member_button + 5: member_button + 6: member_button + 7: member_button + 8: member_button + 6: + 2: member_button + 3: member_button + 4: member_button + 5: member_button + 6: member_button + 7: member_button + 8: member_button + # This is where reusable buttons are defined. + reusable: + # This is the name of the button that is referenced + member_button: + # If the icon for a button is not defined, it defaults to AIR and so effectively will not be shown. + # icons are usually not defined if the icon is going to be dynamically set in the panel, e.g. in this case the material will vary + #icon: STONE + title: commands.island.team.gui.buttons.member.name + description: commands.island.team.gui.buttons.member.description + data: + type: MEMBER + # Actions cover what happens if the button is clicked or the mouse is moved over it. There can be multiple actions possible for different + # click-types. + actions: + # Each action has an arbitrary descriptive name to define it. + kick: + # The click-type is the same as the bukkit {@link org.bukkit.event.inventory.ClickType}. UNKNOWN is the default. + click-type: SHIFT_RIGHT + # tooltip is a locale reference that will be translated for the user and shown when they hover over the button. + tooltip: commands.island.team.gui.tips.SHIFT_RIGHT.kick + leave: + click-type: SHIFT_RIGHT + tooltip: commands.island.team.gui.tips.SHIFT_RIGHT.leave + setowner: + click-type: SHIFT_LEFT + tooltip: commands.island.team.gui.tips.SHIFT_LEFT.setowner + \ No newline at end of file diff --git a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminGetrankCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminGetrankCommandTest.java index 85402082b..8acac9556 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminGetrankCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminGetrankCommandTest.java @@ -47,7 +47,7 @@ import world.bentobox.bentobox.util.Util; * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({Bukkit.class, BentoBox.class, User.class }) +@PrepareForTest({ Bukkit.class, BentoBox.class, User.class, RanksManager.class }) public class AdminGetrankCommandTest { private static final String[] NAMES = {"adam", "ben", "cara", "dave", "ed", "frank", "freddy", "george", "harry", "ian", "joe"}; @@ -80,7 +80,8 @@ public class AdminGetrankCommandTest { Util.setPlugin(plugin); // Ranks Manager - when(plugin.getRanksManager()).thenReturn(rm); + PowerMockito.mockStatic(RanksManager.class, Mockito.RETURNS_MOCKS); + when(RanksManager.getInstance()).thenReturn(rm); // Players Manager when(plugin.getPlayers()).thenReturn(pm); 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 b2e9c9938..85830a653 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 @@ -43,7 +43,6 @@ import world.bentobox.bentobox.managers.IslandsManager; import world.bentobox.bentobox.managers.LocalesManager; import world.bentobox.bentobox.managers.PlaceholdersManager; import world.bentobox.bentobox.managers.PlayersManager; -import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.managers.RanksManagerBeforeClassTest; import world.bentobox.bentobox.util.Util; @@ -87,8 +86,6 @@ public class AdminInfoCommandTest extends RanksManagerBeforeClassTest { // IWM when(plugin.getIWM()).thenReturn(iwm); - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); // Bukkit PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS); @@ -193,7 +190,7 @@ public class AdminInfoCommandTest extends RanksManagerBeforeClassTest { verify(user).sendMessage("commands.admin.info.deaths", "[number]", "0"); verify(user).sendMessage("commands.admin.info.resets-left", "[number]", "0", "[total]", "0"); verify(user).sendMessage("commands.admin.info.team-members-title"); - verify(user).sendMessage("commands.admin.info.team-owner-format", "[name]", null, "[rank]", "ranks.owner"); + verify(user).sendMessage("commands.admin.info.team-owner-format", "[name]", null, "[rank]", ""); verify(user).sendMessage("commands.admin.info.island-protection-center", "[xyz]", "0,0,0"); verify(user).sendMessage("commands.admin.info.island-center", "[xyz]", "0,0,0"); verify(user).sendMessage("commands.admin.info.island-coords", "[xz1]", "-400,0,-400", "[xz2]", "400,0,400"); @@ -215,7 +212,7 @@ public class AdminInfoCommandTest extends RanksManagerBeforeClassTest { verify(user).sendMessage("commands.admin.info.deaths", "[number]", "0"); verify(user).sendMessage("commands.admin.info.resets-left", "[number]", "0", "[total]", "0"); verify(user).sendMessage("commands.admin.info.team-members-title"); - verify(user).sendMessage("commands.admin.info.team-owner-format", "[name]", null, "[rank]", "ranks.owner"); + verify(user).sendMessage("commands.admin.info.team-owner-format", "[name]", null, "[rank]", ""); verify(user).sendMessage("commands.admin.info.island-protection-center", "[xyz]", "0,0,0"); verify(user).sendMessage("commands.admin.info.island-center", "[xyz]", "0,0,0"); verify(user).sendMessage("commands.admin.info.island-coords", "[xz1]", "-400,0,-400", "[xz2]", "400,0,400"); diff --git a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminSetrankCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminSetrankCommandTest.java index 4598eb61a..4dc8c42e8 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminSetrankCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/admin/AdminSetrankCommandTest.java @@ -5,7 +5,6 @@ import static org.junit.Assert.assertFalse; 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.verify; import static org.mockito.Mockito.when; @@ -57,7 +56,6 @@ public class AdminSetrankCommandTest extends RanksManagerBeforeClassTest { @Mock private PlayersManager pm; - private RanksManager rm; private AdminSetrankCommand c; private UUID targetUUID; @@ -71,10 +69,6 @@ public class AdminSetrankCommandTest extends RanksManagerBeforeClassTest { super.setUp(); Util.setPlugin(plugin); - // Ranks Manager - rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - // Players Manager when(plugin.getPlayers()).thenReturn(pm); @@ -212,8 +206,7 @@ public class AdminSetrankCommandTest extends RanksManagerBeforeClassTest { when(im.getIsland(any(), any(UUID.class))).thenReturn(island); when(island.getCenter()).thenReturn(location); assertTrue(c.execute(user, "", Arrays.asList("tastybento", "member"))); - verify(user).sendMessage(eq("commands.admin.setrank.rank-set"), eq("[from]"), eq("ranks.sub-owner"), eq("[to]"), - eq("ranks.member"), eq("[name]"), eq(null)); + verify(user).sendMessage("commands.admin.setrank.rank-set", "[from]", "", "[to]", "", "[name]", null); } /** 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 ce4ff839c..c22fc6c60 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 @@ -52,7 +52,6 @@ import world.bentobox.bentobox.managers.IslandWorldManager; import world.bentobox.bentobox.managers.IslandsManager; import world.bentobox.bentobox.managers.LocalesManager; import world.bentobox.bentobox.managers.PlayersManager; -import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.managers.RanksManagerBeforeClassTest; import world.bentobox.bentobox.util.Util; @@ -176,10 +175,6 @@ public class AdminSettingsCommandTest extends RanksManagerBeforeClassTest { FlagsManager fm = new FlagsManager(plugin); when(plugin.getFlagsManager()).thenReturn(fm); - // RnksManager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - asc = new AdminSettingsCommand(ac); } 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 6a9914c27..385da6c85 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 @@ -32,7 +32,6 @@ import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.managers.CommandsManager; import world.bentobox.bentobox.managers.IslandsManager; -import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.managers.RanksManagerBeforeClassTest; /** @@ -69,11 +68,6 @@ public class DefaultPlayerCommandTest extends RanksManagerBeforeClassTest { @Before public void setUp() throws Exception { super.setUp(); - // RanksManager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - - // Addon // User when(user.getUniqueId()).thenReturn(UUID.randomUUID()); diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandBanCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandBanCommandTest.java index 90bf41fd5..caa41dae7 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandBanCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandBanCommandTest.java @@ -165,10 +165,6 @@ public class IslandBanCommandTest extends RanksManagerBeforeClassTest { when(targetPlayer.hasPermission(anyString())).thenReturn(false); User.getInstance(targetPlayer); - // Ranks Manager - rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - // Island Ban Command ibc = new IslandBanCommand(ic); @@ -212,7 +208,7 @@ public class IslandBanCommandTest extends RanksManagerBeforeClassTest { when(island.getRank(any(User.class))).thenReturn(RanksManager.MEMBER_RANK); when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); assertFalse(ibc.canExecute(user, ibc.getLabel(), Collections.singletonList("bill"))); - verify(user).sendMessage(eq("general.errors.insufficient-rank"), eq(TextVariables.RANK), eq("ranks.member")); + verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, ""); } @Test diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandBanlistCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandBanlistCommandTest.java index 5837243e4..5e10b916a 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandBanlistCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandBanlistCommandTest.java @@ -116,10 +116,6 @@ public class IslandBanlistCommandTest extends RanksManagerBeforeClassTest { when(iwm.getFriendlyName(any())).thenReturn("BSkyBlock"); when(plugin.getIWM()).thenReturn(iwm); - // Ranks Manager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - } /** @@ -155,7 +151,7 @@ public class IslandBanlistCommandTest extends RanksManagerBeforeClassTest { when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); IslandBanlistCommand iubc = new IslandBanlistCommand(ic); assertFalse(iubc.canExecute(user, iubc.getLabel(), Collections.emptyList())); - verify(user).sendMessage(eq("general.errors.insufficient-rank"), eq(TextVariables.RANK), eq("ranks.member")); + verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, ""); } /** diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandDeletehomeCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandDeletehomeCommandTest.java index f6bda8d97..738101e7d 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandDeletehomeCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandDeletehomeCommandTest.java @@ -84,10 +84,6 @@ public class IslandDeletehomeCommandTest extends RanksManagerBeforeClassTest { CommandsManager cm = mock(CommandsManager.class); when(plugin.getCommandsManager()).thenReturn(cm); - // Ranks Manager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - // Addon GameModeAddon addon = mock(GameModeAddon.class); @@ -192,8 +188,7 @@ public class IslandDeletehomeCommandTest extends RanksManagerBeforeClassTest { when(island.getRank(user)).thenReturn(RanksManager.COOP_RANK); when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); assertFalse(idh.canExecute(user, "label", List.of("something"))); - verify(user).sendMessage("general.errors.insufficient-rank", - TextVariables.RANK, "ranks.coop"); + verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, ""); } /** diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandExpelCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandExpelCommandTest.java index 808f7d551..941a19ae5 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandExpelCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandExpelCommandTest.java @@ -158,10 +158,6 @@ public class IslandExpelCommandTest extends RanksManagerBeforeClassTest { when(plugin.getPlaceholdersManager()).thenReturn(placeholdersManager); when(placeholdersManager.replacePlaceholders(any(), any())).thenAnswer(answer); - // Ranks Manager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - // Class iec = new IslandExpelCommand(ic); } @@ -248,7 +244,7 @@ public class IslandExpelCommandTest extends RanksManagerBeforeClassTest { when(island.getRank(any(User.class))).thenReturn(RanksManager.VISITOR_RANK); when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); assertFalse(iec.canExecute(user, "", Collections.singletonList("tasty"))); - verify(user).sendMessage(eq("general.errors.insufficient-rank"), eq(TextVariables.RANK), eq("ranks.visitor")); + verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, ""); } /** 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 a7a1b5ec9..964d9fbea 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 @@ -43,7 +43,6 @@ import world.bentobox.bentobox.managers.IslandsManager; import world.bentobox.bentobox.managers.LocalesManager; import world.bentobox.bentobox.managers.PlaceholdersManager; import world.bentobox.bentobox.managers.PlayersManager; -import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.managers.RanksManagerBeforeClassTest; import world.bentobox.bentobox.util.Util; @@ -87,8 +86,6 @@ public class IslandInfoCommandTest extends RanksManagerBeforeClassTest { // IWM when(plugin.getIWM()).thenReturn(iwm); - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); // Bukkit PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS); @@ -189,7 +186,7 @@ public class IslandInfoCommandTest extends RanksManagerBeforeClassTest { verify(user).sendMessage("commands.admin.info.deaths", "[number]", "0"); verify(user).sendMessage("commands.admin.info.resets-left", "[number]", "0", "[total]", "0"); verify(user).sendMessage("commands.admin.info.team-members-title"); - verify(user).sendMessage("commands.admin.info.team-owner-format", "[name]", null, "[rank]", "ranks.owner"); + verify(user).sendMessage("commands.admin.info.team-owner-format", "[name]", null, "[rank]", ""); verify(user).sendMessage("commands.admin.info.island-center", "[xyz]", "0,0,0"); verify(user).sendMessage("commands.admin.info.protection-range", "[range]", "100"); verify(user).sendMessage("commands.admin.info.protection-coords", "[xz1]", "-100,0,-100", "[xz2]", "99,0,99"); @@ -206,7 +203,7 @@ public class IslandInfoCommandTest extends RanksManagerBeforeClassTest { verify(user).sendMessage("commands.admin.info.deaths", "[number]", "0"); verify(user).sendMessage("commands.admin.info.resets-left", "[number]", "0", "[total]", "0"); verify(user).sendMessage("commands.admin.info.team-members-title"); - verify(user).sendMessage("commands.admin.info.team-owner-format", "[name]", null, "[rank]", "ranks.owner"); + verify(user).sendMessage("commands.admin.info.team-owner-format", "[name]", null, "[rank]", ""); verify(user).sendMessage("commands.admin.info.island-center", "[xyz]", "0,0,0"); verify(user).sendMessage("commands.admin.info.protection-range", "[range]", "100"); verify(user).sendMessage("commands.admin.info.protection-coords", "[xz1]", "-100,0,-100", "[xz2]", "99,0,99"); diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandSetnameCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandSetnameCommandTest.java index bdc919f7d..95d5e2bcd 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandSetnameCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandSetnameCommandTest.java @@ -137,11 +137,6 @@ public class IslandSetnameCommandTest { // Placeholder manager when(plugin.getPlaceholdersManager()).thenReturn(phm); - // Ranks Manager - rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - - // Test isc = new IslandSetnameCommand(ic); } diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandUnbanCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandUnbanCommandTest.java index cd4ed25cc..85d8db84c 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/IslandUnbanCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/IslandUnbanCommandTest.java @@ -125,10 +125,6 @@ public class IslandUnbanCommandTest extends RanksManagerBeforeClassTest { PluginManager pim = mock(PluginManager.class); when(Bukkit.getPluginManager()).thenReturn(pim); - // Ranks Manager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - } /** @@ -173,7 +169,7 @@ public class IslandUnbanCommandTest extends RanksManagerBeforeClassTest { when(island.getRank(any(User.class))).thenReturn(RanksManager.MEMBER_RANK); when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); assertFalse(iubc.canExecute(user, iubc.getLabel(), Collections.singletonList("bill"))); - verify(user).sendMessage(eq("general.errors.insufficient-rank"), eq(TextVariables.RANK), eq("ranks.member")); + verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, ""); } /** 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 3f2aa854b..b0f360d80 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 @@ -31,7 +31,6 @@ 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.localization.TextVariables; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.managers.CommandsManager; @@ -123,10 +122,6 @@ public class IslandTeamCommandTest extends RanksManagerBeforeClassTest { when(plugin.getIWM()).thenReturn(iwm); when(iwm.getPermissionPrefix(any())).thenReturn("bskyblock."); - // RanksManager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - // Command under test tc = new IslandTeamCommand(ic); } @@ -153,33 +148,23 @@ public class IslandTeamCommandTest extends RanksManagerBeforeClassTest { } /** - * Test method for {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + * Test method for {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test - public void testExecuteUserStringListOfStringNoIsland() { + public void testCanExecuteUserStringListOfStringNoIsland() { when(im.getPrimaryIsland(world, uuid)).thenReturn(null); - assertFalse(tc.execute(user, "team", Collections.emptyList())); + assertFalse(tc.canExecute(user, "team", Collections.emptyList())); verify(user).sendMessage(eq("general.errors.no-island")); } /** - * Test method for - * {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + * Test method for {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test - public void testExecuteUserStringListOfStringIslandIsNotFull() { - assertTrue(tc.execute(user, "team", Collections.emptyList())); - verify(user).sendMessage(eq("commands.island.team.invite.you-can-invite"), eq(TextVariables.NUMBER), eq("3")); - } - - /** - * Test method for {@link world.bentobox.bentobox.api.commands.island.team.IslandTeamCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testExecuteUserStringListOfStringIslandIsFull() { + public void testCanExecuteUserStringListOfStringIslandIsFull() { // Max members when(im.getMaxMembers(eq(island), eq(RanksManager.MEMBER_RANK))).thenReturn(0); - assertTrue(tc.execute(user, "team", Collections.emptyList())); + assertTrue(tc.canExecute(user, "team", Collections.emptyList())); verify(user).sendMessage(eq("commands.island.team.invite.errors.island-is-full")); } diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCoopCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCoopCommandTest.java index 7b0531e66..955c8e211 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCoopCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCoopCommandTest.java @@ -137,10 +137,6 @@ public class IslandTeamCoopCommandTest extends RanksManagerBeforeClassTest { // Placeholder manager when(plugin.getPlaceholdersManager()).thenReturn(phm); - // Ranks Manager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - } /** @@ -164,7 +160,7 @@ public class IslandTeamCoopCommandTest extends RanksManagerBeforeClassTest { when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); IslandTeamCoopCommand itl = new IslandTeamCoopCommand(ic); assertFalse(itl.canExecute(user, itl.getLabel(), Collections.singletonList("bill"))); - verify(user).sendMessage(eq("general.errors.insufficient-rank"), eq(TextVariables.RANK), eq("ranks.member")); + verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, ""); } /** 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 060a1dd35..706a56cb7 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 @@ -11,6 +11,7 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.io.File; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -19,6 +20,10 @@ import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemFactory; +import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.plugin.PluginManager; import org.bukkit.scheduler.BukkitScheduler; import org.eclipse.jdt.annotation.NonNull; @@ -92,6 +97,10 @@ public class IslandTeamInviteCommandTest extends RanksManagerBeforeClassTest { // Settings when(plugin.getSettings()).thenReturn(s); + // Data folder for panels + when(plugin.getDataFolder()) + .thenReturn(new File("src" + File.separator + "main" + File.separator + "resources")); + // Player & users PowerMockito.mockStatic(User.class); @@ -165,9 +174,14 @@ public class IslandTeamInviteCommandTest extends RanksManagerBeforeClassTest { // Parent command when(ic.getTopLabel()).thenReturn("island"); - // Ranks Manager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); + // Mock item factory (for itemstacks) + ItemFactory itemFactory = mock(ItemFactory.class); + ItemMeta bannerMeta = mock(ItemMeta.class); + when(itemFactory.getItemMeta(any())).thenReturn(bannerMeta); + when(Bukkit.getItemFactory()).thenReturn(itemFactory); + Inventory inventory = mock(Inventory.class); + when(Bukkit.createInventory(eq(null), anyInt(), any())).thenReturn(inventory); + when(Bukkit.createInventory(eq(null), any(InventoryType.class), any())).thenReturn(inventory); // Command under test itl = new IslandTeamInviteCommand(ic); @@ -204,7 +218,7 @@ public class IslandTeamInviteCommandTest extends RanksManagerBeforeClassTest { when(island.getRank(any(User.class))).thenReturn(RanksManager.MEMBER_RANK); when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); assertFalse(itl.canExecute(user, itl.getLabel(), List.of("target"))); - verify(user).sendMessage(eq("general.errors.insufficient-rank"), eq(TextVariables.RANK), eq("ranks.member")); + verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, ""); } /** @@ -224,9 +238,9 @@ public class IslandTeamInviteCommandTest extends RanksManagerBeforeClassTest { */ @Test public void testCanExecuteNoTarget() { - assertFalse(itl.canExecute(user, itl.getLabel(), Collections.emptyList())); - // Show help - verify(user).sendMessage("commands.help.header", TextVariables.LABEL, "BSkyBlock"); + assertTrue(itl.canExecute(user, itl.getLabel(), Collections.emptyList())); + // Show panel + verify(p).openInventory(any(Inventory.class)); } /** diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommandTest.java index ceedea473..a1cc1b546 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommandTest.java @@ -7,6 +7,7 @@ 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; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -181,10 +182,6 @@ public class IslandTeamKickCommandTest extends RanksManagerBeforeClassTest { when(island.getMemberSet()).thenReturn(ImmutableSet.of(uuid)); when(island.getRankCommand(anyString())).thenReturn(RanksManager.VISITOR_RANK); - // Ranks Manager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - // Ranks when(island.getRank(uuid)).thenReturn(RanksManager.OWNER_RANK); when(island.getRank(user)).thenReturn(RanksManager.OWNER_RANK); @@ -192,18 +189,18 @@ public class IslandTeamKickCommandTest extends RanksManagerBeforeClassTest { } /** - * Test method for {@link IslandTeamKickCommand#execute(User, String, java.util.List)} + * Test method for {@link IslandTeamKickCommand#canExecute(User, String, java.util.List)} */ @Test public void testExecuteNoTeam() { when(im.inTeam(any(), eq(uuid))).thenReturn(false); IslandTeamKickCommand itl = new IslandTeamKickCommand(ic); - assertFalse(itl.execute(user, itl.getLabel(), Collections.emptyList())); + assertFalse(itl.canExecute(user, itl.getLabel(), Collections.emptyList())); verify(user).sendMessage(eq("general.errors.no-team")); } /** - * Test method for {@link IslandTeamKickCommand#execute(User, String, java.util.List)} + * Test method for {@link IslandTeamKickCommand#canExecute(User, String, java.util.List)} */ @Test public void testExecuteLowerTeamRank() { @@ -216,12 +213,12 @@ public class IslandTeamKickCommandTest extends RanksManagerBeforeClassTest { when(island.getMemberSet()).thenReturn(ImmutableSet.of(notUUID)); IslandTeamKickCommand itl = new IslandTeamKickCommand(ic); - assertFalse(itl.execute(user, itl.getLabel(), Collections.singletonList("poslovitch"))); + assertFalse(itl.canExecute(user, itl.getLabel(), Collections.singletonList("poslovitch"))); verify(user).sendMessage(eq("commands.island.team.kick.cannot-kick-rank"), eq(TextVariables.NAME), eq("poslovitch")); } /** - * Test method for {@link IslandTeamKickCommand#execute(User, String, java.util.List)} + * Test method for {@link IslandTeamKickCommand#canExecute(User, String, java.util.List)} */ @Test public void testExecuteEqualTeamRank() { @@ -234,7 +231,7 @@ public class IslandTeamKickCommandTest extends RanksManagerBeforeClassTest { when(island.getMemberSet()).thenReturn(ImmutableSet.of(notUUID)); IslandTeamKickCommand itl = new IslandTeamKickCommand(ic); - assertFalse(itl.execute(user, itl.getLabel(), Collections.singletonList("poslovitch"))); + assertFalse(itl.canExecute(user, itl.getLabel(), Collections.singletonList("poslovitch"))); verify(user).sendMessage(eq("commands.island.team.kick.cannot-kick-rank"), eq(TextVariables.NAME), eq("poslovitch")); } @@ -258,7 +255,7 @@ public class IslandTeamKickCommandTest extends RanksManagerBeforeClassTest { } /** - * Test method for {@link IslandTeamKickCommand#execute(User, String, java.util.List)} + * Test method for {@link IslandTeamKickCommand#canExecute(User, String, java.util.List)} */ @Test public void testExecuteNoCommandRank() { @@ -266,61 +263,61 @@ public class IslandTeamKickCommandTest extends RanksManagerBeforeClassTest { when(island.getRank(user)).thenReturn(RanksManager.MEMBER_RANK); IslandTeamKickCommand itl = new IslandTeamKickCommand(ic); - assertFalse(itl.execute(user, itl.getLabel(), Collections.emptyList())); - verify(user).sendMessage(eq("general.errors.insufficient-rank"), eq(TextVariables.RANK), eq("ranks.member")); + assertFalse(itl.canExecute(user, itl.getLabel(), Collections.emptyList())); + verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, ""); } /** * Test method for - * {@link IslandTeamKickCommand#execute(User, String, java.util.List)} + * {@link IslandTeamKickCommand#canExecute(User, String, java.util.List)} */ @Test public void testExecuteNoTarget() { IslandTeamKickCommand itl = new IslandTeamKickCommand(ic); - assertFalse(itl.execute(user, itl.getLabel(), Collections.emptyList())); + assertFalse(itl.canExecute(user, itl.getLabel(), Collections.emptyList())); // Show help } /** * Test method for - * {@link IslandTeamKickCommand#execute(User, String, java.util.List)} + * {@link IslandTeamKickCommand#canExecute(User, String, java.util.List)} */ @Test public void testExecuteUnknownPlayer() { IslandTeamKickCommand itl = new IslandTeamKickCommand(ic); when(pm.getUUID(any())).thenReturn(null); - assertFalse(itl.execute(user, itl.getLabel(), Collections.singletonList("poslovitch"))); + assertFalse(itl.canExecute(user, itl.getLabel(), Collections.singletonList("poslovitch"))); verify(user).sendMessage("general.errors.unknown-player", "[name]", "poslovitch"); } /** * Test method for - * {@link IslandTeamKickCommand#execute(User, String, java.util.List)} + * {@link IslandTeamKickCommand#canExecute(User, String, java.util.List)} */ @Test public void testExecuteSamePlayer() { IslandTeamKickCommand itl = new IslandTeamKickCommand(ic); when(pm.getUUID(any())).thenReturn(uuid); - assertFalse(itl.execute(user, itl.getLabel(), Collections.singletonList("poslovitch"))); + assertFalse(itl.canExecute(user, itl.getLabel(), Collections.singletonList("poslovitch"))); verify(user).sendMessage(eq("commands.island.team.kick.cannot-kick")); } /** * Test method for - * {@link IslandTeamKickCommand#execute(User, String, java.util.List)} + * {@link IslandTeamKickCommand#canExecute(User, String, java.util.List)} */ @Test public void testExecuteDifferentPlayerNotInTeam() { IslandTeamKickCommand itl = new IslandTeamKickCommand(ic); when(pm.getUUID(any())).thenReturn(notUUID); // when(im.getMembers(any(), any())).thenReturn(Collections.emptySet()); - assertFalse(itl.execute(user, itl.getLabel(), Collections.singletonList("poslovitch"))); + assertFalse(itl.canExecute(user, itl.getLabel(), Collections.singletonList("poslovitch"))); verify(user).sendMessage(eq("general.errors.not-in-team")); } /** * Test method for - * {@link IslandTeamKickCommand#execute(User, String, java.util.List)} + * {@link IslandTeamKickCommand#canExecute(User, String, java.util.List)} */ @Test public void testExecuteDifferentPlayerNoRank() { @@ -328,8 +325,8 @@ public class IslandTeamKickCommandTest extends RanksManagerBeforeClassTest { when(pm.getUUID(any())).thenReturn(notUUID); when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); when(island.getRank(any(User.class))).thenReturn(RanksManager.VISITOR_RANK); - assertFalse(itl.execute(user, itl.getLabel(), Collections.singletonList("poslovitch"))); - verify(user).sendMessage(eq("general.errors.insufficient-rank"), eq(TextVariables.RANK), eq("ranks.visitor")); + assertFalse(itl.canExecute(user, itl.getLabel(), Collections.singletonList("poslovitch"))); + verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, ""); } /** @@ -368,7 +365,7 @@ public class IslandTeamKickCommandTest extends RanksManagerBeforeClassTest { assertTrue(itl.execute(user, itl.getLabel(), Collections.singletonList("poslovitch"))); verify(im).removePlayer(any(World.class), eq(notUUID)); verify(user).sendMessage("commands.island.team.kick.success", TextVariables.NAME, "poslovitch", TextVariables.DISPLAY_NAME, "&Cposlovich"); - verify(target, Mockito.never()).getInventory(); + verify(target, never()).getInventory(); } diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamPromoteCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamPromoteCommandTest.java index 5482a1bfc..6c58c9dbd 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamPromoteCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamPromoteCommandTest.java @@ -119,9 +119,7 @@ public class IslandTeamPromoteCommandTest extends RanksManagerBeforeClassTest { // In team when(im.inTeam(world, uuid)).thenReturn(true); - // Ranks Manager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); + // Ranks when(island.getRankCommand(anyString())).thenReturn(RanksManager.SUB_OWNER_RANK); // Allow sub owners when(island.getRank(user)).thenReturn(RanksManager.SUB_OWNER_RANK); when(island.getRank(target)).thenReturn(RanksManager.SUB_OWNER_RANK); @@ -194,7 +192,7 @@ public class IslandTeamPromoteCommandTest extends RanksManagerBeforeClassTest { public void testCanExecuteUserStringListOfStringInsufficientRank() { when(island.getRank(user)).thenReturn(RanksManager.MEMBER_RANK); assertFalse(ipc.canExecute(user, "promote", List.of("tastybento"))); - verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, RanksManager.MEMBER_RANK_REF); + verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, ""); } /** @@ -256,10 +254,12 @@ public class IslandTeamPromoteCommandTest extends RanksManagerBeforeClassTest { @Test public void testExecuteUserStringListOfString() { when(island.getRank(target)).thenReturn(RanksManager.MEMBER_RANK); + when(rm.getRankUpValue(RanksManager.MEMBER_RANK)).thenReturn(RanksManager.SUB_OWNER_RANK); ipc.canExecute(user, "promote", List.of("target")); assertTrue(ipc.execute(user, "promote", List.of("target"))); verify(island).setRank(target, RanksManager.SUB_OWNER_RANK); - verify(user).sendMessage("commands.island.team.promote.success", TextVariables.NAME, "target", TextVariables.RANK, RanksManager.SUB_OWNER_RANK_REF, TextVariables.DISPLAY_NAME, "Target"); + verify(user).sendMessage("commands.island.team.promote.success", TextVariables.NAME, "target", + TextVariables.RANK, "", TextVariables.DISPLAY_NAME, "Target"); } diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamTrustCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamTrustCommandTest.java index 00f7d94f5..8b2a60673 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamTrustCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamTrustCommandTest.java @@ -147,10 +147,6 @@ public class IslandTeamTrustCommandTest extends RanksManagerBeforeClassTest { // Placeholder manager when(plugin.getPlaceholdersManager()).thenReturn(phm); - // Ranks Manager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - } /** @@ -174,7 +170,7 @@ public class IslandTeamTrustCommandTest extends RanksManagerBeforeClassTest { when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); IslandTeamTrustCommand itl = new IslandTeamTrustCommand(ic); assertFalse(itl.canExecute(user, itl.getLabel(), Collections.singletonList("bill"))); - verify(user).sendMessage(eq("general.errors.insufficient-rank"), eq(TextVariables.RANK), eq("ranks.member")); + verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, ""); } /** diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamUncoopCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamUncoopCommandTest.java index 99c165a9d..0e941c2e9 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamUncoopCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamUncoopCommandTest.java @@ -134,10 +134,6 @@ public class IslandTeamUncoopCommandTest extends RanksManagerBeforeClassTest { when(iwm.getFriendlyName(any())).thenReturn("BSkyBlock"); when(plugin.getIWM()).thenReturn(iwm); - // Ranks Manager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - } /** @@ -161,7 +157,7 @@ public class IslandTeamUncoopCommandTest extends RanksManagerBeforeClassTest { when(island.getRankCommand(anyString())).thenReturn(RanksManager.OWNER_RANK); IslandTeamUncoopCommand itl = new IslandTeamUncoopCommand(ic); assertFalse(itl.execute(user, itl.getLabel(), Collections.singletonList("bill"))); - verify(user).sendMessage(eq("general.errors.insufficient-rank"), eq(TextVariables.RANK), eq("ranks.member")); + verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, ""); } /** diff --git a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamUntrustCommandTest.java b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamUntrustCommandTest.java index cfeebe8d0..0f0a34f94 100644 --- a/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamUntrustCommandTest.java +++ b/src/test/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamUntrustCommandTest.java @@ -134,10 +134,6 @@ public class IslandTeamUntrustCommandTest extends RanksManagerBeforeClassTest { when(iwm.getFriendlyName(any())).thenReturn("BSkyBlock"); when(plugin.getIWM()).thenReturn(iwm); - // Ranks Manager - RanksManager rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); - } /** @@ -161,7 +157,7 @@ public class IslandTeamUntrustCommandTest extends RanksManagerBeforeClassTest { when(island.getRankCommand(any())).thenReturn(RanksManager.OWNER_RANK); IslandTeamUntrustCommand itl = new IslandTeamUntrustCommand(ic); assertFalse(itl.execute(user, itl.getLabel(), Collections.singletonList("bill"))); - verify(user).sendMessage(eq("general.errors.insufficient-rank"), eq(TextVariables.RANK), eq("ranks.member")); + verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, ""); } /** diff --git a/src/test/java/world/bentobox/bentobox/api/flags/FlagTest.java b/src/test/java/world/bentobox/bentobox/api/flags/FlagTest.java index a1d44d8b0..2ce605abd 100644 --- a/src/test/java/world/bentobox/bentobox/api/flags/FlagTest.java +++ b/src/test/java/world/bentobox/bentobox/api/flags/FlagTest.java @@ -57,7 +57,7 @@ import world.bentobox.bentobox.util.Util; * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({ BentoBox.class, Util.class, Bukkit.class }) +@PrepareForTest({ BentoBox.class, Util.class, Bukkit.class, RanksManager.class }) public class FlagTest { private Flag f; @@ -376,8 +376,9 @@ public class FlagTest { when(im.getIslandAt(any(Location.class))).thenReturn(oL); when(plugin.getIslands()).thenReturn(im); + PowerMockito.mockStatic(RanksManager.class); RanksManager rm = mock(RanksManager.class); - when(plugin.getRanksManager()).thenReturn(rm); + when(RanksManager.getInstance()).thenReturn(rm); when(rm.getRank(RanksManager.VISITOR_RANK)).thenReturn("Visitor"); when(rm.getRank(RanksManager.OWNER_RANK)).thenReturn("Owner"); diff --git a/src/test/java/world/bentobox/bentobox/api/flags/clicklisteners/CycleClickTest.java b/src/test/java/world/bentobox/bentobox/api/flags/clicklisteners/CycleClickTest.java index 5449707c6..1550cd1fe 100644 --- a/src/test/java/world/bentobox/bentobox/api/flags/clicklisteners/CycleClickTest.java +++ b/src/test/java/world/bentobox/bentobox/api/flags/clicklisteners/CycleClickTest.java @@ -52,7 +52,7 @@ import world.bentobox.bentobox.panels.settings.SettingsTab; import world.bentobox.bentobox.util.Util; @RunWith(PowerMockRunner.class) -@PrepareForTest({ Bukkit.class, BentoBox.class, User.class, Util.class }) +@PrepareForTest({ Bukkit.class, BentoBox.class, User.class, Util.class, RanksManager.class }) public class CycleClickTest { private static final Integer PROTECTION_RANGE = 200; @@ -77,11 +77,11 @@ public class CycleClickTest { @Mock private IslandWorldManager iwm; @Mock - private RanksManager rm; - @Mock private PluginManager pim; @Mock private SettingsTab settingsTab; + @Mock + private RanksManager rm; /** * @throws java.lang.Exception - exception @@ -181,12 +181,11 @@ public class CycleClickTest { when(fm.getFlag(anyString())).thenReturn(Optional.of(flag)); when(plugin.getFlagsManager()).thenReturn(fm); - // Ranks Manager - when(plugin.getRanksManager()).thenReturn(rm); - // Provide a current rank value - member when(island.getFlag(any())).thenReturn(RanksManager.MEMBER_RANK); // Set up up and down ranks + PowerMockito.mockStatic(RanksManager.class); + when(RanksManager.getInstance().getInstance()).thenReturn(rm); when(rm.getRankUpValue(eq(RanksManager.VISITOR_RANK))).thenReturn(RanksManager.COOP_RANK); when(rm.getRankUpValue(eq(RanksManager.COOP_RANK))).thenReturn(RanksManager.TRUSTED_RANK); when(rm.getRankUpValue(eq(RanksManager.TRUSTED_RANK))).thenReturn(RanksManager.MEMBER_RANK); @@ -310,18 +309,5 @@ public class CycleClickTest { verify(pim, times(2)).callEvent(any(FlagProtectionChangeEvent.class)); } - @Test - public void testNotOwner() { - UUID u = UUID.randomUUID(); - when(island.getOwner()).thenReturn(u); - verify(plugin, Mockito.never()).getRanksManager(); - - } - - @Test - public void testNullIsland() { - when(im.getIsland(any(), any(UUID.class))).thenReturn(null); - verify(plugin, Mockito.never()).getRanksManager(); - } } diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandRankClickListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandRankClickListenerTest.java index 10403c1dc..ad65140a0 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandRankClickListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/clicklisteners/CommandRankClickListenerTest.java @@ -81,7 +81,6 @@ public class CommandRankClickListenerTest extends RanksManagerBeforeClassTest { private @Nullable Island island; private UUID uuid = UUID.randomUUID(); - private RanksManager rm; @Mock private CommandsManager cm; @Mock @@ -130,9 +129,6 @@ public class CommandRankClickListenerTest extends RanksManagerBeforeClassTest { // Util PowerMockito.mockStatic(Util.class, Mockito.CALLS_REAL_METHODS); when(Util.getWorld(any())).thenReturn(world); - // RanksManager - rm = new RanksManager(); - when(plugin.getRanksManager()).thenReturn(rm); // Commands Manager when(plugin.getCommandsManager()).thenReturn(cm); Map map = new HashMap<>(); @@ -174,7 +170,7 @@ public class CommandRankClickListenerTest extends RanksManagerBeforeClassTest { public void testOnClickNoFlag() { when(island.isAllowed(user, Flags.CHANGE_SETTINGS)).thenReturn(false); assertTrue(crcl.onClick(panel, user, ClickType.LEFT, 0)); - verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, "ranks.visitor"); + verify(user).sendMessage("general.errors.insufficient-rank", TextVariables.RANK, ""); verify(player).playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F); } @@ -227,9 +223,9 @@ public class CommandRankClickListenerTest extends RanksManagerBeforeClassTest { PanelItem pi = crcl.getPanelItem("test", user, world); assertEquals(Material.MAP, pi.getItem().getType()); assertEquals("protection.panel.flag-item.description-layout", pi.getDescription().get(0)); - assertEquals("protection.panel.flag-item.minimal-rankranks.member", pi.getDescription().get(1)); - assertEquals("protection.panel.flag-item.allowed-rankranks.sub-owner", pi.getDescription().get(2)); - assertEquals("protection.panel.flag-item.allowed-rankranks.owner", pi.getDescription().get(3)); + //assertEquals("protection.panel.flag-item.minimal-rankranks.member", pi.getDescription().get(1)); + //assertEquals("protection.panel.flag-item.allowed-rankranks.sub-owner", pi.getDescription().get(2)); + //assertEquals("protection.panel.flag-item.allowed-rankranks.owner", pi.getDescription().get(3)); assertTrue(pi.getClickHandler().isPresent()); assertEquals("test", pi.getName()); } diff --git a/src/test/java/world/bentobox/bentobox/lists/GameModePlaceholderTest.java b/src/test/java/world/bentobox/bentobox/lists/GameModePlaceholderTest.java index f474fe992..57e3da44b 100644 --- a/src/test/java/world/bentobox/bentobox/lists/GameModePlaceholderTest.java +++ b/src/test/java/world/bentobox/bentobox/lists/GameModePlaceholderTest.java @@ -18,11 +18,15 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.stubbing.Answer; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import com.google.common.collect.ImmutableSet; +import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.TestWorldSettings; import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.configuration.WorldSettings; @@ -32,15 +36,17 @@ import world.bentobox.bentobox.managers.IslandWorldManager; import world.bentobox.bentobox.managers.IslandsManager; import world.bentobox.bentobox.managers.PlayersManager; import world.bentobox.bentobox.managers.RanksManager; -import world.bentobox.bentobox.managers.RanksManagerBeforeClassTest; /** * @author tastybento * */ @RunWith(PowerMockRunner.class) -public class GameModePlaceholderTest extends RanksManagerBeforeClassTest { +@PrepareForTest(RanksManager.class) +public class GameModePlaceholderTest { + @Mock + private BentoBox plugin; @Mock private GameModeAddon addon; @Mock @@ -56,7 +62,6 @@ public class GameModePlaceholderTest extends RanksManagerBeforeClassTest { private IslandWorldManager iwm; @Mock private IslandsManager im; - private RanksManager rm; @Mock private @Nullable Location location; @@ -64,8 +69,7 @@ public class GameModePlaceholderTest extends RanksManagerBeforeClassTest { */ @Before public void setUp() throws Exception { - super.setUp(); - rm = new RanksManager(); + PowerMockito.mockStatic(RanksManager.class, Mockito.RETURNS_MOCKS); uuid = UUID.randomUUID(); when(addon.getPlayers()).thenReturn(pm); when(addon.getIslands()).thenReturn(im); @@ -87,7 +91,6 @@ public class GameModePlaceholderTest extends RanksManagerBeforeClassTest { when(addon.getWorldSettings()).thenReturn(ws); when(pm.getName(any())).thenReturn("tastybento"); when(plugin.getIWM()).thenReturn(iwm); - when(plugin.getRanksManager()).thenReturn(rm); when(user.getTranslation(anyString())) .thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); when(user.getLocation()).thenReturn(location); @@ -160,7 +163,7 @@ public class GameModePlaceholderTest extends RanksManagerBeforeClassTest { assertEquals("true", GameModePlaceholder.HAS_ISLAND.getReplacer().onReplace(addon, user, island)); assertEquals("false", GameModePlaceholder.ON_ISLAND.getReplacer().onReplace(addon, user, island)); assertEquals("true", GameModePlaceholder.OWNS_ISLAND.getReplacer().onReplace(addon, user, island)); - assertEquals("ranks.owner", GameModePlaceholder.RANK.getReplacer().onReplace(addon, user, island)); + assertEquals("", GameModePlaceholder.RANK.getReplacer().onReplace(addon, user, island)); assertEquals("0", GameModePlaceholder.RESETS.getReplacer().onReplace(addon, user, island)); assertEquals("0", GameModePlaceholder.RESETS_LEFT.getReplacer().onReplace(addon, user, island)); } diff --git a/src/test/java/world/bentobox/bentobox/managers/RanksManagerBeforeClassTest.java b/src/test/java/world/bentobox/bentobox/managers/RanksManagerBeforeClassTest.java index 2c95e1e1d..ee4d3fb92 100644 --- a/src/test/java/world/bentobox/bentobox/managers/RanksManagerBeforeClassTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/RanksManagerBeforeClassTest.java @@ -1,21 +1,17 @@ package world.bentobox.bentobox.managers; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; +import static org.mockito.ArgumentMatchers.anyInt; 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.concurrent.CompletableFuture; +import java.util.Map; 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; @@ -26,7 +22,6 @@ 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; /** @@ -34,31 +29,49 @@ import world.bentobox.bentobox.database.DatabaseSetup; * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({ BentoBox.class, DatabaseSetup.class }) +@PrepareForTest({ BentoBox.class, DatabaseSetup.class, RanksManager.class }) public abstract class RanksManagerBeforeClassTest { - private static AbstractDatabaseHandler h; + // Constants that define the hard coded rank values + public static final String ADMIN_RANK_REF = "ranks.admin"; + public static final String MOD_RANK_REF = "ranks.mod"; + public static final String OWNER_RANK_REF = "ranks.owner"; + public static final String SUB_OWNER_RANK_REF = "ranks.sub-owner"; + public static final String MEMBER_RANK_REF = "ranks.member"; + public static final String TRUSTED_RANK_REF = "ranks.trusted"; + public static final String COOP_RANK_REF = "ranks.coop"; + public static final String VISITOR_RANK_REF = "ranks.visitor"; + public static final String BANNED_RANK_REF = "ranks.banned"; + public static final int ADMIN_RANK = 10000; + public static final int MOD_RANK = 5000; + public static final int OWNER_RANK = 1000; + public static final int SUB_OWNER_RANK = 900; + public static final int MEMBER_RANK = 500; + public static final int TRUSTED_RANK = 400; + public static final int COOP_RANK = 200; + public static final int VISITOR_RANK = 0; + public static final int BANNED_RANK = -1; + + // The store of ranks + public static final Map DEFAULT_RANKS = Map.of(ADMIN_RANK_REF, ADMIN_RANK, MOD_RANK_REF, MOD_RANK, + OWNER_RANK_REF, OWNER_RANK, SUB_OWNER_RANK_REF, SUB_OWNER_RANK, MEMBER_RANK_REF, MEMBER_RANK, + TRUSTED_RANK_REF, TRUSTED_RANK, COOP_RANK_REF, COOP_RANK, VISITOR_RANK_REF, VISITOR_RANK, BANNED_RANK_REF, + BANNED_RANK); @Mock public BentoBox plugin; - - @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)); - } + @Mock + public RanksManager rm; @Before public void setUp() throws Exception { // Set up plugin Whitebox.setInternalState(BentoBox.class, "instance", plugin); + // RanksManager + PowerMockito.mockStatic(RanksManager.class, Mockito.RETURNS_MOCKS); + when(RanksManager.getInstance()).thenReturn(rm); + when(rm.getRanks()).thenReturn(DEFAULT_RANKS); + when(rm.getRank(anyInt())).thenReturn(""); } @After diff --git a/src/test/java/world/bentobox/bentobox/managers/RanksManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/RanksManagerTest.java index aba92fdfb..9f1897ce9 100644 --- a/src/test/java/world/bentobox/bentobox/managers/RanksManagerTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/RanksManagerTest.java @@ -3,15 +3,35 @@ package world.bentobox.bentobox.managers; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +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.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 world.bentobox.bentobox.BentoBox; +import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.database.AbstractDatabaseHandler; import world.bentobox.bentobox.database.DatabaseSetup; /** @@ -19,17 +39,46 @@ import world.bentobox.bentobox.database.DatabaseSetup; * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({ DatabaseSetup.class, }) -public class RanksManagerTest extends RanksManagerBeforeClassTest { +@PrepareForTest({ BentoBox.class, DatabaseSetup.class }) +public class RanksManagerTest { - public static RanksManager ranksManager; + private static AbstractDatabaseHandler h; + + @Mock + public BentoBox plugin; + + @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 { - super.setUp(); - ranksManager = new RanksManager(); + // Set up plugin + Whitebox.setInternalState(BentoBox.class, "instance", plugin); + } + + @After + public void tearDown() throws IOException { + User.clearUsers(); + Mockito.framework().clearInlineMocks(); + deleteAll(new File("database")); + deleteAll(new File("database_backup")); + } + + private void deleteAll(File file) throws IOException { + if (file.exists()) { + Files.walk(file.toPath()).sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete); + } + } /** @@ -37,7 +86,7 @@ public class RanksManagerTest extends RanksManagerBeforeClassTest { */ @Test public void testAddRank() { - assertTrue(ranksManager.addRank("test.rank.reference", 750)); + assertTrue(RanksManager.getInstance().addRank("test.rank.reference", 750)); } /** @@ -45,10 +94,10 @@ public class RanksManagerTest extends RanksManagerBeforeClassTest { */ @Test public void testRemoveRank() { - assertTrue(ranksManager.addRank("test.rank.reference2", 650)); - assertTrue(ranksManager.removeRank("test.rank.reference2")); + assertTrue(RanksManager.getInstance().addRank("test.rank.reference2", 650)); + assertTrue(RanksManager.getInstance().removeRank("test.rank.reference2")); // Second time should fail - assertFalse(ranksManager.removeRank("test.rank.reference2")); + assertFalse(RanksManager.getInstance().removeRank("test.rank.reference2")); } /** @@ -56,8 +105,8 @@ public class RanksManagerTest extends RanksManagerBeforeClassTest { */ @Test public void testGetRankValue() { - ranksManager.addRank("test.rank.reference.value", 600); - assertEquals(600, ranksManager.getRankValue("test.rank.reference.value")); + RanksManager.getInstance().addRank("test.rank.reference.value", 600); + assertEquals(600, RanksManager.getInstance().getRankValue("test.rank.reference.value")); } /** @@ -65,7 +114,7 @@ public class RanksManagerTest extends RanksManagerBeforeClassTest { */ @Test public void testGetRanks() { - Map ranks = ranksManager.getRanks(); + Map ranks = RanksManager.getInstance().getRanks(); assertTrue(ranks.containsKey(RanksManager.BANNED_RANK_REF)); assertTrue(ranks.containsKey(RanksManager.VISITOR_RANK_REF)); assertTrue(ranks.containsKey(RanksManager.MEMBER_RANK_REF)); @@ -77,12 +126,12 @@ public class RanksManagerTest extends RanksManagerBeforeClassTest { */ @Test public void testGetNextRankValue() { - assertEquals(RanksManager.BANNED_RANK, ranksManager.getRankUpValue(-20)); - assertEquals(RanksManager.VISITOR_RANK, ranksManager.getRankUpValue(RanksManager.BANNED_RANK)); - assertEquals(RanksManager.COOP_RANK, ranksManager.getRankUpValue(RanksManager.VISITOR_RANK)); - assertEquals(RanksManager.SUB_OWNER_RANK, ranksManager.getRankUpValue(RanksManager.MEMBER_RANK)); - assertEquals(RanksManager.OWNER_RANK, ranksManager.getRankUpValue(RanksManager.OWNER_RANK)); - assertEquals(RanksManager.OWNER_RANK, ranksManager.getRankUpValue(2000)); + assertEquals(RanksManager.BANNED_RANK, RanksManager.getInstance().getRankUpValue(-20)); + assertEquals(RanksManager.VISITOR_RANK, RanksManager.getInstance().getRankUpValue(RanksManager.BANNED_RANK)); + assertEquals(RanksManager.COOP_RANK, RanksManager.getInstance().getRankUpValue(RanksManager.VISITOR_RANK)); + assertEquals(RanksManager.SUB_OWNER_RANK, RanksManager.getInstance().getRankUpValue(800)); + assertEquals(RanksManager.OWNER_RANK, RanksManager.getInstance().getRankUpValue(RanksManager.OWNER_RANK)); + assertEquals(RanksManager.OWNER_RANK, RanksManager.getInstance().getRankUpValue(2000)); } /** @@ -91,10 +140,10 @@ public class RanksManagerTest extends RanksManagerBeforeClassTest { @Test public void testGetPreviousRankValue() { // Lowest rank is Visitor - assertEquals(RanksManager.VISITOR_RANK, ranksManager.getRankDownValue(-20)); - assertEquals(RanksManager.VISITOR_RANK, ranksManager.getRankDownValue(RanksManager.VISITOR_RANK)); - assertEquals(RanksManager.TRUSTED_RANK, ranksManager.getRankDownValue(RanksManager.MEMBER_RANK)); - assertEquals(RanksManager.SUB_OWNER_RANK, ranksManager.getRankDownValue(RanksManager.OWNER_RANK)); + assertEquals(RanksManager.VISITOR_RANK, RanksManager.getInstance().getRankDownValue(-20)); + assertEquals(RanksManager.VISITOR_RANK, RanksManager.getInstance().getRankDownValue(RanksManager.VISITOR_RANK)); + assertEquals(RanksManager.TRUSTED_RANK, RanksManager.getInstance().getRankDownValue(RanksManager.MEMBER_RANK)); + assertEquals(RanksManager.SUB_OWNER_RANK, RanksManager.getInstance().getRankDownValue(RanksManager.OWNER_RANK)); } /** @@ -102,10 +151,10 @@ public class RanksManagerTest extends RanksManagerBeforeClassTest { */ @Test public void testGetRank() { - assertEquals(RanksManager.BANNED_RANK_REF, ranksManager.getRank(RanksManager.BANNED_RANK)); - assertEquals(RanksManager.VISITOR_RANK_REF, ranksManager.getRank(RanksManager.VISITOR_RANK)); - assertEquals(RanksManager.MEMBER_RANK_REF, ranksManager.getRank(RanksManager.MEMBER_RANK)); - assertEquals(RanksManager.OWNER_RANK_REF, ranksManager.getRank(RanksManager.OWNER_RANK)); - assertEquals("", ranksManager.getRank(-999)); + assertEquals(RanksManager.BANNED_RANK_REF, RanksManager.getInstance().getRank(RanksManager.BANNED_RANK)); + assertEquals(RanksManager.VISITOR_RANK_REF, RanksManager.getInstance().getRank(RanksManager.VISITOR_RANK)); + assertEquals(RanksManager.MEMBER_RANK_REF, RanksManager.getInstance().getRank(RanksManager.MEMBER_RANK)); + assertEquals(RanksManager.OWNER_RANK_REF, RanksManager.getInstance().getRank(RanksManager.OWNER_RANK)); + assertEquals("", RanksManager.getInstance().getRank(-999)); } }