int CIcqProto::OnPreBuildContactMenu(WPARAM hContact, LPARAM) { if (hContact == NULL) return 0; if (icqOnline()) { BOOL bCtrlPressed = (GetKeyState(VK_CONTROL)&0x8000 ) != 0; DWORD dwUin = getContactUin(hContact); Menu_ShowItem(g_hContactMenuItems[ICMI_AUTH_REQUEST], dwUin && (bCtrlPressed || (getByte(hContact, "Auth", 0) && getWord(hContact, DBSETTING_SERVLIST_ID, 0)))); Menu_ShowItem(g_hContactMenuItems[ICMI_AUTH_GRANT], dwUin && (bCtrlPressed || getByte(hContact, "Grant", 0))); Menu_ShowItem(g_hContactMenuItems[ICMI_AUTH_REVOKE], dwUin && (bCtrlPressed || (getByte("PrivacyItems", 0) && !getByte(hContact, "Grant", 0)))); Menu_ShowItem(g_hContactMenuItems[ICMI_ADD_TO_SERVLIST], m_bSsiEnabled && !getWord(hContact, DBSETTING_SERVLIST_ID, 0) && !getWord(hContact, DBSETTING_SERVLIST_IGNORE, 0) && !db_get_b(hContact, "CList", "NotOnList", 0)); } Menu_ShowItem(g_hContactMenuItems[ICMI_OPEN_PROFILE],getContactUin(hContact) != 0); BYTE bXStatus = getContactXStatus(hContact); Menu_ShowItem(g_hContactMenuItems[ICMI_XSTATUS_DETAILS], m_bHideXStatusUI ? 0 : bXStatus != 0); if (bXStatus && !m_bHideXStatusUI) { if (bXStatus > 0 && bXStatus <= XSTATUS_COUNT) Menu_ModifyItem(g_hContactMenuItems[ICMI_XSTATUS_DETAILS], NULL, getXStatusIcon(bXStatus, LR_SHARED)); else Menu_ModifyItem(g_hContactMenuItems[ICMI_XSTATUS_DETAILS], NULL, Skin_LoadIcon(SKINICON_OTHER_SMALLDOT)); } return 0; }
int CIcqProto::OnPreBuildContactMenu(WPARAM wParam, LPARAM) { HANDLE hContact = (HANDLE)wParam; if (hContact == NULL) return 0; if (icqOnline()) { BOOL bCtrlPressed = (GetKeyState(VK_CONTROL)&0x8000 ) != 0; DWORD dwUin = getContactUin(hContact); sttEnableMenuItem(g_hContactMenuItems[ICMI_AUTH_REQUEST], dwUin && (bCtrlPressed || (getSettingByte((HANDLE)wParam, "Auth", 0) && getSettingWord((HANDLE)wParam, DBSETTING_SERVLIST_ID, 0)))); sttEnableMenuItem(g_hContactMenuItems[ICMI_AUTH_GRANT], dwUin && (bCtrlPressed || getSettingByte((HANDLE)wParam, "Grant", 0))); sttEnableMenuItem(g_hContactMenuItems[ICMI_AUTH_REVOKE], dwUin && (bCtrlPressed || (getSettingByte(NULL, "PrivacyItems", 0) && !getSettingByte((HANDLE)wParam, "Grant", 0)))); sttEnableMenuItem(g_hContactMenuItems[ICMI_ADD_TO_SERVLIST], m_bSsiEnabled && !getSettingWord((HANDLE)wParam, DBSETTING_SERVLIST_ID, 0) && !getSettingWord((HANDLE)wParam, DBSETTING_SERVLIST_IGNORE, 0) && !DBGetContactSettingByte(hContact, "CList", "NotOnList", 0)); } sttEnableMenuItem(g_hContactMenuItems[ICMI_OPEN_PROFILE],getContactUin(hContact) != 0); BYTE bXStatus = getContactXStatus((HANDLE)wParam); sttEnableMenuItem(g_hContactMenuItems[ICMI_XSTATUS_DETAILS], m_bHideXStatusUI ? 0 : bXStatus != 0); if (bXStatus && !m_bHideXStatusUI) { CLISTMENUITEM clmi = {0}; clmi.cbSize = sizeof(clmi); clmi.flags = CMIM_ICON; if (bXStatus > 0 && bXStatus <= XSTATUS_COUNT) clmi.hIcon = getXStatusIcon(bXStatus, LR_SHARED); else clmi.hIcon = LoadSkinnedIcon(SKINICON_OTHER_SMALLDOT); CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hContactMenuItems[ICMI_XSTATUS_DETAILS], (LPARAM)&clmi); } return 0; }
void CIcqProto::handleXtrazNotify(DWORD dwUin, DWORD dwMID, DWORD dwMID2, WORD wCookie, char* szMsg, int nMsgLen, BOOL bThruDC) { char *szNotify = strstrnull(szMsg, "<NOTIFY>"); char *szQuery = strstrnull(szMsg, "<QUERY>"); MCONTACT hContact = HContactFromUIN(dwUin, NULL); if (hContact) // user sent us xtraz, he supports it SetContactCapabilities(hContact, CAPF_XTRAZ); if (szNotify && szQuery) { // valid request char *szWork, *szEnd; int nNotifyLen, nQueryLen; szNotify += 8; szQuery += 7; szEnd = strstrnull(szMsg, "</NOTIFY>"); if (!szEnd) szEnd = szMsg + nMsgLen; nNotifyLen = (szEnd - szNotify); szEnd = strstrnull(szMsg, "</QUERY>"); if (!szEnd) szEnd = szNotify; szNotify = DemangleXml(szNotify, nNotifyLen); nQueryLen = (szEnd - szQuery); szQuery = DemangleXml(szQuery, nQueryLen); szWork = strstrnull(szQuery, "<PluginID>"); szEnd = strstrnull(szQuery, "</PluginID>"); #ifdef _DEBUG debugLogA("Query: %s", szQuery); debugLogA("Notify: %s", szNotify); #endif if (szWork && szEnd) { // this is our plugin szWork += 10; *szEnd = '\0'; if (!stricmpnull(szWork, "srvMng") && strstrnull(szNotify, "AwayStat")) { char *szSender = strstrnull(szNotify, "<senderId>"); char *szEndSend = strstrnull(szNotify, "</senderId>"); if (szSender && szEndSend) { szSender += 10; *szEndSend = '\0'; if ((DWORD)atoi(szSender) == dwUin) { BYTE dwXId = m_bXStatusEnabled ? getContactXStatus(NULL) : 0; if (dwXId && validateStatusMessageRequest(hContact, MTYPE_SCRIPT_NOTIFY)) { // apply privacy rules NotifyEventHooks(m_modeMsgsEvent, (WPARAM)MTYPE_SCRIPT_NOTIFY, (LPARAM)dwUin); char *tmp = getSettingStringUtf(NULL, DBSETTING_XSTATUS_NAME, ""); char *szXName = MangleXml(tmp, strlennull(tmp)); SAFE_FREE(&tmp); tmp = getSettingStringUtf(NULL, DBSETTING_XSTATUS_MSG, ""); char *szXMsg = MangleXml(tmp, strlennull(tmp)); SAFE_FREE(&tmp); int nResponseLen = 212 + strlennull(szXName) + strlennull(szXMsg) + UINMAXLEN + 2; char *szResponse = (char*)_alloca(nResponseLen + 1); // send response mir_snprintf(szResponse, nResponseLen, "<ret event=\"OnRemoteNotification\">" "<srv><id>cAwaySrv</id>" "<val srv_id=\"cAwaySrv\"><Root>" "<CASXtraSetAwayMessage></CASXtraSetAwayMessage>" "<uin>%d</uin>" "<index>%d</index>" "<title>%s</title>" "<desc>%s</desc></Root></val></srv></ret>", m_dwLocalUIN, dwXId, szXName, szXMsg); SAFE_FREE(&szXName); SAFE_FREE(&szXMsg); struct rates_xstatus_response : public rates_queue_item { protected: virtual rates_queue_item* copyItem(rates_queue_item *aDest = NULL) { rates_xstatus_response *pDest = (rates_xstatus_response*)aDest; if (!pDest) pDest = new rates_xstatus_response(ppro, wGroup); pDest->bThruDC = bThruDC; pDest->dwMsgID1 = dwMsgID1; pDest->dwMsgID2 = dwMsgID2; pDest->wCookie = wCookie; pDest->szResponse = null_strdup(szResponse); return rates_queue_item::copyItem(pDest); }; public: rates_xstatus_response(CIcqProto *ppro, WORD wGroup) : rates_queue_item(ppro, wGroup), szResponse(NULL) {}; virtual ~rates_xstatus_response() { if (bCreated) SAFE_FREE(&szResponse); }; virtual void execute() { ppro->SendXtrazNotifyResponse(dwUin, dwMsgID1, dwMsgID2, wCookie, szResponse, strlennull(szResponse), bThruDC); }; BOOL bThruDC; DWORD dwMsgID1; DWORD dwMsgID2; WORD wCookie; char *szResponse; }; m_ratesMutex->Enter(); WORD wGroup = m_rates->getGroupFromSNAC(ICQ_MSG_FAMILY, ICQ_MSG_RESPONSE); m_ratesMutex->Leave(); rates_xstatus_response rr(this, wGroup); rr.hContact = hContact; rr.dwUin = dwUin; rr.bThruDC = bThruDC; rr.dwMsgID1 = dwMID; rr.dwMsgID2 = dwMID2; rr.wCookie = wCookie; rr.szResponse = szResponse; handleRateItem(&rr, RQT_RESPONSE, 0, !bThruDC); } else if (dwXId) debugLogA("Privacy: Ignoring XStatus request"); else debugLogA("Error: We are not in XStatus, skipping"); } else debugLogA("Error: Invalid sender information"); } else debugLogA("Error: Missing sender information"); } else debugLogA("Error: Unknown plugin \"%s\" in Xtraz message", szWork); } else debugLogA("Error: Missing PluginID in Xtraz message"); SAFE_FREE(&szNotify); SAFE_FREE(&szQuery); } else debugLogA("Error: Invalid Xtraz Notify message"); }
void CIcqProto::handleXtrazNotifyResponse(DWORD dwUin, MCONTACT hContact, WORD wCookie, char* szMsg, int nMsgLen) { char *szMem, *szRes, *szEnd; int nResLen; #ifdef _DEBUG debugLogA("Received Xtraz Notify Response"); #endif szRes = strstrnull(szMsg, "<RES>"); szEnd = strstrnull(szMsg, "</RES>"); if (szRes && szEnd) { // valid response char *szNode, *szWork; szRes += 5; nResLen = szEnd - szRes; szMem = szRes = DemangleXml(szRes, nResLen); #ifdef _DEBUG debugLogA("Response: %s", szRes); #endif ProtoBroadcastAck(hContact, ICQACKTYPE_XTRAZNOTIFY_RESPONSE, ACKRESULT_SUCCESS, (HANDLE)wCookie, (LPARAM)szRes); NextVal: szNode = strstrnull(szRes, "<val srv_id="); if (szNode) szEnd = strstrnull(szNode, ">"); else szEnd = NULL; if (szNode && szEnd) { *(szEnd - 1) = '\0'; szNode += 13; //one more than the length of the string to skip ' or " too szWork = szEnd + 1; if (!stricmpnull(szNode, "cAwaySrv")) { int bChanged = FALSE; *szEnd = ' '; szNode = strstrnull(szWork, "<index>"); szEnd = strstrnull(szWork, "</index>"); if (szNode && szEnd) { szNode += 7; *szEnd = '\0'; if (atoi(szNode) != getContactXStatus(hContact)) { // this is strange - but go on debugLogA("Warning: XStatusIds do not match!"); } *szEnd = ' '; } szNode = strstrnull(szWork, "<title>"); szEnd = strstrnull(szWork, "</title>"); if (szNode && szEnd) { // we got XStatus title, save it char *szXName, *szOldXName; szNode += 7; *szEnd = '\0'; szXName = DemangleXml(szNode, strlennull(szNode)); // check if the name changed szOldXName = getSettingStringUtf(hContact, DBSETTING_XSTATUS_NAME, NULL); if (strcmpnull(szOldXName, szXName)) bChanged = TRUE; SAFE_FREE(&szOldXName); db_set_utf(hContact, m_szModuleName, DBSETTING_XSTATUS_NAME, szXName); SAFE_FREE(&szXName); *szEnd = ' '; } szNode = strstrnull(szWork, "<desc>"); szEnd = strstrnull(szWork, "</desc>"); if (szNode && szEnd) { // we got XStatus mode msg, save it char *szXMsg, *szOldXMsg; szNode += 6; *szEnd = '\0'; szXMsg = DemangleXml(szNode, strlennull(szNode)); // check if the decription changed szOldXMsg = getSettingStringUtf(hContact, DBSETTING_XSTATUS_NAME, NULL); if (strcmpnull(szOldXMsg, szXMsg)) bChanged = TRUE; SAFE_FREE(&szOldXMsg); db_set_utf(hContact, m_szModuleName, DBSETTING_XSTATUS_MSG, szXMsg); SAFE_FREE(&szXMsg); } ProtoBroadcastAck(hContact, ICQACKTYPE_XSTATUS_RESPONSE, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0); } else { char *szSrvEnd = strstrnull(szEnd, "</srv>"); if (szSrvEnd && strstrnull(szSrvEnd, "<val srv_id=")) { // check all values ! szRes = szSrvEnd + 6; // after first value goto NextVal; } // no next val, we were unable to handle packet, write error debugLogA("Error: Unknown serverId \"%s\" in Xtraz response", szNode); } } else debugLogA("Error: Missing serverId in Xtraz response"); SAFE_FREE(&szMem); } else debugLogA("Error: Invalid Xtraz Notify response"); }
void CIcqProto::parseStatusNote(DWORD dwUin, char *szUid, MCONTACT hContact, oscar_tlv_chain *pChain) { DWORD dwStatusNoteTS = time(NULL); BYTE *pStatusNoteTS, *pStatusNote; WORD wStatusNoteTSLen, wStatusNoteLen; BYTE bStatusNoteFlags; if (unpackSessionDataItem(pChain, 0x0D, &pStatusNoteTS, &wStatusNoteTSLen, NULL) && wStatusNoteTSLen == sizeof(DWORD)) unpackDWord(&pStatusNoteTS, &dwStatusNoteTS); // Get Status Note session item if (unpackSessionDataItem(pChain, 0x02, &pStatusNote, &wStatusNoteLen, &bStatusNoteFlags)) { char *szStatusNote = NULL; if ((bStatusNoteFlags & 4) == 4 && wStatusNoteLen >= 4) { BYTE *buf = pStatusNote; WORD buflen = wStatusNoteLen - 2; WORD wTextLen; unpackWord(&buf, &wTextLen); if (wTextLen > buflen) wTextLen = buflen; if (wTextLen > 0) { szStatusNote = (char*)_alloca(wStatusNoteLen + 1); unpackString(&buf, szStatusNote, wTextLen); szStatusNote[wTextLen] = '\0'; buflen -= wTextLen; WORD wEncodingType = 0; char *szEncoding = NULL; if (buflen >= 2) unpackWord(&buf, &wEncodingType); if (wEncodingType == 1 && buflen > 6) { // Encoding specified buf += 2; buflen -= 2; unpackWord(&buf, &wTextLen); if (wTextLen > buflen) wTextLen = buflen; szEncoding = (char*)_alloca(wTextLen + 1); unpackString(&buf, szEncoding, wTextLen); szEncoding[wTextLen] = '\0'; } else if (UTF8_IsValid(szStatusNote)) szEncoding = "utf-8"; szStatusNote = ApplyEncoding(szStatusNote, szEncoding); } } // Check if the status note was changed if (dwStatusNoteTS > getDword(hContact, DBSETTING_STATUS_NOTE_TIME, 0)) { DBVARIANT dbv = {DBVT_DELETED}; if (mir_strlen(szStatusNote) || (!getString(hContact, DBSETTING_STATUS_NOTE, &dbv) && (dbv.type == DBVT_ASCIIZ || dbv.type == DBVT_UTF8) && mir_strlen(dbv.pszVal))) debugLogA("%s changed status note to \"%s\"", strUID(dwUin, szUid), szStatusNote ? szStatusNote : ""); db_free(&dbv); if (szStatusNote) db_set_utf(hContact, m_szModuleName, DBSETTING_STATUS_NOTE, szStatusNote); else delSetting(hContact, DBSETTING_STATUS_NOTE); setDword(hContact, DBSETTING_STATUS_NOTE_TIME, dwStatusNoteTS); if (getContactXStatus(hContact) != 0 || !CheckContactCapabilities(hContact, CAPF_STATUS_MESSAGES)) { setStatusMsgVar(hContact, szStatusNote, false); TCHAR *tszNote = mir_utf8decodeT(szStatusNote); ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, NULL, (LPARAM)tszNote); mir_free(tszNote); } } SAFE_FREE(&szStatusNote); } else if (getContactStatus(hContact) == ID_STATUS_OFFLINE) { setStatusMsgVar(hContact, NULL, false); delSetting(hContact, DBSETTING_STATUS_NOTE); setDword(hContact, DBSETTING_STATUS_NOTE_TIME, dwStatusNoteTS); } }
void CIcqProto::handleServUINSettings(int nPort, serverthread_info *info) { setUserInfo(); /* SNAC 3,4: Tell server who's on our list (deprecated) */ /* SNAC 3,15: Try to add unauthorised contacts to temporary list */ sendEntireListServ(ICQ_BUDDY_FAMILY, ICQ_USER_ADDTOTEMPLIST, BUL_ALLCONTACTS); if (m_iDesiredStatus == ID_STATUS_INVISIBLE) { /* Tell server who's on our visible list (deprecated) */ if (!m_bSsiEnabled) sendEntireListServ(ICQ_BOS_FAMILY, ICQ_CLI_ADDVISIBLE, BUL_VISIBLE); else updateServVisibilityCode(3); } if (m_iDesiredStatus != ID_STATUS_INVISIBLE) { /* Tell server who's on our invisible list (deprecated) */ if (!m_bSsiEnabled) sendEntireListServ(ICQ_BOS_FAMILY, ICQ_CLI_ADDINVISIBLE, BUL_INVISIBLE); else updateServVisibilityCode(4); } // SNAC 1,1E: Set status icq_packet packet; { DWORD dwDirectCookie = rand() ^ (rand() << 16); // Get status WORD wStatus = MirandaStatusToIcq(m_iDesiredStatus); // Get status note & mood char *szStatusNote = PrepareStatusNote(m_iDesiredStatus); BYTE bXStatus = getContactXStatus(NULL); char szMoodData[32]; // prepare mood id if (m_bMoodsEnabled && bXStatus && moodXStatus[bXStatus - 1] != -1) mir_snprintf(szMoodData, "icqmood%d", moodXStatus[bXStatus - 1]); else szMoodData[0] = '\0'; //! Tricky code, this ensures that the status note will be saved to the directory SetStatusNote(szStatusNote, m_bGatewayMode ? 5000 : 2500, TRUE); size_t wStatusNoteLen = mir_strlen(szStatusNote); size_t wStatusMoodLen = mir_strlen(szMoodData); size_t wSessionDataLen = (wStatusNoteLen ? wStatusNoteLen + 4 : 0) + 4 + wStatusMoodLen + 4; serverPacketInit(&packet, 71 + (wSessionDataLen ? wSessionDataLen + 4 : 0)); packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_SET_STATUS); packDWord(&packet, 0x00060004); // TLV 6: Status mode and security flags packWord(&packet, GetMyStatusFlags()); // Status flags packWord(&packet, wStatus); // Status packTLVWord(&packet, 0x0008, 0x0A06); // TLV 8: Independent Status Messages packDWord(&packet, 0x000c0025); // TLV C: Direct connection info packDWord(&packet, getDword("RealIP", 0)); packDWord(&packet, nPort); packByte(&packet, DC_TYPE); // TCP/FLAG firewall settings packWord(&packet, ICQ_VERSION); packDWord(&packet, dwDirectCookie); // DC Cookie packDWord(&packet, WEBFRONTPORT); // Web front port packDWord(&packet, CLIENTFEATURES); // Client features packDWord(&packet, 0x7fffffff); // Abused timestamp packDWord(&packet, ICQ_PLUG_VERSION); // Abused timestamp if (ServiceExists("SecureIM/IsContactSecured")) packDWord(&packet, 0x5AFEC0DE); // SecureIM Abuse else packDWord(&packet, 0x00000000); // Timestamp packWord(&packet, 0x0000); // Unknown packTLVWord(&packet, 0x001F, 0x0000); if (wSessionDataLen) { // Pack session data packWord(&packet, 0x1D); // TLV 1D packWord(&packet, WORD(wSessionDataLen)); // TLV length packWord(&packet, 0x02); // Item Type if (wStatusNoteLen) { packWord(&packet, 0x400 | WORD(wStatusNoteLen + 4)); // Flags + Item Length packWord(&packet, WORD(wStatusNoteLen)); // Text Length packBuffer(&packet, (LPBYTE)szStatusNote, wStatusNoteLen); packWord(&packet, 0); // Encoding not specified (utf-8 is default) } else packWord(&packet, 0); // Flags + Item Length packWord(&packet, 0x0E); // Item Type packWord(&packet, WORD(wStatusMoodLen)); // Flags + Item Length if (wStatusMoodLen) packBuffer(&packet, (LPBYTE)szMoodData, wStatusMoodLen); // Mood // Save current status note & mood db_set_utf(NULL, m_szModuleName, DBSETTING_STATUS_NOTE, szStatusNote); setString(DBSETTING_STATUS_MOOD, szMoodData); } // Release memory SAFE_FREE(&szStatusNote); sendServPacket(&packet); } /* SNAC 1,11 */ serverPacketInit(&packet, 14); packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_SET_IDLE); packDWord(&packet, 0x00000000); sendServPacket(&packet); m_bIdleAllow = 0; // Change status SetCurrentStatus(m_iDesiredStatus); // Finish Login sequence serverPacketInit(&packet, 98); packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_READY); packDWord(&packet, 0x00220001); // imitate ICQ 6 behaviour packDWord(&packet, 0x0110164f); packDWord(&packet, 0x00010004); packDWord(&packet, 0x0110164f); packDWord(&packet, 0x00130004); packDWord(&packet, 0x0110164f); packDWord(&packet, 0x00020001); packDWord(&packet, 0x0110164f); packDWord(&packet, 0x00030001); packDWord(&packet, 0x0110164f); packDWord(&packet, 0x00150001); packDWord(&packet, 0x0110164f); packDWord(&packet, 0x00040001); packDWord(&packet, 0x0110164f); packDWord(&packet, 0x00060001); packDWord(&packet, 0x0110164f); packDWord(&packet, 0x00090001); packDWord(&packet, 0x0110164f); packDWord(&packet, 0x000A0001); packDWord(&packet, 0x0110164f); packDWord(&packet, 0x000B0001); packDWord(&packet, 0x0110164f); sendServPacket(&packet); debugLogA(" *** Yeehah, login sequence complete"); // login sequence is complete enter logged-in mode info->bLoggedIn = true; m_bConnectionLost = false; // enable auto info-update routine icq_EnableUserLookup(true); if (!info->isMigrating) { // Get Offline Messages Reqeust cookie_offline_messages *ack = (cookie_offline_messages*)SAFE_MALLOC(sizeof(cookie_offline_messages)); if (ack) { DWORD dwCookie = AllocateCookie(CKT_OFFLINEMESSAGE, ICQ_MSG_CLI_REQ_OFFLINE, 0, ack); serverPacketInit(&packet, 10); packFNACHeader(&packet, ICQ_MSG_FAMILY, ICQ_MSG_CLI_REQ_OFFLINE, 0, dwCookie); sendServPacket(&packet); } else icq_LogMessage(LOG_WARNING, LPGEN("Failed to request offline messages. They may be received next time you log in.")); // Update our information from the server sendOwnerInfoRequest(); // Request info updates on all contacts icq_RescanInfoUpdate(); // Start sending Keep-Alive packets StartKeepAlive(info); if (m_bAvatarsEnabled) { // Send SNAC 1,4 - request avatar family 0x10 connection icq_requestnewfamily(ICQ_AVATAR_FAMILY, &CIcqProto::StartAvatarThread); m_avatarsConnectionPending = TRUE; debugLogA("Requesting Avatar family entry point."); } // Set last xstatus updateServerCustomStatus(TRUE); } info->isMigrating = false; if (m_bAimEnabled) { char **szAwayMsg = NULL; mir_cslock l(m_modeMsgsMutex); szAwayMsg = MirandaStatusToAwayMsg(m_iStatus); if (szAwayMsg) icq_sendSetAimAwayMsgServ(*szAwayMsg); } }
// CLI_SETUSERINFO void CIcqProto::setUserInfo() { icq_packet packet; size_t wAdditionalData = 0; BYTE bXStatus = getContactXStatus(NULL); if (m_bAimEnabled) wAdditionalData += 16; #ifdef DBG_CAPMTN wAdditionalData += 16; #endif wAdditionalData += 16; // unicode #ifdef DBG_NEWCAPS wAdditionalData += 16; #endif #ifdef DBG_CAPXTRAZ wAdditionalData += 16; #endif #ifdef DBG_OSCARFT wAdditionalData += 16; #endif if (m_bAvatarsEnabled) wAdditionalData += 16; if (m_bXStatusEnabled && bXStatus != 0) wAdditionalData += 16; #ifdef DBG_CAPHTML wAdditionalData += 16; #endif #ifdef DBG_AIMCONTACTSEND wAdditionalData += 16; #endif wAdditionalData += CustomCapList.getCount() * 16; //MIM/PackName bool bHasPackName = false; DBVARIANT dbv; if (!db_get_s(NULL, "ICQCaps", "PackName", &dbv)) { //MIM/PackName bHasPackName = true; wAdditionalData += 16; } serverPacketInit(&packet, 62 + wAdditionalData); packFNACHeader(&packet, ICQ_LOCATION_FAMILY, ICQ_LOCATION_SET_USER_INFO); /* TLV(5): capability data */ packWord(&packet, 0x0005); packWord(&packet, WORD(48 + wAdditionalData)); #ifdef DBG_CAPMTN packDWord(&packet, 0x563FC809); // CAP_TYPING packDWord(&packet, 0x0B6F41BD); packDWord(&packet, 0x9F794226); packDWord(&packet, 0x09DFA2F3); #endif packShortCapability(&packet, 0x1349); // AIM_CAPS_ICQSERVERRELAY // Broadcasts the capability to receive UTF8 encoded messages packShortCapability(&packet, 0x134E); // CAP_UTF8MSGS #ifdef DBG_NEWCAPS // Tells server we understand to new format of caps packShortCapability(&packet, 0x0000); // CAP_SHORTCAPS #endif #ifdef DBG_CAPXTRAZ packDWord(&packet, 0x1a093c6c); // CAP_XTRAZ packDWord(&packet, 0xd7fd4ec5); // Broadcasts the capability to handle packDWord(&packet, 0x9d51a647); // Xtraz packDWord(&packet, 0x4e34f5a0); #endif if (m_bAvatarsEnabled) packShortCapability(&packet, 0x134C); // CAP_DEVILS #ifdef DBG_OSCARFT // Broadcasts the capability to receive Oscar File Transfers packShortCapability(&packet, 0x1343); // CAP_AIM_FILE #endif // Tells the server we can speak to AIM if (m_bAimEnabled) packShortCapability(&packet, 0x134D); // CAP_AIM_COMPATIBLE #ifdef DBG_AIMCONTACTSEND packShortCapability(&packet, 0x134B); // CAP_SENDBUDDYLIST #endif if (m_bXStatusEnabled && bXStatus != 0) packBuffer(&packet, capXStatus[bXStatus - 1], BINARY_CAP_SIZE); packShortCapability(&packet, 0x1344); // CAP_ICQDIRECT #ifdef DBG_CAPHTML packShortCapability(&packet, 0x0002); // CAP_HTMLMSGS #endif packDWord(&packet, 0x4D697261); // Miranda Signature packDWord(&packet, 0x6E64614E); WORD v[4]; CallService(MS_SYSTEM_GETFILEVERSION, 0, (LPARAM)v); packWord(&packet, v[0]); packWord(&packet, v[1]); packWord(&packet, v[2]); packWord(&packet, v[3]); //MIM/PackName if (bHasPackName) { packBuffer(&packet, (BYTE*)dbv.pszVal, 0x10); db_free(&dbv); } if (CustomCapList.getCount()) for (int i = 0; i < CustomCapList.getCount(); i++) packBuffer(&packet, (PBYTE)CustomCapList[i].caps, 0x10); sendServPacket(&packet); }