summaryrefslogtreecommitdiff
path: root/protocols/Steam/src
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2024-12-14 18:18:45 +0300
committerGeorge Hazan <george.hazan@gmail.com>2024-12-14 18:18:45 +0300
commit0646408f9e47b85b304133a46b68311c8a486d6e (patch)
tree8789d2ceb25858f23597a2a721121dddcdbeabc3 /protocols/Steam/src
parent618867f49577c3ec0086084ebbafd5ed734c6143 (diff)
fixes #4800 (Steam: cannot send/receive messages) + obsolete message sending code removed
Diffstat (limited to 'protocols/Steam/src')
-rw-r--r--protocols/Steam/src/api/message.h23
-rw-r--r--protocols/Steam/src/proto.h26
-rw-r--r--protocols/Steam/src/protobuf-c/steammessages_friendmessages.steamclient.pb-c.cpp (renamed from protocols/Steam/src/protobuf-c/steammessages_friendmessages.steamclient.pb-c.c)0
-rw-r--r--protocols/Steam/src/protobuf-c/steammessages_friendmessages.steamclient.pb-c.h10
-rw-r--r--protocols/Steam/src/stdafx.h2
-rw-r--r--protocols/Steam/src/steam_messages.cpp81
-rw-r--r--protocols/Steam/src/steam_proto.cpp9
-rw-r--r--protocols/Steam/src/steam_proto.h21
-rw-r--r--protocols/Steam/src/steam_ws.cpp22
9 files changed, 102 insertions, 92 deletions
diff --git a/protocols/Steam/src/api/message.h b/protocols/Steam/src/api/message.h
deleted file mode 100644
index 5f41876a15..0000000000
--- a/protocols/Steam/src/api/message.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef _STEAM_REQUEST_MESSAGE_H_
-#define _STEAM_REQUEST_MESSAGE_H_
-
-struct SendMessageRequest : public HttpRequest
-{
- SendMessageRequest(const char *token, const char *umqId, const char *steamId, const char *text) :
- HttpRequest(REQUEST_POST, "/ISteamWebUserPresenceOAuth/Message/v0001")
- {
- this << CHAR_PARAM("access_token", token) << CHAR_PARAM("umqid", umqId) << CHAR_PARAM("steamid_dst", steamId)
- << CHAR_PARAM("type", "saytext") << CHAR_PARAM("text", text);
- }
-};
-
-struct SendTypingRequest : public HttpRequest
-{
- SendTypingRequest(const char *token, const char *umqId, const char *steamId) :
- HttpRequest(REQUEST_POST, "/ISteamWebUserPresenceOAuth/Message/v0001")
- {
- this << CHAR_PARAM("access_token", token) << CHAR_PARAM("umqid", umqId) << CHAR_PARAM("steamid_dst", steamId) << CHAR_PARAM("type", "typing");
- }
-};
-
-#endif //_STEAM_REQUEST_MESSAGE_H_
diff --git a/protocols/Steam/src/proto.h b/protocols/Steam/src/proto.h
index b6d0fc9315..2998d34d0f 100644
--- a/protocols/Steam/src/proto.h
+++ b/protocols/Steam/src/proto.h
@@ -1962,6 +1962,25 @@ enum class EMsg
ServerSecretChanged = 12100,
};
+enum class EChatEntryType
+{
+ Invalid = 0,
+ ChatMsg = 1,
+ Typing = 2,
+ InviteGame = 3,
+ Emote = 4, // removed "No longer supported by clients"
+ LobbyGameStart = 5, // removed "Listen for LobbyGameCreated_t callback instead"
+ LeftConversation = 6,
+ Entered = 7,
+ WasKicked = 8,
+ WasBanned = 9,
+ Disconnected = 10,
+ HistoricalChat = 11,
+ Reserved1 = 12,
+ Reserved2 = 13,
+ LinkBlocked = 14,
+};
+
enum class EResult
{
Invalid = 0,
@@ -2123,9 +2142,10 @@ namespace proto
PROTOBUF_PTR(MsgMulti, cmsg_multi__descriptor);
PROTOBUF_PTR(MsgProtoBufHeader, cmsg_proto_buf_header__descriptor);
- PROTOBUF_PTR(MsgClientLogonResponse, cmsg_client_logon_response__descriptor);
+ PROTOBUF_PTR(MsgClientLogonResponse, cmsg_client_logon_response__descriptor);
+ PROTOBUF_PTR(FriendMessagesSendMessageResponse, cfriend_messages__send_message__response__descriptor);
PROTOBUF_PTR(AuthenticationGetPasswordRSAPublicKeyResponse, cauthentication__get_password_rsapublic_key__response__descriptor);
PROTOBUF_PTR(AuthenticationBeginAuthSessionViaCredentialsResponse, cauthentication__begin_auth_session_via_credentials__response__descriptor);
- PROTOBUF_PTR(AuthenticationPollAuthSessionStatusResponse, cauthentication__poll_auth_session_status__response__descriptor);
- PROTOBUF_PTR(AuthenticationUpdateAuthSessionWithSteamGuardCodeResponse, cauthentication__update_auth_session_with_steam_guard_code__response__descriptor);
+ PROTOBUF_PTR(AuthenticationPollAuthSessionStatusResponse, cauthentication__poll_auth_session_status__response__descriptor);
+ PROTOBUF_PTR(AuthenticationUpdateAuthSessionWithSteamGuardCodeResponse, cauthentication__update_auth_session_with_steam_guard_code__response__descriptor);
};
diff --git a/protocols/Steam/src/protobuf-c/steammessages_friendmessages.steamclient.pb-c.c b/protocols/Steam/src/protobuf-c/steammessages_friendmessages.steamclient.pb-c.cpp
index e06b9cd276..e06b9cd276 100644
--- a/protocols/Steam/src/protobuf-c/steammessages_friendmessages.steamclient.pb-c.c
+++ b/protocols/Steam/src/protobuf-c/steammessages_friendmessages.steamclient.pb-c.cpp
diff --git a/protocols/Steam/src/protobuf-c/steammessages_friendmessages.steamclient.pb-c.h b/protocols/Steam/src/protobuf-c/steammessages_friendmessages.steamclient.pb-c.h
index 3d4c801e5b..9a747e890b 100644
--- a/protocols/Steam/src/protobuf-c/steammessages_friendmessages.steamclient.pb-c.h
+++ b/protocols/Steam/src/protobuf-c/steammessages_friendmessages.steamclient.pb-c.h
@@ -4,7 +4,7 @@
#ifndef PROTOBUF_C_steammessages_5ffriendmessages_2esteamclient_2eproto__INCLUDED
#define PROTOBUF_C_steammessages_5ffriendmessages_2esteamclient_2eproto__INCLUDED
-#include <protobuf-c/protobuf-c.h>
+#include "protobuf-c.h"
PROTOBUF_C__BEGIN_DECLS
@@ -70,14 +70,6 @@ extern const ProtobufCServiceDescriptor friend_messages_client__descriptor;
extern "C" void message_init_generic(const ProtobufCMessageDescriptor * desc, ProtobufCMessage * message);
-struct ProtobufCppMessage : public ProtobufCMessage
-{
- ProtobufCppMessage(const ProtobufCMessageDescriptor &descr)
- {
- message_init_generic(&descr, this);
- }
-};
-
struct CFriendMessagesGetRecentMessagesRequest : public ProtobufCppMessage
{
CFriendMessagesGetRecentMessagesRequest() :
diff --git a/protocols/Steam/src/stdafx.h b/protocols/Steam/src/stdafx.h
index 2beb51b714..2fd47d20f1 100644
--- a/protocols/Steam/src/stdafx.h
+++ b/protocols/Steam/src/stdafx.h
@@ -41,6 +41,7 @@
#include "protobuf-c/steammessages_auth.steamclient.pb-c.h"
#include "protobuf-c/steammessages_clientserver_login.pb-c.h"
+#include "protobuf-c/steammessages_friendmessages.steamclient.pb-c.h"
#include "proto.h"
#define MODULE "Steam"
@@ -79,7 +80,6 @@ int64_t getRandomInt();
#include "api/friend.h"
#include "api/friend_list.h"
#include "api/history.h"
-#include "api/message.h"
#include "api/pending.h"
#include "api/search.h"
#include "api/session.h"
diff --git a/protocols/Steam/src/steam_messages.cpp b/protocols/Steam/src/steam_messages.cpp
index ba4f60271f..b5a89e3c8c 100644
--- a/protocols/Steam/src/steam_messages.cpp
+++ b/protocols/Steam/src/steam_messages.cpp
@@ -1,55 +1,48 @@
#include "stdafx.h"
-struct SendMessageParam
+int CSteamProto::SendMsg(MCONTACT hContact, MEVENT, const char *message)
{
- MCONTACT hContact;
- HANDLE hMessage;
-};
+ if (!IsOnline())
+ return -1;
-int CSteamProto::OnSendMessage(MCONTACT hContact, const char *message)
-{
UINT hMessage = InterlockedIncrement(&hMessageProcess);
+ CMStringA szId(FORMAT, "%d", hMessage);
+ {
+ mir_cslock lck(m_csOwnMessages);
+ m_arOwnMessages.insert(new COwnMessage(hContact, hMessage));
+ }
- SendMessageParam *param = (SendMessageParam *)mir_calloc(sizeof(SendMessageParam));
- param->hContact = hContact;
- param->hMessage = (HANDLE)hMessage;
+ 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 = GetId(hContact, DBKEY_STEAM_ID); request.has_steamid = true;
+ request.message = (char *)message;
+ WSSendClient("FriendMessages.SendMessage#1", request, &CSteamProto::OnMessageSent);
- ptrA steamId(getStringA(hContact, DBKEY_STEAM_ID));
- SendRequest(new SendMessageRequest(m_szAccessToken, m_szUmqId, steamId, message), &CSteamProto::OnMessageSent, param);
return hMessage;
}
-void CSteamProto::OnMessageSent(const MHttpResponse &response, void *arg)
+void CSteamProto::OnMessageSent(const uint8_t *buf, size_t cbLen)
{
- SendMessageParam *param = (SendMessageParam *)arg;
-
- std::string error = Translate("Unknown error");
- ptrW steamId(getWStringA(param->hContact, DBKEY_STEAM_ID));
- time_t timestamp = NULL;
-
- JSONNode root = JSONNode::parse(response.body);
- const JSONNode &node = root["error"];
- if (node)
- error = node.as_string();
-
- timestamp = atol(root["utc_timestamp"].as_string().c_str());
- if (timestamp > getDword(param->hContact, DB_KEY_LASTMSGTS))
- setDword(param->hContact, DB_KEY_LASTMSGTS, timestamp);
-
- if (mir_strcmpi(error.c_str(), "OK") != 0) {
- debugLogA(__FUNCTION__ ": failed to send message for %s (%s)", steamId.get(), error.c_str());
- ProtoBroadcastAck(param->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, param->hMessage, _A2T(error.c_str()));
+ proto::FriendMessagesSendMessageResponse reply(buf, cbLen);
+ if (!reply)
+ return;
+
+ COwnMessage *pOwn;
+ {
+ mir_cslock lck(m_csOwnMessages);
+ pOwn = m_arOwnMessages.find((COwnMessage *)&reply->ordinal);
}
- else {
- // remember server time of this message
- auto it = m_mpOutMessages.find(param->hMessage);
- if (it == m_mpOutMessages.end() && timestamp != NULL)
- m_mpOutMessages[param->hMessage] = timestamp;
-
- ProtoBroadcastAck(param->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, param->hMessage, 0);
+
+ if (pOwn) {
+ uint32_t timestamp = (reply->has_server_timestamp) ? reply->server_timestamp : 0;
+ if (timestamp > getDword(pOwn->hContact, DB_KEY_LASTMSGTS))
+ setDword(pOwn->hContact, DB_KEY_LASTMSGTS, timestamp);
+
+ pOwn->timestamp = timestamp;
+ ProtoBroadcastAck(pOwn->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)pOwn->iMessageId, 0);
}
-
- mir_free(param);
}
int CSteamProto::OnPreCreateMessage(WPARAM, LPARAM lParam)
@@ -58,10 +51,10 @@ int CSteamProto::OnPreCreateMessage(WPARAM, LPARAM lParam)
if (mir_strcmp(Proto_GetBaseAccountName(evt->hContact), m_szModuleName))
return 0;
- auto it = m_mpOutMessages.find((HANDLE)evt->seq);
- if (it != m_mpOutMessages.end()) {
- evt->dbei->timestamp = it->second;
- m_mpOutMessages.erase(it);
+ mir_cslock lck(m_csOwnMessages);
+ if (auto *pOwn = m_arOwnMessages.find((COwnMessage *)&evt->seq)) {
+ evt->dbei->timestamp = pOwn->timestamp;
+ m_arOwnMessages.remove(pOwn);
}
return 0;
@@ -74,6 +67,6 @@ int CSteamProto::UserIsTyping(MCONTACT hContact, int type)
return 0;
ptrA steamId(getStringA(hContact, DBKEY_STEAM_ID));
- SendRequest(new SendTypingRequest(m_szAccessToken, m_szUmqId, steamId));
+ //SendRequest(new SendTypingRequest(m_szAccessToken, m_szUmqId, steamId));
return 0;
}
diff --git a/protocols/Steam/src/steam_proto.cpp b/protocols/Steam/src/steam_proto.cpp
index 158b5e215b..9d39d7e907 100644
--- a/protocols/Steam/src/steam_proto.cpp
+++ b/protocols/Steam/src/steam_proto.cpp
@@ -11,6 +11,7 @@ CSteamProto::CSteamProto(const char *protoName, const wchar_t *userName) :
PROTO<CSteamProto>(protoName, userName),
m_impl(*this),
m_arRequests(10, CompareRequests),
+ m_arOwnMessages(1, NumericKeySortT),
m_wszGroupName(this, "DefaultGroup", L"Steam"),
m_wszDeviceName(this, "DeviceName", L"Miranda NG")
{
@@ -223,14 +224,6 @@ HANDLE CSteamProto::SearchByName(const wchar_t *nick, const wchar_t *firstName,
return (HANDLE)STEAM_SEARCH_BYNAME;
}
-int CSteamProto::SendMsg(MCONTACT hContact, MEVENT, const char *message)
-{
- if (!IsOnline())
- return -1;
-
- return OnSendMessage(hContact, message);
-}
-
int CSteamProto::SetStatus(int new_status)
{
// Routing statuses not supported by Steam
diff --git a/protocols/Steam/src/steam_proto.h b/protocols/Steam/src/steam_proto.h
index 5b61ae97f5..7503b4873d 100644
--- a/protocols/Steam/src/steam_proto.h
+++ b/protocols/Steam/src/steam_proto.h
@@ -59,6 +59,17 @@ struct ProtoRequest
MsgCallback pCallback;
};
+struct COwnMessage
+{
+ COwnMessage(MCONTACT _1, int _2) :
+ hContact(_1),
+ iMessageId(_2)
+ {}
+
+ int iMessageId, timestamp = 0;
+ MCONTACT hContact;
+};
+
class CSteamProto : public PROTO<CSteamProto>
{
friend class CSteamGuardDialog;
@@ -108,14 +119,13 @@ class CSteamProto : public PROTO<CSteamProto>
void SetId(MCONTACT, const char *pszSetting, int64_t id);
// polling
- CMStringA m_szRefreshToken, m_szAccessToken, m_szUmqId;
+ CMStringA m_szRefreshToken, m_szAccessToken;
ULONG hAuthProcess = 1;
ULONG hMessageProcess = 1;
int m_iPollingInterval;
time_t m_iPollingStartTime;
mir_cs m_addContactLock;
mir_cs m_setStatusLock;
- std::map<HANDLE, time_t> m_mpOutMessages;
// connection
WebSocket<CSteamProto> *m_ws;
@@ -131,6 +141,7 @@ class CSteamProto : public PROTO<CSteamProto>
void WSSend(EMsg msgType, const ProtobufCppMessage &msg);
void WSSendHeader(EMsg msgType, const CMsgProtoBufHeader &hdr, const ProtobufCppMessage &msg);
+ void WSSendClient(const char *pszServiceName, const ProtobufCppMessage &msg, MsgCallback pCallback = 0);
void WSSendService(const char *pszServiceName, const ProtobufCppMessage &msg, MsgCallback pCallback = 0);
// requests
@@ -203,8 +214,10 @@ class CSteamProto : public PROTO<CSteamProto>
void OnSearchByNameStarted(const MHttpResponse &response, void *arg);
// messages
- int OnSendMessage(MCONTACT hContact, const char *message);
- void OnMessageSent(const MHttpResponse &response, void *arg);
+ mir_cs m_csOwnMessages;
+ OBJLIST<COwnMessage> m_arOwnMessages;
+
+ void OnMessageSent(const uint8_t *buf, size_t cbLen);
int __cdecl OnPreCreateMessage(WPARAM, LPARAM lParam);
// history
diff --git a/protocols/Steam/src/steam_ws.cpp b/protocols/Steam/src/steam_ws.cpp
index e6ee7f7d7a..dcf6d0743a 100644
--- a/protocols/Steam/src/steam_ws.cpp
+++ b/protocols/Steam/src/steam_ws.cpp
@@ -173,6 +173,10 @@ void CSteamProto::ProcessMessage(const uint8_t *buf, size_t cbLen)
case EMsg::ClientLogOnResponse:
OnClientLogon(buf, cbLen);
break;
+
+ case EMsg::ClientLoggedOff:
+ Logout();
+ break;
}
}
@@ -219,6 +223,24 @@ void CSteamProto::WSSendHeader(EMsg msgType, const CMsgProtoBufHeader &hdr, cons
m_ws->sendBinary(hdrbuf.data(), hdrbuf.length());
}
+void CSteamProto::WSSendClient(const char *pszServiceName, const ProtobufCppMessage &msg, MsgCallback pCallback)
+{
+ CMsgProtoBufHeader hdr;
+ hdr.has_client_sessionid = hdr.has_steamid = hdr.has_jobid_source = hdr.has_jobid_target = true;
+ hdr.client_sessionid = m_iSessionId;
+ hdr.jobid_source = getRandomInt();
+ hdr.jobid_target = -1;
+ hdr.target_job_name = (char *)pszServiceName;
+ hdr.realm = 1; hdr.has_realm = true;
+
+ if (pCallback) {
+ mir_cslock lck(m_csRequests);
+ m_arRequests.insert(new ProtoRequest(hdr.jobid_source, pCallback));
+ }
+
+ WSSendHeader(EMsg::ServiceMethodCallFromClient, hdr, msg);
+}
+
void CSteamProto::WSSendService(const char *pszServiceName, const ProtobufCppMessage &msg, MsgCallback pCallback)
{
CMsgProtoBufHeader hdr;