diff options
author | George Hazan <george.hazan@gmail.com> | 2024-12-15 19:45:16 +0300 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2024-12-15 19:45:16 +0300 |
commit | 88500a00ea529173f7dc5c4e560211e28a9d9701 (patch) | |
tree | 381d07aec9115cf3fe99d4593ce64bb9c07f36eb | |
parent | 4bbe001b15dec9cacd882ee55fe54f85c56a147f (diff) |
service message to receive a packet header too
-rw-r--r-- | protocols/Steam/src/protobuf-c/steammessages_base.pb-c.h | 4 | ||||
-rw-r--r-- | protocols/Steam/src/steam_login.cpp | 57 | ||||
-rw-r--r-- | protocols/Steam/src/steam_proto.h | 17 | ||||
-rw-r--r-- | protocols/Steam/src/steam_server.cpp | 36 | ||||
-rw-r--r-- | protocols/Steam/src/steam_ws.cpp | 20 |
5 files changed, 85 insertions, 49 deletions
diff --git a/protocols/Steam/src/protobuf-c/steammessages_base.pb-c.h b/protocols/Steam/src/protobuf-c/steammessages_base.pb-c.h index 4ff94b1524..a561798c6c 100644 --- a/protocols/Steam/src/protobuf-c/steammessages_base.pb-c.h +++ b/protocols/Steam/src/protobuf-c/steammessages_base.pb-c.h @@ -177,6 +177,10 @@ struct CMsgProtoBufHeader : public ProtobufCppMessage ProtobufCppMessage(cmsg_proto_buf_header__descriptor) {} + bool failed() const { + return has_eresult && eresult != 1; + } + protobuf_c_boolean has_steamid; uint64_t steamid; protobuf_c_boolean has_client_sessionid; diff --git a/protocols/Steam/src/steam_login.cpp b/protocols/Steam/src/steam_login.cpp index 33a8548554..13c6b9f371 100644 --- a/protocols/Steam/src/steam_login.cpp +++ b/protocols/Steam/src/steam_login.cpp @@ -65,12 +65,17 @@ void CSteamProto::Login() WSSendService(GetPasswordRSAPublicKey, request, true); } -void CSteamProto::OnGotRsaKey(const CAuthenticationGetPasswordRSAPublicKeyResponse *pResponse) +void CSteamProto::OnGotRsaKey(const CAuthenticationGetPasswordRSAPublicKeyResponse &reply, const CMsgProtoBufHeader &hdr) { + if (hdr.failed()) { + Logout(); + return; + } + // encrypt password ptrA szPassword(getStringA("Password")); - MBinBuffer encPassword(RsaEncrypt(pResponse->publickey_mod, pResponse->publickey_exp, szPassword)); + MBinBuffer encPassword(RsaEncrypt(reply.publickey_mod, reply.publickey_exp, szPassword)); ptrA base64RsaEncryptedPassword(mir_base64_encode(encPassword.data(), encPassword.length())); // run authorization request @@ -87,7 +92,7 @@ void CSteamProto::OnGotRsaKey(const CAuthenticationGetPasswordRSAPublicKeyRespon request.account_name = userName.get(); request.website_id = "Client"; request.encrypted_password = base64RsaEncryptedPassword; - request.encryption_timestamp = pResponse->timestamp; request.has_encryption_timestamp = true; + request.encryption_timestamp = reply.timestamp; request.has_encryption_timestamp = true; request.persistence = ESESSION_PERSISTENCE__k_ESessionPersistence_Persistent; request.has_persistence = true; request.remember_login = request.has_remember_login = true; request.language = 1; request.has_language = true; @@ -101,18 +106,23 @@ void CSteamProto::OnGotRsaKey(const CAuthenticationGetPasswordRSAPublicKeyRespon WSSendService(BeginAuthSessionViaCredentials, request, true); } -void CSteamProto::OnBeginSession(const CAuthenticationBeginAuthSessionViaCredentialsResponse *pResponse) +void CSteamProto::OnBeginSession(const CAuthenticationBeginAuthSessionViaCredentialsResponse &reply, const CMsgProtoBufHeader &hdr) { - if (pResponse->has_client_id && pResponse->has_steamid) { + if (hdr.failed()) { + Logout(); + return; + } + + if (reply.has_client_id && reply.has_steamid) { DeleteAuthSettings(); - SetId(DBKEY_STEAM_ID, m_iSteamId = pResponse->steamid); - SetId(DBKEY_CLIENT_ID, m_iClientId = pResponse->client_id); + SetId(DBKEY_STEAM_ID, m_iSteamId = reply.steamid); + SetId(DBKEY_CLIENT_ID, m_iClientId = reply.client_id); - if (pResponse->has_request_id) - m_requestId.append(pResponse->request_id.data, pResponse->request_id.len); + if (reply.has_request_id) + m_requestId.append(reply.request_id.data, reply.request_id.len); - for (int i = 0; i < pResponse->n_allowed_confirmations; i++) { - auto &conf = pResponse->allowed_confirmations[i]; + for (int i = 0; i < reply.n_allowed_confirmations; i++) { + auto &conf = reply.allowed_confirmations[i]; debugLogA("Confirmation required %d (%s)", conf->confirmation_type, conf->associated_message); switch (conf->confirmation_type) { case EAUTH_SESSION_GUARD_TYPE__k_EAuthSessionGuardType_None: // nothing to do @@ -136,7 +146,7 @@ void CSteamProto::OnBeginSession(const CAuthenticationBeginAuthSessionViaCredent SendPollRequest(); } else { - debugLogA("Something went wrong: %s", pResponse->extended_error_message); + debugLogA("Something went wrong: %s", reply.extended_error_message); Logout(); } } @@ -189,9 +199,12 @@ void CSteamProto::SendConfirmationCode(bool isEmail, const char *pszCode) WSSendService(UpdateAuthSessionWithSteamGuardCode, request, true); } -void CSteamProto::OnGotConfirmationCode(const CAuthenticationUpdateAuthSessionWithSteamGuardCodeResponse*) +void CSteamProto::OnGotConfirmationCode(const CAuthenticationUpdateAuthSessionWithSteamGuardCodeResponse&, const CMsgProtoBufHeader &hdr) { - SendPollRequest(); + if (hdr.failed()) + Logout(); + else + SendPollRequest(); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -204,16 +217,16 @@ void CSteamProto::SendPollRequest() WSSendService(PollAuthSessionStatus, request, true); } -void CSteamProto::OnPollSession(const CAuthenticationPollAuthSessionStatusResponse *pResponse) +void CSteamProto::OnPollSession(const CAuthenticationPollAuthSessionStatusResponse &reply, const CMsgProtoBufHeader &) { - if (pResponse->has_new_client_id) - m_iClientId = pResponse->new_client_id; + if (reply.has_new_client_id) + m_iClientId = reply.new_client_id; - if (pResponse->new_guard_data) - setString("MachineId", pResponse->new_guard_data); + if (reply.new_guard_data) + setString("MachineId", reply.new_guard_data); - m_szAccessToken = pResponse->access_token; - m_szRefreshToken = pResponse->refresh_token; + m_szAccessToken = reply.access_token; + m_szRefreshToken = reply.refresh_token; // sending logon packet ptrA szAccountName(getUStringA(DBKEY_ACCOUNT_NAME)), szPassword(getUStringA("Password")); @@ -225,7 +238,7 @@ void CSteamProto::OnPollSession(const CAuthenticationPollAuthSessionStatusRespon privateIp.v4 = 0; CMsgClientLogon request; - request.access_token = pResponse->refresh_token; + request.access_token = reply.refresh_token; request.machine_name = szMachineName; request.client_language = "english"; request.client_os_type = 16; request.has_client_os_type = true; diff --git a/protocols/Steam/src/steam_proto.h b/protocols/Steam/src/steam_proto.h index c69957cc99..bf25a6fcc3 100644 --- a/protocols/Steam/src/steam_proto.h +++ b/protocols/Steam/src/steam_proto.h @@ -75,6 +75,7 @@ struct COwnMessage int iMessageId, timestamp = 0;
MCONTACT hContact;
+ uint64_t iSourceId = -1;
};
class CSteamProto : public PROTO<CSteamProto>
@@ -138,11 +139,11 @@ class CSteamProto : public PROTO<CSteamProto> void ProcessMulti(const uint8_t *buf, size_t cbLen);
void ProcessMessage(const uint8_t *buf, size_t cbLen);
- void ProcessServiceResponce(const uint8_t *buf, size_t cbLen, const char *pszServiceName);
+ void ProcessServiceResponse(const uint8_t *buf, size_t cbLen, const CMsgProtoBufHeader &hdr);
void WSSend(EMsg msgType, const ProtobufCppMessage &msg);
void WSSendHeader(EMsg msgType, const CMsgProtoBufHeader &hdr, const ProtobufCppMessage &msg);
- void WSSendService(const char *pszServiceName, const ProtobufCppMessage &msg, bool bAnon = false);
+ int64_t WSSendService(const char *pszServiceName, const ProtobufCppMessage &msg, bool bAnon = false);
// requests
bool SendRequest(HttpRequest *request);
@@ -163,11 +164,11 @@ class CSteamProto : public PROTO<CSteamProto> static INT_PTR CALLBACK EnterTotpCode(void *param);
static INT_PTR CALLBACK EnterEmailCode(void *param);
- void OnBeginSession(const CAuthenticationBeginAuthSessionViaCredentialsResponse *pResponse);
+ void OnBeginSession(const CAuthenticationBeginAuthSessionViaCredentialsResponse &pResponse, const CMsgProtoBufHeader &hdr);
void OnClientLogon(const uint8_t *buf, size_t cbLen);
- void OnGotRsaKey(const CAuthenticationGetPasswordRSAPublicKeyResponse *pResponse);
- void OnGotConfirmationCode(const CAuthenticationUpdateAuthSessionWithSteamGuardCodeResponse *pResponse);
- void OnPollSession(const CAuthenticationPollAuthSessionStatusResponse *pResponse);
+ void OnGotRsaKey(const CAuthenticationGetPasswordRSAPublicKeyResponse &pResponse, const CMsgProtoBufHeader &hdr);
+ void OnGotConfirmationCode(const CAuthenticationUpdateAuthSessionWithSteamGuardCodeResponse &pResponse, const CMsgProtoBufHeader &hdr);
+ void OnPollSession(const CAuthenticationPollAuthSessionStatusResponse &pResponse, const CMsgProtoBufHeader &hdr);
void OnGotHosts(const JSONNode &root, void *);
@@ -216,7 +217,7 @@ class CSteamProto : public PROTO<CSteamProto> OBJLIST<COwnMessage> m_arOwnMessages;
void SendFriendMessage(uint32_t msgId, int64_t steamId, const char *pszMessage);
- void OnMessageSent(const CFriendMessagesSendMessageResponse *pResponse);
+ void OnMessageSent(const CFriendMessagesSendMessageResponse &reply, const CMsgProtoBufHeader &hdr);
int __cdecl OnPreCreateMessage(WPARAM, LPARAM lParam);
// history
@@ -349,7 +350,7 @@ struct CMPlugin : public ACCPROTOPLUGIN<CSteamProto> std::map<std::string, const ProtobufCServiceDescriptor*> services;
- typedef void (CSteamProto:: *ServiceResponseHandler)(const ProtobufCMessage *);
+ typedef void (CSteamProto:: *ServiceResponseHandler)(const ProtobufCMessage &msg, const CMsgProtoBufHeader &hdr);
std::map<std::string, ServiceResponseHandler> serviceHandlers;
int Load() override;
diff --git a/protocols/Steam/src/steam_server.cpp b/protocols/Steam/src/steam_server.cpp index c6e50bf891..d34db74b87 100644 --- a/protocols/Steam/src/steam_server.cpp +++ b/protocols/Steam/src/steam_server.cpp @@ -27,24 +27,40 @@ void CSteamProto::SendFriendMessage(uint32_t msgId, int64_t steamId, const char request.contains_bbcode = request.has_contains_bbcode = true; request.steamid = steamId; request.has_steamid = true; request.message = (char *)pszMessage; - WSSendService(FriendSendMessage, request); + + 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 *pResponse) +void CSteamProto::OnMessageSent(const CFriendMessagesSendMessageResponse &reply, const CMsgProtoBufHeader &hdr) { - COwnMessage *pOwn; + COwnMessage tmp(0, 0); { mir_cslock lck(m_csOwnMessages); - pOwn = m_arOwnMessages.find((COwnMessage *)&pResponse->ordinal); + for (auto &it : m_arOwnMessages) + if (it->iSourceId == hdr.jobid_target) { + tmp = *it; + m_arOwnMessages.remove(m_arOwnMessages.indexOf(&it)); + break; + } } - if (pOwn) { - uint32_t timestamp = (pResponse->has_server_timestamp) ? pResponse->server_timestamp : 0; - if (timestamp > getDword(pOwn->hContact, DB_KEY_LASTMSGTS)) - setDword(pOwn->hContact, DB_KEY_LASTMSGTS, timestamp); + if (!tmp.hContact) + return; - pOwn->timestamp = timestamp; - ProtoBroadcastAck(pOwn->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)pOwn->iMessageId, 0); + 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); } } diff --git a/protocols/Steam/src/steam_ws.cpp b/protocols/Steam/src/steam_ws.cpp index 118a303a2d..4071bd5d63 100644 --- a/protocols/Steam/src/steam_ws.cpp +++ b/protocols/Steam/src/steam_ws.cpp @@ -175,7 +175,7 @@ void CSteamProto::ProcessMessage(const uint8_t *buf, size_t cbLen) break; case EMsg::ServiceMethodResponse: - ProcessServiceResponce(buf, cbLen, hdr->target_job_name); + ProcessServiceResponse(buf, cbLen, *hdr); break; case EMsg::ClientLoggedOff: @@ -188,12 +188,12 @@ void CSteamProto::ProcessMessage(const uint8_t *buf, size_t cbLen) } } -void CSteamProto::ProcessServiceResponce(const uint8_t *buf, size_t cbLen, const char *pszServiceName) +void CSteamProto::ProcessServiceResponse(const uint8_t *buf, size_t cbLen, const CMsgProtoBufHeader &hdr) { - char *tmpName = NEWSTR_ALLOCA(pszServiceName); + char *tmpName = NEWSTR_ALLOCA(hdr.target_job_name); char *p = strchr(tmpName, '.'); if (!p) { - debugLogA("Invalid service function: %s", pszServiceName); + debugLogA("Invalid service function: %s", hdr.target_job_name); return; } @@ -207,7 +207,7 @@ void CSteamProto::ProcessServiceResponce(const uint8_t *buf, size_t cbLen, const auto pHandler = g_plugin.serviceHandlers.find(tmpName); if (pHandler == g_plugin.serviceHandlers.end()) { - debugLogA("Unsupported service function: %s", pszServiceName); + debugLogA("Unsupported service function: %s", hdr.target_job_name); return; } @@ -218,13 +218,13 @@ void CSteamProto::ProcessServiceResponce(const uint8_t *buf, size_t cbLen, const auto *pDescr = pMethod->output; if (auto *pMessage = protobuf_c_message_unpack(pDescr, 0, cbLen, buf)) { - debugLogA("Processing service message: %s\n%s", pszServiceName, protobuf_c_text_to_string(*pMessage).c_str()); + debugLogA("Processing service message: %s\n%s", hdr.target_job_name, protobuf_c_text_to_string(*pMessage).c_str()); - (this->*(pHandler->second))(pMessage); + (this->*(pHandler->second))(*pMessage, hdr); protobuf_c_message_free_unpacked(pMessage, 0); } } - else debugLogA("Unregistered service method: %s", pszServiceName); + else debugLogA("Unregistered service method: %s", hdr.target_job_name); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -271,7 +271,7 @@ void CSteamProto::WSSendHeader(EMsg msgType, const CMsgProtoBufHeader &hdr, cons m_ws->sendBinary(hdrbuf.data(), hdrbuf.length()); } -void CSteamProto::WSSendService(const char *pszServiceName, const ProtobufCppMessage &msg, bool bAnon) +int64_t CSteamProto::WSSendService(const char *pszServiceName, const ProtobufCppMessage &msg, bool bAnon) { CMsgProtoBufHeader hdr; hdr.has_client_sessionid = hdr.has_steamid = hdr.has_jobid_source = hdr.has_jobid_target = true; @@ -281,4 +281,6 @@ void CSteamProto::WSSendService(const char *pszServiceName, const ProtobufCppMes hdr.target_job_name = (char *)pszServiceName; hdr.realm = 1; hdr.has_realm = true; WSSendHeader(bAnon ? EMsg::ServiceMethodCallFromClientNonAuthed : EMsg::ServiceMethodCallFromClient, hdr, msg); + + return hdr.jobid_source; } |