From e7ed66477fbc7fcf17d66db49d6db8e01acafb33 Mon Sep 17 00:00:00 2001 From: KingRainbow44 Date: Sat, 6 Jul 2024 22:54:10 -0400 Subject: [PATCH] fix(networking): Prevent hanging the network loop if an exception occurs --- .../net/impl/NetworkTransportImpl.java | 16 +++++++++++++--- .../emu/grasscutter/server/game/GameSession.java | 5 +++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/main/java/emu/grasscutter/net/impl/NetworkTransportImpl.java b/src/main/java/emu/grasscutter/net/impl/NetworkTransportImpl.java index 7d2837147..afdb91ecc 100644 --- a/src/main/java/emu/grasscutter/net/impl/NetworkTransportImpl.java +++ b/src/main/java/emu/grasscutter/net/impl/NetworkTransportImpl.java @@ -2,6 +2,7 @@ package emu.grasscutter.net.impl; import emu.grasscutter.net.INetworkTransport; import emu.grasscutter.server.game.GameSession; +import emu.grasscutter.utils.Utils; import io.netty.buffer.ByteBuf; import io.netty.channel.DefaultEventLoop; import io.netty.channel.EventLoop; @@ -83,11 +84,20 @@ public class NetworkTransportImpl extends KcpServer implements INetworkTransport return; } - transport.networkLoop.submit(() -> session.onReceived(byteBuf.array())); + // Copy the buffer to avoid reference issues. + var data = Utils.byteBufToArray(byteBuf); + + transport.networkLoop.submit(() -> { + // Fun fact: if we don't catch exceptions here, + // we run the risk of locking the entire network loop. + try { + session.onReceived(data); + } catch (Exception ex) { + session.getLogger().warn("Unable to handle received data.", ex); + } + }); } catch (Exception ex) { NetworkTransportImpl.log.warn("Unable to handle received data.", ex); - } finally { - byteBuf.release(); } } diff --git a/src/main/java/emu/grasscutter/server/game/GameSession.java b/src/main/java/emu/grasscutter/server/game/GameSession.java index 7115317a5..f035eca21 100644 --- a/src/main/java/emu/grasscutter/server/game/GameSession.java +++ b/src/main/java/emu/grasscutter/server/game/GameSession.java @@ -14,6 +14,7 @@ import emu.grasscutter.utils.*; import io.netty.buffer.*; import java.net.InetSocketAddress; import lombok.*; +import org.slf4j.Logger; public class GameSession implements IGameSession { @Getter private final GameServer server; @@ -49,6 +50,10 @@ public class GameSession implements IGameSession { return this.session.getAddress(); } + public Logger getLogger() { + return this.session.getLogger(); + } + public synchronized void setPlayer(Player player) { this.player = player; this.player.setSession(this);