Update more more feature patches

This commit is contained in:
Nassim Jahnke
2024-12-16 11:00:21 +01:00
parent 901cf13d01
commit 9bf310baef
3 changed files with 133 additions and 134 deletions

View File

@@ -29,32 +29,31 @@ and compute a deterministic result for the MergerList values.
Additionally, this lets us avoid even allocating new objects for this too, further Additionally, this lets us avoid even allocating new objects for this too, further
reducing memory usage. reducing memory usage.
diff --git a/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java b/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java diff --git a/net/minecraft/world/phys/shapes/IndirectMerger.java b/net/minecraft/world/phys/shapes/IndirectMerger.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 60b56a5086b8aad0fad693f686b89138b3a4c80d..5b079ec43c259368d0eed4e8385880712abda4f7 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java --- a/net/minecraft/world/phys/shapes/IndirectMerger.java
+++ b/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java +++ b/net/minecraft/world/phys/shapes/IndirectMerger.java
@@ -0,0 +0,0 @@ public class IndirectMerger implements IndexMerger { @@ -10,12 +10,32 @@ public class IndirectMerger implements IndexMerger {
private final int[] firstIndices; private final int[] firstIndices;
private final int[] secondIndices; private final int[] secondIndices;
private final int resultLength; private final int resultLength;
+ // Paper start + // Paper start
+ private static final int[] INFINITE_B_1 = new int[]{1, 1}; + private static final int[] INFINITE_B_1 = {1, 1};
+ private static final int[] INFINITE_B_0 = new int[]{0, 0}; + private static final int[] INFINITE_B_0 = {0, 0};
+ private static final int[] INFINITE_C = new int[]{0, 1}; + private static final int[] INFINITE_C = {0, 1};
+ // Paper end + // Paper end
public IndirectMerger(DoubleList first, DoubleList second, boolean includeFirstOnly, boolean includeSecondOnly) { public IndirectMerger(DoubleList lower, DoubleList upper, boolean excludeUpper, boolean excludeLower) {
double d = Double.NaN; double d = Double.NaN;
int i = first.size(); int size = lower.size();
int j = second.size(); int size1 = upper.size();
int k = i + j; int i = size + size1;
+ // Paper start - optimize common path of infinity doublelist + // Paper start - optimize common path of infinity doublelist
+ int size = first.size(); + double tail = lower.getDouble(size - 1);
+ double tail = first.getDouble(size - 1); + double head = lower.getDouble(0);
+ double head = first.getDouble(0); + if (head == Double.NEGATIVE_INFINITY && tail == Double.POSITIVE_INFINITY && !excludeUpper && !excludeLower && (size == 2 || size == 4)) {
+ if (head == Double.NEGATIVE_INFINITY && tail == Double.POSITIVE_INFINITY && !includeFirstOnly && !includeSecondOnly && (size == 2 || size == 4)) { + this.result = upper.toDoubleArray();
+ this.result = second.toDoubleArray(); + this.resultLength = upper.size();
+ this.resultLength = second.size();
+ if (size == 2) { + if (size == 2) {
+ this.firstIndices = INFINITE_B_0; + this.firstIndices = INFINITE_B_0;
+ } else { + } else {
@@ -64,60 +63,60 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return; + return;
+ } + }
+ // Paper end + // Paper end
this.result = new double[k]; this.result = new double[i];
this.firstIndices = new int[k]; this.firstIndices = new int[i];
this.secondIndices = new int[k]; this.secondIndices = new int[i];
diff --git a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java diff --git a/net/minecraft/world/phys/shapes/Shapes.java b/net/minecraft/world/phys/shapes/Shapes.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index e1b4c4b53844b0755e0640a05e8782fd9a7700a2..e759221fb54aa510d2d8bbba47e1d794367aec6d 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java --- a/net/minecraft/world/phys/shapes/Shapes.java
+++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java +++ b/net/minecraft/world/phys/shapes/Shapes.java
@@ -0,0 +0,0 @@ public final class Shapes { @@ -279,9 +279,22 @@ public final class Shapes {
} }
@VisibleForTesting @VisibleForTesting
- protected static IndexMerger createIndexMerger(int size, DoubleList first, DoubleList second, boolean includeFirst, boolean includeSecond) { - protected static IndexMerger createIndexMerger(int size, DoubleList list1, DoubleList list2, boolean excludeUpper, boolean excludeLower) {
+ private static IndexMerger createIndexMerger(int size, DoubleList first, DoubleList second, boolean includeFirst, boolean includeSecond) { // Paper - private + private static IndexMerger createIndexMerger(int size, DoubleList list1, DoubleList list2, boolean excludeUpper, boolean excludeLower) { // Paper - private
+ // Paper start - fast track the most common scenario + // Paper start - fast track the most common scenario
+ // doublelist is usually a DoubleArrayList with Infinite head/tails that falls to the final else clause + // doublelist is usually a DoubleArrayList with Infinite head/tails that falls to the final else clause
+ // This is actually the most common path, so jump to it straight away + // This is actually the most common path, so jump to it straight away
+ if (first.getDouble(0) == Double.NEGATIVE_INFINITY && first.getDouble(first.size() - 1) == Double.POSITIVE_INFINITY) { + if (list1.getDouble(0) == Double.NEGATIVE_INFINITY && list1.getDouble(list1.size() - 1) == Double.POSITIVE_INFINITY) {
+ return new IndirectMerger(first, second, includeFirst, includeSecond); + return new IndirectMerger(list1, list2, excludeUpper, excludeLower);
+ } + }
+ // Split out rest to hopefully inline the above + // Split out rest to hopefully inline the above
+ return lessCommonMerge(size, first, second, includeFirst, includeSecond); + return lessCommonMerge(size, list1, list2, excludeUpper, excludeLower);
+ } + }
+ +
+ private static IndexMerger lessCommonMerge(int size, DoubleList first, DoubleList second, boolean includeFirst, boolean includeSecond) { + private static IndexMerger lessCommonMerge(int size, DoubleList list1, DoubleList list2, boolean excludeUpper, boolean excludeLower) {
int i = first.size() - 1; + // Paper end - fast track the most common scenario
int j = second.size() - 1; int i = list1.size() - 1;
int i1 = list2.size() - 1;
+ // Paper note - Rewrite below as optimized order if instead of nasty ternary + // Paper note - Rewrite below as optimized order if instead of nasty ternary
if (first instanceof CubePointRange && second instanceof CubePointRange) { if (list1 instanceof CubePointRange && list2 instanceof CubePointRange) {
long l = lcm(i, j); long l = lcm(i, i1);
if ((long)size * l <= 256L) { if (size * l <= 256L) {
@@ -0,0 +0,0 @@ public final class Shapes { @@ -289,14 +302,21 @@ public final class Shapes {
} }
} }
- if (first.getDouble(i) < second.getDouble(0) - 1.0E-7) { - if (list1.getDouble(i) < list2.getDouble(0) - 1.0E-7) {
+ // Paper start - Identical happens more often than Disjoint + // Paper start - Identical happens more often than Disjoint
+ if (i == j && Objects.equals(first, second)) { + if (i == i1 && Objects.equals(list1, list2)) {
+ if (first instanceof IdenticalMerger) { + if (list1 instanceof IdenticalMerger) {
+ return (IndexMerger) first; + return (IndexMerger) list1;
+ } else if (second instanceof IdenticalMerger) { + } else if (list2 instanceof IdenticalMerger) {
+ return (IndexMerger) second; + return (IndexMerger) list2;
+ } + }
+ return new IdenticalMerger(first); + return new IdenticalMerger(list1);
+ } else if (first.getDouble(i) < second.getDouble(0) - 1.0E-7) { + } else if (list1.getDouble(i) < list2.getDouble(0) - 1.0E-7) {
return new NonOverlappingMerger(first, second, false); + // Paper end - Identical happens more often than Disjoint
} else if (second.getDouble(j) < first.getDouble(0) - 1.0E-7) { return new NonOverlappingMerger(list1, list2, false);
return new NonOverlappingMerger(second, first, true); } else if (list2.getDouble(i1) < list1.getDouble(0) - 1.0E-7) {
return new NonOverlappingMerger(list2, list1, true);
} else { } else {
- return (IndexMerger)(i == j && Objects.equals(first, second) - return (IndexMerger)(i == i1 && Objects.equals(list1, list2)
- ? new IdenticalMerger(first) - ? new IdenticalMerger(list1)
- : new IndirectMerger(first, second, includeFirst, includeSecond)); - : new IndirectMerger(list1, list2, excludeUpper, excludeLower));
+ return new IndirectMerger(first, second, includeFirst, includeSecond); + return new IndirectMerger(list1, list2, excludeUpper, excludeLower); // Paper - Identical happens more often than Disjoint
} }
+ // Paper end
} }
public interface DoubleLineConsumer {

View File

@@ -9,11 +9,11 @@ when if this was fixed on the client, that wouldn't be needed.
Mojira Issue: https://bugs.mojang.com/browse/MC-235045 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 diff --git a/net/minecraft/commands/CommandSourceStack.java b/net/minecraft/commands/CommandSourceStack.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 704a63890a06d793f8ac3452838917e7c7335232..75262c8c9eaecb4a88a94f4076d67119c67a97da 100644
--- a/src/main/java/net/minecraft/commands/CommandSourceStack.java --- a/net/minecraft/commands/CommandSourceStack.java
+++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java +++ b/net/minecraft/commands/CommandSourceStack.java
@@ -0,0 +0,0 @@ public class CommandSourceStack implements ExecutionCommandSource<CommandSourceS @@ -652,4 +652,20 @@ public class CommandSourceStack implements ExecutionCommandSource<CommandSourceS
return this.source.getBukkitSender(this); return this.source.getBukkitSender(this);
} }
// CraftBukkit end // CraftBukkit end
@@ -34,92 +34,92 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ // Paper end - tell clients to ask server for suggestions for EntityArguments + // 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 diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 45fa9cdc34e78613e346138aa92a6d3bbdee374c..e422a266de555bbf77eee201df9e4c5d89f7b801 100644
--- a/src/main/java/net/minecraft/commands/Commands.java --- a/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java +++ b/net/minecraft/commands/Commands.java
@@ -0,0 +0,0 @@ public class Commands { @@ -510,6 +510,7 @@ public class Commands {
Iterator iterator = children.iterator(); Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> commandNodeToSuggestionNode
// Paper end - Perf: Async command map building ) {
commandNodeToSuggestionNode.keySet().removeIf((node) -> !org.spigotmc.SpigotConfig.sendNamespaced && node.getName().contains(":")); // Paper - Remove namedspaced from result nodes to prevent redirect trimming ~ see comment below
+ boolean registeredAskServerSuggestionsForTree = false; // Paper - tell clients to ask server for suggestions for EntityArguments + boolean registeredAskServerSuggestionsForTree = false; // Paper - tell clients to ask server for suggestions for EntityArguments
while (iterator.hasNext()) { for (CommandNode<CommandSourceStack> commandNode : children) { // Paper - Perf: Async command map building; pass copy of children
CommandNode<CommandSourceStack> commandnode2 = (CommandNode) iterator.next();
// Paper start - Brigadier API // Paper start - Brigadier API
@@ -0,0 +0,0 @@ public class Commands { if (commandNode.clientNode != null) {
@@ -572,6 +573,12 @@ public class Commands {
if (requiredargumentbuilder.getSuggestionsProvider() != null) { RequiredArgumentBuilder<SharedSuggestionProvider, ?> requiredArgumentBuilder = (RequiredArgumentBuilder<SharedSuggestionProvider, ?>)argumentBuilder;
requiredargumentbuilder.suggests(SuggestionProviders.safelySwap(requiredargumentbuilder.getSuggestionsProvider())); if (requiredArgumentBuilder.getSuggestionsProvider() != null) {
requiredArgumentBuilder.suggests(SuggestionProviders.safelySwap(requiredArgumentBuilder.getSuggestionsProvider()));
+ // Paper start - tell clients to ask server for suggestions for EntityArguments + // Paper start - tell clients to ask server for suggestions for EntityArguments
+ registeredAskServerSuggestionsForTree = requiredargumentbuilder.getSuggestionsProvider() == net.minecraft.commands.synchronization.SuggestionProviders.ASK_SERVER; + 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) { + } else if (io.papermc.paper.configuration.GlobalConfiguration.get().commands.fixTargetSelectorTagCompletion && !registeredAskServerSuggestionsForTree && requiredArgumentBuilder.getType() instanceof net.minecraft.commands.arguments.EntityArgument) {
+ requiredargumentbuilder.suggests(requiredargumentbuilder.getType()::listSuggestions); + requiredArgumentBuilder.suggests(requiredArgumentBuilder.getType()::listSuggestions);
+ registeredAskServerSuggestionsForTree = true; // You can only + registeredAskServerSuggestionsForTree = true; // You can only
+ // Paper end - tell clients to ask server for suggestions for EntityArguments + // 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 diff --git a/net/minecraft/commands/arguments/EntityArgument.java b/net/minecraft/commands/arguments/EntityArgument.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index ba9a7636e158222bcfb50ae8487f29df6fdbdd0c..8957b99116cb087198fe372d4d2c2b3397fed19f 100644
--- a/src/main/java/net/minecraft/commands/arguments/EntityArgument.java --- a/net/minecraft/commands/arguments/EntityArgument.java
+++ b/src/main/java/net/minecraft/commands/arguments/EntityArgument.java +++ b/net/minecraft/commands/arguments/EntityArgument.java
@@ -0,0 +0,0 @@ public class EntityArgument implements ArgumentType<EntitySelector> { @@ -138,7 +138,7 @@ public class EntityArgument implements ArgumentType<EntitySelector> {
final boolean permission = object instanceof CommandSourceStack stack final boolean permission = sharedSuggestionProvider instanceof CommandSourceStack stack
? stack.bypassSelectorPermissions || stack.hasPermission(2, "minecraft.command.selector") ? stack.bypassSelectorPermissions || stack.hasPermission(2, "minecraft.command.selector")
: icompletionprovider.hasPermission(2); : sharedSuggestionProvider.hasPermission(2);
- EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader, permission); - EntitySelectorParser entitySelectorParser = new EntitySelectorParser(stringReader, permission);
+ EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader, permission, true); // Paper - tell clients to ask server for suggestions for EntityArguments + EntitySelectorParser entitySelectorParser = new EntitySelectorParser(stringReader, permission, true); // Paper - tell clients to ask server for suggestions for EntityArguments
// Paper end - Fix EntityArgument permissions // Paper end - Fix EntityArgument permissions
try { try {
@@ -0,0 +0,0 @@ public class EntityArgument implements ArgumentType<EntitySelector> { @@ -149,7 +149,19 @@ public class EntityArgument implements ArgumentType<EntitySelector> {
} return entitySelectorParser.fillSuggestions(
builder,
return argumentparserselector.fillSuggestions(suggestionsbuilder, (suggestionsbuilder1) -> { offsetBuilder -> {
- Collection<String> collection = icompletionprovider.getOnlinePlayerNames(); - Collection<String> onlinePlayerNames = sharedSuggestionProvider.getOnlinePlayerNames();
+ // Paper start - tell clients to ask server for suggestions for EntityArguments + // Paper start - tell clients to ask server for suggestions for EntityArguments
+ final Collection<String> collection; + final Collection<String> onlinePlayerNames;
+ if (icompletionprovider instanceof CommandSourceStack commandSourceStack && commandSourceStack.getEntity() instanceof ServerPlayer sourcePlayer) { + if (sharedSuggestionProvider instanceof CommandSourceStack commandSourceStack && commandSourceStack.getEntity() instanceof ServerPlayer sourcePlayer) {
+ collection = new java.util.ArrayList<>(); + onlinePlayerNames = new java.util.ArrayList<>();
+ for (final ServerPlayer player : commandSourceStack.getServer().getPlayerList().getPlayers()) { + for (final ServerPlayer player : commandSourceStack.getServer().getPlayerList().getPlayers()) {
+ if (sourcePlayer.getBukkitEntity().canSee(player.getBukkitEntity())) { + if (sourcePlayer.getBukkitEntity().canSee(player.getBukkitEntity())) {
+ collection.add(player.getGameProfile().getName()); + onlinePlayerNames.add(player.getGameProfile().getName());
+ } + }
+ } + }
+ } else { + } else {
+ collection = icompletionprovider.getOnlinePlayerNames(); + onlinePlayerNames = sharedSuggestionProvider.getOnlinePlayerNames();
+ } + }
+ // Paper end - tell clients to ask server for suggestions for EntityArguments + // Paper end - tell clients to ask server for suggestions for EntityArguments
Iterable<String> iterable = this.playersOnly ? collection : Iterables.concat(collection, icompletionprovider.getSelectedEntities()); Iterable<String> iterable = (Iterable<String>)(this.playersOnly
? onlinePlayerNames
SharedSuggestionProvider.suggest((Iterable) iterable, suggestionsbuilder1); : Iterables.concat(onlinePlayerNames, sharedSuggestionProvider.getSelectedEntities()));
diff --git a/src/main/java/net/minecraft/commands/arguments/selector/EntitySelectorParser.java b/src/main/java/net/minecraft/commands/arguments/selector/EntitySelectorParser.java diff --git a/net/minecraft/commands/arguments/selector/EntitySelectorParser.java b/net/minecraft/commands/arguments/selector/EntitySelectorParser.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index a6f232747df631f6afe440606bea94c588f1a0dd..fb42630741674c6cbd20b7d45d78dea1dc73a78f 100644
--- a/src/main/java/net/minecraft/commands/arguments/selector/EntitySelectorParser.java --- a/net/minecraft/commands/arguments/selector/EntitySelectorParser.java
+++ b/src/main/java/net/minecraft/commands/arguments/selector/EntitySelectorParser.java +++ b/net/minecraft/commands/arguments/selector/EntitySelectorParser.java
@@ -0,0 +0,0 @@ public class EntitySelectorParser { @@ -115,8 +115,15 @@ public class EntitySelectorParser {
private boolean hasScores; private boolean hasScores;
private boolean hasAdvancements; private boolean hasAdvancements;
private boolean usesSelectors; private boolean usesSelectors;
+ public boolean parsingEntityArgumentSuggestions; // Paper - tell clients to ask server for suggestions for EntityArguments + public boolean parsingEntityArgumentSuggestions; // Paper - tell clients to ask server for suggestions for EntityArguments
public EntitySelectorParser(StringReader reader, boolean atAllowed) { public EntitySelectorParser(StringReader reader, boolean allowSelectors) {
+ // Paper start - tell clients to ask server for suggestions for EntityArguments + // Paper start - tell clients to ask server for suggestions for EntityArguments
+ this(reader, atAllowed, false); + this(reader, allowSelectors, false);
+ } + }
+ public EntitySelectorParser(StringReader reader, boolean atAllowed, boolean parsingEntityArgumentSuggestions) { + public EntitySelectorParser(StringReader reader, boolean allowSelectors, boolean parsingEntityArgumentSuggestions) {
+ this.parsingEntityArgumentSuggestions = parsingEntityArgumentSuggestions; + this.parsingEntityArgumentSuggestions = parsingEntityArgumentSuggestions;
+ // Paper end - tell clients to ask server for suggestions for EntityArguments + // Paper end - tell clients to ask server for suggestions for EntityArguments
this.distance = MinMaxBounds.Doubles.ANY; this.reader = reader;
this.level = MinMaxBounds.Ints.ANY; this.allowSelectors = allowSelectors;
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 diff --git a/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java b/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index f6b58139aace70436034f0a16370236d975cb4ae..ee9949c41d38817b21b6f4fd728059a46fddf135 100644
--- a/src/main/java/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java --- a/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java
+++ b/src/main/java/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java +++ b/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java
@@ -0,0 +0,0 @@ public class EntitySelectorOptions { @@ -76,6 +76,19 @@ public class EntitySelectorOptions {
public static final DynamicCommandExceptionType ERROR_ENTITY_TYPE_INVALID = new DynamicCommandExceptionType( public static final DynamicCommandExceptionType ERROR_ENTITY_TYPE_INVALID = new DynamicCommandExceptionType(
entity -> Component.translatableEscape("argument.entity.options.type.invalid", entity) type -> Component.translatableEscape("argument.entity.options.type.invalid", type)
); );
+ // Paper start - tell clients to ask server for suggestions for EntityArguments + // Paper start - tell clients to ask server for suggestions for EntityArguments
+ public static final DynamicCommandExceptionType ERROR_ENTITY_TAG_INVALID = new DynamicCommandExceptionType((object) -> { + public static final DynamicCommandExceptionType ERROR_ENTITY_TAG_INVALID = new DynamicCommandExceptionType((object) -> {
@@ -135,18 +135,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }); + });
+ // Paper end - tell clients to ask server for suggestions for EntityArguments + // 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) { private static void register(String id, EntitySelectorOptions.Modifier handler, Predicate<EntitySelectorParser> predicate, Component tooltip) {
OPTIONS.put(id, new EntitySelectorOptions.Option(handler, condition, description)); OPTIONS.put(id, new EntitySelectorOptions.Option(handler, predicate, tooltip));
@@ -0,0 +0,0 @@ public class EntitySelectorOptions { @@ -299,6 +312,12 @@ public class EntitySelectorOptions {
if (reader.isTag()) { if (parser.isTag()) {
TagKey<EntityType<?>> tagKey = TagKey.create(Registries.ENTITY_TYPE, ResourceLocation.read(reader.getReader())); TagKey<EntityType<?>> tagKey = TagKey.create(Registries.ENTITY_TYPE, ResourceLocation.read(parser.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) + // 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.get(tagKey).isEmpty()) { + if (parser.parsingEntityArgumentSuggestions && io.papermc.paper.configuration.GlobalConfiguration.get().commands.fixTargetSelectorTagCompletion && net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.get(tagKey).isEmpty()) {
+ reader.getReader().setCursor(i); + parser.getReader().setCursor(cursor);
+ throw ERROR_ENTITY_TAG_INVALID.createWithContext(reader.getReader(), tagKey); + throw ERROR_ENTITY_TAG_INVALID.createWithContext(parser.getReader(), tagKey);
+ } + }
+ // Paper end - tell clients to ask server for suggestions for EntityArguments + // Paper end - tell clients to ask server for suggestions for EntityArguments
reader.addPredicate(entity -> entity.getType().is(tagKey) != bl); parser.addPredicate(entity -> entity.getType().is(tagKey) != shouldInvertValue);
} else { } else {
ResourceLocation resourceLocation = ResourceLocation.read(reader.getReader()); ResourceLocation resourceLocation = ResourceLocation.read(parser.getReader());

View File

@@ -51,7 +51,7 @@ index d310e7489fc4ecede8deef59241444769d87b0a1..f268808cb250e374f2d5652b20eece01
- -
- return null; - return null;
- } - }
+ return this.getChunkAtIfLoadedMainThread(chunkX, chunkZ); // Paper - Perf: Optimise getChunkAt calls for loaded chunk + return this.getChunkAtIfLoadedMainThread(chunkX, chunkZ); // Paper - Perf: Optimise getChunkAt calls for loaded chunks
} }
} }