diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 23b203112..fe7d9a9b0 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -755,8 +755,6 @@ PRIVATE mtproto/connection_tcp.cpp mtproto/connection_tcp.h mtproto/core_types.h - mtproto/dc_options.cpp - mtproto/dc_options.h mtproto/dedicated_file_loader.cpp mtproto/dedicated_file_loader.h mtproto/facade.cpp @@ -912,6 +910,8 @@ PRIVATE storage/serialize_common.h storage/serialize_document.cpp storage/serialize_document.h + storage/serialize_peer.cpp + storage/serialize_peer.h storage/storage_account.cpp storage/storage_account.h storage/storage_accounts.cpp diff --git a/Telegram/SourceFiles/api/api_self_destruct.cpp b/Telegram/SourceFiles/api/api_self_destruct.cpp index 80ae25186..64cf1a5b2 100644 --- a/Telegram/SourceFiles/api/api_self_destruct.cpp +++ b/Telegram/SourceFiles/api/api_self_destruct.cpp @@ -12,7 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Api { SelfDestruct::SelfDestruct(not_null api) -: _api(api->instance()) { +: _api(&api->instance()) { } void SelfDestruct::reload() { diff --git a/Telegram/SourceFiles/api/api_sensitive_content.cpp b/Telegram/SourceFiles/api/api_sensitive_content.cpp index 7ff3dd610..02fea25ba 100644 --- a/Telegram/SourceFiles/api/api_sensitive_content.cpp +++ b/Telegram/SourceFiles/api/api_sensitive_content.cpp @@ -21,7 +21,7 @@ constexpr auto kRefreshAppConfigTimeout = 3 * crl::time(1000); SensitiveContent::SensitiveContent(not_null api) : _session(&api->session()) -, _api(api->instance()) +, _api(&api->instance()) , _appConfigReloadTimer([=] { _session->account().appConfig().refresh(); }) { } diff --git a/Telegram/SourceFiles/api/api_updates.cpp b/Telegram/SourceFiles/api/api_updates.cpp index f2f879beb..d693d1280 100644 --- a/Telegram/SourceFiles/api/api_updates.cpp +++ b/Telegram/SourceFiles/api/api_updates.cpp @@ -11,7 +11,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_session.h" #include "main/main_account.h" #include "mtproto/mtp_instance.h" -#include "mtproto/dc_options.h" +#include "mtproto/mtproto_config.h" +#include "mtproto/mtproto_dc_options.h" #include "data/stickers/data_stickers.h" #include "data/data_session.h" #include "data/data_user.h" @@ -39,7 +40,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/confirm_box.h" #include "apiwrap.h" #include "app.h" // App::formatPhone -#include "facades.h" namespace Api { namespace { @@ -340,7 +340,9 @@ void Updates::channelDifferenceDone( channel->ptsSetRequesting(false); if (!isFinal) { - MTP_LOG(0, ("getChannelDifference { good - after not final channelDifference was received }%1").arg(cTestMode() ? " TESTMODE" : "")); + MTP_LOG(0, ("getChannelDifference " + "{ good - after not final channelDifference was received }%1" + ).arg(_session->mtp().isTestMode() ? " TESTMODE" : "")); getChannelDifference(channel); } else if (ranges::contains( _activeChats, @@ -410,7 +412,9 @@ void Updates::differenceDone(const MTPupdates_Difference &result) { _ptsWaiter.setRequesting(false); - MTP_LOG(0, ("getDifference { good - after a slice of difference was received }%1").arg(cTestMode() ? " TESTMODE" : "")); + MTP_LOG(0, ("getDifference " + "{ good - after a slice of difference was received }%1" + ).arg(_session->mtp().isTestMode() ? " TESTMODE" : "")); getDifference(); } break; case mtpc_updates_difference: { @@ -566,7 +570,9 @@ void Updates::getDifferenceAfterFail() { wait = _getDifferenceTimeAfterFail - now; } else { _ptsWaiter.setRequesting(false); - MTP_LOG(0, ("getDifference { force - after get difference failed }%1").arg(cTestMode() ? " TESTMODE" : "")); + MTP_LOG(0, ("getDifference " + "{ force - after get difference failed }%1" + ).arg(_session->mtp().isTestMode() ? " TESTMODE" : "")); getDifference(); } } @@ -650,7 +656,7 @@ void Updates::getChannelDifference( } void Updates::sendPing() { - _session->mtp()->ping(); + _session->mtp().ping(); } void Updates::addActiveChat(rpl::producer chat) { @@ -680,9 +686,10 @@ void Updates::requestChannelRangeDifference(not_null history) { return; } - MTP_LOG(0, ("getChannelDifference { good - " - "after channelDifferenceTooLong was received, " - "validating history part }%1").arg(cTestMode() ? " TESTMODE" : "")); + MTP_LOG(0, ("getChannelDifference " + "{ good - after channelDifferenceTooLong was received, " + "validating history part }%1" + ).arg(_session->mtp().isTestMode() ? " TESTMODE" : "")); channelRangeDifferenceSend(channel, range, channel->pts()); } @@ -752,10 +759,10 @@ void Updates::channelRangeDifferenceDone( } if (!isFinal && nextRequestPts) { - MTP_LOG(0, ("getChannelDifference { " - "good - after not final channelDifference was received, " + MTP_LOG(0, ("getChannelDifference " + "{ good - after not final channelDifference was received, " "validating history part }%1" - ).arg(cTestMode() ? " TESTMODE" : "")); + ).arg(_session->mtp().isTestMode() ? " TESTMODE" : "")); channelRangeDifferenceSend(channel, range, nextRequestPts); } } @@ -764,7 +771,7 @@ void Updates::mtpNewSessionCreated() { Core::App().checkAutoLock(); _updatesSeq = 0; MTP_LOG(0, ("getDifference { after new_session_created }%1" - ).arg(cTestMode() ? " TESTMODE" : "")); + ).arg(_session->mtp().isTestMode() ? " TESTMODE" : "")); getDifference(); } @@ -789,25 +796,26 @@ bool Updates::isIdle() const { void Updates::updateOnline(bool gotOtherOffline) { crl::on_main(&session(), [] { Core::App().checkAutoLock(); }); + const auto &config = _session->serverConfig(); bool isOnline = Core::App().hasActiveWindow(&session()); - int updateIn = Global::OnlineUpdatePeriod(); + int updateIn = config.onlineUpdatePeriod; Assert(updateIn >= 0); if (isOnline) { const auto idle = crl::now() - Core::App().lastNonIdleTime(); - if (idle >= Global::OfflineIdleTimeout()) { + if (idle >= config.offlineIdleTimeout) { isOnline = false; if (!_isIdle) { _isIdle = true; _idleFinishTimer.callOnce(900); } } else { - updateIn = qMin(updateIn, int(Global::OfflineIdleTimeout() - idle)); + updateIn = qMin(updateIn, int(config.offlineIdleTimeout - idle)); Assert(updateIn >= 0); } } auto ms = crl::now(); if (isOnline != _lastWasOnline - || (isOnline && _lastSetOnline + Global::OnlineUpdatePeriod() <= ms) + || (isOnline && _lastSetOnline + config.onlineUpdatePeriod <= ms) || (isOnline && gotOtherOffline)) { api().request(base::take(_onlineRequest)).cancel(); @@ -828,7 +836,7 @@ void Updates::updateOnline(bool gotOtherOffline) { } const auto self = session().user(); - self->onlineTill = base::unixtime::now() + (isOnline ? (Global::OnlineUpdatePeriod() / 1000) : -1); + self->onlineTill = base::unixtime::now() + (isOnline ? (config.onlineUpdatePeriod / 1000) : -1); session().changes().peerUpdated( self, Data::PeerUpdate::Flag::OnlineStatus); @@ -838,7 +846,7 @@ void Updates::updateOnline(bool gotOtherOffline) { _lastSetOnline = ms; } else if (isOnline) { - updateIn = qMin(updateIn, int(_lastSetOnline + Global::OnlineUpdatePeriod() - ms)); + updateIn = qMin(updateIn, int(_lastSetOnline + config.onlineUpdatePeriod - ms)); Assert(updateIn >= 0); } _onlineTimer.callOnce(updateIn); @@ -846,7 +854,7 @@ void Updates::updateOnline(bool gotOtherOffline) { void Updates::checkIdleFinish() { if (crl::now() - Core::App().lastNonIdleTime() - < Global::OfflineIdleTimeout()) { + < _session->serverConfig().offlineIdleTimeout) { _idleFinishTimer.cancel(); _isIdle = false; updateOnline(); @@ -1153,7 +1161,9 @@ void Updates::applyUpdates( || (viaBotId && !session().data().userLoaded(viaBotId->v)) || (entities && !MentionUsersLoaded(&session(), *entities)) || (fwd && !ForwardedInfoDataLoaded(&session(), *fwd))) { - MTP_LOG(0, ("getDifference { good - getting user for updateShortMessage }%1").arg(cTestMode() ? " TESTMODE" : "")); + MTP_LOG(0, ("getDifference " + "{ good - getting user for updateShortMessage }%1" + ).arg(_session->mtp().isTestMode() ? " TESTMODE" : "")); return getDifference(); } if (updateAndApply(d.vpts().v, d.vpts_count().v, updates)) { @@ -1174,7 +1184,9 @@ void Updates::applyUpdates( || (viaBotId && !session().data().userLoaded(viaBotId->v)) || (entities && !MentionUsersLoaded(&session(), *entities)) || (fwd && !ForwardedInfoDataLoaded(&session(), *fwd))) { - MTP_LOG(0, ("getDifference { good - getting user for updateShortChatMessage }%1").arg(cTestMode() ? " TESTMODE" : "")); + MTP_LOG(0, ("getDifference " + "{ good - getting user for updateShortChatMessage }%1" + ).arg(_session->mtp().isTestMode() ? " TESTMODE" : "")); if (chat && noFrom) { session().api().requestFullPeer(chat); } @@ -1232,7 +1244,9 @@ void Updates::applyUpdates( } break; case mtpc_updatesTooLong: { - MTP_LOG(0, ("getDifference { good - updatesTooLong received }%1").arg(cTestMode() ? " TESTMODE" : "")); + MTP_LOG(0, ("getDifference " + "{ good - updatesTooLong received }%1" + ).arg(_session->mtp().isTestMode() ? " TESTMODE" : "")); return getDifference(); } break; } @@ -1248,9 +1262,9 @@ void Updates::feedUpdate(const MTPUpdate &update) { const auto isDataLoaded = AllDataLoadedForMessage(&session(), d.vmessage()); if (!requestingDifference() && isDataLoaded != DataIsLoadedResult::Ok) { - MTP_LOG(0, ("getDifference { good - " - "after not all data loaded in updateNewMessage }%1" - ).arg(cTestMode() ? " TESTMODE" : "")); + MTP_LOG(0, ("getDifference " + "{ good - after not all data loaded in updateNewMessage }%1" + ).arg(_session->mtp().isTestMode() ? " TESTMODE" : "")); // This can be if this update was created by grouping // some short message update into an updates vector. @@ -1265,14 +1279,16 @@ void Updates::feedUpdate(const MTPUpdate &update) { auto channel = session().data().channelLoaded(peerToChannel(PeerFromMessage(d.vmessage()))); const auto isDataLoaded = AllDataLoadedForMessage(&session(), d.vmessage()); if (!requestingDifference() && (!channel || isDataLoaded != DataIsLoadedResult::Ok)) { - MTP_LOG(0, ("getDifference { good - " - "after not all data loaded in updateNewChannelMessage }%1" - ).arg(cTestMode() ? " TESTMODE" : "")); + MTP_LOG(0, ("getDifference " + "{ good - after not all data loaded in updateNewChannelMessage }%1" + ).arg(_session->mtp().isTestMode() ? " TESTMODE" : "")); // Request last active supergroup participants if the 'from' user was not loaded yet. // This will optimize similar getDifference() calls for almost all next messages. if (isDataLoaded == DataIsLoadedResult::FromNotLoaded && channel && channel->isMegagroup()) { - if (channel->mgInfo->lastParticipants.size() < Global::ChatSizeMax() && (channel->mgInfo->lastParticipants.empty() || channel->mgInfo->lastParticipants.size() < channel->membersCount())) { + if (channel->mgInfo->lastParticipants.size() < _session->serverConfig().chatSizeMax + && (channel->mgInfo->lastParticipants.empty() + || channel->mgInfo->lastParticipants.size() < channel->membersCount())) { session().api().requestLastParticipants(channel); } } @@ -1657,11 +1673,11 @@ void Updates::feedUpdate(const MTPUpdate &update) { case mtpc_updateDcOptions: { auto &d = update.c_updateDcOptions(); - Core::App().dcOptions()->addFromList(d.vdc_options()); + session().mtp().dcOptions().addFromList(d.vdc_options()); } break; case mtpc_updateConfig: { - session().mtp()->requestConfig(); + session().mtp().requestConfig(); } break; case mtpc_updateUserPhone: { diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index e60b9d0ed..bcb3aaedb 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -43,6 +43,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mainwindow.h" #include "mainwidget.h" #include "boxes/add_contact_box.h" +#include "mtproto/mtproto_config.h" #include "history/history.h" #include "history/history_message.h" #include "history/history_item_components.h" @@ -231,7 +232,7 @@ bool ApiWrap::BlockedUsersSlice::operator!=(const BlockedUsersSlice &other) cons } ApiWrap::ApiWrap(not_null session) -: MTP::Sender(session->account().mtp()) +: MTP::Sender(&session->account().mtp()) , _session(session) , _messageDataResolveDelayed([=] { resolveMessageDatas(); }) , _webPagesTimer([=] { resolveWebPages(); }) @@ -572,10 +573,10 @@ void ApiWrap::sendMessageFail( FullMsgId itemId) { if (error.type() == qstr("PEER_FLOOD")) { Ui::show(Box( - PeerFloodErrorText(PeerFloodType::Send))); + PeerFloodErrorText(&session(), PeerFloodType::Send))); } else if (error.type() == qstr("USER_BANNED_IN_CHANNEL")) { const auto link = textcmdLink( - Core::App().createInternalLinkFull(qsl("spambot")), + session().createInternalLinkFull(qsl("spambot")), tr::lng_cant_more_info(tr::now)); Ui::show(Box(tr::lng_error_public_groups_denied( tr::now, @@ -754,7 +755,7 @@ QString ApiWrap::exportDirectMessageLink(not_null item) { } } } - return Core::App().createInternalLinkFull(query); + return session().createInternalLinkFull(query); }; const auto i = _unlikelyMessageLinks.find(itemId); const auto current = (i != end(_unlikelyMessageLinks)) @@ -1450,7 +1451,7 @@ void ApiWrap::requestLastParticipants(not_null channel) { channel->inputChannel, MTP_channelParticipantsRecent(), MTP_int(offset), - MTP_int(Global::ChatSizeMax()), + MTP_int(_session->serverConfig().chatSizeMax), MTP_int(participantsHash) )).done([=](const MTPchannels_ChannelParticipants &result) { _participantsRequests.remove(channel); @@ -1480,7 +1481,7 @@ void ApiWrap::requestBots(not_null channel) { channel->inputChannel, MTP_channelParticipantsBots(), MTP_int(offset), - MTP_int(Global::ChatSizeMax()), + MTP_int(_session->serverConfig().chatSizeMax), MTP_int(participantsHash) )).done([this, channel](const MTPchannels_ChannelParticipants &result) { _botsRequests.remove(channel); @@ -1510,7 +1511,7 @@ void ApiWrap::requestAdmins(not_null channel) { channel->inputChannel, MTP_channelParticipantsAdmins(), MTP_int(offset), - MTP_int(Global::ChatSizeMax()), + MTP_int(_session->serverConfig().chatSizeMax), MTP_int(participantsHash) )).done([this, channel](const MTPchannels_ChannelParticipants &result) { _adminsRequests.remove(channel); @@ -1820,7 +1821,7 @@ void ApiWrap::requestChannelMembersForAdd( channel->inputChannel, MTP_channelParticipantsRecent(), MTP_int(offset), - MTP_int(Global::ChatSizeMax()), + MTP_int(_session->serverConfig().chatSizeMax), MTP_int(participantsHash) )).done([this](const MTPchannels_ChannelParticipants &result) { base::take(_channelMembersForAddRequestId); @@ -5038,7 +5039,10 @@ FileLoadTo ApiWrap::fileLoadTaskOptions(const SendAction &action) const { void ApiWrap::uploadPeerPhoto(not_null peer, QImage &&image) { peer = peer->migrateToOrMe(); - const auto ready = PreparePeerPhoto(instance()->mainDcId(), peer->id, std::move(image)); + const auto ready = PreparePeerPhoto( + instance().mainDcId(), + peer->id, + std::move(image)); const auto fakeId = FullMsgId( peerToChannel(peer->id), diff --git a/Telegram/SourceFiles/boxes/add_contact_box.cpp b/Telegram/SourceFiles/boxes/add_contact_box.cpp index 8db083635..fce87ac94 100644 --- a/Telegram/SourceFiles/boxes/add_contact_box.cpp +++ b/Telegram/SourceFiles/boxes/add_contact_box.cpp @@ -118,9 +118,11 @@ style::InputField CreateBioFieldStyle() { return result; } -QString PeerFloodErrorText(PeerFloodType type) { - auto link = textcmdLink( - Core::App().createInternalLinkFull(qsl("spambot")), +QString PeerFloodErrorText( + not_null session, + PeerFloodType type) { + const auto link = textcmdLink( + session->createInternalLinkFull(qsl("spambot")), tr::lng_cant_more_info(tr::now)); if (type == PeerFloodType::InviteGroup) { return tr::lng_cant_invite_not_contact(tr::now, lt_more_info, link); @@ -190,10 +192,10 @@ void ShowAddParticipantsError( } else if (error == qstr("BOT_GROUPS_BLOCKED")) { return tr::lng_error_cant_add_bot(tr::now); } else if (error == qstr("PEER_FLOOD")) { - const auto isGroup = (chat->isChat() || chat->isMegagroup()); - return PeerFloodErrorText(isGroup + const auto type = (chat->isChat() || chat->isMegagroup()) ? PeerFloodType::InviteGroup - : PeerFloodType::InviteChannel); + : PeerFloodType::InviteChannel; + return PeerFloodErrorText(&chat->session(), type); } else if (error == qstr("ADMINS_TOO_MUCH")) { return ((chat->isChat() || chat->isMegagroup()) ? tr::lng_error_admin_limit @@ -453,7 +455,7 @@ GroupInfoBox::GroupInfoBox( const QString &title, Fn)> channelDone) : _navigation(navigation) -, _api(_navigation->session().mtp()) +, _api(&_navigation->session().mtp()) , _type(type) , _initialTitle(title) , _channelDone(std::move(channelDone)) { @@ -598,7 +600,9 @@ void GroupInfoBox::createGroup( } else if (error.type() == qstr("PEER_FLOOD")) { Ui::show( Box( - PeerFloodErrorText(PeerFloodType::InviteGroup)), + PeerFloodErrorText( + &_navigation->session(), + PeerFloodType::InviteGroup)), Ui::LayerOption::KeepOther); } else if (error.type() == qstr("USER_RESTRICTED")) { Ui::show( @@ -750,7 +754,7 @@ SetupChannelBox::SetupChannelBox( bool existing) : _navigation(navigation) , _channel(channel) -, _api(_channel->session().mtp()) +, _api(&_channel->session().mtp()) , _existing(existing) , _privacyGroup( std::make_shared>(Privacy::Public)) @@ -790,7 +794,12 @@ SetupChannelBox::SetupChannelBox( : tr::lng_create_private_channel_about)(tr::now), _defaultOptions, _aboutPublicWidth) -, _link(this, st::setupChannelLink, nullptr, channel->username, true) { +, _link( + this, + st::setupChannelLink, + nullptr, + channel->username, + channel->session().createInternalLink(QString())) { } void SetupChannelBox::prepare() { @@ -1168,7 +1177,7 @@ void SetupChannelBox::firstCheckFail(const RPCError &error) { EditNameBox::EditNameBox(QWidget*, not_null user) : _user(user) -, _api(_user->session().mtp()) +, _api(&_user->session().mtp()) , _first(this, st::defaultInputField, tr::lng_signup_firstname(), _user->firstName) , _last(this, st::defaultInputField, tr::lng_signup_lastname(), _user->lastName) , _invertOrder(langFirstNameGoesSecond()) { @@ -1292,7 +1301,7 @@ RevokePublicLinkBox::Inner::Inner( Fn revokeCallback) : TWidget(parent) , _session(session) -, _api(_session->mtp()) +, _api(&_session->mtp()) , _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom()) , _revokeWidth(st::normalFont->width(tr::lng_channels_too_much_public_revoke(tr::now))) , _revokeCallback(std::move(revokeCallback)) { @@ -1320,7 +1329,7 @@ RevokePublicLinkBox::Inner::Inner( Ui::NameTextOptions()); row.status.setText( st::defaultTextStyle, - Core::App().createInternalLink( + _session->createInternalLink( textcmdLink(1, peer->userName())), Ui::DialogTextOptions()); _rows.push_back(std::move(row)); @@ -1401,7 +1410,7 @@ void RevokePublicLinkBox::Inner::mouseReleaseEvent(QMouseEvent *e) { auto text = text_method( tr::now, lt_link, - Core::App().createInternalLink(pressed->userName()), + _session->createInternalLink(pressed->userName()), lt_group, pressed->name); auto confirmText = tr::lng_channels_too_much_public_revoke(tr::now); diff --git a/Telegram/SourceFiles/boxes/add_contact_box.h b/Telegram/SourceFiles/boxes/add_contact_box.h index e72a2fd20..d28e57450 100644 --- a/Telegram/SourceFiles/boxes/add_contact_box.h +++ b/Telegram/SourceFiles/boxes/add_contact_box.h @@ -46,9 +46,11 @@ enum class PeerFloodType { InviteChannel, }; -style::InputField CreateBioFieldStyle(); +[[nodiscard]] style::InputField CreateBioFieldStyle(); -QString PeerFloodErrorText(PeerFloodType type); +[[nodiscard]] QString PeerFloodErrorText( + not_null session, + PeerFloodType type); void ShowAddParticipantsError( const QString &error, not_null chat, diff --git a/Telegram/SourceFiles/boxes/background_box.cpp b/Telegram/SourceFiles/boxes/background_box.cpp index a39256c42..9ead668bb 100644 --- a/Telegram/SourceFiles/boxes/background_box.cpp +++ b/Telegram/SourceFiles/boxes/background_box.cpp @@ -193,7 +193,7 @@ BackgroundBox::Inner::Inner( not_null session) : RpWidget(parent) , _session(session) -, _api(_session->mtp()) +, _api(&_session->mtp()) , _check(std::make_unique(st::overviewCheck, [=] { update(); })) { _check->setChecked(true, anim::type::instant); if (_session->data().wallpapers().empty()) { diff --git a/Telegram/SourceFiles/boxes/background_preview_box.cpp b/Telegram/SourceFiles/boxes/background_preview_box.cpp index 7a368677f..4d0a4c993 100644 --- a/Telegram/SourceFiles/boxes/background_preview_box.cpp +++ b/Telegram/SourceFiles/boxes/background_preview_box.cpp @@ -514,7 +514,8 @@ void BackgroundPreviewBox::apply() { } void BackgroundPreviewBox::share() { - QGuiApplication::clipboard()->setText(_paper.shareUrl()); + QGuiApplication::clipboard()->setText( + _paper.shareUrl(&_controller->session())); Ui::Toast::Show(tr::lng_background_link_copied(tr::now)); } diff --git a/Telegram/SourceFiles/boxes/change_phone_box.cpp b/Telegram/SourceFiles/boxes/change_phone_box.cpp index 9369fa04b..65dcc5834 100644 --- a/Telegram/SourceFiles/boxes/change_phone_box.cpp +++ b/Telegram/SourceFiles/boxes/change_phone_box.cpp @@ -140,7 +140,7 @@ ChangePhoneBox::EnterPhone::EnterPhone( QWidget*, not_null session) : _session(session) -, _api(session->mtp()) { +, _api(&session->mtp()) { } void ChangePhoneBox::EnterPhone::prepare() { @@ -257,7 +257,7 @@ ChangePhoneBox::EnterCode::EnterCode( int codeLength, int callTimeout) : _session(session) -, _api(session->mtp()) +, _api(&session->mtp()) , _phone(phone) , _hash(hash) , _codeLength(codeLength) diff --git a/Telegram/SourceFiles/boxes/confirm_box.cpp b/Telegram/SourceFiles/boxes/confirm_box.cpp index 67f6872c3..0de763d7b 100644 --- a/Telegram/SourceFiles/boxes/confirm_box.cpp +++ b/Telegram/SourceFiles/boxes/confirm_box.cpp @@ -36,7 +36,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_changes.h" #include "base/unixtime.h" #include "main/main_session.h" -#include "facades.h" +#include "mtproto/mtproto_config.h" +#include "facades.h" // Ui::showChatsList #include "app.h" #include "styles/style_layers.h" #include "styles/style_boxes.h" @@ -351,7 +352,7 @@ MaxInviteBox::MaxInviteBox(QWidget*, not_null channel) : BoxConten tr::lng_participant_invite_sorry( tr::now, lt_count, - Global::ChatSizeMax()), + channel->session().serverConfig().chatSizeMax), kInformBoxTextOptions, (st::boxWidth - st::boxPadding.left() @@ -433,7 +434,7 @@ PinMessageBox::PinMessageBox( not_null peer, MsgId msgId) : _peer(peer) -, _api(peer->session().mtp()) +, _api(&peer->session().mtp()) , _msgId(msgId) , _text(this, tr::lng_pinned_pin_sure(tr::now), st::boxLabel) { } diff --git a/Telegram/SourceFiles/boxes/confirm_phone_box.cpp b/Telegram/SourceFiles/boxes/confirm_phone_box.cpp index 336a9aca9..ab96d75f3 100644 --- a/Telegram/SourceFiles/boxes/confirm_phone_box.cpp +++ b/Telegram/SourceFiles/boxes/confirm_phone_box.cpp @@ -225,7 +225,7 @@ ConfirmPhoneBox::ConfirmPhoneBox( const QString &phone, const QString &hash) : _session(session) -, _api(session->mtp()) +, _api(&session->mtp()) , _phone(phone) , _hash(hash) , _call([this] { sendCall(); }, [this] { update(); }) { diff --git a/Telegram/SourceFiles/boxes/connection_box.cpp b/Telegram/SourceFiles/boxes/connection_box.cpp index eff5032e0..ac25ca944 100644 --- a/Telegram/SourceFiles/boxes/connection_box.cpp +++ b/Telegram/SourceFiles/boxes/connection_box.cpp @@ -1059,9 +1059,7 @@ void ProxiesBoxController::refreshChecker(Item &item) { const auto type = (item.data.type == Type::Http) ? Variants::Http : Variants::Tcp; - const auto mtproto = _account->mtp(); - Assert(mtproto != nullptr); - + const auto mtproto = &_account->mtp(); const auto dcId = mtproto->mainDcId(); item.state = ItemState::Checking; @@ -1084,7 +1082,7 @@ void ProxiesBoxController::refreshChecker(Item &item) { dcId); item.checkerv6 = nullptr; } else { - const auto options = mtproto->dcOptions()->lookup( + const auto options = mtproto->dcOptions().lookup( dcId, MTP::DcType::Regular, true); @@ -1376,9 +1374,7 @@ void ProxiesBoxController::setTryIPv6(bool enabled) { return; } Global::SetTryIPv6(enabled); - if (const auto mtproto = _account->mtp()) { - mtproto->restart(); - } + _account->mtp().restart(); Global::RefConnectionTypeChanged().notify(); saveDelayed(); } @@ -1410,8 +1406,7 @@ void ProxiesBoxController::updateView(const Item &item) { if (!selected || (Global::ProxySettings() != ProxyData::Settings::Enabled)) { return item.state; - } else if (_account->mtp() - && _account->mtp()->dcstate() == MTP::ConnectedState) { + } else if (_account->mtp().dcstate() == MTP::ConnectedState) { return ItemState::Online; } return ItemState::Connecting; diff --git a/Telegram/SourceFiles/boxes/edit_caption_box.cpp b/Telegram/SourceFiles/boxes/edit_caption_box.cpp index df5b732c8..ad2cf53d9 100644 --- a/Telegram/SourceFiles/boxes/edit_caption_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_caption_box.cpp @@ -37,6 +37,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "media/streaming/media_streaming_loader_local.h" #include "storage/localimageloader.h" #include "storage/storage_media_prepare.h" +#include "mtproto/mtproto_config.h" #include "ui/image/image.h" #include "ui/widgets/input_fields.h" #include "ui/widgets/checkbox.h" @@ -46,7 +47,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_session_controller.h" #include "confirm_box.h" #include "apiwrap.h" -#include "facades.h" +#include "facades.h" // App::LambdaDelayed. #include "app.h" #include "styles/style_layers.h" #include "styles/style_boxes.h" @@ -67,7 +68,7 @@ EditCaptionBox::EditCaptionBox( not_null controller, not_null item) : _controller(controller) -, _api(controller->session().mtp()) +, _api(&controller->session().mtp()) , _msgId(item->fullId()) { Expects(item->media() != nullptr); Expects(item->media()->allowsEditCaption()); @@ -304,8 +305,10 @@ EditCaptionBox::EditCaptionBox( Ui::InputField::Mode::MultiLine, tr::lng_photo_caption(), editData); - _field->setMaxLength(Global::CaptionLengthMax()); - _field->setSubmitSettings(_controller->session().settings().sendSubmitWay()); + _field->setMaxLength( + _controller->session().serverConfig().captionLengthMax); + _field->setSubmitSettings( + _controller->session().settings().sendSubmitWay()); _field->setInstantReplaces(Ui::InstantReplaces::Default()); _field->setInstantReplacesEnabled( _controller->session().settings().replaceEmojiValue()); diff --git a/Telegram/SourceFiles/boxes/passcode_box.cpp b/Telegram/SourceFiles/boxes/passcode_box.cpp index 865cf1235..166062615 100644 --- a/Telegram/SourceFiles/boxes/passcode_box.cpp +++ b/Telegram/SourceFiles/boxes/passcode_box.cpp @@ -50,7 +50,7 @@ PasscodeBox::PasscodeBox( not_null session, bool turningOff) : _session(session) -, _api(_session->mtp()) +, _api(&_session->mtp()) , _turningOff(turningOff) , _about(st::boxWidth - st::boxPadding.left() * 1.5) , _oldPasscode(this, st::defaultInputField, tr::lng_passcode_enter_old()) @@ -66,7 +66,7 @@ PasscodeBox::PasscodeBox( not_null session, const CloudFields &fields) : _session(session) -, _api(_session->mtp()) +, _api(&_session->mtp()) , _turningOff(fields.turningOff) , _cloudPwd(true) , _cloudFields(fields) @@ -929,7 +929,7 @@ RecoverBox::RecoverBox( not_null session, const QString &pattern, bool notEmptyPassport) -: _api(session->mtp()) +: _api(&session->mtp()) , _pattern(st::normalFont->elided(tr::lng_signin_recover_hint(tr::now, lt_recover_email, pattern), st::boxWidth - st::boxPadding.left() * 1.5)) , _notEmptyPassport(notEmptyPassport) , _recoverCode(this, st::defaultInputField, tr::lng_signin_code()) { diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp index 007da687a..bf400ead7 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp @@ -146,7 +146,7 @@ void PeerListRowWithLink::paintAction( PeerListGlobalSearchController::PeerListGlobalSearchController( not_null navigation) : _navigation(navigation) -, _api(_navigation->session().mtp()) { +, _api(&_navigation->session().mtp()) { _timer.setCallback([this] { searchOnServer(); }); } diff --git a/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp b/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp index fd2bd3ecc..5395084ef 100644 --- a/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp @@ -20,11 +20,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "dialogs/dialogs_indexed_list.h" #include "base/unixtime.h" #include "main/main_session.h" +#include "mtproto/mtproto_config.h" #include "mainwidget.h" #include "mainwindow.h" #include "window/window_session_controller.h" #include "apiwrap.h" -#include "facades.h" +#include "facades.h" // Ui::showPeerHistory #include "app.h" namespace { @@ -87,10 +88,11 @@ void AddParticipantsBoxController::subscribeToMigration() { } void AddParticipantsBoxController::rowClicked(not_null row) { + const auto &serverConfig = _peer->session().serverConfig(); auto count = fullCount(); auto limit = _peer && (_peer->isChat() || _peer->isMegagroup()) - ? Global::MegagroupSizeMax() - : Global::ChatSizeMax(); + ? serverConfig.megagroupSizeMax + : serverConfig.chatSizeMax; if (count < limit || row->checked()) { delegate()->peerListSetRowChecked(row, !row->checked()); updateTitle(); @@ -100,8 +102,8 @@ void AddParticipantsBoxController::rowClicked(not_null row) { Box(_peer->asChannel()), Ui::LayerOption::KeepOther); } - } else if (count >= Global::ChatSizeMax() - && count < Global::MegagroupSizeMax()) { + } else if (count >= serverConfig.chatSizeMax + && count < serverConfig.megagroupSizeMax) { Ui::show( Box(tr::lng_profile_add_more_after_create(tr::now)), Ui::LayerOption::KeepOther); @@ -166,7 +168,9 @@ void AddParticipantsBoxController::updateTitle() { && _peer->isChannel() && !_peer->isMegagroup()) ? QString() - : qsl("%1 / %2").arg(fullCount()).arg(Global::MegagroupSizeMax()); + : qsl("%1 / %2" + ).arg(fullCount() + ).arg(session().serverConfig().megagroupSizeMax); delegate()->peerListSetTitle(tr::lng_profile_add_participant()); delegate()->peerListSetAdditionalTitle(rpl::single(additional)); } @@ -276,7 +280,7 @@ AddSpecialBoxController::AddSpecialBoxController( peer, &_additional)) , _peer(peer) -, _api(_peer->session().mtp()) +, _api(&_peer->session().mtp()) , _role(role) , _additional(peer, Role::Members) , _adminDoneCallback(std::move(adminDoneCallback)) @@ -829,7 +833,7 @@ AddSpecialBoxSearchController::AddSpecialBoxSearchController( not_null additional) : _peer(peer) , _additional(additional) -, _api(_peer->session().mtp()) +, _api(&_peer->session().mtp()) , _timer([=] { searchOnServer(); }) { subscribeToMigration(); } diff --git a/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp index 43185f80d..28426dc15 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/confirm_box.h" #include "boxes/add_contact_box.h" #include "main/main_session.h" +#include "mtproto/mtproto_config.h" #include "apiwrap.h" #include "lang/lang_keys.h" #include "mainwidget.h" @@ -28,7 +29,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/ui_utility.h" #include "window/window_session_controller.h" #include "history/history.h" -#include "facades.h" namespace { @@ -707,7 +707,8 @@ void ParticipantsOnlineSorter::sort() { const auto channel = _peer->asChannel(); if (channel && (!channel->isMegagroup() - || channel->membersCount() > Global::ChatSizeMax())) { + || (channel->membersCount() + > channel->session().serverConfig().chatSizeMax))) { _onlineCount = 0; return; } @@ -752,7 +753,7 @@ ParticipantsBoxController::ParticipantsBoxController( : PeerListController(CreateSearchController(peer, role, &_additional)) , _navigation(navigation) , _peer(peer) -, _api(_peer->session().mtp()) +, _api(&_peer->session().mtp()) , _role(role) , _additional(peer, _role) { subscribeToMigration(); @@ -844,8 +845,9 @@ void ParticipantsBoxController::Start( return chat ? chat->canAddMembers() : (channel->canAddMembers() - && (channel->membersCount() < Global::ChatSizeMax() - || channel->isMegagroup())); + && (channel->isMegagroup() + || (channel->membersCount() + < channel->session().serverConfig().chatSizeMax))); case Role::Admins: return chat ? chat->canAddAdmins() @@ -924,7 +926,8 @@ void ParticipantsBoxController::addNewParticipants() { if (chat) { AddParticipantsBoxController::Start(_navigation, chat); } else if (channel->isMegagroup() - || channel->membersCount() < Global::ChatSizeMax()) { + || (channel->membersCount() + < channel->session().serverConfig().chatSizeMax)) { const auto count = delegate()->peerListFullRowsCount(); auto already = std::vector>(); already.reserve(count); @@ -1887,7 +1890,7 @@ void ParticipantsBoxController::subscribeToCreatorChange( channel->inputChannel, MTP_channelParticipantsRecent(), MTP_int(0), - MTP_int(Global::ChatSizeMax()), + MTP_int(channel->session().serverConfig().chatSizeMax), MTP_int(0) )).done([=](const MTPchannels_ChannelParticipants &result) { if (channel->amCreator()) { @@ -1922,7 +1925,7 @@ ParticipantsBoxSearchController::ParticipantsBoxSearchController( : _channel(channel) , _role(role) , _additional(additional) -, _api(_channel->session().mtp()) { +, _api(&_channel->session().mtp()) { _timer.setCallback([=] { searchOnServer(); }); } diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index a0a390fe3..ff154168e 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -355,7 +355,7 @@ Controller::Controller( : _navigation(navigation) , _box(box) , _peer(peer) -, _api(_peer->session().mtp()) +, _api(&_peer->session().mtp()) , _isGroup(_peer->isChat() || _peer->isMegagroup()) { _box->setTitle(_isGroup ? tr::lng_edit_group() diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp index 4476fce8d..a0c331060 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp @@ -168,7 +168,7 @@ Controller::Controller( std::optional privacySavedValue, std::optional usernameSavedValue) : _peer(peer) -, _api(_peer->session().mtp()) +, _api(&_peer->session().mtp()) , _privacySavedValue(privacySavedValue) , _usernameSavedValue(usernameSavedValue) , _useLocationPhrases(useLocationPhrases) @@ -335,7 +335,7 @@ object_ptr Controller::createUsernameEdit() { st::setupChannelLink, nullptr, username, - true)); + _peer->session().createInternalLink(QString()))); _controls.usernameInput->heightValue( ) | rpl::start_with_next([placeholder](int height) { placeholder->resize(placeholder->width(), height); diff --git a/Telegram/SourceFiles/boxes/rate_call_box.cpp b/Telegram/SourceFiles/boxes/rate_call_box.cpp index aa6e72b2c..999eb93aa 100644 --- a/Telegram/SourceFiles/boxes/rate_call_box.cpp +++ b/Telegram/SourceFiles/boxes/rate_call_box.cpp @@ -31,7 +31,7 @@ RateCallBox::RateCallBox( uint64 callId, uint64 callAccessHash) : _session(session) -, _api(_session->mtp()) +, _api(&_session->mtp()) , _callId(callId) , _callAccessHash(callAccessHash) { } diff --git a/Telegram/SourceFiles/boxes/report_box.cpp b/Telegram/SourceFiles/boxes/report_box.cpp index a55ab4835..0c6fb1b03 100644 --- a/Telegram/SourceFiles/boxes/report_box.cpp +++ b/Telegram/SourceFiles/boxes/report_box.cpp @@ -28,12 +28,12 @@ constexpr auto kReportReasonLengthMax = 200; ReportBox::ReportBox(QWidget*, not_null peer) : _peer(peer) -, _api(_peer->session().mtp()) { +, _api(&_peer->session().mtp()) { } ReportBox::ReportBox(QWidget*, not_null peer, MessageIdsList ids) : _peer(peer) -, _api(_peer->session().mtp()) +, _api(&_peer->session().mtp()) , _ids(std::move(ids)) { } diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index e3c6570b9..3893ef1a1 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/localstorage.h" #include "storage/storage_media_prepare.h" #include "mainwidget.h" +#include "mtproto/mtproto_config.h" #include "chat_helpers/message_field.h" #include "chat_helpers/emoji_suggestions_widget.h" #include "chat_helpers/tabbed_panel.h" @@ -36,7 +37,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_common.h" #include "window/window_session_controller.h" #include "layout.h" -#include "facades.h" +#include "facades.h" // App::LambdaDelayed. #include "app.h" #include "styles/style_history.h" #include "styles/style_layers.h" @@ -2041,8 +2042,10 @@ void SendFilesBox::applyAlbumOrder() { } void SendFilesBox::setupCaption() { - _caption->setMaxLength(Global::CaptionLengthMax()); - _caption->setSubmitSettings(_controller->session().settings().sendSubmitWay()); + _caption->setMaxLength( + _controller->session().serverConfig().captionLengthMax); + _caption->setSubmitSettings( + _controller->session().settings().sendSubmitWay()); connect(_caption, &Ui::InputField::resized, [=] { captionResized(); }); diff --git a/Telegram/SourceFiles/boxes/sessions_box.cpp b/Telegram/SourceFiles/boxes/sessions_box.cpp index ff494213b..23e07688e 100644 --- a/Telegram/SourceFiles/boxes/sessions_box.cpp +++ b/Telegram/SourceFiles/boxes/sessions_box.cpp @@ -77,7 +77,7 @@ private: SessionsBox::SessionsBox(QWidget*, not_null session) : _session(session) -, _api(_session->mtp()) +, _api(&_session->mtp()) , _shortPollTimer([=] { shortPollSessions(); }) { } diff --git a/Telegram/SourceFiles/boxes/share_box.cpp b/Telegram/SourceFiles/boxes/share_box.cpp index 3f333a498..8c6d0a5fd 100644 --- a/Telegram/SourceFiles/boxes/share_box.cpp +++ b/Telegram/SourceFiles/boxes/share_box.cpp @@ -159,7 +159,7 @@ ShareBox::ShareBox( SubmitCallback &&submitCallback, FilterCallback &&filterCallback) : _navigation(navigation) -, _api(_navigation->session().mtp()) +, _api(&_navigation->session().mtp()) , _copyCallback(std::move(copyCallback)) , _submitCallback(std::move(submitCallback)) , _filterCallback(std::move(filterCallback)) diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.cpp b/Telegram/SourceFiles/boxes/sticker_set_box.cpp index 980c84b26..7359a6e00 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.cpp +++ b/Telegram/SourceFiles/boxes/sticker_set_box.cpp @@ -190,7 +190,8 @@ void StickerSetBox::addStickers() { } void StickerSetBox::shareStickers() { - auto url = Core::App().createInternalLinkFull(qsl("addstickers/") + _inner->shortName()); + const auto url = _controller->session().createInternalLinkFull( + qsl("addstickers/") + _inner->shortName()); QGuiApplication::clipboard()->setText(url); Ui::show(Box(tr::lng_stickers_copied(tr::now))); } @@ -229,7 +230,7 @@ StickerSetBox::Inner::Inner( const MTPInputStickerSet &set) : RpWidget(parent) , _controller(controller) -, _api(_controller->session().mtp()) +, _api(&_controller->session().mtp()) , _input(set) , _previewTimer([=] { showPreview(); }) { set.match([&](const MTPDinputStickerSetID &data) { diff --git a/Telegram/SourceFiles/boxes/stickers_box.cpp b/Telegram/SourceFiles/boxes/stickers_box.cpp index 5638570f3..3ebeb1053 100644 --- a/Telegram/SourceFiles/boxes/stickers_box.cpp +++ b/Telegram/SourceFiles/boxes/stickers_box.cpp @@ -363,7 +363,7 @@ StickersBox::StickersBox( not_null session, Section section) : _session(session) -, _api(session->mtp()) +, _api(&session->mtp()) , _tabs(this, st::stickersTabs) , _unreadBadge( this, @@ -377,7 +377,7 @@ StickersBox::StickersBox( StickersBox::StickersBox(QWidget*, not_null megagroup) : _session(&megagroup->session()) -, _api(_session->mtp()) +, _api(&_session->mtp()) , _section(Section::Installed) , _installed(0, this, megagroup) , _megagroupSet(megagroup) { @@ -391,7 +391,7 @@ StickersBox::StickersBox( not_null session, const MTPVector &attachedSets) : _session(session) -, _api(session->mtp()) +, _api(&session->mtp()) , _section(Section::Attached) , _attached(0, this, session, Section::Attached) , _attachedSets(attachedSets) { @@ -928,7 +928,7 @@ StickersBox::Inner::Inner( StickersBox::Section section) : RpWidget(parent) , _session(session) -, _api(_session->mtp()) +, _api(&_session->mtp()) , _section(section) , _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom()) , _shiftingAnimation([=](crl::time now) { @@ -945,7 +945,7 @@ StickersBox::Inner::Inner( StickersBox::Inner::Inner(QWidget *parent, not_null megagroup) : RpWidget(parent) , _session(&megagroup->session()) -, _api(_session->mtp()) +, _api(&_session->mtp()) , _section(StickersBox::Section::Installed) , _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom()) , _shiftingAnimation([=](crl::time now) { @@ -954,10 +954,16 @@ StickersBox::Inner::Inner(QWidget *parent, not_null megagroup) , _itemsTop(st::membersMarginTop) , _megagroupSet(megagroup) , _megagroupSetInput(_megagroupSet->mgInfo->stickerSet) -, _megagroupSetField(this, st::groupStickersField, rpl::single(qsl("stickerset")), QString(), true) +, _megagroupSetField( + this, + st::groupStickersField, + rpl::single(qsl("stickerset")), + QString(), + _session->createInternalLink(QString())) , _megagroupDivider(this) , _megagroupSubTitle(this, tr::lng_stickers_group_from_your(tr::now), st::boxTitle) { - _megagroupSetField->setLinkPlaceholder(Core::App().createInternalLink(qsl("addstickers/"))); + _megagroupSetField->setLinkPlaceholder( + _session->createInternalLink(qsl("addstickers/"))); _megagroupSetField->setPlaceholderHidden(false); _megagroupSetAddressChangedTimer.setCallback([this] { handleMegagroupSetAddressChange(); }); connect( diff --git a/Telegram/SourceFiles/boxes/username_box.cpp b/Telegram/SourceFiles/boxes/username_box.cpp index d592cea8b..537e65429 100644 --- a/Telegram/SourceFiles/boxes/username_box.cpp +++ b/Telegram/SourceFiles/boxes/username_box.cpp @@ -31,13 +31,13 @@ constexpr auto kMinUsernameLength = 5; UsernameBox::UsernameBox(QWidget*, not_null session) : _session(session) -, _api(_session->mtp()) +, _api(&_session->mtp()) , _username( this, st::defaultInputField, rpl::single(qsl("@username")), session->user()->username, - false) + QString()) , _link(this, QString(), st::boxLinkButton) , _about(st::boxWidth - st::usernamePadding.left()) , _checkTimer(this) { @@ -94,7 +94,8 @@ void UsernameBox::paintEvent(QPaintEvent *e) { if (_link->isHidden()) { p.drawTextLeft(st::usernamePadding.left(), linky, width(), tr::lng_username_link_willbe(tr::now)); p.setPen(st::usernameDefaultFg); - p.drawTextLeft(st::usernamePadding.left(), linky + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2), width(), Core::App().createInternalLinkFull(qsl("username"))); + const auto link = _session->createInternalLinkFull(qsl("username")); + p.drawTextLeft(st::usernamePadding.left(), linky + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2), width(), link); } else { p.drawTextLeft(st::usernamePadding.left(), linky, width(), tr::lng_username_link(tr::now)); } @@ -179,7 +180,8 @@ void UsernameBox::changed() { } void UsernameBox::linkClick() { - QGuiApplication::clipboard()->setText(Core::App().createInternalLinkFull(getName())); + QGuiApplication::clipboard()->setText( + _session->createInternalLinkFull(getName())); Ui::Toast::Show(tr::lng_username_copied(tr::now)); } @@ -251,7 +253,7 @@ QString UsernameBox::getName() const { void UsernameBox::updateLinkText() { QString uname = getName(); - _link->setText(st::boxTextFont->elided(Core::App().createInternalLinkFull(uname), st::boxWidth - st::usernamePadding.left() - st::usernamePadding.right())); + _link->setText(st::boxTextFont->elided(_session->createInternalLinkFull(uname), st::boxWidth - st::usernamePadding.left() - st::usernamePadding.right())); if (uname.isEmpty()) { if (!_link->isHidden()) { _link->hide(); diff --git a/Telegram/SourceFiles/calls/calls_box_controller.cpp b/Telegram/SourceFiles/calls/calls_box_controller.cpp index 3f7dd8c38..b3eb152be 100644 --- a/Telegram/SourceFiles/calls/calls_box_controller.cpp +++ b/Telegram/SourceFiles/calls/calls_box_controller.cpp @@ -216,7 +216,7 @@ void BoxController::Row::stopLastActionRipple() { BoxController::BoxController(not_null window) : _window(window) -, _api(_window->session().mtp()) { +, _api(&_window->session().mtp()) { } Main::Session &BoxController::session() const { diff --git a/Telegram/SourceFiles/calls/calls_call.cpp b/Telegram/SourceFiles/calls/calls_call.cpp index 25cc94531..27079ffad 100644 --- a/Telegram/SourceFiles/calls/calls_call.cpp +++ b/Telegram/SourceFiles/calls/calls_call.cpp @@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "calls/calls_instance.h" #include "base/openssl_help.h" #include "mtproto/mtproto_dh_utils.h" +#include "mtproto/mtproto_config.h" #include "media/audio/media_audio_track.h" #include "base/platform/base_platform_info.h" #include "calls/calls_panel.h" @@ -96,7 +97,7 @@ Call::Call( Type type) : _delegate(delegate) , _user(user) -, _api(_user->session().mtp()) +, _api(&_user->session().mtp()) , _type(type) { _discardByTimeoutTimer.setCallback([this] { hangup(); }); @@ -193,7 +194,8 @@ void Call::startOutgoing() { return; } - _discardByTimeoutTimer.callOnce(Global::CallReceiveTimeoutMs()); + const auto &config = _user->session().serverConfig(); + _discardByTimeoutTimer.callOnce(config.callReceiveTimeoutMs); handleUpdate(phoneCall); }).fail([this](const RPCError &error) { handleRequestError(error); @@ -382,7 +384,8 @@ bool Call::handleUpdate(const MTPPhoneCall &call) { if (_type == Type::Outgoing && _state == State::Waiting && data.vreceive_date().value_or_empty() != 0) { - _discardByTimeoutTimer.callOnce(Global::CallRingTimeoutMs()); + const auto &config = _user->session().serverConfig(); + _discardByTimeoutTimer.callOnce(config.callRingTimeoutMs); setState(State::Ringing); startWaitingTrack(); } @@ -534,6 +537,7 @@ void Call::createAndStartController(const MTPDphoneCall &call) { } const auto &protocol = call.vprotocol().c_phoneCallProtocol(); + const auto &serverConfig = _user->session().serverConfig(); TgVoipConfig config; config.dataSaving = TgVoipDataSaving::Never; @@ -541,8 +545,8 @@ void Call::createAndStartController(const MTPDphoneCall &call) { config.enableNS = true; config.enableAGC = true; config.enableVolumeControl = true; - config.initializationTimeout = Global::CallConnectTimeoutMs() / 1000.; - config.receiveTimeout = Global::CallPacketTimeoutMs() / 1000.; + config.initializationTimeout = serverConfig.callConnectTimeoutMs / 1000.; + config.receiveTimeout = serverConfig.callPacketTimeoutMs / 1000.; config.enableP2P = call.is_p2p_allowed(); config.maxApiLayer = protocol.vmax_layer().v; if (Logs::DebugEnabled()) { diff --git a/Telegram/SourceFiles/calls/calls_instance.cpp b/Telegram/SourceFiles/calls/calls_instance.cpp index 4809102ae..2916f073b 100644 --- a/Telegram/SourceFiles/calls/calls_instance.cpp +++ b/Telegram/SourceFiles/calls/calls_instance.cpp @@ -21,8 +21,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "platform/platform_specific.h" #include "base/unixtime.h" #include "mainwidget.h" +#include "mtproto/mtproto_config.h" #include "boxes/rate_call_box.h" -#include "facades.h" #include "app.h" namespace Calls { @@ -34,7 +34,7 @@ constexpr auto kServerConfigUpdateTimeoutMs = 24 * 3600 * crl::time(1000); Instance::Instance(not_null session) : _session(session) -, _api(_session->mtp()) { +, _api(&_session->mtp()) { } void Instance::startOutgoingCall(not_null user) { @@ -248,6 +248,7 @@ void Instance::handleCallUpdate(const MTPPhoneCall &call) { } else if (user->isSelf()) { LOG(("API Error: Self found in phoneCallRequested.")); } + const auto &config = _session->serverConfig(); if (alreadyInCall() || !user || user->isSelf()) { _api.request(MTPphone_DiscardCall( MTP_flags(0), @@ -256,7 +257,7 @@ void Instance::handleCallUpdate(const MTPPhoneCall &call) { MTP_phoneCallDiscardReasonBusy(), MTP_long(0) )).send(); - } else if (phoneCall.vdate().v + (Global::CallRingTimeoutMs() / 1000) + } else if (phoneCall.vdate().v + (config.callRingTimeoutMs / 1000) < base::unixtime::now()) { LOG(("Ignoring too old call.")); } else { diff --git a/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp index 70d7cb756..6fb082fc0 100644 --- a/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp @@ -134,7 +134,7 @@ GifsListWidget::GifsListWidget( QWidget *parent, not_null controller) : Inner(parent, controller) -, _api(controller->session().mtp()) +, _api(&controller->session().mtp()) , _section(Section::Gifs) , _updateInlineItems([=] { updateInlineItems(); }) , _previewTimer([=] { showPreview(); }) { diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp index ea87276a8..d82fbddee 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp @@ -873,7 +873,7 @@ StickersListWidget::StickersListWidget( QWidget *parent, not_null controller) : Inner(parent, controller) -, _api(controller->session().mtp()) +, _api(&controller->session().mtp()) , _section(Section::Stickers) , _megagroupSetAbout(st::columnMinimalWidthThird - st::emojiScroll.width - st::emojiPanHeaderLeft) , _addText(tr::lng_stickers_featured_add(tr::now).toUpper()) diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index ba1ffae8a..cd8f4eaef 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -39,7 +39,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_accounts.h" #include "main/main_session.h" #include "media/view/media_view_overlay_widget.h" -#include "mtproto/dc_options.h" +#include "mtproto/mtproto_dc_options.h" +#include "mtproto/mtproto_config.h" #include "mtproto/mtp_instance.h" #include "media/audio/media_audio.h" #include "media/audio/media_audio_track.h" @@ -95,7 +96,8 @@ Application::Application(not_null launcher) , _private(std::make_unique()) , _databases(std::make_unique()) , _animationsManager(std::make_unique()) -, _dcOptions(std::make_unique()) +, _fallbackProductionConfig( + std::make_unique(MTP::Environment::Production)) , _accounts(std::make_unique(cDataFile())) , _langpack(std::make_unique()) , _langCloudManager(std::make_unique(langpack())) @@ -122,12 +124,8 @@ Application::Application(not_null launcher) }, _lifetime); accounts().activeValue( - ) | rpl::map([=](Main::Account *account) { - return account ? account->mtpValue() : rpl::never(); - }) | rpl::flatten_latest( - ) | rpl::filter([=](MTP::Instance *instance) { - return instance != nullptr; - }) | rpl::start_with_next([=] { + ) | rpl::filter(rpl::mappers::_1 != nullptr + ) | rpl::take(1) | rpl::start_with_next([=] { if (_window) { // Global::DesktopNotify is used in updateTrayMenu. // This should be called when user settings are read. @@ -149,14 +147,7 @@ Application::~Application() { } unlockTerms(); - for (const auto &[index, account] : accounts().list()) { - if (account->sessionExists()) { - account->session().saveSettingsNowIfNeeded(); - } - // Some MTP requests can be cancelled from data clearing. - account->destroySession(); - account->clearMtp(); - } + accounts().finish(); Local::finish(); @@ -269,7 +260,7 @@ void Application::run() { _window->showSettings(); } - _window->updateIsActive(Global::OnlineFocusTimeout()); + _window->updateIsActiveFocus(); for (const auto &error : Shortcuts::Errors()) { LOG(("Shortcuts Error: %1").arg(error)); @@ -399,6 +390,30 @@ void Application::saveSettingsDelayed(crl::time delay) { _saveSettingsTimer.callOnce(delay); } +MTP::Config &Application::fallbackProductionConfig() const { + if (!_fallbackProductionConfig) { + _fallbackProductionConfig = std::make_unique( + MTP::Environment::Production); + } + return *_fallbackProductionConfig; +} + +void Application::refreshFallbackProductionConfig( + const MTP::Config &config) { + if (config.environment() == MTP::Environment::Production) { + _fallbackProductionConfig = std::make_unique(config); + } +} + +void Application::constructFallbackProductionConfig( + const QByteArray &serialized) { + if (auto config = MTP::Config::FromSerialized(serialized)) { + if (config->environment() == MTP::Environment::Production) { + _fallbackProductionConfig = std::move(config); + } + } +} + void Application::setCurrentProxy( const MTP::ProxyData &proxy, MTP::ProxyData::Settings settings) { @@ -436,18 +451,6 @@ void Application::badMtprotoConfigurationError() { void Application::startLocalStorage() { Local::start(); - - const auto writing = _lifetime.make_state(false); - _dcOptions->changed( - ) | rpl::filter([=] { - return !*writing; - }) | rpl::start_with_next([=] { - *writing = true; - Ui::PostponeCall(this, [=] { - Local::writeSettings(); - }); - }, _lifetime); - _saveSettingsTimer.setCallback([=] { Local::writeSettings(); }); } @@ -498,13 +501,13 @@ void Application::stateChanged(Qt::ApplicationState state) { void Application::handleAppActivated() { checkLocalTime(); if (_window) { - _window->updateIsActive(Global::OnlineFocusTimeout()); + _window->updateIsActiveFocus(); } } void Application::handleAppDeactivated() { if (_window) { - _window->updateIsActive(Global::OfflineBlurTimeout()); + _window->updateIsActiveBlur(); } Ui::Tooltip::Hide(); } @@ -530,21 +533,6 @@ void Application::switchDebugMode() { } } -void Application::switchTestMode() { - if (cTestMode()) { - QFile(cWorkingDir() + qsl("tdata/withtestmode")).remove(); - cSetTestMode(false); - } else { - QFile f(cWorkingDir() + qsl("tdata/withtestmode")); - if (f.open(QIODevice::WriteOnly)) { - f.write("1"); - f.close(); - } - cSetTestMode(true); - } - App::restart(); -} - void Application::switchFreeType() { if (cUseFreeType()) { QFile(cWorkingDir() + qsl("tdata/withfreetype")).remove(); @@ -613,45 +601,6 @@ bool Application::canApplyLangPackWithoutRestart() const { return true; } -void Application::setInternalLinkDomain(const QString &domain) const { - // This domain should start with 'http[s]://' and end with '/'. - // Like 'https://telegram.me/' or 'https://t.me/'. - auto validate = [](const auto &domain) { - const auto prefixes = { - qstr("https://"), - qstr("http://"), - }; - for (const auto &prefix : prefixes) { - if (domain.startsWith(prefix, Qt::CaseInsensitive)) { - return domain.endsWith('/'); - } - } - return false; - }; - if (validate(domain) && domain != Global::InternalLinksDomain()) { - Global::SetInternalLinksDomain(domain); - } -} - -QString Application::createInternalLink(const QString &query) const { - auto result = createInternalLinkFull(query); - auto prefixes = { - qstr("https://"), - qstr("http://"), - }; - for (auto &prefix : prefixes) { - if (result.startsWith(prefix, Qt::CaseInsensitive)) { - return result.mid(prefix.size()); - } - } - LOG(("Warning: bad internal url '%1'").arg(result)); - return result; -} - -QString Application::createInternalLinkFull(const QString &query) const { - return Global::InternalLinksDomain() + query; -} - void Application::checkStartUrl() { if (!cStartUrl().isEmpty() && !locked()) { const auto url = cStartUrl(); diff --git a/Telegram/SourceFiles/core/application.h b/Telegram/SourceFiles/core/application.h index fb39c552c..e85a3e49b 100644 --- a/Telegram/SourceFiles/core/application.h +++ b/Telegram/SourceFiles/core/application.h @@ -49,7 +49,7 @@ class BoxContent; } // namespace Ui namespace MTP { -class DcOptions; +class Config; class Instance; class AuthKey; using AuthKeyPtr = std::shared_ptr; @@ -82,6 +82,11 @@ struct LocalUrlHandler; class Application final : public QObject, private base::Subscriber { public: + struct ProxyChange { + MTP::ProxyData was; + MTP::ProxyData now; + }; + Application(not_null launcher); Application(const Application &other) = delete; Application &operator=(const Application &other) = delete; @@ -132,14 +137,10 @@ public: } void saveSettingsDelayed(crl::time delay = kDefaultSaveDelay); - // Dc options and proxy. - [[nodiscard]] not_null dcOptions() { - return _dcOptions.get(); - } - struct ProxyChange { - MTP::ProxyData was; - MTP::ProxyData now; - }; + // Fallback config and proxy. + [[nodiscard]] MTP::Config &fallbackProductionConfig() const; + void refreshFallbackProductionConfig(const MTP::Config &config); + void constructFallbackProductionConfig(const QByteArray &serialized); void setCurrentProxy( const MTP::ProxyData &proxy, MTP::ProxyData::Settings settings); @@ -183,9 +184,6 @@ public: } // Internal links. - void setInternalLinkDomain(const QString &domain) const; - [[nodiscard]] QString createInternalLink(const QString &query) const; - [[nodiscard]] QString createInternalLinkFull(const QString &query) const; void checkStartUrl(); bool openLocalUrl(const QString &url, QVariant context); bool openInternalUrl(const QString &url, QVariant context); @@ -231,7 +229,6 @@ public: void handleAppDeactivated(); void switchDebugMode(); - void switchTestMode(); void switchFreeType(); void writeInstallBetaVersionsSetting(); @@ -284,7 +281,7 @@ private: const std::unique_ptr _databases; const std::unique_ptr _animationsManager; - const std::unique_ptr _dcOptions; + mutable std::unique_ptr _fallbackProductionConfig; const std::unique_ptr _accounts; std::unique_ptr _window; std::unique_ptr _mediaView; diff --git a/Telegram/SourceFiles/core/launcher.cpp b/Telegram/SourceFiles/core/launcher.cpp index b15a25c40..85ef0654e 100644 --- a/Telegram/SourceFiles/core/launcher.cpp +++ b/Telegram/SourceFiles/core/launcher.cpp @@ -97,12 +97,6 @@ void ComputeDebugMode() { } } -void ComputeTestMode() { - if (QFile::exists(cWorkingDir() + qsl("tdata/withtestmode"))) { - cSetTestMode(true); - } -} - void ComputeExternalUpdater() { QFile file(qsl("/etc/tdesktop/externalupdater")); @@ -350,7 +344,6 @@ int Launcher::exec() { void Launcher::workingFolderReady() { srand((unsigned int)time(nullptr)); - ComputeTestMode(); ComputeDebugMode(); ComputeExternalUpdater(); ComputeFreeType(); @@ -476,7 +469,6 @@ void Launcher::processArguments() { if (parseResult.contains("-externalupdater")) { SetUpdaterDisabledAtStartup(); } - gTestMode = parseResult.contains("-testmode"); gUseFreeType = parseResult.contains("-freetype"); Logs::SetDebugEnabled(parseResult.contains("-debug")); gManyInstance = parseResult.contains("-many"); diff --git a/Telegram/SourceFiles/data/data_folder.cpp b/Telegram/SourceFiles/data/data_folder.cpp index 06ef2d1fa..9d0065dff 100644 --- a/Telegram/SourceFiles/data/data_folder.cpp +++ b/Telegram/SourceFiles/data/data_folder.cpp @@ -20,9 +20,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_account.h" //#include "storage/storage_feed_messages.h" // #feed #include "main/main_session.h" +#include "mtproto/mtproto_config.h" #include "apiwrap.h" #include "mainwidget.h" -#include "facades.h" #include "styles/style_dialogs.h" namespace Data { @@ -31,17 +31,6 @@ namespace { constexpr auto kLoadedChatsMinCount = 20; constexpr auto kShowChatNamesCount = 8; -rpl::producer PinnedDialogsInFolderMaxValue( - not_null session) { - return rpl::single( - rpl::empty_value() - ) | rpl::then( - session->account().configUpdates() - ) | rpl::map([=] { - return Global::PinnedDialogsInFolderMax(); - }); -} - } // namespace // #feed @@ -60,7 +49,7 @@ Folder::Folder(not_null owner, FolderId id) , _chatsList( &owner->session(), FilterId(), - PinnedDialogsInFolderMaxValue(&owner->session())) + owner->session().serverConfig().pinnedDialogsInFolderMax.value()) , _name(tr::lng_archived_name(tr::now)) { indexNameParts(); diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index 4b1aadc1c..6a50820ae 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -24,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_session.h" #include "main/main_account.h" #include "main/main_app_config.h" +#include "mtproto/mtproto_config.h" #include "core/application.h" #include "mainwindow.h" #include "window/window_session_controller.h" @@ -34,7 +35,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/history_view_element.h" #include "history/history_item.h" #include "storage/file_download.h" -#include "facades.h" +#include "facades.h" // Ui::showPeerProfile #include "app.h" namespace { @@ -763,8 +764,8 @@ Data::RestrictionCheckResult PeerData::amRestricted( bool PeerData::canRevokeFullHistory() const { return isUser() && !isSelf() - && Global::RevokePrivateInbox() - && (Global::RevokePrivateTimeLimit() == 0x7FFFFFFF); + && session().serverConfig().revokePrivateInbox + && (session().serverConfig().revokePrivateTimeLimit == 0x7FFFFFFF); } bool PeerData::slowmodeApplied() const { diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index 56e5642a0..c4108d54d 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/image/image_location_factory.h" // Images::FromPhotoSize #include "export/export_controller.h" #include "export/view/export_view_panel_controller.h" +#include "mtproto/mtproto_config.h" #include "window/notifications_manager.h" #include "history/history.h" #include "history/history_item_components.h" @@ -54,7 +55,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/platform/base_platform_info.h" #include "base/unixtime.h" #include "base/call_delayed.h" -#include "facades.h" +#include "facades.h" // Notify::switchInlineBotButtonReceived #include "app.h" #include "styles/style_boxes.h" // st::backgroundSize @@ -188,17 +189,6 @@ std::vector ExtractUnavailableReasons( return FindInlineThumbnail(data.vsizes().v); } -[[nodiscard]] rpl::producer PinnedDialogsCountMaxValue( - not_null session) { - return rpl::single( - rpl::empty_value() - ) | rpl::then( - session->account().configUpdates() - ) | rpl::map([=] { - return Global::PinnedDialogsCountMax(); - }); -} - } // namespace Session::Session(not_null session) @@ -209,7 +199,10 @@ Session::Session(not_null session) , _bigFileCache(Core::App().databases().get( _session->local().cacheBigFilePath(), _session->local().cacheBigFileSettings())) -, _chatsList(session, FilterId(), PinnedDialogsCountMaxValue(session)) +, _chatsList( + session, + FilterId(), + session->serverConfig().pinnedDialogsCountMax.value()) , _contactsList(Dialogs::SortMode::Name) , _contactsNoChatsList(Dialogs::SortMode::Name) , _selfDestructTimer([=] { checkSelfDestructItems(); }) @@ -929,7 +922,7 @@ void Session::startExport(const MTPInputPeer &singlePeer) { return; } _export = std::make_unique( - session().mtp().get(), + &session().mtp(), singlePeer); _exportPanel = std::make_unique( &session(), @@ -1660,8 +1653,8 @@ int Session::pinnedChatsLimit( FilterId filterId) const { if (!filterId) { return folder - ? Global::PinnedDialogsInFolderMax() - : Global::PinnedDialogsCountMax(); + ? session().serverConfig().pinnedDialogsInFolderMax.current() + : session().serverConfig().pinnedDialogsCountMax.current(); } const auto &list = chatsFilters().list(); const auto i = ranges::find(list, filterId, &Data::ChatFilter::id); diff --git a/Telegram/SourceFiles/data/data_types.cpp b/Telegram/SourceFiles/data/data_types.cpp index bd54884b8..39d845878 100644 --- a/Telegram/SourceFiles/data/data_types.cpp +++ b/Telegram/SourceFiles/data/data_types.cpp @@ -48,7 +48,7 @@ Storage::Cache::Key DocumentThumbCacheKey(int32 dcId, uint64 id) { } Storage::Cache::Key WebDocumentCacheKey(const WebFileLocation &location) { - const auto CacheDcId = cTestMode() ? 2 : 4; + const auto CacheDcId = 4; // The default production value. Doesn't matter. const auto dcId = uint64(CacheDcId) & 0xFFULL; const auto &url = location.url(); const auto hash = openssl::Sha256(bytes::make_span(url)); diff --git a/Telegram/SourceFiles/data/data_wall_paper.cpp b/Telegram/SourceFiles/data/data_wall_paper.cpp index 0b54c0de7..e8437169c 100644 --- a/Telegram/SourceFiles/data/data_wall_paper.cpp +++ b/Telegram/SourceFiles/data/data_wall_paper.cpp @@ -154,11 +154,11 @@ bool WallPaper::hasShareUrl() const { return !_slug.isEmpty(); } -QString WallPaper::shareUrl() const { +QString WallPaper::shareUrl(not_null session) const { if (!hasShareUrl()) { return QString(); } - const auto base = Core::App().createInternalLinkFull("bg/" + _slug); + const auto base = session->createInternalLinkFull("bg/" + _slug); auto params = QStringList(); if (isPattern()) { if (_backgroundColor) { diff --git a/Telegram/SourceFiles/data/data_wall_paper.h b/Telegram/SourceFiles/data/data_wall_paper.h index 50fef65e0..98957c78e 100644 --- a/Telegram/SourceFiles/data/data_wall_paper.h +++ b/Telegram/SourceFiles/data/data_wall_paper.h @@ -35,7 +35,7 @@ public: [[nodiscard]] bool isBlurred() const; [[nodiscard]] int patternIntensity() const; [[nodiscard]] bool hasShareUrl() const; - [[nodiscard]] QString shareUrl() const; + [[nodiscard]] QString shareUrl(not_null session) const; void loadDocument() const; void loadDocumentThumbnail() const; diff --git a/Telegram/SourceFiles/data/stickers/data_stickers.cpp b/Telegram/SourceFiles/data/stickers/data_stickers.cpp index 39bbcb5e5..e5daeb82c 100644 --- a/Telegram/SourceFiles/data/stickers/data_stickers.cpp +++ b/Telegram/SourceFiles/data/stickers/data_stickers.cpp @@ -19,10 +19,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "apiwrap.h" #include "storage/storage_account.h" #include "main/main_session.h" +#include "mtproto/mtproto_config.h" #include "ui/toast/toast.h" #include "ui/image/image_location_factory.h" #include "base/unixtime.h" -#include "facades.h" #include "styles/style_chat_helpers.h" namespace Data { @@ -142,7 +142,9 @@ void Stickers::incrementSticker(not_null document) { break; } } - while (!recent.isEmpty() && set->stickers.size() + recent.size() > Global::StickersRecentLimit()) { + while (!recent.isEmpty() + && (set->stickers.size() + recent.size() + > session().serverConfig().stickersRecentLimit)) { writeOldRecent = true; recent.pop_back(); } @@ -184,7 +186,7 @@ void Stickers::addSavedGif(not_null document) { _savedGifs.remove(index); } _savedGifs.push_front(document); - if (_savedGifs.size() > Global::SavedGifsLimit()) { + if (_savedGifs.size() > session().serverConfig().savedGifsLimit) { _savedGifs.pop_back(); } session().local().writeSavedGifs(); @@ -387,7 +389,7 @@ bool Stickers::isFaved(not_null document) { } void Stickers::checkFavedLimit(StickersSet &set) { - if (set.stickers.size() <= Global::StickersFavedLimit()) { + if (set.stickers.size() <= session().serverConfig().stickersFavedLimit) { return; } auto removing = set.stickers.back(); diff --git a/Telegram/SourceFiles/export/view/export_view_panel_controller.cpp b/Telegram/SourceFiles/export/view/export_view_panel_controller.cpp index 4c98e7f6c..c8435ce5c 100644 --- a/Telegram/SourceFiles/export/view/export_view_panel_controller.cpp +++ b/Telegram/SourceFiles/export/view/export_view_panel_controller.cpp @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/labels.h" #include "ui/widgets/separate_panel.h" #include "ui/wrap/padding_wrap.h" +#include "mtproto/mtproto_config.h" #include "boxes/confirm_box.h" #include "lang/lang_keys.h" #include "storage/storage_account.h" @@ -20,7 +21,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_session.h" #include "base/platform/base_platform_info.h" #include "base/unixtime.h" -#include "facades.h" #include "styles/style_export.h" #include "styles/style_layers.h" @@ -77,9 +77,9 @@ void SuggestBox::prepare() { } // namespace -Environment PrepareEnvironment() { +Environment PrepareEnvironment(not_null session) { auto result = Environment(); - result.internalLinksDomain = Global::InternalLinksDomain(); + result.internalLinksDomain = session->serverConfig().internalLinksDomain; result.aboutTelegram = tr::lng_export_about_telegram(tr::now).toUtf8(); result.aboutContacts = tr::lng_export_about_contacts(tr::now).toUtf8(); result.aboutFrequent = tr::lng_export_about_frequent(tr::now).toUtf8(); @@ -188,7 +188,7 @@ void PanelController::showSettings() { settings->startClicks( ) | rpl::start_with_next([=]() { showProgress(); - _process->startExport(*_settings, PrepareEnvironment()); + _process->startExport(*_settings, PrepareEnvironment(_session)); }, settings->lifetime()); settings->cancelClicks( diff --git a/Telegram/SourceFiles/export/view/export_view_panel_controller.h b/Telegram/SourceFiles/export/view/export_view_panel_controller.h index ddcf2cba7..afed15f1b 100644 --- a/Telegram/SourceFiles/export/view/export_view_panel_controller.h +++ b/Telegram/SourceFiles/export/view/export_view_panel_controller.h @@ -22,12 +22,8 @@ class Session; } // namespace Main namespace Export { - -struct Environment; - namespace View { -Environment PrepareEnvironment(); QPointer SuggestStart(not_null session); void ClearSuggestStart(not_null session); bool IsDefaultPath(not_null session, const QString &path); diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index d101f9df6..8e72aed3d 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -356,43 +356,6 @@ struct Data { float64 VideoVolume = kDefaultVolume; base::Observable VideoVolumeChanged; - // config - int32 ChatSizeMax = 200; - int32 MegagroupSizeMax = 10000; - int32 ForwardedCountMax = 100; - int32 OnlineUpdatePeriod = 120000; - int32 OfflineBlurTimeout = 5000; - int32 OfflineIdleTimeout = 30000; - int32 OnlineFocusTimeout = 1000; - int32 OnlineCloudTimeout = 300000; - int32 NotifyCloudDelay = 30000; - int32 NotifyDefaultDelay = 1500; - int32 PushChatPeriod = 60000; - int32 PushChatLimit = 2; - int32 SavedGifsLimit = 200; - int32 EditTimeLimit = 172800; - int32 RevokeTimeLimit = 172800; - int32 RevokePrivateTimeLimit = 172800; - bool RevokePrivateInbox = false; - int32 StickersRecentLimit = 30; - int32 StickersFavedLimit = 5; - int32 PinnedDialogsCountMax = 5; - int32 PinnedDialogsInFolderMax = 100; - QString InternalLinksDomain = qsl("https://t.me/"); - int32 ChannelsReadMediaPeriod = 86400 * 7; - int32 CallReceiveTimeoutMs = 20000; - int32 CallRingTimeoutMs = 90000; - int32 CallConnectTimeoutMs = 30000; - int32 CallPacketTimeoutMs = 10000; - int32 WebFileDcId = cTestMode() ? 2 : 4; - QString TxtDomainString = cTestMode() - ? qsl("tapv3.stel.com") - : qsl("apv3.stel.com"); - bool PhoneCallsEnabled = true; - bool BlockedMode = false; - int32 CaptionLengthMax = 1024; - base::Observable PhoneCallsEnabledChanged; - HiddenPinnedMessagesMap HiddenPinnedMessages; bool AskDownloadPath = false; @@ -475,41 +438,6 @@ DefineRefVar(Global, base::Observable, SongVolumeChanged); DefineVar(Global, float64, VideoVolume); DefineRefVar(Global, base::Observable, VideoVolumeChanged); -// config -DefineVar(Global, int32, ChatSizeMax); -DefineVar(Global, int32, MegagroupSizeMax); -DefineVar(Global, int32, ForwardedCountMax); -DefineVar(Global, int32, OnlineUpdatePeriod); -DefineVar(Global, int32, OfflineBlurTimeout); -DefineVar(Global, int32, OfflineIdleTimeout); -DefineVar(Global, int32, OnlineFocusTimeout); -DefineVar(Global, int32, OnlineCloudTimeout); -DefineVar(Global, int32, NotifyCloudDelay); -DefineVar(Global, int32, NotifyDefaultDelay); -DefineVar(Global, int32, PushChatPeriod); -DefineVar(Global, int32, PushChatLimit); -DefineVar(Global, int32, SavedGifsLimit); -DefineVar(Global, int32, EditTimeLimit); -DefineVar(Global, int32, RevokeTimeLimit); -DefineVar(Global, int32, RevokePrivateTimeLimit); -DefineVar(Global, bool, RevokePrivateInbox); -DefineVar(Global, int32, StickersRecentLimit); -DefineVar(Global, int32, StickersFavedLimit); -DefineVar(Global, int32, PinnedDialogsCountMax); -DefineVar(Global, int32, PinnedDialogsInFolderMax); -DefineVar(Global, QString, InternalLinksDomain); -DefineVar(Global, int32, ChannelsReadMediaPeriod); -DefineVar(Global, int32, CallReceiveTimeoutMs); -DefineVar(Global, int32, CallRingTimeoutMs); -DefineVar(Global, int32, CallConnectTimeoutMs); -DefineVar(Global, int32, CallPacketTimeoutMs); -DefineVar(Global, int32, WebFileDcId); -DefineVar(Global, QString, TxtDomainString); -DefineVar(Global, bool, PhoneCallsEnabled); -DefineVar(Global, bool, BlockedMode); -DefineVar(Global, int32, CaptionLengthMax); -DefineRefVar(Global, base::Observable, PhoneCallsEnabledChanged); - DefineVar(Global, HiddenPinnedMessagesMap, HiddenPinnedMessages); DefineVar(Global, bool, AskDownloadPath); diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h index 7d5be71e5..f83201fac 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -166,41 +166,6 @@ DeclareRefVar(base::Observable, SongVolumeChanged); DeclareVar(float64, VideoVolume); DeclareRefVar(base::Observable, VideoVolumeChanged); -// config -DeclareVar(int32, ChatSizeMax); -DeclareVar(int32, MegagroupSizeMax); -DeclareVar(int32, ForwardedCountMax); -DeclareVar(int32, OnlineUpdatePeriod); -DeclareVar(int32, OfflineBlurTimeout); -DeclareVar(int32, OfflineIdleTimeout); -DeclareVar(int32, OnlineFocusTimeout); // not from config -DeclareVar(int32, OnlineCloudTimeout); -DeclareVar(int32, NotifyCloudDelay); -DeclareVar(int32, NotifyDefaultDelay); -DeclareVar(int32, PushChatPeriod); -DeclareVar(int32, PushChatLimit); -DeclareVar(int32, SavedGifsLimit); -DeclareVar(int32, EditTimeLimit); -DeclareVar(int32, RevokeTimeLimit); -DeclareVar(int32, RevokePrivateTimeLimit); -DeclareVar(bool, RevokePrivateInbox); -DeclareVar(int32, StickersRecentLimit); -DeclareVar(int32, StickersFavedLimit); -DeclareVar(int32, PinnedDialogsCountMax); -DeclareVar(int32, PinnedDialogsInFolderMax); -DeclareVar(QString, InternalLinksDomain); -DeclareVar(int32, ChannelsReadMediaPeriod); -DeclareVar(int32, CallReceiveTimeoutMs); -DeclareVar(int32, CallRingTimeoutMs); -DeclareVar(int32, CallConnectTimeoutMs); -DeclareVar(int32, CallPacketTimeoutMs); -DeclareVar(int32, WebFileDcId); -DeclareVar(QString, TxtDomainString); -DeclareVar(bool, PhoneCallsEnabled); -DeclareVar(bool, BlockedMode); -DeclareVar(int32, CaptionLengthMax); -DeclareRefVar(base::Observable, PhoneCallsEnabledChanged); - typedef QMap HiddenPinnedMessagesMap; DeclareVar(HiddenPinnedMessagesMap, HiddenPinnedMessages); diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp index 43d800cd3..4ab2d87c2 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp @@ -229,7 +229,7 @@ InnerWidget::InnerWidget( , _controller(controller) , _channel(channel) , _history(channel->owner().history(channel)) -, _api(_channel->session().mtp()) +, _api(&_channel->session().mtp()) , _scrollDateCheck([=] { scrollDateCheck(); }) , _emptyText( st::historyAdminLogEmptyWidth 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 97ab2bf4e..e3939d03c 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp @@ -472,7 +472,11 @@ void GenerateItems( auto bodyClientFlags = MTPDmessage_ClientFlag::f_admin_log_entry; auto bodyReplyTo = 0; auto bodyViaBotId = 0; - auto newLink = newValue.isEmpty() ? TextWithEntities() : PrepareText(Core::App().createInternalLinkFull(newValue), QString()); + auto newLink = newValue.isEmpty() + ? TextWithEntities() + : PrepareText( + history->session().createInternalLinkFull(newValue), + QString()); auto body = history->makeMessage( history->nextNonHistoryEntryId(), bodyFlags, @@ -484,7 +488,9 @@ void GenerateItems( QString(), newLink); if (!oldValue.isEmpty()) { - auto oldLink = PrepareText(Core::App().createInternalLinkFull(oldValue), QString()); + auto oldLink = PrepareText( + history->session().createInternalLinkFull(oldValue), + QString()); body->addLogEntryOriginal(id, tr::lng_admin_log_previous_link(tr::now), oldLink); } addPart(body); diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index eccfe232f..9d00e1a6f 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history_service.h" #include "history/history_message.h" #include "history/history.h" +#include "mtproto/mtproto_config.h" #include "media/clip/media_clip_reader.h" #include "ui/effects/ripple_animation.h" #include "ui/text/text_isolated_emoji.h" @@ -42,7 +43,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_channel.h" #include "data/data_chat.h" #include "data/data_user.h" -#include "facades.h" #include "styles/style_dialogs.h" #include "styles/style_history.h" @@ -289,7 +289,8 @@ void HistoryItem::finishEditionToEmpty() { bool HistoryItem::hasUnreadMediaFlag() const { if (_history->peer->isChannel()) { const auto passed = base::unixtime::now() - date(); - if (passed >= Global::ChannelsReadMediaPeriod()) { + const auto &config = _history->session().serverConfig(); + if (passed >= config.channelsReadMediaPeriod) { return false; } } @@ -566,12 +567,13 @@ bool HistoryItem::canDelete() const { bool HistoryItem::canDeleteForEveryone(TimeId now) const { const auto peer = history()->peer; + const auto &config = history()->session().serverConfig(); const auto messageToMyself = peer->isSelf(); const auto messageTooOld = messageToMyself ? false : peer->isUser() - ? (now - date() >= Global::RevokePrivateTimeLimit()) - : (now - date() >= Global::RevokeTimeLimit()); + ? (now - date() >= config.revokePrivateTimeLimit) + : (now - date() >= config.revokeTimeLimit); if (id < 0 || messageToMyself || messageTooOld || isPost()) { return false; } @@ -599,7 +601,7 @@ bool HistoryItem::canDeleteForEveryone(TimeId now) const { return false; } } else if (peer->isUser()) { - return Global::RevokePrivateInbox(); + return config.revokePrivateInbox; } else { return false; } diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index 8e9baca51..b2b256276 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -33,6 +33,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/notifications_manager.h" #include "window/window_session_controller.h" #include "storage/storage_shared_media.h" +#include "mtproto/mtproto_config.h" #include "data/data_session.h" #include "data/data_changes.h" #include "data/data_game.h" @@ -40,7 +41,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_channel.h" #include "data/data_user.h" #include "data/data_histories.h" -#include "facades.h" +#include "facades.h" // Notify::replyMarkupUpdated #include "app.h" #include "styles/style_dialogs.h" #include "styles/style_widgets.h" @@ -208,6 +209,7 @@ void FastShareMessage(not_null item) { }; const auto history = item->history(); const auto owner = &history->owner(); + const auto session = &history->session(); const auto data = std::make_shared( history->peer, owner->itemOrItsGroup(item)); @@ -220,13 +222,11 @@ void FastShareMessage(not_null item) { auto copyCallback = [=]() { if (const auto item = owner->message(data->msgIds[0])) { if (item->hasDirectLink()) { - HistoryView::CopyPostLink( - &item->history()->session(), - item->fullId()); + HistoryView::CopyPostLink(session, item->fullId()); } else if (const auto bot = item->getMessageBot()) { if (const auto media = item->media()) { if (const auto game = media->game()) { - const auto link = Core::App().createInternalLinkFull( + const auto link = session->createInternalLinkFull( bot->username + qsl("?game=") + game->shortName); @@ -782,7 +782,7 @@ bool HistoryMessage::allowsSendNow() const { bool HistoryMessage::isTooOldForEdit(TimeId now) const { return !_history->peer->canEditMessagesIndefinitely() - && (now - date() >= Global::EditTimeLimit()); + && (now - date() >= _history->session().serverConfig().editTimeLimit); } bool HistoryMessage::allowsEdit(TimeId now) const { diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index dc169c5ea..5f3630eec 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -65,6 +65,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "chat_helpers/bot_keyboard.h" #include "chat_helpers/message_field.h" #include "platform/platform_specific.h" +#include "mtproto/mtproto_config.h" #include "lang/lang_keys.h" #include "mainwidget.h" #include "mainwindow.h" @@ -6756,7 +6757,7 @@ void HistoryWidget::paintEditHeader(Painter &p, const QRect &rect, int left, int QString editTimeLeftText; int updateIn = -1; auto timeSinceMessage = ItemDateTime(_replyEditMsg).msecsTo(QDateTime::currentDateTime()); - auto editTimeLeft = (Global::EditTimeLimit() * 1000LL) - timeSinceMessage; + auto editTimeLeft = (session().serverConfig().editTimeLimit * 1000LL) - timeSinceMessage; if (editTimeLeft < 2) { editTimeLeftText = qsl("0:00"); } else if (editTimeLeft > kDisplayEditTimeWarningMs) { diff --git a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp index 4d2fc67d8..94c5928be 100644 --- a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp @@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mainwidget.h" #include "mainwindow.h" #include "main/main_session.h" +#include "mtproto/mtproto_config.h" #include "lang/lang_keys.h" #include "core/shortcuts.h" #include "ui/widgets/buttons.h" @@ -129,9 +130,10 @@ TopBarWidget::TopBarWidget( } }, lifetime()); - subscribe(Global::RefPhoneCallsEnabledChanged(), [this] { + session().serverConfig().phoneCallsEnabled.changes( + ) | rpl::start_with_next([=] { updateControlsVisibility(); - }); + }, lifetime()); rpl::combine( session().settings().thirdSectionInfoEnabledValue(), @@ -156,8 +158,8 @@ Main::Session &TopBarWidget::session() const { } void TopBarWidget::updateConnectingState() { - const auto mtp = _controller->session().mtp()->dcstate(); - if (mtp == MTP::ConnectedState) { + const auto state = _controller->session().mtp().dcstate(); + if (state == MTP::ConnectedState) { if (_connecting) { _connecting = nullptr; update(); @@ -640,7 +642,8 @@ void TopBarWidget::updateControlsVisibility() { const auto callsEnabled = [&] { if (const auto peer = _activeChat.peer()) { if (const auto user = peer->asUser()) { - return Global::PhoneCallsEnabled() && user->hasCalls(); + return session().serverConfig().phoneCallsEnabled.current() + && user->hasCalls(); } } return false; @@ -663,7 +666,9 @@ void TopBarWidget::updateMembersShowArea() { return chat->amIn(); } if (auto megagroup = peer->asMegagroup()) { - return megagroup->canViewMembers() && (megagroup->membersCount() < Global::ChatSizeMax()); + return megagroup->canViewMembers() + && (megagroup->membersCount() + < megagroup->session().serverConfig().chatSizeMax); } return false; }(); @@ -846,7 +851,10 @@ void TopBarWidget::updateOnlineDisplay() { } } } else if (const auto channel = _activeChat.peer()->asChannel()) { - if (channel->isMegagroup() && channel->membersCount() > 0 && channel->membersCount() <= Global::ChatSizeMax()) { + if (channel->isMegagroup() + && (channel->membersCount() > 0) + && (channel->membersCount() + <= channel->session().serverConfig().chatSizeMax)) { if (channel->lastParticipantsRequestNeeded()) { session().api().requestLastParticipants(channel); } diff --git a/Telegram/SourceFiles/info/common_groups/info_common_groups_inner_widget.cpp b/Telegram/SourceFiles/info/common_groups/info_common_groups_inner_widget.cpp index e68dc414e..f1905b000 100644 --- a/Telegram/SourceFiles/info/common_groups/info_common_groups_inner_widget.cpp +++ b/Telegram/SourceFiles/info/common_groups/info_common_groups_inner_widget.cpp @@ -68,7 +68,7 @@ ListController::ListController( not_null user) : PeerListController() , _controller(controller) -, _api(_controller->session().mtp()) +, _api(&_controller->session().mtp()) , _user(user) { _controller->setSearchEnabledByContent(false); } diff --git a/Telegram/SourceFiles/info/info_wrap_widget.cpp b/Telegram/SourceFiles/info/info_wrap_widget.cpp index c6bac04d4..73192e0dc 100644 --- a/Telegram/SourceFiles/info/info_wrap_widget.cpp +++ b/Telegram/SourceFiles/info/info_wrap_widget.cpp @@ -28,12 +28,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/peer_list_box.h" #include "boxes/confirm_box.h" #include "main/main_session.h" +#include "mtproto/mtproto_config.h" #include "data/data_session.h" #include "data/data_changes.h" #include "data/data_user.h" #include "mainwidget.h" #include "lang/lang_keys.h" -#include "facades.h" #include "styles/style_info.h" #include "styles/style_profile.h" @@ -479,7 +479,9 @@ void WrapWidget::addProfileCallsButton() { const auto peer = key().peer(); const auto user = peer ? peer->asUser() : nullptr; - if (!user || user->isSelf() || !Global::PhoneCallsEnabled()) { + if (!user + || user->isSelf() + || !user->session().serverConfig().phoneCallsEnabled.current()) { return; } diff --git a/Telegram/SourceFiles/info/polls/info_polls_results_inner_widget.cpp b/Telegram/SourceFiles/info/polls/info_polls_results_inner_widget.cpp index b25cb2570..4313c1865 100644 --- a/Telegram/SourceFiles/info/polls/info_polls_results_inner_widget.cpp +++ b/Telegram/SourceFiles/info/polls/info_polls_results_inner_widget.cpp @@ -232,7 +232,7 @@ ListController::ListController( , _poll(poll) , _context(context) , _option(option) -, _api(_session->mtp()) { +, _api(&_session->mtp()) { const auto i = ranges::find(poll->answers, option, &PollAnswer::option); Assert(i != poll->answers.end()); _fullCount = i->votes; diff --git a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp index d3c704820..ad7d70d30 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp @@ -301,7 +301,7 @@ object_ptr DetailsFiller::setupInfo() { std::move(linkText), QString()); link->setClickHandlerFilter([peer = _peer](auto&&...) { - const auto link = Core::App().createInternalLinkFull( + const auto link = peer->session().createInternalLinkFull( peer->userName()); if (!link.isEmpty()) { QGuiApplication::clipboard()->setText(link); diff --git a/Telegram/SourceFiles/info/profile/info_profile_values.cpp b/Telegram/SourceFiles/info/profile/info_profile_values.cpp index 9fdd180ef..6e1bbb549 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_values.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_values.cpp @@ -133,10 +133,10 @@ rpl::producer AboutValue(not_null peer) { rpl::producer LinkValue(not_null peer) { return PlainUsernameValue( peer - ) | rpl::map([](QString &&username) { + ) | rpl::map([=](QString &&username) { return username.isEmpty() ? QString() - : Core::App().createInternalLinkFull(username); + : peer->session().createInternalLinkFull(username); }); } diff --git a/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp b/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp index 5c865404b..f8f3252a1 100644 --- a/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp @@ -746,7 +746,7 @@ Widget::Widget( not_null controller) : RpWidget(parent) , _controller(controller) -, _api(_controller->session().mtp()) +, _api(&_controller->session().mtp()) , _contentMaxHeight(st::emojiPanMaxHeight) , _contentHeight(_contentMaxHeight) , _scroll(this, st::inlineBotsScroll) { diff --git a/Telegram/SourceFiles/intro/intro_code.cpp b/Telegram/SourceFiles/intro/intro_code.cpp index b0e8ce2ae..24684ca48 100644 --- a/Telegram/SourceFiles/intro/intro_code.cpp +++ b/Telegram/SourceFiles/intro/intro_code.cpp @@ -211,9 +211,9 @@ void CodeWidget::finished() { } void CodeWidget::cancelled() { - api()->request(base::take(_sentRequest)).cancel(); - api()->request(base::take(_callRequestId)).cancel(); - api()->request(MTPauth_CancelCode( + api().request(base::take(_sentRequest)).cancel(); + api().request(base::take(_callRequestId)).cancel(); + api().request(MTPauth_CancelCode( MTP_string(getData()->phone), MTP_bytes(getData()->phoneHash) )).send(); @@ -224,12 +224,12 @@ void CodeWidget::stopCheck() { } void CodeWidget::checkRequest() { - auto status = api()->instance()->state(_sentRequest); + auto status = api().instance().state(_sentRequest); if (status < 0) { auto leftms = -status; if (leftms >= 1000) { if (_sentRequest) { - api()->request(base::take(_sentRequest)).cancel(); + api().request(base::take(_sentRequest)).cancel(); _sentCode.clear(); } } @@ -282,7 +282,7 @@ void CodeWidget::codeSubmitFail(const RPCError &error) { showCodeError(tr::lng_bad_code()); } else if (err == qstr("SESSION_PASSWORD_NEEDED")) { _checkRequestTimer.callEach(1000); - _sentRequest = api()->request(MTPaccount_GetPassword( + _sentRequest = api().request(MTPaccount_GetPassword( )).done([=](const MTPaccount_Password &result) { gotPassword(result); }).fail([=](const RPCError &error) { @@ -305,7 +305,7 @@ void CodeWidget::sendCall() { if (--_callTimeout <= 0) { _callStatus = CallStatus::Calling; _callTimer.cancel(); - _callRequestId = api()->request(MTPauth_ResendCode( + _callRequestId = api().request(MTPauth_ResendCode( MTP_string(getData()->phone), MTP_bytes(getData()->phoneHash) )).done([=](const MTPauth_SentCode &result) { @@ -383,7 +383,7 @@ void CodeWidget::submit() { getData()->hasRecovery = false; getData()->pwdHint = QString(); getData()->pwdNotEmptyPassport = false; - _sentRequest = api()->request(MTPauth_SignIn( + _sentRequest = api().request(MTPauth_SignIn( MTP_string(getData()->phone), MTP_bytes(getData()->phoneHash), MTP_string(_sentCode) @@ -398,7 +398,7 @@ void CodeWidget::noTelegramCode() { if (_noTelegramCodeRequestId) { return; } - _noTelegramCodeRequestId = api()->request(MTPauth_ResendCode( + _noTelegramCodeRequestId = api().request(MTPauth_ResendCode( MTP_string(getData()->phone), MTP_bytes(getData()->phoneHash) )).done([=](const MTPauth_SentCode &result) { diff --git a/Telegram/SourceFiles/intro/intro_password_check.cpp b/Telegram/SourceFiles/intro/intro_password_check.cpp index 76ac7b621..2a49f3255 100644 --- a/Telegram/SourceFiles/intro/intro_password_check.cpp +++ b/Telegram/SourceFiles/intro/intro_password_check.cpp @@ -114,7 +114,7 @@ void PasswordCheckWidget::activate() { } void PasswordCheckWidget::cancelled() { - api()->request(base::take(_sentRequest)).cancel(); + api().request(base::take(_sentRequest)).cancel(); } void PasswordCheckWidget::pwdSubmitDone(bool recover, const MTPauth_Authorization &result) { @@ -181,8 +181,8 @@ void PasswordCheckWidget::checkPasswordHash() { } void PasswordCheckWidget::requestPasswordData() { - api()->request(base::take(_sentRequest)).cancel(); - _sentRequest = api()->request( + api().request(base::take(_sentRequest)).cancel(); + _sentRequest = api().request( MTPaccount_GetPassword() ).done([=](const MTPaccount_Password &result) { _sentRequest = 0; @@ -204,7 +204,7 @@ void PasswordCheckWidget::passwordChecked() { return serverError(); } _request.id = 0; - _sentRequest = api()->request( + _sentRequest = api().request( MTPauth_CheckPassword(check.result) ).done([=](const MTPauth_Authorization &result) { pwdSubmitDone(false, result); @@ -266,7 +266,7 @@ void PasswordCheckWidget::recoverStartFail(const RPCError &error) { void PasswordCheckWidget::toRecover() { if (_hasRecovery) { if (_sentRequest) { - api()->request(base::take(_sentRequest)).cancel(); + api().request(base::take(_sentRequest)).cancel(); } hideError(); _toRecover->hide(); @@ -278,7 +278,7 @@ void PasswordCheckWidget::toRecover() { _codeField->setFocus(); updateDescriptionText(); if (_emailPattern.isEmpty()) { - api()->request( + api().request( MTPauth_RequestPasswordRecovery() ).done([=](const MTPauth_PasswordRecovery &result) { recoverStarted(result); @@ -301,7 +301,7 @@ void PasswordCheckWidget::toPassword() { void PasswordCheckWidget::showReset() { if (_sentRequest) { - api()->request(base::take(_sentRequest)).cancel(); + api().request(base::take(_sentRequest)).cancel(); } _toRecover->show(); _toPassword->hide(); @@ -334,7 +334,7 @@ void PasswordCheckWidget::submit() { return; } const auto send = crl::guard(this, [=] { - _sentRequest = api()->request( + _sentRequest = api().request( MTPauth_RecoverPassword(MTP_string(code)) ).done([=](const MTPauth_Authorization &result) { pwdSubmitDone(true, result); diff --git a/Telegram/SourceFiles/intro/intro_phone.cpp b/Telegram/SourceFiles/intro/intro_phone.cpp index 4e3d7cea9..9d250c47d 100644 --- a/Telegram/SourceFiles/intro/intro_phone.cpp +++ b/Telegram/SourceFiles/intro/intro_phone.cpp @@ -141,8 +141,8 @@ void PhoneWidget::submit() { _checkRequestTimer.callEach(1000); _sentPhone = phone; - api()->instance()->setUserPhone(_sentPhone); - _sentRequest = api()->request(MTPauth_SendCode( + api().instance().setUserPhone(_sentPhone); + _sentRequest = api().request(MTPauth_SendCode( MTP_string(_sentPhone), MTP_int(ApiId), MTP_string(ApiHash), @@ -159,11 +159,11 @@ void PhoneWidget::stopCheck() { } void PhoneWidget::checkRequest() { - auto status = api()->instance()->state(_sentRequest); + auto status = api().instance().state(_sentRequest); if (status < 0) { auto leftms = -status; if (leftms >= 1000) { - api()->request(base::take(_sentRequest)).cancel(); + api().request(base::take(_sentRequest)).cancel(); } } if (!_sentRequest && status == MTP::RequestSent) { @@ -246,7 +246,7 @@ void PhoneWidget::finished() { } void PhoneWidget::cancelled() { - api()->request(base::take(_sentRequest)).cancel(); + api().request(base::take(_sentRequest)).cancel(); } } // namespace details diff --git a/Telegram/SourceFiles/intro/intro_qr.cpp b/Telegram/SourceFiles/intro/intro_qr.cpp index 84daee0b3..9cc11fbc1 100644 --- a/Telegram/SourceFiles/intro/intro_qr.cpp +++ b/Telegram/SourceFiles/intro/intro_qr.cpp @@ -308,7 +308,7 @@ void QrWidget::refreshCode() { if (_requestId) { return; } - _requestId = api()->request(MTPauth_ExportLoginToken( + _requestId = api().request(MTPauth_ExportLoginToken( MTP_int(ApiId), MTP_string(ApiHash), MTP_vector(0) @@ -356,8 +356,8 @@ void QrWidget::showToken(const QByteArray &token) { void QrWidget::importTo(MTP::DcId dcId, const QByteArray &token) { Expects(_requestId != 0); - api()->instance()->setMainDcId(dcId); - _requestId = api()->request(MTPauth_ImportLoginToken( + api().instance().setMainDcId(dcId); + _requestId = api().request(MTPauth_ImportLoginToken( MTP_bytes(token) )).done([=](const MTPauth_LoginToken &result) { handleTokenResult(result); @@ -382,7 +382,7 @@ void QrWidget::done(const MTPauth_Authorization &authorization) { } void QrWidget::sendCheckPasswordRequest() { - _requestId = api()->request(MTPaccount_GetPassword( + _requestId = api().request(MTPaccount_GetPassword( )).done([=](const MTPaccount_Password &result) { result.match([&](const MTPDaccount_password &data) { getData()->pwdRequest = Core::ParseCloudPasswordCheckRequest( @@ -426,7 +426,7 @@ void QrWidget::finished() { } void QrWidget::cancelled() { - api()->request(base::take(_requestId)).cancel(); + api().request(base::take(_requestId)).cancel(); } } // namespace details diff --git a/Telegram/SourceFiles/intro/intro_signup.cpp b/Telegram/SourceFiles/intro/intro_signup.cpp index f82a54576..df2d2c06d 100644 --- a/Telegram/SourceFiles/intro/intro_signup.cpp +++ b/Telegram/SourceFiles/intro/intro_signup.cpp @@ -101,7 +101,7 @@ void SignupWidget::activate() { } void SignupWidget::cancelled() { - api()->request(base::take(_sentRequest)).cancel(); + api().request(base::take(_sentRequest)).cancel(); } void SignupWidget::nameSubmitDone(const MTPauth_Authorization &result) { @@ -181,7 +181,7 @@ void SignupWidget::submit() { _firstName = _first->getLastText().trimmed(); _lastName = _last->getLastText().trimmed(); - _sentRequest = api()->request(MTPauth_SignUp( + _sentRequest = api().request(MTPauth_SignUp( MTP_string(getData()->phone), MTP_bytes(getData()->phoneHash), MTP_string(_firstName), diff --git a/Telegram/SourceFiles/intro/intro_step.cpp b/Telegram/SourceFiles/intro/intro_step.cpp index 1010b0beb..70c62b864 100644 --- a/Telegram/SourceFiles/intro/intro_step.cpp +++ b/Telegram/SourceFiles/intro/intro_step.cpp @@ -98,11 +98,11 @@ Step::Step( Step::~Step() = default; -not_null Step::api() const { +MTP::Sender &Step::api() const { if (!_api) { - _api.emplace(_account->mtp()); + _api.emplace(&_account->mtp()); } - return &*_api; + return *_api; } void Step::apiClear() { diff --git a/Telegram/SourceFiles/intro/intro_step.h b/Telegram/SourceFiles/intro/intro_step.h index 24b671196..1aa6c4a50 100644 --- a/Telegram/SourceFiles/intro/intro_step.h +++ b/Telegram/SourceFiles/intro/intro_step.h @@ -45,7 +45,7 @@ public: // It should not be called in StartWidget, in other steps it should be // present and not changing. - [[nodiscard]] not_null api() const; + [[nodiscard]] MTP::Sender &api() const; void apiClear(); virtual void finishInit() { diff --git a/Telegram/SourceFiles/intro/intro_widget.cpp b/Telegram/SourceFiles/intro/intro_widget.cpp index 147efa6fb..33f1c3198 100644 --- a/Telegram/SourceFiles/intro/intro_widget.cpp +++ b/Telegram/SourceFiles/intro/intro_widget.cpp @@ -24,7 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/wrap/fade_wrap.h" #include "core/update_checker.h" #include "core/application.h" -#include "mtproto/dc_options.h" +#include "mtproto/mtproto_dc_options.h" #include "window/window_slide_animation.h" #include "window/window_connecting_widget.h" #include "base/platform/base_platform_info.h" @@ -64,14 +64,11 @@ Widget::Widget(QWidget *parent, not_null account) getData()->country = Platform::SystemCountry(); _account->mtpValue( - ) | rpl::start_with_next([=](MTP::Instance *instance) { - if (instance) { - _api.emplace(instance); - createLanguageLink(); - } else { - _api.reset(); - } + ) | rpl::start_with_next([=](not_null instance) { + _api.emplace(instance); + createLanguageLink(); }, lifetime()); + subscribe(Lang::CurrentCloudManager().firstLanguageSuggestion(), [=] { createLanguageLink(); }); @@ -141,9 +138,9 @@ void Widget::handleUpdates(const MTPUpdates &updates) { void Widget::handleUpdate(const MTPUpdate &update) { update.match([&](const MTPDupdateDcOptions &data) { - Core::App().dcOptions()->addFromList(data.vdc_options()); + _account->mtp().dcOptions().addFromList(data.vdc_options()); }, [&](const MTPDupdateConfig &data) { - _account->mtp()->requestConfig(); + _account->mtp().requestConfig(); }, [&](const MTPDupdateServiceNotification &data) { const auto text = TextWithEntities{ qs(data.vmessage()), diff --git a/Telegram/SourceFiles/lang/lang_cloud_manager.cpp b/Telegram/SourceFiles/lang/lang_cloud_manager.cpp index 61ae993dc..0351b03ea 100644 --- a/Telegram/SourceFiles/lang/lang_cloud_manager.cpp +++ b/Telegram/SourceFiles/lang/lang_cloud_manager.cpp @@ -160,15 +160,16 @@ CloudManager::CloudManager(Instance &langpack) : _langpack(langpack) { Core::App().accounts().activeValue( ) | rpl::map([=](Main::Account *account) { - return account ? account->mtpValue() : rpl::never(); - }) | rpl::flatten_latest( - ) | rpl::start_with_next([=](MTP::Instance *instance) { - if (instance) { - _api.emplace(instance); - resendRequests(); - } else { + if (!account) { _api.reset(); } + return account + ? account->mtpValue() + : rpl::never>(); + }) | rpl::flatten_latest( + ) | rpl::start_with_next([=](not_null instance) { + _api.emplace(instance); + resendRequests(); }, _lifetime); } @@ -604,7 +605,7 @@ void CloudManager::switchLangPackId(const Language &data) { void CloudManager::changeIdAndReInitConnection(const Language &data) { _langpack.switchToId(data); if (_api) { - const auto mtproto = _api->instance(); + const auto mtproto = &_api->instance(); mtproto->reInitConnection(mtproto->mainDcId()); } } diff --git a/Telegram/SourceFiles/logs.cpp b/Telegram/SourceFiles/logs.cpp index cfbc69a84..1c4bf00b6 100644 --- a/Telegram/SourceFiles/logs.cpp +++ b/Telegram/SourceFiles/logs.cpp @@ -414,16 +414,11 @@ void start(not_null launcher) { LogsData = nullptr; } - LOG(("Launched version: %1, " - "install beta: %2, " - "alpha: %3, " - "debug mode: %4, " - "test dc: %5" + LOG(("Launched version: %1, install beta: %2, alpha: %3, debug mode: %4" ).arg(AppVersion ).arg(Logs::b(cInstallBetaVersion()) ).arg(cAlphaVersion() - ).arg(Logs::b(DebugEnabled()) - ).arg(Logs::b(cTestMode()))); + ).arg(Logs::b(DebugEnabled()))); LOG(("Executable dir: %1, name: %2").arg(cExeDir()).arg(cExeName())); LOG(("Initial working dir: %1").arg(initialWorkingDir)); LOG(("Working dir: %1").arg(cWorkingDir())); diff --git a/Telegram/SourceFiles/main/main_account.cpp b/Telegram/SourceFiles/main/main_account.cpp index cb51e9620..2e690139a 100644 --- a/Telegram/SourceFiles/main/main_account.cpp +++ b/Telegram/SourceFiles/main/main_account.cpp @@ -13,12 +13,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/storage_account.h" #include "storage/storage_accounts.h" // Storage::StartResult. #include "storage/serialize_common.h" +#include "storage/serialize_peer.h" #include "storage/localstorage.h" #include "data/data_session.h" #include "data/data_user.h" #include "data/data_changes.h" #include "window/window_controller.h" #include "media/audio/media_audio.h" +#include "mtproto/mtproto_config.h" +#include "mtproto/mtproto_dc_options.h" +#include "mtproto/mtp_instance.h" #include "ui/image/image.h" #include "mainwidget.h" #include "api/api_updates.h" @@ -46,7 +50,14 @@ Account::Account(const QString &dataName, int index) ComposeDataString(dataName, index))) { } -Account::~Account() = default; +Account::~Account() { + if (sessionExists()) { + session().saveSettingsNowIfNeeded(); + } + destroySession(); + _mtpValue.reset(nullptr); + base::take(_mtp); +} [[nodiscard]] Storage::StartResult Account::legacyStart( const QByteArray &passcode) { @@ -54,22 +65,27 @@ Account::~Account() = default; const auto result = _local->legacyStart(passcode); if (result == Storage::StartResult::Success) { - finishStarting(); + finishStarting(nullptr); } return result; } void Account::start(std::shared_ptr localKey) { - _local->start(std::move(localKey)); - finishStarting(); + finishStarting(_local->start(std::move(localKey))); } -void Account::startAdded(std::shared_ptr localKey) { +void Account::startAdded( + std::shared_ptr localKey, + std::unique_ptr config) { _local->startAdded(std::move(localKey)); - finishStarting(); + finishStarting(std::move(config)); } -void Account::finishStarting() { +void Account::finishStarting(std::unique_ptr config) { + startMtp(config + ? std::move(config) + : std::make_unique( + Core::App().fallbackProductionConfig())); _appConfig = std::make_unique(this); watchProxyChanges(); watchSessionChanges(); @@ -195,12 +211,10 @@ rpl::producer Account::sessionChanges() const { return _sessionValue.changes(); } -rpl::producer Account::mtpValue() const { - return _mtpValue.value(); -} - -rpl::producer Account::mtpChanges() const { - return _mtpValue.changes(); +rpl::producer> Account::mtpValue() const { + return _mtpValue.value() | rpl::map([](MTP::Instance *instance) { + return not_null{ instance }; + }); } rpl::producer Account::mtpUpdates() const { @@ -214,14 +228,14 @@ rpl::producer<> Account::mtpNewSessionCreated() const { void Account::setLegacyMtpMainDcId(MTP::DcId mainDcId) { Expects(!_mtp); - _mtpConfig.mainDcId = mainDcId; + _mtpFields.mainDcId = mainDcId; } void Account::setLegacyMtpKey(std::shared_ptr key) { Expects(!_mtp); Expects(key != nullptr); - _mtpConfig.keys.push_back(std::move(key)); + _mtpFields.keys.push_back(std::move(key)); } QByteArray Account::serializeMtpAuthorization() const { @@ -270,9 +284,9 @@ QByteArray Account::serializeMtpAuthorization() const { : MTP::AuthKeysList(); return serialize(_mtp->mainDcId(), keys, keysToDestroy); } - const auto &keys = _mtpConfig.keys; + const auto &keys = _mtpFields.keys; const auto &keysToDestroy = _mtpKeysToDestroy; - return serialize(_mtpConfig.mainDcId, keys, keysToDestroy); + return serialize(_mtpFields.mainDcId, keys, keysToDestroy); } void Account::setSessionUserId(UserId userId) { @@ -319,9 +333,9 @@ void Account::setMtpAuthorization(const QByteArray &serialized) { } setSessionUserId(userId); - _mtpConfig.mainDcId = mainDcId; + _mtpFields.mainDcId = mainDcId; - const auto readKeys = [&stream](auto &keys) { + const auto readKeys = [&](auto &keys) { const auto count = Serialize::read(stream); if (stream.status() != QDataStream::Ok) { LOG(("MTP Error: " @@ -340,29 +354,53 @@ void Account::setMtpAuthorization(const QByteArray &serialized) { keys.push_back(std::make_shared(MTP::AuthKey::Type::ReadFromFile, dcId, keyData)); } }; - readKeys(_mtpConfig.keys); + readKeys(_mtpFields.keys); readKeys(_mtpKeysToDestroy); LOG(("MTP Info: " "read keys, current: %1, to destroy: %2" - ).arg(_mtpConfig.keys.size() + ).arg(_mtpFields.keys.size() ).arg(_mtpKeysToDestroy.size())); } -void Account::startMtp() { +void Account::startMtp(std::unique_ptr config) { Expects(!_mtp); - auto config = base::take(_mtpConfig); - config.deviceModel = Core::App().launcher()->deviceModel(); - config.systemVersion = Core::App().launcher()->systemVersion(); + auto fields = base::take(_mtpFields); + fields.config = std::move(config); + fields.deviceModel = Core::App().launcher()->deviceModel(); + fields.systemVersion = Core::App().launcher()->systemVersion(); _mtp = std::make_unique( - Core::App().dcOptions(), MTP::Instance::Mode::Normal, - std::move(config)); + std::move(fields)); + + const auto writingKeys = _mtp->lifetime().make_state(false); _mtp->writeKeysRequests( - ) | rpl::start_with_next([=] { - local().writeMtpData(); + ) | rpl::filter([=] { + return !*writingKeys; + }) | rpl::start_with_next([=] { + *writingKeys = true; + Ui::PostponeCall(_mtp.get(), [=] { + local().writeMtpData(); + *writingKeys = false; + }); }, _mtp->lifetime()); - _mtpConfig.mainDcId = _mtp->mainDcId(); + + const auto writingConfig = _lifetime.make_state(false); + rpl::merge( + _mtp->config().updates(), + _mtp->dcOptions().changed( + ) | rpl::map([] { return rpl::empty_value(); }) + ) | rpl::filter([=] { + return !*writingConfig; + }) | rpl::start_with_next([=] { + *writingConfig = true; + Ui::PostponeCall(_mtp.get(), [=] { + local().writeMtpConfig(); + *writingConfig = false; + }); + }, _lifetime); + + _mtpFields.mainDcId = _mtp->mainDcId(); _mtp->setUpdatesHandler(::rpcDone([=]( const mtpPrime *from, @@ -466,6 +504,8 @@ void Account::loggedOut() { } void Account::destroyMtpKeys(MTP::AuthKeysList &&keys) { + Expects(_mtp != nullptr); + if (keys.empty()) { return; } @@ -474,15 +514,16 @@ void Account::destroyMtpKeys(MTP::AuthKeysList &&keys) { local().writeMtpData(); return; } - auto destroyConfig = MTP::Instance::Config(); - destroyConfig.mainDcId = MTP::Instance::Config::kNoneMainDc; - destroyConfig.keys = std::move(keys); - destroyConfig.deviceModel = Core::App().launcher()->deviceModel(); - destroyConfig.systemVersion = Core::App().launcher()->systemVersion(); + auto destroyFields = MTP::Instance::Fields(); + + destroyFields.mainDcId = MTP::Instance::Fields::kNoneMainDc; + destroyFields.config = std::make_unique(_mtp->config()); + destroyFields.keys = std::move(keys); + destroyFields.deviceModel = Core::App().launcher()->deviceModel(); + destroyFields.systemVersion = Core::App().launcher()->systemVersion(); _mtpForKeysDestroy = std::make_unique( - Core::App().dcOptions(), MTP::Instance::Mode::KeysDestroyer, - std::move(destroyConfig)); + std::move(destroyFields)); _mtpForKeysDestroy->writeKeysRequests( ) | rpl::start_with_next([=] { local().writeMtpData(); @@ -501,8 +542,8 @@ void Account::suggestMainDcId(MTP::DcId mainDcId) { Expects(_mtp != nullptr); _mtp->suggestMainDcId(mainDcId); - if (_mtpConfig.mainDcId != MTP::Instance::Config::kNotSetMainDc) { - _mtpConfig.mainDcId = mainDcId; + if (_mtpFields.mainDcId != MTP::Instance::Fields::kNotSetMainDc) { + _mtpFields.mainDcId = mainDcId; } } @@ -521,25 +562,15 @@ void Account::destroyStaleAuthorizationKeys() { } } -void Account::configUpdated() { - _configUpdates.fire({}); -} - -rpl::producer<> Account::configUpdates() const { - return _configUpdates.events(); -} - void Account::resetAuthorizationKeys() { - _mtpValue = nullptr; - _mtp = nullptr; - startMtp(); + Expects(_mtp != nullptr); + + { + const auto old = base::take(_mtp); + auto config = std::make_unique(old->config()); + startMtp(std::move(config)); + } local().writeMtpData(); } -void Account::clearMtp() { - _mtpValue = nullptr; - _mtp = nullptr; - _mtpForKeysDestroy = nullptr; -} - } // namespace Main diff --git a/Telegram/SourceFiles/main/main_account.h b/Telegram/SourceFiles/main/main_account.h index be949af7a..eefdcd8a0 100644 --- a/Telegram/SourceFiles/main/main_account.h +++ b/Telegram/SourceFiles/main/main_account.h @@ -18,6 +18,7 @@ enum class StartResult : uchar; namespace MTP { class AuthKey; +class Config; } // namespace MTP namespace Main { @@ -37,7 +38,9 @@ public: [[nodiscard]] Storage::StartResult legacyStart( const QByteArray &passcode); void start(std::shared_ptr localKey); - void startAdded(std::shared_ptr localKey); + void startAdded( + std::shared_ptr localKey, + std::unique_ptr config); [[nodiscard]] UserId willHaveUserId() const; void createSession(const MTPUser &user); @@ -67,11 +70,10 @@ public: [[nodiscard]] rpl::producer sessionValue() const; [[nodiscard]] rpl::producer sessionChanges() const; - [[nodiscard]] MTP::Instance *mtp() const { - return _mtp.get(); + [[nodiscard]] MTP::Instance &mtp() const { + return *_mtp; } - [[nodiscard]] rpl::producer mtpValue() const; - [[nodiscard]] rpl::producer mtpChanges() const; + [[nodiscard]] rpl::producer> mtpValue() const; // Set from legacy storage. void setLegacyMtpMainDcId(MTP::DcId mainDcId); @@ -89,24 +91,21 @@ public: [[nodiscard]] QByteArray serializeMtpAuthorization() const; void setMtpAuthorization(const QByteArray &serialized); - void startMtp(); void suggestMainDcId(MTP::DcId mainDcId); void destroyStaleAuthorizationKeys(); - void configUpdated(); - [[nodiscard]] rpl::producer<> configUpdates() const; - void clearMtp(); - rpl::lifetime &lifetime() { + [[nodiscard]] rpl::lifetime &lifetime() { return _lifetime; } private: + void startMtp(std::unique_ptr config); void createSession( const MTPUser &user, QByteArray serialized, int streamVersion, Settings &&settings); - void finishStarting(); + void finishStarting(std::unique_ptr config); void watchProxyChanges(); void watchSessionChanges(); bool checkForUpdates(const mtpPrime *from, const mtpPrime *end); @@ -124,7 +123,6 @@ private: std::unique_ptr _mtpForKeysDestroy; rpl::event_stream _mtpUpdates; rpl::event_stream<> _mtpNewSessionCreated; - rpl::event_stream<> _configUpdates; std::unique_ptr _appConfig; @@ -135,7 +133,7 @@ private: QByteArray _sessionUserSerialized; int32 _sessionUserStreamVersion = 0; std::unique_ptr _storedSettings; - MTP::Instance::Config _mtpConfig; + MTP::Instance::Fields _mtpFields; MTP::AuthKeysList _mtpKeysToDestroy; bool _loggingOut = false; diff --git a/Telegram/SourceFiles/main/main_accounts.cpp b/Telegram/SourceFiles/main/main_accounts.cpp index bb0049887..27a86c356 100644 --- a/Telegram/SourceFiles/main/main_accounts.cpp +++ b/Telegram/SourceFiles/main/main_accounts.cpp @@ -11,6 +11,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/shortcuts.h" #include "main/main_account.h" #include "main/main_session.h" +#include "mtproto/mtproto_config.h" +#include "mtproto/mtproto_dc_options.h" #include "storage/storage_accounts.h" #include "storage/localstorage.h" #include "facades.h" @@ -43,6 +45,12 @@ Storage::StartResult Accounts::start(const QByteArray &passcode) { return result; } +void Accounts::finish() { + _activeIndex = -1; + _active = nullptr; + base::take(_accounts); +} + void Accounts::accountAddedInStorage( int index, std::unique_ptr account) { @@ -115,7 +123,28 @@ rpl::producer Accounts::activeSessionValue() const { return rpl::single(current) | rpl::then(_activeSessions.events()); } -int Accounts::add() { +int Accounts::add(MTP::Environment environment) { + Expects(_active.current() != nullptr); + + static const auto cloneConfig = [](const MTP::Config &config) { + return std::make_unique(config); + }; + static const auto accountConfig = [](not_null account) { + return cloneConfig(account->mtp().config()); + }; + auto config = [&] { + if (_active.current()->mtp().environment() == environment) { + return accountConfig(_active.current()); + } + for (const auto &[index, account] : list()) { + if (account->mtp().environment() == environment) { + return accountConfig(account.get()); + } + } + return (environment == MTP::Environment::Production) + ? cloneConfig(Core::App().fallbackProductionConfig()) + : std::make_unique(environment); + }(); auto index = 0; while (_accounts.contains(index)) { ++index; @@ -124,17 +153,16 @@ int Accounts::add() { index, std::make_unique(_dataName, index) ).first->second.get(); - _local->startAdded(account); + _local->startAdded(account, std::move(config)); watchSession(account); return index; } void Accounts::watchSession(not_null account) { - account->startMtp(); account->sessionChanges( ) | rpl::filter([=](Session *session) { return !session; // removeRedundantAccounts may remove passcode lock. - }) | rpl::start_with_next([=](Session *session) { + }) | rpl::start_with_next([=] { if (account == _active.current()) { activateAuthedAccount(); } @@ -183,6 +211,7 @@ void Accounts::removeRedundantAccounts() { ++i; continue; } + checkForLastProductionConfig(i->second.get()); i = _accounts.erase(i); } @@ -191,6 +220,21 @@ void Accounts::removeRedundantAccounts() { } } +void Accounts::checkForLastProductionConfig( + not_null account) { + const auto mtp = &account->mtp(); + if (mtp->environment() != MTP::Environment::Production) { + return; + } + for (const auto &[index, other] : _accounts) { + if (other.get() != account + && other->mtp().environment() == MTP::Environment::Production) { + return; + } + } + Core::App().refreshFallbackProductionConfig(mtp->config()); +} + void Accounts::activate(int index) { Expects(_accounts.contains(index)); diff --git a/Telegram/SourceFiles/main/main_accounts.h b/Telegram/SourceFiles/main/main_accounts.h index 555472cf8..e51d700d7 100644 --- a/Telegram/SourceFiles/main/main_accounts.h +++ b/Telegram/SourceFiles/main/main_accounts.h @@ -12,6 +12,10 @@ class Accounts; enum class StartResult : uchar; } // namespace Storage +namespace MTP { +enum class Environment : uchar; +} // namespace MTP + namespace Main { class Account; @@ -25,6 +29,7 @@ public: [[nodiscard]] bool started() const; [[nodiscard]] Storage::StartResult start(const QByteArray &passcode); void resetWithForgottenPasscode(); + void finish(); [[nodiscard]] Storage::Accounts &local() const { return *_local; @@ -42,7 +47,7 @@ public: [[nodiscard]] rpl::producer activeSessionValue() const; [[nodiscard]] rpl::producer activeSessionChanges() const; - [[nodiscard]] int add(); + [[nodiscard]] int add(MTP::Environment environment); void activate(int index); // Interface for Storage::Accounts. @@ -55,6 +60,7 @@ private: void removeRedundantAccounts(); void watchSession(not_null account); void scheduleWriteAccounts(); + void checkForLastProductionConfig(not_null account); const QString _dataName; const std::unique_ptr _local; diff --git a/Telegram/SourceFiles/main/main_app_config.cpp b/Telegram/SourceFiles/main/main_app_config.cpp index 4057ed396..4f86f2bcf 100644 --- a/Telegram/SourceFiles/main/main_app_config.cpp +++ b/Telegram/SourceFiles/main/main_app_config.cpp @@ -20,14 +20,9 @@ constexpr auto kRefreshTimeout = 3600 * crl::time(1000); AppConfig::AppConfig(not_null account) : _account(account) { account->mtpValue( - ) | rpl::start_with_next([=](MTP::Instance *instance) { - if (instance) { - _api.emplace(instance); - refresh(); - } else { - _api.reset(); - _requestId = 0; - } + ) | rpl::start_with_next([=](not_null instance) { + _api.emplace(instance); + refresh(); }, _lifetime); } diff --git a/Telegram/SourceFiles/main/main_session.cpp b/Telegram/SourceFiles/main/main_session.cpp index 8b783124d..e9e72babe 100644 --- a/Telegram/SourceFiles/main/main_session.cpp +++ b/Telegram/SourceFiles/main/main_session.cpp @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/application.h" #include "core/changelogs.h" #include "main/main_account.h" +#include "mtproto/mtproto_config.h" #include "chat_helpers/stickers_emoji_pack.h" #include "chat_helpers/stickers_dice_pack.h" #include "storage/file_download.h" @@ -40,6 +41,25 @@ namespace { constexpr auto kLegacyCallsPeerToPeerNobody = 4; +[[nodiscard]] QString ValidatedInternalLinksDomain( + not_null session) { + // This domain should start with 'http[s]://' and end with '/'. + // Like 'https://telegram.me/' or 'https://t.me/'. + const auto &domain = session->serverConfig().internalLinksDomain; + const auto prefixes = { + qstr("https://"), + qstr("http://"), + }; + for (const auto &prefix : prefixes) { + if (domain.startsWith(prefix, Qt::CaseInsensitive)) { + return domain.endsWith('/') + ? domain + : MTP::ConfigFields().internalLinksDomain; + } + } + return MTP::ConfigFields().internalLinksDomain; +} + } // namespace Session::Session( @@ -75,7 +95,7 @@ Session::Session( _api->requestTermsUpdate(); _api->requestFullPeer(_user); - _api->instance()->setUserPhone(_user->phone()); + _api->instance().setUserPhone(_user->phone()); crl::on_main(this, [=] { using Flag = Data::PeerUpdate::Flag; @@ -91,9 +111,9 @@ Session::Session( if (update.flags & Flag::PhoneNumber) { const auto phone = _user->phone(); - _api->instance()->setUserPhone(phone); + _api->instance().setUserPhone(phone); if (!phone.isEmpty()) { - _api->instance()->requestConfig(); + _api->instance().requestConfig(); } } }, _lifetime); @@ -156,19 +176,42 @@ void Session::saveSettingsDelayed(crl::time delay) { } MTP::DcId Session::mainDcId() const { - return _account->mtp()->mainDcId(); + return _account->mtp().mainDcId(); } -not_null Session::mtp() const { +MTP::Instance &Session::mtp() const { return _account->mtp(); } +const MTP::ConfigFields &Session::serverConfig() const { + return _account->mtp().configValues(); +} + void Session::termsDeleteNow() { api().request(MTPaccount_DeleteAccount( MTP_string("Decline ToS update") )).send(); } +QString Session::createInternalLink(const QString &query) const { + auto result = createInternalLinkFull(query); + auto prefixes = { + qstr("https://"), + qstr("http://"), + }; + for (auto &prefix : prefixes) { + if (result.startsWith(prefix, Qt::CaseInsensitive)) { + return result.mid(prefix.size()); + } + } + LOG(("Warning: bad internal url '%1'").arg(result)); + return result; +} + +QString Session::createInternalLinkFull(const QString &query) const { + return ValidatedInternalLinksDomain(this) + query; +} + bool Session::supportMode() const { return (_supportHelper != nullptr); } diff --git a/Telegram/SourceFiles/main/main_session.h b/Telegram/SourceFiles/main/main_session.h index 710e071f8..43d3cf47a 100644 --- a/Telegram/SourceFiles/main/main_session.h +++ b/Telegram/SourceFiles/main/main_session.h @@ -21,6 +21,7 @@ class Updates; namespace MTP { class Instance; +struct ConfigFields; } // namespace MTP namespace Support { @@ -127,7 +128,8 @@ public: // Shortcuts. [[nodiscard]] base::Observable &downloaderTaskFinished(); [[nodiscard]] MTP::DcId mainDcId() const; - [[nodiscard]] not_null mtp() const; + [[nodiscard]] MTP::Instance &mtp() const; + [[nodiscard]] const MTP::ConfigFields &serverConfig() const; [[nodiscard]] ApiWrap &api() { return *_api; } @@ -138,6 +140,10 @@ public: void termsDeleteNow(); + void setInternalLinkDomain(const QString &domain) const; + [[nodiscard]] QString createInternalLink(const QString &query) const; + [[nodiscard]] QString createInternalLinkFull(const QString &query) const; + [[nodiscard]] rpl::lifetime &lifetime() { return _lifetime; } diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 1baca05b8..0441df09f 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -85,7 +85,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_session_controller.h" #include "window/themes/window_theme.h" #include "window/window_history_hider.h" -#include "mtproto/dc_options.h" +#include "mtproto/mtproto_dc_options.h" #include "core/file_utilities.h" #include "core/update_checker.h" #include "core/shortcuts.h" diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index 07b286109..01d166aa7 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -516,7 +516,7 @@ bool MainWindow::doWeMarkAsRead() { if (!_main || Ui::isLayerShown()) { return false; } - updateIsActive(0); + updateIsActive(); return isActive() && _main->doWeMarkAsRead(); } @@ -609,7 +609,7 @@ void MainWindow::updateTrayMenu(bool force) { auto minimizeAction = actions.at(1); minimizeAction->setEnabled(isVisible()); } else { - updateIsActive(0); + updateIsActive(); auto active = Platform::IsWayland() ? isVisible() : isActive(); auto toggleAction = actions.at(0); disconnect(toggleAction, SIGNAL(triggered(bool)), this, SLOT(minimizeToTray())); @@ -705,7 +705,7 @@ void MainWindow::activate() { setVisible(true); psActivateProcess(); activateWindow(); - updateIsActive(Global::OnlineFocusTimeout()); + controller().updateIsActiveFocus(); if (wasHidden) { if (_main) { _main->windowShown(); @@ -743,7 +743,7 @@ void MainWindow::showFromTray(QSystemTrayIcon::ActivationReason reason) { void MainWindow::handleTrayIconActication( QSystemTrayIcon::ActivationReason reason) { - updateIsActive(0); + updateIsActive(); if (Platform::IsMac() && isActive()) { if (trayIcon && !trayIcon->contextMenu()) { showFromTray(reason); diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_loader_mtproto.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_loader_mtproto.cpp index d4b810fe8..2ed5bea92 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_loader_mtproto.cpp +++ b/Telegram/SourceFiles/media/streaming/media_streaming_loader_mtproto.cpp @@ -27,7 +27,7 @@ LoaderMtproto::LoaderMtproto( Data::FileOrigin origin) : DownloadMtprotoTask(owner, location, origin) , _size(size) -, _api(api().instance()) { +, _api(&api().instance()) { } Storage::Cache::Key LoaderMtproto::baseCacheKey() const { diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index 828fdc550..81cbe580b 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -2462,6 +2462,7 @@ void OverlayWidget::initThemePreview() { return result; }(); + const auto weakSession = base::make_weak(&_document->session()); const auto path = _document->location().name(); const auto id = _themePreviewId = rand_value(); const auto weak = Ui::MakeWeak(this); @@ -2473,7 +2474,8 @@ void OverlayWidget::initThemePreview() { std::move(data), Window::Theme::PreviewType::Extended); crl::on_main(weak, [=, result = std::move(preview)]() mutable { - if (id != _themePreviewId) { + const auto session = weakSession.get(); + if (id != _themePreviewId || !session) { return; } _themePreviewId = 0; @@ -2509,7 +2511,7 @@ void OverlayWidget::initThemePreview() { _themeShare->show(); _themeShare->setClickedCallback([=] { QGuiApplication::clipboard()->setText( - Core::App().createInternalLinkFull("addtheme/" + slug)); + session->createInternalLinkFull("addtheme/" + slug)); Ui::Toast::Show( this, tr::lng_background_link_copied(tr::now)); diff --git a/Telegram/SourceFiles/mtproto/config_loader.cpp b/Telegram/SourceFiles/mtproto/config_loader.cpp index fc847c855..ef2151f50 100644 --- a/Telegram/SourceFiles/mtproto/config_loader.cpp +++ b/Telegram/SourceFiles/mtproto/config_loader.cpp @@ -9,7 +9,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mtproto/special_config_request.h" #include "mtproto/facade.h" -#include "mtproto/dc_options.h" +#include "mtproto/mtproto_dc_options.h" +#include "mtproto/mtproto_config.h" #include "mtproto/mtp_instance.h" #include "facades.h" @@ -40,7 +41,7 @@ void ConfigLoader::load() { sendRequest(_instance->mainDcId()); _enumDCTimer.callOnce(kEnumerateDcTimeout); } else { - auto ids = _instance->dcOptions()->configEnumDcIds(); + auto ids = _instance->dcOptions().configEnumDcIds(); Assert(!ids.empty()); _enumCurrent = ids.front(); enumerate(); @@ -87,7 +88,7 @@ void ConfigLoader::enumerate() { if (!_enumCurrent) { _enumCurrent = _instance->mainDcId(); } - auto ids = _instance->dcOptions()->configEnumDcIds(); + auto ids = _instance->dcOptions().configEnumDcIds(); Assert(!ids.empty()); auto i = std::find(ids.cbegin(), ids.cend(), _enumCurrent); @@ -135,7 +136,7 @@ void ConfigLoader::createSpecialLoader() { } else { addSpecialEndpoint(dcId, ip, port, secret); } - }, _phone); + }, _instance->configValues().txtDomainString, _phone); } void ConfigLoader::addSpecialEndpoint( @@ -180,7 +181,7 @@ void ConfigLoader::sendSpecialRequest() { using Flag = MTPDdcOption::Flag; const auto flags = Flag::f_tcpo_only | (endpoint->secret.empty() ? Flag(0) : Flag::f_secret); - _instance->dcOptions()->constructAddOne( + _instance->dcOptions().constructAddOne( _specialEnumCurrent, flags, endpoint->ip, @@ -212,7 +213,7 @@ void ConfigLoader::specialConfigLoaded(const MTPConfig &result) { // We use special config only for dc options. // For everything else we wait for normal config from main dc. - _instance->dcOptions()->setFromList(data.vdc_options()); + _instance->dcOptions().setFromList(data.vdc_options()); } } // namespace details diff --git a/Telegram/SourceFiles/mtproto/connection_abstract.h b/Telegram/SourceFiles/mtproto/connection_abstract.h index 695d83694..9437a4a42 100644 --- a/Telegram/SourceFiles/mtproto/connection_abstract.h +++ b/Telegram/SourceFiles/mtproto/connection_abstract.h @@ -7,7 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once -#include "mtproto/dc_options.h" +#include "mtproto/mtproto_dc_options.h" #include "mtproto/mtproto_proxy_data.h" #include "base/bytes.h" diff --git a/Telegram/SourceFiles/mtproto/dedicated_file_loader.cpp b/Telegram/SourceFiles/mtproto/dedicated_file_loader.cpp index 2a6e573d6..7db41b7c3 100644 --- a/Telegram/SourceFiles/mtproto/dedicated_file_loader.cpp +++ b/Telegram/SourceFiles/mtproto/dedicated_file_loader.cpp @@ -84,7 +84,7 @@ std::optional ParseFile( WeakInstance::WeakInstance(base::weak_ptr session) : _session(session) -, _instance(_session ? _session->account().mtp() : nullptr) { +, _instance(_session ? &_session->account().mtp() : nullptr) { if (!valid()) { return; } diff --git a/Telegram/SourceFiles/mtproto/details/mtproto_dcenter.cpp b/Telegram/SourceFiles/mtproto/details/mtproto_dcenter.cpp index 7dbf0a602..7a1799f11 100644 --- a/Telegram/SourceFiles/mtproto/details/mtproto_dcenter.cpp +++ b/Telegram/SourceFiles/mtproto/details/mtproto_dcenter.cpp @@ -9,7 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mtproto/facade.h" #include "mtproto/mtproto_auth_key.h" -#include "mtproto/dc_options.h" +#include "mtproto/mtproto_dc_options.h" #include "mtproto/mtp_instance.h" #include "mtproto/special_config_request.h" diff --git a/Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp b/Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp index b26308978..21c56003d 100644 --- a/Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp +++ b/Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp @@ -294,7 +294,7 @@ void DomainResolver::performRequest( request.setRawHeader("Host", host.toLatin1()); } } break; - default: Unexpected("Type in SpecialConfigRequest::performRequest."); + default: Unexpected("Type in DomainResolver::performRequest."); } request.setUrl(url); request.setRawHeader("User-Agent", DnsUserAgent()); diff --git a/Telegram/SourceFiles/mtproto/facade.h b/Telegram/SourceFiles/mtproto/facade.h index 6afce1e0d..c0892b3cb 100644 --- a/Telegram/SourceFiles/mtproto/facade.h +++ b/Telegram/SourceFiles/mtproto/facade.h @@ -63,17 +63,17 @@ inline bool isCdnDc(MTPDdcOption::Flags flags) { inline bool isTemporaryDcId(ShiftedDcId shiftedDcId) { auto dcId = BareDcId(shiftedDcId); - return (dcId >= Instance::Config::kTemporaryMainDc); + return (dcId >= Instance::Fields::kTemporaryMainDc); } inline DcId getRealIdFromTemporaryDcId(ShiftedDcId shiftedDcId) { auto dcId = BareDcId(shiftedDcId); - return (dcId >= Instance::Config::kTemporaryMainDc) ? (dcId - Instance::Config::kTemporaryMainDc) : 0; + return (dcId >= Instance::Fields::kTemporaryMainDc) ? (dcId - Instance::Fields::kTemporaryMainDc) : 0; } inline DcId getTemporaryIdFromRealDcId(ShiftedDcId shiftedDcId) { auto dcId = BareDcId(shiftedDcId); - return (dcId < Instance::Config::kTemporaryMainDc) ? (dcId + Instance::Config::kTemporaryMainDc) : 0; + return (dcId < Instance::Fields::kTemporaryMainDc) ? (dcId + Instance::Fields::kTemporaryMainDc) : 0; } namespace details { diff --git a/Telegram/SourceFiles/mtproto/mtp_instance.cpp b/Telegram/SourceFiles/mtproto/mtp_instance.cpp index bf561124c..1b6de5a6d 100644 --- a/Telegram/SourceFiles/mtproto/mtp_instance.cpp +++ b/Telegram/SourceFiles/mtproto/mtp_instance.cpp @@ -11,7 +11,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mtproto/details/mtproto_rsa_public_key.h" #include "mtproto/special_config_request.h" #include "mtproto/session.h" -#include "mtproto/dc_options.h" +#include "mtproto/mtproto_config.h" +#include "mtproto/mtproto_dc_options.h" #include "mtproto/config_loader.h" #include "mtproto/sender.h" #include "storage/localstorage.h" @@ -53,9 +54,18 @@ int GetNextRequestId() { class Instance::Private : private Sender { public: - Private(not_null instance, not_null options, Instance::Mode mode); + Private( + not_null instance, + Instance::Mode mode, + Fields &&fields); - void start(Config &&config); + void start(); + + [[nodiscard]] Config &config() const; + [[nodiscard]] const ConfigFields &configValues() const; + [[nodiscard]] DcOptions &dcOptions() const; + [[nodiscard]] Environment environment() const; + [[nodiscard]] bool isTestMode() const; void resolveProxyDomain(const QString &host); void setGoodProxyDomain(const QString &host, const QString &ip); @@ -72,8 +82,6 @@ public: void addKeysForDestroy(AuthKeysList &&keys); [[nodiscard]] rpl::producer<> allKeysDestroyed() const; - [[nodiscard]] not_null dcOptions(); - // Thread safe. [[nodiscard]] QString deviceModel() const; [[nodiscard]] QString systemVersion() const; @@ -195,8 +203,8 @@ private: void checkDelayedRequests(); const not_null _instance; - const not_null _dcOptions; const Instance::Mode _mode = Instance::Mode::Normal; + const std::unique_ptr _config; std::unique_ptr _mainSessionThread; std::unique_ptr _otherSessionsThread; @@ -205,7 +213,7 @@ private: QString _deviceModel; QString _systemVersion; - DcId _mainDcId = Config::kDefaultMainDc; + DcId _mainDcId = Fields::kDefaultMainDc; bool _mainDcIdForced = false; base::flat_map> _dcenters; std::vector> _dcentersToDestroy; @@ -261,27 +269,36 @@ private: }; +Instance::Fields::Fields() = default; + +Instance::Fields::Fields(Fields &&other) = default; + +auto Instance::Fields::operator=(Fields &&other) -> Fields & = default; + +Instance::Fields::~Fields() = default; + Instance::Private::Private( not_null instance, - not_null options, - Instance::Mode mode) + Instance::Mode mode, + Fields &&fields) : Sender(instance) , _instance(instance) -, _dcOptions(options) -, _mode(mode) { +, _mode(mode) +, _config(std::move(fields.config)) { + Expects(_config != nullptr); + const auto idealThreadPoolSize = QThread::idealThreadCount(); _fileSessionThreads.resize(2 * std::max(idealThreadPoolSize / 2, 1)); + details::unpaused( ) | rpl::start_with_next([=] { unpaused(); }, _lifetime); -} -void Instance::Private::start(Config &&config) { - _deviceModel = std::move(config.deviceModel); - _systemVersion = std::move(config.systemVersion); + _deviceModel = std::move(fields.deviceModel); + _systemVersion = std::move(fields.systemVersion); - for (auto &key : config.keys) { + for (auto &key : fields.keys) { auto dcId = key->dcId(); auto shiftedDcId = dcId; if (isKeysDestroyer()) { @@ -297,22 +314,24 @@ void Instance::Private::start(Config &&config) { addDc(shiftedDcId, std::move(key)); } - if (config.mainDcId != Config::kNotSetMainDc) { - _mainDcId = config.mainDcId; + if (fields.mainDcId != Fields::kNotSetMainDc) { + _mainDcId = fields.mainDcId; _mainDcIdForced = true; } +} +void Instance::Private::start() { if (isKeysDestroyer()) { for (const auto &[shiftedDcId, dc] : _dcenters) { startSession(shiftedDcId); } - } else if (_mainDcId != Config::kNoneMainDc) { + } else if (_mainDcId != Fields::kNoneMainDc) { _mainSession = startSession(_mainDcId); } _checkDelayedTimer.setCallback([this] { checkDelayedRequests(); }); - Assert((_mainDcId == Config::kNoneMainDc) == isKeysDestroyer()); + Assert((_mainDcId == Fields::kNoneMainDc) == isKeysDestroyer()); requestConfig(); } @@ -418,7 +437,8 @@ void Instance::Private::setMainDcId(DcId mainDcId) { } DcId Instance::Private::mainDcId() const { - Expects(_mainDcId != Config::kNoneMainDc); + Expects(_mainDcId != Fields::kNoneMainDc); + return _mainDcId; } @@ -457,7 +477,7 @@ void Instance::Private::syncHttpUnixtime() { InvokeQueued(_instance, [=] { _httpUnixtimeLoader = nullptr; }); - }); + }, configValues().txtDomainString); } void Instance::Private::restartedByTimeout(ShiftedDcId shiftedDcId) { @@ -469,7 +489,7 @@ rpl::producer Instance::Private::restartsByTimeout() const { } void Instance::Private::requestConfigIfOld() { - const auto timeout = Global::BlockedMode() + const auto timeout = _config->values().blockedMode ? kConfigBecomesOldForBlockedIn : kConfigBecomesOldIn; if (crl::now() - _lastConfigLoadedTime >= timeout) { @@ -490,7 +510,7 @@ void Instance::Private::requestConfigIfExpired() { } void Instance::Private::requestCDNConfig() { - if (_cdnConfigLoadRequestId || _mainDcId == Config::kNoneMainDc) { + if (_cdnConfigLoadRequestId || _mainDcId == Fields::kNoneMainDc) { return; } _cdnConfigLoadRequestId = request( @@ -498,7 +518,7 @@ void Instance::Private::requestCDNConfig() { ).done([this](const MTPCdnConfig &result) { _cdnConfigLoadRequestId = 0; result.match([&](const MTPDcdnConfig &data) { - dcOptions()->setCDNConfig(data); + dcOptions().setCDNConfig(data); }); Local::writeSettings(); }).send(); @@ -642,7 +662,7 @@ void Instance::Private::logoutGuestDcs() { dcIds.push_back(key.first); } for (const auto dcId : dcIds) { - if (dcId == mainDcId() || dcOptions()->dcType(dcId) == DcType::Cdn) { + if (dcId == mainDcId() || dcOptions().dcType(dcId) == DcType::Cdn) { continue; } const auto shiftedDcId = MTP::logoutDcId(dcId); @@ -784,8 +804,24 @@ rpl::producer<> Instance::Private::writeKeysRequests() const { return _writeKeysRequests.events(); } -not_null Instance::Private::dcOptions() { - return _dcOptions; +Config &Instance::Private::config() const { + return *_config; +} + +const ConfigFields &Instance::Private::configValues() const { + return _config->values(); +} + +DcOptions &Instance::Private::dcOptions() const { + return _config->dcOptions(); +} + +Environment Instance::Private::environment() const { + return _config->environment(); +} + +bool Instance::Private::isTestMode() const { + return _config->isTestMode(); } QString Instance::Private::deviceModel() const { @@ -809,58 +845,13 @@ void Instance::Private::configLoadDone(const MTPConfig &result) { _lastConfigLoadedTime = crl::now(); const auto &data = result.c_config(); - DEBUG_LOG(("MTP Info: got config, chat_size_max: %1, date: %2, test_mode: %3, this_dc: %4, dc_options.length: %5").arg(data.vchat_size_max().v).arg(data.vdate().v).arg(mtpIsTrue(data.vtest_mode())).arg(data.vthis_dc().v).arg(data.vdc_options().v.size())); - if (data.vdc_options().v.empty()) { - LOG(("MTP Error: config with empty dc_options received!")); - } else { - _dcOptions->setFromList(data.vdc_options()); - } - - Global::SetChatSizeMax(data.vchat_size_max().v); - Global::SetMegagroupSizeMax(data.vmegagroup_size_max().v); - Global::SetForwardedCountMax(data.vforwarded_count_max().v); - Global::SetOnlineUpdatePeriod(data.vonline_update_period_ms().v); - Global::SetOfflineBlurTimeout(data.voffline_blur_timeout_ms().v); - Global::SetOfflineIdleTimeout(data.voffline_idle_timeout_ms().v); - Global::SetOnlineCloudTimeout(data.vonline_cloud_timeout_ms().v); - Global::SetNotifyCloudDelay(data.vnotify_cloud_delay_ms().v); - Global::SetNotifyDefaultDelay(data.vnotify_default_delay_ms().v); - Global::SetPushChatPeriod(data.vpush_chat_period_ms().v); - Global::SetPushChatLimit(data.vpush_chat_limit().v); - Global::SetSavedGifsLimit(data.vsaved_gifs_limit().v); - Global::SetEditTimeLimit(data.vedit_time_limit().v); - Global::SetRevokeTimeLimit(data.vrevoke_time_limit().v); - Global::SetRevokePrivateTimeLimit(data.vrevoke_pm_time_limit().v); - Global::SetRevokePrivateInbox(data.is_revoke_pm_inbox()); - Global::SetStickersRecentLimit(data.vstickers_recent_limit().v); - Global::SetStickersFavedLimit(data.vstickers_faved_limit().v); - Global::SetPinnedDialogsCountMax( - std::max(data.vpinned_dialogs_count_max().v, 1)); - Global::SetPinnedDialogsInFolderMax( - std::max(data.vpinned_infolder_count_max().v, 1)); - Core::App().setInternalLinkDomain(qs(data.vme_url_prefix())); - Global::SetChannelsReadMediaPeriod(data.vchannels_read_media_period().v); - Global::SetWebFileDcId(data.vwebfile_dc_id().v); - Global::SetTxtDomainString(qs(data.vdc_txt_domain_name())); - Global::SetCallReceiveTimeoutMs(data.vcall_receive_timeout_ms().v); - Global::SetCallRingTimeoutMs(data.vcall_ring_timeout_ms().v); - Global::SetCallConnectTimeoutMs(data.vcall_connect_timeout_ms().v); - Global::SetCallPacketTimeoutMs(data.vcall_packet_timeout_ms().v); - if (Global::PhoneCallsEnabled() != data.is_phonecalls_enabled()) { - Global::SetPhoneCallsEnabled(data.is_phonecalls_enabled()); - Global::RefPhoneCallsEnabledChanged().notify(); - } - Global::SetBlockedMode(data.is_blocked_mode()); - Global::SetCaptionLengthMax(data.vcaption_length_max().v); + _config->apply(data); const auto lang = qs(data.vsuggested_lang_code().value_or_empty()); Lang::CurrentCloudManager().setSuggestedLanguage(lang); Lang::CurrentCloudManager().setCurrentVersions( data.vlang_pack_version().value_or_empty(), data.vbase_lang_pack_version().value_or_empty()); - - Core::App().activeAccount().configUpdated(); // #TODO multi - if (const auto prefix = data.vautoupdate_url_prefix()) { Local::writeAutoupdatePrefix(qs(*prefix)); } @@ -1520,7 +1511,7 @@ not_null Instance::Private::getThreadForDc( void Instance::Private::scheduleKeyDestroy(ShiftedDcId shiftedDcId) { Expects(isKeysDestroyer()); - if (dcOptions()->dcType(shiftedDcId) == DcType::Cdn) { + if (dcOptions().dcType(shiftedDcId) == DcType::Cdn) { performKeyDestroy(shiftedDcId); } else { _instance->send(MTPauth_LogOut(), rpcDone([=](const MTPBool &) { @@ -1643,10 +1634,10 @@ void Instance::Private::prepareToDestroy() { } } -Instance::Instance(not_null options, Mode mode, Config &&config) +Instance::Instance(Mode mode, Fields &&fields) : QObject() -, _private(std::make_unique(this, options, mode)) { - _private->start(std::move(config)); +, _private(std::make_unique(this, mode, std::move(fields))) { + _private->start(); } void Instance::resolveProxyDomain(const QString &host) { @@ -1787,10 +1778,26 @@ void Instance::addKeysForDestroy(AuthKeysList &&keys) { _private->addKeysForDestroy(std::move(keys)); } -not_null Instance::dcOptions() { +Config &Instance::config() const { + return _private->config(); +} + +const ConfigFields &Instance::configValues() const { + return _private->configValues(); +} + +DcOptions &Instance::dcOptions() const { return _private->dcOptions(); } +Environment Instance::environment() const { + return _private->environment(); +} + +bool Instance::isTestMode() const { + return _private->isTestMode(); +} + QString Instance::deviceModel() const { return _private->deviceModel(); } diff --git a/Telegram/SourceFiles/mtproto/mtp_instance.h b/Telegram/SourceFiles/mtproto/mtp_instance.h index 7e44f9553..8a0bd0c7d 100644 --- a/Telegram/SourceFiles/mtproto/mtp_instance.h +++ b/Telegram/SourceFiles/mtproto/mtp_instance.h @@ -21,20 +21,29 @@ class Session; } // namespace details class DcOptions; +class Config; +struct ConfigFields; class AuthKey; using AuthKeyPtr = std::shared_ptr; using AuthKeysList = std::vector; +enum class Environment : uchar; class Instance : public QObject { Q_OBJECT public: - struct Config { + struct Fields { + Fields(); + Fields(Fields &&other); + Fields &operator=(Fields &&other); + ~Fields(); + static constexpr auto kNoneMainDc = -1; static constexpr auto kNotSetMainDc = 0; static constexpr auto kDefaultMainDc = 2; static constexpr auto kTemporaryMainDc = 1000; + std::unique_ptr config; DcId mainDcId = kNotSetMainDc; AuthKeysList keys; QString deviceModel; @@ -46,7 +55,7 @@ public: KeysDestroyer, }; - Instance(not_null options, Mode mode, Config &&config); + Instance(Mode mode, Fields &&fields); Instance(const Instance &other) = delete; Instance &operator=(const Instance &other) = delete; ~Instance(); @@ -64,6 +73,11 @@ public: [[nodiscard]] rpl::producer<> allKeysDestroyed() const; // Thread-safe. + [[nodiscard]] Config &config() const; + [[nodiscard]] const ConfigFields &configValues() const; + [[nodiscard]] DcOptions &dcOptions() const; + [[nodiscard]] Environment environment() const; + [[nodiscard]] bool isTestMode() const; [[nodiscard]] QString deviceModel() const; [[nodiscard]] QString systemVersion() const; @@ -74,8 +88,6 @@ public: [[nodiscard]] AuthKeysList getKeysForWrite() const; void addKeysForDestroy(AuthKeysList &&keys); - [[nodiscard]] not_null dcOptions(); - void restart(); void restart(ShiftedDcId shiftedDcId); int32 dcstate(ShiftedDcId shiftedDcId = 0); diff --git a/Telegram/SourceFiles/mtproto/mtproto_config.cpp b/Telegram/SourceFiles/mtproto/mtproto_config.cpp new file mode 100644 index 000000000..8b862ac6d --- /dev/null +++ b/Telegram/SourceFiles/mtproto/mtproto_config.cpp @@ -0,0 +1,259 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "mtproto/mtproto_config.h" + +#include "storage/serialize_common.h" +#include "mtproto/type_utils.h" +#include "logs.h" + +namespace MTP { +namespace { + +constexpr auto kVersion = 1; + +} +Config::Config(Environment environment) : _dcOptions(environment) { + _fields.webFileDcId = _dcOptions.isTestMode() ? 2 : 4; + _fields.txtDomainString = _dcOptions.isTestMode() + ? u"tapv3.stel.com"_q + : u"apv3.stel.com"_q; +} + +Config::Config(const Config &other) +: _dcOptions(other.dcOptions()) +, _fields(other._fields) { +} + +QByteArray Config::serialize() const { + auto options = _dcOptions.serialize(); + auto size = sizeof(qint32) * 2; // version + environment + size += Serialize::bytearraySize(options); + size += 28 * sizeof(qint32); + size += Serialize::stringSize(_fields.internalLinksDomain); + size += Serialize::stringSize(_fields.txtDomainString); + + auto result = QByteArray(); + result.reserve(size); + { + QDataStream stream(&result, QIODevice::WriteOnly); + stream.setVersion(QDataStream::Qt_5_1); + stream + << qint32(kVersion) + << qint32(_dcOptions.isTestMode() + ? Environment::Test + : Environment::Production) + << options + << qint32(_fields.chatSizeMax) + << qint32(_fields.megagroupSizeMax) + << qint32(_fields.forwardedCountMax) + << qint32(_fields.onlineUpdatePeriod) + << qint32(_fields.offlineBlurTimeout) + << qint32(_fields.offlineIdleTimeout) + << qint32(_fields.onlineFocusTimeout) + << qint32(_fields.onlineCloudTimeout) + << qint32(_fields.notifyCloudDelay) + << qint32(_fields.notifyDefaultDelay) + << qint32(_fields.savedGifsLimit) + << qint32(_fields.editTimeLimit) + << qint32(_fields.revokeTimeLimit) + << qint32(_fields.revokePrivateTimeLimit) + << qint32(_fields.revokePrivateInbox ? 1 : 0) + << qint32(_fields.stickersRecentLimit) + << qint32(_fields.stickersFavedLimit) + << qint32(_fields.pinnedDialogsCountMax.current()) + << qint32(_fields.pinnedDialogsInFolderMax.current()) + << _fields.internalLinksDomain + << qint32(_fields.channelsReadMediaPeriod) + << qint32(_fields.callReceiveTimeoutMs) + << qint32(_fields.callRingTimeoutMs) + << qint32(_fields.callConnectTimeoutMs) + << qint32(_fields.callPacketTimeoutMs) + << qint32(_fields.webFileDcId) + << _fields.txtDomainString + << qint32(_fields.phoneCallsEnabled.current() ? 1 : 0) + << qint32(_fields.blockedMode ? 1 : 0) + << qint32(_fields.captionLengthMax); + } + return result; +} + +std::unique_ptr Config::FromSerialized(const QByteArray &serialized) { + auto result = std::unique_ptr(); + auto raw = result.get(); + + QDataStream stream(serialized); + stream.setVersion(QDataStream::Qt_5_1); + + auto version = qint32(); + stream >> version; + if (version != kVersion) { + return result; + } + auto environment = qint32(); + stream >> environment; + switch (environment) { + case qint32(Environment::Test): + result = std::make_unique(Environment::Test); + break; + case qint32(Environment::Production): + result = std::make_unique(Environment::Production); + break; + } + if (!(raw = result.get())) { + return result; + } + + auto dcOptionsSerialized = QByteArray(); + const auto read = [&](auto &field) { + using Type = std::decay_t(); + if constexpr (std::is_same_v + || std::is_same_v>) { + auto value = qint32(); + stream >> value; + field = value; + } else if constexpr (std::is_same_v + || std::is_same_v>) { + auto value = qint32(); + stream >> value; + field = (value == 1); + } else if constexpr (std::is_same_v + || std::is_same_v) { + static_assert(false_(field), "Bad read() call."); + } + }; + + read(dcOptionsSerialized); + read(raw->_fields.chatSizeMax); + read(raw->_fields.megagroupSizeMax); + read(raw->_fields.forwardedCountMax); + read(raw->_fields.onlineUpdatePeriod); + read(raw->_fields.offlineBlurTimeout); + read(raw->_fields.offlineIdleTimeout); + read(raw->_fields.onlineFocusTimeout); + read(raw->_fields.onlineCloudTimeout); + read(raw->_fields.notifyCloudDelay); + read(raw->_fields.notifyDefaultDelay); + read(raw->_fields.savedGifsLimit); + read(raw->_fields.editTimeLimit); + read(raw->_fields.revokeTimeLimit); + read(raw->_fields.revokePrivateTimeLimit); + read(raw->_fields.revokePrivateInbox); + read(raw->_fields.stickersRecentLimit); + read(raw->_fields.stickersFavedLimit); + read(raw->_fields.pinnedDialogsCountMax); + read(raw->_fields.pinnedDialogsInFolderMax); + read(raw->_fields.internalLinksDomain); + read(raw->_fields.channelsReadMediaPeriod); + read(raw->_fields.callReceiveTimeoutMs); + read(raw->_fields.callRingTimeoutMs); + read(raw->_fields.callConnectTimeoutMs); + read(raw->_fields.callPacketTimeoutMs); + read(raw->_fields.webFileDcId); + read(raw->_fields.txtDomainString); + read(raw->_fields.phoneCallsEnabled); + read(raw->_fields.blockedMode); + read(raw->_fields.captionLengthMax); + + if (stream.status() != QDataStream::Ok + || !raw->_dcOptions.constructFromSerialized(dcOptionsSerialized)) { + return nullptr; + } + return result; +} + +const ConfigFields &Config::values() const { + return _fields; +} + +void Config::apply(const MTPDconfig &data) { + if (mtpIsTrue(data.vtest_mode()) != _dcOptions.isTestMode()) { + LOG(("MTP Error: config with wrong test mode field received!")); + return; + } + + DEBUG_LOG(("MTP Info: got config, " + "chat_size_max: %1, " + "date: %2, " + "test_mode: %3, " + "this_dc: %4, " + "dc_options.length: %5" + ).arg(data.vchat_size_max().v + ).arg(data.vdate().v + ).arg(mtpIsTrue(data.vtest_mode()) + ).arg(data.vthis_dc().v + ).arg(data.vdc_options().v.size())); + + _fields.chatSizeMax = data.vchat_size_max().v; + _fields.megagroupSizeMax = data.vmegagroup_size_max().v; + _fields.forwardedCountMax = data.vforwarded_count_max().v; + _fields.onlineUpdatePeriod = data.vonline_update_period_ms().v; + _fields.offlineBlurTimeout = data.voffline_blur_timeout_ms().v; + _fields.offlineIdleTimeout = data.voffline_idle_timeout_ms().v; + _fields.onlineCloudTimeout = data.vonline_cloud_timeout_ms().v; + _fields.notifyCloudDelay = data.vnotify_cloud_delay_ms().v; + _fields.notifyDefaultDelay = data.vnotify_default_delay_ms().v; + _fields.savedGifsLimit = data.vsaved_gifs_limit().v; + _fields.editTimeLimit = data.vedit_time_limit().v; + _fields.revokeTimeLimit = data.vrevoke_time_limit().v; + _fields.revokePrivateTimeLimit = data.vrevoke_pm_time_limit().v; + _fields.revokePrivateInbox = data.is_revoke_pm_inbox(); + _fields.stickersRecentLimit = data.vstickers_recent_limit().v; + _fields.stickersFavedLimit = data.vstickers_faved_limit().v; + _fields.pinnedDialogsCountMax = + std::max(data.vpinned_dialogs_count_max().v, 1); + _fields.pinnedDialogsInFolderMax = + std::max(data.vpinned_infolder_count_max().v, 1); + _fields.internalLinksDomain = qs(data.vme_url_prefix()); + _fields.channelsReadMediaPeriod = data.vchannels_read_media_period().v; + _fields.webFileDcId = data.vwebfile_dc_id().v; + _fields.callReceiveTimeoutMs = data.vcall_receive_timeout_ms().v; + _fields.callRingTimeoutMs = data.vcall_ring_timeout_ms().v; + _fields.callConnectTimeoutMs = data.vcall_connect_timeout_ms().v; + _fields.callPacketTimeoutMs = data.vcall_packet_timeout_ms().v; + _fields.phoneCallsEnabled = data.is_phonecalls_enabled(); + _fields.blockedMode = data.is_blocked_mode(); + _fields.captionLengthMax = data.vcaption_length_max().v; + + if (data.vdc_options().v.empty()) { + LOG(("MTP Error: config with empty dc_options received!")); + } else { + dcOptions().setFromList(data.vdc_options()); + } + + _updates.fire({}); +} + +rpl::producer<> Config::updates() const { + return _updates.events(); +} + +void Config::setChatSizeMax(int value) { + _fields.chatSizeMax = value; +} + +void Config::setSavedGifsLimit(int value) { + _fields.savedGifsLimit = value; +} + +void Config::setStickersRecentLimit(int value) { + _fields.stickersRecentLimit = value; +} + +void Config::setStickersFavedLimit(int value) { + _fields.stickersFavedLimit = value; +} + +void Config::setMegagroupSizeMax(int value) { + _fields.megagroupSizeMax = value; +} + +void Config::setTxtDomainString(const QString &value) { + _fields.txtDomainString = value; +} + +} // namespace MTP diff --git a/Telegram/SourceFiles/mtproto/mtproto_config.h b/Telegram/SourceFiles/mtproto/mtproto_config.h new file mode 100644 index 000000000..6df4dd9c7 --- /dev/null +++ b/Telegram/SourceFiles/mtproto/mtproto_config.h @@ -0,0 +1,93 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +#include "mtproto/mtproto_dc_options.h" + +namespace MTP { + +struct ConfigFields { + int chatSizeMax = 200; + int megagroupSizeMax = 10000; + int forwardedCountMax = 100; + int onlineUpdatePeriod = 120000; + int offlineBlurTimeout = 5000; + int offlineIdleTimeout = 30000; + int onlineFocusTimeout = 1000; // Not from the server config. + int onlineCloudTimeout = 300000; + int notifyCloudDelay = 30000; + int notifyDefaultDelay = 1500; + int savedGifsLimit = 200; + int editTimeLimit = 172800; + int revokeTimeLimit = 172800; + int revokePrivateTimeLimit = 172800; + bool revokePrivateInbox = false; + int stickersRecentLimit = 30; + int stickersFavedLimit = 5; + rpl::variable pinnedDialogsCountMax = 5; + rpl::variable pinnedDialogsInFolderMax = 100; + QString internalLinksDomain = u"https://t.me/"_q; + int channelsReadMediaPeriod = 86400 * 7; + int callReceiveTimeoutMs = 20000; + int callRingTimeoutMs = 90000; + int callConnectTimeoutMs = 30000; + int callPacketTimeoutMs = 10000; + int webFileDcId = 4; + QString txtDomainString; + rpl::variable phoneCallsEnabled = true; + bool blockedMode = false; + int captionLengthMax = 1024; +}; + +class Config final { + struct PrivateTag { + }; + +public: + explicit Config(Environment environment); + Config(const Config &other); + + [[nodiscard]] QByteArray serialize() const; + [[nodiscard]] static std::unique_ptr FromSerialized( + const QByteArray &serialized); + + [[nodiscard]] DcOptions &dcOptions() { + return _dcOptions; + } + [[nodiscard]] const DcOptions &dcOptions() const { + return _dcOptions; + } + [[nodiscard]] MTP::Environment environment() const { + return _dcOptions.environment(); + } + [[nodiscard]] bool isTestMode() const { + return _dcOptions.isTestMode(); + } + + void apply(const MTPDconfig &data); + + [[nodiscard]] const ConfigFields &values() const; + [[nodiscard]] rpl::producer<> updates() const; + + // Set from legacy local stored values. + void setChatSizeMax(int value); + void setSavedGifsLimit(int value); + void setStickersRecentLimit(int value); + void setStickersFavedLimit(int value); + void setMegagroupSizeMax(int value); + void setTxtDomainString(const QString &value); + +private: + DcOptions _dcOptions; + ConfigFields _fields; + + rpl::event_stream<> _updates; + +}; + +} // namespace MTP \ No newline at end of file diff --git a/Telegram/SourceFiles/mtproto/dc_options.cpp b/Telegram/SourceFiles/mtproto/mtproto_dc_options.cpp similarity index 94% rename from Telegram/SourceFiles/mtproto/dc_options.cpp rename to Telegram/SourceFiles/mtproto/mtproto_dc_options.cpp index 95f8a0e0a..d2a54fc8c 100644 --- a/Telegram/SourceFiles/mtproto/dc_options.cpp +++ b/Telegram/SourceFiles/mtproto/mtproto_dc_options.cpp @@ -5,13 +5,16 @@ the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ -#include "mtproto/dc_options.h" +#include "mtproto/mtproto_dc_options.h" #include "mtproto/details/mtproto_rsa_public_key.h" #include "mtproto/facade.h" #include "mtproto/connection_tcp.h" #include "storage/serialize_common.h" +#include +#include + namespace MTP { namespace { @@ -136,10 +139,20 @@ private: }; -DcOptions::DcOptions() { +DcOptions::DcOptions(Environment environment) +: _environment(environment) { constructFromBuiltIn(); } +DcOptions::DcOptions(const DcOptions &other) +: _environment(other._environment) +, _data(other._data) +, _cdnDcIds(other._cdnDcIds) +, _publicKeys(other._publicKeys) +, _cdnPublicKeys(other._cdnPublicKeys) +, _immutable(other._immutable) { +} + DcOptions::~DcOptions() = default; bool DcOptions::ValidateSecret(bytes::const_span secret) { @@ -163,13 +176,21 @@ void DcOptions::readBuiltInPublicKeys() { } } +Environment DcOptions::environment() const { + return _environment; +} + +bool DcOptions::isTestMode() const { + return (_environment != Environment::Production); +} + void DcOptions::constructFromBuiltIn() { WriteLocker lock(this); _data.clear(); readBuiltInPublicKeys(); - const auto list = cTestMode() + const auto list = isTestMode() ? gsl::make_span(kBuiltInDcsTest) : gsl::make_span(kBuiltInDcs).subspan(0); for (const auto &entry : list) { @@ -181,7 +202,7 @@ void DcOptions::constructFromBuiltIn() { ).arg(entry.port)); } - const auto listv6 = cTestMode() + const auto listv6 = isTestMode() ? gsl::make_span(kBuiltInDcsIPv6Test) : gsl::make_span(kBuiltInDcsIPv6).subspan(0); for (const auto &entry : listv6) { @@ -204,7 +225,7 @@ void DcOptions::processFromList( auto data = [&] { if (overwrite) { - return std::map>(); + return base::flat_map>(); } ReadLocker lock(this); return _data; @@ -313,7 +334,7 @@ bool DcOptions::applyOneGuarded( } bool DcOptions::ApplyOneOption( - std::map> &data, + base::flat_map> &data, DcId dcId, Flags flags, const std::string &ip, @@ -336,8 +357,8 @@ bool DcOptions::ApplyOneOption( } std::vector DcOptions::CountOptionsDifference( - const std::map> &a, - const std::map> &b) { + const base::flat_map> &a, + const base::flat_map> &b) { auto result = std::vector(); const auto find = []( const std::vector &where, @@ -389,7 +410,7 @@ std::vector DcOptions::CountOptionsDifference( QByteArray DcOptions::serialize() const { if (_immutable) { // Don't write the overriden options to our settings. - return DcOptions().serialize(); + return DcOptions(_environment).serialize(); } ReadLocker lock(this); @@ -477,7 +498,7 @@ QByteArray DcOptions::serialize() const { return result; } -void DcOptions::constructFromSerialized(const QByteArray &serialized) { +bool DcOptions::constructFromSerialized(const QByteArray &serialized) { QDataStream stream(serialized); stream.setVersion(QDataStream::Qt_5_1); @@ -493,7 +514,7 @@ void DcOptions::constructFromSerialized(const QByteArray &serialized) { } if (stream.status() != QDataStream::Ok) { LOG(("MTP Error: Bad data for DcOptions::constructFromSerialized()")); - return; + return false; } WriteLocker lock(this); @@ -506,7 +527,7 @@ void DcOptions::constructFromSerialized(const QByteArray &serialized) { constexpr auto kMaxIpSize = 45; if (ipSize <= 0 || ipSize > kMaxIpSize) { LOG(("MTP Error: Bad data inside DcOptions::constructFromSerialized()")); - return; + return false; } auto ip = std::string(ipSize, ' '); @@ -519,7 +540,7 @@ void DcOptions::constructFromSerialized(const QByteArray &serialized) { stream >> secretSize; if (secretSize < 0 || secretSize > kMaxSecretSize) { LOG(("MTP Error: Bad data inside DcOptions::constructFromSerialized()")); - return; + return false; } else if (secretSize > 0) { secret.resize(secretSize); stream.readRawData( @@ -530,7 +551,7 @@ void DcOptions::constructFromSerialized(const QByteArray &serialized) { if (stream.status() != QDataStream::Ok) { LOG(("MTP Error: Bad data inside DcOptions::constructFromSerialized()")); - return; + return false; } applyOneGuarded( @@ -547,7 +568,7 @@ void DcOptions::constructFromSerialized(const QByteArray &serialized) { stream >> count; if (stream.status() != QDataStream::Ok) { LOG(("MTP Error: Bad data for CDN config in DcOptions::constructFromSerialized()")); - return; + return false; } for (auto i = 0; i != count; ++i) { @@ -556,7 +577,7 @@ void DcOptions::constructFromSerialized(const QByteArray &serialized) { stream >> dcId >> Serialize::bytes(n) >> Serialize::bytes(e); if (stream.status() != QDataStream::Ok) { LOG(("MTP Error: Bad data for CDN config inside DcOptions::constructFromSerialized()")); - return; + return false; } auto key = RSAPublicKey(n, e); @@ -564,9 +585,11 @@ void DcOptions::constructFromSerialized(const QByteArray &serialized) { _cdnPublicKeys[dcId].emplace(key.fingerprint(), std::move(key)); } else { LOG(("MTP Error: Could not read valid CDN public key.")); + return false; } } } + return true; } rpl::producer DcOptions::changed() const { @@ -640,7 +663,8 @@ bool DcOptions::hasCDNKeysForDc(DcId dcId) const { RSAPublicKey DcOptions::getDcRSAKey( DcId dcId, const QVector &fingerprints) const { - const auto findKey = [&](const std::map &keys) { + const auto findKey = [&]( + const base::flat_map &keys) { for (const auto &fingerprint : fingerprints) { const auto it = keys.find(static_cast(fingerprint.v)); if (it != keys.cend()) { diff --git a/Telegram/SourceFiles/mtproto/dc_options.h b/Telegram/SourceFiles/mtproto/mtproto_dc_options.h similarity index 81% rename from Telegram/SourceFiles/mtproto/dc_options.h rename to Telegram/SourceFiles/mtproto/mtproto_dc_options.h index 11449d3ea..26c6e0861 100644 --- a/Telegram/SourceFiles/mtproto/dc_options.h +++ b/Telegram/SourceFiles/mtproto/mtproto_dc_options.h @@ -27,6 +27,12 @@ enum class DcType { MediaCluster, Cdn, }; + +enum class Environment : uchar { + Production, + Test, +}; + class DcOptions { public: using Flag = MTPDdcOption::Flag; @@ -53,13 +59,17 @@ public: }; - DcOptions(); + explicit DcOptions(Environment environment); + DcOptions(const DcOptions &other); ~DcOptions(); [[nodiscard]] static bool ValidateSecret(bytes::const_span secret); + [[nodiscard]] Environment environment() const; + [[nodiscard]] bool isTestMode() const; + // construct methods don't notify "changed" subscribers. - void constructFromSerialized(const QByteArray &serialized); + bool constructFromSerialized(const QByteArray &serialized); void constructFromBuiltIn(); void constructAddOne( int id, @@ -114,15 +124,15 @@ private: int port, const bytes::vector &secret); static bool ApplyOneOption( - std::map> &data, + base::flat_map> &data, DcId dcId, Flags flags, const std::string &ip, int port, const bytes::vector &secret); static std::vector CountOptionsDifference( - const std::map> &a, - const std::map> &b); + const base::flat_map> &a, + const base::flat_map> &b); static void FilterIfHasWithFlag(Variants &variants, Flag flag); [[nodiscard]] bool hasMediaOnlyOptionsFor(DcId dcId) const; @@ -138,10 +148,13 @@ private: class ReadLocker; friend class ReadLocker; - std::map> _data; - std::set _cdnDcIds; - std::map _publicKeys; - std::map> _cdnPublicKeys; + const Environment _environment = Environment(); + base::flat_map> _data; + base::flat_set _cdnDcIds; + base::flat_map _publicKeys; + base::flat_map< + DcId, + base::flat_map> _cdnPublicKeys; mutable QReadWriteLock _useThroughLockers; rpl::event_stream _changed; diff --git a/Telegram/SourceFiles/mtproto/mtproto_pch.h b/Telegram/SourceFiles/mtproto/mtproto_pch.h index 2804191f4..284089e7e 100644 --- a/Telegram/SourceFiles/mtproto/mtproto_pch.h +++ b/Telegram/SourceFiles/mtproto/mtproto_pch.h @@ -10,10 +10,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include #include +#include + #include #include #include "base/bytes.h" +#include "base/flat_map.h" +#include "base/flat_set.h" #include "logs.h" #include "scheme.h" diff --git a/Telegram/SourceFiles/mtproto/sender.h b/Telegram/SourceFiles/mtproto/sender.h index 189121f1f..c9eaf23fe 100644 --- a/Telegram/SourceFiles/mtproto/sender.h +++ b/Telegram/SourceFiles/mtproto/sender.h @@ -196,8 +196,8 @@ public: : _instance(instance) { } - [[nodiscard]] not_null instance() const { - return _instance; + [[nodiscard]] Instance &instance() const { + return *_instance; } template @@ -247,7 +247,7 @@ public: } mtpRequestId send() { - const auto id = sender()->instance()->send( + const auto id = sender()->_instance->send( _request, takeOnDone(), takeOnFail(), @@ -376,7 +376,7 @@ private: }; template - friend class SpecialRequestBuilder; + friend class SpecificRequestBuilder; friend class RequestBuilder; friend class RequestWrap; friend class SentRequestWrap; diff --git a/Telegram/SourceFiles/mtproto/session.cpp b/Telegram/SourceFiles/mtproto/session.cpp index f850e9956..b4f264662 100644 --- a/Telegram/SourceFiles/mtproto/session.cpp +++ b/Telegram/SourceFiles/mtproto/session.cpp @@ -195,7 +195,7 @@ void Session::watchDcKeyChanges() { } void Session::watchDcOptionsChanges() { - _instance->dcOptions()->changed( + _instance->dcOptions().changed( ) | rpl::filter([=](DcId dcId) { return (BareDcId(_shiftedDcId) == dcId) && (_private != nullptr); }) | rpl::start_with_next([=] { @@ -204,8 +204,8 @@ void Session::watchDcOptionsChanges() { }); }, _lifetime); - if (_instance->dcOptions()->dcType(_shiftedDcId) == DcType::Cdn) { - _instance->dcOptions()->cdnConfigChanged( + if (_instance->dcOptions().dcType(_shiftedDcId) == DcType::Cdn) { + _instance->dcOptions().cdnConfigChanged( ) | rpl::filter([=] { return (_private != nullptr); }) | rpl::start_with_next([=] { diff --git a/Telegram/SourceFiles/mtproto/session_private.cpp b/Telegram/SourceFiles/mtproto/session_private.cpp index 8f7aa7c59..b54b591b0 100644 --- a/Telegram/SourceFiles/mtproto/session_private.cpp +++ b/Telegram/SourceFiles/mtproto/session_private.cpp @@ -13,7 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mtproto/details/mtproto_rsa_public_key.h" #include "mtproto/session.h" #include "mtproto/mtproto_rpc_sender.h" -#include "mtproto/dc_options.h" +#include "mtproto/mtproto_dc_options.h" #include "mtproto/connection_abstract.h" #include "base/openssl_help.h" #include "base/qthelp_url.h" @@ -117,7 +117,7 @@ SessionPrivate::SessionPrivate( : QObject(nullptr) , _instance(instance) , _shiftedDcId(shiftedDcId) -, _realDcType(_instance->dcOptions()->dcType(_shiftedDcId)) +, _realDcType(_instance->dcOptions().dcType(_shiftedDcId)) , _currentDcType(_realDcType) , _state(DisconnectedState) , _retryTimer(thread, [=] { retryByTimer(); }) @@ -203,7 +203,7 @@ int16 SessionPrivate::getProtocolDcId() const { const auto simpleDcId = isTemporaryDcId(dcId) ? getRealIdFromTemporaryDcId(dcId) : dcId; - const auto testedDcId = cTestMode() + const auto testedDcId = _instance->isTestMode() ? (kTestModeDcIdShift + simpleDcId) : simpleDcId; return (_currentDcType == DcType::MediaCluster) @@ -374,7 +374,7 @@ uint32 SessionPrivate::nextRequestSeqNumber(bool needAck) { } bool SessionPrivate::realDcTypeChanged() { - const auto now = _instance->dcOptions()->dcType(_shiftedDcId); + const auto now = _instance->dcOptions().dcType(_shiftedDcId); if (_realDcType == now) { return false; } @@ -936,7 +936,7 @@ void SessionPrivate::connectToServer(bool afterConfig) { _currentDcType = tryAcquireKeyCreation(); if (_currentDcType == DcType::Cdn && !_instance->isKeysDestroyer()) { - if (!_instance->dcOptions()->hasCDNKeysForDc(bareDc)) { + if (!_instance->dcOptions().hasCDNKeysForDc(bareDc)) { requestCDNConfig(); return; } @@ -947,7 +947,7 @@ void SessionPrivate::connectToServer(bool afterConfig) { } else { using Variants = DcOptions::Variants; const auto special = (_currentDcType == DcType::Temporary); - const auto variants = _instance->dcOptions()->lookup( + const auto variants = _instance->dcOptions().lookup( bareDc, _currentDcType, _options->proxy.type != ProxyData::Type::None); @@ -2366,7 +2366,7 @@ void SessionPrivate::applyAuthKey(AuthKeyPtr &&encryptionKey) { BareDcId(_shiftedDcId), getProtocolDcId(), _connection.get(), - _instance->dcOptions()); + &_instance->dcOptions()); } else { DEBUG_LOG(("AuthKey Info: No key in updateAuthKey(), " "but someone is creating already, waiting.")); diff --git a/Telegram/SourceFiles/mtproto/session_private.h b/Telegram/SourceFiles/mtproto/session_private.h index 302067c65..cf7c68ab4 100644 --- a/Telegram/SourceFiles/mtproto/session_private.h +++ b/Telegram/SourceFiles/mtproto/session_private.h @@ -10,7 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mtproto/details/mtproto_received_ids_manager.h" #include "mtproto/details/mtproto_serialized_request.h" #include "mtproto/mtproto_auth_key.h" -#include "mtproto/dc_options.h" +#include "mtproto/mtproto_dc_options.h" #include "mtproto/connection_abstract.h" #include "mtproto/facade.h" #include "base/openssl_help.h" diff --git a/Telegram/SourceFiles/mtproto/special_config_request.cpp b/Telegram/SourceFiles/mtproto/special_config_request.cpp index 2bc5cae2a..ab8bd0c6a 100644 --- a/Telegram/SourceFiles/mtproto/special_config_request.cpp +++ b/Telegram/SourceFiles/mtproto/special_config_request.cpp @@ -8,7 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mtproto/special_config_request.h" #include "mtproto/details/mtproto_rsa_public_key.h" -#include "mtproto/dc_options.h" +#include "mtproto/mtproto_dc_options.h" #include "mtproto/mtproto_auth_key.h" #include "base/unixtime.h" #include "base/openssl_help.h" @@ -189,9 +189,11 @@ SpecialConfigRequest::SpecialConfigRequest( int port, bytes::const_span secret)> callback, Fn timeDoneCallback, + const QString &domainString, const QString &phone) : _callback(std::move(callback)) , _timeDoneCallback(std::move(timeDoneCallback)) +, _domainString(domainString) , _phone(phone) { Expects((_callback == nullptr) != (_timeDoneCallback == nullptr)); @@ -251,12 +253,19 @@ SpecialConfigRequest::SpecialConfigRequest( const std::string &ip, int port, bytes::const_span secret)> callback, + const QString &domainString, const QString &phone) -: SpecialConfigRequest(std::move(callback), nullptr, phone) { +: SpecialConfigRequest(std::move(callback), nullptr, domainString, phone) { } -SpecialConfigRequest::SpecialConfigRequest(Fn timeDoneCallback) -: SpecialConfigRequest(nullptr, std::move(timeDoneCallback), QString()) { +SpecialConfigRequest::SpecialConfigRequest( + Fn timeDoneCallback, + const QString &domainString) +: SpecialConfigRequest( + nullptr, + std::move(timeDoneCallback), + domainString, + QString()) { } void SpecialConfigRequest::sendNextRequest() { @@ -283,7 +292,7 @@ void SpecialConfigRequest::performRequest(const Attempt &attempt) { url.setHost(attempt.data); url.setPath(qsl("/dns-query")); url.setQuery(qsl("name=%1&type=16&random_padding=%2" - ).arg(Global::TxtDomainString() + ).arg(_domainString ).arg(GenerateDnsRandomPadding())); request.setRawHeader("accept", "application/dns-json"); } break; @@ -291,7 +300,7 @@ void SpecialConfigRequest::performRequest(const Attempt &attempt) { url.setHost(attempt.data); url.setPath(qsl("/resolve")); url.setQuery(qsl("name=%1&type=ANY&random_padding=%2" - ).arg(Global::TxtDomainString() + ).arg(_domainString ).arg(GenerateDnsRandomPadding())); if (!attempt.host.isEmpty()) { const auto host = attempt.host + ".google.com"; diff --git a/Telegram/SourceFiles/mtproto/special_config_request.h b/Telegram/SourceFiles/mtproto/special_config_request.h index da4d27f4d..6962c04fe 100644 --- a/Telegram/SourceFiles/mtproto/special_config_request.h +++ b/Telegram/SourceFiles/mtproto/special_config_request.h @@ -25,8 +25,11 @@ public: const std::string &ip, int port, bytes::const_span secret)> callback, + const QString &domainString, const QString &phone); - explicit SpecialConfigRequest(Fn timeDoneCallback); + SpecialConfigRequest( + Fn timeDoneCallback, + const QString &domainString); private: enum class Type { @@ -49,6 +52,7 @@ private: int port, bytes::const_span secret)> callback, Fn timeDoneCallback, + const QString &domainString, const QString &phone); void sendNextRequest(); @@ -65,6 +69,7 @@ private: int port, bytes::const_span secret)> _callback; Fn _timeDoneCallback; + QString _domainString; QString _phone; MTPhelp_ConfigSimple _simpleConfig; diff --git a/Telegram/SourceFiles/passport/passport_form_controller.cpp b/Telegram/SourceFiles/passport/passport_form_controller.cpp index 386ae43a9..80d91a9d3 100644 --- a/Telegram/SourceFiles/passport/passport_form_controller.cpp +++ b/Telegram/SourceFiles/passport/passport_form_controller.cpp @@ -624,7 +624,7 @@ FormController::FormController( not_null controller, const FormRequest &request) : _controller(controller) -, _api(_controller->session().mtp()) +, _api(&_controller->session().mtp()) , _request(PreprocessRequest(request)) , _shortPollTimer([=] { reloadPassword(); }) , _view(std::make_unique(this)) { diff --git a/Telegram/SourceFiles/platform/linux/launcher_linux.cpp b/Telegram/SourceFiles/platform/linux/launcher_linux.cpp index 679f4864b..1d948fd19 100644 --- a/Telegram/SourceFiles/platform/linux/launcher_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/launcher_linux.cpp @@ -67,9 +67,6 @@ bool Launcher::launchUpdater(UpdaterLaunch action) { if (cStartInTray()) { argumentsList.push("-startintray"); } - if (cTestMode()) { - argumentsList.push("-testmode"); - } #ifndef TDESKTOP_DISABLE_AUTOUPDATE if (Core::UpdaterDisabled()) { argumentsList.push("-externalupdater"); diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp index 71f32f6be..fc5b3f140 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp @@ -1025,7 +1025,7 @@ void MainWindow::updateGlobalMenuHook() { canCopy = list->canCopySelected(); canDelete = list->canDeleteSelected(); } - App::wnd()->updateIsActive(0); + App::wnd()->updateIsActive(); const auto logged = account().sessionExists(); const auto locked = Core::App().locked(); const auto inactive = !logged || locked; diff --git a/Telegram/SourceFiles/platform/mac/launcher_mac.mm b/Telegram/SourceFiles/platform/mac/launcher_mac.mm index 080f7471b..a8d0cb26b 100644 --- a/Telegram/SourceFiles/platform/mac/launcher_mac.mm +++ b/Telegram/SourceFiles/platform/mac/launcher_mac.mm @@ -63,7 +63,6 @@ bool Launcher::launchUpdater(UpdaterLaunch action) { if (cLaunchMode() == LaunchModeAutoStart) [args addObject:@"-autostart"]; if (Logs::DebugEnabled()) [args addObject:@"-debug"]; if (cStartInTray()) [args addObject:@"-startintray"]; - if (cTestMode()) [args addObject:@"-testmode"]; if (cUseFreeType()) [args addObject:@"-freetype"]; #ifndef TDESKTOP_DISABLE_AUTOUPDATE if (Core::UpdaterDisabled()) [args addObject:@"-externalupdater"]; diff --git a/Telegram/SourceFiles/platform/mac/mac_touchbar.mm b/Telegram/SourceFiles/platform/mac/mac_touchbar.mm index feeec8ce8..c1b77c3d5 100644 --- a/Telegram/SourceFiles/platform/mac/mac_touchbar.mm +++ b/Telegram/SourceFiles/platform/mac/mac_touchbar.mm @@ -11,6 +11,7 @@ #include "apiwrap.h" #include "main/main_session.h" +#include "mtproto/mtproto_config.h" #include "api/api_sending.h" #include "boxes/confirm_box.h" #include "chat_helpers/emoji_list_widget.h" @@ -39,7 +40,6 @@ #include "window/window_session_controller.h" #include "ui/empty_userpic.h" #include "ui/widgets/input_fields.h" -#include "facades.h" #include "app.h" #include "window/window_controller.h" @@ -1233,7 +1233,8 @@ void AppendEmojiPacks( _mainPinnedButtons = [[NSMutableArray alloc] init]; NSStackView *stackView = [[NSStackView alloc] init]; - for (auto i = kArchiveId; i <= Global::PinnedDialogsCountMax(); i++) { + const auto &config = _session->serverConfig(); + for (auto i = kArchiveId; i <= config.pinnedDialogsCountMax.current(); i++) { PinnedDialogButton *button = [[[PinnedDialogButton alloc] init:i diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.mm b/Telegram/SourceFiles/platform/mac/main_window_mac.mm index 95341c679..64ee4253a 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.mm +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.mm @@ -821,7 +821,7 @@ void MainWindow::updateGlobalMenuHook() { if (_private->_touchBar) { [_private->_touchBar showInputFieldItem:showTouchBarItem]; } - App::wnd()->updateIsActive(0); + App::wnd()->updateIsActive(); const auto logged = account().sessionExists(); const auto locked = Core::App().locked(); const auto inactive = !logged || locked; diff --git a/Telegram/SourceFiles/platform/win/launcher_win.cpp b/Telegram/SourceFiles/platform/win/launcher_win.cpp index b2584cd0c..20d530249 100644 --- a/Telegram/SourceFiles/platform/win/launcher_win.cpp +++ b/Telegram/SourceFiles/platform/win/launcher_win.cpp @@ -68,9 +68,6 @@ bool Launcher::launchUpdater(UpdaterLaunch action) { if (cStartInTray()) { pushArgument(qsl("-startintray")); } - if (cTestMode()) { - pushArgument(qsl("-testmode")); - } if (cUseFreeType()) { pushArgument(qsl("-freetype")); } diff --git a/Telegram/SourceFiles/profile/profile_block_group_members.cpp b/Telegram/SourceFiles/profile/profile_block_group_members.cpp index a67c574af..ab0711376 100644 --- a/Telegram/SourceFiles/profile/profile_block_group_members.cpp +++ b/Telegram/SourceFiles/profile/profile_block_group_members.cpp @@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/peers/edit_participants_box.h" #include "base/unixtime.h" #include "ui/widgets/popup_menu.h" +#include "mtproto/mtproto_config.h" #include "data/data_peer_values.h" #include "data/data_channel.h" #include "data/data_chat.h" @@ -23,7 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "apiwrap.h" #include "main/main_session.h" #include "lang/lang_keys.h" -#include "facades.h" +#include "facades.h" // Ui::showPeerProfile namespace Profile { namespace { @@ -341,7 +342,8 @@ void GroupMembersWidget::fillMegagroupMembers( } _sortByOnline = (megagroup->membersCount() > 0) - && (megagroup->membersCount() <= Global::ChatSizeMax()); + && (megagroup->membersCount() + <= megagroup->session().serverConfig().chatSizeMax); auto &membersList = megagroup->mgInfo->lastParticipants; if (_sortByOnline) { diff --git a/Telegram/SourceFiles/settings.cpp b/Telegram/SourceFiles/settings.cpp index 682f3ab83..4cdbbdded 100644 --- a/Telegram/SourceFiles/settings.cpp +++ b/Telegram/SourceFiles/settings.cpp @@ -24,7 +24,6 @@ uint64 gAlphaVersion = AppAlphaVersion; uint64 gRealAlphaVersion = AppAlphaVersion; QByteArray gAlphaPrivateKey; -bool gTestMode = false; bool gManyInstance = false; QString gKeyFile; QString gWorkingDir, gExeDir, gExeName; diff --git a/Telegram/SourceFiles/settings.h b/Telegram/SourceFiles/settings.h index b87c300b1..2877f6504 100644 --- a/Telegram/SourceFiles/settings.h +++ b/Telegram/SourceFiles/settings.h @@ -35,7 +35,6 @@ DeclareSetting(uint64, AlphaVersion); DeclareSetting(uint64, RealAlphaVersion); DeclareSetting(QByteArray, AlphaPrivateKey); -DeclareSetting(bool, TestMode); DeclareSetting(bool, AutoStart); DeclareSetting(bool, StartMinimized); DeclareSetting(bool, StartInTray); diff --git a/Telegram/SourceFiles/settings/settings_advanced.cpp b/Telegram/SourceFiles/settings/settings_advanced.cpp index c55b7047e..9ed96b9b8 100644 --- a/Telegram/SourceFiles/settings/settings_advanced.cpp +++ b/Telegram/SourceFiles/settings/settings_advanced.cpp @@ -57,9 +57,7 @@ void SetupConnectionType( } #ifndef TDESKTOP_DISABLE_NETWORK_PROXY const auto connectionType = [=] { - const auto transport = account->mtp() - ? account->mtp()->dctransport() - : QString(); + const auto transport = account->mtp().dctransport(); if (Global::ProxySettings() != MTP::ProxyData::Settings::Enabled) { return transport.isEmpty() ? tr::lng_connection_auto_connecting(tr::now) diff --git a/Telegram/SourceFiles/settings/settings_codes.cpp b/Telegram/SourceFiles/settings/settings_codes.cpp index 930df4a17..a1d72d1f3 100644 --- a/Telegram/SourceFiles/settings/settings_codes.cpp +++ b/Telegram/SourceFiles/settings/settings_codes.cpp @@ -13,13 +13,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mainwindow.h" #include "data/data_session.h" #include "main/main_session.h" +#include "main/main_account.h" #include "main/main_accounts.h" #include "boxes/confirm_box.h" #include "lang/lang_cloud_manager.h" #include "lang/lang_instance.h" #include "core/application.h" #include "mtproto/mtp_instance.h" -#include "mtproto/dc_options.h" +#include "mtproto/mtproto_dc_options.h" #include "core/file_utilities.h" #include "core/update_checker.h" #include "window/themes/window_theme.h" @@ -49,12 +50,6 @@ auto GenerateCodes() { codes.emplace(qsl("viewlogs"), [](SessionController *window) { File::ShowInFolder(cWorkingDir() + "log.txt"); }); - codes.emplace(qsl("testmode"), [](SessionController *window) { - auto text = cTestMode() ? qsl("Do you want to disable TEST mode?") : qsl("Do you want to enable TEST mode?\n\nYou will be switched to test cloud."); - Ui::show(Box(text, [] { - Core::App().switchTestMode(); - })); - }); if (!Core::UpdaterDisabled()) { codes.emplace(qsl("testupdate"), [](SessionController *window) { Core::UpdateChecker().test(); @@ -112,10 +107,25 @@ auto GenerateCodes() { })); }); codes.emplace(qsl("endpoints"), [](SessionController *window) { - FileDialog::GetOpenPath(Core::App().getFileDialogParent(), "Open DC endpoints", "DC Endpoints (*.tdesktop-endpoints)", [](const FileDialog::OpenResult &result) { + if (!Core::App().accounts().started()) { + return; + } + const auto weak = window + ? base::make_weak(&window->session().account()) + : nullptr; + FileDialog::GetOpenPath(Core::App().getFileDialogParent(), "Open DC endpoints", "DC Endpoints (*.tdesktop-endpoints)", [weak](const FileDialog::OpenResult &result) { if (!result.paths.isEmpty()) { - if (!Core::App().dcOptions()->loadFromFile(result.paths.front())) { - Ui::show(Box("Could not load endpoints :( Errors in 'log.txt'.")); + const auto loadFor = [&](not_null account) { + if (!account->mtp().dcOptions().loadFromFile(result.paths.front())) { + Ui::show(Box("Could not load endpoints :( Errors in 'log.txt'.")); + } + }; + if (const auto strong = weak.get()) { + loadFor(strong); + } else { + for (const auto &[index, account] : Core::App().accounts().list()) { + loadFor(account.get()); + } } } }); @@ -130,11 +140,26 @@ auto GenerateCodes() { crl::on_main(&Core::App(), [=] { if (window && !Core::App().locked() + && Core::App().accounts().started() && Core::App().accounts().list().size() < 3) { - Core::App().accounts().activate(Core::App().accounts().add()); + Core::App().accounts().activate( + Core::App().accounts().add(MTP::Environment::Production)); } }); }); + + codes.emplace(qsl("acctest"), [](SessionController *window) { + crl::on_main(&Core::App(), [=] { + if (window + && !Core::App().locked() + && Core::App().accounts().started() + && Core::App().accounts().list().size() < 3) { + Core::App().accounts().activate( + Core::App().accounts().add(MTP::Environment::Test)); + } + }); + }); + for (auto i = 0; i != 3; ++i) { codes.emplace(qsl("account%1").arg(i + 1), [=]( SessionController *window) { diff --git a/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp b/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp index d946cb66c..e4b9f352c 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp +++ b/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp @@ -182,7 +182,7 @@ AdminLog::OwnedItem GenerateForwardedItem( BlockedBoxController::BlockedBoxController( not_null window) : _window(window) -, _api(_window->session().mtp()) { +, _api(&_window->session().mtp()) { } Main::Session &BlockedBoxController::session() const { diff --git a/Telegram/SourceFiles/storage/details/storage_settings_scheme.cpp b/Telegram/SourceFiles/storage/details/storage_settings_scheme.cpp index f4fc6e7a4..70686c5b3 100644 --- a/Telegram/SourceFiles/storage/details/storage_settings_scheme.cpp +++ b/Telegram/SourceFiles/storage/details/storage_settings_scheme.cpp @@ -9,8 +9,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/details/storage_file_utilities.h" #include "storage/cache/storage_cache_database.h" -#include "core/application.h" #include "storage/serialize_common.h" +#include "core/application.h" +#include "mtproto/mtproto_config.h" #include "ui/effects/animation_value.h" #include "ui/widgets/input_fields.h" #include "window/themes/window_theme.h" @@ -47,7 +48,7 @@ bool ReadSetting( stream >> dcId >> host >> ip >> port; if (!CheckStreamStatus(stream)) return false; - context.dcOptions.constructAddOne( + context.fallbackConfigLegacyDcOptions.constructAddOne( dcId, 0, ip.toStdString(), @@ -62,7 +63,7 @@ bool ReadSetting( stream >> dcIdWithShift >> flags >> ip >> port; if (!CheckStreamStatus(stream)) return false; - context.dcOptions.constructAddOne( + context.fallbackConfigLegacyDcOptions.constructAddOne( dcIdWithShift, MTPDdcOption::Flags::from_raw(flags), ip.toStdString(), @@ -70,12 +71,13 @@ bool ReadSetting( {}); } break; - case dbiDcOptions: { + case dbiDcOptionsOld: { auto serialized = QByteArray(); stream >> serialized; if (!CheckStreamStatus(stream)) return false; - context.dcOptions.constructFromSerialized(serialized); + context.fallbackConfigLegacyDcOptions.constructFromSerialized( + serialized); } break; case dbiApplicationSettings: { @@ -86,44 +88,44 @@ bool ReadSetting( Core::App().settings().constructFromSerialized(serialized); } break; - case dbiChatSizeMax: { + case dbiChatSizeMaxOld: { qint32 maxSize; stream >> maxSize; if (!CheckStreamStatus(stream)) return false; - Global::SetChatSizeMax(maxSize); + context.fallbackConfigLegacyChatSizeMax = maxSize; } break; - case dbiSavedGifsLimit: { + case dbiSavedGifsLimitOld: { qint32 limit; stream >> limit; if (!CheckStreamStatus(stream)) return false; - Global::SetSavedGifsLimit(limit); + context.fallbackConfigLegacySavedGifsLimit = limit; } break; - case dbiStickersRecentLimit: { + case dbiStickersRecentLimitOld: { qint32 limit; stream >> limit; if (!CheckStreamStatus(stream)) return false; - Global::SetStickersRecentLimit(limit); + context.fallbackConfigLegacyStickersRecentLimit = limit; } break; - case dbiStickersFavedLimit: { + case dbiStickersFavedLimitOld: { qint32 limit; stream >> limit; if (!CheckStreamStatus(stream)) return false; - Global::SetStickersFavedLimit(limit); + context.fallbackConfigLegacyStickersFavedLimit = limit; } break; - case dbiMegagroupSizeMax: { + case dbiMegagroupSizeMaxOld: { qint32 maxSize; stream >> maxSize; if (!CheckStreamStatus(stream)) return false; - Global::SetMegagroupSizeMax(maxSize); + context.fallbackConfigLegacyMegagroupSizeMax = maxSize; } break; case dbiUser: { @@ -407,18 +409,18 @@ bool ReadSetting( Global::RefWorkMode().set(newMode()); } break; - case dbiTxtDomainStringOld: { + case dbiTxtDomainStringOldOld: { QString v; stream >> v; if (!CheckStreamStatus(stream)) return false; } break; - case dbiTxtDomainString: { + case dbiTxtDomainStringOld: { QString v; stream >> v; if (!CheckStreamStatus(stream)) return false; - Global::SetTxtDomainString(v); + context.fallbackConfigLegacyTxtDomainString = v; } break; case dbiConnectionTypeOld: { @@ -659,13 +661,13 @@ bool ReadSetting( } } break; - case dbiLangOld: { + case dbiLangOld: { // deprecated qint32 v; stream >> v; if (!CheckStreamStatus(stream)) return false; } break; - case dbiLangFileOld: { + case dbiLangFileOld: { // deprecated QString v; stream >> v; if (!CheckStreamStatus(stream)) return false; @@ -681,19 +683,19 @@ bool ReadSetting( cSetWindowPos(position); } break; - case dbiLoggedPhoneNumber: { // deprecated + case dbiLoggedPhoneNumberOld: { // deprecated QString v; stream >> v; if (!CheckStreamStatus(stream)) return false; } break; - case dbiMutePeer: { // deprecated + case dbiMutePeerOld: { // deprecated quint64 peerId; stream >> peerId; if (!CheckStreamStatus(stream)) return false; } break; - case dbiMutedPeers: { // deprecated + case dbiMutedPeersOld: { // deprecated quint32 count; stream >> count; if (!CheckStreamStatus(stream)) return false; @@ -1001,6 +1003,14 @@ bool ReadSetting( context.callSettings = callSettings; } break; + case dbiFallbackProductionConfig: { + QByteArray config; + stream >> config; + if (!CheckStreamStatus(stream)) return false; + + context.fallbackConfig = config; + } break; + default: LOG(("App Error: unknown blockId in _readSetting: %1").arg(blockId)); return false; @@ -1009,5 +1019,38 @@ bool ReadSetting( return true; } +void ApplyReadFallbackConfig(ReadSettingsContext &context) { + if (context.fallbackConfig.isEmpty()) { + auto &config = Core::App().fallbackProductionConfig(); + config.dcOptions().addFromOther( + std::move(context.fallbackConfigLegacyDcOptions)); + if (context.fallbackConfigLegacyChatSizeMax > 0) { + config.setChatSizeMax(context.fallbackConfigLegacyChatSizeMax); + } + if (context.fallbackConfigLegacySavedGifsLimit > 0) { + config.setSavedGifsLimit( + context.fallbackConfigLegacySavedGifsLimit); + } + if (context.fallbackConfigLegacyStickersRecentLimit > 0) { + config.setStickersRecentLimit( + context.fallbackConfigLegacyStickersRecentLimit); + } + if (context.fallbackConfigLegacyStickersFavedLimit > 0) { + config.setStickersFavedLimit( + context.fallbackConfigLegacyStickersFavedLimit); + } + if (context.fallbackConfigLegacyMegagroupSizeMax > 0) { + config.setMegagroupSizeMax( + context.fallbackConfigLegacyMegagroupSizeMax); + } + if (!context.fallbackConfigLegacyTxtDomainString.isEmpty()) { + config.setTxtDomainString( + context.fallbackConfigLegacyTxtDomainString); + } + } else { + Core::App().constructFallbackProductionConfig(context.fallbackConfig); + } +} + } // namespace details } // namespace Storage diff --git a/Telegram/SourceFiles/storage/details/storage_settings_scheme.h b/Telegram/SourceFiles/storage/details/storage_settings_scheme.h index 09f68ec72..654f23b2f 100644 --- a/Telegram/SourceFiles/storage/details/storage_settings_scheme.h +++ b/Telegram/SourceFiles/storage/details/storage_settings_scheme.h @@ -7,7 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once -#include "mtproto/dc_options.h" +#include "mtproto/mtproto_dc_options.h" #include "main/main_settings.h" #include "storage/storage_account.h" @@ -30,7 +30,15 @@ struct ReadSettingsContext { bool hasCustomDayBackground = false; // Those fields are written in ReadSetting. - MTP::DcOptions dcOptions; + MTP::DcOptions fallbackConfigLegacyDcOptions + = MTP::DcOptions(MTP::Environment::Production); + qint32 fallbackConfigLegacyChatSizeMax = 0; + qint32 fallbackConfigLegacySavedGifsLimit = 0; + qint32 fallbackConfigLegacyStickersRecentLimit = 0; + qint32 fallbackConfigLegacyStickersFavedLimit = 0; + qint32 fallbackConfigLegacyMegagroupSizeMax = 0; + QString fallbackConfigLegacyTxtDomainString; + QByteArray fallbackConfig; qint64 cacheTotalSizeLimit = 0; qint32 cacheTotalTimeLimit = 0; @@ -62,12 +70,14 @@ struct ReadSettingsContext { int version, ReadSettingsContext &context); +void ApplyReadFallbackConfig(ReadSettingsContext &context); + enum { dbiKey = 0x00, dbiUser = 0x01, dbiDcOptionOldOld = 0x02, - dbiChatSizeMax = 0x03, - dbiMutePeer = 0x04, + dbiChatSizeMaxOld = 0x03, + dbiMutePeerOld = 0x04, dbiSendKeyOld = 0x05, dbiAutoStart = 0x06, dbiStartMinimized = 0x07, @@ -88,8 +98,8 @@ enum { dbiScaleOld = 0x16, dbiEmojiTabOld = 0x17, dbiRecentEmojiOldOld = 0x18, - dbiLoggedPhoneNumber = 0x19, - dbiMutedPeers = 0x1a, + dbiLoggedPhoneNumberOld = 0x19, + dbiMutedPeersOld = 0x1a, // 0x1b reserved dbiNotifyView = 0x1c, dbiSendToMenu = 0x1d, @@ -107,10 +117,10 @@ enum { dbiSongVolume = 0x29, dbiWindowsNotificationsOld = 0x30, dbiIncludeMutedOld = 0x31, - dbiMegagroupSizeMax = 0x32, + dbiMegagroupSizeMaxOld = 0x32, dbiDownloadPath = 0x33, dbiAutoDownloadOld = 0x34, - dbiSavedGifsLimit = 0x35, + dbiSavedGifsLimitOld = 0x35, dbiShowingSavedGifsOld = 0x36, dbiAutoPlayOld = 0x37, dbiAdaptiveForWide = 0x38, @@ -120,23 +130,23 @@ enum { dbiDialogsModeOld = 0x40, dbiModerateMode = 0x41, dbiVideoVolume = 0x42, - dbiStickersRecentLimit = 0x43, + dbiStickersRecentLimitOld = 0x43, dbiNativeNotifications = 0x44, dbiNotificationsCount = 0x45, dbiNotificationsCorner = 0x46, dbiThemeKeyOld = 0x47, dbiDialogsWidthRatioOld = 0x48, dbiUseExternalVideoPlayer = 0x49, - dbiDcOptions = 0x4a, + dbiDcOptionsOld = 0x4a, dbiMtpAuthorization = 0x4b, dbiLastSeenWarningSeenOld = 0x4c, dbiSessionSettings = 0x4d, dbiLangPackKey = 0x4e, dbiConnectionType = 0x4f, - dbiStickersFavedLimit = 0x50, + dbiStickersFavedLimitOld = 0x50, dbiSuggestStickersByEmojiOld = 0x51, dbiSuggestEmojiOld = 0x52, - dbiTxtDomainStringOld = 0x53, + dbiTxtDomainStringOldOld = 0x53, dbiThemeKey = 0x54, dbiTileBackground = 0x55, dbiCacheSettingsOld = 0x56, @@ -146,9 +156,10 @@ enum { dbiLanguagesKey = 0x5a, dbiCallSettings = 0x5b, dbiCacheSettings = 0x5c, - dbiTxtDomainString = 0x5d, + dbiTxtDomainStringOld = 0x5d, dbiApplicationSettings = 0x5e, dbiDialogsFilters = 0x5f, + dbiFallbackProductionConfig = 0x60, dbiEncryptedWithSalt = 333, dbiEncrypted = 444, diff --git a/Telegram/SourceFiles/storage/download_manager_mtproto.cpp b/Telegram/SourceFiles/storage/download_manager_mtproto.cpp index 621ec8e00..4dadef241 100644 --- a/Telegram/SourceFiles/storage/download_manager_mtproto.cpp +++ b/Telegram/SourceFiles/storage/download_manager_mtproto.cpp @@ -119,7 +119,7 @@ DownloadManagerMtproto::DownloadManagerMtproto(not_null api) : _api(api) , _resetGenerationTimer([=] { resetGeneration(); }) , _killSessionsTimer([=] { killSessions(); }) { - _api->instance()->restartsByTimeout( + _api->instance().restartsByTimeout( ) | rpl::filter([](MTP::ShiftedDcId shiftedDcId) { return MTP::isDownloadDcId(shiftedDcId); }) | rpl::start_with_next([=](MTP::ShiftedDcId shiftedDcId) { @@ -353,7 +353,7 @@ void DownloadManagerMtproto::removeSession(MTP::DcId dcId) { Assert(session.requested == kMaxWaitedInSession * kMaxSessionsCount); dc.sessions.pop_back(); - api().instance()->killSession(MTP::downloadDcId(dcId, index)); + api().instance().killSession(MTP::downloadDcId(dcId, index)); dc.lastSessionRemove = crl::now(); } @@ -403,7 +403,7 @@ void DownloadManagerMtproto::killSessions(MTP::DcId dcId) { for (auto j = 0; j != int(sessions.size()); ++j) { Assert(sessions[j].requested == 0); sessions[j] = DcSessionBalanceData(); - api().instance()->stopSession(MTP::downloadDcId(dcId, j)); + api().instance().stopSession(MTP::downloadDcId(dcId, j)); } dc.sessions = base::take(sessions); } diff --git a/Telegram/SourceFiles/storage/file_download_mtproto.cpp b/Telegram/SourceFiles/storage/file_download_mtproto.cpp index fccedf0af..02098d83b 100644 --- a/Telegram/SourceFiles/storage/file_download_mtproto.cpp +++ b/Telegram/SourceFiles/storage/file_download_mtproto.cpp @@ -13,9 +13,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_session.h" #include "apiwrap.h" #include "mtproto/mtp_instance.h" +#include "mtproto/mtproto_config.h" #include "mtproto/mtproto_auth_key.h" #include "base/openssl_help.h" -#include "facades.h" mtpFileLoader::mtpFileLoader( not_null session, @@ -58,7 +58,7 @@ mtpFileLoader::mtpFileLoader( cacheTag) , DownloadMtprotoTask( &session->downloader(), - Global::WebFileDcId(), + session->serverConfig().webFileDcId, { location }) { } @@ -80,7 +80,7 @@ mtpFileLoader::mtpFileLoader( cacheTag) , DownloadMtprotoTask( &session->downloader(), - Global::WebFileDcId(), + session->serverConfig().webFileDcId, { location }) { } diff --git a/Telegram/SourceFiles/storage/file_upload.cpp b/Telegram/SourceFiles/storage/file_upload.cpp index ea43f9335..ccaefa2c4 100644 --- a/Telegram/SourceFiles/storage/file_upload.cpp +++ b/Telegram/SourceFiles/storage/file_upload.cpp @@ -277,7 +277,7 @@ void Uploader::currentFailed() { void Uploader::stopSessions() { for (int i = 0; i < MTP::kUploadSessionsCount; ++i) { - _api->instance()->stopSession(MTP::uploadDcId(i)); + _api->instance().stopSession(MTP::uploadDcId(i)); } } @@ -524,7 +524,7 @@ void Uploader::clear() { dcMap.clear(); sentSize = 0; for (int i = 0; i < MTP::kUploadSessionsCount; ++i) { - _api->instance()->stopSession(MTP::uploadDcId(i)); + _api->instance().stopSession(MTP::uploadDcId(i)); sentSizes[i] = 0; } stopSessionsTimer.stop(); diff --git a/Telegram/SourceFiles/storage/localstorage.cpp b/Telegram/SourceFiles/storage/localstorage.cpp index 9af3578de..9d88cd77e 100644 --- a/Telegram/SourceFiles/storage/localstorage.cpp +++ b/Telegram/SourceFiles/storage/localstorage.cpp @@ -18,8 +18,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/effects/animation_value.h" #include "core/update_checker.h" #include "media/audio/media_audio.h" -#include "mtproto/dc_options.h" +#include "mtproto/mtproto_config.h" +#include "mtproto/mtproto_dc_options.h" #include "core/application.h" +#include "main/main_accounts.h" +#include "main/main_account.h" #include "main/main_session.h" #include "window/themes/window_theme.h" #include "facades.h" @@ -52,18 +55,6 @@ QString _basePath, _userBasePath, _userDbPath; bool _started = false; TaskQueue *_localLoader = nullptr; -bool _working() { - return !_basePath.isEmpty(); -} - -bool CheckStreamStatus(QDataStream &stream) { - if (stream.status() != QDataStream::Ok) { - LOG(("Bad data stream status: %1").arg(stream.status())); - return false; - } - return true; -} - QByteArray _settingsSalt; auto OldKey = MTP::AuthKeyPtr(); @@ -87,8 +78,44 @@ enum class WriteMapWhen { Soon, }; +bool _working() { + return !_basePath.isEmpty(); +} + +bool CheckStreamStatus(QDataStream &stream) { + if (stream.status() != QDataStream::Ok) { + LOG(("Bad data stream status: %1").arg(stream.status())); + return false; + } + return true; +} + +[[nodiscard]] const MTP::Config &LookupFallbackConfig() { + static const auto lookupConfig = [](not_null account) { + const auto mtp = &account->mtp(); + return (mtp->environment() == MTP::Environment::Production) + ? &mtp->config() + : nullptr; + }; + const auto &app = Core::App(); + const auto &accounts = app.accounts(); + const auto production = MTP::Environment::Production; + if (!accounts.started()) { + return app.fallbackProductionConfig(); + } + if (const auto result = lookupConfig(&app.activeAccount())) { + return *result; + } + for (const auto &[_, account] : accounts.list()) { + if (const auto result = lookupConfig(account.get())) { + return *result; + } + } + return app.fallbackProductionConfig(); +} + void applyReadContext(ReadSettingsContext &&context) { - Core::App().dcOptions()->addFromOther(std::move(context.dcOptions)); + ApplyReadFallbackConfig(context); _themeKeyLegacy = context.themeKeyLegacy; _themeKeyDay = context.themeKeyDay; @@ -195,7 +222,10 @@ void _readOldUserSettingsFields( bool _readOldUserSettings(bool remove, ReadSettingsContext &context) { bool result = false; - QFile file(cWorkingDir() + cDataFile() + (cTestMode() ? qsl("_test") : QString()) + qsl("_config")); + // We dropped old test authorizations when migrated to multi auth. + //const auto testPrefix = (cTestMode() ? qsl("_test") : QString()); + const auto testPrefix = QString(); + QFile file(cWorkingDir() + cDataFile() + testPrefix + qsl("_config")); if (file.open(QIODevice::ReadOnly)) { LOG(("App Info: reading old user config...")); qint32 version = 0; @@ -273,7 +303,9 @@ void _readOldMtpDataFields( bool _readOldMtpData(bool remove, ReadSettingsContext &context) { bool result = false; - const auto testPostfix = (cTestMode() ? qsl("_test") : QString()); + // We dropped old test authorizations when migrated to multi auth. + //const auto testPostfix = (cTestMode() ? qsl("_test") : QString()); + const auto testPostfix = QString(); QFile file(cWorkingDir() + cDataFile() + testPostfix); if (file.open(QIODevice::ReadOnly)) { LOG(("App Info: reading old keys...")); @@ -306,7 +338,10 @@ void start() { ReadSettingsContext context; FileReadDescriptor settingsData; - if (!ReadFile(settingsData, cTestMode() ? qsl("settings_test") : qsl("settings"), _basePath)) { + // We dropped old test authorizations when migrated to multi auth. + //const auto name = cTestMode() ? qsl("settings_test") : qsl("settings"); + const auto name = u"settings"_q; + if (!ReadFile(settingsData, name, _basePath)) { _readOldSettings(true, context); _readOldUserSettings(false, context); // needed further in _readUserSettings _readOldMtpData(false, context); // needed further in _readMtpData @@ -367,9 +402,10 @@ void writeSettings() { if (!QDir().exists(_basePath)) QDir().mkpath(_basePath); - FileWriteDescriptor settings( - cTestMode() ? qsl("settings_test") : qsl("settings"), - _basePath); + // We dropped old test authorizations when migrated to multi auth. + //const auto name = cTestMode() ? qsl("settings_test") : qsl("settings"); + const auto name = u"settings"_q; + FileWriteDescriptor settings(name, _basePath); if (_settingsSalt.isEmpty() || !SettingsKey) { _settingsSalt.resize(LocalEncryptSaltSize); memset_rand(_settingsSalt.data(), _settingsSalt.size()); @@ -377,13 +413,12 @@ void writeSettings() { } settings.writeData(_settingsSalt); - const auto dcOptionsSerialized = Core::App().dcOptions()->serialize(); + const auto configSerialized = LookupFallbackConfig().serialize(); const auto applicationSettings = Core::App().settings().serialize(); - quint32 size = 12 * (sizeof(quint32) + sizeof(qint32)); - size += sizeof(quint32) + Serialize::bytearraySize(dcOptionsSerialized); + quint32 size = 9 * (sizeof(quint32) + sizeof(qint32)); + size += sizeof(quint32) + Serialize::bytearraySize(configSerialized); size += sizeof(quint32) + Serialize::bytearraySize(applicationSettings); - size += sizeof(quint32) + Serialize::stringSize(Global::TxtDomainString()); size += sizeof(quint32) + Serialize::stringSize(cDialogLastPath()); auto &proxies = Global::RefProxiesList(); @@ -407,11 +442,6 @@ void writeSettings() { size += sizeof(quint32) + sizeof(qint32) * 8; EncryptedDescriptor data(size); - data.stream << quint32(dbiChatSizeMax) << qint32(Global::ChatSizeMax()); - data.stream << quint32(dbiMegagroupSizeMax) << qint32(Global::MegagroupSizeMax()); - data.stream << quint32(dbiSavedGifsLimit) << qint32(Global::SavedGifsLimit()); - data.stream << quint32(dbiStickersRecentLimit) << qint32(Global::StickersRecentLimit()); - data.stream << quint32(dbiStickersFavedLimit) << qint32(Global::StickersFavedLimit()); data.stream << quint32(dbiAutoStart) << qint32(cAutoStart()); data.stream << quint32(dbiStartMinimized) << qint32(cStartMinimized()); data.stream << quint32(dbiSendToMenu) << qint32(cSendToMenu()); @@ -420,9 +450,8 @@ void writeSettings() { data.stream << quint32(dbiAutoUpdate) << qint32(cAutoUpdate()); data.stream << quint32(dbiLastUpdateCheck) << qint32(cLastUpdateCheck()); data.stream << quint32(dbiScalePercent) << qint32(cConfigScale()); - data.stream << quint32(dbiDcOptions) << dcOptionsSerialized; + data.stream << quint32(dbiFallbackProductionConfig) << configSerialized; data.stream << quint32(dbiApplicationSettings) << applicationSettings; - data.stream << quint32(dbiTxtDomainString) << Global::TxtDomainString(); data.stream << quint32(dbiDialogLastPath) << cDialogLastPath(); data.stream << quint32(dbiAnimationsDisabled) << qint32(anim::Disabled() ? 1 : 0); diff --git a/Telegram/SourceFiles/storage/serialize_common.cpp b/Telegram/SourceFiles/storage/serialize_common.cpp index 93f249ba8..d3f7ec8ad 100644 --- a/Telegram/SourceFiles/storage/serialize_common.cpp +++ b/Telegram/SourceFiles/storage/serialize_common.cpp @@ -7,20 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "storage/serialize_common.h" -#include "main/main_session.h" -#include "data/data_channel.h" -#include "data/data_chat.h" -#include "data/data_user.h" -#include "data/data_session.h" -#include "ui/image/image.h" -#include "app.h" - namespace Serialize { -namespace { - -constexpr auto kModernImageLocationTag = std::numeric_limits::min(); - -} // namespace void writeColor(QDataStream &stream, const QColor &color) { stream << (quint32(uchar(color.red())) @@ -39,323 +26,4 @@ QColor readColor(QDataStream &stream) { int((value >> 24) & 0xFFU)); } -std::optional readLegacyStorageImageLocationOrTag( - int streamAppVersion, - QDataStream &stream) { - qint32 width, height, dc, local; - quint64 volume, secret; - QByteArray fileReference; - stream >> width; - if (width == kModernImageLocationTag) { - return std::nullopt; - } - stream >> height >> dc >> volume >> local >> secret; - if (streamAppVersion >= 1003013) { - stream >> fileReference; - } - if (stream.status() != QDataStream::Ok) { - return std::nullopt; - } - return StorageImageLocation( - StorageFileLocation( - dc, - UserId(0), - MTP_inputFileLocation( - MTP_long(volume), - MTP_int(local), - MTP_long(secret), - MTP_bytes(fileReference))), - width, - height); -} - -int storageImageLocationSize(const StorageImageLocation &location) { - // Modern image location tag + (size + content) of the serialization. - return sizeof(qint32) * 2 + location.serializeSize(); -} - -void writeStorageImageLocation( - QDataStream &stream, - const StorageImageLocation &location) { - stream << kModernImageLocationTag << location.serialize(); -} - -std::optional readStorageImageLocation( - int streamAppVersion, - QDataStream &stream) { - const auto legacy = readLegacyStorageImageLocationOrTag( - streamAppVersion, - stream); - if (legacy) { - return legacy; - } - auto serialized = QByteArray(); - stream >> serialized; - return (stream.status() == QDataStream::Ok) - ? StorageImageLocation::FromSerialized(serialized) - : std::nullopt; -} - -int imageLocationSize(const ImageLocation &location) { - // Modern image location tag + (size + content) of the serialization. - return sizeof(qint32) * 2 + location.serializeSize(); -} - -void writeImageLocation(QDataStream &stream, const ImageLocation &location) { - stream << kModernImageLocationTag << location.serialize(); -} - -std::optional readImageLocation( - int streamAppVersion, - QDataStream &stream) { - const auto legacy = readLegacyStorageImageLocationOrTag( - streamAppVersion, - stream); - if (legacy) { - return ImageLocation( - DownloadLocation{ legacy->file() }, - legacy->width(), - legacy->height()); - } - auto serialized = QByteArray(); - stream >> serialized; - return (stream.status() == QDataStream::Ok) - ? ImageLocation::FromSerialized(serialized) - : std::nullopt; -} - -uint32 peerSize(not_null peer) { - uint32 result = sizeof(quint64) - + sizeof(quint64) - + imageLocationSize(peer->userpicLocation()); - if (peer->isUser()) { - UserData *user = peer->asUser(); - - // first + last + phone + username + access - result += stringSize(user->firstName) + stringSize(user->lastName) + stringSize(user->phone()) + stringSize(user->username) + sizeof(quint64); - - // flags - if (AppVersion >= 9012) { - result += sizeof(qint32); - } - - // onlineTill + contact + botInfoVersion - result += sizeof(qint32) + sizeof(qint32) + sizeof(qint32); - } else if (peer->isChat()) { - ChatData *chat = peer->asChat(); - - // name + count + date + version + admin + old forbidden + left + inviteLink - result += stringSize(chat->name) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(quint32) + stringSize(chat->inviteLink()); - } else if (peer->isChannel()) { - ChannelData *channel = peer->asChannel(); - - // name + access + date + version + old forbidden + flags + inviteLink - result += stringSize(channel->name) + sizeof(quint64) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(quint32) + stringSize(channel->inviteLink()); - } - return result; -} - -void writePeer(QDataStream &stream, PeerData *peer) { - stream << quint64(peer->id) << quint64(peer->userpicPhotoId()); - writeImageLocation(stream, peer->userpicLocation()); - if (const auto user = peer->asUser()) { - stream - << user->firstName - << user->lastName - << user->phone() - << user->username - << quint64(user->accessHash()); - if (AppVersion >= 9012) { - stream << qint32(user->flags()); - } - if (AppVersion >= 9016) { - const auto botInlinePlaceholder = user->isBot() - ? user->botInfo->inlinePlaceholder - : QString(); - stream << botInlinePlaceholder; - } - stream - << qint32(user->onlineTill) - << qint32(user->isContact() ? 1 : 0) - << qint32(user->isBot() ? user->botInfo->version : -1); - } else if (const auto chat = peer->asChat()) { - stream - << chat->name - << qint32(chat->count) - << qint32(chat->date) - << qint32(chat->version()) - << qint32(chat->creator) - << qint32(0) - << quint32(chat->flags()) - << chat->inviteLink(); - } else if (const auto channel = peer->asChannel()) { - stream - << channel->name - << quint64(channel->access) - << qint32(channel->date) - << qint32(channel->version()) - << qint32(0) - << quint32(channel->flags()) - << channel->inviteLink(); - } -} - -PeerData *readPeer( - not_null session, - int streamAppVersion, - QDataStream &stream) { - quint64 peerId = 0, photoId = 0; - stream >> peerId >> photoId; - if (!peerId) { - return nullptr; - } - - const auto userpic = readImageLocation(streamAppVersion, stream); - auto userpicAccessHash = uint64(0); - if (!userpic) { - return nullptr; - } - - const auto selfId = session->userPeerId(); - const auto loaded = (peerId == selfId) - ? session->user().get() - : session->data().peerLoaded(peerId); - const auto result = loaded ? loaded : session->data().peer(peerId).get(); - if (!loaded) { - result->loadedStatus = PeerData::FullLoaded; - } - if (const auto user = result->asUser()) { - QString first, last, phone, username, inlinePlaceholder; - quint64 access; - qint32 flags = 0, onlineTill, contact, botInfoVersion; - stream >> first >> last >> phone >> username >> access; - if (streamAppVersion >= 9012) { - stream >> flags; - } - if (streamAppVersion >= 9016) { - stream >> inlinePlaceholder; - } - stream >> onlineTill >> contact >> botInfoVersion; - - userpicAccessHash = access; - - const auto showPhone = !user->isServiceUser() - && (user->id != selfId) - && (contact <= 0); - const auto pname = (showPhone && !phone.isEmpty()) - ? App::formatPhone(phone) - : QString(); - - if (!loaded) { - user->setPhone(phone); - user->setName(first, last, pname, username); - - user->setFlags(MTPDuser::Flags::from_raw(flags)); - user->setAccessHash(access); - user->onlineTill = onlineTill; - user->setIsContact(contact == 1); - user->setBotInfoVersion(botInfoVersion); - if (!inlinePlaceholder.isEmpty() && user->isBot()) { - user->botInfo->inlinePlaceholder = inlinePlaceholder; - } - - if (user->id == selfId) { - user->input = MTP_inputPeerSelf(); - user->inputUser = MTP_inputUserSelf(); - } else { - user->input = MTP_inputPeerUser(MTP_int(peerToUser(user->id)), MTP_long(user->accessHash())); - user->inputUser = MTP_inputUser(MTP_int(peerToUser(user->id)), MTP_long(user->accessHash())); - } - } - } else if (const auto chat = result->asChat()) { - QString name, inviteLink; - qint32 count, date, version, creator, oldForbidden; - quint32 flagsData, flags; - stream >> name >> count >> date >> version >> creator >> oldForbidden >> flagsData >> inviteLink; - - if (streamAppVersion >= 9012) { - flags = flagsData; - } else { - // flagsData was haveLeft - flags = (flagsData == 1) - ? MTPDchat::Flags(MTPDchat::Flag::f_left) - : MTPDchat::Flags(0); - } - if (oldForbidden) { - flags |= quint32(MTPDchat_ClientFlag::f_forbidden); - } - if (!loaded) { - chat->setName(name); - chat->count = count; - chat->date = date; - - // We don't save participants, admin status and banned rights. - // So we don't restore the version field, info is still unknown. - chat->setVersion(0); - - chat->creator = creator; - chat->setFlags(MTPDchat::Flags::from_raw(flags)); - chat->setInviteLink(inviteLink); - - chat->input = MTP_inputPeerChat(MTP_int(peerToChat(chat->id))); - chat->inputChat = MTP_int(peerToChat(chat->id)); - } - } else if (const auto channel = result->asChannel()) { - QString name, inviteLink; - quint64 access; - qint32 date, version, oldForbidden; - quint32 flags; - stream >> name >> access >> date >> version >> oldForbidden >> flags >> inviteLink; - - userpicAccessHash = access; - - if (oldForbidden) { - flags |= quint32(MTPDchannel_ClientFlag::f_forbidden); - } - if (!loaded) { - channel->setName(name, QString()); - channel->access = access; - channel->date = date; - - // We don't save participants, admin status and banned rights. - // So we don't restore the version field, info is still unknown. - channel->setVersion(0); - - channel->setFlags(MTPDchannel::Flags::from_raw(flags)); - channel->setInviteLink(inviteLink); - - channel->input = MTP_inputPeerChannel(MTP_int(peerToChannel(channel->id)), MTP_long(access)); - channel->inputChannel = MTP_inputChannel(MTP_int(peerToChannel(channel->id)), MTP_long(access)); - } - } - if (!loaded) { - using LocationType = StorageFileLocation::Type; - const auto location = (userpic->valid() && userpic->isLegacy()) - ? userpic->convertToModern( - LocationType::PeerPhoto, - result->id, - userpicAccessHash) - : *userpic; - result->setUserpic(photoId, location); - } - return result; -} - -QString peekUserPhone(int streamAppVersion, QDataStream &stream) { - quint64 peerId = 0, photoId = 0; - stream >> peerId >> photoId; - DEBUG_LOG(("peekUserPhone.id: %1").arg(peerId)); - if (!peerId - || !peerIsUser(peerId) - || !readStorageImageLocation(streamAppVersion, stream)) { - return QString(); - } - - QString first, last, phone; - stream >> first >> last >> phone; - DEBUG_LOG(("peekUserPhone.data: %1 %2 %3" - ).arg(first).arg(last).arg(phone)); - return phone; -} - } // namespace Serialize diff --git a/Telegram/SourceFiles/storage/serialize_common.h b/Telegram/SourceFiles/storage/serialize_common.h index 6db828ecf..fcf017185 100644 --- a/Telegram/SourceFiles/storage/serialize_common.h +++ b/Telegram/SourceFiles/storage/serialize_common.h @@ -8,6 +8,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #pragma once #include "mtproto/mtproto_auth_key.h" +#include "base/bytes.h" + +#include namespace Serialize { @@ -91,26 +94,6 @@ inline int dateTimeSize() { return (sizeof(qint64) + sizeof(quint32) + sizeof(qint8)); } -int storageImageLocationSize(const StorageImageLocation &location); -void writeStorageImageLocation( - QDataStream &stream, - const StorageImageLocation &location); - -// NB! This method can return StorageFileLocation with Type::Generic! -// The reader should discard it or convert to one of the valid modern types. -std::optional readStorageImageLocation( - int streamAppVersion, - QDataStream &stream); - -int imageLocationSize(const ImageLocation &location); -void writeImageLocation(QDataStream &stream, const ImageLocation &location); - -// NB! This method can return StorageFileLocation with Type::Generic! -// The reader should discard it or convert to one of the valid modern types. -std::optional readImageLocation( - int streamAppVersion, - QDataStream &stream); - template inline T read(QDataStream &stream) { auto result = T(); @@ -125,12 +108,4 @@ inline MTP::AuthKey::Data read(QDataStream &stream) { return result; } -uint32 peerSize(not_null peer); -void writePeer(QDataStream &stream, PeerData *peer); -PeerData *readPeer( - not_null session, - int streamAppVersion, - QDataStream &stream); -QString peekUserPhone(int streamAppVersion, QDataStream &stream); - } // namespace Serialize diff --git a/Telegram/SourceFiles/storage/serialize_document.cpp b/Telegram/SourceFiles/storage/serialize_document.cpp index e8fa97d61..34638982e 100644 --- a/Telegram/SourceFiles/storage/serialize_document.cpp +++ b/Telegram/SourceFiles/storage/serialize_document.cpp @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/serialize_document.h" #include "storage/serialize_common.h" +#include "storage/serialize_peer.h" #include "data/data_session.h" #include "data/stickers/data_stickers.h" #include "ui/image/image.h" diff --git a/Telegram/SourceFiles/storage/serialize_peer.cpp b/Telegram/SourceFiles/storage/serialize_peer.cpp new file mode 100644 index 000000000..e888b7cac --- /dev/null +++ b/Telegram/SourceFiles/storage/serialize_peer.cpp @@ -0,0 +1,345 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "storage/serialize_peer.h" + +#include "storage/serialize_common.h" +#include "main/main_session.h" +#include "data/data_channel.h" +#include "data/data_chat.h" +#include "data/data_user.h" +#include "data/data_session.h" +#include "ui/image/image.h" +#include "app.h" + +namespace Serialize { +namespace { + +constexpr auto kModernImageLocationTag = std::numeric_limits::min(); + +} // namespace + +std::optional readLegacyStorageImageLocationOrTag( + int streamAppVersion, + QDataStream &stream) { + qint32 width, height, dc, local; + quint64 volume, secret; + QByteArray fileReference; + stream >> width; + if (width == kModernImageLocationTag) { + return std::nullopt; + } + stream >> height >> dc >> volume >> local >> secret; + if (streamAppVersion >= 1003013) { + stream >> fileReference; + } + if (stream.status() != QDataStream::Ok) { + return std::nullopt; + } + return StorageImageLocation( + StorageFileLocation( + dc, + UserId(0), + MTP_inputFileLocation( + MTP_long(volume), + MTP_int(local), + MTP_long(secret), + MTP_bytes(fileReference))), + width, + height); +} + +int storageImageLocationSize(const StorageImageLocation &location) { + // Modern image location tag + (size + content) of the serialization. + return sizeof(qint32) * 2 + location.serializeSize(); +} + +void writeStorageImageLocation( + QDataStream &stream, + const StorageImageLocation &location) { + stream << kModernImageLocationTag << location.serialize(); +} + +std::optional readStorageImageLocation( + int streamAppVersion, + QDataStream &stream) { + const auto legacy = readLegacyStorageImageLocationOrTag( + streamAppVersion, + stream); + if (legacy) { + return legacy; + } + auto serialized = QByteArray(); + stream >> serialized; + return (stream.status() == QDataStream::Ok) + ? StorageImageLocation::FromSerialized(serialized) + : std::nullopt; +} + +int imageLocationSize(const ImageLocation &location) { + // Modern image location tag + (size + content) of the serialization. + return sizeof(qint32) * 2 + location.serializeSize(); +} + +void writeImageLocation(QDataStream &stream, const ImageLocation &location) { + stream << kModernImageLocationTag << location.serialize(); +} + +std::optional readImageLocation( + int streamAppVersion, + QDataStream &stream) { + const auto legacy = readLegacyStorageImageLocationOrTag( + streamAppVersion, + stream); + if (legacy) { + return ImageLocation( + DownloadLocation{ legacy->file() }, + legacy->width(), + legacy->height()); + } + auto serialized = QByteArray(); + stream >> serialized; + return (stream.status() == QDataStream::Ok) + ? ImageLocation::FromSerialized(serialized) + : std::nullopt; +} + +uint32 peerSize(not_null peer) { + uint32 result = sizeof(quint64) + + sizeof(quint64) + + imageLocationSize(peer->userpicLocation()); + if (peer->isUser()) { + UserData *user = peer->asUser(); + + // first + last + phone + username + access + result += stringSize(user->firstName) + stringSize(user->lastName) + stringSize(user->phone()) + stringSize(user->username) + sizeof(quint64); + + // flags + if (AppVersion >= 9012) { + result += sizeof(qint32); + } + + // onlineTill + contact + botInfoVersion + result += sizeof(qint32) + sizeof(qint32) + sizeof(qint32); + } else if (peer->isChat()) { + ChatData *chat = peer->asChat(); + + // name + count + date + version + admin + old forbidden + left + inviteLink + result += stringSize(chat->name) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(quint32) + stringSize(chat->inviteLink()); + } else if (peer->isChannel()) { + ChannelData *channel = peer->asChannel(); + + // name + access + date + version + old forbidden + flags + inviteLink + result += stringSize(channel->name) + sizeof(quint64) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(quint32) + stringSize(channel->inviteLink()); + } + return result; +} + +void writePeer(QDataStream &stream, PeerData *peer) { + stream << quint64(peer->id) << quint64(peer->userpicPhotoId()); + writeImageLocation(stream, peer->userpicLocation()); + if (const auto user = peer->asUser()) { + stream + << user->firstName + << user->lastName + << user->phone() + << user->username + << quint64(user->accessHash()); + if (AppVersion >= 9012) { + stream << qint32(user->flags()); + } + if (AppVersion >= 9016) { + const auto botInlinePlaceholder = user->isBot() + ? user->botInfo->inlinePlaceholder + : QString(); + stream << botInlinePlaceholder; + } + stream + << qint32(user->onlineTill) + << qint32(user->isContact() ? 1 : 0) + << qint32(user->isBot() ? user->botInfo->version : -1); + } else if (const auto chat = peer->asChat()) { + stream + << chat->name + << qint32(chat->count) + << qint32(chat->date) + << qint32(chat->version()) + << qint32(chat->creator) + << qint32(0) + << quint32(chat->flags()) + << chat->inviteLink(); + } else if (const auto channel = peer->asChannel()) { + stream + << channel->name + << quint64(channel->access) + << qint32(channel->date) + << qint32(channel->version()) + << qint32(0) + << quint32(channel->flags()) + << channel->inviteLink(); + } +} + +PeerData *readPeer( + not_null session, + int streamAppVersion, + QDataStream &stream) { + quint64 peerId = 0, photoId = 0; + stream >> peerId >> photoId; + if (!peerId) { + return nullptr; + } + + const auto userpic = readImageLocation(streamAppVersion, stream); + auto userpicAccessHash = uint64(0); + if (!userpic) { + return nullptr; + } + + const auto selfId = session->userPeerId(); + const auto loaded = (peerId == selfId) + ? session->user().get() + : session->data().peerLoaded(peerId); + const auto result = loaded ? loaded : session->data().peer(peerId).get(); + if (!loaded) { + result->loadedStatus = PeerData::FullLoaded; + } + if (const auto user = result->asUser()) { + QString first, last, phone, username, inlinePlaceholder; + quint64 access; + qint32 flags = 0, onlineTill, contact, botInfoVersion; + stream >> first >> last >> phone >> username >> access; + if (streamAppVersion >= 9012) { + stream >> flags; + } + if (streamAppVersion >= 9016) { + stream >> inlinePlaceholder; + } + stream >> onlineTill >> contact >> botInfoVersion; + + userpicAccessHash = access; + + const auto showPhone = !user->isServiceUser() + && (user->id != selfId) + && (contact <= 0); + const auto pname = (showPhone && !phone.isEmpty()) + ? App::formatPhone(phone) + : QString(); + + if (!loaded) { + user->setPhone(phone); + user->setName(first, last, pname, username); + + user->setFlags(MTPDuser::Flags::from_raw(flags)); + user->setAccessHash(access); + user->onlineTill = onlineTill; + user->setIsContact(contact == 1); + user->setBotInfoVersion(botInfoVersion); + if (!inlinePlaceholder.isEmpty() && user->isBot()) { + user->botInfo->inlinePlaceholder = inlinePlaceholder; + } + + if (user->id == selfId) { + user->input = MTP_inputPeerSelf(); + user->inputUser = MTP_inputUserSelf(); + } else { + user->input = MTP_inputPeerUser(MTP_int(peerToUser(user->id)), MTP_long(user->accessHash())); + user->inputUser = MTP_inputUser(MTP_int(peerToUser(user->id)), MTP_long(user->accessHash())); + } + } + } else if (const auto chat = result->asChat()) { + QString name, inviteLink; + qint32 count, date, version, creator, oldForbidden; + quint32 flagsData, flags; + stream >> name >> count >> date >> version >> creator >> oldForbidden >> flagsData >> inviteLink; + + if (streamAppVersion >= 9012) { + flags = flagsData; + } else { + // flagsData was haveLeft + flags = (flagsData == 1) + ? MTPDchat::Flags(MTPDchat::Flag::f_left) + : MTPDchat::Flags(0); + } + if (oldForbidden) { + flags |= quint32(MTPDchat_ClientFlag::f_forbidden); + } + if (!loaded) { + chat->setName(name); + chat->count = count; + chat->date = date; + + // We don't save participants, admin status and banned rights. + // So we don't restore the version field, info is still unknown. + chat->setVersion(0); + + chat->creator = creator; + chat->setFlags(MTPDchat::Flags::from_raw(flags)); + chat->setInviteLink(inviteLink); + + chat->input = MTP_inputPeerChat(MTP_int(peerToChat(chat->id))); + chat->inputChat = MTP_int(peerToChat(chat->id)); + } + } else if (const auto channel = result->asChannel()) { + QString name, inviteLink; + quint64 access; + qint32 date, version, oldForbidden; + quint32 flags; + stream >> name >> access >> date >> version >> oldForbidden >> flags >> inviteLink; + + userpicAccessHash = access; + + if (oldForbidden) { + flags |= quint32(MTPDchannel_ClientFlag::f_forbidden); + } + if (!loaded) { + channel->setName(name, QString()); + channel->access = access; + channel->date = date; + + // We don't save participants, admin status and banned rights. + // So we don't restore the version field, info is still unknown. + channel->setVersion(0); + + channel->setFlags(MTPDchannel::Flags::from_raw(flags)); + channel->setInviteLink(inviteLink); + + channel->input = MTP_inputPeerChannel(MTP_int(peerToChannel(channel->id)), MTP_long(access)); + channel->inputChannel = MTP_inputChannel(MTP_int(peerToChannel(channel->id)), MTP_long(access)); + } + } + if (!loaded) { + using LocationType = StorageFileLocation::Type; + const auto location = (userpic->valid() && userpic->isLegacy()) + ? userpic->convertToModern( + LocationType::PeerPhoto, + result->id, + userpicAccessHash) + : *userpic; + result->setUserpic(photoId, location); + } + return result; +} + +QString peekUserPhone(int streamAppVersion, QDataStream &stream) { + quint64 peerId = 0, photoId = 0; + stream >> peerId >> photoId; + DEBUG_LOG(("peekUserPhone.id: %1").arg(peerId)); + if (!peerId + || !peerIsUser(peerId) + || !readStorageImageLocation(streamAppVersion, stream)) { + return QString(); + } + + QString first, last, phone; + stream >> first >> last >> phone; + DEBUG_LOG(("peekUserPhone.data: %1 %2 %3" + ).arg(first).arg(last).arg(phone)); + return phone; +} + +} // namespace Serialize diff --git a/Telegram/SourceFiles/storage/serialize_peer.h b/Telegram/SourceFiles/storage/serialize_peer.h new file mode 100644 index 000000000..a56175c76 --- /dev/null +++ b/Telegram/SourceFiles/storage/serialize_peer.h @@ -0,0 +1,40 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +namespace Serialize { + +int storageImageLocationSize(const StorageImageLocation &location); +void writeStorageImageLocation( + QDataStream &stream, + const StorageImageLocation &location); + +// NB! This method can return StorageFileLocation with Type::Generic! +// The reader should discard it or convert to one of the valid modern types. +std::optional readStorageImageLocation( + int streamAppVersion, + QDataStream &stream); + +int imageLocationSize(const ImageLocation &location); +void writeImageLocation(QDataStream &stream, const ImageLocation &location); + +// NB! This method can return StorageFileLocation with Type::Generic! +// The reader should discard it or convert to one of the valid modern types. +std::optional readImageLocation( + int streamAppVersion, + QDataStream &stream); + +uint32 peerSize(not_null peer); +void writePeer(QDataStream &stream, PeerData *peer); +PeerData *readPeer( + not_null session, + int streamAppVersion, + QDataStream &stream); +QString peekUserPhone(int streamAppVersion, QDataStream &stream); + +} // namespace Serialize diff --git a/Telegram/SourceFiles/storage/storage_account.cpp b/Telegram/SourceFiles/storage/storage_account.cpp index 0f52c1e79..8daa289aa 100644 --- a/Telegram/SourceFiles/storage/storage_account.cpp +++ b/Telegram/SourceFiles/storage/storage_account.cpp @@ -15,10 +15,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/details/storage_file_utilities.h" #include "storage/details/storage_settings_scheme.h" #include "storage/serialize_common.h" +#include "storage/serialize_peer.h" #include "storage/serialize_document.h" #include "main/main_account.h" #include "main/main_session.h" -#include "mtproto/dc_options.h" +#include "mtproto/mtproto_config.h" +#include "mtproto/mtproto_dc_options.h" +#include "mtproto/mtp_instance.h" #include "history/history.h" #include "core/application.h" #include "data/stickers/data_stickers.h" @@ -80,7 +83,9 @@ enum { // Local Storage Keys }; [[nodiscard]] FileKey ComputeDataNameKey(const QString &dataName) { - const auto testAddition = (cTestMode() ? qsl(":/test/") : QString()); + // We dropped old test authorizations when migrated to multi auth. + //const auto testAddition = (cTestMode() ? qsl(":/test/") : QString()); + const auto testAddition = QString(); const auto dataNameUtf8 = (dataName + testAddition).toUtf8(); FileKey dataNameHash[2] = { 0 }; hashMd5(dataNameUtf8.constData(), dataNameUtf8.size(), dataNameHash); @@ -94,7 +99,8 @@ enum { // Local Storage Keys [[nodiscard]] QString ComputeDatabasePath(const QString &dataName) { return BaseGlobalPath() + "user_" + dataName - + (cTestMode() ? "[test]" : "") + // We dropped old test authorizations when migrated to multi auth. + //+ (cTestMode() ? "[test]" : "") + '/'; } @@ -131,12 +137,13 @@ StartResult Account::legacyStart(const QByteArray &passcode) { return StartResult::Success; } -void Account::start(MTP::AuthKeyPtr localKey) { +std::unique_ptr Account::start(MTP::AuthKeyPtr localKey) { Expects(localKey != nullptr); _localKey = std::move(localKey); readMapWith(_localKey); clearLegacyFiles(); + return readMtpConfig(); } void Account::startAdded(MTP::AuthKeyPtr localKey) { @@ -173,7 +180,12 @@ base::flat_set Account::collectGoodNames() const { _exportSettingsKey, _trustedBotsKey, }; - auto result = base::flat_set{ "map0", "map1", "maps" }; + auto result = base::flat_set{ + "map0", + "map1", + "maps", + "configs", + }; const auto push = [&](FileKey key) { if (!key) { return; @@ -549,7 +561,8 @@ void Account::reset() { for (const auto &name : names) { if (!name.endsWith(qstr("map0")) && !name.endsWith(qstr("map1")) - && !name.endsWith(qstr("maps"))) { + && !name.endsWith(qstr("maps")) + && !name.endsWith(qstr("configs"))) { QFile::remove(base + name); } } @@ -878,7 +891,7 @@ std::unique_ptr Account::readSettings() { std::unique_ptr Account::applyReadContext( ReadSettingsContext &&context) { - Core::App().dcOptions()->addFromOther(std::move(context.dcOptions)); + ApplyReadFallbackConfig(context); _cacheTotalSizeLimit = context.cacheTotalSizeLimit; _cacheTotalTimeLimit = context.cacheTotalTimeLimit; @@ -908,18 +921,14 @@ std::unique_ptr Account::applyReadContext( } void Account::writeMtpData() { + Expects(_localKey != nullptr); + + const auto serialized = _owner->serializeMtpAuthorization(); + const auto size = sizeof(quint32) + Serialize::bytearraySize(serialized); + FileWriteDescriptor mtp(ToFilePart(_dataNameKey), BaseGlobalPath()); - if (!_localKey) { - LOG(("App Error: localkey not created in _writeMtpData()")); - return; - } - - auto mtpAuthorizationSerialized = _owner->serializeMtpAuthorization(); - - quint32 size = sizeof(quint32) + Serialize::bytearraySize(mtpAuthorizationSerialized); - EncryptedDescriptor data(size); - data.stream << quint32(dbiMtpAuthorization) << mtpAuthorizationSerialized; + data.stream << quint32(dbiMtpAuthorization) << serialized; mtp.writeEncrypted(data, _localKey); } @@ -951,6 +960,35 @@ void Account::readMtpData() { applyReadContext(std::move(context)); } +void Account::writeMtpConfig() { + Expects(_localKey != nullptr); + + const auto serialized = _owner->mtp().config().serialize(); + const auto size = Serialize::bytearraySize(serialized); + + FileWriteDescriptor file(u"config"_q, _basePath); + EncryptedDescriptor data(size); + data.stream << serialized; + file.writeEncrypted(data, _localKey); +} + +std::unique_ptr Account::readMtpConfig() { + Expects(_localKey != nullptr); + + FileReadDescriptor file; + if (!ReadEncryptedFile(file, "config", _basePath, _localKey)) { + return nullptr; + } + + LOG(("App Info: reading encrypted mtp config...")); + auto serialized = QByteArray(); + file.stream >> serialized; + if (!CheckStreamStatus(file.stream)) { + return nullptr; + } + return MTP::Config::FromSerialized(serialized); +} + void Account::writeDrafts(not_null history) { Storage::MessageDraft storedLocalDraft, storedEditDraft; MessageCursor localCursor, editCursor; @@ -1846,7 +1884,9 @@ void Account::importOldRecentStickers() { custom->stickers.push_back(doc); ++custom->count; } - if (recent.size() < Global::StickersRecentLimit() && qAbs(value) > 1) { + if (qAbs(value) > 1 + && (recent.size() + < _owner->session().serverConfig().stickersRecentLimit)) { recent.push_back(qMakePair(doc, qAbs(value))); } } diff --git a/Telegram/SourceFiles/storage/storage_account.h b/Telegram/SourceFiles/storage/storage_account.h index 25bd282c3..dfe18aa56 100644 --- a/Telegram/SourceFiles/storage/storage_account.h +++ b/Telegram/SourceFiles/storage/storage_account.h @@ -28,6 +28,7 @@ class WallPaper; } // namespace Data namespace MTP { +class Config; class AuthKey; using AuthKeyPtr = std::shared_ptr; } // namespace MTP @@ -55,7 +56,8 @@ public: ~Account(); [[nodiscard]] StartResult legacyStart(const QByteArray &passcode); - void start(MTP::AuthKeyPtr localKey); + [[nodiscartd]] std::unique_ptr start( + MTP::AuthKeyPtr localKey); void startAdded(MTP::AuthKeyPtr localKey); [[nodiscard]] int oldMapVersion() const { return _oldMapVersion; @@ -67,6 +69,7 @@ public: void writeSettings(); void writeMtpData(); + void writeMtpConfig(); void writeBackground(const Data::WallPaper &paper, const QImage &image); bool readBackground(); @@ -172,6 +175,7 @@ private: std::unique_ptr readSettings(); void writeSettings(Main::Settings *stored); + std::unique_ptr readMtpConfig(); void readMtpData(); std::unique_ptr applyReadContext( details::ReadSettingsContext &&context); diff --git a/Telegram/SourceFiles/storage/storage_accounts.cpp b/Telegram/SourceFiles/storage/storage_accounts.cpp index a2daa9787..09e06bf91 100644 --- a/Telegram/SourceFiles/storage/storage_accounts.cpp +++ b/Telegram/SourceFiles/storage/storage_accounts.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/details/storage_file_utilities.h" #include "storage/serialize_common.h" +#include "mtproto/mtproto_config.h" #include "main/main_accounts.h" #include "main/main_account.h" #include "facades.h" @@ -25,11 +26,15 @@ constexpr auto kMaxAccounts = 3; } [[nodiscard]] QString ComputeKeyName(const QString &dataName) { - return "key_" + dataName + (cTestMode() ? "[test]" : ""); + // We dropped old test authorizations when migrated to multi auth. + //return "key_" + dataName + (cTestMode() ? "[test]" : ""); + return "key_" + dataName; } [[nodiscard]] QString ComputeInfoName(const QString &dataName) { - return "info_" + dataName + (cTestMode() ? "[test]" : ""); + // We dropped old test authorizations when migrated to multi auth. + //return "info_" + dataName + (cTestMode() ? "[test]" : ""); + return "info_" + dataName; } } // namespace @@ -63,10 +68,12 @@ StartResult Accounts::start(const QByteArray &passcode) { return result; } -void Accounts::startAdded(not_null account) { +void Accounts::startAdded( + not_null account, + std::unique_ptr config) { Expects(_localKey != nullptr); - account->startAdded(_localKey); + account->startAdded(_localKey, std::move(config)); } void Accounts::startWithSingleAccount( diff --git a/Telegram/SourceFiles/storage/storage_accounts.h b/Telegram/SourceFiles/storage/storage_accounts.h index 3926bfd46..9434f8a67 100644 --- a/Telegram/SourceFiles/storage/storage_accounts.h +++ b/Telegram/SourceFiles/storage/storage_accounts.h @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #pragma once namespace MTP { +class Config; class AuthKey; using AuthKeyPtr = std::shared_ptr; } // namespace MTP @@ -30,7 +31,9 @@ public: ~Accounts(); [[nodiscard]] StartResult start(const QByteArray &passcode); - void startAdded(not_null account); + void startAdded( + not_null account, + std::unique_ptr config); void writeAccounts(); void startFromScratch(); diff --git a/Telegram/SourceFiles/support/support_helper.cpp b/Telegram/SourceFiles/support/support_helper.cpp index 174257a39..b86152ca3 100644 --- a/Telegram/SourceFiles/support/support_helper.cpp +++ b/Telegram/SourceFiles/support/support_helper.cpp @@ -289,7 +289,7 @@ TimeId OccupiedBySomeoneTill(History *history) { Helper::Helper(not_null session) : _session(session) -, _api(_session->mtp()) +, _api(&_session->mtp()) , _templates(_session) , _reoccupyTimer([=] { reoccupy(); }) , _checkOccupiedTimer([=] { checkOccupiedChats(); }) { diff --git a/Telegram/SourceFiles/ui/special_fields.cpp b/Telegram/SourceFiles/ui/special_fields.cpp index c7973ca59..5631b426d 100644 --- a/Telegram/SourceFiles/ui/special_fields.cpp +++ b/Telegram/SourceFiles/ui/special_fields.cpp @@ -225,10 +225,9 @@ UsernameInput::UsernameInput( const style::InputField &st, rpl::producer placeholder, const QString &val, - bool isLink) + const QString &linkPlaceholder) : MaskedInputField(parent, st, std::move(placeholder), val) { - setLinkPlaceholder( - isLink ? Core::App().createInternalLink(QString()) : QString()); + setLinkPlaceholder(linkPlaceholder); } void UsernameInput::setLinkPlaceholder(const QString &placeholder) { diff --git a/Telegram/SourceFiles/ui/special_fields.h b/Telegram/SourceFiles/ui/special_fields.h index 2306c8606..77f7c2de6 100644 --- a/Telegram/SourceFiles/ui/special_fields.h +++ b/Telegram/SourceFiles/ui/special_fields.h @@ -73,7 +73,7 @@ public: const style::InputField &st, rpl::producer placeholder, const QString &val, - bool isLink); + const QString &linkPlaceholder); void setLinkPlaceholder(const QString &placeholder); diff --git a/Telegram/SourceFiles/window/main_window.cpp b/Telegram/SourceFiles/window/main_window.cpp index 65fe7b4ec..195c67e5c 100644 --- a/Telegram/SourceFiles/window/main_window.cpp +++ b/Telegram/SourceFiles/window/main_window.cpp @@ -158,8 +158,6 @@ MainWindow::MainWindow(not_null controller) updateControlsGeometry(); }, _outdated->lifetime()); } - - _isActiveTimer.setCallback([this] { updateIsActive(0); }); } Main::Account &MainWindow::account() const { @@ -267,7 +265,7 @@ bool MainWindow::hideNoQuit() { } } else if (Platform::IsMac()) { closeWithoutDestroy(); - updateIsActive(Global::OfflineBlurTimeout()); + controller().updateIsActiveBlur(); updateGlobalMenu(); Ui::showChatsList(); return true; @@ -280,10 +278,7 @@ void MainWindow::clearWidgets() { updateGlobalMenu(); } -void MainWindow::updateIsActive(int timeout) { - if (timeout > 0) { - return _isActiveTimer.callOnce(timeout); - } +void MainWindow::updateIsActive() { _isActive = computeIsActive(); updateIsActiveHook(); } @@ -337,7 +332,11 @@ void MainWindow::init() { void MainWindow::handleStateChanged(Qt::WindowState state) { stateChangedHook(state); - updateIsActive((state == Qt::WindowMinimized) ? Global::OfflineBlurTimeout() : Global::OnlineFocusTimeout()); + if (state == Qt::WindowMinimized) { + controller().updateIsActiveBlur(); + } else { + controller().updateIsActiveFocus(); + } Core::App().updateNonIdle(); if (state == Qt::WindowMinimized && Global::WorkMode().value() == dbiwmTrayOnly) { minimizeToTray(); @@ -593,7 +592,7 @@ bool MainWindow::minimizeToTray() { if (App::quitting() || !hasTrayIcon()) return false; closeWithoutDestroy(); - updateIsActive(Global::OfflineBlurTimeout()); + controller().updateIsActiveBlur(); updateTrayMenu(); updateGlobalMenu(); showTrayTooltip(); diff --git a/Telegram/SourceFiles/window/main_window.h b/Telegram/SourceFiles/window/main_window.h index 3392bd9a5..43e28f728 100644 --- a/Telegram/SourceFiles/window/main_window.h +++ b/Telegram/SourceFiles/window/main_window.h @@ -51,7 +51,9 @@ public: void init(); HitTestResult hitTest(const QPoint &p) const; - void updateIsActive(int timeout); + + void updateIsActive(); + bool isActive() const { return _isActive; } @@ -195,7 +197,6 @@ private: QString _titleText; bool _isActive = false; - base::Timer _isActiveTimer; base::Observable _dragFinished; rpl::event_stream<> _leaveEvents; diff --git a/Telegram/SourceFiles/window/notifications_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp index c00167259..8902445b9 100644 --- a/Telegram/SourceFiles/window/notifications_manager.cpp +++ b/Telegram/SourceFiles/window/notifications_manager.cpp @@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/notifications_manager_default.h" #include "media/audio/media_audio_track.h" #include "media/audio/media_audio.h" +#include "mtproto/mtproto_config.h" #include "history/history.h" #include "history/history_item_components.h" //#include "history/feed/history_feed_section.h" // #feed @@ -121,13 +122,14 @@ void System::schedule(not_null item) { const auto t = base::unixtime::now(); const auto ms = crl::now(); const auto &updates = history->session().updates(); + const auto &config = history->session().serverConfig(); const bool isOnline = updates.lastWasOnline(); - const auto otherNotOld = ((cOtherOnline() * 1000LL) + Global::OnlineCloudTimeout() > t * 1000LL); + const auto otherNotOld = ((cOtherOnline() * 1000LL) + config.onlineCloudTimeout > t * 1000LL); const bool otherLaterThanMe = (cOtherOnline() * 1000LL + (ms - updates.lastSetOnline()) > t * 1000LL); if (!isOnline && otherNotOld && otherLaterThanMe) { - delay = Global::NotifyCloudDelay(); + delay = config.notifyCloudDelay; } else if (cOtherOnline() >= t) { - delay = Global::NotifyDefaultDelay(); + delay = config.notifyDefaultDelay; } auto when = ms + delay; diff --git a/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp b/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp index a28f14e59..71a8c09ce 100644 --- a/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp @@ -843,7 +843,7 @@ void SaveThemeBox( st::createThemeLink, rpl::single(qsl("link")), cloud.slug.isEmpty() ? GenerateSlug() : cloud.slug, - true); + window->account().session().createInternalLink(QString())); linkWrap->widthValue( ) | rpl::start_with_next([=](int width) { link->resize(width, link->height()); @@ -854,7 +854,7 @@ void SaveThemeBox( linkWrap->resize(linkWrap->width(), height); }, link->lifetime()); link->setLinkPlaceholder( - Core::App().createInternalLink(qsl("addtheme/"))); + window->account().session().createInternalLink(qsl("addtheme/"))); link->setPlaceholderHidden(false); link->setMaxLength(kMaxSlugSize); diff --git a/Telegram/SourceFiles/window/themes/window_themes_cloud_list.cpp b/Telegram/SourceFiles/window/themes/window_themes_cloud_list.cpp index a41fed61e..fa04fbd81 100644 --- a/Telegram/SourceFiles/window/themes/window_themes_cloud_list.cpp +++ b/Telegram/SourceFiles/window/themes/window_themes_cloud_list.cpp @@ -586,7 +586,7 @@ void CloudList::showMenu(Element &element) { if (const auto slug = element.theme.slug; !slug.isEmpty()) { _contextMenu->addAction(tr::lng_theme_share(tr::now), [=] { QGuiApplication::clipboard()->setText( - Core::App().createInternalLinkFull("addtheme/" + slug)); + _window->session().createInternalLinkFull("addtheme/" + slug)); Ui::Toast::Show(tr::lng_background_link_copied(tr::now)); }); } diff --git a/Telegram/SourceFiles/window/window_connecting_widget.cpp b/Telegram/SourceFiles/window/window_connecting_widget.cpp index a84b45df1..a735a9c3b 100644 --- a/Telegram/SourceFiles/window/window_connecting_widget.cpp +++ b/Telegram/SourceFiles/window/window_connecting_widget.cpp @@ -290,21 +290,19 @@ void ConnectionState::refreshState() { const auto state = [&]() -> State { const auto under = _widget && _widget->isOver(); const auto ready = (Checker().state() == Checker::State::Ready); - const auto mtp = _account->mtp() - ? _account->mtp()->dcstate() - : MTP::DisconnectedState; + const auto state = _account->mtp().dcstate(); const auto proxy = (Global::ProxySettings() == MTP::ProxyData::Settings::Enabled); - if (mtp == MTP::ConnectingState - || mtp == MTP::DisconnectedState - || (mtp < 0 && mtp > -600)) { + if (state == MTP::ConnectingState + || state == MTP::DisconnectedState + || (state < 0 && state > -600)) { return { State::Type::Connecting, proxy, under, ready }; - } else if (mtp < 0 - && mtp >= -kMinimalWaitingStateDuration + } else if (state < 0 + && state >= -kMinimalWaitingStateDuration && _state.type != State::Type::Waiting) { return { State::Type::Connecting, proxy, under, ready }; - } else if (mtp < 0) { - const auto wait = ((-mtp) / 1000) + 1; + } else if (state < 0) { + const auto wait = ((-state) / 1000) + 1; return { State::Type::Waiting, proxy, under, ready, wait }; } return { State::Type::Connected, proxy, under, ready }; @@ -617,9 +615,7 @@ void ConnectionState::Widget::refreshRetryLink(bool hasRetry) { tr::lng_reconnecting_try_now(tr::now), st::connectingRetryLink); _retry->addClickHandler([=] { - if (const auto mtproto = _account->mtp()) { - mtproto->restart(); - } + _account->mtp().restart(); }); updateRetryGeometry(); } else if (!hasRetry) { diff --git a/Telegram/SourceFiles/window/window_controller.cpp b/Telegram/SourceFiles/window/window_controller.cpp index 8b05d6983..b906131ff 100644 --- a/Telegram/SourceFiles/window/window_controller.cpp +++ b/Telegram/SourceFiles/window/window_controller.cpp @@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_account.h" #include "main/main_accounts.h" #include "main/main_session.h" +#include "mtproto/mtproto_config.h" #include "ui/layers/box_content.h" #include "ui/layers/layer_widget.h" #include "ui/toast/toast.h" @@ -29,7 +30,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Window { Controller::Controller() -: _widget(this) { +: _widget(this) +, _isActiveTimer([=] { updateIsActive(); }) { _widget.init(); } @@ -143,8 +145,20 @@ void Controller::reActivate() { _widget.reActivateWindow(); } -void Controller::updateIsActive(int timeout) { - _widget.updateIsActive(timeout); +void Controller::updateIsActiveFocus() { + _isActiveTimer.callOnce(sessionController() + ? sessionController()->session().serverConfig().onlineFocusTimeout + : crl::time(1000)); +} + +void Controller::updateIsActiveBlur() { + _isActiveTimer.callOnce(sessionController() + ? sessionController()->session().serverConfig().offlineBlurTimeout + : crl::time(1000)); +} + +void Controller::updateIsActive() { + _widget.updateIsActive(); } void Controller::minimize() { diff --git a/Telegram/SourceFiles/window/window_controller.h b/Telegram/SourceFiles/window/window_controller.h index ec7a5493a..32401d17b 100644 --- a/Telegram/SourceFiles/window/window_controller.h +++ b/Telegram/SourceFiles/window/window_controller.h @@ -63,7 +63,9 @@ public: void activate(); void reActivate(); - void updateIsActive(int timeout); + void updateIsActiveFocus(); + void updateIsActiveBlur(); + void updateIsActive(); void minimize(); void close(); @@ -81,6 +83,7 @@ private: Main::Account *_account = nullptr; ::MainWindow _widget; std::unique_ptr _sessionController; + base::Timer _isActiveTimer; rpl::lifetime _accountLifetime; rpl::lifetime _lifetime; diff --git a/Telegram/SourceFiles/window/window_main_menu.cpp b/Telegram/SourceFiles/window/window_main_menu.cpp index 1d8cbe634..e87232633 100644 --- a/Telegram/SourceFiles/window/window_main_menu.cpp +++ b/Telegram/SourceFiles/window/window_main_menu.cpp @@ -28,12 +28,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "core/click_handler_types.h" #include "main/main_session.h" +#include "mtproto/mtproto_config.h" #include "data/data_folder.h" #include "data/data_session.h" #include "data/data_user.h" #include "data/data_changes.h" #include "mainwidget.h" -#include "facades.h" #include "app.h" #include "styles/style_window.h" #include "styles/style_dialogs.h" @@ -221,7 +221,11 @@ MainMenu::MainMenu( updatePhone(); }, lifetime()); - subscribe(Global::RefPhoneCallsEnabledChanged(), [this] { refreshMenu(); }); + _controller->session().serverConfig().phoneCallsEnabled.changes( + ) | rpl::start_with_next([=] { + refreshMenu(); + }, lifetime()); + subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) { if (update.type == Window::Theme::BackgroundUpdate::Type::ApplyingTheme) { refreshMenu(); @@ -261,7 +265,7 @@ void MainMenu::refreshMenu() { box->addLeftButton(tr::lng_profile_add_contact(), [] { App::wnd()->onShowAddContact(); }); })); }, &st::mainMenuContacts, &st::mainMenuContactsOver); - if (Global::PhoneCallsEnabled()) { + if (_controller->session().serverConfig().phoneCallsEnabled.current()) { _menu->addAction(tr::lng_menu_calls(tr::now), [=] { Ui::show(Box(std::make_unique(controller), [](not_null box) { box->addButton(tr::lng_close(), [=] { diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index f6c10bbc8..c6cf23534 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mainwindow.h" #include "api/api_common.h" #include "api/api_chat_filters.h" +#include "mtproto/mtproto_config.h" #include "history/history.h" #include "history/history_item.h" #include "history/history_message.h" // GetErrorTextForSending. @@ -49,7 +50,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_chat_filters.h" #include "dialogs/dialogs_key.h" #include "boxes/peers/edit_peer_info_box.h" -#include "facades.h" +#include "facades.h" // Adaptive::ThreeColumn #include "styles/style_layers.h" #include "styles/style_boxes.h" #include "styles/style_window.h" // st::windowMinWidth @@ -1011,7 +1012,8 @@ void PeerMenuAddChannelMembers( not_null navigation, not_null channel) { if (!channel->isMegagroup() - && channel->membersCount() >= Global::ChatSizeMax()) { + && (channel->membersCount() + >= channel->session().serverConfig().chatSizeMax)) { Ui::show( Box(channel), Ui::LayerOption::KeepOther); diff --git a/Telegram/cmake/lib_mtproto.cmake b/Telegram/cmake/lib_mtproto.cmake index 87a5f5f19..6ede5106f 100644 --- a/Telegram/cmake/lib_mtproto.cmake +++ b/Telegram/cmake/lib_mtproto.cmake @@ -39,6 +39,10 @@ PRIVATE mtproto/mtproto_auth_key.h mtproto/mtproto_concurrent_sender.cpp mtproto/mtproto_concurrent_sender.h + mtproto/mtproto_config.cpp + mtproto/mtproto_config.h + mtproto/mtproto_dc_options.cpp + mtproto/mtproto_dc_options.h mtproto/mtproto_dh_utils.cpp mtproto/mtproto_dh_utils.h mtproto/mtproto_proxy_data.cpp diff --git a/Telegram/lib_rpl b/Telegram/lib_rpl index 88ae67c59..6d6f69235 160000 --- a/Telegram/lib_rpl +++ b/Telegram/lib_rpl @@ -1 +1 @@ -Subproject commit 88ae67c59ab791084f43163d4484c9874003ac42 +Subproject commit 6d6f692354b1b1d7b3808a01cc3337175ea5213d