void CYahooProto::ext_got_picture_checksum(const char *me, const char *who, int cksum) { LOG(("ext_yahoo_got_picture_checksum for %s checksum: %d", who, cksum)); MCONTACT hContact = getbuddyH(who); if (hContact == NULL) { LOG(("Buddy Not Found. Skipping avatar update")); return; } /* Last thing check the checksum and request new one if we need to */ if (!cksum || cksum == -1) { setDword(hContact, "PictCK", 0); reset_avatar(hContact); } else { if (getDword(hContact, "PictCK", 0) != cksum) { // Now save the new checksum. No rush requesting new avatar yet. setDword(hContact, "PictCK", cksum); // Need to delete the Avatar File!! TCHAR szFile[MAX_PATH]; GetAvatarFileName(hContact, szFile, _countof(szFile) - 1, 0); DeleteFile(szFile); // Reset the avatar and cleanup. reset_avatar(hContact); // Request new avatar here... (might also want to check the sharing status?) if (getByte("ShareAvatar", 0) == 2) request_avatar(who); } } }
void CSteamProto::OnLoggedOn(const HttpResponse *response) { if (!CheckResponse(response)) { if (response && response->resultCode == HTTP_CODE_UNAUTHORIZED) { // Probably expired TokenSecret HandleTokenExpired(); return; } // Probably timeout or no connection, we can do nothing here ShowNotification(_T("Steam"), TranslateT("Unknown login error.")); SetStatus(ID_STATUS_OFFLINE); return; } JSONROOT root(response->pData); JSONNode *node = json_get(root, "error"); ptrT error(json_as_string(node)); if (mir_tstrcmpi(error, _T("OK"))) { // Probably expired TokenSecret HandleTokenExpired(); return; } node = json_get(root, "umqid"); setString("UMQID", ptrA(mir_u2a(ptrT(json_as_string(node))))); node = json_get(root, "message"); setDword("MessageID", json_as_int(node)); if (m_lastMessageTS <= 0) { node = json_get(root, "utc_timestamp"); time_t timestamp = _ttoi64(ptrT(json_as_string(node))); setDword("LastMessageTS", timestamp); } // load contact list ptrA token(getStringA("TokenSecret")); ptrA steamId(getStringA("SteamID")); PushRequest( new GetFriendListRequest(token, steamId), &CSteamProto::OnGotFriendList); // start polling thread m_hPollingThread = ForkThreadEx(&CSteamProto::PollingThread, 0, NULL); // go to online now ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, m_iStatus = m_iDesiredStatus); }
void CYahooProto::logoff_buddies() { //set all contacts to 'offline' for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { setWord(hContact, "Status", ID_STATUS_OFFLINE); setDword(hContact, "IdleTS", 0); setDword(hContact, "PictLastCheck", 0); setDword(hContact, "PictLoading", 0); db_unset(hContact, "CList", "StatusMsg"); delSetting(hContact, "YMsg"); delSetting(hContact, "YGMsg"); } }
void CVkProto::OnReceiveMyInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) { debugLogA("CVkProto::OnReceiveMyInfo %d", reply->resultCode); if (reply->resultCode != 200) { ConnectionFailed(LOGINERR_WRONGPASSWORD); return; } JSONNode jnRoot; const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot); if (!jnResponse) return; const JSONNode &jnUser = *(jnResponse.begin()); m_myUserId = jnUser["id"].as_int(); setDword("ID", m_myUserId); OnLoggedIn(); RetrieveUserInfo(m_myUserId); RetrieveUnreadMessages(); RetrieveFriends(); RetrievePollingInfo(); }
// Scans a binary buffer for oscar capabilities and adds them to the contact. // You probably want to call ClearAllContactCapabilities() first. void CIcqProto::SetCapabilitiesFromBuffer(MCONTACT hContact, BYTE *pBuffer, int nLength, BOOL bReset) { // Get current capability flags DWORD fdwContactCaps = bReset ? 0 : getDword(hContact, DBSETTING_CAPABILITIES, 0); // Get capability flags from buffer DWORD fdwCapabilities = GetCapabilitiesFromBuffer(pBuffer, nLength); #ifdef _DEBUG if (bReset) NetLog_CapabilityChange(this, "Set", fdwCapabilities); else { NetLog_CapabilityChange(this, "Removed", fdwContactCaps & ~fdwCapabilities & CapabilityFlagsMask); NetLog_CapabilityChange(this, "Added", fdwCapabilities & ~fdwContactCaps); } #endif if (fdwCapabilities != (fdwContactCaps & ~CapabilityFlagsMask)) { // Get current unmanaged capability flags fdwContactCaps &= ~CapabilityFlagsMask; // Add capability flags from buffer fdwContactCaps |= fdwCapabilities; // And write them back to database setDword(hContact, DBSETTING_CAPABILITIES, fdwContactCaps); } }
void CVkProto::OnReceiveMyInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) { debugLogA("CVkProto::OnReceiveMyInfo %d", reply->resultCode); if (reply->resultCode != 200) { ConnectionFailed(LOGINERR_WRONGPASSWORD); return; } JSONROOT pRoot; JSONNODE *pResponse = CheckJsonResponse(pReq, reply, pRoot); if (pResponse == NULL) return; for (size_t i = 0; i < json_size(pResponse); i++) { JSONNODE *it = json_at(pResponse, i); LPCSTR id = json_name(it); if (!_stricmp(id, "user_id")) { m_myUserId = json_as_int(it); setDword("ID", m_myUserId); } } OnLoggedIn(); RetrieveUserInfo(m_myUserId); RetrieveFriends(); RetrieveUnreadMessages(); RetrievePollingInfo(); }
void CYahooProto::request_avatar(const char* who) { if (!getByte("ShowAvatars", 1)) { LOG(("Avatars disabled, but available for: %s", who)); return; } MCONTACT hContact = getbuddyH(who); if (!hContact) return; time_t cur_time; time(&cur_time); time_t last_chk = getDword(hContact, "PictLastCheck", 0); /* * time() - in seconds ( 60*60 = 1 hour) */ if (getDword(hContact, "PictCK", 0) == 0 || last_chk == 0 || (cur_time - last_chk) > 60) { setDword(hContact, "PictLastCheck", (DWORD)cur_time); LOG(("Requesting Avatar for: %s", who)); yahoo_request_buddy_avatar(m_id, who); } else LOG(("Avatar Not Available for: %s Last Check: %ld Current: %ld (Flood Check in Effect)", who, last_chk, cur_time)); }
int CAimProto::aim_set_away(HANDLE hServerConn, unsigned short &seqno, const char *amsg, bool set)//user info { unsigned short offset=0; char* html_msg = NULL; size_t msg_size = 0; if (set) { if (!amsg) return -1; setDword(AIM_KEY_LA, (DWORD)time(NULL)); html_msg = html_encode(amsg && amsg[0] ? amsg : DEFAULT_AWAY_MSG); msg_size = strlen(html_msg); } aimString str(html_msg); const char *charset = str.isUnicode() ? AIM_MSG_TYPE_UNICODE : AIM_MSG_TYPE; const unsigned short charset_len = (unsigned short)strlen(charset); const char* msg = str.getBuf(); const unsigned short msg_len = str.getSize(); char* buf=(char*)alloca(SNAC_SIZE+TLV_HEADER_SIZE*3+charset_len+msg_len+1); aim_writesnac(0x02,0x04,offset,buf); aim_writetlv(0x03,charset_len,charset,offset,buf); aim_writetlv(0x04,(unsigned short)msg_len,msg,offset,buf); // aim_writetlvchar(0x0f,2,offset,buf); mir_free(html_msg); return aim_sendflap(hServerConn,0x02,offset,buf,seqno); }
void TranslatedBootMedia::updateBootsectorConfig(void) { DWORD tsize, dsize, bsize, totalSize; int driverOffset = 1024; tsize = Utils::getDword(imageBuffer + driverOffset + 2); // get size of text dsize = Utils::getDword(imageBuffer + driverOffset + 6); // get size of data bsize = Utils::getDword(imageBuffer + driverOffset + 10); // get size of bss totalSize = tsize + dsize + bsize; // total size of driver in RAM = size of text + data + bss totalSize = ((totalSize / 1024) + 2) * 1024; // round the size to the nearest biggest kB int pos = getConfigPosition(); if(pos == -1) { Debug::out(LOG_ERROR, "TranslatedBootMedia - didn't find the config position in bootsector."); return; } imageBuffer[pos + 7] = SCapacity - 1; // store how many sectors we should read (without boot sector) setDword(&imageBuffer[pos + 2], totalSize); // store how many RAM we need to reserve for driver in ST updateBootsectorChecksum(); // update the checksum at the end Debug::out(LOG_DEBUG, "TranslatedBootMedia - bootsector will read %d sectors, the driver will take %d kB of RAM.", (int) imageBuffer[pos + 7], (int) (totalSize / 1024)); updateBootsectorConfigWithACSIid(lastUsedAcsiId); }
bool CSteamProto::Relogin() { ptrA token(getStringA("TokenSecret")); if (mir_strlen(token) <= 0) return false; HttpRequest *request = new LogonRequest(token); HttpResponse *response = request->Send(m_hNetlibUser); bool success = false; if (CheckResponse(response)) { JSONROOT root(response->pData); if (root != NULL) { JSONNode *node = json_get(root, "error"); ptrT error(json_as_string(node)); if (!mir_tstrcmpi(error, _T("OK"))) { node = json_get(root, "umqid"); setString("UMQID", ptrA(mir_u2a(ptrT(json_as_string(node))))); node = json_get(root, "message"); setDword("MessageID", json_as_int(node)); success = true; } } } delete request; delete response; return success; }
GGPROTO::GGPROTO(const char* pszProtoName, const TCHAR* tszUserName) : PROTO<GGPROTO>(pszProtoName, tszUserName), avatar_requests(1, HandleKeySortT), avatar_transfers(1, HandleKeySortT) { #ifdef DEBUGMODE extendedLogging = 0; #endif // Init mutexes InitializeCriticalSection(&sess_mutex); InitializeCriticalSection(&ft_mutex); InitializeCriticalSection(&img_mutex); InitializeCriticalSection(&modemsg_mutex); InitializeCriticalSection(&avatar_mutex); InitializeCriticalSection(&sessions_mutex); // Register m_hNetlibUser user TCHAR name[128]; mir_sntprintf(name, SIZEOF(name), TranslateT("%s connection"), m_tszUserName); NETLIBUSER nlu = { 0 }; nlu.cbSize = sizeof(nlu); nlu.flags = NUF_TCHAR | NUF_OUTGOING | NUF_INCOMING | NUF_HTTPCONNS; nlu.szSettingsModule = m_szModuleName; nlu.ptszDescriptiveName = name; m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); // Register services CreateProtoService(PS_GETAVATARCAPS, &GGPROTO::getavatarcaps); CreateProtoService(PS_GETAVATARINFOT, &GGPROTO::getavatarinfo); CreateProtoService(PS_GETMYAVATART, &GGPROTO::getmyavatar); CreateProtoService(PS_SETMYAVATART, &GGPROTO::setmyavatar); CreateProtoService(PS_GETMYAWAYMSG, &GGPROTO::getmyawaymsg); CreateProtoService(PS_SETAWAYMSGT, (MyServiceFunc)&GGPROTO::SetAwayMsg); CreateProtoService(PS_CREATEACCMGRUI, &GGPROTO::get_acc_mgr_gui); CreateProtoService(PS_LEAVECHAT, &GGPROTO::leavechat); // Offline contacts and clear logon time setalloffline(); setDword(GG_KEY_LOGONTIME, 0); db_set_resident(m_szModuleName, GG_KEY_AVATARREQUESTED); TCHAR szPath[MAX_PATH]; mir_sntprintf(szPath, MAX_PATH, _T("%s\\%s\\ImageCache"), (TCHAR*)VARST( _T("%miranda_userdata%")), m_tszUserName); hImagesFolder = FoldersRegisterCustomPathT(LPGEN("Images"), m_szModuleName, szPath, m_tszUserName); DWORD dwVersion; if ((dwVersion = getDword(GG_PLUGINVERSION, 0)) < pluginInfo.version) cleanuplastplugin(dwVersion); links_instance_init(); initavatarrequestthread(); }
void CVkProto::RetrieveUnreadNews(time_t tLastNewsTime) { debugLogA("CVkProto::RetrieveUnreadNews"); if (!IsOnline()) return; time_t tLastNewsReqTime = getDword("LastNewsReqTime", time(NULL) - 24 * 60 * 60); if (time(NULL) - tLastNewsReqTime < 3 * 60) return; CMStringA szFilter; szFilter = m_bNewsFilterPosts ? "post" : ""; szFilter += szFilter.IsEmpty() ? "" : ","; szFilter += m_bNewsFilterPhotos ? "photo" : ""; szFilter += szFilter.IsEmpty() ? "" : ","; szFilter += m_bNewsFilterTags ? "photo_tag" : ""; szFilter += szFilter.IsEmpty() ? "" : ","; szFilter += m_bNewsFilterWallPhotos ? "wall_photo" : ""; if (szFilter.IsEmpty()) { debugLogA("CVkProto::RetrieveUnreadNews szFilter empty"); return; } CMStringA szSource; szSource = m_bNewsSourceFriends ? "friends" : ""; szSource += szSource.IsEmpty() ? "" : ","; szSource += m_bNewsSourceGroups ? "groups" : ""; szSource += szSource.IsEmpty() ? "" : ","; szSource += m_bNewsSourcePages ? "pages" : ""; szSource += szSource.IsEmpty() ? "" : ","; szSource += m_bNewsSourceFollowing ? "following" : ""; if (szSource.IsEmpty()) { debugLogA("CVkProto::RetrieveUnreadNews szSource empty"); return; } Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/newsfeed.get.json", true, &CVkProto::OnReceiveUnreadNews)) << INT_PARAM("count", 100) << INT_PARAM("return_banned", m_bNewsSourceIncludeBanned ? 1 : 0) << INT_PARAM("max_photos", m_iMaxLoadNewsPhoto) << INT_PARAM("start_time", tLastNewsTime + 1) << CHAR_PARAM("filters", szFilter) << CHAR_PARAM("source_ids", szSource) << VER_API; setDword("LastNewsReqTime", (DWORD)time(NULL)); }
void CVkProto::OnReceiveUnreadNews(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) { debugLogA("CVkProto::OnReceiveUnreadNews %d", reply->resultCode); db_unset(NULL, m_szModuleName, "LastNewsReqTime"); if (reply->resultCode != 200) return; JSONNode jnRoot; const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot); if (!jnResponse) return; OBJLIST<CVkUserInfo> vkUsers(5, NumericKeySortT); CreateVkUserInfoList(vkUsers, jnResponse); const JSONNode &jnItems = jnResponse["items"]; OBJLIST<CVKNewsItem> vkNews(5, sttCompareVKNewsItems); if (jnItems) for (auto it = jnItems.begin(); it != jnItems.end(); ++it) { CVKNewsItem *vkNewsItem = GetVkNewsItem((*it), vkUsers); if (!vkNewsItem) continue; CVKNewsItem *vkNewsFoundItem = vkNews.find(vkNewsItem); if (vkNewsFoundItem == NULL) vkNews.insert(vkNewsItem); else if (vkNewsFoundItem->tszType == _T("wall_photo") && vkNewsItem->tszType == _T("post")) { vkNews.remove(vkNewsFoundItem); vkNews.insert(vkNewsItem); } else delete vkNewsItem; } bool bNewsAdded = false; for (int i = 0; i < vkNews.getCount(); i++) if (!(m_bNewsSourceNoReposts && vkNews[i].bIsRepost)) { AddFeedEvent(vkNews[i]); bNewsAdded = true; } if (bNewsAdded) AddCListEvent(true); setDword("LastNewsTime", time(NULL)); vkNews.destroy(); vkUsers.destroy(); }
// Sets one or many oscar capabilities for a given contact void CIcqProto::SetContactCapabilities(MCONTACT hContact, DWORD fdwCapabilities) { // Get current capability flags DWORD fdwContactCaps = getDword(hContact, DBSETTING_CAPABILITIES, 0); if (fdwContactCaps != (fdwContactCaps | fdwCapabilities)) { #ifdef _DEBUG NetLog_CapabilityChange(this, "Added", fdwCapabilities & ~fdwContactCaps); #endif // Update them fdwContactCaps |= fdwCapabilities; // And write it back to disk setDword(hContact, DBSETTING_CAPABILITIES, fdwContactCaps); } }
// Deletes one or many oscar capabilities for a given contact void CIcqProto::ClearContactCapabilities(MCONTACT hContact, DWORD fdwCapabilities) { // Get current capability flags DWORD fdwContactCaps = getDword(hContact, DBSETTING_CAPABILITIES, 0); if (fdwContactCaps != (fdwContactCaps & ~fdwCapabilities)) { #ifdef _DEBUG NetLog_CapabilityChange(this, "Removed", fdwCapabilities & fdwContactCaps); #endif // Clear unwanted capabilities fdwContactCaps &= ~fdwCapabilities; // And write it back to disk setDword(hContact, DBSETTING_CAPABILITIES, fdwContactCaps); } }
void CVkProto::OnSendMessage(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) { int iResult = ACKRESULT_FAILED; if (pReq->pUserInfo == NULL) { debugLogA("CVkProto::OnSendMessage failed! (pUserInfo == NULL)"); return; } CVkSendMsgParam *param = (CVkSendMsgParam *)pReq->pUserInfo; debugLogA("CVkProto::OnSendMessage %d", reply->resultCode); if (reply->resultCode == 200) { JSONNode jnRoot; const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot); if (jnResponse) { UINT mid; if (jnResponse.type() != JSON_STRING) mid = jnResponse.as_int(); else if (_stscanf(jnResponse.as_mstring(), _T("%d"), &mid) != 1) mid = 0; if (param->iMsgID != -1) m_sendIds.insert((HANDLE)mid); if (mid > getDword(param->hContact, "lastmsgid")) setDword(param->hContact, "lastmsgid", mid); if (m_vkOptions.iMarkMessageReadOn >= MarkMsgReadOn::markOnReply) MarkMessagesRead(param->hContact); iResult = ACKRESULT_SUCCESS; } } if (param->pFUP) { ProtoBroadcastAck(param->hContact, ACKTYPE_FILE, iResult, (HANDLE)(param->pFUP)); if (!pReq->bNeedsRestart || m_bTerminated) delete param->pFUP; } else if (m_bServerDelivery) ProtoBroadcastAck(param->hContact, ACKTYPE_MESSAGE, iResult, (HANDLE)(param->iMsgID)); if (!pReq->bNeedsRestart || m_bTerminated) { delete param; pReq->pUserInfo = NULL; } }
// Scans a binary buffer for oscar capabilities and adds them to the contact. // You probably want to call ClearAllContactCapabilities() first. void CIcqProto::AddCapabilitiesFromBuffer(MCONTACT hContact, BYTE *pBuffer, int nLength) { // Get current capability flags DWORD fdwContactCaps = getDword(hContact, DBSETTING_CAPABILITIES, 0); // Get capability flags from buffer DWORD fdwCapabilities = GetCapabilitiesFromBuffer(pBuffer, nLength); if (fdwContactCaps != (fdwContactCaps | fdwCapabilities)) { #ifdef _DEBUG NetLog_CapabilityChange(this, "Added", fdwCapabilities & ~fdwContactCaps); #endif // Add capability flags from buffer fdwContactCaps |= fdwCapabilities; // And write them back to database setDword(hContact, DBSETTING_CAPABILITIES, fdwContactCaps); } }
void MinecraftDynmapProto::SignOnWorker(void*) { SYSTEMTIME t; GetLocalTime(&t); debugLogA("[%d.%d.%d] Using Omegle Protocol %s", t.wDay, t.wMonth, t.wYear, __VERSION_STRING_DOTS); ScopedLock s(signon_lock_); int old_status = m_iStatus; // Load server from database ptrA str(db_get_sa(NULL, m_szModuleName, MINECRAFTDYNMAP_KEY_SERVER)); if (!str || !str[0]) { MessageBox(NULL, TranslateT("Set server address to connect."), m_tszUserName, MB_OK); SetStatus(ID_STATUS_OFFLINE); return; } m_server = str; // Fix format of given server if (m_server.substr(0, 7) != "http://" && m_server.substr(0, 8) != "https://") m_server = "http://" + m_server; if (m_server.substr(m_server.length() - 1, 1) == "/") m_server = m_server.substr(0, m_server.length() -1); if (doSignOn()) { // Signed in, switch to online, create chatroom and start events loop m_iStatus = m_iDesiredStatus; ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); setDword("LogonTS", (DWORD)time(NULL)); ClearChat(); OnJoinChat(0, false); ResetEvent(events_loop_event_); ForkThread(&MinecraftDynmapProto::EventsLoop, this); } else { // Some error ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_FAILED, (HANDLE)old_status, m_iStatus); } }
void CYahooProto::ext_got_picture_upload(const char *me, const char *url, unsigned int ts) { int cksum = 0; DBVARIANT dbv; LOG(("[ext_yahoo_got_picture_upload] url: %s timestamp: %d", url, ts)); if (!url) { LOG(("[ext_yahoo_got_picture_upload] Problem with upload?")); return; } cksum = getDword("TMPAvatarHash", 0); if (cksum != 0) { LOG(("[ext_yahoo_got_picture_upload] Updating Checksum to: %d", cksum)); setDword("AvatarHash", cksum); delSetting("TMPAvatarHash"); // This is only meant for message sessions, but we don't got those in miranda yet //YAHOO_bcast_picture_checksum(cksum); yahoo_send_picture_checksum(m_id, NULL, cksum); // need to tell the stupid Yahoo that our icon updated //YAHOO_bcast_picture_update(2); } else cksum = getDword("AvatarHash", 0); setString("AvatarURL", url); //YAHOO_SetDword("AvatarExpires", ts); if (!getString("AvatarInv", &dbv)) { LOG(("[ext_yahoo_got_picture_upload] Buddy: %s told us this is bad??", dbv.pszVal)); LOG(("[ext_yahoo_got_picture] Sending url: %s checksum: %d to '%s'!", url, cksum, dbv.pszVal)); //void yahoo_send_picture_info(int id, const char *me, const char *who, const char *pic_url, int cksum) yahoo_send_picture_info(m_id, dbv.pszVal, 2, url, cksum); delSetting("AvatarInv"); db_free(&dbv); } }
void CVkProto::RetrieveUnreadNotifications(time_t tLastNotificationsTime) { debugLogA("CVkProto::RetrieveUnreadNotifications"); if (!IsOnline()) return; time_t tLastNotificationsReqTime = getDword("LastNotificationsReqTime", time(NULL) - 24 * 60 * 60); if (time(NULL) - tLastNotificationsReqTime < 3 * 60) return; CMString code(FORMAT, _T("return{\"notifications\":API.notifications.get({\"count\": 100, \"start_time\":%d})%s"), (LONG)(tLastNotificationsTime + 1), m_bNotificationFilterInvites ? _T(",\"groupinvates\":API.groups.getInvites({\"extended\":1})};") : _T("};")); Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/execute.json", true, &CVkProto::OnReceiveUnreadNotifications) << TCHAR_PARAM("code", code) << VER_API); setDword("LastNotificationsReqTime", (DWORD)time(NULL)); }
int CSteamProto::OnIdleChanged(WPARAM, LPARAM lParam) { bool idle = (lParam & IDF_ISIDLE) != 0; bool privacy = (lParam & IDF_PRIVACY) != 0; // Respect user choice about (not) notifying idle to protocols if (privacy) { // Reset it to 0 if there is some time already if (m_idleTS) { m_idleTS = 0; delSetting("IdleTS"); } return 0; } // We don't want to reset idle time when we're already in idle state if (idle && m_idleTS > 0) return 0; if (idle) { // User started being idle MIRANDA_IDLE_INFO mii = { sizeof(mii) }; CallService(MS_IDLE_GETIDLEINFO, 0, (LPARAM)&mii); // Compute time when user really became idle m_idleTS = time(0) - mii.idleTime * 60; setDword("IdleTS", m_idleTS); } else { // User stopped being idle m_idleTS = 0; delSetting("IdleTS"); } return 0; }
void CJabberProto::OnIqResultGetCollectionList(HXML iqNode, CJabberIqInfo*) { const TCHAR *to = xmlGetAttrValue(iqNode, _T("to")); if (to == NULL || mir_tstrcmp( xmlGetAttrValue(iqNode, _T("type")), _T("result"))) return; HXML list = xmlGetChild(iqNode, "list"); if (!list || mir_tstrcmp( xmlGetAttrValue(list, _T("xmlns")), JABBER_FEAT_ARCHIVE)) return; MCONTACT hContact = NULL; time_t tmLast = 0; for (int nodeIdx = 1; ; nodeIdx++) { HXML itemNode = xmlGetNthChild(list, _T("chat"), nodeIdx); if (!itemNode) break; const TCHAR* start = xmlGetAttrValue(itemNode, _T("start")); const TCHAR* with = xmlGetAttrValue(itemNode, _T("with")); if (!start || !with) continue; if (hContact == NULL) { if ((hContact = HContactFromJID(with)) == NULL) continue; tmLast = getDword(hContact, "LastCollection", 0); } m_ThreadInfo->send( XmlNodeIq( AddIQ(&CJabberProto::OnIqResultGetCollection, JABBER_IQ_TYPE_GET)) << XCHILDNS( _T("retrieve"), JABBER_FEAT_ARCHIVE) << XATTR(_T("with"), with) << XATTR(_T("start"), start)); time_t tmThis = str2time(start); if ( tmThis > tmLast) { tmLast = tmThis; setDword(hContact, "LastCollection", tmLast+1); } } }
void OmegleProto::SignOn(void*) { SYSTEMTIME t; GetLocalTime(&t); debugLogA("[%d.%d.%d] Using Omegle Protocol %s", t.wDay, t.wMonth, t.wYear, __VERSION_STRING_DOTS); ScopedLock s(signon_lock_); int old_status = m_iStatus; m_iStatus = m_iDesiredStatus; ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); setDword("LogonTS", (DWORD)time(NULL)); ClearChat(); OnJoinChat(0, false); if (getByte(OMEGLE_KEY_AUTO_CONNECT, 0)) NewChat(); //ToggleStatusMenuItems(true); }
void CVkProto::GetHistoryDlg(MCONTACT hContact, int iLastMsg) { debugLogA("CVkProto::GetHistoryDlg %d", iLastMsg); int lastmsgid = -1; switch (m_iSyncHistoryMetod) { case syncAuto: lastmsgid = getDword(hContact, "lastmsgid", -1); if (lastmsgid == -1 || !IsOnline()) { setDword(hContact, "lastmsgid", iLastMsg); return; } GetServerHistory(hContact, 0, MAXHISTORYMIDSPERONE, 0, lastmsgid); break; case sync1Days: GetServerHistoryLastNDay(hContact, 1); break; case sync3Days: GetServerHistoryLastNDay(hContact, 3); break; } }
void CMsnProto::MSN_GoOffline(void) { if (m_iStatus == ID_STATUS_OFFLINE) return; msnLoggedIn = false; if (mStatusMsgTS) ForkThread(&CMsnProto::msn_storeProfileThread, NULL); mir_free(msnPreviousUUX); msnPreviousUUX = NULL; msnSearchId = NULL; if (!Miranda_Terminated()) MSN_EnableMenuItems(false); MSN_FreeGroups(); MsgQueue_Clear(); clearCachedMsg(); if (!Miranda_Terminated()) { int msnOldStatus = m_iStatus; m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)msnOldStatus, ID_STATUS_OFFLINE); isIdle = false; int count = -1; for (;;) { MsnContact *msc = Lists_GetNext(count); if (msc == NULL) break; if (ID_STATUS_OFFLINE != getWord(msc->hContact, "Status", ID_STATUS_OFFLINE)) { setWord(msc->hContact, "Status", ID_STATUS_OFFLINE); setDword(msc->hContact, "IdleTS", 0); } } } }
void CVkProto::PollUpdates(const JSONNode &jnUpdates) { debugLogA("CVkProto::PollUpdates"); CMStringA mids; int msgid, uid, flags, platform; MCONTACT hContact; for (auto it = jnUpdates.begin(); it != jnUpdates.end(); ++it) { const JSONNode &jnChild = (*it).as_array(); switch (jnChild[json_index_t(0)].as_int()) { case VKPOLL_MSG_DELFLAGS: if (jnChild.size() < 4) break; msgid = jnChild[1].as_int(); flags = jnChild[2].as_int(); uid = jnChild[3].as_int(); hContact = FindUser(uid); if (hContact != NULL && (flags & VKFLAG_MSGUNREAD) && !CheckMid(m_incIds, msgid)) { setDword(hContact, "LastMsgReadTime", time(NULL)); if (ServiceExists(MS_MESSAGESTATE_UPDATE)) { MessageReadData data(time(NULL), MRD_TYPE_READTIME); CallService(MS_MESSAGESTATE_UPDATE, hContact, (LPARAM)&data); } else SetSrmmReadStatus(hContact); if (m_bUserForceOnlineOnActivity) SetInvisible(hContact); if (m_bSyncReadMessageStatusFromServer) MarkDialogAsRead(hContact); } break; case VKPOLL_MSG_ADDED: // new message msgid = jnChild[1].as_int(); // skip outgoing messages sent from a client flags = jnChild[2].as_int(); if (flags & VKFLAG_MSGOUTBOX && !(flags & VKFLAG_MSGCHAT) && CheckMid(m_sendIds, msgid)) break; if (!mids.IsEmpty()) mids.AppendChar(','); mids.AppendFormat("%d", msgid); break; case VKPOLL_READ_ALL_OUT: uid = jnChild[1].as_int(); hContact = FindUser(uid); if (hContact != NULL) { setDword(hContact, "LastMsgReadTime", time(NULL)); if (ServiceExists(MS_MESSAGESTATE_UPDATE)) { MessageReadData data(time(NULL), MRD_TYPE_READTIME); CallService(MS_MESSAGESTATE_UPDATE, hContact, (LPARAM)&data); } else SetSrmmReadStatus(hContact); if (m_bUserForceOnlineOnActivity) SetInvisible(hContact); } break; case VKPOLL_READ_ALL_IN: uid = jnChild[1].as_int(); hContact = FindUser(uid); if (hContact != NULL && m_bSyncReadMessageStatusFromServer) MarkDialogAsRead(hContact); break; case VKPOLL_USR_ONLINE: uid = -jnChild[1].as_int(); if ((hContact = FindUser(uid)) != NULL) { setWord(hContact, "Status", ID_STATUS_ONLINE); platform = jnChild[2].as_int(); SetMirVer(hContact, platform); } break; case VKPOLL_USR_OFFLINE: uid = -jnChild[1].as_int(); if ((hContact = FindUser(uid)) != NULL) { setWord(hContact, "Status", ID_STATUS_OFFLINE); db_unset(hContact, m_szModuleName, "ListeningTo"); SetMirVer(hContact, -1); } break; case VKPOLL_USR_UTN: uid = jnChild[1].as_int(); hContact = FindUser(uid); if (hContact != NULL) { ForkThread(&CVkProto::ContactTypingThread, (void *)hContact); if (m_bUserForceOnlineOnActivity) SetInvisible(hContact); } break; case VKPOLL_CHAT_UTN: ForkThread(&CVkProto::ChatContactTypingThread, new CVKChatContactTypingParam(jnChild[2].as_int(), jnChild[1].as_int())); break; case VKPOLL_CHAT_CHANGED: int chat_id = jnChild[1].as_int(); CVkChatInfo *cc = m_chats.find((CVkChatInfo*)&chat_id); if (cc) RetrieveChatInfo(cc); break; } } RetrieveMessagesByIds(mids); }
void CSteamProto::PollingThread(void*) { debugLog(_T("CSteamProto::PollingThread: entering")); ptrA token(getStringA("TokenSecret")); ptrA umqId(getStringA("UMQID")); UINT32 messageId = getDword("MessageID", 0); //PollApi::PollResult pollResult; int errors = 0; bool breaked = false; while (!isTerminated && !breaked && errors < POLLING_ERRORS_LIMIT) { PollRequest *request = new PollRequest(token, umqId, messageId, IdleSeconds()); //request->nlc = m_pollingConnection; HttpResponse *response = request->Send(m_hNetlibUser); delete request; if (response == NULL || response->resultCode != HTTP_CODE_OK) { if (response != NULL) delete response; errors++; continue; } else errors = 0; JSONROOT root(response->pData); JSONNode *node = json_get(root, "error"); ptrT error(json_as_string(node)); if (!lstrcmpi(error, _T("OK"))) { node = json_get(root, "messagelast"); messageId = json_as_int(node); node = json_get(root, "messages"); JSONNode *nroot = json_as_array(node); if (nroot != NULL) { ParsePollData(nroot); json_delete(nroot); } m_pollingConnection = response->nlc; } else if (!lstrcmpi(error, _T("Timeout"))) { continue; } /*else if (!lstrcmpi(error, _T("Not Logged On"))) // 'else' below will handle this error, we don't need this particular check right now { if (!IsOnline()) { // need to relogin debugLog(_T("CSteamProto::PollingThread: not logged on")); SetStatus(ID_STATUS_OFFLINE); } breaked = true; }*/ else { // something wrong debugLog(_T("CSteamProto::PollingThread: %s (%d)"), error, response->resultCode); // token has expired if (response->resultCode == HTTP_CODE_UNAUTHORIZED) delSetting("TokenSecret"); // too low timeout? node = json_get(root, "sectimeout"); int timeout = json_as_int(node); if (timeout < STEAM_API_TIMEOUT) debugLog(_T("CSteamProto::PollingThread: Timeout is too low (%d)"), timeout); breaked = true; } delete response; } setDword("MessageID", messageId); m_hPollingThread = NULL; debugLog(_T("CSteamProto::PollingThread: leaving")); if (!isTerminated) { debugLog(_T("CSteamProto::PollingThread: unexpected termination; switching protocol to offline")); SetStatus(ID_STATUS_OFFLINE); } }
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::handleUserOffline(BYTE *buf, size_t wLen) { DWORD dwUIN; uid_str szUID; do { oscar_tlv_chain *pChain = NULL; // Unpack the sender's user ID if (!unpackUID(&buf, &wLen, &dwUIN, &szUID)) return; // Warning level? buf += 2; // TLV Count WORD wTLVCount; unpackWord(&buf, &wTLVCount); wLen -= 4; // Skip the TLV chain DWORD dwAwaySince = 0; while (wTLVCount && wLen >= 4) { WORD wTLVType; WORD wTLVLen; unpackWord(&buf, &wTLVType); unpackWord(&buf, &wTLVLen); wLen -= 4; // stop parsing overflowed packet if (wTLVLen > wLen) { disposeChain(&pChain); return; } if (wTLVType == 0x1D) { // read only TLV with Session data into chain BYTE *pTLV = buf - 4; disposeChain(&pChain); pChain = readIntoTLVChain(&pTLV, wLen + 4, 1); } else if (wTLVType == 0x29 && wTLVLen == sizeof(DWORD)) { // get Away Since value BYTE *pData = buf; unpackDWord(&pData, &dwAwaySince); } buf += wTLVLen; wLen -= wTLVLen; wTLVCount--; } // Determine contact MCONTACT hContact = HContactFromUID(dwUIN, szUID, NULL); // Skip contacts that are not already on our list or are already offline if (hContact != INVALID_CONTACT_ID) { WORD wOldStatus = getContactStatus(hContact); // Process Avatar Hash oscar_tlv *pAvatarTLV = pChain ? pChain->getTLV(0x1D, 1) : NULL; if (pAvatarTLV) handleAvatarContactHash(dwUIN, szUID, hContact, pAvatarTLV->pData, pAvatarTLV->wLen); else handleAvatarContactHash(dwUIN, szUID, hContact, NULL, 0); // Process Status Note (offline status note) parseStatusNote(dwUIN, szUID, hContact, pChain); // Update status times setDword(hContact, "IdleTS", 0); setDword(hContact, "AwayTS", dwAwaySince); // Clear custom status & mood char tmp = NULL; handleXStatusCaps(dwUIN, szUID, hContact, (BYTE*)&tmp, 0, &tmp, 0); if (wOldStatus != ID_STATUS_OFFLINE) { debugLogA("%s went offline.", strUID(dwUIN, szUID)); setWord(hContact, "Status", ID_STATUS_OFFLINE); // close Direct Connections to that user CloseContactDirectConns(hContact); // Reset DC status setByte(hContact, "DCStatus", 0); } else debugLogA("%s is offline.", strUID(dwUIN, szUID)); } // Release memory disposeChain(&pChain); } while (wLen >= 1); }
void CIcqProto::handleUserOnline(BYTE *buf, size_t wLen, serverthread_info*) { DWORD dwPort = 0; DWORD dwRealIP = 0; DWORD dwUIN; uid_str szUID; DWORD dwDirectConnCookie = 0; DWORD dwWebPort = 0; DWORD dwFT1 = 0, dwFT2 = 0, dwFT3 = 0; const char *szClient = NULL; BYTE bClientId = 0; WORD wVersion = 0; WORD wTLVCount; WORD wWarningLevel; WORD wStatusFlags; WORD wStatus = 0, wOldStatus = 0; BYTE nTCPFlag = 0; char szStrBuf[MAX_PATH]; // Unpack the sender's user ID if (!unpackUID(&buf, &wLen, &dwUIN, &szUID)) return; // Syntax check if (wLen < 4) return; // Warning level? unpackWord(&buf, &wWarningLevel); wLen -= 2; // TLV count unpackWord(&buf, &wTLVCount); wLen -= 2; // Ignore status notification if the user is not already on our list MCONTACT hContact = HContactFromUID(dwUIN, szUID, NULL); if (hContact == INVALID_CONTACT_ID) { debugLogA("Ignoring user online (%s)", strUID(dwUIN, szUID)); return; } // Read user info TLVs oscar_tlv_chain *pChain; oscar_tlv *pTLV; // Syntax check if (wLen < 4) return; // Get chain if (!(pChain = readIntoTLVChain(&buf, wLen, wTLVCount))) return; // Get Class word WORD wClass = pChain->getWord(0x01, 1); int nIsICQ = wClass & CLASS_ICQ; if (dwUIN) { // Get DC info TLV pTLV = pChain->getTLV(0x0C, 1); if (pTLV && (pTLV->wLen >= 15)) { BYTE *pBuffer = pTLV->pData; nIsICQ = TRUE; unpackDWord(&pBuffer, &dwRealIP); unpackDWord(&pBuffer, &dwPort); unpackByte(&pBuffer, &nTCPFlag); unpackWord(&pBuffer, &wVersion); unpackDWord(&pBuffer, &dwDirectConnCookie); unpackDWord(&pBuffer, &dwWebPort); // Web front port pBuffer += 4; // Client features // Get faked time signatures, used to identify clients if (pTLV->wLen >= 0x23) { unpackDWord(&pBuffer, &dwFT1); unpackDWord(&pBuffer, &dwFT2); unpackDWord(&pBuffer, &dwFT3); } } // Get Status info TLV pTLV = pChain->getTLV(0x06, 1); if (pTLV && (pTLV->wLen >= 4)) { BYTE *pBuffer = pTLV->pData; unpackWord(&pBuffer, &wStatusFlags); unpackWord(&pBuffer, &wStatus); } else if (!nIsICQ) { // Connected thru AIM client, guess by user class if (wClass & CLASS_AWAY) wStatus = ID_STATUS_AWAY; else if (wClass & CLASS_WIRELESS) wStatus = ID_STATUS_ONTHEPHONE; else wStatus = ID_STATUS_ONLINE; wStatusFlags = 0; } else { // Huh? No status TLV? Lets guess then... wStatusFlags = 0; wStatus = ICQ_STATUS_ONLINE; } } else { nIsICQ = FALSE; if (wClass & CLASS_AWAY) wStatus = ID_STATUS_AWAY; else if (wClass & CLASS_WIRELESS) wStatus = ID_STATUS_ONTHEPHONE; else wStatus = ID_STATUS_ONLINE; wStatusFlags = 0; } debugLogA("Flags are %x", wStatusFlags); debugLogA("Status is %x", wStatus); // Get IP TLV DWORD dwIP = pChain->getDWord(0x0A, 1); // Get Online Since TLV DWORD dwOnlineSince = pChain->getDWord(0x03, 1); // Get Away Since TLV DWORD dwAwaySince = pChain->getDWord(0x29, 1); // Get Member Since TLV DWORD dwMemberSince = pChain->getDWord(0x05, 1); // Get Idle timer TLV WORD wIdleTimer = pChain->getWord(0x04, 1); time_t tIdleTS = 0; if (wIdleTimer) { time(&tIdleTS); tIdleTS -= (wIdleTimer*60); } if (wIdleTimer) debugLogA("Idle timer is %u.", wIdleTimer); debugLogA("Online since %s", time2text(dwOnlineSince)); if (dwAwaySince) debugLogA("Status was set on %s", time2text(dwAwaySince)); // Check client capabilities if (hContact != NULL) { wOldStatus = getContactStatus(hContact); // Collect all Capability info from TLV chain BYTE *capBuf = NULL; WORD capLen = 0; // Get Location Capability Info TLVs oscar_tlv *pFullTLV = pChain->getTLV(0x0D, 1); oscar_tlv *pShortTLV = pChain->getTLV(0x19, 1); if (pFullTLV && (pFullTLV->wLen >= BINARY_CAP_SIZE)) capLen += pFullTLV->wLen; if (pShortTLV && (pShortTLV->wLen >= 2)) capLen += (pShortTLV->wLen * 8); capBuf = (BYTE*)_alloca(capLen + BINARY_CAP_SIZE); if (capLen) { BYTE *pCapability = capBuf; capLen = 0; // we need to recount that if (pFullTLV && (pFullTLV->wLen >= BINARY_CAP_SIZE)) { // copy classic Capabilities BYTE *cData = pFullTLV->pData; int cLen = pFullTLV->wLen; while (cLen) { // be impervious to duplicates (AOL sends them sometimes) if (!capLen || !MatchCapability(capBuf, capLen, (capstr*)cData, BINARY_CAP_SIZE)) { // not present, add memcpy(pCapability, cData, BINARY_CAP_SIZE); capLen += BINARY_CAP_SIZE; pCapability += BINARY_CAP_SIZE; } cData += BINARY_CAP_SIZE; cLen -= BINARY_CAP_SIZE; } } if (pShortTLV && (pShortTLV->wLen >= 2)) { // copy short Capabilities capstr tmp; BYTE *cData = pShortTLV->pData; int cLen = pShortTLV->wLen; memcpy(tmp, capShortCaps, BINARY_CAP_SIZE); while (cLen) { // be impervious to duplicates (AOL sends them sometimes) tmp[2] = cData[0]; tmp[3] = cData[1]; if (!capLen || !MatchCapability(capBuf, capLen, &tmp, BINARY_CAP_SIZE)) { // not present, add memcpy(pCapability, tmp, BINARY_CAP_SIZE); capLen += BINARY_CAP_SIZE; pCapability += BINARY_CAP_SIZE; } cData += 2; cLen -= 2; } } debugLogA("Detected %d capability items.", capLen / BINARY_CAP_SIZE); } if (capLen) { // Update the contact's capabilies if present in packet SetCapabilitiesFromBuffer(hContact, capBuf, capLen, wOldStatus == ID_STATUS_OFFLINE); char *szCurrentClient = wOldStatus == ID_STATUS_OFFLINE ? NULL : getSettingStringUtf(hContact, "MirVer", NULL); szClient = detectUserClient(hContact, nIsICQ, wClass, dwOnlineSince, szCurrentClient, wVersion, dwFT1, dwFT2, dwFT3, dwDirectConnCookie, dwWebPort, capBuf, capLen, &bClientId, szStrBuf); // Check if the client changed, if not do not change if (szCurrentClient && !strcmpnull(szCurrentClient, szClient)) szClient = (const char*)-1; SAFE_FREE(&szCurrentClient); } else if (wOldStatus == ID_STATUS_OFFLINE) { // Remove the contact's capabilities if coming from offline ClearAllContactCapabilities(hContact); // no capability debugLogA("No capability info TLVs"); szClient = detectUserClient(hContact, nIsICQ, wClass, dwOnlineSince, NULL, wVersion, dwFT1, dwFT2, dwFT3, dwDirectConnCookie, dwWebPort, NULL, capLen, &bClientId, szStrBuf); } else // Capabilities not present in update packet, do not touch szClient = (const char*)-1; // we don't want to client be overwritten // handle Xtraz status char *moodData = NULL; WORD moodSize = 0; unpackSessionDataItem(pChain, 0x0E, (BYTE**)&moodData, &moodSize, NULL); if (capLen || wOldStatus == ID_STATUS_OFFLINE) handleXStatusCaps(dwUIN, szUID, hContact, capBuf, capLen, moodData, moodSize); else handleXStatusCaps(dwUIN, szUID, hContact, NULL, 0, moodData, moodSize); // Determine support for extended status messages if (pChain->getWord(0x08, 1) == 0x0A06) SetContactCapabilities(hContact, CAPF_STATUS_MESSAGES); else if (wOldStatus == ID_STATUS_OFFLINE) ClearContactCapabilities(hContact, CAPF_STATUS_MESSAGES); if (wOldStatus == ID_STATUS_OFFLINE) { if (CheckContactCapabilities(hContact, CAPF_SRV_RELAY)) debugLogA("Supports advanced messages"); else debugLogA("Does NOT support advanced messages"); } if (!nIsICQ) { // AIM clients does not advertise these, but do support them SetContactCapabilities(hContact, CAPF_UTF | CAPF_TYPING); // Server relayed messages are only supported by ICQ clients ClearContactCapabilities(hContact, CAPF_SRV_RELAY); if (dwUIN && wOldStatus == ID_STATUS_OFFLINE) debugLogA("Logged in with AIM client"); } if (nIsICQ && wVersion < 8) { ClearContactCapabilities(hContact, CAPF_SRV_RELAY); if (wOldStatus == ID_STATUS_OFFLINE) debugLogA("Forcing simple messages due to compability issues"); } // Process Avatar Hash pTLV = pChain->getTLV(0x1D, 1); if (pTLV) handleAvatarContactHash(dwUIN, szUID, hContact, pTLV->pData, pTLV->wLen); else handleAvatarContactHash(dwUIN, szUID, hContact, NULL, 0); // Process Status Note parseStatusNote(dwUIN, szUID, hContact, pChain); } // Free TLV chain disposeChain(&pChain); // Save contacts details in database if (hContact != NULL) { setDword(hContact, "LogonTS", dwOnlineSince); setDword(hContact, "AwayTS", dwAwaySince); setDword(hContact, "IdleTS", tIdleTS); if (dwMemberSince) setDword(hContact, "MemberTS", dwMemberSince); if (nIsICQ) { // on AIM these are not used setDword(hContact, "DirectCookie", dwDirectConnCookie); setByte(hContact, "DCType", (BYTE)nTCPFlag); setWord(hContact, "UserPort", (WORD)(dwPort & 0xffff)); setWord(hContact, "Version", wVersion); } else { delSetting(hContact, "DirectCookie"); delSetting(hContact, "DCType"); delSetting(hContact, "UserPort"); delSetting(hContact, "Version"); } // if no detection, set uknown if (!szClient) szClient = (nIsICQ ? "Unknown" : "Unknown AIM"); if (szClient != (char*)-1) { db_set_utf(hContact, m_szModuleName, "MirVer", szClient); setByte(hContact, "ClientID", bClientId); } if (wOldStatus == ID_STATUS_OFFLINE) { setDword(hContact, "IP", dwIP); setDword(hContact, "RealIP", dwRealIP); } else { // if not first notification only write significant information if (dwIP) setDword(hContact, "IP", dwIP); if (dwRealIP) setDword(hContact, "RealIP", dwRealIP); } setWord(hContact, "Status", (WORD)IcqStatusToMiranda(wStatus)); // Update info? if (dwUIN) { // check if the local copy of user details is up-to-date if (IsMetaInfoChanged(hContact)) icq_QueueUser(hContact); } } LPCTSTR ptszStatus = pcli->pfnGetStatusModeDescription(IcqStatusToMiranda(wStatus), 0); if (wOldStatus != IcqStatusToMiranda(wStatus)) { // And a small log notice... if status was changed if (nIsICQ) debugLogA("%u changed status to %S (v%d).", dwUIN, ptszStatus, wVersion); else debugLogA("%s changed status to %S.", strUID(dwUIN, szUID), ptszStatus); } if (szClient == cliSpamBot) { if (getByte("KillSpambots", DEFAULT_KILLSPAM_ENABLED) && db_get_b(hContact, "CList", "NotOnList", 0)) { // kill spammer icq_DequeueUser(dwUIN); icq_sendRemoveContact(dwUIN, NULL); AddToSpammerList(dwUIN); if (getByte("PopupsSpamEnabled", DEFAULT_SPAM_POPUPS_ENABLED)) ShowPopupMsg(hContact, LPGEN("Spambot Detected"), LPGEN("Contact deleted & further events blocked."), POPTYPE_SPAM); CallService(MS_DB_CONTACT_DELETE, hContact, 0); debugLogA("Contact %u deleted", dwUIN); } } }