diff --git a/Telegram/Resources/scheme.tl b/Telegram/Resources/scheme.tl index 485fdc5fe..ebc5a5950 100644 --- a/Telegram/Resources/scheme.tl +++ b/Telegram/Resources/scheme.tl @@ -186,11 +186,11 @@ inputGeoPointEmpty#e4c123d6 = InputGeoPoint; inputGeoPoint#f3b7acc9 lat:double long:double = InputGeoPoint; inputPhotoEmpty#1cd7bf0d = InputPhoto; -inputPhoto#fb95c6c4 id:long access_hash:long = InputPhoto; +inputPhoto#3bb3b94a id:long access_hash:long file_reference:bytes = InputPhoto; -inputFileLocation#14637196 volume_id:long local_id:int secret:long = InputFileLocation; +inputFileLocation#dfdaabe1 volume_id:long local_id:int secret:long file_reference:bytes = InputFileLocation; inputEncryptedFileLocation#f5235d55 id:long access_hash:long = InputFileLocation; -inputDocumentFileLocation#430f0724 id:long access_hash:long version:int = InputFileLocation; +inputDocumentFileLocation#a9b915b0 id:long access_hash:long version:int file_reference:bytes = InputFileLocation; inputSecureFileLocation#cbc7ee28 id:long access_hash:long = InputFileLocation; inputTakeoutFileLocation#29be5899 = InputFileLocation; @@ -212,7 +212,7 @@ storage.fileMp4#b3cea0e4 = storage.FileType; storage.fileWebp#1081464c = storage.FileType; fileLocationUnavailable#7c596b46 volume_id:long local_id:int secret:long = FileLocation; -fileLocation#53d69076 dc_id:int volume_id:long local_id:int secret:long = FileLocation; +fileLocation#91d11eb dc_id:int volume_id:long local_id:int secret:long file_reference:bytes = FileLocation; userEmpty#200250ba id:int = User; user#2e13f4c3 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?string bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User; @@ -288,7 +288,7 @@ messageActionSecureValuesSent#d95c6154 types:Vector = MessageAc dialog#e4def5db flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage = Dialog; photoEmpty#2331b22d id:long = Photo; -photo#9288dd29 flags:# has_stickers:flags.0?true id:long access_hash:long date:int sizes:Vector = Photo; +photo#9c477dd8 flags:# has_stickers:flags.0?true id:long access_hash:long file_reference:bytes date:int sizes:Vector = Photo; photoSizeEmpty#e17e23c type:string = PhotoSize; photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize; @@ -505,10 +505,10 @@ messages.sentEncryptedMessage#560f8935 date:int = messages.SentEncryptedMessage; messages.sentEncryptedFile#9493ff32 date:int file:EncryptedFile = messages.SentEncryptedMessage; inputDocumentEmpty#72f0eaae = InputDocument; -inputDocument#18798952 id:long access_hash:long = InputDocument; +inputDocument#1abfb575 id:long access_hash:long file_reference:bytes = InputDocument; documentEmpty#36f8c871 id:long = Document; -document#87232bc7 id:long access_hash:long date:int mime_type:string size:int thumb:PhotoSize dc_id:int version:int attributes:Vector = Document; +document#ca84c039 id:long access_hash:long file_reference:bytes date:int mime_type:string size:int thumb:PhotoSize dc_id:int version:int attributes:Vector = Document; help.support#17c6b5f6 phone_number:string user:User = help.Support; diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 7043a7ecd..1bed0a207 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -4226,7 +4226,10 @@ void ApiWrap::uploadAlbumMedia( : MTPDinputMediaPhoto::Flag(0)); const auto media = MTP_inputMediaPhoto( MTP_flags(flags), - MTP_inputPhoto(photo.vid, photo.vaccess_hash), + MTP_inputPhoto( + photo.vid, + photo.vaccess_hash, + photo.vfile_reference), data.has_ttl_seconds() ? data.vttl_seconds : MTPint()); sendAlbumWithUploaded(item, groupId, media); } break; @@ -4244,7 +4247,10 @@ void ApiWrap::uploadAlbumMedia( : MTPDinputMediaDocument::Flag(0)); const auto media = MTP_inputMediaDocument( MTP_flags(flags), - MTP_inputDocument(document.vid, document.vaccess_hash), + MTP_inputDocument( + document.vid, + document.vaccess_hash, + document.vfile_reference), data.has_ttl_seconds() ? data.vttl_seconds : MTPint()); sendAlbumWithUploaded(item, groupId, media); } break; diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index 3bb639793..053b11bde 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -960,7 +960,16 @@ namespace App { auto &d = size.c_photoSize(); if (d.vlocation.type() == mtpc_fileLocation) { auto &l = d.vlocation.c_fileLocation(); - return ImagePtr(StorageImageLocation(d.vw.v, d.vh.v, l.vdc_id.v, l.vvolume_id.v, l.vlocal_id.v, l.vsecret.v), d.vsize.v); + return ImagePtr( + StorageImageLocation( + d.vw.v, + d.vh.v, + l.vdc_id.v, + l.vvolume_id.v, + l.vlocal_id.v, + l.vsecret.v, + l.vfile_reference.v), + d.vsize.v); } } break; case mtpc_photoCachedSize: { @@ -968,10 +977,28 @@ namespace App { if (d.vlocation.type() == mtpc_fileLocation) { auto &l = d.vlocation.c_fileLocation(); auto bytes = qba(d.vbytes); - return ImagePtr(StorageImageLocation(d.vw.v, d.vh.v, l.vdc_id.v, l.vvolume_id.v, l.vlocal_id.v, l.vsecret.v), bytes); + return ImagePtr( + StorageImageLocation( + d.vw.v, + d.vh.v, + l.vdc_id.v, + l.vvolume_id.v, + l.vlocal_id.v, + l.vsecret.v, + l.vfile_reference.v), + bytes); } else if (d.vlocation.type() == mtpc_fileLocationUnavailable) { auto bytes = qba(d.vbytes); - return ImagePtr(StorageImageLocation(d.vw.v, d.vh.v, 0, 0, 0, 0), bytes); + return ImagePtr( + StorageImageLocation( + d.vw.v, + d.vh.v, + 0, + 0, + 0, + 0, + {}), + bytes); } } break; } @@ -1154,19 +1181,6 @@ namespace App { } } - MTPPhoto photoFromUserPhoto(MTPint userId, MTPint date, const MTPUserProfilePhoto &photo) { - if (photo.type() == mtpc_userProfilePhoto) { - const auto &uphoto(photo.c_userProfilePhoto()); - - QVector photoSizes; - photoSizes.push_back(MTP_photoSize(MTP_string("a"), uphoto.vphoto_small, MTP_int(160), MTP_int(160), MTP_int(0))); - photoSizes.push_back(MTP_photoSize(MTP_string("c"), uphoto.vphoto_big, MTP_int(640), MTP_int(640), MTP_int(0))); - - return MTP_photo(MTP_flags(0), uphoto.vphoto_id, MTP_long(0), date, MTP_vector(photoSizes)); - } - return MTP_photoEmpty(MTP_long(0)); - } - QString peerName(const PeerData *peer, bool forDialogs) { return peer ? ((forDialogs && peer->isUser() && !peer->asUser()->nameOrPhone.isEmpty()) ? peer->asUser()->nameOrPhone : peer->name) : lang(lng_deleted); } diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h index 9c0827b6d..0f4414b78 100644 --- a/Telegram/SourceFiles/app.h +++ b/Telegram/SourceFiles/app.h @@ -143,8 +143,6 @@ namespace App { LocationData *location(const LocationCoords &coords); void forgetMedia(); - MTPPhoto photoFromUserPhoto(MTPint userId, MTPint date, const MTPUserProfilePhoto &photo); - Histories &histories(); not_null history(const PeerId &peer); History *historyLoaded(const PeerId &peer); diff --git a/Telegram/SourceFiles/core/update_checker.cpp b/Telegram/SourceFiles/core/update_checker.cpp index 6b4a32439..8972af2b8 100644 --- a/Telegram/SourceFiles/core/update_checker.cpp +++ b/Telegram/SourceFiles/core/update_checker.cpp @@ -1467,7 +1467,8 @@ auto MtpChecker::parseFile(const MTPmessages_Messages &result) const const auto location = MTP_inputDocumentFileLocation( fields.vid, fields.vaccess_hash, - fields.vversion); + fields.vversion, + fields.vfile_reference); return ParsedFile { name, size, fields.vdc_id.v, location }; } diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp index 4658efcd1..ff0708862 100644 --- a/Telegram/SourceFiles/data/data_document.cpp +++ b/Telegram/SourceFiles/data/data_document.cpp @@ -752,11 +752,30 @@ void DocumentData::save( } else { status = FileReady; if (hasWebLocation()) { - _loader = new mtpFileLoader(&_urlLocation, size, fromCloud, autoLoading); + _loader = new mtpFileLoader( + &_urlLocation, + size, + fromCloud, + autoLoading); } else if (!_access && !_url.isEmpty()) { - _loader = new webFileLoader(_url, toFile, fromCloud, autoLoading); + _loader = new webFileLoader( + _url, + toFile, + fromCloud, + autoLoading); } else { - _loader = new mtpFileLoader(_dc, id, _access, _version, locationType(), toFile, size, (saveToCache() ? LoadToCacheAsWell : LoadToFileOnly), fromCloud, autoLoading); + _loader = new mtpFileLoader( + _dc, + id, + _access, + _version, + _fileReference, + locationType(), + toFile, + size, + (saveToCache() ? LoadToCacheAsWell : LoadToFileOnly), + fromCloud, + autoLoading); } _loader->connect(_loader, SIGNAL(progress(FileLoader*)), App::main(), SLOT(documentLoadProgress(FileLoader*))); @@ -984,7 +1003,8 @@ MTPInputDocument DocumentData::mtpInput() const { if (_access) { return MTP_inputDocument( MTP_long(id), - MTP_long(_access)); + MTP_long(_access), + MTP_bytes(_fileReference)); } return MTP_inputDocumentEmpty(); } @@ -1114,7 +1134,11 @@ bool DocumentData::setRemoteVersion(int32 version) { return true; } -void DocumentData::setRemoteLocation(int32 dc, uint64 access) { +void DocumentData::setRemoteLocation( + int32 dc, + uint64 access, + const QByteArray &fileReference) { + _fileReference = fileReference; if (_dc != dc || _access != access) { _dc = dc; _access = access; diff --git a/Telegram/SourceFiles/data/data_document.h b/Telegram/SourceFiles/data/data_document.h index dad17dd43..0b418421c 100644 --- a/Telegram/SourceFiles/data/data_document.h +++ b/Telegram/SourceFiles/data/data_document.h @@ -148,7 +148,10 @@ public: bool hasGoodStickerThumb() const; bool setRemoteVersion(int32 version); // Returns true if version has changed. - void setRemoteLocation(int32 dc, uint64 access); + void setRemoteLocation( + int32 dc, + uint64 access, + const QByteArray &fileReference); void setContentUrl(const QString &url); void setWebLocation(const WebFileLocation &location); bool hasRemoteLocation() const; @@ -198,6 +201,7 @@ private: // Two types of location: from MTProto by dc+access+version or from web by url int32 _dc = 0; uint64 _access = 0; + QByteArray _fileReference; int32 _version = 0; QString _url; QString _filename; diff --git a/Telegram/SourceFiles/data/data_photo.cpp b/Telegram/SourceFiles/data/data_photo.cpp index 6ac365fba..9fa2fe13f 100644 --- a/Telegram/SourceFiles/data/data_photo.cpp +++ b/Telegram/SourceFiles/data/data_photo.cpp @@ -13,7 +13,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "auth_session.h" #include "messenger.h" -PhotoData::PhotoData(const PhotoId &id, const uint64 &access, int32 date, const ImagePtr &thumb, const ImagePtr &medium, const ImagePtr &full) +PhotoData::PhotoData(const PhotoId &id) +: id(id) { +} + +PhotoData::PhotoData( + const PhotoId &id, + const uint64 &access, + const QByteArray &fileReference, + TimeId date, + const ImagePtr &thumb, + const ImagePtr &medium, + const ImagePtr &full) : id(id) , access(access) , date(date) @@ -110,6 +121,13 @@ ImagePtr PhotoData::makeReplyPreview() { return replyPreview; } +MTPInputPhoto PhotoData::mtpInput() const { + return MTP_inputPhoto( + MTP_long(id), + MTP_long(access), + MTP_bytes(fileReference)); +} + void PhotoOpenClickHandler::onClickImpl() const { Messenger::Instance().showPhoto(this); } diff --git a/Telegram/SourceFiles/data/data_photo.h b/Telegram/SourceFiles/data/data_photo.h index 150f46941..45378b1cd 100644 --- a/Telegram/SourceFiles/data/data_photo.h +++ b/Telegram/SourceFiles/data/data_photo.h @@ -11,13 +11,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL class PhotoData { public: + explicit PhotoData(const PhotoId &id); PhotoData( const PhotoId &id, - const uint64 &access = 0, - int32 date = 0, - const ImagePtr &thumb = ImagePtr(), - const ImagePtr &medium = ImagePtr(), - const ImagePtr &full = ImagePtr()); + const uint64 &access, + const QByteArray &fileReference, + TimeId date, + const ImagePtr &thumb, + const ImagePtr &medium, + const ImagePtr &full); void automaticLoad(const HistoryItem *item); void automaticLoadSettingsChanged(); @@ -37,9 +39,12 @@ public: void forget(); ImagePtr makeReplyPreview(); - PhotoId id; - uint64 access; - int32 date; + MTPInputPhoto mtpInput() const; + + PhotoId id = 0; + uint64 access = 0; + QByteArray fileReference; + TimeId date = 0; ImagePtr thumb, replyPreview; ImagePtr medium; ImagePtr full; diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index a594ae838..442004c11 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -799,6 +799,7 @@ not_null Session::photo( return photo( data.c_photo().vid.v, data.c_photo().vaccess_hash.v, + data.c_photo().vfile_reference.v, data.c_photo().vdate.v, ImagePtr(*thumb, "JPG"), ImagePtr(*medium, "JPG"), @@ -813,6 +814,7 @@ not_null Session::photo( not_null Session::photo( PhotoId id, const uint64 &access, + const QByteArray &fileReference, TimeId date, const ImagePtr &thumb, const ImagePtr &medium, @@ -821,6 +823,7 @@ not_null Session::photo( photoApplyFields( result, access, + fileReference, date, thumb, medium, @@ -878,6 +881,7 @@ PhotoData *Session::photoFromWeb( return photo( rand_value(), uint64(0), + QByteArray(), unixtime(), thumb, medium, @@ -941,6 +945,7 @@ void Session::photoApplyFields( photoApplyFields( photo, data.vaccess_hash.v, + data.vfile_reference.v, data.vdate.v, App::image(*thumb), App::image(*medium), @@ -951,6 +956,7 @@ void Session::photoApplyFields( void Session::photoApplyFields( not_null photo, const uint64 &access, + const QByteArray &fileReference, TimeId date, const ImagePtr &thumb, const ImagePtr &medium, @@ -959,6 +965,7 @@ void Session::photoApplyFields( return; } photo->access = access; + photo->fileReference = fileReference; photo->date = date; UpdateImage(photo->thumb, thumb); UpdateImage(photo->medium, medium); @@ -1005,6 +1012,7 @@ not_null Session::document( fields.vid.v, fields.vaccess_hash.v, fields.vversion.v, + fields.vfile_reference.v, fields.vdate.v, fields.vattributes.v, qs(fields.vmime_type), @@ -1021,6 +1029,7 @@ not_null Session::document( DocumentId id, const uint64 &access, int32 version, + const QByteArray &fileReference, TimeId date, const QVector &attributes, const QString &mime, @@ -1033,6 +1042,7 @@ not_null Session::document( result, access, version, + fileReference, date, attributes, mime, @@ -1111,6 +1121,7 @@ DocumentData *Session::documentFromWeb( rand_value(), uint64(0), int32(0), + QByteArray(), unixtime(), data.vattributes.v, data.vmime_type.v, @@ -1132,6 +1143,7 @@ DocumentData *Session::documentFromWeb( rand_value(), uint64(0), int32(0), + QByteArray(), unixtime(), data.vattributes.v, data.vmime_type.v, @@ -1158,6 +1170,7 @@ void Session::documentApplyFields( document, data.vaccess_hash.v, data.vversion.v, + data.vfile_reference.v, data.vdate.v, data.vattributes.v, qs(data.vmime_type), @@ -1171,6 +1184,7 @@ void Session::documentApplyFields( not_null document, const uint64 &access, int32 version, + const QByteArray &fileReference, TimeId date, const QVector &attributes, const QString &mime, @@ -1184,7 +1198,7 @@ void Session::documentApplyFields( document->setattributes(attributes); document->setRemoteVersion(version); if (dc != 0 && access != 0) { - document->setRemoteLocation(dc, access); + document->setRemoteLocation(dc, access, fileReference); } document->date = date; document->setMimeString(mime); diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index 98d57450a..374598e20 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -250,6 +250,7 @@ public: not_null photo( PhotoId id, const uint64 &access, + const QByteArray &fileReference, TimeId date, const ImagePtr &thumb, const ImagePtr &medium, @@ -269,6 +270,7 @@ public: DocumentId id, const uint64 &access, int32 version, + const QByteArray &fileReference, TimeId date, const QVector &attributes, const QString &mime, @@ -435,6 +437,7 @@ private: void photoApplyFields( not_null photo, const uint64 &access, + const QByteArray &fileReference, TimeId date, const ImagePtr &thumb, const ImagePtr &medium, @@ -450,6 +453,7 @@ private: not_null document, const uint64 &access, int32 version, + const QByteArray &fileReference, TimeId date, const QVector &attributes, const QString &mime, diff --git a/Telegram/SourceFiles/export/data/export_data_types.cpp b/Telegram/SourceFiles/export/data/export_data_types.cpp index 5dcc89b60..ab5ba25bf 100644 --- a/Telegram/SourceFiles/export/data/export_data_types.cpp +++ b/Telegram/SourceFiles/export/data/export_data_types.cpp @@ -193,7 +193,8 @@ FileLocation ParseLocation(const MTPFileLocation &data) { MTP_inputFileLocation( data.vvolume_id, data.vlocal_id, - data.vsecret) + data.vsecret, + data.vfile_reference) }; }, [](const MTPDfileLocationUnavailable &data) { return FileLocation{ @@ -201,7 +202,8 @@ FileLocation ParseLocation(const MTPFileLocation &data) { MTP_inputFileLocation( data.vvolume_id, data.vlocal_id, - data.vsecret) + data.vsecret, + MTP_bytes(QByteArray())) }; }); } @@ -397,7 +399,8 @@ Document ParseDocument( result.file.location.data = MTP_inputDocumentFileLocation( data.vid, data.vaccess_hash, - data.vversion); + data.vversion, + data.vfile_reference); const auto path = result.file.suggestedPath = suggestedFolder + DocumentFolder(result) + '/' + CleanDocumentName(ComputeDocumentName(context, result)); diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp index 5fcd21144..812bf59d5 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp @@ -105,12 +105,27 @@ TextWithEntities ExtractEditedText(const MTPMessage &message) { return { text, entities }; } -PhotoData *GenerateChatPhoto(ChannelId channelId, uint64 logEntryId, TimeId date, const MTPDchatPhoto &photo) { +PhotoData *GenerateChatPhoto( + ChannelId channelId, + uint64 logEntryId, + TimeId date, + const MTPDchatPhoto &photo) { // We try to make a unique photoId that will stay the same for each pair (channelId, logEntryId). static const auto RandomIdPart = rand_value(); auto mixinIdPart = (static_cast(static_cast(channelId)) << 32) ^ logEntryId; auto photoId = RandomIdPart ^ mixinIdPart; + const auto fileReference = [&]() -> const MTPbytes * { + const auto takeFrom = [](const MTPFileLocation &location) { + return (location.type() == mtpc_fileLocation) + ? &location.c_fileLocation().vfile_reference + : nullptr; + }; + if (const auto result = takeFrom(photo.vphoto_big)) { + return result; + } + return takeFrom(photo.vphoto_small); + }(); auto photoSizes = QVector(); photoSizes.reserve(2); photoSizes.push_back(MTP_photoSize(MTP_string("a"), photo.vphoto_small, MTP_int(160), MTP_int(160), MTP_int(0))); @@ -119,6 +134,7 @@ PhotoData *GenerateChatPhoto(ChannelId channelId, uint64 logEntryId, TimeId date MTP_flags(0), MTP_long(photoId), MTP_long(0), + fileReference ? (*fileReference) : MTP_bytes(QByteArray()), MTP_int(date), MTP_vector(photoSizes))); } diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index be6e79eea..3f1a32075 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -3101,7 +3101,16 @@ void HistoryWidget::onBotStart() { sendBotCommand(_peer, _peer->asUser(), qsl("/start"), 0); } else { uint64 randomId = rand_value(); - MTP::send(MTPmessages_StartBot(_peer->asUser()->inputUser, MTP_inputPeerEmpty(), MTP_long(randomId), MTP_string(token)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::addParticipantFail, { _peer->asUser(), (PeerData*)nullptr })); + MTP::send( + MTPmessages_StartBot( + _peer->asUser()->inputUser, + MTP_inputPeerEmpty(), + MTP_long(randomId), + MTP_string(token)), + App::main()->rpcDone(&MainWidget::sentUpdatesReceived), + App::main()->rpcFail( + &MainWidget::addParticipantFail, + { _peer->asUser(), (PeerData*)nullptr })); _peer->asUser()->botInfo->startToken = QString(); if (_keyboard->hasMarkup()) { @@ -5754,7 +5763,7 @@ void HistoryWidget::sendExistingPhoto( MTP_int(options.replyTo), MTP_inputMediaPhoto( MTP_flags(0), - MTP_inputPhoto(MTP_long(photo->id), MTP_long(photo->access)), + photo->mtpInput(), MTPint()), MTP_string(caption.text), MTP_long(randomId), diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 71e65e9c1..9a466259a 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -970,8 +970,11 @@ void MainWidget::deletePhotoLayer(PhotoData *photo) { } else if (photo->peer && !photo->peer->isUser() && photo->peer->userpicPhotoId() == photo->id) { Messenger::Instance().peerClearPhoto(photo->peer->id); } else { - MTP::send(MTPphotos_DeletePhotos(MTP_vector(1, MTP_inputPhoto(MTP_long(photo->id), MTP_long(photo->access))))); - Auth().storage().remove(Storage::UserPhotosRemoveOne(me->bareId(), photo->id)); + MTP::send(MTPphotos_DeletePhotos( + MTP_vector(1, photo->mtpInput()))); + Auth().storage().remove(Storage::UserPhotosRemoveOne( + me->bareId(), + photo->id)); } }))); } diff --git a/Telegram/SourceFiles/messenger.cpp b/Telegram/SourceFiles/messenger.cpp index 654ac2332..ae6b25f7b 100644 --- a/Telegram/SourceFiles/messenger.cpp +++ b/Telegram/SourceFiles/messenger.cpp @@ -1017,7 +1017,13 @@ void Messenger::uploadProfilePhoto(QImage &&tosend, const PeerId &peerId) { PhotoId id = rand_value(); - auto photo = MTP_photo(MTP_flags(0), MTP_long(id), MTP_long(0), MTP_int(unixtime()), MTP_vector(photoSizes)); + auto photo = MTP_photo( + MTP_flags(0), + MTP_long(id), + MTP_long(0), + MTP_bytes(QByteArray()), + MTP_int(unixtime()), + MTP_vector(photoSizes)); QString file, filename; int32 filesize = 0; diff --git a/Telegram/SourceFiles/passport/passport_form_controller.cpp b/Telegram/SourceFiles/passport/passport_form_controller.cpp index d43e2dd61..7eec460ef 100644 --- a/Telegram/SourceFiles/passport/passport_form_controller.cpp +++ b/Telegram/SourceFiles/passport/passport_form_controller.cpp @@ -1705,7 +1705,8 @@ void FormController::loadFile(File &file) { file.dcId, file.id, file.accessHash, - 0, + 0, // version + QByteArray(), // file_reference SecureFileLocation, QString(), file.size, diff --git a/Telegram/SourceFiles/storage/file_download.cpp b/Telegram/SourceFiles/storage/file_download.cpp index 4953693ea..252764d9a 100644 --- a/Telegram/SourceFiles/storage/file_download.cpp +++ b/Telegram/SourceFiles/storage/file_download.cpp @@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/localstorage.h" #include "platform/platform_file_utilities.h" #include "auth_session.h" +#include "apiwrap.h" #include "core/crash_reports.h" #include "base/bytes.h" #include "base/openssl_help.h" @@ -392,8 +393,18 @@ void FileLoader::startLoading(bool loadFirst, bool prior) { loadPart(); } -mtpFileLoader::mtpFileLoader(const StorageImageLocation *location, int32 size, LoadFromCloudSetting fromCloud, bool autoLoading) -: FileLoader(QString(), size, UnknownFileLocation, LoadToCacheAsWell, fromCloud, autoLoading) +mtpFileLoader::mtpFileLoader( + const StorageImageLocation *location, + int32 size, + LoadFromCloudSetting fromCloud + , bool autoLoading) +: FileLoader( + QString(), + size, + UnknownFileLocation, + LoadToCacheAsWell, + fromCloud, + autoLoading) , _dcId(location->dc()) , _location(location) { auto shiftedDcId = MTP::downloadDcId(_dcId, 0); @@ -404,12 +415,30 @@ mtpFileLoader::mtpFileLoader(const StorageImageLocation *location, int32 size, L _queue = &i.value(); } -mtpFileLoader::mtpFileLoader(int32 dc, uint64 id, uint64 accessHash, int32 version, LocationType type, const QString &to, int32 size, LoadToCacheSetting toCache, LoadFromCloudSetting fromCloud, bool autoLoading) -: FileLoader(to, size, type, toCache, fromCloud, autoLoading) +mtpFileLoader::mtpFileLoader( + int32 dc, + uint64 id, + uint64 accessHash, + int32 version, + const QByteArray &fileReference, + LocationType type, + const QString &to, + int32 size, + LoadToCacheSetting toCache, + LoadFromCloudSetting fromCloud, + bool autoLoading) +: FileLoader( + to, + size, + type, + toCache, + fromCloud, + autoLoading) , _dcId(dc) , _id(id) , _accessHash(accessHash) -, _version(version) { +, _version(version) +, _fileReference(fileReference) { auto shiftedDcId = MTP::downloadDcId(_dcId, 0); auto i = queues.find(shiftedDcId); if (i == queues.cend()) { @@ -418,8 +447,18 @@ mtpFileLoader::mtpFileLoader(int32 dc, uint64 id, uint64 accessHash, int32 versi _queue = &i.value(); } -mtpFileLoader::mtpFileLoader(const WebFileLocation *location, int32 size, LoadFromCloudSetting fromCloud, bool autoLoading) -: FileLoader(QString(), size, UnknownFileLocation, LoadToCacheAsWell, fromCloud, autoLoading) +mtpFileLoader::mtpFileLoader( + const WebFileLocation *location, + int32 size, + LoadFromCloudSetting fromCloud, + bool autoLoading) +: FileLoader( + QString(), + size, + UnknownFileLocation, + LoadToCacheAsWell, + fromCloud, + autoLoading) , _dcId(location->dc()) , _urlLocation(location) { auto shiftedDcId = MTP::downloadDcId(_dcId, 0); @@ -480,13 +519,39 @@ void mtpFileLoader::makeRequest(int offset) { auto shiftedDcId = MTP::downloadDcId(requestData.dcId, requestData.dcIndex); if (_cdnDcId) { Assert(requestData.dcId == _cdnDcId); - return MTP::send(MTPupload_GetCdnFile(MTP_bytes(_cdnToken), MTP_int(offset), MTP_int(limit)), rpcDone(&mtpFileLoader::cdnPartLoaded), rpcFail(&mtpFileLoader::cdnPartFailed), shiftedDcId, 50); + return MTP::send( + MTPupload_GetCdnFile( + MTP_bytes(_cdnToken), + MTP_int(offset), + MTP_int(limit)), + rpcDone(&mtpFileLoader::cdnPartLoaded), + rpcFail(&mtpFileLoader::cdnPartFailed), + shiftedDcId, + 50); } else if (_urlLocation) { Assert(requestData.dcId == _dcId); - return MTP::send(MTPupload_GetWebFile(MTP_inputWebFileLocation(MTP_bytes(_urlLocation->url()), MTP_long(_urlLocation->accessHash())), MTP_int(offset), MTP_int(limit)), rpcDone(&mtpFileLoader::webPartLoaded), rpcFail(&mtpFileLoader::partFailed), shiftedDcId, 50); + return MTP::send( + MTPupload_GetWebFile( + MTP_inputWebFileLocation( + MTP_bytes(_urlLocation->url()), + MTP_long(_urlLocation->accessHash())), + MTP_int(offset), + MTP_int(limit)), + rpcDone(&mtpFileLoader::webPartLoaded), + rpcFail(&mtpFileLoader::partFailed), + shiftedDcId, + 50); } else { Assert(requestData.dcId == _dcId); - return MTP::send(MTPupload_GetFile(computeLocation(), MTP_int(offset), MTP_int(limit)), rpcDone(&mtpFileLoader::normalPartLoaded), rpcFail(&mtpFileLoader::partFailed), shiftedDcId, 50); + return MTP::send( + MTPupload_GetFile( + computeLocation(), + MTP_int(offset), + MTP_int(limit)), + rpcDone(&mtpFileLoader::normalPartLoaded), + rpcFail(&mtpFileLoader::partFailed), + shiftedDcId, + 50); } }; placeSentRequest(send(), requestData); @@ -494,11 +559,21 @@ void mtpFileLoader::makeRequest(int offset) { MTPInputFileLocation mtpFileLoader::computeLocation() const { if (_location) { - return MTP_inputFileLocation(MTP_long(_location->volume()), MTP_int(_location->local()), MTP_long(_location->secret())); + return MTP_inputFileLocation( + MTP_long(_location->volume()), + MTP_int(_location->local()), + MTP_long(_location->secret()), + MTP_bytes(_location->fileReference())); } else if (_locationType == SecureFileLocation) { - return MTP_inputSecureFileLocation(MTP_long(_id), MTP_long(_accessHash)); + return MTP_inputSecureFileLocation( + MTP_long(_id), + MTP_long(_accessHash)); } - return MTP_inputDocumentFileLocation(MTP_long(_id), MTP_long(_accessHash), MTP_int(_version)); + return MTP_inputDocumentFileLocation( + MTP_long(_id), + MTP_long(_accessHash), + MTP_int(_version), + MTP_bytes(_fileReference)); } void mtpFileLoader::requestMoreCdnFileHashes() { @@ -524,7 +599,9 @@ void mtpFileLoader::requestMoreCdnFileHashes() { placeSentRequest(requestId, requestData); } -void mtpFileLoader::normalPartLoaded(const MTPupload_File &result, mtpRequestId requestId) { +void mtpFileLoader::normalPartLoaded( + const MTPupload_File &result, + mtpRequestId requestId) { Expects(!_finished); Expects(result.type() == mtpc_upload_fileCdnRedirect || result.type() == mtpc_upload_file); @@ -536,7 +613,9 @@ void mtpFileLoader::normalPartLoaded(const MTPupload_File &result, mtpRequestId return partLoaded(offset, buffer); } -void mtpFileLoader::webPartLoaded(const MTPupload_WebFile &result, mtpRequestId requestId) { +void mtpFileLoader::webPartLoaded( + const MTPupload_WebFile &result, + mtpRequestId requestId) { Expects(result.type() == mtpc_upload_webFile); auto offset = finishSentRequestGetOffset(requestId); @@ -799,25 +878,39 @@ void mtpFileLoader::partLoaded(int offset, bytes::const_span buffer) { } } -bool mtpFileLoader::partFailed(const RPCError &error) { - if (MTP::isDefaultHandledError(error)) return false; - +bool mtpFileLoader::partFailed( + const RPCError &error, + mtpRequestId requestId) { + if (MTP::isDefaultHandledError(error)) { + return false; + } cancel(true); return true; } -bool mtpFileLoader::cdnPartFailed(const RPCError &error, mtpRequestId requestId) { - if (MTP::isDefaultHandledError(error)) return false; +bool mtpFileLoader::cdnPartFailed( + const RPCError &error, + mtpRequestId requestId) { + if (MTP::isDefaultHandledError(error)) { + return false; + } if (requestId == _cdnHashesRequestId) { _cdnHashesRequestId = 0; } - if (error.type() == qstr("FILE_TOKEN_INVALID") || error.type() == qstr("REQUEST_TOKEN_INVALID")) { + if (error.type() == qstr("FILE_TOKEN_INVALID") + || error.type() == qstr("REQUEST_TOKEN_INVALID")) { auto offset = finishSentRequestGetOffset(requestId); - changeCDNParams(offset, 0, QByteArray(), QByteArray(), QByteArray(), QVector()); + changeCDNParams( + offset, + 0, + QByteArray(), + QByteArray(), + QByteArray(), + QVector()); return true; } - return partFailed(error); + return partFailed(error, requestId); } void mtpFileLoader::cancelRequests() { @@ -850,8 +943,16 @@ void mtpFileLoader::addCdnHashes(const QVector &hashes) { } } -void mtpFileLoader::changeCDNParams(int offset, MTP::DcId dcId, const QByteArray &token, const QByteArray &encryptionKey, const QByteArray &encryptionIV, const QVector &hashes) { - if (dcId != 0 && (encryptionKey.size() != MTP::CTRState::KeySize || encryptionIV.size() != MTP::CTRState::IvecSize)) { +void mtpFileLoader::changeCDNParams( + int offset, + MTP::DcId dcId, + const QByteArray &token, + const QByteArray &encryptionKey, + const QByteArray &encryptionIV, + const QVector &hashes) { + if (dcId != 0 + && (encryptionKey.size() != MTP::CTRState::KeySize + || encryptionIV.size() != MTP::CTRState::IvecSize)) { LOG(("Message Error: Wrong key (%1) / iv (%2) size in CDN params").arg(encryptionKey.size()).arg(encryptionIV.size())); cancel(true); return; diff --git a/Telegram/SourceFiles/storage/file_download.h b/Telegram/SourceFiles/storage/file_download.h index 5c6673f6b..810d320d8 100644 --- a/Telegram/SourceFiles/storage/file_download.h +++ b/Telegram/SourceFiles/storage/file_download.h @@ -181,9 +181,28 @@ class mtpFileLoader : public FileLoader, public RPCSender { Q_OBJECT public: - mtpFileLoader(const StorageImageLocation *location, int32 size, LoadFromCloudSetting fromCloud, bool autoLoading); - mtpFileLoader(int32 dc, uint64 id, uint64 accessHash, int32 version, LocationType type, const QString &toFile, int32 size, LoadToCacheSetting toCache, LoadFromCloudSetting fromCloud, bool autoLoading); - mtpFileLoader(const WebFileLocation *location, int32 size, LoadFromCloudSetting fromCloud, bool autoLoading); + mtpFileLoader( + const StorageImageLocation *location, + int32 size, + LoadFromCloudSetting fromCloud, + bool autoLoading); + mtpFileLoader( + int32 dc, + uint64 id, + uint64 accessHash, + int32 version, + const QByteArray &fileReference, + LocationType type, + const QString &toFile, + int32 size, + LoadToCacheSetting toCache, + LoadFromCloudSetting fromCloud, + bool autoLoading); + mtpFileLoader( + const WebFileLocation *location, + int32 size, + LoadFromCloudSetting fromCloud, + bool autoLoading); int32 currentOffset(bool includeSkipped = false) const override; @@ -229,7 +248,7 @@ private: bool feedPart(int offset, bytes::const_span buffer); void partLoaded(int offset, bytes::const_span buffer); - bool partFailed(const RPCError &error); + bool partFailed(const RPCError &error, mtpRequestId requestId); bool cdnPartFailed(const RPCError &error, mtpRequestId requestId); void placeSentRequest(mtpRequestId requestId, const RequestData &requestData); @@ -257,6 +276,7 @@ private: uint64 _id = 0; // for document locations uint64 _accessHash = 0; int32 _version = 0; + QByteArray _fileReference; const WebFileLocation *_urlLocation = nullptr; // for webdocument locations diff --git a/Telegram/SourceFiles/storage/localimageloader.cpp b/Telegram/SourceFiles/storage/localimageloader.cpp index d1e32e240..867de671e 100644 --- a/Telegram/SourceFiles/storage/localimageloader.cpp +++ b/Telegram/SourceFiles/storage/localimageloader.cpp @@ -560,7 +560,13 @@ void FileLoadTask::process() { full.save(&buffer, "JPG", 87); } - photo = MTP_photo(MTP_flags(0), MTP_long(_id), MTP_long(0), MTP_int(unixtime()), MTP_vector(photoSizes)); + photo = MTP_photo( + MTP_flags(0), + MTP_long(_id), + MTP_long(0), + MTP_bytes(QByteArray()), + MTP_int(unixtime()), + MTP_vector(photoSizes)); if (filesize < 0) { filesize = _result->filesize = filedata.size(); @@ -603,9 +609,29 @@ void FileLoadTask::process() { auto flags = MTPDdocumentAttributeAudio::Flag::f_voice | MTPDdocumentAttributeAudio::Flag::f_waveform; attributes[0] = MTP_documentAttributeAudio(MTP_flags(flags), MTP_int(_duration), MTPstring(), MTPstring(), MTP_bytes(documentWaveformEncode5bit(_waveform))); attributes.resize(1); - document = MTP_document(MTP_long(_id), MTP_long(0), MTP_int(unixtime()), MTP_string(filemime), MTP_int(filesize), thumbSize, MTP_int(MTP::maindc()), MTP_int(0), MTP_vector(attributes)); + document = MTP_document( + MTP_long(_id), + MTP_long(0), + MTP_bytes(QByteArray()), + MTP_int(unixtime()), + MTP_string(filemime), + MTP_int(filesize), + thumbSize, + MTP_int(MTP::maindc()), + MTP_int(0), + MTP_vector(attributes)); } else if (_type != SendMediaType::Photo) { - document = MTP_document(MTP_long(_id), MTP_long(0), MTP_int(unixtime()), MTP_string(filemime), MTP_int(filesize), thumbSize, MTP_int(MTP::maindc()), MTP_int(0), MTP_vector(attributes)); + document = MTP_document( + MTP_long(_id), + MTP_long(0), + MTP_bytes(QByteArray()), + MTP_int(unixtime()), + MTP_string(filemime), + MTP_int(filesize), + thumbSize, + MTP_int(MTP::maindc()), + MTP_int(0), + MTP_vector(attributes)); _type = SendMediaType::File; } diff --git a/Telegram/SourceFiles/storage/localstorage.cpp b/Telegram/SourceFiles/storage/localstorage.cpp index 1072e4d63..448e2ac12 100644 --- a/Telegram/SourceFiles/storage/localstorage.cpp +++ b/Telegram/SourceFiles/storage/localstorage.cpp @@ -3950,6 +3950,7 @@ void importOldRecentStickers() { id, access, int32(0), + QByteArray(), date, attributes, mime, @@ -4419,8 +4420,10 @@ bool copyThemeColorsToPalette(const QString &path) { return Window::Theme::CopyColorsToPalette(path, themeContent); } -uint32 _peerSize(PeerData *peer) { - uint32 result = sizeof(quint64) + sizeof(quint64) + Serialize::storageImageLocationSize(); +uint32 _peerSize(not_null peer) { + uint32 result = sizeof(quint64) + + sizeof(quint64) + + Serialize::storageImageLocationSize(peer->userpicLocation()); if (peer->isUser()) { UserData *user = peer->asUser(); @@ -4501,11 +4504,13 @@ void _writePeer(QDataStream &stream, PeerData *peer) { } } -PeerData *_readPeer(FileReadDescriptor &from, int32 fileVersion = 0) { +PeerData *_readPeer(int streamAppVersion, QDataStream &stream) { quint64 peerId = 0, photoId = 0; - from.stream >> peerId >> photoId; + stream >> peerId >> photoId; - auto photoLoc = Serialize::readStorageImageLocation(from.stream); + auto photoLoc = Serialize::readStorageImageLocation( + streamAppVersion, + stream); PeerData *result = App::peerLoaded(peerId); bool wasLoaded = (result != nullptr); @@ -4517,14 +4522,14 @@ PeerData *_readPeer(FileReadDescriptor &from, int32 fileVersion = 0) { QString first, last, phone, username, inlinePlaceholder; quint64 access; qint32 flags = 0, onlineTill, contact, botInfoVersion; - from.stream >> first >> last >> phone >> username >> access; - if (from.version >= 9012) { - from.stream >> flags; + stream >> first >> last >> phone >> username >> access; + if (streamAppVersion >= 9012) { + stream >> flags; } - if (from.version >= 9016 || fileVersion >= 9016) { - from.stream >> inlinePlaceholder; + if (streamAppVersion >= 9016) { + stream >> inlinePlaceholder; } - from.stream >> onlineTill >> contact >> botInfoVersion; + stream >> onlineTill >> contact >> botInfoVersion; const auto showPhone = !isServiceUser(user->id) && (user->id != Auth().userPeerId()) @@ -4562,9 +4567,9 @@ PeerData *_readPeer(FileReadDescriptor &from, int32 fileVersion = 0) { QString name, inviteLink; qint32 count, date, version, creator, oldForbidden; quint32 flagsData, flags; - from.stream >> name >> count >> date >> version >> creator >> oldForbidden >> flagsData >> inviteLink; + stream >> name >> count >> date >> version >> creator >> oldForbidden >> flagsData >> inviteLink; - if (from.version >= 9012) { + if (streamAppVersion >= 9012) { flags = flagsData; } else { // flagsData was haveLeft @@ -4592,7 +4597,7 @@ PeerData *_readPeer(FileReadDescriptor &from, int32 fileVersion = 0) { quint64 access; qint32 date, version, oldForbidden; quint32 flags; - from.stream >> name >> access >> date >> version >> oldForbidden >> flags >> inviteLink; + stream >> name >> access >> date >> version >> oldForbidden >> flags >> inviteLink; if (oldForbidden) { flags |= quint32(MTPDchannel_ClientFlag::f_forbidden); } @@ -4637,32 +4642,32 @@ void writeRecentHashtagsAndBots() { _writeMap(WriteMapWhen::Fast); } quint32 size = sizeof(quint32) * 3, writeCnt = 0, searchCnt = 0, botsCnt = cRecentInlineBots().size(); - for (RecentHashtagPack::const_iterator i = write.cbegin(), e = write.cend(); i != e; ++i) { + for (auto i = write.cbegin(), e = write.cend(); i != e; ++i) { if (!i->first.isEmpty()) { size += Serialize::stringSize(i->first) + sizeof(quint16); ++writeCnt; } } - for (RecentHashtagPack::const_iterator i = search.cbegin(), e = search.cend(); i != e; ++i) { + for (auto i = search.cbegin(), e = search.cend(); i != e; ++i) { if (!i->first.isEmpty()) { size += Serialize::stringSize(i->first) + sizeof(quint16); ++searchCnt; } } - for (RecentInlineBots::const_iterator i = bots.cbegin(), e = bots.cend(); i != e; ++i) { + for (auto i = bots.cbegin(), e = bots.cend(); i != e; ++i) { size += _peerSize(*i); } EncryptedDescriptor data(size); data.stream << quint32(writeCnt) << quint32(searchCnt); - for (RecentHashtagPack::const_iterator i = write.cbegin(), e = write.cend(); i != e; ++i) { + for (auto i = write.cbegin(), e = write.cend(); i != e; ++i) { if (!i->first.isEmpty()) data.stream << i->first << quint16(i->second); } - for (RecentHashtagPack::const_iterator i = search.cbegin(), e = search.cend(); i != e; ++i) { + for (auto i = search.cbegin(), e = search.cend(); i != e; ++i) { if (!i->first.isEmpty()) data.stream << i->first << quint16(i->second); } data.stream << quint32(botsCnt); - for (RecentInlineBots::const_iterator i = bots.cbegin(), e = bots.cend(); i != e; ++i) { + for (auto i = bots.cbegin(), e = bots.cend(); i != e; ++i) { _writePeer(data.stream, *i); } FileWriteDescriptor file(_recentHashtagsAndBotsKey); @@ -4713,8 +4718,10 @@ void readRecentHashtagsAndBots() { hashtags.stream >> botsCount; if (botsCount) { bots.reserve(botsCount); - for (uint32 i = 0; i < botsCount; ++i) { - PeerData *peer = _readPeer(hashtags, 9016); + for (auto i = 0; i < botsCount; ++i) { + const auto peer = _readPeer( + hashtags.version, + hashtags.stream); if (peer && peer->isUser() && peer->asUser()->botInfo && !peer->asUser()->botInfo->inlinePlaceholder.isEmpty() && !peer->asUser()->username.isEmpty()) { bots.push_back(peer->asUser()); } @@ -4997,7 +5004,7 @@ void readSavedPeers() { QList peers; peers.reserve(count); for (uint32 i = 0; i < count; ++i) { - PeerData *peer = _readPeer(saved); + const auto peer = _readPeer(saved.version, saved.stream); if (!peer) break; QDateTime t; diff --git a/Telegram/SourceFiles/storage/serialize_common.cpp b/Telegram/SourceFiles/storage/serialize_common.cpp index f5014595f..20fb953da 100644 --- a/Telegram/SourceFiles/storage/serialize_common.cpp +++ b/Telegram/SourceFiles/storage/serialize_common.cpp @@ -9,21 +9,48 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Serialize { -void writeStorageImageLocation(QDataStream &stream, const StorageImageLocation &loc) { - stream << qint32(loc.width()) << qint32(loc.height()); - stream << qint32(loc.dc()) << quint64(loc.volume()) << qint32(loc.local()) << quint64(loc.secret()); +void writeStorageImageLocation( + QDataStream &stream, + const StorageImageLocation &location) { + stream + << qint32(location.width()) + << qint32(location.height()) + << qint32(location.dc()) + << quint64(location.volume()) + << qint32(location.local()) + << quint64(location.secret()); + stream << location.fileReference(); } -StorageImageLocation readStorageImageLocation(QDataStream &stream) { +StorageImageLocation readStorageImageLocation( + int streamAppVersion, + QDataStream &stream) { qint32 width, height, dc, local; quint64 volume, secret; + QByteArray fileReference; stream >> width >> height >> dc >> volume >> local >> secret; - return StorageImageLocation(width, height, dc, volume, local, secret); + if (streamAppVersion >= 1003011) { + stream >> fileReference; + } + return StorageImageLocation( + width, + height, + dc, + volume, + local, + secret, + fileReference); } -int storageImageLocationSize() { - // width + height + dc + volume + local + secret - return sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(quint64) + sizeof(qint32) + sizeof(quint64); +int storageImageLocationSize(const StorageImageLocation &location) { + // width + height + dc + volume + local + secret + fileReference + return sizeof(qint32) + + sizeof(qint32) + + sizeof(qint32) + + sizeof(quint64) + + sizeof(qint32) + + sizeof(quint64) + + bytearraySize(location.fileReference()); } } // namespace Serialize diff --git a/Telegram/SourceFiles/storage/serialize_common.h b/Telegram/SourceFiles/storage/serialize_common.h index 4a363a5ad..980aa3d2e 100644 --- a/Telegram/SourceFiles/storage/serialize_common.h +++ b/Telegram/SourceFiles/storage/serialize_common.h @@ -85,9 +85,13 @@ inline int dateTimeSize() { return (sizeof(qint64) + sizeof(quint32) + sizeof(qint8)); } -void writeStorageImageLocation(QDataStream &stream, const StorageImageLocation &loc); -StorageImageLocation readStorageImageLocation(QDataStream &stream); -int storageImageLocationSize(); +void writeStorageImageLocation( + QDataStream &stream, + const StorageImageLocation &location); +StorageImageLocation readStorageImageLocation( + int streamAppVersion, + QDataStream &stream); +int storageImageLocationSize(const StorageImageLocation &location); template inline T read(QDataStream &stream) { diff --git a/Telegram/SourceFiles/storage/serialize_document.cpp b/Telegram/SourceFiles/storage/serialize_document.cpp index 91e0a7a7d..135b26004 100644 --- a/Telegram/SourceFiles/storage/serialize_document.cpp +++ b/Telegram/SourceFiles/storage/serialize_document.cpp @@ -26,7 +26,7 @@ namespace Serialize { void Document::writeToStream(QDataStream &stream, DocumentData *document) { stream << quint64(document->id) << quint64(document->_access) << qint32(document->date); - stream << qint32(document->_version); + stream << document->_fileReference << qint32(document->_version); stream << document->filename() << document->mimeString() << qint32(document->_dc) << qint32(document->size); stream << qint32(document->dimensions.width()) << qint32(document->dimensions.height()); stream << qint32(document->type); @@ -55,8 +55,12 @@ DocumentData *Document::readFromStreamHelper(int streamAppVersion, QDataStream & quint64 id, access; QString name, mime; qint32 date, dc, size, width, height, type, version; + QByteArray fileReference; stream >> id >> access >> date; if (streamAppVersion >= 9061) { + if (streamAppVersion >= 1003011) { + stream >> fileReference; + } stream >> version; } else { version = 0; @@ -77,7 +81,7 @@ DocumentData *Document::readFromStreamHelper(int streamAppVersion, QDataStream & qint32 typeOfSet; stream >> alt >> typeOfSet; - thumb = readStorageImageLocation(stream); + thumb = readStorageImageLocation(streamAppVersion, stream); if (typeOfSet == StickerSetTypeEmpty) { attributes.push_back(MTP_documentAttributeSticker(MTP_flags(0), MTP_string(alt), MTP_inputStickerSetEmpty(), MTPMaskCoords())); @@ -107,7 +111,7 @@ DocumentData *Document::readFromStreamHelper(int streamAppVersion, QDataStream & if (type == AnimatedDocument) { attributes.push_back(MTP_documentAttributeAnimated()); } - thumb = readStorageImageLocation(stream); + thumb = readStorageImageLocation(streamAppVersion, stream); } if (width > 0 && height > 0) { if (duration >= 0) { @@ -128,6 +132,7 @@ DocumentData *Document::readFromStreamHelper(int streamAppVersion, QDataStream & id, access, version, + fileReference, date, attributes, mime, @@ -160,13 +165,13 @@ int Document::sizeInStream(DocumentData *document) { if (auto sticker = document->sticker()) { // type == StickerDocument // + altlen + alt + type-of-set result += stringSize(sticker->alt) + sizeof(qint32); - // + thumb loc - result += Serialize::storageImageLocationSize(); + // + sticker loc + result += Serialize::storageImageLocationSize(document->sticker()->loc); } else { // + duration result += sizeof(qint32); // + thumb loc - result += Serialize::storageImageLocationSize(); + result += Serialize::storageImageLocationSize(document->thumb->location()); } return result; diff --git a/Telegram/SourceFiles/ui/images.cpp b/Telegram/SourceFiles/ui/images.cpp index 9fbc60cec..7784bacbe 100644 --- a/Telegram/SourceFiles/ui/images.cpp +++ b/Telegram/SourceFiles/ui/images.cpp @@ -405,6 +405,35 @@ uint64 SinglePixKey(Images::Options options) { StorageImageLocation StorageImageLocation::Null; WebFileLocation WebFileLocation::Null; +StorageImageLocation::StorageImageLocation( + int32 width, + int32 height, + int32 dc, + const uint64 &volume, + int32 local, + const uint64 &secret, + const QByteArray &fileReference) +: _widthheight(packIntInt(width, height)) +, _dclocal(packIntInt(dc, local)) +, _volume(volume) +, _secret(secret) +, _fileReference(fileReference) { +} + +StorageImageLocation::StorageImageLocation( + int32 width, + int32 height, + const MTPDfileLocation &location) +: StorageImageLocation( + width, + height, + location.vdc_id.v, + location.vvolume_id.v, + location.vlocal_id.v, + location.vsecret.v, + location.vfile_reference.v) { +} + bool Image::isNull() const { return (this == blank()); } @@ -1099,19 +1128,22 @@ DelayedStorageImage::DelayedStorageImage() : StorageImage(StorageImageLocation() , _loadFromCloud(false) { } -DelayedStorageImage::DelayedStorageImage(int32 w, int32 h) : StorageImage(StorageImageLocation(w, h, 0, 0, 0, 0)) +DelayedStorageImage::DelayedStorageImage(int32 w, int32 h) +: StorageImage(StorageImageLocation(w, h, 0, 0, 0, 0, {})) , _loadRequested(false) , _loadCancelled(false) , _loadFromCloud(false) { } -DelayedStorageImage::DelayedStorageImage(QByteArray &bytes) : StorageImage(StorageImageLocation(), bytes) +DelayedStorageImage::DelayedStorageImage(QByteArray &bytes) +: StorageImage(StorageImageLocation(), bytes) , _loadRequested(false) , _loadCancelled(false) , _loadFromCloud(false) { } -void DelayedStorageImage::setStorageLocation(const StorageImageLocation location) { +void DelayedStorageImage::setStorageLocation( + const StorageImageLocation location) { _location = location; if (_loadRequested) { if (!_loadCancelled) { diff --git a/Telegram/SourceFiles/ui/images.h b/Telegram/SourceFiles/ui/images.h index 928456810..628fb5287 100644 --- a/Telegram/SourceFiles/ui/images.h +++ b/Telegram/SourceFiles/ui/images.h @@ -112,10 +112,19 @@ inline int32 unpackIntSecond(uint64 v) { class StorageImageLocation { public: StorageImageLocation() = default; - StorageImageLocation(int32 width, int32 height, int32 dc, const uint64 &volume, int32 local, const uint64 &secret) : _widthheight(packIntInt(width, height)), _dclocal(packIntInt(dc, local)), _volume(volume), _secret(secret) { - } - StorageImageLocation(int32 width, int32 height, const MTPDfileLocation &location) : _widthheight(packIntInt(width, height)), _dclocal(packIntInt(location.vdc_id.v, location.vlocal_id.v)), _volume(location.vvolume_id.v), _secret(location.vsecret.v) { - } + StorageImageLocation( + int32 width, + int32 height, + int32 dc, + const uint64 &volume, + int32 local, + const uint64 &secret, + const QByteArray &fileReference); + StorageImageLocation( + int32 width, + int32 height, + const MTPDfileLocation &location); + bool isNull() const { return !_dclocal; } @@ -140,16 +149,19 @@ public: uint64 secret() const { return _secret; } + QByteArray fileReference() const { + return _fileReference; + } static StorageImageLocation FromMTP( - int32 width, - int32 height, - const MTPFileLocation &location) { + int32 width, + int32 height, + const MTPFileLocation &location) { if (location.type() == mtpc_fileLocation) { const auto &data = location.c_fileLocation(); return StorageImageLocation(width, height, data); } - return StorageImageLocation(width, height, 0, 0, 0, 0); + return StorageImageLocation(width, height, 0, 0, 0, 0, {}); } static StorageImageLocation FromMTP(const MTPPhotoSize &size) { switch (size.type()) { @@ -172,9 +184,12 @@ private: uint64 _dclocal = 0; uint64 _volume = 0; uint64 _secret = 0; + QByteArray _fileReference; - friend inline bool operator==(const StorageImageLocation &a, const StorageImageLocation &b) { - return (a._dclocal == b._dclocal) && (a._volume == b._volume) && (a._secret == b._secret); + friend inline bool operator==( + const StorageImageLocation &a, + const StorageImageLocation &b) { + return (a._dclocal == b._dclocal) && (a._volume == b._volume); } }; @@ -211,8 +226,12 @@ private: QByteArray _url; int32 _dc = 0; - friend inline bool operator==(const WebFileLocation &a, const WebFileLocation &b) { - return (a._dc == b._dc) && (a._accessHash == b._accessHash) && (a._url == b._url); + friend inline bool operator==( + const WebFileLocation &a, + const WebFileLocation &b) { + return (a._dc == b._dc) + && (a._accessHash == b._accessHash) + && (a._url == b._url); } };