diff options
author | George Hazan <george.hazan@gmail.com> | 2025-05-03 14:39:43 +0300 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2025-05-03 14:39:43 +0300 |
commit | d5fea0729fa274cf6697d376d8aaa45fd1d20523 (patch) | |
tree | 1c13b55612e2d79b3cfd42020ca282eca65ee574 /protocols/Steam/src | |
parent | 3450ef0b5b99eaad7694eeddd7556485effeafff (diff) |
fixes #4905 completely
Diffstat (limited to 'protocols/Steam/src')
-rw-r--r-- | protocols/Steam/src/main.cpp | 5 | ||||
-rw-r--r-- | protocols/Steam/src/steam_chats.cpp | 249 | ||||
-rw-r--r-- | protocols/Steam/src/steam_contacts.cpp | 14 | ||||
-rw-r--r-- | protocols/Steam/src/steam_history.cpp | 2 | ||||
-rw-r--r-- | protocols/Steam/src/steam_menus.cpp | 5 | ||||
-rw-r--r-- | protocols/Steam/src/steam_proto.cpp | 11 | ||||
-rw-r--r-- | protocols/Steam/src/steam_proto.h | 11 |
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);
|