summaryrefslogtreecommitdiff
path: root/protocols/Steam/src
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Steam/src')
-rw-r--r--protocols/Steam/src/api/enums.h30
-rw-r--r--protocols/Steam/src/api/friend_list.h9
-rw-r--r--protocols/Steam/src/main.cpp1
-rw-r--r--protocols/Steam/src/steam_contacts.cpp128
-rw-r--r--protocols/Steam/src/steam_login.cpp3
-rw-r--r--protocols/Steam/src/steam_menus.cpp2
-rw-r--r--protocols/Steam/src/steam_proto.cpp2
-rw-r--r--protocols/Steam/src/steam_proto.h8
8 files changed, 102 insertions, 81 deletions
diff --git a/protocols/Steam/src/api/enums.h b/protocols/Steam/src/api/enums.h
index 2cf767e37f..b93377f5a9 100644
--- a/protocols/Steam/src/api/enums.h
+++ b/protocols/Steam/src/api/enums.h
@@ -1,16 +1,18 @@
#ifndef _STEAM_ENUMS_H_
#define _STEAM_ENUMS_H_
-enum VisibilityState
+enum class FriendRelationship : int
{
- Private = 1,
- FriendsOnly = 2,
- FriendsOfFriends = 3,
- UsersOnly = 4,
- Public = 5,
+ None = 0,
+ Blocked = 1,
+ RequestRecipient = 2,
+ Friend = 3,
+ RequestInitiator = 4,
+ Ignored = 5,
+ IgnoredFriend = 6,
};
-enum PersonaState
+enum class PersonaState : int
{
Offline = 0,
Online = 1,
@@ -64,20 +66,6 @@ inline PersonaStatusFlag operator &(PersonaStatusFlag lhs, PersonaStatusFlag rhs
static_cast<std::underlying_type<PersonaStatusFlag>::type>(rhs));
}
-enum class PersonaRelationshipAction : int
-{
- // friend removed from contact list
- Remove = 0,
- // friend added you to ignore list
- Ignore = 1,
- // friend requested auth
- AuthRequest = 2,
- // friend added you to contact list
- AddToList = 3,
- // friend got (or approved?) your auth request
- AuthRequested = 4,
-};
-
template<typename T>
bool contains_flag(T x, T y) {
return (static_cast<typename std::underlying_type<T>::type>(x)
diff --git a/protocols/Steam/src/api/friend_list.h b/protocols/Steam/src/api/friend_list.h
index 8c9d26a91a..407f33cf38 100644
--- a/protocols/Steam/src/api/friend_list.h
+++ b/protocols/Steam/src/api/friend_list.h
@@ -1,15 +1,6 @@
#ifndef _STEAM_REQUEST_FRIEND_LIST_H_
#define _STEAM_REQUEST_FRIEND_LIST_H_
-struct GetFriendListRequest : public HttpRequest
-{
- GetFriendListRequest(const char *token, int64_t steamId, const char *relationship) :
- HttpRequest(REQUEST_GET, "/ISteamUserOAuth/GetFriendList/v0001")
- {
- this << CHAR_PARAM("access_token", token) << INT64_PARAM("steamid", steamId) << CHAR_PARAM("relationship", relationship);
- }
-};
-
struct AddFriendRequest : public HttpRequest
{
AddFriendRequest(const char *token, const char *sessionId, int64_t steamId, const char *who) :
diff --git a/protocols/Steam/src/main.cpp b/protocols/Steam/src/main.cpp
index efb35cb945..0ee4bae20e 100644
--- a/protocols/Steam/src/main.cpp
+++ b/protocols/Steam/src/main.cpp
@@ -140,6 +140,7 @@ void CMPlugin::InitSteamServices()
// message handlers
messageHandlers[EMsg::ClientLoggedOff] = ServiceResponseHandler(&CSteamProto::OnClientLogoff);
messageHandlers[EMsg::ClientLogOnResponse] = ServiceResponseHandler(&CSteamProto::OnClientLogon);
+ messageHandlers[EMsg::ClientFriendsList] = ServiceResponseHandler(&CSteamProto::OnGotFriendList);
// services from steammessages_auth.steamclient.proto
services["Authentication"] = &authentication__descriptor;
diff --git a/protocols/Steam/src/steam_contacts.cpp b/protocols/Steam/src/steam_contacts.cpp
index aee8c56574..9cbcd9883c 100644
--- a/protocols/Steam/src/steam_contacts.cpp
+++ b/protocols/Steam/src/steam_contacts.cpp
@@ -72,6 +72,15 @@ MCONTACT CSteamProto::GetContact(const char *steamId)
return NULL;
}
+MCONTACT CSteamProto::GetContact(int64_t steamId)
+{
+ for (auto &hContact : AccContacts())
+ if (GetId(hContact, DBKEY_STEAM_ID) == steamId)
+ return hContact;
+
+ return NULL;
+}
+
void CSteamProto::UpdateContactDetails(MCONTACT hContact, const JSONNode &data)
{
// set common data
@@ -351,19 +360,57 @@ MCONTACT CSteamProto::AddContact(const char *steamId, const wchar_t *nick, bool
return hContact;
}
-void CSteamProto::UpdateContactRelationship(MCONTACT hContact, const JSONNode &data)
+MCONTACT CSteamProto::AddContact(int64_t steamId, const wchar_t *nick, bool isTemporary)
{
- const JSONNode &node = data["friend_since"];
- if (node)
- db_set_dw(hContact, "UserInfo", "ContactAddTime", node.as_int());
+ mir_cslock lock(m_addContactLock);
+
+ if (!steamId) {
+ debugLogA(__FUNCTION__ ": empty steam id");
+ return NULL;
+ }
+
+ MCONTACT hContact = GetContact(steamId);
+ if (hContact)
+ return hContact;
+
+ // create contact
+ hContact = db_add_contact();
+ Proto_AddToContact(hContact, m_szModuleName);
+
+ SetId(hContact, DBKEY_STEAM_ID, steamId);
+ if (mir_wstrlen(nick)) {
+ setWString(hContact, "Nick", nick);
+ db_set_ws(hContact, "CList", "MyHandle", nick);
+ }
+
+ if (isTemporary) {
+ debugLogA("Contact %d added as a temporary one");
+ Contact::RemoveFromList(hContact);
+ }
+
+ setByte(hContact, "Auth", 1);
+
+ // move to default group
+ if (!Clist_GroupExists(m_wszGroupName))
+ Clist_GroupCreate(0, m_wszGroupName);
+ Clist_SetGroup(hContact, m_wszGroupName);
+
+ return hContact;
+}
- json_string relationship = data["relationship"].as_string();
- if (relationship == "friend")
+void CSteamProto::UpdateContactRelationship(MCONTACT hContact, FriendRelationship iRelationType)
+{
+ switch (iRelationType) {
+ case FriendRelationship::Friend:
ContactIsFriend(hContact);
- else if (relationship == "ignoredfriend")
+ break;
+ case FriendRelationship::IgnoredFriend:
ContactIsBlocked(hContact);
- else if (relationship == "requestrecipient")
+ break;
+ case FriendRelationship::RequestRecipient:
ContactIsAskingAuth(hContact);
+ break;
+ }
}
void CSteamProto::OnGotAppInfo(const JSONNode &root, void *arg)
@@ -380,48 +427,45 @@ void CSteamProto::OnGotAppInfo(const JSONNode &root, void *arg)
}
}
-void CSteamProto::OnGotFriendList(const JSONNode &root, void *)
+void CSteamProto::OnGotFriendList(const CMsgClientFriendsList &reply, const CMsgProtoBufHeader &hdr)
{
- if (root.isnull())
+ if (hdr.failed())
return;
- // Comma-separated list of steam ids to update summaries
- std::string steamIds = (char *)ptrA(getStringA(DBKEY_STEAM_ID));
-
- // Remember contacts on server
- std::map<json_string, const JSONNode*> friendsMap;
- for (auto &_friend : root["friends"]) {
- json_string steamId = _friend["steamid"].as_string();
- friendsMap.insert(std::make_pair(steamId, &_friend));
- }
-
- if (friendsMap.empty()) {
+ if (reply.n_friends == 0) {
debugLogA("Empty friends list, exiting");
return;
}
+ std::map<uint64_t, FriendRelationship> friendsMap;
+ for (int i = 0; i < reply.n_friends; i++) {
+ auto *F = reply.friends[i];
+ friendsMap[F->ulfriendid | 0x110000100000000ll] = FriendRelationship(F->efriendrelationship);
+ }
+
+ // Comma-separated list of steam ids to update summaries
+ CMStringA steamIds = getMStringA(DBKEY_STEAM_ID);
+
// Check and update contacts in database
for (auto &hContact : AccContacts()) {
- ptrA steamId(getStringA(hContact, DBKEY_STEAM_ID));
- if (steamId == nullptr)
+ int64_t steamId(GetId(hContact, DBKEY_STEAM_ID));
+ if (!steamId)
continue;
- auto it = friendsMap.find((char *)steamId);
+ // Contact was removed from server-list, notify it
+ auto it = friendsMap.find(steamId);
if (it == friendsMap.end()) {
- // Contact was removed from server-list, notify it
- ContactIsRemoved(hContact);
+ if (!reply.bincremental)
+ ContactIsRemoved(hContact);
continue;
}
- const JSONNode &_friend = *it->second;
-
// Contact is on server-list, update (and eventually notify) it
- UpdateContactRelationship(hContact, _friend);
+ UpdateContactRelationship(hContact, it->second);
// Do not update summary for non friends
- json_string relationship = _friend["relationship"].as_string();
- if (relationship == "friend")
- steamIds.append(",").append(it->first);
+ if (it->second == FriendRelationship::Friend)
+ steamIds.AppendFormat(",%lld", it->first);
friendsMap.erase(it);
}
@@ -429,19 +473,15 @@ void CSteamProto::OnGotFriendList(const JSONNode &root, void *)
// Check remaining contacts in map and add them to contact list
for (auto it : friendsMap) {
// Contact is on server-list, but not in database, add (but not notify) it
- const JSONNode &_friend = *it.second;
-
- json_string relationship = _friend["relationship"].as_string();
-
- MCONTACT hContact = AddContact(it.first.c_str(), nullptr, relationship != "friend");
- UpdateContactRelationship(hContact, _friend);
+ MCONTACT hContact = AddContact(it.first, nullptr, it.second != FriendRelationship::Friend);
+ UpdateContactRelationship(hContact, it.second);
- if (relationship == "friend")
- steamIds.append(",").append(it.first);
+ if (it.second == FriendRelationship::Friend)
+ steamIds.AppendFormat(",%lld", it.first);
}
friendsMap.clear();
- if (!steamIds.empty())
+ if (!steamIds.IsEmpty())
SendRequest(new GetUserSummariesRequest(m_szAccessToken, steamIds.c_str()), &CSteamProto::OnGotUserSummaries);
// Load last conversations
@@ -572,7 +612,7 @@ void CSteamProto::OnFriendBlocked(const MHttpResponse &response, void *arg)
return;
}
- MCONTACT hContact = GetContact(steamId);
+ MCONTACT hContact = GetContact(steamId.get());
if (hContact)
ContactIsBlocked(hContact);
}
@@ -586,7 +626,7 @@ void CSteamProto::OnFriendUnblocked(const MHttpResponse &response, void *arg)
return;
}
- MCONTACT hContact = GetContact(steamId);
+ MCONTACT hContact = GetContact(steamId.get());
if (hContact)
ContactIsUnblocked(hContact);
}
@@ -600,7 +640,7 @@ void CSteamProto::OnFriendRemoved(const MHttpResponse &response, void *arg)
return;
}
- MCONTACT hContact = GetContact(steamId);
+ MCONTACT hContact = GetContact(steamId.get());
if (hContact)
ContactIsRemoved(hContact);
}
diff --git a/protocols/Steam/src/steam_login.cpp b/protocols/Steam/src/steam_login.cpp
index 30b773b7db..558a3eddef 100644
--- a/protocols/Steam/src/steam_login.cpp
+++ b/protocols/Steam/src/steam_login.cpp
@@ -265,9 +265,6 @@ void CSteamProto::OnClientLogon(const CMsgClientLogonResponse &reply, const CMsg
// go to online now
ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, m_iStatus = m_iDesiredStatus);
-
- // load contact list
- SendRequest(new GetFriendListRequest(m_szAccessToken, m_iSteamId, "friend,ignoredfriend,requestrecipient"), &CSteamProto::OnGotFriendList);
}
void CSteamProto::OnClientLogoff(const CMsgClientLoggedOff &reply, const CMsgProtoBufHeader&)
diff --git a/protocols/Steam/src/steam_menus.cpp b/protocols/Steam/src/steam_menus.cpp
index 44862a52a8..ddd35fb8a8 100644
--- a/protocols/Steam/src/steam_menus.cpp
+++ b/protocols/Steam/src/steam_menus.cpp
@@ -51,7 +51,7 @@ int CSteamProto::JoinToGameCommand(WPARAM hContact, LPARAM)
INT_PTR CSteamProto::OpenBlockListCommand(WPARAM, LPARAM)
{
- SendRequest(new GetFriendListRequest(m_szAccessToken, m_iSteamId, "ignoredfriend"), &CSteamProto::OnGotBlockList);
+ // SendRequest(new GetFriendListRequest(m_szAccessToken, m_iSteamId, "ignoredfriend"), &CSteamProto::OnGotBlockList);
return 0;
}
diff --git a/protocols/Steam/src/steam_proto.cpp b/protocols/Steam/src/steam_proto.cpp
index 9a34e24c4f..00f9579cdb 100644
--- a/protocols/Steam/src/steam_proto.cpp
+++ b/protocols/Steam/src/steam_proto.cpp
@@ -86,7 +86,7 @@ CSteamProto::~CSteamProto()
MCONTACT CSteamProto::AddToList(int, PROTOSEARCHRESULT *psr)
{
- MCONTACT hContact = AddContact(T2Utf(psr->id.w), psr->nick.w, true);
+ MCONTACT hContact = AddContact(_wtoi64(psr->id.w), psr->nick.w, true);
if (psr->cbSize == sizeof(STEAM_SEARCH_RESULT)) {
STEAM_SEARCH_RESULT *ssr = (STEAM_SEARCH_RESULT *)psr;
diff --git a/protocols/Steam/src/steam_proto.h b/protocols/Steam/src/steam_proto.h
index 5453485a95..7c6b7373ea 100644
--- a/protocols/Steam/src/steam_proto.h
+++ b/protocols/Steam/src/steam_proto.h
@@ -180,7 +180,7 @@ class CSteamProto : public PROTO<CSteamProto>
MCONTACT GetContactFromAuthEvent(MEVENT hEvent);
void UpdateContactDetails(MCONTACT hContact, const JSONNode &data);
- void UpdateContactRelationship(MCONTACT hContact, const JSONNode &data);
+ void UpdateContactRelationship(MCONTACT hContact, FriendRelationship);
void OnGotAppInfo(const JSONNode &root, void *arg);
void ContactIsRemoved(MCONTACT hContact);
@@ -189,10 +189,14 @@ class CSteamProto : public PROTO<CSteamProto>
void ContactIsUnblocked(MCONTACT hContact);
void ContactIsAskingAuth(MCONTACT hContact);
+ void OnGotFriendList(const CMsgClientFriendsList &reply, const CMsgProtoBufHeader &hdr);
+
MCONTACT GetContact(const char *steamId);
MCONTACT AddContact(const char *steamId, const wchar_t *nick = nullptr, bool isTemporary = false);
- void OnGotFriendList(const JSONNode &root, void *);
+ MCONTACT GetContact(int64_t steamId);
+ MCONTACT AddContact(int64_t steamId, const wchar_t *nick = nullptr, bool isTemporary = false);
+
void OnGotBlockList(const JSONNode &root, void *);
void OnGotUserSummaries(const JSONNode &root, void *);
void OnGotAvatar(const MHttpResponse &response, void *arg);