summaryrefslogtreecommitdiff
path: root/protocols/Telegram/tdlib/td/td/telegram/DialogParticipantManager.h
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Telegram/tdlib/td/td/telegram/DialogParticipantManager.h')
-rw-r--r--protocols/Telegram/tdlib/td/td/telegram/DialogParticipantManager.h319
1 files changed, 319 insertions, 0 deletions
diff --git a/protocols/Telegram/tdlib/td/td/telegram/DialogParticipantManager.h b/protocols/Telegram/tdlib/td/td/telegram/DialogParticipantManager.h
new file mode 100644
index 0000000000..d021156625
--- /dev/null
+++ b/protocols/Telegram/tdlib/td/td/telegram/DialogParticipantManager.h
@@ -0,0 +1,319 @@
+//
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024
+//
+// 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/telegram/ChannelId.h"
+#include "td/telegram/ChatId.h"
+#include "td/telegram/DialogAdministrator.h"
+#include "td/telegram/DialogId.h"
+#include "td/telegram/DialogInviteLink.h"
+#include "td/telegram/DialogParticipant.h"
+#include "td/telegram/DialogParticipantFilter.h"
+#include "td/telegram/td_api.h"
+#include "td/telegram/telegram_api.h"
+#include "td/telegram/UserId.h"
+
+#include "td/actor/actor.h"
+#include "td/actor/MultiTimeout.h"
+
+#include "td/utils/common.h"
+#include "td/utils/FlatHashMap.h"
+#include "td/utils/Promise.h"
+#include "td/utils/Status.h"
+
+#include <utility>
+
+namespace td {
+
+class ChannelParticipantFilter;
+
+class Td;
+
+class DialogParticipantManager final : public Actor {
+ public:
+ DialogParticipantManager(Td *td, ActorShared<> parent);
+ DialogParticipantManager(const DialogParticipantManager &) = delete;
+ DialogParticipantManager &operator=(const DialogParticipantManager &) = delete;
+ DialogParticipantManager(DialogParticipantManager &&) = delete;
+ DialogParticipantManager &operator=(DialogParticipantManager &&) = delete;
+ ~DialogParticipantManager() final;
+
+ void update_user_online_member_count(UserId user_id);
+
+ void update_dialog_online_member_count(const vector<DialogParticipant> &participants, DialogId dialog_id,
+ bool is_from_server);
+
+ void on_update_dialog_online_member_count(DialogId dialog_id, int32 online_member_count, bool is_from_server);
+
+ void add_cached_channel_participants(ChannelId channel_id, const vector<UserId> &added_user_ids,
+ UserId inviter_user_id, int32 date);
+
+ void delete_cached_channel_participant(ChannelId channel_id, UserId deleted_user_id);
+
+ void update_cached_channel_participant_status(ChannelId channel_id, UserId user_id,
+ const DialogParticipantStatus &status);
+
+ void on_dialog_opened(DialogId dialog_id);
+
+ void on_dialog_closed(DialogId dialog_id);
+
+ void get_dialog_join_requests(DialogId dialog_id, const string &invite_link, const string &query,
+ td_api::object_ptr<td_api::chatJoinRequest> offset_request, int32 limit,
+ Promise<td_api::object_ptr<td_api::chatJoinRequests>> &&promise);
+
+ void process_dialog_join_request(DialogId dialog_id, UserId user_id, bool approve, Promise<Unit> &&promise);
+
+ void process_dialog_join_requests(DialogId dialog_id, const string &invite_link, bool approve,
+ Promise<Unit> &&promise);
+
+ void speculative_update_dialog_administrators(DialogId dialog_id, UserId user_id,
+ const DialogParticipantStatus &new_status,
+ const DialogParticipantStatus &old_status);
+
+ void on_update_dialog_administrators(DialogId dialog_id, vector<DialogAdministrator> &&administrators,
+ bool have_access, bool from_database);
+
+ void get_dialog_administrators(DialogId dialog_id, Promise<td_api::object_ptr<td_api::chatAdministrators>> &&promise);
+
+ void reload_dialog_administrators(DialogId dialog_id, const vector<DialogAdministrator> &dialog_administrators,
+ Promise<td_api::object_ptr<td_api::chatAdministrators>> &&promise);
+
+ void on_update_bot_stopped(UserId user_id, int32 date, bool is_stopped, bool force = false);
+
+ void on_update_chat_participant(ChatId chat_id, UserId user_id, int32 date, DialogInviteLink invite_link,
+ bool via_join_request,
+ telegram_api::object_ptr<telegram_api::ChatParticipant> old_participant,
+ telegram_api::object_ptr<telegram_api::ChatParticipant> new_participant);
+
+ void on_update_channel_participant(ChannelId channel_id, UserId user_id, int32 date, DialogInviteLink invite_link,
+ bool via_join_request, bool via_dialog_filter_invite_link,
+ telegram_api::object_ptr<telegram_api::ChannelParticipant> old_participant,
+ telegram_api::object_ptr<telegram_api::ChannelParticipant> new_participant);
+
+ void on_update_chat_invite_requester(DialogId dialog_id, UserId user_id, string about, int32 date,
+ DialogInviteLink invite_link);
+
+ void get_dialog_participant(DialogId dialog_id, DialogId participant_dialog_id,
+ Promise<td_api::object_ptr<td_api::chatMember>> &&promise);
+
+ void get_channel_participant(ChannelId channel_id, DialogId participant_dialog_id,
+ Promise<DialogParticipant> &&promise);
+
+ void get_channel_participants(ChannelId channel_id, td_api::object_ptr<td_api::SupergroupMembersFilter> &&filter,
+ string additional_query, int32 offset, int32 limit, int32 additional_limit,
+ Promise<DialogParticipants> &&promise);
+
+ void search_dialog_participants(DialogId dialog_id, const string &query, int32 limit, DialogParticipantFilter filter,
+ Promise<DialogParticipants> &&promise);
+
+ static Promise<td_api::object_ptr<td_api::failedToAddMembers>> wrap_failed_to_add_members_promise(
+ Promise<Unit> &&promise);
+
+ void add_dialog_participant(DialogId dialog_id, UserId user_id, int32 forward_limit,
+ Promise<td_api::object_ptr<td_api::failedToAddMembers>> &&promise);
+
+ void add_dialog_participants(DialogId dialog_id, const vector<UserId> &user_ids,
+ Promise<td_api::object_ptr<td_api::failedToAddMembers>> &&promise);
+
+ void set_dialog_participant_status(DialogId dialog_id, DialogId participant_dialog_id,
+ td_api::object_ptr<td_api::ChatMemberStatus> &&chat_member_status,
+ Promise<Unit> &&promise);
+
+ void ban_dialog_participant(DialogId dialog_id, DialogId participant_dialog_id, int32 banned_until_date,
+ bool revoke_messages, Promise<Unit> &&promise);
+
+ void leave_dialog(DialogId dialog_id, Promise<Unit> &&promise);
+
+ void on_set_channel_participant_status(ChannelId channel_id, DialogId participant_dialog_id,
+ DialogParticipantStatus status);
+
+ bool have_channel_participant_cache(ChannelId channel_id) const;
+
+ void add_channel_participant_to_cache(ChannelId channel_id, const DialogParticipant &dialog_participant,
+ bool allow_replace);
+
+ void drop_channel_participant_cache(ChannelId channel_id);
+
+ struct CanTransferOwnershipResult {
+ enum class Type : uint8 { Ok, PasswordNeeded, PasswordTooFresh, SessionTooFresh };
+ Type type = Type::Ok;
+ int32 retry_after = 0;
+ };
+ void can_transfer_ownership(Promise<CanTransferOwnershipResult> &&promise);
+
+ static td_api::object_ptr<td_api::CanTransferOwnershipResult> get_can_transfer_ownership_result_object(
+ CanTransferOwnershipResult result);
+
+ void transfer_dialog_ownership(DialogId dialog_id, UserId user_id, const string &password, Promise<Unit> &&promise);
+
+ void get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const;
+
+ private:
+ static constexpr int32 ONLINE_MEMBER_COUNT_CACHE_EXPIRE_TIME = 30 * 60;
+
+ static constexpr int32 ONLINE_MEMBER_COUNT_UPDATE_TIME = 5 * 60;
+
+ static constexpr int32 CHANNEL_PARTICIPANT_CACHE_TIME = 1800; // some reasonable limit
+
+ static constexpr int32 MAX_GET_CHANNEL_PARTICIPANTS = 200; // server side limit
+
+ void tear_down() final;
+
+ static void on_update_dialog_online_member_count_timeout_callback(void *dialog_participant_manager_ptr,
+ int64 dialog_id_int);
+
+ void set_dialog_online_member_count(DialogId dialog_id, int32 online_member_count, bool is_from_server,
+ const char *source);
+
+ void on_update_dialog_online_member_count_timeout(DialogId dialog_id);
+
+ void send_update_chat_online_member_count(DialogId dialog_id, int32 online_member_count) const;
+
+ Status can_manage_dialog_join_requests(DialogId dialog_id);
+
+ td_api::object_ptr<td_api::chatAdministrators> get_chat_administrators_object(
+ const vector<DialogAdministrator> &dialog_administrators);
+
+ static string get_dialog_administrators_database_key(DialogId dialog_id);
+
+ void on_load_dialog_administrators_from_database(DialogId dialog_id, string value,
+ Promise<td_api::object_ptr<td_api::chatAdministrators>> &&promise);
+
+ void on_load_administrator_users_finished(DialogId dialog_id, vector<DialogAdministrator> administrators,
+ Result<Unit> result,
+ Promise<td_api::object_ptr<td_api::chatAdministrators>> &&promise);
+
+ void on_reload_dialog_administrators(DialogId dialog_id,
+ Promise<td_api::object_ptr<td_api::chatAdministrators>> &&promise);
+
+ void send_update_chat_member(DialogId dialog_id, UserId agent_user_id, int32 date,
+ const DialogInviteLink &invite_link, bool via_join_request,
+ bool via_dialog_filter_invite_link, const DialogParticipant &old_dialog_participant,
+ const DialogParticipant &new_dialog_participant);
+
+ void do_get_dialog_participant(DialogId dialog_id, DialogId participant_dialog_id,
+ Promise<DialogParticipant> &&promise);
+
+ void finish_get_dialog_participant(DialogParticipant &&dialog_participant,
+ Promise<td_api::object_ptr<td_api::chatMember>> &&promise);
+
+ void finish_get_channel_participant(ChannelId channel_id, DialogId participant_dialog_id,
+ DialogParticipant &&dialog_participant, Promise<DialogParticipant> &&promise);
+
+ std::pair<int32, vector<DialogId>> search_among_dialogs(const vector<DialogId> &dialog_ids, const string &query,
+ int32 limit) const;
+
+ DialogParticipants search_private_chat_participants(UserId peer_user_id, const string &query, int32 limit,
+ DialogParticipantFilter filter) const;
+
+ void search_chat_participants(ChatId chat_id, const string &query, int32 limit, DialogParticipantFilter filter,
+ Promise<DialogParticipants> &&promise);
+
+ void do_search_chat_participants(ChatId chat_id, const string &query, int32 limit, DialogParticipantFilter filter,
+ Promise<DialogParticipants> &&promise);
+
+ void on_get_channel_participants(
+ ChannelId channel_id, ChannelParticipantFilter &&filter, int32 offset, int32 limit, string additional_query,
+ int32 additional_limit,
+ telegram_api::object_ptr<telegram_api::channels_channelParticipants> &&channel_participants,
+ Promise<DialogParticipants> &&promise);
+
+ void set_chat_participant_status(ChatId chat_id, UserId user_id, DialogParticipantStatus status, bool is_recursive,
+ Promise<Unit> &&promise);
+
+ void add_chat_participant(ChatId chat_id, UserId user_id, int32 forward_limit,
+ Promise<td_api::object_ptr<td_api::failedToAddMembers>> &&promise);
+
+ void send_edit_chat_admin_query(ChatId chat_id, UserId user_id, bool is_administrator, Promise<Unit> &&promise);
+
+ void delete_chat_participant(ChatId chat_id, UserId user_id, bool revoke_messages, Promise<Unit> &&promise);
+
+ void add_channel_participant(ChannelId channel_id, UserId user_id, const DialogParticipantStatus &old_status,
+ Promise<td_api::object_ptr<td_api::failedToAddMembers>> &&promise);
+
+ void on_join_channel(ChannelId channel_id, bool was_speculatively_updated, DialogParticipantStatus &&old_status,
+ DialogParticipantStatus &&new_status, Result<Unit> &&result);
+
+ void add_channel_participants(ChannelId channel_id, const vector<UserId> &user_ids,
+ Promise<td_api::object_ptr<td_api::failedToAddMembers>> &&promise);
+
+ void set_channel_participant_status(ChannelId channel_id, DialogId participant_dialog_id,
+ td_api::object_ptr<td_api::ChatMemberStatus> &&chat_member_status,
+ Promise<Unit> &&promise);
+
+ void set_channel_participant_status_impl(ChannelId channel_id, DialogId participant_dialog_id,
+ DialogParticipantStatus new_status, DialogParticipantStatus old_status,
+ Promise<Unit> &&promise);
+
+ void promote_channel_participant(ChannelId channel_id, UserId user_id, const DialogParticipantStatus &new_status,
+ const DialogParticipantStatus &old_status, Promise<Unit> &&promise);
+
+ void restrict_channel_participant(ChannelId channel_id, DialogId participant_dialog_id,
+ DialogParticipantStatus &&new_status, DialogParticipantStatus &&old_status,
+ Promise<Unit> &&promise);
+
+ void speculative_add_channel_user(ChannelId channel_id, UserId user_id, const DialogParticipantStatus &new_status,
+ const DialogParticipantStatus &old_status);
+
+ void update_channel_participant_status_cache(ChannelId channel_id, DialogId participant_dialog_id,
+ DialogParticipantStatus &&dialog_participant_status);
+
+ const DialogParticipant *get_channel_participant_from_cache(ChannelId channel_id, DialogId participant_dialog_id);
+
+ static void on_channel_participant_cache_timeout_callback(void *dialog_participant_manager_ptr,
+ int64 channel_id_long);
+
+ void on_channel_participant_cache_timeout(ChannelId channel_id);
+
+ void set_cached_channel_participants(ChannelId channel_id, vector<DialogParticipant> participants);
+
+ void drop_cached_channel_participants(ChannelId channel_id);
+
+ void update_channel_online_member_count(ChannelId channel_id, bool is_from_server);
+
+ void transfer_channel_ownership(ChannelId channel_id, UserId user_id,
+ tl_object_ptr<telegram_api::InputCheckPasswordSRP> input_check_password,
+ Promise<Unit> &&promise);
+
+ struct OnlineMemberCountInfo {
+ int32 online_member_count = 0;
+ double update_time = 0;
+ bool is_update_sent = false;
+ };
+ FlatHashMap<DialogId, OnlineMemberCountInfo, DialogIdHash> dialog_online_member_counts_;
+
+ struct UserOnlineMemberDialogs {
+ FlatHashMap<DialogId, int32, DialogIdHash> online_member_dialogs_; // dialog_id -> time
+ };
+ FlatHashMap<UserId, unique_ptr<UserOnlineMemberDialogs>, UserIdHash> user_online_member_dialogs_;
+
+ FlatHashMap<DialogId, vector<DialogAdministrator>, DialogIdHash> dialog_administrators_;
+
+ // bot-administrators only
+ struct ChannelParticipantInfo {
+ DialogParticipant participant_;
+
+ int32 last_access_date_ = 0;
+ };
+ struct ChannelParticipants {
+ FlatHashMap<DialogId, ChannelParticipantInfo, DialogIdHash> participants_;
+ };
+ FlatHashMap<ChannelId, ChannelParticipants, ChannelIdHash> channel_participants_;
+
+ FlatHashMap<ChannelId, vector<DialogParticipant>, ChannelIdHash> cached_channel_participants_;
+
+ FlatHashMap<ChannelId, vector<Promise<td_api::object_ptr<td_api::failedToAddMembers>>>, ChannelIdHash>
+ join_channel_queries_;
+
+ MultiTimeout update_dialog_online_member_count_timeout_{"UpdateDialogOnlineMemberCountTimeout"};
+ MultiTimeout channel_participant_cache_timeout_{"ChannelParticipantCacheTimeout"};
+
+ Td *td_;
+ ActorShared<> parent_;
+};
+
+} // namespace td