From 97d772455be44b3693678bb5192e5c6bc777bc98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20P=C3=B6sel?= Date: Mon, 8 Dec 2014 23:53:49 +0000 Subject: Steam: Refactor statuses support - allow changing own status - change own status when it changes on server - temporary don't distinguish between playing/not playing contacts - fix steam<->miranda status mapping git-svn-id: http://svn.miranda-ng.org/main/trunk@11291 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Steam/Steam_10.vcxproj | 1 + protocols/Steam/Steam_10.vcxproj.filters | 3 ++ protocols/Steam/Steam_12.vcxproj | 1 + protocols/Steam/Steam_12.vcxproj.filters | 3 ++ protocols/Steam/src/Steam/message.h | 2 +- protocols/Steam/src/Steam/status.h | 24 +++++++++++++ protocols/Steam/src/Steam/steam.h | 1 + protocols/Steam/src/steam_account.cpp | 35 ++++++++++++++++++- protocols/Steam/src/steam_contacts.cpp | 60 +++++++++++++++++++++----------- protocols/Steam/src/steam_proto.cpp | 24 ++++++++++--- protocols/Steam/src/steam_proto.h | 1 + protocols/Steam/src/steam_utils.cpp | 30 ++++++++-------- 12 files changed, 144 insertions(+), 41 deletions(-) create mode 100644 protocols/Steam/src/Steam/status.h (limited to 'protocols/Steam') diff --git a/protocols/Steam/Steam_10.vcxproj b/protocols/Steam/Steam_10.vcxproj index 7adb920113..3edf0526e2 100644 --- a/protocols/Steam/Steam_10.vcxproj +++ b/protocols/Steam/Steam_10.vcxproj @@ -201,6 +201,7 @@ + diff --git a/protocols/Steam/Steam_10.vcxproj.filters b/protocols/Steam/Steam_10.vcxproj.filters index f652465c1e..985a3abcb4 100644 --- a/protocols/Steam/Steam_10.vcxproj.filters +++ b/protocols/Steam/Steam_10.vcxproj.filters @@ -110,6 +110,9 @@ Header Files\Steam + + Header Files\Steam + diff --git a/protocols/Steam/Steam_12.vcxproj b/protocols/Steam/Steam_12.vcxproj index 192936124f..55c5854fa4 100644 --- a/protocols/Steam/Steam_12.vcxproj +++ b/protocols/Steam/Steam_12.vcxproj @@ -204,6 +204,7 @@ + diff --git a/protocols/Steam/Steam_12.vcxproj.filters b/protocols/Steam/Steam_12.vcxproj.filters index 0a9df2ae03..c4727501f1 100644 --- a/protocols/Steam/Steam_12.vcxproj.filters +++ b/protocols/Steam/Steam_12.vcxproj.filters @@ -100,6 +100,9 @@ Header Files\Steam + + + Header Files\Steam Header Files\Steam diff --git a/protocols/Steam/src/Steam/message.h b/protocols/Steam/src/Steam/message.h index 29a6afab12..c5bac75aff 100644 --- a/protocols/Steam/src/Steam/message.h +++ b/protocols/Steam/src/Steam/message.h @@ -117,7 +117,7 @@ namespace SteamWebApi steamId, ptrA(mir_urlEncode(text))); - SetData(data, data.GetLength()); // FIXME: Is correct to give CMStringA or does it cause memory leak inside that method? + SetData(data, data.GetLength()); } }; } diff --git a/protocols/Steam/src/Steam/status.h b/protocols/Steam/src/Steam/status.h new file mode 100644 index 0000000000..686ff062d3 --- /dev/null +++ b/protocols/Steam/src/Steam/status.h @@ -0,0 +1,24 @@ +#ifndef _STEAM_STATUS_H_ +#define _STEAM_STATUS_H_ + +namespace SteamWebApi +{ + class SetStatusRequest : public HttpsPostRequest + { + public: + SetStatusRequest(const char *token, const char *umqId, int state) : + HttpsPostRequest(STEAM_API_URL "/ISteamWebUserPresenceOAuth/Message/v0001") + { + CMStringA data; + data.AppendFormat("access_token=%s&umqid=%s&type=personastate&persona_state=%d", + token, + umqId, + state); + + SetData(data, data.GetLength()); + } + }; +} + + +#endif //_STEAM_STATUS_H_ \ No newline at end of file diff --git a/protocols/Steam/src/Steam/steam.h b/protocols/Steam/src/Steam/steam.h index c32da7e92a..7809553c1b 100644 --- a/protocols/Steam/src/Steam/steam.h +++ b/protocols/Steam/src/Steam/steam.h @@ -121,5 +121,6 @@ namespace SteamWebApi #include "Steam\search.h" #include "Steam\avatar.h" #include "Steam\captcha.h" +#include "Steam\status.h" #endif //_STEAM_H_ \ No newline at end of file diff --git a/protocols/Steam/src/steam_account.cpp b/protocols/Steam/src/steam_account.cpp index b428896fcc..62e442a032 100644 --- a/protocols/Steam/src/steam_account.cpp +++ b/protocols/Steam/src/steam_account.cpp @@ -221,7 +221,8 @@ void CSteamProto::OnGotSession(const NETLIBHTTPREQUEST *response, void *arg) void CSteamProto::OnLoggedOn(const NETLIBHTTPREQUEST *response, void *arg) { - if (response == NULL) { + if (response == NULL) + { // set status to offline m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, ID_STATUS_OFFLINE); @@ -262,4 +263,36 @@ void CSteamProto::OnLoggedOn(const NETLIBHTTPREQUEST *response, void *arg) // go to online now ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, m_iStatus = m_iDesiredStatus); +} + +void CSteamProto::OnStatusChanged(const NETLIBHTTPREQUEST *response, void *arg) +{ + if (response == NULL) + { + m_iDesiredStatus = m_iStatus; + ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_FAILED, (HANDLE)m_iStatus, m_iStatus); + return; + } + + JSONROOT root(response->pData); + + /*JSONNODE *node = json_get(root, "success"); + if (!json_as_bool(node)) { + return; + } + + JSONNODE *node = json_get(root, "error"); + ptrW error(json_as_string(node)); + if (lstrcmpi(error, L"OK")/* || response->resultCode == HTTP_STATUS_UNAUTHORIZED*//*) + { + // set status to offline + m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; + ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, ID_STATUS_OFFLINE); + return; + }*/ + + int new_status = (int)arg; + int old_status = m_iStatus; + m_iStatus = m_iDesiredStatus = new_status; + ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); } \ No newline at end of file diff --git a/protocols/Steam/src/steam_contacts.cpp b/protocols/Steam/src/steam_contacts.cpp index 1fca7bc85c..3bba9d6ac3 100644 --- a/protocols/Steam/src/steam_contacts.cpp +++ b/protocols/Steam/src/steam_contacts.cpp @@ -112,34 +112,52 @@ void CSteamProto::UpdateContact(MCONTACT hContact, JSONNODE *data) node = json_get(data, "timecreated"); setDword(hContact, "MemberTS", json_as_int(node)); - // only for contacts - if (hContact) + node = json_get(data, "lastlogoff"); + setDword(hContact, "LogoffTS", json_as_int(node)); + + // status + node = json_get(data, "personastate"); + WORD steamStatus = json_as_int(node); + WORD status = SteamToMirandaStatus(steamStatus); + if (hContact != NULL) { - node = json_get(data, "lastlogoff"); - setDword(hContact, "LogoffTS", json_as_int(node)); + // contact status + setWord(hContact, "Status", status); + } + else + { + // my status + // TODO: uncomment when invisible status is used in Steam proto + /*if (status == ID_STATUS_OFFLINE) + status = ID_STATUS_INVISIBLE;*/ - node = json_get(data, "gameid"); - DWORD gameId = node ? atol(_T2A(json_as_string(node))) : 0; - if (gameId > 0) + if (status != ID_STATUS_OFFLINE) { - node = json_get(data, "gameextrainfo"); - const wchar_t *gameInfo = json_as_string(node); + int old_status = m_iStatus; + m_iStatus = m_iDesiredStatus = status; + ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); + } + } - db_set_ws(hContact, "CList", "StatusMsg", gameInfo); - setWord(hContact, "Status", ID_STATUS_OUTTOLUNCH); + node = json_get(data, "gameid"); + DWORD gameId = node ? atol(_T2A(json_as_string(node))) : 0; + if (gameId > 0) + { + node = json_get(data, "gameextrainfo"); + const wchar_t *gameInfo = json_as_string(node); - setWString(hContact, "GameInfo", gameInfo); - setDword(hContact, "GameID", gameId); - } - else - { - node = json_get(data, "personastate"); - WORD status = SteamToMirandaStatus(json_as_int(node)); - setWord(hContact, "Status", status); + if (hContact != NULL) + db_set_ws(hContact, "CList", "StatusMsg", gameInfo); + setWString(hContact, "GameInfo", gameInfo); + setDword(hContact, "GameID", gameId); + } + else + { + if (hContact != NULL) db_unset(hContact, "CList", "StatusMsg"); - delSetting(hContact, "GameID"); - } + + delSetting(hContact, "GameID"); } } diff --git a/protocols/Steam/src/steam_proto.cpp b/protocols/Steam/src/steam_proto.cpp index 612d66768f..36592a4082 100644 --- a/protocols/Steam/src/steam_proto.cpp +++ b/protocols/Steam/src/steam_proto.cpp @@ -35,6 +35,7 @@ CSteamProto::CSteamProto(const char* protoName, const TCHAR* userName) : Skin_AddIcon(&sid); // temporary DB settings + db_set_resident(m_szModuleName, "Status"); // NOTE: XStatus cannot be temporary db_set_resident(m_szModuleName, "IdleTS"); SetAllContactsStatus(ID_STATUS_OFFLINE); @@ -199,11 +200,11 @@ DWORD_PTR __cdecl CSteamProto:: GetCaps(int type, MCONTACT hContact) case PFLAGNUM_1: return PF1_IM | PF1_BASICSEARCH | PF1_SEARCHBYNAME | PF1_AUTHREQ | PF1_SERVERCLIST | PF1_ADDSEARCHRES; case PFLAGNUM_2: - return PF2_ONLINE | PF2_SHORTAWAY | PF2_HEAVYDND | PF2_OUTTOLUNCH; + return PF2_ONLINE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_HEAVYDND | PF2_OUTTOLUNCH | PF2_FREECHAT; case PFLAGNUM_4: return PF4_AVATARS | PF4_NOCUSTOMAUTH | PF4_NOAUTHDENYREASON | PF4_FORCEAUTH | PF4_FORCEADDED | PF4_IMSENDUTF | PF4_SUPPORTIDLE;// | PF4_IMSENDOFFLINE | PF4_SUPPORTTYPING; case PFLAGNUM_5: - return PF2_SHORTAWAY | PF2_HEAVYDND | PF2_OUTTOLUNCH; + return 0; case PFLAG_UNIQUEIDTEXT: return (DWORD_PTR)Translate("SteamID"); case PFLAG_UNIQUEIDSETTING: @@ -325,10 +326,15 @@ int CSteamProto::SetStatus(int new_status) // Routing statuses not supported by Steam switch (new_status) { - case ID_STATUS_OFFLINE: + case ID_STATUS_OCCUPIED: + new_status = ID_STATUS_DND; break; - default: + case ID_STATUS_ONTHEPHONE: + new_status = ID_STATUS_AWAY; + break; + + case ID_STATUS_INVISIBLE: new_status = ID_STATUS_ONLINE; break; } @@ -362,6 +368,16 @@ int CSteamProto::SetStatus(int new_status) //ForkThread(&CSteamProto::LogInThread, NULL); StartQueue(); } + else { + ptrA token(getStringA("TokenSecret")); + ptrA sessionId(getStringA("SessionID")); + int state = MirandaToSteamState(new_status); + + PushRequest( + new SteamWebApi::SetStatusRequest(token, sessionId, state), + &CSteamProto::OnStatusChanged, + (void *)new_status); + } return 0; } diff --git a/protocols/Steam/src/steam_proto.h b/protocols/Steam/src/steam_proto.h index 82dd4f925b..95832418fe 100644 --- a/protocols/Steam/src/steam_proto.h +++ b/protocols/Steam/src/steam_proto.h @@ -188,6 +188,7 @@ protected: void OnGotSession(const NETLIBHTTPREQUEST *response, void *arg); void OnLoggedOn(const NETLIBHTTPREQUEST *response, void *arg); + void OnStatusChanged(const NETLIBHTTPREQUEST *response, void *arg); // contacts void SetContactStatus(MCONTACT hContact, WORD status); diff --git a/protocols/Steam/src/steam_utils.cpp b/protocols/Steam/src/steam_utils.cpp index 1e7d27b3ec..7c5888645f 100644 --- a/protocols/Steam/src/steam_utils.cpp +++ b/protocols/Steam/src/steam_utils.cpp @@ -6,17 +6,18 @@ WORD CSteamProto::SteamToMirandaStatus(int state) { case 0: //Offline return ID_STATUS_OFFLINE; + case 1: //Online + return ID_STATUS_ONLINE; case 2: //Busy return ID_STATUS_DND; case 3: //Away return ID_STATUS_AWAY; - case 4: //Playing + case 4: //Snoozing + return ID_STATUS_NA; + case 5: //Looking to trade return ID_STATUS_OUTTOLUNCH; - /*case 5: //Looking to trade - return "trade"; - case 6: //Looking to play - return "play";*/ - //case 1: //Online + case 6: //Looking to play + return ID_STATUS_FREECHAT; default: return ID_STATUS_ONLINE; } @@ -28,19 +29,20 @@ int CSteamProto::MirandaToSteamState(int status) { case ID_STATUS_OFFLINE: return 0; //Offline + case ID_STATUS_ONLINE: + return 1; //Online case ID_STATUS_DND: return 2; //Busy case ID_STATUS_AWAY: return 3; //Away - /*case PF2_OUTTOLUNCH: - return 4; //Playing - case 5: //Looking to trade - return "trade"; - case 6: //Looking to play - return "play";*/ - //case 1: //Online + case ID_STATUS_NA: + return 4; //Snoozing + case ID_STATUS_OUTTOLUNCH: + return 5; //Looking to trade + case ID_STATUS_FREECHAT: + return 6; //Looking to play default: - return ID_STATUS_ONLINE; + return 1; } } -- cgit v1.2.3