Пример #1
0
/**
 * 好友更改个人信息.
 */
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();
}
Пример #2
0
/**
 * 好友发送个性签名.
 */
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();
        }
}
Пример #3
0
/**
 * 好友请求本计算机的共享文件.
 */
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);
        }
}
Пример #4
0
/**
 * 好友上线.
 */
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);
        }
}
Пример #5
0
/**
 * 好友接收到消息.
 */
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;      //标记此包编号已经被回复
        }
}
Пример #6
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);
}
Пример #7
0
/**
 * 确保好友一定在线.
 * @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;
}
Пример #8
0
/**
 * 封装消息.
 * @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;
}
Пример #9
0
/**
 * 好友退出.
 */
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();
}
Пример #10
0
/**
 * 回馈消息.
 * @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);
        para.dtlist = NULL;     //防止参数数据被修改
}
Пример #11
0
/**
 * 好友发送头像数据.
 */
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();
        }
}
Пример #12
0
/**
 * 请求文件数据入口.
 * @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);
}
Пример #13
0
/**
 * 接收好友文件信息.
 */
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(&para);
                g_datalist_set_data(&para, "palinfo", cthrd.GetPalFromList(ipv4));
                g_datalist_set_data_full(&para, "extra-data", g_strdup(ptr),
                                                 GDestroyNotify(g_free));
                g_datalist_set_data(&para, "packetno", GUINT_TO_POINTER(packetno));
                g_datalist_set_data(&para, "commandno", GUINT_TO_POINTER(commandno));
                pthread_create(&pid, NULL, ThreadFunc(RecvFile::RecvEntry), para);
                pthread_detach(pid);
        }
}
Пример #14
0
/**
 * 好友在线.
 */
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);
}
Пример #15
0
/**
 * 好友广播消息.
 */
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);
}
Пример #16
0
/**
 * 好友发送消息.
 *
 */
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);
}