413 lines
15 KiB
C++
413 lines
15 KiB
C++
/*
|
||
This file is part of Telegram Desktop,
|
||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||
|
||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
It is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU General Public License for more details.
|
||
|
||
In addition, as a special exception, the copyright holders give permission
|
||
to link the code of portions of this program with the OpenSSL library.
|
||
|
||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||
*/
|
||
#pragma once
|
||
|
||
#include "core/version.h"
|
||
#include "settings.h"
|
||
|
||
constexpr str_const AppNameOld = "Telegram Win (Unofficial)";
|
||
constexpr str_const AppName = "Telegram Desktop";
|
||
|
||
constexpr str_const AppId = "{53F49750-6209-4FBF-9CA8-7A333C87D1ED}"; // used in updater.cpp and Setup.iss for Windows
|
||
constexpr str_const AppFile = "Telegram";
|
||
|
||
enum {
|
||
MTPShortBufferSize = 65535, // of ints, 256 kb
|
||
MTPPacketSizeMax = 67108864, // 64 mb
|
||
MTPIdsBufferSize = 400, // received msgIds and wereAcked msgIds count stored
|
||
MTPCheckResendTimeout = 10000, // how much time passed from send till we resend request or check it's state, in ms
|
||
MTPCheckResendWaiting = 1000, // how much time to wait for some more requests, when resending request or checking it's state, in ms
|
||
MTPAckSendWaiting = 10000, // how much time to wait for some more requests, when sending msg acks
|
||
MTPResendThreshold = 1, // how much ints should message contain for us not to resend, but to check it's state
|
||
MTPContainerLives = 600, // container lives 10 minutes in haveSent map
|
||
MTPMinReceiveDelay = 4000, // 4 seconds
|
||
MTPMaxReceiveDelay = 64000, // 64 seconds
|
||
MTPMinConnectDelay = 1000, // tcp connect should take less then 1 second
|
||
MTPMaxConnectDelay = 8000, // tcp connect should take 8 seconds max
|
||
MTPConnectionOldTimeout = 192000, // 192 seconds
|
||
MTPTcpConnectionWaitTimeout = 2000, // 2 seconds waiting for tcp, until we accept http
|
||
MTPIPv4ConnectionWaitTimeout = 1000, // 1 seconds waiting for ipv4, until we accept ipv6
|
||
MTPMillerRabinIterCount = 30, // 30 Miller-Rabin iterations for dh_prime primality check
|
||
|
||
MTPUploadSessionsCount = 2, // max 2 upload sessions is created
|
||
MTPDownloadSessionsCount = 2, // max 2 download sessions is created
|
||
MTPKillFileSessionTimeout = 5000, // how much time without upload / download causes additional session kill
|
||
|
||
MTPEnumDCTimeout = 8000, // 8 seconds timeout for help_getConfig to work (then move to other dc)
|
||
|
||
MTPDebugBufferSize = 1024 * 1024, // 1 mb start size
|
||
|
||
MaxUsersPerInvite = 100, // max users in one super group invite request
|
||
|
||
MTPPingDelayDisconnect = 60, // 1 min
|
||
MTPPingSendAfterAuto = 30, // send new ping starting from 30 seconds (add to existing container)
|
||
MTPPingSendAfter = 45, // send new ping after 45 seconds without ping
|
||
|
||
MTPChannelGetDifferenceLimit = 100,
|
||
|
||
MaxSelectedItems = 100,
|
||
|
||
MaxPhoneCodeLength = 4, // max length of country phone code
|
||
MaxPhoneTailLength = 32, // rest of the phone number, without country code (seen 12 at least), need more for service numbers
|
||
|
||
MaxScrollSpeed = 37, // 37px per 15ms while select-by-drag
|
||
FingerAccuracyThreshold = 3, // touch flick ignore 3px
|
||
MaxScrollAccelerated = 4000, // 4000px per second
|
||
MaxScrollFlick = 2500, // 2500px per second
|
||
|
||
LocalEncryptIterCount = 4000, // key derivation iteration count
|
||
LocalEncryptNoPwdIterCount = 4, // key derivation iteration count without pwd (not secure anyway)
|
||
LocalEncryptSaltSize = 32, // 256 bit
|
||
LocalEncryptKeySize = 256, // 2048 bit
|
||
|
||
AnimationTimerDelta = 7,
|
||
ClipThreadsCount = 8,
|
||
AverageGifSize = 320 * 240,
|
||
WaitBeforeGifPause = 200, // wait 200ms for gif draw before pausing it
|
||
InlineBotRequestDelay = 400, // wait 400ms before context bot realtime request
|
||
RecentInlineBotsLimit = 10,
|
||
|
||
AVBlockSize = 4096, // 4Kb for ffmpeg blocksize
|
||
|
||
SaveRecentEmojisTimeout = 3000, // 3 secs
|
||
SaveWindowPositionTimeout = 1000, // 1 sec
|
||
|
||
AutoSearchTimeout = 900, // 0.9 secs
|
||
SearchPerPage = 50,
|
||
SearchManyPerPage = 100,
|
||
LinksOverviewPerPage = 12,
|
||
MediaOverviewStartPerPage = 5,
|
||
MediaOverviewPreloadCount = 4,
|
||
|
||
// a new message from the same sender is attached to previous within 15 minutes
|
||
AttachMessageToPreviousSecondsDelta = 900,
|
||
|
||
AudioVoiceMsgSimultaneously = 4,
|
||
AudioSongSimultaneously = 4,
|
||
AudioCheckPositionTimeout = 100, // 100ms per check audio pos
|
||
AudioCheckPositionDelta = 2400, // update position called each 2400 samples
|
||
AudioFadeTimeout = 7, // 7ms
|
||
AudioFadeDuration = 500,
|
||
AudioVoiceMsgSkip = 400, // 200ms
|
||
AudioVoiceMsgFade = 300, // 300ms
|
||
AudioPreloadSamples = 5 * 48000, // preload next part if less than 5 seconds remains
|
||
AudioVoiceMsgFrequency = 48000, // 48 kHz
|
||
AudioVoiceMsgMaxLength = 100 * 60, // 100 minutes
|
||
AudioVoiceMsgUpdateView = 100, // 100ms
|
||
AudioVoiceMsgChannels = 2, // stereo
|
||
AudioVoiceMsgBufferSize = 1024 * 1024, // 1 Mb buffers
|
||
AudioVoiceMsgInMemory = 2 * 1024 * 1024, // 2 Mb audio is hold in memory and auto loaded
|
||
AudioPauseDeviceTimeout = 3000, // pause in 3 secs after playing is over
|
||
|
||
WaveformSamplesCount = 100,
|
||
|
||
StickerInMemory = 2 * 1024 * 1024, // 2 Mb stickers hold in memory, auto loaded and displayed inline
|
||
StickerMaxSize = 2048, // 2048x2048 is a max image size for sticker
|
||
|
||
AnimationInMemory = 10 * 1024 * 1024, // 10 Mb gif and mp4 animations held in memory while playing
|
||
|
||
MediaViewImageSizeLimit = 100 * 1024 * 1024, // show up to 100mb jpg/png/gif docs in app
|
||
MaxZoomLevel = 7, // x8
|
||
ZoomToScreenLevel = 1024, // just constant
|
||
|
||
ShortcutsCountLimit = 256, // how many shortcuts can be in json file
|
||
|
||
PreloadHeightsCount = 3, // when 3 screens to scroll left make a preload request
|
||
EmojiPanPerRow = 7,
|
||
EmojiPanRowsPerPage = 6,
|
||
StickerPanPerRow = 5,
|
||
StickerPanRowsPerPage = 4,
|
||
StickersUpdateTimeout = 3600000, // update not more than once in an hour
|
||
|
||
SearchPeopleLimit = 5,
|
||
MinUsernameLength = 5,
|
||
MaxUsernameLength = 32,
|
||
UsernameCheckTimeout = 200,
|
||
|
||
MaxChannelDescription = 255,
|
||
MaxGroupChannelTitle = 255,
|
||
MaxPhotoCaption = 200,
|
||
|
||
MaxMessageSize = 4096,
|
||
MaxHttpRedirects = 5, // when getting external data/images
|
||
|
||
WriteMapTimeout = 1000,
|
||
SaveDraftTimeout = 1000, // save draft after 1 secs of not changing text
|
||
SaveDraftAnywayTimeout = 5000, // or save anyway each 5 secs
|
||
SaveCloudDraftIdleTimeout = 14000, // save draft to the cloud after 14 more seconds
|
||
SaveCloudDraftTimeout = 1000, // save draft to the cloud with 1 sec extra delay
|
||
SaveDraftBeforeQuitTimeout = 1500, // give the app 1.5 secs to save drafts to cloud when quitting
|
||
|
||
SetOnlineAfterActivity = 30, // user with hidden last seen stays online for such amount of seconds in the interface
|
||
|
||
ServiceUserId = 777000,
|
||
WebPageUserId = 701000,
|
||
|
||
CacheBackgroundTimeout = 3000, // cache background scaled image after 3s
|
||
BackgroundsInRow = 3,
|
||
|
||
UpdateDelayConstPart = 8 * 3600, // 8 hour min time between update check requests
|
||
UpdateDelayRandPart = 8 * 3600, // 8 hour max - min time between update check requests
|
||
|
||
WrongPasscodeTimeout = 1500,
|
||
SessionsShortPollTimeout = 60000,
|
||
|
||
ChoosePeerByDragTimeout = 1000, // 1 second mouse not moved to choose dialog when dragging a file
|
||
ReloadChannelMembersTimeout = 1000, // 1 second wait before reload members in channel after adding
|
||
|
||
PinnedMessageTextLimit = 16,
|
||
};
|
||
|
||
inline bool isNotificationsUser(uint64 id) {
|
||
return (id == 333000) || (id == ServiceUserId);
|
||
}
|
||
|
||
inline bool isServiceUser(uint64 id) {
|
||
return !(id % 1000);// (id == 333000) || (id == ServiceUserId);
|
||
}
|
||
|
||
#ifdef Q_OS_WIN
|
||
inline const GUID &cGUID() {
|
||
static const GUID gGuid = { 0x87a94ab0, 0xe370, 0x4cde, { 0x98, 0xd3, 0xac, 0xc1, 0x10, 0xc5, 0x96, 0x7d } };
|
||
|
||
return gGuid;
|
||
}
|
||
#endif
|
||
|
||
inline const char *cGUIDStr() {
|
||
static const char *gGuidStr = "{87A94AB0-E370-4cde-98D3-ACC110C5967D}";
|
||
|
||
return gGuidStr;
|
||
}
|
||
|
||
inline const char **cPublicRSAKeys(int &keysCount) {
|
||
static const char *(keys[]) = {"\
|
||
-----BEGIN RSA PUBLIC KEY-----\n\
|
||
MIIBCgKCAQEAwVACPi9w23mF3tBkdZz+zwrzKOaaQdr01vAbU4E1pvkfj4sqDsm6\n\
|
||
lyDONS789sVoD/xCS9Y0hkkC3gtL1tSfTlgCMOOul9lcixlEKzwKENj1Yz/s7daS\n\
|
||
an9tqw3bfUV/nqgbhGX81v/+7RFAEd+RwFnK7a+XYl9sluzHRyVVaTTveB2GazTw\n\
|
||
Efzk2DWgkBluml8OREmvfraX3bkHZJTKX4EQSjBbbdJ2ZXIsRrYOXfaA+xayEGB+\n\
|
||
8hdlLmAjbCVfaigxX0CDqWeR1yFL9kwd9P0NsZRPsmoqVwMbMu7mStFai6aIhc3n\n\
|
||
Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB\n\
|
||
-----END RSA PUBLIC KEY-----"};
|
||
keysCount = arraysize(keys);
|
||
return keys;
|
||
}
|
||
|
||
struct BuiltInDc {
|
||
int id;
|
||
const char *ip;
|
||
int port;
|
||
};
|
||
|
||
static const BuiltInDc _builtInDcs[] = {
|
||
{ 1, "149.154.175.50", 443 },
|
||
{ 2, "149.154.167.51", 443 },
|
||
{ 3, "149.154.175.100", 443 },
|
||
{ 4, "149.154.167.91", 443 },
|
||
{ 5, "149.154.171.5", 443 }
|
||
};
|
||
|
||
static const BuiltInDc _builtInDcsIPv6[] = {
|
||
{ 1, "2001:b28:f23d:f001::a", 443 },
|
||
{ 2, "2001:67c:4e8:f002::a", 443 },
|
||
{ 3, "2001:b28:f23d:f003::a", 443 },
|
||
{ 4, "2001:67c:4e8:f004::a", 443 },
|
||
{ 5, "2001:b28:f23f:f005::a", 443 }
|
||
};
|
||
|
||
static const BuiltInDc _builtInTestDcs[] = {
|
||
{ 1, "149.154.175.10", 443 },
|
||
{ 2, "149.154.167.40", 443 },
|
||
{ 3, "149.154.175.117", 443 }
|
||
};
|
||
|
||
static const BuiltInDc _builtInTestDcsIPv6[] = {
|
||
{ 1, "2001:b28:f23d:f001::e", 443 },
|
||
{ 2, "2001:67c:4e8:f002::e", 443 },
|
||
{ 3, "2001:b28:f23d:f003::e", 443 }
|
||
};
|
||
|
||
inline const BuiltInDc *builtInDcs() {
|
||
return cTestMode() ? _builtInTestDcs : _builtInDcs;
|
||
}
|
||
|
||
inline int builtInDcsCount() {
|
||
return (cTestMode() ? sizeof(_builtInTestDcs) : sizeof(_builtInDcs)) / sizeof(BuiltInDc);
|
||
}
|
||
|
||
inline const BuiltInDc *builtInDcsIPv6() {
|
||
return cTestMode() ? _builtInTestDcsIPv6 : _builtInDcsIPv6;
|
||
}
|
||
|
||
inline int builtInDcsCountIPv6() {
|
||
return (cTestMode() ? sizeof(_builtInTestDcsIPv6) : sizeof(_builtInDcsIPv6)) / sizeof(BuiltInDc);
|
||
}
|
||
|
||
static const char *UpdatesPublicKey = "\
|
||
-----BEGIN RSA PUBLIC KEY-----\n\
|
||
MIGJAoGBAMA4ViQrjkPZ9xj0lrer3r23JvxOnrtE8nI69XLGSr+sRERz9YnUptnU\n\
|
||
BZpkIfKaRcl6XzNJiN28cVwO1Ui5JSa814UAiDHzWUqCaXUiUEQ6NmNTneiGx2sQ\n\
|
||
+9PKKlb8mmr3BB9A45ZNwLT6G9AK3+qkZLHojeSA+m84/a6GP4svAgMBAAE=\n\
|
||
-----END RSA PUBLIC KEY-----\
|
||
";
|
||
|
||
static const char *UpdatesPublicAlphaKey = "\
|
||
-----BEGIN RSA PUBLIC KEY-----\n\
|
||
MIGJAoGBALWu9GGs0HED7KG7BM73CFZ6o0xufKBRQsdnq3lwA8nFQEvmdu+g/I1j\n\
|
||
0LQ+0IQO7GW4jAgzF/4+soPDb6uHQeNFrlVx1JS9DZGhhjZ5rf65yg11nTCIHZCG\n\
|
||
w/CVnbwQOw0g5GBwwFV3r0uTTvy44xx8XXxk+Qknu4eBCsmrAFNnAgMBAAE=\n\
|
||
-----END RSA PUBLIC KEY-----\
|
||
";
|
||
|
||
#ifdef CUSTOM_API_ID
|
||
#include "../../../TelegramPrivate/custom_api_id.h" // Custom API id and API hash
|
||
#else
|
||
static const int32 ApiId = 17349;
|
||
static const char *ApiHash = "344583e45741c457fe1862106095a5eb";
|
||
#endif
|
||
|
||
#ifndef BETA_VERSION_MACRO
|
||
#error "Beta version macro is not defined."
|
||
#endif
|
||
|
||
#if (defined CUSTOM_API_ID) && (BETA_VERSION_MACRO > 0ULL)
|
||
#include "../../../TelegramPrivate/beta_private.h" // private key for downloading closed betas
|
||
#else
|
||
static const char *BetaPrivateKey = "";
|
||
#endif
|
||
|
||
inline const char *cApiDeviceModel() {
|
||
#ifdef Q_OS_WIN
|
||
return "PC";
|
||
#elif defined Q_OS_MAC
|
||
return "Mac";
|
||
#elif defined Q_OS_LINUX
|
||
return "PC";
|
||
#endif
|
||
}
|
||
inline const char *cApiSystemVersion() {
|
||
#ifdef Q_OS_WIN
|
||
return "Windows";
|
||
#elif defined Q_OS_MAC
|
||
return "OS X";
|
||
#elif defined Q_OS_LINUX
|
||
return "Linux";
|
||
#endif
|
||
}
|
||
inline QString cApiAppVersion() {
|
||
return QString::number(AppVersion);
|
||
}
|
||
|
||
extern QString gKeyFile;
|
||
inline const QString &cDataFile() {
|
||
if (!gKeyFile.isEmpty()) return gKeyFile;
|
||
static const QString res(qsl("data"));
|
||
return res;
|
||
}
|
||
|
||
inline const QString &cTempDir() {
|
||
static const QString res = cWorkingDir() + qsl("tdata/tdld/");
|
||
return res;
|
||
}
|
||
|
||
static const char *DefaultCountry = "US";
|
||
static const char *DefaultLanguage = "en";
|
||
|
||
enum {
|
||
DefaultChatBackground = 21,
|
||
|
||
DialogsFirstLoad = 20, // first dialogs part size requested
|
||
DialogsPerPage = 500, // next dialogs part size
|
||
|
||
MessagesFirstLoad = 30, // first history part size requested
|
||
MessagesPerPage = 50, // next history part size
|
||
|
||
FileLoaderQueueStopTimeout = 5000,
|
||
|
||
DownloadPartSize = 64 * 1024, // 64kb for photo
|
||
DocumentDownloadPartSize = 128 * 1024, // 128kb for document
|
||
MaxUploadPhotoSize = 256 * 1024 * 1024, // 256mb photos max
|
||
MaxUploadDocumentSize = 1500 * 1024 * 1024, // 1500mb documents max
|
||
UseBigFilesFrom = 10 * 1024 * 1024, // mtp big files methods used for files greater than 10mb
|
||
MaxFileQueries = 16, // max 16 file parts downloaded at the same time
|
||
MaxWebFileQueries = 8, // max 8 http[s] files downloaded at the same time
|
||
|
||
UploadPartSize = 32 * 1024, // 32kb for photo
|
||
DocumentMaxPartsCount = 3000, // no more than 3000 parts
|
||
DocumentUploadPartSize0 = 32 * 1024, // 32kb for tiny document ( < 1mb )
|
||
DocumentUploadPartSize1 = 64 * 1024, // 64kb for little document ( <= 32mb )
|
||
DocumentUploadPartSize2 = 128 * 1024, // 128kb for small document ( <= 375mb )
|
||
DocumentUploadPartSize3 = 256 * 1024, // 256kb for medium document ( <= 750mb )
|
||
DocumentUploadPartSize4 = 512 * 1024, // 512kb for large document ( <= 1500mb )
|
||
MaxUploadFileParallelSize = MTPUploadSessionsCount * 512 * 1024, // max 512kb uploaded at the same time in each session
|
||
UploadRequestInterval = 500, // one part each half second, if not uploaded faster
|
||
|
||
MaxPhotosInMemory = 50, // try to clear some memory after 50 photos are created
|
||
NoUpdatesTimeout = 60 * 1000, // if nothing is received in 1 min we ping
|
||
NoUpdatesAfterSleepTimeout = 60 * 1000, // if nothing is received in 1 min when was a sleepmode we ping
|
||
WaitForSkippedTimeout = 1000, // 1s wait for skipped seq or pts in updates
|
||
WaitForChannelGetDifference = 1000, // 1s wait after show channel history before sending getChannelDifference
|
||
|
||
MemoryForImageCache = 64 * 1024 * 1024, // after 64mb of unpacked images we try to clear some memory
|
||
NotifyWindowsCount = 3, // 3 desktop notifies at the same time
|
||
NotifySettingSaveTimeout = 1000, // wait 1 second before saving notify setting to server
|
||
NotifyDeletePhotoAfter = 60000, // delete notify photo after 1 minute
|
||
UpdateChunk = 100 * 1024, // 100kb parts when downloading the update
|
||
IdleMsecs = 60 * 1000, // after 60secs without user input we think we are idle
|
||
|
||
UpdateFullChannelTimeout = 5000, // not more than once in 5 seconds
|
||
SendViewsTimeout = 1000, // send views each second
|
||
|
||
ForwardOnAdd = 100, // how many messages from chat history server should forward to user, that was added to this chat
|
||
};
|
||
|
||
inline const QRegularExpression &cWordSplit() {
|
||
static QRegularExpression regexp(qsl("[\\@\\s\\-\\+\\(\\)\\[\\]\\{\\}\\<\\>\\,\\.\\:\\!\\_\\;\\\"\\'\\x0]"));
|
||
return regexp;
|
||
}
|
||
|
||
inline const QRegularExpression &cRussianLetters() {
|
||
static QRegularExpression regexp(QString::fromUtf8("[а-яА-ЯёЁ]"));
|
||
return regexp;
|
||
}
|
||
|
||
inline QStringList cImgExtensions() {
|
||
static QStringList imgExtensions;
|
||
if (imgExtensions.isEmpty()) {
|
||
imgExtensions.reserve(4);
|
||
imgExtensions.push_back(qsl(".jpg"));
|
||
imgExtensions.push_back(qsl(".jpeg"));
|
||
imgExtensions.push_back(qsl(".png"));
|
||
imgExtensions.push_back(qsl(".gif"));
|
||
}
|
||
return imgExtensions;
|
||
}
|
||
|
||
inline QStringList cPhotoExtensions() {
|
||
static QStringList photoExtensions;
|
||
if (photoExtensions.isEmpty()) {
|
||
photoExtensions.push_back(qsl(".jpg"));
|
||
photoExtensions.push_back(qsl(".jpeg"));
|
||
}
|
||
return photoExtensions;
|
||
}
|