Ver Fonte

收消息模式确定,一发一收。

tanghai há 13 anos atrás
pai
commit
539e9d422b

+ 43 - 0
CSharp/App/Modules/Robot/Protos/Messages.cs

@@ -36,6 +36,49 @@ namespace Robot.Protos
 		}
 	}
 
+	[DataContract]
+	public class SMSG_Lock_For_Safe_Time
+	{
+		[DataMember(Order = 1, IsRequired = true)]
+		public uint Time
+		{
+			get;
+			set;
+		}
+	}
+
+	[DataContract]
+	public class SMSG_Password_Protect_Type
+	{
+		[DataMember(Order = 1, IsRequired = true)]
+		public uint Code
+		{
+			get;
+			set;
+		}
+
+		[DataMember(Order = 2, IsRequired = true)]
+		public uint SubCode
+		{
+			get;
+			set;
+		}
+
+		[DataMember(Order = 3, IsRequired = true)]
+		public uint PasswordProtectType
+		{
+			get;
+			set;
+		}
+
+		[DataMember(Order = 4, IsRequired = false)]
+		public byte[] PpcCoordinate
+		{
+			get;
+			set;
+		}
+	}
+
 
 	[DataContract]
 	public class SMSG_Auth_Challenge

+ 15 - 0
CSharp/App/Modules/Robot/RealmException.cs

@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Robot
+{
+	public class RealmException: Exception
+	{
+		public RealmException(string message): base(message)
+		{
+		}
+	}
+}

+ 18 - 0
CSharp/App/Modules/Robot/RealmInfo.cs

@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Robot.Protos;
+
+namespace Robot
+{
+	public class RealmInfo
+	{
+		public SMSG_Password_Protect_Type SmsgPasswordProtectType
+		{
+			get;
+			set;
+		}
+	}
+}

+ 95 - 17
CSharp/App/Modules/Robot/RealmSession.cs

@@ -1,7 +1,8 @@
-using System;
+using System;
 using System.IO;
 using System.Net;
 using System.Net.Sockets;
+using System.Threading.Tasks;
 using Helper;
 using Log;
 using Org.BouncyCastle.Utilities.Encoders;
@@ -15,6 +16,7 @@ namespace Robot
 	public class RealmSession: IDisposable
 	{
 		private readonly NetworkStream networkStream;
+		private RealmInfo realmInfo = new RealmInfo();
 
 		public RealmSession(string host, ushort port)
 		{
@@ -51,7 +53,7 @@ namespace Robot
 
 		public async void SendMessage<T>(ushort opcode, T message)
 		{
-			byte[] protoBytes = ProtobufHelper.ProtoToBytes(message);
+			byte[] protoBytes = ProtobufHelper.ToBytes(message);
 			var neworkBytes = new byte[sizeof(int) + sizeof(ushort) + protoBytes.Length];
 
 			int totalSize = sizeof(ushort) + protoBytes.Length;
@@ -67,31 +69,107 @@ namespace Robot
 			await networkStream.WriteAsync(neworkBytes, 0, neworkBytes.Length);
 		}
 
-		public void Login(string account, string password)
+		public async Task<bool> Handle_CMSG_AuthLogonPermit_Response()
 		{
-			try
+			var result = await RecvMessage();
+			ushort opcode = result.Item1;
+			byte[] message = result.Item2;
+			
+			if (opcode == 0)
+			{
+				Logger.Trace("opcode == 0");
+				throw new RealmException("opcode == 0");
+			}
+
+			if (opcode == MessageOpcode.SMSG_LOCK_FOR_SAFE_TIME)
+			{
+				var smsgLockForSafeTime = 
+					ProtobufHelper.FromBytes<SMSG_Lock_For_Safe_Time>(message);
+				Logger.Trace("account lock time: {0}", smsgLockForSafeTime.Time);
+				return false;
+			}
+
+			if (opcode != MessageOpcode.SMSG_PASSWORD_PROTECT_TYPE)
+			{
+				throw new RealmException(string.Format("error opcode: {0}", opcode));
+			}
+
+			var smsgPasswordProtectType = 
+				ProtobufHelper.FromBytes<SMSG_Password_Protect_Type>(message);
+			this.realmInfo.SmsgPasswordProtectType = smsgPasswordProtectType;
+
+			Logger.Trace("message: {0}", JsonHelper.ToString(smsgPasswordProtectType));
+
+			if (smsgPasswordProtectType.Code != 200)
 			{
-				byte[] passwordBytes = password.ToByteArray();
-				var digest = new MD5Digest();
-				var passwordMd5 = new byte[digest.GetDigestSize()];
+				return false;
+			}
 
-				digest.BlockUpdate(passwordBytes, 0, passwordBytes.Length);
-				digest.DoFinal(passwordMd5, 0);
+			return true;
+		}
 
-				var cmsgAuthLogonPermit = new CMSG_AuthLogonPermit
+		public async Task<Tuple<ushort, byte[]>> RecvMessage()
+		{
+			int totalReadSize = 0;
+			int needReadSize = sizeof (int);
+			var packetBytes = new byte[needReadSize];
+			while (totalReadSize != needReadSize)
+			{
+				int readSize = await networkStream.ReadAsync(packetBytes, totalReadSize, packetBytes.Length);
+				if (readSize == 0)
 				{
-					Account = account,
-					PasswordMd5 = Hex.ToHexString(passwordMd5)
-				};
+					return new Tuple<ushort, byte[]>(0, new byte[] {});
+				}
+				totalReadSize += readSize;
+			}
 
-				Logger.Debug("password: {0}", cmsgAuthLogonPermit.PasswordMd5);
+			int packetSize = BitConverter.ToInt32(packetBytes, 0);
 
-				SendMessage(MessageOpcode.CMSG_AUTHLOGONPERMIT, cmsgAuthLogonPermit);
+			// 读opcode和message
+			totalReadSize = 0;
+			needReadSize = packetSize;
+			var contentBytes = new byte[needReadSize];
+			while (totalReadSize != needReadSize)
+			{
+				int readSize = await networkStream.ReadAsync(contentBytes, totalReadSize, contentBytes.Length);
+				if (readSize == 0)
+				{
+					return new Tuple<ushort, byte[]>(0, new byte[] {});
+				}
+				totalReadSize += readSize;
 			}
-			catch (SocketException e)
+			ushort opcode = BitConverter.ToUInt16(contentBytes, 0);
+			var messageBytes = new byte[needReadSize - sizeof(ushort)];
+			Array.Copy(contentBytes, sizeof (ushort), messageBytes, 0, messageBytes.Length);
+
+			return new Tuple<ushort, byte[]>(opcode, messageBytes);
+		}
+
+		public async Task<bool> Login(string account, string password)
+		{
+			byte[] passwordBytes = password.ToByteArray();
+			var digest = new MD5Digest();
+			var passwordMd5 = new byte[digest.GetDigestSize()];
+
+			digest.BlockUpdate(passwordBytes, 0, passwordBytes.Length);
+			digest.DoFinal(passwordMd5, 0);
+
+			var cmsgAuthLogonPermit = new CMSG_AuthLogonPermit
+			{
+				Account = account,
+				PasswordMd5 = Hex.ToHexString(passwordMd5)
+			};
+			
+			this.SendMessage(MessageOpcode.CMSG_AUTHLOGONPERMIT, cmsgAuthLogonPermit);
+
+			bool result = await Handle_CMSG_AuthLogonPermit_Response();
+
+			if (result == false)
 			{
-				Logger.Debug("socket exception, error: {}", e.ErrorCode);
+				return false;
 			}
+
+			return true;
 		}
 	}
 }

+ 2 - 0
CSharp/App/Modules/Robot/Robot.csproj

@@ -63,6 +63,8 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Protos\Messages.cs" />
+    <Compile Include="RealmException.cs" />
+    <Compile Include="RealmInfo.cs" />
     <Compile Include="RealmSession.cs" />
     <Compile Include="Robot.cs" />
     <Compile Include="RobotModule.cs" />

+ 1 - 1
CSharp/App/Modules/Robot/RobotView.xaml.cs

@@ -31,7 +31,7 @@ namespace Modules.Robot
 
 		private void btnLogin_Click(object sender, RoutedEventArgs e)
 		{
-			this.ViewModel.Login("egametang@163.com", "111111");
+			this.ViewModel.Login("egametang@163.com", "163bio1");
 		}
 	}
 }

+ 11 - 2
CSharp/App/Modules/Robot/RobotViewModel.cs

@@ -2,6 +2,7 @@
 using System.ComponentModel.Composition;
 using System.Windows.Threading;
 using ENet;
+using Log;
 using Microsoft.Practices.Prism.ViewModel;
 using Robot;
 
@@ -75,7 +76,7 @@ namespace Modules.Robot
 			this.clientHost.Dispose();
 		}
 
-		public void Login(string account, string password)
+		public async void Login(string account, string password)
 		{
 			//try
 			//{
@@ -97,7 +98,15 @@ namespace Modules.Robot
 			//}
 
 			var session = new RealmSession("192.168.11.95", 8888);
-			session.Login(account, password);
+			bool result = await session.Login(account, password);
+
+			if (result == false)
+			{
+				Logger.Debug("session login fail!");
+				return;
+			}
+
+			Logger.Debug("session login success!");
 		}
 	}
 }

+ 2 - 0
CSharp/Platform/Helper/Helper.csproj

@@ -38,10 +38,12 @@
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
+    <Reference Include="System.Runtime.Serialization" />
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
     <Compile Include="ByteHelper.cs" />
+    <Compile Include="JsonHelper.cs" />
     <Compile Include="LoaderHelper.cs" />
     <Compile Include="ProtobufHelper.cs" />
     <Compile Include="StringHelper.cs" />

+ 34 - 0
CSharp/Platform/Helper/JsonHelper.cs

@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Runtime.Serialization.Json; 
+
+namespace Helper
+{
+	public static class JsonHelper
+	{
+		public static string ToString<T>(T obj)
+		{
+			var serializer = new DataContractJsonSerializer(typeof(T));
+			using (var ms = new MemoryStream())
+			{
+				serializer.WriteObject(ms, obj);
+				string str = Encoding.UTF8.GetString(ms.ToArray());
+				return str;
+			}
+		}
+
+		public static T FromString<T>(string str)
+		{
+			var serializer = new DataContractJsonSerializer(typeof(T));
+			using (var ms = new MemoryStream(Encoding.Default.GetBytes(str)))
+			{
+				var obj = (T)serializer.ReadObject(ms);
+				return obj;
+			}
+		}
+	}
+}

+ 7 - 1
CSharp/Platform/Helper/ProtobufHelper.cs

@@ -5,11 +5,17 @@ namespace Helper
 {
 	public static class ProtobufHelper
 	{
-		public static byte[] ProtoToBytes<T>(T message)
+		public static byte[] ToBytes<T>(T message)
 		{
 			var ms = new MemoryStream();
 			Serializer.Serialize(ms, message);
 			return ms.ToArray();
 		}
+
+		public static T FromBytes<T>(byte[] bytes)
+		{
+			var ms = new MemoryStream(bytes, 0, bytes.Length);
+			return Serializer.Deserialize<T>(ms);
+		}
 	}
 }