[skip ci] Prevent disconnects on encode/decode/handle errors
This commit is contained in:
+43
-7
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
Submodule coreSubProjects updated: 93b57ae2e1...e62c6a5c55
+5
-4
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user