Skip to content

Commit 6f3c424

Browse files
committed
enable specifying nation ID in /nation command
1 parent d8586cf commit 6f3c424

File tree

6 files changed

+185
-50
lines changed

6 files changed

+185
-50
lines changed

.run/Package.run.xml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="Package" type="MavenRunConfiguration" factoryName="Maven">
3+
<MavenSettings>
4+
<option name="myGeneralSettings" />
5+
<option name="myRunnerSettings" />
6+
<option name="myRunnerParameters">
7+
<MavenRunnerParameters>
8+
<option name="cmdOptions" />
9+
<option name="profiles">
10+
<set />
11+
</option>
12+
<option name="goals">
13+
<list>
14+
<option value="package" />
15+
</list>
16+
</option>
17+
<option name="multimoduleDir" />
18+
<option name="pomFileName" />
19+
<option name="profilesMap">
20+
<map />
21+
</option>
22+
<option name="projectsCmdOptionValues">
23+
<list />
24+
</option>
25+
<option name="resolveToWorkspace" value="false" />
26+
<option name="workingDirPath" value="$PROJECT_DIR$" />
27+
</MavenRunnerParameters>
28+
</option>
29+
</MavenSettings>
30+
<method v="2" />
31+
</configuration>
32+
</component>

src/main/java/pro/cloudnode/smp/smpcore/Messages.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,10 @@ public Messages() {
392392
return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.kick-leadership")));
393393
}
394394

395+
public @NotNull Component nationNotFound(final @NotNull String nation) {
396+
return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.nation-not-found")), Placeholder.unparsed("nation", nation));
397+
}
398+
395399
public record SubCommandArgument(@NotNull String name, boolean required) {
396400
public @NotNull Component component() {
397401
return required ? SMPCore.messages().subCommandArgumentRequired(name) : SMPCore.messages()

src/main/java/pro/cloudnode/smp/smpcore/Permission.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,20 @@ public final class Permission {
6868
public static @NotNull String NATION_MEMBERS_LIST = "smpcore.nation.members.list";
6969

7070
/**
71-
* Kick nation members
71+
* List the member of any nation
72+
*/
73+
public static @NotNull String NATION_MEMBERS_LIST_OTHER = "smpcore.nation.members.list.other";
74+
75+
/**
76+
* Kick members of your nation
7277
*/
7378
public static @NotNull String NATION_MEMBERS_KICK = "smpcore.nation.members.kick";
7479

80+
/**
81+
* Kick members of any nation
82+
*/
83+
public static @NotNull String NATION_MEMBERS_KICK_OTHER = "smpcore.nation.members.kick.other";
84+
7585
/**
7686
* Appoint nation citizen as vice-leader
7787
*/

src/main/java/pro/cloudnode/smp/smpcore/command/Command.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
import org.bukkit.command.CommandExecutor;
66
import org.bukkit.command.CommandSender;
77
import org.bukkit.command.TabCompleter;
8+
import org.bukkit.permissions.Permissible;
89
import org.jetbrains.annotations.NotNull;
910
import org.jetbrains.annotations.Nullable;
1011
import pro.cloudnode.smp.smpcore.SMPCore;
1112

13+
import java.util.Arrays;
1214
import java.util.List;
1315

1416
public abstract class Command implements TabCompleter, CommandExecutor {
@@ -34,4 +36,14 @@ public final boolean onCommand(final @NotNull CommandSender sender, final @NotNu
3436
if (args.length > 0 && tab != null) return tab.stream().filter(e -> e.toLowerCase().startsWith(args[args.length - 1].toLowerCase())).toList();
3537
else return tab;
3638
}
39+
40+
/**
41+
* Check for the presence of any of the permissions (using OR).
42+
*
43+
* @param permissible Permissible to check
44+
* @param permissions Permissions to check
45+
*/
46+
public static boolean hasAnyPermission(final @NotNull Permissible permissible, final @NotNull String @NotNull ... permissions) {
47+
return Arrays.stream(permissions).anyMatch(permissible::hasPermission);
48+
}
3749
}

src/main/java/pro/cloudnode/smp/smpcore/command/NationCommand.java

Lines changed: 122 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -20,91 +20,167 @@
2020
public final class NationCommand extends Command {
2121

2222
@Override
23-
public boolean run(final @NotNull CommandSender sender, final @NotNull String label, final @NotNull String @NotNull [] args) {
23+
public boolean run(
24+
final @NotNull CommandSender sender,
25+
final @NotNull String label,
26+
@NotNull String @NotNull [] args
27+
) {
2428
if (!sender.hasPermission(Permission.NATION))
2529
return sendMessage(sender, SMPCore.messages().errorNoPermission());
26-
if (!(sender instanceof final @NotNull Player player))
27-
return sendMessage(sender, SMPCore.messages().errorNotPlayer());
28-
final @NotNull Optional<@NotNull Member> member = Member.get(player);
29-
if (member.isEmpty())
30-
return sendMessage(sender, SMPCore.messages().errorNotMember());
3130

32-
if (args.length == 0) return helpSubCommands(member.get(), sender, label);
33-
final @NotNull String command = label + " " + args[0];
31+
final @NotNull Optional<@NotNull Member> member = sender instanceof final @NotNull Player player ? Member.get(
32+
player) : Optional.empty();
33+
34+
final @NotNull Optional<@NotNull Nation> nation;
35+
if (args.length > 0 && args[0].startsWith("id:")) {
36+
final @NotNull String id = args[0].substring(3);
37+
nation = Nation.get(id);
38+
args = Arrays.copyOfRange(args, 1, args.length);
39+
if (nation.isEmpty())
40+
return sendMessage(sender, SMPCore.messages().nationNotFound(id));
41+
}
42+
else
43+
nation = member.flatMap(Member::nation);
44+
45+
if (args.length == 0)
46+
return helpSubCommands(member.orElse(null), nation.orElse(null), sender, label);
47+
48+
final boolean other = member.isEmpty() || nation.isEmpty() || !nation.get().id.equals(member.get().nationID);
49+
final @NotNull String command = label + (other && nation.isPresent() ? " id:" + nation.get().id : "") + " "
50+
+ args[0];
3451
final @NotNull String @NotNull [] argsSubset = Arrays.copyOfRange(args, 1, args.length);
3552
switch (args[0]) {
36-
case "members": return members(member.get(), sender, command, argsSubset);
37-
default: return helpSubCommands(member.get(), sender, label);
53+
case "members":
54+
return members(member.orElse(null), nation.orElse(null), sender, command, argsSubset);
55+
default:
56+
return helpSubCommands(member.orElse(null), nation.orElse(null), sender, label);
3857
}
3958
}
4059

4160
@Override
42-
public @Nullable List<@NotNull String> tab(final @NotNull CommandSender sender, final @NotNull String label, final @NotNull String @NotNull [] args) {
61+
public @Nullable List<@NotNull String> tab(
62+
final @NotNull CommandSender sender,
63+
final @NotNull String label,
64+
final @NotNull String @NotNull [] args
65+
) {
4366
return List.of();
4467
}
4568

46-
public boolean helpSubCommands(final @NotNull Member member, final @NotNull CommandSender sender, final @NotNull String label) {
47-
final @NotNull String command = "/" + label;
69+
public boolean helpSubCommands(
70+
final @Nullable Member member,
71+
final @Nullable Nation nation,
72+
final @NotNull CommandSender sender,
73+
final @NotNull String label
74+
) {
75+
final boolean other = member == null || nation == null || !nation.id.equals(member.nationID);
76+
77+
final @NotNull String command = "/" + label + (other && nation != null ? " id:" + nation.id : "");
4878
final @NotNull TextComponent.Builder subCommandBuilder = Component.text()
49-
.append(SMPCore.messages().subCommandHeader("Nation", command + " ...")).append(Component.newline());
50-
if (member.nationID != null && (
51-
sender.hasPermission(Permission.NATION_MEMBERS_LIST)
52-
|| sender.hasPermission(Permission.NATION_MEMBERS_KICK)
53-
)) subCommandBuilder.append(Component.newline()).append(SMPCore.messages()
54-
.subCommandEntry(command + " members ", "members"));
79+
.append(SMPCore.messages().subCommandHeader("Nation", command + " ..."))
80+
.append(Component.newline());
81+
82+
if (nation != null) {
83+
if ((
84+
!other && hasAnyPermission(sender, Permission.NATION_MEMBERS_LIST, Permission.NATION_MEMBERS_KICK)
85+
) || hasAnyPermission(sender, Permission.NATION_MEMBERS_LIST_OTHER, Permission.NATION_MEMBERS_KICK_OTHER))
86+
subCommandBuilder.append(Component.newline())
87+
.append(SMPCore.messages().subCommandEntry(command + " members ", "members"));
88+
}
89+
5590
return sendMessage(sender, subCommandBuilder.build());
5691
}
5792

58-
public boolean members(final @NotNull Member member, final @NotNull CommandSender sender, final @NotNull String label, final @NotNull String @NotNull [] args) {
59-
if (args.length == 0) return membersSubcommand(sender, "/" + label);
93+
public boolean members(
94+
final @Nullable Member member,
95+
final @Nullable Nation nation,
96+
final @NotNull CommandSender sender,
97+
final @NotNull String label,
98+
final @NotNull String @NotNull [] args
99+
) {
100+
if (nation == null)
101+
return sendMessage(sender, SMPCore.messages().errorNotInNation());
102+
103+
if (args.length == 0)
104+
return membersSubcommand(member, nation, sender, "/" + label);
60105
final @NotNull String command = label + " " + args[0];
61106
final @NotNull String @NotNull [] argsSubset = Arrays.copyOfRange(args, 1, args.length);
62107
return switch (args[0]) {
63-
case "list" -> listMembers(member, sender);
64-
case "kick" -> kickMember(member, sender, command, argsSubset);
65-
default -> membersSubcommand(sender, "/" + label);
108+
case "list" -> listMembers(member, nation, sender);
109+
case "kick" -> kickMember(member, nation, sender, command, argsSubset);
110+
default -> membersSubcommand(member, nation, sender, "/" + label);
66111
};
67112
}
68113

69-
public boolean membersSubcommand(final @NotNull CommandSender sender, final @NotNull String label) {
114+
public boolean membersSubcommand(
115+
final @Nullable Member member,
116+
final @NotNull Nation nation,
117+
final @NotNull CommandSender sender,
118+
final @NotNull String label
119+
) {
120+
final boolean other = member == null || !nation.id.equals(member.nationID);
121+
70122
final @NotNull TextComponent.Builder subCommandBuilder = Component.text()
71-
.append(SMPCore.messages().subCommandHeader("Nation Members", label + " ...")).append(Component.newline());
72-
if (sender.hasPermission(Permission.NATION_MEMBERS_LIST)) subCommandBuilder.append(Component.newline()).append(SMPCore.messages()
73-
.subCommandEntry(label + " list ", "list"));
74-
if (sender.hasPermission(Permission.NATION_MEMBERS_KICK)) subCommandBuilder.append(Component.newline()).append(SMPCore.messages()
75-
.subCommandEntry(label + " kick ", "kick", Messages.SubCommandArgument.of(new Messages.SubCommandArgument("member", true)), "remove a member from the nation"));
123+
.append(SMPCore.messages().subCommandHeader("Nation Members", label + " ..."))
124+
.append(Component.newline());
125+
126+
if ((!other && sender.hasPermission(Permission.NATION_MEMBERS_LIST))
127+
|| sender.hasPermission(Permission.NATION_MEMBERS_LIST_OTHER))
128+
subCommandBuilder.append(Component.newline())
129+
.append(SMPCore.messages().subCommandEntry(label + " list ", "list", "List nation members."));
130+
131+
if ((!other && sender.hasPermission(Permission.NATION_MEMBERS_KICK))
132+
|| sender.hasPermission(Permission.NATION_MEMBERS_KICK_OTHER))
133+
subCommandBuilder.append(Component.newline()).append(SMPCore.messages().subCommandEntry(
134+
label + " kick ", "kick", new Messages.SubCommandArgument[]{
135+
new Messages.SubCommandArgument("member", true)
136+
}, "Kick a member from the nation."
137+
));
138+
76139
return sendMessage(sender, subCommandBuilder.build());
77140
}
78141

79-
public boolean listMembers(final @NotNull Member member, final @NotNull CommandSender sender) {
80-
if (!sender.hasPermission(Permission.NATION_MEMBERS_LIST))
142+
public boolean listMembers(
143+
final @Nullable Member member,
144+
final @NotNull Nation nation,
145+
final @NotNull CommandSender sender
146+
) {
147+
if (!sender.hasPermission(Permission.NATION_MEMBERS_LIST_OTHER) && (
148+
member == null || !nation.id.equals(member.nationID)
149+
|| !sender.hasPermission(Permission.NATION_MEMBERS_LIST)
150+
))
81151
return sendMessage(sender, SMPCore.messages().errorNoPermission());
82-
83-
final @NotNull Optional<@NotNull Nation> nation = member.nation();
84-
if (nation.isEmpty())
85-
return sendMessage(sender, SMPCore.messages().errorNotInNation());
86-
87-
return sendMessage(sender, SMPCore.messages().nationMembersList(nation.get(), sender));
152+
else
153+
return sendMessage(sender, SMPCore.messages().nationMembersList(nation, sender));
88154
}
89155

90-
public boolean kickMember(final @NotNull Member member, final @NotNull CommandSender sender, final @NotNull String label, final @NotNull String @NotNull [] args) {
91-
if (!sender.hasPermission(Permission.NATION_MEMBERS_KICK))
156+
public boolean kickMember(
157+
final @Nullable Member member,
158+
final @NotNull Nation nation,
159+
final @NotNull CommandSender sender,
160+
final @NotNull String label,
161+
final @NotNull String @NotNull [] args
162+
) {
163+
if (!sender.hasPermission(Permission.NATION_MEMBERS_KICK_OTHER) && (
164+
member == null || !nation.id.equals(member.nationID)
165+
|| !sender.hasPermission(Permission.NATION_MEMBERS_KICK)
166+
))
92167
return sendMessage(sender, SMPCore.messages().errorNoPermission());
93-
final @NotNull Optional<@NotNull Nation> nation = member.nation();
94-
if (nation.isEmpty())
95-
return sendMessage(sender, SMPCore.messages().errorNotInNation());
96-
if (args.length == 0) return sendMessage(sender, SMPCore.messages().usage(label, "kick <member>"));
168+
169+
if (args.length == 0)
170+
return sendMessage(sender, SMPCore.messages().usage(label, "kick <member>"));
171+
97172
final @NotNull OfflinePlayer target = sender.getServer().getOfflinePlayer(args[0]);
98173
final @NotNull Optional<@NotNull Member> targetMemberOptional = Member.get(target);
99174
if (targetMemberOptional.isEmpty())
100175
return sendMessage(sender, SMPCore.messages().errorNotMember(target));
176+
101177
final @NotNull Member targetMember = targetMemberOptional.get();
102178
if (targetMember.nationID == null || !targetMember.nationID.equals(member.nationID))
103179
return sendMessage(sender, SMPCore.messages().errorMemberNotYourNation(targetMember));
104-
if (targetMember.uuid.equals(nation.get().leaderUUID) || targetMember.uuid.equals(nation.get().viceLeaderUUID))
180+
if (targetMember.uuid.equals(nation.leaderUUID) || targetMember.uuid.equals(nation.viceLeaderUUID))
105181
return sendMessage(sender, SMPCore.messages().errorKickLeadership());
106182

107-
nation.get().remove(targetMember);
183+
nation.remove(targetMember);
108184
return sendMessage(sender, SMPCore.messages().nationMembersKicked(targetMember));
109185
}
110186
}

src/main/resources/messages.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ unbanned-member: <green>(!) Unbanned member <gray><player></gray> and <gray><n-a
1010

1111
subcommands:
1212
header: <green><name> Sub Commands:</green> <gray>(<usage>)</gray>
13-
entry: <click:suggest_command:<command>><dark_gray>></dark_gray> <white><label></white><gray><args></gray></click>
14-
entry-with-description: <click:suggest_command:<command>><dark_gray>></dark_gray> <white><label></white><gray><args></gray> <dark_gray>-</dark_gray> <gray><description></gray></click>
13+
entry: <click:suggest_command:"<command>"><dark_gray>></dark_gray> <white><label></white><gray><args></gray></click>
14+
entry-with-description: <click:suggest_command:"<command>"><dark_gray>></dark_gray> <white><label></white><gray><args></gray> <dark_gray>-</dark_gray> <gray><description></gray></click>
1515
argument:
1616
required: <dark_gray><</dark_gray><arg><dark_gray>></dark_gray>
1717
optional: <dark_gray>[</dark_gray><arg><dark_gray>]</dark_gray>
@@ -80,4 +80,5 @@ error:
8080
not-in-nation: <red>(!) You are not a member of any nation.</red>
8181
member-not-your-nation: <red>(!) Member <gray><player></gray> is not a member of your nation.</red>
8282
not-player: <red>(!) You must be a player to use this command.</red>
83-
nation-kick-leadership: <red>(!) You cannot kick a member of the nation's leadership.</red>
83+
kick-leadership: <red>(!) You cannot kick a member of the nation's leadership.</red>
84+
nation-not-found: <red>(!) Nation <gray><nation></gray> not found.</red>

0 commit comments

Comments
 (0)