int CMraProto::MraContactDeleted(WPARAM hContact, LPARAM) { if (!m_bLoggedIn || !hContact) return 0; if (IsContactMra(hContact)) { DWORD dwID, dwGroupID; GetContactBasicInfoW(hContact, &dwID, &dwGroupID, NULL, NULL, NULL, NULL, NULL, NULL); MraSetContactStatus(hContact, ID_STATUS_OFFLINE); if (!db_get_b(hContact, "CList", "NotOnList", 0) || dwID != -1) { DWORD dwFlags = CONTACT_FLAG_REMOVED; MraModifyContact(hContact, &dwID, &dwFlags); } MraAvatarsDeleteContactAvatarFile(hAvatarsQueueHandle, hContact); } return 0; }
int CMraProto::SetStatus(int iNewStatus) { // remap global statuses to local supported switch (iNewStatus) { case ID_STATUS_OCCUPIED: iNewStatus = ID_STATUS_DND; break; case ID_STATUS_NA: case ID_STATUS_ONTHEPHONE: case ID_STATUS_OUTTOLUNCH: iNewStatus = ID_STATUS_AWAY; break; } // nothing to change if (m_iStatus == iNewStatus) return 0; DWORD dwOldStatusMode; //set all contacts to offline if ((m_iDesiredStatus = iNewStatus) == ID_STATUS_OFFLINE) { m_bLoggedIn = FALSE; dwOldStatusMode = InterlockedExchange((volatile LONG*)&m_iStatus, m_iDesiredStatus); // всех в offline, только если мы бывали подключены if (dwOldStatusMode > ID_STATUS_OFFLINE) for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) SetContactBasicInfoW(hContact, SCBIFSI_LOCK_CHANGES_EVENTS, (SCBIF_ID | SCBIF_GROUP_ID | SCBIF_SERVER_FLAG | SCBIF_STATUS), -1, -1, 0, 0, ID_STATUS_OFFLINE, 0, 0, 0); NETLIB_CLOSEHANDLE(m_hConnection); } else { // если offline то сразу ставим connecting, но обработка как offline dwOldStatusMode = InterlockedCompareExchange((volatile LONG*)&m_iStatus, ID_STATUS_CONNECTING, ID_STATUS_OFFLINE); switch (dwOldStatusMode) { case ID_STATUS_OFFLINE: // offline, connecting if (StartConnect() != NO_ERROR) { m_bLoggedIn = FALSE; m_iDesiredStatus = ID_STATUS_OFFLINE; dwOldStatusMode = InterlockedExchange((volatile LONG*)&m_iStatus, m_iDesiredStatus); } break; case ID_STATUS_ONLINE:// connected, change status case ID_STATUS_AWAY: case ID_STATUS_DND: case ID_STATUS_FREECHAT: case ID_STATUS_INVISIBLE: MraSendNewStatus(m_iDesiredStatus, m_iXStatus, _T(""), _T("")); case ID_STATUS_CONNECTING: // предотвращаем переход в любой статус (кроме offline) из статуса connecting, если он не вызван самим плагином if (dwOldStatusMode == ID_STATUS_CONNECTING && iNewStatus != m_iDesiredStatus) break; default: dwOldStatusMode = InterlockedExchange((volatile LONG*)&m_iStatus, m_iDesiredStatus); break; } } MraSetContactStatus(NULL, m_iStatus); ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)dwOldStatusMode, m_iStatus); return 0; }