diff options
| author | George Hazan <george.hazan@gmail.com> | 2024-12-17 23:24:44 +0300 |
|---|---|---|
| committer | George Hazan <george.hazan@gmail.com> | 2024-12-17 23:24:44 +0300 |
| commit | 4c3d77032316bc8814cddc00d020ba00d4533999 (patch) | |
| tree | 1862e30966a69bf94a7288b95baed5b04a040d80 /protocols | |
| parent | 4b5082aef3817173bc254755c0ec352da064a440 (diff) | |
Steam:
- contact statuses are back;
- contact info is back too;
- Miranda's account status is passed to the server;
- some old code removed;
Diffstat (limited to 'protocols')
| -rw-r--r-- | protocols/Steam/src/main.cpp | 2 | ||||
| -rw-r--r-- | protocols/Steam/src/protobuf-c/protobuf-c-text.cpp | 9 | ||||
| -rw-r--r-- | protocols/Steam/src/stdafx.h | 6 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_avatars.cpp | 17 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_contacts.cpp | 295 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_login.cpp | 4 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_messages.cpp | 67 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_proto.cpp | 10 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_proto.h | 23 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_server.cpp | 68 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_utils.cpp | 14 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_utils.h | 18 | ||||
| -rw-r--r-- | protocols/Steam/src/steam_ws.cpp | 2 |
13 files changed, 264 insertions, 271 deletions
diff --git a/protocols/Steam/src/main.cpp b/protocols/Steam/src/main.cpp index 9e69376684..fcb3b1b9d9 100644 --- a/protocols/Steam/src/main.cpp +++ b/protocols/Steam/src/main.cpp @@ -138,6 +138,7 @@ void CMPlugin::InitSteamServices() messageHandlers[EMsg::ClientLoggedOff] = ServiceResponseHandler(&CSteamProto::OnClientLogoff);
messageHandlers[EMsg::ClientLogOnResponse] = ServiceResponseHandler(&CSteamProto::OnClientLogon);
messageHandlers[EMsg::ClientFriendsList] = ServiceResponseHandler(&CSteamProto::OnGotFriendList);
+ messageHandlers[EMsg::ClientPersonaState] = ServiceResponseHandler(&CSteamProto::OnGotFriendInfo);
// services from steammessages_auth.steamclient.proto
services["Authentication"] = &authentication__descriptor;
@@ -163,6 +164,7 @@ void CMPlugin::InitSteamServices() serviceHandlers[FriendSendMessage] = ServiceResponseHandler(&CSteamProto::OnMessageSent);
serviceHandlers[FriendGetActiveSessions] = ServiceResponseHandler(&CSteamProto::OnGotConversations);
+ serviceHandlers[FriendGetIncomingMessage] = ServiceResponseHandler(&CSteamProto::OnGotIncomingMessage);
serviceHandlers[NotificationReceived] = ServiceResponseHandler(&CSteamProto::OnGotNotification);
}
diff --git a/protocols/Steam/src/protobuf-c/protobuf-c-text.cpp b/protocols/Steam/src/protobuf-c/protobuf-c-text.cpp index 68e54f143e..44fa0b7232 100644 --- a/protocols/Steam/src/protobuf-c/protobuf-c-text.cpp +++ b/protocols/Steam/src/protobuf-c/protobuf-c-text.cpp @@ -60,7 +60,7 @@ esc_str(const char *src, size_t len) } } - char *dst = (char *)malloc((escapes * 4) + ((len - escapes) * 2) + 1); + char *dst = (char *)malloc((escapes * 2) + ((len - escapes) * 2) + 1); if (!dst) { return NULL; } @@ -95,12 +95,7 @@ esc_str(const char *src, size_t len) /* Escape with octal if !isprint. */ default: - if (!isprint(src[i])) { - dst_len += sprintf(dst + dst_len, "\\%03o", src[i]); - } - else { - dst[dst_len++] = src[i]; - } + dst[dst_len++] = src[i]; break; } } diff --git a/protocols/Steam/src/stdafx.h b/protocols/Steam/src/stdafx.h index 87d0bbeace..ff762f0d39 100644 --- a/protocols/Steam/src/stdafx.h +++ b/protocols/Steam/src/stdafx.h @@ -68,15 +68,11 @@ extern HANDLE hExtraXStatus; #define STEAM_DB_GETEVENTTEXT_CHATSTATES "/GetEventText2000"
#define STEAM_DB_EVENT_CHATSTATES_GONE 1
-#define now() time(0)
-
-int64_t getRandomInt();
-CMStringA protobuf_c_text_to_string(const ProtobufCMessage &msg);
-
#include "steam_dialogs.h"
#include "api/enums.h"
#include "steam_proto.h"
+#include "steam_utils.h"
#include "api/app_info.h"
#include "api/avatar.h"
diff --git a/protocols/Steam/src/steam_avatars.cpp b/protocols/Steam/src/steam_avatars.cpp index 2a7de109ca..022ec914c5 100644 --- a/protocols/Steam/src/steam_avatars.cpp +++ b/protocols/Steam/src/steam_avatars.cpp @@ -23,17 +23,18 @@ bool CSteamProto::GetDbAvatarInfo(PROTO_AVATAR_INFORMATION &pai) return true;
}
-void CSteamProto::CheckAvatarChange(MCONTACT hContact, std::string avatarUrl)
+void CSteamProto::CheckAvatarChange(MCONTACT hContact, const char *avatarHash)
{
- if (avatarUrl.empty())
- return;
-
// Check for avatar change
- ptrA oldAvatarUrl(getStringA(hContact, "AvatarUrl"));
- bool update_required = (!oldAvatarUrl || avatarUrl.compare(oldAvatarUrl));
+ ptrA oldAvatarHash(getStringA(hContact, "AvatarHash"));
+ bool update_required = mir_strcmp(oldAvatarHash, avatarHash) != 0;
- if (update_required)
- setString(hContact, "AvatarUrl", avatarUrl.c_str());
+ if (update_required) {
+ if (avatarHash)
+ setString(hContact, "AvatarHash", avatarHash);
+ else
+ delSetting(hContact, "AvatarHash");
+ }
if (!hContact) {
PROTO_AVATAR_INFORMATION ai = { 0 };
diff --git a/protocols/Steam/src/steam_contacts.cpp b/protocols/Steam/src/steam_contacts.cpp index dddca89631..9291629968 100644 --- a/protocols/Steam/src/steam_contacts.cpp +++ b/protocols/Steam/src/steam_contacts.cpp @@ -81,166 +81,134 @@ MCONTACT CSteamProto::GetContact(int64_t steamId) return NULL; } -void CSteamProto::UpdateContactDetails(MCONTACT hContact, const JSONNode &data) +void CSteamProto::OnGotFriendInfo(const CMsgClientPersonaState &reply, const CMsgProtoBufHeader &) { - // set common data - CMStringW nick = data["personaname"].as_mstring(); - setWString(hContact, "Nick", nick); - - json_string homepage = data["profileurl"].as_string(); - setString(hContact, "Homepage", homepage.c_str()); - - json_string primaryClanId = data["primaryclanid"].as_string(); - setString(hContact, "PrimaryClanID", primaryClanId.c_str()); - - // set name - const JSONNode &node = data["realname"]; - if (node) { - CMStringW realName = node.as_mstring(); - if (!realName.IsEmpty()) { - int pos = realName.Find(L' ', 1); - if (pos != -1) { - setWString(hContact, "FirstName", realName.Mid(0, pos)); - setWString(hContact, "LastName", realName.Mid(pos + 1)); - } - else { - setWString(hContact, "FirstName", realName); - delSetting(hContact, "LastName"); - } - } - } - else { - delSetting(hContact, "FirstName"); - delSetting(hContact, "LastName"); - } - - // avatar - bool biggerAvatars = getBool("UseBigAvatars", false); - json_string avatarUrl = data[biggerAvatars ? "avatarfull" : "avatarmedium"].as_string(); - CheckAvatarChange(hContact, avatarUrl); - - // set country - json_string countryCode = data["loccountrycode"].as_string(); - if (!countryCode.empty()) { - char *country = (char *)CallService(MS_UTILS_GETCOUNTRYBYISOCODE, (WPARAM)countryCode.c_str(), 0); - setString(hContact, "Country", country); - } - else delSetting(hContact, "Country"); - - // state code - // 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 - // 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 - setDword(hContact, "MemberTS", data["timecreated"].as_int()); - - // last logout time - setDword(hContact, "LogoffTS", data["lastlogoff"].as_int()); - - if (!IsOnline()) - return; - - // status - // note: this here is often wrong info, probably depending on publicity of steam profile - // but sometimes polling does not get status at all - uint16_t oldStatus = getWord(hContact, "Status", ID_STATUS_OFFLINE); - // so, set status only if contact is offline - if (oldStatus == ID_STATUS_OFFLINE) { - uint16_t status = SteamToMirandaStatus((PersonaState)data["personastate"].as_int()); - SetContactStatus(hContact, status); - } + for (int i = 0; i < reply.n_friends; i++) { + auto *F = reply.friends[i]; - // client - const JSONNode &nFlags = data["personastateflags"]; - PersonaStateFlag stateflags = (nFlags) ? (PersonaStateFlag)nFlags.as_int() : (PersonaStateFlag)(-1); + auto hContact = GetContact(F->friendid); + if (!hContact && F->friendid != m_iSteamId) + hContact = AddContact(F->friendid); - if (stateflags == PersonaStateFlag::None) { - // nothing special, either standard client or in different status (only online, I want to play, I want to trade statuses support this flags) - uint16_t status = getWord(hContact, "Status", ID_STATUS_OFFLINE); - if (status == ID_STATUS_ONLINE || status == ID_STATUS_FREECHAT) - setWString(hContact, "MirVer", L"Steam"); - } - else if (contains_flag(stateflags, PersonaStateFlag::InJoinableGame)) { - // game - setWString(hContact, "MirVer", L"Steam (in game)"); - } - else if (contains_flag(stateflags, PersonaStateFlag::ClientTypeWeb)) { - // on website - setWString(hContact, "MirVer", L"Steam (website)"); - } - else if (contains_flag(stateflags, PersonaStateFlag::ClientTypeMobile)) { - // on mobile - setWString(hContact, "MirVer", L"Steam (mobile)"); - } - else if (contains_flag(stateflags, PersonaStateFlag::ClientTypeBigPicture)) { - // on big picture - setWString(hContact, "MirVer", L"Steam (Big Picture)"); - } - else if (contains_flag(stateflags, PersonaStateFlag::ClientTypeVR)) { - // on VR - setWString(hContact, "MirVer", L"Steam (VR)"); - } - else { - // none/unknown (e.g. when contact is offline) - delSetting(hContact, "MirVer"); - } + // set name + if (F->player_name) { + CMStringW realName(Utf2T(F->player_name)); + if (!realName.IsEmpty()) { + int pos = realName.Find(L' ', 1); + if (pos != -1) { + setWString(hContact, "FirstName", realName.Mid(0, pos)); + setWString(hContact, "LastName", realName.Mid(pos + 1)); + } + else { + setWString(hContact, "FirstName", realName); + delSetting(hContact, "LastName"); + } + } + } + else { + delSetting(hContact, "FirstName"); + delSetting(hContact, "LastName"); + } - // playing game - json_string appId = data["gameid"].as_string(); - CMStringW gameInfo = data["gameextrainfo"].as_mstring(); - if (!appId.empty() || !gameInfo.IsEmpty()) { - uint32_t gameId = atol(appId.c_str()); - json_string serverIP = data["gameserverip"].as_string(); - json_string serverID = data["gameserversteamid"].as_string(); + // avatar + if (F->avatar_hash.len != 0) { + CMStringA szHash; + szHash.Truncate(int(F->avatar_hash.len) * 2 + 1); + bin2hex(F->avatar_hash.data, F->avatar_hash.len, szHash.GetBuffer()); + CheckAvatarChange(hContact, szHash); + } + else CheckAvatarChange(hContact, 0); + + // last logout time + if (F->has_last_logoff) + setDword(hContact, "LogoffTS", F->last_logoff); + if (F->has_last_logon) + setDword(hContact, "LogonTS", F->last_logon); + + // status + // note: this here is often wrong info, probably depending on publicity of steam profile + // but sometimes polling does not get status at all + int oldStatus = Contact::GetStatus(hContact); + // so, set status only if contact is offline + if (oldStatus == ID_STATUS_OFFLINE) { + uint16_t status = SteamToMirandaStatus(PersonaState(F->persona_state)); + SetContactStatus(hContact, status); + } - setDword(hContact, "GameID", gameId); - setString(hContact, "ServerIP", serverIP.c_str()); - setString(hContact, "ServerID", serverID.c_str()); + // client + PersonaStateFlag stateflags = (F->has_persona_state_flags) ? (PersonaStateFlag)(F->persona_state_flags) : (PersonaStateFlag)(-1); - CMStringW message(gameInfo); - if (gameId && message.IsEmpty()) - SendRequest(new GetAppInfoRequest(m_szAccessToken, appId.c_str()), &CSteamProto::OnGotAppInfo, (void*)hContact); + if (stateflags == PersonaStateFlag::None) { + // nothing special, either standard client or in different status (only online, I want to play, I want to trade statuses support this flags) + uint16_t status = getWord(hContact, "Status", ID_STATUS_OFFLINE); + if (status == ID_STATUS_ONLINE || status == ID_STATUS_FREECHAT) + setWString(hContact, "MirVer", L"Steam"); + } + else if (contains_flag(stateflags, PersonaStateFlag::InJoinableGame)) { + // game + setWString(hContact, "MirVer", L"Steam (in game)"); + } + else if (contains_flag(stateflags, PersonaStateFlag::ClientTypeWeb)) { + // on website + setWString(hContact, "MirVer", L"Steam (website)"); + } + else if (contains_flag(stateflags, PersonaStateFlag::ClientTypeMobile)) { + // on mobile + setWString(hContact, "MirVer", L"Steam (mobile)"); + } + else if (contains_flag(stateflags, PersonaStateFlag::ClientTypeBigPicture)) { + // on big picture + setWString(hContact, "MirVer", L"Steam (Big Picture)"); + } + else if (contains_flag(stateflags, PersonaStateFlag::ClientTypeVR)) { + // on VR + setWString(hContact, "MirVer", L"Steam (VR)"); + } else { - if (!gameId) - message.Append(TranslateT(" (Non-Steam)")); - if (!serverIP.empty()) - message.AppendFormat(TranslateT(" on server %S"), serverIP.c_str()); + // none/unknown (e.g. when contact is offline) + delSetting(hContact, "MirVer"); } - setDword(hContact, "XStatusId", gameId); - setWString(hContact, "XStatusName", TranslateT("Playing")); - setWString(hContact, "XStatusMsg", message); + // playing game + /* + json_string appId = data["gameid"].as_string(); + CMStringW gameInfo = data["gameextrainfo"].as_mstring(); + if (!appId.empty() || !gameInfo.IsEmpty()) { + uint32_t gameId = atol(appId.c_str()); + json_string serverIP = data["gameserverip"].as_string(); + json_string serverID = data["gameserversteamid"].as_string(); + + setDword(hContact, "GameID", gameId); + setString(hContact, "ServerIP", serverIP.c_str()); + setString(hContact, "ServerID", serverID.c_str()); + + CMStringW message(gameInfo); + if (gameId && message.IsEmpty()) + SendRequest(new GetAppInfoRequest(m_szAccessToken, appId.c_str()), &CSteamProto::OnGotAppInfo, (void *)hContact); + else { + if (!gameId) + message.Append(TranslateT(" (Non-Steam)")); + if (!serverIP.empty()) + message.AppendFormat(TranslateT(" on server %S"), serverIP.c_str()); + } - SetContactExtraIcon(hContact, gameId); - } - else { - delSetting(hContact, "GameID"); - delSetting(hContact, "ServerIP"); - delSetting(hContact, "ServerID"); + setDword(hContact, "XStatusId", gameId); + setWString(hContact, "XStatusName", TranslateT("Playing")); + setWString(hContact, "XStatusMsg", message); - delSetting(hContact, "XStatusId"); - delSetting(hContact, "XStatusName"); - delSetting(hContact, "XStatusMsg"); + SetContactExtraIcon(hContact, gameId); + } + else {*/ + delSetting(hContact, "GameID"); + delSetting(hContact, "ServerIP"); + delSetting(hContact, "ServerID"); - SetContactExtraIcon(hContact, NULL); + delSetting(hContact, "XStatusId"); + delSetting(hContact, "XStatusName"); + delSetting(hContact, "XStatusMsg"); + + SetContactExtraIcon(hContact, NULL); + // } } } @@ -300,8 +268,11 @@ void CSteamProto::ContactIsAskingAuth(MCONTACT hContact) return; // create auth request event - ptrA steamId(getUStringA(hContact, DBKEY_STEAM_ID)); - SendRequest(new GetUserSummariesRequest(m_szAccessToken, steamId), &CSteamProto::OnGotUserSummaries); + uint64_t id(GetId(hContact, DBKEY_STEAM_ID)); + SendUserInfoRequest(id, true); + + char steamId[100]; + _i64toa(id, steamId, 10); ptrA nickName(getUStringA(hContact, "Nick")); if (nickName == nullptr) @@ -505,16 +476,6 @@ void CSteamProto::OnGotBlockList(const JSONNode &root, void *) } } -void CSteamProto::OnGotUserSummaries(const JSONNode &root, void *) -{ - for (auto &player : root["players"]) { - json_string steamId = player["steamid"].as_string(); - CMStringW nick = player["personaname"].as_mstring(); - MCONTACT hContact = !IsMe(steamId.c_str()) ? AddContact(steamId.c_str(), nick) : 0; - UpdateContactDetails(hContact, player); - } -} - void CSteamProto::OnGotAvatar(const MHttpResponse &response, void *arg) { PROTO_AVATAR_INFORMATION ai = { 0 }; @@ -646,20 +607,6 @@ void CSteamProto::OnFriendRemoved(const MHttpResponse &response, void *arg) ContactIsRemoved(hContact); } -void CSteamProto::OnAuthRequested(const JSONNode &root, void *) -{ - if (root.isnull()) - return; - - for (auto &player : root["players"]) { - 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) { ptrA steamId((char *)arg); diff --git a/protocols/Steam/src/steam_login.cpp b/protocols/Steam/src/steam_login.cpp index e83853c7e5..702e47839a 100644 --- a/protocols/Steam/src/steam_login.cpp +++ b/protocols/Steam/src/steam_login.cpp @@ -17,7 +17,7 @@ bool CSteamProto::IsOnline() bool CSteamProto::IsMe(const char *steamId) { - return m_iSteamId == _atoi64(steamId); + return m_iSteamId == (uint64_t)_atoi64(steamId); } void CSteamProto::Logout() @@ -265,6 +265,8 @@ 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); + + SendPersonaStatus(m_iStatus); } void CSteamProto::OnClientLogoff(const CMsgClientLoggedOff &reply, const CMsgProtoBufHeader&) diff --git a/protocols/Steam/src/steam_messages.cpp b/protocols/Steam/src/steam_messages.cpp index 17da66fbb7..25ccc07800 100644 --- a/protocols/Steam/src/steam_messages.cpp +++ b/protocols/Steam/src/steam_messages.cpp @@ -1,5 +1,72 @@ #include "stdafx.h"
+void CSteamProto::SendFriendMessage(uint32_t msgId, int64_t steamId, const char *pszMessage)
+{
+ CMStringA szId(FORMAT, "%d", msgId);
+
+ CFriendMessagesSendMessageRequest request;
+ request.chat_entry_type = (int)EChatEntryType::ChatMsg; request.has_chat_entry_type = true;
+ request.client_message_id = szId.GetBuffer();
+ request.contains_bbcode = request.has_contains_bbcode = true;
+ request.steamid = steamId; request.has_steamid = true;
+ request.message = (char *)pszMessage;
+
+ auto iSourceId = WSSendService(FriendSendMessage, request);
+ mir_cslock lck(m_csOwnMessages);
+ if (COwnMessage *pOwn = m_arOwnMessages.find((COwnMessage *)&msgId))
+ pOwn->iSourceId = iSourceId;
+}
+
+void CSteamProto::OnMessageSent(const CFriendMessagesSendMessageResponse &reply, const CMsgProtoBufHeader &hdr)
+{
+ COwnMessage tmp(0, 0);
+ {
+ mir_cslock lck(m_csOwnMessages);
+ for (auto &it : m_arOwnMessages)
+ if (it->iSourceId == hdr.jobid_target) {
+ tmp = *it;
+ m_arOwnMessages.remove(m_arOwnMessages.indexOf(&it));
+ break;
+ }
+ }
+
+ if (!tmp.hContact)
+ return;
+
+ if (hdr.failed()) {
+ CMStringW wszMessage(FORMAT, TranslateT("Message sending has failed with error %d"), hdr.eresult);
+ ProtoBroadcastAck(tmp.hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)tmp.iMessageId, (LPARAM)wszMessage.c_str());
+ }
+ else {
+ uint32_t timestamp = (reply.has_server_timestamp) ? reply.server_timestamp : 0;
+ if (timestamp > getDword(tmp.hContact, DB_KEY_LASTMSGTS))
+ setDword(tmp.hContact, DB_KEY_LASTMSGTS, timestamp);
+
+ tmp.timestamp = timestamp;
+ ProtoBroadcastAck(tmp.hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)tmp.iMessageId, 0);
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CSteamProto::OnGotIncomingMessage(const CFriendMessagesIncomingMessageNotification &reply, const CMsgProtoBufHeader &)
+{
+ MCONTACT hContact = GetContact(AccountIdToSteamId(reply.steamid_friend));
+ if (!hContact) {
+ debugLogA("message from unknown account %lld ignored", reply.steamid_friend);
+ return;
+ }
+
+ DB::EventInfo dbei;
+ dbei.flags = DBEF_UTF;
+ dbei.cbBlob = (int)mir_strlen(reply.message);
+ dbei.pBlob = reply.message;
+ dbei.timestamp = reply.has_rtime32_server_timestamp ? reply.rtime32_server_timestamp : time(0);
+ ProtoChainRecvMsg(hContact, dbei);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
int CSteamProto::UserIsTyping(MCONTACT hContact, int type)
{
// NOTE: Steam doesn't support sending "user stopped typing" so we're sending only positive info
diff --git a/protocols/Steam/src/steam_proto.cpp b/protocols/Steam/src/steam_proto.cpp index 00f9579cdb..a6bef00d29 100644 --- a/protocols/Steam/src/steam_proto.cpp +++ b/protocols/Steam/src/steam_proto.cpp @@ -86,12 +86,10 @@ CSteamProto::~CSteamProto() MCONTACT CSteamProto::AddToList(int, PROTOSEARCHRESULT *psr)
{
- MCONTACT hContact = AddContact(_wtoi64(psr->id.w), psr->nick.w, true);
+ uint64_t id = _wtoi64(psr->id.w);
+ MCONTACT hContact = AddContact(id, psr->nick.w, true);
- if (psr->cbSize == sizeof(STEAM_SEARCH_RESULT)) {
- STEAM_SEARCH_RESULT *ssr = (STEAM_SEARCH_RESULT *)psr;
- UpdateContactDetails(hContact, *ssr->data);
- }
+ SendUserInfoRequest(id, true);
return hContact;
}
@@ -280,6 +278,8 @@ int CSteamProto::SetStatus(int new_status) else if (IsOnline()) {
m_iStatus = new_status;
ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);
+
+ SendPersonaStatus(m_iStatus);
}
return 0;
}
diff --git a/protocols/Steam/src/steam_proto.h b/protocols/Steam/src/steam_proto.h index 2d7f1c4b5b..cbf7d6eaba 100644 --- a/protocols/Steam/src/steam_proto.h +++ b/protocols/Steam/src/steam_proto.h @@ -24,6 +24,7 @@ #define FriendSendMessage "FriendMessages.SendMessage#1"
#define FriendGetActiveSessions "FriendMessages.GetActiveMessageSessions#1"
+#define FriendGetIncomingMessage "FriendMessagesClient.IncomingMessage#1"
#define NotificationReceived "SteamNotificationClient.NotificationsReceived#1"
@@ -115,7 +116,7 @@ class CSteamProto : public PROTO<CSteamProto> ptrW m_password;
bool m_bTerminated;
time_t m_idleTS;
- int64_t m_iSteamId, m_iClientId, m_iSessionId;
+ uint64_t m_iSteamId, m_iClientId, m_iSessionId;
MBinBuffer m_requestId;
int64_t GetId(const char *pszSetting);
@@ -152,7 +153,9 @@ class CSteamProto : public PROTO<CSteamProto> void SendHeartBeat();
void SendLogout();
+ void SendPersonaStatus(int iStatus);
void SendPollRequest();
+ void SendUserInfoRequest(uint64_t id, bool bRetrieveState);
void SendUserInfoRequest(const std::vector<uint64_t> &ids, bool bRetrieveState);
// login
@@ -180,7 +183,7 @@ class CSteamProto : public PROTO<CSteamProto> // avatars
wchar_t *GetAvatarFilePath(MCONTACT hContact);
bool GetDbAvatarInfo(PROTO_AVATAR_INFORMATION &pai);
- void CheckAvatarChange(MCONTACT hContact, std::string avatarUrl);
+ void CheckAvatarChange(MCONTACT hContact, const char *avatarHash);
INT_PTR __cdecl GetAvatarInfo(WPARAM, LPARAM);
INT_PTR __cdecl GetAvatarCaps(WPARAM, LPARAM);
@@ -192,7 +195,6 @@ class CSteamProto : public PROTO<CSteamProto> MCONTACT GetContactFromAuthEvent(MEVENT hEvent);
- void UpdateContactDetails(MCONTACT hContact, const JSONNode &data);
void UpdateContactRelationship(MCONTACT hContact, FriendRelationship);
void OnGotAppInfo(const JSONNode &root, void *arg);
@@ -203,6 +205,7 @@ class CSteamProto : public PROTO<CSteamProto> void ContactIsAskingAuth(MCONTACT hContact);
void OnGotFriendList(const CMsgClientFriendsList &reply, const CMsgProtoBufHeader &hdr);
+ void OnGotFriendInfo(const CMsgClientPersonaState &reply, const CMsgProtoBufHeader &hdr);
MCONTACT GetContact(const char *steamId);
MCONTACT AddContact(const char *steamId, const wchar_t *nick = nullptr, bool isTemporary = false);
@@ -211,7 +214,6 @@ class CSteamProto : public PROTO<CSteamProto> 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);
void OnFriendAdded(const MHttpResponse &response, void *arg);
@@ -219,8 +221,6 @@ class CSteamProto : public PROTO<CSteamProto> void OnFriendUnblocked(const MHttpResponse &response, void *arg);
void OnFriendRemoved(const MHttpResponse &response, void *arg);
- void OnAuthRequested(const JSONNode &root, void *arg);
-
void OnPendingApproved(const JSONNode &root, void *arg);
void OnPendingIgnoreded(const JSONNode &root, void *arg);
@@ -257,6 +257,7 @@ class CSteamProto : public PROTO<CSteamProto> OBJLIST<COwnMessage> m_arOwnMessages;
void SendFriendMessage(uint32_t msgId, int64_t steamId, const char *pszMessage);
+ void OnGotIncomingMessage(const CFriendMessagesIncomingMessageNotification &reply, const CMsgProtoBufHeader &hdr);
void OnMessageSent(const CFriendMessagesSendMessageResponse &reply, const CMsgProtoBufHeader &hdr);
int __cdecl OnPreCreateMessage(WPARAM, LPARAM lParam);
@@ -275,13 +276,6 @@ class CSteamProto : public PROTO<CSteamProto> int __cdecl OnIdleChanged(WPARAM, LPARAM);
int __cdecl OnOptionsInit(WPARAM wParam, LPARAM lParam);
- // utils
- static uint16_t SteamToMirandaStatus(PersonaState state);
- static PersonaState MirandaToSteamState(int status);
-
- static void ShowNotification(const wchar_t *message, int flags = 0, MCONTACT hContact = NULL);
- static void ShowNotification(const wchar_t *caption, const wchar_t *message, int flags = 0, MCONTACT hContact = NULL);
-
INT_PTR __cdecl OnGetEventTextChatStates(WPARAM wParam, LPARAM lParam);
// helpers
@@ -372,7 +366,4 @@ struct CMPlugin : public ACCPROTOPLUGIN<CSteamProto> int OnReloadIcons(WPARAM wParam, LPARAM lParam);
void SetContactExtraIcon(MCONTACT hContact, int status);
-MBinBuffer RsaEncrypt(const char *pszModulus, const char *exponent, const char *data);
-MBinBuffer createMachineID(const char *accName);
-
#endif //_STEAM_PROTO_H_
diff --git a/protocols/Steam/src/steam_server.cpp b/protocols/Steam/src/steam_server.cpp index f7330dbc49..061c2ec6c2 100644 --- a/protocols/Steam/src/steam_server.cpp +++ b/protocols/Steam/src/steam_server.cpp @@ -17,55 +17,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "stdafx.h" -void CSteamProto::SendFriendMessage(uint32_t msgId, int64_t steamId, const char *pszMessage) -{ - CMStringA szId(FORMAT, "%d", msgId); - - CFriendMessagesSendMessageRequest request; - request.chat_entry_type = (int)EChatEntryType::ChatMsg; request.has_chat_entry_type = true; - request.client_message_id = szId.GetBuffer(); - request.contains_bbcode = request.has_contains_bbcode = true; - request.steamid = steamId; request.has_steamid = true; - request.message = (char *)pszMessage; - - auto iSourceId = WSSendService(FriendSendMessage, request); - mir_cslock lck(m_csOwnMessages); - if (COwnMessage *pOwn = m_arOwnMessages.find((COwnMessage *)&msgId)) - pOwn->iSourceId = iSourceId; -} - -void CSteamProto::OnMessageSent(const CFriendMessagesSendMessageResponse &reply, const CMsgProtoBufHeader &hdr) -{ - COwnMessage tmp(0, 0); - { - mir_cslock lck(m_csOwnMessages); - for (auto &it : m_arOwnMessages) - if (it->iSourceId == hdr.jobid_target) { - tmp = *it; - m_arOwnMessages.remove(m_arOwnMessages.indexOf(&it)); - break; - } - } - - if (!tmp.hContact) - return; - - if (hdr.failed()) { - CMStringW wszMessage(FORMAT, TranslateT("Message sending has failed with error %d"), hdr.eresult); - ProtoBroadcastAck(tmp.hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)tmp.iMessageId, (LPARAM)wszMessage.c_str()); - } - else { - uint32_t timestamp = (reply.has_server_timestamp) ? reply.server_timestamp : 0; - if (timestamp > getDword(tmp.hContact, DB_KEY_LASTMSGTS)) - setDword(tmp.hContact, DB_KEY_LASTMSGTS, timestamp); - - tmp.timestamp = timestamp; - ProtoBroadcastAck(tmp.hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)tmp.iMessageId, 0); - } -} - -///////////////////////////////////////////////////////////////////////////////////////// - void CSteamProto::OnGotNotification(const CSteamNotificationNotificationsReceivedNotification &reply, const CMsgProtoBufHeader &hdr) { if (hdr.eresult != 1) @@ -81,15 +32,32 @@ void CSteamProto::OnGotNotification(const CSteamNotificationNotificationsReceive ///////////////////////////////////////////////////////////////////////////////////////// +void CSteamProto::SendPersonaStatus(int status) +{ + CMsgClientChangeStatus request; + request.persona_state = (int)MirandaToSteamState(status); request.has_persona_state = true; + WSSend(EMsg::ClientChangeStatus, request); +} + +///////////////////////////////////////////////////////////////////////////////////////// + void CSteamProto::SendFriendActiveSessions() { CFriendsMessagesGetActiveMessageSessionsRequest request; - request.has_only_sessions_with_messages = request.only_sessions_with_messages = true; + request.has_lastmessage_since = true; + request.has_only_sessions_with_messages = false; request.only_sessions_with_messages = true; WSSendService(FriendGetActiveSessions, request); } ///////////////////////////////////////////////////////////////////////////////////////// +void CSteamProto::SendUserInfoRequest(uint64_t id, bool bRetrieveState) +{ + std::vector<uint64_t> ids; + ids.push_back(id & 0xFFFFFFFFll); + SendUserInfoRequest(ids, bRetrieveState); +} + void CSteamProto::SendUserInfoRequest(const std::vector<uint64_t> &ids, bool bRetrieveState) { CMsgClientRequestFriendData request; diff --git a/protocols/Steam/src/steam_utils.cpp b/protocols/Steam/src/steam_utils.cpp index ebc3c2b6f8..912f84318f 100644 --- a/protocols/Steam/src/steam_utils.cpp +++ b/protocols/Steam/src/steam_utils.cpp @@ -75,8 +75,9 @@ void CSteamProto::SetId(const char *pszSetting, int64_t id) }
/////////////////////////////////////////////////////////////////////////////////////////
+// Statuses
-uint16_t CSteamProto::SteamToMirandaStatus(PersonaState state)
+int SteamToMirandaStatus(PersonaState state)
{
switch (state) {
case PersonaState::Offline:
@@ -99,7 +100,7 @@ uint16_t CSteamProto::SteamToMirandaStatus(PersonaState state) }
}
-PersonaState CSteamProto::MirandaToSteamState(int status)
+PersonaState MirandaToSteamState(int status)
{
switch (status) {
case ID_STATUS_OFFLINE:
@@ -121,7 +122,10 @@ PersonaState CSteamProto::MirandaToSteamState(int status) }
}
-void CSteamProto::ShowNotification(const wchar_t *caption, const wchar_t *message, int flags, MCONTACT hContact)
+/////////////////////////////////////////////////////////////////////////////////////////
+// Popups
+
+void ShowNotification(const wchar_t *caption, const wchar_t *message, int flags, MCONTACT hContact)
{
if (Miranda_IsTerminated())
return;
@@ -140,11 +144,13 @@ void CSteamProto::ShowNotification(const wchar_t *caption, const wchar_t *messag MessageBox(nullptr, message, caption, MB_OK | flags);
}
-void CSteamProto::ShowNotification(const wchar_t *message, int flags, MCONTACT hContact)
+void ShowNotification(const wchar_t *message, int flags, MCONTACT hContact)
{
ShowNotification(_A2W(MODULE), message, flags, hContact);
}
+/////////////////////////////////////////////////////////////////////////////////////////
+
INT_PTR CSteamProto::OnGetEventTextChatStates(WPARAM pEvent, LPARAM datatype)
{
// Retrieves a chat state description from an event
diff --git a/protocols/Steam/src/steam_utils.h b/protocols/Steam/src/steam_utils.h new file mode 100644 index 0000000000..40cdd07088 --- /dev/null +++ b/protocols/Steam/src/steam_utils.h @@ -0,0 +1,18 @@ +#ifndef _STEAM_UTILS_H_ +#define _STEAM_UTILS_H_ + +int SteamToMirandaStatus(PersonaState state); +PersonaState MirandaToSteamState(int status); + +void ShowNotification(const wchar_t *message, int flags = 0, MCONTACT hContact = NULL); +void ShowNotification(const wchar_t *caption, const wchar_t *message, int flags = 0, MCONTACT hContact = NULL); + +MBinBuffer RsaEncrypt(const char *pszModulus, const char *exponent, const char *data); +MBinBuffer createMachineID(const char *accName); + +#define now() time(0) + +int64_t getRandomInt(); +CMStringA protobuf_c_text_to_string(const ProtobufCMessage &msg); + +#endif //_STEAM_UTILS_H_ diff --git a/protocols/Steam/src/steam_ws.cpp b/protocols/Steam/src/steam_ws.cpp index 93e63f5606..585d995e24 100644 --- a/protocols/Steam/src/steam_ws.cpp +++ b/protocols/Steam/src/steam_ws.cpp @@ -221,7 +221,7 @@ void CSteamProto::ProcessServiceResponse(const uint8_t *buf, size_t cbLen, const *p1 = 0; if (auto *pMethod = protobuf_c_service_descriptor_get_method_by_name(it->second, p)) { - auto *pDescr = pMethod->output; + auto *pDescr = (hdr.jobid_target == -1) ? pMethod->input : pMethod->output; if (auto *pMessage = protobuf_c_message_unpack(pDescr, 0, cbLen, buf)) { debugLogA("Processing service message: %s\n%s", hdr.target_job_name, protobuf_c_text_to_string(*pMessage).c_str()); |
