mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-26 19:14:02 +02:00
1201 lines
30 KiB
C++
1201 lines
30 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 "storage/details/storage_settings_scheme.h"
|
|
|
|
#include "storage/details/storage_file_utilities.h"
|
|
#include "storage/cache/storage_cache_database.h"
|
|
#include "storage/serialize_common.h"
|
|
#include "core/application.h"
|
|
#include "core/core_settings.h"
|
|
#include "mtproto/mtproto_config.h"
|
|
#include "ui/widgets/input_fields.h"
|
|
#include "ui/chat/attach/attach_send_files_way.h"
|
|
#include "ui/power_saving.h"
|
|
#include "window/themes/window_theme.h"
|
|
#include "core/update_checker.h"
|
|
#include "platform/platform_specific.h"
|
|
#include "boxes/send_files_box.h"
|
|
|
|
namespace Storage {
|
|
namespace details {
|
|
namespace {
|
|
|
|
using Cache::Database;
|
|
|
|
[[nodiscard]] bool NoTimeLimit(qint32 storedLimitValue) {
|
|
// This is a workaround for a bug in storing the cache time limit.
|
|
// See https://github.com/telegramdesktop/tdesktop/issues/5611
|
|
return !storedLimitValue
|
|
|| (storedLimitValue == qint32(std::numeric_limits<int32>::max()))
|
|
|| (storedLimitValue == qint32(std::numeric_limits<int64>::max()));
|
|
}
|
|
|
|
} // namespace
|
|
|
|
bool ReadSetting(
|
|
quint32 blockId,
|
|
QDataStream &stream,
|
|
int version,
|
|
ReadSettingsContext &context) {
|
|
switch (blockId) {
|
|
case dbiDcOptionOldOld: {
|
|
quint32 dcId, port;
|
|
QString host, ip;
|
|
stream >> dcId >> host >> ip >> port;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.fallbackConfigLegacyDcOptions.constructAddOne(
|
|
dcId,
|
|
0,
|
|
ip.toStdString(),
|
|
port,
|
|
{});
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiDcOptionOld: {
|
|
quint32 dcIdWithShift, port;
|
|
qint32 flags;
|
|
QString ip;
|
|
stream >> dcIdWithShift >> flags >> ip >> port;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.fallbackConfigLegacyDcOptions.constructAddOne(
|
|
dcIdWithShift,
|
|
MTPDdcOption::Flags::from_raw(flags),
|
|
ip.toStdString(),
|
|
port,
|
|
{});
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiDcOptionsOld: {
|
|
auto serialized = QByteArray();
|
|
stream >> serialized;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.fallbackConfigLegacyDcOptions.constructFromSerialized(
|
|
serialized);
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiApplicationSettings: {
|
|
auto serialized = QByteArray();
|
|
stream >> serialized;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
Core::App().settings().addFromSerialized(serialized);
|
|
} break;
|
|
|
|
case dbiChatSizeMaxOld: {
|
|
qint32 maxSize;
|
|
stream >> maxSize;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.fallbackConfigLegacyChatSizeMax = maxSize;
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiSavedGifsLimitOld: {
|
|
qint32 limit;
|
|
stream >> limit;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.fallbackConfigLegacySavedGifsLimit = limit;
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiStickersRecentLimitOld: {
|
|
qint32 limit;
|
|
stream >> limit;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.fallbackConfigLegacyStickersRecentLimit = limit;
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiStickersFavedLimitOld: {
|
|
qint32 limit;
|
|
stream >> limit;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.fallbackConfigLegacyStickersFavedLimit = limit;
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiMegagroupSizeMaxOld: {
|
|
qint32 maxSize;
|
|
stream >> maxSize;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.fallbackConfigLegacyMegagroupSizeMax = maxSize;
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiUser: {
|
|
quint32 dcId;
|
|
qint32 userId;
|
|
stream >> userId >> dcId;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
DEBUG_LOG(("MTP Info: user found, dc %1, uid %2").arg(dcId).arg(userId));
|
|
context.mtpLegacyMainDcId = dcId;
|
|
context.mtpLegacyUserId = userId;
|
|
} break;
|
|
|
|
case dbiKey: {
|
|
qint32 dcId;
|
|
stream >> dcId;
|
|
auto key = Serialize::read<MTP::AuthKey::Data>(stream);
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.mtpLegacyKeys.push_back(std::make_shared<MTP::AuthKey>(
|
|
MTP::AuthKey::Type::ReadFromFile,
|
|
dcId,
|
|
key));
|
|
} break;
|
|
|
|
case dbiMtpAuthorization: {
|
|
auto serialized = QByteArray();
|
|
stream >> serialized;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.mtpAuthorization = serialized;
|
|
} break;
|
|
|
|
case dbiAutoStart: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
cSetAutoStart(v == 1);
|
|
} break;
|
|
|
|
case dbiStartMinimized: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
cSetStartMinimized(v == 1);
|
|
} break;
|
|
|
|
case dbiSendToMenu: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
cSetSendToMenu(v == 1);
|
|
} break;
|
|
|
|
case dbiUseExternalVideoPlayerOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
} break;
|
|
|
|
case dbiCacheSettingsOld: {
|
|
qint64 size;
|
|
qint32 time;
|
|
stream >> size >> time;
|
|
if (!CheckStreamStatus(stream)
|
|
|| size <= Database::Settings().maxDataSize
|
|
|| (!NoTimeLimit(time) && time < 0)) {
|
|
return false;
|
|
}
|
|
context.cacheTotalSizeLimit = size;
|
|
context.cacheTotalTimeLimit = NoTimeLimit(time) ? 0 : time;
|
|
context.cacheBigFileTotalSizeLimit = size;
|
|
context.cacheBigFileTotalTimeLimit = NoTimeLimit(time) ? 0 : time;
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiCacheSettings: {
|
|
qint64 size, sizeBig;
|
|
qint32 time, timeBig;
|
|
stream >> size >> time >> sizeBig >> timeBig;
|
|
if (!CheckStreamStatus(stream)
|
|
|| size <= Database::Settings().maxDataSize
|
|
|| sizeBig <= Database::Settings().maxDataSize
|
|
|| (!NoTimeLimit(time) && time < 0)
|
|
|| (!NoTimeLimit(timeBig) && timeBig < 0)) {
|
|
return false;
|
|
}
|
|
|
|
context.cacheTotalSizeLimit = size;
|
|
context.cacheTotalTimeLimit = NoTimeLimit(time) ? 0 : time;
|
|
context.cacheBigFileTotalSizeLimit = sizeBig;
|
|
context.cacheBigFileTotalTimeLimit = NoTimeLimit(timeBig) ? 0 : timeBig;
|
|
} break;
|
|
|
|
case dbiPowerSaving: {
|
|
qint32 settings;
|
|
stream >> settings;
|
|
if (!CheckStreamStatus(stream)) {
|
|
return false;
|
|
}
|
|
|
|
PowerSaving::Set(PowerSaving::Flags::from_raw(settings));
|
|
} break;
|
|
|
|
case dbiSoundFlashBounceNotifyOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
Core::App().settings().setSoundNotify((v & 0x01) == 0x01);
|
|
Core::App().settings().setFlashBounceNotify((v & 0x02) == 0x00);
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiAutoDownloadOld: {
|
|
qint32 photo, audio, gif;
|
|
stream >> photo >> audio >> gif;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
using namespace Data::AutoDownload;
|
|
auto &settings = context.sessionSettings().autoDownload();
|
|
const auto disabled = [](qint32 value, qint32 mask) {
|
|
return (value & mask) != 0;
|
|
};
|
|
const auto set = [&](Type type, qint32 value) {
|
|
constexpr auto kNoPrivate = qint32(0x01);
|
|
constexpr auto kNoGroups = qint32(0x02);
|
|
if (disabled(value, kNoPrivate)) {
|
|
settings.setBytesLimit(Source::User, type, 0);
|
|
}
|
|
if (disabled(value, kNoGroups)) {
|
|
settings.setBytesLimit(Source::Group, type, 0);
|
|
settings.setBytesLimit(Source::Channel, type, 0);
|
|
}
|
|
};
|
|
set(Type::Photo, photo);
|
|
set(Type::VoiceMessage, audio);
|
|
set(Type::AutoPlayGIF, gif);
|
|
set(Type::AutoPlayVideoMessage, gif);
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiAutoPlayOld: {
|
|
qint32 gif;
|
|
stream >> gif;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
if (!gif) {
|
|
using namespace Data::AutoDownload;
|
|
auto &settings = context.sessionSettings().autoDownload();
|
|
const auto types = {
|
|
Type::AutoPlayGIF,
|
|
Type::AutoPlayVideo,
|
|
Type::AutoPlayVideoMessage,
|
|
};
|
|
const auto sources = {
|
|
Source::User,
|
|
Source::Group,
|
|
Source::Channel
|
|
};
|
|
for (const auto source : sources) {
|
|
for (const auto type : types) {
|
|
settings.setBytesLimit(source, type, 0);
|
|
}
|
|
}
|
|
}
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiDialogsModeOld: {
|
|
qint32 enabled, modeInt;
|
|
stream >> enabled >> modeInt;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiDialogsFiltersOld: {
|
|
qint32 enabled;
|
|
stream >> enabled;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.sessionSettings().setDialogsFiltersEnabled(enabled == 1);
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiModerateModeOld: {
|
|
qint32 enabled;
|
|
stream >> enabled;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
Core::App().settings().setModerateModeEnabled(enabled == 1);
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiIncludeMutedOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
Core::App().settings().setIncludeMutedCounter(v == 1);
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiShowingSavedGifsOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiDesktopNotifyOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
Core::App().settings().setDesktopNotify(v == 1);
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiWindowsNotificationsOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiNativeNotificationsOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
Core::App().settings().setNativeNotifications(v == 1);
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiNotificationsCountOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
Core::App().settings().setNotificationsCount((v > 0 ? v : 3));
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiNotificationsCornerOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
Core::App().settings().setNotificationsCorner(static_cast<Core::Settings::ScreenCorner>((v >= 0 && v < 4) ? v : 2));
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiDialogsWidthRatioOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
Core::App().settings().setDialogsWidthRatio(v / 1000000.);
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiLastSeenWarningSeenOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
Core::App().settings().setLastSeenWarningSeen(v == 1);
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiSessionSettings: {
|
|
QByteArray v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.sessionSettings().addFromSerialized(v);
|
|
} break;
|
|
|
|
case dbiWorkModeOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
const auto newMode = [v] {
|
|
using WorkMode = Core::Settings::WorkMode;
|
|
switch (static_cast<WorkMode>(v)) {
|
|
case WorkMode::TrayOnly: return WorkMode::TrayOnly;
|
|
case WorkMode::WindowOnly: return WorkMode::WindowOnly;
|
|
};
|
|
return WorkMode::WindowAndTray;
|
|
}();
|
|
Core::App().settings().setWorkMode(newMode);
|
|
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiTxtDomainStringOldOld: {
|
|
QString v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiTxtDomainStringOld: {
|
|
QString v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.fallbackConfigLegacyTxtDomainString = v;
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiConnectionTypeOldOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
// const auto dbictAuto = 0;
|
|
// const auto dbictHttpAuto = 1; // not used
|
|
const auto dbictHttpProxy = 2;
|
|
const auto dbictTcpProxy = 3;
|
|
// const auto dbictProxiesListOld = 4;
|
|
// const auto dbictProxiesList = 5;
|
|
|
|
MTP::ProxyData proxy;
|
|
switch (v) {
|
|
case dbictHttpProxy:
|
|
case dbictTcpProxy: {
|
|
qint32 port;
|
|
stream >> proxy.host >> port >> proxy.user >> proxy.password;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
proxy.port = uint32(port);
|
|
proxy.type = (v == dbictTcpProxy)
|
|
? MTP::ProxyData::Type::Socks5
|
|
: MTP::ProxyData::Type::Http;
|
|
} break;
|
|
};
|
|
auto &proxySettings = Core::App().settings().proxy();
|
|
proxySettings.setSelected(proxy ? proxy : MTP::ProxyData());
|
|
proxySettings.setSettings(proxy
|
|
? MTP::ProxyData::Settings::Enabled
|
|
: MTP::ProxyData::Settings::System);
|
|
proxySettings.list() = proxy
|
|
? std::vector<MTP::ProxyData>{ 1, proxy }
|
|
: std::vector<MTP::ProxyData>{};
|
|
Core::App().refreshGlobalProxy();
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiConnectionTypeOld: {
|
|
qint32 connectionType;
|
|
stream >> connectionType;
|
|
if (!CheckStreamStatus(stream)) {
|
|
return false;
|
|
}
|
|
|
|
auto &proxySettings = Core::App().settings().proxy();
|
|
|
|
const auto legacyProxyTypeShift = 1024;
|
|
|
|
// const auto dbictAuto = 0;
|
|
// const auto dbictHttpAuto = 1; // not used
|
|
const auto dbictHttpProxy = 2;
|
|
const auto dbictTcpProxy = 3;
|
|
const auto dbictProxiesListOld = 4;
|
|
const auto dbictProxiesList = 5;
|
|
|
|
const auto readProxy = [&] {
|
|
using Type = MTP::ProxyData::Type;
|
|
qint32 proxyType, port;
|
|
MTP::ProxyData proxy;
|
|
stream
|
|
>> proxyType
|
|
>> proxy.host
|
|
>> port
|
|
>> proxy.user
|
|
>> proxy.password;
|
|
proxy.port = port;
|
|
proxy.type = (proxyType == dbictTcpProxy)
|
|
? Type::Socks5
|
|
: (proxyType == dbictHttpProxy)
|
|
? Type::Http
|
|
: (proxyType == legacyProxyTypeShift + int(Type::Socks5))
|
|
? Type::Socks5
|
|
: (proxyType == legacyProxyTypeShift + int(Type::Http))
|
|
? Type::Http
|
|
: (proxyType == legacyProxyTypeShift + int(Type::Mtproto))
|
|
? Type::Mtproto
|
|
: Type::None;
|
|
return proxy;
|
|
};
|
|
if (connectionType == dbictProxiesListOld
|
|
|| connectionType == dbictProxiesList) {
|
|
qint32 count = 0, index = 0;
|
|
stream >> count >> index;
|
|
qint32 settings = 0, calls = 0;
|
|
if (connectionType == dbictProxiesList) {
|
|
stream >> settings >> calls;
|
|
} else if (std::abs(index) > count) {
|
|
calls = 1;
|
|
index -= (index > 0 ? count : -count);
|
|
}
|
|
|
|
auto list = std::vector<MTP::ProxyData>();
|
|
for (auto i = 0; i < count; ++i) {
|
|
const auto proxy = readProxy();
|
|
if (proxy) {
|
|
list.push_back(proxy);
|
|
} else if (index < -list.size()) {
|
|
++index;
|
|
} else if (index > list.size()) {
|
|
--index;
|
|
}
|
|
}
|
|
if (!CheckStreamStatus(stream)) {
|
|
return false;
|
|
}
|
|
proxySettings.list() = list;
|
|
if (connectionType == dbictProxiesListOld) {
|
|
settings = static_cast<qint32>(
|
|
(index > 0 && index <= list.size()
|
|
? MTP::ProxyData::Settings::Enabled
|
|
: MTP::ProxyData::Settings::System));
|
|
index = std::abs(index);
|
|
}
|
|
proxySettings.setSelected((index > 0 && index <= list.size())
|
|
? list[index - 1]
|
|
: MTP::ProxyData());
|
|
|
|
const auto unchecked = static_cast<MTP::ProxyData::Settings>(settings);
|
|
switch (unchecked) {
|
|
case MTP::ProxyData::Settings::Enabled:
|
|
proxySettings.setSettings(proxySettings.selected()
|
|
? MTP::ProxyData::Settings::Enabled
|
|
: MTP::ProxyData::Settings::System);
|
|
break;
|
|
case MTP::ProxyData::Settings::Disabled:
|
|
case MTP::ProxyData::Settings::System:
|
|
proxySettings.setSettings(unchecked);
|
|
break;
|
|
default:
|
|
proxySettings.setSettings(MTP::ProxyData::Settings::System);
|
|
break;
|
|
}
|
|
proxySettings.setUseProxyForCalls(calls == 1);
|
|
} else {
|
|
const auto proxy = readProxy();
|
|
if (!CheckStreamStatus(stream)) {
|
|
return false;
|
|
}
|
|
if (proxy) {
|
|
proxySettings.list() = { 1, proxy };
|
|
proxySettings.setSelected(proxy);
|
|
proxySettings.setSettings((connectionType == dbictTcpProxy
|
|
|| connectionType == dbictHttpProxy)
|
|
? MTP::ProxyData::Settings::Enabled
|
|
: MTP::ProxyData::Settings::System);
|
|
} else {
|
|
proxySettings.list() = {};
|
|
proxySettings.setSelected(MTP::ProxyData());
|
|
proxySettings.setSettings(MTP::ProxyData::Settings::System);
|
|
}
|
|
}
|
|
Core::App().refreshGlobalProxy();
|
|
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiThemeKeyOld: {
|
|
quint64 key = 0;
|
|
stream >> key;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
DEBUG_LOG(("Theme: read key legacy: %1").arg(key));
|
|
context.themeKeyLegacy = key;
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiThemeKey: {
|
|
quint64 keyDay = 0, keyNight = 0;
|
|
quint32 nightMode = 0;
|
|
stream >> keyDay >> keyNight >> nightMode;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
DEBUG_LOG(("Theme: read keys (night: %1) day_key: %2, night_key: %3, "
|
|
).arg(Logs::b(nightMode == 1)
|
|
).arg(keyDay
|
|
).arg(keyNight));
|
|
context.themeKeyDay = keyDay;
|
|
context.themeKeyNight = keyNight;
|
|
Window::Theme::SetNightModeValue(nightMode == 1);
|
|
} break;
|
|
|
|
case dbiBackgroundKey: {
|
|
quint64 keyDay = 0, keyNight = 0;
|
|
stream >> keyDay >> keyNight;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.backgroundKeyDay = keyDay;
|
|
context.backgroundKeyNight = keyNight;
|
|
context.backgroundKeysRead = true;
|
|
} break;
|
|
|
|
case dbiLangPackKey: {
|
|
quint64 langPackKey = 0;
|
|
stream >> langPackKey;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.langPackKey = langPackKey;
|
|
} break;
|
|
|
|
case dbiLanguagesKey: {
|
|
quint64 languagesKey = 0;
|
|
stream >> languagesKey;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.languagesKey = languagesKey;
|
|
} break;
|
|
|
|
case dbiTryIPv6Old: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
Core::App().settings().proxy().setTryIPv6(v == 1);
|
|
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiSeenTrayTooltip: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
cSetSeenTrayTooltip(v == 1);
|
|
} break;
|
|
|
|
case dbiAutoUpdate: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
cSetAutoUpdate(v == 1);
|
|
if (!Core::UpdaterDisabled() && !cAutoUpdate()) {
|
|
Core::UpdateChecker().stop();
|
|
}
|
|
} break;
|
|
|
|
case dbiLastUpdateCheck: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
cSetLastUpdateCheck(v);
|
|
} break;
|
|
|
|
case dbiScaleOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
SetScaleChecked([&] {
|
|
constexpr auto kAuto = 0;
|
|
constexpr auto kOne = 1;
|
|
constexpr auto kOneAndQuarter = 2;
|
|
constexpr auto kOneAndHalf = 3;
|
|
constexpr auto kTwo = 4;
|
|
switch (v) {
|
|
case kAuto: return style::kScaleAuto;
|
|
case kOne: return 100;
|
|
case kOneAndQuarter: return 125;
|
|
case kOneAndHalf: return 150;
|
|
case kTwo: return 200;
|
|
}
|
|
return cConfigScale();
|
|
}());
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiScalePercent: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
// If cConfigScale() has value then it was set via command line.
|
|
if (cConfigScale() == style::kScaleAuto) {
|
|
SetScaleChecked(v);
|
|
}
|
|
} break;
|
|
|
|
case dbiLangOld: { // deprecated
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiLangFileOld: { // deprecated
|
|
QString v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiWindowPositionOld: {
|
|
auto position = Core::WindowPosition();
|
|
if (!CheckStreamStatus(stream)) {
|
|
return false;
|
|
}
|
|
stream >> position.x >> position.y >> position.w >> position.h;
|
|
stream >> position.moncrc >> position.maximized;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
DEBUG_LOG(("Window Pos: Read from legacy storage %1, %2, %3, %4 (scale %5%, maximized %6)")
|
|
.arg(position.x)
|
|
.arg(position.y)
|
|
.arg(position.w)
|
|
.arg(position.h)
|
|
.arg(position.scale)
|
|
.arg(Logs::b(position.maximized)));
|
|
|
|
Core::App().settings().setWindowPosition(position);
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiLoggedPhoneNumberOld: { // deprecated
|
|
QString v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiMutePeerOld: { // deprecated
|
|
quint64 peerId;
|
|
stream >> peerId;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiMutedPeersOld: { // deprecated
|
|
quint32 count;
|
|
stream >> count;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
for (uint32 i = 0; i < count; ++i) {
|
|
quint64 peerId;
|
|
stream >> peerId;
|
|
}
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiSendKeyOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
using SendSettings = Ui::InputSubmitSettings;
|
|
const auto unchecked = static_cast<SendSettings>(v);
|
|
|
|
if (unchecked != SendSettings::Enter
|
|
&& unchecked != SendSettings::CtrlEnter) {
|
|
return false;
|
|
}
|
|
Core::App().settings().setSendSubmitWay(unchecked);
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiCatsAndDogsOld: { // deprecated
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiTileBackgroundOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
bool tile = (version < 8005 && !context.legacyHasCustomDayBackground)
|
|
? false
|
|
: (v == 1);
|
|
if (Window::Theme::IsNightMode()) {
|
|
context.tileDay = tile;
|
|
} else {
|
|
context.tileNight = tile;
|
|
}
|
|
context.tileRead = true;
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiTileBackground: {
|
|
qint32 tileDay, tileNight;
|
|
stream >> tileDay >> tileNight;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.tileDay = tileDay;
|
|
context.tileNight = tileNight;
|
|
context.tileRead = true;
|
|
} break;
|
|
|
|
case dbiAdaptiveForWideOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
Core::App().settings().setAdaptiveForWide(v == 1);
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiAutoLockOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
Core::App().settings().setAutoLock(v);
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiReplaceEmojiOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
Core::App().settings().setReplaceEmoji(v == 1);
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiSuggestEmojiOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
Core::App().settings().setSuggestEmoji(v == 1);
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiSuggestStickersByEmojiOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
Core::App().settings().setSuggestStickersByEmoji(v == 1);
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiDefaultAttach: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
} break;
|
|
|
|
case dbiNotifyViewOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
const auto newView = [&] {
|
|
using Notify = Core::Settings::NotifyView;
|
|
switch (static_cast<Notify>(v)) {
|
|
case Notify::ShowNothing: return Notify::ShowNothing;
|
|
case Notify::ShowName: return Notify::ShowName;
|
|
}
|
|
return Notify::ShowPreview;
|
|
}();
|
|
Core::App().settings().setNotifyView(newView);
|
|
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiAskDownloadPathOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
Core::App().settings().setAskDownloadPath(v == 1);
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiDownloadPathOldOld: {
|
|
QString v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
#ifndef OS_WIN_STORE
|
|
if (!v.isEmpty() && v != FileDialog::Tmp() && !v.endsWith('/')) {
|
|
v += '/';
|
|
}
|
|
Core::App().settings().setDownloadPathBookmark(QByteArray());
|
|
Core::App().settings().setDownloadPath(v);
|
|
#endif // OS_WIN_STORE
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiDownloadPathOld: {
|
|
QString v;
|
|
QByteArray bookmark;
|
|
stream >> v >> bookmark;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
#ifndef OS_WIN_STORE
|
|
if (!v.isEmpty() && v != FileDialog::Tmp() && !v.endsWith('/')) {
|
|
v += '/';
|
|
}
|
|
Core::App().settings().setDownloadPathBookmark(bookmark);
|
|
Core::App().settings().setDownloadPath(v);
|
|
psDownloadPathEnableAccess();
|
|
#endif // OS_WIN_STORE
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiCompressPastedImageOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
auto way = Ui::SendFilesWay();
|
|
way.setGroupFiles(v == 1);
|
|
way.setSendImagesAsPhotos(v == 1);
|
|
Core::App().settings().setSendFilesWay(way);
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiEmojiTabOld: { // deprecated
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiRecentEmojiOldOldOld: {
|
|
auto v = QVector<QPair<uint32, ushort>>();
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
if (!v.isEmpty()) {
|
|
auto p = QVector<QPair<QString, ushort>>();
|
|
p.reserve(v.size());
|
|
for (auto &item : v) {
|
|
auto oldKey = uint64(item.first);
|
|
switch (oldKey) {
|
|
case 0xD83CDDEFLLU: oldKey = 0xD83CDDEFD83CDDF5LLU; break;
|
|
case 0xD83CDDF0LLU: oldKey = 0xD83CDDF0D83CDDF7LLU; break;
|
|
case 0xD83CDDE9LLU: oldKey = 0xD83CDDE9D83CDDEALLU; break;
|
|
case 0xD83CDDE8LLU: oldKey = 0xD83CDDE8D83CDDF3LLU; break;
|
|
case 0xD83CDDFALLU: oldKey = 0xD83CDDFAD83CDDF8LLU; break;
|
|
case 0xD83CDDEBLLU: oldKey = 0xD83CDDEBD83CDDF7LLU; break;
|
|
case 0xD83CDDEALLU: oldKey = 0xD83CDDEAD83CDDF8LLU; break;
|
|
case 0xD83CDDEELLU: oldKey = 0xD83CDDEED83CDDF9LLU; break;
|
|
case 0xD83CDDF7LLU: oldKey = 0xD83CDDF7D83CDDFALLU; break;
|
|
case 0xD83CDDECLLU: oldKey = 0xD83CDDECD83CDDE7LLU; break;
|
|
}
|
|
auto id = Ui::Emoji::IdFromOldKey(oldKey);
|
|
if (!id.isEmpty()) {
|
|
p.push_back(qMakePair(id, item.second));
|
|
}
|
|
}
|
|
Core::App().settings().setLegacyRecentEmojiPreload(std::move(p));
|
|
}
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiRecentEmojiOldOld: {
|
|
auto v = QVector<QPair<uint64, ushort>>();
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
if (!v.isEmpty()) {
|
|
auto p = QVector<QPair<QString, ushort>>();
|
|
p.reserve(v.size());
|
|
for (auto &item : v) {
|
|
auto id = Ui::Emoji::IdFromOldKey(item.first);
|
|
if (!id.isEmpty()) {
|
|
p.push_back(qMakePair(id, item.second));
|
|
}
|
|
}
|
|
Core::App().settings().setLegacyRecentEmojiPreload(std::move(p));
|
|
}
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiRecentEmojiOld: {
|
|
auto v = QVector<QPair<QString, ushort>>();
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
Core::App().settings().setLegacyRecentEmojiPreload(std::move(v));
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiRecentStickers: {
|
|
RecentStickerPreload v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
cSetRecentStickersPreload(v);
|
|
} break;
|
|
|
|
case dbiEmojiVariantsOldOld: {
|
|
auto v = QMap<uint32, uint64>();
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
auto variants = QMap<QString, int>();
|
|
for (auto i = v.cbegin(), e = v.cend(); i != e; ++i) {
|
|
auto id = Ui::Emoji::IdFromOldKey(static_cast<uint64>(i.key()));
|
|
if (!id.isEmpty()) {
|
|
auto index = Ui::Emoji::ColorIndexFromOldKey(i.value());
|
|
if (index >= 0) {
|
|
variants.insert(id, index);
|
|
}
|
|
}
|
|
}
|
|
Core::App().settings().setLegacyEmojiVariants(std::move(variants));
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiEmojiVariantsOld: {
|
|
auto v = QMap<QString, int>();
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
Core::App().settings().setLegacyEmojiVariants(std::move(v));
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiHiddenPinnedMessagesOld: {
|
|
auto v = QMap<uint64, int32>();
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
for (auto i = v.begin(), e = v.end(); i != e; ++i) {
|
|
context.sessionSettings().setHiddenPinnedMessageId(
|
|
DeserializePeerId(i.key()),
|
|
MsgId(0), // topicRootId
|
|
MsgId(i.value()));
|
|
}
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiDialogLastPath: {
|
|
QString path;
|
|
stream >> path;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
cSetDialogLastPath(path);
|
|
} break;
|
|
|
|
case dbiSongVolumeOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
Core::App().settings().setSongVolume(std::clamp(v / 1e6, 0., 1.));
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiVideoVolumeOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
Core::App().settings().setVideoVolume(std::clamp(v / 1e6, 0., 1.));
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiPlaybackSpeedOld: {
|
|
qint32 v;
|
|
stream >> v;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
if (v == 2) {
|
|
Core::App().settings().setVoicePlaybackSpeed(2.);
|
|
}
|
|
context.legacyRead = true;
|
|
} break;
|
|
|
|
case dbiCallSettingsOld: {
|
|
QByteArray callSettings;
|
|
stream >> callSettings;
|
|
if (!CheckStreamStatus(stream)) return false;
|
|
|
|
QDataStream settingsStream(&callSettings, QIODevice::ReadOnly);
|
|
settingsStream.setVersion(QDataStream::Qt_5_1);
|
|
QString outputDeviceID;
|
|
QString inputDeviceID;
|
|
qint32 outputVolume;
|
|
qint32 inputVolume;
|
|
qint32 duckingEnabled;
|
|
|
|
settingsStream >> outputDeviceID;
|
|
settingsStream >> outputVolume;
|
|
settingsStream >> inputDeviceID;
|
|
settingsStream >> inputVolume;
|
|
settingsStream >> duckingEnabled;
|
|
if (CheckStreamStatus(settingsStream)) {
|
|
auto &app = Core::App().settings();
|
|
app.setCallOutputDeviceId(outputDeviceID);
|
|
app.setCallOutputVolume(outputVolume);
|
|
app.setCallInputDeviceId(inputDeviceID);
|
|
app.setCallInputVolume(inputVolume);
|
|
app.setCallAudioDuckingEnabled(duckingEnabled);
|
|
}
|
|
context.legacyRead = true;
|
|
} 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;
|
|
}
|
|
|
|
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.fallbackConfigLegacyStickersRecentLimit > 0) {
|
|
config.setStickersRecentLimit(
|
|
context.fallbackConfigLegacyStickersRecentLimit);
|
|
}
|
|
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
|