diff --git a/Telegram/SourceFiles/calls/calls_call.cpp b/Telegram/SourceFiles/calls/calls_call.cpp index 7a55991dbd..3a34f07836 100644 --- a/Telegram/SourceFiles/calls/calls_call.cpp +++ b/Telegram/SourceFiles/calls/calls_call.cpp @@ -303,7 +303,6 @@ void Call::startOutgoing() { _api.request(MTPphone_RequestCall( MTP_flags(flags), _user->inputUser, - MTPInputGroupCall(), MTP_int(base::RandomValue()), MTP_bytes(_gaHash), MTP_phoneCallProtocol( diff --git a/Telegram/SourceFiles/calls/group/calls_group_call.cpp b/Telegram/SourceFiles/calls/group/calls_group_call.cpp index ce0fddd314..3ab9bfb314 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_call.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_call.cpp @@ -1428,7 +1428,7 @@ void GroupCall::rejoin(not_null as) { ? Flag::f_video_stopped : Flag(0)) | (_conferenceJoinMessageId ? Flag::f_invite_msg_id : Flag()) - | (_e2e ? Flag::f_public_key : Flag()); + | (_e2e ? (Flag::f_public_key | Flag::f_block) : Flag()); _api.request(MTPphone_JoinGroupCall( MTP_flags(flags), (_conferenceLinkSlug.isEmpty() @@ -1438,6 +1438,10 @@ void GroupCall::rejoin(not_null as) { joinAs()->input, MTP_string(_joinHash), (_e2e ? TdE2E::PublicKeyToMTP(_e2e->myKey()) : MTPint256()), + (_e2e + ? MTP_bytes( + _e2e->lastBlock0().value_or(TdE2E::Block()).data) + : MTPbytes()), MTP_int(_conferenceJoinMessageId.bare), MTP_dataJSON(MTP_bytes(json)) )).done([=]( diff --git a/Telegram/SourceFiles/calls/group/calls_group_menu.cpp b/Telegram/SourceFiles/calls/group/calls_group_menu.cpp index 51a9068a73..277c64356e 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_menu.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_menu.cpp @@ -490,11 +490,12 @@ void FillMenu( Fn)> showBox) { const auto weak = base::make_weak(call); const auto resolveReal = [=] { - const auto real = peer->groupCall(); - const auto strong = weak.get(); - return (real && strong && (real->id() == strong->id())) - ? real - : nullptr; + if (const auto strong = weak.get()) { + if (const auto real = strong->lookupReal()) { + return real; + } + } + return (Data::GroupCall*)nullptr; }; const auto real = resolveReal(); if (!real) { diff --git a/Telegram/SourceFiles/data/data_media_types.cpp b/Telegram/SourceFiles/data/data_media_types.cpp index 2be78e44fc..067e8af492 100644 --- a/Telegram/SourceFiles/data/data_media_types.cpp +++ b/Telegram/SourceFiles/data/data_media_types.cpp @@ -467,8 +467,8 @@ Call ComputeCallData(const MTPDmessageActionPhoneCall &call) { return CallFinishReason::Hangup; }, [](const MTPDphoneCallDiscardReasonMissed &) { return CallFinishReason::Missed; - }, [](const MTPDphoneCallDiscardReasonAllowGroupCall &) { - return CallFinishReason::AllowGroupCall; + }, [](const MTPDphoneCallDiscardReasonMigrateConferenceCall &) { + return CallFinishReason::MigrateConferenceCall; }); Unexpected("Call reason type."); } diff --git a/Telegram/SourceFiles/data/data_media_types.h b/Telegram/SourceFiles/data/data_media_types.h index b6e2a32bbd..14452c7972 100644 --- a/Telegram/SourceFiles/data/data_media_types.h +++ b/Telegram/SourceFiles/data/data_media_types.h @@ -46,7 +46,7 @@ enum class CallFinishReason : char { Busy, Disconnected, Hangup, - AllowGroupCall, + MigrateConferenceCall, }; struct SharedContact final { diff --git a/Telegram/SourceFiles/export/data/export_data_types.cpp b/Telegram/SourceFiles/export/data/export_data_types.cpp index e9a91b434f..919b35f8ef 100644 --- a/Telegram/SourceFiles/export/data/export_data_types.cpp +++ b/Telegram/SourceFiles/export/data/export_data_types.cpp @@ -1471,8 +1471,8 @@ ServiceAction ParseServiceAction( return Reason::Hangup; }, [](const MTPDphoneCallDiscardReasonBusy &data) { return Reason::Busy; - }, [](const MTPDphoneCallDiscardReasonAllowGroupCall &) { - return Reason::AllowGroupCall; + }, [](const MTPDphoneCallDiscardReasonMigrateConferenceCall &) { + return Reason::MigrateConferenceCall; }); } result.content = content; diff --git a/Telegram/SourceFiles/export/data/export_data_types.h b/Telegram/SourceFiles/export/data/export_data_types.h index afdf7251bf..3b37de23d9 100644 --- a/Telegram/SourceFiles/export/data/export_data_types.h +++ b/Telegram/SourceFiles/export/data/export_data_types.h @@ -503,7 +503,7 @@ struct ActionPhoneCall { Disconnect, Hangup, Busy, - AllowGroupCall, + MigrateConferenceCall, }; DiscardReason discardReason = DiscardReason::Unknown; int duration = 0; diff --git a/Telegram/SourceFiles/export/output/export_output_json.cpp b/Telegram/SourceFiles/export/output/export_output_json.cpp index e8d083dfb7..5e263e60d3 100644 --- a/Telegram/SourceFiles/export/output/export_output_json.cpp +++ b/Telegram/SourceFiles/export/output/export_output_json.cpp @@ -472,6 +472,8 @@ QByteArray SerializeMessage( case Reason::Disconnect: return "disconnect"; case Reason::Hangup: return "hangup"; case Reason::Missed: return "missed"; + case Reason::MigrateConferenceCall: + return "migrate_conference_all"; } return ""; }()); diff --git a/Telegram/SourceFiles/mtproto/scheme/api.tl b/Telegram/SourceFiles/mtproto/scheme/api.tl index ec6d3baef5..71bf5182ad 100644 --- a/Telegram/SourceFiles/mtproto/scheme/api.tl +++ b/Telegram/SourceFiles/mtproto/scheme/api.tl @@ -903,7 +903,7 @@ phoneCallDiscardReasonMissed#85e42301 = PhoneCallDiscardReason; phoneCallDiscardReasonDisconnect#e095c1a0 = PhoneCallDiscardReason; phoneCallDiscardReasonHangup#57adc690 = PhoneCallDiscardReason; phoneCallDiscardReasonBusy#faf7e8c9 = PhoneCallDiscardReason; -phoneCallDiscardReasonAllowGroupCall#afe2b839 encrypted_key:bytes = PhoneCallDiscardReason; +phoneCallDiscardReasonMigrateConferenceCall#9fbbf1f7 slug:string = PhoneCallDiscardReason; dataJSON#7d748d04 data:string = DataJSON; @@ -958,11 +958,11 @@ inputStickerSetItem#32da9e9c flags:# document:InputDocument emoji:string mask_co inputPhoneCall#1e36fded id:long access_hash:long = InputPhoneCall; phoneCallEmpty#5366c915 id:long = PhoneCall; -phoneCallWaiting#eed42858 flags:# video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long protocol:PhoneCallProtocol receive_date:flags.0?int conference_call:flags.8?InputGroupCall = PhoneCall; -phoneCallRequested#45361c63 flags:# video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_a_hash:bytes protocol:PhoneCallProtocol conference_call:flags.8?InputGroupCall = PhoneCall; -phoneCallAccepted#22fd7181 flags:# video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_b:bytes protocol:PhoneCallProtocol conference_call:flags.8?InputGroupCall = PhoneCall; -phoneCall#3ba5940c flags:# p2p_allowed:flags.5?true video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connections:Vector start_date:int custom_parameters:flags.7?DataJSON conference_call:flags.8?InputGroupCall = PhoneCall; -phoneCallDiscarded#f9d25503 flags:# need_rating:flags.2?true need_debug:flags.3?true video:flags.6?true id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int conference_call:flags.8?InputGroupCall = PhoneCall; +phoneCallWaiting#c5226f17 flags:# video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long protocol:PhoneCallProtocol receive_date:flags.0?int = PhoneCall; +phoneCallRequested#14b0ed0c flags:# video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_a_hash:bytes protocol:PhoneCallProtocol = PhoneCall; +phoneCallAccepted#3660c311 flags:# video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_b:bytes protocol:PhoneCallProtocol = PhoneCall; +phoneCall#30535af5 flags:# p2p_allowed:flags.5?true video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connections:Vector start_date:int custom_parameters:flags.7?DataJSON = PhoneCall; +phoneCallDiscarded#50ca4de1 flags:# need_rating:flags.2?true need_debug:flags.3?true video:flags.6?true id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = PhoneCall; phoneConnection#9cc123c7 flags:# tcp:flags.0?true id:long ip:string ipv6:string port:int peer_tag:bytes = PhoneConnection; phoneConnectionWebrtc#635fe375 flags:# turn:flags.0?true stun:flags.1?true id:long ip:string ipv6:string port:int username:string password:string = PhoneConnection; @@ -2576,7 +2576,7 @@ stickers.deleteStickerSet#87704394 stickerset:InputStickerSet = Bool; stickers.replaceSticker#4696459a sticker:InputDocument new_sticker:InputStickerSetItem = messages.StickerSet; phone.getCallConfig#55451fa9 = DataJSON; -phone.requestCall#a6c4600c flags:# video:flags.0?true user_id:InputUser conference_call:flags.1?InputGroupCall 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; @@ -2585,7 +2585,7 @@ phone.setCallRating#59ead627 flags:# user_initiative:flags.0?true peer:InputPhon phone.saveCallDebug#277add7e peer:InputPhoneCall debug:DataJSON = Bool; phone.sendSignalingData#ff7a9383 peer:InputPhoneCall data:bytes = Bool; phone.createGroupCall#48cdc6d8 flags:# rtmp_stream:flags.2?true peer:InputPeer random_id:int title:flags.0?string schedule_date:flags.1?int = Updates; -phone.joinGroupCall#ffae43f4 flags:# muted:flags.0?true video_stopped:flags.2?true call:InputGroupCall join_as:InputPeer invite_hash:flags.1?string public_key:flags.3?int256 invite_msg_id:flags.4?int params:DataJSON = Updates; +phone.joinGroupCall#dac17b9e flags:# muted:flags.0?true video_stopped:flags.2?true call:InputGroupCall join_as:InputPeer invite_hash:flags.1?string public_key:flags.3?int256 block:flags.3?bytes invite_msg_id:flags.4?int params:DataJSON = Updates; phone.leaveGroupCall#500377f9 call:InputGroupCall source:int = Updates; phone.inviteToGroupCall#7b393160 call:InputGroupCall users:Vector = Updates; phone.discardGroupCall#7a777135 call:InputGroupCall = Updates; @@ -2607,7 +2607,6 @@ phone.getGroupCallStreamChannels#1ab21940 call:InputGroupCall = phone.GroupCallS phone.getGroupCallStreamRtmpUrl#deb3abbf peer:InputPeer revoke:Bool = phone.GroupCallStreamRtmpUrl; phone.saveCallLog#41248786 peer:InputPhoneCall file:InputFile = Bool; phone.createConferenceCall#dae2632f public_key:int256 zero_block:bytes = phone.GroupCall; -phone.addConferenceCallParticipant#3cb2a504 call:InputGroupCall peer:InputPeer block:bytes = Updates; phone.deleteConferenceCallParticipant#7b8cc2a3 call:InputGroupCall peer:InputPeer block:bytes = Updates; phone.sendConferenceCallBroadcast#c6701900 call:InputGroupCall block:bytes = Updates; phone.inviteConferenceCallParticipant#3e9cf7ee call:InputGroupCall user_id:InputUser = Updates; diff --git a/Telegram/SourceFiles/tde2e/tde2e_api.cpp b/Telegram/SourceFiles/tde2e/tde2e_api.cpp index 23bdc6bc08..190247a8bc 100644 --- a/Telegram/SourceFiles/tde2e/tde2e_api.cpp +++ b/Telegram/SourceFiles/tde2e/tde2e_api.cpp @@ -109,6 +109,10 @@ void Call::apply( bool fromShortPoll) { Expects(subchain >= 0 && subchain < kSubChainsCount); + if (!subchain && index >= _lastBlock0Height) { + _lastBlock0 = block; + _lastBlock0Height = index; + } if (!subchain && !_id.v) { create(block); } @@ -213,6 +217,10 @@ rpl::producer Call::failures() const { return _failures.events(); } +const std::optional &Call::lastBlock0() const { + return _lastBlock0; +} + std::vector Call::encrypt(const std::vector &data) const { const auto result = tde2e_api::call_encrypt( std::int64_t(_id.v), diff --git a/Telegram/SourceFiles/tde2e/tde2e_api.h b/Telegram/SourceFiles/tde2e/tde2e_api.h index 17634d9835..5385a8681c 100644 --- a/Telegram/SourceFiles/tde2e/tde2e_api.h +++ b/Telegram/SourceFiles/tde2e/tde2e_api.h @@ -75,6 +75,8 @@ public: [[nodiscard]] std::optional failed() const; [[nodiscard]] rpl::producer failures() const; + [[nodiscard]] const std::optional &lastBlock0() const; + [[nodiscard]] std::vector encrypt( const std::vector &data) const; [[nodiscard]] std::vector decrypt( @@ -107,6 +109,9 @@ private: SubChainState _subchains[kSubChainsCount]; rpl::event_stream _subchainRequests; + std::optional _lastBlock0; + int _lastBlock0Height = 0; + }; } // namespace TdE2E