summaryrefslogtreecommitdiff
path: root/protocols/Steam/src/steam_ws.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Steam/src/steam_ws.cpp')
-rw-r--r--protocols/Steam/src/steam_ws.cpp115
1 files changed, 69 insertions, 46 deletions
diff --git a/protocols/Steam/src/steam_ws.cpp b/protocols/Steam/src/steam_ws.cpp
index bbf8a5b7a0..118a303a2d 100644
--- a/protocols/Steam/src/steam_ws.cpp
+++ b/protocols/Steam/src/steam_ws.cpp
@@ -123,42 +123,41 @@ void CSteamProto::ProcessMulti(const uint8_t *buf, size_t cbLen)
void CSteamProto::ProcessMessage(const uint8_t *buf, size_t cbLen)
{
- Netlib_Dump(HNETLIBCONN(m_ws->getConn()), buf, cbLen, false, 0);
-
uint32_t dwSign = *(uint32_t *)buf; buf += sizeof(uint32_t); cbLen -= sizeof(uint32_t);
EMsg msgType = (EMsg)(dwSign & ~STEAM_PROTOCOL_MASK);
bool bIsProto = (dwSign & STEAM_PROTOCOL_MASK) != 0;
- CMsgProtoBufHeader hdr;
-
if (msgType == EMsg::ChannelEncryptRequest || msgType == EMsg::ChannelEncryptResult) {
+ CMsgProtoBufHeader hdr;
hdr.has_jobid_source = hdr.has_jobid_target = true;
hdr.jobid_source = *(int64_t *)buf; buf += sizeof(int64_t);
hdr.jobid_target = *(int64_t *)buf; buf += sizeof(int64_t);
+ debugLogA("encrypted results cannot be processed, ignoring");
+ return;
}
- else if (bIsProto) {
- uint32_t hdrLen = *(uint32_t *)buf; buf += sizeof(uint32_t); cbLen -= sizeof(uint32_t);
- proto::MsgProtoBufHeader tmpHeader(buf, hdrLen);
- if (tmpHeader == nullptr) {
- debugLogA("Unable to decode message header, exiting");
- return;
- }
-
- memcpy(&hdr, tmpHeader, sizeof(hdr));
- buf += hdrLen; cbLen -= hdrLen;
-
- if (hdr.has_client_sessionid)
- m_iSessionId = hdr.client_sessionid;
+
+ if (!bIsProto) {
+ debugLogA("Got unknown packet, exiting");
+ Netlib_Dump(HNETLIBCONN(m_ws->getConn()), buf, cbLen, false, 0);
+ return;
}
- else {
- debugLogA("Got unknown header, exiting");
+
+ uint32_t hdrLen = *(uint32_t *)buf; buf += sizeof(uint32_t); cbLen -= sizeof(uint32_t);
+ proto::MsgProtoBufHeader hdr(buf, hdrLen);
+ if (hdr == nullptr) {
+ debugLogA("Unable to decode message header, exiting");
return;
}
+ buf += hdrLen; cbLen -= hdrLen;
+
+ if (hdr->has_client_sessionid)
+ m_iSessionId = hdr->client_sessionid;
+
MsgCallback pCallback = 0;
{
mir_cslock lck(m_csRequests);
- if (auto *pReq = m_arRequests.find((ProtoRequest *)&hdr.jobid_target)) {
+ if (auto *pReq = m_arRequests.find((ProtoRequest *)&hdr->jobid_target)) {
pCallback = pReq->pCallback;
m_arRequests.remove(pReq);
}
@@ -175,10 +174,57 @@ void CSteamProto::ProcessMessage(const uint8_t *buf, size_t cbLen)
OnClientLogon(buf, cbLen);
break;
+ case EMsg::ServiceMethodResponse:
+ ProcessServiceResponce(buf, cbLen, hdr->target_job_name);
+ break;
+
case EMsg::ClientLoggedOff:
+ debugLogA("received logout request");
Logout();
break;
+
+ default:
+ Netlib_Dump(HNETLIBCONN(m_ws->getConn()), buf, cbLen, false, 0);
+ }
+}
+
+void CSteamProto::ProcessServiceResponce(const uint8_t *buf, size_t cbLen, const char *pszServiceName)
+{
+ char *tmpName = NEWSTR_ALLOCA(pszServiceName);
+ char *p = strchr(tmpName, '.');
+ if (!p) {
+ debugLogA("Invalid service function: %s", pszServiceName);
+ return;
+ }
+
+ *p = 0;
+ auto it = g_plugin.services.find(tmpName);
+ if (it == g_plugin.services.end()) {
+ debugLogA("Unregistered service module: %s", tmpName);
+ return;
+ }
+ *p = '.';
+
+ auto pHandler = g_plugin.serviceHandlers.find(tmpName);
+ if (pHandler == g_plugin.serviceHandlers.end()) {
+ debugLogA("Unsupported service function: %s", pszServiceName);
+ return;
+ }
+
+ if (char *p1 = strchr(++p, '#'))
+ *p1 = 0;
+
+ if (auto *pMethod = protobuf_c_service_descriptor_get_method_by_name(it->second, p)) {
+ 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());
+
+ (this->*(pHandler->second))(pMessage);
+ protobuf_c_message_free_unpacked(pMessage, 0);
+ }
}
+ else debugLogA("Unregistered service method: %s", pszServiceName);
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -225,37 +271,14 @@ 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)
+void 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;
- hdr.client_sessionid = m_iSessionId;
+ hdr.client_sessionid = bAnon ? 0 : 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;
- hdr.has_client_sessionid = hdr.has_steamid = hdr.has_jobid_source = hdr.has_jobid_target = true;
- 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::ServiceMethodCallFromClientNonAuthed, hdr, msg);
+ WSSendHeader(bAnon ? EMsg::ServiceMethodCallFromClientNonAuthed : EMsg::ServiceMethodCallFromClient, hdr, msg);
}