瀏覽代碼

ping pong support

JasonWang 6 年之前
父節點
當前提交
14bea411af
共有 43 個文件被更改,包括 658 次插入78 次删除
  1. 27 0
      src/MineCase.Core/Game/GameProfile.cs
  2. 10 0
      src/MineCase.Core/Util/Text/IText.cs
  3. 10 0
      src/MineCase.Core/Util/Text/StandardText.cs
  4. 10 0
      src/MineCase.Core/Util/Text/Style.cs
  5. 15 0
      src/MineCase.Core/World/GameType.cs
  6. 0 5
      src/MineCase.Gateway/MineCase.Gateway.csproj
  7. 38 9
      src/MineCase.Gateway/Network/ClientSession.cs
  8. 1 1
      src/MineCase.Gateway/Network/Handler/Handshaking/IHandshakeNetHandler.cs
  9. 6 3
      src/MineCase.Gateway/Network/Handler/Handshaking/ServerHandshakeNetHandler.cs
  10. 15 0
      src/MineCase.Gateway/Network/Handler/Login/IServerLoginNetHandler.cs
  11. 88 0
      src/MineCase.Gateway/Network/Handler/Login/ServerLoginNetHandler.cs
  12. 10 0
      src/MineCase.Gateway/Network/Handler/Play/IServerPlayNetHandler.cs
  13. 20 0
      src/MineCase.Gateway/Network/Handler/Play/ServerPlayNetHandler.cs
  14. 6 3
      src/MineCase.Gateway/Network/Handler/Status/ServerStatusNetHandler.cs
  15. 5 0
      src/MineCase.Protocol/MineCase.Protocol.csproj
  16. 2 3
      src/MineCase.Protocol/Protocol/Handshaking/Server/Handshake.cs
  17. 45 0
      src/MineCase.Protocol/Protocol/Login/Client/EncryptionRequest.cs
  18. 25 0
      src/MineCase.Protocol/Protocol/Login/Client/LoginDisconnect.cs
  19. 21 0
      src/MineCase.Protocol/Protocol/Login/Client/LoginPluginRequest.cs
  20. 30 0
      src/MineCase.Protocol/Protocol/Login/Client/LoginSuccess.cs
  21. 25 0
      src/MineCase.Protocol/Protocol/Login/Client/SetCompression.cs
  22. 34 0
      src/MineCase.Protocol/Protocol/Login/Server/EncryptionResponse.cs
  23. 31 0
      src/MineCase.Protocol/Protocol/Login/Server/LoginPluginResponse.cs
  24. 25 0
      src/MineCase.Protocol/Protocol/Login/Server/LoginStart.cs
  25. 8 3
      src/MineCase.Protocol/Protocol/Packet.cs
  26. 3 2
      src/MineCase.Protocol/Protocol/PacketDecoder.cs
  27. 1 1
      src/MineCase.Protocol/Protocol/PacketEncoder.cs
  28. 49 29
      src/MineCase.Protocol/Protocol/ProtocolType.cs
  29. 0 1
      src/MineCase.Protocol/Protocol/SessionState.cs
  30. 1 2
      src/MineCase.Protocol/Protocol/Status/Client/Pong.cs
  31. 1 2
      src/MineCase.Protocol/Protocol/Status/Client/Response.cs
  32. 1 2
      src/MineCase.Protocol/Protocol/Status/Server/Ping.cs
  33. 1 1
      src/MineCase.Protocol/Protocol/Status/Server/Request.cs
  34. 6 1
      src/MineCase.Protocol/Serialization/BinaryReaderExtensions.cs
  35. 1 1
      src/MineCase.Protocol/Serialization/BinaryWriterExtensions.cs
  36. 1 1
      src/MineCase.Protocol/Serialization/DataType.cs
  37. 10 0
      src/MineCase.Server.Grains/Entity/Entity.cs
  38. 10 0
      src/MineCase.Server.Grains/Entity/Player/PlayerEntity.cs
  39. 0 4
      src/MineCase.Server.Grains/MineCase.Server.Grains.csproj
  40. 30 0
      src/MineCase.Server.Grains/Server/Management/ManagementSettings.cs
  41. 21 0
      src/MineCase.Server.Grains/Server/MinecraftServer.cs
  42. 0 4
      src/MineCase.Server.Interfaces/MineCase.Server.Interfaces.csproj
  43. 15 0
      src/MineCase.Server.Interfaces/Server/IMinecraftServer.cs

+ 27 - 0
src/MineCase.Core/Game/GameProfile.cs

@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MineCase.Core.Game
+{
+    public class GameProfile
+    {
+        public string UUID { get; set; } = null;
+
+        public string Name { get; set; } = null;
+
+        public GameProfile()
+        {
+        }
+
+        public GameProfile(string uuid, string name)
+        {
+            UUID = uuid;
+            Name = name;
+        }
+
+        public bool Complete{
+            get { return UUID != null && Name != null; }
+        }
+    }
+}

+ 10 - 0
src/MineCase.Core/Util/Text/IText.cs

@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MineCase.Core.Util.Text
+{
+    public class IText
+    {
+    }
+}

+ 10 - 0
src/MineCase.Core/Util/Text/StandardText.cs

@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MineCase.Core.Util.Text
+{
+    public class StandardText
+    {
+    }
+}

+ 10 - 0
src/MineCase.Core/Util/Text/Style.cs

@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MineCase.Core.Util.Text
+{
+    public class Style
+    {
+    }
+}

+ 15 - 0
src/MineCase.Core/World/GameType.cs

@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MineCase.Core.World
+{
+    public enum GameType
+    {
+        NotSet = -1,
+        Survival = 0,
+        Creative = 1,
+        Adventure = 2,
+        Spectator = 3,
+    }
+}

+ 0 - 5
src/MineCase.Gateway/MineCase.Gateway.csproj

@@ -34,9 +34,4 @@
     <ProjectReference Include="..\MineCase.Server.Interfaces\MineCase.Server.Interfaces.csproj" />
   </ItemGroup>
 
-  <ItemGroup>
-    <Folder Include="Network\Handler\Play\" />
-    <Folder Include="Network\Handler\Login\" />
-  </ItemGroup>
-
 </Project>

+ 38 - 9
src/MineCase.Gateway/Network/ClientSession.cs

@@ -7,9 +7,12 @@ 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.Handshaking;
 using MineCase.Protocol.Protocol;
+using MineCase.Protocol.Protocol.Handshaking.Server;
+using MineCase.Protocol.Protocol.Login.Server;
 using MineCase.Protocol.Protocol.Status.Server;
 using Orleans;
 using ProtocolType = MineCase.Protocol.Protocol.ProtocolType;
@@ -46,7 +49,7 @@ namespace MineCase.Gateway.Network
             _packetInfo = new PacketInfo();
             _encoder = new PacketEncoder(PacketDirection.ClientBound, _packetInfo);
             _decoder = new PacketDecoder(PacketDirection.ServerBound, _packetInfo);
-            _packetHandler = new ServerHandshakeNetHandler(this);
+            _packetHandler = new ServerHandshakeNetHandler(this, _client);
             _outcomingPacketDispatcher = new ActionBlock<ISerializablePacket>(SendOutcomingPacket);
         }
 
@@ -100,13 +103,13 @@ namespace MineCase.Gateway.Network
             switch (state)
             {
                 case SessionState.Login:
-                    throw new NotImplementedException();
+                    _packetHandler = new ServerLoginNetHandler(this, _client);
                     break;
                 case SessionState.Status:
-                    _packetHandler = new ServerStatusNetHandler(this);
+                    _packetHandler = new ServerStatusNetHandler(this, _client);
                     break;
                 case SessionState.Play:
-                    throw new NotImplementedException();
+                    _packetHandler = new ServerPlayNetHandler(this, _client);
                     break;
                 default:
                     throw new NotImplementedException("Invalid intention " + state.ToString());
@@ -166,8 +169,7 @@ namespace MineCase.Gateway.Network
                     rawPacket.Length = rawPacket.RawData.Length;
                 }
 
-                System.Console.WriteLine($"Send packet id:{_packetInfo.GetPacketId(packet):x2}, length: {rawPacket.Length}");
-
+                // System.Console.WriteLine($"Send packet id:{_packetInfo.GetPacketId(packet):x2}, length: {rawPacket.Length}");
                 await rawPacket.SerializeAsync(_dataStream);
             }
         }
@@ -240,13 +242,40 @@ namespace MineCase.Gateway.Network
             }
         }
 
-        private Task ProcessLoginPacket(ISerializablePacket packet)
+        private async Task ProcessLoginPacket(ISerializablePacket packet)
         {
-            return Task.CompletedTask;
+            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.Gateway/Network/Handler/Handshaking/IHandshakeNetHandler.cs

@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 using System.Text;
 using System.Threading.Tasks;
-using MineCase.Protocol.Handshaking;
+using MineCase.Protocol.Protocol.Handshaking.Server;
 
 namespace MineCase.Gateway.Network.Handler.Handshaking
 {

+ 6 - 3
src/MineCase.Gateway/Network/Handler/Handshaking/ServerHandshakeNetHandler.cs

@@ -3,9 +3,9 @@ using System.Collections.Generic;
 using System.Text;
 using System.Threading.Tasks;
 using MineCase.Gateway.Network.Handler.Status;
-using MineCase.Protocol.Handshaking;
 using MineCase.Protocol.Protocol;
-using MineCase.Protocol.Protocol.Status.Server;
+using MineCase.Protocol.Protocol.Handshaking.Server;
+using Orleans;
 
 namespace MineCase.Gateway.Network.Handler.Handshaking
 {
@@ -13,9 +13,12 @@ namespace MineCase.Gateway.Network.Handler.Handshaking
     {
         private ClientSession _clientSession;
 
-        public ServerHandshakeNetHandler(ClientSession session)
+        private IGrainFactory _client;
+
+        public ServerHandshakeNetHandler(ClientSession session, IGrainFactory client)
         {
             _clientSession = session;
+            _client = client;
         }
 
         public Task ProcessHandshake(Handshake packet)

+ 15 - 0
src/MineCase.Gateway/Network/Handler/Login/IServerLoginNetHandler.cs

@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using MineCase.Protocol.Protocol.Login.Server;
+
+namespace MineCase.Gateway.Network.Handler.Login
+{
+    public interface IServerLoginNetHandler : INetHandler
+    {
+        Task ProcessLoginStart(LoginStart packet);
+
+        Task ProcessEncryptionResponse(EncryptionResponse packet);
+    }
+}

+ 88 - 0
src/MineCase.Gateway/Network/Handler/Login/ServerLoginNetHandler.cs

@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using MineCase.Core.Game;
+using MineCase.Protocol.Protocol.Login.Client;
+using MineCase.Protocol.Protocol.Login.Server;
+using MineCase.Server.Server;
+using Orleans;
+
+namespace MineCase.Gateway.Network.Handler.Login
+{
+    public enum LoginState
+    {
+        Hello,
+        Key,
+        Authenticating,
+        ReadyToAccept,
+        DelayAccept,
+        Accepted,
+    }
+
+    public class ServerLoginNetHandler : IServerLoginNetHandler
+    {
+        private ClientSession _clientSession;
+
+        private IGrainFactory _client;
+
+        private LoginState _loginState;
+
+        private GameProfile _gameProfile;
+
+        public ServerLoginNetHandler(ClientSession session, IGrainFactory client)
+        {
+            _clientSession = session;
+            _client = client;
+            _loginState = LoginState.Hello;
+            _gameProfile = new GameProfile();
+        }
+
+        public Task ProcessEncryptionResponse(EncryptionResponse packet)
+        {
+            throw new NotImplementedException();
+        }
+
+        public async Task ProcessLoginStart(LoginStart packet)
+        {
+            if (_loginState != LoginState.Hello)
+                throw new InvalidOperationException("ProcessLoginStart: Invalid login state.");
+            _gameProfile = new GameProfile(null, packet.Name);
+            var server = _client.GetGrain<IMinecraftServer>("Default");
+
+            if (await server.GetOnlineMode())
+            {
+                throw new NotImplementedException("ProcessLoginStart: Online mode is not implemented.");
+            }
+            else
+            {
+                _loginState = LoginState.ReadyToAccept;
+                await TryAcceptPlayer();
+            }
+        }
+
+        private async Task TryAcceptPlayer()
+        {
+            if (!_gameProfile.Complete)
+            {
+                // Offline profile
+                _gameProfile = new GameProfile(Guid.NewGuid().ToString(), _gameProfile.Name);
+            }
+
+            _loginState = LoginState.Accepted;
+            var server = _client.GetGrain<IMinecraftServer>("Default");
+            if (await server.GetNetworkCompressionThreshold() >= 0)
+            {
+                throw new NotImplementedException("TryAcceptPlayer: Packet compression is not implemented.");
+            }
+
+            LoginSuccess successPacket = new LoginSuccess
+            {
+                UUID = _gameProfile.UUID,
+                Username = _gameProfile.Name,
+            };
+
+            await _clientSession.SendPacket(successPacket);
+        }
+    }
+}

+ 10 - 0
src/MineCase.Gateway/Network/Handler/Play/IServerPlayNetHandler.cs

@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MineCase.Gateway.Network.Handler.Play
+{
+    public interface IServerPlayNetHandler : INetHandler
+    {
+    }
+}

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

@@ -0,0 +1,20 @@
+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;
+        }
+    }
+}

+ 6 - 3
src/MineCase.Gateway/Network/Handler/Status/ServerStatusNetHandler.cs

@@ -4,6 +4,7 @@ using System.Text;
 using System.Threading.Tasks;
 using MineCase.Protocol.Protocol.Status.Client;
 using MineCase.Protocol.Protocol.Status.Server;
+using Orleans;
 
 namespace MineCase.Gateway.Network.Handler.Status
 {
@@ -11,9 +12,12 @@ namespace MineCase.Gateway.Network.Handler.Status
     {
         private ClientSession _clientSession;
 
-        public ServerStatusNetHandler(ClientSession session)
+        private IGrainFactory _client;
+
+        public ServerStatusNetHandler(ClientSession session, IGrainFactory client)
         {
             _clientSession = session;
+            _client = client;
         }
 
         public Task ProcessPing(Ping packetIn)
@@ -34,8 +38,7 @@ namespace MineCase.Gateway.Network.Handler.Status
         ""max"": 100,
         ""online"": 0,
         ""sample"": []
-    }, ""description"": { ""text"": ""Hello MineCase""},
-""favicon"": null
+    }, ""description"": { ""text"": ""Hello MineCase""}
 }";
             return _clientSession.SendPacket(reponse);
         }

+ 5 - 0
src/MineCase.Protocol/MineCase.Protocol.csproj

@@ -28,4 +28,9 @@
     <ProjectReference Include="..\MineCase.Core\MineCase.Core.csproj" />
   </ItemGroup>
 
+  <ItemGroup>
+    <Folder Include="Protocol\Play\Server\" />
+    <Folder Include="Protocol\Play\Client\" />
+  </ItemGroup>
+
 </Project>

+ 2 - 3
src/MineCase.Protocol/Protocol/Handshaking/Handshake.cs → src/MineCase.Protocol/Protocol/Handshaking/Server/Handshake.cs

@@ -3,12 +3,11 @@ using System.Collections.Generic;
 using System.IO;
 using System.Text;
 using MineCase.Protocol.Protocol;
-using MineCase.Protocol.Serialization;
 using MineCase.Serialization;
 
-namespace MineCase.Protocol.Handshaking
+namespace MineCase.Protocol.Protocol.Handshaking.Server
 {
-    [Packet(0x00)]
+    [Packet(0x00, ProtocolType.Handshake, PacketDirection.ServerBound)]
     public sealed class Handshake : ISerializablePacket
     {
         [SerializeAs(DataType.VarInt)]

+ 45 - 0
src/MineCase.Protocol/Protocol/Login/Client/EncryptionRequest.cs

@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using MineCase.Serialization;
+
+namespace MineCase.Protocol.Protocol.Login.Client
+{
+    [Packet(0x01, ProtocolType.Login, PacketDirection.ClientBound)]
+    public sealed class EncryptionRequest : ISerializablePacket
+    {
+        [SerializeAs(DataType.String)]
+        public string ServerID;
+
+        [SerializeAs(DataType.VarInt)]
+        public int PublicKeyLength;
+
+        [SerializeAs(DataType.ByteArray)]
+        public byte[] PublicKey;
+
+        [SerializeAs(DataType.VarInt)]
+        public int VerifyTokenLength;
+
+        [SerializeAs(DataType.ByteArray)]
+        public byte[] VerifyToken;
+
+        public void Deserialize(BinaryReader br)
+        {
+            ServerID = br.ReadAsString();
+            PublicKeyLength = br.ReadAsVarInt(out _);
+            PublicKey = br.ReadAsByteArray(PublicKeyLength);
+            VerifyTokenLength = br.ReadAsVarInt(out _);
+            VerifyToken = br.ReadAsByteArray(VerifyTokenLength);
+        }
+
+        public void Serialize(BinaryWriter bw)
+        {
+            bw.WriteAsString(ServerID);
+            bw.WriteAsVarInt(PublicKeyLength, out _);
+            bw.WriteAsByteArray(PublicKey);
+            bw.WriteAsVarInt(VerifyTokenLength, out _);
+            bw.WriteAsByteArray(VerifyToken);
+        }
+    }
+}

+ 25 - 0
src/MineCase.Protocol/Protocol/Login/Client/LoginDisconnect.cs

@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using MineCase.Serialization;
+
+namespace MineCase.Protocol.Protocol.Login.Client
+{
+    [Packet(0x00, ProtocolType.Login, PacketDirection.ClientBound)]
+    public sealed class LoginDisconnect : ISerializablePacket
+    {
+        [SerializeAs(DataType.Chat)]
+        public string Reason;
+
+        public void Deserialize(BinaryReader br)
+        {
+            Reason = br.ReadAsString();
+        }
+
+        public void Serialize(BinaryWriter bw)
+        {
+            bw.Write(Reason);
+        }
+    }
+}

+ 21 - 0
src/MineCase.Protocol/Protocol/Login/Client/LoginPluginRequest.cs

@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace MineCase.Protocol.Protocol.Login.Client
+{
+    [Packet(0x04, ProtocolType.Login, PacketDirection.ClientBound)]
+    public sealed class LoginPluginRequest : ISerializablePacket
+    {
+        public void Deserialize(BinaryReader br)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void Serialize(BinaryWriter bw)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

+ 30 - 0
src/MineCase.Protocol/Protocol/Login/Client/LoginSuccess.cs

@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using MineCase.Serialization;
+
+namespace MineCase.Protocol.Protocol.Login.Client
+{
+    [Packet(0x02, ProtocolType.Login, PacketDirection.ClientBound)]
+    public sealed class LoginSuccess : ISerializablePacket
+    {
+        [SerializeAs(DataType.String)]
+        public string UUID;
+
+        [SerializeAs(DataType.String)]
+        public string Username;
+
+        public void Deserialize(BinaryReader br)
+        {
+            UUID = br.ReadAsString();
+            Username = br.ReadAsString();
+        }
+
+        public void Serialize(BinaryWriter bw)
+        {
+            bw.WriteAsString(UUID);
+            bw.WriteAsString(Username);
+        }
+    }
+}

+ 25 - 0
src/MineCase.Protocol/Protocol/Login/Client/SetCompression.cs

@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using MineCase.Serialization;
+
+namespace MineCase.Protocol.Protocol.Login.Client
+{
+    [Packet(0x03, ProtocolType.Login, PacketDirection.ClientBound)]
+    public sealed class SetCompression : ISerializablePacket
+    {
+        [SerializeAs(DataType.VarInt)]
+        public int Threshold;
+
+        public void Deserialize(BinaryReader br)
+        {
+            Threshold = br.ReadAsVarInt(out _);
+        }
+
+        public void Serialize(BinaryWriter bw)
+        {
+            bw.WriteAsVarInt(Threshold, out _);
+        }
+    }
+}

+ 34 - 0
src/MineCase.Protocol/Protocol/Login/Server/EncryptionResponse.cs

@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using MineCase.Serialization;
+
+namespace MineCase.Protocol.Protocol.Login.Server
+{
+    [Packet(0x02, ProtocolType.Login, PacketDirection.ServerBound)]
+    public sealed class EncryptionResponse : ISerializablePacket
+    {
+        [SerializeAs(DataType.VarInt)]
+        public int SharedSecretLength;
+
+        [SerializeAs(DataType.ByteArray)]
+        public byte[] SharedSecret;
+
+        [SerializeAs(DataType.VarInt)]
+        public int VerifyTokenLength;
+
+        [SerializeAs(DataType.ByteArray)]
+        public byte[] VerifyToken;
+
+        public void Deserialize(BinaryReader br)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void Serialize(BinaryWriter bw)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

+ 31 - 0
src/MineCase.Protocol/Protocol/Login/Server/LoginPluginResponse.cs

@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using MineCase.Serialization;
+
+namespace MineCase.Protocol.Protocol.Login.Server
+{
+    [Packet(0x01, ProtocolType.Login, PacketDirection.ServerBound)]
+    public sealed class LoginPluginResponse : ISerializablePacket
+    {
+        [SerializeAs(DataType.VarInt)]
+        public int MessageID;
+
+        [SerializeAs(DataType.Boolean)]
+        public bool Successful;
+
+        [SerializeAs(DataType.ByteArray)]
+        public byte[] Data;
+
+        public void Deserialize(BinaryReader br)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void Serialize(BinaryWriter bw)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

+ 25 - 0
src/MineCase.Protocol/Protocol/Login/Server/LoginStart.cs

@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using MineCase.Serialization;
+
+namespace MineCase.Protocol.Protocol.Login.Server
+{
+    [Packet(0x00, ProtocolType.Login, PacketDirection.ServerBound)]
+    public sealed class LoginStart : ISerializablePacket
+    {
+        [SerializeAs(DataType.String)]
+        public string Name;
+
+        public void Deserialize(BinaryReader br)
+        {
+            Name = br.ReadAsString();
+        }
+
+        public void Serialize(BinaryWriter bw)
+        {
+            bw.WriteAsString(Name);
+        }
+    }
+}

+ 8 - 3
src/MineCase.Protocol/Protocol/Packet.cs

@@ -3,7 +3,6 @@ using System.Collections.Generic;
 using System.IO;
 using System.Text;
 using System.Threading.Tasks;
-using MineCase.Protocol.Serialization;
 using MineCase.Serialization;
 
 namespace MineCase.Protocol.Protocol
@@ -40,7 +39,7 @@ namespace MineCase.Protocol.Protocol
             if (RawData != null)
             {
                 await stream.WriteAsync(RawData, 0, Length);
-                System.Console.WriteLine($"Write packet length to stream: {Length}");
+                // System.Console.WriteLine($"Write packet length to stream: {Length}");
             }
 
             // System.Console.WriteLine($"Write packet length: {Length}");
@@ -52,9 +51,15 @@ namespace MineCase.Protocol.Protocol
     {
         public uint PacketId { get; }
 
-        public PacketAttribute(uint packetId)
+        public ProtocolType PacketType { get; }
+
+        public PacketDirection Direction { get; }
+
+        public PacketAttribute(uint packetId, ProtocolType packetType, PacketDirection direction)
         {
             PacketId = packetId;
+            PacketType = packetType;
+            Direction = direction;
         }
     }
 

+ 3 - 2
src/MineCase.Protocol/Protocol/PacketDecoder.cs

@@ -3,7 +3,7 @@ using System.Collections.Generic;
 using System.IO;
 using System.Text;
 using System.Threading.Tasks;
-using MineCase.Protocol.Serialization;
+using MineCase.Serialization;
 
 namespace MineCase.Protocol.Protocol
 {
@@ -24,7 +24,8 @@ namespace MineCase.Protocol.Protocol
             using (BinaryReader br = new BinaryReader(stream, Encoding.UTF8, true))
             {
                 int id = br.ReadAsVarInt(out _);
-                System.Console.WriteLine($"Read packet id: {id:X2}");
+
+                // System.Console.WriteLine($"Read packet id: {id:X2}");
                 packet = _packetInfo.GetPacket(_direction, protocolType, id);
                 packet.Deserialize(br);
             }

+ 1 - 1
src/MineCase.Protocol/Protocol/PacketEncoder.cs

@@ -3,7 +3,7 @@ using System.Collections.Generic;
 using System.IO;
 using System.Text;
 using System.Threading.Tasks;
-using MineCase.Protocol.Serialization;
+using MineCase.Serialization;
 
 namespace MineCase.Protocol.Protocol
 {

+ 49 - 29
src/MineCase.Protocol/Protocol/ProtocolType.cs

@@ -1,8 +1,11 @@
 using System;
 using System.Collections.Generic;
 using System.IO;
+using System.Reflection;
 using System.Text;
-using MineCase.Protocol.Handshaking;
+using MineCase.Protocol.Protocol.Handshaking.Server;
+using MineCase.Protocol.Protocol.Login.Client;
+using MineCase.Protocol.Protocol.Login.Server;
 using MineCase.Protocol.Protocol.Status.Client;
 using MineCase.Protocol.Protocol.Status.Server;
 
@@ -33,46 +36,29 @@ namespace MineCase.Protocol.Protocol
 
     public class PacketInfo
     {
-        private Dictionary<Type, int> _typeIdPairs = new Dictionary<Type, int>();
-        private Dictionary<Type, ProtocolType> _idProtocolTypePairs = new Dictionary<Type, ProtocolType>();
-        private Dictionary<Type, PacketDirection> _idPacketDirectionPairs = new Dictionary<Type, PacketDirection>();
-
         public PacketInfo()
         {
-            _typeIdPairs.Add(typeof(Request), 0x00);
-            _idProtocolTypePairs.Add(typeof(Request), ProtocolType.Status);
-            _idPacketDirectionPairs.Add(typeof(Request), PacketDirection.ServerBound);
-
-            _typeIdPairs.Add(typeof(Response), 0x00);
-            _idProtocolTypePairs.Add(typeof(Response), ProtocolType.Status);
-            _idPacketDirectionPairs.Add(typeof(Response), PacketDirection.ClientBound);
-
-            _typeIdPairs.Add(typeof(Ping), 0x01);
-            _idProtocolTypePairs.Add(typeof(Ping), ProtocolType.Status);
-            _idPacketDirectionPairs.Add(typeof(Ping), PacketDirection.ServerBound);
-
-            _typeIdPairs.Add(typeof(Pong), 0x01);
-            _idProtocolTypePairs.Add(typeof(Pong), ProtocolType.Status);
-            _idPacketDirectionPairs.Add(typeof(Pong), PacketDirection.ClientBound);
-
-            _typeIdPairs.Add(typeof(Handshake), 0x00);
-            _idProtocolTypePairs.Add(typeof(Handshake), ProtocolType.Handshake);
-            _idPacketDirectionPairs.Add(typeof(Handshake), PacketDirection.ServerBound);
         }
 
         public int GetPacketId(ISerializablePacket packet)
         {
-            return _typeIdPairs.GetValueOrDefault(packet.GetType(), -1);
+            var typeInfo = packet.GetType().GetTypeInfo();
+            var attr = typeInfo.GetCustomAttribute<PacketAttribute>();
+            return (int)attr.PacketId;
         }
 
         public PacketDirection GetPacketDirection(ISerializablePacket packet)
         {
-            return _idPacketDirectionPairs[packet.GetType()];
+            var typeInfo = packet.GetType().GetTypeInfo();
+            var attr = typeInfo.GetCustomAttribute<PacketAttribute>();
+            return attr.Direction;
         }
 
         public ProtocolType GetProtocolType(ISerializablePacket packet)
         {
-            return _idProtocolTypePairs[packet.GetType()];
+            var typeInfo = packet.GetType().GetTypeInfo();
+            var attr = typeInfo.GetCustomAttribute<PacketAttribute>();
+            return attr.PacketType;
         }
 
         public ISerializablePacket GetPacket(PacketDirection direction, ProtocolType protocolType, int id)
@@ -84,7 +70,7 @@ namespace MineCase.Protocol.Protocol
                     case ProtocolType.Handshake:
                         return null;
                     case ProtocolType.Login:
-                        return null;
+                        return GetPacketClientLogin(id);
                     case ProtocolType.Play:
                         return null;
                     case ProtocolType.Status:
@@ -100,7 +86,7 @@ namespace MineCase.Protocol.Protocol
                     case ProtocolType.Handshake:
                         return GetPacketServerHandshake(id);
                     case ProtocolType.Login:
-                        return null;
+                        return GetPacketServerLogin(id);
                     case ProtocolType.Play:
                         return null;
                     case ProtocolType.Status:
@@ -154,5 +140,39 @@ namespace MineCase.Protocol.Protocol
                     throw new InvalidDataException($"Unrecognizable packet id: 0x{id:X2}.");
             }
         }
+
+        public ISerializablePacket GetPacketServerLogin(int id)
+        {
+            switch (id)
+            {
+                case 0x00:
+                    return new LoginStart();
+                case 0x01:
+                    return new EncryptionResponse();
+                case 0x02:
+                    return new LoginPluginResponse();
+                default:
+                    throw new InvalidDataException($"Unrecognizable packet id: 0x{id:X2}.");
+            }
+        }
+
+        public ISerializablePacket GetPacketClientLogin(int id)
+        {
+            switch (id)
+            {
+                case 0x00:
+                    return new LoginDisconnect();
+                case 0x01:
+                    return new EncryptionRequest();
+                case 0x02:
+                    return new LoginSuccess();
+                case 0x03:
+                    return new SetCompression();
+                case 0x04:
+                    return new LoginPluginRequest();
+                default:
+                    throw new InvalidDataException($"Unrecognizable packet id: 0x{id:X2}.");
+            }
+        }
     }
 }

+ 0 - 1
src/MineCase.Protocol/Protocol/SessionState.cs

@@ -26,5 +26,4 @@ namespace MineCase.Protocol.Protocol
         /// </summary>
         Login = 2,
     }
-
 }

+ 1 - 2
src/MineCase.Protocol/Protocol/Status/Client/Pong.cs

@@ -2,12 +2,11 @@
 using System.Collections.Generic;
 using System.IO;
 using System.Text;
-using MineCase.Protocol.Serialization;
 using MineCase.Serialization;
 
 namespace MineCase.Protocol.Protocol.Status.Client
 {
-    [Packet(0x01)]
+    [Packet(0x01, ProtocolType.Status, PacketDirection.ClientBound)]
     public sealed class Pong : ISerializablePacket
     {
         [SerializeAs(DataType.Long)]

+ 1 - 2
src/MineCase.Protocol/Protocol/Status/Client/Response.cs

@@ -2,12 +2,11 @@
 using System.Collections.Generic;
 using System.IO;
 using System.Text;
-using MineCase.Protocol.Serialization;
 using MineCase.Serialization;
 
 namespace MineCase.Protocol.Protocol.Status.Client
 {
-    [Packet(0x00)]
+    [Packet(0x00, ProtocolType.Status, PacketDirection.ClientBound)]
     public sealed class Response : ISerializablePacket
     {
         [SerializeAs(DataType.String)]

+ 1 - 2
src/MineCase.Protocol/Protocol/Status/Server/Ping.cs

@@ -3,12 +3,11 @@ using System.Collections.Generic;
 using System.IO;
 using System.Text;
 using MineCase.Protocol.Protocol;
-using MineCase.Protocol.Serialization;
 using MineCase.Serialization;
 
 namespace MineCase.Protocol.Protocol.Status.Server
 {
-    [Packet(0x01)]
+    [Packet(0x01, ProtocolType.Status, PacketDirection.ServerBound)]
     public sealed class Ping : ISerializablePacket
     {
         [SerializeAs(DataType.Long)]

+ 1 - 1
src/MineCase.Protocol/Protocol/Status/Server/Request.cs

@@ -5,7 +5,7 @@ using System.Text;
 
 namespace MineCase.Protocol.Protocol.Status.Server
 {
-    [Packet(0x00)]
+    [Packet(0x00, ProtocolType.Status, PacketDirection.ServerBound)]
     public sealed class Request : ISerializablePacket
     {
         public static readonly Request Empty = new Request();

+ 6 - 1
src/MineCase.Protocol/Serialization/BinaryReaderExtensions.cs

@@ -4,7 +4,7 @@ using System.IO;
 using System.Text;
 using System.Threading.Tasks;
 
-namespace MineCase.Protocol.Serialization
+namespace MineCase.Serialization
 {
     internal static class BinaryReaderExtensions
     {
@@ -69,6 +69,11 @@ namespace MineCase.Protocol.Serialization
             var bytes = br.ReadBytes((int)len);
             return Encoding.UTF8.GetString(bytes);
         }
+
+        public static byte[] ReadAsByteArray(this BinaryReader br, int length)
+        {
+            return br.ReadBytes(length);
+        }
     }
 
     internal static class StreamExtensions

+ 1 - 1
src/MineCase.Protocol/Serialization/BinaryWriterExtensions.cs

@@ -3,7 +3,7 @@ using System.Collections.Generic;
 using System.IO;
 using System.Text;
 
-namespace MineCase.Protocol.Serialization
+namespace MineCase.Serialization
 {
     internal static class BinaryWriterExtensions
     {

+ 1 - 1
src/MineCase.Protocol/Serialization/DataType.cs

@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 using System.Text;
 
-namespace MineCase.Protocol.Serialization
+namespace MineCase.Serialization
 {
     internal static class DataTypeSizeExtensions
     {

+ 10 - 0
src/MineCase.Server.Grains/Entity/Entity.cs

@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MineCase.Server.Entity
+{
+    public class Entity
+    {
+    }
+}

+ 10 - 0
src/MineCase.Server.Grains/Entity/Player/PlayerEntity.cs

@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MineCase.Server.Entity.Player
+{
+    public class PlayerEntity
+    {
+    }
+}

+ 0 - 4
src/MineCase.Server.Grains/MineCase.Server.Grains.csproj

@@ -33,8 +33,4 @@
     <ProjectReference Include="..\MineCase.Server.Interfaces\MineCase.Server.Interfaces.csproj" />
   </ItemGroup>
 
-  <ItemGroup>
-    <Folder Include="Server\" />
-  </ItemGroup>
-
 </Project>

+ 30 - 0
src/MineCase.Server.Grains/Server/Management/ManagementSettings.cs

@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MineCase.Server.Server;
+
+namespace MineCase.Server.Server.Management
+{
+    public abstract class ManagementSettings
+    {
+        private IMinecraftServer _server;
+
+        private readonly List<ServerPlayerEntity> players = new List<>();
+        private readonly Map<UUID, ServerPlayerEntity> uuidToPlayerMap = Maps.newHashMap();
+        private readonly BanList bannedPlayers = new BanList(FILE_PLAYERBANS);
+        private readonly IPBanList bannedIPs = new IPBanList(FILE_IPBANS);
+        private readonly OpList ops = new OpList(FILE_OPS);
+        private readonly WhiteList whiteListedPlayers = new WhiteList(FILE_WHITELIST);
+        private readonly Map<UUID, ServerStatisticsManager> playerStatFiles = Maps.newHashMap();
+        private readonly Map<UUID, PlayerAdvancements> advancements = Maps.newHashMap();
+        private IPlayerFileData playerDataManager;
+        private bool whiteListEnforced;
+        protected readonly int maxPlayers;
+        private int viewDistance;
+        private GameType gameType;
+        private bool commandsAllowedForAll;
+        private int playerPingIndex;
+        private readonly List<ServerPlayerEntity> playersView = java.util.Collections.unmodifiableList(players);
+
+    }
+}

+ 21 - 0
src/MineCase.Server.Grains/Server/MinecraftServer.cs

@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using Orleans;
+
+namespace MineCase.Server.Server
+{
+    public class MinecraftServer : Grain, IMinecraftServer
+    {
+        public Task<int> GetNetworkCompressionThreshold()
+        {
+            return Task.FromResult(-1);
+        }
+
+        public Task<bool> GetOnlineMode()
+        {
+            return Task.FromResult(false);
+        }
+    }
+}

+ 0 - 4
src/MineCase.Server.Interfaces/MineCase.Server.Interfaces.csproj

@@ -31,8 +31,4 @@
     <ProjectReference Include="..\MineCase.Protocol\MineCase.Protocol.csproj" />
   </ItemGroup>
 
-  <ItemGroup>
-    <Folder Include="Server\" />
-  </ItemGroup>
-
 </Project>

+ 15 - 0
src/MineCase.Server.Interfaces/Server/IMinecraftServer.cs

@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using Orleans;
+
+namespace MineCase.Server.Server
+{
+    public interface IMinecraftServer : IGrainWithStringKey
+    {
+        Task<bool> GetOnlineMode();
+
+        Task<int> GetNetworkCompressionThreshold();
+    }
+}