aboutsummaryrefslogtreecommitdiffhomepage
path: root/patch-remap/mache-vineflower/net/minecraft/commands
diff options
context:
space:
mode:
authorMiniDigger | Martin <[email protected]>2024-01-14 11:04:49 +0100
committerMiniDigger | Martin <[email protected]>2024-01-14 11:04:49 +0100
commitbee74680e607c2e29b038329f62181238911cd83 (patch)
tree708fd1a4a0227d9071243adf2a42d5e9e96cde4a /patch-remap/mache-vineflower/net/minecraft/commands
parent0a44692ef6ff6e255d48eb3ba1bb114166eafda9 (diff)
downloadPaper-softspoon.tar.gz
Paper-softspoon.zip
add remapped patches as a testsoftspoon
Diffstat (limited to 'patch-remap/mache-vineflower/net/minecraft/commands')
-rw-r--r--patch-remap/mache-vineflower/net/minecraft/commands/CommandSource.java.patch36
-rw-r--r--patch-remap/mache-vineflower/net/minecraft/commands/CommandSourceStack.java.patch631
-rw-r--r--patch-remap/mache-vineflower/net/minecraft/commands/Commands.java.patch556
-rw-r--r--patch-remap/mache-vineflower/net/minecraft/commands/arguments/EntityArgument.java.patch225
-rw-r--r--patch-remap/mache-vineflower/net/minecraft/commands/arguments/blocks/BlockStateParser.java.patch641
-rw-r--r--patch-remap/mache-vineflower/net/minecraft/commands/arguments/selector/EntitySelector.java.patch280
-rw-r--r--patch-remap/mache-vineflower/net/minecraft/commands/arguments/selector/EntitySelectorParser.java.patch449
7 files changed, 2818 insertions, 0 deletions
diff --git a/patch-remap/mache-vineflower/net/minecraft/commands/CommandSource.java.patch b/patch-remap/mache-vineflower/net/minecraft/commands/CommandSource.java.patch
new file mode 100644
index 0000000000..ee54b4a935
--- /dev/null
+++ b/patch-remap/mache-vineflower/net/minecraft/commands/CommandSource.java.patch
@@ -0,0 +1,36 @@
+--- a/net/minecraft/commands/CommandSource.java
++++ b/net/minecraft/commands/CommandSource.java
+@@ -3,10 +3,10 @@
+ import net.minecraft.network.chat.Component;
+
+ public interface CommandSource {
++
+ CommandSource NULL = new CommandSource() {
+ @Override
+- public void sendSystemMessage(Component component) {
+- }
++ public void sendSystemMessage(Component component) {}
+
+ @Override
+ public boolean acceptsSuccess() {
+@@ -22,6 +22,13 @@
+ public boolean shouldInformAdmins() {
+ return false;
+ }
++
++ // CraftBukkit start
++ @Override
++ public org.bukkit.command.CommandSender getBukkitSender(CommandSourceStack wrapper) {
++ throw new UnsupportedOperationException("Not supported yet.");
++ }
++ // CraftBukkit end
+ };
+
+ void sendSystemMessage(Component component);
+@@ -35,4 +42,6 @@
+ default boolean alwaysAccepts() {
+ return false;
+ }
++
++ org.bukkit.command.CommandSender getBukkitSender(CommandSourceStack wrapper); // CraftBukkit
+ }
diff --git a/patch-remap/mache-vineflower/net/minecraft/commands/CommandSourceStack.java.patch b/patch-remap/mache-vineflower/net/minecraft/commands/CommandSourceStack.java.patch
new file mode 100644
index 0000000000..97067f7d0a
--- /dev/null
+++ b/patch-remap/mache-vineflower/net/minecraft/commands/CommandSourceStack.java.patch
@@ -0,0 +1,631 @@
+--- a/net/minecraft/commands/CommandSourceStack.java
++++ b/net/minecraft/commands/CommandSourceStack.java
+@@ -1,7 +1,6 @@
+ package net.minecraft.commands;
+
+ import com.google.common.collect.Lists;
+-import com.mojang.brigadier.CommandDispatcher;
+ import com.mojang.brigadier.Message;
+ import com.mojang.brigadier.context.CommandContext;
+ import com.mojang.brigadier.exceptions.CommandExceptionType;
+@@ -10,6 +9,7 @@
+ import com.mojang.brigadier.suggestion.Suggestions;
+ import com.mojang.brigadier.suggestion.SuggestionsBuilder;
+ import java.util.Collection;
++import java.util.Iterator;
+ import java.util.Objects;
+ import java.util.Set;
+ import java.util.concurrent.CompletableFuture;
+@@ -26,6 +26,7 @@
+ import net.minecraft.network.chat.ChatType;
+ import net.minecraft.network.chat.Component;
+ import net.minecraft.network.chat.ComponentUtils;
++import net.minecraft.network.chat.MutableComponent;
+ import net.minecraft.network.chat.OutgoingChatMessage;
+ import net.minecraft.resources.ResourceKey;
+ import net.minecraft.resources.ResourceLocation;
+@@ -42,11 +43,13 @@
+ import net.minecraft.world.level.dimension.DimensionType;
+ import net.minecraft.world.phys.Vec2;
+ import net.minecraft.world.phys.Vec3;
++import com.mojang.brigadier.tree.CommandNode; // CraftBukkit
+
+ public class CommandSourceStack implements ExecutionCommandSource<CommandSourceStack>, SharedSuggestionProvider {
++
+ public static final SimpleCommandExceptionType ERROR_NOT_PLAYER = new SimpleCommandExceptionType(Component.translatable("permissions.requires.player"));
+ public static final SimpleCommandExceptionType ERROR_NOT_ENTITY = new SimpleCommandExceptionType(Component.translatable("permissions.requires.entity"));
+- private final CommandSource source;
++ public final CommandSource source;
+ private final Vec3 worldPosition;
+ private final ServerLevel level;
+ private final int permissionLevel;
+@@ -61,285 +64,80 @@
+ private final Vec2 rotation;
+ private final CommandSigningContext signingContext;
+ private final TaskChainer chatMessageChainer;
++ public volatile CommandNode currentCommand; // CraftBukkit
+
+- public CommandSourceStack(
+- CommandSource source,
+- Vec3 worldPosition,
+- Vec2 rotation,
+- ServerLevel level,
+- int permissionLevel,
+- String textName,
+- Component displayName,
+- MinecraftServer server,
+- @Nullable Entity entity
+- ) {
+- this(
+- source,
+- worldPosition,
+- rotation,
+- level,
+- permissionLevel,
+- textName,
+- displayName,
+- server,
+- entity,
+- false,
+- CommandResultCallback.EMPTY,
+- EntityAnchorArgument.Anchor.FEET,
+- CommandSigningContext.ANONYMOUS,
+- TaskChainer.immediate(server)
+- );
++ public CommandSourceStack(CommandSource source, Vec3 worldPosition, Vec2 rotation, ServerLevel level, int permissionLevel, String textName, Component displayName, MinecraftServer server, @Nullable Entity entity) {
++ this(source, worldPosition, rotation, level, permissionLevel, textName, displayName, server, entity, false, CommandResultCallback.EMPTY, EntityAnchorArgument.Anchor.FEET, CommandSigningContext.ANONYMOUS, TaskChainer.immediate(server));
+ }
+
+- protected CommandSourceStack(
+- CommandSource commandSource,
+- Vec3 vec3,
+- Vec2 vec2,
+- ServerLevel serverLevel,
+- int i,
+- String string,
+- Component component,
+- MinecraftServer minecraftServer,
+- @Nullable Entity entity,
+- boolean flag,
+- CommandResultCallback commandResultCallback,
+- EntityAnchorArgument.Anchor anchor,
+- CommandSigningContext commandSigningContext,
+- TaskChainer taskChainer
+- ) {
+- this.source = commandSource;
+- this.worldPosition = vec3;
+- this.level = serverLevel;
++ protected CommandSourceStack(CommandSource icommandlistener, Vec3 vec3d, Vec2 vec2f, ServerLevel worldserver, int i, String s, Component ichatbasecomponent, MinecraftServer minecraftserver, @Nullable Entity entity, boolean flag, CommandResultCallback commandresultcallback, EntityAnchorArgument.Anchor argumentanchor_anchor, CommandSigningContext commandsigningcontext, TaskChainer taskchainer) {
++ this.source = icommandlistener;
++ this.worldPosition = vec3d;
++ this.level = worldserver;
+ this.silent = flag;
+ this.entity = entity;
+ this.permissionLevel = i;
+- this.textName = string;
+- this.displayName = component;
+- this.server = minecraftServer;
+- this.resultCallback = commandResultCallback;
+- this.anchor = anchor;
+- this.rotation = vec2;
+- this.signingContext = commandSigningContext;
+- this.chatMessageChainer = taskChainer;
++ this.textName = s;
++ this.displayName = ichatbasecomponent;
++ this.server = minecraftserver;
++ this.resultCallback = commandresultcallback;
++ this.anchor = argumentanchor_anchor;
++ this.rotation = vec2f;
++ this.signingContext = commandsigningcontext;
++ this.chatMessageChainer = taskchainer;
+ }
+
+ public CommandSourceStack withSource(CommandSource source) {
+- return this.source == source
+- ? this
+- : new CommandSourceStack(
+- source,
+- this.worldPosition,
+- this.rotation,
+- this.level,
+- this.permissionLevel,
+- this.textName,
+- this.displayName,
+- this.server,
+- this.entity,
+- this.silent,
+- this.resultCallback,
+- this.anchor,
+- this.signingContext,
+- this.chatMessageChainer
+- );
++ return this.source == source ? this : new CommandSourceStack(source, this.worldPosition, this.rotation, this.level, this.permissionLevel, this.textName, this.displayName, this.server, this.entity, this.silent, this.resultCallback, this.anchor, this.signingContext, this.chatMessageChainer);
+ }
+
+ public CommandSourceStack withEntity(Entity entity) {
+- return this.entity == entity
+- ? this
+- : new CommandSourceStack(
+- this.source,
+- this.worldPosition,
+- this.rotation,
+- this.level,
+- this.permissionLevel,
+- entity.getName().getString(),
+- entity.getDisplayName(),
+- this.server,
+- entity,
+- this.silent,
+- this.resultCallback,
+- this.anchor,
+- this.signingContext,
+- this.chatMessageChainer
+- );
++ return this.entity == entity ? this : new CommandSourceStack(this.source, this.worldPosition, this.rotation, this.level, this.permissionLevel, entity.getName().getString(), entity.getDisplayName(), this.server, entity, this.silent, this.resultCallback, this.anchor, this.signingContext, this.chatMessageChainer);
+ }
+
+ public CommandSourceStack withPosition(Vec3 pos) {
+- return this.worldPosition.equals(pos)
+- ? this
+- : new CommandSourceStack(
+- this.source,
+- pos,
+- this.rotation,
+- this.level,
+- this.permissionLevel,
+- this.textName,
+- this.displayName,
+- this.server,
+- this.entity,
+- this.silent,
+- this.resultCallback,
+- this.anchor,
+- this.signingContext,
+- this.chatMessageChainer
+- );
++ return this.worldPosition.equals(pos) ? this : new CommandSourceStack(this.source, pos, this.rotation, this.level, this.permissionLevel, this.textName, this.displayName, this.server, this.entity, this.silent, this.resultCallback, this.anchor, this.signingContext, this.chatMessageChainer);
+ }
+
+ public CommandSourceStack withRotation(Vec2 rotation) {
+- return this.rotation.equals(rotation)
+- ? this
+- : new CommandSourceStack(
+- this.source,
+- this.worldPosition,
+- rotation,
+- this.level,
+- this.permissionLevel,
+- this.textName,
+- this.displayName,
+- this.server,
+- this.entity,
+- this.silent,
+- this.resultCallback,
+- this.anchor,
+- this.signingContext,
+- this.chatMessageChainer
+- );
++ return this.rotation.equals(rotation) ? this : new CommandSourceStack(this.source, this.worldPosition, rotation, this.level, this.permissionLevel, this.textName, this.displayName, this.server, this.entity, this.silent, this.resultCallback, this.anchor, this.signingContext, this.chatMessageChainer);
+ }
+
+ @Override
+- public CommandSourceStack withCallback(CommandResultCallback commandResultCallback) {
+- return Objects.equals(this.resultCallback, commandResultCallback)
+- ? this
+- : new CommandSourceStack(
+- this.source,
+- this.worldPosition,
+- this.rotation,
+- this.level,
+- this.permissionLevel,
+- this.textName,
+- this.displayName,
+- this.server,
+- this.entity,
+- this.silent,
+- commandResultCallback,
+- this.anchor,
+- this.signingContext,
+- this.chatMessageChainer
+- );
++ public CommandSourceStack withCallback(CommandResultCallback commandresultcallback) {
++ return Objects.equals(this.resultCallback, commandresultcallback) ? this : new CommandSourceStack(this.source, this.worldPosition, this.rotation, this.level, this.permissionLevel, this.textName, this.displayName, this.server, this.entity, this.silent, commandresultcallback, this.anchor, this.signingContext, this.chatMessageChainer);
+ }
+
+- public CommandSourceStack withCallback(CommandResultCallback commandResultCallback, BinaryOperator<CommandResultCallback> binaryOperator) {
+- CommandResultCallback commandResultCallback1 = binaryOperator.apply(this.resultCallback, commandResultCallback);
+- return this.withCallback(commandResultCallback1);
++ public CommandSourceStack withCallback(CommandResultCallback commandresultcallback, BinaryOperator<CommandResultCallback> binaryoperator) {
++ CommandResultCallback commandresultcallback1 = (CommandResultCallback) binaryoperator.apply(this.resultCallback, commandresultcallback);
++
++ return this.withCallback(commandresultcallback1);
+ }
+
+ public CommandSourceStack withSuppressedOutput() {
+- return !this.silent && !this.source.alwaysAccepts()
+- ? new CommandSourceStack(
+- this.source,
+- this.worldPosition,
+- this.rotation,
+- this.level,
+- this.permissionLevel,
+- this.textName,
+- this.displayName,
+- this.server,
+- this.entity,
+- true,
+- this.resultCallback,
+- this.anchor,
+- this.signingContext,
+- this.chatMessageChainer
+- )
+- : this;
++ return !this.silent && !this.source.alwaysAccepts() ? new CommandSourceStack(this.source, this.worldPosition, this.rotation, this.level, this.permissionLevel, this.textName, this.displayName, this.server, this.entity, true, this.resultCallback, this.anchor, this.signingContext, this.chatMessageChainer) : this;
+ }
+
+ public CommandSourceStack withPermission(int permissionLevel) {
+- return permissionLevel == this.permissionLevel
+- ? this
+- : new CommandSourceStack(
+- this.source,
+- this.worldPosition,
+- this.rotation,
+- this.level,
+- permissionLevel,
+- this.textName,
+- this.displayName,
+- this.server,
+- this.entity,
+- this.silent,
+- this.resultCallback,
+- this.anchor,
+- this.signingContext,
+- this.chatMessageChainer
+- );
++ return permissionLevel == this.permissionLevel ? this : new CommandSourceStack(this.source, this.worldPosition, this.rotation, this.level, permissionLevel, this.textName, this.displayName, this.server, this.entity, this.silent, this.resultCallback, this.anchor, this.signingContext, this.chatMessageChainer);
+ }
+
+ public CommandSourceStack withMaximumPermission(int permissionLevel) {
+- return permissionLevel <= this.permissionLevel
+- ? this
+- : new CommandSourceStack(
+- this.source,
+- this.worldPosition,
+- this.rotation,
+- this.level,
+- permissionLevel,
+- this.textName,
+- this.displayName,
+- this.server,
+- this.entity,
+- this.silent,
+- this.resultCallback,
+- this.anchor,
+- this.signingContext,
+- this.chatMessageChainer
+- );
++ return permissionLevel <= this.permissionLevel ? this : new CommandSourceStack(this.source, this.worldPosition, this.rotation, this.level, permissionLevel, this.textName, this.displayName, this.server, this.entity, this.silent, this.resultCallback, this.anchor, this.signingContext, this.chatMessageChainer);
+ }
+
+ public CommandSourceStack withAnchor(EntityAnchorArgument.Anchor anchor) {
+- return anchor == this.anchor
+- ? this
+- : new CommandSourceStack(
+- this.source,
+- this.worldPosition,
+- this.rotation,
+- this.level,
+- this.permissionLevel,
+- this.textName,
+- this.displayName,
+- this.server,
+- this.entity,
+- this.silent,
+- this.resultCallback,
+- anchor,
+- this.signingContext,
+- this.chatMessageChainer
+- );
++ return anchor == this.anchor ? this : new CommandSourceStack(this.source, this.worldPosition, this.rotation, this.level, this.permissionLevel, this.textName, this.displayName, this.server, this.entity, this.silent, this.resultCallback, anchor, this.signingContext, this.chatMessageChainer);
+ }
+
+ public CommandSourceStack withLevel(ServerLevel level) {
+ if (level == this.level) {
+ return this;
+ } else {
+- double teleportationScale = DimensionType.getTeleportationScale(this.level.dimensionType(), level.dimensionType());
+- Vec3 vec3 = new Vec3(this.worldPosition.x * teleportationScale, this.worldPosition.y, this.worldPosition.z * teleportationScale);
+- return new CommandSourceStack(
+- this.source,
+- vec3,
+- this.rotation,
+- level,
+- this.permissionLevel,
+- this.textName,
+- this.displayName,
+- this.server,
+- this.entity,
+- this.silent,
+- this.resultCallback,
+- this.anchor,
+- this.signingContext,
+- this.chatMessageChainer
+- );
++ double d0 = DimensionType.getTeleportationScale(this.level.dimensionType(), level.dimensionType());
++ Vec3 vec3d = new Vec3(this.worldPosition.x * d0, this.worldPosition.y, this.worldPosition.z * d0);
++
++ return new CommandSourceStack(this.source, vec3d, this.rotation, level, this.permissionLevel, this.textName, this.displayName, this.server, this.entity, this.silent, this.resultCallback, this.anchor, this.signingContext, this.chatMessageChainer);
+ }
+ }
+
+@@ -348,35 +146,19 @@
+ }
+
+ public CommandSourceStack facing(Vec3 lookPos) {
+- Vec3 vec3 = this.anchor.apply(this);
+- double d = lookPos.x - vec3.x;
+- double d1 = lookPos.y - vec3.y;
+- double d2 = lookPos.z - vec3.z;
+- double squareRoot = Math.sqrt(d * d + d2 * d2);
+- float f = Mth.wrapDegrees((float)(-(Mth.atan2(d1, squareRoot) * 180.0F / (float)Math.PI)));
+- float f1 = Mth.wrapDegrees((float)(Mth.atan2(d2, d) * 180.0F / (float)Math.PI) - 90.0F);
++ Vec3 vec3d1 = this.anchor.apply(this);
++ double d0 = lookPos.x - vec3d1.x;
++ double d1 = lookPos.y - vec3d1.y;
++ double d2 = lookPos.z - vec3d1.z;
++ double d3 = Math.sqrt(d0 * d0 + d2 * d2);
++ float f = Mth.wrapDegrees((float) (-(Mth.atan2(d1, d3) * 57.2957763671875D)));
++ float f1 = Mth.wrapDegrees((float) (Mth.atan2(d2, d0) * 57.2957763671875D) - 90.0F);
++
+ return this.withRotation(new Vec2(f, f1));
+ }
+
+- public CommandSourceStack withSigningContext(CommandSigningContext commandSigningContext, TaskChainer taskChainer) {
+- return commandSigningContext == this.signingContext && taskChainer == this.chatMessageChainer
+- ? this
+- : new CommandSourceStack(
+- this.source,
+- this.worldPosition,
+- this.rotation,
+- this.level,
+- this.permissionLevel,
+- this.textName,
+- this.displayName,
+- this.server,
+- this.entity,
+- this.silent,
+- this.resultCallback,
+- this.anchor,
+- commandSigningContext,
+- taskChainer
+- );
++ public CommandSourceStack withSigningContext(CommandSigningContext commandsigningcontext, TaskChainer taskchainer) {
++ return commandsigningcontext == this.signingContext && taskchainer == this.chatMessageChainer ? this : new CommandSourceStack(this.source, this.worldPosition, this.rotation, this.level, this.permissionLevel, this.textName, this.displayName, this.server, this.entity, this.silent, this.resultCallback, this.anchor, commandsigningcontext, taskchainer);
+ }
+
+ public Component getDisplayName() {
+@@ -389,9 +171,23 @@
+
+ @Override
+ public boolean hasPermission(int level) {
++ // CraftBukkit start
++ CommandNode currentCommand = this.currentCommand;
++ if (currentCommand != null) {
++ return hasPermission(level, org.bukkit.craftbukkit.command.VanillaCommandWrapper.getPermission(currentCommand));
++ }
++ // CraftBukkit end
++
+ return this.permissionLevel >= level;
+ }
+
++ // CraftBukkit start
++ public boolean hasPermission(int i, String bukkitPermission) {
++ // World is null when loading functions
++ return ((getLevel() == null || !getLevel().getCraftServer().ignoreVanillaPermissions) && this.permissionLevel >= i) || getBukkitSender().hasPermission(bukkitPermission);
++ }
++ // CraftBukkit end
++
+ public Vec3 getPosition() {
+ return this.worldPosition;
+ }
+@@ -407,24 +203,38 @@
+
+ public Entity getEntityOrException() throws CommandSyntaxException {
+ if (this.entity == null) {
+- throw ERROR_NOT_ENTITY.create();
++ throw CommandSourceStack.ERROR_NOT_ENTITY.create();
+ } else {
+ return this.entity;
+ }
+ }
+
+ public ServerPlayer getPlayerOrException() throws CommandSyntaxException {
+- Entity var2 = this.entity;
+- if (var2 instanceof ServerPlayer) {
+- return (ServerPlayer)var2;
++ Entity entity = this.entity;
++
++ if (entity instanceof ServerPlayer) {
++ ServerPlayer entityplayer = (ServerPlayer) entity;
++
++ return entityplayer;
+ } else {
+- throw ERROR_NOT_PLAYER.create();
++ throw CommandSourceStack.ERROR_NOT_PLAYER.create();
+ }
+ }
+
+ @Nullable
+ public ServerPlayer getPlayer() {
+- return this.entity instanceof ServerPlayer serverPlayer ? serverPlayer : null;
++ Entity entity = this.entity;
++ ServerPlayer entityplayer;
++
++ if (entity instanceof ServerPlayer) {
++ ServerPlayer entityplayer1 = (ServerPlayer) entity;
++
++ entityplayer = entityplayer1;
++ } else {
++ entityplayer = null;
++ }
++
++ return entityplayer;
+ }
+
+ public boolean isPlayer() {
+@@ -452,66 +262,81 @@
+ }
+
+ public boolean shouldFilterMessageTo(ServerPlayer receiver) {
+- ServerPlayer player = this.getPlayer();
+- return receiver != player && (player != null && player.isTextFilteringEnabled() || receiver.isTextFilteringEnabled());
++ ServerPlayer entityplayer1 = this.getPlayer();
++
++ return receiver == entityplayer1 ? false : entityplayer1 != null && entityplayer1.isTextFilteringEnabled() || receiver.isTextFilteringEnabled();
+ }
+
+ public void sendChatMessage(OutgoingChatMessage message, boolean shouldFilter, ChatType.Bound boundChatType) {
+ if (!this.silent) {
+- ServerPlayer player = this.getPlayer();
+- if (player != null) {
+- player.sendChatMessage(message, shouldFilter, boundChatType);
++ ServerPlayer entityplayer = this.getPlayer();
++
++ if (entityplayer != null) {
++ entityplayer.sendChatMessage(message, shouldFilter, boundChatType);
+ } else {
+ this.source.sendSystemMessage(boundChatType.decorate(message.content()));
+ }
++
+ }
+ }
+
+ public void sendSystemMessage(Component message) {
+ if (!this.silent) {
+- ServerPlayer player = this.getPlayer();
+- if (player != null) {
+- player.sendSystemMessage(message);
++ ServerPlayer entityplayer = this.getPlayer();
++
++ if (entityplayer != null) {
++ entityplayer.sendSystemMessage(message);
+ } else {
+ this.source.sendSystemMessage(message);
+ }
++
+ }
+ }
+
+ public void sendSuccess(Supplier<Component> messageSupplier, boolean allowLogging) {
+- boolean flag = this.source.acceptsSuccess() && !this.silent;
+- boolean flag1 = allowLogging && this.source.shouldInformAdmins() && !this.silent;
+- if (flag || flag1) {
+- Component component = messageSupplier.get();
+- if (flag) {
+- this.source.sendSystemMessage(component);
+- }
++ boolean flag1 = this.source.acceptsSuccess() && !this.silent;
++ boolean flag2 = allowLogging && this.source.shouldInformAdmins() && !this.silent;
+
++ if (flag1 || flag2) {
++ Component ichatbasecomponent = (Component) messageSupplier.get();
++
+ if (flag1) {
+- this.broadcastToAdmins(component);
++ this.source.sendSystemMessage(ichatbasecomponent);
+ }
++
++ if (flag2) {
++ this.broadcastToAdmins(ichatbasecomponent);
++ }
++
+ }
+ }
+
+ private void broadcastToAdmins(Component message) {
+- Component component = Component.translatable("chat.type.admin", this.getDisplayName(), message).withStyle(ChatFormatting.GRAY, ChatFormatting.ITALIC);
++ MutableComponent ichatmutablecomponent = Component.translatable("chat.type.admin", this.getDisplayName(), message).withStyle(ChatFormatting.GRAY, ChatFormatting.ITALIC);
++
+ if (this.server.getGameRules().getBoolean(GameRules.RULE_SENDCOMMANDFEEDBACK)) {
+- for (ServerPlayer serverPlayer : this.server.getPlayerList().getPlayers()) {
+- if (serverPlayer != this.source && this.server.getPlayerList().isOp(serverPlayer.getGameProfile())) {
+- serverPlayer.sendSystemMessage(component);
++ Iterator iterator = this.server.getPlayerList().getPlayers().iterator();
++
++ while (iterator.hasNext()) {
++ ServerPlayer entityplayer = (ServerPlayer) iterator.next();
++
++ if (entityplayer != this.source && entityplayer.getBukkitEntity().hasPermission("minecraft.admin.command_feedback")) { // CraftBukkit
++ entityplayer.sendSystemMessage(ichatmutablecomponent);
+ }
+ }
+ }
+
+ if (this.source != this.server && this.server.getGameRules().getBoolean(GameRules.RULE_LOGADMINCOMMANDS)) {
+- this.server.sendSystemMessage(component);
++ this.server.sendSystemMessage(ichatmutablecomponent);
+ }
++
+ }
+
+ public void sendFailure(Component message) {
+ if (this.source.acceptsFailure() && !this.silent) {
+ this.source.sendSystemMessage(Component.empty().append(message).withStyle(ChatFormatting.RED));
+ }
++
+ }
+
+ @Override
+@@ -545,14 +370,9 @@
+ }
+
+ @Override
+- public CompletableFuture<Suggestions> suggestRegistryElements(
+- ResourceKey<? extends Registry<?>> resourceKey,
+- SharedSuggestionProvider.ElementSuggestionType registryKey,
+- SuggestionsBuilder builder,
+- CommandContext<?> context
+- ) {
+- return this.registryAccess().registry(resourceKey).map(registry -> {
+- this.suggestRegistryElements((Registry<?>)registry, registryKey, builder);
++ public CompletableFuture<Suggestions> suggestRegistryElements(ResourceKey<? extends Registry<?>> resourceKey, SharedSuggestionProvider.a registryKey, SuggestionsBuilder builder, CommandContext<?> context) {
++ return (CompletableFuture) this.registryAccess().registry(resourceKey).map((iregistry) -> {
++ this.suggestRegistryElements(iregistry, registryKey, builder);
+ return builder.buildFuture();
+ }).orElseGet(Suggestions::empty);
+ }
+@@ -573,23 +393,30 @@
+ }
+
+ @Override
+- public CommandDispatcher<CommandSourceStack> dispatcher() {
++ public com.mojang.brigadier.CommandDispatcher<CommandSourceStack> dispatcher() {
+ return this.getServer().getFunctions().getDispatcher();
+ }
+
+ @Override
+- public void handleError(CommandExceptionType commandExceptionType, Message message, boolean flag, @Nullable TraceCallbacks traceCallbacks) {
+- if (traceCallbacks != null) {
+- traceCallbacks.onError(message.getString());
++ public void handleError(CommandExceptionType commandexceptiontype, Message message, boolean flag, @Nullable TraceCallbacks tracecallbacks) {
++ if (tracecallbacks != null) {
++ tracecallbacks.onError(message.getString());
+ }
+
+ if (!flag) {
+ this.sendFailure(ComponentUtils.fromMessage(message));
+ }
++
+ }
+
+ @Override
+ public boolean isSilent() {
+ return this.silent;
+ }
++
++ // CraftBukkit start
++ public org.bukkit.command.CommandSender getBukkitSender() {
++ return source.getBukkitSender(this);
++ }
++ // CraftBukkit end
+ }
diff --git a/patch-remap/mache-vineflower/net/minecraft/commands/Commands.java.patch b/patch-remap/mache-vineflower/net/minecraft/commands/Commands.java.patch
new file mode 100644
index 0000000000..3091ae10af
--- /dev/null
+++ b/patch-remap/mache-vineflower/net/minecraft/commands/Commands.java.patch
@@ -0,0 +1,556 @@
+--- a/net/minecraft/commands/Commands.java
++++ b/net/minecraft/commands/Commands.java
+@@ -1,21 +1,19 @@
+ package net.minecraft.commands;
+
+ import com.google.common.collect.Maps;
+-import com.mojang.brigadier.CommandDispatcher;
+ import com.mojang.brigadier.ParseResults;
+ import com.mojang.brigadier.StringReader;
+ import com.mojang.brigadier.arguments.ArgumentType;
+ import com.mojang.brigadier.builder.ArgumentBuilder;
+ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
+ import com.mojang.brigadier.builder.RequiredArgumentBuilder;
+-import com.mojang.brigadier.context.CommandContext;
+ import com.mojang.brigadier.context.CommandContextBuilder;
+ import com.mojang.brigadier.context.ContextChain;
+ import com.mojang.brigadier.exceptions.CommandSyntaxException;
+ import com.mojang.brigadier.tree.CommandNode;
+ import com.mojang.brigadier.tree.RootCommandNode;
+ import com.mojang.logging.LogUtils;
+-import java.util.Collection;
++import java.util.Iterator;
+ import java.util.Map;
+ import java.util.Optional;
+ import java.util.Set;
+@@ -42,7 +40,6 @@
+ import net.minecraft.network.chat.ComponentUtils;
+ import net.minecraft.network.chat.HoverEvent;
+ import net.minecraft.network.chat.MutableComponent;
+-import net.minecraft.network.chat.Style;
+ import net.minecraft.network.protocol.game.ClientboundCommandsPacket;
+ import net.minecraft.resources.ResourceKey;
+ import net.minecraft.server.MinecraftServer;
+@@ -137,17 +134,27 @@
+ import net.minecraft.world.level.GameRules;
+ import org.slf4j.Logger;
+
++// CraftBukkit start
++import com.google.common.base.Joiner;
++import java.util.Collection;
++import java.util.LinkedHashSet;
++import org.bukkit.event.player.PlayerCommandSendEvent;
++import org.bukkit.event.server.ServerCommandEvent;
++// CraftBukkit end
++
+ public class Commands {
+- private static final ThreadLocal<ExecutionContext<CommandSourceStack>> CURRENT_EXECUTION_CONTEXT = new ThreadLocal<>();
++
++ private static final ThreadLocal<ExecutionContext<CommandSourceStack>> CURRENT_EXECUTION_CONTEXT = new ThreadLocal();
+ private static final Logger LOGGER = LogUtils.getLogger();
+ public static final int LEVEL_ALL = 0;
+ public static final int LEVEL_MODERATORS = 1;
+ public static final int LEVEL_GAMEMASTERS = 2;
+ public static final int LEVEL_ADMINS = 3;
+ public static final int LEVEL_OWNERS = 4;
+- private final CommandDispatcher<CommandSourceStack> dispatcher = new CommandDispatcher<>();
++ private final com.mojang.brigadier.CommandDispatcher<CommandSourceStack> dispatcher = new com.mojang.brigadier.CommandDispatcher();
+
+ public Commands(Commands.CommandSelection selection, CommandBuildContext context) {
++ this(); // CraftBukkit
+ AdvancementCommands.register(this.dispatcher);
+ AttributeCommand.register(this.dispatcher, context);
+ ExecuteCommand.register(this.dispatcher, context);
+@@ -248,157 +255,256 @@
+ PublishCommand.register(this.dispatcher);
+ }
+
++ // CraftBukkit start
++ }
++
++ public Commands() {
++ // CraftBukkkit end
+ this.dispatcher.setConsumer(ExecutionCommandSource.resultConsumer());
+ }
+
+ public static <S> ParseResults<S> mapSource(ParseResults<S> parseResults, UnaryOperator<S> mapper) {
+- CommandContextBuilder<S> context = parseResults.getContext();
+- CommandContextBuilder<S> commandContextBuilder = context.withSource(mapper.apply(context.getSource()));
+- return new ParseResults<>(commandContextBuilder, parseResults.getReader(), parseResults.getExceptions());
++ CommandContextBuilder<S> commandcontextbuilder = parseResults.getContext();
++ CommandContextBuilder<S> commandcontextbuilder1 = commandcontextbuilder.withSource(mapper.apply(commandcontextbuilder.getSource()));
++
++ return new ParseResults(commandcontextbuilder1, parseResults.getReader(), parseResults.getExceptions());
+ }
+
+- public void performPrefixedCommand(CommandSourceStack commandSourceStack, String string) {
+- string = string.startsWith("/") ? string.substring(1) : string;
+- this.performCommand(this.dispatcher.parse(string, commandSourceStack), string);
++ // CraftBukkit start
++ public void dispatchServerCommand(CommandSourceStack sender, String command) {
++ Joiner joiner = Joiner.on(" ");
++ if (command.startsWith("/")) {
++ command = command.substring(1);
++ }
++
++ ServerCommandEvent event = new ServerCommandEvent(sender.getBukkitSender(), command);
++ org.bukkit.Bukkit.getPluginManager().callEvent(event);
++ if (event.isCancelled()) {
++ return;
++ }
++ command = event.getCommand();
++
++ String[] args = command.split(" ");
++
++ String cmd = args[0];
++ if (cmd.startsWith("minecraft:")) cmd = cmd.substring("minecraft:".length());
++ if (cmd.startsWith("bukkit:")) cmd = cmd.substring("bukkit:".length());
++
++ // Block disallowed commands
++ if (cmd.equalsIgnoreCase("stop") || cmd.equalsIgnoreCase("kick") || cmd.equalsIgnoreCase("op")
++ || cmd.equalsIgnoreCase("deop") || cmd.equalsIgnoreCase("ban") || cmd.equalsIgnoreCase("ban-ip")
++ || cmd.equalsIgnoreCase("pardon") || cmd.equalsIgnoreCase("pardon-ip") || cmd.equalsIgnoreCase("reload")) {
++ return;
++ }
++
++ // Handle vanilla commands;
++ if (sender.getLevel().getCraftServer().getCommandBlockOverride(args[0])) {
++ args[0] = "minecraft:" + args[0];
++ }
++
++ String newCommand = joiner.join(args);
++ this.performPrefixedCommand(sender, newCommand, newCommand);
+ }
++ // CraftBukkit end
+
+- public void performCommand(ParseResults<CommandSourceStack> parseResults, String string) {
+- CommandSourceStack commandSourceStack = parseResults.getContext().getSource();
+- commandSourceStack.getServer().getProfiler().push(() -> "/" + string);
+- ContextChain<CommandSourceStack> contextChain = finishParsing(parseResults, string, commandSourceStack);
++ public void performPrefixedCommand(CommandSourceStack commandlistenerwrapper, String s) {
++ // CraftBukkit start
++ this.performPrefixedCommand(commandlistenerwrapper, s, s);
++ }
+
++ public void performPrefixedCommand(CommandSourceStack commandlistenerwrapper, String s, String label) {
++ s = s.startsWith("/") ? s.substring(1) : s;
++ this.performCommand(this.dispatcher.parse(s, commandlistenerwrapper), s, label);
++ // CraftBukkit end
++ }
++
++ public void performCommand(ParseResults<CommandSourceStack> parseresults, String s) {
++ this.performCommand(parseresults, s, s);
++ }
++
++ public void performCommand(ParseResults<CommandSourceStack> parseresults, String s, String label) { // CraftBukkit
++ CommandSourceStack commandlistenerwrapper = (CommandSourceStack) parseresults.getContext().getSource();
++
++ commandlistenerwrapper.getServer().getProfiler().push(() -> {
++ return "/" + s;
++ });
++ ContextChain contextchain = finishParsing(parseresults, s, commandlistenerwrapper, label); // CraftBukkit
++
+ try {
+- if (contextChain != null) {
+- executeCommandInContext(
+- commandSourceStack,
+- executionContext -> ExecutionContext.queueInitialCommandExecution(
+- executionContext, string, contextChain, commandSourceStack, CommandResultCallback.EMPTY
+- )
+- );
++ if (contextchain != null) {
++ executeCommandInContext(commandlistenerwrapper, (executioncontext) -> {
++ ExecutionContext.queueInitialCommandExecution(executioncontext, s, contextchain, commandlistenerwrapper, CommandResultCallback.EMPTY);
++ });
+ }
+- } catch (Exception var12) {
+- MutableComponent mutableComponent = Component.literal(var12.getMessage() == null ? var12.getClass().getName() : var12.getMessage());
+- if (LOGGER.isDebugEnabled()) {
+- LOGGER.error("Command exception: /{}", string, var12);
+- StackTraceElement[] stackTrace = var12.getStackTrace();
++ } catch (Exception exception) {
++ MutableComponent ichatmutablecomponent = Component.literal(exception.getMessage() == null ? exception.getClass().getName() : exception.getMessage());
+
+- for (int i = 0; i < Math.min(stackTrace.length, 3); i++) {
+- mutableComponent.append("\n\n")
+- .append(stackTrace[i].getMethodName())
+- .append("\n ")
+- .append(stackTrace[i].getFileName())
+- .append(":")
+- .append(String.valueOf(stackTrace[i].getLineNumber()));
++ if (Commands.LOGGER.isDebugEnabled()) {
++ Commands.LOGGER.error("Command exception: /{}", s, exception);
++ StackTraceElement[] astacktraceelement = exception.getStackTrace();
++
++ for (int i = 0; i < Math.min(astacktraceelement.length, 3); ++i) {
++ ichatmutablecomponent.append("\n\n").append(astacktraceelement[i].getMethodName()).append("\n ").append(astacktraceelement[i].getFileName()).append(":").append(String.valueOf(astacktraceelement[i].getLineNumber()));
+ }
+ }
+
+- commandSourceStack.sendFailure(
+- Component.translatable("command.failed")
+- .withStyle(style -> style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, mutableComponent)))
+- );
++ commandlistenerwrapper.sendFailure(Component.translatable("command.failed").withStyle((chatmodifier) -> {
++ return chatmodifier.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, ichatmutablecomponent));
++ }));
+ if (SharedConstants.IS_RUNNING_IN_IDE) {
+- commandSourceStack.sendFailure(Component.literal(Util.describeError(var12)));
+- LOGGER.error("'/{}' threw an exception", string, var12);
++ commandlistenerwrapper.sendFailure(Component.literal(Util.describeError(exception)));
++ Commands.LOGGER.error("'/{}' threw an exception", s, exception);
+ }
+ } finally {
+- commandSourceStack.getServer().getProfiler().pop();
++ commandlistenerwrapper.getServer().getProfiler().pop();
+ }
++
+ }
+
+ @Nullable
+- private static ContextChain<CommandSourceStack> finishParsing(
+- ParseResults<CommandSourceStack> parseResults, String string, CommandSourceStack commandSourceStack
+- ) {
++ private static ContextChain<CommandSourceStack> finishParsing(ParseResults<CommandSourceStack> parseresults, String s, CommandSourceStack commandlistenerwrapper, String label) { // CraftBukkit
+ try {
+- validateParseResults(parseResults);
+- return ContextChain.tryFlatten(parseResults.getContext().build(string))
+- .orElseThrow(() -> CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownCommand().createWithContext(parseResults.getReader()));
+- } catch (CommandSyntaxException var7) {
+- commandSourceStack.sendFailure(ComponentUtils.fromMessage(var7.getRawMessage()));
+- if (var7.getInput() != null && var7.getCursor() >= 0) {
+- int min = Math.min(var7.getInput().length(), var7.getCursor());
+- MutableComponent mutableComponent = Component.empty()
+- .withStyle(ChatFormatting.GRAY)
+- .withStyle(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/" + string)));
+- if (min > 10) {
+- mutableComponent.append(CommonComponents.ELLIPSIS);
++ validateParseResults(parseresults);
++ return (ContextChain) ContextChain.tryFlatten(parseresults.getContext().build(s)).orElseThrow(() -> {
++ return CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownCommand().createWithContext(parseresults.getReader());
++ });
++ } catch (CommandSyntaxException commandsyntaxexception) {
++ commandlistenerwrapper.sendFailure(ComponentUtils.fromMessage(commandsyntaxexception.getRawMessage()));
++ if (commandsyntaxexception.getInput() != null && commandsyntaxexception.getCursor() >= 0) {
++ int i = Math.min(commandsyntaxexception.getInput().length(), commandsyntaxexception.getCursor());
++ MutableComponent ichatmutablecomponent = Component.empty().withStyle(ChatFormatting.GRAY).withStyle((chatmodifier) -> {
++ return chatmodifier.withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, label)); // CraftBukkit
++ });
++
++ if (i > 10) {
++ ichatmutablecomponent.append(CommonComponents.ELLIPSIS);
+ }
+
+- mutableComponent.append(var7.getInput().substring(Math.max(0, min - 10), min));
+- if (min < var7.getInput().length()) {
+- Component component = Component.literal(var7.getInput().substring(min)).withStyle(ChatFormatting.RED, ChatFormatting.UNDERLINE);
+- mutableComponent.append(component);
++ ichatmutablecomponent.append(commandsyntaxexception.getInput().substring(Math.max(0, i - 10), i));
++ if (i < commandsyntaxexception.getInput().length()) {
++ MutableComponent ichatmutablecomponent1 = Component.literal(commandsyntaxexception.getInput().substring(i)).withStyle(ChatFormatting.RED, ChatFormatting.UNDERLINE);
++
++ ichatmutablecomponent.append((Component) ichatmutablecomponent1);
+ }
+
+- mutableComponent.append(Component.translatable("command.context.here").withStyle(ChatFormatting.RED, ChatFormatting.ITALIC));
+- commandSourceStack.sendFailure(mutableComponent);
++ ichatmutablecomponent.append((Component) Component.translatable("command.context.here").withStyle(ChatFormatting.RED, ChatFormatting.ITALIC));
++ commandlistenerwrapper.sendFailure(ichatmutablecomponent);
+ }
+
+ return null;
+ }
+ }
+
+- public static void executeCommandInContext(CommandSourceStack commandSourceStack, Consumer<ExecutionContext<CommandSourceStack>> consumer) {
+- MinecraftServer server = commandSourceStack.getServer();
+- ExecutionContext<CommandSourceStack> executionContext = CURRENT_EXECUTION_CONTEXT.get();
+- boolean flag = executionContext == null;
++ public static void executeCommandInContext(CommandSourceStack commandlistenerwrapper, Consumer<ExecutionContext<CommandSourceStack>> consumer) {
++ MinecraftServer minecraftserver = commandlistenerwrapper.getServer();
++ ExecutionContext<CommandSourceStack> executioncontext = (ExecutionContext) Commands.CURRENT_EXECUTION_CONTEXT.get();
++ boolean flag = executioncontext == null;
++
+ if (flag) {
+- int max = Math.max(1, server.getGameRules().getInt(GameRules.RULE_MAX_COMMAND_CHAIN_LENGTH));
+- int _int = server.getGameRules().getInt(GameRules.RULE_MAX_COMMAND_FORK_COUNT);
++ int i = Math.max(1, minecraftserver.getGameRules().getInt(GameRules.RULE_MAX_COMMAND_CHAIN_LENGTH));
++ int j = minecraftserver.getGameRules().getInt(GameRules.RULE_MAX_COMMAND_FORK_COUNT);
+
+- try (ExecutionContext<CommandSourceStack> executionContext1 = new ExecutionContext<>(max, _int, server.getProfiler())) {
+- CURRENT_EXECUTION_CONTEXT.set(executionContext1);
+- consumer.accept(executionContext1);
+- executionContext1.runCommandQueue();
++ try {
++ ExecutionContext executioncontext1 = new ExecutionContext<>(i, j, minecraftserver.getProfiler());
++
++ try {
++ Commands.CURRENT_EXECUTION_CONTEXT.set(executioncontext1);
++ consumer.accept(executioncontext1);
++ executioncontext1.runCommandQueue();
++ } catch (Throwable throwable) {
++ try {
++ executioncontext1.close();
++ } catch (Throwable throwable1) {
++ throwable.addSuppressed(throwable1);
++ }
++
++ throw throwable;
++ }
++
++ executioncontext1.close();
+ } finally {
+- CURRENT_EXECUTION_CONTEXT.set(null);
++ Commands.CURRENT_EXECUTION_CONTEXT.set(null); // CraftBukkit - decompile error
+ }
+ } else {
+- consumer.accept(executionContext);
++ consumer.accept(executioncontext);
+ }
++
+ }
+
+ public void sendCommands(ServerPlayer player) {
+- Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> map = Maps.newHashMap();
+- RootCommandNode<SharedSuggestionProvider> rootCommandNode = new RootCommandNode<>();
+- map.put(this.dispatcher.getRoot(), rootCommandNode);
+- this.fillUsableCommands(this.dispatcher.getRoot(), rootCommandNode, player.createCommandSourceStack(), map);
+- player.connection.send(new ClientboundCommandsPacket(rootCommandNode));
++ // CraftBukkit start
++ // Register Vanilla commands into builtRoot as before
++ Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> map = Maps.newIdentityHashMap(); // Use identity to prevent aliasing issues
++ RootCommandNode vanillaRoot = new RootCommandNode();
++
++ RootCommandNode<CommandSourceStack> vanilla = player.server.vanillaCommandDispatcher.getDispatcher().getRoot();
++ map.put(vanilla, vanillaRoot);
++ this.fillUsableCommands(vanilla, vanillaRoot, player.createCommandSourceStack(), (Map) map);
++
++ // Now build the global commands in a second pass
++ RootCommandNode<SharedSuggestionProvider> rootcommandnode = new RootCommandNode();
++
++ map.put(this.dispatcher.getRoot(), rootcommandnode);
++ this.fillUsableCommands(this.dispatcher.getRoot(), rootcommandnode, player.createCommandSourceStack(), map);
++
++ Collection<String> bukkit = new LinkedHashSet<>();
++ for (CommandNode node : rootcommandnode.getChildren()) {
++ bukkit.add(node.getName());
++ }
++
++ PlayerCommandSendEvent event = new PlayerCommandSendEvent(player.getBukkitEntity(), new LinkedHashSet<>(bukkit));
++ event.getPlayer().getServer().getPluginManager().callEvent(event);
++
++ // Remove labels that were removed during the event
++ for (String orig : bukkit) {
++ if (!event.getCommands().contains(orig)) {
++ rootcommandnode.removeCommand(orig);
++ }
++ }
++ // CraftBukkit end
++ player.connection.send(new ClientboundCommandsPacket(rootcommandnode));
+ }
+
+- private void fillUsableCommands(
+- CommandNode<CommandSourceStack> rootCommandSource,
+- CommandNode<SharedSuggestionProvider> rootSuggestion,
+- CommandSourceStack source,
+- Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> commandNodeToSuggestionNode
+- ) {
+- for (CommandNode<CommandSourceStack> commandNode : rootCommandSource.getChildren()) {
+- if (commandNode.canUse(source)) {
+- ArgumentBuilder<SharedSuggestionProvider, ?> argumentBuilder = (ArgumentBuilder) commandNode.createBuilder();
+- argumentBuilder.requires(sharedSuggestionProvider -> true);
+- if (argumentBuilder.getCommand() != null) {
+- argumentBuilder.executes(commandContext -> 0);
++ private void fillUsableCommands(CommandNode<CommandSourceStack> rootCommandSource, CommandNode<SharedSuggestionProvider> rootSuggestion, CommandSourceStack source, Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> commandNodeToSuggestionNode) {
++ Iterator iterator = rootCommandSource.getChildren().iterator();
++
++ while (iterator.hasNext()) {
++ CommandNode<CommandSourceStack> commandnode2 = (CommandNode) iterator.next();
++
++ if (commandnode2.canUse(source)) {
++ ArgumentBuilder argumentbuilder = commandnode2.createBuilder(); // CraftBukkit - decompile error
++
++ argumentbuilder.requires((icompletionprovider) -> {
++ return true;
++ });
++ if (argumentbuilder.getCommand() != null) {
++ argumentbuilder.executes((commandcontext) -> {
++ return 0;
++ });
+ }
+
+- if (argumentBuilder instanceof RequiredArgumentBuilder) {
+- RequiredArgumentBuilder<SharedSuggestionProvider, ?> requiredArgumentBuilder = (RequiredArgumentBuilder<SharedSuggestionProvider, ?>)argumentBuilder;
+- if (requiredArgumentBuilder.getSuggestionsProvider() != null) {
+- requiredArgumentBuilder.suggests(SuggestionProviders.safelySwap(requiredArgumentBuilder.getSuggestionsProvider()));
++ if (argumentbuilder instanceof RequiredArgumentBuilder) {
++ RequiredArgumentBuilder<SharedSuggestionProvider, ?> requiredargumentbuilder = (RequiredArgumentBuilder) argumentbuilder;
++
++ if (requiredargumentbuilder.getSuggestionsProvider() != null) {
++ requiredargumentbuilder.suggests(SuggestionProviders.safelySwap(requiredargumentbuilder.getSuggestionsProvider()));
+ }
+ }
+
+- if (argumentBuilder.getRedirect() != null) {
+- argumentBuilder.redirect(commandNodeToSuggestionNode.get(argumentBuilder.getRedirect()));
++ if (argumentbuilder.getRedirect() != null) {
++ argumentbuilder.redirect((CommandNode) commandNodeToSuggestionNode.get(argumentbuilder.getRedirect()));
+ }
+
+- CommandNode<SharedSuggestionProvider> commandNode1 = argumentBuilder.build();
+- commandNodeToSuggestionNode.put(commandNode, commandNode1);
+- rootSuggestion.addChild(commandNode1);
+- if (!commandNode.getChildren().isEmpty()) {
+- this.fillUsableCommands(commandNode, commandNode1, source, commandNodeToSuggestionNode);
++ CommandNode commandnode3 = argumentbuilder.build(); // CraftBukkit - decompile error
++
++ commandNodeToSuggestionNode.put(commandnode2, commandnode3);
++ rootSuggestion.addChild(commandnode3);
++ if (!commandnode2.getChildren().isEmpty()) {
++ this.fillUsableCommands(commandnode2, commandnode3, source, commandNodeToSuggestionNode);
+ }
+ }
+ }
++
+ }
+
+ public static LiteralArgumentBuilder<CommandSourceStack> literal(String name) {
+@@ -410,46 +516,40 @@
+ }
+
+ public static Predicate<String> createValidator(Commands.ParseFunction parser) {
+- return string -> {
++ return (s) -> {
+ try {
+- parser.parse(new StringReader(string));
++ parser.parse(new StringReader(s));
+ return true;
+- } catch (CommandSyntaxException var3) {
++ } catch (CommandSyntaxException commandsyntaxexception) {
+ return false;
+ }
+ };
+ }
+
+- public CommandDispatcher<CommandSourceStack> getDispatcher() {
++ public com.mojang.brigadier.CommandDispatcher<CommandSourceStack> getDispatcher() {
+ return this.dispatcher;
+ }
+
+- public static <S> void validateParseResults(ParseResults<S> parseResults) throws CommandSyntaxException {
+- CommandSyntaxException parseException = getParseException(parseResults);
+- if (parseException != null) {
+- throw parseException;
++ public static <S> void validateParseResults(ParseResults<S> parseresults) throws CommandSyntaxException {
++ CommandSyntaxException commandsyntaxexception = getParseException(parseresults);
++
++ if (commandsyntaxexception != null) {
++ throw commandsyntaxexception;
+ }
+ }
+
+ @Nullable
+ public static <S> CommandSyntaxException getParseException(ParseResults<S> result) {
+- if (!result.getReader().canRead()) {
+- return null;
+- } else if (result.getExceptions().size() == 1) {
+- return result.getExceptions().values().iterator().next();
+- } else {
+- return result.getContext().getRange().isEmpty()
+- ? CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownCommand().createWithContext(result.getReader())
+- : CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownArgument().createWithContext(result.getReader());
+- }
++ return !result.getReader().canRead() ? null : (result.getExceptions().size() == 1 ? (CommandSyntaxException) result.getExceptions().values().iterator().next() : (result.getContext().getRange().isEmpty() ? CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownCommand().createWithContext(result.getReader()) : CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownArgument().createWithContext(result.getReader())));
+ }
+
+ public static CommandBuildContext createValidationContext(final HolderLookup.Provider provider) {
+ return new CommandBuildContext() {
+ @Override
+ public <T> HolderLookup<T> holderLookup(ResourceKey<? extends Registry<T>> registryResourceKey) {
+- final HolderLookup.RegistryLookup<T> registryLookup = provider.lookupOrThrow(registryResourceKey);
+- return new HolderLookup.Delegate<T>(registryLookup) {
++ final HolderLookup.RegistryLookup<T> holderlookup_c = provider.lookupOrThrow(registryResourceKey);
++
++ return new HolderLookup.Delegate<T>(holderlookup_c) {
+ @Override
+ public Optional<HolderSet.Named<T>> get(TagKey<T> tagKey) {
+ return Optional.of(this.getOrThrow(tagKey));
+@@ -457,8 +557,11 @@
+
+ @Override
+ public HolderSet.Named<T> getOrThrow(TagKey<T> tagKey) {
+- Optional<HolderSet.Named<T>> optional = registryLookup.get(tagKey);
+- return optional.orElseGet(() -> HolderSet.emptyNamed(registryLookup, tagKey));
++ Optional<HolderSet.Named<T>> optional = holderlookup_c.get(tagKey);
++
++ return (HolderSet.Named) optional.orElseGet(() -> {
++ return HolderSet.emptyNamed(holderlookup_c, tagKey);
++ });
+ }
+ };
+ }
+@@ -466,43 +569,42 @@
+ }
+
+ public static void validate() {
+- CommandBuildContext commandBuildContext = createValidationContext(VanillaRegistries.createLookup());
+- CommandDispatcher<CommandSourceStack> dispatcher = new Commands(Commands.CommandSelection.ALL, commandBuildContext).getDispatcher();
+- RootCommandNode<CommandSourceStack> root = dispatcher.getRoot();
+- dispatcher.findAmbiguities(
+- (commandNode, commandNode1, commandNode2, collection) -> LOGGER.warn(
+- "Ambiguity between arguments {} and {} with inputs: {}", dispatcher.getPath(commandNode1), dispatcher.getPath(commandNode2), collection
+- )
+- );
+- Set<ArgumentType<?>> set = ArgumentUtils.findUsedArgumentTypes(root);
+- Set<ArgumentType<?>> set1 = set.stream()
+- .filter(argumentType -> !ArgumentTypeInfos.isClassRecognized(argumentType.getClass()))
+- .collect(Collectors.toSet());
++ CommandBuildContext commandbuildcontext = createValidationContext(VanillaRegistries.createLookup());
++ com.mojang.brigadier.CommandDispatcher<CommandSourceStack> com_mojang_brigadier_commanddispatcher = (new Commands(Commands.CommandSelection.ALL, commandbuildcontext)).getDispatcher();
++ RootCommandNode<CommandSourceStack> rootcommandnode = com_mojang_brigadier_commanddispatcher.getRoot();
++
++ com_mojang_brigadier_commanddispatcher.findAmbiguities((commandnode, commandnode1, commandnode2, collection) -> {
++ Commands.LOGGER.warn("Ambiguity between arguments {} and {} with inputs: {}", new Object[]{com_mojang_brigadier_commanddispatcher.getPath(commandnode1), com_mojang_brigadier_commanddispatcher.getPath(commandnode2), collection});
++ });
++ Set<ArgumentType<?>> set = ArgumentUtils.findUsedArgumentTypes(rootcommandnode);
++ Set<ArgumentType<?>> set1 = (Set) set.stream().filter((argumenttype) -> {
++ return !ArgumentTypeInfos.isClassRecognized(argumenttype.getClass());
++ }).collect(Collectors.toSet());
++
+ if (!set1.isEmpty()) {
+- LOGGER.warn(
+- "Missing type registration for following arguments:\n {}",
+- set1.stream().map(argumentType -> "\t" + argumentType).collect(Collectors.joining(",\n"))
+- );
++ Commands.LOGGER.warn("Missing type registration for following arguments:\n {}", set1.stream().map((argumenttype) -> {
++ return "\t" + argumenttype;
++ }).collect(Collectors.joining(",\n")));
+ throw new IllegalStateException("Unregistered argument types");
+ }
+ }
+
+ public static enum CommandSelection {
+- ALL(true, true),
+- DEDICATED(false, true),
+- INTEGRATED(true, false);
+
++ ALL(true, true), DEDICATED(false, true), INTEGRATED(true, false);
++
+ final boolean includeIntegrated;
+ final boolean includeDedicated;
+
+- private CommandSelection(boolean includeIntegrated, boolean includeDedicated) {
+- this.includeIntegrated = includeIntegrated;
+- this.includeDedicated = includeDedicated;
++ private CommandSelection(boolean flag, boolean flag1) {
++ this.includeIntegrated = flag;
++ this.includeDedicated = flag1;
+ }
+ }
+
+ @FunctionalInterface
+ public interface ParseFunction {
++
+ void parse(StringReader input) throws CommandSyntaxException;
+ }
+ }
diff --git a/patch-remap/mache-vineflower/net/minecraft/commands/arguments/EntityArgument.java.patch b/patch-remap/mache-vineflower/net/minecraft/commands/arguments/EntityArgument.java.patch
new file mode 100644
index 0000000000..b7d912eaab
--- /dev/null
+++ b/patch-remap/mache-vineflower/net/minecraft/commands/arguments/EntityArgument.java.patch
@@ -0,0 +1,225 @@
+--- a/net/minecraft/commands/arguments/EntityArgument.java
++++ b/net/minecraft/commands/arguments/EntityArgument.java
+@@ -25,17 +25,14 @@
+ import net.minecraft.world.entity.Entity;
+
+ public class EntityArgument implements ArgumentType<EntitySelector> {
++
+ private static final Collection<String> EXAMPLES = Arrays.asList("Player", "0123", "@e", "@e[type=foo]", "dd12be42-52a9-4a91-a8a1-11c01849e498");
+ public static final SimpleCommandExceptionType ERROR_NOT_SINGLE_ENTITY = new SimpleCommandExceptionType(Component.translatable("argument.entity.toomany"));
+ public static final SimpleCommandExceptionType ERROR_NOT_SINGLE_PLAYER = new SimpleCommandExceptionType(Component.translatable("argument.player.toomany"));
+- public static final SimpleCommandExceptionType ERROR_ONLY_PLAYERS_ALLOWED = new SimpleCommandExceptionType(
+- Component.translatable("argument.player.entities")
+- );
++ public static final SimpleCommandExceptionType ERROR_ONLY_PLAYERS_ALLOWED = new SimpleCommandExceptionType(Component.translatable("argument.player.entities"));
+ public static final SimpleCommandExceptionType NO_ENTITIES_FOUND = new SimpleCommandExceptionType(Component.translatable("argument.entity.notfound.entity"));
+ public static final SimpleCommandExceptionType NO_PLAYERS_FOUND = new SimpleCommandExceptionType(Component.translatable("argument.entity.notfound.player"));
+- public static final SimpleCommandExceptionType ERROR_SELECTORS_NOT_ALLOWED = new SimpleCommandExceptionType(
+- Component.translatable("argument.entity.selector.not_allowed")
+- );
++ public static final SimpleCommandExceptionType ERROR_SELECTORS_NOT_ALLOWED = new SimpleCommandExceptionType(Component.translatable("argument.entity.selector.not_allowed"));
+ final boolean single;
+ final boolean playersOnly;
+
+@@ -49,7 +46,7 @@
+ }
+
+ public static Entity getEntity(CommandContext<CommandSourceStack> context, String name) throws CommandSyntaxException {
+- return context.getArgument(name, EntitySelector.class).findSingleEntity(context.getSource());
++ return ((EntitySelector) context.getArgument(name, EntitySelector.class)).findSingleEntity((CommandSourceStack) context.getSource());
+ }
+
+ public static EntityArgument entities() {
+@@ -57,20 +54,21 @@
+ }
+
+ public static Collection<? extends Entity> getEntities(CommandContext<CommandSourceStack> context, String name) throws CommandSyntaxException {
+- Collection<? extends Entity> optionalEntities = getOptionalEntities(context, name);
+- if (optionalEntities.isEmpty()) {
+- throw NO_ENTITIES_FOUND.create();
++ Collection<? extends Entity> collection = getOptionalEntities(context, name);
++
++ if (collection.isEmpty()) {
++ throw EntityArgument.NO_ENTITIES_FOUND.create();
+ } else {
+- return optionalEntities;
++ return collection;
+ }
+ }
+
+ public static Collection<? extends Entity> getOptionalEntities(CommandContext<CommandSourceStack> context, String name) throws CommandSyntaxException {
+- return context.getArgument(name, EntitySelector.class).findEntities(context.getSource());
++ return ((EntitySelector) context.getArgument(name, EntitySelector.class)).findEntities((CommandSourceStack) context.getSource());
+ }
+
+ public static Collection<ServerPlayer> getOptionalPlayers(CommandContext<CommandSourceStack> context, String name) throws CommandSyntaxException {
+- return context.getArgument(name, EntitySelector.class).findPlayers(context.getSource());
++ return ((EntitySelector) context.getArgument(name, EntitySelector.class)).findPlayers((CommandSourceStack) context.getSource());
+ }
+
+ public static EntityArgument player() {
+@@ -78,7 +76,7 @@
+ }
+
+ public static ServerPlayer getPlayer(CommandContext<CommandSourceStack> context, String name) throws CommandSyntaxException {
+- return context.getArgument(name, EntitySelector.class).findSinglePlayer(context.getSource());
++ return ((EntitySelector) context.getArgument(name, EntitySelector.class)).findSinglePlayer((CommandSourceStack) context.getSource());
+ }
+
+ public static EntityArgument players() {
+@@ -86,74 +84,83 @@
+ }
+
+ public static Collection<ServerPlayer> getPlayers(CommandContext<CommandSourceStack> context, String name) throws CommandSyntaxException {
+- List<ServerPlayer> list = context.getArgument(name, EntitySelector.class).findPlayers(context.getSource());
++ List<ServerPlayer> list = ((EntitySelector) context.getArgument(name, EntitySelector.class)).findPlayers((CommandSourceStack) context.getSource());
++
+ if (list.isEmpty()) {
+- throw NO_PLAYERS_FOUND.create();
++ throw EntityArgument.NO_PLAYERS_FOUND.create();
+ } else {
+ return list;
+ }
+ }
+
+- @Override
+ public EntitySelector parse(StringReader reader) throws CommandSyntaxException {
+- int i = 0;
+- EntitySelectorParser entitySelectorParser = new EntitySelectorParser(reader);
+- EntitySelector entitySelector = entitySelectorParser.parse();
+- if (entitySelector.getMaxResults() > 1 && this.single) {
++ // CraftBukkit start
++ return parse(reader, false);
++ }
++
++ public EntitySelector parse(StringReader stringreader, boolean overridePermissions) throws CommandSyntaxException {
++ // CraftBukkit end
++ boolean flag = false;
++ EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader);
++ EntitySelector entityselector = argumentparserselector.parse(overridePermissions); // CraftBukkit
++
++ if (entityselector.getMaxResults() > 1 && this.single) {
+ if (this.playersOnly) {
+- reader.setCursor(0);
+- throw ERROR_NOT_SINGLE_PLAYER.createWithContext(reader);
++ stringreader.setCursor(0);
++ throw EntityArgument.ERROR_NOT_SINGLE_PLAYER.createWithContext(stringreader);
+ } else {
+- reader.setCursor(0);
+- throw ERROR_NOT_SINGLE_ENTITY.createWithContext(reader);
++ stringreader.setCursor(0);
++ throw EntityArgument.ERROR_NOT_SINGLE_ENTITY.createWithContext(stringreader);
+ }
+- } else if (entitySelector.includesEntities() && this.playersOnly && !entitySelector.isSelfSelector()) {
+- reader.setCursor(0);
+- throw ERROR_ONLY_PLAYERS_ALLOWED.createWithContext(reader);
++ } else if (entityselector.includesEntities() && this.playersOnly && !entityselector.isSelfSelector()) {
++ stringreader.setCursor(0);
++ throw EntityArgument.ERROR_ONLY_PLAYERS_ALLOWED.createWithContext(stringreader);
+ } else {
+- return entitySelector;
++ return entityselector;
+ }
+ }
+
+- @Override
+- public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
+- if (context.getSource() instanceof SharedSuggestionProvider sharedSuggestionProvider) {
+- StringReader stringReader = new StringReader(builder.getInput());
+- stringReader.setCursor(builder.getStart());
+- EntitySelectorParser entitySelectorParser = new EntitySelectorParser(stringReader, sharedSuggestionProvider.hasPermission(2));
++ public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> commandcontext, SuggestionsBuilder suggestionsbuilder) {
++ Object object = commandcontext.getSource();
+
++ if (object instanceof SharedSuggestionProvider) {
++ SharedSuggestionProvider icompletionprovider = (SharedSuggestionProvider) object;
++ StringReader stringreader = new StringReader(suggestionsbuilder.getInput());
++
++ stringreader.setCursor(suggestionsbuilder.getStart());
++ EntitySelectorParser argumentparserselector = new EntitySelectorParser(stringreader, icompletionprovider.hasPermission(2));
++
+ try {
+- entitySelectorParser.parse();
+- } catch (CommandSyntaxException var7) {
++ argumentparserselector.parse();
++ } catch (CommandSyntaxException commandsyntaxexception) {
++ ;
+ }
+
+- return entitySelectorParser.fillSuggestions(
+- builder,
+- offsetBuilder -> {
+- Collection<String> onlinePlayerNames = sharedSuggestionProvider.getOnlinePlayerNames();
+- Iterable<String> iterable = (Iterable<String>)(this.playersOnly
+- ? onlinePlayerNames
+- : Iterables.concat(onlinePlayerNames, sharedSuggestionProvider.getSelectedEntities()));
+- SharedSuggestionProvider.suggest(iterable, offsetBuilder);
+- }
+- );
++ return argumentparserselector.fillSuggestions(suggestionsbuilder, (suggestionsbuilder1) -> {
++ Collection<String> collection = icompletionprovider.getOnlinePlayerNames();
++ Iterable<String> iterable = this.playersOnly ? collection : Iterables.concat(collection, icompletionprovider.getSelectedEntities());
++
++ SharedSuggestionProvider.suggest((Iterable) iterable, suggestionsbuilder1);
++ });
+ } else {
+ return Suggestions.empty();
+ }
+ }
+
+- @Override
+ public Collection<String> getExamples() {
+- return EXAMPLES;
++ return EntityArgument.EXAMPLES;
+ }
+
+ public static class Info implements ArgumentTypeInfo<EntityArgument, EntityArgument.Info.Template> {
++
+ private static final byte FLAG_SINGLE = 1;
+ private static final byte FLAG_PLAYERS_ONLY = 2;
+
+- @Override
++ public Info() {}
++
+ public void serializeToNetwork(EntityArgument.Info.Template template, FriendlyByteBuf buffer) {
+ int i = 0;
++
+ if (template.single) {
+ i |= 1;
+ }
+@@ -167,28 +174,28 @@
+
+ @Override
+ public EntityArgument.Info.Template deserializeFromNetwork(FriendlyByteBuf buffer) {
+- byte _byte = buffer.readByte();
+- return new EntityArgument.Info.Template((_byte & 1) != 0, (_byte & 2) != 0);
++ byte b0 = buffer.readByte();
++
++ return new EntityArgument.Info.Template((b0 & 1) != 0, (b0 & 2) != 0);
+ }
+
+- @Override
+ public void serializeToJson(EntityArgument.Info.Template template, JsonObject json) {
+ json.addProperty("amount", template.single ? "single" : "multiple");
+ json.addProperty("type", template.playersOnly ? "players" : "entities");
+ }
+
+- @Override
+ public EntityArgument.Info.Template unpack(EntityArgument argument) {
+ return new EntityArgument.Info.Template(argument.single, argument.playersOnly);
+ }
+
+ public final class Template implements ArgumentTypeInfo.Template<EntityArgument> {
++
+ final boolean single;
+ final boolean playersOnly;
+
+- Template(boolean single, boolean playersOnly) {
+- this.single = single;
+- this.playersOnly = playersOnly;
++ Template(boolean flag, boolean flag1) {
++ this.single = flag;
++ this.playersOnly = flag1;
+ }
+
+ @Override
diff --git a/patch-remap/mache-vineflower/net/minecraft/commands/arguments/blocks/BlockStateParser.java.patch b/patch-remap/mache-vineflower/net/minecraft/commands/arguments/blocks/BlockStateParser.java.patch
new file mode 100644
index 0000000000..77aa7b9a06
--- /dev/null
+++ b/patch-remap/mache-vineflower/net/minecraft/commands/arguments/blocks/BlockStateParser.java.patch
@@ -0,0 +1,641 @@
+--- a/net/minecraft/commands/arguments/blocks/BlockStateParser.java
++++ b/net/minecraft/commands/arguments/blocks/BlockStateParser.java
+@@ -1,6 +1,7 @@
+ package net.minecraft.commands.arguments.blocks;
+
+ import com.google.common.collect.Maps;
++import com.google.common.collect.UnmodifiableIterator;
+ import com.mojang.brigadier.StringReader;
+ import com.mojang.brigadier.exceptions.CommandSyntaxException;
+ import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
+@@ -10,10 +11,11 @@
+ import com.mojang.brigadier.suggestion.Suggestions;
+ import com.mojang.brigadier.suggestion.SuggestionsBuilder;
+ import com.mojang.datafixers.util.Either;
++import java.util.Iterator;
+ import java.util.Locale;
+ import java.util.Map;
+-import java.util.Optional;
+ import java.util.Map.Entry;
++import java.util.Optional;
+ import java.util.concurrent.CompletableFuture;
+ import java.util.function.Function;
+ import javax.annotation.Nullable;
+@@ -29,35 +31,32 @@
+ import net.minecraft.resources.ResourceLocation;
+ import net.minecraft.tags.TagKey;
+ import net.minecraft.world.level.block.Block;
+-import net.minecraft.world.level.block.state.BlockState;
++import net.minecraft.world.level.block.state.IBlockData;
+ import net.minecraft.world.level.block.state.StateDefinition;
+ import net.minecraft.world.level.block.state.properties.Property;
+
+ public class BlockStateParser {
+- public static final SimpleCommandExceptionType ERROR_NO_TAGS_ALLOWED = new SimpleCommandExceptionType(
+- Component.translatable("argument.block.tag.disallowed")
+- );
+- public static final DynamicCommandExceptionType ERROR_UNKNOWN_BLOCK = new DynamicCommandExceptionType(
+- block -> Component.translatableEscape("argument.block.id.invalid", block)
+- );
+- public static final Dynamic2CommandExceptionType ERROR_UNKNOWN_PROPERTY = new Dynamic2CommandExceptionType(
+- (block, property) -> Component.translatableEscape("argument.block.property.unknown", block, property)
+- );
+- public static final Dynamic2CommandExceptionType ERROR_DUPLICATE_PROPERTY = new Dynamic2CommandExceptionType(
+- (property, block) -> Component.translatableEscape("argument.block.property.duplicate", block, property)
+- );
+- public static final Dynamic3CommandExceptionType ERROR_INVALID_VALUE = new Dynamic3CommandExceptionType(
+- (block, value, property) -> Component.translatableEscape("argument.block.property.invalid", block, property, value)
+- );
+- public static final Dynamic2CommandExceptionType ERROR_EXPECTED_VALUE = new Dynamic2CommandExceptionType(
+- (property, block) -> Component.translatableEscape("argument.block.property.novalue", property, block)
+- );
+- public static final SimpleCommandExceptionType ERROR_EXPECTED_END_OF_PROPERTIES = new SimpleCommandExceptionType(
+- Component.translatable("argument.block.property.unclosed")
+- );
+- public static final DynamicCommandExceptionType ERROR_UNKNOWN_TAG = new DynamicCommandExceptionType(
+- blockTag -> Component.translatableEscape("arguments.block.tag.unknown", blockTag)
+- );
++
++ public static final SimpleCommandExceptionType ERROR_NO_TAGS_ALLOWED = new SimpleCommandExceptionType(Component.translatable("argument.block.tag.disallowed"));
++ public static final DynamicCommandExceptionType ERROR_UNKNOWN_BLOCK = new DynamicCommandExceptionType((object) -> {
++ return Component.translatableEscape("argument.block.id.invalid", object);
++ });
++ public static final Dynamic2CommandExceptionType ERROR_UNKNOWN_PROPERTY = new Dynamic2CommandExceptionType((object, object1) -> {
++ return Component.translatableEscape("argument.block.property.unknown", object, object1);
++ });
++ public static final Dynamic2CommandExceptionType ERROR_DUPLICATE_PROPERTY = new Dynamic2CommandExceptionType((object, object1) -> {
++ return Component.translatableEscape("argument.block.property.duplicate", object1, object);
++ });
++ public static final Dynamic3CommandExceptionType ERROR_INVALID_VALUE = new Dynamic3CommandExceptionType((object, object1, object2) -> {
++ return Component.translatableEscape("argument.block.property.invalid", object, object2, object1);
++ });
++ public static final Dynamic2CommandExceptionType ERROR_EXPECTED_VALUE = new Dynamic2CommandExceptionType((object, object1) -> {
++ return Component.translatableEscape("argument.block.property.novalue", object, object1);
++ });
++ public static final SimpleCommandExceptionType ERROR_EXPECTED_END_OF_PROPERTIES = new SimpleCommandExceptionType(Component.translatable("argument.block.property.unclosed"));
++ public static final DynamicCommandExceptionType ERROR_UNKNOWN_TAG = new DynamicCommandExceptionType((object) -> {
++ return Component.translatableEscape("arguments.block.tag.unknown", object);
++ });
+ private static final char SYNTAX_START_PROPERTIES = '[';
+ private static final char SYNTAX_START_NBT = '{';
+ private static final char SYNTAX_END_PROPERTIES = ']';
+@@ -69,75 +68,76 @@
+ private final StringReader reader;
+ private final boolean forTesting;
+ private final boolean allowNbt;
+- private final Map<Property<?>, Comparable<?>> properties = Maps.newHashMap();
++ private final Map<Property<?>, Comparable<?>> properties = Maps.newLinkedHashMap(); // CraftBukkit - stable
+ private final Map<String, String> vagueProperties = Maps.newHashMap();
+ private ResourceLocation id = new ResourceLocation("");
+ @Nullable
+- private StateDefinition<Block, BlockState> definition;
++ private StateDefinition<Block, IBlockData> definition;
+ @Nullable
+- private BlockState state;
++ private IBlockData state;
+ @Nullable
+ private CompoundTag nbt;
+ @Nullable
+ private HolderSet<Block> tag;
+- private Function<SuggestionsBuilder, CompletableFuture<Suggestions>> suggestions = SUGGEST_NOTHING;
++ private Function<SuggestionsBuilder, CompletableFuture<Suggestions>> suggestions;
+
+ private BlockStateParser(HolderLookup<Block> blocks, StringReader reader, boolean forTesting, boolean allowNbt) {
++ this.suggestions = BlockStateParser.SUGGEST_NOTHING;
+ this.blocks = blocks;
+ this.reader = reader;
+ this.forTesting = forTesting;
+ this.allowNbt = allowNbt;
+ }
+
+- public static BlockStateParser.BlockResult parseForBlock(HolderLookup<Block> lookup, String input, boolean allowNbt) throws CommandSyntaxException {
++ public static BlockStateParser.a parseForBlock(HolderLookup<Block> lookup, String input, boolean allowNbt) throws CommandSyntaxException {
+ return parseForBlock(lookup, new StringReader(input), allowNbt);
+ }
+
+- public static BlockStateParser.BlockResult parseForBlock(HolderLookup<Block> lookup, StringReader reader, boolean allowNbt) throws CommandSyntaxException {
+- int cursor = reader.getCursor();
++ public static BlockStateParser.a parseForBlock(HolderLookup<Block> lookup, StringReader reader, boolean allowNbt) throws CommandSyntaxException {
++ int i = reader.getCursor();
+
+ try {
+- BlockStateParser blockStateParser = new BlockStateParser(lookup, reader, false, allowNbt);
+- blockStateParser.parse();
+- return new BlockStateParser.BlockResult(blockStateParser.state, blockStateParser.properties, blockStateParser.nbt);
+- } catch (CommandSyntaxException var5) {
+- reader.setCursor(cursor);
+- throw var5;
++ BlockStateParser argumentblock = new BlockStateParser(lookup, reader, false, allowNbt);
++
++ argumentblock.parse();
++ return new BlockStateParser.a(argumentblock.state, argumentblock.properties, argumentblock.nbt);
++ } catch (CommandSyntaxException commandsyntaxexception) {
++ reader.setCursor(i);
++ throw commandsyntaxexception;
+ }
+ }
+
+- public static Either<BlockStateParser.BlockResult, BlockStateParser.TagResult> parseForTesting(HolderLookup<Block> lookup, String input, boolean allowNbt) throws CommandSyntaxException {
++ public static Either<BlockStateParser.a, BlockStateParser.b> parseForTesting(HolderLookup<Block> lookup, String input, boolean allowNbt) throws CommandSyntaxException {
+ return parseForTesting(lookup, new StringReader(input), allowNbt);
+ }
+
+- public static Either<BlockStateParser.BlockResult, BlockStateParser.TagResult> parseForTesting(
+- HolderLookup<Block> lookup, StringReader reader, boolean allowNbt
+- ) throws CommandSyntaxException {
+- int cursor = reader.getCursor();
++ public static Either<BlockStateParser.a, BlockStateParser.b> parseForTesting(HolderLookup<Block> lookup, StringReader reader, boolean allowNbt) throws CommandSyntaxException {
++ int i = reader.getCursor();
+
+ try {
+- BlockStateParser blockStateParser = new BlockStateParser(lookup, reader, true, allowNbt);
+- blockStateParser.parse();
+- return blockStateParser.tag != null
+- ? Either.right(new BlockStateParser.TagResult(blockStateParser.tag, blockStateParser.vagueProperties, blockStateParser.nbt))
+- : Either.left(new BlockStateParser.BlockResult(blockStateParser.state, blockStateParser.properties, blockStateParser.nbt));
+- } catch (CommandSyntaxException var5) {
+- reader.setCursor(cursor);
+- throw var5;
++ BlockStateParser argumentblock = new BlockStateParser(lookup, reader, true, allowNbt);
++
++ argumentblock.parse();
++ return argumentblock.tag != null ? Either.right(new BlockStateParser.b(argumentblock.tag, argumentblock.vagueProperties, argumentblock.nbt)) : Either.left(new BlockStateParser.a(argumentblock.state, argumentblock.properties, argumentblock.nbt));
++ } catch (CommandSyntaxException commandsyntaxexception) {
++ reader.setCursor(i);
++ throw commandsyntaxexception;
+ }
+ }
+
+ public static CompletableFuture<Suggestions> fillSuggestions(HolderLookup<Block> lookup, SuggestionsBuilder builder, boolean forTesting, boolean allowNbt) {
+- StringReader stringReader = new StringReader(builder.getInput());
+- stringReader.setCursor(builder.getStart());
+- BlockStateParser blockStateParser = new BlockStateParser(lookup, stringReader, forTesting, allowNbt);
++ StringReader stringreader = new StringReader(builder.getInput());
+
++ stringreader.setCursor(builder.getStart());
++ BlockStateParser argumentblock = new BlockStateParser(lookup, stringreader, forTesting, allowNbt);
++
+ try {
+- blockStateParser.parse();
+- } catch (CommandSyntaxException var7) {
++ argumentblock.parse();
++ } catch (CommandSyntaxException commandsyntaxexception) {
++ ;
+ }
+
+- return blockStateParser.suggestions.apply(builder.createOffset(stringReader.getCursor()));
++ return (CompletableFuture) argumentblock.suggestions.apply(builder.createOffset(stringreader.getCursor()));
+ }
+
+ private void parse() throws CommandSyntaxException {
+@@ -164,9 +164,10 @@
+ }
+
+ if (this.allowNbt && this.reader.canRead() && this.reader.peek() == '{') {
+- this.suggestions = SUGGEST_NOTHING;
++ this.suggestions = BlockStateParser.SUGGEST_NOTHING;
+ this.readNbt();
+ }
++
+ }
+
+ private CompletableFuture<Suggestions> suggestPropertyNameOrEnd(SuggestionsBuilder builder) {
+@@ -186,11 +187,14 @@
+ }
+
+ private CompletableFuture<Suggestions> suggestPropertyName(SuggestionsBuilder builder) {
+- String string = builder.getRemaining().toLowerCase(Locale.ROOT);
++ String s = builder.getRemaining().toLowerCase(Locale.ROOT);
++ Iterator iterator = this.state.getProperties().iterator();
+
+- for (Property<?> property : this.state.getProperties()) {
+- if (!this.properties.containsKey(property) && property.getName().startsWith(string)) {
+- builder.suggest(property.getName() + "=");
++ while (iterator.hasNext()) {
++ Property<?> iblockstate = (Property) iterator.next();
++
++ if (!this.properties.containsKey(iblockstate) && iblockstate.getName().startsWith(s)) {
++ builder.suggest(iblockstate.getName() + "=");
+ }
+ }
+
+@@ -198,12 +202,20 @@
+ }
+
+ private CompletableFuture<Suggestions> suggestVaguePropertyName(SuggestionsBuilder builder) {
+- String string = builder.getRemaining().toLowerCase(Locale.ROOT);
++ String s = builder.getRemaining().toLowerCase(Locale.ROOT);
++
+ if (this.tag != null) {
+- for (Holder<Block> holder : this.tag) {
+- for (Property<?> property : holder.value().getStateDefinition().getProperties()) {
+- if (!this.vagueProperties.containsKey(property.getName()) && property.getName().startsWith(string)) {
+- builder.suggest(property.getName() + "=");
++ Iterator iterator = this.tag.iterator();
++
++ while (iterator.hasNext()) {
++ Holder<Block> holder = (Holder) iterator.next();
++ Iterator iterator1 = ((Block) holder.value()).getStateDefinition().getProperties().iterator();
++
++ while (iterator1.hasNext()) {
++ Property<?> iblockstate = (Property) iterator1.next();
++
++ if (!this.vagueProperties.containsKey(iblockstate.getName()) && iblockstate.getName().startsWith(s)) {
++ builder.suggest(iblockstate.getName() + "=");
+ }
+ }
+ }
+@@ -225,8 +237,12 @@
+ return this.state.hasBlockEntity();
+ } else {
+ if (this.tag != null) {
+- for (Holder<Block> holder : this.tag) {
+- if (holder.value().defaultBlockState().hasBlockEntity()) {
++ Iterator iterator = this.tag.iterator();
++
++ while (iterator.hasNext()) {
++ Holder<Block> holder = (Holder) iterator.next();
++
++ if (((Block) holder.value()).defaultBlockState().hasBlockEntity()) {
+ return true;
+ }
+ }
+@@ -257,11 +273,17 @@
+ }
+
+ private static <T extends Comparable<T>> SuggestionsBuilder addSuggestions(SuggestionsBuilder builder, Property<T> property) {
+- for (T comparable : property.getPossibleValues()) {
+- if (comparable instanceof Integer integer) {
++ Iterator iterator = property.getPossibleValues().iterator();
++
++ while (iterator.hasNext()) {
++ T t0 = (T) iterator.next(); // CraftBukkit - decompile error
++
++ if (t0 instanceof Integer) {
++ Integer integer = (Integer) t0;
++
+ builder.suggest(integer);
+ } else {
+- builder.suggest(property.getName(comparable));
++ builder.suggest(property.getName(t0));
+ }
+ }
+
+@@ -270,17 +292,26 @@
+
+ private CompletableFuture<Suggestions> suggestVaguePropertyValue(SuggestionsBuilder builder, String propertyName) {
+ boolean flag = false;
++
+ if (this.tag != null) {
+- for (Holder<Block> holder : this.tag) {
+- Block block = holder.value();
+- Property<?> property = block.getStateDefinition().getProperty(propertyName);
+- if (property != null) {
+- addSuggestions(builder, property);
++ Iterator iterator = this.tag.iterator();
++
++ while (iterator.hasNext()) {
++ Holder<Block> holder = (Holder) iterator.next();
++ Block block = (Block) holder.value();
++ Property<?> iblockstate = block.getStateDefinition().getProperty(propertyName);
++
++ if (iblockstate != null) {
++ addSuggestions(builder, iblockstate);
+ }
+
+ if (!flag) {
+- for (Property<?> property1 : block.getStateDefinition().getProperties()) {
+- if (!this.vagueProperties.containsKey(property1.getName())) {
++ Iterator iterator1 = block.getStateDefinition().getProperties().iterator();
++
++ while (iterator1.hasNext()) {
++ Property<?> iblockstate1 = (Property) iterator1.next();
++
++ if (!this.vagueProperties.containsKey(iblockstate1.getName())) {
+ flag = true;
+ break;
+ }
+@@ -301,9 +332,12 @@
+ if (builder.getRemaining().isEmpty() && this.tag != null) {
+ boolean flag = false;
+ boolean flag1 = false;
++ Iterator iterator = this.tag.iterator();
+
+- for (Holder<Block> holder : this.tag) {
+- Block block = holder.value();
++ while (iterator.hasNext()) {
++ Holder<Block> holder = (Holder) iterator.next();
++ Block block = (Block) holder.value();
++
+ flag |= !block.getStateDefinition().getProperties().isEmpty();
+ flag1 |= block.defaultBlockState().hasBlockEntity();
+ if (flag && flag1) {
+@@ -352,27 +386,31 @@
+ }
+
+ private void readBlock() throws CommandSyntaxException {
+- int cursor = this.reader.getCursor();
++ int i = this.reader.getCursor();
++
+ this.id = ResourceLocation.read(this.reader);
+- Block block = this.blocks.get(ResourceKey.create(Registries.BLOCK, this.id)).orElseThrow(() -> {
+- this.reader.setCursor(cursor);
+- return ERROR_UNKNOWN_BLOCK.createWithContext(this.reader, this.id.toString());
+- }).value();
++ Block block = (Block) ((Holder.Reference) this.blocks.get(ResourceKey.create(Registries.BLOCK, this.id)).orElseThrow(() -> {
++ this.reader.setCursor(i);
++ return BlockStateParser.ERROR_UNKNOWN_BLOCK.createWithContext(this.reader, this.id.toString());
++ })).value();
++
+ this.definition = block.getStateDefinition();
+ this.state = block.defaultBlockState();
+ }
+
+ private void readTag() throws CommandSyntaxException {
+ if (!this.forTesting) {
+- throw ERROR_NO_TAGS_ALLOWED.createWithContext(this.reader);
++ throw BlockStateParser.ERROR_NO_TAGS_ALLOWED.createWithContext(this.reader);
+ } else {
+- int cursor = this.reader.getCursor();
++ int i = this.reader.getCursor();
++
+ this.reader.expect('#');
+ this.suggestions = this::suggestTag;
+- ResourceLocation resourceLocation = ResourceLocation.read(this.reader);
+- this.tag = this.blocks.get(TagKey.create(Registries.BLOCK, resourceLocation)).orElseThrow(() -> {
+- this.reader.setCursor(cursor);
+- return ERROR_UNKNOWN_TAG.createWithContext(this.reader, resourceLocation.toString());
++ ResourceLocation minecraftkey = ResourceLocation.read(this.reader);
++
++ this.tag = (HolderSet) this.blocks.get(TagKey.create(Registries.BLOCK, minecraftkey)).orElseThrow(() -> {
++ this.reader.setCursor(i);
++ return BlockStateParser.ERROR_UNKNOWN_TAG.createWithContext(this.reader, minecraftkey.toString());
+ });
+ }
+ }
+@@ -382,51 +420,60 @@
+ this.suggestions = this::suggestPropertyNameOrEnd;
+ this.reader.skipWhitespace();
+
+- while (this.reader.canRead() && this.reader.peek() != ']') {
+- this.reader.skipWhitespace();
+- int cursor = this.reader.getCursor();
+- String string = this.reader.readString();
+- Property<?> property = this.definition.getProperty(string);
+- if (property == null) {
+- this.reader.setCursor(cursor);
+- throw ERROR_UNKNOWN_PROPERTY.createWithContext(this.reader, this.id.toString(), string);
+- }
++ while (true) {
++ if (this.reader.canRead() && this.reader.peek() != ']') {
++ this.reader.skipWhitespace();
++ int i = this.reader.getCursor();
++ String s = this.reader.readString();
++ Property<?> iblockstate = this.definition.getProperty(s);
+
+- if (this.properties.containsKey(property)) {
+- this.reader.setCursor(cursor);
+- throw ERROR_DUPLICATE_PROPERTY.createWithContext(this.reader, this.id.toString(), string);
+- }
++ if (iblockstate == null) {
++ this.reader.setCursor(i);
++ throw BlockStateParser.ERROR_UNKNOWN_PROPERTY.createWithContext(this.reader, this.id.toString(), s);
++ }
+
+- this.reader.skipWhitespace();
+- this.suggestions = this::suggestEquals;
+- if (!this.reader.canRead() || this.reader.peek() != '=') {
+- throw ERROR_EXPECTED_VALUE.createWithContext(this.reader, this.id.toString(), string);
+- }
++ if (this.properties.containsKey(iblockstate)) {
++ this.reader.setCursor(i);
++ throw BlockStateParser.ERROR_DUPLICATE_PROPERTY.createWithContext(this.reader, this.id.toString(), s);
++ }
+
+- this.reader.skip();
+- this.reader.skipWhitespace();
+- this.suggestions = builder -> addSuggestions(builder, property).buildFuture();
+- int cursor1 = this.reader.getCursor();
+- this.setValue(property, this.reader.readString(), cursor1);
+- this.suggestions = this::suggestNextPropertyOrEnd;
+- this.reader.skipWhitespace();
+- if (this.reader.canRead()) {
+- if (this.reader.peek() != ',') {
+- if (this.reader.peek() != ']') {
+- throw ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
+- }
+- break;
++ this.reader.skipWhitespace();
++ this.suggestions = this::suggestEquals;
++ if (!this.reader.canRead() || this.reader.peek() != '=') {
++ throw BlockStateParser.ERROR_EXPECTED_VALUE.createWithContext(this.reader, this.id.toString(), s);
+ }
+
+ this.reader.skip();
+- this.suggestions = this::suggestPropertyName;
++ this.reader.skipWhitespace();
++ this.suggestions = (suggestionsbuilder) -> {
++ return addSuggestions(suggestionsbuilder, iblockstate).buildFuture();
++ };
++ int j = this.reader.getCursor();
++
++ this.setValue(iblockstate, this.reader.readString(), j);
++ this.suggestions = this::suggestNextPropertyOrEnd;
++ this.reader.skipWhitespace();
++ if (!this.reader.canRead()) {
++ continue;
++ }
++
++ if (this.reader.peek() == ',') {
++ this.reader.skip();
++ this.suggestions = this::suggestPropertyName;
++ continue;
++ }
++
++ if (this.reader.peek() != ']') {
++ throw BlockStateParser.ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
++ }
+ }
+- }
+
+- if (this.reader.canRead()) {
+- this.reader.skip();
+- } else {
+- throw ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
++ if (this.reader.canRead()) {
++ this.reader.skip();
++ return;
++ }
++
++ throw BlockStateParser.ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
+ }
+ }
+
+@@ -434,100 +481,117 @@
+ this.reader.skip();
+ this.suggestions = this::suggestVaguePropertyNameOrEnd;
+ int i = -1;
++
+ this.reader.skipWhitespace();
+
+- while (this.reader.canRead() && this.reader.peek() != ']') {
+- this.reader.skipWhitespace();
+- int cursor = this.reader.getCursor();
+- String string = this.reader.readString();
+- if (this.vagueProperties.containsKey(string)) {
+- this.reader.setCursor(cursor);
+- throw ERROR_DUPLICATE_PROPERTY.createWithContext(this.reader, this.id.toString(), string);
+- }
++ while (true) {
++ if (this.reader.canRead() && this.reader.peek() != ']') {
++ this.reader.skipWhitespace();
++ int j = this.reader.getCursor();
++ String s = this.reader.readString();
+
+- this.reader.skipWhitespace();
+- if (!this.reader.canRead() || this.reader.peek() != '=') {
+- this.reader.setCursor(cursor);
+- throw ERROR_EXPECTED_VALUE.createWithContext(this.reader, this.id.toString(), string);
+- }
++ if (this.vagueProperties.containsKey(s)) {
++ this.reader.setCursor(j);
++ throw BlockStateParser.ERROR_DUPLICATE_PROPERTY.createWithContext(this.reader, this.id.toString(), s);
++ }
+
+- this.reader.skip();
+- this.reader.skipWhitespace();
+- this.suggestions = builder -> this.suggestVaguePropertyValue(builder, string);
+- i = this.reader.getCursor();
+- String string1 = this.reader.readString();
+- this.vagueProperties.put(string, string1);
+- this.reader.skipWhitespace();
+- if (this.reader.canRead()) {
++ this.reader.skipWhitespace();
++ if (!this.reader.canRead() || this.reader.peek() != '=') {
++ this.reader.setCursor(j);
++ throw BlockStateParser.ERROR_EXPECTED_VALUE.createWithContext(this.reader, this.id.toString(), s);
++ }
++
++ this.reader.skip();
++ this.reader.skipWhitespace();
++ this.suggestions = (suggestionsbuilder) -> {
++ return this.suggestVaguePropertyValue(suggestionsbuilder, s);
++ };
++ i = this.reader.getCursor();
++ String s1 = this.reader.readString();
++
++ this.vagueProperties.put(s, s1);
++ this.reader.skipWhitespace();
++ if (!this.reader.canRead()) {
++ continue;
++ }
++
+ i = -1;
+- if (this.reader.peek() != ',') {
+- if (this.reader.peek() != ']') {
+- throw ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
+- }
+- break;
++ if (this.reader.peek() == ',') {
++ this.reader.skip();
++ this.suggestions = this::suggestVaguePropertyName;
++ continue;
+ }
+
++ if (this.reader.peek() != ']') {
++ throw BlockStateParser.ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
++ }
++ }
++
++ if (this.reader.canRead()) {
+ this.reader.skip();
+- this.suggestions = this::suggestVaguePropertyName;
++ return;
+ }
+- }
+
+- if (this.reader.canRead()) {
+- this.reader.skip();
+- } else {
+ if (i >= 0) {
+ this.reader.setCursor(i);
+ }
+
+- throw ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
++ throw BlockStateParser.ERROR_EXPECTED_END_OF_PROPERTIES.createWithContext(this.reader);
+ }
+ }
+
+ private void readNbt() throws CommandSyntaxException {
+- this.nbt = new TagParser(this.reader).readStruct();
++ this.nbt = (new TagParser(this.reader)).readStruct();
+ }
+
+ private <T extends Comparable<T>> void setValue(Property<T> property, String value, int valuePosition) throws CommandSyntaxException {
+- Optional<T> value1 = property.getValue(value);
+- if (value1.isPresent()) {
+- this.state = this.state.setValue(property, value1.get());
+- this.properties.put(property, value1.get());
++ Optional<T> optional = property.getValue(value);
++
++ if (optional.isPresent()) {
++ this.state = (IBlockData) this.state.setValue(property, (T) optional.get()); // CraftBukkit - decompile error
++ this.properties.put(property, (Comparable) optional.get());
+ } else {
+ this.reader.setCursor(valuePosition);
+- throw ERROR_INVALID_VALUE.createWithContext(this.reader, this.id.toString(), property.getName(), value);
++ throw BlockStateParser.ERROR_INVALID_VALUE.createWithContext(this.reader, this.id.toString(), property.getName(), value);
+ }
+ }
+
+- public static String serialize(BlockState state) {
+- StringBuilder stringBuilder = new StringBuilder(state.getBlockHolder().unwrapKey().map(blockKey -> blockKey.location().toString()).orElse("air"));
++ public static String serialize(IBlockData state) {
++ StringBuilder stringbuilder = new StringBuilder((String) state.getBlockHolder().unwrapKey().map((resourcekey) -> {
++ return resourcekey.location().toString();
++ }).orElse("air"));
++
+ if (!state.getProperties().isEmpty()) {
+- stringBuilder.append('[');
++ stringbuilder.append('[');
+ boolean flag = false;
+
+- for (Entry<Property<?>, Comparable<?>> entry : state.getValues().entrySet()) {
++ for (UnmodifiableIterator unmodifiableiterator = state.getValues().entrySet().iterator(); unmodifiableiterator.hasNext(); flag = true) {
++ Entry<Property<?>, Comparable<?>> entry = (Entry) unmodifiableiterator.next();
++
+ if (flag) {
+- stringBuilder.append(',');
++ stringbuilder.append(',');
+ }
+
+- appendProperty(stringBuilder, entry.getKey(), entry.getValue());
+- flag = true;
++ appendProperty(stringbuilder, (Property) entry.getKey(), (Comparable) entry.getValue());
+ }
+
+- stringBuilder.append(']');
++ stringbuilder.append(']');
+ }
+
+- return stringBuilder.toString();
++ return stringbuilder.toString();
+ }
+
+ private static <T extends Comparable<T>> void appendProperty(StringBuilder builder, Property<T> property, Comparable<?> value) {
+ builder.append(property.getName());
+ builder.append('=');
+- builder.append(property.getName((T)value));
++ builder.append(property.getName((T) value)); // CraftBukkit - decompile error
+ }
+
+- public static record BlockResult(BlockState blockState, Map<Property<?>, Comparable<?>> properties, @Nullable CompoundTag nbt) {
++ public static record a(IBlockData blockState, Map<Property<?>, Comparable<?>> properties, @Nullable CompoundTag nbt) {
++
+ }
+
+- public static record TagResult(HolderSet<Block> tag, Map<String, String> vagueProperties, @Nullable CompoundTag nbt) {
++ public static record b(HolderSet<Block> tag, Map<String, String> vagueProperties, @Nullable CompoundTag nbt) {
++
+ }
+ }
diff --git a/patch-remap/mache-vineflower/net/minecraft/commands/arguments/selector/EntitySelector.java.patch b/patch-remap/mache-vineflower/net/minecraft/commands/arguments/selector/EntitySelector.java.patch
new file mode 100644
index 0000000000..150b9bd72a
--- /dev/null
+++ b/patch-remap/mache-vineflower/net/minecraft/commands/arguments/selector/EntitySelector.java.patch
@@ -0,0 +1,280 @@
+--- a/net/minecraft/commands/arguments/selector/EntitySelector.java
++++ b/net/minecraft/commands/arguments/selector/EntitySelector.java
+@@ -3,6 +3,7 @@
+ import com.google.common.collect.Lists;
+ import com.mojang.brigadier.exceptions.CommandSyntaxException;
+ import java.util.Collections;
++import java.util.Iterator;
+ import java.util.List;
+ import java.util.UUID;
+ import java.util.function.BiConsumer;
+@@ -23,11 +24,11 @@
+ import net.minecraft.world.phys.Vec3;
+
+ public class EntitySelector {
++
+ public static final int INFINITE = Integer.MAX_VALUE;
+- public static final BiConsumer<Vec3, List<? extends Entity>> ORDER_ARBITRARY = (center, entityList) -> {
++ public static final BiConsumer<Vec3, List<? extends Entity>> ORDER_ARBITRARY = (vec3d, list) -> {
+ };
+ private static final EntityTypeTest<Entity, ?> ANY_TYPE = new EntityTypeTest<Entity, Entity>() {
+- @Override
+ public Entity tryCast(Entity entity) {
+ return entity;
+ }
+@@ -54,21 +55,7 @@
+ private final EntityTypeTest<Entity, ?> type;
+ private final boolean usesSelector;
+
+- public EntitySelector(
+- int maxResults,
+- boolean includeEntities,
+- boolean worldLimited,
+- Predicate<Entity> predicate,
+- MinMaxBounds.Doubles range,
+- Function<Vec3, Vec3> positions,
+- @Nullable AABB aabb,
+- BiConsumer<Vec3, List<? extends Entity>> order,
+- boolean currentEntity,
+- @Nullable String playerName,
+- @Nullable UUID entityUUID,
+- @Nullable EntityType<?> type,
+- boolean usesSelector
+- ) {
++ public EntitySelector(int maxResults, boolean includeEntities, boolean worldLimited, Predicate<Entity> predicate, MinMaxBounds.Doubles range, Function<Vec3, Vec3> positions, @Nullable AABB aabb, BiConsumer<Vec3, List<? extends Entity>> order, boolean currentEntity, @Nullable String playerName, @Nullable UUID entityUUID, @Nullable EntityType<?> type, boolean usesSelector) {
+ this.maxResults = maxResults;
+ this.includesEntities = includeEntities;
+ this.worldLimited = worldLimited;
+@@ -80,7 +67,7 @@
+ this.currentEntity = currentEntity;
+ this.playerName = playerName;
+ this.entityUUID = entityUUID;
+- this.type = (EntityTypeTest<Entity, ?>)(type == null ? ANY_TYPE : type);
++ this.type = (EntityTypeTest) (type == null ? EntitySelector.ANY_TYPE : type);
+ this.usesSelector = usesSelector;
+ }
+
+@@ -105,7 +92,7 @@
+ }
+
+ private void checkPermissions(CommandSourceStack source) throws CommandSyntaxException {
+- if (this.usesSelector && !source.hasPermission(2)) {
++ if (this.usesSelector && !source.hasPermission(2, "minecraft.command.selector")) { // CraftBukkit
+ throw EntityArgument.ERROR_SELECTORS_NOT_ALLOWED.create();
+ }
+ }
+@@ -113,17 +100,20 @@
+ public Entity findSingleEntity(CommandSourceStack source) throws CommandSyntaxException {
+ this.checkPermissions(source);
+ List<? extends Entity> list = this.findEntities(source);
++
+ if (list.isEmpty()) {
+ throw EntityArgument.NO_ENTITIES_FOUND.create();
+ } else if (list.size() > 1) {
+ throw EntityArgument.ERROR_NOT_SINGLE_ENTITY.create();
+ } else {
+- return list.get(0);
++ return (Entity) list.get(0);
+ }
+ }
+
+ public List<? extends Entity> findEntities(CommandSourceStack source) throws CommandSyntaxException {
+- return this.findEntitiesRaw(source).stream().filter(entity -> entity.getType().isEnabled(source.enabledFeatures())).toList();
++ return this.findEntitiesRaw(source).stream().filter((entity) -> {
++ return entity.getType().isEnabled(source.enabledFeatures());
++ }).toList();
+ }
+
+ private List<? extends Entity> findEntitiesRaw(CommandSourceStack source) throws CommandSyntaxException {
+@@ -131,113 +121,147 @@
+ if (!this.includesEntities) {
+ return this.findPlayers(source);
+ } else if (this.playerName != null) {
+- ServerPlayer playerByName = source.getServer().getPlayerList().getPlayerByName(this.playerName);
+- return (List<? extends Entity>)(playerByName == null ? Collections.emptyList() : Lists.newArrayList(playerByName));
++ ServerPlayer entityplayer = source.getServer().getPlayerList().getPlayerByName(this.playerName);
++
++ return (List) (entityplayer == null ? Collections.emptyList() : Lists.newArrayList(new ServerPlayer[]{entityplayer}));
+ } else if (this.entityUUID != null) {
+- for (ServerLevel serverLevel : source.getServer().getAllLevels()) {
+- Entity entity = serverLevel.getEntity(this.entityUUID);
+- if (entity != null) {
+- return Lists.newArrayList(entity);
++ Iterator iterator = source.getServer().getAllLevels().iterator();
++
++ Entity entity;
++
++ do {
++ if (!iterator.hasNext()) {
++ return Collections.emptyList();
+ }
+- }
+
+- return Collections.emptyList();
++ ServerLevel worldserver = (ServerLevel) iterator.next();
++
++ entity = worldserver.getEntity(this.entityUUID);
++ } while (entity == null);
++
++ return Lists.newArrayList(new Entity[]{entity});
+ } else {
+- Vec3 vec3 = this.position.apply(source.getPosition());
+- Predicate<Entity> predicate = this.getPredicate(vec3);
++ Vec3 vec3d = (Vec3) this.position.apply(source.getPosition());
++ Predicate<Entity> predicate = this.getPredicate(vec3d);
++
+ if (this.currentEntity) {
+- return (List<? extends Entity>)(source.getEntity() != null && predicate.test(source.getEntity())
+- ? Lists.newArrayList(source.getEntity())
+- : Collections.emptyList());
++ return (List) (source.getEntity() != null && predicate.test(source.getEntity()) ? Lists.newArrayList(new Entity[]{source.getEntity()}) : Collections.emptyList());
+ } else {
+ List<Entity> list = Lists.newArrayList();
++
+ if (this.isWorldLimited()) {
+- this.addEntities(list, source.getLevel(), vec3, predicate);
++ this.addEntities(list, source.getLevel(), vec3d, predicate);
+ } else {
+- for (ServerLevel serverLevel1 : source.getServer().getAllLevels()) {
+- this.addEntities(list, serverLevel1, vec3, predicate);
++ Iterator iterator1 = source.getServer().getAllLevels().iterator();
++
++ while (iterator1.hasNext()) {
++ ServerLevel worldserver1 = (ServerLevel) iterator1.next();
++
++ this.addEntities(list, worldserver1, vec3d, predicate);
+ }
+ }
+
+- return this.sortAndLimit(vec3, list);
++ return this.sortAndLimit(vec3d, list);
+ }
+ }
+ }
+
+ private void addEntities(List<Entity> result, ServerLevel level, Vec3 pos, Predicate<Entity> predicate) {
+- int resultLimit = this.getResultLimit();
+- if (result.size() < resultLimit) {
++ int i = this.getResultLimit();
++
++ if (result.size() < i) {
+ if (this.aabb != null) {
+- level.getEntities(this.type, this.aabb.move(pos), predicate, result, resultLimit);
++ level.getEntities(this.type, this.aabb.move(pos), predicate, result, i);
+ } else {
+- level.getEntities(this.type, predicate, result, resultLimit);
++ level.getEntities(this.type, predicate, result, i);
+ }
++
+ }
+ }
+
+ private int getResultLimit() {
+- return this.order == ORDER_ARBITRARY ? this.maxResults : Integer.MAX_VALUE;
++ return this.order == EntitySelector.ORDER_ARBITRARY ? this.maxResults : Integer.MAX_VALUE;
+ }
+
+ public ServerPlayer findSinglePlayer(CommandSourceStack source) throws CommandSyntaxException {
+ this.checkPermissions(source);
+ List<ServerPlayer> list = this.findPlayers(source);
++
+ if (list.size() != 1) {
+ throw EntityArgument.NO_PLAYERS_FOUND.create();
+ } else {
+- return list.get(0);
++ return (ServerPlayer) list.get(0);
+ }
+ }
+
+ public List<ServerPlayer> findPlayers(CommandSourceStack source) throws CommandSyntaxException {
+ this.checkPermissions(source);
++ ServerPlayer entityplayer;
++
+ if (this.playerName != null) {
+- ServerPlayer playerByName = source.getServer().getPlayerList().getPlayerByName(this.playerName);
+- return (List<ServerPlayer>)(playerByName == null ? Collections.emptyList() : Lists.newArrayList(playerByName));
++ entityplayer = source.getServer().getPlayerList().getPlayerByName(this.playerName);
++ return (List) (entityplayer == null ? Collections.emptyList() : Lists.newArrayList(new ServerPlayer[]{entityplayer}));
+ } else if (this.entityUUID != null) {
+- ServerPlayer playerByName = source.getServer().getPlayerList().getPlayer(this.entityUUID);
+- return (List<ServerPlayer>)(playerByName == null ? Collections.emptyList() : Lists.newArrayList(playerByName));
++ entityplayer = source.getServer().getPlayerList().getPlayer(this.entityUUID);
++ return (List) (entityplayer == null ? Collections.emptyList() : Lists.newArrayList(new ServerPlayer[]{entityplayer}));
+ } else {
+- Vec3 vec3 = this.position.apply(source.getPosition());
+- Predicate<Entity> predicate = this.getPredicate(vec3);
++ Vec3 vec3d = (Vec3) this.position.apply(source.getPosition());
++ Predicate<Entity> predicate = this.getPredicate(vec3d);
++
+ if (this.currentEntity) {
+- if (source.getEntity() instanceof ServerPlayer serverPlayer && predicate.test(serverPlayer)) {
+- return Lists.newArrayList(serverPlayer);
++ Entity entity = source.getEntity();
++
++ if (entity instanceof ServerPlayer) {
++ ServerPlayer entityplayer1 = (ServerPlayer) entity;
++
++ if (predicate.test(entityplayer1)) {
++ return Lists.newArrayList(new ServerPlayer[]{entityplayer1});
++ }
+ }
+
+ return Collections.emptyList();
+ } else {
+- int resultLimit = this.getResultLimit();
+- List<ServerPlayer> players;
++ int i = this.getResultLimit();
++ Object object;
++
+ if (this.isWorldLimited()) {
+- players = source.getLevel().getPlayers(predicate, resultLimit);
++ object = source.getLevel().getPlayers(predicate, i);
+ } else {
+- players = Lists.newArrayList();
++ object = Lists.newArrayList();
++ Iterator iterator = source.getServer().getPlayerList().getPlayers().iterator();
+
+- for (ServerPlayer serverPlayer1 : source.getServer().getPlayerList().getPlayers()) {
+- if (predicate.test(serverPlayer1)) {
+- players.add(serverPlayer1);
+- if (players.size() >= resultLimit) {
+- return players;
++ while (iterator.hasNext()) {
++ ServerPlayer entityplayer2 = (ServerPlayer) iterator.next();
++
++ if (predicate.test(entityplayer2)) {
++ ((List) object).add(entityplayer2);
++ if (((List) object).size() >= i) {
++ return (List) object;
+ }
+ }
+ }
+ }
+
+- return this.sortAndLimit(vec3, players);
++ return this.sortAndLimit(vec3d, (List) object);
+ }
+ }
+ }
+
+ private Predicate<Entity> getPredicate(Vec3 pos) {
+ Predicate<Entity> predicate = this.predicate;
++
+ if (this.aabb != null) {
+- AABB aABB = this.aabb.move(pos);
+- predicate = predicate.and(entity -> aABB.intersects(entity.getBoundingBox()));
++ AABB axisalignedbb = this.aabb.move(pos);
++
++ predicate = predicate.and((entity) -> {
++ return axisalignedbb.intersects(entity.getBoundingBox());
++ });
+ }
+
+ if (!this.range.isAny()) {
+- predicate = predicate.and(entity -> this.range.matchesSqr(entity.distanceToSqr(pos)));
++ predicate = predicate.and((entity) -> {
++ return this.range.matchesSqr(entity.distanceToSqr(pos));
++ });
+ }
+
+ return predicate;
diff --git a/patch-remap/mache-vineflower/net/minecraft/commands/arguments/selector/EntitySelectorParser.java.patch b/patch-remap/mache-vineflower/net/minecraft/commands/arguments/selector/EntitySelectorParser.java.patch
new file mode 100644
index 0000000000..174e410812
--- /dev/null
+++ b/patch-remap/mache-vineflower/net/minecraft/commands/arguments/selector/EntitySelectorParser.java.patch
@@ -0,0 +1,449 @@
+--- a/net/minecraft/commands/arguments/selector/EntitySelectorParser.java
++++ b/net/minecraft/commands/arguments/selector/EntitySelectorParser.java
+@@ -30,6 +30,7 @@
+ import net.minecraft.world.phys.Vec3;
+
+ public class EntitySelectorParser {
++
+ public static final char SYNTAX_SELECTOR_START = '@';
+ private static final char SYNTAX_OPTIONS_START = '[';
+ private static final char SYNTAX_OPTIONS_END = ']';
+@@ -42,41 +43,39 @@
+ private static final char SELECTOR_RANDOM_PLAYERS = 'r';
+ private static final char SELECTOR_CURRENT_ENTITY = 's';
+ private static final char SELECTOR_ALL_ENTITIES = 'e';
+- public static final SimpleCommandExceptionType ERROR_INVALID_NAME_OR_UUID = new SimpleCommandExceptionType(
+- Component.translatable("argument.entity.invalid")
+- );
+- public static final DynamicCommandExceptionType ERROR_UNKNOWN_SELECTOR_TYPE = new DynamicCommandExceptionType(
+- type -> Component.translatableEscape("argument.entity.selector.unknown", type)
+- );
+- public static final SimpleCommandExceptionType ERROR_SELECTORS_NOT_ALLOWED = new SimpleCommandExceptionType(
+- Component.translatable("argument.entity.selector.not_allowed")
+- );
+- public static final SimpleCommandExceptionType ERROR_MISSING_SELECTOR_TYPE = new SimpleCommandExceptionType(
+- Component.translatable("argument.entity.selector.missing")
+- );
+- public static final SimpleCommandExceptionType ERROR_EXPECTED_END_OF_OPTIONS = new SimpleCommandExceptionType(
+- Component.translatable("argument.entity.options.unterminated")
+- );
+- public static final DynamicCommandExceptionType ERROR_EXPECTED_OPTION_VALUE = new DynamicCommandExceptionType(
+- value -> Component.translatableEscape("argument.entity.options.valueless", value)
+- );
+- public static final BiConsumer<Vec3, List<? extends Entity>> ORDER_NEAREST = (pos, entities) -> entities.sort(
+- (entity1, entity2) -> Doubles.compare(entity1.distanceToSqr(pos), entity2.distanceToSqr(pos))
+- );
+- public static final BiConsumer<Vec3, List<? extends Entity>> ORDER_FURTHEST = (pos, entities) -> entities.sort(
+- (entity1, entity2) -> Doubles.compare(entity2.distanceToSqr(pos), entity1.distanceToSqr(pos))
+- );
+- public static final BiConsumer<Vec3, List<? extends Entity>> ORDER_RANDOM = (pos, entities) -> Collections.shuffle(entities);
+- public static final BiFunction<SuggestionsBuilder, Consumer<SuggestionsBuilder>, CompletableFuture<Suggestions>> SUGGEST_NOTHING = (builder, consumer) -> builder.buildFuture(
+-
+- );
++ public static final SimpleCommandExceptionType ERROR_INVALID_NAME_OR_UUID = new SimpleCommandExceptionType(Component.translatable("argument.entity.invalid"));
++ public static final DynamicCommandExceptionType ERROR_UNKNOWN_SELECTOR_TYPE = new DynamicCommandExceptionType((object) -> {
++ return Component.translatableEscape("argument.entity.selector.unknown", object);
++ });
++ public static final SimpleCommandExceptionType ERROR_SELECTORS_NOT_ALLOWED = new SimpleCommandExceptionType(Component.translatable("argument.entity.selector.not_allowed"));
++ public static final SimpleCommandExceptionType ERROR_MISSING_SELECTOR_TYPE = new SimpleCommandExceptionType(Component.translatable("argument.entity.selector.missing"));
++ public static final SimpleCommandExceptionType ERROR_EXPECTED_END_OF_OPTIONS = new SimpleCommandExceptionType(Component.translatable("argument.entity.options.unterminated"));
++ public static final DynamicCommandExceptionType ERROR_EXPECTED_OPTION_VALUE = new DynamicCommandExceptionType((object) -> {
++ return Component.translatableEscape("argument.entity.options.valueless", object);
++ });
++ public static final BiConsumer<Vec3, List<? extends Entity>> ORDER_NEAREST = (vec3d, list) -> {
++ list.sort((entity, entity1) -> {
++ return Doubles.compare(entity.distanceToSqr(vec3d), entity1.distanceToSqr(vec3d));
++ });
++ };
++ public static final BiConsumer<Vec3, List<? extends Entity>> ORDER_FURTHEST = (vec3d, list) -> {
++ list.sort((entity, entity1) -> {
++ return Doubles.compare(entity1.distanceToSqr(vec3d), entity.distanceToSqr(vec3d));
++ });
++ };
++ public static final BiConsumer<Vec3, List<? extends Entity>> ORDER_RANDOM = (vec3d, list) -> {
++ Collections.shuffle(list);
++ };
++ public static final BiFunction<SuggestionsBuilder, Consumer<SuggestionsBuilder>, CompletableFuture<Suggestions>> SUGGEST_NOTHING = (suggestionsbuilder, consumer) -> {
++ return suggestionsbuilder.buildFuture();
++ };
+ private final StringReader reader;
+ private final boolean allowSelectors;
+ private int maxResults;
+ private boolean includesEntities;
+ private boolean worldLimited;
+- private MinMaxBounds.Doubles distance = MinMaxBounds.Doubles.ANY;
+- private MinMaxBounds.Ints level = MinMaxBounds.Ints.ANY;
++ private MinMaxBounds.Doubles distance;
++ private MinMaxBounds.Ints level;
+ @Nullable
+ private Double x;
+ @Nullable
+@@ -89,17 +88,17 @@
+ private Double deltaY;
+ @Nullable
+ private Double deltaZ;
+- private WrappedMinMaxBounds rotX = WrappedMinMaxBounds.ANY;
+- private WrappedMinMaxBounds rotY = WrappedMinMaxBounds.ANY;
+- private Predicate<Entity> predicate = entity -> true;
+- private BiConsumer<Vec3, List<? extends Entity>> order = EntitySelector.ORDER_ARBITRARY;
++ private WrappedMinMaxBounds rotX;
++ private WrappedMinMaxBounds rotY;
++ private Predicate<Entity> predicate;
++ private BiConsumer<Vec3, List<? extends Entity>> order;
+ private boolean currentEntity;
+ @Nullable
+ private String playerName;
+ private int startPosition;
+ @Nullable
+ private UUID entityUUID;
+- private BiFunction<SuggestionsBuilder, Consumer<SuggestionsBuilder>, CompletableFuture<Suggestions>> suggestions = SUGGEST_NOTHING;
++ private BiFunction<SuggestionsBuilder, Consumer<SuggestionsBuilder>, CompletableFuture<Suggestions>> suggestions;
+ private boolean hasNameEquals;
+ private boolean hasNameNotEquals;
+ private boolean isLimited;
+@@ -120,58 +119,61 @@
+ }
+
+ public EntitySelectorParser(StringReader reader, boolean allowSelectors) {
++ this.distance = MinMaxBounds.Doubles.ANY;
++ this.level = MinMaxBounds.Ints.ANY;
++ this.rotX = WrappedMinMaxBounds.ANY;
++ this.rotY = WrappedMinMaxBounds.ANY;
++ this.predicate = (entity) -> {
++ return true;
++ };
++ this.order = EntitySelector.ORDER_ARBITRARY;
++ this.suggestions = EntitySelectorParser.SUGGEST_NOTHING;
+ this.reader = reader;
+ this.allowSelectors = allowSelectors;
+ }
+
+ public EntitySelector getSelector() {
+- AABB aABB;
++ AABB axisalignedbb;
++
+ if (this.deltaX == null && this.deltaY == null && this.deltaZ == null) {
+ if (this.distance.max().isPresent()) {
+- double d = this.distance.max().get();
+- aABB = new AABB(-d, -d, -d, d + 1.0, d + 1.0, d + 1.0);
++ double d0 = (Double) this.distance.max().get();
++
++ axisalignedbb = new AABB(-d0, -d0, -d0, d0 + 1.0D, d0 + 1.0D, d0 + 1.0D);
+ } else {
+- aABB = null;
++ axisalignedbb = null;
+ }
+ } else {
+- aABB = this.createAabb(this.deltaX == null ? 0.0 : this.deltaX, this.deltaY == null ? 0.0 : this.deltaY, this.deltaZ == null ? 0.0 : this.deltaZ);
++ axisalignedbb = this.createAabb(this.deltaX == null ? 0.0D : this.deltaX, this.deltaY == null ? 0.0D : this.deltaY, this.deltaZ == null ? 0.0D : this.deltaZ);
+ }
+
+- Function<Vec3, Vec3> function;
++ Function<Vec3, Vec3> function; // CraftBukkit - decompile error
++
+ if (this.x == null && this.y == null && this.z == null) {
+- function = vec -> vec;
++ function = (vec3d) -> {
++ return vec3d;
++ };
+ } else {
+- function = vec -> new Vec3(this.x == null ? vec.x : this.x, this.y == null ? vec.y : this.y, this.z == null ? vec.z : this.z);
++ function = (vec3d) -> {
++ return new Vec3(this.x == null ? vec3d.x : this.x, this.y == null ? vec3d.y : this.y, this.z == null ? vec3d.z : this.z);
++ };
+ }
+
+- return new EntitySelector(
+- this.maxResults,
+- this.includesEntities,
+- this.worldLimited,
+- this.predicate,
+- this.distance,
+- function,
+- aABB,
+- this.order,
+- this.currentEntity,
+- this.playerName,
+- this.entityUUID,
+- this.type,
+- this.usesSelectors
+- );
++ return new EntitySelector(this.maxResults, this.includesEntities, this.worldLimited, this.predicate, this.distance, function, axisalignedbb, this.order, this.currentEntity, this.playerName, this.entityUUID, this.type, this.usesSelectors);
+ }
+
+- private AABB createAabb(double sizeX, double sizeY, double sizeZ) {
+- boolean flag = sizeX < 0.0;
+- boolean flag1 = sizeY < 0.0;
+- boolean flag2 = sizeZ < 0.0;
+- double d = flag ? sizeX : 0.0;
+- double d1 = flag1 ? sizeY : 0.0;
+- double d2 = flag2 ? sizeZ : 0.0;
+- double d3 = (flag ? 0.0 : sizeX) + 1.0;
+- double d4 = (flag1 ? 0.0 : sizeY) + 1.0;
+- double d5 = (flag2 ? 0.0 : sizeZ) + 1.0;
+- return new AABB(d, d1, d2, d3, d4, d5);
++ private AABB createAabb(double sizeX, double d1, double sizeY) {
++ boolean flag = sizeX < 0.0D;
++ boolean flag1 = d1 < 0.0D;
++ boolean flag2 = sizeY < 0.0D;
++ double d3 = flag ? sizeX : 0.0D;
++ double d4 = flag1 ? d1 : 0.0D;
++ double d5 = flag2 ? sizeY : 0.0D;
++ double d6 = (flag ? 0.0D : sizeX) + 1.0D;
++ double d7 = (flag1 ? 0.0D : d1) + 1.0D;
++ double d8 = (flag2 ? 0.0D : sizeY) + 1.0D;
++
++ return new AABB(d3, d4, d5, d6, d7, d8);
+ }
+
+ private void finalizePredicates() {
+@@ -184,50 +186,58 @@
+ }
+
+ if (!this.level.isAny()) {
+- this.predicate = this.predicate.and(entity -> entity instanceof ServerPlayer && this.level.matches(((ServerPlayer)entity).experienceLevel));
++ this.predicate = this.predicate.and((entity) -> {
++ return !(entity instanceof ServerPlayer) ? false : this.level.matches(((ServerPlayer) entity).experienceLevel);
++ });
+ }
++
+ }
+
+ private Predicate<Entity> createRotationPredicate(WrappedMinMaxBounds angleBounds, ToDoubleFunction<Entity> angleFunction) {
+- double d = (double)Mth.wrapDegrees(angleBounds.min() == null ? 0.0F : angleBounds.min());
+- double d1 = (double)Mth.wrapDegrees(angleBounds.max() == null ? 359.0F : angleBounds.max());
+- return entity -> {
+- double d3 = Mth.wrapDegrees(angleFunction.applyAsDouble(entity));
+- return d > d1 ? d3 >= d || d3 <= d1 : d3 >= d && d3 <= d1;
++ double d0 = (double) Mth.wrapDegrees(angleBounds.min() == null ? 0.0F : angleBounds.min());
++ double d1 = (double) Mth.wrapDegrees(angleBounds.max() == null ? 359.0F : angleBounds.max());
++
++ return (entity) -> {
++ double d2 = Mth.wrapDegrees(angleFunction.applyAsDouble(entity));
++
++ return d0 > d1 ? d2 >= d0 || d2 <= d1 : d2 >= d0 && d2 <= d1;
+ };
+ }
+
+- protected void parseSelector() throws CommandSyntaxException {
+- this.usesSelectors = true;
++ // CraftBukkit start
++ protected void parseSelector(boolean overridePermissions) throws CommandSyntaxException {
++ this.usesSelectors = !overridePermissions;
++ // CraftBukkit end
+ this.suggestions = this::suggestSelector;
+ if (!this.reader.canRead()) {
+- throw ERROR_MISSING_SELECTOR_TYPE.createWithContext(this.reader);
++ throw EntitySelectorParser.ERROR_MISSING_SELECTOR_TYPE.createWithContext(this.reader);
+ } else {
+- int cursor = this.reader.getCursor();
+- char c = this.reader.read();
+- if (c == 'p') {
++ int i = this.reader.getCursor();
++ char c0 = this.reader.read();
++
++ if (c0 == 'p') {
+ this.maxResults = 1;
+ this.includesEntities = false;
+- this.order = ORDER_NEAREST;
++ this.order = EntitySelectorParser.ORDER_NEAREST;
+ this.limitToType(EntityType.PLAYER);
+- } else if (c == 'a') {
++ } else if (c0 == 'a') {
+ this.maxResults = Integer.MAX_VALUE;
+ this.includesEntities = false;
+ this.order = EntitySelector.ORDER_ARBITRARY;
+ this.limitToType(EntityType.PLAYER);
+- } else if (c == 'r') {
++ } else if (c0 == 'r') {
+ this.maxResults = 1;
+ this.includesEntities = false;
+- this.order = ORDER_RANDOM;
++ this.order = EntitySelectorParser.ORDER_RANDOM;
+ this.limitToType(EntityType.PLAYER);
+- } else if (c == 's') {
++ } else if (c0 == 's') {
+ this.maxResults = 1;
+ this.includesEntities = true;
+ this.currentEntity = true;
+ } else {
+- if (c != 'e') {
+- this.reader.setCursor(cursor);
+- throw ERROR_UNKNOWN_SELECTOR_TYPE.createWithContext(this.reader, "@" + c);
++ if (c0 != 'e') {
++ this.reader.setCursor(i);
++ throw EntitySelectorParser.ERROR_UNKNOWN_SELECTOR_TYPE.createWithContext(this.reader, "@" + String.valueOf(c0));
+ }
+
+ this.maxResults = Integer.MAX_VALUE;
+@@ -242,6 +252,7 @@
+ this.suggestions = this::suggestOptionsKeyOrClose;
+ this.parseOptions();
+ }
++
+ }
+ }
+
+@@ -250,20 +261,20 @@
+ this.suggestions = this::suggestName;
+ }
+
+- int cursor = this.reader.getCursor();
+- String string = this.reader.readString();
++ int i = this.reader.getCursor();
++ String s = this.reader.readString();
+
+ try {
+- this.entityUUID = UUID.fromString(string);
++ this.entityUUID = UUID.fromString(s);
+ this.includesEntities = true;
+- } catch (IllegalArgumentException var4) {
+- if (string.isEmpty() || string.length() > 16) {
+- this.reader.setCursor(cursor);
+- throw ERROR_INVALID_NAME_OR_UUID.createWithContext(this.reader);
++ } catch (IllegalArgumentException illegalargumentexception) {
++ if (s.isEmpty() || s.length() > 16) {
++ this.reader.setCursor(i);
++ throw EntitySelectorParser.ERROR_INVALID_NAME_OR_UUID.createWithContext(this.reader);
+ }
+
+ this.includesEntities = false;
+- this.playerName = string;
++ this.playerName = s;
+ }
+
+ this.maxResults = 1;
+@@ -273,41 +284,47 @@
+ this.suggestions = this::suggestOptionsKey;
+ this.reader.skipWhitespace();
+
+- while (this.reader.canRead() && this.reader.peek() != ']') {
+- this.reader.skipWhitespace();
+- int cursor = this.reader.getCursor();
+- String string = this.reader.readString();
+- EntitySelectorOptions.Modifier modifier = EntitySelectorOptions.get(this, string, cursor);
+- this.reader.skipWhitespace();
+- if (!this.reader.canRead() || this.reader.peek() != '=') {
+- this.reader.setCursor(cursor);
+- throw ERROR_EXPECTED_OPTION_VALUE.createWithContext(this.reader, string);
+- }
++ while (true) {
++ if (this.reader.canRead() && this.reader.peek() != ']') {
++ this.reader.skipWhitespace();
++ int i = this.reader.getCursor();
++ String s = this.reader.readString();
++ EntitySelectorOptions.Modifier playerselector_a = EntitySelectorOptions.get(this, s, i);
+
+- this.reader.skip();
+- this.reader.skipWhitespace();
+- this.suggestions = SUGGEST_NOTHING;
+- modifier.handle(this);
+- this.reader.skipWhitespace();
+- this.suggestions = this::suggestOptionsNextOrClose;
+- if (this.reader.canRead()) {
+- if (this.reader.peek() != ',') {
+- if (this.reader.peek() != ']') {
+- throw ERROR_EXPECTED_END_OF_OPTIONS.createWithContext(this.reader);
+- }
+- break;
++ this.reader.skipWhitespace();
++ if (!this.reader.canRead() || this.reader.peek() != '=') {
++ this.reader.setCursor(i);
++ throw EntitySelectorParser.ERROR_EXPECTED_OPTION_VALUE.createWithContext(this.reader, s);
+ }
+
+ this.reader.skip();
+- this.suggestions = this::suggestOptionsKey;
++ this.reader.skipWhitespace();
++ this.suggestions = EntitySelectorParser.SUGGEST_NOTHING;
++ playerselector_a.handle(this);
++ this.reader.skipWhitespace();
++ this.suggestions = this::suggestOptionsNextOrClose;
++ if (!this.reader.canRead()) {
++ continue;
++ }
++
++ if (this.reader.peek() == ',') {
++ this.reader.skip();
++ this.suggestions = this::suggestOptionsKey;
++ continue;
++ }
++
++ if (this.reader.peek() != ']') {
++ throw EntitySelectorParser.ERROR_EXPECTED_END_OF_OPTIONS.createWithContext(this.reader);
++ }
+ }
+- }
+
+- if (this.reader.canRead()) {
+- this.reader.skip();
+- this.suggestions = SUGGEST_NOTHING;
+- } else {
+- throw ERROR_EXPECTED_END_OF_OPTIONS.createWithContext(this.reader);
++ if (this.reader.canRead()) {
++ this.reader.skip();
++ this.suggestions = EntitySelectorParser.SUGGEST_NOTHING;
++ return;
++ }
++
++ throw EntitySelectorParser.ERROR_EXPECTED_END_OF_OPTIONS.createWithContext(this.reader);
+ }
+ }
+
+@@ -448,15 +465,21 @@
+ }
+
+ public EntitySelector parse() throws CommandSyntaxException {
++ // CraftBukkit start
++ return parse(false);
++ }
++
++ public EntitySelector parse(boolean overridePermissions) throws CommandSyntaxException {
++ // CraftBukkit end
+ this.startPosition = this.reader.getCursor();
+ this.suggestions = this::suggestNameOrSelector;
+ if (this.reader.canRead() && this.reader.peek() == '@') {
+ if (!this.allowSelectors) {
+- throw ERROR_SELECTORS_NOT_ALLOWED.createWithContext(this.reader);
++ throw EntitySelectorParser.ERROR_SELECTORS_NOT_ALLOWED.createWithContext(this.reader);
+ }
+
+ this.reader.skip();
+- this.parseSelector();
++ this.parseSelector(overridePermissions); // CraftBukkit
+ } else {
+ this.parseNameOrUUID();
+ }
+@@ -483,15 +506,17 @@
+ }
+
+ private CompletableFuture<Suggestions> suggestName(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
+- SuggestionsBuilder suggestionsBuilder = builder.createOffset(this.startPosition);
+- consumer.accept(suggestionsBuilder);
+- return builder.add(suggestionsBuilder).buildFuture();
++ SuggestionsBuilder suggestionsbuilder1 = builder.createOffset(this.startPosition);
++
++ consumer.accept(suggestionsbuilder1);
++ return builder.add(suggestionsbuilder1).buildFuture();
+ }
+
+ private CompletableFuture<Suggestions> suggestSelector(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
+- SuggestionsBuilder suggestionsBuilder = builder.createOffset(builder.getStart() - 1);
+- fillSelectorSuggestions(suggestionsBuilder);
+- builder.add(suggestionsBuilder);
++ SuggestionsBuilder suggestionsbuilder1 = builder.createOffset(builder.getStart() - 1);
++
++ fillSelectorSuggestions(suggestionsbuilder1);
++ builder.add(suggestionsbuilder1);
+ return builder.buildFuture();
+ }
+
+@@ -531,7 +556,7 @@
+ }
+
+ public CompletableFuture<Suggestions> fillSuggestions(SuggestionsBuilder builder, Consumer<SuggestionsBuilder> consumer) {
+- return this.suggestions.apply(builder.createOffset(this.reader.getCursor()), consumer);
++ return (CompletableFuture) this.suggestions.apply(builder.createOffset(this.reader.getCursor()), consumer);
+ }
+
+ public boolean hasNameEquals() {