From 0df83e38b761889679ce83a556d9d8e737d2d8b9 Mon Sep 17 00:00:00 2001 From: Riley Park Date: Tue, 21 Dec 2021 23:07:17 -0800 Subject: [PATCH] Adventure changes for Java 17 and Component support for resourcepack prompt --- patches/api/Adventure.patch | 183 ++++++++++++++--- patches/server/Adventure.patch | 188 ++++++++++-------- .../server/Complete-resource-pack-API.patch | 9 - .../Flag-to-disable-the-channel-limit.patch | 2 +- 4 files changed, 254 insertions(+), 128 deletions(-) diff --git a/patches/api/Adventure.patch b/patches/api/Adventure.patch index 4fb579bcdf..6766221f3f 100644 --- a/patches/api/Adventure.patch +++ b/patches/api/Adventure.patch @@ -390,9 +390,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; -+import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer; ++import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +import org.bukkit.Bukkit; -+import org.checkerframework.checker.nullness.qual.NonNull; ++import org.jetbrains.annotations.NotNull; + +/** + * Paper API-specific methods for working with {@link Component}s and related. @@ -407,7 +407,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * + * @return a component flattener + */ -+ public static @NonNull ComponentFlattener flattener() { ++ public static @NotNull ComponentFlattener flattener() { + return Bukkit.getUnsafe().componentFlattener(); + } + @@ -420,7 +420,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * + * @return a serializer to plain text + */ -+ public static @NonNull PlainComponentSerializer plainSerializer() { ++ public static @NotNull PlainTextComponentSerializer plainSerializer() { + return Bukkit.getUnsafe().plainComponentSerializer(); + } + @@ -434,7 +434,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * + * @return a json component serializer + */ -+ public static @NonNull GsonComponentSerializer gsonSerializer() { ++ public static @NotNull GsonComponentSerializer gsonSerializer() { + return Bukkit.getUnsafe().gsonComponentSerializer(); + } + @@ -449,7 +449,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * + * @return a json component serializer + */ -+ public static @NonNull GsonComponentSerializer colorDownsamplingGsonSerializer() { ++ public static @NotNull GsonComponentSerializer colorDownsamplingGsonSerializer() { + return Bukkit.getUnsafe().colorDownsamplingGsonComponentSerializer(); + } + @@ -467,7 +467,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * + * @return a section serializer + */ -+ public static @NonNull LegacyComponentSerializer legacySectionSerializer() { ++ public static @NotNull LegacyComponentSerializer legacySectionSerializer() { + return Bukkit.getUnsafe().legacyComponentSerializer(); + } +} @@ -1095,7 +1095,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public interface UnsafeValues { + // Paper start + net.kyori.adventure.text.flattener.ComponentFlattener componentFlattener(); -+ net.kyori.adventure.text.serializer.plain.PlainComponentSerializer plainComponentSerializer(); ++ net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer plainComponentSerializer(); + net.kyori.adventure.text.serializer.gson.GsonComponentSerializer gsonComponentSerializer(); + net.kyori.adventure.text.serializer.gson.GsonComponentSerializer colorDownsamplingGsonComponentSerializer(); + net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer legacyComponentSerializer(); @@ -1776,18 +1776,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.sendSignChange(loc, lines, DyeColor.BLACK); + } + - /** - * Send a sign change. This fakes a sign change packet for a user at - * a certain location. This will not actually change the world in any way. -@@ -0,0 +0,0 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM - * - * @param loc the location of the sign - * @param lines the new text on the sign or null to clear it ++ /** ++ * Send a sign change. This fakes a sign change packet for a user at ++ * a certain location. This will not actually change the world in any way. ++ * This method will use a sign at the location's block or a faked sign ++ * sent via ++ * {@link #sendBlockChange(org.bukkit.Location, org.bukkit.Material, byte)}. ++ *

++ * If the client does not have a sign at the given location it will ++ * display an error message to the user. ++ * ++ * @param loc the location of the sign ++ * @param lines the new text on the sign or null to clear it + * @param dyeColor the color of the sign - * @throws IllegalArgumentException if location is null ++ * @throws IllegalArgumentException if location is null + * @throws IllegalArgumentException if dyeColor is null - * @throws IllegalArgumentException if lines is non-null and has a length less than 4 - */ ++ * @throws IllegalArgumentException if lines is non-null and has a length less than 4 ++ */ + default void sendSignChange(@NotNull Location loc, @Nullable java.util.List lines, @NotNull DyeColor dyeColor) throws IllegalArgumentException { + this.sendSignChange(loc, lines, dyeColor, false); + } @@ -1835,22 +1840,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + throws IllegalArgumentException; + // Paper end + -+ /** -+ * Send a sign change. This fakes a sign change packet for a user at -+ * a certain location. This will not actually change the world in any way. -+ * This method will use a sign at the location's block or a faked sign -+ * sent via -+ * {@link #sendBlockChange(org.bukkit.Location, org.bukkit.Material, byte)}. -+ *

-+ * If the client does not have a sign at the given location it will -+ * display an error message to the user. -+ * -+ * @param loc the location of the sign -+ * @param lines the new text on the sign or null to clear it -+ * @throws IllegalArgumentException if location is null -+ * @throws IllegalArgumentException if lines is non-null and has a length less than 4 + /** + * Send a sign change. This fakes a sign change packet for a user at + * a certain location. This will not actually change the world in any way. +@@ -0,0 +0,0 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM + * @param lines the new text on the sign or null to clear it + * @throws IllegalArgumentException if location is null + * @throws IllegalArgumentException if lines is non-null and has a length less than 4 + * @deprecated in favour of {@link #sendSignChange(org.bukkit.Location, java.util.List)} -+ */ + */ + @Deprecated // Paper public void sendSignChange(@NotNull Location loc, @Nullable String[] lines) throws IllegalArgumentException; @@ -1875,6 +1873,116 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public void sendSignChange(@NotNull Location loc, @Nullable String[] lines, @NotNull DyeColor dyeColor, boolean hasGlowingText) throws IllegalArgumentException; /** +@@ -0,0 +0,0 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM + */ + public void setResourcePack(@NotNull String url, @Nullable byte[] hash, @Nullable String prompt); + ++ // Paper start ++ /** ++ * Request that the player's client download and switch resource packs. ++ *

++ * The player's client will download the new resource pack asynchronously ++ * in the background, and will automatically switch to it once the ++ * download is complete. If the client has downloaded and cached a ++ * resource pack with the same hash in the past it will not download but ++ * directly apply the cached pack. If the hash is null and the client has ++ * downloaded and cached the same resource pack in the past, it will ++ * perform a file size check against the response content to determine if ++ * the resource pack has changed and needs to be downloaded again. When ++ * this request is sent for the very first time from a given server, the ++ * client will first display a confirmation GUI to the player before ++ * proceeding with the download. ++ *

++ * Notes: ++ *

++ * ++ * @param url The URL from which the client will download the resource ++ * pack. The string must contain only US-ASCII characters and should ++ * be encoded as per RFC 1738. ++ * @param hash The sha1 hash sum of the resource pack file which is used ++ * to apply a cached version of the pack directly without downloading ++ * if it is available. Hast to be 20 bytes long! ++ * @param prompt The optional custom prompt message to be shown to client. ++ * @throws IllegalArgumentException Thrown if the URL is null. ++ * @throws IllegalArgumentException Thrown if the URL is too long. The ++ * length restriction is an implementation specific arbitrary value. ++ * @throws IllegalArgumentException Thrown if the hash is not 20 bytes ++ * long. ++ */ ++ default void setResourcePack(@NotNull String url, byte @Nullable [] hash, net.kyori.adventure.text.@Nullable Component prompt) { ++ this.setResourcePack(url, hash, prompt, false); ++ } ++ // Paper end ++ + /** + * Request that the player's client download and switch resource packs. + *

+@@ -0,0 +0,0 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM + */ + public void setResourcePack(@NotNull String url, @Nullable byte[] hash, @Nullable String prompt, boolean force); + ++ // Paper end ++ /** ++ * Request that the player's client download and switch resource packs. ++ *

++ * The player's client will download the new resource pack asynchronously ++ * in the background, and will automatically switch to it once the ++ * download is complete. If the client has downloaded and cached a ++ * resource pack with the same hash in the past it will not download but ++ * directly apply the cached pack. If the hash is null and the client has ++ * downloaded and cached the same resource pack in the past, it will ++ * perform a file size check against the response content to determine if ++ * the resource pack has changed and needs to be downloaded again. When ++ * this request is sent for the very first time from a given server, the ++ * client will first display a confirmation GUI to the player before ++ * proceeding with the download. ++ *

++ * Notes: ++ *

++ * ++ * @param url The URL from which the client will download the resource ++ * pack. The string must contain only US-ASCII characters and should ++ * be encoded as per RFC 1738. ++ * @param hash The sha1 hash sum of the resource pack file which is used ++ * to apply a cached version of the pack directly without downloading ++ * if it is available. Hast to be 20 bytes long! ++ * @param prompt The optional custom prompt message to be shown to client. ++ * @param force If true, the client will be disconnected from the server ++ * when it declines to use the resource pack. ++ * @throws IllegalArgumentException Thrown if the URL is null. ++ * @throws IllegalArgumentException Thrown if the URL is too long. The ++ * length restriction is an implementation specific arbitrary value. ++ * @throws IllegalArgumentException Thrown if the hash is not 20 bytes ++ * long. ++ */ ++ public void setResourcePack(@NotNull String url, byte @Nullable [] hash, net.kyori.adventure.text.@Nullable Component prompt, boolean force); ++ // Paper end ++ + /** + * Gets the Scoreboard displayed to this player + * @@ -0,0 +0,0 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param title Title text @@ -4122,3 +4230,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 "Lorg/jetbrains/annotations/Nullable;", "Lorg/jetbrains/annotations/NotNull;", "Lorg/jetbrains/annotations/Contract;", +@@ -0,0 +0,0 @@ public class AnnotationTest { + if (method.invisibleTypeAnnotations != null) { + for (final org.objectweb.asm.tree.TypeAnnotationNode invisibleTypeAnnotation : method.invisibleTypeAnnotations) { + final org.objectweb.asm.TypeReference ref = new org.objectweb.asm.TypeReference(invisibleTypeAnnotation.typeRef); +- if (ref.getSort() == org.objectweb.asm.TypeReference.METHOD_FORMAL_PARAMETER && ref.getTypeParameterIndex() == i && java.util.Arrays.binarySearch(ACCEPTED_ANNOTATIONS, invisibleTypeAnnotation.desc) >= 0) { ++ if (ref.getSort() == org.objectweb.asm.TypeReference.METHOD_FORMAL_PARAMETER && ref.getTypeParameterIndex() == i && org.apache.commons.lang.ArrayUtils.contains(ACCEPTED_ANNOTATIONS, invisibleTypeAnnotation.desc)) { + continue dancing; + } + } diff --git a/patches/server/Adventure.patch b/patches/server/Adventure.patch index bf5280f2ba..beb1d4ed54 100644 --- a/patches/server/Adventure.patch +++ b/patches/server/Adventure.patch @@ -43,27 +43,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import net.minecraft.network.chat.Style; +import net.minecraft.util.FormattedCharSequence; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jetbrains.annotations.Nullable; + +public final class AdventureComponent implements net.minecraft.network.chat.Component { -+ final Component wrapped; -+ private net.minecraft.network.chat.@MonotonicNonNull Component converted; ++ final Component adventure; ++ private net.minecraft.network.chat.@MonotonicNonNull Component vanilla; + -+ public AdventureComponent(final Component wrapped) { -+ this.wrapped = wrapped; ++ public AdventureComponent(final Component adventure) { ++ this.adventure = adventure; + } + + public net.minecraft.network.chat.Component deepConverted() { -+ net.minecraft.network.chat.Component converted = this.converted; -+ if (converted == null) { -+ converted = PaperAdventure.WRAPPER_AWARE_SERIALIZER.serialize(this.wrapped); -+ this.converted = converted; ++ net.minecraft.network.chat.Component vanilla = this.vanilla; ++ if (vanilla == null) { ++ vanilla = PaperAdventure.WRAPPER_AWARE_SERIALIZER.serialize(this.adventure); ++ this.vanilla = vanilla; + } -+ return converted; ++ return vanilla; + } + + public net.minecraft.network.chat.@Nullable Component deepConvertedIfPresent() { -+ return this.converted; ++ return this.vanilla; + } + + @Override @@ -73,8 +73,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + @Override + public String getContents() { -+ if (this.wrapped instanceof TextComponent) { -+ return ((TextComponent) this.wrapped).content(); ++ if (this.adventure instanceof TextComponent) { ++ return ((TextComponent) this.adventure).content(); + } else { + return this.deepConverted().getContents(); + } @@ -82,7 +82,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + @Override + public String getString() { -+ return PaperAdventure.PLAIN.serialize(this.wrapped); ++ return PaperAdventure.PLAIN.serialize(this.adventure); + } + + @Override @@ -108,7 +108,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public static class Serializer implements JsonSerializer { + @Override + public JsonElement serialize(final AdventureComponent src, final Type type, final JsonSerializationContext context) { -+ return PaperAdventure.GSON.serializer().toJsonTree(src.wrapped, Component.class); ++ return PaperAdventure.GSON.serializer().toJsonTree(src.adventure, Component.class); + } + } +} @@ -527,7 +527,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; -+import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer; ++import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +import net.kyori.adventure.translation.GlobalTranslator; +import net.kyori.adventure.translation.TranslationRegistry; +import net.kyori.adventure.translation.Translator; @@ -544,8 +544,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.WrittenBookItem; +import org.bukkit.ChatColor; -+import org.checkerframework.checker.nullness.qual.NonNull; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; + +public final class PaperAdventure { + public static final AttributeKey LOCALE_ATTRIBUTE = AttributeKey.valueOf("adventure:locale"); @@ -560,7 +560,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + } -+ final @NonNull String translated = Language.getInstance().getOrDefault(translatable.key()); ++ final @NotNull String translated = Language.getInstance().getOrDefault(translatable.key()); + + final Matcher matcher = LOCALIZATION_PATTERN.matcher(translated); + final List args = translatable.args(); @@ -599,7 +599,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + }) + .build(); + public static final LegacyComponentSerializer LEGACY_SECTION_UXRC = LegacyComponentSerializer.builder().flattener(FLATTENER).hexColors().useUnusualXRepeatedCharacterHexFormat().build(); -+ public static final PlainComponentSerializer PLAIN = PlainComponentSerializer.builder().flattener(FLATTENER).build(); ++ public static final PlainTextComponentSerializer PLAIN = PlainTextComponentSerializer.builder().flattener(FLATTENER).build(); + public static final GsonComponentSerializer GSON = GsonComponentSerializer.builder() + .legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.INSTANCE) + .build(); @@ -609,7 +609,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + .build(); + private static final Codec NBT_CODEC = new Codec() { + @Override -+ public @NonNull CompoundTag decode(final @NonNull String encoded) throws IOException { ++ public @NotNull CompoundTag decode(final @NotNull String encoded) throws IOException { + try { + return TagParser.parseTag(encoded); + } catch (final CommandSyntaxException e) { @@ -618,7 +618,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + @Override -+ public @NonNull String encode(final @NonNull CompoundTag decoded) { ++ public @NotNull String encode(final @NotNull CompoundTag decoded) { + return decoded.toString(); + } + }; @@ -671,6 +671,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + public static net.minecraft.network.chat.Component asVanilla(final Component component) { ++ if (component == null) return null; + if (true) return new AdventureComponent(component); + return net.minecraft.network.chat.Component.Serializer.fromJson(GSON.serializer().toJsonTree(component)); + } @@ -697,7 +698,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + public static String asJsonString(final net.minecraft.network.chat.Component component, final Locale locale) { + if (component instanceof AdventureComponent) { -+ return asJsonString(((AdventureComponent) component).wrapped, locale); ++ return asJsonString(((AdventureComponent) component).adventure, locale); + } + return net.minecraft.network.chat.Component.Serializer.toJson(component); + } @@ -722,71 +723,47 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // BossBar + + public static BossEvent.BossBarColor asVanilla(final BossBar.Color color) { -+ if (color == BossBar.Color.PINK) { -+ return BossEvent.BossBarColor.PINK; -+ } else if (color == BossBar.Color.BLUE) { -+ return BossEvent.BossBarColor.BLUE; -+ } else if (color == BossBar.Color.RED) { -+ return BossEvent.BossBarColor.RED; -+ } else if (color == BossBar.Color.GREEN) { -+ return BossEvent.BossBarColor.GREEN; -+ } else if (color == BossBar.Color.YELLOW) { -+ return BossEvent.BossBarColor.YELLOW; -+ } else if (color == BossBar.Color.PURPLE) { -+ return BossEvent.BossBarColor.PURPLE; -+ } else if (color == BossBar.Color.WHITE) { -+ return BossEvent.BossBarColor.WHITE; -+ } -+ throw new IllegalArgumentException(color.name()); ++ return switch (color) { ++ case PINK -> BossEvent.BossBarColor.PINK; ++ case BLUE -> BossEvent.BossBarColor.BLUE; ++ case RED -> BossEvent.BossBarColor.RED; ++ case GREEN -> BossEvent.BossBarColor.GREEN; ++ case YELLOW -> BossEvent.BossBarColor.YELLOW; ++ case PURPLE -> BossEvent.BossBarColor.PURPLE; ++ case WHITE -> BossEvent.BossBarColor.WHITE; ++ }; + } + + public static BossBar.Color asAdventure(final BossEvent.BossBarColor color) { -+ if(color == BossEvent.BossBarColor.PINK) { -+ return BossBar.Color.PINK; -+ } else if(color == BossEvent.BossBarColor.BLUE) { -+ return BossBar.Color.BLUE; -+ } else if(color == BossEvent.BossBarColor.RED) { -+ return BossBar.Color.RED; -+ } else if(color == BossEvent.BossBarColor.GREEN) { -+ return BossBar.Color.GREEN; -+ } else if(color == BossEvent.BossBarColor.YELLOW) { -+ return BossBar.Color.YELLOW; -+ } else if(color == BossEvent.BossBarColor.PURPLE) { -+ return BossBar.Color.PURPLE; -+ } else if(color == BossEvent.BossBarColor.WHITE) { -+ return BossBar.Color.WHITE; -+ } -+ throw new IllegalArgumentException(color.name()); ++ return switch (color) { ++ case PINK -> BossBar.Color.PINK; ++ case BLUE -> BossBar.Color.BLUE; ++ case RED -> BossBar.Color.RED; ++ case GREEN -> BossBar.Color.GREEN; ++ case YELLOW -> BossBar.Color.YELLOW; ++ case PURPLE -> BossBar.Color.PURPLE; ++ case WHITE -> BossBar.Color.WHITE; ++ }; + } + + public static BossEvent.BossBarOverlay asVanilla(final BossBar.Overlay overlay) { -+ if (overlay == BossBar.Overlay.PROGRESS) { -+ return BossEvent.BossBarOverlay.PROGRESS; -+ } else if (overlay == BossBar.Overlay.NOTCHED_6) { -+ return BossEvent.BossBarOverlay.NOTCHED_6; -+ } else if (overlay == BossBar.Overlay.NOTCHED_10) { -+ return BossEvent.BossBarOverlay.NOTCHED_10; -+ } else if (overlay == BossBar.Overlay.NOTCHED_12) { -+ return BossEvent.BossBarOverlay.NOTCHED_12; -+ } else if (overlay == BossBar.Overlay.NOTCHED_20) { -+ return BossEvent.BossBarOverlay.NOTCHED_20; -+ } -+ throw new IllegalArgumentException(overlay.name()); ++ return switch (overlay) { ++ case PROGRESS -> BossEvent.BossBarOverlay.PROGRESS; ++ case NOTCHED_6 -> BossEvent.BossBarOverlay.NOTCHED_6; ++ case NOTCHED_10 -> BossEvent.BossBarOverlay.NOTCHED_10; ++ case NOTCHED_12 -> BossEvent.BossBarOverlay.NOTCHED_12; ++ case NOTCHED_20 -> BossEvent.BossBarOverlay.NOTCHED_20; ++ }; + } + + public static BossBar.Overlay asAdventure(final BossEvent.BossBarOverlay overlay) { -+ if (overlay == BossEvent.BossBarOverlay.PROGRESS) { -+ return BossBar.Overlay.PROGRESS; -+ } else if (overlay == BossEvent.BossBarOverlay.NOTCHED_6) { -+ return BossBar.Overlay.NOTCHED_6; -+ } else if (overlay == BossEvent.BossBarOverlay.NOTCHED_10) { -+ return BossBar.Overlay.NOTCHED_10; -+ } else if (overlay == BossEvent.BossBarOverlay.NOTCHED_12) { -+ return BossBar.Overlay.NOTCHED_12; -+ } else if (overlay == BossEvent.BossBarOverlay.NOTCHED_20) { -+ return BossBar.Overlay.NOTCHED_20; -+ } -+ throw new IllegalArgumentException(overlay.name()); ++ return switch (overlay) { ++ case PROGRESS -> BossBar.Overlay.PROGRESS; ++ case NOTCHED_6 -> BossBar.Overlay.NOTCHED_6; ++ case NOTCHED_10 -> BossBar.Overlay.NOTCHED_10; ++ case NOTCHED_12 -> BossBar.Overlay.NOTCHED_12; ++ case NOTCHED_20 -> BossBar.Overlay.NOTCHED_20; ++ }; + } + + public static void setFlag(final BossBar bar, final BossBar.Flag flag, final boolean value) { @@ -876,14 +853,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + // Colors + -+ public static @NonNull TextColor asAdventure(ChatFormatting minecraftColor) { -+ if (minecraftColor.getColor() == null) { ++ public static @NotNull TextColor asAdventure(final ChatFormatting formatting) { ++ final Integer color = formatting.getColor(); ++ if (color == null) { + throw new IllegalArgumentException("Not a valid color"); + } -+ return TextColor.color(minecraftColor.getColor()); ++ return TextColor.color(color); + } + -+ public static @Nullable ChatFormatting asVanilla(TextColor color) { ++ public static @Nullable ChatFormatting asVanilla(final TextColor color) { + return ChatFormatting.getByHexValue(color.value()); + } +} @@ -952,7 +930,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Override + public Component deserialize(final net.minecraft.network.chat.Component input) { + if (input instanceof AdventureComponent) { -+ return ((AdventureComponent) input).wrapped; ++ return ((AdventureComponent) input).adventure; + } + return PaperAdventure.GSON.serializer().fromJson(net.minecraft.network.chat.Component.Serializer.toJsonTree(input), Component.class); + } @@ -2534,6 +2512,46 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + + @Override + public void setResourcePack(String url) { +- this.setResourcePack(url, null); ++ this.setResourcePack(url, (byte[]) null); + } + + @Override +@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + + @Override + public void setResourcePack(String url, byte[] hash, boolean force) { +- this.setResourcePack(url, hash, null, force); ++ this.setResourcePack(url, hash, (String) null, force); + } + + @Override +@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + } + } + ++ // Paper start ++ @Override ++ public void setResourcePack(String url, byte[] hashBytes, net.kyori.adventure.text.Component prompt, boolean force) { ++ Validate.notNull(url, "Resource pack URL cannot be null"); ++ final String hash; ++ if (hashBytes != null) { ++ Validate.isTrue(hashBytes.length == 20, "Resource pack hash should be 20 bytes long but was " + hashBytes.length); ++ hash = BaseEncoding.base16().lowerCase().encode(hashBytes); ++ } else { ++ hash = ""; ++ } ++ this.getHandle().sendTexturePack(url, hash, force, io.papermc.paper.adventure.PaperAdventure.asVanilla(prompt)); ++ } ++ // Paper end ++ + public void addChannel(String channel) { + Preconditions.checkState(this.channels.size() < 128, "Cannot register channel '%s'. Too many channels registered!", channel); + channel = StandardMessenger.validateAndCorrectChannel(channel); +@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return (this.getHandle().clientViewDistance == null) ? Bukkit.getViewDistance() : this.getHandle().clientViewDistance; } @@ -3529,7 +3547,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + @Override -+ public net.kyori.adventure.text.serializer.plain.PlainComponentSerializer plainComponentSerializer() { ++ public net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer plainComponentSerializer() { + return io.papermc.paper.adventure.PaperAdventure.PLAIN; + } + diff --git a/patches/server/Complete-resource-pack-API.patch b/patches/server/Complete-resource-pack-API.patch index 2261bab9f1..0d986f72d3 100644 --- a/patches/server/Complete-resource-pack-API.patch +++ b/patches/server/Complete-resource-pack-API.patch @@ -46,15 +46,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public CraftPlayer(CraftServer server, ServerPlayer entity) { super(server, entity); @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { - - @Override - public void setResourcePack(String url) { -- this.setResourcePack(url, null); -+ this.setResourcePack(url, (byte[]) null); - } - - @Override -@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public boolean getAffectsSpawning() { return this.getHandle().affectsSpawning; } diff --git a/patches/server/Flag-to-disable-the-channel-limit.patch b/patches/server/Flag-to-disable-the-channel-limit.patch index e73ce09e34..28a4e04765 100644 --- a/patches/server/Flag-to-disable-the-channel-limit.patch +++ b/patches/server/Flag-to-disable-the-channel-limit.patch @@ -21,7 +21,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public CraftPlayer(CraftServer server, ServerPlayer entity) { @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { - } + // Paper end public void addChannel(String channel) { - Preconditions.checkState(this.channels.size() < 128, "Cannot register channel '%s'. Too many channels registered!", channel);