From 1253019c0c1a50f07f2cf7a0835654e218646377 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Mon, 28 Feb 2022 14:16:17 -0800 Subject: [PATCH] Readd 'Fix entity type tags suggestions in selectors' --- ...y-type-tags-suggestions-in-selectors.patch | 151 ++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 patches/server/Fix-entity-type-tags-suggestions-in-selectors.patch diff --git a/patches/server/Fix-entity-type-tags-suggestions-in-selectors.patch b/patches/server/Fix-entity-type-tags-suggestions-in-selectors.patch new file mode 100644 index 000000000..2c974a01c --- /dev/null +++ b/patches/server/Fix-entity-type-tags-suggestions-in-selectors.patch @@ -0,0 +1,151 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +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/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java ++++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java +@@ -0,0 +0,0 @@ public class PaperConfig { + itemValidationBookPageLength = getInt("settings.item-validation.book.page", itemValidationBookPageLength); + } + ++ public static boolean fixTargetSelectorTagCompletion = true; ++ private static void fixTargetSelectorTagCompletion() { ++ fixTargetSelectorTagCompletion = getBoolean("settings.fix-target-selector-tag-completion", fixTargetSelectorTagCompletion); ++ } ++ + public static final class PacketLimit { + public final double packetLimitInterval; + public final double maxPacketRate; +diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/commands/CommandSourceStack.java ++++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java +@@ -0,0 +0,0 @@ public class CommandSourceStack implements SharedSuggestionProvider, com.destroy + return this.source.getBukkitSender(this); + } + // CraftBukkit end ++ // Paper start - override getSelectedEntities ++ @Override ++ public Collection getSelectedEntities() { ++ if (com.destroystokyo.paper.PaperConfig.fixTargetSelectorTagCompletion && this.source instanceof ServerPlayer player) { ++ double pickDistance = player.gameMode.getGameModeForPlayer().isCreative() ? 5.0F : 4.5F; ++ Vec3 min = player.getEyePosition(1.0F); ++ Vec3 viewVector = player.getViewVector(1.0F); ++ Vec3 max = min.add(viewVector.x * pickDistance, viewVector.y * pickDistance, viewVector.z * pickDistance); ++ net.minecraft.world.phys.AABB aabb = player.getBoundingBox().expandTowards(viewVector.scale(pickDistance)).inflate(1.0D, 1.0D, 1.0D); ++ pickDistance = player.gameMode.getGameModeForPlayer().isCreative() ? 6.0F : pickDistance; ++ net.minecraft.world.phys.EntityHitResult hitResult = net.minecraft.world.entity.projectile.ProjectileUtil.getEntityHitResult(player, min, max, aabb, (e) -> !e.isSpectator() && e.isPickable(), pickDistance); ++ return hitResult != null ? java.util.Collections.singletonList(hitResult.getEntity().getStringUUID()) : SharedSuggestionProvider.super.getSelectedEntities(); ++ } ++ return SharedSuggestionProvider.super.getSelectedEntities(); ++ } ++ // Paper end + } +diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/commands/Commands.java ++++ b/src/main/java/net/minecraft/commands/Commands.java +@@ -0,0 +0,0 @@ public class Commands { + private void fillUsableCommands(CommandNode tree, CommandNode result, CommandSourceStack source, Map, CommandNode> resultNodes) { + Iterator iterator = tree.getChildren().iterator(); + ++ boolean registeredAskServerSuggestionsForTree = false; // Paper - tell clients to ask server for suggestions for EntityArguments + while (iterator.hasNext()) { + CommandNode commandnode2 = (CommandNode) iterator.next(); + if ( !org.spigotmc.SpigotConfig.sendNamespaced && commandnode2.getName().contains( ":" ) ) continue; // Spigot +@@ -0,0 +0,0 @@ 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 (com.destroystokyo.paper.PaperConfig.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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/commands/arguments/EntityArgument.java ++++ b/src/main/java/net/minecraft/commands/arguments/EntityArgument.java +@@ -0,0 +0,0 @@ public class EntityArgument implements ArgumentType { + + stringreader.setCursor(suggestionsbuilder.getStart()); + SharedSuggestionProvider icompletionprovider = (SharedSuggestionProvider) commandcontext.getSource(); +- EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader, icompletionprovider.hasPermission(2)); ++ EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader, icompletionprovider.hasPermission(2), true); // Paper + + try { + argumentparserselector.parse(); +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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/commands/arguments/selector/EntitySelectorParser.java ++++ b/src/main/java/net/minecraft/commands/arguments/selector/EntitySelectorParser.java +@@ -0,0 +0,0 @@ public class EntitySelectorParser { + private boolean hasScores; + private boolean hasAdvancements; + private boolean usesSelectors; ++ public boolean parsingEntityArgumentSuggestions; // Paper - track when parsing EntityArgument suggestions + + public EntitySelectorParser(StringReader reader) { + this(reader, true); + } + + public EntitySelectorParser(StringReader reader, boolean atAllowed) { ++ // Paper start ++ this(reader, atAllowed, false); ++ } ++ public EntitySelectorParser(StringReader reader, boolean atAllowed, boolean parsingEntityArgumentSuggestions) { ++ this.parsingEntityArgumentSuggestions = parsingEntityArgumentSuggestions; ++ // Paper end + 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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 +@@ -0,0 +0,0 @@ public class EntitySelectorOptions { + public static final DynamicCommandExceptionType ERROR_ENTITY_TYPE_INVALID = new DynamicCommandExceptionType((entity) -> { + return new TranslatableComponent("argument.entity.options.type.invalid", entity); + }); ++ // Paper start ++ 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 + + private static void register(String id, EntitySelectorOptions.Modifier handler, Predicate condition, Component description) { + OPTIONS.put(id, new EntitySelectorOptions.Option(handler, condition, description)); +@@ -0,0 +0,0 @@ public class EntitySelectorOptions { + + if (reader.isTag()) { + TagKey> tagKey = TagKey.create(Registry.ENTITY_TYPE_REGISTRY, ResourceLocation.read(reader.getReader())); ++ // Paper start - throw error if invalid entity tag (only on suggestions to keep cmd success behavior) ++ if (com.destroystokyo.paper.PaperConfig.fixTargetSelectorTagCompletion && reader.parsingEntityArgumentSuggestions && !Registry.ENTITY_TYPE.isKnownTagName(tagKey)) { ++ reader.getReader().setCursor(i); ++ throw ERROR_ENTITY_TAG_INVALID.createWithContext(reader.getReader(), tagKey); ++ } ++ // Paper end + reader.addPredicate((entity) -> { + return entity.getType().is(tagKey) != bl; + });