DWORD CMraProto::MraSetXStatusInternal(DWORD dwXStatus) { if (IsXStatusValid(dwXStatus)) { CMStringW szBuff; // obsolete (TODO: remove in next version) char szValueName[MAX_PATH]; mir_snprintf(szValueName, SIZEOF(szValueName), "XStatus%ldName", dwXStatus); if (!mraGetStringW(NULL, szValueName, szBuff)) szBuff = lpcszXStatusNameDef[dwXStatus]; mraSetStringExW(NULL, DBSETTING_XSTATUSNAME, szBuff); // obsolete (TODO: remove in next version) mir_snprintf(szValueName, SIZEOF(szValueName), "XStatus%ldMsg", dwXStatus); if (mraGetStringW(NULL, szValueName, szBuff)) mraSetStringExW(NULL, DBSETTING_XSTATUSMSG, szBuff); else delSetting(DBSETTING_XSTATUSMSG); } else { delSetting(DBSETTING_XSTATUSNAME); delSetting(DBSETTING_XSTATUSMSG); dwXStatus = MRA_MIR_XSTATUS_NONE; } DWORD dwOldStatusMode = InterlockedExchange((volatile LONG*)&m_iXStatus, dwXStatus); setByte(DBSETTING_XSTATUSID, (BYTE)dwXStatus); MraSendNewStatus(m_iStatus, dwXStatus, _T(""), _T("")); return dwOldStatusMode; }
int CMraProto::SetAwayMsg(int m_iStatus, const TCHAR* msg) { if (!m_bLoggedIn) return 1; size_t dwStatusDescSize = mir_tstrlen(msg); DWORD dwStatus = m_iStatus; DWORD dwXStatus = m_iXStatus; // не отправл¤ем новый статусный текст дл¤ хстатусов, дл¤ хстатусов только эвей сообщени¤ if (dwStatus != ID_STATUS_ONLINE || IsXStatusValid(dwXStatus) == FALSE) { dwStatusDescSize = min(dwStatusDescSize, STATUS_DESC_MAX); MraSendNewStatus(dwStatus, dwXStatus, _T(""), msg); } 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; }