diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index e89099b1..46ff70bd 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -2645,6 +2645,9 @@ ContactsManager::ContactsManager(Td *td, ActorShared<> parent) : td_(td), parent user_nearby_timeout_.set_callback(on_user_nearby_timeout_callback); user_nearby_timeout_.set_callback_data(static_cast(this)); + + slow_mode_delay_timeout_.set_callback(on_slow_mode_delay_timeout_callback); + slow_mode_delay_timeout_.set_callback_data(static_cast(this)); } void ContactsManager::tear_down() { @@ -2748,6 +2751,24 @@ void ContactsManager::on_user_nearby_timeout(UserId user_id) { } } +void ContactsManager::on_slow_mode_delay_timeout_callback(void *contacts_manager_ptr, int64 channel_id_long) { + if (G()->close_flag()) { + return; + } + + auto contacts_manager = static_cast(contacts_manager_ptr); + send_closure_later(contacts_manager->actor_id(contacts_manager), &ContactsManager::on_slow_mode_delay_timeout, + ChannelId(narrow_cast(channel_id_long))); +} + +void ContactsManager::on_slow_mode_delay_timeout(ChannelId channel_id) { + if (G()->close_flag()) { + return; + } + + on_update_channel_slow_mode_next_send_date(channel_id, 0); +} + template void ContactsManager::BotInfo::store(StorerT &storer) const { using td::store; @@ -8020,6 +8041,22 @@ void ContactsManager::update_channel_full(ChannelFull *channel_full, ChannelId c channel_full->administrator_count = channel_full->participant_count; } + if (channel_full->is_slow_mode_next_send_date_changed) { + auto now = G()->server_time(); + if (channel_full->slow_mode_next_send_date > now + 3601) { + channel_full->slow_mode_next_send_date = static_cast(now) + 3601; + } + if (channel_full->slow_mode_next_send_date <= now) { + channel_full->slow_mode_next_send_date = 0; + } + if (channel_full->slow_mode_next_send_date == 0) { + slow_mode_delay_timeout_.cancel_timeout(channel_id.get()); + } else { + slow_mode_delay_timeout_.set_timeout_in(channel_id.get(), channel_full->slow_mode_next_send_date - now + 0.002); + } + channel_full->is_slow_mode_next_send_date_changed = false; + } + channel_full->need_send_update |= channel_full->is_changed; channel_full->need_save_to_database |= channel_full->is_changed; channel_full->is_changed = false; @@ -9577,6 +9614,7 @@ void ContactsManager::invalidate_channel_full(ChannelId channel_id, bool drop_in if (drop_slow_mode_delay && channel_full->slow_mode_delay != 0) { channel_full->slow_mode_delay = 0; channel_full->slow_mode_next_send_date = 0; + channel_full->is_slow_mode_next_send_date_changed = true; channel_full->is_changed = true; } update_channel_full(channel_full, channel_id); @@ -9733,6 +9771,7 @@ void ContactsManager::on_update_channel_full_slow_mode_next_send_date(ChannelFul } if (channel_full->slow_mode_next_send_date != slow_mode_next_send_date) { channel_full->slow_mode_next_send_date = slow_mode_next_send_date; + channel_full->is_slow_mode_next_send_date_changed = true; channel_full->is_changed = true; } } @@ -10527,6 +10566,14 @@ void ContactsManager::on_update_channel_slow_mode_delay(ChannelId channel_id, in } } +void ContactsManager::on_update_channel_slow_mode_next_send_date(ChannelId channel_id, int32 next_send_date) { + auto channel_full = get_channel_full_force(channel_id); + if (channel_full != nullptr) { + on_update_channel_full_slow_mode_next_send_date(channel_full, next_send_date); + update_channel_full(channel_full, channel_id); + } +} + void ContactsManager::on_update_channel_bot_user_ids(ChannelId channel_id, vector &&bot_user_ids) { CHECK(channel_id.is_valid()); if (!have_channel(channel_id)) { diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 970e7025..c7f1db3d 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -186,6 +186,7 @@ class ContactsManager : public Actor { void on_update_channel_linked_channel_id(ChannelId channel_id, ChannelId group_channel_id); void on_update_channel_location(ChannelId channel_id, const DialogLocation &location); void on_update_channel_slow_mode_delay(ChannelId channel_id, int32 slow_mode_delay); + void on_update_channel_slow_mode_next_send_date(ChannelId channel_id, int32 next_send_date); void on_update_channel_is_all_history_available(ChannelId channel_id, bool is_all_history_available); void on_update_channel_default_permissions(ChannelId channel_id, RestrictedRights default_permissions); void on_update_channel_administrator_count(ChannelId channel_id, int32 administrator_count); @@ -246,8 +247,6 @@ class ContactsManager : public Actor { void on_channel_unban_timeout(ChannelId channel_id); - void on_user_nearby_timeout(UserId user_id); - void check_dialog_username(DialogId dialog_id, const string &username, Promise &&promise); static td_api::object_ptr get_check_chat_username_result_object( @@ -764,6 +763,7 @@ class ContactsManager : public Actor { bool can_view_statistics = false; bool is_all_history_available = true; + bool is_slow_mode_next_send_date_changed = true; bool is_changed = true; // have new changes that need to be sent to the client and database bool need_send_update = true; // have new changes that need only to be sent to the client bool need_save_to_database = true; // have new changes that need only to be saved to the database @@ -1286,8 +1286,14 @@ class ContactsManager : public Actor { static void on_user_nearby_timeout_callback(void *contacts_manager_ptr, int64 user_id_long); + static void on_slow_mode_delay_timeout_callback(void *contacts_manager_ptr, int64 channel_id_long); + void on_user_online_timeout(UserId user_id); + void on_user_nearby_timeout(UserId user_id); + + void on_slow_mode_delay_timeout(ChannelId channel_id); + void tear_down() override; Td *td_; @@ -1401,7 +1407,8 @@ class ContactsManager : public Actor { MultiTimeout user_online_timeout_{"UserOnlineTimeout"}; MultiTimeout channel_unban_timeout_{"ChannelUnbanTimeout"}; - MultiTimeout user_nearby_timeout_{"UserOnlineTimeout"}; + MultiTimeout user_nearby_timeout_{"UserNearbyTimeout"}; + MultiTimeout slow_mode_delay_timeout_{"SlowModeDelayTimeout"}; }; } // namespace td