From 29785297b5f7db6a99a48435b8814c9ff35e6d52 Mon Sep 17 00:00:00 2001
From: Jason <jasonpenilla2@me.com>
Date: Fri, 7 May 2021 16:12:03 -0700
Subject: [PATCH] Allow for Component suggestion tooltips in
 AsyncTabCompleteEvent (#5504)

---
 ...ent-suggestion-tooltips-in-AsyncTabC.patch | 407 ++++++++++++++++++
 ...ent-suggestion-tooltips-in-AsyncTabC.patch | 132 ++++++
 ...ab-completions-for-brigadier-comman.patch} |  81 ++--
 ...temConsumeEvent-cancelling-properly.patch} |   0
 ...patch => 0703-Add-bypass-host-check.patch} |   0
 ...on-t-throw-when-loading-invalid-TEs.patch} |   0
 ...0705-Set-area-affect-cloud-rotation.patch} |   0
 ...add-isDeeplySleeping-to-HumanEntity.patch} |   0
 ...ting-give-items-on-item-drop-cancel.patch} |   0
 ...add-consumeFuel-to-FurnaceBurnEvent.patch} |   0
 ...-set-drop-chance-to-EntityEquipment.patch} |   0
 ...ix-PigZombieAngerEvent-cancellation.patch} |   0
 ...-checkReach-check-for-Shulker-boxes.patch} |   0
 ...ix-PlayerItemHeldEvent-firing-twice.patch} |   4 +-
 ... => 0713-Added-PlayerDeepSleepEvent.patch} |   0
 ...ld-API.patch => 0714-More-World-API.patch} |   0
 ... 0715-Added-PlayerBedFailEnterEvent.patch} |   0
 ...-to-convert-between-Component-and-B.patch} |   0
 ...n-acting-as-a-bed-respawn-from-the-.patch} |   0
 ...-RespawnFlags-to-PlayerRespawnEvent.patch} |   4 +-
 ...acon-activation-deactivation-events.patch} |   0
 ...dd-Channel-initialization-listeners.patch} |   0
 ...mands-if-tab-completion-is-disabled.patch} |   0
 ...> 0722-Add-more-WanderingTrader-API.patch} |   0
 24 files changed, 573 insertions(+), 55 deletions(-)
 create mode 100644 Spigot-API-Patches/0295-Allow-for-Component-suggestion-tooltips-in-AsyncTabC.patch
 create mode 100644 Spigot-Server-Patches/0700-Allow-for-Component-suggestion-tooltips-in-AsyncTabC.patch
 rename Spigot-Server-Patches/{0700-Enhance-console-tab-completions-for-brigadier-comman.patch => 0701-Enhance-console-tab-completions-for-brigadier-comman.patch} (86%)
 rename Spigot-Server-Patches/{0701-Fix-PlayerItemConsumeEvent-cancelling-properly.patch => 0702-Fix-PlayerItemConsumeEvent-cancelling-properly.patch} (100%)
 rename Spigot-Server-Patches/{0702-Add-bypass-host-check.patch => 0703-Add-bypass-host-check.patch} (100%)
 rename Spigot-Server-Patches/{0703-don-t-throw-when-loading-invalid-TEs.patch => 0704-don-t-throw-when-loading-invalid-TEs.patch} (100%)
 rename Spigot-Server-Patches/{0704-Set-area-affect-cloud-rotation.patch => 0705-Set-area-affect-cloud-rotation.patch} (100%)
 rename Spigot-Server-Patches/{0705-add-isDeeplySleeping-to-HumanEntity.patch => 0706-add-isDeeplySleeping-to-HumanEntity.patch} (100%)
 rename Spigot-Server-Patches/{0706-Fix-duplicating-give-items-on-item-drop-cancel.patch => 0707-Fix-duplicating-give-items-on-item-drop-cancel.patch} (100%)
 rename Spigot-Server-Patches/{0707-add-consumeFuel-to-FurnaceBurnEvent.patch => 0708-add-consumeFuel-to-FurnaceBurnEvent.patch} (100%)
 rename Spigot-Server-Patches/{0708-add-get-set-drop-chance-to-EntityEquipment.patch => 0709-add-get-set-drop-chance-to-EntityEquipment.patch} (100%)
 rename Spigot-Server-Patches/{0709-fix-PigZombieAngerEvent-cancellation.patch => 0710-fix-PigZombieAngerEvent-cancellation.patch} (100%)
 rename Spigot-Server-Patches/{0710-Fix-checkReach-check-for-Shulker-boxes.patch => 0711-Fix-checkReach-check-for-Shulker-boxes.patch} (100%)
 rename Spigot-Server-Patches/{0711-fix-PlayerItemHeldEvent-firing-twice.patch => 0712-fix-PlayerItemHeldEvent-firing-twice.patch} (92%)
 rename Spigot-Server-Patches/{0712-Added-PlayerDeepSleepEvent.patch => 0713-Added-PlayerDeepSleepEvent.patch} (100%)
 rename Spigot-Server-Patches/{0713-More-World-API.patch => 0714-More-World-API.patch} (100%)
 rename Spigot-Server-Patches/{0714-Added-PlayerBedFailEnterEvent.patch => 0715-Added-PlayerBedFailEnterEvent.patch} (100%)
 rename Spigot-Server-Patches/{0715-Implement-methods-to-convert-between-Component-and-B.patch => 0716-Implement-methods-to-convert-between-Component-and-B.patch} (100%)
 rename Spigot-Server-Patches/{0716-Fix-anchor-respawn-acting-as-a-bed-respawn-from-the-.patch => 0717-Fix-anchor-respawn-acting-as-a-bed-respawn-from-the-.patch} (100%)
 rename Spigot-Server-Patches/{0717-add-RespawnFlags-to-PlayerRespawnEvent.patch => 0718-add-RespawnFlags-to-PlayerRespawnEvent.patch} (95%)
 rename Spigot-Server-Patches/{0718-Introduce-beacon-activation-deactivation-events.patch => 0719-Introduce-beacon-activation-deactivation-events.patch} (100%)
 rename Spigot-Server-Patches/{0719-Add-Channel-initialization-listeners.patch => 0720-Add-Channel-initialization-listeners.patch} (100%)
 rename Spigot-Server-Patches/{0720-Send-empty-commands-if-tab-completion-is-disabled.patch => 0721-Send-empty-commands-if-tab-completion-is-disabled.patch} (100%)
 rename Spigot-Server-Patches/{0721-Add-more-WanderingTrader-API.patch => 0722-Add-more-WanderingTrader-API.patch} (100%)

diff --git a/Spigot-API-Patches/0295-Allow-for-Component-suggestion-tooltips-in-AsyncTabC.patch b/Spigot-API-Patches/0295-Allow-for-Component-suggestion-tooltips-in-AsyncTabC.patch
new file mode 100644
index 0000000000..9908089e18
--- /dev/null
+++ b/Spigot-API-Patches/0295-Allow-for-Component-suggestion-tooltips-in-AsyncTabC.patch
@@ -0,0 +1,407 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: jmp <jasonpenilla2@me.com>
+Date: Thu, 1 Apr 2021 00:34:41 -0700
+Subject: [PATCH] Allow for Component suggestion tooltips in
+ AsyncTabCompleteEvent
+
+
+diff --git a/src/main/java/com/destroystokyo/paper/event/server/AsyncTabCompleteEvent.java b/src/main/java/com/destroystokyo/paper/event/server/AsyncTabCompleteEvent.java
+index 619ed37169c126a8c75d02699a04728bac49d10d..31c90ab0710020a2ff104b5cb8af604f3d682f31 100644
+--- a/src/main/java/com/destroystokyo/paper/event/server/AsyncTabCompleteEvent.java
++++ b/src/main/java/com/destroystokyo/paper/event/server/AsyncTabCompleteEvent.java
+@@ -24,6 +24,11 @@
+ package com.destroystokyo.paper.event.server;
+ 
+ import com.google.common.collect.ImmutableList;
++import io.papermc.paper.util.TransformingRandomAccessList;
++import net.kyori.adventure.text.Component;
++import net.kyori.examination.Examinable;
++import net.kyori.examination.ExaminableProperty;
++import net.kyori.examination.string.StringExaminer;
+ import org.apache.commons.lang.Validate;
+ import org.bukkit.Location;
+ import org.bukkit.command.Command;
+@@ -34,6 +39,7 @@ import org.bukkit.event.HandlerList;
+ 
+ import java.util.ArrayList;
+ import java.util.List;
++import java.util.stream.Stream;
+ import org.jetbrains.annotations.NotNull;
+ import org.jetbrains.annotations.Nullable;
+ 
+@@ -48,15 +54,29 @@ public class AsyncTabCompleteEvent extends Event implements Cancellable {
+     private final boolean isCommand;
+     @Nullable
+     private final Location loc;
+-    @NotNull private List<String> completions;
++    private final List<Completion> completions = new ArrayList<>();
++    private final List<String> stringCompletions = new TransformingRandomAccessList<>(
++        this.completions,
++        Completion::suggestion,
++        Completion::completion
++    );
+     private boolean cancelled;
+     private boolean handled = false;
+     private boolean fireSyncHandler = true;
+ 
++    public AsyncTabCompleteEvent(@NotNull CommandSender sender, @NotNull String buffer, boolean isCommand, @Nullable Location loc) {
++        super(true);
++        this.sender = sender;
++        this.buffer = buffer;
++        this.isCommand = isCommand;
++        this.loc = loc;
++    }
++
++    @Deprecated
+     public AsyncTabCompleteEvent(@NotNull CommandSender sender, @NotNull List<String> completions, @NotNull String buffer, boolean isCommand, @Nullable Location loc) {
+         super(true);
+         this.sender = sender;
+-        this.completions = completions;
++        this.completions.addAll(fromStrings(completions));
+         this.buffer = buffer;
+         this.isCommand = isCommand;
+         this.loc = loc;
+@@ -84,7 +104,7 @@ public class AsyncTabCompleteEvent extends Event implements Cancellable {
+      */
+     @NotNull
+     public List<String> getCompletions() {
+-        return completions;
++        return this.stringCompletions;
+     }
+ 
+     /**
+@@ -98,8 +118,42 @@ public class AsyncTabCompleteEvent extends Event implements Cancellable {
+      * @param completions the new completions
+      */
+     public void setCompletions(@NotNull List<String> completions) {
++        if (completions == this.stringCompletions) {
++            return;
++        }
+         Validate.notNull(completions);
+-        this.completions = new ArrayList<>(completions);
++        this.completions.clear();
++        this.completions.addAll(fromStrings(completions));
++    }
++
++    /**
++     * The list of {@link Completion completions} which will be offered to the sender, in order.
++     * This list is mutable and reflects what will be offered.
++     * <p>
++     * If this collection is not empty after the event is fired, then
++     * the standard process of calling {@link Command#tabComplete(CommandSender, String, String[])}
++     * or current player names will not be called.
++     *
++     * @return a list of offered completions
++     */
++    public @NotNull List<@NotNull Completion> completions() {
++        return this.completions;
++    }
++
++    /**
++     * Set the {@link Completion completions} offered, overriding any already set.
++     * If this collection is not empty after the event is fired, then
++     * the standard process of calling {@link Command#tabComplete(CommandSender, String, String[])}
++     * or current player names will not be called.
++     * <p>
++     * The passed collection will be cloned to a new List. You must call {{@link #completions()}} to mutate from here
++     *
++     * @param newCompletions the new completions
++     */
++    public void completions(final @NotNull List<@NotNull Completion> newCompletions) {
++        Validate.notNull(newCompletions, "new completions");
++        this.completions.clear();
++        this.completions.addAll(newCompletions);
+     }
+ 
+     /**
+@@ -174,4 +228,102 @@ public class AsyncTabCompleteEvent extends Event implements Cancellable {
+     public static HandlerList getHandlerList() {
+         return handlers;
+     }
++
++    private static @NotNull List<Completion> fromStrings(final @NotNull List<String> strings) {
++        final List<Completion> list = new ArrayList<>();
++        for (final String it : strings) {
++            list.add(new CompletionImpl(it, null));
++        }
++        return list;
++    }
++
++    /**
++     * A rich tab completion, consisting of a string suggestion, and a nullable {@link Component} tooltip.
++     */
++    public interface Completion extends Examinable {
++        /**
++         * Get the suggestion string for this {@link Completion}.
++         *
++         * @return suggestion string
++         */
++        @NotNull String suggestion();
++
++        /**
++         * Get the suggestion tooltip for this {@link Completion}.
++         *
++         * @return tooltip component
++         */
++        @Nullable Component tooltip();
++
++        @Override
++        default @NotNull Stream<? extends ExaminableProperty> examinableProperties() {
++            return Stream.of(ExaminableProperty.of("suggestion", this.suggestion()), ExaminableProperty.of("tooltip", this.tooltip()));
++        }
++
++        /**
++         * Create a new {@link Completion} from a suggestion string.
++         *
++         * @param suggestion suggestion string
++         * @return new completion instance
++         */
++        static @NotNull Completion completion(final @NotNull String suggestion) {
++            return new CompletionImpl(suggestion, null);
++        }
++
++        /**
++         * Create a new {@link Completion} from a suggestion string and a tooltip {@link Component}.
++         *
++         * <p>If the provided component is null, the suggestion will not have a tooltip.</p>
++         *
++         * @param suggestion suggestion string
++         * @param tooltip    tooltip component, or null
++         * @return new completion instance
++         */
++        static @NotNull Completion completion(final @NotNull String suggestion, final @Nullable Component tooltip) {
++            return new CompletionImpl(suggestion, tooltip);
++        }
++    }
++
++    static final class CompletionImpl implements Completion {
++        private final String suggestion;
++        private final Component tooltip;
++
++        CompletionImpl(final @NotNull String suggestion, final @Nullable Component tooltip) {
++            this.suggestion = suggestion;
++            this.tooltip = tooltip;
++        }
++
++        @Override
++        public @NotNull String suggestion() {
++            return this.suggestion;
++        }
++
++        @Override
++        public @Nullable Component tooltip() {
++            return this.tooltip;
++        }
++
++        @Override
++        public boolean equals(final @Nullable Object o) {
++            if (this == o) {
++                return true;
++            }
++            if (o == null || this.getClass() != o.getClass()) {
++                return false;
++            }
++            final CompletionImpl that = (CompletionImpl) o;
++            return this.suggestion.equals(that.suggestion)
++                && java.util.Objects.equals(this.tooltip, that.tooltip);
++        }
++
++        @Override
++        public int hashCode() {
++            return java.util.Objects.hash(this.suggestion, this.tooltip);
++        }
++
++        @Override
++        public @NotNull String toString() {
++            return StringExaminer.simpleEscaping().examine(this);
++        }
++    }
+ }
+diff --git a/src/main/java/io/papermc/paper/util/TransformingRandomAccessList.java b/src/main/java/io/papermc/paper/util/TransformingRandomAccessList.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..6f560a51277ccbd46a9142cfa057d276118c1c7b
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/util/TransformingRandomAccessList.java
+@@ -0,0 +1,169 @@
++package io.papermc.paper.util;
++
++import org.checkerframework.checker.nullness.qual.NonNull;
++import org.jetbrains.annotations.NotNull;
++
++import java.util.AbstractList;
++import java.util.Iterator;
++import java.util.List;
++import java.util.ListIterator;
++import java.util.RandomAccess;
++import java.util.function.Function;
++import java.util.function.Predicate;
++
++import static com.google.common.base.Preconditions.checkNotNull;
++
++/**
++ * Modified version of the Guava class with the same name to support add operations.
++ *
++ * @param <F> backing list element type
++ * @param <T> transformed list element type
++ */
++public final class TransformingRandomAccessList<F, T> extends AbstractList<T> implements RandomAccess {
++    final List<F> fromList;
++    final Function<? super F, ? extends T> toFunction;
++    final Function<? super T, ? extends F> fromFunction;
++
++    /**
++     * Create a new {@link TransformingRandomAccessList}.
++     *
++     * @param fromList     backing list
++     * @param toFunction   function mapping backing list element type to transformed list element type
++     * @param fromFunction function mapping transformed list element type to backing list element type
++     */
++    public TransformingRandomAccessList(
++        final @NonNull List<F> fromList,
++        final @NonNull Function<? super F, ? extends T> toFunction,
++        final @NonNull Function<? super T, ? extends F> fromFunction
++    ) {
++        this.fromList = checkNotNull(fromList);
++        this.toFunction = checkNotNull(toFunction);
++        this.fromFunction = checkNotNull(fromFunction);
++    }
++
++    @Override
++    public void clear() {
++        this.fromList.clear();
++    }
++
++    @Override
++    public T get(int index) {
++        return this.toFunction.apply(this.fromList.get(index));
++    }
++
++    @Override
++    public @NotNull Iterator<T> iterator() {
++        return this.listIterator();
++    }
++
++    @Override
++    public @NotNull ListIterator<T> listIterator(int index) {
++        return new TransformedListIterator<F, T>(this.fromList.listIterator(index)) {
++            @Override
++            T transform(F from) {
++                return TransformingRandomAccessList.this.toFunction.apply(from);
++            }
++
++            @Override
++            F transformBack(T from) {
++                return TransformingRandomAccessList.this.fromFunction.apply(from);
++            }
++        };
++    }
++
++    @Override
++    public boolean isEmpty() {
++        return this.fromList.isEmpty();
++    }
++
++    @Override
++    public boolean removeIf(Predicate<? super T> filter) {
++        checkNotNull(filter);
++        return this.fromList.removeIf(element -> filter.test(this.toFunction.apply(element)));
++    }
++
++    @Override
++    public T remove(int index) {
++        return this.toFunction.apply(this.fromList.remove(index));
++    }
++
++    @Override
++    public int size() {
++        return this.fromList.size();
++    }
++
++    @Override
++    public T set(int i, T t) {
++        return this.toFunction.apply(this.fromList.set(i, this.fromFunction.apply(t)));
++    }
++
++    @Override
++    public void add(int i, T t) {
++        this.fromList.add(i, this.fromFunction.apply(t));
++    }
++
++    static abstract class TransformedListIterator<F, T> implements ListIterator<T>, Iterator<T> {
++        final Iterator<F> backingIterator;
++
++        TransformedListIterator(ListIterator<F> backingIterator) {
++            this.backingIterator = checkNotNull((Iterator<F>) backingIterator);
++        }
++
++        private ListIterator<F> backingIterator() {
++            return cast(this.backingIterator);
++        }
++
++        static <A> ListIterator<A> cast(Iterator<A> iterator) {
++            return (ListIterator<A>) iterator;
++        }
++
++        @Override
++        public final boolean hasPrevious() {
++            return this.backingIterator().hasPrevious();
++        }
++
++        @Override
++        public final T previous() {
++            return this.transform(this.backingIterator().previous());
++        }
++
++        @Override
++        public final int nextIndex() {
++            return this.backingIterator().nextIndex();
++        }
++
++        @Override
++        public final int previousIndex() {
++            return this.backingIterator().previousIndex();
++        }
++
++        @Override
++        public void set(T element) {
++            this.backingIterator().set(this.transformBack(element));
++        }
++
++        @Override
++        public void add(T element) {
++            this.backingIterator().add(this.transformBack(element));
++        }
++
++        abstract T transform(F from);
++
++        abstract F transformBack(T to);
++
++        @Override
++        public final boolean hasNext() {
++            return this.backingIterator.hasNext();
++        }
++
++        @Override
++        public final T next() {
++            return this.transform(this.backingIterator.next());
++        }
++
++        @Override
++        public final void remove() {
++            this.backingIterator.remove();
++        }
++    }
++}
+diff --git a/src/test/java/org/bukkit/AnnotationTest.java b/src/test/java/org/bukkit/AnnotationTest.java
+index 19271057cf24329757c9419fa6c97848e008a96c..82b2783497947f336b0dd95db61f31f8f77f446c 100644
+--- a/src/test/java/org/bukkit/AnnotationTest.java
++++ b/src/test/java/org/bukkit/AnnotationTest.java
+@@ -48,6 +48,8 @@ public class AnnotationTest {
+         // Generic functional interface
+         "org/bukkit/util/Consumer",
+         // Paper start
++        "io/papermc/paper/util/TransformingRandomAccessList",
++        "io/papermc/paper/util/TransformingRandomAccessList$TransformedListIterator",
+         // Timings history is broken in terms of nullability due to guavas Function defining that the param is NonNull
+         "co/aikar/timings/TimingHistory$2",
+         "co/aikar/timings/TimingHistory$2$1",
diff --git a/Spigot-Server-Patches/0700-Allow-for-Component-suggestion-tooltips-in-AsyncTabC.patch b/Spigot-Server-Patches/0700-Allow-for-Component-suggestion-tooltips-in-AsyncTabC.patch
new file mode 100644
index 0000000000..fef6b7dd93
--- /dev/null
+++ b/Spigot-Server-Patches/0700-Allow-for-Component-suggestion-tooltips-in-AsyncTabC.patch
@@ -0,0 +1,132 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: jmp <jasonpenilla2@me.com>
+Date: Thu, 1 Apr 2021 00:34:02 -0700
+Subject: [PATCH] Allow for Component suggestion tooltips in
+ AsyncTabCompleteEvent
+
+
+diff --git a/src/main/java/net/minecraft/server/network/PlayerConnection.java b/src/main/java/net/minecraft/server/network/PlayerConnection.java
+index 6ad075907d56a8f41ca3a7b82ff90a6d3ad9f1d4..db42f3b524adc4458c9c468b0299332e73a07a44 100644
+--- a/src/main/java/net/minecraft/server/network/PlayerConnection.java
++++ b/src/main/java/net/minecraft/server/network/PlayerConnection.java
+@@ -771,12 +771,11 @@ public class PlayerConnection implements PacketListenerPlayIn {
+ 
+         // Paper start - async tab completion
+         com.destroystokyo.paper.event.server.AsyncTabCompleteEvent event;
+-        java.util.List<String> completions = new java.util.ArrayList<>();
+         String buffer = packetplayintabcomplete.c();
+-        event = new com.destroystokyo.paper.event.server.AsyncTabCompleteEvent(this.getPlayer(), completions,
++        event = new com.destroystokyo.paper.event.server.AsyncTabCompleteEvent(this.getPlayer(),
+                 buffer, true, null);
+         event.callEvent();
+-        completions = event.isCancelled() ? com.google.common.collect.ImmutableList.of() : event.getCompletions();
++        java.util.List<com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion> completions = event.isCancelled() ? com.google.common.collect.ImmutableList.of() : event.completions();
+         // If the event isn't handled, we can assume that we have no completions, and so we'll ask the server
+         if (!event.isHandled()) {
+             if (!event.isCancelled()) {
+@@ -795,10 +794,16 @@ public class PlayerConnection implements PacketListenerPlayIn {
+                 });
+             }
+         } else if (!completions.isEmpty()) {
+-            com.mojang.brigadier.suggestion.SuggestionsBuilder builder = new com.mojang.brigadier.suggestion.SuggestionsBuilder(packetplayintabcomplete.c(), stringreader.getTotalLength());
++            com.mojang.brigadier.suggestion.SuggestionsBuilder builder0 = new com.mojang.brigadier.suggestion.SuggestionsBuilder(packetplayintabcomplete.c(), stringreader.getTotalLength());
+ 
+-            builder = builder.createOffset(builder.getInput().lastIndexOf(' ') + 1);
+-            completions.forEach(builder::suggest);
++            final com.mojang.brigadier.suggestion.SuggestionsBuilder builder = builder0.createOffset(builder0.getInput().lastIndexOf(' ') + 1);
++            completions.forEach(completion -> {
++                if (completion.tooltip() == null) {
++                    builder.suggest(completion.suggestion());
++                } else {
++                    builder.suggest(completion.suggestion(), PaperAdventure.asVanilla(completion.tooltip()));
++                }
++            });
+             com.mojang.brigadier.suggestion.Suggestions suggestions = builder.buildFuture().join();
+             com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getPlayer(), suggestions, buffer);
+             suggestEvent.setCancelled(suggestions.isEmpty());
+diff --git a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java
+index c5e00bd9e2790992202aadf8eec2002fc88c78f1..dd8e87ad192c19743577bb95253a127072ea196c 100644
+--- a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java
++++ b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java
+@@ -29,34 +29,56 @@ public class ConsoleCommandCompleter implements Completer {
+         final CraftServer server = this.server.server;
+         final String buffer = line.line();
+         // Async Tab Complete
+-        com.destroystokyo.paper.event.server.AsyncTabCompleteEvent event;
+-        java.util.List<String> completions = new java.util.ArrayList<>();
+-        event = new com.destroystokyo.paper.event.server.AsyncTabCompleteEvent(server.getConsoleSender(), completions,
+-            buffer, true, null);
++        final com.destroystokyo.paper.event.server.AsyncTabCompleteEvent event =
++            new com.destroystokyo.paper.event.server.AsyncTabCompleteEvent(server.getConsoleSender(), buffer, true, null);
+         event.callEvent();
+-        completions = event.isCancelled() ? com.google.common.collect.ImmutableList.of() : event.getCompletions();
++        final List<com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion> completions = event.isCancelled() ? com.google.common.collect.ImmutableList.of() : event.completions();
+ 
+         if (event.isCancelled() || event.isHandled()) {
+             // Still fire sync event with the provided completions, if someone is listening
+             if (!event.isCancelled() && TabCompleteEvent.getHandlerList().getRegisteredListeners().length > 0) {
+-                List<String> finalCompletions = completions;
++                List<com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion> finalCompletions = new java.util.ArrayList<>(completions);
+                 Waitable<List<String>> syncCompletions = new Waitable<List<String>>() {
+                     @Override
+                     protected List<String> evaluate() {
+-                        org.bukkit.event.server.TabCompleteEvent syncEvent = new org.bukkit.event.server.TabCompleteEvent(server.getConsoleSender(), buffer, finalCompletions);
++                        org.bukkit.event.server.TabCompleteEvent syncEvent = new org.bukkit.event.server.TabCompleteEvent(server.getConsoleSender(), buffer,
++                            finalCompletions.stream()
++                                .map(com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion::suggestion)
++                                .collect(java.util.stream.Collectors.toList()));
+                         return syncEvent.callEvent() ? syncEvent.getCompletions() : com.google.common.collect.ImmutableList.of();
+                     }
+                 };
+                 server.getServer().processQueue.add(syncCompletions);
+                 try {
+-                    completions = syncCompletions.get();
++                    final List<String> legacyCompletions = syncCompletions.get();
++                    completions.removeIf(it -> !legacyCompletions.contains(it.suggestion())); // remove any suggestions that were removed
++                    // add any new suggestions
++                    for (final String completion : legacyCompletions) {
++                        if (notNewSuggestion(completions, completion)) {
++                            continue;
++                        }
++                        completions.add(com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion.completion(completion));
++                    }
+                 } catch (InterruptedException | ExecutionException e1) {
+                     e1.printStackTrace();
+                 }
+             }
+ 
+             if (!completions.isEmpty()) {
+-                candidates.addAll(completions.stream().map(Candidate::new).collect(java.util.stream.Collectors.toList()));
++                for (final com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion completion : completions) {
++                    if (completion.suggestion().isEmpty()) {
++                        continue;
++                    }
++                    candidates.add(new Candidate(
++                        completion.suggestion(),
++                        completion.suggestion(),
++                        null,
++                        io.papermc.paper.adventure.PaperAdventure.PLAIN.serializeOr(completion.tooltip(), null),
++                        null,
++                        null,
++                        false
++                    ));
++                }
+             }
+             return;
+         }
+@@ -106,4 +128,15 @@ public class ConsoleCommandCompleter implements Completer {
+             Thread.currentThread().interrupt();
+         }
+     }
++
++    // Paper start
++    private boolean notNewSuggestion(final List<com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion> completions, final String completion) {
++        for (final com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion it : completions) {
++            if (it.suggestion().equals(completion)) {
++                return true;
++            }
++        }
++        return false;
++    }
++    // Paper end
+ }
diff --git a/Spigot-Server-Patches/0700-Enhance-console-tab-completions-for-brigadier-comman.patch b/Spigot-Server-Patches/0701-Enhance-console-tab-completions-for-brigadier-comman.patch
similarity index 86%
rename from Spigot-Server-Patches/0700-Enhance-console-tab-completions-for-brigadier-comman.patch
rename to Spigot-Server-Patches/0701-Enhance-console-tab-completions-for-brigadier-comman.patch
index 6a4e84db96..5636a8b6e4 100644
--- a/Spigot-Server-Patches/0700-Enhance-console-tab-completions-for-brigadier-comman.patch
+++ b/Spigot-Server-Patches/0701-Enhance-console-tab-completions-for-brigadier-comman.patch
@@ -52,23 +52,22 @@ index 89eeb9d202405747409e65fcf226d95379987e29..ad87b575a0261200b280884e054a59e3
      @Override
 diff --git a/src/main/java/io/papermc/paper/console/BrigadierCommandCompleter.java b/src/main/java/io/papermc/paper/console/BrigadierCommandCompleter.java
 new file mode 100644
-index 0000000000000000000000000000000000000000..1b2681e2c0a7c5f7b386e861fecc3002782a09a5
+index 0000000000000000000000000000000000000000..edd231d95a04a1c4832f1ca8a3da6a56e9472ca1
 --- /dev/null
 +++ b/src/main/java/io/papermc/paper/console/BrigadierCommandCompleter.java
-@@ -0,0 +1,120 @@
+@@ -0,0 +1,95 @@
 +package io.papermc.paper.console;
 +
++import com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion;
 +import com.mojang.brigadier.CommandDispatcher;
 +import com.mojang.brigadier.ParseResults;
 +import com.mojang.brigadier.StringReader;
 +import com.mojang.brigadier.suggestion.Suggestion;
 +import io.papermc.paper.adventure.PaperAdventure;
-+import net.kyori.adventure.text.Component;
 +import net.minecraft.commands.CommandListenerWrapper;
 +import net.minecraft.network.chat.ChatComponentUtils;
 +import net.minecraft.server.dedicated.DedicatedServer;
 +import org.checkerframework.checker.nullness.qual.NonNull;
-+import org.checkerframework.checker.nullness.qual.Nullable;
 +import org.jline.reader.Candidate;
 +import org.jline.reader.LineReader;
 +import org.jline.reader.ParsedLine;
@@ -77,6 +76,8 @@ index 0000000000000000000000000000000000000000..1b2681e2c0a7c5f7b386e861fecc3002
 +import java.util.Collections;
 +import java.util.List;
 +
++import static com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion.completion;
++
 +public final class BrigadierCommandCompleter {
 +    private final CommandListenerWrapper commandSourceStack;
 +    private final DedicatedServer server;
@@ -86,9 +87,9 @@ index 0000000000000000000000000000000000000000..1b2681e2c0a7c5f7b386e861fecc3002
 +        this.commandSourceStack = commandSourceStack;
 +    }
 +
-+    public void complete(final @NonNull LineReader reader, final @NonNull ParsedLine line, final @NonNull List<Candidate> candidates, final @NonNull List<String> stringCompletions) {
++    public void complete(final @NonNull LineReader reader, final @NonNull ParsedLine line, final @NonNull List<Candidate> candidates, final @NonNull List<Completion> existing) {
 +        if (!com.destroystokyo.paper.PaperConfig.enableBrigadierConsoleCompletions) {
-+            this.addCandidates(candidates, Collections.emptyList(), stringCompletions);
++            this.addCandidates(candidates, Collections.emptyList(), existing);
 +            return;
 +        }
 +        final CommandDispatcher<CommandListenerWrapper> dispatcher = this.server.getCommandDispatcher().dispatcher();
@@ -96,25 +97,25 @@ index 0000000000000000000000000000000000000000..1b2681e2c0a7c5f7b386e861fecc3002
 +        this.addCandidates(
 +            candidates,
 +            dispatcher.getCompletionSuggestions(results, line.cursor()).join().getList(),
-+            stringCompletions
++            existing
 +        );
 +    }
 +
 +    private void addCandidates(
 +        final @NonNull List<Candidate> candidates,
 +        final @NonNull List<Suggestion> brigSuggestions,
-+        final @NonNull List<String> stringSuggestions
++        final @NonNull List<Completion> existing
 +    ) {
 +        final List<Completion> completions = new ArrayList<>();
 +        brigSuggestions.forEach(it -> completions.add(toCompletion(it)));
-+        for (final String string : stringSuggestions) {
-+            if (string.isEmpty() || brigSuggestions.stream().anyMatch(it -> it.getText().equals(string))) {
++        for (final Completion completion : existing) {
++            if (completion.suggestion().isEmpty() || brigSuggestions.stream().anyMatch(it -> it.getText().equals(completion.suggestion()))) {
 +                continue;
 +            }
-+            completions.add(completion(string));
++            completions.add(completion);
 +        }
 +        for (final Completion completion : completions) {
-+            if (completion.completion().isEmpty()) {
++            if (completion.suggestion().isEmpty()) {
 +                continue;
 +            }
 +            candidates.add(toCandidate(completion));
@@ -122,7 +123,7 @@ index 0000000000000000000000000000000000000000..1b2681e2c0a7c5f7b386e861fecc3002
 +    }
 +
 +    private static @NonNull Candidate toCandidate(final @NonNull Completion completion) {
-+        final String suggestionText = completion.completion();
++        final String suggestionText = completion.suggestion();
 +        final String suggestionTooltip = PaperAdventure.PLAIN.serializeOr(completion.tooltip(), null);
 +        return new Candidate(
 +            suggestionText,
@@ -149,32 +150,6 @@ index 0000000000000000000000000000000000000000..1b2681e2c0a7c5f7b386e861fecc3002
 +        }
 +        return stringReader;
 +    }
-+
-+    static final class Completion {
-+        private final String completion;
-+        private final Component tooltip;
-+
-+        Completion(final @NonNull String completion, final @Nullable Component tooltip) {
-+            this.completion = completion;
-+            this.tooltip = tooltip;
-+        }
-+
-+        @NonNull String completion() {
-+            return this.completion;
-+        }
-+
-+        @Nullable Component tooltip() {
-+            return this.tooltip;
-+        }
-+    }
-+
-+    static @NonNull Completion completion(final @NonNull String completion) {
-+        return new Completion(completion, null);
-+    }
-+
-+    static @NonNull Completion completion(final @NonNull String completion, final @Nullable Component tooltip) {
-+        return new Completion(completion, tooltip);
-+    }
 +}
 diff --git a/src/main/java/io/papermc/paper/console/BrigadierCommandHighlighter.java b/src/main/java/io/papermc/paper/console/BrigadierCommandHighlighter.java
 new file mode 100644
@@ -275,7 +250,7 @@ index b00e5d811ddfa12937f57bac4debb2fdd057d6e1..d14e4bf09bc43e78a9da07ea062ed886
      }
  }
 diff --git a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java
-index c5e00bd9e2790992202aadf8eec2002fc88c78f1..bb837136285737862aa0b0f3d7fbe834bd69f741 100644
+index dd8e87ad192c19743577bb95253a127072ea196c..5e1312941f9a554fc83adc02e81980069b8d015d 100644
 --- a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java
 +++ b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java
 @@ -18,9 +18,11 @@ import org.bukkit.event.server.TabCompleteEvent;
@@ -290,19 +265,24 @@ index c5e00bd9e2790992202aadf8eec2002fc88c78f1..bb837136285737862aa0b0f3d7fbe834
      }
  
      // Paper start - Change method signature for JLine update
-@@ -55,9 +57,10 @@ public class ConsoleCommandCompleter implements Completer {
+@@ -64,7 +66,7 @@ public class ConsoleCommandCompleter implements Completer {
                  }
              }
  
 -            if (!completions.isEmpty()) {
 +            if (false && !completions.isEmpty()) {
-                 candidates.addAll(completions.stream().map(Candidate::new).collect(java.util.stream.Collectors.toList()));
+                 for (final com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion completion : completions) {
+                     if (completion.suggestion().isEmpty()) {
+                         continue;
+@@ -80,6 +82,7 @@ public class ConsoleCommandCompleter implements Completer {
+                     ));
+                 }
              }
 +            this.addCompletions(reader, line, candidates, completions);
              return;
          }
  
-@@ -77,10 +80,12 @@ public class ConsoleCommandCompleter implements Completer {
+@@ -99,10 +102,12 @@ public class ConsoleCommandCompleter implements Completer {
          try {
              List<String> offers = waitable.get();
              if (offers == null) {
@@ -315,23 +295,22 @@ index c5e00bd9e2790992202aadf8eec2002fc88c78f1..bb837136285737862aa0b0f3d7fbe834
              for (String completion : offers) {
                  if (completion.isEmpty()) {
                      continue;
-@@ -88,6 +93,8 @@ public class ConsoleCommandCompleter implements Completer {
+@@ -110,6 +115,8 @@ public class ConsoleCommandCompleter implements Completer {
  
                  candidates.add(new Candidate(completion));
              }
 +             */
-+            this.addCompletions(reader, line, candidates, offers);
++            this.addCompletions(reader, line, candidates, offers.stream().map(com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion::completion).collect(java.util.stream.Collectors.toList()));
              // Paper end
  
              // Paper start - JLine handles cursor now
-@@ -106,4 +113,10 @@ public class ConsoleCommandCompleter implements Completer {
-             Thread.currentThread().interrupt();
+@@ -138,5 +145,9 @@ public class ConsoleCommandCompleter implements Completer {
          }
+         return false;
      }
 +
-+    // Paper start
-+    private void addCompletions(final LineReader reader, final ParsedLine line, final List<Candidate> candidates, final List<String> stringCompletions) {
-+        this.brigadierCompleter.complete(reader, line, candidates, stringCompletions);
++    private void addCompletions(final LineReader reader, final ParsedLine line, final List<Candidate> candidates, final List<com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion> existing) {
++        this.brigadierCompleter.complete(reader, line, candidates, existing);
 +    }
-+    // Paper end
+     // Paper end
  }
diff --git a/Spigot-Server-Patches/0701-Fix-PlayerItemConsumeEvent-cancelling-properly.patch b/Spigot-Server-Patches/0702-Fix-PlayerItemConsumeEvent-cancelling-properly.patch
similarity index 100%
rename from Spigot-Server-Patches/0701-Fix-PlayerItemConsumeEvent-cancelling-properly.patch
rename to Spigot-Server-Patches/0702-Fix-PlayerItemConsumeEvent-cancelling-properly.patch
diff --git a/Spigot-Server-Patches/0702-Add-bypass-host-check.patch b/Spigot-Server-Patches/0703-Add-bypass-host-check.patch
similarity index 100%
rename from Spigot-Server-Patches/0702-Add-bypass-host-check.patch
rename to Spigot-Server-Patches/0703-Add-bypass-host-check.patch
diff --git a/Spigot-Server-Patches/0703-don-t-throw-when-loading-invalid-TEs.patch b/Spigot-Server-Patches/0704-don-t-throw-when-loading-invalid-TEs.patch
similarity index 100%
rename from Spigot-Server-Patches/0703-don-t-throw-when-loading-invalid-TEs.patch
rename to Spigot-Server-Patches/0704-don-t-throw-when-loading-invalid-TEs.patch
diff --git a/Spigot-Server-Patches/0704-Set-area-affect-cloud-rotation.patch b/Spigot-Server-Patches/0705-Set-area-affect-cloud-rotation.patch
similarity index 100%
rename from Spigot-Server-Patches/0704-Set-area-affect-cloud-rotation.patch
rename to Spigot-Server-Patches/0705-Set-area-affect-cloud-rotation.patch
diff --git a/Spigot-Server-Patches/0705-add-isDeeplySleeping-to-HumanEntity.patch b/Spigot-Server-Patches/0706-add-isDeeplySleeping-to-HumanEntity.patch
similarity index 100%
rename from Spigot-Server-Patches/0705-add-isDeeplySleeping-to-HumanEntity.patch
rename to Spigot-Server-Patches/0706-add-isDeeplySleeping-to-HumanEntity.patch
diff --git a/Spigot-Server-Patches/0706-Fix-duplicating-give-items-on-item-drop-cancel.patch b/Spigot-Server-Patches/0707-Fix-duplicating-give-items-on-item-drop-cancel.patch
similarity index 100%
rename from Spigot-Server-Patches/0706-Fix-duplicating-give-items-on-item-drop-cancel.patch
rename to Spigot-Server-Patches/0707-Fix-duplicating-give-items-on-item-drop-cancel.patch
diff --git a/Spigot-Server-Patches/0707-add-consumeFuel-to-FurnaceBurnEvent.patch b/Spigot-Server-Patches/0708-add-consumeFuel-to-FurnaceBurnEvent.patch
similarity index 100%
rename from Spigot-Server-Patches/0707-add-consumeFuel-to-FurnaceBurnEvent.patch
rename to Spigot-Server-Patches/0708-add-consumeFuel-to-FurnaceBurnEvent.patch
diff --git a/Spigot-Server-Patches/0708-add-get-set-drop-chance-to-EntityEquipment.patch b/Spigot-Server-Patches/0709-add-get-set-drop-chance-to-EntityEquipment.patch
similarity index 100%
rename from Spigot-Server-Patches/0708-add-get-set-drop-chance-to-EntityEquipment.patch
rename to Spigot-Server-Patches/0709-add-get-set-drop-chance-to-EntityEquipment.patch
diff --git a/Spigot-Server-Patches/0709-fix-PigZombieAngerEvent-cancellation.patch b/Spigot-Server-Patches/0710-fix-PigZombieAngerEvent-cancellation.patch
similarity index 100%
rename from Spigot-Server-Patches/0709-fix-PigZombieAngerEvent-cancellation.patch
rename to Spigot-Server-Patches/0710-fix-PigZombieAngerEvent-cancellation.patch
diff --git a/Spigot-Server-Patches/0710-Fix-checkReach-check-for-Shulker-boxes.patch b/Spigot-Server-Patches/0711-Fix-checkReach-check-for-Shulker-boxes.patch
similarity index 100%
rename from Spigot-Server-Patches/0710-Fix-checkReach-check-for-Shulker-boxes.patch
rename to Spigot-Server-Patches/0711-Fix-checkReach-check-for-Shulker-boxes.patch
diff --git a/Spigot-Server-Patches/0711-fix-PlayerItemHeldEvent-firing-twice.patch b/Spigot-Server-Patches/0712-fix-PlayerItemHeldEvent-firing-twice.patch
similarity index 92%
rename from Spigot-Server-Patches/0711-fix-PlayerItemHeldEvent-firing-twice.patch
rename to Spigot-Server-Patches/0712-fix-PlayerItemHeldEvent-firing-twice.patch
index 5c4f22712a..9d3a5dd90b 100644
--- a/Spigot-Server-Patches/0711-fix-PlayerItemHeldEvent-firing-twice.patch
+++ b/Spigot-Server-Patches/0712-fix-PlayerItemHeldEvent-firing-twice.patch
@@ -17,10 +17,10 @@ index d68f3e6b35f0af846c8a66710c5752508c095179..0e8ee44d0104ca7c666f57bdb54e0957
          return this.itemInHandIndex;
      }
 diff --git a/src/main/java/net/minecraft/server/network/PlayerConnection.java b/src/main/java/net/minecraft/server/network/PlayerConnection.java
-index 6ad075907d56a8f41ca3a7b82ff90a6d3ad9f1d4..b543776da3b799643893984a8c6f29477ed78d4a 100644
+index db42f3b524adc4458c9c468b0299332e73a07a44..fd9f38f0bb723b3e78bd013ccb9538489a9ca43e 100644
 --- a/src/main/java/net/minecraft/server/network/PlayerConnection.java
 +++ b/src/main/java/net/minecraft/server/network/PlayerConnection.java
-@@ -1903,6 +1903,7 @@ public class PlayerConnection implements PacketListenerPlayIn {
+@@ -1908,6 +1908,7 @@ public class PlayerConnection implements PacketListenerPlayIn {
          PlayerConnectionUtils.ensureMainThread(packetplayinhelditemslot, this, this.player.getWorldServer());
          if (this.player.isFrozen()) return; // CraftBukkit
          if (packetplayinhelditemslot.b() >= 0 && packetplayinhelditemslot.b() < PlayerInventory.getHotbarSize()) {
diff --git a/Spigot-Server-Patches/0712-Added-PlayerDeepSleepEvent.patch b/Spigot-Server-Patches/0713-Added-PlayerDeepSleepEvent.patch
similarity index 100%
rename from Spigot-Server-Patches/0712-Added-PlayerDeepSleepEvent.patch
rename to Spigot-Server-Patches/0713-Added-PlayerDeepSleepEvent.patch
diff --git a/Spigot-Server-Patches/0713-More-World-API.patch b/Spigot-Server-Patches/0714-More-World-API.patch
similarity index 100%
rename from Spigot-Server-Patches/0713-More-World-API.patch
rename to Spigot-Server-Patches/0714-More-World-API.patch
diff --git a/Spigot-Server-Patches/0714-Added-PlayerBedFailEnterEvent.patch b/Spigot-Server-Patches/0715-Added-PlayerBedFailEnterEvent.patch
similarity index 100%
rename from Spigot-Server-Patches/0714-Added-PlayerBedFailEnterEvent.patch
rename to Spigot-Server-Patches/0715-Added-PlayerBedFailEnterEvent.patch
diff --git a/Spigot-Server-Patches/0715-Implement-methods-to-convert-between-Component-and-B.patch b/Spigot-Server-Patches/0716-Implement-methods-to-convert-between-Component-and-B.patch
similarity index 100%
rename from Spigot-Server-Patches/0715-Implement-methods-to-convert-between-Component-and-B.patch
rename to Spigot-Server-Patches/0716-Implement-methods-to-convert-between-Component-and-B.patch
diff --git a/Spigot-Server-Patches/0716-Fix-anchor-respawn-acting-as-a-bed-respawn-from-the-.patch b/Spigot-Server-Patches/0717-Fix-anchor-respawn-acting-as-a-bed-respawn-from-the-.patch
similarity index 100%
rename from Spigot-Server-Patches/0716-Fix-anchor-respawn-acting-as-a-bed-respawn-from-the-.patch
rename to Spigot-Server-Patches/0717-Fix-anchor-respawn-acting-as-a-bed-respawn-from-the-.patch
diff --git a/Spigot-Server-Patches/0717-add-RespawnFlags-to-PlayerRespawnEvent.patch b/Spigot-Server-Patches/0718-add-RespawnFlags-to-PlayerRespawnEvent.patch
similarity index 95%
rename from Spigot-Server-Patches/0717-add-RespawnFlags-to-PlayerRespawnEvent.patch
rename to Spigot-Server-Patches/0718-add-RespawnFlags-to-PlayerRespawnEvent.patch
index cc5ab87b4e..f74833a611 100644
--- a/Spigot-Server-Patches/0717-add-RespawnFlags-to-PlayerRespawnEvent.patch
+++ b/Spigot-Server-Patches/0718-add-RespawnFlags-to-PlayerRespawnEvent.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] add RespawnFlags to PlayerRespawnEvent
 
 
 diff --git a/src/main/java/net/minecraft/server/network/PlayerConnection.java b/src/main/java/net/minecraft/server/network/PlayerConnection.java
-index b543776da3b799643893984a8c6f29477ed78d4a..9455cb9bc849a330e57fdc466fb51902631e22d8 100644
+index fd9f38f0bb723b3e78bd013ccb9538489a9ca43e..8c9e97bb093c0e6297397edc71d72deebbcfbed9 100644
 --- a/src/main/java/net/minecraft/server/network/PlayerConnection.java
 +++ b/src/main/java/net/minecraft/server/network/PlayerConnection.java
-@@ -2436,7 +2436,7 @@ public class PlayerConnection implements PacketListenerPlayIn {
+@@ -2441,7 +2441,7 @@ public class PlayerConnection implements PacketListenerPlayIn {
              case PERFORM_RESPAWN:
                  if (this.player.viewingCredits) {
                      this.player.viewingCredits = false;
diff --git a/Spigot-Server-Patches/0718-Introduce-beacon-activation-deactivation-events.patch b/Spigot-Server-Patches/0719-Introduce-beacon-activation-deactivation-events.patch
similarity index 100%
rename from Spigot-Server-Patches/0718-Introduce-beacon-activation-deactivation-events.patch
rename to Spigot-Server-Patches/0719-Introduce-beacon-activation-deactivation-events.patch
diff --git a/Spigot-Server-Patches/0719-Add-Channel-initialization-listeners.patch b/Spigot-Server-Patches/0720-Add-Channel-initialization-listeners.patch
similarity index 100%
rename from Spigot-Server-Patches/0719-Add-Channel-initialization-listeners.patch
rename to Spigot-Server-Patches/0720-Add-Channel-initialization-listeners.patch
diff --git a/Spigot-Server-Patches/0720-Send-empty-commands-if-tab-completion-is-disabled.patch b/Spigot-Server-Patches/0721-Send-empty-commands-if-tab-completion-is-disabled.patch
similarity index 100%
rename from Spigot-Server-Patches/0720-Send-empty-commands-if-tab-completion-is-disabled.patch
rename to Spigot-Server-Patches/0721-Send-empty-commands-if-tab-completion-is-disabled.patch
diff --git a/Spigot-Server-Patches/0721-Add-more-WanderingTrader-API.patch b/Spigot-Server-Patches/0722-Add-more-WanderingTrader-API.patch
similarity index 100%
rename from Spigot-Server-Patches/0721-Add-more-WanderingTrader-API.patch
rename to Spigot-Server-Patches/0722-Add-more-WanderingTrader-API.patch