Skip to content

Commit 6dcb40f

Browse files
authored
Merge pull request #3380 from Multiverse/fix/issuer-aware-argument
Better error message for teleport command when no players match selectors
2 parents 2bb6010 + f181bb7 commit 6dcb40f

File tree

4 files changed

+67
-76
lines changed

4 files changed

+67
-76
lines changed

src/main/java/org/mvplugins/multiverse/core/command/MVCommandContexts.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,12 @@ private IssuerAwareContextBuilder<Player[]> playerArrayContextBuilder() {
278278
})
279279
.issuerOnlyFailMessage((context) -> Message.of("This command can only be used by a player."))
280280
.issuerAwareInputFailMessage((context, input) -> Message.of("Invalid player: " + input + ". Either specify an online player or use this command as a player."))
281-
.inputOnlyFailMessage((context, input) -> Message.of("Player " + input + " not found."));
281+
.inputOnlyFailMessage((context, input) -> {
282+
if (PlayerFinder.isSelector(input)) {
283+
return Message.of("No player(s) matched selector: " + input + ".");
284+
}
285+
return Message.of("Player(s) " + input + " not found.");
286+
});
282287
}
283288

284289
private PlayerLocation parsePlayerLocation(BukkitCommandExecutionContext context) {

src/main/java/org/mvplugins/multiverse/core/command/context/issueraware/IssuerAwareContextBuilder.java

Lines changed: 49 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -123,48 +123,8 @@ public IssuerAwareContextBuilder<T> inputOnlyFailMessage(BiFunction<BukkitComman
123123
*/
124124
@ApiStatus.AvailableSince("5.1")
125125
public IssuerAwareContextResolver<T, BukkitCommandExecutionContext> generateContext() {
126-
Objects.requireNonNull(fromPlayer);
127-
Objects.requireNonNull(fromInput);
128-
Objects.requireNonNull(issuerOnlyFailMessage);
129-
Objects.requireNonNull(issuerAwarePlayerFailMessage);
130-
Objects.requireNonNull(issuerAwareInputFailMessage);
131-
Objects.requireNonNull(inputOnlyFailMessage);
132-
133-
return context -> {
134-
BukkitCommandIssuer issuer = context.getIssuer();
135-
String resolve = context.getFlagValue("resolve", "");
136-
137-
if (resolve.equals("issuerOnly")) {
138-
if (issuer.isPlayer()) {
139-
T result = fromPlayer.apply(context, issuer.getPlayer());
140-
if (result != null) {
141-
return result;
142-
}
143-
}
144-
throw new InvalidCommandArgument(issuerOnlyFailMessage.apply(context).formatted(issuer));
145-
}
146-
147-
String input = context.getFirstArg();
148-
T result = fromInput.apply(context, input);
149-
if (result != null) {
150-
context.popFirstArg();
151-
return result;
152-
}
153-
154-
if (resolve.equals("issuerAware")) {
155-
if (issuer.isPlayer()) {
156-
Player player = issuer.getPlayer();
157-
result = fromPlayer.apply(context, player);
158-
if (result != null) {
159-
return result;
160-
}
161-
throw new InvalidCommandArgument(issuerAwarePlayerFailMessage.apply(context, player).formatted(issuer));
162-
}
163-
throw new InvalidCommandArgument(issuerAwareInputFailMessage.apply(context, input).formatted(issuer));
164-
}
165-
166-
throw new InvalidCommandArgument(inputOnlyFailMessage.apply(context, input).formatted(issuer));
167-
};
126+
validateRequiredVariables();
127+
return context -> resolveValue(context, GenericIssuerAwareValue::new).value;
168128
}
169129

170130
/**
@@ -178,49 +138,66 @@ public IssuerAwareContextResolver<T, BukkitCommandExecutionContext> generateCont
178138
*/
179139
@ApiStatus.AvailableSince("5.1")
180140
public <I extends IssuerAwareValue> IssuerAwareContextResolver<I, BukkitCommandExecutionContext> generateContext(BiFunction<Boolean, T, I> createValue) {
181-
// todo: This is a copy and paste from above
141+
validateRequiredVariables();
142+
return context -> resolveValue(context, createValue);
143+
}
182144

145+
private void validateRequiredVariables() {
183146
Objects.requireNonNull(fromPlayer);
184147
Objects.requireNonNull(fromInput);
185148
Objects.requireNonNull(issuerOnlyFailMessage);
186149
Objects.requireNonNull(issuerAwarePlayerFailMessage);
187150
Objects.requireNonNull(issuerAwareInputFailMessage);
188151
Objects.requireNonNull(inputOnlyFailMessage);
152+
}
189153

190-
return context -> {
191-
BukkitCommandIssuer issuer = context.getIssuer();
192-
String resolve = context.getFlagValue("resolve", "");
154+
private <I extends IssuerAwareValue> I resolveValue(BukkitCommandExecutionContext context, BiFunction<Boolean, T, I> createValue) {
155+
BukkitCommandIssuer issuer = context.getIssuer();
156+
String resolve = context.getFlagValue("resolve", "");
193157

194-
if (resolve.equals("issuerOnly")) {
195-
if (issuer.isPlayer()) {
196-
T result = fromPlayer.apply(context, issuer.getPlayer());
197-
if (result != null) {
198-
return createValue.apply(true, result);
199-
}
158+
if (resolve.equals("issuerOnly")) {
159+
if (issuer.isPlayer()) {
160+
T result = fromPlayer.apply(context, issuer.getPlayer());
161+
if (result != null) {
162+
return createValue.apply(true, result);
200163
}
201-
throw new InvalidCommandArgument(issuerOnlyFailMessage.apply(context).formatted(issuer));
202164
}
203-
204-
String input = context.getFirstArg();
205-
T result = fromInput.apply(context, input);
206-
if (result != null) {
207-
context.popFirstArg();
208-
return createValue.apply(false, result);
209-
}
210-
211-
if (resolve.equals("issuerAware")) {
212-
if (issuer.isPlayer()) {
213-
Player player = issuer.getPlayer();
214-
result = fromPlayer.apply(context, player);
215-
if (result != null) {
216-
return createValue.apply(true, result);
217-
}
218-
throw new InvalidCommandArgument(issuerAwarePlayerFailMessage.apply(context, player).formatted(issuer));
165+
throw new InvalidCommandArgument(issuerOnlyFailMessage.apply(context).formatted(issuer));
166+
}
167+
168+
String input = context.getFirstArg();
169+
T result = fromInput.apply(context, input);
170+
if (result != null) {
171+
context.popFirstArg();
172+
return createValue.apply(false, result);
173+
}
174+
175+
int maxArgForAware = context.getFlagValue("maxArgForAware", Integer.MAX_VALUE);
176+
long argLengthWithoutFlags = context.getArgs().stream()
177+
.takeWhile(value -> !value.startsWith("--") && !value.isEmpty())
178+
.count();
179+
180+
if (resolve.equals("issuerAware") && argLengthWithoutFlags <= maxArgForAware) {
181+
if (issuer.isPlayer()) {
182+
Player player = issuer.getPlayer();
183+
result = fromPlayer.apply(context, player);
184+
if (result != null) {
185+
return createValue.apply(true, result);
219186
}
220-
throw new InvalidCommandArgument(issuerAwareInputFailMessage.apply(context, input).formatted(issuer));
187+
throw new InvalidCommandArgument(issuerAwarePlayerFailMessage.apply(context, player).formatted(issuer));
221188
}
189+
throw new InvalidCommandArgument(issuerAwareInputFailMessage.apply(context, input).formatted(issuer));
190+
}
191+
192+
throw new InvalidCommandArgument(inputOnlyFailMessage.apply(context, input).formatted(issuer));
193+
}
194+
195+
private static class GenericIssuerAwareValue<T> extends IssuerAwareValue {
196+
private final T value;
222197

223-
throw new InvalidCommandArgument(inputOnlyFailMessage.apply(context, input).formatted(issuer));
224-
};
198+
public GenericIssuerAwareValue(boolean byIssuer, T value) {
199+
super(byIssuer);
200+
this.value = value;
201+
}
225202
}
226203
}

src/main/java/org/mvplugins/multiverse/core/commands/TeleportCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ final class TeleportCommand extends CoreCommand {
6464
void onTeleportCommand(
6565
MVCommandIssuer issuer,
6666

67-
@co.aikar.commands.annotation.Flags("resolve=issuerAware")
67+
@co.aikar.commands.annotation.Flags("resolve=issuerAware,maxArgForAware=1")
6868
@Syntax("[player]")
6969
@Description("{@@mv-core.teleport.player.description}")
7070
PlayerArrayValue playersValue,

src/main/java/org/mvplugins/multiverse/core/utils/PlayerFinder.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
import java.util.ArrayList;
44
import java.util.List;
55
import java.util.UUID;
6-
import java.util.regex.Pattern;
76
import java.util.stream.Collectors;
87

98
import com.dumptruckman.minecraft.util.Logging;
109
import com.google.common.base.Strings;
1110
import org.bukkit.Bukkit;
1211
import org.bukkit.command.CommandSender;
1312
import org.bukkit.entity.Player;
13+
import org.jetbrains.annotations.ApiStatus;
1414
import org.jetbrains.annotations.NotNull;
1515
import org.jetbrains.annotations.Nullable;
1616

@@ -112,7 +112,16 @@ public final class PlayerFinder {
112112
return playerResults;
113113
}
114114

115-
private static boolean isSelector(@NotNull String playerIdentifier) {
115+
/**
116+
* Check if the player identifier is a selector.
117+
*
118+
* @param playerIdentifier An identifier of name, UUID or selector.
119+
* @return True if the identifier is a selector, else false.
120+
*
121+
* @since 5.4
122+
*/
123+
@ApiStatus.AvailableSince("5.4")
124+
public static boolean isSelector(@NotNull String playerIdentifier) {
116125
return VANILLA_SELECTORS.stream().anyMatch(playerIdentifier::startsWith);
117126
}
118127

0 commit comments

Comments
 (0)