/** * 好友更改个人信息. */ void UdpData::SomeoneAbsence() { PalInfo *pal; const char *ptr; /* 若好友不兼容iptux协议,则需转码 */ pal = cthrd.GetPalFromList(ipv4); //利用好友链表只增不减的特性,无须加锁 ptr = iptux_skip_string(buf, size, 3); if (!ptr || *ptr == '\0') ConvertEncode(pal ? pal->encode : progdt.encode); /* 加入或更新好友列表 */ gdk_threads_enter(); pthread_mutex_lock(cthrd.GetMutex()); if (pal) { UpdatePalInfo(pal); cthrd.UpdatePalToList(ipv4); } else { pal = CreatePalInfo(); cthrd.AttachPalToList(pal); } pthread_mutex_unlock(cthrd.GetMutex()); if (mwin.PaltreeContainItem(ipv4)) mwin.UpdateItemToPaltree(ipv4); else mwin.AttachItemToPaltree(ipv4); gdk_threads_leave(); }
/** * 好友发送个性签名. */ void UdpData::SomeoneSendSign() { PalInfo *pal; char *sign; if (!(pal = cthrd.GetPalFromList(ipv4))) return; /* 若好友不兼容iptux协议,则需转码 */ if (!FLAG_ISSET(pal->flags, 0)) ConvertEncode(pal->encode); /* 对编码作适当调整 */ if (strcasecmp(pal->encode, encode ? encode : "utf-8") != 0) { g_free(pal->encode); pal->encode = g_strdup(encode ? encode : "utf-8"); } /* 更新 */ if ( (sign = ipmsg_get_attach(buf, ':', 5))) { g_free(pal->sign); pal->sign = sign; gdk_threads_enter(); pthread_mutex_lock(cthrd.GetMutex()); cthrd.UpdatePalToList(ipv4); pthread_mutex_unlock(cthrd.GetMutex()); mwin.UpdateItemToPaltree(ipv4); gdk_threads_leave(); } }
/** * 好友请求本计算机的共享文件. */ void UdpData::SomeoneAskShared() { Command cmd; pthread_t pid; PalInfo *pal; const char *limit; char *passwd; if (!(pal = cthrd.GetPalFromList(ipv4))) return; limit = cthrd.GetAccessPublicLimit(); if (!limit || *limit == '\0') { pthread_create(&pid, NULL, ThreadFunc(ThreadAskSharedFile), pal); pthread_detach(pid); } else if (!(iptux_get_dec_number(buf, ':', 4) & IPTUX_PASSWDOPT)) { cmd.SendFileInfo(cthrd.UdpSockQuote(), pal, IPTUX_SHAREDOPT | IPTUX_PASSWDOPT, ""); } else if ( (passwd = ipmsg_get_attach(buf, ':', 5))) { if (strcmp(passwd, limit) == 0) { pthread_create(&pid, NULL, ThreadFunc(ThreadAskSharedFile), pal); pthread_detach(pid); } g_free(passwd); } }
/** * 好友上线. */ void UdpData::SomeoneEntry() { Command cmd; pthread_t pid; PalInfo *pal; /* 转换缓冲区数据编码 */ ConvertEncode(progdt.encode); /* 加入或更新好友列表 */ gdk_threads_enter(); pthread_mutex_lock(cthrd.GetMutex()); if ( (pal = cthrd.GetPalFromList(ipv4))) { UpdatePalInfo(pal); cthrd.UpdatePalToList(ipv4); } else { pal = CreatePalInfo(); cthrd.AttachPalToList(pal); } pthread_mutex_unlock(cthrd.GetMutex()); if (mwin.PaltreeContainItem(ipv4)) mwin.UpdateItemToPaltree(ipv4); else mwin.AttachItemToPaltree(ipv4); gdk_threads_leave(); /* 通知好友本大爷在线 */ cmd.SendAnsentry(cthrd.UdpSockQuote(), pal); if (FLAG_ISSET(pal->flags, 0)) { pthread_create(&pid, NULL, ThreadFunc(CoreThread::SendFeatureData), pal); pthread_detach(pid); } }
/** * 好友接收到消息. */ void UdpData::SomeoneRecvmsg() { uint32_t packetno; PalInfo *pal; if ( (pal = cthrd.GetPalFromList(ipv4))) { packetno = iptux_get_dec_number(buf, ':', 5); if (packetno == pal->rpacketn) pal->rpacketn = 0; //标记此包编号已经被回复 } }
/** * 请求获取此好友的共享文件. * @param grpinf 好友群组信息 */ void DialogPeer::AskSharedFiles(GroupInfo *grpinf) { Command cmd; PalInfo *pal; if (!(grpinf->member)) pal = cthrd.GetPalFromList(grpinf->grpid); else pal = (PalInfo *)grpinf->member->data; cmd.SendAskShared(cthrd.UdpSockQuote(), pal, 0, NULL); }
/** * 确保好友一定在线. * @return 好友数据 */ PalInfo *UdpData::AssertPalOnline() { PalInfo *pal; if ( (pal = cthrd.GetPalFromList(ipv4))) { /* 既然好友不在线,那么他自然不在列表中 */ if (!FLAG_ISSET(pal->flags, 1)) { FLAG_SET(pal->flags, 1); gdk_threads_enter(); pthread_mutex_lock(cthrd.GetMutex()); cthrd.UpdatePalToList(ipv4); pthread_mutex_unlock(cthrd.GetMutex()); mwin.AttachItemToPaltree(ipv4); gdk_threads_leave(); } } else { SomeoneLost(); pal = cthrd.GetPalFromList(ipv4); } return pal; }
/** * 封装消息. * @param dtlist 数据链表 * @return 消息封装包 */ MsgPara *DialogPeer::PackageMsg(GSList *dtlist) { MsgPara *para; para = new MsgPara; if (!(grpinf->member)) para->pal = cthrd.GetPalFromList(grpinf->grpid); else para->pal = (PalInfo *)grpinf->member->data; para->stype = MESSAGE_SOURCE_TYPE_SELF; para->btype = grpinf->type; para->dtlist = dtlist; return para; }
/** * 好友退出. */ void UdpData::SomeoneExit() { PalInfo *pal; /* 从好友链表中删除 */ gdk_threads_enter(); if (mwin.PaltreeContainItem(ipv4)) mwin.DelItemFromPaltree(ipv4); pthread_mutex_lock(cthrd.GetMutex()); if ( (pal = cthrd.GetPalFromList(ipv4))) { cthrd.DelPalFromList(ipv4); FLAG_CLR(pal->flags, 1); } pthread_mutex_unlock(cthrd.GetMutex()); gdk_threads_leave(); }
/** * 回馈消息. * @param dtlist 数据链表 * @note 请不要修改链表(dtlist)中的数据 */ void DialogPeer::FeedbackMsg(const GSList *dtlist) { MsgPara para; /* 构建消息封装包 */ if (grpinf->member) para.pal = (PalInfo *)grpinf->member->data; else para.pal = cthrd.GetPalFromList(grpinf->grpid); para.stype = MESSAGE_SOURCE_TYPE_SELF; para.btype = grpinf->type; para.dtlist = (GSList *)dtlist; /* 交给某人处理吧 */ cthrd.InsertMsgToGroupInfoItem(grpinf, ¶); para.dtlist = NULL; //防止参数数据被修改 }
/** * 好友发送头像数据. */ void UdpData::SomeoneSendIcon() { PalInfo *pal; char *iconfile; if (!(pal = cthrd.GetPalFromList(ipv4)) || FLAG_ISSET(pal->flags, 2)) return; /* 接收并更新数据 */ if ( (iconfile = RecvPalIcon())) { g_free(pal->iconfile); pal->iconfile = iconfile; gdk_threads_enter(); pthread_mutex_lock(cthrd.GetMutex()); cthrd.UpdatePalToList(ipv4); pthread_mutex_unlock(cthrd.GetMutex()); mwin.UpdateItemToPaltree(ipv4); gdk_threads_leave(); } }
/** * 请求文件数据入口. * @param sock tcp socket * @param fileattr 文件类型 * @param attach 附加数据 */ void SendFile::RequestDataEntry(int sock, uint32_t fileattr, char *attach) { struct sockaddr_in addr; socklen_t len; PalInfo *pal; FileInfo *file; uint32_t fileid; uint32_t filectime; /* 检查文件属性是否匹配 */ fileid = iptux_get_hex_number(attach, ':', 1); file = (FileInfo *)cthrd.GetFileFromAll(fileid); /* 兼容windows版信鸽(IPMSG) ,这里的信鸽不是飞鸽传书(IPMSG)*/ if(!file) { fileid = iptux_get_dec_number(attach, ':', 1); file = (FileInfo *)cthrd.GetFileFromAll(fileid); } /* 兼容adroid版信鸽(IPMSG) */ if(!file) { fileid = iptux_get_hex_number(attach, ':', 0); filectime = iptux_get_dec_number(attach, ':', 1); file = (FileInfo *)cthrd.GetFileFromAllWithPacketN(fileid,filectime); } if (!file || GET_MODE(file->fileattr) != GET_MODE(fileattr)) return; /* 检查好友数据是否存在 */ len = sizeof(addr); getpeername(sock, (struct sockaddr *)&addr, &len); if (!(pal = cthrd.GetPalFromList(addr.sin_addr.s_addr))) return; /* 发送文件数据 */ // /** // *文件信息可能被删除或修改,必须单独复制一份. // */ // file->fileown = pal; ThreadSendFile(sock, file); }
/** * 接收好友文件信息. */ void UdpData::RecvPalFile() { uint32_t packetno, commandno; const char *ptr; pthread_t pid; GData *para; packetno = iptux_get_dec_number(buf, ':', 1); commandno = iptux_get_dec_number(buf, ':', 4); ptr = iptux_skip_string(buf, size, 1); /* 只有当此为共享文件信息或文件信息不为空才需要接收 */ if ((commandno & IPTUX_SHAREDOPT) || (ptr && *ptr != '\0')) { para = NULL; g_datalist_init(¶); g_datalist_set_data(¶, "palinfo", cthrd.GetPalFromList(ipv4)); g_datalist_set_data_full(¶, "extra-data", g_strdup(ptr), GDestroyNotify(g_free)); g_datalist_set_data(¶, "packetno", GUINT_TO_POINTER(packetno)); g_datalist_set_data(¶, "commandno", GUINT_TO_POINTER(commandno)); pthread_create(&pid, NULL, ThreadFunc(RecvFile::RecvEntry), para); pthread_detach(pid); } }
/** * 好友在线. */ void UdpData::SomeoneAnsentry() { Command cmd; pthread_t pid; PalInfo *pal; const char *ptr; /* 若好友不兼容iptux协议,则需转码 */ ptr = iptux_skip_string(buf, size, 3); if (!ptr || *ptr == '\0') ConvertEncode(progdt.encode); /* 加入或更新好友列表 */ gdk_threads_enter(); pthread_mutex_lock(cthrd.GetMutex()); if ( (pal = cthrd.GetPalFromList(ipv4))) { UpdatePalInfo(pal); cthrd.UpdatePalToList(ipv4); } else { pal = CreatePalInfo(); cthrd.AttachPalToList(pal); } pthread_mutex_unlock(cthrd.GetMutex()); if (mwin.PaltreeContainItem(ipv4)) mwin.UpdateItemToPaltree(ipv4); else mwin.AttachItemToPaltree(ipv4); gdk_threads_leave(); /* 更新本大爷的数据信息 */ if (FLAG_ISSET(pal->flags, 0)) { pthread_create(&pid, NULL, ThreadFunc(CoreThread::SendFeatureData), pal); pthread_detach(pid); } else if (strcasecmp(progdt.encode, pal->encode) != 0) cmd.SendAnsentry(cthrd.UdpSockQuote(), pal); }
/** * 好友广播消息. */ void UdpData::SomeoneBcstmsg() { GroupInfo *grpinf; PalInfo *pal; uint32_t commandno, packetno; char *text; /* 如果对方兼容iptux协议,则无须再转换编码 */ pal = cthrd.GetPalFromList(ipv4); if (!pal || !FLAG_ISSET(pal->flags, 0)) ConvertEncode(pal ? pal->encode : progdt.encode); /* 确保好友在线,并对编码作出适当调整 */ pal = AssertPalOnline(); if (strcasecmp(pal->encode, encode ? encode : "utf-8") != 0) { g_free(pal->encode); pal->encode = g_strdup(encode ? encode : "utf-8"); } /* 检查此消息是否过时 */ packetno = iptux_get_dec_number(buf, ':', 1); if (packetno <= pal->packetn) return; pal->packetn = packetno; /* 插入消息&在消息队列中注册 */ text = ipmsg_get_attach(buf, ':', 5); if (text && *text != '\0') { commandno = iptux_get_dec_number(buf, ':', 4); /*/* 插入消息 */ switch (GET_OPT(commandno)) { case IPTUX_BROADCASTOPT: InsertMessage(pal, GROUP_BELONG_TYPE_BROADCAST, text); break; case IPTUX_GROUPOPT: InsertMessage(pal, GROUP_BELONG_TYPE_GROUP, text); break; case IPTUX_SEGMENTOPT: InsertMessage(pal, GROUP_BELONG_TYPE_SEGMENT, text); break; case IPTUX_REGULAROPT: default: InsertMessage(pal, GROUP_BELONG_TYPE_REGULAR, text); break; } /*/* 注册消息 */ pthread_mutex_lock(cthrd.GetMutex()); switch (GET_OPT(commandno)) { case IPTUX_BROADCASTOPT: grpinf = cthrd.GetPalBroadcastItem(pal); break; case IPTUX_GROUPOPT: grpinf = cthrd.GetPalGroupItem(pal); break; case IPTUX_SEGMENTOPT: grpinf = cthrd.GetPalSegmentItem(pal); break; case IPTUX_REGULAROPT: default: grpinf = cthrd.GetPalRegularItem(pal); break; } if (!grpinf->dialog && !cthrd.MsglineContainItem(grpinf)) cthrd.PushItemToMsgline(grpinf); pthread_mutex_unlock(cthrd.GetMutex()); } g_free(text); /* 播放提示音 */ if (FLAG_ISSET(progdt.sndfgs, 1)) sndsys.Playing(progdt.msgtip); }
/** * 好友发送消息. * */ void UdpData::SomeoneSendmsg() { GroupInfo *grpinf; PalInfo *pal; Command cmd; uint32_t commandno, packetno; char *text; pthread_t pid; DialogPeer *dlgpr; GtkWidget *window; /* 如果对方兼容iptux协议,则无须再转换编码 */ pal = cthrd.GetPalFromList(ipv4); if (!pal || !FLAG_ISSET(pal->flags, 0)) ConvertEncode(pal ? pal->encode : progdt.encode); /* 确保好友在线,并对编码作出适当调整 */ pal = AssertPalOnline(); if (strcasecmp(pal->encode, encode ? encode : "utf-8") != 0) { g_free(pal->encode); pal->encode = g_strdup(encode ? encode : "utf-8"); } /* 回复好友并检查此消息是否过时 */ commandno = iptux_get_dec_number(buf, ':', 4); packetno = iptux_get_dec_number(buf, ':', 1); if (commandno & IPMSG_SENDCHECKOPT) cmd.SendReply(cthrd.UdpSockQuote(), pal, packetno); if (packetno <= pal->packetn) return; pal->packetn = packetno; /* 插入消息&在消息队列中注册 */ text = ipmsg_get_attach(buf, ':', 5); if (text && *text != '\0') { /*/* 插入消息 */ // if ((commandno & IPMSG_BROADCASTOPT) || (commandno & IPMSG_MULTICASTOPT)) // InsertMessage(pal, GROUP_BELONG_TYPE_BROADCAST, text); // else InsertMessage(pal, GROUP_BELONG_TYPE_REGULAR, text); } g_free(text); /*/* 注册消息 */ pthread_mutex_lock(cthrd.GetMutex()); // if ((commandno & IPMSG_BROADCASTOPT) || (commandno & IPMSG_MULTICASTOPT)) // grpinf = cthrd.GetPalBroadcastItem(pal); // else grpinf = cthrd.GetPalRegularItem(pal); if (!grpinf->dialog && !cthrd.MsglineContainItem(grpinf)) cthrd.PushItemToMsgline(grpinf); pthread_mutex_unlock(cthrd.GetMutex()); /* 标记位处理 先处理底层数据,后面显示窗口*/ if (commandno & IPMSG_FILEATTACHOPT) { if ((commandno & IPTUX_SHAREDOPT) && (commandno & IPTUX_PASSWDOPT)) { pthread_create(&pid, NULL, ThreadFunc(ThreadAskSharedPasswd), pal); pthread_detach(pid); } else RecvPalFile(); } window = GTK_WIDGET(grpinf->dialog); //这里不知道为什么运行时一直会提示window不是object dlgpr = (DialogPeer *)(g_object_get_data(G_OBJECT(window),"dialog")); if(grpinf->dialog) dlgpr->ShowDialogPeer(dlgpr); /* 是否直接弹出聊天窗口 */ if (FLAG_ISSET(progdt.flags, 7)) { gdk_threads_enter(); if (!(grpinf->dialog)) { // switch (grpinf->type) { // case GROUP_BELONG_TYPE_REGULAR: DialogPeer::PeerDialogEntry(grpinf); // break; // case GROUP_BELONG_TYPE_SEGMENT: // case GROUP_BELONG_TYPE_GROUP: // case GROUP_BELONG_TYPE_BROADCAST: // DialogGroup::GroupDialogEntry(grpinf); // default: // break; // } } else { gtk_window_present(GTK_WINDOW(grpinf->dialog)); } gdk_threads_leave(); } /* 播放提示音 */ if (FLAG_ISSET(progdt.sndfgs, 1)) sndsys.Playing(progdt.msgtip); }