Merge commit '70b71d569b81c66b25f8f77d9536b1d41fbf091d'

This commit is contained in:
Andrea Cavalli 2021-03-21 01:04:45 +01:00
commit 78291a96d4
49 changed files with 2484 additions and 671 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
project(TDLib VERSION 1.7.2 LANGUAGES CXX C)
project(TDLib VERSION 1.7.3 LANGUAGES CXX C)
if (NOT DEFINED CMAKE_MODULE_PATH)
set(CMAKE_MODULE_PATH "")
@ -325,6 +325,7 @@ set(TDLIB_SOURCE
td/telegram/Global.cpp
td/telegram/GroupCallManager.cpp
td/telegram/GroupCallParticipant.cpp
td/telegram/GroupCallParticipantOrder.cpp
td/telegram/HashtagHints.cpp
td/telegram/InlineQueriesManager.cpp
td/telegram/InputDialogId.cpp
@ -505,6 +506,7 @@ set(TDLIB_SOURCE
td/telegram/GroupCallId.h
td/telegram/GroupCallManager.h
td/telegram/GroupCallParticipant.h
td/telegram/GroupCallParticipantOrder.h
td/telegram/HashtagHints.h
td/telegram/InlineQueriesManager.h
td/telegram/InputDialogId.h

View File

@ -218,7 +218,7 @@ target_link_libraries(YourTarget PRIVATE Td::TdStatic)
Or you could install `TDLib` and then reference it in your CMakeLists.txt like this:
```
find_package(Td 1.7.2 REQUIRED)
find_package(Td 1.7.3 REQUIRED)
target_link_libraries(YourTarget PRIVATE Td::TdStatic)
```
See [example/cpp/CMakeLists.txt](https://github.com/tdlib/td/tree/master/example/cpp/CMakeLists.txt).

View File

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
project(TdExample VERSION 1.0 LANGUAGES CXX)
find_package(Td 1.7.2 REQUIRED)
find_package(Td 1.7.3 REQUIRED)
add_executable(tdjson_example tdjson_example.cpp)
target_link_libraries(tdjson_example PRIVATE Td::TdJson)

View File

@ -66,8 +66,8 @@ class TdExample {
} else if (!are_authorized_) {
process_response(client_manager_->receive(10));
} else {
std::cout << "Enter action [q] quit [u] check for updates and request results [c] show chats [m <id> <text>] "
"send message [me] show self [l] logout: "
std::cout << "Enter action [q] quit [u] check for updates and request results [c] show chats [m <chat_id> "
"<text>] send message [me] show self [l] logout: "
<< std::endl;
std::string line;
std::getline(std::cin, line);
@ -123,7 +123,7 @@ class TdExample {
}
auto chats = td::move_tl_object_as<td_api::chats>(object);
for (auto chat_id : chats->chat_ids_) {
std::cout << "[id:" << chat_id << "] [title:" << chat_title_[chat_id] << "]" << std::endl;
std::cout << "[chat_id:" << chat_id << "] [title:" << chat_title_[chat_id] << "]" << std::endl;
}
});
}

View File

@ -1,6 +1,6 @@
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011">
<Metadata>
<Identity Id="Telegram.Td.UWP" Version="1.7.2" Language="en-US" Publisher="Telegram LLC" />
<Identity Id="Telegram.Td.UWP" Version="1.7.3" Language="en-US" Publisher="Telegram LLC" />
<DisplayName>TDLib for Universal Windows Platform</DisplayName>
<Description>TDLib is a library for building Telegram clients</Description>
<MoreInfo>https://core.telegram.org/tdlib</MoreInfo>

View File

@ -455,7 +455,7 @@ chatMemberStatusCreator custom_title:string is_anonymous:Bool is_member:Bool = C
//@description The user is a member of a chat and has some additional privileges. In basic groups, administrators can edit and delete messages sent by others, add new members, ban unprivileged members, and manage voice chats. In supergroups and channels, there are more detailed options for administrator privileges
//@custom_title A custom title of the administrator; 0-16 characters without emojis; applicable to supergroups only
//@can_be_edited True, if the current user can edit the administrator privileges for the called user
//@can_manage_chat True, if the administrator can get chat event log, get chat statistics, get message statistics in channels, get channel members, see anonymous administrators in supergoups and ignore slow mode. Implied by any other privilege; applicable to supergroups and channels only
//@can_manage_chat True, if the administrator can get chat event log, get chat statistics, get message statistics in channels, get channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other privilege; applicable to supergroups and channels only
//@can_change_info True, if the administrator can change the chat title, photo, and other settings
//@can_post_messages True, if the administrator can create channel posts; applicable to channels only
//@can_edit_messages True, if the administrator can edit messages of other users and pin messages; applicable to channels only
@ -464,7 +464,7 @@ chatMemberStatusCreator custom_title:string is_anonymous:Bool is_member:Bool = C
//@can_restrict_members True, if the administrator can restrict, ban, or unban chat members
//@can_pin_messages True, if the administrator can pin messages; applicable to basic groups and supergroups only
//@can_promote_members True, if the administrator can add new administrators with a subset of their own privileges or demote administrators that were directly or indirectly promoted by them
//@can_manage_voice_chats True, if the administrator can manage voice chats; applicable to basic groups and supergroups only
//@can_manage_voice_chats True, if the administrator can manage voice chats
//@is_anonymous True, if the administrator isn't shown in the chat member list and sends messages anonymously; applicable to supergroups only
chatMemberStatusAdministrator custom_title:string can_be_edited:Bool can_manage_chat:Bool can_change_info:Bool can_post_messages:Bool can_edit_messages:Bool can_delete_messages:Bool can_invite_users:Bool can_restrict_members:Bool can_pin_messages:Bool can_promote_members:Bool can_manage_voice_chats:Bool is_anonymous:Bool = ChatMemberStatus;
@ -891,6 +891,13 @@ chatSourcePublicServiceAnnouncement type:string text:string = ChatSource;
chatPosition list:ChatList order:int64 is_pinned:Bool source:ChatSource = ChatPosition;
//@description Describes a voice chat
//@group_call_id Group call identifier of an active voice chat; 0 if none. Full informationa about the voice chat can be received through the method getGroupCall
//@has_participants True, if the voice chat has participants
//@default_participant_alias Default group call participant identifier to join the voice chat; may be null
voiceChat group_call_id:int32 has_participants:Bool default_participant_alias:MessageSender = VoiceChat;
//@description A chat. (Can be a private chat, basic group, supergroup, or secret chat)
//@id Chat unique identifier
//@type Type of the chat
@ -913,12 +920,11 @@ chatPosition list:ChatList order:int64 is_pinned:Bool source:ChatSource = ChatPo
//@notification_settings Notification settings for this chat
//@message_ttl_setting Current message Time To Live setting (self-destruct timer) for the chat; 0 if not defined. TTL is counted from the time message or its content is viewed in secret chats and from the send date in other chats
//@action_bar Describes actions which should be possible to do through a chat action bar; may be null
//@voice_chat_group_call_id Group call identifier of an active voice chat; 0 if none or unknown. The voice chat can be received through the method getGroupCall
//@is_voice_chat_empty True, if an active voice chat is empty
//@voice_chat Contains information about voice chat of the chat
//@reply_markup_message_id Identifier of the message from which reply markup needs to be used; 0 if there is no default custom reply markup in the chat
//@draft_message A draft of a message in the chat; may be null
//@client_data Contains application-specific data associated with the chat. (For example, the chat scroll position or local chat notification settings can be stored here.) Persistent if the message database is used
chat id:int53 type:ChatType title:string photo:chatPhotoInfo permissions:chatPermissions last_message:message positions:vector<chatPosition> is_marked_as_unread:Bool is_blocked:Bool has_scheduled_messages:Bool can_be_deleted_only_for_self:Bool can_be_deleted_for_all_users:Bool can_be_reported:Bool default_disable_notification:Bool unread_count:int32 last_read_inbox_message_id:int53 last_read_outbox_message_id:int53 unread_mention_count:int32 notification_settings:chatNotificationSettings message_ttl_setting:int32 action_bar:ChatActionBar voice_chat_group_call_id:int32 is_voice_chat_empty:Bool reply_markup_message_id:int53 draft_message:draftMessage client_data:string = Chat;
chat id:int53 type:ChatType title:string photo:chatPhotoInfo permissions:chatPermissions last_message:message positions:vector<chatPosition> is_marked_as_unread:Bool is_blocked:Bool has_scheduled_messages:Bool can_be_deleted_only_for_self:Bool can_be_deleted_for_all_users:Bool can_be_reported:Bool default_disable_notification:Bool unread_count:int32 last_read_inbox_message_id:int53 last_read_outbox_message_id:int53 unread_mention_count:int32 notification_settings:chatNotificationSettings message_ttl_setting:int32 action_bar:ChatActionBar voice_chat:voiceChat reply_markup_message_id:int53 draft_message:draftMessage client_data:string = Chat;
//@description Represents a list of chats @total_count Approximate total count of chats found @chat_ids List of chat identifiers
chats total_count:int32 chat_ids:vector<int53> = Chats;
@ -2101,11 +2107,12 @@ callStateDiscarded reason:CallDiscardReason need_rating:Bool need_debug_informat
callStateError error:error = CallState;
//@description Describes a recently speaking user in a group call @user_id User identifier @is_speaking True, is the user has spoken recently
groupCallRecentSpeaker user_id:int32 is_speaking:Bool = GroupCallRecentSpeaker;
//@description Describes a recently speaking participant in a group call @speaker Speaking participantt @is_speaking True, is the user has spoken recently
groupCallRecentSpeaker speaker:MessageSender is_speaking:Bool = GroupCallRecentSpeaker;
//@description Describes a group call
//@id Group call identifier
//@title Group call title
//@is_active True, if the call is active
//@is_joined True, if the call is joined
//@need_rejoin True, if user was kicked from the call because of network loss and the call needs to be rejoined
@ -2116,8 +2123,9 @@ groupCallRecentSpeaker user_id:int32 is_speaking:Bool = GroupCallRecentSpeaker;
//@recent_speakers Recently speaking users in the group call
//@mute_new_participants True, if only group call administrators can unmute new participants
//@can_change_mute_new_participants True, if the current user can enable or disable mute_new_participants setting
//@record_duration Duration of the ongoing group call recording, in seconds; 0 if none. An updateGroupCall update is not triggered when value of this field changes, but the same recording goes on
//@duration Call duration; for ended calls only
groupCall id:int32 is_active:Bool is_joined:Bool need_rejoin:Bool can_unmute_self:Bool can_be_managed:Bool participant_count:int32 loaded_all_participants:Bool recent_speakers:vector<groupCallRecentSpeaker> mute_new_participants:Bool can_change_mute_new_participants:Bool duration:int32 = GroupCall;
groupCall id:int32 title:string is_active:Bool is_joined:Bool need_rejoin:Bool can_unmute_self:Bool can_be_managed:Bool participant_count:int32 loaded_all_participants:Bool recent_speakers:vector<groupCallRecentSpeaker> mute_new_participants:Bool can_change_mute_new_participants:Bool record_duration:int32 duration:int32 = GroupCall;
//@description Describes a payload fingerprint for interaction with tgcalls @hash Value of the field hash @setup Value of the field setup @fingerprint Value of the field fingerprint
groupCallPayloadFingerprint hash:string setup:string fingerprint:string = GroupCallPayloadFingerprint;
@ -2130,13 +2138,22 @@ groupCallPayload ufrag:string pwd:string fingerprints:vector<groupCallPayloadFin
//@ip Value of the field ip @type Value of the field type @tcp_type Value of the field tcp_type @rel_addr Value of the field rel_addr @rel_port Value of the field rel_port
groupCallJoinResponseCandidate port:string protocol:string network:string generation:string id:string component:string foundation:string priority:string ip:string type:string tcp_type:string rel_addr:string rel_port:string = GroupCallJoinResponseCandidate;
//@description Describes a join response for interaction with tgcalls @payload Join response payload to pass to tgcalls @candidates Join response candidates to pass to tgcalls
groupCallJoinResponse payload:groupCallPayload candidates:vector<groupCallJoinResponseCandidate> = GroupCallJoinResponse;
//@class GroupCallJoinResponse @description Describes a group call join response
//@description Contains data needed to join the group call with WebRTC @payload Group call payload to pass to tgcalls @candidates Join response candidates to pass to tgcalls
groupCallJoinResponseWebrtc payload:groupCallPayload candidates:vector<groupCallJoinResponseCandidate> = GroupCallJoinResponse;
//@description Describes that group call needs to be joined as a stream
groupCallJoinResponseStream = GroupCallJoinResponse;
//@description Represents a group call participant
//@user_id Identifier of the user
//@participant Identifier of the group call participant
//@source User's synchronization source
//@bio The participant user's bio or the participant chat's description
//@is_speaking True, if the participant is speaking as set by setGroupCallParticipantIsSpeaking
//@is_hand_raised True, if the participant hand is raised
//@can_be_muted_for_all_users True, if the current user can mute the participant for all other group call participants
//@can_be_unmuted_for_all_users True, if the current user can allow the participant to unmute themself or unmute the participant (if the participant is the current user)
//@can_be_muted_for_current_user True, if the current user can mute the participant only for self
@ -2145,8 +2162,8 @@ groupCallJoinResponse payload:groupCallPayload candidates:vector<groupCallJoinRe
//@is_muted_for_current_user True, if the participant is muted for the current user
//@can_unmute_self True, if the participant is muted for all users, but can unmute themself
//@volume_level Participant's volume level; 1-20000 in hundreds of percents
//@order User's order in the group call participant list. The bigger is order, the higher is user in the list. If order is 0, the user must be removed from the participant list
groupCallParticipant user_id:int32 source:int32 is_speaking:Bool can_be_muted_for_all_users:Bool can_be_unmuted_for_all_users:Bool can_be_muted_for_current_user:Bool can_be_unmuted_for_current_user:Bool is_muted_for_all_users:Bool is_muted_for_current_user:Bool can_unmute_self:Bool volume_level:int32 order:int64 = GroupCallParticipant;
//@order User's order in the group call participant list. Orders must be compared lexicographically. The bigger is order, the higher is user in the list. If order is empty, the user must be removed from the participant list
groupCallParticipant participant:MessageSender source:int32 bio:string is_speaking:Bool is_hand_raised:Bool can_be_muted_for_all_users:Bool can_be_unmuted_for_all_users:Bool can_be_muted_for_current_user:Bool can_be_unmuted_for_current_user:Bool is_muted_for_all_users:Bool is_muted_for_current_user:Bool can_unmute_self:Bool volume_level:int32 order:string = GroupCallParticipant;
//@class CallProblem @description Describes the exact type of a problem with a call
@ -2453,11 +2470,11 @@ chatEventVoiceChatCreated group_call_id:int32 = ChatEventAction;
//@description A voice chat was discarded @group_call_id Identifier of the voice chat. The voice chat can be received through the method getGroupCall
chatEventVoiceChatDiscarded group_call_id:int32 = ChatEventAction;
//@description A voice chat participant was muted or unmuted @user_id Identifier of the affected user @is_muted New value of is_muted
chatEventVoiceChatParticipantIsMutedToggled user_id:int32 is_muted:Bool = ChatEventAction;
//@description A voice chat participant was muted or unmuted @participant Identifier of the affected group call participant @is_muted New value of is_muted
chatEventVoiceChatParticipantIsMutedToggled participant:MessageSender is_muted:Bool = ChatEventAction;
//@description A voice chat participant volume level was changed @user_id Identifier of the affected user @volume_level New value of volume_level; 1-20000 in hundreds of percents
chatEventVoiceChatParticipantVolumeLevelChanged user_id:int32 volume_level:int32 = ChatEventAction;
//@description A voice chat participant volume level was changed @participant Identifier of the affected group call participant @volume_level New value of volume_level; 1-20000 in hundreds of percents
chatEventVoiceChatParticipantVolumeLevelChanged participant:MessageSender volume_level:int32 = ChatEventAction;
//@description The mute_new_participants setting of a voice chat was toggled @mute_new_participants New value of the mute_new_participants setting
chatEventVoiceChatMuteNewParticipantsToggled mute_new_participants:Bool = ChatEventAction;
@ -3388,8 +3405,8 @@ updateChatIsBlocked chat_id:int53 is_blocked:Bool = Update;
//@description A chat's has_scheduled_messages field has changed @chat_id Chat identifier @has_scheduled_messages New value of has_scheduled_messages
updateChatHasScheduledMessages chat_id:int53 has_scheduled_messages:Bool = Update;
//@description A chat voice chat state has changed @chat_id Chat identifier @voice_chat_group_call_id New value of voice_chat_group_call_id @is_voice_chat_empty New value of is_voice_chat_empty
updateChatVoiceChat chat_id:int53 voice_chat_group_call_id:int32 is_voice_chat_empty:Bool = Update;
//@description A chat voice chat state has changed @chat_id Chat identifier @voice_chat New value of voice_chat
updateChatVoiceChat chat_id:int53 voice_chat:voiceChat = Update;
//@description The value of the default disable_notification parameter, used when a message is sent to the chat, was changed @chat_id Chat identifier @default_disable_notification The new default_disable_notification value
updateChatDefaultDisableNotification chat_id:int53 default_disable_notification:Bool = Update;
@ -3906,7 +3923,7 @@ searchChatMessages chat_id:int53 query:string sender:MessageSender from_message_
//@description Searches for messages in all chats except secret chats. Returns the results in reverse chronological order (i.e., in order of decreasing (date, chat_id, message_id)).
//-For optimal performance the number of returned messages is chosen by the library
//@chat_list Chat list in which to search messages; pass null to search in all chats regardless of their chat list
//@chat_list Chat list in which to search messages; pass null to search in all chats regardless of their chat list. Only Main and Archive chat lists are supported
//@query Query to search for
//@offset_date The date of the message starting from which the results should be fetched. Use 0 or any date in the future to get results from the last message
//@offset_chat_id The chat identifier of the last found message, or 0 for the first request
@ -4215,8 +4232,12 @@ viewMessages chat_id:int53 message_thread_id:int53 message_ids:vector<int53> for
//@description Informs TDLib that the message content has been opened (e.g., the user has opened a photo, video, document, location or venue, or has listened to an audio file or voice note message). An updateMessageContentOpened update will be generated if something has changed @chat_id Chat identifier of the message @message_id Identifier of the message with the opened content
openMessageContent chat_id:int53 message_id:int53 = Ok;
//@description Returns an HTTP URL to open when user clicks on a given HTTP link. This method can be used to automatically login user on a Telegram site @link The HTTP link
getExternalLink link:string = HttpUrl;
//@description Returns information about an action to be done when the current user clicks an HTTP link. This method can be used to automatically authorize the current user on a website @link The HTTP link
getExternalLinkInfo link:string = LoginUrlInfo;
//@description Returns an HTTP URL which can be used to automatically authorize the current user on a website after clicking an HTTP link. Use the method getExternalLinkInfo to find whether a prior user confirmation is needed
//@link The HTTP link @allow_write_access True, if the current user allowed the bot, returned in getExternalLinkInfo, to send them messages
getExternalLink link:string allow_write_access:Bool = HttpUrl;
//@description Marks all mentions in a chat as read @chat_id Chat identifier
@ -4548,34 +4569,65 @@ sendCallRating call_id:int32 rating:int32 comment:string problems:vector<CallPro
sendCallDebugInformation call_id:int32 debug_information:string = Ok;
//@description Creates a voice chat (a group call bound to a chat). Available only for basic groups and supergroups; requires can_manage_voice_chats rights @chat_id Chat identifier
//@description Returns list of user and chat, which can be used as aliases to join a voice chat in the chat @chat_id Chat identifier
getAvailableVoiceChatAliases chat_id:int53 = MessageSenders;
//@description Creates a voice chat (a group call bound to a chat). Available only for basic groups, supergroups and channels; requires can_manage_voice_chats rights @chat_id Chat identifier
createVoiceChat chat_id:int53 = GroupCallId;
//@description Returns information about a group call @group_call_id Group call identifier
getGroupCall group_call_id:int32 = GroupCall;
//@description Joins a group call @group_call_id Group call identifier @payload Group join payload, received from tgcalls. Use null to cancel previous joinGroupCall request @source Caller synchronization source identifier; received from tgcalls @is_muted True, if the user's microphone is muted
joinGroupCall group_call_id:int32 payload:groupCallPayload source:int32 is_muted:Bool = GroupCallJoinResponse;
//@description Joins a group call
//@group_call_id Group call identifier
//@participant_alias Identifier of the group call participant, which will be used to join the call; voice chats only
//@payload Group join payload; received from tgcalls
//@source Caller synchronization source identifier; received from tgcalls
//@is_muted True, if the user's microphone is muted
//@invite_hash If non-empty, invite hash to be used to join the group call without being muted by administrators
joinGroupCall group_call_id:int32 participant_alias:MessageSender payload:groupCallPayload source:int32 is_muted:Bool invite_hash:string = GroupCallJoinResponse;
//@description Sets group call title. Requires groupCall.can_be_managed group call flag @group_call_id Group call identifier @title New group call title; 1-64 characters
setGroupCallTitle group_call_id:int32 title:string = Ok;
//@description Toggles whether new participants of a group call can be unmuted only by administrators of the group call. Requires groupCall.can_change_mute_new_participants group call flag
//@group_call_id Group call identifier @mute_new_participants New value of the mute_new_participants setting
toggleGroupCallMuteNewParticipants group_call_id:int32 mute_new_participants:Bool = Ok;
//@description Revokes invite link for a group call. Requires groupCall.can_be_managed group call flag @group_call_id Group call identifier
revokeGroupCallInviteLink group_call_id:int32 = Ok;
//@description Invites users to a group call. Sends a service message of type messageInviteToGroupCall for voice chats
//@group_call_id Group call identifier @user_ids User identifiers. At most 10 users can be invited simultaneously
inviteGroupCallParticipants group_call_id:int32 user_ids:vector<int32> = Ok;
//@description Returns invite link to a voice chat in a public chat
//@group_call_id Group call identifier
//@can_self_unmute Pass true if the invite_link should contain an invite hash, passing which to joinGroupCall would allow the invited user to unmute themself. Requires groupCall.can_be_managed group call flag
getGroupCallInviteLink group_call_id:int32 can_self_unmute:Bool = HttpUrl;
//@description Starts recording of a group call. Requires groupCall.can_be_managed group call flag @group_call_id Group call identifier @title Group call recording title; 0-64 characters
startGroupCallRecording group_call_id:int32 title:string = Ok;
//@description Ends recording of a group call. Requires groupCall.can_be_managed group call flag @group_call_id Group call identifier
endGroupCallRecording group_call_id:int32 = Ok;
//@description Informs TDLib that a group call participant speaking state has changed @group_call_id Group call identifier
//@source Group call participant's synchronization source identifier, or 0 for the current user @is_speaking True, if the user is speaking
setGroupCallParticipantIsSpeaking group_call_id:int32 source:int32 is_speaking:Bool = Ok;
//@description Toggles whether a group call participant is muted, unmuted, or allowed to unmute themself
//@group_call_id Group call identifier @user_id User identifier @is_muted Pass true if the user must be muted and false otherwise
toggleGroupCallParticipantIsMuted group_call_id:int32 user_id:int32 is_muted:Bool = Ok;
//@group_call_id Group call identifier @participant Participant identifier @is_muted Pass true if the user must be muted and false otherwise
toggleGroupCallParticipantIsMuted group_call_id:int32 participant:MessageSender is_muted:Bool = Ok;
//@description Changes a group call participant's volume level. If the current user can manage the group call, then the participant's volume level will be changed for all users with default volume level
//@group_call_id Group call identifier @user_id User identifier @volume_level New participant's volume level; 1-20000 in hundreds of percents
setGroupCallParticipantVolumeLevel group_call_id:int32 user_id:int32 volume_level:int32 = Ok;
//@group_call_id Group call identifier @participant Participant identifier @volume_level New participant's volume level; 1-20000 in hundreds of percents
setGroupCallParticipantVolumeLevel group_call_id:int32 participant:MessageSender volume_level:int32 = Ok;
//@description Toggles whether a group call participant hand is rased
//@group_call_id Group call identifier @participant Participant identifier
//@is_hand_raised Pass true if the user's hand should be raised. Only self hand can be raised. Requires groupCall.can_be_managed group call flag to lower other's hand
toggleGroupCallParticipantIsHandRaised group_call_id:int32 participant:MessageSender is_hand_raised:Bool = Ok;
//@description Loads more group call participants. The loaded participants will be received through updates. Use the field groupCall.loaded_all_participants to check whether all participants has already been loaded
//@group_call_id Group call identifier. The group call must be previously received through getGroupCall and must be joined or being joined
@ -4588,6 +4640,12 @@ leaveGroupCall group_call_id:int32 = Ok;
//@description Discards a group call. Requires groupCall.can_be_managed @group_call_id Group call identifier
discardGroupCall group_call_id:int32 = Ok;
//@description Returns a file with a segment of a group call stream in a modified OGG format
//@group_call_id Group call identifier
//@time_offset Point in time when the stream segment begins; Unix timestamp in milliseconds
//@scale Segment duration scale; 0-1. Segment's duration is 1000/(2**scale) milliseconds
getGroupCallStreamSegment group_call_id:int32 time_offset:int53 scale:int32 = FilePart;
//@description Changes the block state of a message sender. Currently, only users and supergroup chats can be blocked @sender Message Sender @is_blocked New value of is_blocked
toggleMessageSenderIsBlocked sender:MessageSender is_blocked:Bool = Ok;

View File

@ -79,6 +79,7 @@ inputPhotoFileLocation#40181ffe id:long access_hash:long file_reference:bytes th
inputPhotoLegacyFileLocation#d83466f3 id:long access_hash:long file_reference:bytes volume_id:long local_id:int secret:long = InputFileLocation;
inputPeerPhotoFileLocation#27d69997 flags:# big:flags.0?true peer:InputPeer volume_id:long local_id:int = InputFileLocation;
inputStickerSetThumb#dbaeae9 stickerset:InputStickerSet volume_id:long local_id:int = InputFileLocation;
inputGroupCallStream#bba51639 call:InputGroupCall time_ms:long scale:int = InputFileLocation;
peerUser#9db1bc6d user_id:int = Peer;
peerChat#bad0e5bb chat_id:int = Peer;
@ -114,8 +115,8 @@ chatForbidden#7328bdb id:int title:string = Chat;
channel#d31a961e flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?Vector<RestrictionReason> admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int = Chat;
channelForbidden#289da732 flags:# broadcast:flags.5?true megagroup:flags.8?true id:int access_hash:long title:string until_date:flags.16?int = Chat;
chatFull#f06c4018 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:int about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int = ChatFull;
channelFull#2548c037 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?int location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> = ChatFull;
chatFull#8a1e2983 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:int about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer = ChatFull;
channelFull#548c3f93 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?int location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer = ChatFull;
chatParticipant#c8d7493e user_id:int inviter_id:int date:int = ChatParticipant;
chatParticipantCreator#da13538a user_id:int = ChatParticipant;
@ -273,7 +274,7 @@ updateNewMessage#1f2b0afd message:Message pts:int pts_count:int = Update;
updateMessageID#4e90bfd6 id:int random_id:long = Update;
updateDeleteMessages#a20db0e5 messages:Vector<int> pts:int pts_count:int = Update;
updateUserTyping#5c486927 user_id:int action:SendMessageAction = Update;
updateChatUserTyping#9a65ea1f chat_id:int user_id:int action:SendMessageAction = Update;
updateChatUserTyping#86cadb6c chat_id:int from_id:Peer action:SendMessageAction = Update;
updateChatParticipants#7761198 participants:ChatParticipants = Update;
updateUserStatus#1bfbd823 user_id:int status:UserStatus = Update;
updateUserName#a7332b73 user_id:int first_name:string last_name:string username:string = Update;
@ -350,7 +351,7 @@ updateChannelMessageForwards#6e8a84df channel_id:int id:int forwards:int = Updat
updateReadChannelDiscussionInbox#1cc7de54 flags:# channel_id:int top_msg_id:int read_max_id:int broadcast_id:flags.0?int broadcast_post:flags.0?int = Update;
updateReadChannelDiscussionOutbox#4638a26c channel_id:int top_msg_id:int read_max_id:int = Update;
updatePeerBlocked#246a4b22 peer_id:Peer blocked:Bool = Update;
updateChannelUserTyping#ff2abe9f flags:# channel_id:int top_msg_id:flags.0?int user_id:int action:SendMessageAction = Update;
updateChannelUserTyping#6b171718 flags:# channel_id:int top_msg_id:flags.0?int from_id:Peer action:SendMessageAction = Update;
updatePinnedMessages#ed85eab5 flags:# pinned:flags.0?true peer:Peer messages:Vector<int> pts:int pts_count:int = Update;
updatePinnedChannelMessages#8588878b flags:# pinned:flags.0?true channel_id:int messages:Vector<int> pts:int pts_count:int = Update;
updateChat#1330a196 chat_id:int = Update;
@ -1189,15 +1190,15 @@ peerBlocked#e8fd8014 peer_id:Peer date:int = PeerBlocked;
stats.messageStats#8999f295 views_graph:StatsGraph = stats.MessageStats;
groupCallDiscarded#7780bcb4 id:long access_hash:long duration:int = GroupCall;
groupCall#55903081 flags:# join_muted:flags.1?true can_change_join_muted:flags.2?true id:long access_hash:long participants_count:int params:flags.0?DataJSON version:int = GroupCall;
groupCall#c0c2052e flags:# join_muted:flags.1?true can_change_join_muted:flags.2?true join_date_asc:flags.6?true id:long access_hash:long participants_count:int params:flags.0?DataJSON title:flags.3?string stream_dc_id:flags.4?int record_start_date:flags.5?int version:int = GroupCall;
inputGroupCall#d8aa840f id:long access_hash:long = InputGroupCall;
groupCallParticipant#64c62a15 flags:# muted:flags.0?true left:flags.1?true can_self_unmute:flags.2?true just_joined:flags.4?true versioned:flags.5?true min:flags.8?true muted_by_you:flags.9?true volume_by_admin:flags.10?true user_id:int date:int active_date:flags.3?int source:int volume:flags.7?int = GroupCallParticipant;
groupCallParticipant#19adba89 flags:# muted:flags.0?true left:flags.1?true can_self_unmute:flags.2?true just_joined:flags.4?true versioned:flags.5?true min:flags.8?true muted_by_you:flags.9?true volume_by_admin:flags.10?true self:flags.12?true peer:Peer date:int active_date:flags.3?int source:int volume:flags.7?int about:flags.11?string raise_hand_rating:flags.13?long = GroupCallParticipant;
phone.groupCall#66ab0bfc call:GroupCall participants:Vector<GroupCallParticipant> participants_next_offset:string users:Vector<User> = phone.GroupCall;
phone.groupCall#9e727aad call:GroupCall participants:Vector<GroupCallParticipant> participants_next_offset:string chats:Vector<Chat> users:Vector<User> = phone.GroupCall;
phone.groupParticipants#9cfeb92d count:int participants:Vector<GroupCallParticipant> next_offset:string users:Vector<User> version:int = phone.GroupParticipants;
phone.groupParticipants#f47751b6 count:int participants:Vector<GroupCallParticipant> next_offset:string chats:Vector<Chat> users:Vector<User> version:int = phone.GroupParticipants;
inlineQueryPeerTypeSameBotPM#3081ed9d = InlineQueryPeerType;
inlineQueryPeerTypePM#833c0fac = InlineQueryPeerType;
@ -1226,6 +1227,10 @@ messages.chatAdminsWithInvites#b69b72d7 admins:Vector<ChatAdminWithInvites> user
messages.checkedHistoryImportPeer#a24de717 confirm_text:string = messages.CheckedHistoryImportPeer;
phone.joinAsPeers#afe5623f peers:Vector<Peer> chats:Vector<Chat> users:Vector<User> = phone.JoinAsPeers;
phone.exportedGroupCallInvite#204bd158 link:string = phone.ExportedGroupCallInvite;
---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@ -1458,8 +1463,8 @@ messages.getEmojiKeywordsDifference#1508b6af lang_code:string from_version:int =
messages.getEmojiKeywordsLanguages#4e9963b2 lang_codes:Vector<string> = Vector<EmojiLanguage>;
messages.getEmojiURL#d5b10c26 lang_code:string = EmojiURL;
messages.getSearchCounters#732eef00 peer:InputPeer filters:Vector<MessagesFilter> = Vector<messages.SearchCounter>;
messages.requestUrlAuth#e33f5613 peer:InputPeer msg_id:int button_id:int = UrlAuthResult;
messages.acceptUrlAuth#f729ea98 flags:# write_allowed:flags.0?true peer:InputPeer msg_id:int button_id:int = UrlAuthResult;
messages.requestUrlAuth#198fb446 flags:# peer:flags.1?InputPeer msg_id:flags.1?int button_id:flags.1?int url:flags.2?string = UrlAuthResult;
messages.acceptUrlAuth#b12c7125 flags:# write_allowed:flags.0?true peer:flags.1?InputPeer msg_id:flags.1?int button_id:flags.1?int url:flags.2?string = UrlAuthResult;
messages.hidePeerSettingsBar#4facb138 peer:InputPeer = Bool;
messages.getScheduledHistory#e2c2685b peer:InputPeer hash:int = messages.Messages;
messages.getScheduledMessages#bdbb0464 peer:InputPeer id:Vector<int> = messages.Messages;
@ -1598,15 +1603,19 @@ phone.setCallRating#59ead627 flags:# user_initiative:flags.0?true peer:InputPhon
phone.saveCallDebug#277add7e peer:InputPhoneCall debug:DataJSON = Bool;
phone.sendSignalingData#ff7a9383 peer:InputPhoneCall data:bytes = Bool;
phone.createGroupCall#bd3dabe0 peer:InputPeer random_id:int = Updates;
phone.joinGroupCall#5f9c8e62 flags:# muted:flags.0?true call:InputGroupCall params:DataJSON = Updates;
phone.joinGroupCall#b132ff7b flags:# muted:flags.0?true call:InputGroupCall join_as:InputPeer invite_hash:flags.1?string params:DataJSON = Updates;
phone.leaveGroupCall#500377f9 call:InputGroupCall source:int = Updates;
phone.editGroupCallMember#a5e76cd8 flags:# muted:flags.0?true call:InputGroupCall user_id:InputUser volume:flags.1?int = Updates;
phone.inviteToGroupCall#7b393160 call:InputGroupCall users:Vector<InputUser> = Updates;
phone.discardGroupCall#7a777135 call:InputGroupCall = Updates;
phone.toggleGroupCallSettings#74bbb43d flags:# call:InputGroupCall join_muted:flags.0?Bool = Updates;
phone.toggleGroupCallSettings#74bbb43d flags:# reset_invite_hash:flags.1?true call:InputGroupCall join_muted:flags.0?Bool = Updates;
phone.getGroupCall#c7cb017 call:InputGroupCall = phone.GroupCall;
phone.getGroupParticipants#c9f1d285 call:InputGroupCall ids:Vector<int> sources:Vector<int> offset:string limit:int = phone.GroupParticipants;
phone.getGroupParticipants#c558d8ab call:InputGroupCall ids:Vector<InputPeer> sources:Vector<int> offset:string limit:int = phone.GroupParticipants;
phone.checkGroupCall#b74a7bea call:InputGroupCall source:int = Bool;
phone.toggleGroupCallRecord#c02a66d7 flags:# start:flags.0?true call:InputGroupCall title:flags.1?string = Updates;
phone.editGroupCallParticipant#d975eb80 flags:# muted:flags.0?true call:InputGroupCall participant:InputPeer volume:flags.1?int raise_hand:flags.2?Bool = Updates;
phone.editGroupCallTitle#1ca6ac0a call:InputGroupCall title:string = Updates;
phone.getGroupCallJoinAs#ef7c213a peer:InputPeer = phone.JoinAsPeers;
phone.exportGroupCallInvite#e6aa647f flags:# can_self_unmute:flags.0?true call:InputGroupCall = phone.ExportedGroupCallInvite;
langpack.getLangPack#f2f2330a lang_pack:string lang_code:string = LangPackDifference;
langpack.getStrings#efea3803 lang_pack:string lang_code:string keys:Vector<string> = Vector<LangPackString>;

View File

@ -302,7 +302,7 @@ FileId AnimationsManager::dup_animation(FileId new_id, FileId old_id) {
bool AnimationsManager::merge_animations(FileId new_id, FileId old_id, bool can_delete_old) {
if (!old_id.is_valid()) {
LOG(ERROR) << "Old file id is invalid";
LOG(ERROR) << "Old file identifier is invalid";
return true;
}

View File

@ -115,7 +115,7 @@ FileId AudiosManager::dup_audio(FileId new_id, FileId old_id) {
bool AudiosManager::merge_audios(FileId new_id, FileId old_id, bool can_delete_old) {
if (!old_id.is_valid()) {
LOG(ERROR) << "Old file id is invalid";
LOG(ERROR) << "Old file identifier is invalid";
return true;
}

View File

@ -308,7 +308,7 @@ void AuthManager::check_password(uint64 query_id, string password) {
return on_query_error(query_id, Status::Error(8, "Call to checkAuthenticationPassword unexpected"));
}
LOG(INFO) << "Have SRP id " << wait_password_state_.srp_id_;
LOG(INFO) << "Have SRP ID " << wait_password_state_.srp_id_;
on_new_query(query_id);
password_ = std::move(password);
start_net_query(NetQueryType::GetPassword,
@ -569,7 +569,7 @@ void AuthManager::on_get_password_result(NetQueryPtr &result) {
}
if (state_ == State::WaitPassword) {
LOG(INFO) << "Have SRP id " << wait_password_state_.srp_id_;
LOG(INFO) << "Have SRP ID " << wait_password_state_.srp_id_;
auto hash = PasswordManager::get_input_check_password(password_, wait_password_state_.current_client_salt_,
wait_password_state_.current_server_salt_,
wait_password_state_.srp_g_, wait_password_state_.srp_p_,

View File

@ -11,6 +11,7 @@
#include "td/telegram/Global.h"
#include "td/telegram/JsonValue.h"
#include "td/telegram/logevent/LogEvent.h"
#include "td/telegram/MessagesManager.h"
#include "td/telegram/net/AuthDataShared.h"
#include "td/telegram/net/ConnectionCreator.h"
#include "td/telegram/net/DcId.h"
@ -891,6 +892,8 @@ void ConfigManager::start_up() {
autologin_update_time_ = Time::now() - 365 * 86400;
autologin_domains_ = full_split(G()->td_db()->get_binlog_pmc()->get("autologin_domains"), '\xFF');
url_auth_domains_ = full_split(G()->td_db()->get_binlog_pmc()->get("url_auth_domains"), '\xFF');
}
ActorShared<> ConfigManager::create_reference() {
@ -967,33 +970,38 @@ void ConfigManager::get_app_config(Promise<td_api::object_ptr<td_api::JsonValue>
}
}
void ConfigManager::get_external_link(string &&link, Promise<string> &&promise) {
void ConfigManager::get_external_link_info(string &&link, Promise<td_api::object_ptr<td_api::LoginUrlInfo>> &&promise) {
auto default_result = td_api::make_object<td_api::loginUrlInfoOpen>(link, false);
if (G()->close_flag()) {
return promise.set_value(std::move(link));
return promise.set_value(std::move(default_result));
}
auto r_url = parse_url(link);
if (r_url.is_error()) {
return promise.set_value(std::move(link));
return promise.set_value(std::move(default_result));
}
if (!td::contains(autologin_domains_, r_url.ok().host_)) {
return promise.set_value(std::move(link));
if (td::contains(url_auth_domains_, r_url.ok().host_)) {
send_closure(G()->messages_manager(), &MessagesManager::get_link_login_url_info, link, std::move(promise));
return;
}
return promise.set_value(std::move(default_result));
}
if (autologin_update_time_ < Time::now() - 10000) {
auto query_promise = PromiseCreator::lambda([link = std::move(link), promise = std::move(promise)](
Result<td_api::object_ptr<td_api::JsonValue>> &&result) mutable {
if (result.is_error()) {
return promise.set_value(std::move(link));
return promise.set_value(td_api::make_object<td_api::loginUrlInfoOpen>(link, false));
}
send_closure(G()->config_manager(), &ConfigManager::get_external_link, std::move(link), std::move(promise));
send_closure(G()->config_manager(), &ConfigManager::get_external_link_info, std::move(link), std::move(promise));
});
return get_app_config(std::move(query_promise));
}
if (autologin_token_.empty()) {
return promise.set_value(std::move(link));
return promise.set_value(std::move(default_result));
}
auto url = r_url.move_as_ok();
@ -1018,7 +1026,7 @@ void ConfigManager::get_external_link(string &&link, Promise<string> &&promise)
url.query_ = PSTRING() << path << parameters << added_parameter << hash;
promise.set_value(url.get_url());
promise.set_value(td_api::make_object<td_api::loginUrlInfoOpen>(url.get_url(), false));
}
void ConfigManager::get_content_settings(Promise<Unit> &&promise) {
@ -1524,6 +1532,9 @@ void ConfigManager::process_app_config(tl_object_ptr<telegram_api::JSONValue> &c
autologin_domains_.clear();
autologin_update_time_ = Time::now();
auto old_url_auth_domains = std::move(url_auth_domains_);
url_auth_domains_.clear();
vector<tl_object_ptr<telegram_api::jsonObjectValue>> new_values;
string ignored_restriction_reasons;
vector<string> dice_emojis;
@ -1714,6 +1725,22 @@ void ConfigManager::process_app_config(tl_object_ptr<telegram_api::JSONValue> &c
}
continue;
}
if (key == "url_auth_domains") {
if (value->get_id() == telegram_api::jsonArray::ID) {
auto domains = std::move(static_cast<telegram_api::jsonArray *>(value)->value_);
for (auto &domain : domains) {
CHECK(domain != nullptr);
if (domain->get_id() == telegram_api::jsonString::ID) {
url_auth_domains_.push_back(std::move(static_cast<telegram_api::jsonString *>(domain.get())->value_));
} else {
LOG(ERROR) << "Receive unexpected url auth domain " << to_string(domain);
}
}
} else {
LOG(ERROR) << "Receive unexpected url_auth_domains " << to_string(*value);
}
continue;
}
new_values.push_back(std::move(key_value));
}
@ -1725,6 +1752,9 @@ void ConfigManager::process_app_config(tl_object_ptr<telegram_api::JSONValue> &c
if (autologin_domains_ != old_autologin_domains) {
G()->td_db()->get_binlog_pmc()->set("autologin_domains", implode(autologin_domains_, '\xFF'));
}
if (url_auth_domains_ != old_url_auth_domains) {
G()->td_db()->get_binlog_pmc()->set("url_auth_domains", implode(url_auth_domains_, '\xFF'));
}
ConfigShared &shared_config = G()->shared_config();

View File

@ -93,7 +93,7 @@ class ConfigManager : public NetQueryCallback {
void get_app_config(Promise<td_api::object_ptr<td_api::JsonValue>> &&promise);
void get_external_link(string &&link, Promise<string> &&promise);
void get_external_link_info(string &&link, Promise<td_api::object_ptr<td_api::LoginUrlInfo>> &&promise);
void get_content_settings(Promise<Unit> &&promise);
@ -119,6 +119,7 @@ class ConfigManager : public NetQueryCallback {
string autologin_token_;
vector<string> autologin_domains_;
double autologin_update_time_ = 0.0;
vector<string> url_auth_domains_;
FloodControlStrict lazy_request_flood_control_;

View File

@ -22,6 +22,7 @@
#include "td/telegram/files/FileType.h"
#include "td/telegram/FolderId.h"
#include "td/telegram/Global.h"
#include "td/telegram/GroupCallManager.h"
#include "td/telegram/InlineQueriesManager.h"
#include "td/telegram/InputGroupCallId.h"
#include "td/telegram/logevent/LogEvent.h"
@ -3471,7 +3472,7 @@ UserId ContactsManager::load_my_id() {
return my_id;
}
LOG(ERROR) << "Wrong my id = \"" << id_string << "\" stored in database";
LOG(ERROR) << "Wrong my ID = \"" << id_string << "\" stored in database";
}
return UserId();
}
@ -4774,6 +4775,43 @@ RestrictedRights ContactsManager::get_secret_chat_default_permissions(SecretChat
return RestrictedRights(true, true, true, true, true, true, true, true, false, false, false);
}
string ContactsManager::get_dialog_about(DialogId dialog_id) {
switch (dialog_id.get_type()) {
case DialogType::User: {
auto user_full = get_user_full_force(dialog_id.get_user_id());
if (user_full != nullptr) {
return user_full->about;
}
break;
}
case DialogType::Chat: {
auto chat_full = get_chat_full_force(dialog_id.get_chat_id(), "get_dialog_about");
if (chat_full != nullptr) {
return chat_full->description;
}
break;
}
case DialogType::Channel: {
auto channel_full = get_channel_full_force(dialog_id.get_channel_id(), "get_dialog_about");
if (channel_full != nullptr) {
return channel_full->description;
}
break;
}
case DialogType::SecretChat: {
auto user_full = get_user_full_force(get_secret_chat_user_id(dialog_id.get_secret_chat_id()));
if (user_full != nullptr) {
return user_full->about;
}
break;
}
case DialogType::None:
default:
UNREACHABLE();
}
return string();
}
int32 ContactsManager::get_secret_chat_date(SecretChatId secret_chat_id) const {
auto c = get_secret_chat(secret_chat_id);
if (c == nullptr) {
@ -4858,7 +4896,7 @@ FolderId ContactsManager::get_secret_chat_initial_folder_id(SecretChatId secret_
}
UserId ContactsManager::get_my_id() const {
LOG_IF(ERROR, !my_id_.is_valid()) << "Wrong or unknown my id returned";
LOG_IF(ERROR, !my_id_.is_valid()) << "Wrong or unknown my ID returned";
return my_id_;
}
@ -4868,7 +4906,7 @@ void ContactsManager::set_my_id(UserId my_id) {
LOG(ERROR) << "Already know that me is " << my_old_id << " but received userSelf with " << my_id;
}
if (!my_id.is_valid()) {
LOG(ERROR) << "Receive invalid my id " << my_id;
LOG(ERROR) << "Receive invalid my ID " << my_id;
return;
}
if (my_old_id != my_id) {
@ -6111,6 +6149,7 @@ void ContactsManager::on_update_profile_success(int32 flags, const string &first
user_full->about = about;
user_full->is_changed = true;
update_user_full(user_full, my_user_id);
td_->group_call_manager_->on_update_dialog_about(DialogId(my_user_id), user_full->about, true);
}
}
}
@ -9217,6 +9256,8 @@ void ContactsManager::on_load_user_full_from_database(UserId user_id, string val
register_user_photo(u, user_id, user_full->photo);
}
td_->group_call_manager_->on_update_dialog_about(DialogId(user_id), user_full->about, false);
update_user_full(user_full, user_id, true);
if (is_user_deleted(user_id)) {
@ -9406,6 +9447,9 @@ void ContactsManager::on_load_chat_full_from_database(ChatId chat_id, string val
reload_chat_full(chat_id, Auto());
}
}
td_->group_call_manager_->on_update_dialog_about(DialogId(chat_id), chat_full->description, false);
on_update_chat_full_photo(chat_full, chat_id, std::move(chat_full->photo));
update_chat_full(chat_full, chat_id, true);
@ -9516,6 +9560,8 @@ void ContactsManager::on_load_channel_full_from_database(ChannelId channel_id, s
}
}
td_->group_call_manager_->on_update_dialog_about(DialogId(channel_id), channel_full->description, false);
td_->messages_manager_->on_dialog_bots_updated(DialogId(channel_id), channel_full->bot_user_ids, true);
update_channel_full(channel_full, channel_id, true);
@ -10053,14 +10099,18 @@ void ContactsManager::on_get_user_full(tl_object_ptr<telegram_api::userFull> &&u
bool supports_video_calls = user->video_calls_available_ && !user->phone_calls_private_;
bool has_private_calls = user->phone_calls_private_;
if (user_full->can_be_called != can_be_called || user_full->supports_video_calls != supports_video_calls ||
user_full->has_private_calls != has_private_calls || user_full->about != user->about_) {
user_full->has_private_calls != has_private_calls) {
user_full->can_be_called = can_be_called;
user_full->supports_video_calls = supports_video_calls;
user_full->has_private_calls = has_private_calls;
user_full->about = std::move(user->about_);
user_full->is_changed = true;
}
if (user_full->about != user->about_) {
user_full->about = std::move(user->about_);
user_full->is_changed = true;
td_->group_call_manager_->on_update_dialog_about(DialogId(user_id), user_full->about, true);
}
auto photo = get_photo(td_->file_manager_.get(), std::move(user->profile_photo_), DialogId(user_id));
if (photo != user_full->photo) {
@ -10287,6 +10337,16 @@ void ContactsManager::on_get_chat_full(tl_object_ptr<telegram_api::ChatFull> &&c
}
td_->messages_manager_->on_update_dialog_group_call_id(DialogId(chat_id), input_group_call_id);
}
{
DialogId default_join_group_call_as_dialog_id;
if (chat->groupcall_default_join_as_ != nullptr) {
default_join_group_call_as_dialog_id = DialogId(chat->groupcall_default_join_as_);
}
// use send closure later to not crete synchronously default_join_group_call_as_dialog_id
send_closure_later(G()->messages_manager(),
&MessagesManager::on_update_dialog_default_join_group_call_as_dialog_id, DialogId(chat_id),
default_join_group_call_as_dialog_id, false);
}
{
MessageTtlSetting message_ttl_setting;
if ((chat->flags_ & CHAT_FULL_FLAG_HAS_MESSAGE_TTL) != 0) {
@ -10309,6 +10369,7 @@ void ContactsManager::on_get_chat_full(tl_object_ptr<telegram_api::ChatFull> &&c
if (chat_full->description != chat->about_) {
chat_full->description = std::move(chat->about_);
chat_full->is_changed = true;
td_->group_call_manager_->on_update_dialog_about(DialogId(chat_id), chat_full->description, true);
}
if (chat_full->can_set_username != chat->can_set_username_) {
chat_full->can_set_username = chat->can_set_username_;
@ -10402,7 +10463,7 @@ void ContactsManager::on_get_chat_full(tl_object_ptr<telegram_api::ChatFull> &&c
channel_full->repair_request_version = 0;
channel_full->expires_at = Time::now() + CHANNEL_FULL_EXPIRE_TIME;
if (channel_full->description != channel->about_ || channel_full->participant_count != participant_count ||
if (channel_full->participant_count != participant_count ||
channel_full->administrator_count != administrator_count ||
channel_full->restricted_count != restricted_count || channel_full->banned_count != banned_count ||
channel_full->can_get_participants != can_get_participants ||
@ -10412,7 +10473,6 @@ void ContactsManager::on_get_chat_full(tl_object_ptr<telegram_api::ChatFull> &&c
channel_full->can_view_statistics != can_view_statistics || channel_full->stats_dc_id != stats_dc_id ||
channel_full->sticker_set_id != sticker_set_id ||
channel_full->is_all_history_available != is_all_history_available) {
channel_full->description = std::move(channel->about_);
channel_full->participant_count = participant_count;
channel_full->administrator_count = administrator_count;
channel_full->restricted_count = restricted_count;
@ -10428,6 +10488,12 @@ void ContactsManager::on_get_chat_full(tl_object_ptr<telegram_api::ChatFull> &&c
channel_full->is_changed = true;
}
if (channel_full->description != channel->about_) {
channel_full->description = std::move(channel->about_);
channel_full->is_changed = true;
td_->group_call_manager_->on_update_dialog_about(DialogId(channel_id), channel_full->description, true);
}
if (have_participant_count && c->participant_count != participant_count) {
c->participant_count = participant_count;
c->is_changed = true;
@ -10477,13 +10543,19 @@ void ContactsManager::on_get_chat_full(tl_object_ptr<telegram_api::ChatFull> &&c
InputGroupCallId input_group_call_id;
if (channel->call_ != nullptr) {
input_group_call_id = InputGroupCallId(channel->call_);
if (input_group_call_id.is_valid() && !c->is_megagroup) {
LOG(ERROR) << "Receive " << input_group_call_id << " in " << channel_id;
input_group_call_id = InputGroupCallId();
}
}
td_->messages_manager_->on_update_dialog_group_call_id(DialogId(channel_id), input_group_call_id);
}
{
DialogId default_join_group_call_as_dialog_id;
if (channel->groupcall_default_join_as_ != nullptr) {
default_join_group_call_as_dialog_id = DialogId(channel->groupcall_default_join_as_);
}
// use send closure later to not crete synchronously default_join_group_call_as_dialog_id
send_closure_later(G()->messages_manager(),
&MessagesManager::on_update_dialog_default_join_group_call_as_dialog_id, DialogId(channel_id),
default_join_group_call_as_dialog_id, false);
}
if (participant_count >= 190) {
int32 online_member_count = 0;
@ -11200,6 +11272,7 @@ void ContactsManager::drop_user_full(UserId user_id) {
user_full->is_changed = true;
update_user_full(user_full, user_id);
td_->group_call_manager_->on_update_dialog_about(DialogId(user_id), user_full->about, true);
}
void ContactsManager::update_user_online_member_count(User *u) {
@ -12731,6 +12804,7 @@ void ContactsManager::on_update_chat_description(ChatId chat_id, string &&descri
chat_full->description = std::move(description);
chat_full->is_changed = true;
update_chat_full(chat_full, chat_id);
td_->group_call_manager_->on_update_dialog_about(DialogId(chat_id), chat_full->description, true);
}
}
@ -12931,6 +13005,7 @@ void ContactsManager::on_update_channel_description(ChannelId channel_id, string
channel_full->description = std::move(description);
channel_full->is_changed = true;
update_channel_full(channel_full, channel_id);
td_->group_call_manager_->on_update_dialog_about(DialogId(channel_id), channel_full->description, true);
}
}

View File

@ -132,6 +132,8 @@ class ContactsManager : public Actor {
RestrictedRights get_channel_default_permissions(ChannelId channel_id) const;
RestrictedRights get_secret_chat_default_permissions(SecretChatId secret_chat_id) const;
string get_dialog_about(DialogId dialog_id);
bool is_update_about_username_change_received(UserId user_id) const;
void for_each_secret_chat_with_user(UserId user_id, std::function<void(SecretChatId)> f);

View File

@ -368,7 +368,7 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo
// fix_animated_sticker_type();
}
LOG(DEBUG) << "Receive document with id = " << id << " of type " << document_type;
LOG(DEBUG) << "Receive document with ID = " << id << " of type " << document_type;
if (!is_web && !DcId::is_valid(dc_id)) {
LOG(ERROR) << "Wrong dc_id = " << dc_id;
return {};
@ -660,7 +660,7 @@ FileId DocumentsManager::dup_document(FileId new_id, FileId old_id) {
bool DocumentsManager::merge_documents(FileId new_id, FileId old_id, bool can_delete_old) {
if (!old_id.is_valid()) {
LOG(ERROR) << "Old file id is invalid";
LOG(ERROR) << "Old file identifier is invalid";
return true;
}

View File

@ -120,7 +120,7 @@ bool operator!=(const Game &lhs, const Game &rhs) {
}
StringBuilder &operator<<(StringBuilder &string_builder, const Game &game) {
return string_builder << "Game[id = " << game.id_ << ", access_hash = " << game.access_hash_
return string_builder << "Game[ID = " << game.id_ << ", access_hash = " << game.access_hash_
<< ", bot = " << game.bot_user_id_ << ", short_name = " << game.short_name_
<< ", title = " << game.title_ << ", description = " << game.description_
<< ", photo = " << game.photo_ << ", animation_file_id = " << game.animation_file_id_ << "]";

File diff suppressed because it is too large Load Diff

View File

@ -41,8 +41,16 @@ class GroupCallManager : public Actor {
void memory_stats(vector<string> &output);
DialogId get_group_call_participant_id(const td_api::object_ptr<td_api::MessageSender> &message_sender);
bool is_group_call_being_joined(InputGroupCallId input_group_call_id) const;
bool is_group_call_joined(InputGroupCallId input_group_call_id) const;
GroupCallId get_group_call_id(InputGroupCallId input_group_call_id, DialogId dialog_id);
void get_group_call_join_as(DialogId dialog_id, Promise<td_api::object_ptr<td_api::messageSenders>> &&promise);
void create_voice_chat(DialogId dialog_id, Promise<GroupCallId> &&promise);
void get_group_call(GroupCallId group_call_id, Promise<td_api::object_ptr<td_api::groupCall>> &&promise);
@ -52,33 +60,50 @@ class GroupCallManager : public Actor {
void reload_group_call(InputGroupCallId input_group_call_id,
Promise<td_api::object_ptr<td_api::groupCall>> &&promise);
void join_group_call(GroupCallId group_call_id, td_api::object_ptr<td_api::groupCallPayload> &&payload,
int32 audio_source, bool is_muted,
Promise<td_api::object_ptr<td_api::groupCallJoinResponse>> &&promise);
void get_group_call_stream_segment(GroupCallId group_call_id, int64 time_offset, int32 scale,
Promise<string> &&promise);
void join_group_call(GroupCallId group_call_id, DialogId as_dialog_id,
td_api::object_ptr<td_api::groupCallPayload> &&payload, int32 audio_source, bool is_muted,
const string &invite_hash, Promise<td_api::object_ptr<td_api::GroupCallJoinResponse>> &&promise);
void set_group_call_title(GroupCallId group_call_id, string title, Promise<Unit> &&promise);
void toggle_group_call_mute_new_participants(GroupCallId group_call_id, bool mute_new_participants,
Promise<Unit> &&promise);
void revoke_group_call_invite_link(GroupCallId group_call_id, Promise<Unit> &&promise);
void invite_group_call_participants(GroupCallId group_call_id, vector<UserId> &&user_ids, Promise<Unit> &&promise);
void get_group_call_invite_link(GroupCallId group_call_id, bool can_self_unmute, Promise<string> &&promise);
void toggle_group_call_recording(GroupCallId group_call_id, bool is_enabled, string title, Promise<Unit> &&promise);
void set_group_call_participant_is_speaking(GroupCallId group_call_id, int32 audio_source, bool is_speaking,
Promise<Unit> &&promise, int32 date = 0);
void toggle_group_call_participant_is_muted(GroupCallId group_call_id, UserId user_id, bool is_muted,
void toggle_group_call_participant_is_muted(GroupCallId group_call_id, DialogId dialog_id, bool is_muted,
Promise<Unit> &&promise);
void set_group_call_participant_volume_level(GroupCallId group_call_id, UserId user_id, int32 volume_level,
void set_group_call_participant_volume_level(GroupCallId group_call_id, DialogId dialog_id, int32 volume_level,
Promise<Unit> &&promise);
void toggle_group_call_participant_is_hand_raised(GroupCallId group_call_id, DialogId dialog_id, bool is_hand_raised,
Promise<Unit> &&promise);
void load_group_call_participants(GroupCallId group_call_id, int32 limit, Promise<Unit> &&promise);
void leave_group_call(GroupCallId group_call_id, Promise<Unit> &&promise);
void discard_group_call(GroupCallId group_call_id, Promise<Unit> &&promise);
void on_update_dialog_about(DialogId dialog_id, const string &about, bool from_server);
void on_update_group_call(tl_object_ptr<telegram_api::GroupCall> group_call_ptr, DialogId dialog_id);
void on_user_speaking_in_group_call(GroupCallId group_call_id, UserId user_id, int32 date, bool recursive = false);
void on_user_speaking_in_group_call(GroupCallId group_call_id, DialogId dialog_id, int32 date,
bool is_recursive = false);
void on_get_group_call_participants(InputGroupCallId input_group_call_id,
tl_object_ptr<telegram_api::phone_groupParticipants> &&participants, bool is_load,
@ -86,7 +111,7 @@ class GroupCallManager : public Actor {
void on_update_group_call_participants(InputGroupCallId input_group_call_id,
vector<tl_object_ptr<telegram_api::groupCallParticipant>> &&participants,
int32 version);
int32 version, bool is_recursive = false);
void process_join_group_call_response(InputGroupCallId input_group_call_id, uint64 generation,
tl_object_ptr<telegram_api::Updates> &&updates, Promise<Unit> &&promise);
@ -98,12 +123,19 @@ class GroupCallManager : public Actor {
struct PendingJoinRequest;
static constexpr int32 RECENT_SPEAKER_TIMEOUT = 60 * 60;
static constexpr int32 UPDATE_GROUP_CALL_PARTICIPANT_ORDER_TIMEOUT = 10;
static constexpr int32 CHECK_GROUP_CALL_IS_JOINED_TIMEOUT = 10;
static constexpr size_t MAX_TITLE_LENGTH = 64; // server side limit for group call/call record title length
void tear_down() override;
void memory_cleanup(bool full);
static void on_update_group_call_participant_order_timeout_callback(void *group_call_manager_ptr,
int64 group_call_id_int);
void on_update_group_call_participant_order_timeout(GroupCallId group_call_id);
static void on_check_group_call_is_joined_timeout_callback(void *group_call_manager_ptr, int64 group_call_id_int);
void on_check_group_call_is_joined_timeout(GroupCallId group_call_id);
@ -133,16 +165,27 @@ class GroupCallManager : public Actor {
bool can_manage_group_call(InputGroupCallId input_group_call_id) const;
bool get_group_call_joined_date_asc(InputGroupCallId input_group_call_id) const;
void on_voice_chat_created(DialogId dialog_id, InputGroupCallId input_group_call_id, Promise<GroupCallId> &&promise);
void finish_get_group_call(InputGroupCallId input_group_call_id,
Result<tl_object_ptr<telegram_api::phone_groupCall>> &&result);
void finish_get_group_call_stream_segment(InputGroupCallId input_group_call_id, int32 audio_source,
Result<string> &&result, Promise<string> &&promise);
void finish_check_group_call_is_joined(InputGroupCallId input_group_call_id, int32 audio_source,
Result<Unit> &&result);
static const string &get_group_call_title(const GroupCall *group_call);
static bool get_group_call_mute_new_participants(const GroupCall *group_call);
static int32 get_group_call_record_start_date(const GroupCall *group_call);
static bool get_group_call_has_recording(const GroupCall *group_call);
bool need_group_call_participants(InputGroupCallId input_group_call_id) const;
bool need_group_call_participants(InputGroupCallId input_group_call_id, const GroupCall *group_call) const;
@ -153,11 +196,14 @@ class GroupCallManager : public Actor {
void on_sync_group_call_participants_failed(InputGroupCallId input_group_call_id);
int64 get_real_participant_order(const GroupCallParticipant &participant, int64 min_order) const;
GroupCallParticipantOrder get_real_participant_order(bool can_manage, const GroupCallParticipant &participant,
const GroupCallParticipants *participants) const;
void process_my_group_call_participant(InputGroupCallId input_group_call_id, GroupCallParticipant &&participant);
void process_group_call_participants(InputGroupCallId group_call_id,
vector<tl_object_ptr<telegram_api::groupCallParticipant>> &&participants,
bool is_load, bool is_sync);
int32 version, const string &offset, bool is_load, bool is_sync);
bool update_group_call_participant_can_be_muted(bool can_manage, const GroupCallParticipants *participants,
GroupCallParticipant &participant);
@ -167,6 +213,10 @@ class GroupCallManager : public Actor {
int process_group_call_participant(InputGroupCallId group_call_id, GroupCallParticipant &&participant);
void on_add_group_call_participant(InputGroupCallId input_group_call_id, DialogId participant_dialog_id);
void on_remove_group_call_participant(InputGroupCallId input_group_call_id, DialogId participant_dialog_id);
void try_load_group_call_administrators(InputGroupCallId input_group_call_id, DialogId dialog_id);
void finish_load_group_call_administrators(InputGroupCallId input_group_call_id, Result<DialogParticipants> &&result);
@ -177,14 +227,18 @@ class GroupCallManager : public Actor {
void finish_join_group_call(InputGroupCallId input_group_call_id, uint64 generation, Status error);
void process_group_call_after_join_requests(InputGroupCallId input_group_call_id);
void process_group_call_after_join_requests(InputGroupCallId input_group_call_id, const char *source);
GroupCallParticipants *add_group_call_participants(InputGroupCallId input_group_call_id);
GroupCallParticipant *get_group_call_participant(InputGroupCallId input_group_call_id, UserId user_id);
GroupCallParticipant *get_group_call_participant(InputGroupCallId input_group_call_id, DialogId dialog_id);
static GroupCallParticipant *get_group_call_participant(GroupCallParticipants *group_call_participants,
UserId user_id);
GroupCallParticipant *get_group_call_participant(GroupCallParticipants *group_call_participants,
DialogId dialog_id) const;
void send_edit_group_call_title_query(InputGroupCallId input_group_call_id, const string &title);
void on_edit_group_call_title(InputGroupCallId input_group_call_id, const string &title, Result<Unit> &&result);
void send_toggle_group_call_mute_new_participants_query(InputGroupCallId input_group_call_id,
bool mute_new_participants);
@ -192,12 +246,20 @@ class GroupCallManager : public Actor {
void on_toggle_group_call_mute_new_participants(InputGroupCallId input_group_call_id, bool mute_new_participants,
Result<Unit> &&result);
void on_toggle_group_call_participant_is_muted(InputGroupCallId input_group_call_id, UserId user_id,
void send_toggle_group_call_recording_query(InputGroupCallId input_group_call_id, bool is_enabled,
const string &title, uint64 generation);
void on_toggle_group_call_recording(InputGroupCallId input_group_call_id, uint64 generation, Result<Unit> &&result);
void on_toggle_group_call_participant_is_muted(InputGroupCallId input_group_call_id, DialogId dialog_id,
uint64 generation, Promise<Unit> &&promise);
void on_set_group_call_participant_volume_level(InputGroupCallId input_group_call_id, UserId user_id,
void on_set_group_call_participant_volume_level(InputGroupCallId input_group_call_id, DialogId dialog_id,
uint64 generation, Promise<Unit> &&promise);
void on_toggle_group_call_participant_is_hand_raised(InputGroupCallId input_group_call_id, DialogId dialog_id,
uint64 generation, Promise<Unit> &&promise);
void on_group_call_left(InputGroupCallId input_group_call_id, int32 audio_source, bool need_rejoin);
void on_group_call_left_impl(GroupCall *group_call, bool need_rejoin);
@ -209,19 +271,22 @@ class GroupCallManager : public Actor {
void on_participant_speaking_in_group_call(InputGroupCallId input_group_call_id,
const GroupCallParticipant &participant);
void remove_recent_group_call_speaker(InputGroupCallId input_group_call_id, UserId user_id);
void remove_recent_group_call_speaker(InputGroupCallId input_group_call_id, DialogId dialog_id);
void on_group_call_recent_speakers_updated(const GroupCall *group_call, GroupCallRecentSpeakers *recent_speakers);
UserId set_group_call_participant_is_speaking_by_source(InputGroupCallId input_group_call_id, int32 audio_source,
bool is_speaking, int32 date);
DialogId set_group_call_participant_is_speaking_by_source(InputGroupCallId input_group_call_id, int32 audio_source,
bool is_speaking, int32 date);
static Result<td_api::object_ptr<td_api::groupCallJoinResponse>> get_group_call_join_response_object(
static Result<td_api::object_ptr<td_api::GroupCallJoinResponse>> get_group_call_join_response_object(
string json_response);
void try_clear_group_call_participants(InputGroupCallId input_group_call_id);
void update_group_call_dialog(const GroupCall *group_call, const char *source);
bool set_group_call_participant_count(GroupCall *group_call, int32 count, const char *source,
bool force_update = false);
void update_group_call_dialog(const GroupCall *group_call, const char *source, bool force);
vector<td_api::object_ptr<td_api::groupCallRecentSpeaker>> get_recent_speakers(const GroupCall *group_call,
bool for_update);
@ -253,6 +318,7 @@ class GroupCallManager : public Actor {
std::unordered_map<InputGroupCallId, unique_ptr<GroupCallParticipants>, InputGroupCallIdHash>
group_call_participants_;
std::unordered_map<DialogId, vector<InputGroupCallId>, DialogIdHash> participant_id_to_group_call_id_;
std::unordered_map<GroupCallId, unique_ptr<GroupCallRecentSpeakers>, GroupCallIdHash> group_call_recent_speakers_;
@ -262,10 +328,15 @@ class GroupCallManager : public Actor {
std::unordered_map<InputGroupCallId, unique_ptr<PendingJoinRequest>, InputGroupCallIdHash> pending_join_requests_;
uint64 join_group_request_generation_ = 0;
uint64 set_volume_level_generation_ = 0;
uint64 toggle_recording_generation_ = 0;
uint64 toggle_is_muted_generation_ = 0;
uint64 set_volume_level_generation_ = 0;
uint64 toggle_is_hand_raised_generation_ = 0;
MultiTimeout update_group_call_participant_order_timeout_{"UpdateGroupCallParticipantOrderTimeout"};
MultiTimeout check_group_call_is_joined_timeout_{"CheckGroupCallIsJoinedTimeout"};
MultiTimeout pending_send_speaking_action_timeout_{"PendingSendSpeakingActionTimeout"};
MultiTimeout recent_speaker_update_timeout_{"RecentSpeakerUpdateTimeout"};

View File

@ -6,19 +6,24 @@
//
#include "td/telegram/GroupCallParticipant.h"
#include "td/telegram/ContactsManager.h"
#include "td/telegram/Global.h"
#include "td/telegram/MessagesManager.h"
#include "td/telegram/Td.h"
#include "td/utils/logging.h"
namespace td {
GroupCallParticipant::GroupCallParticipant(const tl_object_ptr<telegram_api::groupCallParticipant> &participant) {
GroupCallParticipant::GroupCallParticipant(const tl_object_ptr<telegram_api::groupCallParticipant> &participant,
int32 call_version) {
CHECK(participant != nullptr);
user_id = UserId(participant->user_id_);
dialog_id = DialogId(participant->peer_);
about = std::move(participant->about_);
audio_source = participant->source_;
server_is_muted_by_themselves = participant->can_self_unmute_;
server_is_muted_by_admin = participant->muted_ && !participant->can_self_unmute_;
server_is_muted_locally = participant->muted_by_you_;
is_self = participant->self_;
if ((participant->flags_ & telegram_api::groupCallParticipant::VOLUME_MASK) != 0) {
volume_level = participant->volume_;
if (volume_level < MIN_VOLUME_LEVEL || volume_level > MAX_VOLUME_LEVEL) {
@ -33,19 +38,39 @@ GroupCallParticipant::GroupCallParticipant(const tl_object_ptr<telegram_api::gro
active_date = participant->active_date_;
}
if (joined_date < 0 || active_date < 0) {
LOG(ERROR) << "Receive invalid " << to_string(participant);
LOG(ERROR) << "Receive invalid active_date/joined_date in " << to_string(participant);
joined_date = 0;
active_date = 0;
}
if ((participant->flags_ & telegram_api::groupCallParticipant::RAISE_HAND_RATING_MASK) != 0) {
raise_hand_rating = participant->raise_hand_rating_;
if (raise_hand_rating < 0) {
LOG(ERROR) << "Receive invalid raise_hand_rating in " << to_string(participant);
raise_hand_rating = 0;
}
}
}
is_just_joined = participant->just_joined_;
is_min = (participant->flags_ & telegram_api::groupCallParticipant::MIN_MASK) != 0;
is_min = participant->min_;
version = call_version;
}
bool GroupCallParticipant::is_versioned_update(const tl_object_ptr<telegram_api::groupCallParticipant> &participant) {
// updates about new and left participants must be applyed as versioned, even they don't increase version
return participant->just_joined_ || participant->left_ || participant->versioned_;
}
GroupCallParticipantOrder GroupCallParticipant::get_real_order(bool can_manage, bool joined_date_asc,
bool keep_active_date) const {
auto sort_active_date = td::max(active_date, local_active_date);
if (!keep_active_date && sort_active_date < G()->unix_time() - 300) {
sort_active_date = 0;
}
auto sort_raise_hand_rating = can_manage ? raise_hand_rating : 0;
auto sort_joined_date = joined_date_asc ? std::numeric_limits<int32>::max() - joined_date : joined_date;
return GroupCallParticipantOrder(sort_active_date, sort_raise_hand_rating, sort_joined_date);
}
bool GroupCallParticipant::get_is_muted_by_themselves() const {
return have_pending_is_muted ? pending_is_muted_by_themselves : server_is_muted_by_themselves;
}
@ -66,10 +91,15 @@ int32 GroupCallParticipant::get_volume_level() const {
return pending_volume_level != 0 ? pending_volume_level : volume_level;
}
bool GroupCallParticipant::get_is_hand_raised() const {
return have_pending_is_hand_raised ? pending_is_hand_raised : raise_hand_rating != 0;
}
void GroupCallParticipant::update_from(const GroupCallParticipant &old_participant) {
CHECK(!old_participant.is_min);
if (joined_date < old_participant.joined_date) {
LOG(ERROR) << "Join date decreased from " << old_participant.joined_date << " to " << joined_date;
LOG(ERROR) << "Join date of " << old_participant.dialog_id << " decreased from " << old_participant.joined_date
<< " to " << joined_date;
joined_date = old_participant.joined_date;
}
if (active_date < old_participant.active_date) {
@ -84,6 +114,10 @@ void GroupCallParticipant::update_from(const GroupCallParticipant &old_participa
is_volume_level_local = true;
volume_level = old_participant.volume_level;
}
if (audio_source == old_participant.audio_source) {
is_self = old_participant.is_self;
}
}
is_min = false;
@ -95,9 +129,13 @@ void GroupCallParticipant::update_from(const GroupCallParticipant &old_participa
pending_is_muted_by_admin = old_participant.pending_is_muted_by_admin;
pending_is_muted_locally = old_participant.pending_is_muted_locally;
pending_is_muted_generation = old_participant.pending_is_muted_generation;
have_pending_is_hand_raised = old_participant.have_pending_is_hand_raised;
pending_is_hand_raised = old_participant.pending_is_hand_raised;
pending_is_hand_raised_generation = old_participant.pending_is_hand_raised_generation;
}
bool GroupCallParticipant::update_can_be_muted(bool can_manage, bool is_self, bool is_admin) {
bool GroupCallParticipant::update_can_be_muted(bool can_manage, bool is_admin) {
bool is_muted_by_admin = get_is_muted_by_admin();
bool is_muted_by_themselves = get_is_muted_by_themselves();
bool is_muted_locally = get_is_muted_locally();
@ -141,8 +179,8 @@ bool GroupCallParticipant::update_can_be_muted(bool can_manage, bool is_self, bo
return false;
}
bool GroupCallParticipant::set_pending_is_muted(bool is_muted, bool can_manage, bool is_self, bool is_admin) {
update_can_be_muted(can_manage, is_self, is_admin);
bool GroupCallParticipant::set_pending_is_muted(bool is_muted, bool can_manage, bool is_admin) {
update_can_be_muted(can_manage, is_admin);
if (is_muted) {
if (!can_be_muted_for_all_users && !can_be_muted_only_for_self) {
return false;
@ -197,32 +235,32 @@ bool GroupCallParticipant::set_pending_is_muted(bool is_muted, bool can_manage,
}
have_pending_is_muted = true;
update_can_be_muted(can_manage, is_self, is_admin);
update_can_be_muted(can_manage, is_admin);
return true;
}
td_api::object_ptr<td_api::groupCallParticipant> GroupCallParticipant::get_group_call_participant_object(
ContactsManager *contacts_manager) const {
td_api::object_ptr<td_api::groupCallParticipant> GroupCallParticipant::get_group_call_participant_object(Td *td) const {
if (!is_valid()) {
return nullptr;
}
return td_api::make_object<td_api::groupCallParticipant>(
contacts_manager->get_user_id_object(user_id, "get_group_call_participant_object"), audio_source, is_speaking,
can_be_muted_for_all_users, can_be_unmuted_for_all_users, can_be_muted_only_for_self,
td->messages_manager_->get_message_sender_object(dialog_id), audio_source, about, is_speaking,
get_is_hand_raised(), can_be_muted_for_all_users, can_be_unmuted_for_all_users, can_be_muted_only_for_self,
can_be_unmuted_only_for_self, get_is_muted_for_all_users(), get_is_muted_locally(), get_is_muted_by_themselves(),
get_volume_level(), order);
get_volume_level(), order.get_group_call_participant_order_object());
}
bool operator==(const GroupCallParticipant &lhs, const GroupCallParticipant &rhs) {
return lhs.user_id == rhs.user_id && lhs.audio_source == rhs.audio_source &&
return lhs.dialog_id == rhs.dialog_id && lhs.audio_source == rhs.audio_source && lhs.about == rhs.about &&
lhs.is_speaking == rhs.is_speaking && lhs.get_is_hand_raised() == rhs.get_is_hand_raised() &&
lhs.can_be_muted_for_all_users == rhs.can_be_muted_for_all_users &&
lhs.can_be_unmuted_for_all_users == rhs.can_be_unmuted_for_all_users &&
lhs.can_be_muted_only_for_self == rhs.can_be_muted_only_for_self &&
lhs.can_be_unmuted_only_for_self == rhs.can_be_unmuted_only_for_self &&
lhs.get_is_muted_for_all_users() == rhs.get_is_muted_for_all_users() &&
lhs.get_is_muted_locally() == rhs.get_is_muted_locally() &&
lhs.get_is_muted_by_themselves() == rhs.get_is_muted_by_themselves() && lhs.is_speaking == rhs.is_speaking &&
lhs.get_is_muted_by_themselves() == rhs.get_is_muted_by_themselves() &&
lhs.get_volume_level() == rhs.get_volume_level() && lhs.order == rhs.order;
}
@ -231,7 +269,7 @@ bool operator!=(const GroupCallParticipant &lhs, const GroupCallParticipant &rhs
}
StringBuilder &operator<<(StringBuilder &string_builder, const GroupCallParticipant &group_call_participant) {
return string_builder << '[' << group_call_participant.user_id << " with source "
return string_builder << '[' << group_call_participant.dialog_id << " with source "
<< group_call_participant.audio_source << " and order " << group_call_participant.order << ']';
}

View File

@ -6,27 +6,31 @@
//
#pragma once
#include "td/telegram/DialogId.h"
#include "td/telegram/GroupCallParticipantOrder.h"
#include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h"
#include "td/telegram/UserId.h"
#include "td/utils/common.h"
#include "td/utils/StringBuilder.h"
namespace td {
class ContactsManager;
class Td;
struct GroupCallParticipant {
UserId user_id;
DialogId dialog_id;
string about;
int32 audio_source = 0;
int32 joined_date = 0;
int32 active_date = 0;
int32 volume_level = 10000;
int64 raise_hand_rating = 0;
bool is_volume_level_local = false;
bool server_is_muted_by_themselves = false;
bool server_is_muted_by_admin = false;
bool server_is_muted_locally = false;
bool is_self = false;
bool can_be_muted_for_all_users = false;
bool can_be_unmuted_for_all_users = false;
@ -38,7 +42,8 @@ struct GroupCallParticipant {
bool is_just_joined = false;
bool is_speaking = false;
int32 local_active_date = 0;
int64 order = 0;
GroupCallParticipantOrder order;
int32 version = 0;
int32 pending_volume_level = 0;
uint64 pending_volume_level_generation = 0;
@ -49,27 +54,29 @@ struct GroupCallParticipant {
bool pending_is_muted_locally = false;
uint64 pending_is_muted_generation = 0;
bool have_pending_is_hand_raised = false;
bool pending_is_hand_raised = false;
uint64 pending_is_hand_raised_generation = 0;
static constexpr int32 MIN_VOLUME_LEVEL = 1;
static constexpr int32 MAX_VOLUME_LEVEL = 20000;
GroupCallParticipant() = default;
explicit GroupCallParticipant(const tl_object_ptr<telegram_api::groupCallParticipant> &participant);
GroupCallParticipant(const tl_object_ptr<telegram_api::groupCallParticipant> &participant, int32 call_version);
static bool is_versioned_update(const tl_object_ptr<telegram_api::groupCallParticipant> &participant);
void update_from(const GroupCallParticipant &old_participant);
bool update_can_be_muted(bool can_manage, bool is_self, bool is_admin);
bool update_can_be_muted(bool can_manage, bool is_admin);
bool set_pending_is_muted(bool is_muted, bool can_manage, bool is_self, bool is_admin);
bool set_pending_is_muted(bool is_muted, bool can_manage, bool is_admin);
int64 get_real_order() const {
return (static_cast<int64>(max(active_date, local_active_date)) << 32) + joined_date;
}
GroupCallParticipantOrder get_real_order(bool can_manage, bool joined_date_asc, bool keep_active_date) const;
bool is_valid() const {
return user_id.is_valid();
return dialog_id.is_valid();
}
bool get_is_muted_by_themselves() const;
@ -82,8 +89,9 @@ struct GroupCallParticipant {
int32 get_volume_level() const;
td_api::object_ptr<td_api::groupCallParticipant> get_group_call_participant_object(
ContactsManager *contacts_manager) const;
bool get_is_hand_raised() const;
td_api::object_ptr<td_api::groupCallParticipant> get_group_call_participant_object(Td *td) const;
};
bool operator==(const GroupCallParticipant &lhs, const GroupCallParticipant &rhs);

View File

@ -0,0 +1,64 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include "td/telegram/GroupCallParticipantOrder.h"
#include "td/utils/logging.h"
#include "td/utils/misc.h"
#include <limits>
#include <tuple>
namespace td {
GroupCallParticipantOrder GroupCallParticipantOrder::max() {
return GroupCallParticipantOrder(std::numeric_limits<int32>::max(), std::numeric_limits<int64>::max(),
std::numeric_limits<int32>::max());
}
bool GroupCallParticipantOrder::is_valid() const {
return *this != GroupCallParticipantOrder();
}
string GroupCallParticipantOrder::get_group_call_participant_order_object() const {
return PSTRING() << lpad0(to_string(active_date), 10) << lpad0(to_string(raise_hand_rating), 19)
<< lpad0(to_string(joined_date), 10);
}
bool operator==(const GroupCallParticipantOrder &lhs, const GroupCallParticipantOrder &rhs) {
return lhs.active_date == rhs.active_date && lhs.joined_date == rhs.joined_date &&
lhs.raise_hand_rating == rhs.raise_hand_rating;
}
bool operator!=(const GroupCallParticipantOrder &lhs, const GroupCallParticipantOrder &rhs) {
return !(lhs == rhs);
}
bool operator<(const GroupCallParticipantOrder &lhs, const GroupCallParticipantOrder &rhs) {
return std::tie(lhs.active_date, lhs.raise_hand_rating, lhs.joined_date) <
std::tie(rhs.active_date, rhs.raise_hand_rating, rhs.joined_date);
}
bool operator<=(const GroupCallParticipantOrder &lhs, const GroupCallParticipantOrder &rhs) {
return !(rhs < lhs);
}
bool operator>(const GroupCallParticipantOrder &lhs, const GroupCallParticipantOrder &rhs) {
return rhs < lhs;
}
bool operator>=(const GroupCallParticipantOrder &lhs, const GroupCallParticipantOrder &rhs) {
return !(lhs < rhs);
}
StringBuilder &operator<<(StringBuilder &string_builder,
const GroupCallParticipantOrder &group_call_participant_order) {
return string_builder << group_call_participant_order.active_date << '/'
<< group_call_participant_order.raise_hand_rating << '/'
<< group_call_participant_order.joined_date;
}
} // namespace td

View File

@ -0,0 +1,54 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#pragma once
#include "td/utils/common.h"
#include "td/utils/StringBuilder.h"
namespace td {
class GroupCallParticipantOrder {
int32 active_date = 0;
int32 joined_date = 0;
int64 raise_hand_rating = 0;
friend StringBuilder &operator<<(StringBuilder &string_builder,
const GroupCallParticipantOrder &group_call_participant_order);
friend bool operator==(const GroupCallParticipantOrder &lhs, const GroupCallParticipantOrder &rhs);
friend bool operator<(const GroupCallParticipantOrder &lhs, const GroupCallParticipantOrder &rhs);
public:
GroupCallParticipantOrder() = default;
GroupCallParticipantOrder(int32 active_date, int64 raise_hand_rating, int32 joined_date)
: active_date(active_date), joined_date(joined_date), raise_hand_rating(raise_hand_rating) {
}
static GroupCallParticipantOrder max();
bool is_valid() const;
string get_group_call_participant_order_object() const;
};
bool operator==(const GroupCallParticipantOrder &lhs, const GroupCallParticipantOrder &rhs);
bool operator!=(const GroupCallParticipantOrder &lhs, const GroupCallParticipantOrder &rhs);
bool operator<(const GroupCallParticipantOrder &lhs, const GroupCallParticipantOrder &rhs);
bool operator<=(const GroupCallParticipantOrder &lhs, const GroupCallParticipantOrder &rhs);
bool operator>(const GroupCallParticipantOrder &lhs, const GroupCallParticipantOrder &rhs);
bool operator>=(const GroupCallParticipantOrder &lhs, const GroupCallParticipantOrder &rhs);
StringBuilder &operator<<(StringBuilder &string_builder, const GroupCallParticipantOrder &group_call_participant_order);
} // namespace td

View File

@ -211,7 +211,7 @@ tl_object_ptr<telegram_api::inputBotInlineMessageID> InlineQueriesManager::get_i
if (!DcId::is_valid(result->dc_id_)) {
return nullptr;
}
LOG(INFO) << "Have inline message id: " << to_string(result);
LOG(INFO) << "Have inline message identifier: " << to_string(result);
return result;
}
@ -220,7 +220,7 @@ string InlineQueriesManager::get_inline_message_id(
if (input_bot_inline_message_id == nullptr) {
return string();
}
LOG(INFO) << "Got inline message id: " << to_string(input_bot_inline_message_id);
LOG(INFO) << "Got inline message identifier: " << to_string(input_bot_inline_message_id);
return base64url_encode(serialize(*input_bot_inline_message_id));
}

View File

@ -3841,9 +3841,9 @@ class SetTypingQuery : public Td::ResultHandler {
explicit SetTypingQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
}
NetQueryRef send(DialogId dialog_id, MessageId message_id, tl_object_ptr<telegram_api::SendMessageAction> &&action) {
NetQueryRef send(DialogId dialog_id, tl_object_ptr<telegram_api::InputPeer> &&input_peer, MessageId message_id,
tl_object_ptr<telegram_api::SendMessageAction> &&action) {
dialog_id_ = dialog_id;
auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Write);
CHECK(input_peer != nullptr);
int32 flags = 0;
@ -4634,11 +4634,18 @@ class RequestUrlAuthQuery : public Td::ResultHandler {
void send(string url, DialogId dialog_id, MessageId message_id, int32 button_id) {
url_ = std::move(url);
dialog_id_ = dialog_id;
auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Read);
CHECK(input_peer != nullptr);
int32 flags = 0;
tl_object_ptr<telegram_api::InputPeer> input_peer;
if (dialog_id.is_valid()) {
dialog_id_ = dialog_id;
input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Read);
CHECK(input_peer != nullptr);
flags |= telegram_api::messages_requestUrlAuth::PEER_MASK;
} else {
flags |= telegram_api::messages_requestUrlAuth::URL_MASK;
}
send_query(G()->net_query_creator().create(telegram_api::messages_requestUrlAuth(
std::move(input_peer), message_id.get_server_message_id().get(), button_id)));
flags, std::move(input_peer), message_id.get_server_message_id().get(), button_id, url_)));
}
void on_result(uint64 id, BufferSlice packet) override {
@ -4676,7 +4683,8 @@ class RequestUrlAuthQuery : public Td::ResultHandler {
}
void on_error(uint64 id, Status status) override {
if (!td->messages_manager_->on_get_dialog_error(dialog_id_, status, "RequestUrlAuthQuery")) {
if (!dialog_id_.is_valid() ||
!td->messages_manager_->on_get_dialog_error(dialog_id_, status, "RequestUrlAuthQuery")) {
LOG(INFO) << "RequestUrlAuthQuery returned " << status;
}
promise_.set_value(td_api::make_object<td_api::loginUrlInfoOpen>(url_, false));
@ -4694,15 +4702,21 @@ class AcceptUrlAuthQuery : public Td::ResultHandler {
void send(string url, DialogId dialog_id, MessageId message_id, int32 button_id, bool allow_write_access) {
url_ = std::move(url);
dialog_id_ = dialog_id;
auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Read);
CHECK(input_peer != nullptr);
int32 flags = 0;
tl_object_ptr<telegram_api::InputPeer> input_peer;
if (dialog_id.is_valid()) {
dialog_id_ = dialog_id;
input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Read);
CHECK(input_peer != nullptr);
flags |= telegram_api::messages_acceptUrlAuth::PEER_MASK;
} else {
flags |= telegram_api::messages_acceptUrlAuth::URL_MASK;
}
if (allow_write_access) {
flags |= telegram_api::messages_acceptUrlAuth::WRITE_ALLOWED_MASK;
}
send_query(G()->net_query_creator().create(telegram_api::messages_acceptUrlAuth(
flags, false /*ignored*/, std::move(input_peer), message_id.get_server_message_id().get(), button_id)));
flags, false /*ignored*/, std::move(input_peer), message_id.get_server_message_id().get(), button_id, url_)));
}
void on_result(uint64 id, BufferSlice packet) override {
@ -4729,7 +4743,8 @@ class AcceptUrlAuthQuery : public Td::ResultHandler {
}
void on_error(uint64 id, Status status) override {
if (!td->messages_manager_->on_get_dialog_error(dialog_id_, status, "AcceptUrlAuthQuery")) {
if (!dialog_id_.is_valid() ||
!td->messages_manager_->on_get_dialog_error(dialog_id_, status, "AcceptUrlAuthQuery")) {
LOG(INFO) << "AcceptUrlAuthQuery returned " << status;
}
promise_.set_error(std::move(status));
@ -5458,6 +5473,7 @@ void MessagesManager::Dialog::store(StorerT &storer) const {
bool has_last_yet_unsent_message = last_message_id.is_valid() && last_message_id.is_yet_unsent();
bool has_active_group_call_id = active_group_call_id.is_valid();
bool has_message_ttl_setting = !message_ttl_setting.is_empty();
bool has_default_join_group_call_as_dialog_id = default_join_group_call_as_dialog_id.is_valid();
BEGIN_STORE_FLAGS();
STORE_FLAG(has_draft_message);
STORE_FLAG(has_last_database_message);
@ -5519,6 +5535,7 @@ void MessagesManager::Dialog::store(StorerT &storer) const {
STORE_FLAG(can_invite_members);
STORE_FLAG(has_message_ttl_setting);
STORE_FLAG(is_message_ttl_setting_inited);
STORE_FLAG(has_default_join_group_call_as_dialog_id);
END_STORE_FLAGS();
}
@ -5609,6 +5626,9 @@ void MessagesManager::Dialog::store(StorerT &storer) const {
if (has_message_ttl_setting) {
store(message_ttl_setting, storer);
}
if (has_default_join_group_call_as_dialog_id) {
store(default_join_group_call_as_dialog_id, storer);
}
}
// do not forget to resolve dialog dependencies including dependencies of last_message
@ -5640,6 +5660,7 @@ void MessagesManager::Dialog::parse(ParserT &parser) {
bool has_distance = false;
bool has_active_group_call_id = false;
bool has_message_ttl_setting = false;
bool has_default_join_group_call_as_dialog_id = false;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(has_draft_message);
PARSE_FLAG(has_last_database_message);
@ -5701,6 +5722,7 @@ void MessagesManager::Dialog::parse(ParserT &parser) {
PARSE_FLAG(can_invite_members);
PARSE_FLAG(has_message_ttl_setting);
PARSE_FLAG(is_message_ttl_setting_inited);
PARSE_FLAG(has_default_join_group_call_as_dialog_id);
END_PARSE_FLAGS();
} else {
is_folder_id_inited = false;
@ -5843,6 +5865,9 @@ void MessagesManager::Dialog::parse(ParserT &parser) {
if (has_message_ttl_setting) {
parse(message_ttl_setting, parser);
}
if (has_default_join_group_call_as_dialog_id) {
parse(default_join_group_call_as_dialog_id, parser);
}
}
template <class StorerT>
@ -6114,6 +6139,13 @@ td_api::object_ptr<td_api::MessageSender> MessagesManager::get_message_sender_ob
return get_message_sender_object_const(user_id, dialog_id);
}
td_api::object_ptr<td_api::MessageSender> MessagesManager::get_message_sender_object_const(DialogId dialog_id) const {
if (dialog_id.get_type() == DialogType::User) {
return get_message_sender_object_const(dialog_id.get_user_id(), DialogId());
}
return get_message_sender_object_const(UserId(), dialog_id);
}
td_api::object_ptr<td_api::MessageSender> MessagesManager::get_message_sender_object(DialogId dialog_id) {
if (dialog_id.get_type() == DialogType::User) {
return get_message_sender_object(dialog_id.get_user_id(), DialogId());
@ -6992,7 +7024,7 @@ void MessagesManager::update_message_interaction_info(FullMessageId full_message
}
if (update_message_interaction_info(dialog_id, m, view_count, forward_count, has_reply_info,
std::move(new_reply_info))) {
std::move(new_reply_info), "update_message_interaction_info")) {
on_message_changed(d, m, true, "update_message_interaction_info");
}
}
@ -7077,7 +7109,7 @@ td_api::object_ptr<td_api::messageInteractionInfo> MessagesManager::get_message_
bool MessagesManager::update_message_interaction_info(DialogId dialog_id, Message *m, int32 view_count,
int32 forward_count, bool has_reply_info,
MessageReplyInfo &&reply_info) {
MessageReplyInfo &&reply_info, const char *source) {
CHECK(m != nullptr);
m->interaction_info_update_date = G()->unix_time(); // doesn't force message saving
if (m->message_id.is_valid_scheduled()) {
@ -7111,7 +7143,8 @@ bool MessagesManager::update_message_interaction_info(DialogId dialog_id, Messag
if (need_update_reply_info) {
if (m->reply_info.channel_id != reply_info.channel_id) {
if (m->reply_info.channel_id.is_valid() && reply_info.channel_id.is_valid() && m->message_id.is_server()) {
LOG(ERROR) << "Reply info changed from " << m->reply_info << " to " << reply_info;
LOG(ERROR) << "Reply info of " << FullMessageId{dialog_id, m->message_id} << " changed from " << m->reply_info
<< " to " << reply_info << " from " << source;
}
}
m->reply_info = std::move(reply_info);
@ -7341,13 +7374,14 @@ void MessagesManager::on_update_delete_scheduled_messages(DialogId dialog_id,
send_update_chat_has_scheduled_messages(d, true);
}
void MessagesManager::on_user_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, UserId user_id,
DialogAction action, int32 date, MessageContentType message_content_type) {
if (td_->auth_manager_->is_bot() || !user_id.is_valid() || is_broadcast_channel(dialog_id)) {
void MessagesManager::on_user_dialog_action(DialogId dialog_id, MessageId top_thread_message_id,
DialogId typing_dialog_id, DialogAction action, int32 date,
MessageContentType message_content_type) {
if (td_->auth_manager_->is_bot() || !typing_dialog_id.is_valid() || is_broadcast_channel(dialog_id)) {
return;
}
if (top_thread_message_id != MessageId() && !top_thread_message_id.is_valid()) {
LOG(ERROR) << "Ignore typing in the message thread of " << top_thread_message_id;
LOG(ERROR) << "Ignore " << action << " in the message thread of " << top_thread_message_id;
return;
}
@ -7360,10 +7394,17 @@ void MessagesManager::on_user_dialog_action(DialogId dialog_id, MessageId top_th
const Dialog *d = get_dialog_force(dialog_id);
if (d != nullptr && d->active_group_call_id.is_valid()) {
auto group_call_id = td_->group_call_manager_->get_group_call_id(d->active_group_call_id, dialog_id);
td_->group_call_manager_->on_user_speaking_in_group_call(group_call_id, user_id, date);
td_->group_call_manager_->on_user_speaking_in_group_call(group_call_id, dialog_id, date);
}
return;
}
if (typing_dialog_id.get_type() != DialogType::User) {
LOG(ERROR) << "Ignore " << action << " of " << typing_dialog_id << " in " << dialog_id;
return;
}
auto user_id = typing_dialog_id.get_user_id();
{
auto message_import_progress = action.get_importing_messages_action_progress();
if (message_import_progress >= 0) {
@ -7373,11 +7414,11 @@ void MessagesManager::on_user_dialog_action(DialogId dialog_id, MessageId top_th
}
if (!td_->contacts_manager_->have_min_user(user_id)) {
LOG(DEBUG) << "Ignore typing of unknown " << user_id;
LOG(DEBUG) << "Ignore " << action << " of unknown " << user_id;
return;
}
if (!have_dialog(dialog_id)) {
LOG(DEBUG) << "Ignore typing in unknown " << dialog_id;
LOG(DEBUG) << "Ignore " << action << " in unknown " << dialog_id;
return;
}
@ -7466,7 +7507,8 @@ void MessagesManager::cancel_user_dialog_action(DialogId dialog_id, const Messag
return;
}
on_user_dialog_action(dialog_id, MessageId(), m->sender_user_id, DialogAction(), m->date, m->content->get_type());
on_user_dialog_action(dialog_id, MessageId(), DialogId(m->sender_user_id), DialogAction(), m->date,
m->content->get_type());
}
void MessagesManager::add_pending_channel_update(DialogId dialog_id, tl_object_ptr<telegram_api::Update> &&update,
@ -8768,6 +8810,21 @@ void MessagesManager::get_login_url(DialogId dialog_id, MessageId message_id, in
->send(r_url.move_as_ok(), dialog_id, message_id, button_id, allow_write_access);
}
void MessagesManager::get_link_login_url_info(const string &url,
Promise<td_api::object_ptr<td_api::LoginUrlInfo>> &&promise) {
if (G()->close_flag()) {
return promise.set_value(td_api::make_object<td_api::loginUrlInfoOpen>(url, false));
}
td_->create_handler<RequestUrlAuthQuery>(std::move(promise))->send(url, DialogId(), MessageId(), 0);
}
void MessagesManager::get_link_login_url(const string &url, bool allow_write_access,
Promise<td_api::object_ptr<td_api::httpUrl>> &&promise) {
td_->create_handler<AcceptUrlAuthQuery>(std::move(promise))
->send(url, DialogId(), MessageId(), 0, allow_write_access);
}
void MessagesManager::load_secret_thumbnail(FileId thumbnail_file_id) {
class Callback : public FileManager::DownloadCallback {
public:
@ -11246,10 +11303,6 @@ void MessagesManager::on_dialog_deleted(DialogId dialog_id, Promise<Unit> &&prom
}
void MessagesManager::on_update_dialog_group_call_rights(DialogId dialog_id) {
if (td_->auth_manager_->is_bot()) {
return;
}
auto d = get_dialog(dialog_id);
if (d == nullptr) {
// nothing to do
@ -11581,7 +11634,7 @@ void MessagesManager::read_history_inbox(DialogId dialog_id, MessageId max_messa
LOG(ERROR) << "Have unknown " << unread_count << " unread messages up to " << max_message_id << " in "
<< dialog_id << " with last_new_message_id = " << d->last_new_message_id
<< ", last_message_id = " << d->last_message_id
<< ", last_database_message_id = " << d->last_database_message_id;
<< ", last_database_message_id = " << d->last_database_message_id << " from " << source;
}
unread_count = 0;
}
@ -12795,7 +12848,7 @@ void MessagesManager::init() {
} else if (begins_with(log_string, " local message ")) {
log_string.remove_prefix(15);
} else {
LOG(ERROR) << "Message id expected, found " << log_string;
LOG(ERROR) << "Message identifier expected, found " << log_string;
continue;
}
@ -13713,7 +13766,7 @@ std::pair<DialogId, unique_ptr<MessagesManager::Message>> MessagesManager::creat
message->contains_mention || dialog_type == DialogType::User);
if (content_type == MessageContentType::ExpiredPhoto || content_type == MessageContentType::ExpiredVideo) {
CHECK(message->ttl == 0); // ttl is ignored/set to 0 if the message has already been expired
CHECK(message->ttl == 0); // TTL is ignored/set to 0 if the message has already been expired
if (message->reply_markup != nullptr) {
if (message->reply_markup->type != ReplyMarkup::Type::InlineKeyboard) {
message->had_reply_markup = true;
@ -13728,7 +13781,7 @@ std::pair<DialogId, unique_ptr<MessagesManager::Message>> MessagesManager::creat
if (message_info.media_album_id != 0) {
if (!is_allowed_media_group_content(content_type)) {
LOG(ERROR) << "Receive media group id " << message_info.media_album_id << " in " << message_id << " from "
LOG(ERROR) << "Receive media group identifier " << message_info.media_album_id << " in " << message_id << " from "
<< dialog_id << " with content "
<< oneline(to_string(
get_message_content_object(message->content.get(), td_, message->date, is_content_secret)));
@ -13820,14 +13873,14 @@ FullMessageId MessagesManager::on_get_message(MessageInfo &&message_info, bool f
if (message_id <= d->last_new_message_id) {
if (get_message_force(d, message_id, "receive missed unsent message not from update") != nullptr) {
LOG(ERROR) << "New " << old_message_id << "/" << message_id << " in " << dialog_id << " from " << source
<< " has id less than last_new_message_id = " << d->last_new_message_id;
<< " has identifier less than last_new_message_id = " << d->last_new_message_id;
return FullMessageId();
}
// if there is no message yet, then it is likely was missed because of a server bug and is being repaired via
// get_message_from_server from after_get_difference
// TODO move to INFO
LOG(ERROR) << "Receive " << old_message_id << "/" << message_id << " in " << dialog_id << " from " << source
<< " with id less than last_new_message_id = " << d->last_new_message_id
<< " with identifier less than last_new_message_id = " << d->last_new_message_id
<< " and trying to add it anyway";
} else {
LOG(ERROR) << "Ignore " << old_message_id << "/" << message_id << " received not through update from " << source
@ -15094,8 +15147,8 @@ void MessagesManager::fix_dialog_last_notification_id(Dialog *d, bool from_menti
CHECK(!message_id.is_scheduled());
MessagesConstIterator it(d, message_id);
auto &group_info = from_mentions ? d->mention_notification_group : d->message_notification_group;
VLOG(notifications) << "Trying to fix last notification id in " << group_info.group_id << " from " << d->dialog_id
<< " from " << message_id << "/" << group_info.last_notification_id;
VLOG(notifications) << "Trying to fix last notification identifier in " << group_info.group_id << " from "
<< d->dialog_id << " from " << message_id << "/" << group_info.last_notification_id;
if (*it != nullptr && ((*it)->message_id == message_id || (*it)->have_next)) {
while (*it != nullptr) {
const Message *m = *it;
@ -20116,6 +20169,16 @@ td_api::object_ptr<td_api::ChatActionBar> MessagesManager::get_chat_action_bar_o
return nullptr;
}
td_api::object_ptr<td_api::voiceChat> MessagesManager::get_voice_chat_object(const Dialog *d) const {
auto active_group_call_id = td_->group_call_manager_->get_group_call_id(d->active_group_call_id, d->dialog_id);
auto default_participant_alias = d->default_join_group_call_as_dialog_id.is_valid()
? get_message_sender_object_const(d->default_join_group_call_as_dialog_id)
: nullptr;
return make_tl_object<td_api::voiceChat>(active_group_call_id.get(),
active_group_call_id.is_valid() ? !d->is_group_call_empty : false,
std::move(default_participant_alias));
}
td_api::object_ptr<td_api::chat> MessagesManager::get_chat_object(const Dialog *d) const {
CHECK(d != nullptr);
@ -20175,8 +20238,6 @@ td_api::object_ptr<td_api::chat> MessagesManager::get_chat_object(const Dialog *
// TODO hide/show draft message when can_send_message(dialog_id) changes
auto draft_message = can_send_message(d->dialog_id).is_ok() ? get_draft_message_object(d->draft_message) : nullptr;
auto active_group_call_id = td_->group_call_manager_->get_group_call_id(d->active_group_call_id, d->dialog_id);
return make_tl_object<td_api::chat>(
d->dialog_id.get(), get_chat_type_object(d->dialog_id), get_dialog_title(d->dialog_id),
get_chat_photo_info_object(td_->file_manager_.get(), get_dialog_photo(d->dialog_id)),
@ -20187,8 +20248,7 @@ td_api::object_ptr<td_api::chat> MessagesManager::get_chat_object(const Dialog *
d->server_unread_count + d->local_unread_count, d->last_read_inbox_message_id.get(),
d->last_read_outbox_message_id.get(), d->unread_mention_count,
get_chat_notification_settings_object(&d->notification_settings),
d->message_ttl_setting.get_message_ttl_setting_object(), get_chat_action_bar_object(d),
active_group_call_id.get(), active_group_call_id.is_valid() ? d->is_group_call_empty : true,
d->message_ttl_setting.get_message_ttl_setting_object(), get_chat_action_bar_object(d), get_voice_chat_object(d),
d->reply_markup_message_id.get(), std::move(draft_message), d->client_data);
}
@ -26136,7 +26196,8 @@ unique_ptr<MessagesManager::MessageForwardInfo> MessagesManager::get_message_for
if (forward_header->from_id_ != nullptr) {
sender_dialog_id = DialogId(forward_header->from_id_);
if (!sender_dialog_id.is_valid()) {
LOG(ERROR) << "Receive invalid sender id in message forward header: " << oneline(to_string(forward_header));
LOG(ERROR) << "Receive invalid sender identifier in message forward header: "
<< oneline(to_string(forward_header));
sender_dialog_id = DialogId();
}
}
@ -27534,8 +27595,9 @@ MessagesManager::MessageNotificationGroup MessagesManager::get_message_notificat
if (last_notification_date != group_info.last_notification_date ||
last_notification_id != group_info.last_notification_id) {
LOG(ERROR) << "Fix last notification date in " << d->dialog_id << " from " << group_info.last_notification_date
<< " to " << last_notification_date << " and last notification id from "
<< group_info.last_notification_id << " to " << last_notification_id;
<< " to " << last_notification_date << " and last notification identifier from "
<< group_info.last_notification_id << " to " << last_notification_id << " in " << group_id << " of type "
<< result.type;
set_dialog_last_notification(d->dialog_id, group_info, last_notification_date, last_notification_id,
"get_message_notification_group_force");
}
@ -27641,7 +27703,8 @@ vector<Notification> MessagesManager::get_message_notifications_from_database_fo
auto notification_id = m->notification_id.is_valid() ? m->notification_id : m->removed_notification_id;
if (!notification_id.is_valid()) {
VLOG(ERROR) << "Can't find notification ID for " << m->message_id << " in " << d->dialog_id;
LOG(ERROR) << "Can't find notification identifier for " << m->message_id << " in " << d->dialog_id
<< " with from_mentions = " << from_mentions;
continue;
}
CHECK(m->message_id.is_valid());
@ -27649,7 +27712,7 @@ vector<Notification> MessagesManager::get_message_notifications_from_database_fo
bool is_correct = true;
if (notification_id.get() >= from_notification_id.get()) {
// possible if two messages has the same notification_id
LOG(ERROR) << "Have nonmonotoic notification ids: " << d->dialog_id << " " << m->message_id << " "
LOG(ERROR) << "Have nonmonotonic notification identifiers: " << d->dialog_id << " " << m->message_id << " "
<< notification_id << " " << from_message_id << " " << from_notification_id;
is_correct = false;
} else {
@ -27657,8 +27720,8 @@ vector<Notification> MessagesManager::get_message_notifications_from_database_fo
is_found = true;
}
if (m->message_id >= from_message_id) {
LOG(ERROR) << "Have nonmonotoic message ids: " << d->dialog_id << " " << m->message_id << " " << notification_id
<< " " << from_message_id << " " << from_notification_id;
LOG(ERROR) << "Have nonmonotonic message identifiers: " << d->dialog_id << " " << m->message_id << " "
<< notification_id << " " << from_message_id << " " << from_notification_id;
is_correct = false;
} else {
from_message_id = m->message_id;
@ -27900,7 +27963,8 @@ void MessagesManager::on_get_message_notifications_from_database(DialogId dialog
auto notification_id = m->notification_id.is_valid() ? m->notification_id : m->removed_notification_id;
if (!notification_id.is_valid()) {
VLOG(ERROR) << "Can't find notification ID for " << m->message_id << " in " << d->dialog_id;
LOG(ERROR) << "Can't find notification identifier for " << m->message_id << " in " << d->dialog_id
<< " with from_mentions = " << from_mentions;
continue;
}
CHECK(m->message_id.is_valid());
@ -28877,10 +28941,8 @@ void MessagesManager::send_update_chat_voice_chat(const Dialog *d) {
CHECK(d != nullptr);
LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id << " in send_update_chat_voice_chat";
on_dialog_updated(d->dialog_id, "send_update_chat_voice_chat");
auto group_call_id = td_->group_call_manager_->get_group_call_id(d->active_group_call_id, d->dialog_id);
send_closure(G()->td(), &Td::send_update,
td_api::make_object<td_api::updateChatVoiceChat>(d->dialog_id.get(), group_call_id.get(),
d->is_group_call_empty));
td_api::make_object<td_api::updateChatVoiceChat>(d->dialog_id.get(), get_voice_chat_object(d)));
}
void MessagesManager::send_update_chat_message_ttl_setting(const Dialog *d) {
@ -30058,12 +30120,11 @@ void MessagesManager::do_set_dialog_folder_id(Dialog *d, FolderId folder_id) {
}
void MessagesManager::on_update_dialog_group_call(DialogId dialog_id, bool has_active_group_call,
bool is_group_call_empty, const char *source) {
bool is_group_call_empty, const char *source, bool force) {
LOG(INFO) << "Update voice chat in " << dialog_id << " with has_active_voice_chat = " << has_active_group_call
<< " and is_voice_chat_empty = " << is_group_call_empty << " from " << source;
CHECK(dialog_id.is_valid());
Dialog *d = get_dialog(dialog_id); // must not create the Dialog, because is called from on_get_chat
Dialog *d = get_dialog(dialog_id); // must not create the Dialog, because it is called from on_get_chat
if (d == nullptr) {
LOG(INFO) << "Can't find " << dialog_id;
pending_dialog_group_call_updates_[dialog_id] = {has_active_group_call, is_group_call_empty};
@ -30073,9 +30134,20 @@ void MessagesManager::on_update_dialog_group_call(DialogId dialog_id, bool has_a
if (!has_active_group_call) {
is_group_call_empty = false;
}
if (d->active_group_call_id.is_valid() && has_active_group_call && is_group_call_empty &&
(td_->group_call_manager_->is_group_call_being_joined(d->active_group_call_id) ||
td_->group_call_manager_->is_group_call_joined(d->active_group_call_id))) {
LOG(INFO) << "Fix is_group_call_empty to false";
is_group_call_empty = false;
}
if (d->has_active_group_call == has_active_group_call && d->is_group_call_empty == is_group_call_empty) {
return;
}
if (!force && d->active_group_call_id.is_valid() && has_active_group_call &&
td_->group_call_manager_->is_group_call_being_joined(d->active_group_call_id)) {
LOG(INFO) << "Ignore update in a being joined group call";
return;
}
if (d->has_active_group_call && !has_active_group_call && d->active_group_call_id.is_valid()) {
d->active_group_call_id = InputGroupCallId();
@ -30118,6 +30190,36 @@ void MessagesManager::on_update_dialog_group_call_id(DialogId dialog_id, InputGr
}
}
void MessagesManager::on_update_dialog_default_join_group_call_as_dialog_id(DialogId dialog_id,
DialogId default_join_as_dialog_id,
bool force) {
auto d = get_dialog_force(dialog_id);
if (d == nullptr) {
// nothing to do
return;
}
if (!force && d->active_group_call_id.is_valid() &&
td_->group_call_manager_->is_group_call_being_joined(d->active_group_call_id)) {
LOG(INFO) << "Ignore default_join_as_dialog_id update in a being joined group call";
return;
}
if (default_join_as_dialog_id.is_valid()) {
if (default_join_as_dialog_id.get_type() != DialogType::User) {
force_create_dialog(default_join_as_dialog_id, "on_update_dialog_default_join_group_call_as_dialog_id");
} else if (!td_->contacts_manager_->have_user_force(default_join_as_dialog_id.get_user_id()) ||
default_join_as_dialog_id != get_my_dialog_id()) {
default_join_as_dialog_id = DialogId();
}
}
if (d->default_join_group_call_as_dialog_id != default_join_as_dialog_id) {
d->default_join_group_call_as_dialog_id = default_join_as_dialog_id;
send_update_chat_voice_chat(d);
}
}
void MessagesManager::on_update_dialog_message_ttl_setting(DialogId dialog_id, MessageTtlSetting message_ttl_setting) {
auto d = get_dialog_force(dialog_id);
if (d == nullptr) {
@ -30734,16 +30836,26 @@ void MessagesManager::send_dialog_action(DialogId dialog_id, MessageId top_threa
return promise.set_error(Status::Error(5, "Invalid message thread specified"));
}
auto can_send_status = can_send_message(dialog_id);
if (can_send_status.is_error()) {
if (td_->auth_manager_->is_bot()) {
return promise.set_error(can_send_status.move_as_error());
tl_object_ptr<telegram_api::InputPeer> input_peer;
if (action == DialogAction::get_speaking_action()) {
input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read);
if (input_peer == nullptr) {
return promise.set_error(Status::Error(400, "Have no access to the chat"));
}
} else {
auto can_send_status = can_send_message(dialog_id);
if (can_send_status.is_error()) {
if (td_->auth_manager_->is_bot()) {
return promise.set_error(can_send_status.move_as_error());
}
return promise.set_value(Unit());
}
return promise.set_value(Unit());
}
if (is_dialog_action_unneeded(dialog_id)) {
return promise.set_value(Unit());
if (is_dialog_action_unneeded(dialog_id)) {
return promise.set_value(Unit());
}
input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write);
}
if (dialog_id.get_type() == DialogType::SecretChat) {
@ -30758,8 +30870,9 @@ void MessagesManager::send_dialog_action(DialogId dialog_id, MessageId top_threa
LOG(INFO) << "Cancel previous send chat action query";
cancel_query(query_ref);
}
query_ref = td_->create_handler<SetTypingQuery>(std::move(promise))
->send(dialog_id, top_thread_message_id, action.get_input_send_message_action());
query_ref =
td_->create_handler<SetTypingQuery>(std::move(promise))
->send(dialog_id, std::move(input_peer), top_thread_message_id, action.get_input_send_message_action());
}
void MessagesManager::on_send_dialog_action_timeout(DialogId dialog_id) {
@ -30834,8 +30947,8 @@ void MessagesManager::on_active_dialog_action_timeout(DialogId dialog_id) {
while (actions_it->second[0].start_time + DIALOG_ACTION_TIMEOUT < now + 0.1) {
CHECK(actions_it->second[0].user_id != prev_user_id);
prev_user_id = actions_it->second[0].user_id;
on_user_dialog_action(dialog_id, actions_it->second[0].top_thread_message_id, actions_it->second[0].user_id,
DialogAction(), 0);
on_user_dialog_action(dialog_id, actions_it->second[0].top_thread_message_id,
DialogId(actions_it->second[0].user_id), DialogAction(), 0);
actions_it = active_dialog_actions_.find(dialog_id);
if (actions_it == active_dialog_actions_.end()) {
@ -30854,8 +30967,8 @@ void MessagesManager::clear_active_dialog_actions(DialogId dialog_id) {
auto actions_it = active_dialog_actions_.find(dialog_id);
while (actions_it != active_dialog_actions_.end()) {
CHECK(!actions_it->second.empty());
on_user_dialog_action(dialog_id, actions_it->second[0].top_thread_message_id, actions_it->second[0].user_id,
DialogAction(), 0);
on_user_dialog_action(dialog_id, actions_it->second[0].top_thread_message_id,
DialogId(actions_it->second[0].user_id), DialogAction(), 0);
actions_it = active_dialog_actions_.find(dialog_id);
}
}
@ -31826,31 +31939,30 @@ tl_object_ptr<td_api::ChatEventAction> MessagesManager::get_chat_event_action_ob
}
case telegram_api::channelAdminLogEventActionParticipantMute::ID: {
auto action = move_tl_object_as<telegram_api::channelAdminLogEventActionParticipantMute>(action_ptr);
GroupCallParticipant participant(std::move(action->participant_));
GroupCallParticipant participant(std::move(action->participant_), 0);
if (!participant.is_valid()) {
return nullptr;
}
return make_tl_object<td_api::chatEventVoiceChatParticipantIsMutedToggled>(
td_->contacts_manager_->get_user_id_object(participant.user_id, "LogEventActionParticipantMute"), true);
get_message_sender_object(participant.dialog_id), true);
}
case telegram_api::channelAdminLogEventActionParticipantUnmute::ID: {
auto action = move_tl_object_as<telegram_api::channelAdminLogEventActionParticipantUnmute>(action_ptr);
GroupCallParticipant participant(std::move(action->participant_));
GroupCallParticipant participant(std::move(action->participant_), 0);
if (!participant.is_valid()) {
return nullptr;
}
return make_tl_object<td_api::chatEventVoiceChatParticipantIsMutedToggled>(
td_->contacts_manager_->get_user_id_object(participant.user_id, "LogEventActionParticipantUnmute"), false);
get_message_sender_object(participant.dialog_id), false);
}
case telegram_api::channelAdminLogEventActionParticipantVolume::ID: {
auto action = move_tl_object_as<telegram_api::channelAdminLogEventActionParticipantVolume>(action_ptr);
GroupCallParticipant participant(std::move(action->participant_));
GroupCallParticipant participant(std::move(action->participant_), 0);
if (!participant.is_valid()) {
return nullptr;
}
return make_tl_object<td_api::chatEventVoiceChatParticipantVolumeLevelChanged>(
td_->contacts_manager_->get_user_id_object(participant.user_id, "LogEventActionParticipantVolume"),
participant.volume_level);
get_message_sender_object(participant.dialog_id), participant.volume_level);
}
case telegram_api::channelAdminLogEventActionToggleGroupCallSetting::ID: {
auto action = move_tl_object_as<telegram_api::channelAdminLogEventActionToggleGroupCallSetting>(action_ptr);
@ -32248,7 +32360,7 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq
<< d->last_new_message_id << " to " << message_id;
}
LOG(ERROR) << "New " << message_id << " in " << dialog_id << " from " << source
<< " has id less than last_new_message_id = " << d->last_new_message_id;
<< " has identifier less than last_new_message_id = " << d->last_new_message_id;
dump_debug_message_op(d);
}
}
@ -32694,7 +32806,7 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq
set_dialog_last_read_inbox_message_id(d, MessageId::min(), server_unread_count, local_unread_count, false,
source);
} else {
// if non-scheduled outgoing message has id one greater than last_read_inbox_message_id,
// if non-scheduled outgoing message has identifier one greater than last_read_inbox_message_id,
// then definitely there are no unread incoming messages before it
if (message_id.is_server() && d->last_read_inbox_message_id.is_valid() &&
d->last_read_inbox_message_id.is_server() &&
@ -32767,7 +32879,8 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq
if (next_message != nullptr) {
if (next_message->message_id.is_server() &&
!(td_->auth_manager_->is_bot() && Slice(source) == Slice("GetChannelMessagesQuery"))) {
LOG(ERROR) << "Can't attach " << m->message_id << " from " << source << " before " << next_message->message_id
LOG(ERROR) << "Can't attach " << m->message_id << " from " << source << " from "
<< (m->from_database ? "database" : "server") << " before " << next_message->message_id
<< " and after " << previous_message->message_id << " in " << dialog_id;
dump_debug_message_op(d);
}
@ -33519,9 +33632,10 @@ bool MessagesManager::update_message(Dialog *d, Message *old_message, unique_ptr
CHECK(!is_scheduled);
if (old_message->notification_id.is_valid()) {
if (new_message->notification_id.is_valid()) {
LOG(ERROR) << "Notification id for " << message_id << " in " << dialog_id << " has tried to change from "
<< old_message->notification_id << " to " << new_message->notification_id
<< ", message content type is " << old_content_type << '/' << new_content_type;
LOG(ERROR) << "Notification identifier for " << message_id << " in " << dialog_id
<< " has tried to change from " << old_message->notification_id << " to "
<< new_message->notification_id << ", message content type is " << old_content_type << '/'
<< new_content_type;
}
} else {
CHECK(new_message->notification_id.is_valid());
@ -33640,7 +33754,7 @@ bool MessagesManager::update_message(Dialog *d, Message *old_message, unique_ptr
need_send_update = true;
}
if (update_message_interaction_info(dialog_id, old_message, new_message->view_count, new_message->forward_count, true,
std::move(new_message->reply_info))) {
std::move(new_message->reply_info), "update_message")) {
need_send_update = true;
}
if (old_message->restriction_reasons != new_message->restriction_reasons) {
@ -34125,6 +34239,10 @@ MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr<Dialog> &&d,
MessageId last_clear_history_message_id = d->last_clear_history_message_id;
d->last_clear_history_date = 0;
d->last_clear_history_message_id = MessageId();
DialogId default_join_group_call_as_dialog_id = d->default_join_group_call_as_dialog_id;
if (default_join_group_call_as_dialog_id != dialog_id && !have_dialog(default_join_group_call_as_dialog_id)) {
d->default_join_group_call_as_dialog_id = DialogId();
}
if (d->message_notification_group.group_id.is_valid()) {
notification_group_id_to_dialog_id_.emplace(d->message_notification_group.group_id, d->dialog_id);
@ -34163,14 +34281,15 @@ MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr<Dialog> &&d,
send_update_new_chat(dialog);
fix_new_dialog(dialog, std::move(last_database_message), last_database_message_id, order, last_clear_history_date,
last_clear_history_message_id, is_loaded_from_database);
last_clear_history_message_id, default_join_group_call_as_dialog_id, is_loaded_from_database);
return dialog;
}
void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr<Message> &&last_database_message,
MessageId last_database_message_id, int64 order, int32 last_clear_history_date,
MessageId last_clear_history_message_id, bool is_loaded_from_database) {
MessageId last_clear_history_message_id,
DialogId default_join_group_call_as_dialog_id, bool is_loaded_from_database) {
CHECK(d != nullptr);
auto dialog_id = d->dialog_id;
auto dialog_type = dialog_id.get_type();
@ -34203,11 +34322,11 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr<Message> &&last_datab
}
if (being_added_dialog_id_ != dialog_id && !d->is_folder_id_inited && !td_->auth_manager_->is_bot() &&
order != DEFAULT_ORDER) {
// asynchronously get dialog folder id from the server
// asynchronously get dialog folder identifier from the server
get_dialog_info_full(dialog_id, Auto());
}
if (!d->is_message_ttl_setting_inited && !td_->auth_manager_->is_bot() && order != DEFAULT_ORDER) {
// asynchronously get dialog message ttl setting from the server
// asynchronously get dialog message TTL setting from the server
get_dialog_info_full(dialog_id, Auto());
}
if (!d->know_action_bar && !td_->auth_manager_->is_bot() && dialog_type != DialogType::SecretChat &&
@ -34274,18 +34393,32 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr<Message> &&last_datab
}
}
auto pending_it = pending_add_dialog_last_database_message_dependent_dialogs_.find(dialog_id);
if (pending_it != pending_add_dialog_last_database_message_dependent_dialogs_.end()) {
auto pending_dialogs = std::move(pending_it->second);
pending_add_dialog_last_database_message_dependent_dialogs_.erase(pending_it);
{
auto it = pending_add_dialog_last_database_message_dependent_dialogs_.find(dialog_id);
if (it != pending_add_dialog_last_database_message_dependent_dialogs_.end()) {
auto pending_dialog_ids = std::move(it->second);
pending_add_dialog_last_database_message_dependent_dialogs_.erase(it);
for (auto &pending_dialog_id : pending_dialogs) {
auto &counter_message = pending_add_dialog_last_database_message_[pending_dialog_id];
CHECK(counter_message.first > 0);
counter_message.first--;
if (counter_message.first == 0) {
add_dialog_last_database_message(get_dialog(pending_dialog_id), std::move(counter_message.second));
pending_add_dialog_last_database_message_.erase(pending_dialog_id);
for (auto &pending_dialog_id : pending_dialog_ids) {
auto &counter_message = pending_add_dialog_last_database_message_[pending_dialog_id];
CHECK(counter_message.first > 0);
counter_message.first--;
if (counter_message.first == 0) {
add_dialog_last_database_message(get_dialog(pending_dialog_id), std::move(counter_message.second));
pending_add_dialog_last_database_message_.erase(pending_dialog_id);
}
}
}
}
{
auto it = pending_add_default_join_group_call_as_dialog_id_.find(dialog_id);
if (it != pending_add_default_join_group_call_as_dialog_id_.end()) {
auto pending_dialog_ids = std::move(it->second);
pending_add_default_join_group_call_as_dialog_id_.erase(it);
for (auto &pending_dialog_id : pending_dialog_ids) {
on_update_dialog_default_join_group_call_as_dialog_id(pending_dialog_id, dialog_id, false);
}
}
}
@ -34384,6 +34517,17 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr<Message> &&last_datab
}
}
if (default_join_group_call_as_dialog_id != d->default_join_group_call_as_dialog_id) {
CHECK(default_join_group_call_as_dialog_id.is_valid());
if (!have_dialog(default_join_group_call_as_dialog_id)) {
LOG(INFO) << "Postpone adding of default join voice chat as " << default_join_group_call_as_dialog_id << " in "
<< dialog_id;
pending_add_default_join_group_call_as_dialog_id_[default_join_group_call_as_dialog_id].push_back(dialog_id);
} else {
on_update_dialog_default_join_group_call_as_dialog_id(dialog_id, default_join_group_call_as_dialog_id, false);
}
}
switch (dialog_type) {
case DialogType::User:
break;
@ -35163,6 +35307,9 @@ unique_ptr<MessagesManager::Dialog> MessagesManager::parse_dialog(DialogId dialo
Dependencies dependencies;
add_dialog_dependencies(dependencies, dialog_id);
if (d->default_join_group_call_as_dialog_id != dialog_id) {
add_dialog_and_dependencies(dependencies, d->default_join_group_call_as_dialog_id);
}
if (d->messages != nullptr) {
add_message_dependencies(dependencies, dialog_id, d->messages.get());
}

View File

@ -151,6 +151,8 @@ class MessagesManager : public Actor {
td_api::object_ptr<td_api::MessageSender> get_message_sender_object(UserId user_id, DialogId dialog_id);
td_api::object_ptr<td_api::MessageSender> get_message_sender_object_const(DialogId dialog_id) const;
td_api::object_ptr<td_api::MessageSender> get_message_sender_object(DialogId dialog_id);
static vector<MessageId> get_message_ids(const vector<int64> &input_message_ids);
@ -290,10 +292,13 @@ class MessagesManager : public Actor {
void on_update_dialog_folder_id(DialogId dialog_id, FolderId folder_id);
void on_update_dialog_group_call(DialogId dialog_id, bool has_active_group_call, bool is_group_call_empty,
const char *source);
const char *source, bool force = false);
void on_update_dialog_group_call_id(DialogId dialog_id, InputGroupCallId input_group_call_id);
void on_update_dialog_default_join_group_call_as_dialog_id(DialogId dialog_id, DialogId default_join_as_dialog_id,
bool force);
void on_update_dialog_message_ttl_setting(DialogId dialog_id, MessageTtlSetting message_ttl_setting);
void on_update_dialog_filters();
@ -338,8 +343,9 @@ class MessagesManager : public Actor {
void on_update_delete_scheduled_messages(DialogId dialog_id, vector<ScheduledServerMessageId> &&server_message_ids);
void on_user_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, UserId user_id, DialogAction action,
int32 date, MessageContentType message_content_type = MessageContentType::None);
void on_user_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, DialogId typing_dialog_id,
DialogAction action, int32 date,
MessageContentType message_content_type = MessageContentType::None);
void read_history_inbox(DialogId dialog_id, MessageId max_message_id, int32 unread_count, const char *source);
@ -502,6 +508,11 @@ class MessagesManager : public Actor {
bool have_dialog(DialogId dialog_id) const;
bool have_dialog_force(DialogId dialog_id);
bool have_dialog_info(DialogId dialog_id) const;
bool have_dialog_info_force(DialogId dialog_id) const;
void reload_dialog_info_full(DialogId dialog_id);
bool load_dialog(DialogId dialog_id, int left_tries, Promise<Unit> &&promise);
void load_dialogs(vector<DialogId> dialog_ids, Promise<Unit> &&promise);
@ -799,6 +810,11 @@ class MessagesManager : public Actor {
void get_login_url(DialogId dialog_id, MessageId message_id, int32 button_id, bool allow_write_access,
Promise<td_api::object_ptr<td_api::httpUrl>> &&promise);
void get_link_login_url_info(const string &url, Promise<td_api::object_ptr<td_api::LoginUrlInfo>> &&promise);
void get_link_login_url(const string &url, bool allow_write_access,
Promise<td_api::object_ptr<td_api::httpUrl>> &&promise);
void on_authorization_success();
void before_get_difference();
@ -1084,7 +1100,7 @@ class MessagesManager : public Actor {
int32 ttl_period = 0; // counted from message send date
int32 ttl = 0; // counted from message content view date
double ttl_expires_at = 0; // only for ttl
double ttl_expires_at = 0; // only for TTL
int64 media_album_id = 0;
@ -1165,6 +1181,7 @@ class MessagesManager : public Actor {
std::unordered_set<MessageId, MessageIdHash> updated_read_history_message_ids;
LogEventIdWithGeneration set_folder_id_log_event_id;
InputGroupCallId active_group_call_id;
DialogId default_join_group_call_as_dialog_id;
FolderId folder_id;
vector<DialogListId> dialog_list_ids; // TODO replace with mask
@ -1953,7 +1970,7 @@ class MessagesManager : public Actor {
const Message *m) const;
bool update_message_interaction_info(DialogId dialog_id, Message *m, int32 view_count, int32 forward_count,
bool has_reply_info, MessageReplyInfo &&reply_info);
bool has_reply_info, MessageReplyInfo &&reply_info, const char *source);
bool update_message_contains_unread_mention(Dialog *d, Message *m, bool contains_unread_mention, const char *source);
@ -2403,7 +2420,7 @@ class MessagesManager : public Actor {
void fix_new_dialog(Dialog *d, unique_ptr<Message> &&last_database_message, MessageId last_database_message_id,
int64 order, int32 last_clear_history_date, MessageId last_clear_history_message_id,
bool is_loaded_from_database);
DialogId default_join_group_call_as_dialog_id, bool is_loaded_from_database);
void add_dialog_last_database_message(Dialog *d, unique_ptr<Message> &&last_database_message);
@ -2414,10 +2431,9 @@ class MessagesManager : public Actor {
td_api::object_ptr<td_api::ChatActionBar> get_chat_action_bar_object(const Dialog *d,
bool hide_unarchive = false) const;
td_api::object_ptr<td_api::chat> get_chat_object(const Dialog *d) const;
td_api::object_ptr<td_api::voiceChat> get_voice_chat_object(const Dialog *d) const;
bool have_dialog_info(DialogId dialog_id) const;
bool have_dialog_info_force(DialogId dialog_id) const;
td_api::object_ptr<td_api::chat> get_chat_object(const Dialog *d) const;
Dialog *get_dialog(DialogId dialog_id);
const Dialog *get_dialog(DialogId dialog_id) const;
@ -2433,8 +2449,6 @@ class MessagesManager : public Actor {
void send_search_public_dialogs_query(const string &query, Promise<Unit> &&promise);
void reload_dialog_info_full(DialogId dialog_id);
vector<DialogId> get_pinned_dialog_ids(DialogListId dialog_list_id) const;
void reload_pinned_dialogs(DialogListId dialog_list_id, Promise<Unit> &&promise);
@ -3292,6 +3306,9 @@ class MessagesManager : public Actor {
std::unordered_map<DialogId, std::pair<int32, unique_ptr<Message>>, DialogIdHash>
pending_add_dialog_last_database_message_; // dialog -> dependency counter + message
std::unordered_map<DialogId, vector<DialogId>, DialogIdHash>
pending_add_default_join_group_call_as_dialog_id_; // dialog_id -> dependent dialogs
struct CallsDbState {
std::array<MessageId, 2> first_calls_database_message_id_by_index;
std::array<int32, 2> message_count_by_index;

View File

@ -253,7 +253,8 @@ void NotificationManager::init() {
VLOG(notifications) << "Load call_notification_group_ids = " << call_notification_group_ids;
for (auto &group_id : call_notification_group_ids) {
if (group_id.get() > current_notification_group_id_.get()) {
LOG(ERROR) << "Fix current notification group id from " << current_notification_group_id_ << " to " << group_id;
LOG(ERROR) << "Fix current notification group identifier from " << current_notification_group_id_ << " to "
<< group_id;
current_notification_group_id_ = group_id;
G()->td_db()->get_binlog_pmc()->set("notification_group_id_current",
to_string(current_notification_group_id_.get()));
@ -417,14 +418,15 @@ NotificationManager::NotificationGroups::iterator NotificationManager::get_group
group_key.last_notification_date = notification.date;
}
if (notification.notification_id.get() > current_notification_id_.get()) {
LOG(ERROR) << "Fix current notification id from " << current_notification_id_ << " to "
LOG(ERROR) << "Fix current notification identifier from " << current_notification_id_ << " to "
<< notification.notification_id;
current_notification_id_ = notification.notification_id;
G()->td_db()->get_binlog_pmc()->set("notification_id_current", to_string(current_notification_id_.get()));
}
}
if (group_id.get() > current_notification_group_id_.get()) {
LOG(ERROR) << "Fix current notification group id from " << current_notification_group_id_ << " to " << group_id;
LOG(ERROR) << "Fix current notification group identifier from " << current_notification_group_id_ << " to "
<< group_id;
current_notification_group_id_ = group_id;
G()->td_db()->get_binlog_pmc()->set("notification_group_id_current",
to_string(current_notification_group_id_.get()));
@ -739,7 +741,7 @@ NotificationId NotificationManager::get_next_notification_id() {
return NotificationId();
}
if (current_notification_id_.get() == std::numeric_limits<int32>::max()) {
LOG(ERROR) << "Notification id overflowed";
LOG(ERROR) << "Notification identifier overflowed";
return NotificationId();
}
@ -753,7 +755,7 @@ NotificationGroupId NotificationManager::get_next_notification_group_id() {
return NotificationGroupId();
}
if (current_notification_group_id_.get() == std::numeric_limits<int32>::max()) {
LOG(ERROR) << "Notification group id overflowed";
LOG(ERROR) << "Notification group identifier overflowed";
return NotificationGroupId();
}

View File

@ -746,7 +746,7 @@ void answer_shipping_query(int64 shipping_query_id, vector<tl_object_ptr<td_api:
return promise.set_error(Status::Error(400, "Shipping option must be non-empty"));
}
if (!clean_input_string(option->id_)) {
return promise.set_error(Status::Error(400, "Shipping option id must be encoded in UTF-8"));
return promise.set_error(Status::Error(400, "Shipping option identifier must be encoded in UTF-8"));
}
if (!clean_input_string(option->title_)) {
return promise.set_error(Status::Error(400, "Shipping option title must be encoded in UTF-8"));
@ -836,7 +836,7 @@ void send_payment_form(ServerMessageId server_message_id, const string &order_in
auto credentials_saved = static_cast<const td_api::inputCredentialsSaved *>(credentials.get());
auto credentials_id = credentials_saved->saved_credentials_id_;
if (!clean_input_string(credentials_id)) {
return promise.set_error(Status::Error(400, "Credentials id must be encoded in UTF-8"));
return promise.set_error(Status::Error(400, "Credentials identifier must be encoded in UTF-8"));
}
auto temp_password_state =
G()->td().get_actor_unsafe()->password_manager_->get_actor_unsafe()->get_temp_password_state_sync();

View File

@ -218,7 +218,7 @@ bool operator!=(const ProfilePhoto &lhs, const ProfilePhoto &rhs) {
}
StringBuilder &operator<<(StringBuilder &string_builder, const ProfilePhoto &profile_photo) {
return string_builder << "<id = " << profile_photo.id << ", small_file_id = " << profile_photo.small_file_id
return string_builder << "<ID = " << profile_photo.id << ", small_file_id = " << profile_photo.small_file_id
<< ", big_file_id = " << profile_photo.big_file_id
<< ", has_animation = " << profile_photo.has_animation << ">";
}
@ -717,7 +717,7 @@ Photo get_photo(FileManager *file_manager, tl_object_ptr<telegram_api::photo> &&
res.has_stickers = (photo->flags_ & telegram_api::photo::HAS_STICKERS_MASK) != 0;
if (res.is_empty()) {
LOG(ERROR) << "Receive photo with id " << res.id.get();
LOG(ERROR) << "Receive photo with identifier " << res.id.get();
res.id = -3;
}
@ -933,11 +933,11 @@ bool operator!=(const Photo &lhs, const Photo &rhs) {
}
StringBuilder &operator<<(StringBuilder &string_builder, const Photo &photo) {
string_builder << "[id = " << photo.id.get() << ", photos = " << format::as_array(photo.photos);
string_builder << "[ID = " << photo.id.get() << ", photos = " << format::as_array(photo.photos);
if (!photo.animations.empty()) {
string_builder << ", animations = " << format::as_array(photo.animations);
}
return string_builder << "]";
return string_builder << ']';
}
static tl_object_ptr<telegram_api::fileLocationToBeDeprecated> copy_location(

View File

@ -82,7 +82,7 @@ static StringBuilder &operator<<(StringBuilder &string_builder, const InlineKeyb
string_builder << "Buy";
break;
case InlineKeyboardButton::Type::UrlAuth:
string_builder << "UrlAuth, id = " << keyboard_button.id;
string_builder << "UrlAuth, ID = " << keyboard_button.id;
break;
case InlineKeyboardButton::Type::CallbackWithPassword:
string_builder << "CallbackWithPassword";

View File

@ -646,7 +646,7 @@ void SecretChatActor::run_fill_gaps() {
void SecretChatActor::run_pfs() {
while (true) {
LOG(INFO) << "Run pfs loop: " << pfs_state_;
LOG(INFO) << "Run PFS loop: " << pfs_state_;
if (pfs_state_.state == PfsState::Empty &&
(pfs_state_.last_message_id + 100 < seq_no_state_.message_id ||
pfs_state_.last_timestamp + 60 * 60 * 24 * 7 < Time::now()) &&
@ -1078,7 +1078,7 @@ void SecretChatActor::do_outbound_message_impl(unique_ptr<log_event::OutboundSec
binlog_event->crc = crc64(binlog_event->encrypted_message.as_slice());
LOG(INFO) << "Do outbound message: " << *binlog_event << tag("crc", binlog_event->crc);
auto &state_id_ref = random_id_to_outbound_message_state_token_[binlog_event->random_id];
LOG_CHECK(state_id_ref == 0) << "Random id collision";
LOG_CHECK(state_id_ref == 0) << "Random ID collision";
state_id_ref = outbound_message_states_.create();
const uint64 state_id = state_id_ref;
auto *state = outbound_message_states_.get(state_id);
@ -2283,9 +2283,9 @@ Status SecretChatActor::on_inbound_action(secret_api::DecryptedMessageAction &ac
// Also, if SeqNoState with message_id greater than current message_id is not saved, then corresponding action will be
// replayed.
//
// This works only for ttl, not for pfs. Same ttl action may be processed twice.
// This works only for TTL, not for PFS. Same TTL action may be processed twice.
if (message_id < seq_no_state_.message_id) {
LOG(INFO) << "Drop old inbound DecryptedMessageAction (non-pfs action): " << to_string(action);
LOG(INFO) << "Drop old inbound DecryptedMessageAction (non-PFS action): " << to_string(action);
return Status::OK();
}
pfs_state_.message_id = message_id; // replay protection
@ -2305,7 +2305,7 @@ void SecretChatActor::on_outbound_action(secret_api::DecryptedMessageAction &act
// see comment in on_inbound_action
if (message_id < seq_no_state_.message_id) {
LOG(INFO) << "Drop old outbound DecryptedMessageAction (non-pfs action): " << to_string(action);
LOG(INFO) << "Drop old outbound DecryptedMessageAction (non-PFS action): " << to_string(action);
return;
}
pfs_state_.message_id = message_id; // replay protection

View File

@ -2101,7 +2101,7 @@ FileId StickersManager::dup_sticker(FileId new_id, FileId old_id) {
bool StickersManager::merge_stickers(FileId new_id, FileId old_id, bool can_delete_old) {
if (!old_id.is_valid()) {
LOG(ERROR) << "Old file id is invalid";
LOG(ERROR) << "Old file identifier is invalid";
return true;
}
@ -2703,7 +2703,7 @@ StickerSetId StickersManager::on_get_messages_sticker_set(StickerSetId sticker_s
for (int64 document_id : pack->documents_) {
auto it = document_id_to_sticker_id.find(document_id);
if (it == document_id_to_sticker_id.end()) {
LOG(ERROR) << "Can't find document with id " << document_id << " in " << set_id << "/" << s->short_name
LOG(ERROR) << "Can't find document with ID " << document_id << " in " << set_id << "/" << s->short_name
<< " from " << source;
continue;
}

View File

@ -3355,7 +3355,7 @@ DbKey Td::as_db_key(string key) {
void Td::request(uint64 id, tl_object_ptr<td_api::Function> function) {
if (id == 0) {
LOG(ERROR) << "Ignore request with id == 0: " << to_string(function);
LOG(ERROR) << "Ignore request with ID == 0: " << to_string(function);
return;
}
@ -5533,19 +5533,19 @@ void Td::on_request(uint64 id, const td_api::openMessageContent &request) {
id, messages_manager_->open_message_content({DialogId(request.chat_id_), MessageId(request.message_id_)}));
}
void Td::on_request(uint64 id, td_api::getExternalLinkInfo &request) {
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.link_);
CREATE_REQUEST_PROMISE();
send_closure_later(G()->config_manager(), &ConfigManager::get_external_link_info, std::move(request.link_),
std::move(promise));
}
void Td::on_request(uint64 id, td_api::getExternalLink &request) {
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.link_);
CREATE_REQUEST_PROMISE();
auto query_promise = [promise = std::move(promise)](Result<string> &&result) mutable {
if (result.is_error()) {
promise.set_error(result.move_as_error());
} else {
promise.set_value(td_api::make_object<td_api::httpUrl>(result.ok()));
}
};
send_closure_later(G()->config_manager(), &ConfigManager::get_external_link, std::move(request.link_),
std::move(query_promise));
messages_manager_->get_link_login_url(request.link_, request.allow_write_access_, std::move(promise));
}
void Td::on_request(uint64 id, const td_api::getChatHistory &request) {
@ -6024,6 +6024,12 @@ void Td::on_request(uint64 id, td_api::sendCallDebugInformation &request) {
std::move(request.debug_information_), std::move(promise));
}
void Td::on_request(uint64 id, const td_api::getAvailableVoiceChatAliases &request) {
CHECK_IS_USER();
CREATE_REQUEST_PROMISE();
group_call_manager_->get_group_call_join_as(DialogId(request.chat_id_), std::move(promise));
}
void Td::on_request(uint64 id, const td_api::createVoiceChat &request) {
CHECK_IS_USER();
CREATE_REQUEST_PROMISE();
@ -6045,9 +6051,20 @@ void Td::on_request(uint64 id, const td_api::getGroupCall &request) {
void Td::on_request(uint64 id, td_api::joinGroupCall &request) {
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.invite_hash_);
CREATE_REQUEST_PROMISE();
group_call_manager_->join_group_call(GroupCallId(request.group_call_id_), std::move(request.payload_),
request.source_, request.is_muted_, std::move(promise));
group_call_manager_->join_group_call(GroupCallId(request.group_call_id_),
group_call_manager_->get_group_call_participant_id(request.participant_alias_),
std::move(request.payload_), request.source_, request.is_muted_,
request.invite_hash_, std::move(promise));
}
void Td::on_request(uint64 id, td_api::setGroupCallTitle &request) {
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.title_);
CREATE_OK_REQUEST_PROMISE();
group_call_manager_->set_group_call_title(GroupCallId(request.group_call_id_), std::move(request.title_),
std::move(promise));
}
void Td::on_request(uint64 id, const td_api::toggleGroupCallMuteNewParticipants &request) {
@ -6057,6 +6074,12 @@ void Td::on_request(uint64 id, const td_api::toggleGroupCallMuteNewParticipants
request.mute_new_participants_, std::move(promise));
}
void Td::on_request(uint64 id, const td_api::revokeGroupCallInviteLink &request) {
CHECK_IS_USER();
CREATE_OK_REQUEST_PROMISE();
group_call_manager_->revoke_group_call_invite_link(GroupCallId(request.group_call_id_), std::move(promise));
}
void Td::on_request(uint64 id, const td_api::inviteGroupCallParticipants &request) {
CHECK_IS_USER();
CREATE_OK_REQUEST_PROMISE();
@ -6068,6 +6091,35 @@ void Td::on_request(uint64 id, const td_api::inviteGroupCallParticipants &reques
std::move(promise));
}
void Td::on_request(uint64 id, const td_api::getGroupCallInviteLink &request) {
CHECK_IS_USER();
CREATE_REQUEST_PROMISE();
auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result<string> result) mutable {
if (result.is_error()) {
promise.set_error(result.move_as_error());
} else {
promise.set_value(td_api::make_object<td_api::httpUrl>(result.move_as_ok()));
}
});
group_call_manager_->get_group_call_invite_link(GroupCallId(request.group_call_id_), request.can_self_unmute_,
std::move(query_promise));
}
void Td::on_request(uint64 id, td_api::startGroupCallRecording &request) {
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.title_);
CREATE_OK_REQUEST_PROMISE();
group_call_manager_->toggle_group_call_recording(GroupCallId(request.group_call_id_), true, std::move(request.title_),
std::move(promise));
}
void Td::on_request(uint64 id, const td_api::endGroupCallRecording &request) {
CHECK_IS_USER();
CREATE_OK_REQUEST_PROMISE();
group_call_manager_->toggle_group_call_recording(GroupCallId(request.group_call_id_), false, string(),
std::move(promise));
}
void Td::on_request(uint64 id, const td_api::setGroupCallParticipantIsSpeaking &request) {
CHECK_IS_USER();
CREATE_OK_REQUEST_PROMISE();
@ -6079,14 +6131,24 @@ void Td::on_request(uint64 id, const td_api::toggleGroupCallParticipantIsMuted &
CHECK_IS_USER();
CREATE_OK_REQUEST_PROMISE();
group_call_manager_->toggle_group_call_participant_is_muted(
GroupCallId(request.group_call_id_), UserId(request.user_id_), request.is_muted_, std::move(promise));
GroupCallId(request.group_call_id_), group_call_manager_->get_group_call_participant_id(request.participant_),
request.is_muted_, std::move(promise));
}
void Td::on_request(uint64 id, const td_api::setGroupCallParticipantVolumeLevel &request) {
CHECK_IS_USER();
CREATE_OK_REQUEST_PROMISE();
group_call_manager_->set_group_call_participant_volume_level(
GroupCallId(request.group_call_id_), UserId(request.user_id_), request.volume_level_, std::move(promise));
GroupCallId(request.group_call_id_), group_call_manager_->get_group_call_participant_id(request.participant_),
request.volume_level_, std::move(promise));
}
void Td::on_request(uint64 id, const td_api::toggleGroupCallParticipantIsHandRaised &request) {
CHECK_IS_USER();
CREATE_OK_REQUEST_PROMISE();
group_call_manager_->toggle_group_call_participant_is_hand_raised(
GroupCallId(request.group_call_id_), group_call_manager_->get_group_call_participant_id(request.participant_),
request.is_hand_raised_, std::move(promise));
}
void Td::on_request(uint64 id, const td_api::loadGroupCallParticipants &request) {
@ -6108,6 +6170,22 @@ void Td::on_request(uint64 id, const td_api::discardGroupCall &request) {
group_call_manager_->discard_group_call(GroupCallId(request.group_call_id_), std::move(promise));
}
void Td::on_request(uint64 id, const td_api::getGroupCallStreamSegment &request) {
CHECK_IS_USER();
CREATE_REQUEST_PROMISE();
auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result<string> result) mutable {
if (result.is_error()) {
promise.set_error(result.move_as_error());
} else {
auto file_part = td_api::make_object<td_api::filePart>();
file_part->data_ = result.move_as_ok();
promise.set_value(std::move(file_part));
}
});
group_call_manager_->get_group_call_stream_segment(GroupCallId(request.group_call_id_), request.time_offset_,
request.scale_, std::move(query_promise));
}
void Td::on_request(uint64 id, const td_api::upgradeBasicGroupChatToSupergroupChat &request) {
CHECK_IS_USER();
CREATE_REQUEST(UpgradeGroupChatToSupergroupChatRequest, request.chat_id_);

View File

@ -249,7 +249,7 @@ class Td final : public NetQueryCallback {
static td_api::object_ptr<td_api::Object> static_request(td_api::object_ptr<td_api::Function> function);
private:
static constexpr const char *TDLIB_VERSION = "1.7.2";
static constexpr const char *TDLIB_VERSION = "1.7.3";
static constexpr int64 ONLINE_ALARM_ID = 0;
static constexpr int64 PING_SERVER_ALARM_ID = -1;
static constexpr int32 PING_SERVER_TIMEOUT = 300;
@ -593,6 +593,8 @@ class Td final : public NetQueryCallback {
void on_request(uint64 id, const td_api::openMessageContent &request);
void on_request(uint64 id, td_api::getExternalLinkInfo &request);
void on_request(uint64 id, td_api::getExternalLink &request);
void on_request(uint64 id, const td_api::getChatHistory &request);
@ -715,28 +717,44 @@ class Td final : public NetQueryCallback {
void on_request(uint64 id, td_api::sendCallDebugInformation &request);
void on_request(uint64 id, const td_api::getAvailableVoiceChatAliases &request);
void on_request(uint64 id, const td_api::createVoiceChat &request);
void on_request(uint64 id, const td_api::getGroupCall &request);
void on_request(uint64 id, td_api::joinGroupCall &request);
void on_request(uint64 id, td_api::setGroupCallTitle &request);
void on_request(uint64 id, const td_api::toggleGroupCallMuteNewParticipants &request);
void on_request(uint64 id, const td_api::revokeGroupCallInviteLink &request);
void on_request(uint64 id, const td_api::inviteGroupCallParticipants &request);
void on_request(uint64 id, const td_api::getGroupCallInviteLink &request);
void on_request(uint64 id, td_api::startGroupCallRecording &request);
void on_request(uint64 id, const td_api::endGroupCallRecording &request);
void on_request(uint64 id, const td_api::setGroupCallParticipantIsSpeaking &request);
void on_request(uint64 id, const td_api::toggleGroupCallParticipantIsMuted &request);
void on_request(uint64 id, const td_api::setGroupCallParticipantVolumeLevel &request);
void on_request(uint64 id, const td_api::toggleGroupCallParticipantIsHandRaised &request);
void on_request(uint64 id, const td_api::loadGroupCallParticipants &request);
void on_request(uint64 id, const td_api::leaveGroupCall &request);
void on_request(uint64 id, const td_api::discardGroupCall &request);
void on_request(uint64 id, const td_api::getGroupCallStreamSegment &request);
void on_request(uint64 id, const td_api::upgradeBasicGroupChatToSupergroupChat &request);
void on_request(uint64 id, const td_api::getChatListsToAddChat &request);

View File

@ -1088,7 +1088,7 @@ vector<DialogId> UpdatesManager::get_chat_dialog_ids(const telegram_api::Updates
continue;
}
LOG(ERROR) << "Can't find id of " << oneline(to_string(chat));
LOG(ERROR) << "Can't find identifier of " << oneline(to_string(chat));
}
return dialog_ids;
}
@ -2516,15 +2516,15 @@ int32 UpdatesManager::get_update_qts(const telegram_api::Update *update) {
}
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateUserTyping> update, Promise<Unit> &&promise) {
UserId user_id(update->user_id_);
td_->messages_manager_->on_user_dialog_action(DialogId(user_id), MessageId(), user_id,
DialogId dialog_id(UserId(update->user_id_));
td_->messages_manager_->on_user_dialog_action(dialog_id, MessageId(), dialog_id,
DialogAction(std::move(update->action_)), get_short_update_date());
promise.set_value(Unit());
}
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateChatUserTyping> update, Promise<Unit> &&promise) {
td_->messages_manager_->on_user_dialog_action(DialogId(ChatId(update->chat_id_)), MessageId(),
UserId(update->user_id_), DialogAction(std::move(update->action_)),
DialogId(update->from_id_), DialogAction(std::move(update->action_)),
get_short_update_date());
promise.set_value(Unit());
}
@ -2535,7 +2535,7 @@ void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateChannelUserTypi
top_thread_message_id = MessageId(ServerMessageId(update->top_msg_id_));
}
td_->messages_manager_->on_user_dialog_action(DialogId(ChannelId(update->channel_id_)), top_thread_message_id,
UserId(update->user_id_), DialogAction(std::move(update->action_)),
DialogId(update->from_id_), DialogAction(std::move(update->action_)),
get_short_update_date());
promise.set_value(Unit());
}
@ -2543,7 +2543,7 @@ void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateChannelUserTypi
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateEncryptedChatTyping> update, Promise<Unit> &&promise) {
SecretChatId secret_chat_id(update->chat_id_);
UserId user_id = td_->contacts_manager_->get_secret_chat_user_id(secret_chat_id);
td_->messages_manager_->on_user_dialog_action(DialogId(secret_chat_id), MessageId(), user_id,
td_->messages_manager_->on_user_dialog_action(DialogId(secret_chat_id), MessageId(), DialogId(user_id),
DialogAction::get_typing_action(), get_short_update_date());
promise.set_value(Unit());
}
@ -2836,7 +2836,7 @@ void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateGroupCall> upda
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateGroupCallParticipants> update,
Promise<Unit> &&promise) {
send_closure(G()->group_call_manager(), &GroupCallManager::on_update_group_call_participants,
InputGroupCallId(update->call_), std::move(update->participants_), update->version_);
InputGroupCallId(update->call_), std::move(update->participants_), update->version_, false);
promise.set_value(Unit());
}

View File

@ -84,7 +84,7 @@ bool operator!=(const Venue &lhs, const Venue &rhs) {
StringBuilder &operator<<(StringBuilder &string_builder, const Venue &venue) {
return string_builder << "Venue[location = " << venue.location_ << ", title = " << venue.title_
<< ", address = " << venue.address_ << ", provider = " << venue.provider_
<< ", id = " << venue.id_ << ", type = " << venue.type_ << "]";
<< ", ID = " << venue.id_ << ", type = " << venue.type_ << "]";
}
Result<Venue> process_input_message_venue(tl_object_ptr<td_api::InputMessageContent> &&input_message_content) {

View File

@ -8,7 +8,7 @@
namespace td {
constexpr int32 MTPROTO_LAYER = 124;
constexpr int32 MTPROTO_LAYER = 125;
enum class Version : int32 {
Initial, // 0

View File

@ -124,7 +124,7 @@ FileId VideoNotesManager::dup_video_note(FileId new_id, FileId old_id) {
bool VideoNotesManager::merge_video_notes(FileId new_id, FileId old_id, bool can_delete_old) {
if (!old_id.is_valid()) {
LOG(ERROR) << "Old file id is invalid";
LOG(ERROR) << "Old file identifier is invalid";
return true;
}

View File

@ -164,7 +164,7 @@ FileId VideosManager::dup_video(FileId new_id, FileId old_id) {
bool VideosManager::merge_videos(FileId new_id, FileId old_id, bool can_delete_old) {
if (!old_id.is_valid()) {
LOG(ERROR) << "Old file id is invalid";
LOG(ERROR) << "Old file identifier is invalid";
return true;
}

View File

@ -92,7 +92,7 @@ FileId VoiceNotesManager::dup_voice_note(FileId new_id, FileId old_id) {
bool VoiceNotesManager::merge_voice_notes(FileId new_id, FileId old_id, bool can_delete_old) {
if (!old_id.is_valid()) {
LOG(ERROR) << "Old file id is invalid";
LOG(ERROR) << "Old file identifier is invalid";
return true;
}

View File

@ -1074,7 +1074,7 @@ WebPageId WebPagesManager::get_web_page_by_url(const string &url) const {
return WebPageId();
}
LOG(INFO) << "Get web page id for the url \"" << url << '"';
LOG(INFO) << "Get web page identifier for the url \"" << url << '"';
auto it = url_to_web_page_id_.find(url);
if (it != url_to_web_page_id_.end()) {
@ -1085,7 +1085,7 @@ WebPageId WebPagesManager::get_web_page_by_url(const string &url) const {
}
WebPageId WebPagesManager::get_web_page_by_url(const string &url, Promise<Unit> &&promise) {
LOG(INFO) << "Trying to get web page id for the url \"" << url << '"';
LOG(INFO) << "Trying to get web page identifier for the url \"" << url << '"';
auto it = url_to_web_page_id_.find(url);
if (it != url_to_web_page_id_.end()) {

View File

@ -295,7 +295,7 @@ class CliClient final : public Actor {
void update_option(const td_api::updateOption &option) {
if (option.name_ == "my_id" && option.value_->get_id() == td_api::optionValueInteger::ID) {
my_id_ = static_cast<int32>(static_cast<const td_api::optionValueInteger *>(option.value_.get())->value_);
LOG(INFO) << "Set my id to " << my_id_;
LOG(INFO) << "Set my user identifier to " << my_id_;
}
}
@ -2668,23 +2668,37 @@ class CliClient final : public Actor {
as_call_id(call_id), rating, "Wow, such good call! (TDLib test)", std::move(problems)));
} else if (op == "scdi" || op == "SendCallDebugInformation") {
send_request(td_api::make_object<td_api::sendCallDebugInformation>(as_call_id(args), "{}"));
} else if (op == "gavca") {
send_request(td_api::make_object<td_api::getAvailableVoiceChatAliases>(as_chat_id(args)));
} else if (op == "cvc") {
send_request(td_api::make_object<td_api::createVoiceChat>(as_chat_id(args)));
} else if (op == "ggc") {
send_request(td_api::make_object<td_api::getGroupCall>(as_group_call_id(args)));
} else if (op == "ggcss") {
send_request(td_api::make_object<td_api::getGroupCallStreamSegment>(as_group_call_id(args),
(std::time(nullptr) - 5) * 1000, 0));
} else if (op == "jgc") {
string group_call_id;
string participant_alias;
string invite_hash;
get_args(args, group_call_id, participant_alias, invite_hash);
vector<td_api::object_ptr<td_api::groupCallPayloadFingerprint>> fingerprints;
fingerprints.push_back(td_api::make_object<td_api::groupCallPayloadFingerprint>("hash", "setup", "fingerprint"));
fingerprints.push_back(td_api::make_object<td_api::groupCallPayloadFingerprint>("h2", "s2", "fingerprint2"));
send_request(td_api::make_object<td_api::joinGroupCall>(
as_group_call_id(args),
as_group_call_id(group_call_id), as_message_sender(participant_alias),
td_api::make_object<td_api::groupCallPayload>("ufrag", "pwd", std::move(fingerprints)), group_call_source_,
true));
} else if (op == "jgcc") {
send_request(td_api::make_object<td_api::joinGroupCall>(as_group_call_id(args), nullptr, 0, true));
true, invite_hash));
} else if (op == "sgct") {
string chat_id;
string title;
get_args(args, chat_id, title);
send_request(td_api::make_object<td_api::setGroupCallTitle>(as_group_call_id(chat_id), title));
} else if (op == "tgcmnp" || op == "tgcmnpe") {
send_request(
td_api::make_object<td_api::toggleGroupCallMuteNewParticipants>(as_group_call_id(args), op == "tgcmnpe"));
} else if (op == "rgcil") {
send_request(td_api::make_object<td_api::revokeGroupCallInviteLink>(as_group_call_id(args)));
} else if (op == "sgcpis") {
string group_call_id;
int32 source;
@ -2698,20 +2712,41 @@ class CliClient final : public Actor {
get_args(args, group_call_id, user_ids);
send_request(td_api::make_object<td_api::inviteGroupCallParticipants>(as_group_call_id(group_call_id),
as_user_ids(user_ids)));
} else if (op == "ggcil") {
string group_call_id;
bool can_self_unmute;
get_args(args, group_call_id, can_self_unmute);
send_request(
td_api::make_object<td_api::getGroupCallInviteLink>(as_group_call_id(group_call_id), can_self_unmute));
} else if (op == "sgcr") {
string chat_id;
string title;
get_args(args, chat_id, title);
send_request(td_api::make_object<td_api::startGroupCallRecording>(as_group_call_id(chat_id), title));
} else if (op == "egcr") {
string chat_id = args;
send_request(td_api::make_object<td_api::endGroupCallRecording>(as_group_call_id(chat_id)));
} else if (op == "tgcpim") {
string group_call_id;
string user_id;
string participant_id;
bool is_muted;
get_args(args, group_call_id, user_id, is_muted);
send_request(td_api::make_object<td_api::toggleGroupCallParticipantIsMuted>(as_group_call_id(group_call_id),
as_user_id(user_id), is_muted));
get_args(args, group_call_id, participant_id, is_muted);
send_request(td_api::make_object<td_api::toggleGroupCallParticipantIsMuted>(
as_group_call_id(group_call_id), as_message_sender(participant_id), is_muted));
} else if (op == "sgcpvl") {
string group_call_id;
string user_id;
string participant_id;
int32 volume_level;
get_args(args, group_call_id, user_id, volume_level);
send_request(td_api::make_object<td_api::setGroupCallParticipantVolumeLevel>(as_group_call_id(group_call_id),
as_user_id(user_id), volume_level));
get_args(args, group_call_id, participant_id, volume_level);
send_request(td_api::make_object<td_api::setGroupCallParticipantVolumeLevel>(
as_group_call_id(group_call_id), as_message_sender(participant_id), volume_level));
} else if (op == "tgcpihr") {
string group_call_id;
string participant_id;
bool is_hand_raised;
get_args(args, group_call_id, participant_id, is_hand_raised);
send_request(td_api::make_object<td_api::toggleGroupCallParticipantIsHandRaised>(
as_group_call_id(group_call_id), as_message_sender(participant_id), is_hand_raised));
} else if (op == "lgcp") {
string group_call_id;
string limit;
@ -3891,9 +3926,12 @@ class CliClient final : public Actor {
string message_id;
get_args(args, chat_id, message_id);
send_request(td_api::make_object<td_api::openMessageContent>(as_chat_id(chat_id), as_message_id(message_id)));
} else if (op == "gel") {
} else if (op == "geli") {
string link = args;
send_request(td_api::make_object<td_api::getExternalLink>(link));
send_request(td_api::make_object<td_api::getExternalLinkInfo>(link));
} else if (op == "gel" || op == "gelw") {
string link = args;
send_request(td_api::make_object<td_api::getExternalLink>(link, op == "gelw"));
} else if (op == "racm") {
string chat_id = args;
send_request(td_api::make_object<td_api::readAllChatMentions>(as_chat_id(chat_id)));

View File

@ -275,7 +275,7 @@ class FileDb : public FileDbInterface {
if (ids.size() > 1) {
send_closure(file_db_actor_id, &FileDbActor::optimize_refs, std::move(ids), id);
}
//LOG(DEBUG) << "By id " << id.get() << " found data " << format::as_hex_dump<4>(Slice(data_str));
//LOG(DEBUG) << "By ID " << id.get() << " found data " << format::as_hex_dump<4>(Slice(data_str));
//LOG(INFO) << attempt_count;
log_event::WithVersion<TlParser> parser(data_str);
@ -292,7 +292,7 @@ class FileDb : public FileDbInterface {
static Result<FileDbId> get_id(SqliteKeyValue &pmc, const string &key) TD_WARN_UNUSED_RESULT {
auto id_str = pmc.get(key);
//LOG(DEBUG) << "Found id " << id_str << " by key " << format::as_hex_dump<4>(Slice(key));
//LOG(DEBUG) << "Found ID " << id_str << " by key " << format::as_hex_dump<4>(Slice(key));
if (id_str.empty()) {
return Status::Error("There is no such a key in database");
}

View File

@ -413,7 +413,7 @@ void FileGenerateManager::generate_file(uint64 query_id, FullGenerateFileLocatio
CHECK(query_id != 0);
auto it_flag = query_id_to_query_.emplace(query_id, Query{});
LOG_CHECK(it_flag.second) << "Query id must be unique";
LOG_CHECK(it_flag.second) << "Query identifier must be unique";
auto parent = actor_shared(this, query_id);
Slice file_id_query = "#file_id#";

View File

@ -110,7 +110,7 @@ struct PhotoRemoteFileLocation {
};
inline StringBuilder &operator<<(StringBuilder &string_builder, const PhotoRemoteFileLocation &location) {
return string_builder << "[id = " << location.id_ << ", access_hash = " << location.access_hash_
return string_builder << "[ID = " << location.id_ << ", access_hash = " << location.access_hash_
<< ", volume_id = " << location.volume_id_ << ", local_id = " << location.local_id_ << "]";
}
@ -173,7 +173,7 @@ struct CommonRemoteFileLocation {
};
inline StringBuilder &operator<<(StringBuilder &string_builder, const CommonRemoteFileLocation &location) {
return string_builder << "[id = " << location.id_ << ", access_hash = " << location.access_hash_ << "]";
return string_builder << "[ID = " << location.id_ << ", access_hash = " << location.access_hash_ << "]";
}
class FullRemoteFileLocation {

View File

@ -1447,7 +1447,8 @@ Result<FileId> FileManager::merge(FileId x_file_id, FileId y_file_id, bool no_sy
}
FileNodePtr x_node = no_sync ? get_file_node(x_file_id) : get_sync_file_node(x_file_id);
if (!x_node) {
return Status::Error(PSLICE() << "Can't merge files. First id is invalid: " << x_file_id << " and " << y_file_id);
return Status::Error(PSLICE() << "Can't merge files. First identifier is invalid: " << x_file_id << " and "
<< y_file_id);
}
if (!y_file_id.is_valid()) {
@ -1456,7 +1457,8 @@ Result<FileId> FileManager::merge(FileId x_file_id, FileId y_file_id, bool no_sy
}
FileNodePtr y_node = get_file_node(y_file_id);
if (!y_node) {
return Status::Error(PSLICE() << "Can't merge files. Second id is invalid: " << x_file_id << " and " << y_file_id);
return Status::Error(PSLICE() << "Can't merge files. Second identifier is invalid: " << x_file_id << " and "
<< y_file_id);
}
if (x_file_id == x_node->upload_pause_) {
@ -3201,8 +3203,8 @@ Result<FileId> FileManager::get_map_thumbnail_file_id(Location location, int32 z
x = clamp(x, 0, size - 1); // just in case
y = clamp(y, 0, size - 1); // just in case
string conversion = PSTRING() << "#map#" << zoom << "#" << x << "#" << y << "#" << width << "#" << height << "#"
<< scale << "#";
string conversion = PSTRING() << "#map#" << zoom << '#' << x << '#' << y << '#' << width << '#' << height << '#'
<< scale << '#';
return register_generate(
owner_dialog_id.get_type() == DialogType::SecretChat ? FileType::EncryptedThumbnail : FileType::Thumbnail,
FileLocationSource::FromUser, string(), std::move(conversion), owner_dialog_id, 0);

View File

@ -144,7 +144,7 @@ T trim(T str) {
string lpad(string str, size_t size, char c);
string lpad0(const string str, size_t size);
string lpad0(string str, size_t size);
string rpad(string str, size_t size, char c);

View File

@ -67,6 +67,14 @@ static const char gzip_bomb_arr[] =
const char *gzip_bomb = gzip_bomb_arr;
const size_t gzip_bomb_size = sizeof(gzip_bomb_arr) - 1;
static const char gzip_arr[] =
"eJztxT1LQmEAgNGXMJEIukNI0pDS0hAUSiCa4uZfELqgQwUFuQjXhkDFisrARajBocmISFA0GstBg4owopuIgdAiKE0SfkSBf6HB5TnLmYnpxMBv89"
"ExVnBN7pWvll_ePZqMpPo2Fg6dT-GQdfbA_zH_eftzVE16g8l9Ze7cP33ZTn2dlPP9XEfpXbyeqtnrm50HS7G0dbzyZpPNSkW_"
"tLmeCCT0pbrzO21otbfjqqyNuIySTjNCRERERERERERERERERERERERERERERERERERE_2k3ZA8YhRBhcb_"
"2XHN7zoR5alwbvfMtEhERERERERERERERERER0ZCqTzREVzKNyvlV8Qf1dzn-";
const char *gzip = gzip_arr;
const size_t gzip_size = sizeof(gzip_arr) - 1;
static const char sqlite_sample_db_v3_arr[] =
"olFZ1MdfY0Abj+LtR9ft6DTZgEHW7/"
"z7yAhC07NKr7pBAHWkbQyMPtyVSIW7PLdVaQIHYwLgd7ovQSzD7eTINxZh6Nxpwa8HTynvjhHIdQhtysRL9m3mTEj4mbjU48zq+jcFdsnzG+"

View File

@ -14,6 +14,9 @@ extern const size_t thumbnail_size;
extern const char *gzip_bomb;
extern const size_t gzip_bomb_size;
extern const char *gzip;
extern const size_t gzip_size;
extern const char *sqlite_sample_db_v3;
extern const size_t sqlite_sample_db_v3_size;

View File

@ -68,11 +68,14 @@ static string gen_http_content() {
return rand_string(std::numeric_limits<char>::min(), std::numeric_limits<char>::max(), len);
}
static string make_http_query(string content, bool is_chunked, bool is_gzip, double gzip_k = 5,
static string make_http_query(string content, bool is_json, bool is_chunked, bool is_gzip, double gzip_k = 5,
string zip_override = "") {
HttpHeaderCreator hc;
hc.init_post("/");
hc.add_header("jfkdlsahhjk", rand_string('a', 'z', Random::fast(1, 2000)));
if (is_json) {
hc.add_header("content-type", "application/json");
}
if (is_gzip) {
BufferSlice zip;
if (zip_override.empty()) {
@ -102,7 +105,7 @@ static string make_http_query(string content, bool is_chunked, bool is_gzip, dou
static string rand_http_query(string content) {
bool is_chunked = Random::fast_bool();
bool is_gzip = Random::fast_bool();
return make_http_query(std::move(content), is_chunked, is_gzip);
return make_http_query(std::move(content), false, is_chunked, is_gzip);
}
static string join(const std::vector<string> &v) {
@ -216,7 +219,7 @@ TEST(Http, gzip_bomb) {
auto gzip_bomb_str =
gzdecode(gzdecode(base64url_decode(Slice(gzip_bomb, gzip_bomb_size)).ok()).as_slice()).as_slice().str();
auto query = make_http_query("", false, true, 0.01, gzip_bomb_str);
auto query = make_http_query("", false, false, true, 0.01, gzip_bomb_str);
auto parts = rand_split(query);
td::ChainBufferWriter input_writer;
auto input = input_writer.extract_reader();
@ -235,6 +238,26 @@ TEST(Http, gzip_bomb) {
}
}
TEST(Http, gzip) {
return;
auto gzip_str = gzdecode(base64url_decode(Slice(gzip, gzip_size)).ok()).as_slice().str();
td::ChainBufferWriter input_writer;
auto input = input_writer.extract_reader();
HttpReader reader;
reader.init(&input, 0, 0);
auto query = make_http_query("", true, false, true, 0.01, gzip_str);
input_writer.append(query);
input.sync_with_writer();
HttpQuery q;
auto r_state = reader.read_next(&q);
ASSERT_TRUE(r_state.is_error());
ASSERT_EQ(413, r_state.error().code());
}
TEST(Http, aes_ctr_encode_decode_flow) {
auto str = rand_string('a', 'z', 1000000);
auto parts = rand_split(str);
@ -418,7 +441,7 @@ TEST(Http, gzip_bomb_with_limit) {
gzip_bomb_str = sink.result()->move_as_buffer_slice().as_slice().str();
}
auto query = make_http_query("", false, true, 0.01, gzip_bomb_str);
auto query = make_http_query("", false, false, true, 0.01, gzip_bomb_str);
auto parts = rand_split(query);
td::ChainBufferWriter input_writer;
auto input = input_writer.extract_reader();