void CSteamProto::OnGotHistoryMessages(const HttpResponse *response, void *arg) { MCONTACT hContact = FindContact((char*)arg); if (!hContact) return; if (!ResponseHttpOk(response)) return; JSONROOT root(response->pData); if (root == NULL) return; JSONNode *node = json_get(root, "response"); JSONNode *messages = json_get(node, "messages"); JSONNode *nmessages = json_as_array(messages); // Self SteamID ptrA steamId(getStringA("SteamID")); for (size_t i = json_size(nmessages); i > 0; i--) { JSONNode *message = json_at(nmessages, i - 1); node = json_get(message, "accountid"); const char *authorSteamId = AccountIdToSteamId(_ttoi64(ptrT(json_as_string(node)))); node = json_get(message, "message"); ptrT text(json_as_string(node)); T2Utf szMessage(text); node = json_get(message, "timestamp"); time_t timestamp = _ttoi64(ptrT(json_as_string(node))); // Ignore already existing messages if (timestamp <= m_lastMessageTS) continue; PROTORECVEVENT recv = { 0 }; recv.timestamp = timestamp; recv.szMessage = szMessage; if (strcmp(steamId, authorSteamId)) { // Received message ProtoChainRecvMsg(hContact, &recv); } else { // Sent message recv.flags = PREF_SENT; Proto_RecvMessage(hContact, &recv); } } json_delete(nmessages); }
void CSteamProto::OnGotConversations(const HttpResponse *response) { // Don't load any messages when we don't have lastMessageTS, as it may cause duplicates if (m_lastMessageTS <= 0) return; if (!ResponseHttpOk(response)) return; JSONROOT root(response->pData); if (root == NULL) return; JSONNode *node = json_get(root, "response"); JSONNode *sessions = json_get(node, "message_sessions"); JSONNode *nsessions = json_as_array(sessions); if (nsessions != NULL) { ptrA token(getStringA("TokenSecret")); ptrA steamId(getStringA("SteamID")); for (size_t i = 0; i < json_size(nsessions); i++) { JSONNode *session = json_at(nsessions, i); node = json_get(session, "accountid_friend"); const char *who = AccountIdToSteamId(_ttoi64(ptrT(json_as_string(node)))); node = json_get(session, "last_message"); time_t lastMessageTS = _ttoi64(ptrT(json_as_string(node))); /*node = json_get(session, "last_view"); time_t last_view = _ttoi64(ptrT(json_as_string(node))); node = json_get(session, "unread_message_count"); long unread_count = json_as_int(node);*/ if (lastMessageTS > m_lastMessageTS) { PushRequest( new GetHistoryMessagesRequest(token, steamId, who, m_lastMessageTS), &CSteamProto::OnGotHistoryMessages, mir_strdup(who), MirFreeArg); } } json_delete(nsessions); } }
void CSteamProto::PollingThread(void*) { debugLog(_T("CSteamProto::PollingThread: entering")); ptrA token(getStringA("TokenSecret")); ptrA umqId(getStringA("UMQID")); UINT32 messageId = getDword("MessageID", 0); 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 (!ResponseHttpOk(response)) { errors++; } else { ptrA body((char*)mir_calloc(response->dataLength + 2)); mir_strncpy(body, response->pData, response->dataLength + 1); JSONROOT root(body); if (root == NULL) { errors++; } else { errors = 0; JSONNode *node = json_get(root, "error"); if (node) { 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("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 if (lstrcmpi(error, _T("Timeout"))) { // 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); } }