283 lines
8.9 KiB
C++
283 lines
8.9 KiB
C++
/*
|
|
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;
|
|
|
|
} // namespace
|
|
|
|
QString ConfigDefaultReactionEmoji() {
|
|
static const auto result = QString::fromUtf8("\xf0\x9f\x91\x8d");
|
|
return result;
|
|
}
|
|
|
|
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
|
|
+ Serialize::bytearraySize(options)
|
|
+ 19 * sizeof(qint32)
|
|
+ Serialize::stringSize(_fields.internalLinksDomain)
|
|
+ 6 * sizeof(qint32)
|
|
+ Serialize::stringSize(_fields.txtDomainString)
|
|
+ 3 * sizeof(qint32)
|
|
+ Serialize::stringSize(_fields.reactionDefaultEmoji)
|
|
+ sizeof(quint64);
|
|
|
|
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(0) // legacy savedGifsLimit
|
|
<< qint32(_fields.editTimeLimit)
|
|
<< qint32(_fields.revokeTimeLimit)
|
|
<< qint32(_fields.revokePrivateTimeLimit)
|
|
<< qint32(_fields.revokePrivateInbox ? 1 : 0)
|
|
<< qint32(_fields.stickersRecentLimit)
|
|
<< qint32(0) // legacy stickersFavedLimit
|
|
<< qint32(0) // legacy pinnedDialogsCountMax
|
|
<< qint32(0) // legacy pinnedDialogsInFolderMax
|
|
<< _fields.internalLinksDomain
|
|
<< qint32(_fields.channelsReadMediaPeriod)
|
|
<< qint32(_fields.callReceiveTimeoutMs)
|
|
<< qint32(_fields.callRingTimeoutMs)
|
|
<< qint32(_fields.callConnectTimeoutMs)
|
|
<< qint32(_fields.callPacketTimeoutMs)
|
|
<< qint32(_fields.webFileDcId)
|
|
<< _fields.txtDomainString
|
|
<< qint32(1) // legacy phoneCallsEnabled
|
|
<< qint32(_fields.blockedMode ? 1 : 0)
|
|
<< qint32(_fields.captionLengthMax)
|
|
<< _fields.reactionDefaultEmoji
|
|
<< quint64(_fields.reactionDefaultCustom);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
std::unique_ptr<Config> Config::FromSerialized(const QByteArray &serialized) {
|
|
auto result = std::unique_ptr<Config>();
|
|
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<Config>(Environment::Test);
|
|
break;
|
|
case qint32(Environment::Production):
|
|
result = std::make_unique<Config>(Environment::Production);
|
|
break;
|
|
}
|
|
if (!(raw = result.get())) {
|
|
return result;
|
|
}
|
|
|
|
auto dcOptionsSerialized = QByteArray();
|
|
auto legacySavedGifsLimit = int();
|
|
auto legacyStickersFavedLimit = int();
|
|
auto legacyPinnedDialogsCountMax = 0;
|
|
auto legacyPinnedDialogsInFolderMax = 0;
|
|
auto legacyPhoneCallsEnabled = rpl::variable<bool>();
|
|
const auto read = [&](auto &field) {
|
|
using Type = std::remove_reference_t<decltype(field)>;
|
|
if constexpr (std::is_same_v<Type, int>
|
|
|| std::is_same_v<Type, rpl::variable<int>>) {
|
|
auto value = qint32();
|
|
stream >> value;
|
|
field = value;
|
|
} else if constexpr (std::is_same_v<Type, uint64>) {
|
|
auto value = quint64();
|
|
stream >> value;
|
|
field = value;
|
|
} else if constexpr (std::is_same_v<Type, bool>
|
|
|| std::is_same_v<Type, rpl::variable<bool>>) {
|
|
auto value = qint32();
|
|
stream >> value;
|
|
field = (value == 1);
|
|
} else if constexpr (std::is_same_v<Type, QByteArray>
|
|
|| std::is_same_v<Type, QString>) {
|
|
stream >> field;
|
|
} else {
|
|
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(legacySavedGifsLimit);
|
|
read(raw->_fields.editTimeLimit);
|
|
read(raw->_fields.revokeTimeLimit);
|
|
read(raw->_fields.revokePrivateTimeLimit);
|
|
read(raw->_fields.revokePrivateInbox);
|
|
read(raw->_fields.stickersRecentLimit);
|
|
read(legacyStickersFavedLimit);
|
|
read(legacyPinnedDialogsCountMax);
|
|
read(legacyPinnedDialogsInFolderMax);
|
|
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(legacyPhoneCallsEnabled);
|
|
read(raw->_fields.blockedMode);
|
|
read(raw->_fields.captionLengthMax);
|
|
if (!stream.atEnd()) {
|
|
read(raw->_fields.reactionDefaultEmoji);
|
|
read(raw->_fields.reactionDefaultCustom);
|
|
}
|
|
|
|
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.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.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.blockedMode = data.is_blocked_mode();
|
|
_fields.captionLengthMax = data.vcaption_length_max().v;
|
|
_fields.reactionDefaultEmoji = ConfigDefaultReactionEmoji();
|
|
_fields.reactionDefaultCustom = 0;
|
|
if (const auto reaction = data.vreactions_default()) {
|
|
reaction->match([&](const MTPDreactionEmpty &) {
|
|
}, [&](const MTPDreactionEmoji &data) {
|
|
_fields.reactionDefaultEmoji = qs(data.vemoticon());
|
|
}, [&](const MTPDreactionCustomEmoji &data) {
|
|
_fields.reactionDefaultCustom = data.vdocument_id().v;
|
|
});
|
|
}
|
|
_fields.autologinToken = qs(data.vautologin_token().value_or_empty());
|
|
|
|
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::setStickersRecentLimit(int value) {
|
|
_fields.stickersRecentLimit = value;
|
|
}
|
|
|
|
void Config::setMegagroupSizeMax(int value) {
|
|
_fields.megagroupSizeMax = value;
|
|
}
|
|
|
|
void Config::setTxtDomainString(const QString &value) {
|
|
_fields.txtDomainString = value;
|
|
}
|
|
|
|
} // namespace MTP
|