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);