summaryrefslogtreecommitdiff
path: root/protocols/Steam/src
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Steam/src')
-rw-r--r--protocols/Steam/src/main.cpp5
-rw-r--r--protocols/Steam/src/steam_chats.cpp249
-rw-r--r--protocols/Steam/src/steam_contacts.cpp14
-rw-r--r--protocols/Steam/src/steam_history.cpp2
-rw-r--r--protocols/Steam/src/steam_menus.cpp5
-rw-r--r--protocols/Steam/src/steam_proto.cpp11
-rw-r--r--protocols/Steam/src/steam_proto.h11
7 files changed, 197 insertions, 100 deletions
diff --git a/protocols/Steam/src/main.cpp b/protocols/Steam/src/main.cpp
index babfc1b747..db0028325e 100644
--- a/protocols/Steam/src/main.cpp
+++ b/protocols/Steam/src/main.cpp
@@ -139,6 +139,7 @@ void CMPlugin::InitSteamServices()
messageHandlers[EMsg::ClientLogOnResponse] = ServiceResponseHandler(&CSteamProto::OnClientLogon);
messageHandlers[EMsg::ClientFriendsList] = ServiceResponseHandler(&CSteamProto::OnGotFriendList);
messageHandlers[EMsg::ClientPersonaState] = ServiceResponseHandler(&CSteamProto::OnGotFriendInfo);
+ messageHandlers[EMsg::ClientClanState] = ServiceResponseHandler(&CSteamProto::OnGotClanInfo);
messageHandlers[EMsg::ClientPICSProductInfoResponse] = ServiceResponseHandler(&CSteamProto::OnGotAppInfo);
// services from steammessages_auth.steamclient.proto
@@ -174,11 +175,11 @@ void CMPlugin::InitSteamServices()
serviceHandlers[GetMyChatRoomGroups] = ServiceResponseHandler(&CSteamProto::OnGetMyChats);
serviceHandlers[GetChatHistory] = ServiceResponseHandler(&CSteamProto::OnGetChatHistory);
- serviceHandlers[LeaveChatGroup] = ServiceResponseHandler(&CSteamProto::OnLeftChat);
serviceHandlers[DeleteChatMessage] = ServiceResponseHandler(&CSteamProto::OnDoNothing);
serviceHandlers[NotifyIncomingChatMessage] = ServiceResponseHandler(&CSteamProto::OnGetChatMessage);
+ serviceHandlers[NotifyAckChatMessageEcho] = ServiceResponseHandler(&CSteamProto::OnDoNothing);
serviceHandlers[NotifyModifiedChatMessage] = ServiceResponseHandler(&CSteamProto::OnDoNothing);
- serviceHandlers[NotifyChatGroupUserStateChanged] = ServiceResponseHandler(&CSteamProto::OnDoNothing);
+ serviceHandlers[NotifyChatGroupUserStateChanged] = ServiceResponseHandler(&CSteamProto::OnChatChanged);
serviceHandlers[GetOwnAuthorizedDevices] = ServiceResponseHandler(&CSteamProto::OnGotDeviceList);
diff --git a/protocols/Steam/src/steam_chats.cpp b/protocols/Steam/src/steam_chats.cpp
index 0b459100ac..60aebc5487 100644
--- a/protocols/Steam/src/steam_chats.cpp
+++ b/protocols/Steam/src/steam_chats.cpp
@@ -31,45 +31,90 @@ void CSteamProto::OnGetMyChats(const CChatRoomGetMyChatRoomGroupsResponse &reply
std::map<MCONTACT, bool> chatIds;
for (unsigned i = 0; i < reply.n_chat_room_groups; i++) {
auto *pGroup = reply.chat_room_groups[i]->group_summary;
+ ProcessGroupChat(pGroup);
- CMStringW wszGrpName;
- if (pGroup->n_chat_rooms > 1 && pGroup->chat_group_name) {
- wszGrpName = CMStringW(m_wszGroupName) + L"\\" + Utf2T(pGroup->chat_group_name);
- if (!Clist_GroupExists(wszGrpName))
- Clist_GroupCreate(0, wszGrpName);
+ for (unsigned k = 0; k < pGroup->n_chat_rooms; k++) {
+ auto *pChat = pGroup->chat_rooms[k];
+ CMStringW wszId(FORMAT, L"%lld_%lld", pGroup->chat_group_id, pChat->chat_id);
+
+ if (auto *si = Chat_Find(wszId, m_szModuleName))
+ chatIds[si->hContact] = true;
}
+ }
- SESSION_INFO *pOwner = 0;
+ // clean garbage
+ for (auto &cc : AccContacts()) {
+ if (!Contact::IsGroupChat(cc))
+ continue;
- for (unsigned k = 0; k < pGroup->n_chat_rooms; k++) {
- std::vector<uint64_t> ids;
+ if (chatIds.find(cc) == chatIds.end())
+ db_delete_contact(cc, CDF_DEL_CONTACT);
+ }
+}
- auto *pChat = pGroup->chat_rooms[k];
- CMStringW wszId(FORMAT, L"%lld_%lld", 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);
- if (pOwner == 0) {
- if (!si->arStatuses.getCount()) {
- Chat_AddGroup(si, TranslateT("Owner"));
- Chat_AddGroup(si, TranslateT("Participant"));
-
- for (unsigned 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);
+void CSteamProto::OnChatChanged(const ChatRoomClientNotifyChatGroupUserStateChangedNotification &reply, const CMsgProtoBufHeader &hdr)
+{
+ if (hdr.failed())
+ return;
+
+ switch (reply.user_action) {
+ case ECHAT_ROOM_MEMBER_STATE_CHANGE__k_EChatRoomMemberStateChange_Joined:
+ ProcessGroupChat(reply.group_summary);
+ break;
+
+ case ECHAT_ROOM_MEMBER_STATE_CHANGE__k_EChatRoomMemberStateChange_Parted:
+ LeaveGroupChat(reply.chat_group_id);
+ break;
+ }
+}
+
+void CSteamProto::ProcessGroupChat(const CChatRoomGetChatRoomGroupSummaryResponse *pGroup)
+{
+ CMStringW wszGrpName;
+ if (pGroup->n_chat_rooms > 1 && pGroup->chat_group_name) {
+ wszGrpName = CMStringW(m_wszGroupName) + L"\\" + Utf2T(pGroup->chat_group_name);
+ if (!Clist_GroupExists(wszGrpName))
+ Clist_GroupCreate(0, wszGrpName);
+ }
+
+ SESSION_INFO *pOwner = 0;
+
+ for (unsigned k = 0; k < pGroup->n_chat_rooms; k++) {
+ std::vector<uint64_t> ids;
+
+ auto *pChat = pGroup->chat_rooms[k];
+ CMStringW wszId(FORMAT, L"%lld_%lld", 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);
+ if (pOwner == 0) {
+ if (!si->arStatuses.getCount()) {
+ Chat_AddGroup(si, TranslateT("Owner"));
+ Chat_AddGroup(si, TranslateT("Participant"));
+
+ for (unsigned 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 {
+ CMStringA szSetting(FORMAT, "UserInfo_%lld", iSteamId);
+ ptrW szName(g_plugin.getWStringA(szSetting));
+ if (szName)
+ wszNick = szName;
else {
ids.push_back(iSteamId);
{
@@ -78,54 +123,98 @@ void CSteamProto::OnGetMyChats(const CChatRoomGetMyChatRoomGroupsResponse &reply
}
wszNick = L"@" + wszUserId;
}
-
- gce.pszNick.w = wszNick;
- gce.pszStatus.w = (pGroup->top_members[j] == pGroup->accountid_owner) ? TranslateT("Owner") : TranslateT("Participant");
- Chat_Event(&gce);
}
+
+ gce.pszNick.w = wszNick;
+ gce.pszStatus.w = (pGroup->top_members[j] == pGroup->accountid_owner) ? TranslateT("Owner") : TranslateT("Participant");
+ Chat_Event(&gce);
}
- pOwner = si;
}
- else si->pParent = pOwner;
+ pOwner = si;
+ }
+ else si->pParent = pOwner;
- chatIds[si->hContact] = true;
+ setDword(si->hContact, DBKEY_CHAT_ID, pChat->chat_id);
+ if (!wszGrpName.IsEmpty())
+ Clist_SetGroup(si->hContact, wszGrpName);
- setDword(si->hContact, "ChatId", pChat->chat_id);
- if (!wszGrpName.IsEmpty())
- Clist_SetGroup(si->hContact, wszGrpName);
+ if (mir_strlen(pGroup->chat_group_tagline)) {
+ Utf2T wszTopic(pGroup->chat_group_tagline);
+ Chat_SetStatusbarText(si, wszTopic);
- 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);
+ }
- 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);
+
+ if (!ids.empty())
+ SendUserInfoRequest(ids);
+
+ if (pChat->voice_allowed)
+ ExtraIcon_SetIcon(hExtraXStatus, si->hContact, Skin_GetIconHandle(SKINICON_OTHER_SOUND));
+
+ uint32_t dwLastMsgId = getDword(si->hContact, DBKEY_LASTMSG);
+ if (pChat->time_last_message > dwLastMsgId)
+ SendGetChatHistory(si->hContact, dwLastMsgId);
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CSteamProto::OnGotClanInfo(const CMsgClientClanState &reply, const CMsgProtoBufHeader &hdr)
+{
+ if (hdr.failed())
+ return;
- Chat_Control(si, WINDOW_HIDDEN);
- Chat_Control(si, SESSION_ONLINE);
+ CMStringW wszId(FORMAT, L"%lld", reply.steamid_clan);
+ auto *si = Chat_Find(wszId, m_szModuleName);
+ if (si == nullptr) {
+ si = Chat_NewSession(GCW_SERVER, m_szModuleName, wszId, Utf2T(reply.name_info->clan_name));
+ Chat_Control(si, WINDOW_HIDDEN);
+ Chat_Control(si, SESSION_ONLINE);
+ }
- if (!ids.empty())
- SendUserInfoRequest(ids);
+ GCEVENT gce = { si, GC_EVENT_INFORMATION };
+ gce.time = time(0);
- if (pChat->voice_allowed)
- ExtraIcon_SetIcon(hExtraXStatus, si->hContact, Skin_GetIconHandle(SKINICON_OTHER_SOUND));
+ if (reply.name_info) {
+ if (reply.name_info->has_sha_avatar) {
+ CMStringA szHash; szHash.Preallocate((int)reply.name_info->sha_avatar.len * 2);
+ bin2hex(reply.name_info->sha_avatar.data, reply.name_info->sha_avatar.len, szHash.GetBuffer());
+ CheckAvatarChange(si->hContact, szHash);
+ }
- uint32_t dwLastMsgId = getDword(si->hContact, DBKEY_LASTMSG);
- if (pChat->time_last_message > dwLastMsgId)
- SendGetChatHistory(si->hContact, dwLastMsgId);
+ if (reply.user_counts) {
+ CMStringW wszText;
+ auto &C = *reply.user_counts;
+
+ if (C.has_members)
+ wszText.AppendFormat(L"%d %s\r\n", C.members, TranslateT("total members"));
+ if (C.has_online)
+ wszText.AppendFormat(L"%d %s\r\n", C.online, TranslateT("online members"));
+ if (C.has_chatting)
+ wszText.AppendFormat(L"%d %s\r\n", C.chatting, TranslateT("chatting"));
+ if (C.has_in_game)
+ wszText.AppendFormat(L"%d %s\r\n", C.in_game, TranslateT("in game"));
+
+ if (!wszText.IsEmpty()) {
+ gce.pszText.w = wszText;
+ Chat_Event(&gce);
+ }
}
}
- // clean garbage
- for (auto &cc : AccContacts()) {
- if (!Contact::IsGroupChat(cc))
- continue;
+ for (unsigned n = 0; n < reply.n_announcements; n++) {
+ auto *E = reply.announcements[n];
+ Utf2T wszText(E->headline);
- if (chatIds.find(cc) == chatIds.end())
- db_delete_contact(cc, CDF_DEL_CONTACT);
+ gce.time = E->event_time;
+ gce.pszText.w = wszText;
+ Chat_Event(&gce);
}
}
@@ -135,7 +224,7 @@ 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.chat_id = getDword(hContact, DBKEY_CHAT_ID); request.has_chat_id = true;
request.start_time = iLastMsgId; request.has_start_time = true;
WSSendService(GetChatHistory, request, (void*)hContact);
}
@@ -149,7 +238,7 @@ void CSteamProto::OnGetChatHistory(const CChatRoomGetMessageHistoryResponse &rep
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");
+ uint32_t iChatId = getDword(si->hContact, DBKEY_CHAT_ID);
for (int i = (int)reply.n_messages - 1; i >= 0; i--) {
auto *pMsg = reply.messages[i];
@@ -255,25 +344,21 @@ 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));
+ WSSendService(LeaveChatGroup, request);
return 0;
}
-void CSteamProto::OnLeftChat(const CChatRoomLeaveChatRoomGroupResponse&, const CMsgProtoBufHeader &hdr)
+void CSteamProto::LeaveGroupChat(int64_t chatGroupId)
{
- 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, GetId(cc, "ChatId"));
- if (auto *si = Chat_Find(wszId, m_szModuleName))
- Chat_Terminate(si);
+ for (auto &cc : AccContacts()) {
+ if (!Contact::IsGroupChat(cc) || GetId(cc, DBKEY_STEAM_ID) != chatGroupId)
+ continue;
- db_delete_contact(cc);
- }
+ CMStringW wszId(FORMAT, L"%lld_%d", chatGroupId, getDword(cc, DBKEY_CHAT_ID));
+ if (auto *si = Chat_Find(wszId, m_szModuleName))
+ Chat_Terminate(si);
- delete pGroupId;
+ db_delete_contact(cc, CDF_FROM_SERVER);
}
}
@@ -304,7 +389,7 @@ int CSteamProto::GcEventHook(WPARAM, LPARAM lParam)
CChatRoomSendChatMessageRequest request;
request.chat_group_id = _wtoi64(si->ptszID); request.has_chat_group_id = true;
- request.chat_id = getDword(si->hContact, "ChatId"); request.has_chat_id = true;
+ request.chat_id = getDword(si->hContact, DBKEY_CHAT_ID); request.has_chat_id = true;
request.echo_to_sender = request.has_echo_to_sender = true;
request.message = szText;
WSSendService(SendChatMessage, request);
diff --git a/protocols/Steam/src/steam_contacts.cpp b/protocols/Steam/src/steam_contacts.cpp
index d751f62c78..f34886c723 100644
--- a/protocols/Steam/src/steam_contacts.cpp
+++ b/protocols/Steam/src/steam_contacts.cpp
@@ -85,9 +85,17 @@ void CSteamProto::OnGotFriendInfo(const CMsgClientPersonaState &reply, const CMs
}
}
- auto hContact = GetContact(F->friendid);
- if (!si && !hContact && F->friendid != m_iSteamId)
- hContact = AddContact(F->friendid);
+ MCONTACT hContact = GetContact(F->friendid);
+ if (!hContact) {
+ CMStringA szId(FORMAT, "%lld", F->friendid);
+ if (F->player_name && F->player_name != szId) {
+ szId.Format("UserInfo_%lld", F->friendid);
+ g_plugin.setUString(0, szId, F->player_name);
+ }
+
+ if (!si) // don't create contacts for all that slack
+ continue;
+ }
// set name
if (F->player_name) {
diff --git a/protocols/Steam/src/steam_history.cpp b/protocols/Steam/src/steam_history.cpp
index b3c409c71d..251ee89b22 100644
--- a/protocols/Steam/src/steam_history.cpp
+++ b/protocols/Steam/src/steam_history.cpp
@@ -15,7 +15,7 @@ INT_PTR CSteamProto::SvcLoadServerHistory(WPARAM hContact, LPARAM)
if (Contact::IsGroupChat(hContact)) {
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.chat_id = getDword(hContact, DBKEY_CHAT_ID); request.has_chat_id = true;
request.max_count = 100; request.has_max_count = true;
WSSendService(GetChatHistory, request, (void *)hContact);
}
diff --git a/protocols/Steam/src/steam_menus.cpp b/protocols/Steam/src/steam_menus.cpp
index 1926c27179..110cb8f10a 100644
--- a/protocols/Steam/src/steam_menus.cpp
+++ b/protocols/Steam/src/steam_menus.cpp
@@ -1,6 +1,5 @@
#include "stdafx.h"
-int CSteamProto::hChooserMenu;
HGENMENU CSteamProto::contactMenuItems[CMI_MAX];
INT_PTR CSteamProto::AuthRequestCommand(WPARAM hContact, LPARAM)
@@ -92,10 +91,6 @@ void CSteamProto::OnInitStatusMenu()
void CSteamProto::InitMenus()
{
- hChooserMenu = Menu_AddObject("SteamAccountChooser", LPGEN("Steam menu chooser"), nullptr, "Steam/MenuChoose");
-
- //////////////////////////////////////////////////////////////////////////////////////
- // Contact menu initialization
CMenuItem mi(&g_plugin);
mi.flags = CMIF_UNICODE;
diff --git a/protocols/Steam/src/steam_proto.cpp b/protocols/Steam/src/steam_proto.cpp
index 42d0004b64..442fd8cfee 100644
--- a/protocols/Steam/src/steam_proto.cpp
+++ b/protocols/Steam/src/steam_proto.cpp
@@ -294,12 +294,15 @@ HANDLE CSteamProto::GetAwayMsg(MCONTACT hContact)
/////////////////////////////////////////////////////////////////////////////////////////
-bool CSteamProto::OnContactDeleted(MCONTACT hContact, uint32_t)
+bool CSteamProto::OnContactDeleted(MCONTACT hContact, uint32_t flags)
{
- // remove only authorized contacts
+ // react only to the contact deletions from Miranda
+ if (flags & CDF_FROM_SERVER)
+ return true;
+
if (Contact::IsGroupChat(hContact))
SvcLeaveChat(hContact, 0);
- else if (!getByte(hContact, "Auth"))
+ else if (!getByte(hContact, "Auth")) // remove only authorized contacts
SendUserRemoveRequest(hContact);
return true;
@@ -329,7 +332,7 @@ void CSteamProto::OnMarkRead(MCONTACT hContact, MEVENT hDbEvent)
if (Contact::IsGroupChat(hContact)) {
CChatRoomAckChatMessageNotification 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.chat_id = getDword(hContact, DBKEY_CHAT_ID); request.has_chat_id = true;
request.timestamp = dbei.iTimestamp; request.has_timestamp = true;
WSSendService(AckChatMessage, request);
}
diff --git a/protocols/Steam/src/steam_proto.h b/protocols/Steam/src/steam_proto.h
index 15af1e7059..a158011cd2 100644
--- a/protocols/Steam/src/steam_proto.h
+++ b/protocols/Steam/src/steam_proto.h
@@ -14,6 +14,7 @@
#define DBKEY_CLIENT_ID "ClientID"
#define DBKEY_STEAM_ID "SteamID"
+#define DBKEY_CHAT_ID "ChatId"
#define DBKEY_ACCOUNT_NAME "Username"
// Steam services
@@ -38,8 +39,8 @@
#define AckChatMessage "ChatRoom.AckChatMessage#1"
#define DeleteChatMessage "ChatRoom.DeleteChatMessages#1"
-
#define NotifyIncomingChatMessage "ChatRoomClient.NotifyIncomingChatMessage#1"
+#define NotifyAckChatMessageEcho "ChatRoomClient.NotifyAckChatMessageEcho#1"
#define NotifyModifiedChatMessage "ChatRoomClient.NotifyChatMessageModified#1"
#define NotifyChatGroupUserStateChanged "ChatRoomClient.NotifyChatGroupUserStateChanged#1"
@@ -241,11 +242,16 @@ class CSteamProto : public PROTO<CSteamProto>
void SendGetChatsRequest();
void OnGetMyChats(const CChatRoomGetMyChatRoomGroupsResponse &pResponse, const CMsgProtoBufHeader &hdr);
+ void OnGotClanInfo(const CMsgClientClanState &reply, const CMsgProtoBufHeader &hdr);
+
void SendGetChatHistory(MCONTACT hContact, uint32_t iLastMsgId);
void OnGetChatHistory(const CChatRoomGetMessageHistoryResponse &reply, const CMsgProtoBufHeader &hdr);
+ void OnChatChanged(const ChatRoomClientNotifyChatGroupUserStateChangedNotification &reply, const CMsgProtoBufHeader &hdr);
+ void ProcessGroupChat(const CChatRoomGetChatRoomGroupSummaryResponse *pGroup);
+ void LeaveGroupChat(int64_t chatGroupId);
+
void OnGetChatMessage(const CChatRoomIncomingChatMessageNotification &reply, const CMsgProtoBufHeader &hdr);
- void OnLeftChat(const CChatRoomLeaveChatRoomGroupResponse &reply, const CMsgProtoBufHeader &hdr);
INT_PTR __cdecl SvcLeaveChat(WPARAM, LPARAM);
@@ -303,7 +309,6 @@ class CSteamProto : public PROTO<CSteamProto>
void OnGotHistoryMessages(const CMsgClientChatGetFriendMessageHistoryResponse &reply, const CMsgProtoBufHeader &hdr);
// menus
- static int hChooserMenu;
static HGENMENU contactMenuItems[CMI_MAX];
INT_PTR __cdecl AuthRequestCommand(WPARAM, LPARAM);