diff --git a/common/src/main/java/com/seibel/distanthorizons/common/AbstractPluginPacketSender.java b/common/src/main/java/com/seibel/distanthorizons/common/AbstractPluginPacketSender.java index fe3618759..d034742d2 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/AbstractPluginPacketSender.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/AbstractPluginPacketSender.java @@ -2,18 +2,21 @@ package com.seibel.distanthorizons.common; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.logging.ConfigBasedLogger; +import com.seibel.distanthorizons.core.network.event.ProtocolErrorEvent; import com.seibel.distanthorizons.core.network.messages.MessageRegistry; import com.seibel.distanthorizons.core.network.messages.NetworkMessage; -import com.seibel.distanthorizons.core.network.INetworkObject; +import com.seibel.distanthorizons.core.network.messages.base.CloseReasonMessage; import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender; import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper; import com.seibel.distanthorizons.coreapi.ModInfo; +import io.netty.buffer.ByteBufUtil; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; import org.apache.logging.log4j.LogManager; import org.jetbrains.annotations.Nullable; +import java.io.IOException; import java.util.Objects; public abstract class AbstractPluginPacketSender implements IPluginPacketSender @@ -43,6 +46,8 @@ public abstract class AbstractPluginPacketSender implements IPluginPacketSender @Nullable public static NetworkMessage decodeMessage(FriendlyByteBuf in) { + NetworkMessage message = null; + try { if (in.readShort() != ModInfo.PROTOCOL_VERSION) @@ -50,24 +55,55 @@ public abstract class AbstractPluginPacketSender implements IPluginPacketSender return null; } - NetworkMessage message = MessageRegistry.INSTANCE.createMessage(in.readUnsignedShort()); - return INetworkObject.decodeToInstance(message, in); + message = MessageRegistry.INSTANCE.createMessage(in.readUnsignedShort()); + message.decode(in); + + if (in.isReadable()) + { + throw new IOException("Buffer has not been fully read"); + } + + return message; } catch (Exception e) { LOGGER.error("Failed to decode message", e); - return null; + LOGGER.error("Buffer: {}", in); + LOGGER.error("Buffer contents: {}", ByteBufUtil.hexDump(in)); + + return new ProtocolErrorEvent(e, message); + } + finally + { + // Prevent connection crashing if not entire buffer has been read + in.readerIndex(in.writerIndex()); } } public static void encodeMessage(FriendlyByteBuf out, NetworkMessage message) { + // This is intentionally unhandled, because errors related to this are unlikely to appear in wild Objects.requireNonNull(message); - out.writeShort(ModInfo.PROTOCOL_VERSION); - out.writeShort(MessageRegistry.INSTANCE.getMessageId(message)); - message.encode(out); + try + { + out.markWriterIndex(); + out.writeShort(MessageRegistry.INSTANCE.getMessageId(message)); + message.encode(out); + } + catch (Exception e) + { + LOGGER.error("Failed to encode message", e); + LOGGER.error("Message: {}", message); + message.session.tryHandleMessage(new ProtocolErrorEvent(e, message)); + + // Encode close reason message instead + out.resetWriterIndex(); + message = new CloseReasonMessage("Internal error on opposing side"); + out.writeShort(MessageRegistry.INSTANCE.getMessageId(message)); + message.encode(out); + } } } \ No newline at end of file diff --git a/coreSubProjects b/coreSubProjects index 71e4cd627..dee13a4ec 160000 --- a/coreSubProjects +++ b/coreSubProjects @@ -1 +1 @@ -Subproject commit 71e4cd62729ce6a98e36ef3cc5b37b5c81db95fd +Subproject commit dee13a4ec470e8ef1b098f8a6569b90033144830 diff --git a/fabric/src/main/java/com/seibel/distanthorizons/fabric/FabricPluginPacketSender.java b/fabric/src/main/java/com/seibel/distanthorizons/fabric/FabricPluginPacketSender.java index 60c2efd2c..dfc923dbf 100644 --- a/fabric/src/main/java/com/seibel/distanthorizons/fabric/FabricPluginPacketSender.java +++ b/fabric/src/main/java/com/seibel/distanthorizons/fabric/FabricPluginPacketSender.java @@ -3,13 +3,14 @@ package com.seibel.distanthorizons.fabric; import com.seibel.distanthorizons.common.AbstractPluginPacketSender; import com.seibel.distanthorizons.core.network.messages.NetworkMessage; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; -import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; -import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerPlayer; #if MC_VER >= MC_1_20_6 import com.seibel.distanthorizons.common.CommonPacketPayload; +#else // < 1.20.6 +import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; +import net.minecraft.network.FriendlyByteBuf; #endif public class FabricPluginPacketSender extends AbstractPluginPacketSender @@ -19,7 +20,7 @@ public class FabricPluginPacketSender extends AbstractPluginPacketSender { #if MC_VER >= MC_1_20_6 ClientPlayNetworking.send(new CommonPacketPayload(message)); - #else + #else // < 1.20.6 FriendlyByteBuf buffer = PacketByteBufs.create(); AbstractPluginPacketSender.encodeMessage(buffer, message); ClientPlayNetworking.send(PLUGIN_CHANNEL_RESOURCE, buffer); @@ -31,7 +32,7 @@ public class FabricPluginPacketSender extends AbstractPluginPacketSender { #if MC_VER >= MC_1_20_6 ServerPlayNetworking.send(serverPlayer, new CommonPacketPayload(message)); - #else + #else // < 1.20.6 FriendlyByteBuf buffer = PacketByteBufs.create(); AbstractPluginPacketSender.encodeMessage(buffer, message); ServerPlayNetworking.send(serverPlayer, PLUGIN_CHANNEL_RESOURCE, buffer);