예제 #1
0
void ICQClientPrivate::snac_lists(unsigned short type, unsigned short seq)
{
    switch (type){
    case ICQ_SNACxLISTS_RIGHTS:
        log(L_DEBUG, "List rights");
        break;
    case ICQ_SNACxLISTS_ROSTER:{
            char c;
            unsigned short list_len;
            log(L_DEBUG,"Rosters");
            sock->readBuffer >> c;
            if (c){
                log(L_WARN, "Bad first roster byte %02X", c);
                break;
            }
            bool bIgnoreTime = false;
            vector<ICQGroup*>::iterator it_grp;
            list<ICQUser*>::iterator it_usr;
            if (!m_bRosters){
                m_bRosters = true;
                client->contacts.Invisible = 0;
                for (it_grp = client->contacts.groups.begin(); it_grp != client->contacts.groups.end(); it_grp++)
                    (*it_grp)->bChecked = false;
                for (it_usr = client->contacts.users.begin(); it_usr != client->contacts.users.end(); it_usr++){
                    if ((*it_usr)->Type != USER_TYPE_ICQ) continue;
                    (*it_usr)->Id = 0;
                    (*it_usr)->GrpId = 0;
                    (*it_usr)->IgnoreId = 0;
                    (*it_usr)->VisibleId = 0;
                    (*it_usr)->InvisibleId = 0;
                }
            }
            sock->readBuffer >> list_len;
            for (unsigned i = 0; i < list_len; i++){
                string str;
                unsigned short id, grp_id, type, len;
                sock->readBuffer.unpackStr(str);
                sock->readBuffer >> grp_id >> id >> type >> len;
                TlvList *inf = NULL;
                if (len){
                    Buffer b(len);
                    b.pack(sock->readBuffer.Data(sock->readBuffer.readPos()), len);
                    sock->readBuffer.incReadPos(len);
                    inf = new TlvList(b);
                }
                switch (type){
                case 0x0000: /* User */{
                        unsigned long uin = atol(str.c_str());
                        if (uin){
                            Tlv *tlv_name = NULL;
                            if (inf) tlv_name = (*inf)(0x0131);
                            string alias = tlv_name ? (char*)(*tlv_name) : "";
                            client->fromUTF(alias, client->owner->Encoding.c_str());
                            bool needAuth = false;
                            if (inf && (*inf)(0x0066)) needAuth = true;
                            ICQUser *user = client->getUser(uin, true);
                            user->Id = id;
                            user->GrpId = grp_id;
                            user->Alias = alias;
                            user->WaitAuth = needAuth;
                            Tlv *tlv_phone = NULL;
                            if (inf) tlv_phone = (*inf)(0x13A);
                            if (tlv_phone){
                                user->Phones.add(*tlv_phone, "Private cellular", SMS, true, false);
                                user->adjustPhones();
                            }
                        }else{
                            bIgnoreTime = true;
                        }
                        break;
                    }
                case ICQ_GROUPS:{
                        if (str.size() == 0) break;
                        client->fromUTF(str, client->owner->Encoding.c_str());
                        ICQGroup *grp = client->getGroup(grp_id, true);
                        if (grp == NULL){
                            grp = client->createGroup();
                            client->contacts.groups.push_back(grp);
                        }
                        grp->Id = grp_id;
                        grp->Name = str;
                        grp->bChecked = true;
                        break;
                    }
                case ICQ_VISIBLE_LIST:{
                        unsigned long uin = atol(str.c_str());
                        if (uin)
                            client->getUser(atol(str.c_str()), true)->VisibleId = id;
                        break;
                    }
                case ICQ_INVISIBLE_LIST:{
                        unsigned long uin = atol(str.c_str());
                        if (uin)
                            client->getUser(atol(str.c_str()), true)->InvisibleId = id;
                        break;
                    }
                case ICQ_IGNORE_LIST:{
                        unsigned long uin = atol(str.c_str());
                        if (uin)
                            client->getUser(atol(str.c_str()), true)->IgnoreId = id;
                        break;
                    }
                case ICQ_INVISIBLE_STATE:
                    client->contacts.Invisible = id;
                    break;
                case 0x0009:
                case 0x0011:
                case 0x0013:
                    break;
                default:
                    log(L_WARN,"Unknown roster type %04X", type);
                }
                if (inf) delete inf;
            }
            unsigned long time;
            sock->readBuffer >> time;
            if ((time == 0) && list_len && !bIgnoreTime)
                break;

            client->contacts.Time = time;
            for (;;){
                bool ok = true;
                for (it_grp = client->contacts.groups.begin(); it_grp != client->contacts.groups.end(); it_grp++){
                    if (!(*it_grp)->bChecked){
                        client->contacts.groups.erase(it_grp);
                        ok = false;
                        break;
                    }
                }
                if (ok) break;
            }
            for (it_usr = client->contacts.users.begin(); it_usr != client->contacts.users.end(); it_usr++){
                unsigned short grpId = (*it_usr)->GrpId;
                bool ok = false;
                for (it_grp = client->contacts.groups.begin(); it_grp != client->contacts.groups.end(); it_grp++){
                    if ((*it_grp)->Id == grpId){
                        ok = true;
                        break;
                    }
                }
                if (!ok) (*it_usr)->GrpId = 0;
            }
            ICQEvent e(EVENT_GROUP_CHANGED);
            client->process_event(&e);
            m_state = Logged;
        }
    case ICQ_SNACxLISTS_ROSTERxOK:	// FALLTHROUGH
        {
            log(L_DEBUG, "Rosters OK");
            snac(ICQ_SNACxFAM_LISTS, ICQ_SNACxLISTS_UNKNOWN);
            sendPacket();
            sendCapability();
            sendICMB();
            sendLogonStatus();
            sendClientReady();
            sendMessageRequest();
            sendPhoneStatus();
            if (client->owner->Nick.size() == 0){
                client->addInfoRequest(client->owner->Uin);
                client->searchByUin(client->owner->Uin);
            }
            list<ICQUser*>::iterator it;
            for (it = client->contacts.users.begin(); it != client->contacts.users.end(); it++){
                ICQUser *u = *it;
                if (u->IgnoreId) continue;
                if (u->Nick.size() || u->Alias.size()) continue;
                client->addInfoRequest(u->Uin);
            }
            if (client->contacts.groups.size() == 0){
                m_state = Logged;
                client->createGroup("General");
            }
            if (client->contacts.Invisible == 0){
                snac(ICQ_SNACxFAM_LISTS, ICQ_SNACxLISTS_EDIT);
                sendPacket();
                snac(ICQ_SNACxFAM_LISTS, ICQ_SNACxLISTS_CREATE, true);
                sock->writeBuffer
                << 0x00000000L << 0x00000001L
                << 0x000400C8L << (unsigned short)0;
                sendPacket();
                snac(ICQ_SNACxFAM_LISTS, ICQ_SNACxLISTS_SAVE);
                sendPacket();
            }
            break;
        }
    case ICQ_SNACxLISTS_ADDED:{
            sock->readBuffer.incReadPos(8);
            unsigned long uin = sock->readBuffer.unpackUin();
            ICQAddedToList *m = new ICQAddedToList;
            m->Uin.push_back(uin);
            messageReceived(m);
            break;
        }
    case ICQ_SNACxLISTS_AUTHxREQUEST:{
            sock->readBuffer.incReadPos(8);
            unsigned long uin = sock->readBuffer.unpackUin();
            ICQUser *u = client->getUser(uin);
            string message;
            string charset;
            unsigned short have_charset;
            sock->readBuffer.unpackStr(message);
            sock->readBuffer >> have_charset;
            if (have_charset){
                sock->readBuffer.incReadPos(2);
                sock->readBuffer.unpackStr(charset);
            }
            if (charset.size()){
                client->translate(client->localCharset(u), charset.c_str(), message);
            }else{
                client->fromServer(message, u);
            }
            log(L_DEBUG, "Auth request %lu", uin);

            ICQAuthRequest *m = new ICQAuthRequest;
            m->Uin.push_back(uin);
            m->Message = message;
            messageReceived(m);
            break;
        }
    case ICQ_SNACxLISTS_AUTH:{
            sock->readBuffer.incReadPos(8);
            unsigned long uin = sock->readBuffer.unpackUin();
            char auth_ok;
            sock->readBuffer >> auth_ok;
            string message;
            string charset;
            unsigned short have_charset;
            sock->readBuffer.unpackStr(message);
            sock->readBuffer >> have_charset;
            if (have_charset){
                sock->readBuffer.incReadPos(2);
                sock->readBuffer.unpackStr(charset);
            }
            ICQUser *u = client->getUser(uin);
            if (charset.size()){
                client->translate(client->localCharset(u), charset.c_str(), message);
            }else{
                client->fromServer(message, u);
            }
            log(L_DEBUG, "Auth %u %lu", auth_ok, uin);
            if (auth_ok){
                ICQUser *user = client->getUser(uin);
                if (user){
                    user->WaitAuth = false;
                    ICQEvent e(EVENT_INFO_CHANGED, uin);
                    client->process_event(&e);
                }
                ICQAuthGranted *m = new ICQAuthGranted();
                m->Uin.push_back(uin);
                messageReceived(m);
            }else{
                ICQAuthRefused *m = new ICQAuthRefused();
                m->Uin.push_back(uin);
                m->Message = message;
                messageReceived(m);
            }
            break;
        }
    case ICQ_SNACxLISTS_DONE:{
            ICQEvent *e = findListEvent(seq);
            if (e == NULL) break;
            sock->readBuffer.incReadPos(8);
            unsigned short res;
            sock->readBuffer >> res;
            e->processAnswer(this, sock->readBuffer, res);
            delete e;
            break;
        }
    default:
        log(L_WARN, "Unknown lists family type %04X", type);
    }
}
예제 #2
0
void ICQClient::snac_lists(unsigned short type, unsigned short seq)
{
    bool bFull = false;
    switch (type){
    case ICQ_SNACxLISTS_RIGHTS:
        log(L_DEBUG, "List rights");
        break;
    case ICQ_SNACxLISTS_ROSTER:{
            char c;
            unsigned short list_len;
            log(L_DEBUG,"Rosters");
            if (m_bRosters){
                log(L_DEBUG, "Rosters part 2");
                break;
            }
            readBuffer >> c;
            if (c){
                log(L_WARN, "Bad first roster byte %02X", c);
                break;
            }
            vector<ICQGroup*>::iterator it_grp;
            list<ICQUser*>::iterator it_usr;
            for (it_grp = contacts.groups.begin(); it_grp != contacts.groups.end(); it_grp++)
                (*it_grp)->bChecked = false;
            for (it_usr = contacts.users.begin(); it_usr != contacts.users.end(); it_usr++){
                if ((*it_usr)->Type != USER_TYPE_ICQ) continue;
                (*it_usr)->Id = 0;
                (*it_usr)->GrpId = 0;
                (*it_usr)->inIgnore = false;
                (*it_usr)->inVisible = false;
                (*it_usr)->inInvisible = false;
            }
            readBuffer >> list_len;
            for (unsigned i = 0; i < list_len; i++){
                string str;
                unsigned short id, grp_id, type, len;
                readBuffer.unpackStr(str);
                readBuffer >> grp_id >> id >> type >> len;
                TlvList *inf = NULL;
                if (len){
                    Buffer b(len);
                    b.pack(readBuffer.Data(readBuffer.readPos()), len);
                    readBuffer.incReadPos(len);
                    inf = new TlvList(b);
                }
                switch (type){
                case 0x0000: /* User */{
                        unsigned long uin = atol(str.c_str());
                        if (uin == 0){
                            log(L_WARN, "Bad uin record %s\n", str.c_str());
                            break;
                        }
                        Tlv *tlv_name = NULL;
                        if (inf) tlv_name = (*inf)(0x0131);
                        string alias = tlv_name ? (char*)(*tlv_name) : "";
                        fromUTF(alias);
                        bool needAuth = false;
                        if (inf && (*inf)(0x0066)) needAuth = true;
                        ICQUser *user = getUser(uin, true);
                        user->Id = id;
                        user->GrpId = grp_id;
                        user->Alias = alias;
                        user->WaitAuth = needAuth;
                        break;
                    }
                case ICQ_GROUPS:{
                        if (str.size() == 0) break;
                        fromUTF(str);
                        ICQGroup *grp = getGroup(grp_id, true);
                        if (grp == NULL){
                            grp = new ICQGroup();
                            contacts.groups.push_back(grp);
                        }
                        grp->Id = grp_id;
                        grp->Name = str;
                        grp->bChecked = true;
                        break;
                    }
                case ICQ_VISIBLE_LIST:{
                        unsigned long uin = atol(str.c_str());
                        if (uin)
                            getUser(atol(str.c_str()), true)->inVisible = true;
                        break;
                    }
                case ICQ_INVISIBLE_LIST:{
                        unsigned long uin = atol(str.c_str());
                        if (uin)
                            getUser(atol(str.c_str()), true)->inInvisible = true;
                        break;
                    }
                case ICQ_IGNORE_LIST:{
                        unsigned long uin = atol(str.c_str());
                        if (uin)
                            getUser(atol(str.c_str()), true)->inIgnore = true;
                        break;
                    }
                case ICQ_INVISIBLE_STATE:
                    contacts.Invisible = id;
                    break;
                case 0x0009:
                    break;
                default:
                    log(L_WARN,"Unknown roster type %04X", type);
                }
                if (inf) delete inf;
            }
            unsigned long time;
            readBuffer >> time;
            contacts.Time = time;
            for (;;){
                bool ok = true;
                for (it_grp = contacts.groups.begin(); it_grp != contacts.groups.end(); it_grp++){
                    if (!(*it_grp)->bChecked){
                        contacts.groups.erase(it_grp);
                        ok = false;
                        break;
                    }
                }
                if (ok) break;
            }
            for (it_usr = contacts.users.begin(); it_usr != contacts.users.end(); it_usr++){
                unsigned short grpId = (*it_usr)->GrpId();
                bool ok = false;
                for (it_grp = contacts.groups.begin(); it_grp != contacts.groups.end(); it_grp++){
                    if ((*it_grp)->Id() == grpId){
                        ok = true;
                        break;
                    }
                }
                if (!ok) (*it_usr)->GrpId = 0;
            }
            ICQEvent e(EVENT_GROUP_CHANGED);
            process_event(&e);
            m_state = Logged;
            bFull = true;
        }
    case ICQ_SNACxLISTS_ROSTERxOK:	// FALLTHROUGH
        {
            m_bRosters = true;
            log(L_DEBUG, "Rosters OK");
            snac(ICQ_SNACxFAM_LISTS, ICQ_SNACxLISTS_UNKNOWN);
            sendPacket();
            sendCapability();
            sendICMB();
            sendLogonStatus();
            sendClientReady();
            sendMessageRequest();
            sendPhoneInit();
            sendPhoneStatus();
            if (bFull || (Nick.size() == 0)){
                addInfoRequest(Uin);
                searchByUin(Uin);
            }
            list<ICQUser*>::iterator it;
            for (it = contacts.users.begin(); it != contacts.users.end(); it++){
                if ((*it)->inIgnore()) continue;
                if (!bFull && (*it)->Nick.size()) continue;
                addInfoRequest((*it)->Uin);
            }
            if (contacts.groups.size() == 0){
                m_state = Logged;
                createGroup("General");
            }
            break;
        }
    case ICQ_SNACxLISTS_ADDED:{
            readBuffer.incReadPos(8);
            unsigned long uin = readBuffer.unpackUin();
            ICQAddedToList *m = new ICQAddedToList;
            m->Uin.push_back(uin);
            messageReceived(m);
            break;
        }
    case ICQ_SNACxLISTS_AUTHxREQUEST:{
            readBuffer.incReadPos(8);
            unsigned long uin = readBuffer.unpackUin();
            ICQUser *u = getUser(uin);
            string message;
            string charset;
            unsigned short have_charset;
            readBuffer.unpackStr(message);
            readBuffer >> have_charset;
            if (have_charset){
                readBuffer.incReadPos(2);
                readBuffer.unpackStr(charset);
            }
            if (charset.size()){
                translate(localCharset(u), charset.c_str(), message);
            }else{
                fromServer(message, u);
            }
            log(L_DEBUG, "Auth request %lu", uin);

            ICQAuthRequest *m = new ICQAuthRequest;
            m->Uin.push_back(uin);
            m->Message = message;
            messageReceived(m);
            break;
        }
    case ICQ_SNACxLISTS_AUTH:{
            readBuffer.incReadPos(8);
            unsigned long uin = readBuffer.unpackUin();
            char auth_ok; readBuffer >> auth_ok;
            string message;
            string charset;
            unsigned short have_charset;
            readBuffer.unpackStr(message);
            readBuffer >> have_charset;
            if (have_charset){
                readBuffer.incReadPos(2);
                readBuffer.unpackStr(charset);
            }
            ICQUser *u = getUser(uin);
            if (charset.size()){
                translate(localCharset(u), charset.c_str(), message);
            }else{
                fromServer(message, u);
            }
            log(L_DEBUG, "Auth %u %lu", auth_ok, uin);
            if (auth_ok){
                ICQUser *user = getUser(uin);
                if (user){
                    user->WaitAuth = false;
                    ICQEvent e(EVENT_INFO_CHANGED, uin);
                    process_event(&e);
                }
                ICQAuthGranted *m = new ICQAuthGranted();
                m->Uin.push_back(uin);
                messageReceived(m);
            }else{
                ICQAuthRefused *m = new ICQAuthRefused();
                m->Uin.push_back(uin);
                m->Message = message;
                messageReceived(m);
            }
            break;
        }
    case ICQ_SNACxLISTS_DONE:{
            ICQEvent *e = findListEvent(seq);
            if (e == NULL) break;
            readBuffer.incReadPos(8);
            unsigned short res;
            readBuffer >> res;
            e->processAnswer(this, readBuffer, res);
            delete e;
            break;
        }
    default:
        log(L_WARN, "Unknown lists family type %04X", type);
    }
}