From 02260169dc542a2134438ec5d24eda2eb146d486 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Fri, 27 Dec 2024 19:22:39 +0300 Subject: Steam: - fixes offline / missing messages fetching; - two HTTP queries removed and replaced with new API calls --- protocols/Steam/src/api/app_info.h | 25 -------- protocols/Steam/src/api/history.h | 18 ------ protocols/Steam/src/main.cpp | 89 +++++++++++++-------------- protocols/Steam/src/stdafx.h | 5 +- protocols/Steam/src/steam_contacts.cpp | 2 +- protocols/Steam/src/steam_history.cpp | 108 +++++++++++++++++++++------------ protocols/Steam/src/steam_messages.cpp | 4 +- protocols/Steam/src/steam_proto.cpp | 6 +- protocols/Steam/src/steam_proto.h | 8 ++- protocols/Steam/src/steam_server.cpp | 14 +++++ protocols/Steam/src/version.h | 2 +- 11 files changed, 143 insertions(+), 138 deletions(-) delete mode 100644 protocols/Steam/src/api/app_info.h delete mode 100644 protocols/Steam/src/api/history.h (limited to 'protocols/Steam/src') diff --git a/protocols/Steam/src/api/app_info.h b/protocols/Steam/src/api/app_info.h deleted file mode 100644 index d8a187d444..0000000000 --- a/protocols/Steam/src/api/app_info.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _STEAM_REQUEST_APP_INFO_H_ -#define _STEAM_REQUEST_APP_INFO_H_ - -struct GetAppInfoRequest : public HttpRequest -{ - GetAppInfoRequest(const char *token, uint32_t appId) : - HttpRequest(REQUEST_GET, "/ISteamGameOAuth/GetAppInfo/v0001") - { - this << CHAR_PARAM("access_token", token) << INT_PARAM("appIds", appId); - } - - //{ - // "apps": [ - // { - // "appid": 271590, - // "name" : "Grand Theft Auto V", - // "iconurl" : "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/271590/1e72f87eb927fa1485e68aefaff23c7fd7178251.jpg", - // "logourl" : "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/271590/e447e82f8b0c67f9e001498503c62f2a187bc609.jpg", - // "logosmallurl" : "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/271590/e447e82f8b0c67f9e001498503c62f2a187bc609_thumb.jpg" - // } - // ] - //} -}; - -#endif //_STEAM_REQUEST_APP_INFO_H_ diff --git a/protocols/Steam/src/api/history.h b/protocols/Steam/src/api/history.h deleted file mode 100644 index d3e4a49988..0000000000 --- a/protocols/Steam/src/api/history.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _STEAM_REQUEST_HISTORY_H_ -#define _STEAM_REQUEST_HISTORY_H_ - -struct GetHistoryMessagesRequest : public HttpRequest -{ - GetHistoryMessagesRequest(const char *token, int64_t steamId, int64_t who, time_t since) : - HttpRequest(REQUEST_GET, "/IFriendMessagesService/GetRecentMessages/v0001") - { - this - << CHAR_PARAM("access_token", token) - << INT64_PARAM("steamid1", steamId) - << INT64_PARAM("steamid2", who) - // Steam somehow doesn't respect too precise start time parameter, so we better request older time and then do own filtering again - << INT64_PARAM("rtime32_start_time", since - 1500); - } -}; - -#endif //_STEAM_REQUEST_HISTORY_H_ diff --git a/protocols/Steam/src/main.cpp b/protocols/Steam/src/main.cpp index 5be2f85902..5c4df55a31 100644 --- a/protocols/Steam/src/main.cpp +++ b/protocols/Steam/src/main.cpp @@ -42,19 +42,19 @@ void CMPlugin::InitSteamServices() messages[EMsg::ClientLogOnResponse] = &cmsg_client_logon_response__descriptor; messages[EMsg::ClientLogOff] = &cmsg_client_log_off__descriptor; messages[EMsg::ClientLoggedOff] = &cmsg_client_logged_off__descriptor; - // messages[EMsg::ClientUpdateMachineAuth] = &cmsg_Client__UpdateMachineAuth; - // messages[EMsg::ClientUpdateMachineAuthResponse] = &cmsg_Client_UpdateMachineAuthResponse; + messages[EMsg::ClientUpdateMachineAuth] = &cmsg_client_update_machine_auth__descriptor; + messages[EMsg::ClientUpdateMachineAuthResponse] = &cmsg_client_update_machine_auth_response__descriptor; messages[EMsg::ClientNewLoginKey] = &cmsg_client_new_login_key__descriptor; messages[EMsg::ClientNewLoginKeyAccepted] = &cmsg_client_new_login_key_accepted__descriptor; messages[EMsg::ClientRequestWebAPIAuthenticateUserNonceResponse] = &cmsg_client_request_web_apiauthenticate_user_nonce_response__descriptor; messages[EMsg::ClientCMList] = &cmsg_client_cmlist__descriptor; - // messages[EMsg::ClientItemAnnouncements] = &cmsg_Client__ItemAnnouncements; - // messages[EMsg::ClientRequestItemAnnouncements] = &cmsg_Client_RequestItemAnnouncements; - // messages[EMsg::ClientCommentNotifications] = &cmsg_Client_CommentNotifications; - // messages[EMsg::ClientRequestCommentNotifications] = &cmsg_Client_RequestCommentNotifications; - // messages[EMsg::ClientUserNotifications] = &cmsg_Client_UserNotifications; - // messages[EMsg::ClientFSOfflineMessageNotification] = &cmsg_Client__OfflineMessageNotification; - // messages[EMsg::ClientFSRequestOfflineMessageCount] = &cmsg_Client_RequestOfflineMessageCount; + messages[EMsg::ClientItemAnnouncements] = &cmsg_client_item_announcements__descriptor; + messages[EMsg::ClientRequestItemAnnouncements] = &cmsg_client_request_item_announcements__descriptor; + messages[EMsg::ClientCommentNotifications] = &cmsg_client_comment_notifications__descriptor; + messages[EMsg::ClientRequestCommentNotifications] = &cmsg_client_request_comment_notifications__descriptor; + messages[EMsg::ClientUserNotifications] = &cmsg_client_user_notifications__descriptor; + messages[EMsg::ClientFSOfflineMessageNotification] = &cmsg_client_offline_message_notification__descriptor; + messages[EMsg::ClientFSRequestOfflineMessageCount] = &cmsg_client_request_offline_message_count__descriptor; messages[EMsg::ClientGamesPlayed] = &cmsg_client_games_played__descriptor; messages[EMsg::ClientGamesPlayedWithDataBlob] = &cmsg_client_games_played__descriptor; messages[EMsg::ClientAccountInfo] = &cmsg_client_account_info__descriptor; @@ -64,17 +64,17 @@ void CMPlugin::InitSteamServices() messages[EMsg::ClientLicenseList] = &cmsg_client_license_list__descriptor; // messages[EMsg::ClientGMSServerQuery] = &cmsg_Client_GMSServerQuery; // messages[EMsg::GMSClientServerQueryResponse] = &cmsg_GMSClientServerQueryResponse; - // messages[EMsg::ClientPICSChangesSinceResponse] = &cmsg_Client_PICSChangesSinceResponse; - // messages[EMsg::ClientPICSProductInfoResponse] = &cmsg_Client_PICSProductInfoResponse; - // messages[EMsg::ClientPICSAccessTokenResponse] = &cmsg_Client_PICSAccessTokenResponse; - // messages[EMsg::EconTrading_InitiateTradeResponse] = &cmsg_Trading_InitiateTradeResponse; - // messages[EMsg::EconTrading_InitiateTradeResult] = &cmsg_Trading_InitiateTradeResponse; - // messages[EMsg::EconTrading_StartSession] = &cmsg_Trading_StartSession; + messages[EMsg::ClientPICSChangesSinceResponse] = &cmsg_client_picschanges_since_response__descriptor; + messages[EMsg::ClientPICSProductInfoResponse] = &cmsg_client_picsproduct_info_response__descriptor; + messages[EMsg::ClientPICSAccessTokenResponse] = &cmsg_client_picsaccess_token_response__descriptor; + messages[EMsg::EconTrading_InitiateTradeResponse] = &cmsg_trading__initiate_trade_request__descriptor; + messages[EMsg::EconTrading_InitiateTradeResult] = &cmsg_trading__initiate_trade_response__descriptor; + messages[EMsg::EconTrading_StartSession] = &cmsg_trading__start_session__descriptor; messages[EMsg::ClientChangeStatus] = &cmsg_client_change_status__descriptor; messages[EMsg::ClientAddFriendResponse] = &cmsg_client_add_friend_response__descriptor; messages[EMsg::ClientRemoveFriend] = &cmsg_client_remove_friend__descriptor; - // messages[EMsg::ClientFSGetFriendsSteamLevels] = &cmsg_Client_FSGetFriendsSteamLevels; - // messages[EMsg::ClientFSGetFriendsSteamLevelsResponse] = &cmsg_Client_FSGetFriendsSteamLevelsResponse; + messages[EMsg::ClientFSGetFriendsSteamLevels] = &cmsg_client_fsget_friends_steam_levels__descriptor; + messages[EMsg::ClientFSGetFriendsSteamLevelsResponse] = &cmsg_client_fsget_friends_steam_levels_response__descriptor; messages[EMsg::ClientPersonaState] = &cmsg_client_persona_state__descriptor; messages[EMsg::ClientClanState] = &cmsg_client_clan_state__descriptor; messages[EMsg::ClientFriendsList] = &cmsg_client_friends_list__descriptor; @@ -83,8 +83,8 @@ void CMPlugin::InitSteamServices() messages[EMsg::ClientChatInvite] = &cmsg_client_chat_invite__descriptor; messages[EMsg::ClientFriendMsgIncoming] = &cmsg_client_friend_msg_incoming__descriptor; messages[EMsg::ClientFriendMsgEchoToSender] = &cmsg_client_friend_msg_incoming__descriptor; - // messages[EMsg::ClientFSGetFriendMessageHistory] = &cmsg_Client_ChatGetFriendMessageHistory; - // messages[EMsg::ClientFSGetFriendMessageHistoryResponse] = &cmsg_Client_ChatGetFriendMessageHistoryResponse; + messages[EMsg::ClientFSGetFriendMessageHistory] = &cmsg_client_chat_get_friend_message_history__descriptor; + messages[EMsg::ClientFSGetFriendMessageHistoryResponse] = &cmsg_client_chat_get_friend_message_history_response__descriptor; messages[EMsg::ClientFriendsGroupsList] = &cmsg_client_friends_groups_list__descriptor; messages[EMsg::AMClientCreateFriendsGroup] = &cmsg_client_create_friends_group__descriptor; messages[EMsg::AMClientCreateFriendsGroupResponse] = &cmsg_client_create_friends_group_response__descriptor; @@ -99,12 +99,12 @@ void CMPlugin::InitSteamServices() messages[EMsg::ClientPlayerNicknameList] = &cmsg_client_player_nickname_list__descriptor; messages[EMsg::AMClientSetPlayerNickname] = &cmsg_client_set_player_nickname__descriptor; messages[EMsg::AMClientSetPlayerNicknameResponse] = &cmsg_client_set_player_nickname_response__descriptor; - // messages[EMsg::ClientRegisterKey] = &cmsg_Client_RegisterKey; - // messages[EMsg::ClientPurchaseResponse] = &cmsg_Client_PurchaseResponse; - // messages[EMsg::ClientRequestFreeLicense] = &cmsg_Client_RequestFreeLicense; - // messages[EMsg::ClientRequestFreeLicenseResponse] = &cmsg_Client_RequestFreeLicenseResponse; - // messages[EMsg::ClientGetNumberOfCurrentPlayersDP] = &cmsg_DPGetNumberOfCurrentPlayers; - // messages[EMsg::ClientGetNumberOfCurrentPlayersDPResponse] = &cmsg_DPGetNumberOfCurrentPlayersResponse; + messages[EMsg::ClientRegisterKey] = &cmsg_client_register_key__descriptor; + messages[EMsg::ClientPurchaseResponse] = &cmsg_client_purchase_response__descriptor; + messages[EMsg::ClientRequestFreeLicense] = &cmsg_client_request_free_license__descriptor; + messages[EMsg::ClientRequestFreeLicenseResponse] = &cmsg_client_request_free_license_response__descriptor; + messages[EMsg::ClientGetNumberOfCurrentPlayersDP] = &cmsg_dpget_number_of_current_players__descriptor; + messages[EMsg::ClientGetNumberOfCurrentPlayersDPResponse] = &cmsg_dpget_number_of_current_players_response__descriptor; messages[EMsg::ClientGetAppOwnershipTicketResponse] = &cmsg_client_get_app_ownership_ticket_response__descriptor; messages[EMsg::ClientGameConnectTokens] = &cmsg_client_game_connect_tokens__descriptor; messages[EMsg::ClientAuthList] = &cmsg_client_auth_list__descriptor; @@ -112,27 +112,27 @@ void CMPlugin::InitSteamServices() messages[EMsg::ClientTicketAuthComplete] = &cmsg_client_ticket_auth_complete__descriptor; messages[EMsg::ClientRequestEncryptedAppTicket] = &cmsg_client_request_encrypted_app_ticket__descriptor; messages[EMsg::ClientRequestEncryptedAppTicketResponse] = &cmsg_client_request_encrypted_app_ticket_response__descriptor; - // messages[EMsg::ClientCurrentUIMode] = &cmsg_Client_UIMode; - // messages[EMsg::ClientVanityURLChangedNotification] = &cmsg_Client_VanityURLChangedNotification; - // messages[EMsg::ClientAMGetPersonaNameHistory] = &cmsg_Client_AMGetPersonaNameHistory; - // messages[EMsg::ClientAMGetPersonaNameHistoryResponse] = &cmsg_Client_AMGetPersonaNameHistoryResponse; - // messages[EMsg::ClientGetCDNAuthToken] = &cmsg_Client_GetCDNAuthToken; - // messages[EMsg::ClientGetCDNAuthTokenResponse] = &cmsg_Client_GetCDNAuthTokenResponse; - // messages[EMsg::ClientKickPlayingSession] = &cmsg_Client_KickPlayingSession; - // messages[EMsg::ClientPlayingSessionState] = &cmsg_Client_PlayingSessionState; - // messages[EMsg::ClientToGC] = &cmsg_GCClient; - // messages[EMsg::ClientFromGC] = &cmsg_GCClient; - // messages[EMsg::ClientRichPresenceUpload] = &cmsg_Client_RichPresenceUpload; - // messages[EMsg::ClientRichPresenceRequest] = &cmsg_Client_RichPresenceRequest; - // messages[EMsg::ClientRichPresenceInfo] = &cmsg_Client_RichPresenceInfo; + messages[EMsg::ClientCurrentUIMode] = &cmsg_client_uimode__descriptor; + messages[EMsg::ClientVanityURLChangedNotification] = &cmsg_client_vanity_urlchanged_notification__descriptor; + messages[EMsg::ClientAMGetPersonaNameHistory] = &cmsg_client_amget_persona_name_history__descriptor; + messages[EMsg::ClientAMGetPersonaNameHistoryResponse] = &cmsg_client_amget_persona_name_history_response__descriptor; + messages[EMsg::ClientGetCDNAuthToken] = &cmsg_client_get_cdnauth_token__descriptor; + messages[EMsg::ClientGetCDNAuthTokenResponse] = &cmsg_client_get_cdnauth_token_response__descriptor; + messages[EMsg::ClientKickPlayingSession] = &cmsg_client_kick_playing_session__descriptor; + messages[EMsg::ClientPlayingSessionState] = &cmsg_client_playing_session_state__descriptor; + messages[EMsg::ClientToGC] = &cmsg_gcclient__descriptor; + messages[EMsg::ClientFromGC] = &cmsg_gcclient__descriptor; + messages[EMsg::ClientRichPresenceUpload] = &cmsg_client_rich_presence_upload__descriptor; + messages[EMsg::ClientRichPresenceRequest] = &cmsg_client_rich_presence_request__descriptor; + messages[EMsg::ClientRichPresenceInfo] = &cmsg_client_rich_presence_info__descriptor; messages[EMsg::ClientGetEmoticonList] = &cmsg_client_get_emoticon_list__descriptor; messages[EMsg::ClientEmoticonList] = &cmsg_client_emoticon_list__descriptor; - // messages[EMsg::ClientGetAuthorizedDevicesResponse] = &cmsg_Client_GetAuthorizedDevices; - // messages[EMsg::ClientAuthorizeLocalDeviceRequest] = &cmsg_Client_AuthorizeLocalDeviceRequest; - // messages[EMsg::ClientAuthorizeLocalDeviceResponse] = &cmsg_Client_AuthorizeLocalDevice; - // messages[EMsg::ClientDeauthorizeDeviceRequest] = &cmsg_Client_DeauthorizeDeviceRequest; - // messages[EMsg::ClientDeauthorizeDevice] = &cmsg_Client_DeauthorizeDevice; - // messages[EMsg::ClientUseLocalDeviceAuthorizations] = &cmsg_Client_UseLocalDeviceAuthorizations; + messages[EMsg::ClientGetAuthorizedDevicesResponse] = &cmsg_client_get_authorized_devices__descriptor; + messages[EMsg::ClientAuthorizeLocalDeviceRequest] = &cmsg_client_authorize_local_device_request__descriptor; + messages[EMsg::ClientAuthorizeLocalDeviceResponse] = &cmsg_client_authorize_local_device__descriptor; + messages[EMsg::ClientDeauthorizeDeviceRequest] = &cmsg_client_deauthorize_device_request__descriptor; + messages[EMsg::ClientDeauthorizeDevice] = &cmsg_client_deauthorize_device__descriptor; + messages[EMsg::ClientUseLocalDeviceAuthorizations] = &cmsg_client_use_local_device_authorizations__descriptor; // message handlers messageHandlers[EMsg::ClientLoggedOff] = ServiceResponseHandler(&CSteamProto::OnClientLogoff); @@ -164,6 +164,7 @@ void CMPlugin::InitSteamServices() serviceHandlers[FriendSendMessage] = ServiceResponseHandler(&CSteamProto::OnMessageSent); serviceHandlers[FriendGetActiveSessions] = ServiceResponseHandler(&CSteamProto::OnGotConversations); + serviceHandlers[FriendGetRecentMessages] = ServiceResponseHandler(&CSteamProto::OnGotRecentMessages); serviceHandlers[FriendGetIncomingMessage] = ServiceResponseHandler(&CSteamProto::OnGotIncomingMessage); serviceHandlers[NotificationReceived] = ServiceResponseHandler(&CSteamProto::OnGotNotification); diff --git a/protocols/Steam/src/stdafx.h b/protocols/Steam/src/stdafx.h index 0ba41ec036..7dbc349381 100644 --- a/protocols/Steam/src/stdafx.h +++ b/protocols/Steam/src/stdafx.h @@ -42,13 +42,14 @@ #include "protobuf-c/steammessages_auth.steamclient.pb-c.h" #include "protobuf-c/steammessages_chat.steamclient.pb-c.h" #include "protobuf-c/steammessages_clientserver.pb-c.h" +#include "protobuf-c/steammessages_clientserver_2.pb-c.h" +#include "protobuf-c/steammessages_clientserver_appinfo.pb-c.h" #include "protobuf-c/steammessages_clientserver_login.pb-c.h" #include "protobuf-c/steammessages_friendmessages.steamclient.pb-c.h" #include "protobuf-c/steammessages_notifications.steamclient.pb-c.h" #include "proto.h" #define MODULE "Steam" -#define DB_KEY_LASTMSGTS "LastMessageTS" #define STEAM_API_TIMEOUT 20 #define STEAM_API_IDLEOUT_AWAY 600 @@ -74,11 +75,9 @@ extern HANDLE hExtraXStatus; #include "steam_proto.h" #include "steam_utils.h" -#include "api/app_info.h" #include "api/avatar.h" #include "api/captcha.h" #include "api/friend.h" -#include "api/history.h" #include "api/pending.h" #include "api/search.h" #include "api/session.h" diff --git a/protocols/Steam/src/steam_contacts.cpp b/protocols/Steam/src/steam_contacts.cpp index 5886f262c4..da654dfa3e 100644 --- a/protocols/Steam/src/steam_contacts.cpp +++ b/protocols/Steam/src/steam_contacts.cpp @@ -171,7 +171,7 @@ void CSteamProto::OnGotFriendInfo(const CMsgClientPersonaState &reply, const CMs CMStringW message(gameInfo); if (gameId && message.IsEmpty()) - SendRequest(new GetAppInfoRequest(m_szAccessToken, gameId), &CSteamProto::OnGotAppInfo, (void *)hContact); + SendAppInfoRequest(gameId); else { if (!gameId) message.Append(TranslateT(" (Non-Steam)")); diff --git a/protocols/Steam/src/steam_history.cpp b/protocols/Steam/src/steam_history.cpp index 8158c9e4c6..616f54c9df 100644 --- a/protocols/Steam/src/steam_history.cpp +++ b/protocols/Steam/src/steam_history.cpp @@ -1,66 +1,94 @@ #include "stdafx.h" -void CSteamProto::OnGotConversations(const CFriendsMessagesGetActiveMessageSessionsResponse &reply, const CMsgProtoBufHeader &hdr) +void CSteamProto::SendHistoryRequest(uint64_t accountId, uint32_t startTime) +{ + CFriendMessagesGetRecentMessagesRequest request; + request.steamid1 = m_iSteamId; request.has_steamid1 = true; + request.steamid2 = AccountIdToSteamId(accountId); request.has_steamid2 = true; + request.rtime32_start_time = startTime; request.has_rtime32_start_time = true; + WSSendService(FriendGetRecentMessages, request); +} + +void CSteamProto::OnGotRecentMessages(const CFriendMessagesGetRecentMessagesResponse &reply, const CMsgProtoBufHeader &hdr) { if (hdr.failed()) return; - for (int i=0; i < reply.n_message_sessions; i++) { - auto *session = reply.message_sessions[i]; + for (int i = 0; i < reply.n_messages; i++) { + auto *pMsg = reply.messages[i]; + auto steamId = AccountIdToSteamId(pMsg->accountid); - uint64_t steamId = session->accountid_friend; MCONTACT hContact = GetContact(steamId); if (!hContact) continue; - // Don't load any messages when we don't have lastMessageTS, as it may cause duplicates - time_t storedMessageTS = getDword(hContact, DB_KEY_LASTMSGTS); - if (storedMessageTS == 0) - continue; + char szMsgId[100]; + itoa(pMsg->timestamp, szMsgId, 10); - time_t lastMessageTS = session->last_message; - if (lastMessageTS > storedMessageTS) - SendRequest(new GetHistoryMessagesRequest(m_szAccessToken, m_iSteamId, steamId, storedMessageTS), &CSteamProto::OnGotHistoryMessages, (void*)hContact); + DB::EventInfo dbei(pMsg->has_timestamp ? db_event_getById(m_szModuleName, szMsgId) : 0); + dbei.flags = DBEF_UTF; + if (steamId == m_iSteamId) + dbei.flags |= DBEF_SENT; + dbei.cbBlob = (int)mir_strlen(pMsg->message); + dbei.pBlob = mir_strdup(pMsg->message); + dbei.timestamp = pMsg->has_timestamp ? pMsg->timestamp : time(0); + dbei.szId = szMsgId; + + if (dbei.getEvent()) + db_event_edit(dbei.getEvent(), &dbei, true); + else + ProtoChainRecvMsg(hContact, dbei); } } -void CSteamProto::OnGotHistoryMessages(const JSONNode &root, void *arg) +void CSteamProto::OnGotConversations(const CFriendsMessagesGetActiveMessageSessionsResponse &reply, const CMsgProtoBufHeader &hdr) { - if (root.isnull()) + if (hdr.failed()) return; - MCONTACT hContact = UINT_PTR(arg); - time_t storedMessageTS = getDword(hContact, DB_KEY_LASTMSGTS); - time_t newTS = storedMessageTS; - - const JSONNode &response = root["response"]; - const JSONNode &messages = response["messages"]; - for (size_t i = messages.size(); i > 0; i--) { - const JSONNode &message = messages[i - 1]; - - long long accountId = _wtoi64(message["accountid"].as_mstring()); - uint64_t steamId = AccountIdToSteamId(accountId); - - json_string text = message["message"].as_string(); - - time_t timestamp = _wtoi64(message["timestamp"].as_mstring()); + for (int i=0; i < reply.n_message_sessions; i++) { + auto *session = reply.message_sessions[i]; - // Ignore already existing messages - if (timestamp <= storedMessageTS) + uint64_t steamId = AccountIdToSteamId(session->accountid_friend); + MCONTACT hContact = GetContact(steamId); + if (!hContact) continue; - DB::EventInfo dbei; - dbei.timestamp = timestamp; - dbei.pBlob = (char *)text.c_str(); + time_t storedMessageTS = getDword(hContact, DBKEY_LASTMSG); + if (session->last_message > storedMessageTS) + SendHistoryRequest(steamId, storedMessageTS); + } +} - if (steamId == m_iSteamId) - dbei.flags = DBEF_SENT; +void CSteamProto::OnGotHistoryMessages(const CMsgClientChatGetFriendMessageHistoryResponse &reply, const CMsgProtoBufHeader &hdr) +{ + if (hdr.failed()) + return; - RecvMsg(hContact, dbei); + MCONTACT hContact = GetContact(reply.steamid); + if (!hContact) + return; - if (timestamp > newTS) - newTS = timestamp; + for (int i = 0; i < reply.n_messages; i++) { + auto *pMsg = reply.messages[i]; + + char szMsgId[100]; + itoa(pMsg->timestamp, szMsgId, 10); + + DB::EventInfo dbei(pMsg->has_timestamp ? db_event_getById(m_szModuleName, szMsgId) : 0); + dbei.flags = DBEF_UTF; + if (pMsg->has_unread && !pMsg->unread) + dbei.flags |= DBEF_READ; + if (pMsg->accountid == m_iSteamId) + dbei.flags |= DBEF_SENT; + dbei.cbBlob = (int)mir_strlen(pMsg->message); + dbei.pBlob = mir_strdup(pMsg->message); + dbei.timestamp = pMsg->has_timestamp ? pMsg->timestamp : time(0); + dbei.szId = szMsgId; + + if (dbei.getEvent()) + db_event_edit(dbei.getEvent(), &dbei, true); + else + ProtoChainRecvMsg(hContact, dbei); } - - setDword(hContact, DB_KEY_LASTMSGTS, newTS); } diff --git a/protocols/Steam/src/steam_messages.cpp b/protocols/Steam/src/steam_messages.cpp index f41ec3b84f..8c8cfab442 100644 --- a/protocols/Steam/src/steam_messages.cpp +++ b/protocols/Steam/src/steam_messages.cpp @@ -32,8 +32,8 @@ void CSteamProto::OnMessageSent(const CFriendMessagesSendMessageResponse &reply, } 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); + if (timestamp > getDword(tmp.hContact, DBKEY_LASTMSG)) + setDword(tmp.hContact, DBKEY_LASTMSG, timestamp); tmp.timestamp = timestamp; ProtoBroadcastAck(tmp.hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)tmp.iMessageId, 0); diff --git a/protocols/Steam/src/steam_proto.cpp b/protocols/Steam/src/steam_proto.cpp index cd95b072e2..a21247bf90 100644 --- a/protocols/Steam/src/steam_proto.cpp +++ b/protocols/Steam/src/steam_proto.cpp @@ -48,10 +48,10 @@ CSteamProto::CSteamProto(const char *protoName, const wchar_t *userName) : debugLogA(__FUNCTION__":Setting protocol / module name to '%s'", m_szModuleName); - if (uint32_t iGlobalValue = getDword(DB_KEY_LASTMSGTS)) { + if (uint32_t iGlobalValue = getDword(DBKEY_LASTMSG)) { for (auto &cc : AccContacts()) - setDword(cc, DB_KEY_LASTMSGTS, iGlobalValue); - delSetting(DB_KEY_LASTMSGTS); + setDword(cc, DBKEY_LASTMSG, iGlobalValue); + delSetting(DBKEY_LASTMSG); } } diff --git a/protocols/Steam/src/steam_proto.h b/protocols/Steam/src/steam_proto.h index 02a613c617..14d03366b2 100644 --- a/protocols/Steam/src/steam_proto.h +++ b/protocols/Steam/src/steam_proto.h @@ -11,6 +11,7 @@ #define STEAM_MODULE "Steam" #define DBKEY_HOSTS_COUNT "HostsCount" #define DBKEY_HOSTS_DATE "HostsDate" +#define DBKEY_LASTMSG "LastMessageTS" #define DBKEY_CLIENT_ID "ClientID" #define DBKEY_STEAM_ID "SteamID" @@ -24,6 +25,7 @@ #define FriendSendMessage "FriendMessages.SendMessage#1" #define FriendGetActiveSessions "FriendMessages.GetActiveMessageSessions#1" +#define FriendGetRecentMessages "FriendMessages.GetRecentMessages#1" #define FriendGetIncomingMessage "FriendMessagesClient.IncomingMessage#1" #define NotificationReceived "SteamNotificationClient.NotificationsReceived#1" @@ -152,6 +154,7 @@ class CSteamProto : public PROTO bool SendRequest(HttpRequest *request, HttpCallback callback, void *param = nullptr); bool SendRequest(HttpRequest *request, JsonCallback callback, void *param = nullptr); + void SendAppInfoRequest(uint32_t appId); void SendHeartBeat(); void SendLogout(); void SendPersonaStatus(int iStatus); @@ -225,8 +228,11 @@ class CSteamProto : public PROTO void OnSearchByNameStarted(const MHttpResponse &response, void *arg); // history + void SendHistoryRequest(uint64_t accountId, uint32_t startTime); + void OnGotRecentMessages(const CFriendMessagesGetRecentMessagesResponse &reply, const CMsgProtoBufHeader &hdr); + void OnGotConversations(const CFriendsMessagesGetActiveMessageSessionsResponse &reply, const CMsgProtoBufHeader &hdr); - void OnGotHistoryMessages(const JSONNode &root, void *); + void OnGotHistoryMessages(const CMsgClientChatGetFriendMessageHistoryResponse &reply, const CMsgProtoBufHeader &hdr); // menus static int hChooserMenu; diff --git a/protocols/Steam/src/steam_server.cpp b/protocols/Steam/src/steam_server.cpp index 3efa43764b..c0f7e8b7fe 100644 --- a/protocols/Steam/src/steam_server.cpp +++ b/protocols/Steam/src/steam_server.cpp @@ -32,6 +32,20 @@ void CSteamProto::OnGotNotification(const CSteamNotificationNotificationsReceive ///////////////////////////////////////////////////////////////////////////////////////// +void CSteamProto::SendAppInfoRequest(uint32_t appId) +{ + CMsgClientPICSProductInfoRequest__AppInfo appInfo; + appInfo.appid = appId; appInfo.has_appid = true; + auto *pInfo = &appInfo; + + CMsgClientPICSProductInfoRequest request; + request.n_apps = 1; + request.apps = &pInfo; + WSSend(EMsg::ClientPICSProductInfoRequest, request); +} + +///////////////////////////////////////////////////////////////////////////////////////// + void CSteamProto::SendPersonaStatus(int status) { CMsgClientChangeStatus request; diff --git a/protocols/Steam/src/version.h b/protocols/Steam/src/version.h index 1b4c2a16c8..3ab560904b 100644 --- a/protocols/Steam/src/version.h +++ b/protocols/Steam/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 96 #define __RELEASE_NUM 1 -#define __BUILD_NUM 2 +#define __BUILD_NUM 3 #include -- cgit v1.2.3