/// <summary> /// 分析网络数据包并进行转换为信息对象 /// </summary> /// <param name="packs">接收到的封包对象</param> /// <returns></returns> /// <remarks> /// 对于分包消息,如果收到的只是片段并且尚未接收完全,则不会进行解析 /// </remarks> public static IPMessager.Entity.Message ParseToMessage(params Entity.PackedNetworkMessage[] packs) { if (packs.Length == 0 || (packs[0].PackageCount > 1 && packs.Length != packs[0].PackageCount)) { return(null); } //尝试解压缩,先排序 Array.Sort(packs); //尝试解压缩 System.IO.MemoryStream ms = new System.IO.MemoryStream(); System.IO.Compression.GZipStream zip = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Decompress); try { Array.ForEach(packs, s => zip.Write(s.Data, 0, s.Data.Length)); } catch (Exception) { OnDecompressFailed(new DecomprssFailedEventArgs(packs)); return(null); } zip.Close(); ms.Flush(); ms.Seek(0, System.IO.SeekOrigin.Begin); //构造读取流 System.IO.BinaryReader br = new System.IO.BinaryReader(ms, System.Text.Encoding.Unicode); //开始读出数据 IPMessager.Entity.Message m = new FSLib.IPMessager.Entity.Message(packs[0].RemoteIP); m.PackageNo = br.ReadUInt64(); //包编号 ulong tl = br.ReadUInt64(); m.Command = (Define.Consts.Commands)(tl & 0xFF); //命令编码 m.Options = tl & 0xFFFFFF00; //命令参数 m.UserName = br.ReadString(); //用户名 m.HostName = br.ReadString(); //主机名 int length = br.ReadInt32(); m.NormalMsgBytes = new byte[length]; br.Read(m.NormalMsgBytes, 0, length); length = br.ReadInt32(); m.ExtendMessageBytes = new byte[length]; br.Read(m.ExtendMessageBytes, 0, length); if (!Consts.Check(m.Options, Consts.Cmd_All_Option.BinaryMessage)) { m.NormalMsg = System.Text.Encoding.Unicode.GetString(m.NormalMsgBytes, 0, length); //正文 m.ExtendMessage = System.Text.Encoding.Unicode.GetString(m.ExtendMessageBytes, 0, length); //扩展消息 } return(m); }
/// <summary> /// 从文本信息里面解析出任务信息 /// </summary> /// <param name="taskMessage"></param> /// <returns></returns> public static FileTaskInfo DecompileTaskInfo(Host Host, Message msg) { if (!msg.IsFileAttached || string.IsNullOrEmpty(msg.ExtendMessage)) return null; FileTaskInfo task = new FileTaskInfo(FileTransferDirection.Receive, msg.PackageNo, Host); string[] f = msg.ExtendMessage.Split('\a'); for (int i = 0; i < f.Length; i++) { string[] ef = f[i].Split(':'); if (ef.Length < 5) continue; int index = 0; string name = ""; ulong size = 0ul; ulong filetypeAttr; if (!int.TryParse(ef[0], out index) || !ulong.TryParse(ef[2], System.Globalization.NumberStyles.AllowHexSpecifier, null, out size) || !ulong.TryParse(ef[4], System.Globalization.NumberStyles.AllowHexSpecifier, null, out filetypeAttr)) continue; name = ef[1]; if (string.IsNullOrEmpty(name)) continue; else name = Network.TCPThread.replaceReg.Replace(name, "_"); task.TaskList.Add(new FileTaskItem() { TaskInfo = task, TotalSize = size, CancelPadding = false, FileCount = 0, FolderCount = 0, FinishedFileCount = 0, FinishedSize = 0, FinishedFolderCount = 0, EndTime = null, FullPath = "", CurrentFileTransfered = 0, Index = index, IsFolder = (filetypeAttr & (ulong)Define.Consts.Cmd_FileType_Option.Dir) == (ulong)Define.Consts.Cmd_FileType_Option.Dir, StartTime = null, CurrentName = name, CurrentFileSize = (filetypeAttr & (ulong)Define.Consts.Cmd_FileType_Option.Dir) == (ulong)Define.Consts.Cmd_FileType_Option.Dir ? 0ul : size, State = FileTaskItemState.Scheduled, Name = name }); } if (task.TaskList.Count == 0) return null; else return task; }
/// <summary> /// 处理信息到达事件 /// </summary> /// <param name="host"></param> /// <param name="msg"></param> void TextMessageReceived(Host host, FSLib.IPMessager.Entity.Message msg) { IChatService cs = this.OpenChatTab(host); cs.DropMessage(msg); if (Env.ClientConfig.ChatConfig.AutoChangeCurrentTabToNew) { this.SelectTab(cs as TabPage); } //SOUND if (!Forms.FrameContainer.ContainerForm.IsMute && Env.ClientConfig.Sound.EnableNewMsgSound) { Env.SoundManager.PlayNewMsg(); } }
/// <summary> /// 格式化消息文本 /// </summary> /// <param name="msg"></param> public void FormatMessage(Alias.Message msg) { if (FSLib.IPMessager.Define.Consts.Check(msg.Options, FSLib.IPMessager.Define.Consts.Cmd_Send_Option.Content_Html)) { //HTML文本 } else if (FSLib.IPMessager.Define.Consts.Check(msg.Options, FSLib.IPMessager.Define.Consts.Cmd_Send_Option.Content_Html)) { //RTF文本,貌似无法显示吧..咋办? } else { //文本,格式化it msg.NormalMsg = System.Web.HttpUtility.HtmlEncode(msg.NormalMsg).Replace("\n", "<br />"); } }
/// <summary> /// 分析网络数据包并进行转换为信息对象 /// </summary> /// <param name="packs">接收到的封包对象</param> /// <returns></returns> /// <remarks> /// 对于分包消息,如果收到的只是片段并且尚未接收完全,则不会进行解析 /// </remarks> public static IPMessager.Entity.Message ParseToMessage(params Entity.PackedNetworkMessage[] packs) { if (packs.Length == 0 || (packs[0].PackageCount > 1 && packs.Length != packs[0].PackageCount)) { return(null); } var ms = DecompressMessagePacks(packs); if (ms == null) { OnDecompressFailed(new DecomprssFailedEventArgs(packs)); return(null); } //构造读取流 var br = new System.IO.BinaryReader(ms, System.Text.Encoding.Unicode); //开始读出数据 var m = new FSLib.IPMessager.Entity.Message(packs[0].RemoteIP); m.PackageNo = br.ReadUInt64(); //包编号 var tl = br.ReadUInt64(); m.Command = (Define.Consts.Commands)(tl & 0xFF); //命令编码 m.Options = tl & 0xFFFFFF00; //命令参数 m.UserName = br.ReadString(); //用户名 m.HostName = br.ReadString(); //主机名 var length = br.ReadInt32(); m.NormalMsgBytes = new byte[length]; br.Read(m.NormalMsgBytes, 0, length); length = br.ReadInt32(); m.ExtendMessageBytes = new byte[length]; br.Read(m.ExtendMessageBytes, 0, length); if (!Consts.Check(m.Options, Consts.Cmd_All_Option.BinaryMessage)) { m.NormalMsg = System.Text.Encoding.Unicode.GetString(m.NormalMsgBytes, 0, length); //正文 m.ExtendMessage = System.Text.Encoding.Unicode.GetString(m.ExtendMessageBytes, 0, length); //扩展消息 } return(m); }
/// <summary> /// 提交消息 /// </summary> /// <param name="msg"></param> public void DropMessage(Alias.Message msg) { if (browser.ReadyState == WebBrowserReadyState.Complete) { FormatMessage(msg); object[] param = new object[] { msg.PackageNo.ToString(), msg.IsEncrypt?1:0, DateTime.Now.ToString(), msg.NormalMsg, msg.IsSecret?1:0, 0, 0, msg.IsAutoSendMessage?1:0, msg.AutoReplyTime == null?"":msg.AutoReplyTime.Value.ToString() }; browser.Document.InvokeScript("messageReceied", param); } else { notReadyScriptList.Add(msg); } }
private void ProcessCommand_DelMsg(Message message, Host host) { if (host == null) return; }
//请求查询版本信息 private void ProcessCommand_GetInfo(Message message, Host host) { if (host == null) return; string version = Config.VersionInfo; if (string.IsNullOrEmpty(version)) { version = System.Reflection.Assembly.GetExecutingAssembly().FullName; } MessageProxy.SendWithNoCheck(host, Consts.Commands.SendInfo, 0, version, ""); }
//查询版本回应 private void ProcessCommand_SendInfo(Message message, Host host) { if (host == null) return; host.ClientVersion = message.NormalMsg; }
/// <summary> /// 创建一个新的 PackageEventArgs 对象. /// </summary> public MessageEventArgs(Message message) { Message = message; IsHandled = false; this.Host = message.Host; }
/// <summary> /// 发送确认打开消息的包 /// </summary> /// <param name="m">原始数据包</param> public void SendReadMessageSignal(Message m) { MessageProxy.SendWithNoCheck(m.Host, Consts.Commands.ReadMsg, 0, m.PackageNo.ToString(), ""); }
private void ProcessCommand_IsGetList(Message message, Host host) { if (host == null) return; }
//收到消息包了? private void ProcessCommand_RecvMsg(Message message, Host host) { if (host == null) return; ulong pkno = message.NormalMsg.TryParseToInt(0ul); if (pkno == 0) return; Client.PopSendItemFromList(pkno, 0); OnTextMessageArrived(new MessageEventArgs(message, host)); }
//AnsEntry void ProcessCommand_AnsEntry(Message m, Host h) { if (h == null && (Config.IgnoreNoAddListFlag || !Consts.Check(m.Options, Consts.Cmd_Send_Option.NoAddList))) { h = new Host() { ClientVersion = string.Empty, GroupName = m.ExtendMessage, HasShare = false, HostSub = new HostSub() { HostName = m.HostName, Ipv4Address = m.HostAddr, UserName = m.UserName }, Index = 0, IsEnhancedContractEnabled = Consts.Check(m.Options, Consts.Cmd_All_Option.EnableNewDataContract), NickName = m.NormalMsg }; if (Consts.Check(m.Options, Consts.Cmd_All_Option.Absence)) h.ChangeAbsenceMode(true, Resources.CommandExecutor_ProcessCommand_Br_Entry_LeaveModeText); LivedHost.Add(m.HostAddr.Address.ToString(), h); h.AbsenceModeChanged += Host_AbsendModeChanged; //立刻查询离开消息 if (h.IsInAbsenceMode) Host_AbsendModeChanged(h, null); m.Host = h; } h.SupportEncrypt = Consts.Check(m.Options, Consts.Cmd_All_Option.Encrypt); h.SupportFileTransport = Consts.Check(m.Options, Consts.Cmd_All_Option.FileAttach); }
//Br_Exit void ProcessCommand_Br_Exit(Message m, Host h) { //如果开启了通知功能,则告知非本网段主机 if (h == null) return; LivedHost.Delete(h.HostSub.Ipv4Address.Address.ToString()); //通知非本网段主机 if (Config.EnableHostNotifyBroadcast && !Config.ForceOldContract) { Host[] list = LivedHost.Values.Where(s => s.HostSub.IPHeader != h.HostSub.IPHeader).Distinct(Helper.HostSubEqualityCompare.StaticObj).ToArray(); Array.ForEach(list, s => { MessageProxy.SendWithNoCheck(s, Consts.Commands.Br_Exit_Forward, 0, s.HostSub.Ipv4Address.Address.GetAddressBytes(), BitConverter.GetBytes(s.HostSub.PortNo)); }); } }
//Br_Entry void ProcessCommand_Br_Entry(Message m, Host h) { if (h == null && (Config.IgnoreNoAddListFlag || !Consts.Check(m.Options, Consts.Cmd_Send_Option.NoAddList))) { h = new Host() { ClientVersion = string.Empty, GroupName = m.ExtendMessage, HasShare = false, HostSub = new HostSub() { HostName = m.HostName, Ipv4Address = m.HostAddr, UserName = m.UserName }, Index = 0, IsEnhancedContractEnabled = Consts.Check(m.Options, Consts.Cmd_All_Option.EnableNewDataContract), NickName = m.NormalMsg, HostFeature = m.Options }; if (Consts.Check(m.Options, Consts.Cmd_All_Option.Absence)) h.ChangeAbsenceMode(true, Resources.CommandExecutor_ProcessCommand_Br_Entry_LeaveModeText); h.SupportEncrypt = Consts.Check(m.Options, Consts.Cmd_All_Option.Encrypt); h.SupportFileTransport = Consts.Check(m.Options, Consts.Cmd_All_Option.FileAttach); LivedHost.Add(m.HostAddr.Address.ToString(), h); h.AbsenceModeChanged += Host_AbsendModeChanged; //立刻查询离开消息 if (h.IsInAbsenceMode) Host_AbsendModeChanged(h, null); m.Host = h; } ulong opt = 0ul; if (Config.IsInAbsenceMode) opt |= (ulong)Consts.Cmd_All_Option.Absence; if (Config.EnableFileTransfer) opt |= (ulong)Consts.Cmd_All_Option.FileAttach; //插件 if (Config.Services != null) Config.Services.ProviderExecute(s => opt |= s.GenerateClientFeatures()); //回复证明自己在线 MessageProxy.SendWithNoCheck(h, Consts.Commands.AnsEntry, opt, Config.NickName, Config.GroupName); //如果开启了通知功能,则告知非本网段主机 if (h != null && Config.EnableHostNotifyBroadcast && !Config.ForceOldContract) { Host[] list = LivedHost.Values.Where(s => s.HostSub.IPHeader != h.HostSub.IPHeader && h.IsEnhancedContractEnabled).Distinct(Helper.HostSubEqualityCompare.StaticObj).ToArray(); Array.ForEach(list, s => MessageProxy.SendWithNoCheck(s, Consts.Commands.Br_Entry_Forward, 0, s.HostSub.Ipv4Address.Address.GetAddressBytes(), BitConverter.GetBytes(s.HostSub.PortNo))); } }
//处理空命令 private void ProcessCommand_Nop(Message m, Host h) { if (h == null) return; }
/// <summary> /// 发送打包好的消息 /// </summary> /// <param name="cm"></param> /// <returns>返回发出的消息包编号</returns> public ulong Send(Message cm) { if (!Client.IsInitialized) return 0ul; cm.Options |= (ulong)Define.Consts.Cmd_All_Option.EnableNewDataContract; MessageEventArgs mea = new MessageEventArgs(cm) { Message = cm, IsHandled = false, Host = cm.Host }; OnMessageSending(mea); if (mea.IsHandled) return mea.Message.PackageNo; //判断远程主机是否支持这个模式 if (!Config.ForceOldContract && cm.Host != null && cm.Host.IsEnhancedContractEnabled) { Entity.PackedNetworkMessage[] pnm = MessagePackerV2.BuildNetworkMessage(cm); PackageEventArgs pea = new PackageEventArgs(pnm.Length > 1, pnm[0], pnm); OnPckageSending(pea); if (!pea.IsHandled) { Array.ForEach(pnm, s => { Client.Send(s); }); OnPackageSended(pea); } } else { Entity.PackedNetworkMessage pn = MessagePacker.BuildNetworkMessage(cm); PackageEventArgs pe = new PackageEventArgs(false, pn, null); OnPckageSending(pe); if (!pe.IsHandled) { Client.Send(pn); OnPackageSended(pe); } } OnMessageSended(mea); return cm.PackageNo; }
/// <summary> /// 分析网络数据包并进行转换为信息对象 /// </summary> /// <param name="packs">接收到的封包对象</param> /// <returns></returns> /// <remarks> /// 对于分包消息,如果收到的只是片段并且尚未接收完全,则不会进行解析 /// </remarks> public static IPMessager.Entity.Message ParseToMessage(params Entity.PackedNetworkMessage[] packs) { if (packs.Length == 0 || (packs[0].PackageCount > 1 && packs.Length != packs[0].PackageCount)) return null; var ms = DecompressMessagePacks(packs); if (ms == null) { OnDecompressFailed(new DecomprssFailedEventArgs(packs)); return null; } //构造读取流 var br = new System.IO.BinaryReader(ms, System.Text.Encoding.Unicode); //开始读出数据 var m = new FSLib.IPMessager.Entity.Message(packs[0].RemoteIP); m.PackageNo = br.ReadUInt64(); //包编号 var tl = br.ReadUInt64(); m.Command = (Define.Consts.Commands)(tl & 0xFF); //命令编码 m.Options = tl & 0xFFFFFF00; //命令参数 m.UserName = br.ReadString(); //用户名 m.HostName = br.ReadString(); //主机名 var length = br.ReadInt32(); m.NormalMsgBytes = new byte[length]; br.Read(m.NormalMsgBytes, 0, length); length = br.ReadInt32(); m.ExtendMessageBytes = new byte[length]; br.Read(m.ExtendMessageBytes, 0, length); if (!Consts.Check(m.Options, Consts.Cmd_All_Option.BinaryMessage)) { m.NormalMsg = System.Text.Encoding.Unicode.GetString(m.NormalMsgBytes, 0, length); //正文 m.ExtendMessage = System.Text.Encoding.Unicode.GetString(m.ExtendMessageBytes, 0, length); //扩展消息 } return m; }
private void ProcessCommand_ReadMsg(Message message, Host host) { if (host != null) OnTextMessageOpened(new MessageEventArgs(message, host)); }
/// <summary> /// 检测是否需要发送回复包来确认收到 /// </summary> /// <param name="message"></param> /// <returns></returns> static bool DetermineConfirm2(Message message) { return !message.IsBroadCast && message.IsRequireReadCheck && !message.IsAutoSendMessage; }
//数据包收到确认 private void ProcessCommand_Ex_PackageRecevied(Message message, Host host) { if (host == null) return; ulong pkno = message.NormalMsg.TryParseToInt(0ul); int pkindex = message.ExtendMessage.TryParseToInt(0); if (pkno == 0) return; Client.PopSendItemFromList(pkno, pkindex); }
private void ProcessCommand_GetFileData(Message message, Host host) { if (host == null) return; //this command was executed by tcp file send,so we doesn't process this command here //but maybe we need to keep this section because it maybe useable }
//接收到文字消息 private void ProcessCommand_SendMsg(Message message, Host host) { if (host == null) return; //确认是否需要自动回复? if (!message.IsAutoSendMessage && (Config.AutoReply || (Config.AutoReplyWhenAbsence && Config.IsInAbsenceMode))) { string msg = string.IsNullOrEmpty(Config.AutoReplyMessage) ? Config.AutoReplyMessage : Config.AbsenceMessage; if (string.IsNullOrEmpty(msg)) msg = Resources.CommandExecutor_ProcessCommand_SendMsg_AutoReplyMessage; MessageProxy.SendWithNoCheck(host, Consts.Commands.SendMsg, (ulong)Consts.Cmd_Send_Option.AutoRet, msg, string.Empty); message.AutoReplyTime = DateTime.Now; } //触发事件 MessageEventArgs e = new MessageEventArgs(message, host); OnTextMessageReceiving(e); if (!e.IsHandled) OnTextMessageReceived(e); }
//process received absencemode private void ProcessCommand_SendAbsenceInfo(Message message, Host host) { if (host == null) return; host.ChangeAbsenceMode(host.IsInAbsenceMode, message.NormalMsg); }
//离开状态或昵称更改 private void ProcessCommand_BrAbsence(Message message, Host host) { if (host == null) return; host.ChangeAbsenceMode(Consts.Check(message.Options, Consts.Cmd_All_Option.Absence), ""); if (!string.IsNullOrEmpty(message.NormalMsg)) host.NickName = message.NormalMsg; if (!string.IsNullOrEmpty(message.ExtendMessage)) host.GroupName = message.ExtendMessage; host.HostFeature = message.Options; }
//发送离开信息? private void ProcessCommand_GetAbsenceInfo(Message message, Host host) { if (host == null) return; MessageProxy.SendWithNoCheck(host, Consts.Commands.SendAbsenceInfo, 0ul, Config.IsInAbsenceMode ? Config.AbsenceMessage : Resources.CommandExecutor_ProcessCommand_GetAbsenceInfo_NotAbsenceMode, ""); }
private void ProcessCommand_ReleaseFiles(Message message, Host host) { if (host == null) return; //释放文件 ulong pkgid = 0; if (!ulong.TryParse(message.NormalMsg, out pkgid) || pkgid == 0) return; FileTaskManager.ReleaseFile(pkgid); }
/// <summary> /// 创建一个新的 MessageEventArgs 对象. /// </summary> public MessageEventArgs(Message message, Host host) { Message = message; this.Host = host; IsHandled = false; }