mirror of
https://github.com/PaperMC/Paper.git
synced 2024-09-27 14:12:45 +02:00
157 lines
12 KiB
Diff
157 lines
12 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
|
Date: Sun, 22 Aug 2021 15:21:57 -0700
|
|
Subject: [PATCH] Fix entity type tags suggestions in selectors
|
|
|
|
This would really be better as a client fix because just to fix it
|
|
all EntityArguments have been told to ask the server for completions
|
|
when if this was fixed on the client, that wouldn't be needed.
|
|
|
|
Mojira Issue: https://bugs.mojang.com/browse/MC-235045
|
|
|
|
diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java
|
|
index 3c0d2332207ba638faaaa4280bce18c334a01271..e6c7f62ed379a78645933670299e4fcda8540ed1 100644
|
|
--- a/src/main/java/net/minecraft/commands/CommandSourceStack.java
|
|
+++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java
|
|
@@ -462,4 +462,20 @@ public class CommandSourceStack implements ExecutionCommandSource<CommandSourceS
|
|
return this.source.getBukkitSender(this);
|
|
}
|
|
// CraftBukkit end
|
|
+ // Paper start - tell clients to ask server for suggestions for EntityArguments
|
|
+ @Override
|
|
+ public Collection<String> getSelectedEntities() {
|
|
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().commands.fixTargetSelectorTagCompletion && this.source instanceof ServerPlayer player) {
|
|
+ final Entity cameraEntity = player.getCamera();
|
|
+ final double pickDistance = player.gameMode.getGameModeForPlayer().isCreative() ? 6.0F : 4.5F;
|
|
+ final Vec3 min = cameraEntity.getEyePosition(1.0F);
|
|
+ final Vec3 viewVector = cameraEntity.getViewVector(1.0F);
|
|
+ final Vec3 max = min.add(viewVector.x * pickDistance, viewVector.y * pickDistance, viewVector.z * pickDistance);
|
|
+ final net.minecraft.world.phys.AABB aabb = cameraEntity.getBoundingBox().expandTowards(viewVector.scale(pickDistance)).inflate(1.0D, 1.0D, 1.0D);
|
|
+ final net.minecraft.world.phys.EntityHitResult hitResult = net.minecraft.world.entity.projectile.ProjectileUtil.getEntityHitResult(cameraEntity, min, max, aabb, (e) -> !e.isSpectator() && e.isPickable(), pickDistance * pickDistance);
|
|
+ return hitResult != null ? java.util.Collections.singletonList(hitResult.getEntity().getStringUUID()) : SharedSuggestionProvider.super.getSelectedEntities();
|
|
+ }
|
|
+ return SharedSuggestionProvider.super.getSelectedEntities();
|
|
+ }
|
|
+ // Paper end - tell clients to ask server for suggestions for EntityArguments
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
|
|
index e1aa1e1f23512fc7d2267ff8e75358b67cb419a3..aa2fca6917fb67fe0e9ba067d11487c3a274f675 100644
|
|
--- a/src/main/java/net/minecraft/commands/Commands.java
|
|
+++ b/src/main/java/net/minecraft/commands/Commands.java
|
|
@@ -517,6 +517,7 @@ public class Commands {
|
|
private void fillUsableCommands(CommandNode<CommandSourceStack> tree, CommandNode<SharedSuggestionProvider> result, CommandSourceStack source, Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> resultNodes) {
|
|
Iterator iterator = tree.getChildren().iterator();
|
|
|
|
+ boolean registeredAskServerSuggestionsForTree = false; // Paper - tell clients to ask server for suggestions for EntityArguments
|
|
while (iterator.hasNext()) {
|
|
CommandNode<CommandSourceStack> commandnode2 = (CommandNode) iterator.next();
|
|
// Paper start - Brigadier API
|
|
@@ -543,6 +544,12 @@ public class Commands {
|
|
|
|
if (requiredargumentbuilder.getSuggestionsProvider() != null) {
|
|
requiredargumentbuilder.suggests(SuggestionProviders.safelySwap(requiredargumentbuilder.getSuggestionsProvider()));
|
|
+ // Paper start - tell clients to ask server for suggestions for EntityArguments
|
|
+ registeredAskServerSuggestionsForTree = requiredargumentbuilder.getSuggestionsProvider() == net.minecraft.commands.synchronization.SuggestionProviders.ASK_SERVER;
|
|
+ } else if (io.papermc.paper.configuration.GlobalConfiguration.get().commands.fixTargetSelectorTagCompletion && !registeredAskServerSuggestionsForTree && requiredargumentbuilder.getType() instanceof net.minecraft.commands.arguments.EntityArgument) {
|
|
+ requiredargumentbuilder.suggests(requiredargumentbuilder.getType()::listSuggestions);
|
|
+ registeredAskServerSuggestionsForTree = true; // You can only
|
|
+ // Paper end - tell clients to ask server for suggestions for EntityArguments
|
|
}
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/commands/arguments/EntityArgument.java b/src/main/java/net/minecraft/commands/arguments/EntityArgument.java
|
|
index 2043001c16b3530c2d3f52efda10bcad424881c0..7976885b902a6ce7d80f31e49448c99452eb9765 100644
|
|
--- a/src/main/java/net/minecraft/commands/arguments/EntityArgument.java
|
|
+++ b/src/main/java/net/minecraft/commands/arguments/EntityArgument.java
|
|
@@ -131,7 +131,7 @@ public class EntityArgument implements ArgumentType<EntitySelector> {
|
|
final boolean permission = object instanceof CommandSourceStack stack
|
|
? stack.bypassSelectorPermissions || stack.hasPermission(2, "minecraft.command.selector")
|
|
: icompletionprovider.hasPermission(2);
|
|
- EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader, permission);
|
|
+ EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader, permission, true); // Paper - tell clients to ask server for suggestions for EntityArguments
|
|
// Paper end - Fix EntityArgument suggestion permissions
|
|
|
|
try {
|
|
@@ -141,7 +141,19 @@ public class EntityArgument implements ArgumentType<EntitySelector> {
|
|
}
|
|
|
|
return argumentparserselector.fillSuggestions(suggestionsbuilder, (suggestionsbuilder1) -> {
|
|
- Collection<String> collection = icompletionprovider.getOnlinePlayerNames();
|
|
+ // Paper start - tell clients to ask server for suggestions for EntityArguments
|
|
+ final Collection<String> collection;
|
|
+ if (icompletionprovider instanceof CommandSourceStack commandSourceStack && commandSourceStack.getEntity() instanceof ServerPlayer sourcePlayer) {
|
|
+ collection = new java.util.ArrayList<>();
|
|
+ for (final ServerPlayer player : commandSourceStack.getServer().getPlayerList().getPlayers()) {
|
|
+ if (sourcePlayer.getBukkitEntity().canSee(player.getBukkitEntity())) {
|
|
+ collection.add(player.getGameProfile().getName());
|
|
+ }
|
|
+ }
|
|
+ } else {
|
|
+ collection = icompletionprovider.getOnlinePlayerNames();
|
|
+ }
|
|
+ // Paper end - tell clients to ask server for suggestions for EntityArguments
|
|
Iterable<String> iterable = this.playersOnly ? collection : Iterables.concat(collection, icompletionprovider.getSelectedEntities());
|
|
|
|
SharedSuggestionProvider.suggest((Iterable) iterable, suggestionsbuilder1);
|
|
diff --git a/src/main/java/net/minecraft/commands/arguments/selector/EntitySelectorParser.java b/src/main/java/net/minecraft/commands/arguments/selector/EntitySelectorParser.java
|
|
index 3d897ec6920eff6176ddac9f0442a997b9ef14fd..abaf1ea340c69c8bee80e64567b44b5ce66d5fa3 100644
|
|
--- a/src/main/java/net/minecraft/commands/arguments/selector/EntitySelectorParser.java
|
|
+++ b/src/main/java/net/minecraft/commands/arguments/selector/EntitySelectorParser.java
|
|
@@ -113,12 +113,19 @@ public class EntitySelectorParser {
|
|
private boolean hasScores;
|
|
private boolean hasAdvancements;
|
|
private boolean usesSelectors;
|
|
+ public boolean parsingEntityArgumentSuggestions; // Paper - tell clients to ask server for suggestions for EntityArguments
|
|
|
|
public EntitySelectorParser(StringReader reader) {
|
|
this(reader, true);
|
|
}
|
|
|
|
public EntitySelectorParser(StringReader reader, boolean atAllowed) {
|
|
+ // Paper start - tell clients to ask server for suggestions for EntityArguments
|
|
+ this(reader, atAllowed, false);
|
|
+ }
|
|
+ public EntitySelectorParser(StringReader reader, boolean atAllowed, boolean parsingEntityArgumentSuggestions) {
|
|
+ this.parsingEntityArgumentSuggestions = parsingEntityArgumentSuggestions;
|
|
+ // Paper end - tell clients to ask server for suggestions for EntityArguments
|
|
this.distance = MinMaxBounds.Doubles.ANY;
|
|
this.level = MinMaxBounds.Ints.ANY;
|
|
this.rotX = WrappedMinMaxBounds.ANY;
|
|
diff --git a/src/main/java/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java b/src/main/java/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java
|
|
index 44982ff2cdd6e03f0b9ce8c3cc87561ef183ef06..626fe7a45c2edba68eb201974e9f8f5eebf75cc0 100644
|
|
--- a/src/main/java/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java
|
|
+++ b/src/main/java/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java
|
|
@@ -76,6 +76,19 @@ public class EntitySelectorOptions {
|
|
public static final DynamicCommandExceptionType ERROR_ENTITY_TYPE_INVALID = new DynamicCommandExceptionType(
|
|
entity -> Component.translatableEscape("argument.entity.options.type.invalid", entity)
|
|
);
|
|
+ // Paper start - tell clients to ask server for suggestions for EntityArguments
|
|
+ public static final DynamicCommandExceptionType ERROR_ENTITY_TAG_INVALID = new DynamicCommandExceptionType((object) -> {
|
|
+ return io.papermc.paper.adventure.PaperAdventure
|
|
+ .asVanilla(net.kyori.adventure.text.Component
|
|
+ .text("Invalid or unknown entity type tag '" + object + "'")
|
|
+ .hoverEvent(net.kyori.adventure.text.event.HoverEvent
|
|
+ .showText(net.kyori.adventure.text.Component
|
|
+ .text("You can disable this error in 'paper.yml'")
|
|
+ )
|
|
+ )
|
|
+ );
|
|
+ });
|
|
+ // Paper end - tell clients to ask server for suggestions for EntityArguments
|
|
|
|
private static void register(String id, EntitySelectorOptions.Modifier handler, Predicate<EntitySelectorParser> condition, Component description) {
|
|
OPTIONS.put(id, new EntitySelectorOptions.Option(handler, condition, description));
|
|
@@ -297,6 +310,12 @@ public class EntitySelectorOptions {
|
|
|
|
if (reader.isTag()) {
|
|
TagKey<EntityType<?>> tagKey = TagKey.create(Registries.ENTITY_TYPE, ResourceLocation.read(reader.getReader()));
|
|
+ // Paper start - tell clients to ask server for suggestions for EntityArguments; throw error if invalid entity tag (only on suggestions to keep cmd success behavior)
|
|
+ if (reader.parsingEntityArgumentSuggestions && io.papermc.paper.configuration.GlobalConfiguration.get().commands.fixTargetSelectorTagCompletion && net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.getTag(tagKey).isEmpty()) {
|
|
+ reader.getReader().setCursor(i);
|
|
+ throw ERROR_ENTITY_TAG_INVALID.createWithContext(reader.getReader(), tagKey);
|
|
+ }
|
|
+ // Paper end - tell clients to ask server for suggestions for EntityArguments
|
|
reader.addPredicate(entity -> entity.getType().is(tagKey) != bl);
|
|
} else {
|
|
ResourceLocation resourceLocation = ResourceLocation.read(reader.getReader());
|