From 4c781ebb7be5ff34f03aaf2d79ffa59026f4cec5 Mon Sep 17 00:00:00 2001 From: levlam Date: Sat, 8 Jun 2019 12:26:35 +0300 Subject: [PATCH] Update layer to 98. GitOrigin-RevId: 7bc09a6ec637f12b2f90bc1fb6d82903feffc376 --- td/generate/scheme/td_api.tl | 2 +- td/generate/scheme/td_api.tlo | Bin 155752 -> 155752 bytes td/generate/scheme/telegram_api.tl | 38 +++--- td/generate/scheme/telegram_api.tlo | Bin 180264 -> 181176 bytes td/telegram/CallActor.cpp | 44 ++++--- td/telegram/CallActor.h | 7 +- td/telegram/CallManager.cpp | 9 +- td/telegram/CallManager.h | 5 +- td/telegram/ContactsManager.cpp | 37 +++--- td/telegram/DocumentsManager.cpp | 5 +- td/telegram/MessageContent.cpp | 44 ++++--- td/telegram/MessagesManager.cpp | 8 +- td/telegram/Photo.cpp | 194 +++++++++++++--------------- td/telegram/Photo.h | 52 +++++++- td/telegram/StickersManager.cpp | 9 +- td/telegram/Td.cpp | 4 +- td/telegram/Version.h | 1 + td/telegram/WebPageBlock.cpp | 5 +- td/telegram/files/FileLocation.h | 48 +++---- td/telegram/net/DcId.h | 7 + td/telegram/net/MtprotoHeader.cpp | 2 +- 21 files changed, 291 insertions(+), 230 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 5fdb420a..0159537a 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1837,7 +1837,7 @@ chatEventDescriptionChanged old_description:string new_description:string = Chat chatEventUsernameChanged old_username:string new_username:string = ChatEventAction; //@description The chat photo was changed @old_photo Previous chat photo value; may be null @new_photo New chat photo value; may be null -chatEventPhotoChanged old_photo:chatPhoto new_photo:chatPhoto = ChatEventAction; +chatEventPhotoChanged old_photo:photo new_photo:photo = ChatEventAction; //@description The can_invite_users permission of a supergroup chat was toggled @can_invite_users New value of can_invite_users permission chatEventInvitesToggled can_invite_users:Bool = ChatEventAction; diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index 70ad7cd0a50b467dfb33b1a8805911efb4b490f1..1b1dd2cb673fe40f99cb4bb74e7c9ef6ff4723c6 100644 GIT binary patch delta 496 zcmaEHfb+!x&J6~vEYG6+l{cHPa(IAQlO23*AdCjz2ngejuLhVg-JpWe03u}Lhaofv zQ|OPMjs(c`o5zHF7=WP2nN5eow(THDY_fyD25!j)e-+%4d;B#xVa75|S9D_XhB_($ z>Zk<=7fk(igBn!>;UQadR`Vfq3=MuEu& zAtE3K4-ZO+#DpOH#W;CkivHveCL9oloCtvi{GSjDh=@ff)FBz684!^xp-?G-Fc+{$ Rb3|BsL>S}th%hDrE&vLTtq}kK delta 491 zcmaEHfb+!x&J6~vEZRZk<=7 version:int = ChatParticipants; chatPhotoEmpty#37c1011c = ChatPhoto; -chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto; +chatPhoto#475cdbd5 photo_small:FileLocation photo_big:FileLocation dc_id:int = ChatPhoto; messageEmpty#83e5de54 id:int = Message; message#44f9b43d flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector views:flags.10?int edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long = Message; @@ -156,7 +156,7 @@ messageActionHistoryClear#9fbab604 = MessageAction; messageActionGameScore#92a72876 game_id:long score:int = MessageAction; messageActionPaymentSentMe#8f31b327 flags:# currency:string total_amount:long payload:bytes info:flags.0?PaymentRequestedInfo shipping_option_id:flags.1?string charge:PaymentCharge = MessageAction; messageActionPaymentSent#40699cd0 currency:string total_amount:long = MessageAction; -messageActionPhoneCall#80e11a7f flags:# call_id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = MessageAction; +messageActionPhoneCall#80e11a7f flags:# video:flags.2?true call_id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = MessageAction; messageActionScreenshotTaken#4792929b = MessageAction; messageActionCustomAction#fae69f56 message:string = MessageAction; messageActionBotAllowed#abe9affe domain:string = MessageAction; @@ -167,7 +167,7 @@ messageActionContactSignUp#f3f25f76 = MessageAction; 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#9c477dd8 flags:# has_stickers:flags.0?true id:long access_hash:long file_reference:bytes date:int sizes:Vector = Photo; +photo#d07504a5 flags:# has_stickers:flags.0?true id:long access_hash:long file_reference:bytes date:int sizes:Vector dc_id:int = Photo; photoSizeEmpty#e17e23c type:string = PhotoSize; photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize; @@ -494,13 +494,13 @@ chatInviteEmpty#69df3769 = ExportedChatInvite; chatInviteExported#fc2e05bc link:string = ExportedChatInvite; chatInviteAlready#5a686d7c chat:Chat = ChatInvite; -chatInvite#db74f558 flags:# channel:flags.0?true broadcast:flags.1?true public:flags.2?true megagroup:flags.3?true title:string photo:ChatPhoto participants_count:int participants:flags.4?Vector = ChatInvite; +chatInvite#dfc2f58e flags:# channel:flags.0?true broadcast:flags.1?true public:flags.2?true megagroup:flags.3?true title:string photo:Photo participants_count:int participants:flags.4?Vector = ChatInvite; inputStickerSetEmpty#ffb62b95 = InputStickerSet; inputStickerSetID#9de7a269 id:long access_hash:long = InputStickerSet; inputStickerSetShortName#861cc8a0 short_name:string = InputStickerSet; -stickerSet#6a90bcb7 flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumb:flags.4?PhotoSize count:int hash:int = StickerSet; +stickerSet#eeb46f27 flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumb:flags.4?PhotoSize thumb_dc_id:flags.4?int count:int hash:int = StickerSet; messages.stickerSet#b60a24a6 set:StickerSet packs:Vector documents:Vector = messages.StickerSet; @@ -778,11 +778,11 @@ inputStickerSetItem#ffa0a496 flags:# document:InputDocument emoji:string mask_co inputPhoneCall#1e36fded id:long access_hash:long = InputPhoneCall; phoneCallEmpty#5366c915 id:long = PhoneCall; -phoneCallWaiting#1b8f4ad1 flags:# id:long access_hash:long date:int admin_id:int participant_id:int protocol:PhoneCallProtocol receive_date:flags.0?int = PhoneCall; -phoneCallRequested#83761ce4 id:long access_hash:long date:int admin_id:int participant_id:int g_a_hash:bytes protocol:PhoneCallProtocol = PhoneCall; -phoneCallAccepted#6d003d3f id:long access_hash:long date:int admin_id:int participant_id:int g_b:bytes protocol:PhoneCallProtocol = PhoneCall; -phoneCall#e6f9ddf3 flags:# p2p_allowed:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connection:PhoneConnection alternative_connections:Vector start_date:int = PhoneCall; -phoneCallDiscarded#50ca4de1 flags:# need_rating:flags.2?true need_debug:flags.3?true id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = PhoneCall; +phoneCallWaiting#1b8f4ad1 flags:# video:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int protocol:PhoneCallProtocol receive_date:flags.0?int = PhoneCall; +phoneCallRequested#87eabb53 flags:# video:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int g_a_hash:bytes protocol:PhoneCallProtocol = PhoneCall; +phoneCallAccepted#997c454a flags:# video:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int g_b:bytes protocol:PhoneCallProtocol = PhoneCall; +phoneCall#8742ae7f flags:# p2p_allowed:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connections:Vector start_date:int = PhoneCall; +phoneCallDiscarded#50ca4de1 flags:# need_rating:flags.2?true need_debug:flags.3?true video:flags.5?true id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = PhoneCall; phoneConnection#9d4c17c0 id:long ip:string ipv6:string port:int peer_tag:bytes = PhoneConnection; @@ -808,7 +808,7 @@ langPackLanguage#eeca5ce3 flags:# official:flags.0?true rtl:flags.2?true beta:fl channelAdminLogEventActionChangeTitle#e6dfb825 prev_value:string new_value:string = ChannelAdminLogEventAction; channelAdminLogEventActionChangeAbout#55188a2e prev_value:string new_value:string = ChannelAdminLogEventAction; channelAdminLogEventActionChangeUsername#6a4afc38 prev_value:string new_value:string = ChannelAdminLogEventAction; -channelAdminLogEventActionChangePhoto#b82f55c3 prev_photo:ChatPhoto new_photo:ChatPhoto = ChannelAdminLogEventAction; +channelAdminLogEventActionChangePhoto#434bd2af prev_photo:Photo new_photo:Photo = ChannelAdminLogEventAction; channelAdminLogEventActionToggleInvites#1b7907ae new_value:Bool = ChannelAdminLogEventAction; channelAdminLogEventActionToggleSignatures#26ae0971 new_value:Bool = ChannelAdminLogEventAction; channelAdminLogEventActionUpdatePinned#e9e82c18 message:Message = ChannelAdminLogEventAction; @@ -1013,6 +1013,8 @@ emojiURL#a575739d url:string = EmojiURL; emojiLanguage#b3fb5361 lang_code:string = EmojiLanguage; +fileLocationToBeDeprecated#bc7fc6cd volume_id:long local_id:int = FileLocation; + ---functions--- invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; @@ -1312,11 +1314,11 @@ stickers.changeStickerPosition#ffb6d4ca sticker:InputDocument position:int = mes stickers.addStickerToSet#8653febe stickerset:InputStickerSet sticker:InputStickerSetItem = messages.StickerSet; phone.getCallConfig#55451fa9 = DataJSON; -phone.requestCall#5b95b3d4 user_id:InputUser random_id:int g_a_hash:bytes protocol:PhoneCallProtocol = phone.PhoneCall; +phone.requestCall#42ff96ed flags:# video:flags.0?true user_id:InputUser random_id:int g_a_hash:bytes protocol:PhoneCallProtocol = phone.PhoneCall; phone.acceptCall#3bd2b4a0 peer:InputPhoneCall g_b:bytes protocol:PhoneCallProtocol = phone.PhoneCall; phone.confirmCall#2efe1722 peer:InputPhoneCall g_a:bytes key_fingerprint:long protocol:PhoneCallProtocol = phone.PhoneCall; phone.receivedCall#17d54f61 peer:InputPhoneCall = Bool; -phone.discardCall#78d413a6 peer:InputPhoneCall duration:int reason:PhoneCallDiscardReason connection_id:long = Updates; +phone.discardCall#b2cbc1c0 flags:# video:flags.0?true peer:InputPhoneCall duration:int reason:PhoneCallDiscardReason connection_id:long = Updates; phone.setCallRating#59ead627 flags:# user_initiative:flags.0?true peer:InputPhoneCall rating:int comment:string = Updates; phone.saveCallDebug#277add7e peer:InputPhoneCall debug:DataJSON = Bool; diff --git a/td/generate/scheme/telegram_api.tlo b/td/generate/scheme/telegram_api.tlo index 3544556d8d751f0372ef16775c07641507048e1e..f6db54365cbed6162ee7027d91766d636bb69aef 100644 GIT binary patch delta 2228 zcmaJ?Z)_7~7{BLwWnIh21`R8tutsWDL&G{(lcFG9+ie}pP{JhB6zSN?+R(1u=mwG^ zQ&IK-q2nFABP!VTM#PF$0`h@~ec!uVMiuVU^FIH6 z&;L8#s~O*`Nw%@daMf>285(A_{4Vx=Q2sUe$vbM)uUdla+#c?$?>~(4=Q$Twbn)Eo z$=P+mkiRj~+JZ`EmGid3KE(of#i%Q3=!ka5WLYd2>0lTY8irCnJ6osboJaqD6U{Ci zQ}&&9-BF^8oPqzjbfJ=~h>YFlxkXoi3;%NNBR;+OelcYDtCid5P)!ECcdQiIu?mmq zK*h&j^spR>6;0V2MZ!?iEE4e=TOLR2STW7f5-a(;yjbl$@y!}1N;yoTM#f>_NMxwk zY0wcuR_$`mGOJd;dzON_of5yHj#+eyYe_@w`3J^`$W-{Thf`%#M2=8 z8E6Plor9|-1UWT6v^t@o<8f-kd4-b934=QAX7qVzAxi8jz}Jt%0^a)SNP*PMqBp8} z-R5z{jHhag9_SPxQ+tRbgNFv&Ek;7fJs|DcfA@>)>efI@tf8YP81pkk&S%DGO&}Hk zhm)`rd9jMuA67{`GVr_|$4fb~RVXz&Bob{W%n~Q*(Gtg?&BI)mY{%IISa5F-TY{D&Cr&M53$1zn ze!X?3NK5^#j|E$|`n%TqV@;$2xuoO(6=>aCOOXw^s0UIJzWL;pmC|5dx?RpU{gF|k z8$X$6DSLu#{s=l+^%Nhv>nfrHhqD|so>oBb9PxSK9=L@ICE(H1ONR~1z${XpWndJq z-v<*_1=JP8pv22&oUMdmysH|P;2o7<)shQ2v#0APZtcaXO3*&mI`bc!)wS^>IBR*F zjiCx|81r#}iMgx%!zq2J2ViSRb z;>a0UAwV?+?{iSB5KBW!VVHSR$?AQ~bx$dCpk(cc45y5_u4Zg-6D4{LbXO=ly&T5r zCgSJ|;KJ$WVIO@8xu-!x|5FSeu7z@8tPXreE%}|Ow@r7QA#ZFsz~-{q3SKDGh?~&X ziaX0-9!hK}#_22=uy;Faq*n+(2!UOs>|xkJDPb}UAr<{W3FaQKl`Clt@o;Ajx9mL#Ohl4@h^V&IYf_DU8^6n7%Lr%-Wo-_>GyUFkUu%*E}Ut;`t2UZDJ?!lKTv5P|wp-&9Zmjc(JDBCQ) z62LZL1F#{{XYQ%pNG~cbZeaB|`!=hkPvP2Y?6tLA>g?C2@Z>0~N8Fxeirk9eKMP>q z;eId(*-_R6-0z1UIAAr*{cHuc9Ar&6 PG{Ji4ff7;^Y=HY0Xb3Y* delta 2121 zcmaJ?ZA=qq9KZkdPTNvVk!CFurO9w$g0l!BiQ&gBy!x zBN@c%13tvf1e3+MD2krj)y+hV$-;*%VuBMg%rG)zHb1Z|M$PtNeV*s8c3rmn^nZT; z_t#5&l69dcYqXgc;p-EBzKPE97WpXu8Hfc#c^?_kN&Q>MDI6C%-#)cd9v9q#IC8|@ zVL~J3Lb<}wtIM6a^WHj<&`%mJ*rm7<72D|k1CVO#9OD@8K`Ta zGN(4H9<G(Z~Vh{ZPLu-4+Sqx9nvG zQ@VE2k)|c0>=T9P>Bs;LMZSc#gFviJSNHF>2dWs?!xM~iJlII{r+lLdLIlI9`L&YKpX$?{cl)eF}mmRkHPyK+H*ON;4K zX~==0Ja$9k+ilpH01JKLf@A~?pHLiV_=X9OI^bmqxi;w;&E<6-TM})Fge8|h6nalO z*devYq-KuDk>D2M?6r`<57$8LzjWWN+x>bRI6eX%@y5~ya#mY>Ve>{Bk#E?>Z zExt&(T?Xw?VhlvWVJW~4WinQBXU44cXSJ}GKKXg2)gOvUZQ@YJMD zHii2(K!P574sHF>jr%L%)6~0dw*4nsvg%f>kb`W%t`8#r|ENRHyW2yy=P zDZxdTAyG}(nKMRJ)SOAm<5Rotn>*U2Hg8*mESi^P&uO|kytNQ=urC*E*n1^8Uu6CM zbMJ|kGIj+9jOu`X1J{dK9_Gi;{RSiBuRt)cmO1W%8xLRQ&G;G5mr*55u?Z!Kb?JCd z8uq=A#B2f|dW|VbY@(4C8xQ+=2P^xepP$*1cRpvbi%sY|&B6A7zpa@}Img{NYsfl{ z`8?b^%9~Nw@d7;GPn=!j=Y&ala5whJNv7#4ugA|0fmxZA`9>Y>0CJo!X03=Se8obM iUI={h5ftM2!@M2Ex9G7sCuz%ci+9ppSG>3Q7U6G1o)|a) diff --git a/td/telegram/CallActor.cpp b/td/telegram/CallActor.cpp index 4f488b89..056294da 100644 --- a/td/telegram/CallActor.cpp +++ b/td/telegram/CallActor.cpp @@ -116,10 +116,11 @@ CallActor::CallActor(CallId call_id, ActorShared<> parent, Promise promis } void CallActor::create_call(UserId user_id, tl_object_ptr &&input_user, - CallProtocol &&protocol, Promise &&promise) { + CallProtocol &&protocol, bool is_video, Promise &&promise) { CHECK(state_ == State::Empty); state_ = State::SendRequestQuery; is_outgoing_ = true; + is_video_ = is_video; user_id_ = user_id; input_user_ = std::move(input_user); call_state_.protocol = std::move(protocol); @@ -130,11 +131,13 @@ void CallActor::create_call(UserId user_id, tl_object_ptr promise) { +void CallActor::discard_call(bool is_disconnected, int32 duration, bool is_video, int64 connection_id, + Promise<> promise) { promise.set_value(Unit()); if (state_ == State::Discarded || state_ == State::WaitDiscardResult || state_ == State::SendDiscardQuery) { return; } + is_video_ |= is_video; if (state_ == State::WaitRequestResult && !request_query_ref_.empty()) { LOG(INFO) << "Cancel request call query"; @@ -250,7 +253,6 @@ Status CallActor::do_update_call(telegram_api::phoneCallEmpty &call) { return Status::Error(400, "Call is finished"); } -//phoneCallWaiting#1b8f4ad1 flags:# id:long access_hash:long date:int admin_id:int participant_id:int protocol:PhoneCallProtocol receive_date:flags.0?int = PhoneCall; Status CallActor::do_update_call(telegram_api::phoneCallWaiting &call) { if (state_ != State::WaitRequestResult && state_ != State::WaitAcceptResult) { return Status::Error(500, PSLICE() << "Drop unexpected " << to_string(call)); @@ -272,6 +274,7 @@ Status CallActor::do_update_call(telegram_api::phoneCallWaiting &call) { call_id_ = call.id_; call_access_hash_ = call.access_hash_; is_call_id_inited_ = true; + is_video_ |= (call.flags_ & telegram_api::phoneCallWaiting::VIDEO_MASK) != 0; call_admin_id_ = call.admin_id_; call_participant_id_ = call.participant_id_; if (call_id_promise_) { @@ -286,7 +289,6 @@ Status CallActor::do_update_call(telegram_api::phoneCallWaiting &call) { return Status::OK(); } -//phoneCallRequested#83761ce4 id:long access_hash:long date:int admin_id:int participant_id:int g_a_hash:bytes protocol:PhoneCallProtocol = PhoneCall; Status CallActor::do_update_call(telegram_api::phoneCallRequested &call) { if (state_ != State::Empty) { return Status::Error(500, PSLICE() << "Drop unexpected " << to_string(call)); @@ -295,6 +297,7 @@ Status CallActor::do_update_call(telegram_api::phoneCallRequested &call) { call_id_ = call.id_; call_access_hash_ = call.access_hash_; is_call_id_inited_ = true; + is_video_ |= (call.flags_ & telegram_api::phoneCallRequested::VIDEO_MASK) != 0; call_admin_id_ = call.admin_id_; call_participant_id_ = call.participant_id_; if (call_id_promise_) { @@ -318,7 +321,6 @@ tl_object_ptr CallActor::get_input_phone_call(cons return make_tl_object(call_id_, call_access_hash_); } -//phoneCallAccepted#6d003d3f id:long access_hash:long date:int admin_id:int participant_id:int g_b:bytes protocol:PhoneCallProtocol = PhoneCall; Status CallActor::do_update_call(telegram_api::phoneCallAccepted &call) { if (state_ != State::WaitRequestResult) { return Status::Error(500, PSLICE() << "Drop unexpected " << to_string(call)); @@ -335,6 +337,7 @@ Status CallActor::do_update_call(telegram_api::phoneCallAccepted &call) { call_id_promise_.set_value(std::move(call.id_)); } } + is_video_ |= (call.flags_ & telegram_api::phoneCallAccepted::VIDEO_MASK) != 0; dh_handshake_.set_g_a(call.g_b_.as_slice()); TRY_STATUS(dh_handshake_.run_checks(true, DhCache::instance())); std::tie(call_state_.key_fingerprint, call_state_.key) = dh_handshake_.gen_key(); @@ -352,7 +355,6 @@ void CallActor::on_begin_exchanging_key() { set_timeout_in(timeout); } -//phoneCall#ffe6ab67 id:long access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connection:PhoneConnection alternative_connections:Vector start_date:int = PhoneCall; Status CallActor::do_update_call(telegram_api::phoneCall &call) { if (state_ != State::WaitAcceptResult && state_ != State::WaitConfirmResult) { return Status::Error(500, PSLICE() << "Drop unexpected " << to_string(call)); @@ -372,8 +374,7 @@ Status CallActor::do_update_call(telegram_api::phoneCall &call) { call_state_.emojis_fingerprint = get_emojis_fingerprint(call_state_.key, is_outgoing_ ? dh_handshake_.get_g_b() : dh_handshake_.get_g_a()); - call_state_.connections.push_back(CallConnection::from_telegram_api(*call.connection_)); - for (auto &connection : call.alternative_connections_) { + for (auto &connection : call.connections_) { call_state_.connections.push_back(CallConnection::from_telegram_api(*connection)); } call_state_.protocol = CallProtocol::from_telegram_api(*call.protocol_); @@ -384,15 +385,15 @@ Status CallActor::do_update_call(telegram_api::phoneCall &call) { return Status::OK(); } -//phoneCallDiscarded#50ca4de1 flags:# need_rating:flags.2?true need_debug:flags.3?true id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = PhoneCall; Status CallActor::do_update_call(telegram_api::phoneCallDiscarded &call) { LOG(DEBUG) << "Do update call to Discarded"; - on_call_discarded(get_call_discard_reason(call.reason_), call.need_rating_, call.need_debug_); + on_call_discarded(get_call_discard_reason(call.reason_), call.need_rating_, call.need_debug_, call.video_); return Status::OK(); } -void CallActor::on_call_discarded(CallDiscardReason reason, bool need_rating, bool need_debug) { +void CallActor::on_call_discarded(CallDiscardReason reason, bool need_rating, bool need_debug, bool is_video) { state_ = State::Discarded; + is_video_ |= is_video; if (call_state_.discard_reason == CallDiscardReason::Empty || reason != CallDiscardReason::Empty) { call_state_.discard_reason = reason; @@ -508,7 +509,6 @@ void CallActor::on_received_query_result(NetQueryPtr net_query) { } } -//phone.requestCall#5b95b3d4 user_id:InputUser random_id:int g_a_hash:bytes protocol:PhoneCallProtocol = phone.PhoneCall; void CallActor::try_send_request_query() { LOG(INFO) << "Trying to send request query"; if (!load_dh_config()) { @@ -516,8 +516,12 @@ void CallActor::try_send_request_query() { } dh_handshake_.set_config(dh_config_->g, dh_config_->prime); CHECK(input_user_ != nullptr); - auto tl_query = telegram_api::phone_requestCall(std::move(input_user_), Random::secure_int32(), - BufferSlice(dh_handshake_.get_g_b_hash()), + int32 flags = 0; + if (is_video_) { + flags |= telegram_api::phone_requestCall::VIDEO_MASK; + } + auto tl_query = telegram_api::phone_requestCall(flags, false /*ignored*/, std::move(input_user_), + Random::secure_int32(), BufferSlice(dh_handshake_.get_g_b_hash()), call_state_.protocol.as_telegram_api()); auto query = G()->net_query_creator().create(create_storer(tl_query)); state_ = State::WaitRequestResult; @@ -596,14 +600,18 @@ void CallActor::on_confirm_query_result(NetQueryPtr net_query) { void CallActor::try_send_discard_query() { if (call_id_ == 0) { LOG(INFO) << "Failed to send discard query, because call_id_ is unknown"; - on_call_discarded(CallDiscardReason::Missed, false, false); + on_call_discarded(CallDiscardReason::Missed, false, false, is_video_); yield(); return; } LOG(INFO) << "Trying to send discard query"; - auto tl_query = - telegram_api::phone_discardCall(get_input_phone_call("try_send_discard_query"), duration_, - get_input_phone_call_discard_reason(call_state_.discard_reason), connection_id_); + int32 flags = 0; + if (is_video_) { + flags |= telegram_api::phone_discardCall::VIDEO_MASK; + } + auto tl_query = telegram_api::phone_discardCall( + flags, false /*ignored*/, get_input_phone_call("try_send_discard_query"), duration_, + get_input_phone_call_discard_reason(call_state_.discard_reason), connection_id_); auto query = G()->net_query_creator().create(create_storer(tl_query)); state_ = State::WaitDiscardResult; send_with_promise(std::move(query), PromiseCreator::lambda([actor_id = actor_id(this)](NetQueryPtr net_query) { diff --git a/td/telegram/CallActor.h b/td/telegram/CallActor.h index cec2ad68..97ddba36 100644 --- a/td/telegram/CallActor.h +++ b/td/telegram/CallActor.h @@ -78,8 +78,8 @@ class CallActor : public NetQueryCallback { CallActor(CallId call_id, ActorShared<> parent, Promise promise); void create_call(UserId user_id, tl_object_ptr &&input_user, CallProtocol &&protocol, - Promise &&promise); - void discard_call(bool is_disconnected, int32 duration, int64 connection_id, Promise<> promise); + bool is_video, Promise &&promise); + void discard_call(bool is_disconnected, int32 duration, bool is_video, int64 connection_id, Promise<> promise); void accept_call(CallProtocol &&protocol, Promise<> promise); void rate_call(int32 rating, string comment, Promise<> promise); void send_call_debug_information(string data, Promise<> promise); @@ -114,6 +114,7 @@ class CallActor : public NetQueryCallback { bool is_accepted_{false}; bool is_outgoing_{false}; + bool is_video_{false}; UserId user_id_; tl_object_ptr input_user_; @@ -160,7 +161,7 @@ class CallActor : public NetQueryCallback { void on_begin_exchanging_key(); - void on_call_discarded(CallDiscardReason reason, bool need_rating, bool need_debug); + void on_call_discarded(CallDiscardReason reason, bool need_rating, bool need_debug, bool is_video); void on_set_rating_query_result(NetQueryPtr net_query); void on_set_debug_query_result(NetQueryPtr net_query); diff --git a/td/telegram/CallManager.cpp b/td/telegram/CallManager.cpp index 03d8beb4..b99ee5ab 100644 --- a/td/telegram/CallManager.cpp +++ b/td/telegram/CallManager.cpp @@ -45,21 +45,22 @@ void CallManager::update_call(Update call) { } void CallManager::create_call(UserId user_id, tl_object_ptr &&input_user, - CallProtocol &&protocol, Promise promise) { + CallProtocol &&protocol, bool is_video, Promise promise) { LOG(INFO) << "Create call with " << user_id; auto call_id = create_call_actor(); auto actor = get_call_actor(call_id); CHECK(!actor.empty()); - send_closure(actor, &CallActor::create_call, user_id, std::move(input_user), std::move(protocol), std::move(promise)); + send_closure(actor, &CallActor::create_call, user_id, std::move(input_user), std::move(protocol), is_video, + std::move(promise)); } -void CallManager::discard_call(CallId call_id, bool is_disconnected, int32 duration, int64 connection_id, +void CallManager::discard_call(CallId call_id, bool is_disconnected, int32 duration, bool is_video, int64 connection_id, Promise<> promise) { auto actor = get_call_actor(call_id); if (actor.empty()) { return promise.set_error(Status::Error(400, "Call not found")); } - send_closure(actor, &CallActor::discard_call, is_disconnected, duration, connection_id, std::move(promise)); + send_closure(actor, &CallActor::discard_call, is_disconnected, duration, is_video, connection_id, std::move(promise)); } void CallManager::accept_call(CallId call_id, CallProtocol &&protocol, Promise<> promise) { diff --git a/td/telegram/CallManager.h b/td/telegram/CallManager.h index b8056a0b..f4f6d315 100644 --- a/td/telegram/CallManager.h +++ b/td/telegram/CallManager.h @@ -28,8 +28,9 @@ class CallManager : public Actor { void update_call(Update call); void create_call(UserId user_id, tl_object_ptr &&input_user, CallProtocol &&protocol, - Promise promise); - void discard_call(CallId call_id, bool is_disconnected, int32 duration, int64 connection_id, Promise<> promise); + bool is_video, Promise promise); + void discard_call(CallId call_id, bool is_disconnected, int32 duration, bool is_video, int64 connection_id, + Promise<> promise); void accept_call(CallId call_id, CallProtocol &&protocol, Promise<> promise); void rate_call(CallId call_id, int32 rating, string comment, Promise<> promise); void send_call_debug_information(CallId call_id, string data, Promise<> promise); diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 23de6d92..845e4cd1 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -5468,10 +5468,8 @@ ContactsManager::User *ContactsManager::get_user_force(UserId user_id) { telegram_api::user::PHONE_MASK | telegram_api::user::PHOTO_MASK | telegram_api::user::VERIFIED_MASK | telegram_api::user::SUPPORT_MASK; auto profile_photo = telegram_api::make_object( - 3337190045231018, - telegram_api::make_object(1, 702229962, 26779, 5859320227133863146, BufferSlice()), - telegram_api::make_object(1, 702229962, 26781, -3695031185685824216, - BufferSlice())); + 3337190045231018, telegram_api::make_object(702229962, 26779), + telegram_api::make_object(702229962, 26781), 1); if (G()->is_test_dc()) { profile_photo = nullptr; flags -= telegram_api::user::PHOTO_MASK; @@ -6590,7 +6588,7 @@ void ContactsManager::on_get_user_photos(UserId user_id, int32 offset, int32 lim auto server_photo = telegram_api::move_object_as(photo_ptr); auto profile_photo = convert_photo_to_profile_photo(server_photo); if (profile_photo) { - get_profile_photo(td_->file_manager_.get(), std::move(profile_photo)); + get_profile_photo(td_->file_manager_.get(), user_id, u->access_hash, std::move(profile_photo)); } else { LOG(ERROR) << "Failed to get profile photo from " << to_string(server_photo); } @@ -6961,19 +6959,6 @@ void ContactsManager::on_update_user_photo(User *u, UserId user_id, tl_object_ptr &&photo) { if (td_->auth_manager_->is_bot() && !G()->parameters().use_file_db && !u->is_photo_inited) { bool is_empty = photo == nullptr || photo->get_id() == telegram_api::userProfilePhotoEmpty::ID; - if (!is_empty) { - CHECK(photo->get_id() == telegram_api::userProfilePhoto::ID); - auto user_photo = static_cast(photo.get()); - - auto copy_location = [](telegram_api::FileLocation *location_ptr) { - if (location_ptr->get_id() == telegram_api::fileLocation::ID) { - auto location = static_cast(location_ptr); - location->file_reference_ = location->file_reference_.copy(); - } - }; - copy_location(user_photo->photo_small_.get()); - copy_location(user_photo->photo_big_.get()); - } pending_user_photos_[user_id] = std::move(photo); UserFull *user_full = get_user_full(user_id); @@ -6995,7 +6980,7 @@ void ContactsManager::on_update_user_photo(User *u, UserId user_id, void ContactsManager::do_update_user_photo(User *u, UserId user_id, tl_object_ptr &&photo) { u->is_photo_inited = true; - ProfilePhoto new_photo = get_profile_photo(td_->file_manager_.get(), std::move(photo)); + ProfilePhoto new_photo = get_profile_photo(td_->file_manager_.get(), user_id, u->access_hash, std::move(photo)); if (new_photo != u->photo) { u->photo = new_photo; @@ -8009,7 +7994,13 @@ void ContactsManager::on_get_dialog_invite_link_info(const string &invite_link, invite_link_info->chat_id = ChatId(); invite_link_info->channel_id = ChannelId(); invite_link_info->title = chat_invite->title_; - invite_link_info->photo = get_dialog_photo(td_->file_manager_.get(), std::move(chat_invite->photo_)); + if (chat_invite->photo_ != nullptr && chat_invite->photo_->get_id() == telegram_api::photo::ID) { + auto photo = telegram_api::move_object_as(chat_invite->photo_); + invite_link_info->photo = + get_profile_photo(td_->file_manager_.get(), UserId(), 0, convert_photo_to_profile_photo(photo)); + } else { + invite_link_info->photo = DialogPhoto(); + } invite_link_info->participant_count = chat_invite->participants_count_; invite_link_info->participant_user_ids.clear(); for (auto &user : chat_invite->participants_) { @@ -8476,7 +8467,8 @@ void ContactsManager::on_update_chat_participant_count(Chat *c, ChatId chat_id, void ContactsManager::on_update_chat_photo(Chat *c, ChatId chat_id, tl_object_ptr &&chat_photo_ptr) { - DialogPhoto new_chat_photo = get_dialog_photo(td_->file_manager_.get(), std::move(chat_photo_ptr)); + DialogPhoto new_chat_photo = + get_dialog_photo(td_->file_manager_.get(), DialogId(chat_id), 0, std::move(chat_photo_ptr)); if (new_chat_photo != c->photo) { if (c->photo_source_id.is_valid()) { @@ -8601,7 +8593,8 @@ void ContactsManager::invalidate_chat_full(ChatId chat_id) { void ContactsManager::on_update_channel_photo(Channel *c, ChannelId channel_id, tl_object_ptr &&chat_photo_ptr) { - DialogPhoto new_chat_photo = get_dialog_photo(td_->file_manager_.get(), std::move(chat_photo_ptr)); + DialogPhoto new_chat_photo = + get_dialog_photo(td_->file_manager_.get(), DialogId(channel_id), c->access_hash, std::move(chat_photo_ptr)); if (new_chat_photo != c->photo) { if (c->photo_source_id.is_valid()) { diff --git a/td/telegram/DocumentsManager.cpp b/td/telegram/DocumentsManager.cpp index 3466947f..5c8a898e 100644 --- a/td/telegram/DocumentsManager.cpp +++ b/td/telegram/DocumentsManager.cpp @@ -227,8 +227,9 @@ 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, 0, "", owner_dialog_id, - std::move(thumb), has_webp_thumbnail, has_png_thumbnail); + 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), + has_webp_thumbnail, has_png_thumbnail); if (photo_size.get_offset() == 0) { thumbnail = std::move(photo_size.get<0>()); } else { diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index acf8d6a4..a75a13fe 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -443,10 +443,11 @@ class MessageCall : public MessageContent { int64 call_id; int32 duration; CallDiscardReason discard_reason; + bool is_video; MessageCall() = default; - MessageCall(int64 call_id, int32 duration, CallDiscardReason discard_reason) - : call_id(call_id), duration(duration), discard_reason(discard_reason) { + MessageCall(int64 call_id, int32 duration, CallDiscardReason discard_reason, bool is_video) + : call_id(call_id), duration(duration), discard_reason(discard_reason), is_video(is_video) { } MessageContentType get_type() const override { @@ -906,6 +907,9 @@ static void store(const MessageContent *content, StorerT &storer) { } case MessageContentType::Call: { auto m = static_cast(content); + BEGIN_STORE_FLAGS(); + STORE_FLAG(m->is_video); + END_STORE_FLAGS(); store(m->call_id, storer); store(m->duration, storer); store(m->discard_reason, storer); @@ -1227,6 +1231,13 @@ static void parse(unique_ptr &content, ParserT &parser) { } case MessageContentType::Call: { auto m = make_unique(); + if (parser.version() >= static_cast(Version::AddVideoCallsSupport)) { + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(m->is_video); + END_PARSE_FLAGS(); + } else { + m->is_video = false; + } parse(m->call_id, parser); parse(m->duration, parser); parse(m->discard_reason, parser); @@ -2891,10 +2902,9 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo CHECK(new_file_view.has_remote_location()); CHECK(!new_file_view.remote_location().is_web()); FileId file_id = td->file_manager_->register_remote( - FullRemoteFileLocation(FileType::Photo, new_file_view.remote_location().get_id(), - new_file_view.remote_location().get_access_hash(), 0, 0, 0, DcId::invalid(), - new_file_view.remote_location().get_upload_file_reference().str(), - new_file_view.remote_location().get_download_file_reference().str()), + FullRemoteFileLocation({FileType::Photo, 'i'}, new_file_view.remote_location().get_id(), + new_file_view.remote_location().get_access_hash(), 0, 0, DcId::invalid(), + new_file_view.remote_location().get_upload_file_reference().str()), FileLocationSource::FromServer, dialog_id, old_photo->photos.back().size, 0, ""); LOG_STATUS(td->file_manager_->merge(file_id, old_file_id)); } @@ -3078,7 +3088,7 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo case MessageContentType::Call: { auto old_ = static_cast(old_content); auto new_ = static_cast(new_content); - if (old_->call_id != new_->call_id) { + if (old_->call_id != new_->call_id || old_->is_video != new_->is_video) { is_content_changed = true; } if (old_->duration != new_->duration || old_->discard_reason != new_->discard_reason) { @@ -3330,14 +3340,12 @@ static tl_object_ptr secret_to_telegram(FromT &from); // fileLocationUnavailable#7c596b46 volume_id:long local_id:int secret:long = FileLocation; static auto secret_to_telegram(secret_api::fileLocationUnavailable &file_location) { - return make_tl_object(file_location.volume_id_, file_location.local_id_, - file_location.secret_); + return make_tl_object(file_location.volume_id_, file_location.local_id_); } // fileLocation#53d69076 dc_id:int volume_id:long local_id:int secret:long = FileLocation; static auto secret_to_telegram(secret_api::fileLocation &file_location) { - return make_tl_object(file_location.dc_id_, file_location.volume_id_, - file_location.local_id_, file_location.secret_, BufferSlice()); + return make_tl_object(file_location.volume_id_, file_location.local_id_); } // photoSizeEmpty#e17e23c type:string = PhotoSize; @@ -3353,9 +3361,9 @@ static auto secret_to_telegram(secret_api::photoSize &photo_size) { if (!clean_input_string(photo_size.type_)) { photo_size.type_.clear(); } - return make_tl_object(photo_size.type_, - secret_to_telegram(*photo_size.location_), - photo_size.w_, photo_size.h_, photo_size.size_); + return make_tl_object( + photo_size.type_, secret_to_telegram(*photo_size.location_), + photo_size.w_, photo_size.h_, photo_size.size_); } // photoCachedSize#e9a734fa type:string location:FileLocation w:int h:int bytes:bytes = PhotoSize; @@ -3364,8 +3372,8 @@ static auto secret_to_telegram(secret_api::photoCachedSize &photo_size) { photo_size.type_.clear(); } return make_tl_object( - photo_size.type_, secret_to_telegram(*photo_size.location_), photo_size.w_, - photo_size.h_, photo_size.bytes_.clone()); + photo_size.type_, secret_to_telegram(*photo_size.location_), + photo_size.w_, photo_size.h_, photo_size.bytes_.clone()); } // documentAttributeImageSize #6c37c15c w:int h:int = DocumentAttribute; @@ -4214,7 +4222,9 @@ unique_ptr get_action_message_content(Td *td, tl_object_ptr(action); auto duration = (phone_call->flags_ & telegram_api::messageActionPhoneCall::DURATION_MASK) != 0 ? phone_call->duration_ : 0; - return make_unique(phone_call->call_id_, duration, get_call_discard_reason(phone_call->reason_)); + auto is_video = (phone_call->flags_ & telegram_api::messageActionPhoneCall::VIDEO_MASK) != 0; + return make_unique(phone_call->call_id_, duration, get_call_discard_reason(phone_call->reason_), + is_video); } case telegram_api::messageActionPaymentSent::ID: { LOG_IF(ERROR, td->auth_manager_->is_bot()) << "Receive MessageActionPaymentSent in " << owner_dialog_id; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 66a51913..1a9666d3 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -22185,10 +22185,10 @@ tl_object_ptr MessagesManager::get_chat_event_action_ob case telegram_api::channelAdminLogEventActionChangePhoto::ID: { auto action = move_tl_object_as(action_ptr); auto file_manager = td_->file_manager_.get(); - auto old_photo = td::get_dialog_photo(file_manager, std::move(action->prev_photo_)); - auto new_photo = td::get_dialog_photo(file_manager, std::move(action->new_photo_)); - return make_tl_object(get_chat_photo_object(file_manager, &old_photo), - get_chat_photo_object(file_manager, &new_photo)); + auto old_photo = get_photo(file_manager, std::move(action->prev_photo_), DialogId()); + auto new_photo = get_photo(file_manager, std::move(action->new_photo_), DialogId()); + return make_tl_object(get_photo_object(file_manager, &old_photo), + get_photo_object(file_manager, &new_photo)); } case telegram_api::channelAdminLogEventActionDefaultBannedRights::ID: { auto action = move_tl_object_as(action_ptr); diff --git a/td/telegram/Photo.cpp b/td/telegram/Photo.cpp index f41d24f5..05b35947 100644 --- a/td/telegram/Photo.cpp +++ b/td/telegram/Photo.cpp @@ -95,54 +95,24 @@ td_api::object_ptr get_minithumbnail_object(const string return nullptr; } -static FileId register_photo(FileManager *file_manager, FileType file_type, int64 id, int64 access_hash, - std::string upload_file_reference, - tl_object_ptr &&location_ptr, DialogId owner_dialog_id, - int32 file_size, bool is_webp = false, bool is_png = false) { - DcId dc_id; - int32 local_id; - int64 volume_id; - int64 secret; - std::string download_file_reference; - switch (location_ptr->get_id()) { - case telegram_api::fileLocationUnavailable::ID: { - auto location = move_tl_object_as(location_ptr); - dc_id = DcId::invalid(); - local_id = location->local_id_; - volume_id = location->volume_id_; - secret = location->secret_; - break; - } - case telegram_api::fileLocation::ID: { - auto location = move_tl_object_as(location_ptr); - if (!DcId::is_valid(location->dc_id_)) { - dc_id = DcId::invalid(); - } else { - dc_id = DcId::internal(location->dc_id_); - } - local_id = location->local_id_; - volume_id = location->volume_id_; - secret = location->secret_; - download_file_reference = location->file_reference_.as_slice().str(); - break; - } - default: - UNREACHABLE(); - break; - } - +static FileId register_photo(FileManager *file_manager, const PhotoSizeSource &source, int64 id, int64 access_hash, + std::string file_reference, + tl_object_ptr &&location, + DialogId owner_dialog_id, int32 file_size, DcId dc_id, bool is_webp = false, + bool is_png = false) { + int32 local_id = location->local_id_; + int64 volume_id = location->volume_id_; LOG(DEBUG) << "Receive " << (is_webp ? "webp" : (is_png ? "png" : "jpeg")) << " photo of type " - << static_cast(file_type) << " in [" << dc_id << "," << volume_id << "," << local_id << "]. Id: (" - << id << ", " << access_hash << ")"; + << static_cast(source.file_type) << " in [" << dc_id << "," << volume_id << "," << local_id + << "]. Id: (" << id << ", " << access_hash << ")"; auto suggested_name = PSTRING() << static_cast(volume_id) << "_" << static_cast(local_id) << (is_webp ? ".webp" : (is_png ? ".png" : ".jpg")); - return file_manager->register_remote(FullRemoteFileLocation(file_type, id, access_hash, local_id, volume_id, secret, - dc_id, upload_file_reference, download_file_reference), - FileLocationSource::FromServer, owner_dialog_id, file_size, 0, - std::move(suggested_name)); + return file_manager->register_remote( + FullRemoteFileLocation(source, id, access_hash, local_id, volume_id, dc_id, std::move(file_reference)), + FileLocationSource::FromServer, owner_dialog_id, file_size, 0, std::move(suggested_name)); } -ProfilePhoto get_profile_photo(FileManager *file_manager, +ProfilePhoto get_profile_photo(FileManager *file_manager, UserId user_id, int64 user_access_hash, tl_object_ptr &&profile_photo_ptr) { ProfilePhoto result; int32 profile_photo_id = @@ -153,11 +123,12 @@ ProfilePhoto get_profile_photo(FileManager *file_manager, case telegram_api::userProfilePhoto::ID: { auto profile_photo = move_tl_object_as(profile_photo_ptr); + auto dc_id = DcId::create(profile_photo->dc_id_); result.id = profile_photo->photo_id_; - result.small_file_id = register_photo(file_manager, FileType::ProfilePhoto, result.id, 0, "", - std::move(profile_photo->photo_small_), DialogId(), 0); - result.big_file_id = register_photo(file_manager, FileType::ProfilePhoto, result.id, 0, "", - std::move(profile_photo->photo_big_), DialogId(), 0); + result.small_file_id = register_photo(file_manager, {DialogId(user_id), user_access_hash, false}, result.id, 0, + "", std::move(profile_photo->photo_small_), DialogId(), 0, dc_id); + result.big_file_id = register_photo(file_manager, {DialogId(user_id), user_access_hash, true}, result.id, 0, "", + std::move(profile_photo->photo_big_), DialogId(), 0, dc_id); break; } default: @@ -205,7 +176,8 @@ StringBuilder &operator<<(StringBuilder &string_builder, const ProfilePhoto &pro << ", big_file_id = " << profile_photo.big_file_id << ">"; } -DialogPhoto get_dialog_photo(FileManager *file_manager, tl_object_ptr &&chat_photo_ptr) { +DialogPhoto get_dialog_photo(FileManager *file_manager, DialogId dialog_id, int64 dialog_access_hash, + tl_object_ptr &&chat_photo_ptr) { int32 chat_photo_id = chat_photo_ptr == nullptr ? telegram_api::chatPhotoEmpty::ID : chat_photo_ptr->get_id(); DialogPhoto result; @@ -215,10 +187,11 @@ DialogPhoto get_dialog_photo(FileManager *file_manager, tl_object_ptr(chat_photo_ptr); - result.small_file_id = register_photo(file_manager, FileType::ProfilePhoto, 0, 0, "", - std::move(chat_photo->photo_small_), DialogId(), 0); - result.big_file_id = register_photo(file_manager, FileType::ProfilePhoto, 0, 0, "", - std::move(chat_photo->photo_big_), DialogId(), 0); + auto dc_id = DcId::create(chat_photo->dc_id_); + result.small_file_id = register_photo(file_manager, {dialog_id, dialog_access_hash, false}, 0, 0, "", + std::move(chat_photo->photo_small_), DialogId(), 0, dc_id); + result.big_file_id = register_photo(file_manager, {dialog_id, dialog_access_hash, true}, 0, 0, "", + std::move(chat_photo->photo_big_), DialogId(), 0, dc_id); break; } @@ -249,6 +222,25 @@ vector dialog_photo_get_file_ids(const DialogPhoto &dialog_photo) { return result; } +DialogPhoto as_dialog_photo(const Photo &photo) { + DialogPhoto result; + if (photo.id != -2) { + for (auto &size : photo.photos) { + if (size.type == 'a') { + result.small_file_id = size.file_id; + } else if (size.type == 'c') { + result.big_file_id = size.file_id; + } + } + if (!result.small_file_id.is_valid() || !result.big_file_id.is_valid()) { + LOG(ERROR) << "Failed to convert " << photo << " to chat photo"; + return DialogPhoto(); + } + } + + return result; +} + bool operator==(const DialogPhoto &lhs, const DialogPhoto &rhs) { return lhs.small_file_id == rhs.small_file_id && lhs.big_file_id == rhs.big_file_id; } @@ -276,9 +268,10 @@ PhotoSize get_secret_thumbnail_photo_size(FileManager *file_manager, BufferSlice auto dc_id = DcId::invalid(); auto local_id = Random::secure_int32(); auto volume_id = Random::secure_int64(); - auto secret = 0; + res.file_id = file_manager->register_remote( - FullRemoteFileLocation(FileType::EncryptedThumbnail, 0, 0, local_id, volume_id, secret, dc_id, "", ""), + FullRemoteFileLocation(PhotoSizeSource(FileType::EncryptedThumbnail, 't'), 0, 0, local_id, volume_id, dc_id, + string()), FileLocationSource::FromServer, owner_dialog_id, res.size, 0, PSTRING() << static_cast(volume_id) << "_" << static_cast(local_id) << ".jpg"); file_manager->set_content(res.file_id, std::move(bytes)); @@ -286,13 +279,13 @@ PhotoSize get_secret_thumbnail_photo_size(FileManager *file_manager, BufferSlice return res; } -Variant get_photo_size(FileManager *file_manager, FileType file_type, int64 id, int64 access_hash, - std::string upload_file_reference, DialogId owner_dialog_id, - tl_object_ptr &&size_ptr, bool is_webp, - bool is_png) { +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, + bool is_webp, bool is_png) { CHECK(size_ptr != nullptr); - tl_object_ptr location_ptr; + tl_object_ptr location; string type; PhotoSize res; BufferSlice content; @@ -303,7 +296,7 @@ Variant get_photo_size(FileManager *file_manager, FileType fi auto size = move_tl_object_as(size_ptr); type = std::move(size->type_); - location_ptr = std::move(size->location_); + location = std::move(size->location_); res.dimensions = get_dimensions(size->w_, size->h_); res.size = size->size_; @@ -313,7 +306,7 @@ Variant get_photo_size(FileManager *file_manager, FileType fi auto size = move_tl_object_as(size_ptr); type = std::move(size->type_); - location_ptr = std::move(size->location_); + location = std::move(size->location_); CHECK(size->bytes_.size() <= static_cast(std::numeric_limits::max())); res.dimensions = get_dimensions(size->w_, size->h_); res.size = static_cast(size->bytes_.size()); @@ -331,20 +324,23 @@ Variant get_photo_size(FileManager *file_manager, FileType fi break; } - res.file_id = register_photo(file_manager, file_type, id, access_hash, upload_file_reference, std::move(location_ptr), - owner_dialog_id, res.size, is_webp, is_png); + if (type.size() != 1) { + res.type = 0; + LOG(ERROR) << "Wrong photoSize \"" << type << "\" " << res; + } else { + res.type = static_cast(type[0]); + } + if (source.type == PhotoSizeSource::Type::Thumbnail) { + source.thumbnail_type = res.type; + } + + res.file_id = register_photo(file_manager, source, id, access_hash, file_reference, std::move(location), + owner_dialog_id, res.size, dc_id, is_webp, is_png); if (!content.empty()) { file_manager->set_content(res.file_id, std::move(content)); } - if (type.size() != 1) { - res.type = 0; - LOG(ERROR) << "Wrong photoSize " << res; - } else { - res.type = static_cast(type[0]); - } - return std::move(res); } @@ -488,14 +484,8 @@ StringBuilder &operator<<(StringBuilder &string_builder, const PhotoSize &photo_ Photo get_photo(FileManager *file_manager, tl_object_ptr &&file, tl_object_ptr &&photo, DialogId owner_dialog_id) { - DcId dc_id; - if (!DcId::is_valid(file->dc_id_)) { - dc_id = DcId::invalid(); - } else { - dc_id = DcId::internal(file->dc_id_); - } FileId file_id = file_manager->register_remote( - FullRemoteFileLocation(FileType::Encrypted, file->id_, file->access_hash_, dc_id, ""), + FullRemoteFileLocation(FileType::Encrypted, file->id_, file->access_hash_, DcId::create(file->dc_id_), string()), FileLocationSource::FromServer, owner_dialog_id, photo->size_, 0, PSTRING() << static_cast(file->id_) << ".jpg"); file_manager->set_encryption_key(file_id, FileEncryptionKey{photo->key_.as_slice(), photo->iv_.as_slice()}); @@ -518,6 +508,16 @@ Photo get_photo(FileManager *file_manager, tl_object_ptr &&photo, DialogId owner_dialog_id) { + if (photo == nullptr || photo->get_id() == telegram_api::photoEmpty::ID) { + Photo result; + result.id = -2; + return result; + } + CHECK(photo->get_id() == telegram_api::photo::ID); + return get_photo(file_manager, move_tl_object_as(photo), owner_dialog_id); +} + Photo get_photo(FileManager *file_manager, tl_object_ptr &&photo, DialogId owner_dialog_id) { Photo res; @@ -526,9 +526,9 @@ Photo get_photo(FileManager *file_manager, tl_object_ptr && res.has_stickers = (photo->flags_ & telegram_api::photo::HAS_STICKERS_MASK) != 0; for (auto &size_ptr : photo->sizes_) { - auto photo_size = - get_photo_size(file_manager, FileType::Photo, photo->id_, photo->access_hash_, - photo->file_reference_.as_slice().str(), owner_dialog_id, std::move(size_ptr), false, false); + auto photo_size = get_photo_size(file_manager, {FileType::Photo, 0}, photo->id_, photo->access_hash_, + photo->file_reference_.as_slice().str(), DcId::create(photo->dc_id_), + owner_dialog_id, std::move(size_ptr), false, false); if (photo_size.get_offset() == 0) { res.photos.push_back(std::move(photo_size.get<0>())); } else { @@ -716,31 +716,20 @@ StringBuilder &operator<<(StringBuilder &string_builder, const Photo &photo) { return string_builder << "[id = " << photo.id << ", photos = " << format::as_array(photo.photos) << "]"; } -static tl_object_ptr copy_location( - const tl_object_ptr &location_ptr) { - CHECK(location_ptr != nullptr); - switch (location_ptr->get_id()) { - case telegram_api::fileLocationUnavailable::ID: { - auto location = static_cast(location_ptr.get()); - return make_tl_object(location->volume_id_, location->local_id_, - location->secret_); - } - case telegram_api::fileLocation::ID: { - auto location = static_cast(location_ptr.get()); - return make_tl_object(location->dc_id_, location->volume_id_, location->local_id_, - location->secret_, location->file_reference_.clone()); - } - default: - UNREACHABLE(); - return nullptr; - } +static tl_object_ptr copy_location( + const tl_object_ptr &location) { + CHECK(location != nullptr); + return make_tl_object(location->volume_id_, location->local_id_); } tl_object_ptr convert_photo_to_profile_photo( const tl_object_ptr &photo) { - CHECK(photo != nullptr); - tl_object_ptr photo_small; - tl_object_ptr photo_big; + if (photo == nullptr) { + return nullptr; + } + + tl_object_ptr photo_small; + tl_object_ptr photo_big; for (auto &size_ptr : photo->sizes_) { switch (size_ptr->get_id()) { case telegram_api::photoSizeEmpty::ID: @@ -773,7 +762,8 @@ tl_object_ptr convert_photo_to_profile_photo( if (photo_small == nullptr || photo_big == nullptr) { return nullptr; } - return make_tl_object(photo->id_, std::move(photo_small), std::move(photo_big)); + return make_tl_object(photo->id_, std::move(photo_small), std::move(photo_big), + photo->dc_id_); } } // namespace td diff --git a/td/telegram/Photo.h b/td/telegram/Photo.h index a8bd4b5c..3454e819 100644 --- a/td/telegram/Photo.h +++ b/td/telegram/Photo.h @@ -9,7 +9,9 @@ #include "td/telegram/DialogId.h" #include "td/telegram/files/FileId.h" #include "td/telegram/files/FileType.h" +#include "td/telegram/net/DcId.h" #include "td/telegram/SecretInputMedia.h" +#include "td/telegram/UserId.h" #include "td/telegram/secret_api.h" #include "td/telegram/td_api.h" @@ -45,6 +47,41 @@ struct PhotoSize { FileId file_id; }; +struct PhotoSizeSource { + enum class Type : int32 { Thumbnail, DialogPhoto, StickerSetThumbnail }; + Type type; + FileType file_type; + + // for photos, document thumbnails, encrypted thumbnails + int32 thumbnail_type = 0; + + // for dialog photos + DialogId dialog_id; + int64 dialog_access_hash = 0; + bool is_big = false; + + // for sticker set thumbnails + int64 sticker_set_id = 0; + int64 sticker_set_access_hash = 0; + + PhotoSizeSource(FileType file_type, int32 thumbnail_type) + : type(Type::Thumbnail), file_type(file_type), thumbnail_type(thumbnail_type) { + } + PhotoSizeSource(DialogId dialog_id, int64 dialog_access_hash, bool is_big) + : type(Type::DialogPhoto) + , file_type(FileType::ProfilePhoto) + , dialog_id(dialog_id) + , dialog_access_hash(dialog_access_hash) + , is_big(is_big) { + } + PhotoSizeSource(int64 sticker_set_id, int64 sticker_set_access_hash) + : type(Type::StickerSetThumbnail) + , file_type(FileType::Thumbnail) + , sticker_set_id(sticker_set_id) + , sticker_set_access_hash(sticker_set_access_hash) { + } +}; + struct Photo { int64 id = 0; int32 date = 0; @@ -64,7 +101,7 @@ StringBuilder &operator<<(StringBuilder &string_builder, const Dimensions &dimen td_api::object_ptr get_minithumbnail_object(const string &packed); -ProfilePhoto get_profile_photo(FileManager *file_manager, +ProfilePhoto get_profile_photo(FileManager *file_manager, UserId user_id, int64 user_access_hash, tl_object_ptr &&profile_photo_ptr); tl_object_ptr get_profile_photo_object(FileManager *file_manager, const ProfilePhoto *profile_photo); @@ -74,9 +111,12 @@ bool operator!=(const ProfilePhoto &lhs, const ProfilePhoto &rhs); StringBuilder &operator<<(StringBuilder &string_builder, const ProfilePhoto &profile_photo); -DialogPhoto get_dialog_photo(FileManager *file_manager, tl_object_ptr &&chat_photo_ptr); +DialogPhoto get_dialog_photo(FileManager *file_manager, DialogId dialog_id, int64 dialog_access_hash, + tl_object_ptr &&chat_photo_ptr); tl_object_ptr get_chat_photo_object(FileManager *file_manager, const DialogPhoto *dialog_photo); +DialogPhoto as_dialog_photo(const Photo &photo); + vector dialog_photo_get_file_ids(const DialogPhoto &dialog_photo); bool operator==(const DialogPhoto &lhs, const DialogPhoto &rhs); @@ -86,9 +126,10 @@ StringBuilder &operator<<(StringBuilder &string_builder, const DialogPhoto &dial PhotoSize get_secret_thumbnail_photo_size(FileManager *file_manager, BufferSlice bytes, DialogId owner_dialog_id, int32 width, int32 height); -Variant get_photo_size(FileManager *file_manager, FileType file_type, int64 id, int64 access_hash, - std::string upload_file_reference, DialogId owner_dialog_id, - tl_object_ptr &&size_ptr, bool is_webp, bool is_png); +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, + bool is_webp, bool is_png); PhotoSize get_web_document_photo_size(FileManager *file_manager, FileType file_type, DialogId owner_dialog_id, tl_object_ptr web_document_ptr); td_api::object_ptr get_photo_size_object(FileManager *file_manager, const PhotoSize *photo_size); @@ -102,6 +143,7 @@ bool operator<(const PhotoSize &lhs, const PhotoSize &rhs); StringBuilder &operator<<(StringBuilder &string_builder, const PhotoSize &photo_size); +Photo get_photo(FileManager *file_manager, tl_object_ptr &&photo, DialogId owner_dialog_id); Photo get_photo(FileManager *file_manager, tl_object_ptr &&photo, DialogId owner_dialog_id); Photo get_photo(FileManager *file_manager, tl_object_ptr &&file, tl_object_ptr &&photo, DialogId owner_dialog_id); diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 62d33d81..2312293c 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -1248,6 +1248,7 @@ std::pair StickersManager::on_get_sticker_document(tl_object_ptr< LOG(ERROR) << "Wrong dc_id = " << document->dc_id_ << " in document " << to_string(document); return {}; } + auto dc_id = DcId::internal(document->dc_id_); Dimensions dimensions; tl_object_ptr sticker; @@ -1272,13 +1273,13 @@ std::pair StickersManager::on_get_sticker_document(tl_object_ptr< int64 document_id = document->id_; FileId sticker_id = td_->file_manager_->register_remote( - FullRemoteFileLocation(FileType::Sticker, document_id, document->access_hash_, DcId::internal(document->dc_id_), + FullRemoteFileLocation(FileType::Sticker, document_id, document->access_hash_, dc_id, document->file_reference_.as_slice().str()), FileLocationSource::FromServer, DialogId(), document->size_, 0, PSTRING() << document_id << ".webp"); PhotoSize thumbnail; for (auto &thumb : document->thumbs_) { - auto photo_size = get_photo_size(td_->file_manager_.get(), FileType::Thumbnail, 0, 0, "", DialogId(), + auto photo_size = get_photo_size(td_->file_manager_.get(), {FileType::Thumbnail, 0}, 0, 0, "", dc_id, DialogId(), std::move(thumb), has_webp_thumbnail(sticker), false); if (photo_size.get_offset() == 0) { thumbnail = std::move(photo_size.get<0>()); @@ -1732,8 +1733,8 @@ int64 StickersManager::on_get_sticker_set(tl_object_ptrthumb_ != nullptr) { - auto photo_size = get_photo_size(td_->file_manager_.get(), FileType::Thumbnail, 0, 0, "", DialogId(), - std::move(set->thumb_), true, false); + auto photo_size = get_photo_size(td_->file_manager_.get(), {set_id, s->access_hash}, 0, 0, "", + DcId::create(set->thumb_dc_id_), DialogId(), std::move(set->thumb_), true, false); if (photo_size.get_offset() == 0) { thumbnail = std::move(photo_size.get<0>()); } else { diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index d87aa881..e52d60b2 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -5736,14 +5736,14 @@ void Td::on_request(uint64 id, td_api::createCall &request) { } send_closure(G()->call_manager(), &CallManager::create_call, user_id, std::move(input_user), - CallProtocol::from_td_api(*request.protocol_), std::move(query_promise)); + CallProtocol::from_td_api(*request.protocol_), false, std::move(query_promise)); } void Td::on_request(uint64 id, td_api::discardCall &request) { CHECK_IS_USER(); CREATE_OK_REQUEST_PROMISE(); send_closure(G()->call_manager(), &CallManager::discard_call, CallId(request.call_id_), request.is_disconnected_, - request.duration_, request.connection_id_, std::move(promise)); + request.duration_, false, request.connection_id_, std::move(promise)); } void Td::on_request(uint64 id, td_api::acceptCall &request) { diff --git a/td/telegram/Version.h b/td/telegram/Version.h index b2e7abbb..2599256f 100644 --- a/td/telegram/Version.h +++ b/td/telegram/Version.h @@ -30,6 +30,7 @@ enum class Version : int32 { SupportInstantView2_0, AddNotificationGroupInfoMaxRemovedMessageId, SupportMinithumbnails, + AddVideoCallsSupport, Next }; diff --git a/td/telegram/WebPageBlock.cpp b/td/telegram/WebPageBlock.cpp index f962e5e6..f8ef18fa 100644 --- a/td/telegram/WebPageBlock.cpp +++ b/td/telegram/WebPageBlock.cpp @@ -2023,8 +2023,11 @@ unique_ptr get_web_page_block(Td *td, tl_object_ptrcontacts_manager_->get_channel_dialog_photo(channel_id), td->contacts_manager_->get_channel_username(channel_id)); } else { + bool has_access_hash = (channel->flags_ & telegram_api::channel::ACCESS_HASH_MASK) != 0; return td::make_unique( - std::move(channel->title_), get_dialog_photo(td->file_manager_.get(), std::move(channel->photo_)), + std::move(channel->title_), + get_dialog_photo(td->file_manager_.get(), DialogId(channel_id), + has_access_hash ? channel->access_hash_ : 0, std::move(channel->photo_)), std::move(channel->username_)); } } else { diff --git a/td/telegram/files/FileLocation.h b/td/telegram/files/FileLocation.h index 3e54f5fa..cbc2e73f 100644 --- a/td/telegram/files/FileLocation.h +++ b/td/telegram/files/FileLocation.h @@ -11,6 +11,7 @@ #include "td/telegram/files/FileBitmask.h" #include "td/telegram/files/FileType.h" #include "td/telegram/net/DcId.h" +#include "td/telegram/Photo.h" #include "td/utils/base64.h" #include "td/utils/buffer.h" @@ -345,6 +346,14 @@ class FullRemoteFileLocation { return type; } + void check_file_reference() { + FileReferenceView view(file_reference_); + if (!(view.has_upload() && view.has_download())) { + LOG(ERROR) << "Tried to register file with invalid file reference"; + file_reference_.clear(); + } + } + public: template void store(StorerT &storer) const; @@ -476,7 +485,8 @@ class FullRemoteFileLocation { return make_tl_object(common().id_, common().access_hash_); } else { return make_tl_object( - common().id_, common().access_hash_, BufferSlice(FileReferenceView(file_reference_).download())); + common().id_, common().access_hash_, BufferSlice(FileReferenceView(file_reference_).download()), + string()); } case LocationType::Web: case LocationType::None: @@ -514,31 +524,29 @@ class FullRemoteFileLocation { // TODO: this constructor is just for immediate unserialize FullRemoteFileLocation() = default; - FullRemoteFileLocation(FileType file_type, int64 id, int64 access_hash, int32 local_id, int64 volume_id, int64 secret, - DcId dc_id, std::string upload_file_reference, std::string download_file_reference) - : file_type_(file_type) + + // photo + FullRemoteFileLocation(const PhotoSizeSource &source, int64 id, int64 access_hash, int32 local_id, int64 volume_id, + DcId dc_id, std::string file_reference) + : file_type_(source.file_type) , dc_id_(dc_id) - , file_reference_(FileReferenceView::create_two(upload_file_reference, download_file_reference)) - , variant_(PhotoRemoteFileLocation{id, access_hash, volume_id, secret, local_id}) { + , file_reference_(FileReferenceView::create_one(file_reference)) + , variant_(PhotoRemoteFileLocation{id, access_hash, volume_id, -1, local_id}) { // TODO(now) use source CHECK(is_photo()); - FileReferenceView view(file_reference_); - if (!(view.has_upload() && view.has_download())) { - LOG(ERROR) << "Tried to register file with invalid file reference"; - file_reference_.clear(); - } + check_file_reference(); } + + // document FullRemoteFileLocation(FileType file_type, int64 id, int64 access_hash, DcId dc_id, std::string file_reference) : file_type_(file_type) , dc_id_(dc_id) , file_reference_(FileReferenceView::create_one(file_reference)) , variant_(CommonRemoteFileLocation{id, access_hash}) { CHECK(is_common()); - FileReferenceView view(file_reference_); - if (!(view.has_upload() && view.has_download())) { - LOG(ERROR) << "Tried to register file with invalid file reference"; - file_reference_.clear(); - } + check_file_reference(); } + + // web document FullRemoteFileLocation(FileType file_type, string url, int64 access_hash) : file_type_(file_type) , web_location_flag_{true} @@ -648,14 +656,6 @@ class RemoteFileLocation { } explicit RemoteFileLocation(const PartialRemoteFileLocation &partial) : variant_(partial) { } - RemoteFileLocation(FileType file_type, int64 id, int64 access_hash, int32 local_id, int64 volume_id, int64 secret, - DcId dc_id, std::string upload_file_reference, std::string download_file_reference) - : variant_(FullRemoteFileLocation{file_type, id, access_hash, local_id, volume_id, secret, dc_id, - std::move(upload_file_reference), std::move(download_file_reference)}) { - } - RemoteFileLocation(FileType file_type, int64 id, int64 access_hash, DcId dc_id, std::string file_reference) - : variant_(FullRemoteFileLocation{file_type, id, access_hash, dc_id, std::move(file_reference)}) { - } private: Variant variant_; diff --git a/td/telegram/net/DcId.h b/td/telegram/net/DcId.h index d61546d1..8ad7a017 100644 --- a/td/telegram/net/DcId.h +++ b/td/telegram/net/DcId.h @@ -40,6 +40,13 @@ class DcId { static DcId from_value(int32 value) { return DcId{value, false}; } + static DcId create(int32 dc_id_value) { + if (DcId::is_valid(dc_id_value)) { + return DcId(dc_id_value, true); + } else { + return DcId::invalid(); + } + } bool is_empty() const { return !is_valid(); diff --git a/td/telegram/net/MtprotoHeader.cpp b/td/telegram/net/MtprotoHeader.cpp index 3f5232cb..af639964 100644 --- a/td/telegram/net/MtprotoHeader.cpp +++ b/td/telegram/net/MtprotoHeader.cpp @@ -21,7 +21,7 @@ class HeaderStorer { } template void store(StorerT &storer) const { - constexpr int32 LAYER = 97; + constexpr int32 LAYER = 98; using td::store; // invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;