diff options
Diffstat (limited to 'protocols/Steam/src')
| -rw-r--r-- | protocols/Steam/src/api/history.h | 27 | ||||
| -rw-r--r-- | protocols/Steam/src/stdafx.h | 1 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_contacts.cpp | 8 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_history.cpp | 121 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_polling.cpp | 6 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_proto.cpp | 4 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_proto.h | 17 | 
7 files changed, 183 insertions, 1 deletions
diff --git a/protocols/Steam/src/api/history.h b/protocols/Steam/src/api/history.h new file mode 100644 index 0000000000..fc3c7c8a6b --- /dev/null +++ b/protocols/Steam/src/api/history.h @@ -0,0 +1,27 @@ +#ifndef _STEAM_REQUEST_HISTORY_H_ +#define _STEAM_REQUEST_HISTORY_H_ + +class GetConversationsRequest : public HttpRequest +{ +public: +	GetConversationsRequest(const char *token) : +		HttpRequest(REQUEST_GET, STEAM_API_URL "/IFriendMessagesService/GetActiveMessageSessions/v0001") +	{ +		AddParameter("access_token", token); +	} +}; + +class GetHistoryMessagesRequest : public HttpRequest +{ +public: +	GetHistoryMessagesRequest(const char *token, const char *steamId, const char *who, time_t since) : +		HttpRequest(REQUEST_GET, STEAM_API_URL "/IFriendMessagesService/GetRecentMessages/v0001") +	{ +		AddParameter("access_token", token); +		AddParameter("steamid1", steamId); +		AddParameter("steamid2", who); +		AddParameter("rtime32_start_time=%d", since); +	} +}; + +#endif //_STEAM_REQUEST_HISTORY_H_ diff --git a/protocols/Steam/src/stdafx.h b/protocols/Steam/src/stdafx.h index da39bcaed8..b86ae3908f 100644 --- a/protocols/Steam/src/stdafx.h +++ b/protocols/Steam/src/stdafx.h @@ -69,6 +69,7 @@ extern HANDLE hExtraXStatus;  #include "api\captcha.h"
  #include "api\friend.h"
  #include "api\friend_list.h"
 +#include "api\history.h"
  #include "api\login.h"
  #include "api\message.h"
  #include "api\pending.h"
 diff --git a/protocols/Steam/src/steam_contacts.cpp b/protocols/Steam/src/steam_contacts.cpp index 69572b2953..b069052cbc 100644 --- a/protocols/Steam/src/steam_contacts.cpp +++ b/protocols/Steam/src/steam_contacts.cpp @@ -432,15 +432,21 @@ void CSteamProto::OnGotFriendList(const HttpResponse *response)  	// We need to delete nroot here at the end, because we had references to JSONNode objects stored in friends map  	json_delete(nroot); +	ptrA token(getStringA("TokenSecret")); +  	if (!steamIds.empty())  	{  		//steamIds.pop_back(); -		ptrA token(getStringA("TokenSecret"));  		PushRequest(  			new GetUserSummariesRequest(token, steamIds.c_str()),  			&CSteamProto::OnGotUserSummaries);  	} + +	// Download last messages +	PushRequest( +		new GetConversationsRequest(token), +		&CSteamProto::OnGotConversations);  }  void CSteamProto::OnGotBlockList(const HttpResponse *response) diff --git a/protocols/Steam/src/steam_history.cpp b/protocols/Steam/src/steam_history.cpp new file mode 100644 index 0000000000..dc1f746928 --- /dev/null +++ b/protocols/Steam/src/steam_history.cpp @@ -0,0 +1,121 @@ +#include "stdafx.h" + +void CSteamProto::OnGotConversations(const HttpResponse *response) +{ +	if (!ResponseHttpOk(response)) +		return; + +	JSONROOT root(response->pData); +	if (root == NULL) +		return; + +	JSONNode *node = json_get(root, "response"); + +	if (m_lastMessageTS <= 0) +	{ +		// Remember and save actual timestamp (as it is first we've got) +		JSONNode *timestampNode = json_get(node, "timestamp"); +		m_lastMessageTS = _ttoi64(ptrT(json_as_string(timestampNode))); +		setDword("LastMessageTS", m_lastMessageTS); + +		// And don't load any messages as it may cause duplicates +		return; +	} + +	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::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) - 1; i >= 0; i--) +	{ +		JSONNode *message = json_at(nmessages, i); + +		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))); + +		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); +		} + +		// Update last message timestamp +		if (timestamp > getDword("LastMessageTS", 0)) +			setDword("LastMessageTS", timestamp); +	} + +	json_delete(nmessages); +} diff --git a/protocols/Steam/src/steam_polling.cpp b/protocols/Steam/src/steam_polling.cpp index 8086db033e..eadade3d99 100644 --- a/protocols/Steam/src/steam_polling.cpp +++ b/protocols/Steam/src/steam_polling.cpp @@ -215,6 +215,12 @@ void CSteamProto::PollingThread(void*)  					if (!lstrcmpi(error, _T("OK")))  					{ +						// Remember last message timestamp +						node = json_get(root, "timestamp"); +						time_t lastMessageTS = _ttoi64(ptrT(json_as_string(node))); +						if (lastMessageTS > getDword("LastMessageTS", 0)) +							setDword("LastMessageTS", lastMessageTS); +  						node = json_get(root, "messagelast");  						messageId = json_as_int(node); diff --git a/protocols/Steam/src/steam_proto.cpp b/protocols/Steam/src/steam_proto.cpp index 8d70098aa0..e0ec091bee 100644 --- a/protocols/Steam/src/steam_proto.cpp +++ b/protocols/Steam/src/steam_proto.cpp @@ -7,6 +7,7 @@ CSteamProto::CSteamProto(const char* protoName, const TCHAR* userName)  	CreateProtoService(PS_CREATEACCMGRUI, &CSteamProto::OnAccountManagerInit);  	m_idleTS = 0; +	m_lastMessageTS = 0;  	isLoginAgain = false;  	m_hQueueThread = NULL;  	m_pollingConnection = NULL; @@ -319,6 +320,9 @@ int CSteamProto::SetStatus(int new_status)  	}  	else if (old_status == ID_STATUS_OFFLINE)  	{ +		// Load last message timestamp for correct loading of messages history +		m_lastMessageTS = getDword("LastMessageTS", 0); +  		m_iStatus = ID_STATUS_CONNECTING;  		ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); diff --git a/protocols/Steam/src/steam_proto.h b/protocols/Steam/src/steam_proto.h index 3c282f35e7..88fb947eab 100644 --- a/protocols/Steam/src/steam_proto.h +++ b/protocols/Steam/src/steam_proto.h @@ -86,6 +86,12 @@ protected:  	mir_cs set_status_lock;
  	std::map<HANDLE, time_t> m_mpOutMessages;
 +	/**
 +	 * Used only to compare in steam_history.cpp, others should write such value directly to db profile, because PollingThread
 +	 * may start sooner than steam_history requests so it could possibly break getting history messages from server
 +	 */
 +	time_t m_lastMessageTS;
 +
  	// instances
  	static LIST<CSteamProto> InstanceList;
  	static int CompareProtos(const CSteamProto *p1, const CSteamProto *p2);
 @@ -162,6 +168,10 @@ protected:  	void OnMessageSent(const HttpResponse *response, void *arg);
  	int __cdecl OnPreCreateMessage(WPARAM, LPARAM lParam);
 +	// history
 +	void OnGotConversations(const HttpResponse *response);
 +	void OnGotHistoryMessages(const HttpResponse *response, void *arg);
 +
  	// menus
  	static int hChooserMenu;
  	static HGENMENU contactMenuItems[CMI_MAX];
 @@ -231,6 +241,13 @@ protected:  		// ... or we can report real idle info
  		// return m_idleTS ? time(0) - m_idleTS : 0;
  	}
 +
 +	inline const char *AccountIdToSteamId(long long accountId)
 +	{
 +		static char steamId[20];
 +		mir_snprintf(steamId, "%llu", accountId + 76561197960265728ll);
 +		return steamId;
 +	}
  };
  int OnReloadIcons(WPARAM wParam, LPARAM lParam);
  | 
