Skip to content

Commit 813cc99

Browse files
Add ExecutableBy.OPERATORS
1 parent a0a4c3f commit 813cc99

3 files changed

Lines changed: 41 additions & 5 deletions

File tree

src/main/java/org/skriptlang/skript/bukkit/command/custom/ExecutableBy.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package org.skriptlang.skript.bukkit.command.custom;
22

3+
import com.google.common.collect.Sets;
34
import org.bukkit.command.BlockCommandSender;
45
import org.bukkit.command.CommandSender;
56
import org.bukkit.command.ConsoleCommandSender;
67
import org.bukkit.command.RemoteConsoleCommandSender;
78
import org.bukkit.entity.Player;
89

10+
import java.util.Set;
911
import java.util.function.Predicate;
1012

1113
/**
@@ -18,6 +20,11 @@ public enum ExecutableBy {
1820
*/
1921
PLAYERS(sender -> sender instanceof Player),
2022

23+
/**
24+
* This command is only executable by operators.
25+
*/
26+
OPERATORS(CommandSender::isOp),
27+
2128
/**
2229
* This command is only executable by console.
2330
*/
@@ -45,9 +52,21 @@ public Predicate<CommandSender> predicate() {
4552
public String toString() {
4653
return switch (this) {
4754
case PLAYERS -> "players";
55+
case OPERATORS -> "operators";
4856
case CONSOLE -> "the console";
4957
case BLOCKS -> "blocks";
5058
};
5159
}
5260

61+
/**
62+
* Compares whether a set of {@link ExecutableBy}s is a superset of another.
63+
* @param first The first set.
64+
* @param second The second set.
65+
* @return Whether the first set includes all {@link CommandSender}s covered by the second.
66+
*/
67+
public static boolean isSuperSet(Set<ExecutableBy> first, Set<ExecutableBy> second) {
68+
Set<ExecutableBy> difference = Sets.difference(second, first);
69+
return difference.isEmpty() || difference.equals(Set.of(ExecutableBy.OPERATORS));
70+
}
71+
5372
}

src/main/java/org/skriptlang/skript/bukkit/command/elements/structures/util/SubCommandEntryData.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,14 @@ protected List<String> getValue(String value) {
9898
protected Set<ExecutableBy> getValue(String value) {
9999
EnumSet<ExecutableBy> executableBy = EnumSet.noneOf(ExecutableBy.class);
100100
for (String type : pattern.split(value)) {
101-
if (type.equalsIgnoreCase("console") || type.equalsIgnoreCase("the console")) {
102-
executableBy.add(ExecutableBy.CONSOLE);
103-
} else if (type.equalsIgnoreCase("players") || type.equalsIgnoreCase("player")) {
101+
// "player" kept for compatibility
102+
if (type.equalsIgnoreCase("players") || type.equalsIgnoreCase("player")) {
104103
executableBy.add(ExecutableBy.PLAYERS);
105-
} else if (type.equalsIgnoreCase("blocks") || type.equalsIgnoreCase("block")) {
104+
} else if (type.equalsIgnoreCase("operators") || type.equalsIgnoreCase("ops")) {
105+
executableBy.add(ExecutableBy.OPERATORS);
106+
} else if (type.equalsIgnoreCase("console") || type.equalsIgnoreCase("the console")) {
107+
executableBy.add(ExecutableBy.CONSOLE);
108+
} else if (type.equalsIgnoreCase("blocks")) {
106109
executableBy.add(ExecutableBy.BLOCKS);
107110
} else {
108111
Skript.error("Invalid command sender type: " + type);
@@ -239,7 +242,7 @@ public SubCommandEntryData(String key, boolean optional, boolean multiple) {
239242
return null;
240243
}
241244
Set<ExecutableBy> parent = parsingData.getExecutorData(ExecutorData::executableBy);
242-
if (parent != null && !parent.containsAll(executableBy)) {
245+
if (parent != null && !ExecutableBy.isSuperSet(parent, executableBy)) {
243246
Skript.error("It is not possible to restrict execution to " + CollectionUtils.toString(executableBy, true) +
244247
" as the parent command is only executable by " + CollectionUtils.toString(parent, true) + ".");
245248
return null;

src/test/skript/tests/bukkit/command/StructCommand.sk

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,19 @@ parse:
3030
command /entries_test_3:
3131
subcommand test:
3232

33+
# expect operators to be allowed below players (or other kinds)
34+
parse:
35+
results: {-StructCommand::entries::4::*}
36+
code:
37+
command /entries_test_4:
38+
executable by: players
39+
trigger:
40+
stop
41+
subcommand test:
42+
executable by: operators
43+
trigger:
44+
stop
45+
3346
# expect error for duplicate argument names
3447
parse:
3548
results: {-StructCommand::args::1::*}
@@ -114,6 +127,7 @@ test "StructCommand":
114127
assert {-StructCommand::entries::1::*} is {_error_missing_trigger}
115128
assert {-StructCommand::entries::2::*} is "It is not possible to restrict execution to the console as the parent command is only executable by players."
116129
assert {-StructCommand::entries::3::*} is {_error_missing_trigger} and {_error_missing_trigger}
130+
assert {-StructCommand::entries::4::*} is not set
117131
assert {-StructCommand::args::1::*} is "The argument name 'x' was already used."
118132
assert {-StructCommand::args::2::*} is "text arguments do not support minimum or maximum values."
119133
assert {-StructCommand::args::3::*} is not set

0 commit comments

Comments
 (0)