summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--protocols/Steam/Steam.vcxproj1
-rw-r--r--protocols/Steam/Steam.vcxproj.filters3
-rw-r--r--protocols/Steam/src/main.cpp5
-rw-r--r--protocols/Steam/src/stdafx.h1
-rw-r--r--protocols/Steam/src/steam_chats.cpp300
-rw-r--r--protocols/Steam/src/steam_login.cpp10
-rw-r--r--protocols/Steam/src/steam_messages.cpp28
-rw-r--r--protocols/Steam/src/steam_proto.cpp18
-rw-r--r--protocols/Steam/src/steam_proto.h37
-rw-r--r--protocols/Steam/src/steam_server.cpp3
-rw-r--r--protocols/Steam/src/steam_ws.cpp41
11 files changed, 406 insertions, 41 deletions
diff --git a/protocols/Steam/Steam.vcxproj b/protocols/Steam/Steam.vcxproj
index 0f29dd2747..445cb17cd3 100644
--- a/protocols/Steam/Steam.vcxproj
+++ b/protocols/Steam/Steam.vcxproj
@@ -79,6 +79,7 @@
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="src\steam_avatars.cpp" />
+ <ClCompile Include="src\steam_chats.cpp" />
<ClCompile Include="src\steam_contacts.cpp" />
<ClCompile Include="src\steam_crypt.cpp" />
<ClCompile Include="src\steam_dialogs.cpp" />
diff --git a/protocols/Steam/Steam.vcxproj.filters b/protocols/Steam/Steam.vcxproj.filters
index 3bd5e7610d..c1d24742be 100644
--- a/protocols/Steam/Steam.vcxproj.filters
+++ b/protocols/Steam/Steam.vcxproj.filters
@@ -111,6 +111,9 @@
<ClCompile Include="src\protobuf-c\steammessages_deviceauth.steamclient.pb-c.cpp">
<Filter>Source Files\protobuf</Filter>
</ClCompile>
+ <ClCompile Include="src\steam_chats.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\resource.h">
diff --git a/protocols/Steam/src/main.cpp b/protocols/Steam/src/main.cpp
index 920345a2e5..828311e40f 100644
--- a/protocols/Steam/src/main.cpp
+++ b/protocols/Steam/src/main.cpp
@@ -171,6 +171,11 @@ void CMPlugin::InitSteamServices()
serviceHandlers[FriendGetRecentMessages] = ServiceResponseHandler(&CSteamProto::OnGotRecentMessages);
serviceHandlers[FriendGetIncomingMessage] = ServiceResponseHandler(&CSteamProto::OnGotIncomingMessage);
+ serviceHandlers[GetMyChatRoomGroups] = ServiceResponseHandler(&CSteamProto::OnGetMyChats);
+ serviceHandlers[GetChatHistory] = ServiceResponseHandler(&CSteamProto::OnGetChatHistory);
+ serviceHandlers[NotifyIncomingChatMessage] = ServiceResponseHandler(&CSteamProto::OnGetChatMessage);
+ serviceHandlers[LeaveChatGroup] = ServiceResponseHandler(&CSteamProto::OnLeftChat);
+
serviceHandlers[GetOwnAuthorizedDevices] = ServiceResponseHandler(&CSteamProto::OnGotDeviceList);
serviceHandlers[NotificationReceived] = ServiceResponseHandler(&CSteamProto::OnGotNotification);
diff --git a/protocols/Steam/src/stdafx.h b/protocols/Steam/src/stdafx.h
index 56b6647f22..37c008b5b1 100644
--- a/protocols/Steam/src/stdafx.h
+++ b/protocols/Steam/src/stdafx.h
@@ -13,6 +13,7 @@
#include <algorithm>
#include <newpluginapi.h>
+#include <m_chat_int.h>
#include <m_contacts.h>
#include <m_database.h>
#include <m_langpack.h>
diff --git a/protocols/Steam/src/steam_chats.cpp b/protocols/Steam/src/steam_chats.cpp
new file mode 100644
index 0000000000..7d25507bde
--- /dev/null
+++ b/protocols/Steam/src/steam_chats.cpp
@@ -0,0 +1,300 @@
+/*
+Copyright (C) 2012-25 Miranda NG team (https://miranda-ng.org)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "stdafx.h"
+
+void CSteamProto::SendGetChatsRequest()
+{
+ CChatRoomGetMyChatRoomGroupsRequest request;
+ WSSendService(GetMyChatRoomGroups, request);
+}
+
+void CSteamProto::OnGetMyChats(const CChatRoomGetMyChatRoomGroupsResponse &reply, const CMsgProtoBufHeader &hdr)
+{
+ if (hdr.failed())
+ return;
+
+ for (int i = 0; i < reply.n_chat_room_groups; i++) {
+ auto *pGroup = reply.chat_room_groups[i]->group_summary;
+
+ SESSION_INFO *pOwner = 0;
+
+ for (int k = 0; k < pGroup->n_chat_rooms; k++) {
+ auto *pChat = pGroup->chat_rooms[k];
+ CMStringW wszId(FORMAT, L"%lld_%d", pGroup->chat_group_id, pChat->chat_id);
+
+ CMStringW wszTitle(Utf2T(pChat->chat_name));
+ if (wszTitle.IsEmpty())
+ wszTitle = Utf2T(pGroup->chat_group_name);
+
+ auto *si = Chat_NewSession(GCW_CHATROOM, m_szModuleName, wszId, wszTitle);
+ Chat_AddGroup(si, TranslateT("Owner"));
+ Chat_AddGroup(si, TranslateT("Participant"));
+
+ if (pOwner == 0) {
+ for (int j = 0; j < pGroup->n_top_members; j++) {
+ uint64_t iSteamId = AccountIdToSteamId(pGroup->top_members[j]);
+ CMStringW wszUserId(FORMAT, L"%lld", iSteamId), wszNick;
+
+ GCEVENT gce = { si, GC_EVENT_JOIN };
+ gce.pszUID.w = wszUserId;
+
+ if (iSteamId == m_iSteamId) {
+ gce.bIsMe = true;
+ wszNick = getMStringW("Nick");
+ }
+ else if (MCONTACT hContact = GetContact(iSteamId))
+ wszNick = Clist_GetContactDisplayName(hContact);
+ else
+ wszNick = L"@" + wszUserId;
+
+ gce.pszNick.w = wszNick;
+ gce.pszStatus.w = (pGroup->top_members[j] == pGroup->accountid_owner) ? TranslateT("Owner") : TranslateT("Participant");
+ Chat_Event(&gce);
+ }
+ }
+ else si->pParent = pOwner;
+
+ setDword(si->hContact, "ChatId", pChat->chat_id);
+
+ if (mir_strlen(pGroup->chat_group_tagline)) {
+ Utf2T wszTopic(pGroup->chat_group_tagline);
+ Chat_SetStatusbarText(si, wszTopic);
+
+ GCEVENT gce = { si, GC_EVENT_TOPIC };
+ gce.pszText.w = wszTopic;
+ gce.time = time(0);
+ Chat_Event(&gce);
+ }
+
+ Chat_Control(si, WINDOW_HIDDEN);
+ Chat_Control(si, SESSION_ONLINE);
+
+ uint32_t dwLastMsgId = getDword(si->hContact, DBKEY_LASTMSG);
+ if (pChat->time_last_message > dwLastMsgId)
+ SendGetChatHistory(si->hContact, dwLastMsgId);
+ }
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CSteamProto::SendGetChatHistory(MCONTACT hContact, uint32_t iLastMsgId)
+{
+ CChatRoomGetMessageHistoryRequest request;
+ request.chat_group_id = GetId(hContact, DBKEY_STEAM_ID); request.has_chat_group_id = true;
+ request.chat_id = getDword(hContact, "ChatId"); request.has_chat_id = true;
+ request.last_time = iLastMsgId; request.has_last_time = true;
+ WSSendService(GetChatHistory, request, (void*)hContact);
+}
+
+void CSteamProto::OnGetChatHistory(const CChatRoomGetMessageHistoryResponse &reply, const CMsgProtoBufHeader &hdr)
+{
+ if (hdr.failed())
+ return;
+
+ if (auto *si = Chat_Find(UINT_PTR(GetRequestInfo(hdr.jobid_target)), m_szModuleName)) {
+ uint32_t iLastMsg = getDword(si->hContact, DBKEY_LASTMSG);
+ uint32_t iChatId = getDword(si->hContact, "ChatId");
+
+ for (int i = (int)reply.n_messages - 1; i >= 0; i--) {
+ auto *pMsg = reply.messages[i];
+ if (pMsg->server_timestamp > iLastMsg)
+ iLastMsg = pMsg->server_timestamp;
+
+ // some slack, skip it
+ if (pMsg->server_message)
+ continue;
+
+ char szMsgId[100], szUserId[100];
+ mir_snprintf(szMsgId, "%d_%d", iChatId, pMsg->server_timestamp);
+ _i64toa(AccountIdToSteamId(pMsg->sender), szUserId, 10);
+
+ DB::EventInfo dbei(db_event_getById(m_szModuleName, szMsgId));
+ dbei.flags |= DBEF_UTF;
+ dbei.eventType = EVENTTYPE_MESSAGE;
+ dbei.szModule = m_szModuleName;
+ replaceStr(dbei.pBlob, mir_strdup(pMsg->message));
+ dbei.cbBlob = (int)mir_strlen(dbei.pBlob);
+ dbei.timestamp = pMsg->server_timestamp;
+ dbei.szId = szMsgId;
+ dbei.szUserId = szUserId;
+
+ if (dbei.getEvent())
+ db_event_edit(dbei.getEvent(), &dbei, true);
+ else
+ db_event_add(si->hContact, &dbei);
+ }
+
+ setDword(si->hContact, DBKEY_LASTMSG, iLastMsg);
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CSteamProto::OnGetChatMessage(const CChatRoomIncomingChatMessageNotification &reply, const CMsgProtoBufHeader &hdr)
+{
+ if (hdr.failed())
+ return;
+
+ CMStringW wszId(FORMAT, L"%lld_%lld", reply.chat_group_id, reply.chat_id);
+ if (auto *si = Chat_Find(wszId, m_szModuleName)) {
+ char szMsgId[100], szUserId[100];
+ mir_snprintf(szMsgId, "%lld_%d", reply.chat_id, reply.timestamp);
+ _i64toa(reply.steamid_sender, szUserId, 10);
+
+ DB::EventInfo dbei(db_event_getById(m_szModuleName, szMsgId));
+ dbei.flags |= DBEF_UTF;
+ dbei.eventType = EVENTTYPE_MESSAGE;
+ dbei.szModule = m_szModuleName;
+ replaceStr(dbei.pBlob, mir_strdup(reply.message));
+ dbei.cbBlob = (int)mir_strlen(dbei.pBlob);
+ dbei.timestamp = reply.timestamp;
+ dbei.szId = szMsgId;
+ dbei.szUserId = szUserId;
+
+ if (dbei.getEvent())
+ db_event_edit(dbei.getEvent(), &dbei, true);
+ else
+ db_event_add(si->hContact, &dbei);
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+INT_PTR CSteamProto::SvcLeaveChat(WPARAM hContact, LPARAM)
+{
+ CChatRoomLeaveChatRoomGroupRequest request;
+ request.chat_group_id = GetId(hContact, DBKEY_STEAM_ID); request.has_chat_group_id = true;
+ WSSendService(LeaveChatGroup, request, new uint64_t(request.chat_group_id));
+ return 0;
+}
+
+void CSteamProto::OnLeftChat(const CChatRoomLeaveChatRoomGroupResponse&, const CMsgProtoBufHeader &hdr)
+{
+ if (auto *pGroupId = (int64_t *)GetRequestInfo(hdr.jobid_target)) {
+ for (auto &cc : AccContacts()) {
+ if (!Contact::IsGroupChat(cc) || GetId(cc, DBKEY_STEAM_ID) != *pGroupId)
+ continue;
+
+ CMStringW wszId(FORMAT, L"%lld_%lld", *pGroupId, getDword(cc, "ChatId"));
+ if (auto *si = Chat_Find(wszId, m_szModuleName))
+ Chat_Terminate(si);
+
+ db_delete_contact(cc);
+ }
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+enum
+{
+ IDM_LEAVE = 1,
+};
+
+int CSteamProto::GcEventHook(WPARAM, LPARAM lParam)
+{
+ GCHOOK *gch = (GCHOOK *)lParam;
+ if (gch == nullptr)
+ return 0;
+
+ if (mir_strcmpi(gch->si->pszModule, m_szModuleName))
+ return 0;
+
+ switch (gch->iType) {
+ case GC_USER_MESSAGE:
+ if (gch->ptszText && mir_wstrlen(gch->ptszText) > 0) {
+ rtrimw(gch->ptszText);
+ T2Utf szMessage(gch->ptszText);
+
+ CChatRoomSendChatMessageRequest request;
+ request.chat_group_id = _wtoi64(gch->si->ptszID); request.has_chat_group_id = true;
+ request.chat_id = getDword(gch->si->hContact, "ChatId"); request.has_chat_id = true;
+ request.echo_to_sender = request.has_echo_to_sender = true;
+ request.message = szMessage;
+ WSSendService(SendChatMessage, request);
+ }
+ break;
+
+ case GC_USER_PRIVMESS:
+ Chat_SendPrivateMessage(gch);
+ break;
+
+ case GC_USER_LOGMENU:
+ Chat_LogMenu(gch);
+ break;
+
+ case GC_USER_NICKLISTMENU:
+ break;
+ }
+ return 0;
+}
+
+void CSteamProto::Chat_SendPrivateMessage(GCHOOK *gch)
+{
+ uint64_t iSteamId = _wtoi64(gch->ptszUID);
+ MCONTACT hContact = GetContact(iSteamId);
+ if (!hContact) {
+ PROTOSEARCHRESULT psr = { sizeof(psr) };
+ psr.id.w = (wchar_t *)gch->ptszUID;
+ psr.firstName.w = (wchar_t *)gch->ptszNick;
+
+ hContact = AddToList(PALF_TEMPORARY, &psr);
+ if (hContact == 0)
+ return;
+
+ setWString(hContact, "Nick", gch->ptszNick);
+ Contact::Hide(hContact);
+ db_set_dw(hContact, "Ignore", "Mask1", 0);
+ }
+
+ CallService(MS_MSG_SENDMESSAGE, hContact, 0);
+}
+
+void CSteamProto::Chat_LogMenu(GCHOOK *gch)
+{
+ switch (gch->dwData) {
+ case IDM_LEAVE:
+ SvcLeaveChat(gch->si->hContact, 0);
+ break;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static gc_item sttLogListItems[] =
+{
+ { LPGENW("&Leave chat session"), IDM_LEAVE, MENU_ITEM }
+};
+
+int CSteamProto::GcMenuHook(WPARAM, LPARAM lParam)
+{
+ GCMENUITEMS *gcmi = (GCMENUITEMS *)lParam;
+ if (gcmi == nullptr)
+ return 0;
+
+ if (mir_strcmpi(gcmi->pszModule, m_szModuleName))
+ return 0;
+
+ if (gcmi->Type == MENU_ON_LOG) {
+ Chat_AddMenuItems(gcmi->hMenu, _countof(sttLogListItems), sttLogListItems, &g_plugin);
+ }
+ else if (gcmi->Type == MENU_ON_NICKLIST) {
+ }
+ return 0;
+}
diff --git a/protocols/Steam/src/steam_login.cpp b/protocols/Steam/src/steam_login.cpp
index 1c2c130287..1235130542 100644
--- a/protocols/Steam/src/steam_login.cpp
+++ b/protocols/Steam/src/steam_login.cpp
@@ -57,7 +57,7 @@ void CSteamProto::Login()
CAuthenticationGetPasswordRSAPublicKeyRequest request;
request.account_name = username.get();
- WSSendService(GetPasswordRSAPublicKey, request, true);
+ WSSendAnon(GetPasswordRSAPublicKey, request);
}
void CSteamProto::OnGotRsaKey(const CAuthenticationGetPasswordRSAPublicKeyResponse &reply, const CMsgProtoBufHeader &hdr)
@@ -98,7 +98,7 @@ void CSteamProto::OnGotRsaKey(const CAuthenticationGetPasswordRSAPublicKeyRespon
request.platform_type = details.platform_type; request.has_platform_type = true;
request.guard_data = machineId;
- WSSendService(BeginAuthSessionViaCredentials, request, true);
+ WSSendAnon(BeginAuthSessionViaCredentials, request);
}
void CSteamProto::OnBeginSession(const CAuthenticationBeginAuthSessionViaCredentialsResponse &reply, const CMsgProtoBufHeader &hdr)
@@ -191,7 +191,7 @@ void CSteamProto::SendConfirmationCode(bool isEmail, const char *pszCode)
request.code_type = EAUTH_SESSION_GUARD_TYPE__k_EAuthSessionGuardType_DeviceCode;
request.has_code_type = true;
request.code = (char*)pszCode;
- WSSendService(UpdateAuthSessionWithSteamGuardCode, request, true);
+ WSSendAnon(UpdateAuthSessionWithSteamGuardCode, request);
}
void CSteamProto::OnGotConfirmationCode(const CAuthenticationUpdateAuthSessionWithSteamGuardCodeResponse &, const CMsgProtoBufHeader &hdr)
@@ -209,7 +209,7 @@ void CSteamProto::SendPollRequest()
CAuthenticationPollAuthSessionStatusRequest request;
request.client_id = GetId(DBKEY_CLIENT_ID); request.has_client_id = true;
request.request_id.data = m_requestId.data(); request.request_id.len = m_requestId.length(); request.has_request_id = true;
- WSSendService(PollAuthSessionStatus, request, true);
+ WSSendAnon(PollAuthSessionStatus, request);
}
void CSteamProto::OnPollSession(const CAuthenticationPollAuthSessionStatusResponse &reply, const CMsgProtoBufHeader &)
@@ -262,7 +262,7 @@ void CSteamProto::OnClientLogon(const CMsgClientLogonResponse &reply, const CMsg
ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, m_iStatus = m_iDesiredStatus);
SendPersonaStatus(m_iStatus);
- SendDeviceListRequest();
+ SendGetChatsRequest();
WSSend(EMsg::ClientChatGetFriendMessageHistoryForOfflineMessages, NoResponse());
}
diff --git a/protocols/Steam/src/steam_messages.cpp b/protocols/Steam/src/steam_messages.cpp
index 8c8cfab442..da65a5b424 100644
--- a/protocols/Steam/src/steam_messages.cpp
+++ b/protocols/Steam/src/steam_messages.cpp
@@ -1,42 +1,32 @@
#include "stdafx.h"
-int64_t CSteamProto::SendFriendMessage(EChatEntryType entry_type, int64_t steamId, const char *pszMessage)
+void CSteamProto::SendFriendMessage(EChatEntryType entry_type, int64_t steamId, const char *pszMessage, void *pInfo)
{
CFriendMessagesSendMessageRequest request;
request.chat_entry_type = (int)entry_type; request.has_chat_entry_type = true;
request.contains_bbcode = request.has_contains_bbcode = true;
request.steamid = steamId; request.has_steamid = true;
request.message = (char *)pszMessage;
- return WSSendService(FriendSendMessage, request);
+ WSSendService(FriendSendMessage, request, pInfo);
}
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)
+ auto *pOwn = (COwnMessage*)GetRequestInfo(hdr.jobid_target);
+ if (pOwn == nullptr)
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());
+ ProtoBroadcastAck(pOwn->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)pOwn->iMessageId, (LPARAM)wszMessage.c_str());
}
else {
uint32_t timestamp = (reply.has_server_timestamp) ? reply.server_timestamp : 0;
- if (timestamp > getDword(tmp.hContact, DBKEY_LASTMSG))
- setDword(tmp.hContact, DBKEY_LASTMSG, timestamp);
+ if (timestamp > getDword(pOwn->hContact, DBKEY_LASTMSG))
+ setDword(pOwn->hContact, DBKEY_LASTMSG, timestamp);
- tmp.timestamp = timestamp;
- ProtoBroadcastAck(tmp.hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)tmp.iMessageId, 0);
+ pOwn->timestamp = timestamp;
+ ProtoBroadcastAck(pOwn->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)pOwn->iMessageId, 0);
}
}
diff --git a/protocols/Steam/src/steam_proto.cpp b/protocols/Steam/src/steam_proto.cpp
index a21247bf90..f8cee175d0 100644
--- a/protocols/Steam/src/steam_proto.cpp
+++ b/protocols/Steam/src/steam_proto.cpp
@@ -46,13 +46,17 @@ CSteamProto::CSteamProto(const char *protoName, const wchar_t *userName) :
nlu.szSettingsModule = m_szModuleName;
m_hNetlibUser = Netlib_RegisterUser(&nlu);
- debugLogA(__FUNCTION__":Setting protocol / module name to '%s'", m_szModuleName);
+ // groupchat initialization
+ GCREGISTER gcr = {};
+ gcr.dwFlags = GC_TYPNOTIF | GC_DATABASE;
+ gcr.ptszDispName = m_tszUserName;
+ gcr.pszModule = m_szModuleName;
+ Chat_Register(&gcr);
- if (uint32_t iGlobalValue = getDword(DBKEY_LASTMSG)) {
- for (auto &cc : AccContacts())
- setDword(cc, DBKEY_LASTMSG, iGlobalValue);
- delSetting(DBKEY_LASTMSG);
- }
+ CreateProtoService(PS_LEAVECHAT, &CSteamProto::SvcLeaveChat);
+
+ HookProtoEvent(ME_GC_EVENT, &CSteamProto::GcEventHook);
+ HookProtoEvent(ME_GC_BUILDMENU, &CSteamProto::GcMenuHook);
}
CSteamProto::~CSteamProto()
@@ -194,7 +198,7 @@ int CSteamProto::SendMsg(MCONTACT hContact, MEVENT, const char *message)
m_arOwnMessages.insert(pOwn);
}
- pOwn->iSourceId = SendFriendMessage(EChatEntryType::ChatMsg, GetId(hContact, DBKEY_STEAM_ID), message);
+ SendFriendMessage(EChatEntryType::ChatMsg, GetId(hContact, DBKEY_STEAM_ID), message, pOwn);
return hMessage;
}
diff --git a/protocols/Steam/src/steam_proto.h b/protocols/Steam/src/steam_proto.h
index 446680db43..63473ecb9b 100644
--- a/protocols/Steam/src/steam_proto.h
+++ b/protocols/Steam/src/steam_proto.h
@@ -29,6 +29,13 @@
#define FriendGetRecentMessages "FriendMessages.GetRecentMessages#1"
#define FriendGetIncomingMessage "FriendMessagesClient.IncomingMessage#1"
+#define GetMyChatRoomGroups "ChatRoom.GetMyChatRoomGroups#1"
+#define GetChatHistory "ChatRoom.GetMessageHistory#1"
+#define SendChatMessage "ChatRoom.SendChatMessage#1"
+#define LeaveChatGroup "ChatRoom.LeaveChatRoomGroup#1"
+
+#define NotifyIncomingChatMessage "ChatRoomClient.NotifyIncomingChatMessage#1"
+
#define NotificationReceived "SteamNotificationClient.NotificationsReceived#1"
struct SendAuthParam
@@ -82,7 +89,6 @@ struct COwnMessage
int iMessageId, timestamp = 0;
MCONTACT hContact;
- uint64_t iSourceId = -1;
};
class CSteamProto : public PROTO<CSteamProto>
@@ -137,6 +143,12 @@ class CSteamProto : public PROTO<CSteamProto>
// connection
WebSocket<CSteamProto> *m_ws;
+
+ mir_cs m_csRequestLock;
+ std::map<uint64_t, void *> m_requestInfo;
+
+ void SetRequestInfo(uint64_t, void *);
+ void* GetRequestInfo(uint64_t);
void __cdecl ServerThread(void *);
bool ServerThreadStub(const char *szHost);
@@ -147,8 +159,9 @@ class CSteamProto : public PROTO<CSteamProto>
void WSSend(EMsg msgType, const ProtobufCppMessage &msg);
void WSSendRaw(EMsg msgType, const MBinBuffer &buf);
+ void WSSendAnon(const char *pszServiceName, const ProtobufCppMessage &msg);
void WSSendHeader(EMsg msgType, const CMsgProtoBufHeader &hdr, const ProtobufCppMessage &msg);
- int64_t WSSendService(const char *pszServiceName, const ProtobufCppMessage &msg, bool bAnon = false);
+ void WSSendService(const char *pszServiceName, const ProtobufCppMessage &msg, void *pInfo = nullptr);
// requests
bool SendRequest(HttpRequest *request);
@@ -194,6 +207,24 @@ class CSteamProto : public PROTO<CSteamProto>
INT_PTR __cdecl GetAvatarCaps(WPARAM, LPARAM);
INT_PTR __cdecl GetMyAvatar(WPARAM, LPARAM);
+ // chats
+ void SendGetChatsRequest();
+ void OnGetMyChats(const CChatRoomGetMyChatRoomGroupsResponse &pResponse, const CMsgProtoBufHeader &hdr);
+
+ void SendGetChatHistory(MCONTACT hContact, uint32_t iLastMsgId);
+ void OnGetChatHistory(const CChatRoomGetMessageHistoryResponse &reply, const CMsgProtoBufHeader &hdr);
+
+ void OnGetChatMessage(const CChatRoomIncomingChatMessageNotification &reply, const CMsgProtoBufHeader &hdr);
+ void OnLeftChat(const CChatRoomLeaveChatRoomGroupResponse &reply, const CMsgProtoBufHeader &hdr);
+
+ INT_PTR __cdecl SvcLeaveChat(WPARAM, LPARAM);
+
+ int __cdecl GcMenuHook(WPARAM, LPARAM);
+ int __cdecl GcEventHook(WPARAM, LPARAM);
+
+ void Chat_LogMenu(GCHOOK *gch);
+ void Chat_SendPrivateMessage(GCHOOK *gch);
+
// contacts
void SetAllContactStatuses(int status);
void SetContactStatus(MCONTACT hContact, uint16_t status);
@@ -262,7 +293,7 @@ class CSteamProto : public PROTO<CSteamProto>
mir_cs m_csOwnMessages;
OBJLIST<COwnMessage> m_arOwnMessages;
- int64_t SendFriendMessage(EChatEntryType, int64_t steamId, const char *pszMessage);
+ void SendFriendMessage(EChatEntryType, int64_t steamId, const char *pszMessage, void *pInfo = nullptr);
void OnGotIncomingMessage(const CFriendMessagesIncomingMessageNotification &reply, const CMsgProtoBufHeader &hdr);
void OnMessageSent(const CFriendMessagesSendMessageResponse &reply, const CMsgProtoBufHeader &hdr);
int __cdecl OnPreCreateMessage(WPARAM, LPARAM lParam);
diff --git a/protocols/Steam/src/steam_server.cpp b/protocols/Steam/src/steam_server.cpp
index 41a9ca550e..0714e10e78 100644
--- a/protocols/Steam/src/steam_server.cpp
+++ b/protocols/Steam/src/steam_server.cpp
@@ -73,9 +73,8 @@ void CSteamProto::SendDeviceListRequest()
WSSendService(GetOwnAuthorizedDevices, request);
}
-void CSteamProto::OnGotDeviceList(const CDeviceAuthGetOwnAuthorizedDevicesResponse &pResponse, const CMsgProtoBufHeader &hdr)
+void CSteamProto::OnGotDeviceList(const CDeviceAuthGetOwnAuthorizedDevicesResponse &, const CMsgProtoBufHeader &)
{
-
}
/////////////////////////////////////////////////////////////////////////////////////////
diff --git a/protocols/Steam/src/steam_ws.cpp b/protocols/Steam/src/steam_ws.cpp
index 27d244c45c..41acb5efbb 100644
--- a/protocols/Steam/src/steam_ws.cpp
+++ b/protocols/Steam/src/steam_ws.cpp
@@ -288,16 +288,47 @@ void CSteamProto::WSSendHeader(EMsg msgType, const CMsgProtoBufHeader &hdr, cons
m_ws->sendBinary(hdrbuf.data(), hdrbuf.length());
}
-int64_t CSteamProto::WSSendService(const char *pszServiceName, const ProtobufCppMessage &msg, bool bAnon)
+void CSteamProto::WSSendAnon(const char *pszServiceName, const ProtobufCppMessage &msg)
{
CMsgProtoBufHeader hdr;
hdr.has_client_sessionid = hdr.has_steamid = hdr.has_jobid_source = hdr.has_jobid_target = true;
- if (!bAnon)
- hdr.steamid = m_iSteamId, hdr.client_sessionid = m_iSessionId;
hdr.jobid_source = getRandomInt();
hdr.jobid_target = -1;
hdr.target_job_name = (char *)pszServiceName;
- WSSendHeader(bAnon ? EMsg::ServiceMethodCallFromClientNonAuthed : EMsg::ServiceMethodCallFromClient, hdr, msg);
+ WSSendHeader(EMsg::ServiceMethodCallFromClientNonAuthed, hdr, msg);
+}
+
+void CSteamProto::WSSendService(const char *pszServiceName, const ProtobufCppMessage &msg, void *pInfo)
+{
+ CMsgProtoBufHeader hdr;
+ hdr.has_client_sessionid = hdr.has_steamid = hdr.has_jobid_source = hdr.has_jobid_target = true;
+ hdr.steamid = m_iSteamId, hdr.client_sessionid = m_iSessionId;
+ hdr.jobid_source = getRandomInt();
+ hdr.jobid_target = -1;
+ hdr.target_job_name = (char *)pszServiceName;
+
+ if (pInfo)
+ SetRequestInfo(hdr.jobid_source, pInfo);
- return hdr.jobid_source;
+ WSSendHeader(EMsg::ServiceMethodCallFromClient, hdr, msg);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CSteamProto::SetRequestInfo(uint64_t requestId, void *pInfo)
+{
+ mir_cslock lck(m_csRequestLock);
+ m_requestInfo[requestId] = pInfo;
+}
+
+void* CSteamProto::GetRequestInfo(uint64_t requestId)
+{
+ mir_cslock lck(m_csRequestLock);
+ auto it = m_requestInfo.find(requestId);
+ if (it == m_requestInfo.end())
+ return nullptr;
+
+ void *pRet = it->second;
+ m_requestInfo.erase(it);
+ return pRet;
}