Skip to content

Commit 4a2bfc7

Browse files
authored
Merge pull request #3361 from Multiverse/v5.4
V5.4
2 parents f053944 + 3074cfa commit 4a2bfc7

32 files changed

+737
-367
lines changed

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.bukkit.Material;
2828
import org.bukkit.World;
2929
import org.bukkit.command.CommandSender;
30+
import org.bukkit.entity.Entity;
3031
import org.bukkit.entity.Player;
3132
import org.bukkit.entity.SpawnCategory;
3233
import org.jetbrains.annotations.NotNull;
@@ -43,9 +44,9 @@
4344
import org.mvplugins.multiverse.core.destination.DestinationInstance;
4445
import org.mvplugins.multiverse.core.destination.DestinationSuggestionPacket;
4546
import org.mvplugins.multiverse.core.destination.DestinationsProvider;
47+
import org.mvplugins.multiverse.core.destination.core.WorldDestination;
4648
import org.mvplugins.multiverse.core.permissions.CorePermissionsChecker;
4749
import org.mvplugins.multiverse.core.utils.REPatterns;
48-
import org.mvplugins.multiverse.core.utils.StringFormatter;
4950
import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld;
5051
import org.mvplugins.multiverse.core.world.MultiverseWorld;
5152
import org.mvplugins.multiverse.core.world.WorldManager;
@@ -100,7 +101,7 @@ public class MVCommandCompletions extends PaperCommandCompletions {
100101
registerAsyncCompletion("mvworlds", this::suggestMVWorlds);
101102
registerAsyncCompletion("mvworldpropsname", this::suggestMVWorldPropsName);
102103
registerAsyncCompletion("mvworldpropsvalue", this::suggestMVWorldPropsValue);
103-
registerAsyncCompletion("playersarray", this::suggestPlayersArray);
104+
registerCompletion("playersarray", this::suggestPlayersArray); // getting online players cannot be async
104105
registerStaticCompletion("propsmodifyaction", suggestEnums(PropertyModifyAction.class));
105106
registerStaticCompletion("spawncategories", suggestEnums(SpawnCategory.class));
106107
registerAsyncCompletion("spawncategorypropsname", this::suggestSpawnCategoryPropsName);
@@ -224,18 +225,22 @@ private Collection<String> suggestDestinations(BukkitCommandCompletionContext co
224225
// Most likely console did not specify a player
225226
return Collections.<String>emptyList();
226227
}
227-
if (context.hasConfig("othersOnly") && (players.length == 1 && players[0].equals(context.getIssuer().getIssuer()))) {
228+
CommandSender sender = context.getIssuer().getIssuer();
229+
if (context.hasConfig("othersOnly") && (players.length == 1 && players[0].equals(sender))) {
228230
return Collections.<String>emptyList();
229231
}
230-
return suggestDestinationsWithPerms(context.getIssuer().getIssuer(), players, context.getInput());
232+
return suggestDestinationsWithPerms(sender, Arrays.asList(players), context.getInput());
231233
})
232234
.getOrElse(Collections.emptyList());
233235
}
234236

235-
private Collection<String> suggestDestinationsWithPerms(CommandSender teleporter, Player[] players, String deststring) {
237+
private Collection<String> suggestDestinationsWithPerms(CommandSender teleporter, List<Entity> teleportees, String deststring) {
236238
return destinationsProvider.suggestDestinations(teleporter, deststring).stream()
239+
.filter(packet -> !config.getSimplifiedDestinationTabCompletion()
240+
|| packet.destination() instanceof WorldDestination
241+
|| deststring.startsWith(packet.destination().getIdentifier() + ":"))
237242
.filter(packet -> corePermissionsChecker
238-
.checkDestinationPacketPermission(teleporter, Arrays.asList(players), packet))
243+
.checkDestinationPacketPermission(teleporter, teleportees, packet))
239244
.map(DestinationSuggestionPacket::parsableString)
240245
.toList();
241246
}

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

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import co.aikar.commands.PaperCommandContexts;
1212
import co.aikar.commands.contexts.ContextResolver;
1313
import com.google.common.base.Strings;
14+
import io.vavr.control.Option;
1415
import io.vavr.control.Try;
1516
import jakarta.inject.Inject;
1617
import org.bukkit.Bukkit;
@@ -272,13 +273,25 @@ private IssuerAwareContextBuilder<Player> playerContextBuilder() {
272273
private IssuerAwareContextBuilder<Player[]> playerArrayContextBuilder() {
273274
return new IssuerAwareContextBuilder<Player[]>()
274275
.fromPlayer((context, player) -> new Player[]{player})
275-
.fromInput((context, input) -> {
276-
Player[] players = PlayerFinder.getMulti(input, context.getSender()).toArray(new Player[0]);
277-
return (players.length == 0) ? null : players;
278-
})
276+
.fromInput((context, input) -> PlayerFinder
277+
.tryGetMulti(input, context.getSender())
278+
.map(list -> list.toArray(new Player[0]))
279+
.map(arr -> (arr.length == 0) ? null : arr)
280+
.getOrElseThrow(failure -> {
281+
if (failure instanceof MVInvalidCommandArgument mvFailure) {
282+
throw mvFailure;
283+
}
284+
throw new InvalidCommandArgument(failure.getLocalizedMessage() + " "
285+
+ Option.of(failure.getCause()).map(Throwable::getLocalizedMessage).getOrElse(""));
286+
}))
279287
.issuerOnlyFailMessage((context) -> Message.of("This command can only be used by a player."))
280288
.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."));
289+
.inputOnlyFailMessage((context, input) -> {
290+
if (PlayerFinder.isSelector(input)) {
291+
return Message.of("No player(s) matched selector: " + input + ".");
292+
}
293+
return Message.of("Player(s) " + input + " not found.");
294+
});
282295
}
283296

284297
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/EntitySpawnConfigCommand.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ final class EntitySpawnConfigCommand extends CoreCommand {
5252
void onInfoCommand(
5353
MVCommandIssuer issuer,
5454

55-
@Flags("resolve=issuerAware")
55+
@Flags("resolve=issuerAware,maxArgForAware=0")
5656
@Syntax("[world]")
5757
MultiverseWorld world,
5858

@@ -91,7 +91,7 @@ private List<String> getEntitySpawnConfigList(MultiverseWorld world) {
9191
void onModifyCommand(
9292
MVCommandIssuer issuer,
9393

94-
@Flags("resolve=issuerAware")
94+
@Flags("resolve=issuerAware,maxArgForAware=4")
9595
@Syntax("[world]")
9696
MultiverseWorld world,
9797

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ class InfoCommand extends CoreCommand {
6161
public void onInfoCommand(
6262
MVCommandIssuer issuer,
6363

64-
@Flags("resolve=issuerAware")
65-
@Syntax("<world>")
64+
@Flags("resolve=issuerAware,maxArgForAware=0")
65+
@Syntax("[world]")
6666
@Description("{@@mv-core.info.description.world}")
6767
LoadedMultiverseWorld world,
6868

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,12 @@ class ModifyCommand extends CoreCommand {
4949
"@propsmodifyaction:notByIssuerForArg=arg1|@mvworldpropsname:byIssuerForArg=arg1 " +
5050
"@mvworldpropsname:notByIssuerForArg=arg1|@mvworldpropsvalue:byIssuerForArg=arg1 " +
5151
"@mvworldpropsvalue:notByIssuerForArg=arg1")
52-
@Syntax("[world] <set|add|remove|reset> <property> <value>")
52+
@Syntax("[world] <set|add|remove|reset> <property> [value]")
5353
@Description("{@@mv-core.modify.description}")
5454
void onModifyCommand(// SUPPRESS CHECKSTYLE: ParameterNumber
5555
MVCommandIssuer issuer,
5656

57-
@Flags("resolve=issuerAware")
57+
@Flags("resolve=issuerAware,maxArgForAware=3")
5858
@Syntax("[world]")
5959
@Description("{@@mv-core.modify.world.description}")
6060
@NotNull MultiverseWorldValue worldValue,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ final class PurgeAllEntitiesCommand extends CoreCommand {
3333
void onPurgeAllEntitiesCommand(
3434
MVCommandIssuer issuer,
3535

36-
@Flags("resolve=issuerAware")
36+
@Flags("resolve=issuerAware,maxArgForAware=1")
3737
@Syntax("[world]")
3838
LoadedMultiverseWorld world,
3939

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ final class PurgeEntitiesCommand extends CoreCommand {
2828
void onPurgeEntityCommand(
2929
MVCommandIssuer issuer,
3030

31-
@Flags("resolve=issuerAware")
31+
@Flags("resolve=issuerAware,maxArgForAware=0")
3232
@Syntax("[world]")
3333
LoadedMultiverseWorld world
3434
) {

0 commit comments

Comments
 (0)