Support file reference repair for bot description photo and animation.

This commit is contained in:
levlam 2022-08-06 13:42:35 +03:00
parent 14fa1d71d9
commit 44e96081c6
6 changed files with 96 additions and 21 deletions

View File

@ -3401,8 +3401,8 @@ ContactsManager::ContactsManager(Td *td, ActorShared<> parent) : td_(td), parent
ContactsManager::~ContactsManager() {
Scheduler::instance()->destroy_on_scheduler(
G()->get_gc_scheduler_id(), users_, users_full_, user_photos_, unknown_users_, pending_user_photos_,
user_profile_photo_file_source_ids_, my_photo_file_id_, chats_, chats_full_, unknown_chats_,
chat_full_file_source_ids_, min_channels_, channels_, channels_full_, unknown_channels_,
user_profile_photo_file_source_ids_, my_photo_file_id_, user_full_file_source_ids_, chats_, chats_full_,
unknown_chats_, chat_full_file_source_ids_, min_channels_, channels_, channels_full_, unknown_channels_,
invalidated_channels_full_, channel_full_file_source_ids_, secret_chats_, unknown_secret_chats_,
secret_chats_with_user_, invite_link_infos_, dialog_access_by_invite_link_, loaded_from_database_users_,
unavailable_user_fulls_, loaded_from_database_chats_, unavailable_chat_fulls_, loaded_from_database_channels_,
@ -10562,6 +10562,33 @@ void ContactsManager::update_user_full(UserFull *user_full, UserId user_id, cons
td_->messages_manager_->drop_common_dialogs_cache(user_id);
user_full->is_common_chat_count_changed = false;
}
if (user_full->are_files_changed) {
auto file_ids = photo_get_file_ids(user_full->description_photo);
if (user_full->description_animation_file_id.is_valid()) {
file_ids.push_back(user_full->description_animation_file_id);
}
if (user_full->registered_file_ids != file_ids) {
auto &file_source_id = user_full->file_source_id;
if (!file_source_id.is_valid()) {
file_source_id = user_full_file_source_ids_.get(user_id);
if (file_source_id.is_valid()) {
VLOG(file_references) << "Move " << file_source_id << " inside of " << user_id;
user_full_file_source_ids_.erase(user_id);
} else {
VLOG(file_references) << "Need to create new file source for full " << user_id;
file_source_id = td_->file_reference_manager_->create_user_full_file_source(user_id);
}
}
for (auto &file_id : user_full->registered_file_ids) {
td_->file_manager_->remove_file_source(file_id, file_source_id);
}
user_full->registered_file_ids = std::move(file_ids);
for (auto &file_id : user_full->registered_file_ids) {
td_->file_manager_->add_file_source(file_id, file_source_id);
}
}
}
user_full->need_send_update |= user_full->is_changed;
user_full->need_save_to_database |= user_full->is_changed;
@ -10838,11 +10865,15 @@ void ContactsManager::on_get_user_full(tl_object_ptr<telegram_api::userFull> &&u
on_update_user_full_commands(user_full, user_id, std::move(user->bot_info_->commands_));
on_update_user_full_menu_button(user_full, user_id, std::move(user->bot_info_->menu_button_));
}
if (user_full->description != description || user_full->description_photo != description_photo ||
user_full->description_animation_file_id != description_animation_file_id) {
if (user_full->description != description) {
user_full->description = std::move(description);
user_full->is_changed = true;
}
if (user_full->description_photo != description_photo ||
user_full->description_animation_file_id != description_animation_file_id) {
user_full->description_photo = std::move(description_photo);
user_full->description_animation_file_id = description_animation_file_id;
user_full->are_files_changed = true;
user_full->is_changed = true;
}
@ -12093,7 +12124,7 @@ void ContactsManager::drop_user_photos(UserId user_id, bool is_empty, bool drop_
user_full->expires_at = 0.0;
user_full->need_save_to_database = true;
}
reload_user_full(user_id);
reload_user_full(user_id, Auto());
}
update_user_full(user_full, user_id, "drop_user_photos");
}
@ -12129,6 +12160,7 @@ void ContactsManager::drop_user_full(UserId user_id) {
user_full->broadcast_administrator_rights = {};
user_full->premium_gift_options.clear();
user_full->voice_messages_forbidden = false;
user_full->are_files_changed = true;
user_full->is_changed = true;
update_user_full(user_full, user_id, "drop_user_full");
@ -14596,11 +14628,9 @@ void ContactsManager::load_user_full(UserId user_id, bool force, Promise<Unit> &
promise.set_value(Unit());
}
void ContactsManager::reload_user_full(UserId user_id) {
auto r_input_user = get_input_user(user_id);
if (r_input_user.is_ok()) {
send_get_user_full_query(user_id, r_input_user.move_as_ok(), Auto(), "reload_user_full");
}
void ContactsManager::reload_user_full(UserId user_id, Promise<Unit> &&promise) {
TRY_RESULT_PROMISE(promise, input_user, get_input_user(user_id));
send_get_user_full_query(user_id, std::move(input_user), std::move(promise), "reload_user_full");
}
void ContactsManager::send_get_user_full_query(UserId user_id, tl_object_ptr<telegram_api::InputUser> &&input_user,
@ -14725,6 +14755,25 @@ FileSourceId ContactsManager::get_user_profile_photo_file_source_id(UserId user_
return source_id;
}
FileSourceId ContactsManager::get_user_full_file_source_id(UserId user_id) {
if (!user_id.is_valid()) {
return FileSourceId();
}
if (get_user_full(user_id) != nullptr) {
VLOG(file_references) << "Don't need to create file source for full " << user_id;
// user full was already added, source ID was registered and shouldn't be needed
return FileSourceId();
}
auto &source_id = user_full_file_source_ids_[user_id];
if (!source_id.is_valid()) {
source_id = td_->file_reference_manager_->create_user_full_file_source(user_id);
}
VLOG(file_references) << "Return " << source_id << " for full " << user_id;
return source_id;
}
FileSourceId ContactsManager::get_chat_full_file_source_id(ChatId chat_id) {
if (!chat_id.is_valid()) {
return FileSourceId();

View File

@ -492,7 +492,8 @@ class ContactsManager final : public Actor {
bool get_user(UserId user_id, int left_tries, Promise<Unit> &&promise);
void reload_user(UserId user_id, Promise<Unit> &&promise);
void load_user_full(UserId user_id, bool force, Promise<Unit> &&promise, const char *source);
void reload_user_full(UserId user_id);
FileSourceId get_user_full_file_source_id(UserId user_id);
void reload_user_full(UserId user_id, Promise<Unit> &&promise);
std::pair<int32, vector<const Photo *>> get_user_profile_photos(UserId user_id, int32 offset, int32 limit,
Promise<Unit> &&promise);
@ -717,6 +718,8 @@ class ContactsManager final : public Actor {
string description;
Photo description_photo;
FileId description_animation_file_id;
vector<FileId> registered_file_ids;
FileSourceId file_source_id;
vector<PremiumGiftOption> premium_gift_options;
@ -736,6 +739,7 @@ class ContactsManager final : public Actor {
bool voice_messages_forbidden = false;
bool is_common_chat_count_changed = true;
bool are_files_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
@ -1703,6 +1707,7 @@ class ContactsManager final : public Actor {
};
WaitFreeHashMap<std::pair<UserId, int64>, FileSourceId, UserIdPhotoIdHash> user_profile_photo_file_source_ids_;
FlatHashMap<int64, FileId> my_photo_file_id_;
WaitFreeHashMap<UserId, FileSourceId, UserIdHash> user_full_file_source_ids_;
WaitFreeHashMap<ChatId, unique_ptr<Chat>, ChatIdHash> chats_;
WaitFreeHashMap<ChatId, unique_ptr<ChatFull>, ChatIdHash> chats_full_;

View File

@ -115,6 +115,11 @@ FileSourceId FileReferenceManager::create_background_file_source(BackgroundId ba
return add_file_source_id(source, PSLICE() << background_id);
}
FileSourceId FileReferenceManager::create_user_full_file_source(UserId user_id) {
FileSourceUserFull source{user_id};
return add_file_source_id(source, PSLICE() << "full " << user_id);
}
FileSourceId FileReferenceManager::create_chat_full_file_source(ChatId chat_id) {
FileSourceChatFull source{chat_id};
return add_file_source_id(source, PSLICE() << "full " << chat_id);
@ -320,6 +325,10 @@ void FileReferenceManager::send_query(Destination dest, FileSourceId file_source
[&](const FileSourceSavedRingtones &source) {
send_closure_later(G()->notification_settings_manager(), &NotificationSettingsManager::repair_saved_ringtones,
std::move(promise));
},
[&](const FileSourceUserFull &source) {
send_closure_later(G()->contacts_manager(), &ContactsManager::reload_user_full, source.user_id,
std::move(promise));
}));
}

View File

@ -57,6 +57,7 @@ class FileReferenceManager final : public Actor {
FileSourceId create_recent_stickers_file_source(bool is_attached);
FileSourceId create_favorite_stickers_file_source();
FileSourceId create_background_file_source(BackgroundId background_id, int64 access_hash);
FileSourceId create_user_full_file_source(UserId user_id);
FileSourceId create_chat_full_file_source(ChatId chat_id);
FileSourceId create_channel_full_file_source(ChannelId channel_id);
FileSourceId create_app_config_file_source();
@ -156,12 +157,16 @@ class FileReferenceManager final : public Actor {
struct FileSourceSavedRingtones {
// empty
};
struct FileSourceUserFull {
UserId user_id;
};
// append only
using FileSource = Variant<FileSourceMessage, FileSourceUserPhoto, FileSourceChatPhoto, FileSourceChannelPhoto,
FileSourceWallpapers, FileSourceWebPage, FileSourceSavedAnimations,
FileSourceRecentStickers, FileSourceFavoriteStickers, FileSourceBackground,
FileSourceChatFull, FileSourceChannelFull, FileSourceAppConfig, FileSourceSavedRingtones>;
using FileSource =
Variant<FileSourceMessage, FileSourceUserPhoto, FileSourceChatPhoto, FileSourceChannelPhoto, FileSourceWallpapers,
FileSourceWebPage, FileSourceSavedAnimations, FileSourceRecentStickers, FileSourceFavoriteStickers,
FileSourceBackground, FileSourceChatFull, FileSourceChannelFull, FileSourceAppConfig,
FileSourceSavedRingtones, FileSourceUserFull>;
WaitFreeVector<FileSource> file_sources_;
int64 query_generation_{0};

View File

@ -51,7 +51,8 @@ void FileReferenceManager::store_file_source(FileSourceId file_source_id, Storer
},
[&](const FileSourceChatFull &source) { td::store(source.chat_id, storer); },
[&](const FileSourceChannelFull &source) { td::store(source.channel_id, storer); },
[&](const FileSourceAppConfig &source) {}, [&](const FileSourceSavedRingtones &source) {}));
[&](const FileSourceAppConfig &source) {}, [&](const FileSourceSavedRingtones &source) {},
[&](const FileSourceUserFull &source) { td::store(source.user_id, storer); }));
}
template <class ParserT>
@ -117,6 +118,11 @@ FileSourceId FileReferenceManager::parse_file_source(Td *td, ParserT &parser) {
return td->stickers_manager_->get_app_config_file_source_id();
case 13:
return td->notification_settings_manager_->get_saved_ringtones_file_source_id();
case 14: {
UserId user_id;
td::parse(user_id, parser);
return td->contacts_manager_->get_user_full_file_source_id(user_id);
}
default:
parser.set_error("Invalid type in FileSource");
return FileSourceId();

View File

@ -8451,7 +8451,7 @@ void MessagesManager::reget_dialog_action_bar(DialogId dialog_id, const char *so
LOG(INFO) << "Reget action bar in " << dialog_id << " from " << source;
switch (dialog_id.get_type()) {
case DialogType::User:
td_->contacts_manager_->reload_user_full(dialog_id.get_user_id());
td_->contacts_manager_->reload_user_full(dialog_id.get_user_id(), Auto());
return;
case DialogType::Chat:
case DialogType::Channel:
@ -18453,7 +18453,8 @@ void MessagesManager::reload_dialog_info_full(DialogId dialog_id, const char *so
LOG(INFO) << "Reload full info about " << dialog_id << " from " << source;
switch (dialog_id.get_type()) {
case DialogType::User:
send_closure_later(td_->contacts_manager_actor_, &ContactsManager::reload_user_full, dialog_id.get_user_id());
send_closure_later(td_->contacts_manager_actor_, &ContactsManager::reload_user_full, dialog_id.get_user_id(),
Promise<Unit>());
return;
case DialogType::Chat:
send_closure_later(td_->contacts_manager_actor_, &ContactsManager::reload_chat_full, dialog_id.get_chat_id(),
@ -21106,7 +21107,7 @@ void MessagesManager::open_dialog(Dialog *d) {
// to repair dialog action bar
auto user_id = td_->contacts_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id());
if (user_id.is_valid()) {
td_->contacts_manager_->reload_user_full(user_id);
td_->contacts_manager_->reload_user_full(user_id, Promise<Unit>());
}
break;
}
@ -34958,7 +34959,7 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq
switch (dialog_type) {
case DialogType::User:
td_->contacts_manager_->invalidate_user_full(dialog_id.get_user_id());
td_->contacts_manager_->reload_user_full(dialog_id.get_user_id());
td_->contacts_manager_->reload_user_full(dialog_id.get_user_id(), Promise<Unit>());
break;
case DialogType::Chat:
case DialogType::Channel:
@ -34968,7 +34969,7 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq
auto user_id = td_->contacts_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id());
if (user_id.is_valid()) {
td_->contacts_manager_->invalidate_user_full(user_id);
td_->contacts_manager_->reload_user_full(user_id);
td_->contacts_manager_->reload_user_full(user_id, Promise<Unit>());
}
break;
}