void MsgEdit::markAsRead() { if (msg == NULL) return; if (pMain->SimpleMode()){ if (!msg->Received) return; pClient->markAsRead(msg); }else{ ICQUser *u = pClient->getUser(Uin()); if (u){ History h(Uin()); for (;;){ bool bExit = true; for (list<unsigned long>::iterator it = u->unreadMsgs.begin(); it != u->unreadMsgs.end(); it++){ ICQMessage *msg = h.getMessage(*it); if (msg == NULL) continue; unsigned type = msg->Type(); if ((type == ICQ_MSGxMSG) || (type == ICQ_MSGxURL) || (type == ICQ_MSGxSMS)){ pClient->markAsRead(msg); bExit = false; break; } } if (bExit) break; } } } setupNext(); }
bool ICQClient::load(istream &s, string &nextPart) { ICQUser::load(s, nextPart); for (;;){ if (!strcmp(nextPart.c_str(), "[ContactList]")){ contacts.load(s, nextPart); continue; } if (!strcmp(nextPart.c_str(), "[Group]")){ ICQGroup *grp = new ICQGroup; if (grp->load(s, nextPart)){ contacts.groups.push_back(grp); }else{ delete grp; } continue; } if (!strcmp(nextPart.c_str(), "[User]")){ ICQUser *u = new ICQUser; if (u->load(s, nextPart) && u->Uin() && (u->Uin() != Uin())){ contacts.users.push_back(u); }else{ delete u; } continue; } break; } if (*EncryptedPassword.c_str() == 0) storePassword(DecryptedPassword.c_str()); setupProxy(); ICQEvent e(EVENT_INFO_CHANGED); process_event(&e); return true; }
void MsgEdit::chatChanged() { if (msg && (msg->Type() == ICQ_MSGxCHAT) && msg->Received()){ QWidget *chat = pMain->chatWindow(Uin()); btnAccept->setEnabled(chat == NULL); } }
void ICQClient::serverRequest(unsigned short cmd, unsigned short seq) { snac(ICQ_SNACxFAM_VARIOUS, ICQ_SNACxVAR_REQxSRV, true); writeBuffer.tlv(0x0001, 0); writeBuffer.pack((char*)&Uin(), 4); writeBuffer << cmd; writeBuffer << htons(seq ? seq : m_nMsgSequence); }
void MsgEdit::ftChanged() { if (msg && (msg->Type() == ICQ_MSGxFILE) && msg->Received()){ ICQFile *f = static_cast<ICQFile*>(msg); QWidget *file = pMain->ftWindow(Uin(), f->shortName()); btnAccept->setEnabled(file == NULL); } }
void ICQClient::processMsgQueueSMS() { list<ICQEvent*>::iterator it; for (it = msgQueue.begin(); it != msgQueue.end();){ ICQEvent *e = *it; if (e->message() == NULL){ it++; continue; } if (e->message()->Type() != ICQ_MSGxSMS){ it++; continue; } ICQSMS *msg = static_cast<ICQSMS*>(e->message()); XmlBranch xmltree("icq_sms_message"); string destination = "+"; for (const char *p = msg->Phone.c_str(); *p; p++){ if ((*p >= '0') && (*p <= '9')) destination += *p; } string text = clearHTML(msg->Message.c_str()); toUTF(text); string sender = name(true); char uin[13]; snprintf(uin, sizeof(uin), "%lu", Uin()); xmltree.pushnode(new XmlLeaf("destination",destination)); xmltree.pushnode(new XmlLeaf("text",text)); xmltree.pushnode(new XmlLeaf("codepage","1252")); xmltree.pushnode(new XmlLeaf("encoding","urf8")); xmltree.pushnode(new XmlLeaf("senders_UIN",uin)); xmltree.pushnode(new XmlLeaf("senders_name",sender)); xmltree.pushnode(new XmlLeaf("delivery_receipt","Yes")); /* Time string, format: Wkd, DD Mnm YYYY HH:MM:SS TMZ */ char timestr[30]; time_t t; struct tm *tm; time(&t); tm = gmtime(&t); strftime(timestr, 30, "%a, %d %b %Y %T %Z", tm); xmltree.pushnode(new XmlLeaf("time",string(timestr))); string xmlstr = xmltree.toString(0); serverRequest(ICQ_SRVxREQ_MORE); writeBuffer << ICQ_SRVxREQ_SEND_SMS << 0x00010016L << 0x00000000L << 0x00000000L << 0x00000000L << 0x00000000L << (unsigned long)(xmlstr.size()); writeBuffer << xmlstr.c_str(); sendServerRequest(); msgQueue.remove(e); e->m_nId = m_nMsgSequence; varEvents.push_back(e); it = msgQueue.begin(); } }
void MsgEdit::messageReceived(ICQMessage *m) { if (m->getUin() != Uin()) return; setupNext(); if (msg && msg->Received && (static_cast<UserBox*>(topLevelWidget())->currentUser() == Uin)) return; if (canSend()) return; ICQMessage *msg_copy = history()->getMessage(m->Id); setMessage(msg_copy, false, true); if (qApp->activeWindow() != topLevelWidget()) return; if (static_cast<UserBox*>(topLevelWidget())->currentUser() != Uin) return; pClient->markAsRead(m); setupNext(); }
void ICQClient::snac_buddy(unsigned short type, unsigned short) { switch (type){ case ICQ_SNACxBDY_RIGHTSxGRANTED: log(L_DEBUG, "Buddy rights granted"); break; case ICQ_SNACxBDY_USEROFFLINE:{ unsigned long uin = readBuffer.unpackUin(); ICQUser *user = getUser(uin); if (user && (user->uStatus != ICQ_STATUS_OFFLINE)){ log(L_DEBUG, "User %lu [%s] offline", uin, user->Alias.c_str()); user->setOffline(); ICQEvent e(EVENT_STATUS_CHANGED, uin); process_event(&e); } break; } case ICQ_SNACxBDY_USERONLINE:{ unsigned long uin = readBuffer.unpackUin(); if (uin == Uin()) break; ICQUser *user = getUser(uin); if (user){ time_t now; time(&now); bool changed = false; unsigned long cookie1, cookie2, cookie3; cookie1 = cookie2 = cookie3 = 0; unsigned short level, len; readBuffer >> level >> len; TlvList tlv(readBuffer); // Status TLV Tlv *tlvStatus = tlv(0x0006); if (tlvStatus){ unsigned long status = *tlvStatus; log(L_DEBUG, "User %lu [%s] online [%08lX]", uin, user->Alias.c_str(), status); if (status != user->uStatus){ user->prevStatus = user->uStatus; user->uStatus = status; if (status & 0xFF){ addResponseRequest(uin); }else{ user->AutoReply = ""; } user->StatusTime = (unsigned long)now; changed = true; } } // Online time TLV Tlv *tlvOnlineTime = tlv(0x0003); if (tlvOnlineTime){ user->OnlineTime = (unsigned long)(*tlvOnlineTime); changed = true; } Tlv *tlvNATime = tlv(0x0004); if (tlvNATime){ user->StatusTime = (unsigned long)now - (unsigned short)(*tlvNATime) * 60L; changed = true; } // IP TLV Tlv *tlvIP = tlv(0x000A); if (tlvIP){ unsigned long ip = htonl((unsigned long)(*tlvIP)); if (user->IP() != ip) user->HostName = ""; user->IP = ip; changed = true; } // Direct connection info Tlv *tlvDirect = tlv(0x000C); if (tlvDirect){ user->ClientType = 0; Buffer info(*tlvDirect); unsigned long realIP; unsigned short port; char mode, version, junk; info >> realIP; info.incReadPos(2); info >> port; realIP = htonl(realIP); if (user->RealIP != realIP) user->RealHostName =""; user->RealIP = realIP; user->Port = port; info >> mode >> junk >> version >> user->DCcookie; info.incReadPos(8); info >> cookie1 >> cookie2 >> cookie3; if (cookie3 != user->PhoneBookTime()){ user->bPhoneChanged = true; user->PhoneBookTime = cookie3; } user->PhoneStatusTime = cookie2; user->TimeStamp = cookie1; if (mode == MODE_DENIED) mode = MODE_INDIRECT; if ((mode != MODE_DIRECT) && (mode != MODE_INDIRECT)) mode = MODE_INDIRECT; user->Mode = (unsigned short)mode; user->Version = (unsigned short)version; changed = true; if (user->DCcookie == 0) user->ClientType = 4; if ((user->DCcookie == cookie1) && (cookie1 == cookie2)) user->ClientType = 5; if (cookie1 == 0x279c6996) user->ClientType = 3; } Tlv *tlvCapability = tlv(0x000D); if (tlvCapability){ user->GetRTF = false; Buffer info(*tlvCapability); for (; info.readPos() < info.size(); ){ capability cap; info.unpack((char*)cap, sizeof(capability)); if (!memcmp(cap, capabilities[1], sizeof(capability))){ user->GetRTF = true; if (!user->CanPlugin){ if (user->bPhoneChanged) addPhoneRequest(uin); user->CanPlugin = true; } } if (!memcmp(cap, capabilities[3], sizeof(capability))) user->CanResponse = true; if (!memcmp(cap, capabilities[5], sizeof(capability))) user->ClientType = 2; if (!memcmp(cap, capabilities[4], sizeof(capability))) user->ClientType = 1; if (!memcmp(cap, capabilities[4], sizeof(capability)-1) && (cap[sizeof(capability)-1] > (1 << 6)) && (cap[sizeof(capability)-1] != 0x92)) user->ClientType = (char)(cap[sizeof(capability)-1]); } } Tlv *tlvPlugin = tlv(0x0011); if (tlvPlugin){ Buffer info(*tlvPlugin); char reqType; info >> reqType; info.incReadPos(10); capability cap; info.unpack((char*)cap, sizeof(capability)); if (user->CanPlugin && !memcmp(cap, PHONEBOOK_SIGN, sizeof(capability))){ if (reqType == 3){ info.incReadPos(3); info >> user->PhoneState; if (user->bPhoneChanged) addPhoneRequest(uin); }else if (reqType == 2) if (user->bPhoneChanged) addPhoneRequest(uin); } addInfoRequest(uin); changed = true; } if (changed){ ICQEvent e(EVENT_STATUS_CHANGED, uin); process_event(&e); user->prevStatus = user->uStatus; } } break; }
bool FullInfoEvent::processAnswer(ICQClient *client, Buffer &b, unsigned short nSubtype) { ICQUser *u; log(L_DEBUG, "Info about %lu %04X", Uin(), nSubtype); if (Uin() == client->Uin){ u = client; }else{ u = client->getUser(Uin(), false); if (u == NULL){ log(L_WARN, "User %lu for info not found", Uin()); return true; } } switch (nSubtype){ case ICQ_SRVxGENERAL_INFO:{ unsigned short n; char hideEmail; b >> u->Nick >> u->FirstName >> u->LastName >> u->EMail >> u->City >> u->State >> u->HomePhone >> u->HomeFax >> u->Address >> u->PrivateCellular >> u->Zip; b.unpack(n); u->Country = n; b >> u->TimeZone >> hideEmail; u->HiddenEMail = (hideEmail != 0); client->fromServer(u->Nick); client->fromServer(u->FirstName); client->fromServer(u->LastName); client->fromServer(u->City); client->fromServer(u->State); client->fromServer(u->Address); client->fromServer(u->Zip); client->fromServer(u->HomePhone); client->fromServer(u->HomeFax); client->fromServer(u->PrivateCellular); u->adjustEMails(u->EMails); break; } case ICQ_SRVxMORE_INFO:{ char c; b >> u->Age >> c >> u->Gender >> u->Homepage >> u->BirthYear >> u->BirthMonth >> u->BirthDay >> u->Language1 >> u->Language2 >> u->Language3; u->BirthYear = htons(u->BirthYear()); client->fromServer(u->Homepage); break; } case ICQ_SRVxEMAIL_INFO:{ EMailPtrList mails; char c; b >> c; for (;c > 0;c--){ char d; b >> d; string s; b >> s; client->fromServer(s); if (s.length() == 0) continue; EMailInfo *email = new EMailInfo; email->Email = s; email->Hide = (d != 0); mails.push_back(email); } u->adjustEMails(mails); break; } case ICQ_SRVxWORK_INFO:{ unsigned short n; b >> u->WorkCity >> u->WorkState >> u->WorkPhone >> u->WorkFax >> u->WorkAddress >> u->WorkZip; b.unpack(n); u->WorkCountry = n; b >> u->WorkName >> u->WorkDepartment >> u->WorkPosition; b.unpack(n); u->Occupation = n; b >> u->WorkHomepage; client->fromServer(u->WorkCity); client->fromServer(u->WorkState); client->fromServer(u->WorkPhone); client->fromServer(u->WorkFax); client->fromServer(u->WorkZip); client->fromServer(u->WorkAddress); client->fromServer(u->WorkName); client->fromServer(u->WorkDepartment); client->fromServer(u->WorkPosition); client->fromServer(u->WorkHomepage); break; } case ICQ_SRVxABOUT_INFO: b >> u->About; client->fromServer(u->About); break; case ICQ_SRVxINTERESTS_INFO:{ char n; b >> n; u->Interests.clear(); for (; n > 0; n--){ unsigned short c; b.unpack(c); string s; b >> s; client->fromServer(s); if (c == 0) continue; ExtInfo *interest = new ExtInfo; interest->Category = c; interest->Specific = s; u->Interests.push_back(interest); } break; } case ICQ_SRVxBACKGROUND_INFO:{ char n; u->Backgrounds.clear(); u->Affilations.clear(); b >> n; for (; n > 0; n--){ unsigned short c; b.unpack(c); string s; b >> s; client->fromServer(s); if (c == 0) continue; ExtInfo *info = new ExtInfo; info->Category = c; info->Specific = s; u->Backgrounds.push_back(info); } b >> n; for (; n > 0; n--){ unsigned short c; b.unpack(c); string s; b >> s; client->fromServer(s); if (c == 0) continue; ExtInfo *info = new ExtInfo; info->Category = c; info->Specific = s; u->Affilations.push_back(info); } break; } case ICQ_SRVxUNKNOWN_INFO: break; default: log(L_WARN, "Unknwon info type %04X for %lu", nSubtype, Uin()); } m_nParts++; if (m_nParts >= 8){ u->adjustPhones(); client->process_event(this); return true; } return false; }
void ICQClient::snac_service(unsigned short type, unsigned short) { switch (type){ case ICQ_SNACxSRV_RATExCHANGE: break; case ICQ_SNACxSRV_RATExINFO: log(L_DEBUG, "Rate info"); snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_RATExACK); writeBuffer << 0x00010002L << 0x00030004L << 0x0005; sendPacket(); snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_GETxUSERxINFO); sendPacket(); listsRequest(); locationRequest(); buddyRequest(); messageRequest(); bosRequest(); break; case ICQ_SNACxSRV_MOTD: log(L_DEBUG, "Motd"); snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_REQxRATExINFO); sendPacket(); break; case ICQ_SNACxSRV_ACKxIMxICQ: log(L_DEBUG, "Ack im icq"); break; case ICQ_SNACxSRV_NAMExINFO:{ unsigned long uin = readBuffer.unpackUin(); if (uin == 0){ char n; readBuffer >> n; readBuffer.incReadPos(n); uin = readBuffer.unpackUin(); } if (uin != Uin()){ log(L_WARN, "No my name info (%lu)", uin); break; } readBuffer.incReadPos(4); TlvList tlv(readBuffer); Tlv *tlvIP = tlv(0x000A); if (tlvIP) RealIP = htonl((unsigned long)(*tlvIP)); log(L_DEBUG, "Name info"); bool bSend = true; if (needPhonebookUpdate){ sendInfoUpdate(); needPhonebookUpdate = false; bSend = false; } if (needPhoneStatusUpdate){ sendPhoneStatus(); needPhoneStatusUpdate = false; bSend = false; } break; } case ICQ_SNACxSRV_READYxSERVER: log(L_DEBUG, "Server ready"); snac(ICQ_SNACxFAM_SERVICE, ICQ_SNACxSRV_IMxICQ); writeBuffer << 0x00010003L; writeBuffer << 0x00130002L; writeBuffer << 0x00020001L; writeBuffer << 0x00030001L; writeBuffer << 0x00150001L; writeBuffer << 0x00040001L; writeBuffer << 0x00060001L; writeBuffer << 0x00090001L; writeBuffer << 0x000a0001L; writeBuffer << 0x000b0001L; sendPacket(); break; default: log(L_WARN, "Unknown service family type %04X", type); }
void MsgEdit::processEvent(ICQEvent *e) { ICQUser *u; switch (e->type()){ case EVENT_ACKED: if (e->message() && (e->message() == message())){ sendEvent = NULL; setMessage(); if (bCloseSend){ close(); }else{ action(mnuAction); switch (e->message()->Type()){ case ICQ_MSGxFILE: emit setStatus(i18n("Transfer started"), 2000); break; case ICQ_MSGxCHAT: emit setStatus(i18n("Chat started"), 2000); break; } } } break; case EVENT_INFO_CHANGED: fillPhones(); u = pClient->getUser(Uin); if (u && u->inIgnore()) QTimer::singleShot(10, this, SLOT(close())); break; case EVENT_USER_DELETED: if (e->Uin() == Uin) close(); break; } if (e->message() && (e->message() == message())){ if (e->type() == EVENT_MESSAGE_SEND){ if (e->state == ICQEvent::Success){ history()->addMessage(message()); if (!msgTail.isEmpty()){ emit addMessage(message(), false, true); emit showMessage(Uin(), message()->Id); if (e->message()->Type() == ICQ_MSGxSMS){ ICQSMS *m = new ICQSMS; m->Uin.push_back(Uin); m->Message = smsChunk(); m->Phone = phoneEdit->lineEdit()->text().local8Bit(); msg = m; sendEvent = pClient->sendMessage(msg); return; } log(L_WARN, "Bad type for chunked message"); } if (bCloseSend){ close(); }else{ emit addMessage(message(), false, true); emit showMessage(Uin(), message()->Id); setMessage(); action(mnuAction); emit setStatus(i18n("Message sent"), 2000); } }else{ e->message()->bDelete = false; emit setStatus(i18n("Send failed"), 2000); if (e->message() && *(e->message()->DeclineReason.c_str())) BalloonMsg::message(QString::fromLocal8Bit(msg->DeclineReason.c_str()), btnNext); } bCloseSend = false; sendEvent = NULL; setState(); }else if ((e->type() == EVENT_MESSAGE_RECEIVED) && (e->state == ICQEvent::Fail)){ msg = NULL; setMessage(); action(mnuAction); } } }
QString MsgEdit::userName() { if (Uin() == 0) return "[New]"; CUser user(Uin); return user.name(); }