/// <summary> /// 检查包是否重复收到 /// </summary> /// <param name="packet">The packet.</param> /// <returns></returns> public bool IsDuplicated(InPacket packet) { if (parsers[packet.GetFamily()] != null) { return parsers[packet.GetFamily()].IsDuplicate(packet); } return false; }
public void PacketArrived(InPacket inPacket) { try { foreach (IPacketListener listener in listeners) { if (listener.Accept(inPacket)) { listener.PacketArrived(inPacket); return; } } } catch (Exception e) { client.LogManager.Log(ToString() + ":" + e.Message + "\n\r" + e.StackTrace); ErrorPacket errorPacket = new ErrorPacket(ErrorPacketType.RUNTIME_ERROR, client,e); errorPacket.ErrorMessage = client.GenerateCrashReport(e, inPacket); errorPacket.Family = ProtocolFamily.Basic; errorPacket.ConnectionId = TS.QQ.Net.QQPort.Main.Name; client.PacketManager.AddIncomingPacket(errorPacket, errorPacket.ConnectionId); } }
/// <summary> /// 返回这个回复包对应的请求包 /// </summary> /// <param name="packet">The packet.</param> /// <returns>你的请求包</returns> public OutPacket RetrieveSent(InPacket packet) { if (!sent.Contains(packet)) { return null; } OutPacket outPacket = (OutPacket)sent[packet]; sent.Remove(packet); return outPacket; }
/// <summary>删除ack对应的请求包 /// </summary> /// <param name="ack">The ack.</param> public void Remove(InPacket ack) { foreach (OutPacket packet in timeOutQueue) { if (packet.Equals(ack)) { timeOutQueue.Remove(packet); //toPort.Remove(packet); break; } } }
public bool IsDuplicatedNeedReply(InPacket packet) { return packet.Command == QQCommand.Recv_IM_09; }
public bool IsDuplicate(InPacket packet) { return history.Check(packet, true); }
/// <summary> /// 通过回复包获得请求包 /// 通过重载Packet的Equals方法,本判断两个不同类型的对象相等。 /// </summary> /// <param name="inPacket">The in packet.</param> /// <returns>OutPacket对象,如果没有找到,返回null</returns> public OutPacket RetriveSent(InPacket inPacket) { if (parsers[inPacket.GetFamily()] != null) { PacketHistory history = parsers[inPacket.GetFamily()].GetHistory(); if (history != null) { return history.RetrieveSent(inPacket); } } return null; }
public void PushIn(InPacket inPacket) { client.PacketManager.AddIncomingPacket(inPacket, ID); }
public OutPacket RetrieveSent(InPacket inPacket) { return helper.RetriveSent(inPacket); }
public void PacketArrived(InPacket inPacket) { // BasicInPacket packet = (BasicInPacket)inPacket; if (inPacket is UnknownInPacket) { client.PacketManager.OnReceivedUnknownPacket(new QQEventArgs<UnknownInPacket, OutPacket>(client, (UnknownInPacket)inPacket, null)); return; } if (inPacket is ErrorPacket) { ErrorPacket error = (ErrorPacket)inPacket; if (error.ErrorType == ErrorPacketType.ERROR_TIMEOUT) { client.PacketManager.OnSendPacketTimeOut(new QQEventArgs<InPacket, OutPacket>(client, null, error.TimeOutPacket)); } else { client.OnError(new QQEventArgs<ErrorPacket, OutPacket>(client, (ErrorPacket)inPacket, null)); } return; } // 检查目前是否已经登录 if (!client.QQUser.IsLoggedIn) { //按理说应该把在登陆之前时收到的包缓存起来,但是在实际中观察发现,登录之前收到的 //东西基本没用,所以在这里不做任何事情,简单的抛弃这个包 if (!IsPreloginPacket(inPacket)) { return; } } // 现在开始判断包的类型,作出相应的处理 ConnectionPolicy policy = client.ConnectionManager.GetConnection(inPacket.PortName).Policy; // 根据输入包,检索对应的输出包 OutPacket outPacket = policy.RetrieveSent(inPacket); // 这里检查是不是服务器发回的确认包 // 为什么要检查这个呢,因为有些包是服务器主动发出的,对于这些包我们是不需要 // 从超时发送队列中移除的,如果是服务器的确认包,那么我们就需要把超时发送队列 // 中包移除 switch (inPacket.Command) { //// 这三种包是服务器先发出的,我们要确认 case QQCommand.Recv_IM: case QQCommand.Recv_IM_09: case QQCommand.BroadCast: case QQCommand.Friend_Change_Status: break; // 其他情况我们删除超时队列中的包 default: client.PacketManager.RemoveResendPacket(inPacket); client.PacketManager.OnSendPacketSuccessed(new QQEventArgs<InPacket, OutPacket>(client, inPacket, outPacket)); break; } switch (inPacket.Command) { case QQCommand.Touch: client.LoginManager.ProcessLoginTouchReply((LoginTouchReplyPacket)inPacket, outPacket as LoginTouchPacket); break; case QQCommand.LoginVerify: client.LoginManager.ProcessLoginVerifyReply((LoginVerifyReplyPacket)inPacket, outPacket as LoginVerifyPacket); break; case QQCommand.LoginGetInfo: client.LoginManager.ProcessLoginGetInfoReply((LoginGetInfoReplyPacket)inPacket, outPacket as LoginGetInfoPacket); break; case QQCommand.Login_A4: client.LoginManager.ProcessLoginA4Reply((LoginA4ReplyPacket)inPacket, outPacket as LoginA4Packet); break; case QQCommand.LoginGetList: client.LoginManager.ProcessLoginGetListReply((LoginGetListReplyPacket)inPacket, outPacket as LoginGetListPacket); break; case QQCommand.LoginSendInfo: client.LoginManager.ProcessLoginSendInfoReply((LoginSendInfoReplyPacket)inPacket, outPacket as LoginSendInfoPacket); break; case QQCommand.Keep_Alive: client.LoginManager.ProcessKeepAliveReply((KeepAliveReplyPacket)inPacket, outPacket as KeepAlivePacket); break; case QQCommand.Change_Status: client.PrivateManager.ProcessChangeStatusReply((ChangeStatusReplyPacket)inPacket, outPacket as ChangeStatusPacket); break; case QQCommand.GetLevel: client.PrivateManager.ProcessGetLevelReply((GetLevelReplyPacket)inPacket, outPacket as GetLevelPacket); break; case QQCommand.GroupLabel: //client.PrivateManager.ProcessGetLevelReply((GetLevelReplyPacket)inPacket, outPacket as GetLevelPacket); break; case QQCommand.Get_Friend_List: client.FriendManager.ProcessGetFriendListReply((GetFriendListReplyPacket)inPacket, outPacket as GetFriendListPacket); break; case QQCommand.Get_Online_OP: client.FriendManager.ProcessGetFriendOnlineReply((GetOnlineOpReplyPacket)inPacket, outPacket as GetOnlineOpPacket); break; case QQCommand.Recv_IM_09: case QQCommand.Recv_IM: ProcessReceiveIM((ReceiveIMPacket)inPacket); break; case QQCommand.Friend_Change_Status: ProcessFriendChangeStatus((FriendChangeStatusPacket)inPacket); break; case QQCommand.BroadCast: ProcessSystemNotification((SystemNotificationPacket)inPacket); break; case QQCommand.Add_Friend: ProcessAddFriendReply((AddFriendReplyPacket)inPacket, outPacket as AddFriendPacket); break; case QQCommand.AddFriendAuthorize: ProcessAuthorizeReply((AddFriendAuthorizeReplyPacket)inPacket, outPacket as AddFriendAuthorizePacket); break; case QQCommand.RequestToken: ProcessRequestTokenReply((RequestTokenReplyPacket)inPacket, outPacket as RequestTokenPacket); break; #region QQ2005 case QQCommand.Request_Login_Token_05: this.user = client.QQUser; ProcessRequestLoginTokenReply((RequestLoginTokenReplyPacket)inPacket, outPacket as RequestLoginTokenPacket); break; //case QQCommand.Keep_Alive_05: // ProcessKeepAliveReply((KeepAliveReplyPacket)inPacket, outPacket as KeepAlivePacket); // break; //case QQCommand.Get_Friend_List_05: // ProcessGetFriendListReply((GetFriendListReplyPacket)inPacket, outPacket as GetFriendListPacket); // break; case QQCommand.Get_UserInfo_05: ProcessGetUserInfoReply((GetUserInfoReplyPacket)inPacket, outPacket as GetUserInfoPacket); break; //case QQCommand.Change_Status_05: // ProcessChangeStatusReply((ChangeStatusReplyPacket)inPacket, outPacket as ChangeStatusPacket); // break; case QQCommand.Add_Friend_Auth_05: ProcessAddFriendAuthReply((AddFriendAuthResponseReplyPacket)inPacket, outPacket as AddFriendAuthResponsePacket); break; case QQCommand.Remove_Self_05: ProcessRemoveSelfReply((RemoveSelfReplyPacket)inPacket, outPacket as RemoveSelfPacket); break; case QQCommand.Delete_Friend_05: ProcessDeleteFriendReply((DeleteFriendReplyPacket)inPacket, outPacket as DeleteFriendPacket); break; case QQCommand.Upload_Group_Friend_05: ProcessUploadGroupFriendReply((UploadGroupFriendReplyPacket)inPacket, (UploadGroupFriendPacket)outPacket); break; case QQCommand.Modify_Info_05: ProcessModifyInfoReply((ModifyInfoReplyPacket)inPacket, (ModifyInfoPacket)outPacket); break; case QQCommand.Signature_OP_05: ProcessSignatureOpReply((SignatureOpReplyPacket)inPacket, (SignatureOpPacket)outPacket); break; case QQCommand.Privacy_Data_OP_05: ProcessPrivacyDataOpReply((PrivacyDataOpReplyPacket)inPacket, (PrivacyDataOpPacket)outPacket); break; case QQCommand.Friend_Data_OP_05: ProcessFriendDataOpReply((FriendDataOpReplyPacket)inPacket, (FriendDataOpPacket)outPacket); break; //case QQCommand.Friend_Level_OP_05: // ProcessFriendLevelOpReply((FriendLevelOpReplyPacket)inPacket, (FriendLevelOpPacket)outPacket); // break; case QQCommand.User_Property_OP_05: PocessUserPropertyOpReply((UserPropertyOpReplyPacket)inPacket, (UserPropertyOpPacket)outPacket); break; //case QQCommand.Download_Group_Friend_05: // ProcessDownloadGroupFriendReply((DownloadGroupFriendReplyPacket)inPacket, (DownloadGroupFriendPacket)outPacket); // break; case QQCommand.Group_Data_OP_05: ProcessGroupNameOpReply((GroupDataOpReplyPacket)inPacket, (GroupDataOpPacket)outPacket); break; case QQCommand.Search_User_05: ProcessSearchUserReply((SearchUserReplyPacket)inPacket, (SearchUserPacket)outPacket); break; case QQCommand.Weather_OP_05: ProcessWeatherOpReply((WeatherOpReplyPacket)inPacket, (WeatherOpPacket)outPacket); break; case QQCommand.Cluster_Cmd: ProcessClusterCommandReply((ClusterCommandReplyPacket)inPacket, (ClusterCommandPacket)outPacket); break; #endregion //default: } }
/// <summary>判断包是否时登录前可以出现的包,有些包是在登录前可以处理的,如果不是,应该缓存起来等 /// 到登录成功后再处理,不过但是在实际中观察发现,登录之前收到的东西基本没用,可以不管 /// </summary> /// <param name="inPacket">The in packet.</param> /// <returns></returns> private bool IsPreloginPacket(InPacket inPacket) { switch (inPacket.Command) { case QQCommand.Touch: case QQCommand.LoginRequest: case QQCommand.Login_A4: case QQCommand.LoginVerify: case QQCommand.LoginGetInfo: case QQCommand.LoginGetList: case QQCommand.LoginSendInfo: case QQCommand.Request_Login_Token_05: //case QQCommand.Login_05: return true; case QQCommand.Unknown: return inPacket is ErrorPacket; default: return false; } }
/// <summary> /// 收到服务器确认 /// 删除一个重发包 /// <remark>abu 2008-03-08 </remark> /// </summary> /// <param name="packet">The packet.</param> public void RemoveResendPacket(InPacket packet) { resendTrigger.Remove(packet); }
/// <summary>通知包处理器包到达事件 /// <remark>abu 2008-03-07 </remark> /// </summary> /// <param name="inPacket">The in packet.</param> public void FirePacketArrivedEvent(InPacket inPacket) { router.PacketArrived(inPacket); }
/// <summary> /// 添加输入包 /// </summary> /// <param name="inPacket">The in packet.</param> public void AddIncomingPacket(InPacket inPacket, string portName) { lock (receiveQueue) { if (inPacket == null) { return; } inPacket.PortName = portName; receiveQueue.Enqueue(inPacket); //inConn.Add(inPacket, portName); ThreadExcutor.Submit(this.packetIncomTrigger, this); } }