From cbb30636815eaeceea3d64ccf7738a3ef8d25e5a Mon Sep 17 00:00:00 2001 From: Moulberry Date: Fri, 26 Apr 2024 13:53:52 +0800 Subject: [PATCH 01/10] Add specific error when encoding packet with no registered codec --- .../CustomPayloadPacketCodecMixin.java | 20 +++++++++++++++++-- .../play/NetworkingPlayPacketTest.java | 13 ++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/CustomPayloadPacketCodecMixin.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/CustomPayloadPacketCodecMixin.java index 539264541e..b371b35378 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/CustomPayloadPacketCodecMixin.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/CustomPayloadPacketCodecMixin.java @@ -46,15 +46,31 @@ public void fabric_setPacketCodecProvider(CustomPayloadTypeProvider customPay } @WrapOperation(method = { - "encode(Lnet/minecraft/network/PacketByteBuf;Lnet/minecraft/network/packet/CustomPayload$Id;Lnet/minecraft/network/packet/CustomPayload;)V", "decode(Lnet/minecraft/network/PacketByteBuf;)Lnet/minecraft/network/packet/CustomPayload;" }, at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/CustomPayload$1;getCodec(Lnet/minecraft/util/Identifier;)Lnet/minecraft/network/codec/PacketCodec;")) - private PacketCodec wrapGetCodec(@Coerce PacketCodec instance, Identifier identifier, Operation> original, B packetByteBuf) { + private PacketCodec wrapGetCodecDecode(@Coerce PacketCodec instance, Identifier identifier, Operation> original, B packetByteBuf) { + if (customPayloadTypeProvider != null) { + CustomPayload.Type payloadType = customPayloadTypeProvider.get(packetByteBuf, identifier); + + if (payloadType != null) { + return payloadType.codec(); + } + } + + return original.call(instance, identifier); + } + + @WrapOperation(method = { + "encode(Lnet/minecraft/network/PacketByteBuf;Lnet/minecraft/network/packet/CustomPayload$Id;Lnet/minecraft/network/packet/CustomPayload;)V", + }, at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/CustomPayload$1;getCodec(Lnet/minecraft/util/Identifier;)Lnet/minecraft/network/codec/PacketCodec;")) + private PacketCodec wrapGetCodecEncode(@Coerce PacketCodec instance, Identifier identifier, Operation> original, B packetByteBuf) { if (customPayloadTypeProvider != null) { CustomPayload.Type payloadType = customPayloadTypeProvider.get(packetByteBuf, identifier); if (payloadType != null) { return payloadType.codec(); + } else if (!identifier.getNamespace().equals("minecraft")) { + throw new RuntimeException("Failed to find encoder for custom payload channel \"" + identifier + "\". Are you sure you registered one using PayloadTypeRegistry for both the client and server?"); } } diff --git a/fabric-networking-api-v1/src/testmod/java/net/fabricmc/fabric/test/networking/play/NetworkingPlayPacketTest.java b/fabric-networking-api-v1/src/testmod/java/net/fabricmc/fabric/test/networking/play/NetworkingPlayPacketTest.java index 3cc4305a04..0f1ff5e820 100644 --- a/fabric-networking-api-v1/src/testmod/java/net/fabricmc/fabric/test/networking/play/NetworkingPlayPacketTest.java +++ b/fabric-networking-api-v1/src/testmod/java/net/fabricmc/fabric/test/networking/play/NetworkingPlayPacketTest.java @@ -79,6 +79,10 @@ public static void registerCommand(CommandDispatcher dispat ctx.getSource().sendMessage(Text.literal("Spamming unknown packets state:" + spamUnknownPackets)); return Command.SINGLE_SUCCESS; })) + .then(literal("sendMissingCodec").executes(ctx -> { + ServerPlayNetworking.getSender(ctx.getSource().getPlayer()).sendPacket(new CustomPayloadWithoutCodec()); + return Command.SINGLE_SUCCESS; + })) .then(literal("simple").executes(ctx -> { ServerPlayNetworking.send(ctx.getSource().getPlayer(), new OverlayPacket(Text.literal("simple"))); return Command.SINGLE_SUCCESS; @@ -123,6 +127,15 @@ public void onInitialize() { }); } + public record CustomPayloadWithoutCodec() implements CustomPayload { + public static final CustomPayload.Id ID = new Id<>(NetworkingTestmods.id("no_codec")); + + @Override + public Id getId() { + return ID; + } + } + public record OverlayPacket(Text message) implements CustomPayload { public static final CustomPayload.Id ID = new Id<>(NetworkingTestmods.id("test_channel")); public static final PacketCodec CODEC = CustomPayload.codecOf(OverlayPacket::write, OverlayPacket::new); From efffa6e05c9bc9d8dce8a5982695a6484d93c799 Mon Sep 17 00:00:00 2001 From: Moulberry Date: Fri, 26 Apr 2024 22:02:52 +0800 Subject: [PATCH 02/10] Use different method to throw error which should be more compatible with mods --- .../CustomPayloadPacketCodecMixin.java | 20 ++---------- .../networking/UnknownCustomPayloadMixin.java | 32 +++++++++++++++++++ .../fabric-networking-api-v1.mixins.json | 1 + 3 files changed, 35 insertions(+), 18 deletions(-) create mode 100644 fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/CustomPayloadPacketCodecMixin.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/CustomPayloadPacketCodecMixin.java index b371b35378..539264541e 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/CustomPayloadPacketCodecMixin.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/CustomPayloadPacketCodecMixin.java @@ -45,32 +45,16 @@ public void fabric_setPacketCodecProvider(CustomPayloadTypeProvider customPay this.customPayloadTypeProvider = customPayloadTypeProvider; } - @WrapOperation(method = { - "decode(Lnet/minecraft/network/PacketByteBuf;)Lnet/minecraft/network/packet/CustomPayload;" - }, at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/CustomPayload$1;getCodec(Lnet/minecraft/util/Identifier;)Lnet/minecraft/network/codec/PacketCodec;")) - private PacketCodec wrapGetCodecDecode(@Coerce PacketCodec instance, Identifier identifier, Operation> original, B packetByteBuf) { - if (customPayloadTypeProvider != null) { - CustomPayload.Type payloadType = customPayloadTypeProvider.get(packetByteBuf, identifier); - - if (payloadType != null) { - return payloadType.codec(); - } - } - - return original.call(instance, identifier); - } - @WrapOperation(method = { "encode(Lnet/minecraft/network/PacketByteBuf;Lnet/minecraft/network/packet/CustomPayload$Id;Lnet/minecraft/network/packet/CustomPayload;)V", + "decode(Lnet/minecraft/network/PacketByteBuf;)Lnet/minecraft/network/packet/CustomPayload;" }, at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/CustomPayload$1;getCodec(Lnet/minecraft/util/Identifier;)Lnet/minecraft/network/codec/PacketCodec;")) - private PacketCodec wrapGetCodecEncode(@Coerce PacketCodec instance, Identifier identifier, Operation> original, B packetByteBuf) { + private PacketCodec wrapGetCodec(@Coerce PacketCodec instance, Identifier identifier, Operation> original, B packetByteBuf) { if (customPayloadTypeProvider != null) { CustomPayload.Type payloadType = customPayloadTypeProvider.get(packetByteBuf, identifier); if (payloadType != null) { return payloadType.codec(); - } else if (!identifier.getNamespace().equals("minecraft")) { - throw new RuntimeException("Failed to find encoder for custom payload channel \"" + identifier + "\". Are you sure you registered one using PayloadTypeRegistry for both the client and server?"); } } diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java new file mode 100644 index 0000000000..2672075aff --- /dev/null +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java @@ -0,0 +1,32 @@ +package net.fabricmc.fabric.mixin.networking; + +import com.llamalad7.mixinextras.injector.ModifyReturnValue; + +import net.minecraft.network.PacketByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.packet.CustomPayload; +import net.minecraft.network.packet.UnknownCustomPayload; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Coerce; + +@Mixin(UnknownCustomPayload.class) +public class UnknownCustomPayloadMixin { + + @ModifyReturnValue(method = "createCodec", at = @At("RETURN")) + private static PacketCodec createCodec(@Coerce PacketCodec codec) { + return new PacketCodec<>() { + @Override + public CustomPayload decode(T buf) { + return codec.decode(buf); + } + + @Override + public void encode(T buf, CustomPayload value) { + throw new RuntimeException("Failed to find encoder for custom payload. Are you sure you registered one using PayloadTypeRegistry for both the client and server?"); + } + }; + } + +} diff --git a/fabric-networking-api-v1/src/main/resources/fabric-networking-api-v1.mixins.json b/fabric-networking-api-v1/src/main/resources/fabric-networking-api-v1.mixins.json index 73c21a5583..298f227425 100644 --- a/fabric-networking-api-v1/src/main/resources/fabric-networking-api-v1.mixins.json +++ b/fabric-networking-api-v1/src/main/resources/fabric-networking-api-v1.mixins.json @@ -12,6 +12,7 @@ "EntityTrackerEntryMixin", "LoginQueryRequestS2CPacketMixin", "LoginQueryResponseC2SPacketMixin", + "UnknownCustomPayloadMixin", "PlayerManagerMixin", "ServerCommonNetworkHandlerMixin", "ServerConfigurationNetworkHandlerMixin", From 9fd7ccbab125fbcaaf207b15e8ee7942e353ffbd Mon Sep 17 00:00:00 2001 From: Moulberry Date: Fri, 26 Apr 2024 22:19:07 +0800 Subject: [PATCH 03/10] Fix stylecheck errors --- .../networking/UnknownCustomPayloadMixin.java | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java index 2672075aff..676c46f9ec 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java @@ -1,19 +1,33 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package net.fabricmc.fabric.mixin.networking; import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Coerce; import net.minecraft.network.PacketByteBuf; import net.minecraft.network.codec.PacketCodec; import net.minecraft.network.packet.CustomPayload; import net.minecraft.network.packet.UnknownCustomPayload; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Coerce; - @Mixin(UnknownCustomPayload.class) public class UnknownCustomPayloadMixin { - @ModifyReturnValue(method = "createCodec", at = @At("RETURN")) private static PacketCodec createCodec(@Coerce PacketCodec codec) { return new PacketCodec<>() { @@ -28,5 +42,4 @@ public void encode(T buf, CustomPayload value) { } }; } - } From 5c7d9e54b554b5fd31aa8f19ab43ed8426ddd846 Mon Sep 17 00:00:00 2001 From: Moulberry Date: Fri, 26 Apr 2024 22:20:16 +0800 Subject: [PATCH 04/10] Add payload id to error message --- .../fabric/mixin/networking/UnknownCustomPayloadMixin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java index 676c46f9ec..fe85343177 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java @@ -38,7 +38,7 @@ public CustomPayload decode(T buf) { @Override public void encode(T buf, CustomPayload value) { - throw new RuntimeException("Failed to find encoder for custom payload. Are you sure you registered one using PayloadTypeRegistry for both the client and server?"); + throw new RuntimeException("Failed to find encoder for custom payload '" + value.getId().id() + "'. Are you sure you registered one using PayloadTypeRegistry for both the client and server?"); } }; } From d31b2629453cde3703a9a9e50e2750643705b6d1 Mon Sep 17 00:00:00 2001 From: Moulberry Date: Fri, 26 Apr 2024 22:27:19 +0800 Subject: [PATCH 05/10] Trim error message to be less confusing for end users --- .../fabric/mixin/networking/UnknownCustomPayloadMixin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java index fe85343177..6c2869fbb4 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java @@ -38,7 +38,7 @@ public CustomPayload decode(T buf) { @Override public void encode(T buf, CustomPayload value) { - throw new RuntimeException("Failed to find encoder for custom payload '" + value.getId().id() + "'. Are you sure you registered one using PayloadTypeRegistry for both the client and server?"); + throw new RuntimeException("Failed to find encoder for custom payload '" + value.getId().id() + "'"); } }; } From 4cfb6551c4f23ab2e140662e429b2f84bb5c670f Mon Sep 17 00:00:00 2001 From: Moulberry Date: Fri, 26 Apr 2024 22:29:33 +0800 Subject: [PATCH 06/10] Reword error message --- .../fabric/mixin/networking/UnknownCustomPayloadMixin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java index 6c2869fbb4..8c057512ae 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java @@ -38,7 +38,7 @@ public CustomPayload decode(T buf) { @Override public void encode(T buf, CustomPayload value) { - throw new RuntimeException("Failed to find encoder for custom payload '" + value.getId().id() + "'"); + throw new RuntimeException("Custom payload '" + value.getId().id() + "' has no registered codec"); } }; } From 0c1891e6e02e80bf69fe8180fe8519bc19a4f5da Mon Sep 17 00:00:00 2001 From: Moulberry Date: Wed, 1 May 2024 20:38:18 +0800 Subject: [PATCH 07/10] Add unit test for encoding an unregistered custom payload --- .../unit/PayloadTypeRegistryTests.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/fabric-networking-api-v1/src/test/java/net/fabricmc/fabric/test/networking/unit/PayloadTypeRegistryTests.java b/fabric-networking-api-v1/src/test/java/net/fabricmc/fabric/test/networking/unit/PayloadTypeRegistryTests.java index 60032215a3..4a2327d894 100644 --- a/fabric-networking-api-v1/src/test/java/net/fabricmc/fabric/test/networking/unit/PayloadTypeRegistryTests.java +++ b/fabric-networking-api-v1/src/test/java/net/fabricmc/fabric/test/networking/unit/PayloadTypeRegistryTests.java @@ -16,9 +16,6 @@ package net.fabricmc.fabric.test.networking.unit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; - import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -35,6 +32,8 @@ import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; +import static org.junit.jupiter.api.Assertions.*; + public class PayloadTypeRegistryTests { @BeforeAll static void beforeAll() { @@ -112,6 +111,17 @@ void S2CConfig() { } } + @Test + void handleUnregisteredCustomPayloadError() { + // Create packet with no registered codec + var packetToSend = new CustomPayloadS2CPacket(() -> CustomPayload.id("no_codec")); + + // Should be *exactly* RuntimeException (with our custom message), NOT ClassCastException + assertThrowsExactly(RuntimeException.class, () -> { + CustomPayloadS2CPacket.CONFIGURATION_CODEC.encode(PacketByteBufs.create(), packetToSend); + }); + } + private record C2SPlayPayload(String value) implements CustomPayload { public static final CustomPayload.Id ID = CustomPayload.id("fabric:c2s_play"); public static final PacketCodec CODEC = PacketCodecs.STRING.xmap(C2SPlayPayload::new, C2SPlayPayload::value).cast(); From 1323070b628dff14a61c6359c2d4de23d241065e Mon Sep 17 00:00:00 2001 From: Moulberry Date: Wed, 1 May 2024 20:41:59 +0800 Subject: [PATCH 08/10] Fix checkstyle errors --- .../test/networking/unit/PayloadTypeRegistryTests.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fabric-networking-api-v1/src/test/java/net/fabricmc/fabric/test/networking/unit/PayloadTypeRegistryTests.java b/fabric-networking-api-v1/src/test/java/net/fabricmc/fabric/test/networking/unit/PayloadTypeRegistryTests.java index 4a2327d894..68eff25449 100644 --- a/fabric-networking-api-v1/src/test/java/net/fabricmc/fabric/test/networking/unit/PayloadTypeRegistryTests.java +++ b/fabric-networking-api-v1/src/test/java/net/fabricmc/fabric/test/networking/unit/PayloadTypeRegistryTests.java @@ -16,6 +16,10 @@ package net.fabricmc.fabric.test.networking.unit; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrowsExactly; +import static org.junit.jupiter.api.Assertions.fail; + import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -32,8 +36,6 @@ import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; -import static org.junit.jupiter.api.Assertions.*; - public class PayloadTypeRegistryTests { @BeforeAll static void beforeAll() { From 176b1cbcd4b6664d956a78311ef761d4cd416f67 Mon Sep 17 00:00:00 2001 From: Moulberry Date: Wed, 1 May 2024 20:55:13 +0800 Subject: [PATCH 09/10] Add additional test to ensure that the decode() wrapper is working correctly --- .../networking/unit/PayloadTypeRegistryTests.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/fabric-networking-api-v1/src/test/java/net/fabricmc/fabric/test/networking/unit/PayloadTypeRegistryTests.java b/fabric-networking-api-v1/src/test/java/net/fabricmc/fabric/test/networking/unit/PayloadTypeRegistryTests.java index 68eff25449..9ea514ae3a 100644 --- a/fabric-networking-api-v1/src/test/java/net/fabricmc/fabric/test/networking/unit/PayloadTypeRegistryTests.java +++ b/fabric-networking-api-v1/src/test/java/net/fabricmc/fabric/test/networking/unit/PayloadTypeRegistryTests.java @@ -30,6 +30,7 @@ import net.minecraft.network.codec.PacketCodec; import net.minecraft.network.codec.PacketCodecs; import net.minecraft.network.packet.CustomPayload; +import net.minecraft.network.packet.UnknownCustomPayload; import net.minecraft.network.packet.c2s.common.CustomPayloadC2SPacket; import net.minecraft.network.packet.s2c.common.CustomPayloadS2CPacket; @@ -114,7 +115,7 @@ void S2CConfig() { } @Test - void handleUnregisteredCustomPayloadError() { + void handleUnregisteredCustomPayloadEncodeError() { // Create packet with no registered codec var packetToSend = new CustomPayloadS2CPacket(() -> CustomPayload.id("no_codec")); @@ -124,6 +125,15 @@ void handleUnregisteredCustomPayloadError() { }); } + @Test + void handleUnregisteredCustomPayloadDecodeAsUnknownCustomPayload() { + PacketByteBuf buf = PacketByteBufs.create(); + + buf.writeString("minecraft:no_codec"); + + assertEquals(UnknownCustomPayload.class, CustomPayloadS2CPacket.CONFIGURATION_CODEC.decode(buf).payload().getClass()); + } + private record C2SPlayPayload(String value) implements CustomPayload { public static final CustomPayload.Id ID = CustomPayload.id("fabric:c2s_play"); public static final PacketCodec CODEC = PacketCodecs.STRING.xmap(C2SPlayPayload::new, C2SPlayPayload::value).cast(); From 0434f47f81a0cdf56a5f76ac3e478526183127a6 Mon Sep 17 00:00:00 2001 From: Moulberry Date: Wed, 1 May 2024 21:10:54 +0800 Subject: [PATCH 10/10] Add documentation to mixin explaining the purpose of the fix --- .../mixin/networking/UnknownCustomPayloadMixin.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java index 8c057512ae..799ba75adf 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/UnknownCustomPayloadMixin.java @@ -28,6 +28,19 @@ @Mixin(UnknownCustomPayload.class) public class UnknownCustomPayloadMixin { + /* + This mixin fixes an issue where a CustomPayload with no registered codec throws a confusing ClassCastException + when encoded + + The root cause is that the vanilla encode() method has its second argument as UnknownCustomPayload + Even though the encode() method is empty, Java will still do an implicit cast to UnknownCustomPayload + This will result in a ClassCastException being thrown + + This mixin creates a wrapper around the PacketCodec that uses the base interface CustomPayload as the argument to encode() + Without the explicit `throw new RuntimeException`, this would actually not cause any errors and encoding would succeed + However, it may be confusing for mod developers ("why isn't my packet being serialized?!") + Therefore, we opt to instead throw an explicit error stating that the payload type has no registered codec + */ @ModifyReturnValue(method = "createCodec", at = @At("RETURN")) private static PacketCodec createCodec(@Coerce PacketCodec codec) { return new PacketCodec<>() {