JasonWang пре 6 година
родитељ
комит
f6d4d0fd6e

+ 17 - 182
src/MineCase.Gateway/Network/ClientSession.cs

@@ -5,11 +5,6 @@ using System.Net.Sockets;
 using System.Text;
 using System.Threading.Tasks;
 using System.Threading.Tasks.Dataflow;
-using MineCase.Gateway.Network.Handler;
-using MineCase.Gateway.Network.Handler.Handshaking;
-using MineCase.Gateway.Network.Handler.Login;
-using MineCase.Gateway.Network.Handler.Play;
-using MineCase.Gateway.Network.Handler.Status;
 using MineCase.Protocol.Protocol;
 using MineCase.Protocol.Protocol.Handshaking.Server;
 using MineCase.Protocol.Protocol.Login.Server;
@@ -22,42 +17,24 @@ namespace MineCase.Gateway.Network
 {
     public class ClientSession : IDisposable
     {
-        private readonly Guid _sessionId;
+        private readonly Guid _sessionId = Guid.NewGuid();
         private TcpClient _tcpClient = null;
         private IClusterClient _client = null;
         private NetworkStream _dataStream = null;
 
-        private volatile bool _useCompression = false;
-        private uint _compressThreshold;
-
         private bool disposed = false;
 
-        private PacketInfo _packetInfo;
-        private PacketEncoder _encoder;
-        private PacketDecoder _decoder;
-        private INetHandler _packetHandler;
-
-        private SessionState _sessionState = SessionState.Handshake;
-
-        private readonly ActionBlock<ISerializablePacket> _outcomingPacketDispatcher;
+        private readonly ActionBlock<RawPacket> _outcomingPacketDispatcher = null;
 
-        private IClientboundPacketObserver _clientboundPacketObserverRef;
+        private IClientboundPacketObserver _clientboundPacketObserverRef = null;
 
         private readonly OutcomingPacketObserver _outcomingPacketObserver;
 
         public ClientSession(TcpClient tcpClient, IClusterClient clusterClient)
         {
-            _sessionId = Guid.NewGuid();
             _tcpClient = tcpClient;
             _client = clusterClient;
-
-            _packetInfo = new PacketInfo();
-            _encoder = new PacketEncoder(PacketDirection.ClientBound, _packetInfo);
-            _decoder = new PacketDecoder(PacketDirection.ServerBound, _packetInfo);
-            _packetHandler = new ServerHandshakeNetHandler(this, _client);
-            _outcomingPacketDispatcher = new ActionBlock<ISerializablePacket>(SendOutcomingPacket);
-
-            _clientboundPacketObserverRef = null;
+            _outcomingPacketDispatcher = new ActionBlock<RawPacket>(SendOutcomingPacket);
             _outcomingPacketObserver = new OutcomingPacketObserver(this);
         }
 
@@ -100,30 +77,6 @@ namespace MineCase.Gateway.Network
         {
         }
 
-        // Switch session state
-        public void SetSessionState(SessionState state)
-        {
-            _sessionState = state;
-        }
-
-        public void SetNetHandler(SessionState state)
-        {
-            switch (state)
-            {
-                case SessionState.Login:
-                    _packetHandler = new ServerLoginNetHandler(this, _client);
-                    break;
-                case SessionState.Status:
-                    _packetHandler = new ServerStatusNetHandler(this, _client);
-                    break;
-                case SessionState.Play:
-                    _packetHandler = new ServerPlayNetHandler(this, _client);
-                    break;
-                default:
-                    throw new NotImplementedException("Invalid intention " + state.ToString());
-            }
-        }
-
         // Startup session
         public async Task Startup()
         {
@@ -155,21 +108,19 @@ namespace MineCase.Gateway.Network
             }
         }
 
-        // Send Packet to game clients
-        public async Task SendPacket(ISerializablePacket packet)
+        // Process raw packet
+        private async Task ProcessPacket()
         {
-            try
-            {
-                if (!_outcomingPacketDispatcher.Completion.IsCompleted)
-                    await _outcomingPacketDispatcher.SendAsync(packet);
-            }
-            catch
-            {
-                _outcomingPacketDispatcher.Complete();
-            }
+            // Read raw packet
+            RawPacket rawPacket = new RawPacket();
+            await rawPacket.DeserializeAsync(_dataStream);
+
+            var router = _client.GetGrain<IPacketRouter>(_sessionId);
+            await router.ProcessPacket(rawPacket);
         }
 
-        public async void DispatchOutcomingPacket(ISerializablePacket packet)
+        // Send Packet to game clients
+        public async void DispatchOutcomingPacket(RawPacket packet)
         {
             try
             {
@@ -182,7 +133,7 @@ namespace MineCase.Gateway.Network
             }
         }
 
-        private async Task SendOutcomingPacket(ISerializablePacket packet)
+        private async Task SendOutcomingPacket(RawPacket packet)
         {
             if (packet == null)
             {
@@ -191,127 +142,11 @@ namespace MineCase.Gateway.Network
             }
             else
             {
-                RawPacket rawPacket = new RawPacket();
-                using (MemoryStream ms = new MemoryStream())
-                {
-                    if (_useCompression)
-                        _encoder.Encode(packet, ms);
-                    else
-                        _encoder.Encode(packet, ms);
-                    rawPacket.RawData = ms.ToArray();
-                    rawPacket.Length = rawPacket.RawData.Length;
-                }
-
                 // System.Console.WriteLine($"Send packet id:{_packetInfo.GetPacketId(packet):x2}, length: {rawPacket.Length}");
-                await rawPacket.SerializeAsync(_dataStream);
-            }
-        }
-
-        // Process packets from game clients
-        private async Task ProcessPacket()
-        {
-            // Read raw packet
-            RawPacket rawPacket = new RawPacket();
-            await rawPacket.DeserializeAsync(_dataStream);
-
-            // Read packet
-            ISerializablePacket packet = null;
-            using (MemoryStream ms = new MemoryStream(rawPacket.RawData))
-            {
-                packet = _decoder.Decode((ProtocolType)_sessionState, ms);
-            }
-
-            switch (_sessionState)
-            {
-                case SessionState.Handshake:
-                    await ProcessHandshakePacket(packet);
-                    break;
-                case SessionState.Login:
-                    await ProcessLoginPacket(packet);
-                    break;
-                case SessionState.Play:
-                    await ProcessPlayPacket(packet);
-                    break;
-                case SessionState.Status:
-                    await ProcessStatusPacket(packet);
-                    break;
-                default:
-                    throw new InvalidDataException($"Invalid session state.");
-            }
-        }
-
-        private async Task ProcessStatusPacket(ISerializablePacket packet)
-        {
-            var handler = (IServerStatusNetHandler)_packetHandler;
-            int packetId = _packetInfo.GetPacketId(packet);
-            switch (packetId)
-            {
-                // request
-                case 0x00:
-                    await handler.ProcessRequest((Request)packet);
-                    break;
-
-                // ping
-                case 0x01:
-                    await handler.ProcessPing((Ping)packet);
-                    break;
-                default:
-                    throw new InvalidDataException($"Unrecognizable packet id: 0x{packetId:X2}.");
+                await packet.SerializeAsync(_dataStream);
             }
         }
 
-        private async Task ProcessHandshakePacket(ISerializablePacket packet)
-        {
-            var handler = (IHandshakeNetHandler)_packetHandler;
-            int packetId = _packetInfo.GetPacketId(packet);
-            switch (packetId)
-            {
-                // handshake
-                case 0x00:
-                    await handler.ProcessHandshake((Handshake)packet);
-                    break;
-                default:
-                    throw new InvalidDataException($"Unrecognizable packet id: 0x{packetId:X2}.");
-            }
-        }
-
-        private async Task ProcessLoginPacket(ISerializablePacket packet)
-        {
-            var handler = (IServerLoginNetHandler)_packetHandler;
-            int packetId = _packetInfo.GetPacketId(packet);
-            switch (packetId)
-            {
-                // Login Start
-                case 0x00:
-                    await handler.ProcessLoginStart((LoginStart)packet);
-                    break;
-
-                // Encryption Response
-                case 0x01:
-                    await handler.ProcessEncryptionResponse((EncryptionResponse)packet);
-                    break;
-                default:
-                    throw new InvalidDataException($"Unrecognizable packet id: 0x{packetId:X2}.");
-            }
-        }
-
-        private Task ProcessPlayPacket(ISerializablePacket packet)
-        {
-            var handler = (IServerPlayNetHandler)_packetHandler;
-            int packetId = _packetInfo.GetPacketId(packet);
-            switch (packetId)
-            {
-                // handshake
-                case 0x00:
-                    // await handler.ProcessHandshake((Handshake)packet);
-                    break;
-                default:
-                    throw new InvalidDataException($"Unrecognizable packet id: 0x{packetId:X2}.");
-            }
-
-            return Task.CompletedTask;
-        }
-
         private class OutcomingPacketObserver : IClientboundPacketObserver
         {
             private readonly ClientSession _session;
@@ -326,7 +161,7 @@ namespace MineCase.Gateway.Network
                 _session.OnClosed();
             }
 
-            public void ReceivePacket(ISerializablePacket packet)
+            public void ReceivePacket(RawPacket packet)
             {
                 _session.DispatchOutcomingPacket(packet);
             }

+ 0 - 20
src/MineCase.Gateway/Network/Handler/Play/ServerPlayNetHandler.cs

@@ -1,20 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Orleans;
-
-namespace MineCase.Gateway.Network.Handler.Play
-{
-    public class ServerPlayNetHandler : IServerPlayNetHandler
-    {
-        private ClientSession _clientSession;
-
-        private IGrainFactory _client;
-
-        public ServerPlayNetHandler(ClientSession session, IGrainFactory client)
-        {
-            _clientSession = session;
-            _client = client;
-        }
-    }
-}

+ 23 - 4
src/MineCase.Server.Grains/Network/ClientboundPacketSink.cs

@@ -1,4 +1,5 @@
 using System;
+using System.IO;
 using System.Threading.Tasks;
 using MineCase.Protocol.Protocol;
 using Orleans;
@@ -10,12 +11,17 @@ namespace MineCase.Server.Network
     {
         private GrainObserverManager<IClientboundPacketObserver> _subsManager;
 
-        public ClientboundPacketSinkGrain()
-        {
-        }
+        private volatile bool _useCompression = false;
+        private uint _compressThreshold;
+
+        private PacketInfo _packetInfo;
+        private PacketEncoder _encoder;
 
         public override Task OnActivateAsync()
         {
+            _packetInfo = new PacketInfo();
+            _encoder = new PacketEncoder(PacketDirection.ClientBound, _packetInfo);
+
             _subsManager = new GrainObserverManager<IClientboundPacketObserver>();
             _subsManager.ExpirationDuration = new TimeSpan(0, 0, 60);
             return base.OnActivateAsync();
@@ -38,9 +44,22 @@ namespace MineCase.Server.Network
         public Task SendPacket(ISerializablePacket packet)
         {
             if (_subsManager.Count == 0)
+            {
                 DeactivateOnIdle();
+            }
             else
-                _subsManager.Notify(n => n.ReceivePacket(packet));
+            {
+                RawPacket rawPacket = new RawPacket();
+                using (MemoryStream ms = new MemoryStream())
+                {
+                    _encoder.Encode(packet, ms);
+                    rawPacket.Length = (int)ms.Length;
+                    rawPacket.RawData = ms.ToArray();
+                }
+
+                _subsManager.Notify(n => n.ReceivePacket(rawPacket));
+            }
+
             return Task.CompletedTask;
         }
 

+ 1 - 1
src/MineCase.Gateway/Network/Handler/Handshaking/IHandshakeNetHandler.cs → src/MineCase.Server.Grains/Network/Handler/Handshaking/IHandshakeNetHandler.cs

@@ -4,7 +4,7 @@ using System.Text;
 using System.Threading.Tasks;
 using MineCase.Protocol.Protocol.Handshaking.Server;
 
-namespace MineCase.Gateway.Network.Handler.Handshaking
+namespace MineCase.Server.Network.Handler.Handshaking
 {
     public interface IHandshakeNetHandler : INetHandler
     {

+ 13 - 13
src/MineCase.Gateway/Network/Handler/Handshaking/ServerHandshakeNetHandler.cs → src/MineCase.Server.Grains/Network/Handler/Handshaking/ServerHandshakeNetHandler.cs

@@ -2,58 +2,58 @@
 using System.Collections.Generic;
 using System.Text;
 using System.Threading.Tasks;
-using MineCase.Gateway.Network.Handler.Status;
 using MineCase.Protocol.Protocol;
 using MineCase.Protocol.Protocol.Handshaking.Server;
 using Orleans;
 
-namespace MineCase.Gateway.Network.Handler.Handshaking
+namespace MineCase.Server.Network.Handler.Handshaking
 {
     public class ServerHandshakeNetHandler : IHandshakeNetHandler
     {
-        private ClientSession _clientSession;
+        private IPacketRouter _clientSession;
+
+        private IClientboundPacketSink _packetSink;
 
         private IGrainFactory _client;
 
-        public ServerHandshakeNetHandler(ClientSession session, IGrainFactory client)
+        public ServerHandshakeNetHandler(IPacketRouter session, IClientboundPacketSink packetSink, IGrainFactory client)
         {
             _clientSession = session;
+            _packetSink = packetSink;
             _client = client;
         }
 
-        public Task ProcessHandshake(Handshake packet)
+        public async Task ProcessHandshake(Handshake packet)
         {
             if (packet.NextState == (int)SessionState.Login)
             {
-                _clientSession.SetSessionState(SessionState.Login);
+                await _clientSession.SetSessionState(SessionState.Login);
                 if (packet.ProtocolVersion > Protocol.Protocol.Protocol.Version)
                 {
                     // ITextComponent itextcomponent = new TranslationTextComponent("multiplayer.disconnect.outdated_server", SharedConstants.getVersion().getName());
                     // this.networkManager.sendPacket(new SDisconnectLoginPacket(itextcomponent));
-                    _clientSession.Close();
+                    await _packetSink.Close();
                 }
                 else if (packet.ProtocolVersion > Protocol.Protocol.Protocol.Version)
                 {
                     // ITextComponent itextcomponent1 = new TranslationTextComponent("multiplayer.disconnect.outdated_client", SharedConstants.getVersion().getName());
                     // this.networkManager.sendPacket(new SDisconnectLoginPacket(itextcomponent1));
-                    _clientSession.Close();
+                    await _packetSink.Close();
                 }
                 else
                 {
-                    _clientSession.SetNetHandler(SessionState.Login);
+                    await _clientSession.SetNetHandler(SessionState.Login);
                 }
             }
             else if (packet.NextState == (int)SessionState.Status)
             {
-                _clientSession.SetSessionState(SessionState.Status);
-                _clientSession.SetNetHandler(SessionState.Status);
+                await _clientSession.SetSessionState(SessionState.Status);
+                await _clientSession.SetNetHandler(SessionState.Status);
             }
             else
             {
                 throw new NotImplementedException("Invalid intention " + packet.NextState.ToString());
             }
-
-            return Task.CompletedTask;
         }
     }
 }

+ 1 - 1
src/MineCase.Gateway/Network/Handler/INetHandler.cs → src/MineCase.Server.Grains/Network/Handler/INetHandler.cs

@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 using System.Text;
 
-namespace MineCase.Gateway.Network.Handler
+namespace MineCase.Server.Network.Handler
 {
     public interface INetHandler
     {

+ 1 - 1
src/MineCase.Gateway/Network/Handler/Login/IServerLoginNetHandler.cs → src/MineCase.Server.Grains/Network/Handler/Login/IServerLoginNetHandler.cs

@@ -4,7 +4,7 @@ using System.Text;
 using System.Threading.Tasks;
 using MineCase.Protocol.Protocol.Login.Server;
 
-namespace MineCase.Gateway.Network.Handler.Login
+namespace MineCase.Server.Network.Handler.Login
 {
     public interface IServerLoginNetHandler : INetHandler
     {

+ 9 - 6
src/MineCase.Gateway/Network/Handler/Login/ServerLoginNetHandler.cs → src/MineCase.Server.Grains/Network/Handler/Login/ServerLoginNetHandler.cs

@@ -9,7 +9,7 @@ using MineCase.Protocol.Protocol.Login.Server;
 using MineCase.Server.Server;
 using Orleans;
 
-namespace MineCase.Gateway.Network.Handler.Login
+namespace MineCase.Server.Network.Handler.Login
 {
     public enum LoginState
     {
@@ -23,7 +23,9 @@ namespace MineCase.Gateway.Network.Handler.Login
 
     public class ServerLoginNetHandler : IServerLoginNetHandler
     {
-        private ClientSession _clientSession;
+        private IPacketRouter _clientSession;
+
+        private IClientboundPacketSink _packetSink;
 
         private IGrainFactory _client;
 
@@ -31,9 +33,10 @@ namespace MineCase.Gateway.Network.Handler.Login
 
         private GameProfile _gameProfile;
 
-        public ServerLoginNetHandler(ClientSession session, IGrainFactory client)
+        public ServerLoginNetHandler(IPacketRouter session, IClientboundPacketSink packetSink, IGrainFactory client)
         {
             _clientSession = session;
+            _packetSink = packetSink;
             _client = client;
             _loginState = LoginState.Hello;
             _gameProfile = new GameProfile();
@@ -83,13 +86,13 @@ namespace MineCase.Gateway.Network.Handler.Login
                 Username = _gameProfile.Name,
             };
 
-            await _clientSession.SendPacket(successPacket);
+            await _packetSink.SendPacket(successPacket);
 
             // Change session state
-            _clientSession.SetSessionState(SessionState.Play);
+            await _clientSession.SetSessionState(SessionState.Play);
 
             // Set net handler
-            _clientSession.SetNetHandler(SessionState.Play);
+            await _clientSession.SetNetHandler(SessionState.Play);
         }
     }
 }

+ 1 - 1
src/MineCase.Gateway/Network/Handler/Play/IServerPlayNetHandler.cs → src/MineCase.Server.Grains/Network/Handler/Play/IServerPlayNetHandler.cs

@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 using System.Text;
 
-namespace MineCase.Gateway.Network.Handler.Play
+namespace MineCase.Server.Network.Handler.Play
 {
     public interface IServerPlayNetHandler : INetHandler
     {

+ 23 - 0
src/MineCase.Server.Grains/Network/Handler/Play/ServerPlayNetHandler.cs

@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Orleans;
+
+namespace MineCase.Server.Network.Handler.Play
+{
+    public class ServerPlayNetHandler : IServerPlayNetHandler
+    {
+        private IPacketRouter _clientSession;
+
+        private IClientboundPacketSink _packetSink;
+
+        private IGrainFactory _client;
+
+        public ServerPlayNetHandler(IPacketRouter session, IClientboundPacketSink packetSink, IGrainFactory client)
+        {
+            _clientSession = session;
+            _packetSink = packetSink;
+            _client = client;
+        }
+    }
+}

+ 1 - 1
src/MineCase.Gateway/Network/Handler/Status/IServerStatusNetHandler.cs → src/MineCase.Server.Grains/Network/Handler/Status/IServerStatusNetHandler.cs

@@ -4,7 +4,7 @@ using System.Text;
 using System.Threading.Tasks;
 using MineCase.Protocol.Protocol.Status.Server;
 
-namespace MineCase.Gateway.Network.Handler.Status
+namespace MineCase.Server.Network.Handler.Status
 {
     public interface IServerStatusNetHandler : INetHandler
     {

+ 8 - 5
src/MineCase.Gateway/Network/Handler/Status/ServerStatusNetHandler.cs → src/MineCase.Server.Grains/Network/Handler/Status/ServerStatusNetHandler.cs

@@ -6,17 +6,20 @@ using MineCase.Protocol.Protocol.Status.Client;
 using MineCase.Protocol.Protocol.Status.Server;
 using Orleans;
 
-namespace MineCase.Gateway.Network.Handler.Status
+namespace MineCase.Server.Network.Handler.Status
 {
     public class ServerStatusNetHandler : IServerStatusNetHandler
     {
-        private ClientSession _clientSession;
+        private IPacketRouter _clientSession;
+
+        private IClientboundPacketSink _packetSink;
 
         private IGrainFactory _client;
 
-        public ServerStatusNetHandler(ClientSession session, IGrainFactory client)
+        public ServerStatusNetHandler(IPacketRouter session, IClientboundPacketSink packetSink, IGrainFactory client)
         {
             _clientSession = session;
+            _packetSink = packetSink;
             _client = client;
         }
 
@@ -24,7 +27,7 @@ namespace MineCase.Gateway.Network.Handler.Status
         {
             var pong = new Pong();
             pong.Payload = packetIn.Payload;
-            return _clientSession.SendPacket(pong);
+            return _packetSink.SendPacket(pong);
         }
 
         public Task ProcessRequest(Request packetIn)
@@ -40,7 +43,7 @@ namespace MineCase.Gateway.Network.Handler.Status
         ""sample"": []
     }, ""description"": { ""text"": ""Hello MineCase""}
 }";
-            return _clientSession.SendPacket(reponse);
+            return _packetSink.SendPacket(reponse);
         }
     }
 }

+ 175 - 0
src/MineCase.Server.Grains/Network/PacketRouter.cs

@@ -0,0 +1,175 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+using MineCase.Protocol.Protocol;
+using MineCase.Protocol.Protocol.Handshaking.Server;
+using MineCase.Protocol.Protocol.Login.Server;
+using MineCase.Protocol.Protocol.Status.Server;
+using MineCase.Server.Network.Handler;
+using MineCase.Server.Network.Handler.Handshaking;
+using MineCase.Server.Network.Handler.Login;
+using MineCase.Server.Network.Handler.Play;
+using MineCase.Server.Network.Handler.Status;
+using Orleans;
+
+namespace MineCase.Server.Network
+{
+    public class PacketRouter : Grain, IPacketRouter
+    {
+        private PacketInfo _packetInfo;
+        private PacketDecoder _decoder;
+        private INetHandler _packetHandler;
+
+        private SessionState _sessionState = SessionState.Handshake;
+
+        public override Task OnActivateAsync()
+        {
+            _packetInfo = new PacketInfo();
+            _decoder = new PacketDecoder(PacketDirection.ServerBound, _packetInfo);
+            _packetHandler = new ServerHandshakeNetHandler(
+                GrainFactory.GetGrain<IPacketRouter>(this.GetPrimaryKey()),
+                GrainFactory.GetGrain<IClientboundPacketSink>(this.GetPrimaryKey()),
+                GrainFactory);
+            return base.OnActivateAsync();
+        }
+
+        // Switch session state
+        public Task SetSessionState(SessionState state)
+        {
+            _sessionState = state;
+            return Task.CompletedTask;
+        }
+
+        public Task SetNetHandler(SessionState state)
+        {
+            switch (state)
+            {
+                case SessionState.Login:
+                    _packetHandler = new ServerLoginNetHandler(
+                        GrainFactory.GetGrain<IPacketRouter>(this.GetPrimaryKey()),
+                        GrainFactory.GetGrain<IClientboundPacketSink>(this.GetPrimaryKey()),
+                        GrainFactory);
+                    break;
+                case SessionState.Status:
+                    _packetHandler = new ServerStatusNetHandler(
+                        GrainFactory.GetGrain<IPacketRouter>(this.GetPrimaryKey()),
+                        GrainFactory.GetGrain<IClientboundPacketSink>(this.GetPrimaryKey()),
+                        GrainFactory);
+                    break;
+                case SessionState.Play:
+                    _packetHandler = new ServerPlayNetHandler(
+                        GrainFactory.GetGrain<IPacketRouter>(this.GetPrimaryKey()),
+                        GrainFactory.GetGrain<IClientboundPacketSink>(this.GetPrimaryKey()),
+                        GrainFactory);
+                    break;
+                default:
+                    throw new NotImplementedException("Invalid intention " + state.ToString());
+            }
+
+            return Task.CompletedTask;
+        }
+
+        // Process packets from game clients
+        public async Task ProcessPacket(RawPacket rawPacket)
+        {
+            // Read packet
+            ISerializablePacket packet = null;
+            using (MemoryStream ms = new MemoryStream(rawPacket.RawData))
+            {
+                packet = _decoder.Decode((ProtocolType)_sessionState, ms);
+            }
+
+            switch (_sessionState)
+            {
+                case SessionState.Handshake:
+                    await ProcessHandshakePacket(packet);
+                    break;
+                case SessionState.Login:
+                    await ProcessLoginPacket(packet);
+                    break;
+                case SessionState.Play:
+                    await ProcessPlayPacket(packet);
+                    break;
+                case SessionState.Status:
+                    await ProcessStatusPacket(packet);
+                    break;
+                default:
+                    throw new InvalidDataException($"Invalid session state.");
+            }
+        }
+
+        private async Task ProcessStatusPacket(ISerializablePacket packet)
+        {
+            var handler = (IServerStatusNetHandler)_packetHandler;
+            int packetId = _packetInfo.GetPacketId(packet);
+            switch (packetId)
+            {
+                // request
+                case 0x00:
+                    await handler.ProcessRequest((Request)packet);
+                    break;
+
+                // ping
+                case 0x01:
+                    await handler.ProcessPing((Ping)packet);
+                    break;
+                default:
+                    throw new InvalidDataException($"Unrecognizable packet id: 0x{packetId:X2}.");
+            }
+        }
+
+        private async Task ProcessHandshakePacket(ISerializablePacket packet)
+        {
+            var handler = (IHandshakeNetHandler)_packetHandler;
+            int packetId = _packetInfo.GetPacketId(packet);
+            switch (packetId)
+            {
+                // handshake
+                case 0x00:
+                    await handler.ProcessHandshake((Handshake)packet);
+                    break;
+                default:
+                    throw new InvalidDataException($"Unrecognizable packet id: 0x{packetId:X2}.");
+            }
+        }
+
+        private async Task ProcessLoginPacket(ISerializablePacket packet)
+        {
+            var handler = (IServerLoginNetHandler)_packetHandler;
+            int packetId = _packetInfo.GetPacketId(packet);
+            switch (packetId)
+            {
+                // Login Start
+                case 0x00:
+                    await handler.ProcessLoginStart((LoginStart)packet);
+                    break;
+
+                // Encryption Response
+                case 0x01:
+                    await handler.ProcessEncryptionResponse((EncryptionResponse)packet);
+                    break;
+                default:
+                    throw new InvalidDataException($"Unrecognizable packet id: 0x{packetId:X2}.");
+            }
+        }
+
+        private Task ProcessPlayPacket(ISerializablePacket packet)
+        {
+            var handler = (IServerPlayNetHandler)_packetHandler;
+            int packetId = _packetInfo.GetPacketId(packet);
+            switch (packetId)
+            {
+                // handshake
+                case 0x00:
+                    // await handler.ProcessHandshake((Handshake)packet);
+                    break;
+                default:
+                    throw new InvalidDataException($"Unrecognizable packet id: 0x{packetId:X2}.");
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+}

+ 1 - 1
src/MineCase.Server.Interfaces/Network/IClientboundPacketObserver.cs

@@ -9,7 +9,7 @@ namespace MineCase.Server.Network
 {
     public interface IClientboundPacketObserver : IGrainObserver
     {
-        void ReceivePacket(ISerializablePacket packet);
+        void ReceivePacket(RawPacket packet);
 
         void OnClosed();
     }

+ 18 - 0
src/MineCase.Server.Interfaces/Network/IPacketRouter.cs

@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using MineCase.Protocol.Protocol;
+using Orleans;
+
+namespace MineCase.Server.Network
+{
+    public interface IPacketRouter : IGrainWithGuidKey
+    {
+        Task SetSessionState(SessionState state);
+
+        Task SetNetHandler(SessionState state);
+
+        Task ProcessPacket(RawPacket rawPacket);
+    }
+}