13
0
geforkt von Mirrors/Paper

Use Codecs for adventure Component conversions & network serialization ()

* finish implementing all adventure components in codecs

* add some initial tests

* Add round trip tests for text and translatable components

* Add more round trip test data (score component is failing)

* Add more round trip test data

* Fix SCORE_COMPONENT_MAP_CODEC

* Improve test failure messages

* Add failure cases

* Add a couple more test data

* Make use of AdventureCodecs

* Update patches after rebase

* Squash changes into adventure patch

* Fix AT formatting

* update comment

---------

Co-authored-by: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Dieser Commit ist enthalten in:
Jake Potrebic 2023-12-11 22:02:06 -08:00 committet von GitHub
Ursprung 82f9280ae4
Commit 7c2dc4b342
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 4AEE18F83AFDEB23
637 geänderte Dateien mit 965 neuen und 421 gelöschten Zeilen
patches/server
0010-Adventure.patch0056-Player-Tab-List-and-Title-APIs.patch0132-Use-TerminalConsoleAppender-for-console-improvements.patch0233-Remove-unnecessary-itemmeta-handling.patch0420-incremental-chunk-and-player-saving.patch0420-initial-work-on-native-Adventure-codecs.patch0421-Support-old-UUID-format-for-NBT.patch0422-Convert-legacy-attributes-in-Item-Meta.patch0423-Remove-some-streams-from-structures.patch0424-Remove-streams-from-classes-related-villager-gossip.patch0425-Support-components-in-ItemMeta.patch0426-Improve-fix-EntityTargetLivingEntityEvent.patch0427-Add-entity-liquid-API.patch0428-Update-itemstack-legacy-name-and-lore.patch0429-Add-PrepareResultEvent.patch0430-Don-t-check-chunk-for-portal-on-world-gen-entity-add.patch0431-Fix-arrows-never-despawning-MC-125757.patch0432-Thread-Safe-Vanilla-Command-permission-checking.patch0433-Fix-SPIGOT-5989.patch0434-Fix-SPIGOT-5824-Bukkit-world-container-is-not-used.patch0435-Fix-SPIGOT-5885-Unable-to-disable-advancements.patch0436-Fix-AdvancementDataPlayer-leak-due-from-quitting-ear.patch0437-Optimize-NetworkManager-Exception-Handling.patch0438-Fix-some-rails-connecting-improperly.patch0439-Fix-regex-mistake-in-CB-NBT-int-deserialization.patch0440-Brand-support.patch0441-Add-playPickupItemAnimation-to-LivingEntity.patch0442-Don-t-require-FACING-data.patch0443-Fix-SpawnChangeEvent-not-firing-for-all-use-cases.patch0444-Add-moon-phase-API.patch0445-Do-not-let-the-server-load-chunks-from-newer-version.patch0446-Prevent-headless-pistons-from-being-created.patch0447-Add-BellRingEvent.patch0448-Add-zombie-targets-turtle-egg-config.patch0449-Buffer-joins-to-world.patch0450-Eigencraft-redstone-implementation.patch0451-Fix-hex-colors-not-working-in-some-kick-messages.patch0452-PortalCreateEvent-needs-to-know-its-entity.patch0453-Add-more-Evoker-API.patch0454-Add-methods-to-get-translation-keys.patch0455-Create-HoverEvent-from-ItemStack-Entity.patch0456-Cache-block-data-strings.patch0457-Fix-Entity-Teleportation-and-cancel-velocity-if-tele.patch0458-Add-additional-open-container-api-to-HumanEntity.patch0459-Cache-DataFixerUpper-Rewrite-Rules-on-demand.patch0460-Extend-block-drop-capture-to-capture-all-items-added.patch0461-Expose-the-Entity-Counter-to-allow-plugins-to-use-va.patch0462-Lazily-track-plugin-scoreboards-by-default.patch0463-Entity-isTicking.patch0464-Fix-deop-kicking-non-whitelisted-player-when-white-l.patch0465-Fix-Concurrency-issue-in-ShufflingList.patch0466-Reset-Ender-Crystals-on-Dragon-Spawn.patch0467-Fix-for-large-move-vectors-crashing-server.patch0468-Optimise-getType-calls.patch0469-Villager-resetOffers.patch0470-Retain-block-place-order-when-capturing-blockstates.patch0471-Reduce-blockpos-allocation-from-pathfinding.patch0472-Fix-item-locations-dropped-from-campfires.patch0473-Fixed-TileEntityBell-memory-leak.patch0474-Avoid-error-bubbling-up-when-item-stack-is-empty-in-.patch0475-Add-getOfflinePlayerIfCached-String.patch0476-Add-ignore-discounts-API.patch0477-Toggle-for-removing-existing-dragon.patch0478-Fix-client-lag-on-advancement-loading.patch0479-Item-no-age-no-player-pickup.patch0480-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch0481-Beacon-API-custom-effect-ranges.patch0482-Add-API-for-quit-reason.patch0483-Add-Wandering-Trader-spawn-rate-config-options.patch0484-Expose-world-spawn-angle.patch0485-Add-Destroy-Speed-API.patch0486-Fix-Player-spawnParticle-x-y-z-precision-loss.patch0487-Add-LivingEntity-clearActiveItem.patch0488-Add-PlayerItemCooldownEvent.patch0489-Significantly-improve-performance-of-the-end-generat.patch0490-More-lightning-API.patch0491-Climbing-should-not-bypass-cramming-gamerule.patch0492-Added-missing-default-perms-for-commands.patch0493-Add-PlayerShearBlockEvent.patch0494-Limit-recipe-packets.patch0495-Fix-CraftSound-backwards-compatibility.patch0496-Player-Chunk-Load-Unload-Events.patch0497-Optimize-Dynamic-get-Missing-Keys.patch0498-Expose-LivingEntity-hurt-direction.patch0499-Add-OBSTRUCTED-reason-to-BedEnterResult.patch0500-Do-not-crash-from-invalid-ingredient-lists-in-Villag.patch0501-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch0502-Implement-TargetHitEvent.patch0503-MC-4-Fix-item-position-desync.patch0504-Additional-Block-Material-API-s.patch0505-Fix-harming-potion-dupe.patch0506-Implement-API-to-get-Material-from-Boats-and-Minecar.patch0507-Cache-burn-durations.patch0508-Allow-disabling-mob-spawner-spawn-egg-transformation.patch0509-Fix-Not-a-string-Map-Conversion-spam.patch0510-Implement-PlayerFlowerPotManipulateEvent.patch0511-Fix-interact-event-not-being-called-sometimes.patch0512-Zombie-API-breaking-doors.patch0513-Fix-nerfed-slime-when-splitting.patch0514-Add-EntityLoadCrossbowEvent.patch

Datei-Diff unterdrückt, da er zu groß ist Diff laden

Datei anzeigen

@ -5,12 +5,12 @@ Subject: [PATCH] Player Tab List and Title APIs
diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
index bc7d0cc8d66f07b45cffd9952829cc9bed9ce260..3374ea2fa61e1683c4c4d7ea3ef9b8a20cd09f62 100644 index 50c7e0a449ea9d71e21e86b4f03dac0298f96130..dd542b8b235115c4ce54578120d9bc184e852676 100644
--- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java --- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java
+++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java +++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
@@ -538,6 +538,12 @@ public class FriendlyByteBuf extends ByteBuf { @@ -541,6 +541,12 @@ public class FriendlyByteBuf extends ByteBuf {
// TODO this.adventure$locale
return this.writeWithCodec(NbtOps.INSTANCE, ComponentSerialization.CODEC, text); return this.writeWithCodec(NbtOps.INSTANCE, ComponentSerialization.CODEC, text);
// Paper end - adventure
} }
+ // Paper start - deprecated Tab List & Title APIs + // Paper start - deprecated Tab List & Title APIs
+ @Deprecated + @Deprecated

Datei anzeigen

@ -206,10 +206,10 @@ index 0000000000000000000000000000000000000000..8f07539a82f449ad217e316a7513a170
+ +
+} +}
diff --git a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java diff --git a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java
index 3dc613116c086444ece88bcb0a569eeea953074f..db54a9c32578defa02fa58dc694c96684a4885ac 100644 index 1fb9b0ea9f2dbff12d8d2fbc2ad2f4d88ca9f7ad..66ff48a12c8322cfbfd17c470d03dad1f912d123 100644
--- a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java --- a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java
+++ b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java +++ b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java
@@ -20,6 +20,7 @@ import net.kyori.adventure.text.TranslatableComponent; @@ -22,6 +22,7 @@ import net.kyori.adventure.text.TranslatableComponent;
import net.kyori.adventure.text.flattener.ComponentFlattener; import net.kyori.adventure.text.flattener.ComponentFlattener;
import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.serializer.ComponentSerializer; import net.kyori.adventure.text.serializer.ComponentSerializer;
@ -217,14 +217,12 @@ index 3dc613116c086444ece88bcb0a569eeea953074f..db54a9c32578defa02fa58dc694c9668
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer; import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
@@ -107,6 +108,9 @@ public final class PaperAdventure { @@ -109,6 +110,7 @@ public final class PaperAdventure {
public static final AttributeKey<Locale> LOCALE_ATTRIBUTE = AttributeKey.valueOf("adventure:locale"); // init after FLATTENER because classloading triggered here might create a logger public static final AttributeKey<Locale> LOCALE_ATTRIBUTE = AttributeKey.valueOf("adventure:locale"); // init after FLATTENER because classloading triggered here might create a logger
@Deprecated @Deprecated
public static final PlainComponentSerializer PLAIN = PlainComponentSerializer.builder().flattener(FLATTENER).build(); public static final PlainComponentSerializer PLAIN = PlainComponentSerializer.builder().flattener(FLATTENER).build();
+
+ public static final ANSIComponentSerializer ANSI_SERIALIZER = ANSIComponentSerializer.builder().flattener(FLATTENER).build(); + public static final ANSIComponentSerializer ANSI_SERIALIZER = ANSIComponentSerializer.builder().flattener(FLATTENER).build();
+ static final Codec<CompoundTag, String, IOException, IOException> NBT_CODEC = new Codec<CompoundTag, String, IOException, IOException>() {
private static final Codec<CompoundTag, String, IOException, IOException> NBT_CODEC = new Codec<CompoundTag, String, IOException, IOException>() {
@Override @Override
public @NotNull CompoundTag decode(final @NotNull String encoded) throws IOException { public @NotNull CompoundTag decode(final @NotNull String encoded) throws IOException {
diff --git a/src/main/java/io/papermc/paper/adventure/providers/ComponentLoggerProviderImpl.java b/src/main/java/io/papermc/paper/adventure/providers/ComponentLoggerProviderImpl.java diff --git a/src/main/java/io/papermc/paper/adventure/providers/ComponentLoggerProviderImpl.java b/src/main/java/io/papermc/paper/adventure/providers/ComponentLoggerProviderImpl.java

Datei anzeigen

@ -5,10 +5,10 @@ Subject: [PATCH] Remove unnecessary itemmeta handling
diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
index 3374ea2fa61e1683c4c4d7ea3ef9b8a20cd09f62..23d78a3193c30dd99d42182628c0e9e4527fc143 100644 index dd542b8b235115c4ce54578120d9bc184e852676..6b566413cd53f84820f0920249037fc9c2c1c4ca 100644
--- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java --- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java
+++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java +++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
@@ -642,7 +642,7 @@ public class FriendlyByteBuf extends ByteBuf { @@ -645,7 +645,7 @@ public class FriendlyByteBuf extends ByteBuf {
if (item.canBeDepleted() || item.shouldOverrideMultiplayerNbt()) { if (item.canBeDepleted() || item.shouldOverrideMultiplayerNbt()) {
// Spigot start - filter // Spigot start - filter
stack = stack.copy(); stack = stack.copy();
@ -17,7 +17,7 @@ index 3374ea2fa61e1683c4c4d7ea3ef9b8a20cd09f62..23d78a3193c30dd99d42182628c0e9e4
// Spigot end // Spigot end
nbttagcompound = stack.getTag(); nbttagcompound = stack.getTag();
} }
@@ -663,7 +663,7 @@ public class FriendlyByteBuf extends ByteBuf { @@ -666,7 +666,7 @@ public class FriendlyByteBuf extends ByteBuf {
itemstack.setTag(this.readNbt()); itemstack.setTag(this.readNbt());
// CraftBukkit start // CraftBukkit start

Datei anzeigen

@ -76,7 +76,7 @@ index 974b4970be214ca36a801d39932abcc751e540a5..63fad53a9184d7ab97f143b7d85ae9ef
public void close() throws IOException { public void close() throws IOException {
// CraftBukkit start // CraftBukkit start
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index d672b95fe589a57d469811a12420d7d16ea173c7..93a60c6dcbe29637e96aa57a76a5ceb544495fb5 100644 index c877aca6093435be9d349c07ea1b01d06bcbd416..17802108f41c98b77c89922451ee56b5ba2dcde2 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java --- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1302,6 +1302,37 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1302,6 +1302,37 @@ public class ServerLevel extends Level implements WorldGenLevel {

Datei anzeigen

@ -1,303 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Tue, 5 Dec 2023 16:47:40 -0800
Subject: [PATCH] initial work on native Adventure codecs
== AT ==
public net.minecraft.network.chat.HoverEvent$ItemStackInfo item
public net.minecraft.network.chat.HoverEvent$ItemStackInfo count
public net.minecraft.network.chat.HoverEvent$ItemStackInfo tag
public net.minecraft.network.chat.contents.TranslatableContents filterAllowedArguments(Ljava/lang/Object;)Lcom/mojang/serialization/DataResult;
diff --git a/src/main/java/io/papermc/paper/adventure/AdventureCodecs.java b/src/main/java/io/papermc/paper/adventure/AdventureCodecs.java
new file mode 100644
index 0000000000000000000000000000000000000000..87ad79ae42595116a0c1976c418a184cf0d6ddba
--- /dev/null
+++ b/src/main/java/io/papermc/paper/adventure/AdventureCodecs.java
@@ -0,0 +1,273 @@
+package io.papermc.paper.adventure;
+
+import com.mojang.datafixers.util.Either;
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.DataResult;
+import com.mojang.serialization.MapCodec;
+import com.mojang.serialization.codecs.RecordCodecBuilder;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import net.kyori.adventure.key.Key;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.KeybindComponent;
+import net.kyori.adventure.text.ScoreComponent;
+import net.kyori.adventure.text.SelectorComponent;
+import net.kyori.adventure.text.TextComponent;
+import net.kyori.adventure.text.TranslatableComponent;
+import net.kyori.adventure.text.event.ClickEvent;
+import net.kyori.adventure.text.event.HoverEvent;
+import net.kyori.adventure.text.format.NamedTextColor;
+import net.kyori.adventure.text.format.Style;
+import net.kyori.adventure.text.format.TextColor;
+import net.kyori.adventure.text.format.TextDecoration;
+import net.minecraft.core.UUIDUtil;
+import net.minecraft.core.registries.BuiltInRegistries;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.network.chat.ComponentSerialization;
+import net.minecraft.network.chat.contents.KeybindContents;
+import net.minecraft.network.chat.contents.ScoreContents;
+import net.minecraft.network.chat.contents.TranslatableContents;
+import net.minecraft.util.ExtraCodecs;
+import net.minecraft.util.StringRepresentable;
+import net.minecraft.world.item.Item;
+import net.minecraft.world.item.ItemStack;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.checkerframework.framework.qual.DefaultQualifier;
+import org.intellij.lang.annotations.Subst;
+
+import static net.kyori.adventure.text.Component.text;
+import static net.minecraft.util.ExtraCodecs.recursive;
+import static net.minecraft.util.ExtraCodecs.strictOptionalField;
+
+@DefaultQualifier(NonNull.class)
+public final class AdventureCodecs {
+
+ public static final Codec<Component> COMPONENT_CODEC = recursive("adventure Component", AdventureCodecs::createCodec);
+
+ private static final Codec<TextColor> TEXT_COLOR_CODEC = Codec.STRING.comapFlatMap(s -> {
+ if (s.startsWith("#")) {
+ @Nullable TextColor value = TextColor.fromHexString(s);
+ return value != null ? DataResult.success(value) : DataResult.error(() -> "Cannot convert " + s + " to adventure TextColor");
+ } else {
+ final @Nullable NamedTextColor value = NamedTextColor.NAMES.value(s);
+ return value != null ? DataResult.success(value) : DataResult.error(() -> "Cannot convert " + s + " to adventure NamedTextColor");
+ }
+ }, textColor -> {
+ if (textColor instanceof NamedTextColor named) {
+ return NamedTextColor.NAMES.keyOrThrow(named);
+ } else {
+ return textColor.asHexString();
+ }
+ });
+
+ private static final Codec<Key> KEY_CODEC = Codec.STRING.comapFlatMap(s -> {
+ return Key.parseable(s) ? DataResult.success(Key.key(s)) : DataResult.error(() -> "Cannot convert " + s + " to adventure Key");
+ }, Key::asString);
+
+ private static final Codec<ClickEvent.Action> CLICK_EVENT_ACTION_CODEC = Codec.STRING.comapFlatMap(s -> {
+ final ClickEvent.@Nullable Action value = ClickEvent.Action.NAMES.value(s);
+ return value != null ? DataResult.success(value) : DataResult.error(() -> "Cannot convert " + s + " to adventure ClickEvent$Action");
+ }, ClickEvent.Action.NAMES::keyOrThrow);
+ private static final Codec<ClickEvent> CLICK_EVENT_CODEC = RecordCodecBuilder.create((instance) -> {
+ return instance.group(
+ CLICK_EVENT_ACTION_CODEC.fieldOf("action").forGetter(ClickEvent::action),
+ Codec.STRING.fieldOf("value").forGetter(ClickEvent::value)
+ ).apply(instance, ClickEvent::clickEvent);
+ });
+
+ private static Codec<HoverEvent.ShowEntity> showEntityCodec(final Codec<Component> componentCodec) {
+ return RecordCodecBuilder.create((instance) -> {
+ return instance.group(
+ KEY_CODEC.fieldOf("type").forGetter(HoverEvent.ShowEntity::type),
+ UUIDUtil.LENIENT_CODEC.fieldOf("id").forGetter(HoverEvent.ShowEntity::id),
+ strictOptionalField(componentCodec, "name").forGetter(he -> Optional.ofNullable(he.name()))
+ ).apply(instance, (key, uuid, component) -> {
+ return HoverEvent.ShowEntity.showEntity(key, uuid, component.orElse(null));
+ });
+ });
+ }
+
+ private static Codec<HoverEvent.ShowItem> showItemCodec(final Codec<Component> componentCodec) {
+ return net.minecraft.network.chat.HoverEvent.ItemStackInfo.CODEC.xmap(isi -> {
+ @Subst("key") final String typeKey = BuiltInRegistries.ITEM.getKey(isi.item).toString();
+ return HoverEvent.ShowItem.showItem(Key.key(typeKey), isi.count, PaperAdventure.asBinaryTagHolder(isi.tag.orElse(null)));
+ }, si -> {
+ final Item itemType = BuiltInRegistries.ITEM.get(PaperAdventure.asVanilla(si.item()));
+ final ItemStack stack;
+ try {
+ final @Nullable CompoundTag tag = si.nbt() != null ? si.nbt().get(PaperAdventure.NBT_CODEC) : null;
+ stack = new ItemStack(BuiltInRegistries.ITEM.wrapAsHolder(itemType), si.count(), Optional.ofNullable(tag));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return new net.minecraft.network.chat.HoverEvent.ItemStackInfo(stack);
+ });
+ }
+
+ // TODO legacies
+ private static final HoverEventType<HoverEvent.ShowEntity> SHOW_ENTITY_HOVER_EVENT_TYPE = new HoverEventType<>(AdventureCodecs::showEntityCodec, HoverEvent.Action.SHOW_ENTITY, "show_entity");
+ private static final HoverEventType<HoverEvent.ShowItem> SHOW_ITEM_HOVER_EVENT_TYPE = new HoverEventType<>(AdventureCodecs::showItemCodec, HoverEvent.Action.SHOW_ITEM, "show_item");
+ private static final HoverEventType<Component> SHOW_TEXT_HOVER_EVENT_TYPE = new HoverEventType<>(Function.identity(), HoverEvent.Action.SHOW_TEXT, "show_text");
+ private static final Codec<HoverEventType<?>> HOVER_EVENT_TYPE_CODEC = StringRepresentable.fromValues(() -> new HoverEventType<?>[]{ SHOW_ENTITY_HOVER_EVENT_TYPE, SHOW_ITEM_HOVER_EVENT_TYPE, SHOW_TEXT_HOVER_EVENT_TYPE });
+
+ private record HoverEventType<V>(Function<Codec<Component>, Codec<HoverEvent<V>>> codec, String id) implements StringRepresentable {
+ private HoverEventType(final Function<Codec<Component>, Codec<V>> contentCodec, final HoverEvent.Action<V> action, final String id) {
+ this(cc -> contentCodec.apply(cc).xmap(v -> {
+ return HoverEvent.hoverEvent(action, v);
+ }, HoverEvent::value), id);
+ }
+ @Override
+ public String getSerializedName() {
+ return this.id;
+ }
+ }
+
+ private static MapCodec<HoverEvent<?>> hoverEventMapCodec(final Codec<Component> componentCodec) {
+ return HOVER_EVENT_TYPE_CODEC.dispatchMap("action", he -> {
+ if (he.action() == HoverEvent.Action.SHOW_ENTITY) {
+ return SHOW_ENTITY_HOVER_EVENT_TYPE;
+ } else if (he.action() == HoverEvent.Action.SHOW_ITEM) {
+ return SHOW_ITEM_HOVER_EVENT_TYPE;
+ } else if (he.action() == HoverEvent.Action.SHOW_TEXT) {
+ return SHOW_TEXT_HOVER_EVENT_TYPE;
+ } else {
+ throw new IllegalStateException();
+ }
+ }, het -> het.codec.apply(componentCodec));
+ }
+
+ public static MapCodec<Style> styleCodec(final Codec<Component> componentCodec) {
+ return RecordCodecBuilder.mapCodec((instance) -> {
+ return instance.group(
+ strictOptionalField(TEXT_COLOR_CODEC, "color").forGetter(nullableGetter(Style::color)),
+ strictOptionalField(Codec.BOOL, "bold").forGetter(decorationGetter(TextDecoration.BOLD)),
+ strictOptionalField(Codec.BOOL, "italic").forGetter(decorationGetter(TextDecoration.ITALIC)),
+ strictOptionalField(Codec.BOOL, "underlined").forGetter(decorationGetter(TextDecoration.UNDERLINED)),
+ strictOptionalField(Codec.BOOL, "strikethrough").forGetter(decorationGetter(TextDecoration.STRIKETHROUGH)),
+ strictOptionalField(Codec.BOOL, "obfuscated").forGetter(decorationGetter(TextDecoration.OBFUSCATED)),
+ strictOptionalField(CLICK_EVENT_CODEC, "clickEvent").forGetter(nullableGetter(Style::clickEvent)),
+ strictOptionalField(hoverEventMapCodec(componentCodec).codec(), "hoverEvent").forGetter(nullableGetter(Style::hoverEvent)),
+ strictOptionalField(Codec.STRING, "insertion").forGetter(nullableGetter(Style::insertion)),
+ strictOptionalField(KEY_CODEC, "font").forGetter(nullableGetter(Style::font))
+ ).apply(instance, (textColor, bold, italic, underlined, strikethrough, obfuscated, clickEvent, hoverEvent, insertion, font) -> {
+ return Style.style(builder -> {
+ textColor.ifPresent(builder::color);
+ bold.ifPresent(styleBooleanConsumer(builder, TextDecoration.BOLD));
+ italic.ifPresent(styleBooleanConsumer(builder, TextDecoration.ITALIC));
+ underlined.ifPresent(styleBooleanConsumer(builder, TextDecoration.UNDERLINED));
+ strikethrough.ifPresent(styleBooleanConsumer(builder, TextDecoration.STRIKETHROUGH));
+ obfuscated.ifPresent(styleBooleanConsumer(builder, TextDecoration.OBFUSCATED));
+ clickEvent.ifPresent(builder::clickEvent);
+ hoverEvent.ifPresent(builder::hoverEvent);
+ insertion.ifPresent(builder::insertion);
+ font.ifPresent(builder::font);
+ });
+ });
+ });
+ }
+ private static Consumer<Boolean> styleBooleanConsumer(final Style.Builder builder, final TextDecoration decoration) {
+ return b -> builder.decoration(decoration, b);
+ }
+
+ private static Function<Style, Optional<Boolean>> decorationGetter(final TextDecoration decoration) {
+ return style -> Optional.ofNullable(style.decoration(decoration) == TextDecoration.State.NOT_SET ? null : style.decoration(decoration) == TextDecoration.State.TRUE);
+ }
+
+ private static <R, T> Function<R, Optional<T>> nullableGetter(final Function<R, @Nullable T> getter) {
+ return style -> Optional.ofNullable(getter.apply(style));
+ }
+
+ private static final MapCodec<TextComponent> TEXT_COMPONENT_MAP_CODEC = RecordCodecBuilder.mapCodec((instance) -> {
+ return instance.group(Codec.STRING.fieldOf("text").forGetter(TextComponent::content)).apply(instance, Component::text);
+ });
+ private static final Codec<Object> PRIMITIVE_ARG_CODEC = ExtraCodecs.validate(ExtraCodecs.JAVA, TranslatableContents::filterAllowedArguments);
+ private static final Codec<Component> ARG_CODEC = Codec.either(PRIMITIVE_ARG_CODEC, COMPONENT_CODEC).xmap((primitiveOrComponent) -> {
+ return primitiveOrComponent.map(o -> text(String.valueOf(o)), Function.identity()); // just toString all primitives (not 100% correct to vanilla spec)
+ }, Either::right);
+ private static final MapCodec<TranslatableComponent> TRANSLATABLE_COMPONENT_MAP_CODEC = RecordCodecBuilder.mapCodec((instance) -> {
+ return instance.group(
+ Codec.STRING.fieldOf("translate").forGetter(TranslatableComponent::key),
+ Codec.STRING.optionalFieldOf("fallback").forGetter(nullableGetter(TranslatableComponent::fallback)),
+ strictOptionalField(ARG_CODEC.listOf(), "with").forGetter(c -> c.args().isEmpty() ? Optional.empty() : Optional.of(c.args()))
+ ).apply(instance, (key, fallback, components) -> {
+ return Component.translatable(key, components.orElse(Collections.emptyList())).fallback(fallback.orElse(null));
+ });
+ });
+
+ private static final MapCodec<KeybindComponent> KEYBIND_COMPONENT_MAP_CODEC = KeybindContents.CODEC.xmap(k -> Component.keybind(k.getName()), k -> new KeybindContents(k.keybind()));
+ private static final MapCodec<ScoreComponent> SCORE_COMPONENT_MAP_CODEC = ScoreContents.INNER_CODEC.xmap(s -> Component.score(s.getName(), s.getObjective()), s -> new ScoreContents(s.name(), s.objective()));
+ private static final MapCodec<SelectorComponent> SELECTOR_COMPONENT_MAP_CODEC = RecordCodecBuilder.mapCodec((instance) -> {
+ return instance.group(
+ Codec.STRING.fieldOf("selector").forGetter(SelectorComponent::pattern),
+ strictOptionalField(COMPONENT_CODEC, "separator").forGetter(nullableGetter(SelectorComponent::separator))
+ ).apply(instance, (selector, component) -> Component.selector(selector, component.orElse(null)));
+ });
+
+ private record ComponentType<C extends Component>(MapCodec<C> codec, Predicate<Component> test, String id) implements StringRepresentable {
+ @Override
+ public String getSerializedName() {
+ return this.id;
+ }
+ }
+
+ private static final ComponentType<TextComponent> PLAIN = new ComponentType<>(TEXT_COMPONENT_MAP_CODEC, TextComponent.class::isInstance, "text");
+ private static final ComponentType<TranslatableComponent> TRANSLATABLE = new ComponentType<>(TRANSLATABLE_COMPONENT_MAP_CODEC, TranslatableComponent.class::isInstance, "translatable");
+ private static final ComponentType<KeybindComponent> KEYBIND = new ComponentType<>(KEYBIND_COMPONENT_MAP_CODEC, KeybindComponent.class::isInstance, "keybind");
+ private static final ComponentType<ScoreComponent> SCORE = new ComponentType<>(SCORE_COMPONENT_MAP_CODEC, ScoreComponent.class::isInstance, "score");
+ private static final ComponentType<SelectorComponent> SELECTOR = new ComponentType<>(SELECTOR_COMPONENT_MAP_CODEC, SelectorComponent.class::isInstance, "selector");
+
+ private static Codec<Component> createCodec(final Codec<Component> selfCodec) {
+ final ComponentType<?>[] types = new ComponentType<?>[]{PLAIN, TRANSLATABLE, KEYBIND, SCORE, SELECTOR};
+ final MapCodec<Component> legacyCodec = ComponentSerialization.createLegacyComponentMatcher(types, ComponentType::codec, component -> {
+ for (final ComponentType<?> type : types) {
+ if (type.test().test(component)) {
+ return type;
+ }
+ }
+ throw new IllegalStateException("Unexpected component type " + component);
+ }, "type");
+
+ final Codec<Component> directCodec = RecordCodecBuilder.create((instance) -> {
+ return instance.group(
+ legacyCodec.forGetter(Function.identity()),
+ strictOptionalField(ExtraCodecs.nonEmptyList(selfCodec.listOf()), "extra", List.of()).forGetter(Component::children),
+ styleCodec(selfCodec).forGetter(Component::style)
+ ).apply(instance, (component, children, style) -> {
+ return component.style(style).children(children);
+ });
+ });
+
+ return Codec.either(Codec.either(Codec.STRING, ExtraCodecs.nonEmptyList(selfCodec.listOf())), directCodec).xmap((stringOrListOrComponent) -> {
+ return stringOrListOrComponent.map((stringOrList) -> stringOrList.map(Component::text, AdventureCodecs::createFromList), Function.identity());
+ }, (text) -> {
+ final @Nullable String string = tryCollapseToString(text);
+ return string != null ? Either.left(Either.left(string)) : Either.right(text);
+ });
+ }
+
+ private static @Nullable String tryCollapseToString(final Component component) {
+ if (component instanceof final TextComponent textComponent) {
+ if (component.children().isEmpty() && component.style().isEmpty()) {
+ return textComponent.content();
+ }
+ }
+ return null;
+ }
+
+ private static Component createFromList(final List<Component> components) {
+ Component component = components.get(0);
+ for (int i = 1; i < components.size(); i++) {
+ component = component.append(components.get(i));
+ }
+ return component;
+ }
+
+ private AdventureCodecs() {
+ }
+}
diff --git a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java
index db54a9c32578defa02fa58dc694c96684a4885ac..4ded541e9f2f19ef244fed290da3983b319f2c39 100644
--- a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java
+++ b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java
@@ -111,7 +111,7 @@ public final class PaperAdventure {
public static final ANSIComponentSerializer ANSI_SERIALIZER = ANSIComponentSerializer.builder().flattener(FLATTENER).build();
- private static final Codec<CompoundTag, String, IOException, IOException> NBT_CODEC = new Codec<CompoundTag, String, IOException, IOException>() {
+ public static final Codec<CompoundTag, String, IOException, IOException> NBT_CODEC = new Codec<CompoundTag, String, IOException, IOException>() {
@Override
public @NotNull CompoundTag decode(final @NotNull String encoded) throws IOException {
try {

Datei anzeigen

@ -57,7 +57,7 @@ index 698fc66f8c232644f2d747c81f8ac2e39204fd7f..8cb7e9d67fc4713dc327ad0459518f06
} catch (Exception ex) { } catch (Exception ex) {
ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t dispatch custom payload", ex); ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t dispatch custom payload", ex);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index e10cad5e2b078ff6ff7cba84dfa105ea5704d019..630f98fc58579c0a900d8ff6712a463742f90338 100644 index fb3b8f8eab00a2aadfee7780dfb0988f6fe3fc65..bb5c1a3ce83d737ac218a5b590b585916ac2d4d7 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -2999,6 +2999,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @@ -2999,6 +2999,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player {

Datei anzeigen

@ -6,7 +6,7 @@ Subject: [PATCH] Extend block drop capture to capture all items added to the
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 8ee66b28ee350564f0595541b904d593a6e3c8d5..6b5f325f847c096a4092ef3591627b21246601a0 100644 index 0bd086f67f5d1f06f66499ae961c71e780a8290a..0fa23738e2a095f55960ebbcfe3198d4feff4b01 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java --- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1528,6 +1528,12 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -1528,6 +1528,12 @@ public class ServerLevel extends Level implements WorldGenLevel {

Datei anzeigen

@ -37,7 +37,7 @@ index 478abaffd1a80949b96f1c1774c98134be92e5ac..063742400f3065ace62b64b42d952517
// Paper start - replace player chunk loader // Paper start - replace player chunk loader
private final java.util.concurrent.atomic.AtomicReference<io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances> viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1)); private final java.util.concurrent.atomic.AtomicReference<io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances> viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1));
diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
index 9647f6a274f4a4d2a940759b9cbd00569ac3bb18..e9b46bc0650050595f9db503c747350dc1997a5d 100644 index 8cb7e9d67fc4713dc327ad0459518f062dc9264e..4a2ff42950a9c15a3dbbf9ca7e3c43cad4c77404 100644
--- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
@@ -302,6 +302,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack @@ -302,6 +302,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack

Datei anzeigen

@ -5,7 +5,7 @@ Subject: [PATCH] Fix Player spawnParticle x/y/z precision loss
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 630f98fc58579c0a900d8ff6712a463742f90338..32c51de77dcd278f895969c513e38075dad83ace 100644 index bb5c1a3ce83d737ac218a5b590b585916ac2d4d7..b3cbd7779ca2046d952352a9cb9f509e8525b344 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -2562,7 +2562,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @@ -2562,7 +2562,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden Mehr anzeigen