From 1d6556613e6f95bcd5cee64f8699ed34a83ee610 Mon Sep 17 00:00:00 2001 From: tastybento Date: Wed, 3 Jan 2024 15:55:31 +0900 Subject: [PATCH] Added support for kick, setowner, and leave. --- .../island/team/IslandTeamCommand.java | 156 +++++++++++++----- .../island/team/IslandTeamKickCommand.java | 2 +- .../island/team/IslandTeamLeaveCommand.java | 2 +- .../team/IslandTeamSetownerCommand.java | 13 +- .../island/team/IslandTeamUncoopCommand.java | 2 +- .../island/team/IslandTeamUntrustCommand.java | 2 +- .../bentobox/bentobox/api/flags/Flag.java | 1 - src/main/resources/locales/en-US.yml | 18 +- src/main/resources/panels/team_panel.yml | 24 ++- 9 files changed, 160 insertions(+), 60 deletions(-) diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamCommand.java index e1a836d1e..1c5cbc031 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 @@ -8,17 +8,18 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; 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.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; -import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.events.IslandBaseEvent; import world.bentobox.bentobox.api.events.team.TeamEvent; @@ -56,6 +57,16 @@ public class IslandTeamCommand extends CompositeCommand { private int rank = RanksManager.OWNER_RANK; + private IslandTeamKickCommand kickCommand; + + private IslandTeamLeaveCommand leaveCommand; + + private IslandTeamSetownerCommand setOwnerCommand; + + private IslandTeamUncoopCommand uncoopCommand; + + private IslandTeamUntrustCommand unTrustCommand; + public IslandTeamCommand(CompositeCommand parent) { super(parent, "team"); inviteMap = new HashMap<>(); @@ -68,24 +79,24 @@ public class IslandTeamCommand extends CompositeCommand { setDescription("commands.island.team.description"); // Register commands new IslandTeamInviteCommand(this); - new IslandTeamLeaveCommand(this); - new IslandTeamSetownerCommand(this); - new IslandTeamKickCommand(this); + leaveCommand = new IslandTeamLeaveCommand(this); + setOwnerCommand = new IslandTeamSetownerCommand(this); + kickCommand = new IslandTeamKickCommand(this); new IslandTeamInviteAcceptCommand(this); new IslandTeamInviteRejectCommand(this); if (RanksManager.getInstance().rankExists(RanksManager.COOP_RANK_REF)) { new IslandTeamCoopCommand(this); - new IslandTeamUncoopCommand(this); + uncoopCommand = new IslandTeamUncoopCommand(this); } if (RanksManager.getInstance().rankExists(RanksManager.TRUSTED_RANK_REF)) { new IslandTeamTrustCommand(this); - new IslandTeamUntrustCommand(this); + unTrustCommand = new IslandTeamUntrustCommand(this); } new IslandTeamPromoteCommand(this, "promote"); new IslandTeamPromoteCommand(this, "demote"); // Panels - getPlugin().saveResource("panels/team_panel.yml", false); + getPlugin().saveResource("panels/team_panel.yml", true); } @Override @@ -145,18 +156,46 @@ public class IslandTeamCommand extends CompositeCommand { private PanelItem createRankButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot) { PanelItemBuilder builder = new PanelItemBuilder(); - builder.name("Rank"); + builder.name(user.getTranslation("commands.island.team.gui.buttons.rank-filter.name")); builder.icon(Material.AMETHYST_SHARD); - builder.description("Rank shown = " + user.getTranslation(RanksManager.getInstance().getRank(rank))); - builder.clickHandler((panel, user, clickType, clickSlot) -> { - BentoBox.getInstance().logDebug("Rank = " + rank); - if (clickType.equals(ClickType.RIGHT)) { - rank = RanksManager.getInstance().getRankDownValue(rank); - - } else { - rank = RanksManager.getInstance().getRankUpValue(rank); + // 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)); } - BentoBox.getInstance().logDebug("New Rank = " + rank); + }); + 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; @@ -279,35 +318,48 @@ public class IslandTeamCommand extends CompositeCommand { } /** - * Shows a member's head - * @param rank - the rank to show + * 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 rank, int slot, List actions) { + private PanelItem getMemberButton(int targetRank, int slot, List actions) { if (slot == 0 && island.getOwner() != null) { // Owner return getMemberButton(RanksManager.OWNER_RANK, 1, actions); } - long count = island.getMemberSet(rank, false).size(); - String ref = RanksManager.getInstance().getRank(rank); - User player = island.getMemberSet(rank, false).stream().sorted().skip(slot - 1L).limit(1L) + String ref = RanksManager.getInstance().getRank(targetRank); + User member = island.getMemberSet(targetRank, false).stream().sorted().skip(slot - 1L).limit(1L) .map(User::getInstance).findFirst().orElse(null); - if (player != null) { - if (player.isOnline()) { - return new PanelItemBuilder().icon(player.getName()).name(player.getDisplayName()) - .description( - user.getTranslation("commands.island.team.info.rank-layout.generic", TextVariables.RANK, - user.getTranslation(ref), TextVariables.NUMBER, String.valueOf(count))) - .clickHandler((panel, user, clickType, i) -> clickListener(panel, user, clickType, i, player, + // Make button description depending on viewer + List desc = new ArrayList<>(); + int userRank = Objects.requireNonNull(island).getRank(user); + if (userRank >= island.getRankCommand(this.getLabel() + " kick") && !user.equals(member)) { + // Add the tooltip for kicking + actions.stream().filter(ar -> ar.actionType().equalsIgnoreCase("kick")).map(ActionRecords::tooltip) + .findFirst().map(user::getTranslation).ifPresent(desc::add); + } + if (!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(ActionRecords::tooltip) + .findFirst().map(user::getTranslation).ifPresent(desc::add); + } + if (member != null) { + 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 - return new PanelItemBuilder().icon(player.getName()).name(player.getDisplayName()) - .description(offlinePlayerStatus(user, Bukkit.getOfflinePlayer(player.getUniqueId()))) - .clickHandler((panel, user, clickType, i) -> clickListener(panel, user, clickType, i, player, + desc.add(0, user.getTranslation(ref)); + desc.add(1, offlinePlayerStatus(user, Bukkit.getOfflinePlayer(member.getUniqueId()))); + return new PanelItemBuilder().icon(member.getName()).name(member.getDisplayName()) + .description(desc) + .clickHandler((panel, user, clickType, i) -> clickListener(panel, user, clickType, i, member, actions)) .build(); } @@ -315,20 +367,32 @@ public class IslandTeamCommand extends CompositeCommand { return null; } - private boolean clickListener(Panel panel, User user, ClickType clickType, int i, User player, + private boolean clickListener(Panel panel, User clicker, ClickType clickType, int i, User member, List actions) { + int rank = Objects.requireNonNull(island).getRank(clicker); for (ItemTemplateRecord.ActionRecords action : actions) { if (clickType == action.clickType() || action.clickType() == ClickType.UNKNOWN) { switch (action.actionType().toUpperCase(Locale.ENGLISH)) { case "KICK" -> { - // Kick the player - if (!player.equals(user)) { - this.user.closeInventory(); - BentoBox.getInstance() - .logDebug(this.getTopLabel() + " " + this.getLabel() + " kick " + player.getName()); - user.performCommand(this.getTopLabel() + " " + this.getLabel() + " kick " + player.getName()); + // Kick the player, or uncoop, or untrust + if (!member.equals(clicker) && rank >= island.getRankCommand(this.getLabel() + " kick")) { + clicker.closeInventory(); + removePlayer(clicker, member); + clicker.getPlayer().playSound(clicker.getLocation(), Sound.BLOCK_GLASS_BREAK, 1F, 1F); + } + } + case "SETOWNER" -> { + // Make the player the leader of the island + if (!member.equals(clicker) && clicker.getUniqueId().equals(island.getOwner())) { + clicker.closeInventory(); + this.setOwnerCommand.setOwner(clicker, member.getUniqueId()); + } + } + case "LEAVE" -> { + if (member.equals(clicker) && !clicker.getUniqueId().equals(island.getOwner())) { + clicker.closeInventory(); + leaveCommand.leave(clicker); } - } } } @@ -336,6 +400,16 @@ public class IslandTeamCommand extends CompositeCommand { return true; } + private void removePlayer(User clicker, User member) { + // If member then kick, if coop, uncoop, if trusted, then untrust + 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 -> kickCommand.kick(clicker, member.getUniqueId()); + } + + } + private List showMembers() { List message = new ArrayList<>(); // Gather online members 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 9c27b7baf..6024c7426 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 @@ -84,7 +84,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..8e34ba1c9 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,7 +65,7 @@ public class IslandTeamLeaveCommand extends ConfirmableCommand { } - private void leave(User user) { + protected void leave(User user) { Island island = getIslands().getIsland(getWorld(), user); if (island == null) { user.sendMessage("general.errors.no-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..0c792fe6b 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 @@ -69,19 +69,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, @Nullable 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/IslandTeamUncoopCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamUncoopCommand.java index 6c9533110..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 @@ -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 05581286c..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 @@ -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 abb185b5f..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,6 @@ public class Flag implements Comparable { // Protection flag pib.description(user.getTranslation("protection.panel.flag-item.description-layout", TextVariables.DESCRIPTION, user.getTranslation(getDescriptionReference()))); - plugin.getRanksManager(); 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)); diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index c19344d20..2ab0bbba7 100644 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -619,10 +619,22 @@ commands: status: name: Status description: The status of the team + rank-filter: + name: Rank Filter + description: &a Click to cycle ranks tips: - click-to-view: Click to view - right-click-to-kick: Right click to kick player - requires confirmation - click-to-invite: Click to invite a team member + shift-right: + kick: | + &a Shift-right click + &a to kick player + leave: | + &a Shift-right click + &a to leave team + shift-left: + setowner: | + &a Shift-left to + &a set owner to + &a this player info: description: display detailed info about your team member-layout: diff --git a/src/main/resources/panels/team_panel.yml b/src/main/resources/panels/team_panel.yml index cad6ace1f..a6611ccc8 100644 --- a/src/main/resources/panels/team_panel.yml +++ b/src/main/resources/panels/team_panel.yml @@ -21,7 +21,7 @@ team_panel: # 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 - 0: + 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. @@ -38,14 +38,17 @@ team_panel: # 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: - # Change rank + # Rank filter data: type: RANK + name: commands.island.team.gui.buttons.rank-filter actions: - add: + cycle-up: click-type: LEFT - tooltip: commands.island.team.gui.tips.click-to-change-rank - + tooltip: commands.island.team.gui.tips.right-click.rank + cycle-down: + click-type: RIGHT + tooltip: commands.island.team.gui.tips.right-click.rank 2: 2: member_button 3: member_button @@ -103,6 +106,13 @@ team_panel: # 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: RIGHT + 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.right-click-to-kick \ No newline at end of file + 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