diff --git a/api/src/main/java/com/github/retrooper/packetevents/protocol/chat/ChatType.java b/api/src/main/java/com/github/retrooper/packetevents/protocol/chat/ChatType.java index ae2b84cc8..421637d36 100644 --- a/api/src/main/java/com/github/retrooper/packetevents/protocol/chat/ChatType.java +++ b/api/src/main/java/com/github/retrooper/packetevents/protocol/chat/ChatType.java @@ -31,20 +31,25 @@ import net.kyori.adventure.util.Index; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.UnknownNullability; + +import java.util.Objects; import static com.github.retrooper.packetevents.util.adventure.AdventureIndexUtil.indexValueOrThrow; public interface ChatType extends MappedEntity, CopyableEntity { + @UnknownNullability("only nullable for 1.19") ChatTypeDecoration getChatDecoration(); @ApiStatus.Obsolete(since = "1.19.1") - ChatTypeDecoration getOverlayDecoration(); + @Nullable ChatTypeDecoration getOverlayDecoration(); + @UnknownNullability("only nullable for 1.19") ChatTypeDecoration getNarrationDecoration(); @ApiStatus.Obsolete(since = "1.19.1") - NarrationPriority getNarrationPriority(); + @Nullable NarrationPriority getNarrationPriority(); static ChatType readDirect(PacketWrapper wrapper) { ChatTypeDecoration chatDecoration = ChatTypeDecoration.read(wrapper); @@ -58,48 +63,78 @@ static void writeDirect(PacketWrapper wrapper, ChatType chatType) { } static ChatType decode(NBT nbt, ClientVersion version, @Nullable TypesBuilderData data) { + // everything is nullable in 1.19, even the chat format! NBTCompound compound = (NBTCompound) nbt; - NBTCompound chatTag = compound.getCompoundTagOrThrow("chat"); - NBTCompound narrationTag = compound.getCompoundTagOrThrow("narration"); + NBTCompound chatTag = compound.getCompoundTagOrNull("chat"); + NBTCompound narrationTag = compound.getCompoundTagOrNull("narration"); ChatTypeDecoration overlay = null; NarrationPriority narrationPriority = null; if (version.isOlderThan(ClientVersion.V_1_19_1)) { - overlay = ChatTypeDecoration.decode(compound.getCompoundTagOrThrow("overlay"), version); - narrationPriority = indexValueOrThrow(NarrationPriority.ID_INDEX, - narrationTag.getStringTagValueOrThrow("priority")); - chatTag = chatTag.getCompoundTagOrThrow("description"); - narrationTag = narrationTag.getCompoundTagOrThrow("description"); + NBTCompound overlayTag = compound.getCompoundTagOrNull("overlay"); + if (overlayTag != null) { + // why is this nullable? why is this wrapped? There is no reason to wrap this... + overlayTag = overlayTag.getCompoundTagOrNull("description"); + if (overlayTag != null) { + overlay = ChatTypeDecoration.decode(overlayTag, version); + } + } + if (chatTag != null) { + chatTag = chatTag.getCompoundTagOrNull("description"); + } + if (narrationTag != null) { + // the priority is the ONLY value which isn't nullable! + narrationPriority = indexValueOrThrow(NarrationPriority.ID_INDEX, + narrationTag.getStringTagValueOrThrow("priority")); + narrationTag = narrationTag.getCompoundTagOrNull("description"); + } + } else { + // ensure this isn't null in everything but 1.19 + Objects.requireNonNull(chatTag, "NBT chat does not exist"); + Objects.requireNonNull(narrationTag, "NBT narration does not exist"); } - ChatTypeDecoration chat = ChatTypeDecoration.decode(chatTag, version); - ChatTypeDecoration narration = ChatTypeDecoration.decode(narrationTag, version); + ChatTypeDecoration chat = chatTag == null ? null : ChatTypeDecoration.decode(chatTag, version); + ChatTypeDecoration narration = narrationTag == null ? null : ChatTypeDecoration.decode(narrationTag, version); return new StaticChatType(data, chat, overlay, narration, narrationPriority); } static NBT encode(ChatType chatType, ClientVersion version) { NBTCompound compound = new NBTCompound(); - NBT chatTag = ChatTypeDecoration.encode(chatType.getChatDecoration(), version); - NBT narrationTag = ChatTypeDecoration.encode(chatType.getNarrationDecoration(), version); + NBT chatTag = chatType.getChatDecoration() == null ? null : + ChatTypeDecoration.encode(chatType.getChatDecoration(), version); + NBT narrationTag = chatType.getNarrationDecoration() == null ? null : + ChatTypeDecoration.encode(chatType.getNarrationDecoration(), version); if (version.isOlderThan(ClientVersion.V_1_19_1)) { - if (chatType.getOverlayDecoration() != null) { - compound.setTag("overlay", - ChatTypeDecoration.encode(chatType.getOverlayDecoration(), version)); + ChatTypeDecoration overlayDeco = chatType.getOverlayDecoration(); + if (overlayDeco != null) { + NBTCompound overlayCompound = new NBTCompound(); + overlayCompound.setTag("description", + ChatTypeDecoration.encode(overlayDeco, version)); + compound.setTag("overlay", overlayCompound); } - NBTCompound narrationCompound = new NBTCompound(); - narrationCompound.setTag("description", narrationTag); - if (chatType.getNarrationPriority() != null) { - narrationCompound.setTag("priority", new NBTString(chatType.getNarrationPriority().getId())); + if (narrationTag != null) { + NBTCompound narrationCompound = new NBTCompound(); + narrationCompound.setTag("description", narrationTag); + if (chatType.getNarrationPriority() != null) { + narrationCompound.setTag("priority", new NBTString(chatType.getNarrationPriority().getId())); + } + narrationTag = narrationCompound; + } + if (chatTag != null) { + NBTCompound chatCompound = new NBTCompound(); + chatCompound.setTag("description", chatTag); + chatTag = chatCompound; } - narrationTag = narrationCompound; - NBTCompound chatCompound = new NBTCompound(); - chatCompound.setTag("description", chatTag); - chatTag = chatCompound; } - compound.setTag("chat", chatTag); - compound.setTag("narration", narrationTag); + if (chatTag != null) { + compound.setTag("chat", chatTag); + } + if (narrationTag != null) { + compound.setTag("narration", narrationTag); + } return compound; } diff --git a/api/src/main/java/com/github/retrooper/packetevents/protocol/chat/StaticChatType.java b/api/src/main/java/com/github/retrooper/packetevents/protocol/chat/StaticChatType.java index 80ce9faa0..f57e7038e 100644 --- a/api/src/main/java/com/github/retrooper/packetevents/protocol/chat/StaticChatType.java +++ b/api/src/main/java/com/github/retrooper/packetevents/protocol/chat/StaticChatType.java @@ -21,14 +21,15 @@ import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity; import com.github.retrooper.packetevents.util.mappings.TypesBuilderData; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.UnknownNullability; import java.util.Objects; public class StaticChatType extends AbstractMappedEntity implements ChatType { - private final ChatTypeDecoration chatDecoration; + private final @UnknownNullability("only nullable for 1.19") ChatTypeDecoration chatDecoration; private final @Nullable ChatTypeDecoration overlayDecoration; - private final ChatTypeDecoration narrationDecoration; + private final @UnknownNullability("only nullable for 1.19") ChatTypeDecoration narrationDecoration; private final @Nullable NarrationPriority narrationPriority; public StaticChatType( @@ -47,9 +48,9 @@ public StaticChatType( } public StaticChatType( - ChatTypeDecoration chatDecoration, + @UnknownNullability("only nullable for 1.19") ChatTypeDecoration chatDecoration, @Nullable ChatTypeDecoration overlayDecoration, - ChatTypeDecoration narrationDecoration, + @UnknownNullability("only nullable for 1.19") ChatTypeDecoration narrationDecoration, @Nullable NarrationPriority narrationPriority ) { this(null, chatDecoration, overlayDecoration, narrationDecoration, narrationPriority); @@ -57,9 +58,9 @@ public StaticChatType( public StaticChatType( @Nullable TypesBuilderData data, - ChatTypeDecoration chatDecoration, + @UnknownNullability("only nullable for 1.19") ChatTypeDecoration chatDecoration, @Nullable ChatTypeDecoration overlayDecoration, - ChatTypeDecoration narrationDecoration, + @UnknownNullability("only nullable for 1.19") ChatTypeDecoration narrationDecoration, @Nullable NarrationPriority narrationPriority ) { super(data); @@ -76,7 +77,7 @@ public ChatType copy(@Nullable TypesBuilderData newData) { } @Override - public ChatTypeDecoration getChatDecoration() { + public @UnknownNullability("only nullable for 1.19") ChatTypeDecoration getChatDecoration() { return this.chatDecoration; } @@ -86,7 +87,7 @@ public ChatTypeDecoration getChatDecoration() { } @Override - public ChatTypeDecoration getNarrationDecoration() { + public @UnknownNullability("only nullable for 1.19") ChatTypeDecoration getNarrationDecoration() { return this.narrationDecoration; } @@ -100,9 +101,9 @@ public boolean deepEquals(Object obj) { if (!(obj instanceof StaticChatType)) return false; if (!super.equals(obj)) return false; StaticChatType that = (StaticChatType) obj; - if (!this.chatDecoration.equals(that.chatDecoration)) return false; + if (!Objects.equals(this.chatDecoration, that.chatDecoration)) return false; if (!Objects.equals(this.overlayDecoration, that.overlayDecoration)) return false; - if (!this.narrationDecoration.equals(that.narrationDecoration)) return false; + if (!Objects.equals(this.narrationDecoration, that.narrationDecoration)) return false; return this.narrationPriority == that.narrationPriority; } diff --git a/api/src/main/java/com/github/retrooper/packetevents/util/mappings/SynchronizedRegistriesHandler.java b/api/src/main/java/com/github/retrooper/packetevents/util/mappings/SynchronizedRegistriesHandler.java index 90d94e343..28619a7d9 100644 --- a/api/src/main/java/com/github/retrooper/packetevents/util/mappings/SynchronizedRegistriesHandler.java +++ b/api/src/main/java/com/github/retrooper/packetevents/util/mappings/SynchronizedRegistriesHandler.java @@ -119,14 +119,14 @@ public static void handleLegacyRegistries( for (NBT tag : registryData.getTags().values()) { NBTCompound compound = (NBTCompound) tag; // extract registry name - ResourceLocation registryName = new ResourceLocation( - compound.getStringTagValueOrThrow("type")); + ResourceLocation registryName = new ResourceLocation(compound.getStringTagValueOrThrow("type")); // extract registry entries - NBTList nbtElements = - compound.getCompoundListTagOrThrow("value"); - // store registry elements - handleRegistry(user, version, registryName, - RegistryElement.convertNbt(nbtElements), cacheKey); + NBTList nbtElements = compound.getCompoundListTagOrNull("value"); + if (nbtElements != null) { + // store registry elements + handleRegistry(user, version, registryName, + RegistryElement.convertNbt(nbtElements), cacheKey); + } } }