diff --git a/td/generate/scheme/telegram_api.tl b/td/generate/scheme/telegram_api.tl index 5bdda4caa..e5c176f6d 100644 --- a/td/generate/scheme/telegram_api.tl +++ b/td/generate/scheme/telegram_api.tl @@ -181,6 +181,7 @@ photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = Phot photoCachedSize#e9a734fa type:string location:FileLocation w:int h:int bytes:bytes = PhotoSize; photoStrippedSize#e0b0bc2e type:string bytes:bytes = PhotoSize; photoSizeProgressive#5aa86a51 type:string location:FileLocation w:int h:int sizes:Vector = PhotoSize; +photoPathSize#d8214d41 type:string bytes:bytes = PhotoSize; geoPointEmpty#1117dd5f = GeoPoint; geoPoint#b2a2f663 flags:# long:double lat:double access_hash:long accuracy_radius:flags.0?int = GeoPoint; diff --git a/td/generate/scheme/telegram_api.tlo b/td/generate/scheme/telegram_api.tlo index bb3f233d1..bb074e340 100644 Binary files a/td/generate/scheme/telegram_api.tlo and b/td/generate/scheme/telegram_api.tlo differ diff --git a/td/telegram/DocumentsManager.cpp b/td/telegram/DocumentsManager.cpp index dff1ad48b..96ddb6e7f 100644 --- a/td/telegram/DocumentsManager.cpp +++ b/td/telegram/DocumentsManager.cpp @@ -261,11 +261,13 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo if (document_type != Document::Type::VoiceNote) { for (auto &thumb : document->thumbs_) { - auto photo_size = - get_photo_size(td_->file_manager_.get(), {FileType::Thumbnail, 0}, id, access_hash, file_reference, - DcId::create(dc_id), owner_dialog_id, std::move(thumb), thumbnail_format); + auto photo_size = get_photo_size(td_->file_manager_.get(), {FileType::Thumbnail, 0}, id, access_hash, + file_reference, DcId::create(dc_id), owner_dialog_id, std::move(thumb), + thumbnail_format, document_type != Document::Type::Sticker); if (photo_size.get_offset() == 0) { - thumbnail = std::move(photo_size.get<0>()); + if (!thumbnail.file_id.is_valid()) { + thumbnail = std::move(photo_size.get<0>()); + } } else { minithumbnail = std::move(photo_size.get<1>()); } @@ -429,8 +431,8 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo std::move(mime_type), !is_web); break; case Document::Type::Sticker: - td_->stickers_manager_->create_sticker(file_id, std::move(thumbnail), dimensions, std::move(sticker), - is_animated_sticker, load_data_multipromise_ptr); + td_->stickers_manager_->create_sticker(file_id, std::move(minithumbnail), std::move(thumbnail), dimensions, + std::move(sticker), is_animated_sticker, load_data_multipromise_ptr); break; case Document::Type::Video: td_->videos_manager_->create_video(file_id, std::move(minithumbnail), std::move(thumbnail), diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index c0a86779d..a52766d90 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -1638,8 +1638,9 @@ static Result create_input_message_content( } case td_api::inputMessageSticker::ID: { auto input_sticker = static_cast(input_message_content.get()); - td->stickers_manager_->create_sticker( - file_id, thumbnail, get_dimensions(input_sticker->width_, input_sticker->height_), nullptr, false, nullptr); + td->stickers_manager_->create_sticker(file_id, string(), thumbnail, + get_dimensions(input_sticker->width_, input_sticker->height_), nullptr, + false, nullptr); content = make_unique(file_id); break; diff --git a/td/telegram/Photo.cpp b/td/telegram/Photo.cpp index c512b1637..1e35b4175 100644 --- a/td/telegram/Photo.cpp +++ b/td/telegram/Photo.cpp @@ -358,7 +358,7 @@ PhotoSize get_secret_thumbnail_photo_size(FileManager *file_manager, BufferSlice Variant get_photo_size(FileManager *file_manager, PhotoSizeSource source, int64 id, int64 access_hash, std::string file_reference, DcId dc_id, DialogId owner_dialog_id, tl_object_ptr &&size_ptr, - PhotoFormat format) { + PhotoFormat format, bool expect_jpeg_minithumbnail) { CHECK(size_ptr != nullptr); tl_object_ptr location; @@ -393,6 +393,10 @@ Variant get_photo_size(FileManager *file_manager, PhotoSizeSo } case telegram_api::photoStrippedSize::ID: { auto size = move_tl_object_as(size_ptr); + if (!expect_jpeg_minithumbnail) { + LOG(ERROR) << "Receive unexpected JPEG minithumbnail"; + return std::move(res); + } return size->bytes_.as_slice().str(); } case telegram_api::photoSizeProgressive::ID: { @@ -413,6 +417,14 @@ Variant get_photo_size(FileManager *file_manager, PhotoSizeSo break; } + case telegram_api::photoPathSize::ID: { + auto size = move_tl_object_as(size_ptr); + if (expect_jpeg_minithumbnail) { + LOG(ERROR) << "Receive unexpected SVG minithumbnail"; + return std::move(res); + } + return size->bytes_.as_slice().str(); + } default: UNREACHABLE(); break; @@ -704,7 +716,7 @@ Photo get_photo(FileManager *file_manager, tl_object_ptr && for (auto &size_ptr : photo->sizes_) { auto photo_size = get_photo_size(file_manager, {FileType::Photo, 0}, photo->id_, photo->access_hash_, photo->file_reference_.as_slice().str(), dc_id, owner_dialog_id, - std::move(size_ptr), PhotoFormat::Jpeg); + std::move(size_ptr), PhotoFormat::Jpeg, true); if (photo_size.get_offset() == 0) { PhotoSize &size = photo_size.get<0>(); if (size.type == 0 || size.type == 't' || size.type == 'i' || size.type == 'u' || size.type == 'v') { diff --git a/td/telegram/Photo.h b/td/telegram/Photo.h index 43db9372a..1d8a23572 100644 --- a/td/telegram/Photo.h +++ b/td/telegram/Photo.h @@ -113,7 +113,7 @@ PhotoSize get_secret_thumbnail_photo_size(FileManager *file_manager, BufferSlice Variant get_photo_size(FileManager *file_manager, PhotoSizeSource source, int64 id, int64 access_hash, string file_reference, DcId dc_id, DialogId owner_dialog_id, tl_object_ptr &&size_ptr, - PhotoFormat format); + PhotoFormat format, bool expect_jpeg_minithumbnail); AnimationSize get_animation_size(FileManager *file_manager, PhotoSizeSource source, int64 id, int64 access_hash, string file_reference, DcId dc_id, DialogId owner_dialog_id, tl_object_ptr &&size); diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index e335d7f8f..32fac339e 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -1547,19 +1547,24 @@ FileId StickersManager::on_get_sticker(unique_ptr new_sticker, bool rep } if (s->alt != new_sticker->alt && !new_sticker->alt.empty()) { LOG(DEBUG) << "Sticker " << file_id << " emoji has changed"; - s->alt = new_sticker->alt; + s->alt = std::move(new_sticker->alt); + s->is_changed = true; + } + if (s->minithumbnail != new_sticker->minithumbnail) { + LOG(DEBUG) << "Sticker " << file_id << " minithumbnail has changed"; + s->minithumbnail = std::move(new_sticker->minithumbnail); s->is_changed = true; } if (s->s_thumbnail != new_sticker->s_thumbnail && new_sticker->s_thumbnail.file_id.is_valid()) { LOG_IF(INFO, s->s_thumbnail.file_id.is_valid()) << "Sticker " << file_id << " s thumbnail has changed from " << s->s_thumbnail << " to " << new_sticker->s_thumbnail; - s->s_thumbnail = new_sticker->s_thumbnail; + s->s_thumbnail = std::move(new_sticker->s_thumbnail); s->is_changed = true; } if (s->m_thumbnail != new_sticker->m_thumbnail && new_sticker->m_thumbnail.file_id.is_valid()) { LOG_IF(INFO, s->m_thumbnail.file_id.is_valid()) << "Sticker " << file_id << " m thumbnail has changed from " << s->m_thumbnail << " to " << new_sticker->m_thumbnail; - s->m_thumbnail = new_sticker->m_thumbnail; + s->m_thumbnail = std::move(new_sticker->m_thumbnail); s->is_changed = true; } if (s->is_animated != new_sticker->is_animated && new_sticker->is_animated) { @@ -1635,20 +1640,24 @@ std::pair StickersManager::on_get_sticker_document( PSTRING() << document_id << (is_animated ? ".tgs" : ".webp")); PhotoSize thumbnail; + string minithumbnail; for (auto &thumb : document->thumbs_) { auto photo_size = get_photo_size(td_->file_manager_.get(), {FileType::Thumbnail, 0}, document_id, document->access_hash_, document->file_reference_.as_slice().str(), dc_id, DialogId(), std::move(thumb), - has_webp_thumbnail(sticker) ? PhotoFormat::Webp : PhotoFormat::Jpeg); + has_webp_thumbnail(sticker) ? PhotoFormat::Webp : PhotoFormat::Jpeg, false); if (photo_size.get_offset() == 0) { - thumbnail = std::move(photo_size.get<0>()); + if (!thumbnail.file_id.is_valid()) { + thumbnail = std::move(photo_size.get<0>()); + } break; } else { - LOG(ERROR) << "Receive minithumbnail for a sticker " << sticker_id << ": " << to_string(sticker); + minithumbnail = std::move(photo_size.get<1>()); } } - create_sticker(sticker_id, std::move(thumbnail), dimensions, std::move(sticker), is_animated, nullptr); + create_sticker(sticker_id, std::move(minithumbnail), std::move(thumbnail), dimensions, std::move(sticker), + is_animated, nullptr); return {document_id, sticker_id}; } @@ -1963,7 +1972,7 @@ void StickersManager::add_sticker_thumbnail(Sticker *s, PhotoSize thumbnail) { LOG(ERROR) << "Receive sticker thumbnail of unsupported type " << thumbnail.type; } -void StickersManager::create_sticker(FileId file_id, PhotoSize thumbnail, Dimensions dimensions, +void StickersManager::create_sticker(FileId file_id, string minithumbnail, PhotoSize thumbnail, Dimensions dimensions, tl_object_ptr sticker, bool is_animated, MultiPromiseActor *load_data_multipromise_ptr) { if (is_animated && dimensions.width == 0) { @@ -1974,6 +1983,7 @@ void StickersManager::create_sticker(FileId file_id, PhotoSize thumbnail, Dimens auto s = make_unique(); s->file_id = file_id; s->dimensions = dimensions; + s->minithumbnail = std::move(minithumbnail); add_sticker_thumbnail(s.get(), thumbnail); if (sticker != nullptr) { s->set_id = on_get_input_sticker_set(file_id, std::move(sticker->stickerset_), load_data_multipromise_ptr); @@ -2158,14 +2168,17 @@ StickerSetId StickersManager::on_get_sticker_set(tl_object_ptrflags_ & telegram_api::stickerSet::MASKS_MASK) != 0; PhotoSize thumbnail; + string minithumbnail; if (set->thumb_ != nullptr) { auto photo_size = get_photo_size(td_->file_manager_.get(), {set_id.get(), s->access_hash}, 0, 0, "", DcId::create(set->thumb_dc_id_), DialogId(), std::move(set->thumb_), - is_animated ? PhotoFormat::Tgs : PhotoFormat::Webp); + is_animated ? PhotoFormat::Tgs : PhotoFormat::Webp, false); if (photo_size.get_offset() == 0) { - thumbnail = std::move(photo_size.get<0>()); + if (!thumbnail.file_id.is_valid()) { + thumbnail = std::move(photo_size.get<0>()); + } } else { - LOG(ERROR) << "Receive minithumbnail for a " << set_id; + minithumbnail = std::move(photo_size.get<1>()); } } if (!s->is_inited) { @@ -2173,9 +2186,10 @@ StickerSetId StickersManager::on_get_sticker_set(tl_object_ptris_inited = true; s->title = std::move(set->title_); s->short_name = std::move(set->short_name_); + s->minithumbnail = std::move(minithumbnail); s->thumbnail = std::move(thumbnail); s->is_thumbnail_reloaded = true; - s->are_legacy_thumbnails_reloaded = true; + s->are_legacy_sticker_thumbnails_reloaded = true; s->sticker_count = set->count_; s->hash = set->hash_; s->is_official = is_official; @@ -2209,15 +2223,20 @@ StickerSetId StickersManager::on_get_sticker_set(tl_object_ptris_masks].add(set_id.get(), PSLICE() << s->title << ' ' << s->short_name); } } + if (s->minithumbnail != minithumbnail) { + LOG(INFO) << "Minithumbnail of " << set_id << " has changed"; + s->minithumbnail = std::move(minithumbnail); + s->is_changed = true; + } if (s->thumbnail != thumbnail) { LOG(INFO) << "Thumbnail of " << set_id << " has changed from " << s->thumbnail << " to " << thumbnail; s->thumbnail = std::move(thumbnail); s->is_changed = true; } - if (!s->is_thumbnail_reloaded || !s->are_legacy_thumbnails_reloaded) { + if (!s->is_thumbnail_reloaded || !s->are_legacy_sticker_thumbnails_reloaded) { LOG(INFO) << "Sticker thumbnails and thumbnail of " << set_id << " was reloaded"; s->is_thumbnail_reloaded = true; - s->are_legacy_thumbnails_reloaded = true; + s->are_legacy_sticker_thumbnails_reloaded = true; s->need_save_to_database = true; } @@ -3399,7 +3418,7 @@ void StickersManager::on_load_sticker_set_from_database(StickerSetId sticker_set << format::as_hex_dump<4>(Slice(value)); } } - if (!sticker_set->is_thumbnail_reloaded || !sticker_set->are_legacy_thumbnails_reloaded) { + if (!sticker_set->is_thumbnail_reloaded || !sticker_set->are_legacy_sticker_thumbnails_reloaded) { do_reload_sticker_set(sticker_set_id, get_input_sticker_set(sticker_set), Auto()); } @@ -4290,7 +4309,7 @@ Result> StickersManager::prepare_input_file if (is_animated) { int32 width = for_thumbnail ? 100 : 512; - create_sticker(file_id, PhotoSize(), get_dimensions(width, width), nullptr, true, nullptr); + create_sticker(file_id, string(), PhotoSize(), get_dimensions(width, width), nullptr, true, nullptr); } else { td_->documents_manager_->create_document(file_id, string(), PhotoSize(), "sticker.png", "image/png", false); } diff --git a/td/telegram/StickersManager.h b/td/telegram/StickersManager.h index dc018fca7..7e4ec1254 100644 --- a/td/telegram/StickersManager.h +++ b/td/telegram/StickersManager.h @@ -69,7 +69,7 @@ class StickersManager : public Actor { void unregister_dice(const string &emoji, int32 value, FullMessageId full_message_id, const char *source); - void create_sticker(FileId file_id, PhotoSize thumbnail, Dimensions dimensions, + void create_sticker(FileId file_id, string minithumbnail, PhotoSize thumbnail, Dimensions dimensions, tl_object_ptr sticker, bool is_animated, MultiPromiseActor *load_data_multipromise_ptr); @@ -304,6 +304,7 @@ class StickersManager : public Actor { StickerSetId set_id; string alt; Dimensions dimensions; + string minithumbnail; PhotoSize s_thumbnail; PhotoSize m_thumbnail; FileId file_id; @@ -331,6 +332,7 @@ class StickersManager : public Actor { int32 hash = 0; int32 expires_at = 0; + string minithumbnail; PhotoSize thumbnail; vector sticker_ids; @@ -344,7 +346,7 @@ class StickersManager : public Actor { bool is_masks = false; bool is_viewed = true; bool is_thumbnail_reloaded = false; - bool are_legacy_thumbnails_reloaded = false; + bool are_legacy_sticker_thumbnails_reloaded = false; mutable bool was_update_sent = false; // does the sticker set is known to the client bool is_changed = true; // have new changes that need to be sent to the client and database bool need_save_to_database = true; // have new changes that need only to be saved to the database diff --git a/td/telegram/StickersManager.hpp b/td/telegram/StickersManager.hpp index a2bff4cc8..640822d33 100644 --- a/td/telegram/StickersManager.hpp +++ b/td/telegram/StickersManager.hpp @@ -25,11 +25,13 @@ void StickersManager::store_sticker(FileId file_id, bool in_sticker_set, StorerT CHECK(it != stickers_.end()); const Sticker *sticker = it->second.get(); bool has_sticker_set_access_hash = sticker->set_id.is_valid() && !in_sticker_set; + bool has_minithumbnail = !sticker->minithumbnail.empty(); BEGIN_STORE_FLAGS(); STORE_FLAG(sticker->is_mask); STORE_FLAG(has_sticker_set_access_hash); STORE_FLAG(in_sticker_set); STORE_FLAG(sticker->is_animated); + STORE_FLAG(has_minithumbnail); END_STORE_FLAGS(); if (!in_sticker_set) { store(sticker->set_id.get(), storer); @@ -50,6 +52,9 @@ void StickersManager::store_sticker(FileId file_id, bool in_sticker_set, StorerT store(sticker->y_shift, storer); store(sticker->scale, storer); } + if (has_minithumbnail) { + store(sticker->minithumbnail, storer); + } } template @@ -61,11 +66,13 @@ FileId StickersManager::parse_sticker(bool in_sticker_set, ParserT &parser) { auto sticker = make_unique(); bool has_sticker_set_access_hash; bool in_sticker_set_stored; + bool has_minithumbnail; BEGIN_PARSE_FLAGS(); PARSE_FLAG(sticker->is_mask); PARSE_FLAG(has_sticker_set_access_hash); PARSE_FLAG(in_sticker_set_stored); PARSE_FLAG(sticker->is_animated); + PARSE_FLAG(has_minithumbnail); END_PARSE_FLAGS(); if (in_sticker_set_stored != in_sticker_set) { Slice data = parser.template fetch_string_raw(parser.get_left_len()); @@ -105,6 +112,9 @@ FileId StickersManager::parse_sticker(bool in_sticker_set, ParserT &parser) { parse(sticker->y_shift, parser); parse(sticker->scale, parser); } + if (has_minithumbnail) { + parse(sticker->minithumbnail, parser); + } if (parser.get_error() != nullptr || !sticker->file_id.is_valid()) { return FileId(); } @@ -119,6 +129,7 @@ void StickersManager::store_sticker_set(const StickerSet *sticker_set, bool with bool is_loaded = sticker_set->is_loaded && is_full; bool has_expires_at = !sticker_set->is_installed && sticker_set->expires_at != 0; bool has_thumbnail = sticker_set->thumbnail.file_id.is_valid(); + bool has_minithumbnail = !sticker_set->minithumbnail.empty(); BEGIN_STORE_FLAGS(); STORE_FLAG(sticker_set->is_inited); STORE_FLAG(was_loaded); @@ -132,7 +143,8 @@ void StickersManager::store_sticker_set(const StickerSet *sticker_set, bool with STORE_FLAG(has_thumbnail); STORE_FLAG(sticker_set->is_thumbnail_reloaded); STORE_FLAG(sticker_set->is_animated); - STORE_FLAG(sticker_set->are_legacy_thumbnails_reloaded); + STORE_FLAG(sticker_set->are_legacy_sticker_thumbnails_reloaded); + STORE_FLAG(has_minithumbnail); END_STORE_FLAGS(); store(sticker_set->id.get(), storer); store(sticker_set->access_hash, storer); @@ -147,6 +159,9 @@ void StickersManager::store_sticker_set(const StickerSet *sticker_set, bool with if (has_thumbnail) { store(sticker_set->thumbnail, storer); } + if (has_minithumbnail) { + store(sticker_set->minithumbnail, storer); + } uint32 stored_sticker_count = narrow_cast(is_full ? sticker_set->sticker_ids.size() : stickers_limit); store(stored_sticker_count, storer); @@ -175,9 +190,10 @@ void StickersManager::parse_sticker_set(StickerSet *sticker_set, ParserT &parser bool is_archived; bool is_official; bool is_masks; - bool is_animated; bool has_expires_at; bool has_thumbnail; + bool is_animated; + bool has_minithumbnail; BEGIN_PARSE_FLAGS(); PARSE_FLAG(sticker_set->is_inited); PARSE_FLAG(sticker_set->was_loaded); @@ -191,7 +207,8 @@ void StickersManager::parse_sticker_set(StickerSet *sticker_set, ParserT &parser PARSE_FLAG(has_thumbnail); PARSE_FLAG(sticker_set->is_thumbnail_reloaded); PARSE_FLAG(is_animated); - PARSE_FLAG(sticker_set->are_legacy_thumbnails_reloaded); + PARSE_FLAG(sticker_set->are_legacy_sticker_thumbnails_reloaded); + PARSE_FLAG(has_minithumbnail); END_PARSE_FLAGS(); int64 sticker_set_id; int64 access_hash; @@ -206,6 +223,8 @@ void StickersManager::parse_sticker_set(StickerSet *sticker_set, ParserT &parser if (sticker_set->is_inited) { string title; string short_name; + string minithumbnail; + PhotoSize thumbnail; int32 sticker_count; int32 hash; int32 expires_at = 0; @@ -217,11 +236,17 @@ void StickersManager::parse_sticker_set(StickerSet *sticker_set, ParserT &parser parse(expires_at, parser); } if (has_thumbnail) { - parse(sticker_set->thumbnail, parser); + parse(thumbnail, parser); } + if (has_minithumbnail) { + parse(minithumbnail, parser); + } + if (!was_inited) { sticker_set->title = std::move(title); sticker_set->short_name = std::move(short_name); + sticker_set->minithumbnail = std::move(minithumbnail); + sticker_set->thumbnail = std::move(thumbnail); sticker_set->sticker_count = sticker_count; sticker_set->hash = hash; sticker_set->expires_at = expires_at; diff --git a/td/telegram/Version.h b/td/telegram/Version.h index 4a2097404..79e030266 100644 --- a/td/telegram/Version.h +++ b/td/telegram/Version.h @@ -8,7 +8,7 @@ namespace td { -constexpr int32 MTPROTO_LAYER = 120; +constexpr int32 MTPROTO_LAYER = 121; enum class Version : int32 { Initial, // 0