示例#1
0
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);
}
示例#2
0
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);
	}
}
示例#3
0
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);
	}
}