diff options
author | aunsane <aunsane@gmail.com> | 2018-01-14 22:02:44 +0300 |
---|---|---|
committer | aunsane <aunsane@gmail.com> | 2018-01-14 22:03:16 +0300 |
commit | 7cb1539b0dbcf585472dd2341129adf174bb0bb5 (patch) | |
tree | 6879adfdd3ebf5f64557525df118e0753969fd95 /protocols/Steam/src/steam_contacts.cpp | |
parent | a6b0d0df4854ffda2577e2b61844467253eb9e0f (diff) |
Steam: refactoring pt.2
Diffstat (limited to 'protocols/Steam/src/steam_contacts.cpp')
-rw-r--r-- | protocols/Steam/src/steam_contacts.cpp | 573 |
1 files changed, 294 insertions, 279 deletions
diff --git a/protocols/Steam/src/steam_contacts.cpp b/protocols/Steam/src/steam_contacts.cpp index 98f06662de..894853f46b 100644 --- a/protocols/Steam/src/steam_contacts.cpp +++ b/protocols/Steam/src/steam_contacts.cpp @@ -2,6 +2,9 @@ void CSteamProto::SetContactStatus(MCONTACT hContact, WORD status) { + if (!hContact) + return; + WORD oldStatus = getWord(hContact, "Status", ID_STATUS_OFFLINE); if (oldStatus != status) { @@ -11,19 +14,13 @@ void CSteamProto::SetContactStatus(MCONTACT hContact, WORD status) switch (status) { case ID_STATUS_FREECHAT: - { - // Contact is looking to play, save it to as status message - if (hContact) - db_set_ws(hContact, "CList", "StatusMsg", TranslateT("Looking to play")); - } + // Contact is looking to play, save it to as status message + db_set_ws(hContact, "CList", "StatusMsg", TranslateT("Looking to play")); break; case ID_STATUS_OUTTOLUNCH: - { - // Contact is looking to trade, save it to as status message - if (hContact) - db_set_ws(hContact, "CList", "StatusMsg", TranslateT("Looking to trade")); - } + // Contact is looking to trade, save it to as status message + db_set_ws(hContact, "CList", "StatusMsg", TranslateT("Looking to trade")); break; case ID_STATUS_OFFLINE: @@ -33,16 +30,12 @@ void CSteamProto::SetContactStatus(MCONTACT hContact, WORD status) delSetting(hContact, "XStatusName"); delSetting(hContact, "XStatusMsg"); - if (hContact) - SetContactExtraIcon(hContact, NULL); + SetContactExtraIcon(hContact, NULL); } // no break intentionally default: - { - if (hContact) - db_unset(hContact, "CList", "StatusMsg"); - } + db_unset(hContact, "CList", "StatusMsg"); break; } } @@ -67,20 +60,14 @@ MCONTACT CSteamProto::GetContactFromAuthEvent(MEVENT hEvent) return DbGetAuthEventContact(&dbei); } -MCONTACT CSteamProto::FindContact(const char *steamId) +MCONTACT CSteamProto::GetContact(const char *steamId) { - MCONTACT hContact = NULL; - - mir_cslock lck(this->contact_search_lock); - - for (hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) - { - ptrA cSteamId(db_get_sa(hContact, this->m_szModuleName, "SteamID")); - if (!lstrcmpA(cSteamId, steamId)) - break; + for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { + ptrA cSteamId(getStringA(hContact, "SteamID")); + if (!mir_strcmp(cSteamId, steamId)) + return hContact; } - - return hContact; + return NULL; } void CSteamProto::UpdateContactDetails(MCONTACT hContact, const JSONNode &data) @@ -97,26 +84,21 @@ void CSteamProto::UpdateContactDetails(MCONTACT hContact, const JSONNode &data) // set name JSONNode node = data["realname"]; - if (!node.isnull()) - { + if (!node.isnull()) { CMStringW realName = node.as_mstring(); - if (!realName.IsEmpty()) - { + if (!realName.IsEmpty()) { int pos = realName.Find(L' ', 1); - if (pos != -1) - { + if (pos != -1) { setWString(hContact, "FirstName", realName.Mid(0, pos)); setWString(hContact, "LastName", realName.Mid(pos + 1)); } - else - { + else { setWString(hContact, "FirstName", realName); delSetting(hContact, "LastName"); } } } - else - { + else { delSetting(hContact, "FirstName"); delSetting(hContact, "LastName"); } @@ -128,8 +110,7 @@ void CSteamProto::UpdateContactDetails(MCONTACT hContact, const JSONNode &data) // set country node = data["loccountrycode"]; - if (!node.isnull()) - { + if (!node.isnull()) { json_string countryCode = node.as_string(); char *country = (char *)CallService(MS_UTILS_GETCOUNTRYBYISOCODE, (WPARAM)countryCode.c_str(), 0); setString(hContact, "Country", country); @@ -138,17 +119,25 @@ void CSteamProto::UpdateContactDetails(MCONTACT hContact, const JSONNode &data) delSetting(hContact, "Country"); // state code - node = data["locstatecode"]; - if (!node.isnull()) - setDword(hContact, "StateCode", node.as_int()); - else + // note: it seems that steam sends "incorrect" state code + //node = data["locstatecode"]; + //if (!node.isnull()) + //{ + // json_string stateCode = node.as_string(); + // setString(hContact, "State", stateCode.c_str()); + //} + //else + //{ + // delSetting(hContact, "State"); delSetting(hContact, "StateCode"); + //} // city id - node = data["loccityid"]; - if (!node.isnull()) - setDword(hContact, "CityID", node.as_int()); - else + // note: steam no longer sends state city id + //node = data["loccityid"]; + //if (!node.isnull()) + // setDword(hContact, "CityID", node.as_int()); + //else delSetting(hContact, "CityID"); // account created @@ -160,34 +149,38 @@ void CSteamProto::UpdateContactDetails(MCONTACT hContact, const JSONNode &data) setDword(hContact, "LogoffTS", node.as_int()); // status - // NOTE: this here is wrong info, probably depending on publicity of steam profile, but we don't need this at all, we get status updates by polling - /*node = json_get(data, "personastate"); - status = SteamToMirandaStatus(json_as_int(node)); - SetContactStatus(hContact, status); - */ + node = data["lastlogoff"]; + // note: this here is often wrong info, probably depending on publicity of steam profile + // but sometimes polling does not get status at all + WORD oldStatus = getWord(hContact, "Status", ID_STATUS_OFFLINE); + // so, set status only if contact offline + if (oldStatus == ID_STATUS_OFFLINE) { + WORD status = SteamToMirandaStatus((PersonaState)node.as_int()); + SetContactStatus(hContact, status); + } // client node = data["personastateflags"]; - int stateflags = !node.isnull() ? node.as_int() : -1; + long stateflags = !node.isnull() ? node.as_int() : -1; if (stateflags == 0) { // nothing special, either standard client or in different status (only online, I want to play, I want to trade statuses support this flags) WORD status = getWord(hContact, "Status", ID_STATUS_OFFLINE); if (status == ID_STATUS_ONLINE || status == ID_STATUS_OUTTOLUNCH || status == ID_STATUS_FREECHAT) setWString(hContact, "MirVer", L"Steam"); } - else if (stateflags & 2) { + else if (stateflags & PersonaStateFlag::InJoinableGame) { // game setWString(hContact, "MirVer", L"Steam (in game)"); } - else if (stateflags & 256) { + else if (stateflags & PersonaStateFlag::OnlineUsingWeb) { // on website setWString(hContact, "MirVer", L"Steam (website)"); } - else if (stateflags & 512) { + else if (stateflags & PersonaStateFlag::OnlineUsingMobile) { // on mobile setWString(hContact, "MirVer", L"Steam (mobile)"); } - else if (stateflags & 1024) { + else if (stateflags & PersonaStateFlag::OnlineUsingBigPicture) { // big picture mode setWString(hContact, "MirVer", L"Steam (Big Picture)"); } @@ -199,8 +192,7 @@ void CSteamProto::UpdateContactDetails(MCONTACT hContact, const JSONNode &data) // playing game json_string appId = data["gameid"].as_string(); CMStringW gameInfo = data["gameextrainfo"].as_mstring(); - if (!appId.empty() || !gameInfo.IsEmpty()) - { + if (!appId.empty() || !gameInfo.IsEmpty()) { DWORD gameId = atol(appId.c_str()); json_string serverIP = data["gameserverip"].as_string(); json_string serverID = data["gameserversteamid"].as_string(); @@ -210,16 +202,14 @@ void CSteamProto::UpdateContactDetails(MCONTACT hContact, const JSONNode &data) setString(hContact, "ServerID", serverID.c_str()); CMStringW message(gameInfo); - if (gameId && message.IsEmpty()) - { + if (gameId && message.IsEmpty()) { ptrA token(getStringA("TokenSecret")); PushRequest( new GetAppInfoRequest(token, appId.c_str()), &CSteamProto::OnGotAppInfo, (void*)hContact); } - else - { + else { if (!gameId) message.Append(TranslateT(" (Non-Steam)")); if (!serverIP.empty()) @@ -232,8 +222,7 @@ void CSteamProto::UpdateContactDetails(MCONTACT hContact, const JSONNode &data) SetContactExtraIcon(hContact, gameId); } - else - { + else { delSetting(hContact, "GameID"); delSetting(hContact, "ServerIP"); delSetting(hContact, "ServerID"); @@ -246,136 +235,125 @@ void CSteamProto::UpdateContactDetails(MCONTACT hContact, const JSONNode &data) } } -void CSteamProto::ContactIsRemoved(MCONTACT hContact) +void CSteamProto::ContactIsFriend(MCONTACT hContact) { delSetting(hContact, "AuthAsked"); + delSetting(hContact, "Auth"); + delSetting(hContact, "Grant"); + db_unset(hContact, "CList", "NotOnList"); - // If this contact was authorized and now is not (and isn't filled time of deletion), notify it - if (!getDword(hContact, "DeletedTS", 0) && getByte(hContact, "Auth", 0) == 0) - { - setDword(hContact, "DeletedTS", ::time(nullptr)); + // Check if this contact was removed someday and if so, notify he's back + if (getDword(hContact, "DeletedTS", 0) && !getByte(hContact, "Auth", 0)) { + delSetting(hContact, "DeletedTS"); ptrW nick(getWStringA(hContact, "Nick")); wchar_t message[MAX_PATH]; - mir_snwprintf(message, MAX_PATH, TranslateT("%s has been removed from your contact list"), nick); + mir_snwprintf(message, MAX_PATH, TranslateT("%s is back in your contact list"), nick); - ShowNotification(L"Steam", message); + ShowNotification(message); } +} - if (getByte(hContact, "Auth", 0) != 1) - { - setByte(hContact, "Auth", 1); - } +void CSteamProto::ContactIsBlocked(MCONTACT hContact) +{ + // todo + setByte(hContact, "Block", 1); +} - SetContactStatus(hContact, ID_STATUS_OFFLINE); +void CSteamProto::ContactIsUnblocked(MCONTACT hContact) +{ + delSetting(hContact, "Block"); } -void CSteamProto::ContactIsFriend(MCONTACT hContact) +void CSteamProto::ContactIsRemoved(MCONTACT hContact) { delSetting(hContact, "AuthAsked"); - // Check if this contact was removed someday and if so, notify he's back - if (getDword(hContact, "DeletedTS", 0) && getByte(hContact, "Auth", 0) != 0) - { - delSetting(hContact, "DeletedTS"); + // If this contact was authorized and now is not (and isn't filled time of deletion), notify it + if (!getDword(hContact, "DeletedTS", 0) && !getByte(hContact, "Auth", 0)) { + setDword(hContact, "DeletedTS", now()); ptrW nick(getWStringA(hContact, "Nick")); wchar_t message[MAX_PATH]; - mir_snwprintf(message, MAX_PATH, TranslateT("%s is back in your contact list"), nick); - - ShowNotification(L"Steam", message); - } + mir_snwprintf(message, MAX_PATH, TranslateT("%s has been removed from your contact list"), nick); - if (getByte(hContact, "Auth", 0) != 0 || getByte(hContact, "Grant", 0) != 0) - { - delSetting(hContact, "Auth"); - delSetting(hContact, "Grant"); + ShowNotification(message); } -} -void CSteamProto::ContactIsIgnored(MCONTACT hContact) -{ - // todo - setByte(hContact, "Block", 1); + setByte(hContact, "Auth", 1); + SetContactStatus(hContact, ID_STATUS_OFFLINE); } void CSteamProto::ContactIsAskingAuth(MCONTACT hContact) { - if (getByte(hContact, "AuthAsked", 0) != 0) { + //if (getByte(hContact, "AuthAsked", 0)) // auth request was already showed, do nothing here - return; - } + //return; - if (getByte(hContact, "Auth", 0) == 0) { + /*if (getByte(hContact, "Auth", 0) == 0) { // user was just added or he already has authorization, but because we've just got auth request, he was probably deleted and requested again ContactIsRemoved(hContact); - } + }*/ // create auth request event ptrA steamId(getStringA(hContact, "SteamID")); ptrA nickName(getStringA(hContact, "Nick")); + if (nickName == nullptr) + nickName = mir_strdup(steamId); ptrA firstName(getStringA(hContact, "FirstName")); - if (firstName == NULL) + if (firstName == nullptr) firstName = mir_strdup(""); ptrA lastName(getStringA(hContact, "LastName")); - if (lastName == NULL) + if (lastName == nullptr) lastName = mir_strdup(""); char reason[MAX_PATH]; - mir_snprintf(reason, Translate("%s has added you to his or her Friend List"), nickName); + mir_snprintf(reason, Translate("%s has added you to contact list"), nickName); DB_AUTH_BLOB blob(hContact, nickName, firstName, lastName, steamId, reason); PROTORECVEVENT recv = { 0 }; - recv.timestamp = time(nullptr); + recv.timestamp = now(); recv.szMessage = blob; recv.lParam = blob.size(); ProtoChainRecv(hContact, PSR_AUTH, 0, (LPARAM)&recv); - - // remember to not create this event again, unless authorization status changes again - setByte(hContact, "AuthAsked", 1); } -MCONTACT CSteamProto::AddContact(const char *steamId, bool isTemporary) +MCONTACT CSteamProto::AddContact(const char *steamId, const wchar_t *nick, bool isTemporary) { - MCONTACT hContact = NULL; - - mir_cslock lck(this->contact_search_lock); + mir_cslock lock(m_addContactLock); - for (hContact = db_find_first(this->m_szModuleName); hContact; hContact = db_find_next(hContact, this->m_szModuleName)) - { - ptrA cSteamId(db_get_sa(hContact, this->m_szModuleName, "SteamID")); - if (!lstrcmpA(cSteamId, steamId)) - break; + if (!steamId || !mir_strlen(steamId)) { + debugLogA(__FUNCTION__ ": empty steam id"); + return NULL; } - if (!hContact) - { - // create contact - hContact = db_add_contact(); - Proto_AddToContact(hContact, this->m_szModuleName); + MCONTACT hContact = GetContact(steamId); + if (hContact) + return hContact; - setString(hContact, "SteamID", steamId); + // create contact + hContact = db_add_contact(); + Proto_AddToContact(hContact, m_szModuleName); - // update info - //UpdateContact(hContact, contact); + setString(hContact, "SteamID", steamId); + if (mir_wstrlen(nick)) { + setWString(hContact, "Nick", nick); + db_set_ws(hContact, "CList", "MyHandle", nick); + } - if (isTemporary) - { - setByte(hContact, "Auth", 1); - //setByte(hContact, "Grant", 1); - db_set_b(hContact, "CList", "NotOnList", 1); - } + // update info + //UpdateContact(hContact, contact); - // move to default group - DBVARIANT dbv; - if (!getWString("DefaultGroup", &dbv)) - { - if(Clist_GroupExists(dbv.ptszVal)) - db_set_ws(hContact, "CList", "Group", dbv.ptszVal); - db_free(&dbv); - } - } + if (isTemporary) + db_set_b(hContact, "CList", "NotOnList", 1); + + setByte(hContact, "Auth", 1); + //setByte(hContact, "Grant", 1); + + // move to default group + if (m_defaultGroup) + db_set_ws(hContact, "CList", "Group", m_defaultGroup); return hContact; } @@ -391,11 +369,11 @@ void CSteamProto::UpdateContactRelationship(MCONTACT hContact, const JSONNode &d return; json_string relationship = node.as_string(); - if (!lstrcmpiA(relationship.c_str(), "friend")) + if (!mir_strcmp(relationship.c_str(), "friend")) ContactIsFriend(hContact); - else if (!lstrcmpiA(relationship.c_str(), "ignoredfriend")) - ContactIsIgnored(hContact); - else if (!lstrcmpiA(relationship.c_str(), "requestrecipient")) + else if (!mir_strcmp(relationship.c_str(), "ignoredfriend")) + ContactIsBlocked(hContact); + else if (!mir_strcmp(relationship.c_str(), "requestrecipient")) ContactIsAskingAuth(hContact); } @@ -404,8 +382,7 @@ void CSteamProto::OnGotAppInfo(const JSONNode &root, void *arg) MCONTACT hContact = (UINT_PTR)arg; JSONNode apps = root["apps"].as_array(); - for (const JSONNode &app : apps) - { + for (const JSONNode &app : apps) { DWORD gameId = app["appid"].as_int(); CMStringW message = app["name"].as_mstring(); @@ -424,67 +401,69 @@ void CSteamProto::OnGotFriendList(const JSONNode &root, void*) std::string steamIds = (char*)ptrA(getStringA("SteamID")); // Remember contacts on server - std::map<json_string, JSONNode*> friendsMap; + std::map<json_string, JSONNode*> friendsMap; JSONNode friends = root["friends"].as_array(); - for (const JSONNode &_friend : friends) - { + for (const JSONNode &_friend : friends) { json_string steamId = _friend["steamid"].as_string(); friendsMap.insert(std::make_pair(steamId, json_copy(&_friend))); } - { // Check and update contacts in database - mir_cslock lck(this->contact_search_lock); - - for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) - { - ptrA steamId(getStringA(hContact, "SteamID")); - if (steamId == nullptr) - continue; + // Check and update contacts in database + for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { + ptrA steamId(getStringA(hContact, "SteamID")); + if (steamId == nullptr) + continue; - auto it = friendsMap.find((char*)steamId); - if (it != friendsMap.end()) - { - // Contact is on server-list, update (and eventually notify) it - UpdateContactRelationship(hContact, *it->second); - steamIds.append(",").append(it->first); - json_delete(it->second); - friendsMap.erase(it); - } - else - { - // Contact was removed from server-list, notify it - ContactIsRemoved(hContact); - } + auto it = friendsMap.find((char*)steamId); + if (it == friendsMap.end()) { + // Contact was removed from server-list, notify it + ContactIsRemoved(hContact); + continue; } + + JSONNode _friend = *it->second; + + // Contact is on server-list, update (and eventually notify) it + UpdateContactRelationship(hContact, _friend); + + // Do not update summary for non friends + json_string relationship = _friend["relationship"].as_string(); + if (relationship == "friend") + steamIds.append(",").append(it->first); + + json_delete(it->second); + friendsMap.erase(it); } // Check remaining contacts in map and add them to contact list - for (auto it : friendsMap) - { + for (auto it : friendsMap) { // Contact is on server-list, but not in database, add (but not notify) it - MCONTACT hContact = AddContact(it.first.c_str()); - UpdateContactRelationship(hContact, *it.second); - - steamIds.append(",").append(it.first); + JSONNode _friend = *it.second; + + json_string relationship = _friend["relationship"].as_string(); + + MCONTACT hContact = AddContact(it.first.c_str(), nullptr, relationship != "friend"); + UpdateContactRelationship(hContact, _friend); + + if (relationship == "friend") + steamIds.append(",").append(it.first); + json_delete(it.second); } friendsMap.clear(); - // 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(); + steamIds.pop_back(); PushRequest( new GetUserSummariesRequest(token, steamIds.c_str()), &CSteamProto::OnGotUserSummaries); } - // Download last messages + // Load last conversations PushRequest( new GetConversationsRequest(token), &CSteamProto::OnGotConversations); @@ -501,11 +480,9 @@ void CSteamProto::OnGotBlockList(const JSONNode &root, void*) if (friends.isnull()) return; - for (size_t i = 0; i < friends.size(); i++) + for (const JSONNode &_friend: friends) { - JSONNode node = friends[i].as_node(); - - json_string steamId = node["steamid"].as_string(); + json_string steamId = _friend["steamid"].as_string(); /*MCONTACT hContact = FindContact(steamId); if (!hContact) @@ -514,8 +491,8 @@ void CSteamProto::OnGotBlockList(const JSONNode &root, void*) steamIds.append(steamId).append(","); }*/ - json_string relationship = node["relationship"].as_string(); - if (!lstrcmpiA(relationship.c_str(), "ignoredfriend")) + json_string relationship = _friend["relationship"].as_string(); + if (!mir_strcmp(relationship.c_str(), "ignoredfriend")) { // todo: open block list } @@ -529,15 +506,12 @@ void CSteamProto::OnGotUserSummaries(const JSONNode &root, void*) if (players.isnull()) return; - for (size_t i = 0; i < players.size(); i++) - { - JSONNode player = players[i]; + for (const JSONNode &player : players) { json_string steamId = player["steamid"].as_string(); - - MCONTACT hContact = NULL; - if (!IsMe(steamId.c_str())) - hContact = AddContact(steamId.c_str()); - + CMStringW nick = player["personaname"].as_mstring(); + MCONTACT hContact = !IsMe(steamId.c_str()) + ? hContact = AddContact(steamId.c_str(), nick) + : NULL; UpdateContactDetails(hContact, player); } } @@ -548,8 +522,7 @@ void CSteamProto::OnGotAvatar(const HttpResponse &response, void *arg) ai.hContact = (UINT_PTR)arg; GetDbAvatarInfo(ai); - if (!response.IsSuccess()) - { + if (!response.IsSuccess()) { ptrA steamId(getStringA(ai.hContact, "SteamID")); debugLogA(__FUNCTION__ ": failed to get avatar %s", steamId); @@ -558,11 +531,10 @@ void CSteamProto::OnGotAvatar(const HttpResponse &response, void *arg) return; } - FILE *fp = _wfopen(ai.filename, L"wb"); - if (fp) - { - fwrite(response.Content, sizeof(char), response.Content.GetSize(), fp); - fclose(fp); + FILE *file = _wfopen(ai.filename, L"wb"); + if (file) { + fwrite(response.Content, sizeof(char), response.Content.GetSize(), file); + fclose(file); if (ai.hContact) ProtoBroadcastAck(ai.hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, (HANDLE)&ai, 0); @@ -575,21 +547,63 @@ void CSteamProto::OnFriendAdded(const HttpResponse &response, void *arg) { SendAuthParam *param = (SendAuthParam*)arg; - if (!response.IsSuccess() || lstrcmpiA(response.Content, "true")) - { - ptrA steamId(getStringA(param->hContact, "SteamID")); - debugLogA(__FUNCTION__ ": failed to add friend %s", steamId); + if (!response.IsSuccess() || mir_strcmp(response.Content, "true")) { + + ptrW steamId(getWStringA(param->hContact, "SteamID")); + ptrW who(getWStringA(param->hContact, "Nick")); + if (!who) + who = mir_wstrdup(steamId); - ProtoBroadcastAck(param->hContact, ACKTYPE_AUTHREQ, ACKRESULT_FAILED, param->hAuth, 0); + wchar_t message[MAX_PATH]; + mir_snwprintf(message, L"Error adding friend %s", who); + + JSONNode root = JSONNode::parse(response.Content); + if (root) { + int success = root["success"].as_int(); + if (success == 1) { + JSONNode invited = root["invited"].as_array(); + if (invited.empty()) { + JSONNode errors = root["failed_invites_result"].as_array(); + if (!errors.empty()) { + int first = 0; + int errorCode = errors[first].as_int(); + switch (errorCode) + { + case 11: + mir_snwprintf(message, L"All communication with %s is blocked. Communication is only possible if you have lifted the blocking. To do this, visit the user's Steam Community page.", who); + break; + case 15: + mir_snwprintf(message, L"Request to %s can not be sent. His/her friends list is full.", who); + break; + case 24: + mir_wstrcpy(message, L"Your account does not meet the requirements to use this feature. Visit Steam Support to get more information."); + break; + case 25: + mir_snwprintf(message, L"Request to %s can not be sent. Your friends list is full.", who); + break; + case 40: + mir_snwprintf(message, L"Error adding friend %s. The communication between you and the other Steam member is blocked.", who); + break; + case 84: + mir_wstrcpy(message, L"You've been sending too many invitations lately. Please try again in a day or two."); + break; + } + } + } + else { + ContactIsFriend(param->hContact); + ProtoBroadcastAck(param->hContact, ACKTYPE_AUTHREQ, ACKRESULT_SUCCESS, param->hAuth, 0); + return; + } + } + } + ShowNotification(message, MB_ICONERROR); + ProtoBroadcastAck(param->hContact, ACKTYPE_AUTHREQ, ACKRESULT_FAILED, param->hAuth, 0); return; } - delSetting(param->hContact, "Auth"); - delSetting(param->hContact, "Grant"); - delSetting(param->hContact, "DeletedTS"); - db_unset(param->hContact, "CList", "NotOnList"); - + ContactIsFriend(param->hContact); ProtoBroadcastAck(param->hContact, ACKTYPE_AUTHREQ, ACKRESULT_SUCCESS, param->hAuth, 0); } @@ -597,27 +611,42 @@ void CSteamProto::OnFriendBlocked(const HttpResponse &response, void *arg) { ptrA steamId((char*)arg); - if (!response.IsSuccess() || lstrcmpiA(response.Content, "true")) - { - debugLogA(__FUNCTION__ ": failed to ignore friend %s", (char*)arg); + if (!response.IsSuccess() || mir_strcmp(response.Content, "true")) { + debugLogA(__FUNCTION__ ": failed to ignore friend %s", (char*)steamId); return; } + + MCONTACT hContact = GetContact(steamId); + if (hContact) + ContactIsBlocked(hContact); } -void CSteamProto::OnFriendRemoved(const HttpResponse &response, void *arg) +void CSteamProto::OnFriendUnblocked(const HttpResponse &response, void *arg) { - MCONTACT hContact = (UINT_PTR)arg; + ptrA steamId((char*)arg); - if (!response.IsSuccess() || lstrcmpiA(response.Content, "true")) - { - ptrA who(getStringA(hContact, "SteamID")); + if (!response.IsSuccess() || mir_strcmp(response.Content, "true")) { + debugLogA(__FUNCTION__ ": failed to unignore friend %s", (char*)steamId); + return; + } + + MCONTACT hContact = GetContact(steamId); + if (hContact) + ContactIsUnblocked(hContact); +} - debugLogA(__FUNCTION__ ": failed to remove friend %s", who); +void CSteamProto::OnFriendRemoved(const HttpResponse &response, void *arg) +{ + ptrA steamId((char*)arg); + + if (!response.IsSuccess() || mir_strcmp(response.Content, "true")) { + debugLogA(__FUNCTION__ ": failed to remove friend %s", (char*)steamId); return; } - setByte(hContact, "Auth", 1); - setDword(hContact, "DeletedTS", ::time(nullptr)); + MCONTACT hContact = GetContact(steamId); + if (hContact) + ContactIsRemoved(hContact); } void CSteamProto::OnAuthRequested(const JSONNode &root, void*) @@ -628,13 +657,14 @@ void CSteamProto::OnAuthRequested(const JSONNode &root, void*) int first = 0; JSONNode players = root["players"].as_array(); JSONNode player = players[first]; - if (!player.isnull()) - { - json_string steamId = player["steamid"].as_string(); - MCONTACT hContact = AddContact(steamId.c_str()); - UpdateContactDetails(hContact, player); - ContactIsAskingAuth(hContact); - } + if (player.isnull()) + return; + + json_string steamId = player["steamid"].as_string(); + CMStringW nick = player["personaname"].as_mstring(); + MCONTACT hContact = AddContact(steamId.c_str(), nick); + UpdateContactDetails(hContact, player); + ContactIsAskingAuth(hContact); } void CSteamProto::OnPendingApproved(const JSONNode &root, void *arg) @@ -645,8 +675,7 @@ void CSteamProto::OnPendingApproved(const JSONNode &root, void *arg) return; int success = root["success"].as_int(); - if (success == 0) - { + if (success == 0) { json_string error = root["error_text"].as_string(); debugLogA(__FUNCTION__ ": failed to approve pending from %s (%s)", steamId, ptrA(mir_utf8decodeA(error.c_str()))); } @@ -660,8 +689,7 @@ void CSteamProto::OnPendingIgnoreded(const JSONNode &root, void *arg) return; int success = root["success"].as_int(); - if (success == 0) - { + if (success == 0) { json_string error = root["error_text"].as_string(); debugLogA(__FUNCTION__ ": failed to ignore pending from %s (%s)", steamId, ptrA(mir_utf8decodeA(error.c_str()))); } @@ -671,54 +699,47 @@ void CSteamProto::OnSearchResults(const HttpResponse &response, void *arg) { HANDLE searchType = (HANDLE)arg; - if (!response.IsSuccess()) - { + if (!response.IsSuccess()) { ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, searchType, 0); debugLogA(__FUNCTION__ ": failed to get summaries"); return; } JSONNode root = JSONNode::parse(response.Content); - if (root.isnull()) - { + if (root.isnull()) { ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, searchType, 0); + debugLogA(__FUNCTION__ ": no data"); return; } JSONNode players = root["players"].as_array(); - for (size_t i = 0; i < players.size(); i++) - { - JSONNode player = players[i]; - + for (const JSONNode &player : players) { STEAM_SEARCH_RESULT ssr = { 0 }; - ssr.hdr.cbSize = sizeof(STEAM_SEARCH_RESULT); - ssr.hdr.flags = PSR_UNICODE; + ssr.psr.cbSize = sizeof(STEAM_SEARCH_RESULT); + ssr.psr.flags = PSR_UNICODE; CMStringW steamId = player["steamid"].as_mstring(); - ssr.hdr.id.w = steamId.Detach(); + ssr.psr.id.w = steamId.Detach(); CMStringW nick = player["personaname"].as_mstring(); - ssr.hdr.nick.w = nick.Detach(); + ssr.psr.nick.w = nick.Detach(); JSONNode node = player["realname"]; - if (!node.isnull()) - { + if (!node.isnull()) { CMStringW realName = node.as_mstring(); - if (!realName.IsEmpty()) - { + if (!realName.IsEmpty()) { int pos = realName.Find(' ', 1); - if (pos != -1) - { - ssr.hdr.firstName.w = realName.Mid(0, pos).Detach(); - ssr.hdr.lastName.w = realName.Mid(pos + 1).Detach(); + if (pos != -1) { + ssr.psr.firstName.w = realName.Mid(0, pos).Detach(); + ssr.psr.lastName.w = realName.Mid(pos + 1).Detach(); } else - ssr.hdr.firstName.w = realName.Detach(); + ssr.psr.firstName.w = realName.Detach(); } } - //ssr.contact = contact; - ssr.data = json_copy(&player); // FIXME: is this needed and safe (no memleak) to be here? + // todo: is this needed and safe (no memleak) to be here? + ssr.data = json_copy(&player); ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, searchType, (LPARAM)&ssr); } @@ -728,17 +749,16 @@ void CSteamProto::OnSearchResults(const HttpResponse &response, void *arg) void CSteamProto::OnSearchByNameStarted(const HttpResponse &response, void *arg) { - if (!response.IsSuccess()) - { + if (!response.IsSuccess()) { ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HANDLE)arg, 0); debugLogA(__FUNCTION__ ": failed to get results"); return; } JSONNode root = JSONNode::parse(response.Content); - if (root.isnull()) - { + if (root.isnull()) { ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HANDLE)arg, 0); + debugLogA(__FUNCTION__ ": no data"); return; } @@ -749,27 +769,22 @@ void CSteamProto::OnSearchByNameStarted(const HttpResponse &response, void *arg) std::string steamIds; JSONNode results = root["results"].as_array(); - for (size_t i = 0; i < results.size(); i++) - { - JSONNode result = results[i]; + for (const JSONNode &result : results) { json_string steamId = result["steamid"].as_string(); steamIds.append(steamId).append(","); } - if (!steamIds.empty()) - { - // remove trailing "," - steamIds.pop_back(); - - ptrA token(getStringA("TokenSecret")); - - PushRequest( - new GetUserSummariesRequest(token, steamIds.c_str()), - &CSteamProto::OnSearchResults, - (HANDLE)arg); - } - else - { + if (steamIds.empty()) { ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)arg, 0); + return; } + + // remove trailing "," + steamIds.pop_back(); + + ptrA token(getStringA("TokenSecret")); + PushRequest( + new GetUserSummariesRequest(token, steamIds.c_str()), + &CSteamProto::OnSearchResults, + (HANDLE)arg); } |