From ad04bf77d1c95a9f53dc9dbf7d12b8e12746e759 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 2 Mar 2015 15:34:16 +0300 Subject: [PATCH] 0.7.19 version with passcode lock option --- Telegram/PrepareWin.bat | 8 +- Telegram/Resources/lang.strings | 21 + Telegram/Resources/style.txt | 30 +- Telegram/Setup.iss | 2 + Telegram/SourceFiles/app.cpp | 528 +-------- Telegram/SourceFiles/app.h | 13 +- Telegram/SourceFiles/application.cpp | 98 +- Telegram/SourceFiles/application.h | 3 +- Telegram/SourceFiles/art/sprite.png | Bin 60347 -> 60895 bytes Telegram/SourceFiles/art/sprite_200x.png | Bin 106949 -> 107625 bytes Telegram/SourceFiles/boxes/autolockbox.cpp | 152 +++ Telegram/SourceFiles/boxes/autolockbox.h | 53 + Telegram/SourceFiles/boxes/connectionbox.cpp | 4 +- .../SourceFiles/boxes/downloadpathbox.cpp | 4 +- Telegram/SourceFiles/boxes/languagebox.cpp | 4 +- Telegram/SourceFiles/boxes/passcodebox.cpp | 279 +++++ Telegram/SourceFiles/boxes/passcodebox.h | 64 + Telegram/SourceFiles/boxes/photocropbox.cpp | 1 - Telegram/SourceFiles/boxes/photosendbox.cpp | 9 +- Telegram/SourceFiles/config.h | 6 +- Telegram/SourceFiles/dialogswidget.cpp | 2 + Telegram/SourceFiles/dropdown.cpp | 4 +- Telegram/SourceFiles/gui/filedialog.cpp | 1 - Telegram/SourceFiles/gui/text.cpp | 1 - Telegram/SourceFiles/historywidget.cpp | 13 +- Telegram/SourceFiles/intro/intro.cpp | 7 +- Telegram/SourceFiles/intro/intro.h | 5 +- Telegram/SourceFiles/localstorage.cpp | 1053 +++++++++++++++-- Telegram/SourceFiles/localstorage.h | 13 +- Telegram/SourceFiles/main.cpp | 6 +- Telegram/SourceFiles/mainwidget.cpp | 23 +- Telegram/SourceFiles/mtproto/mtp.cpp | 60 +- Telegram/SourceFiles/mtproto/mtp.h | 8 +- Telegram/SourceFiles/mtproto/mtpAuthKey.h | 7 + .../SourceFiles/mtproto/mtpConnection.cpp | 27 +- Telegram/SourceFiles/mtproto/mtpDC.cpp | 372 +----- Telegram/SourceFiles/mtproto/mtpDC.h | 20 +- Telegram/SourceFiles/passcodewidget.cpp | 216 ++++ Telegram/SourceFiles/passcodewidget.h | 62 + Telegram/SourceFiles/pspecific_linux.cpp | 8 +- Telegram/SourceFiles/pspecific_linux.h | 1 + Telegram/SourceFiles/pspecific_mac.cpp | 29 +- Telegram/SourceFiles/pspecific_mac.h | 1 + Telegram/SourceFiles/pspecific_mac_p.h | 1 + Telegram/SourceFiles/pspecific_mac_p.mm | 7 +- Telegram/SourceFiles/pspecific_wnd.cpp | 15 +- Telegram/SourceFiles/pspecific_wnd.h | 1 + Telegram/SourceFiles/settings.cpp | 5 + Telegram/SourceFiles/settings.h | 15 + Telegram/SourceFiles/settingswidget.cpp | 107 +- Telegram/SourceFiles/settingswidget.h | 15 +- Telegram/SourceFiles/sysbuttons.cpp | 18 + Telegram/SourceFiles/sysbuttons.h | 17 + Telegram/SourceFiles/title.cpp | 65 +- Telegram/SourceFiles/title.h | 1 + Telegram/SourceFiles/types.h | 3 +- Telegram/SourceFiles/window.cpp | 127 +- Telegram/SourceFiles/window.h | 15 +- Telegram/Telegram.plist | 2 +- Telegram/Telegram.rc | Bin 5540 -> 5540 bytes Telegram/Telegram.vcxproj | 167 ++- Telegram/Telegram.vcxproj.filters | 83 +- Telegram/Telegram.xcodeproj/project.pbxproj | 12 +- Telegram/Version.sh | 2 +- 64 files changed, 2699 insertions(+), 1197 deletions(-) create mode 100644 Telegram/SourceFiles/boxes/autolockbox.cpp create mode 100644 Telegram/SourceFiles/boxes/autolockbox.h create mode 100644 Telegram/SourceFiles/boxes/passcodebox.cpp create mode 100644 Telegram/SourceFiles/boxes/passcodebox.h create mode 100644 Telegram/SourceFiles/passcodewidget.cpp create mode 100644 Telegram/SourceFiles/passcodewidget.h diff --git a/Telegram/PrepareWin.bat b/Telegram/PrepareWin.bat index f81bebf88..b343182fa 100644 --- a/Telegram/PrepareWin.bat +++ b/Telegram/PrepareWin.bat @@ -1,9 +1,9 @@ @echo OFF -set "AppVersion=7018" -set "AppVersionStrSmall=0.7.18" -set "AppVersionStr=0.7.18" -set "AppVersionStrFull=0.7.18.0" +set "AppVersion=7019" +set "AppVersionStrSmall=0.7.19" +set "AppVersionStr=0.7.19" +set "AppVersionStrFull=0.7.19.0" set "DevChannel=1" if %DevChannel% neq 0 goto preparedev diff --git a/Telegram/Resources/lang.strings b/Telegram/Resources/lang.strings index 7a24798d9..413314cd4 100644 --- a/Telegram/Resources/lang.strings +++ b/Telegram/Resources/lang.strings @@ -227,6 +227,27 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_local_storage_clear_failed" = "Clear failed :("; "lng_settings_section_advanced" = "Advanced"; + +"lng_passcode_turn_on" = "Turn passcode on"; +"lng_passcode_change" = "Change passcode"; +"lng_passcode_create" = "Create passcode"; +"lng_passcode_remove" = "Remove passcode"; +"lng_passcode_turn_off" = "Turn off"; +"lng_passcode_autolock_away" = "Auto-Lock if away for:"; +"lng_passcode_autolock_inactive" = "Auto-Lock if inactive for:"; +"lng_passcode_autolock_minutes" = "{count:_not_used_|# minute|# minutes}"; +"lng_passcode_autolock_hours" = "{count:_not_used_|# hour|# hours}"; +"lng_passcode_enter_old" = "Enter old passcode"; +"lng_passcode_enter_new" = "Enter new passcode"; +"lng_passcode_confirm_new" = "Re-enter new passcode"; +"lng_passcode_about" = "When you set up a passcode, a lock icon will appear in the corner. Tap it to lock the app.\n\nNote: if you forget the passcode, you'll need to relogin in Telegram Desktop."; +"lng_passcode_differ" = "Passcodes are different"; +"lng_passcode_wrong" = "Wrong passcode"; +"lng_passcode_is_same" = "Passcode was not changed"; +"lng_passcode_enter" = "Enter your Telegram Passcode"; +"lng_passcode_submit" = "Submit"; +"lng_passcode_logout" = "or you can {link_start}log out ยป{link_end}"; + "lng_connection_type" = "Connection type:"; "lng_connection_auto_connecting" = "Default (connecting..)"; "lng_connection_auto" = "Default ({type} used)"; diff --git a/Telegram/Resources/style.txt b/Telegram/Resources/style.txt index 476048bd2..b9b15011a 100644 --- a/Telegram/Resources/style.txt +++ b/Telegram/Resources/style.txt @@ -52,7 +52,7 @@ wndMinHeight: 480px; wndDefWidth: 800px; wndDefHeight: 600px; wndBG: #FFF; -wndShadow: sprite(184px, 21px, 19px, 19px); +wndShadow: sprite(209px, 46px, 19px, 19px); wndShadowShift: 1px; layerAlpha: 0.3; @@ -116,6 +116,12 @@ sysRes: sysButton(sysUpd) { sysCls: sysButton(sysUpd) { img: sprite(276px, 1px, 19px, 19px); } +sysLock: sysButton(sysUpd) { + img: sprite(184px, 22px, 19px, 19px); +} +sysUnlock: sysButton(sysUpd) { + img: sprite(207px, 22px, 19px, 19px); +} titleBackButton: iconedButton(btnDefIconed) { icon: sprite(133px, 197px, 13px, 20px); iconPos: point(5px, 9px); @@ -383,7 +389,7 @@ btnIntroNext: flatButton(btnDefNext, btnDefBig) { width: 300px; } -boxShadow: sprite(240px, 21px, 9px, 9px); +boxShadow: sprite(230px, 46px, 9px, 9px); introCountry: countryInput { width: 300px; @@ -637,7 +643,7 @@ dlgFilter: flatInput(inpDefGray) { phColor: #949494; phFocusColor: #a4a4a4; textMrg: margins(34px, 2px, 34px, 4px); - imgRect: sprite(208px, 28px, 24px, 24px); + imgRect: sprite(227px, 21px, 24px, 24px); imgPos: point(6px, 5px); width: 240px; @@ -1189,7 +1195,7 @@ participantFilter: flatInput(inpDefFlat) { height: 52px; font: font(16px); textMrg: margins(39px, 11px, 10px, 10px); - imgRect: sprite(208px, 28px, 24px, 24px); + imgRect: sprite(227px, 21px, 24px, 24px); imgPos: point(10px, 15px); } participantDelta: 12px; @@ -1308,7 +1314,7 @@ connectingColor: #777; connectingPadding: margins(5px, 5px, 5px, 5px); dropdownPadding: margins(10px, 10px, 10px, 10px); -dropdownShadow: sprite(240px, 35px, 6px, 6px); +dropdownShadow: sprite(241px, 46px, 6px, 6px); dropdownBorder: 1px; dropdownBorderColor: #ebebeb; dropdownBackground: white; @@ -1694,3 +1700,17 @@ backgroundSize: size(108px, 193px); backgroundScroll: flatScroll(newGroupScroll) { topsh: -2px; } + +passcodeHeaderFont: font(19px); +passcodeHeaderHeight: 80px; +passcodeSkip: 40px; +passcodeInput: flatInput(inpIntroPhone) { +} +passcodeSubmit: flatButton(btnIntroNext) { + textTop: 15px; + overTextTop: 15px; + downTextTop: 16px; + width: 225px; + font: font(19px); + overFont: font(19px); +} diff --git a/Telegram/Setup.iss b/Telegram/Setup.iss index 041c43c47..78ade6152 100644 --- a/Telegram/Setup.iss +++ b/Telegram/Setup.iss @@ -61,6 +61,7 @@ Type: files; Name: "{app}\log.txt" Type: filesandordirs; Name: "{app}\DebugLogs" Type: filesandordirs; Name: "{app}\tupdates" Type: filesandordirs; Name: "{app}\tdata" +Type: filesandordirs; Name: "{app}\tcache" Type: filesandordirs; Name: "{app}\tdumps" Type: dirifempty; Name: "{app}" Type: files; Name: "{userappdata}\{#MyAppName}\data" @@ -69,6 +70,7 @@ Type: files; Name: "{userappdata}\{#MyAppName}\log.txt" Type: filesandordirs; Name: "{userappdata}\{#MyAppName}\DebugLogs" Type: filesandordirs; Name: "{userappdata}\{#MyAppName}\tupdates" Type: filesandordirs; Name: "{userappdata}\{#MyAppName}\tdata" +Type: filesandordirs; Name: "{userappdata}\{#MyAppName}\tcache" Type: filesandordirs; Name: "{userappdata}\{#MyAppName}\tdumps" Type: dirifempty; Name: "{userappdata}\{#MyAppName}" diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index 54bae380e..73fbb1096 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -18,8 +18,6 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "stdafx.h" #include "lang.h" -#include "app.h" - #include "audio.h" #include "application.h" #include "fileuploader.h" @@ -111,6 +109,11 @@ namespace App { return w ? w->settingsWidget() : 0; } + bool passcoded() { + Window *w(wnd()); + return w ? w->passcodeWidget() : 0; + } + FileUploader *uploader() { return app() ? app()->uploader() : 0; } @@ -122,6 +125,9 @@ namespace App { bool loggedOut() { Window *w(wnd()); + if (cHasPasscode()) { + cSetHasPasscode(false); + } if (w) { w->tempDirDelete(Local::ClearManagerAll); w->notifyClearFast(); @@ -130,6 +136,8 @@ namespace App { MainWidget *m(main()); if (m) m->destroyData(); MTP::authed(0); + Local::reset(); + cSetOtherOnline(0); histories().clear(); globalNotifyAllPtr = UnknownNotifySettings; @@ -138,6 +146,7 @@ namespace App { App::uploader()->clear(); clearStorageImages(); if (w) { + w->getTitle()->updateBackButton(); w->updateTitleStatus(); w->getTitle()->resizeEvent(0); } @@ -145,7 +154,12 @@ namespace App { } void logOut() { - MTP::logoutKeys(rpcDone(&loggedOut), rpcFail(&loggedOut)); + if (MTP::started()) { + MTP::logoutKeys(rpcDone(&loggedOut), rpcFail(&loggedOut)); + } else { + loggedOut(); + MTP::start(); + } } PeerId peerFromMTP(const MTPPeer &peer_id) { @@ -1477,514 +1491,6 @@ namespace App { if (cSoundNotify() && !psSkipAudioNotify()) audioPlayNotify(); } - void writeConfig() { - QDir().mkdir(cWorkingDir() + qsl("tdata")); - QFile configFile(cWorkingDir() + qsl("tdata/config")); - if (configFile.open(QIODevice::WriteOnly)) { - DEBUG_LOG(("App Info: writing config file")); - QDataStream configStream(&configFile); - configStream.setVersion(QDataStream::Qt_5_1); - configStream << quint32(dbiVersion) << qint32(AppVersion); - - configStream << quint32(dbiAutoStart) << qint32(cAutoStart()); - configStream << quint32(dbiStartMinimized) << qint32(cStartMinimized()); - configStream << quint32(dbiSendToMenu) << qint32(cSendToMenu()); - configStream << quint32(dbiWorkMode) << qint32(cWorkMode()); - configStream << quint32(dbiSeenTrayTooltip) << qint32(cSeenTrayTooltip()); - configStream << quint32(dbiAutoUpdate) << qint32(cAutoUpdate()); - configStream << quint32(dbiLastUpdateCheck) << qint32(cLastUpdateCheck()); - configStream << quint32(dbiScale) << qint32(cConfigScale()); - configStream << quint32(dbiLang) << qint32(cLang()); - configStream << quint32(dbiLangFile) << cLangFile(); - - configStream << quint32(dbiConnectionType) << qint32(cConnectionType()); - if (cConnectionType() == dbictHttpProxy || cConnectionType() == dbictTcpProxy) { - const ConnectionProxy &proxy(cConnectionProxy()); - configStream << proxy.host << qint32(proxy.port) << proxy.user << proxy.password; - } - - TWindowPos pos(cWindowPos()); - configStream << quint32(dbiWindowPosition) << qint32(pos.x) << qint32(pos.y) << qint32(pos.w) << qint32(pos.h) << qint32(pos.moncrc) << qint32(pos.maximized); - - if (configStream.status() != QDataStream::Ok) { - LOG(("App Error: could not write user config file, status: %1").arg(configStream.status())); - } - } else { - LOG(("App Error: could not open user config file for writing")); - } - } - - void readConfig() { - QFile configFile(cWorkingDir() + qsl("tdata/config")); - if (configFile.open(QIODevice::ReadOnly)) { - DEBUG_LOG(("App Info: config file opened for reading")); - QDataStream configStream(&configFile); - configStream.setVersion(QDataStream::Qt_5_1); - - qint32 configVersion = 0; - while (true) { - quint32 blockId; - configStream >> blockId; - if (configStream.status() == QDataStream::ReadPastEnd) { - DEBUG_LOG(("App Info: config file read end")); - break; - } else if (configStream.status() != QDataStream::Ok) { - LOG(("App Error: could not read block id, status: %1 - config file is corrupted?..").arg(configStream.status())); - break; - } - - if (blockId == dbiVersion) { - configStream >> configVersion; - if (configVersion > AppVersion) break; - continue; - } - - switch (blockId) { - case dbiAutoStart: { - qint32 v; - configStream >> v; - cSetAutoStart(v == 1); - } break; - - case dbiStartMinimized: { - qint32 v; - configStream >> v; - cSetStartMinimized(v == 1); - } break; - - case dbiSendToMenu: { - qint32 v; - configStream >> v; - cSetSendToMenu(v == 1); - } break; - - case dbiSoundNotify: { - if (configVersion < 3008) { - qint32 v; - configStream >> v; - cSetSoundNotify(v == 1); - cSetNeedConfigResave(true); - } - } break; - - case dbiDesktopNotify: { - if (configVersion < 3008) { - qint32 v; - configStream >> v; - cSetDesktopNotify(v == 1); - cSetNeedConfigResave(true); - } - } break; - - case dbiWorkMode: { - qint32 v; - configStream >> v; - switch (v) { - case dbiwmTrayOnly: cSetWorkMode(dbiwmTrayOnly); break; - case dbiwmWindowOnly: cSetWorkMode(dbiwmWindowOnly); break; - default: cSetWorkMode(dbiwmWindowAndTray); break; - }; - } break; - - case dbiConnectionType: { - qint32 v; - configStream >> v; - - switch (v) { - case dbictHttpProxy: - case dbictTcpProxy: { - ConnectionProxy p; - qint32 port; - configStream >> p.host >> port >> p.user >> p.password; - p.port = uint32(port); - cSetConnectionProxy(p); - } - cSetConnectionType(DBIConnectionType(v)); - break; - case dbictHttpAuto: - default: cSetConnectionType(dbictAuto); break; - }; - } break; - - case dbiSeenTrayTooltip: { - qint32 v; - configStream >> v; - cSetSeenTrayTooltip(v == 1); - } break; - - case dbiAutoUpdate: { - qint32 v; - configStream >> v; - cSetAutoUpdate(v == 1); - } break; - - case dbiLastUpdateCheck: { - qint32 v; - configStream >> v; - cSetLastUpdateCheck(v); - } break; - - case dbiScale: { - qint32 v; - configStream >> v; - - DBIScale s = cRealScale(); - switch (v) { - case dbisAuto: s = dbisAuto; break; - case dbisOne: s = dbisOne; break; - case dbisOneAndQuarter: s = dbisOneAndQuarter; break; - case dbisOneAndHalf: s = dbisOneAndHalf; break; - case dbisTwo: s = dbisTwo; break; - } - if (cRetina()) s = dbisOne; - cSetConfigScale(s); - cSetRealScale(s); - } break; - - case dbiLang: { - qint32 v; - configStream >> v; - if (v == languageTest || (v >= 0 && v < languageCount)) { - cSetLang(v); - } - } break; - - case dbiLangFile: { - QString v; - configStream >> v; - cSetLangFile(v); - } break; - - case dbiWindowPosition: { - TWindowPos pos; - configStream >> pos.x >> pos.y >> pos.w >> pos.h >> pos.moncrc >> pos.maximized; - cSetWindowPos(pos); - } break; - } - - if (configStream.status() != QDataStream::Ok) { - LOG(("App Error: could not read data, status: %1 - user config file is corrupted?..").arg(configStream.status())); - break; - } - } - } - } - - void writeUserConfig() { - QFile configFile(cWorkingDir() + cDataFile() + qsl("_config")); - if (configFile.open(QIODevice::WriteOnly)) { - DEBUG_LOG(("App Info: writing user config data for encrypt")); - QByteArray toEncrypt; - toEncrypt.reserve(65536); - toEncrypt.resize(4); - { - QBuffer buffer(&toEncrypt); - buffer.open(QIODevice::Append); - - QDataStream stream(&buffer); - stream.setVersion(QDataStream::Qt_5_1); - - if (MTP::authedId()) { - stream << quint32(dbiUser) << qint32(MTP::authedId()) << quint32(MTP::maindc()); - } - - stream << quint32(dbiSendKey) << qint32(cCtrlEnter() ? dbiskCtrlEnter : dbiskEnter); - stream << quint32(dbiTileBackground) << qint32(cTileBackground() ? 1 : 0); - stream << quint32(dbiReplaceEmojis) << qint32(cReplaceEmojis() ? 1 : 0); - stream << quint32(dbiDefaultAttach) << qint32(cDefaultAttach()); - stream << quint32(dbiSoundNotify) << qint32(cSoundNotify()); - stream << quint32(dbiDesktopNotify) << qint32(cDesktopNotify()); - stream << quint32(dbiNotifyView) << qint32(cNotifyView()); - stream << quint32(dbiAskDownloadPath) << qint32(cAskDownloadPath()); - stream << quint32(dbiDownloadPath) << (cAskDownloadPath() ? QString() : cDownloadPath()); - stream << quint32(dbiCompressPastedImage) << qint32(cCompressPastedImage()); - stream << quint32(dbiEmojiTab) << qint32(cEmojiTab()); - - RecentEmojiPreload v; - v.reserve(cGetRecentEmojis().size()); - for (RecentEmojiPack::const_iterator i = cGetRecentEmojis().cbegin(), e = cGetRecentEmojis().cend(); i != e; ++i) { - v.push_back(qMakePair(i->first->code, i->second)); - } - stream << quint32(dbiRecentEmojis) << v; - - writeAllMuted(stream); - - MTP::writeConfig(stream); - if (stream.status() != QDataStream::Ok) { - LOG(("App Error: could not write user config to memory buf, status: %1").arg(stream.status())); - return; - } - } - *(uint32*)(toEncrypt.data()) = toEncrypt.size(); - - uint32 size = toEncrypt.size(), fullSize = size; - if (fullSize & 0x0F) { - fullSize += 0x10 - (fullSize & 0x0F); - toEncrypt.resize(fullSize); - memset_rand(toEncrypt.data() + size, fullSize - size); - } - QByteArray encrypted(16 + fullSize, Qt::Uninitialized); // 128bit of sha1 - key128, sizeof(data), data - hashSha1(toEncrypt.constData(), toEncrypt.size(), encrypted.data()); - aesEncryptLocal(toEncrypt.constData(), encrypted.data() + 16, fullSize, &Local::oldKey(), encrypted.constData()); - - DEBUG_LOG(("App Info: writing user config file")); - QDataStream configStream(&configFile); - configStream.setVersion(QDataStream::Qt_5_1); - configStream << quint32(dbiVersion) << qint32(AppVersion); - - configStream << quint32(dbiEncryptedWithSalt) << cLocalSalt() << encrypted; // write all encrypted data - - if (configStream.status() != QDataStream::Ok) { - LOG(("App Error: could not write user config file, status: %1").arg(configStream.status())); - } - } else { - LOG(("App Error: could not open user config file for writing")); - } - } - - void readUserConfigFields(QIODevice *io) { - if (!io->isOpen()) io->open(QIODevice::ReadOnly); - - QDataStream stream(io); - stream.setVersion(QDataStream::Qt_5_1); - - while (true) { - quint32 blockId; - stream >> blockId; - if (stream.status() == QDataStream::ReadPastEnd) { - DEBUG_LOG(("App Info: config file read end")); - break; - } else if (stream.status() != QDataStream::Ok) { - LOG(("App Error: could not read block id, status: %1 - user config file is corrupted?..").arg(stream.status())); - break; - } - - if (blockId == dbiVersion) { // should not be in encrypted part, just ignore - qint32 configVersion; - stream >> configVersion; - continue; - } - - switch (blockId) { - case dbiEncryptedWithSalt: { - QByteArray salt, data, decrypted; - stream >> salt >> data; - - if (salt.size() != 32) { - LOG(("App Error: bad salt in encrypted part, size: %1").arg(salt.size())); - continue; - } - - cSetLocalSalt(salt); - Local::createOldKey(&salt); - - if (data.size() <= 16 || (data.size() & 0x0F)) { - LOG(("App Error: bad encrypted part size: %1").arg(data.size())); - continue; - } - uint32 fullDataLen = data.size() - 16; - decrypted.resize(fullDataLen); - const char *dataKey = data.constData(), *encrypted = data.constData() + 16; - aesDecryptLocal(encrypted, decrypted.data(), fullDataLen, &Local::oldKey(), dataKey); - uchar sha1Buffer[20]; - if (memcmp(hashSha1(decrypted.constData(), decrypted.size(), sha1Buffer), dataKey, 16)) { - LOG(("App Error: bad decrypt key, data from user-config not decrypted")); - continue; - } - uint32 dataLen = *(const uint32*)decrypted.constData(); - if (dataLen > uint32(decrypted.size()) || dataLen <= fullDataLen - 16 || dataLen < 4) { - LOG(("App Error: bad decrypted part size: %1, fullDataLen: %2, decrypted size: %3").arg(dataLen).arg(fullDataLen).arg(decrypted.size())); - continue; - } - decrypted.resize(dataLen); - QBuffer decryptedStream(&decrypted); - decryptedStream.open(QIODevice::ReadOnly); - decryptedStream.seek(4); // skip size - readUserConfigFields(&decryptedStream); - } break; - - case dbiLoggedPhoneNumber: { - QString v; - stream >> v; - if (stream.status() == QDataStream::Ok) { - cSetLoggedPhoneNumber(v); - } - } break; - - case dbiMutePeer: { - readOneMuted(stream); - } break; - - case dbiMutedPeers: { - readAllMuted(stream); - } break; - - case dbiSendKey: { - qint32 v; - stream >> v; - cSetCtrlEnter(v == dbiskCtrlEnter); - } break; - - case dbiCatsAndDogs: { - qint32 v; - stream >> v; - } break; - - case dbiTileBackground: { - qint32 v; - stream >> v; - cSetTileBackground(v == 1); - } break; - - case dbiReplaceEmojis: { - qint32 v; - stream >> v; - cSetReplaceEmojis(v == 1); - } break; - - case dbiDefaultAttach: { - qint32 v; - stream >> v; - switch (v) { - case dbidaPhoto: cSetDefaultAttach(dbidaPhoto); break; - default: cSetDefaultAttach(dbidaDocument); break; - } - } break; - - case dbiSoundNotify: { - qint32 v; - stream >> v; - cSetSoundNotify(v == 1); - } break; - - case dbiDesktopNotify: { - qint32 v; - stream >> v; - cSetDesktopNotify(v == 1); - } break; - - case dbiNotifyView: { - qint32 v; - stream >> v; - switch (v) { - case dbinvShowNothing: cSetNotifyView(dbinvShowNothing); break; - case dbinvShowName: cSetNotifyView(dbinvShowName); break; - default: cSetNotifyView(dbinvShowPreview); break; - } - } break; - - case dbiAskDownloadPath: { - qint32 v; - stream >> v; - cSetAskDownloadPath(v == 1); - } break; - - case dbiDownloadPath: { - QString v; - stream >> v; - cSetDownloadPath(v); - } break; - - case dbiCompressPastedImage: { - qint32 v; - stream >> v; - cSetCompressPastedImage(v == 1); - } break; - - case dbiEmojiTab: { - qint32 v; - stream >> v; - switch (v) { - case dbietRecent : cSetEmojiTab(dbietRecent); break; - case dbietPeople : cSetEmojiTab(dbietPeople); break; - case dbietNature : cSetEmojiTab(dbietNature); break; - case dbietObjects : cSetEmojiTab(dbietObjects); break; - case dbietPlaces : cSetEmojiTab(dbietPlaces); break; - case dbietSymbols : cSetEmojiTab(dbietSymbols); break; - case dbietStickers: cSetEmojiTab(dbietStickers); break; - } - } break; - - case dbiRecentEmojis: { - RecentEmojiPreload v; - stream >> v; - cSetRecentEmojisPreload(v); - } break; - - default: - if (!MTP::readConfigElem(blockId, stream)) { - } - break; - } - - if (stream.status() != QDataStream::Ok) { - LOG(("App Error: could not read data, status: %1 - user config file is corrupted?..").arg(stream.status())); - break; - } - } - } - - void readUserConfig() { - QFile configFile(cWorkingDir() + cDataFile() + qsl("_config")); - if (configFile.open(QIODevice::ReadOnly)) { - DEBUG_LOG(("App Info: user config file opened for reading")); - { - QDataStream configStream(&configFile); - configStream.setVersion(QDataStream::Qt_5_1); - - quint32 blockId; - configStream >> blockId; - if (configStream.status() == QDataStream::ReadPastEnd) { - DEBUG_LOG(("App Info: config file read end")); - return; - } else if (configStream.status() != QDataStream::Ok) { - LOG(("App Error: could not read block id, status: %1 - user config file is corrupted?..").arg(configStream.status())); - return; - } - - if (blockId == dbiVersion) { - qint32 configVersion; - configStream >> configVersion; - if (configVersion > AppVersion) return; - - configStream >> blockId; - if (configStream.status() == QDataStream::ReadPastEnd) { - DEBUG_LOG(("App Info: config file read end")); - return; - } else if (configStream.status() != QDataStream::Ok) { - LOG(("App Error: could not read block id, status: %1 - user config file is corrupted?..").arg(configStream.status())); - return; - } - if (blockId != dbiEncryptedWithSalt) { // old version data - not encrypted - cSetNeedConfigResave(true); - } - } else { - cSetNeedConfigResave(true); - } - } - - configFile.reset(); - readUserConfigFields(&configFile); - } - } - - void writeAllMuted(QDataStream &stream) { // deprecated - } - - void readOneMuted(QDataStream &stream) { // deprecated - quint64 peerId; - stream >> peerId; - } - - void readAllMuted(QDataStream &stream) { - quint32 count; - stream >> count; - - for (uint32 i = 0; i < count; ++i) { - readOneMuted(stream); - } - } - void checkImageCacheSize() { int64 nowImageCacheSize = imageCacheSize(); if (nowImageCacheSize > serviceImageCacheSize + MemoryForImageCache) { diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h index c5dd461c0..6cd4c5b7b 100644 --- a/Telegram/SourceFiles/app.h +++ b/Telegram/SourceFiles/app.h @@ -39,6 +39,7 @@ namespace App { Window *wnd(); MainWidget *main(); SettingsWidget *settings(); + bool passcoded(); FileUploader *uploader(); void showSettings(); @@ -151,18 +152,6 @@ namespace App { void deinitMedia(bool completely = true); void playSound(); - void writeConfig(); - void readConfig(); - void writeUserConfig(); - void readUserConfig(); - - void muteHistory(History *history); - void unmuteHistory(History *history); - void writeAllMuted(QDataStream &stream); - void readAllMuted(QDataStream &stream); - void readOneMuted(QDataStream &stream); - bool isPeerMuted(const PeerId &peer); - void checkImageCacheSize(); bool isValidPhone(QString phone); diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index 180a3497b..af3d868f6 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -152,7 +152,6 @@ Application::Application(int &argc, char **argv) : PsApplication(argc, argv), installTranslator(_translator = new Translator()); - Local::start(); style::startManager(); anim::startManager(); historyInit(); @@ -174,8 +173,8 @@ Application::Application(int &argc, char **argv) : PsApplication(argc, argv), connect(this, SIGNAL(updateFailed()), this, SLOT(onUpdateFailed())); connect(this, SIGNAL(updateReady()), this, SLOT(onUpdateReady())); connect(this, SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(onAppStateChanged(Qt::ApplicationState))); - connect(&writeUserConfigTimer, SIGNAL(timeout()), this, SLOT(onWriteUserConfig())); - writeUserConfigTimer.setSingleShot(true); + //connect(&writeUserConfigTimer, SIGNAL(timeout()), this, SLOT(onWriteUserConfig())); + //writeUserConfigTimer.setSingleShot(true); connect(&killDownloadSessionsTimer, SIGNAL(timeout()), this, SLOT(killDownloadSessions())); @@ -191,7 +190,7 @@ void Application::onAppUpdate(const MTPhelp_AppUpdate &response) { updateRequestId = 0; cSetLastUpdateCheck(unixtime()); - App::writeConfig(); + Local::writeSettings(); if (response.type() == mtpc_help_noAppUpdate) { startUpdateCheck(); } else { @@ -205,7 +204,7 @@ void Application::onAppUpdate(const MTPhelp_AppUpdate &response) { bool Application::onAppUpdateFail() { updateRequestId = 0; cSetLastUpdateCheck(unixtime()); - App::writeConfig(); + Local::writeSettings(); startUpdateCheck(); return true; } @@ -239,7 +238,7 @@ void Application::updateGotCurrent() { emit updateLatest(); } startUpdateCheck(true); - App::writeConfig(); + Local::writeSettings(); } void Application::updateFailedCurrent(QNetworkReply::NetworkError e) { @@ -259,7 +258,7 @@ void Application::onUpdateReady() { updateCheckTimer.stop(); cSetLastUpdateCheck(unixtime()); - App::writeConfig(); + Local::writeSettings(); } void Application::onUpdateFailed() { @@ -271,7 +270,7 @@ void Application::onUpdateFailed() { } cSetLastUpdateCheck(unixtime()); - App::writeConfig(); + Local::writeSettings(); } void Application::regPhotoUpdate(const PeerId &peer, MsgId msgId) { @@ -347,11 +346,11 @@ void Application::peerClearPhoto(PeerId peer) { } } -void Application::writeUserConfigIn(uint64 ms) { - if (!writeUserConfigTimer.isActive()) { - writeUserConfigTimer.start(ms); - } -} +//void Application::writeUserConfigIn(uint64 ms) { +// if (!writeUserConfigTimer.isActive()) { +// writeUserConfigTimer.start(ms); +// } +//} void Application::killDownloadSessionsStart(int32 dc) { if (killDownloadSessionTimes.constFind(dc) == killDownloadSessionTimes.cend()) { @@ -373,9 +372,9 @@ void Application::checkLocalTime() { if (App::main()) App::main()->checkLastUpdate(checkms()); } -void Application::onWriteUserConfig() { - App::writeUserConfig(); -} +//void Application::onWriteUserConfig() { +// Local::writeUserSettings(); +//} void Application::onAppStateChanged(Qt::ApplicationState state) { checkLocalTime(); @@ -649,32 +648,44 @@ void Application::socketError(QLocalSocket::LocalSocketError e) { startApp(); } +void Application::checkMapVersion() { + if (Local::oldMapVersion() < AppVersion) { + psRegisterCustomScheme(); + if (Local::oldMapVersion()) { + QString versionFeatures; + if (DevChannel && Local::oldMapVersion() < 7019) { + versionFeatures = QString::fromUtf8("\xe2\x80\x94 Passcode lock option added"); + } else if (!DevChannel && Local::oldMapVersion() < 7017) { + versionFeatures = lang(lng_new_version_minor).trimmed(); + } + if (!versionFeatures.isEmpty()) { + versionFeatures = lng_new_version_wrap(lt_version, QString::fromStdWString(AppVersionStr), lt_changes, versionFeatures, lt_link, qsl("https://desktop.telegram.org/#changelog")); + window->serviceNotification(versionFeatures); + } + } + } +} + void Application::startApp() { cChangeTimeFormat(QLocale::system().timeFormat(QLocale::ShortFormat)); DEBUG_LOG(("Application Info: starting app..")); Local::ReadMapState state = Local::readMap(QByteArray()); + if (state == Local::ReadMapPassNeeded) { + cSetHasPasscode(true); + } DEBUG_LOG(("Application Info: local map read..")); - App::readUserConfig(); - if (!Local::oldKey().created()) { - Local::createOldKey(); - cSetNeedConfigResave(true); - } - if (cNeedConfigResave()) { - App::writeConfig(); - App::writeUserConfig(); - cSetNeedConfigResave(false); - } - DEBUG_LOG(("Application Info: user config read..")); window->createWinId(); window->init(); DEBUG_LOG(("Application Info: window created..")); - MTP::start(); + if (state != Local::ReadMapPassNeeded) { + MTP::start(); + } MTP::setStateChangedHandler(mtpStateChanged); MTP::setSessionResetHandler(mtpSessionReset); @@ -685,12 +696,15 @@ void Application::startApp() { App::initMedia(); DEBUG_LOG(("Application Info: showing.")); - if (MTP::authedId()) { - window->setupMain(false); + if (state == Local::ReadMapPassNeeded) { + window->setupPasscode(false); } else { - window->setupIntro(false); + if (MTP::authedId()) { + window->setupMain(false); + } else { + window->setupIntro(false); + } } - window->firstShow(); if (cStartToSettings()) { @@ -698,20 +712,9 @@ void Application::startApp() { } QNetworkProxyFactory::setUseSystemConfiguration(true); - if (Local::oldMapVersion() < AppVersion) { - psRegisterCustomScheme(); - if (Local::oldMapVersion()) { - QString versionFeatures; - if (DevChannel && Local::oldMapVersion() < 7018) { - versionFeatures = QString::fromUtf8("\xe2\x80\x94 Windows: crash on start fixed for some Intel cards\n\xe2\x80\x94 Linux: tray icon returned in Pantheon and Gnome"); - } else if (!DevChannel && Local::oldMapVersion() < 7017) { - versionFeatures = lang(lng_new_version_minor).trimmed(); - } - if (!versionFeatures.isEmpty()) { - versionFeatures = lng_new_version_wrap(lt_version, QString::fromStdWString(AppVersionStr), lt_changes, versionFeatures, lt_link, qsl("https://desktop.telegram.org/#changelog")); - window->serviceNotification(versionFeatures); - } - } + + if (state != Local::ReadMapPassNeeded) { + checkMapVersion(); } window->updateIsActive(cOnlineFocusTimeout()); @@ -844,8 +847,7 @@ Application::~Application() { cSetChatDogImage(0); style::stopManager(); - Local::stop(); - + delete _translator; } diff --git a/Telegram/SourceFiles/application.h b/Telegram/SourceFiles/application.h index 21495a02c..a55d8f76d 100644 --- a/Telegram/SourceFiles/application.h +++ b/Telegram/SourceFiles/application.h @@ -76,6 +76,7 @@ public: void killDownloadSessionsStop(int32 dc); void checkLocalTime(); + void checkMapVersion(); signals: @@ -107,7 +108,7 @@ public slots: void photoUpdated(MsgId msgId, const MTPInputFile &file); void onEnableDebugMode(); - void onWriteUserConfig(); +// void onWriteUserConfig(); void killDownloadSessions(); void onAppStateChanged(Qt::ApplicationState state); diff --git a/Telegram/SourceFiles/art/sprite.png b/Telegram/SourceFiles/art/sprite.png index 25c31ec9e367cfba315971f15cb9681ce698b273..6c67e40626599f0ae2061f9905abb78902fd00c8 100644 GIT binary patch delta 44215 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 diff --git a/Telegram/SourceFiles/art/sprite_200x.png b/Telegram/SourceFiles/art/sprite_200x.png index 2e0db7e59a4a0f4a1617cee4ec621b99034f52e1..86ab815e807c8a2e5a8f25eff6db4fcea590994e 100644 GIT binary patch literal 107625 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 literal 106949 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

eqV?Jt9+)NimvSyWz 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::langsPadding.left() + st::langPadding.left(), y + st::langPadding.top()); + y += st::langPadding.top() + _options.back()->height() + st::langPadding.bottom(); + connect(_options.back(), SIGNAL(changed()), this, SLOT(onChange())); + } + + _done.move(0, _height - _done.height()); + + connect(&_done, SIGNAL(clicked()), this, SLOT(onClose())); + + resize(_width, _height); + + showAll(); + _cache = myGrab(this, rect()); + hideAll(); +} + +void AutoLockBox::hideAll() { + _done.hide(); + for (int32 i = 0, l = _options.size(); i < l; ++i) { + _options[i]->hide(); + } +} + +void AutoLockBox::showAll() { + _done.show(); + for (int32 i = 0, l = _options.size(); i < l; ++i) { + _options[i]->show(); + } +} + +void AutoLockBox::keyPressEvent(QKeyEvent *e) { + if (e->key() == Qt::Key_Escape) { + onClose(); + } +} + +void AutoLockBox::parentResized() { + QSize s = parentWidget()->size(); + setGeometry((s.width() - _width) / 2, (s.height() - _height) / 2, _width, _height); + update(); +} + +void AutoLockBox::paintEvent(QPaintEvent *e) { + QPainter p(this); + if (_cache.isNull()) { + if (!_hiding || a_opacity.current() > 0.01) { + // fill bg + p.fillRect(0, 0, _width, _height, st::boxBG->b); + + // paint shadows + p.fillRect(0, st::addContactTitleHeight, _width, st::scrollDef.topsh, st::scrollDef.shColor->b); + + // draw box title / text + p.setFont(st::addContactTitleFont->f); + p.setPen(st::black->p); + p.drawText(st::addContactTitlePos.x(), st::addContactTitlePos.y() + st::addContactTitleFont->ascent, lang(lng_languages)); + } + } else { + p.setOpacity(a_opacity.current()); + p.drawPixmap(0, 0, _cache); + } +} + +void AutoLockBox::animStep(float64 ms) { + if (ms >= 1) { + a_opacity.finish(); + _cache = QPixmap(); + if (!_hiding) { + showAll(); + setFocus(); + } + } else { + a_opacity.update(ms, anim::linear); + } + update(); +} + +void AutoLockBox::onChange() { + if (isHidden()) return; + + for (int32 i = 0, l = _options.size(); i < l; ++i) { + int32 v = _options[i]->val(); + if (_options[i]->checked()) { + cSetAutoLock(v); + Local::writeUserSettings(); + } + } + App::wnd()->checkAutoLock(); + onClose(); +} + +void AutoLockBox::onClose() { + emit closed(); +} + +void AutoLockBox::startHide() { + _hiding = true; + if (_cache.isNull()) { + _cache = myGrab(this, rect()); + hideAll(); + } + a_opacity.start(0); +} + +AutoLockBox::~AutoLockBox() { + for (int32 i = 0, l = _options.size(); i < l; ++i) { + delete _options[i]; + } +} diff --git a/Telegram/SourceFiles/boxes/autolockbox.h b/Telegram/SourceFiles/boxes/autolockbox.h new file mode 100644 index 000000000..727c20794 --- /dev/null +++ b/Telegram/SourceFiles/boxes/autolockbox.h @@ -0,0 +1,53 @@ +/* +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. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include "layerwidget.h" + +class AutoLockBox : public LayeredWidget { + Q_OBJECT + +public: + + AutoLockBox(); + void parentResized(); + void animStep(float64 ms); + void keyPressEvent(QKeyEvent *e); + void paintEvent(QPaintEvent *e); + void startHide(); + ~AutoLockBox(); + +public slots: + + void onChange(); + void onClose(); + +private: + + void hideAll(); + void showAll(); + + QVector _options; + int32 _width, _height; + BottomButton _done; + + bool _hiding; + QPixmap _cache; + + anim::fvalue a_opacity; +}; diff --git a/Telegram/SourceFiles/boxes/connectionbox.cpp b/Telegram/SourceFiles/boxes/connectionbox.cpp index b8ef5d458..d8b8cb487 100644 --- a/Telegram/SourceFiles/boxes/connectionbox.cpp +++ b/Telegram/SourceFiles/boxes/connectionbox.cpp @@ -18,6 +18,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "stdafx.h" #include "lang.h" +#include "localstorage.h" + #include "connectionbox.h" #include "mainwidget.h" #include "window.h" @@ -203,7 +205,7 @@ void ConnectionBox::onSave() { QNetworkProxyFactory::setUseSystemConfiguration(false); QNetworkProxyFactory::setUseSystemConfiguration(true); } - App::writeConfig(); + Local::writeSettings(); MTP::restart(); reinitImageLinkManager(); emit closed(); diff --git a/Telegram/SourceFiles/boxes/downloadpathbox.cpp b/Telegram/SourceFiles/boxes/downloadpathbox.cpp index f9a4a7bc6..5981baf2e 100644 --- a/Telegram/SourceFiles/boxes/downloadpathbox.cpp +++ b/Telegram/SourceFiles/boxes/downloadpathbox.cpp @@ -18,6 +18,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "stdafx.h" #include "lang.h" +#include "localstorage.h" + #include "downloadpathbox.h" #include "gui/filedialog.h" @@ -181,7 +183,7 @@ void DownloadPathBox::onEditPath() { void DownloadPathBox::onSave() { cSetDownloadPath(_defaultRadio.checked() ? QString() : (_tempRadio.checked() ? qsl("tmp") : _path)); - App::writeUserConfig(); + Local::writeUserSettings(); emit closed(); } diff --git a/Telegram/SourceFiles/boxes/languagebox.cpp b/Telegram/SourceFiles/boxes/languagebox.cpp index 6a36e3c88..25a973fb2 100644 --- a/Telegram/SourceFiles/boxes/languagebox.cpp +++ b/Telegram/SourceFiles/boxes/languagebox.cpp @@ -18,6 +18,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "stdafx.h" #include "lang.h" +#include "localstorage.h" + #include "languagebox.h" #include "confirmbox.h" #include "mainwidget.h" @@ -183,7 +185,7 @@ void LanguageBox::onSave() { for (int32 i = 0, l = _langs.size(); i < l; ++i) { if (_langs[i]->checked()) { cSetLang(_langs[i]->val()); - App::writeConfig(); + Local::writeSettings(); cSetRestarting(true); cSetRestartingToSettings(true); App::quit(); diff --git a/Telegram/SourceFiles/boxes/passcodebox.cpp b/Telegram/SourceFiles/boxes/passcodebox.cpp new file mode 100644 index 000000000..c6e6de55c --- /dev/null +++ b/Telegram/SourceFiles/boxes/passcodebox.cpp @@ -0,0 +1,279 @@ +/* +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. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "lang.h" + +#include "passcodebox.h" +#include "window.h" + +#include "localstorage.h" + +PasscodeBox::PasscodeBox(bool turningOff) : _turningOff(turningOff), +_about(st::addContactWidth - st::addContactPadding.left() - st::addContactPadding.right()), +_saveButton(this, lang(lng_settings_save), st::btnSelectDone), +_cancelButton(this, lang(lng_cancel), st::btnSelectCancel), +_oldPasscode(this, st::inpAddContact, lang(lng_passcode_enter_old)), +_newPasscode(this, st::inpAddContact, lang(lng_passcode_enter_new)), +_reenterPasscode(this, st::inpAddContact, lang(lng_passcode_confirm_new)), +a_opacity(0, 1), _hiding(false) { + + _width = st::addContactWidth; + _about.setRichText(st::usernameFont, lang(lng_passcode_about)); + int32 aboutHeight = _about.countHeight(_width - st::addContactPadding.left() - st::addContactPadding.right()); + _oldPasscode.setEchoMode(QLineEdit::Password); + _newPasscode.setEchoMode(QLineEdit::Password); + _reenterPasscode.setEchoMode(QLineEdit::Password); + if (turningOff) { + _oldPasscode.show(); + _boxTitle = lang(lng_passcode_remove); + _height = st::addContactTitleHeight + st::addContactPadding.top() + 1 * _oldPasscode.height() + st::usernameSkip + aboutHeight + st::addContactPadding.bottom() + _saveButton.height(); + } else { + if (cHasPasscode()) { + _oldPasscode.show(); + _boxTitle = lang(lng_passcode_change); + _height = st::addContactTitleHeight + st::addContactPadding.top() + 3 * _oldPasscode.height() + st::usernameSkip * 2 + 1 * st::addContactDelta + aboutHeight + st::addContactPadding.bottom() + _saveButton.height(); + } else { + _oldPasscode.hide(); + _boxTitle = lang(lng_passcode_create); + _height = st::addContactTitleHeight + st::addContactPadding.top() + 2 * _oldPasscode.height() + st::usernameSkip + 1 * st::addContactDelta + aboutHeight + st::addContactPadding.bottom() + _saveButton.height(); + } + } + + _oldPasscode.setGeometry(st::addContactPadding.left(), st::addContactTitleHeight + st::addContactPadding.top(), _width - st::addContactPadding.left() - st::addContactPadding.right(), _oldPasscode.height()); + _newPasscode.setGeometry(st::addContactPadding.left(), _oldPasscode.y() + ((turningOff || cHasPasscode()) ? (_oldPasscode.height() + st::usernameSkip) : 0), _oldPasscode.width(), _oldPasscode.height()); + _reenterPasscode.setGeometry(st::addContactPadding.left(), _newPasscode.y() + _newPasscode.height() + st::addContactDelta, _newPasscode.width(), _newPasscode.height()); + + int32 buttonTop = _height - _cancelButton.height(); + _cancelButton.move(0, buttonTop); + _saveButton.move(_width - _saveButton.width(), buttonTop); + + connect(&_saveButton, SIGNAL(clicked()), this, SLOT(onSave())); + connect(&_cancelButton, SIGNAL(clicked()), this, SLOT(onCancel())); + + _badOldTimer.setSingleShot(true); + connect(&_badOldTimer, SIGNAL(timeout()), this, SLOT(onBadOldPasscode())); + + connect(&_oldPasscode, SIGNAL(changed()), this, SLOT(onOldChanged())); + connect(&_newPasscode, SIGNAL(changed()), this, SLOT(onNewChanged())); + connect(&_reenterPasscode, SIGNAL(changed()), this, SLOT(onNewChanged())); + + resize(_width, _height); + + showAll(); + _cache = myGrab(this, rect()); + hideAll(); +} + +void PasscodeBox::hideAll() { + _oldPasscode.hide(); + _newPasscode.hide(); + _reenterPasscode.hide(); + _saveButton.hide(); + _cancelButton.hide(); +} + +void PasscodeBox::showAll() { + if (_turningOff) { + _oldPasscode.show(); + _newPasscode.hide(); + _reenterPasscode.hide(); + } else { + if (cHasPasscode()) { + _oldPasscode.show(); + } else { + _oldPasscode.hide(); + } + _newPasscode.show(); + _reenterPasscode.show(); + } + _saveButton.show(); + _cancelButton.show(); +} + +void PasscodeBox::keyPressEvent(QKeyEvent *e) { + if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) { + if (_oldPasscode.hasFocus()) { + if (_turningOff) { + onSave(); + } else { + _newPasscode.setFocus(); + } + } else if (_newPasscode.hasFocus()) { + _reenterPasscode.setFocus(); + } else if (_reenterPasscode.hasFocus()) { + if (cHasPasscode() && _oldPasscode.text().isEmpty()) { + _oldPasscode.setFocus(); + _oldPasscode.notaBene(); + } else if (_newPasscode.text().isEmpty()) { + _newPasscode.setFocus(); + _newPasscode.notaBene(); + } else if (_reenterPasscode.text().isEmpty()) { + _reenterPasscode.notaBene(); + } else { + onSave(); + } + } + } else if (e->key() == Qt::Key_Escape) { + onCancel(); + } +} + +void PasscodeBox::parentResized() { + QSize s = parentWidget()->size(); + setGeometry((s.width() - _width) / 2, (s.height() - _height) / 2, _width, _height); + update(); +} + +void PasscodeBox::paintEvent(QPaintEvent *e) { + QPainter p(this); + if (_cache.isNull()) { + if (!_hiding || a_opacity.current() > 0.01) { + // fill bg + p.fillRect(QRect(QPoint(0, 0), size()), st::boxBG->b); + + // paint shadows + p.fillRect(0, st::addContactTitleHeight, _width, st::scrollDef.topsh, st::scrollDef.shColor->b); + p.fillRect(0, size().height() - st::btnSelectCancel.height - st::scrollDef.bottomsh, _width, st::scrollDef.bottomsh, st::scrollDef.shColor->b); + + p.setPen(st::usernameColor->p); + _about.draw(p, st::addContactPadding.left(), (_turningOff ? _oldPasscode : _reenterPasscode).y() + _oldPasscode.height() + st::usernameSkip, _width - st::addContactPadding.left() - st::addContactPadding.right()); + + if (!_oldError.isEmpty()) { + p.setPen(st::setErrColor->p); + p.drawText(QRect(0, _oldPasscode.y() + _oldPasscode.height(), _width, st::usernameSkip), _oldError, style::al_center); + } + + if (!_newError.isEmpty()) { + p.setPen(st::setErrColor->p); + p.drawText(QRect(0, _reenterPasscode.y() + _reenterPasscode.height(), _width, st::usernameSkip), _newError, style::al_center); + } + + // paint button sep + p.fillRect(st::btnSelectCancel.width, size().height() - st::btnSelectCancel.height, st::lineWidth, st::btnSelectCancel.height, st::btnSelectSep->b); + + // draw box title / text + p.setPen(st::black->p); + p.setFont(st::addContactTitleFont->f); + p.drawText(st::addContactTitlePos.x(), st::addContactTitlePos.y() + st::addContactTitleFont->ascent, _boxTitle); + } + } else { + p.setOpacity(a_opacity.current()); + p.drawPixmap(0, 0, _cache); + } +} + +void PasscodeBox::animStep(float64 dt) { + if (dt >= 1) { + a_opacity.finish(); + _cache = QPixmap(); + if (!_hiding) { + showAll(); + if (_oldPasscode.isHidden()) { + _newPasscode.setFocus(); + } else { + _oldPasscode.setFocus(); + } + } + } else { + a_opacity.update(dt, anim::linear); + } + update(); +} + +void PasscodeBox::onSave() { + QString old = _oldPasscode.text(), pwd = _newPasscode.text(), conf = _reenterPasscode.text(); + if (_turningOff || cHasPasscode()) { + if (Local::checkPasscode(old.toUtf8())) { + if (_turningOff) pwd = conf = QString(); + } else { + _oldPasscode.setDisabled(true); + _newPasscode.setDisabled(true); + _reenterPasscode.setDisabled(true); + _saveButton.setDisabled(true); + _oldError = QString(); + update(); + _badOldTimer.start(WrongPasscodeTimeout); + return; + } + } + if (!_turningOff && pwd.isEmpty()) { + _newPasscode.setFocus(); + _newPasscode.notaBene(); + return; + } + if (pwd != conf) { + _reenterPasscode.setFocus(); + _reenterPasscode.notaBene(); + if (!conf.isEmpty()) { + _newError = lang(lng_passcode_differ); + update(); + } + } else if (!_turningOff && cHasPasscode() && old == pwd) { + _newPasscode.setFocus(); + _newPasscode.notaBene(); + _newError = lang(lng_passcode_is_same); + update(); + } else { + Local::setPasscode(pwd.toUtf8()); + App::wnd()->checkAutoLock(); + App::wnd()->getTitle()->showUpdateBtn(); + emit closed(); + } +} + +void PasscodeBox::onBadOldPasscode() { + _oldPasscode.setDisabled(false); + _newPasscode.setDisabled(false); + _reenterPasscode.setDisabled(false); + _saveButton.setDisabled(false); + _oldPasscode.selectAll(); + _oldPasscode.setFocus(); + _oldPasscode.notaBene(); + _oldError = lang(lng_passcode_wrong); + update(); +} + +void PasscodeBox::onOldChanged() { + if (!_oldError.isEmpty()) { + _oldError = QString(); + update(); + } +} + +void PasscodeBox::onNewChanged() { + if (!_newError.isEmpty()) { + _newError = QString(); + update(); + } +} + +void PasscodeBox::onCancel() { + emit closed(); +} + +void PasscodeBox::startHide() { + _hiding = true; + if (_cache.isNull()) { + _cache = myGrab(this, rect()); + hideAll(); + } + a_opacity.start(0); +} + +PasscodeBox::~PasscodeBox() { +} diff --git a/Telegram/SourceFiles/boxes/passcodebox.h b/Telegram/SourceFiles/boxes/passcodebox.h new file mode 100644 index 000000000..7e1d33b3f --- /dev/null +++ b/Telegram/SourceFiles/boxes/passcodebox.h @@ -0,0 +1,64 @@ +/* +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. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include "layerwidget.h" + +class PasscodeBox : public LayeredWidget { + Q_OBJECT + +public: + + PasscodeBox(bool turningOff = false); + void parentResized(); + void animStep(float64 dt); + void keyPressEvent(QKeyEvent *e); + void paintEvent(QPaintEvent *e); + void startHide(); + ~PasscodeBox(); + +public slots: + + void onSave(); + void onBadOldPasscode(); + void onOldChanged(); + void onNewChanged(); + void onCancel(); + +private: + + void hideAll(); + void showAll(); + + bool _turningOff; + + QString _boxTitle; + Text _about; + + int32 _width, _height; + FlatButton _saveButton, _cancelButton; + FlatInput _oldPasscode, _newPasscode, _reenterPasscode; + + QPixmap _cache; + + anim::fvalue a_opacity; + bool _hiding; + + QTimer _badOldTimer; + QString _oldError, _newError; +}; diff --git a/Telegram/SourceFiles/boxes/photocropbox.cpp b/Telegram/SourceFiles/boxes/photocropbox.cpp index fd975ccba..9d30e1ba4 100644 --- a/Telegram/SourceFiles/boxes/photocropbox.cpp +++ b/Telegram/SourceFiles/boxes/photocropbox.cpp @@ -19,7 +19,6 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "style.h" #include "lang.h" -#include "app.h" #include "application.h" #include "mainwidget.h" #include "photocropbox.h" diff --git a/Telegram/SourceFiles/boxes/photosendbox.cpp b/Telegram/SourceFiles/boxes/photosendbox.cpp index 92443cf62..11bcf1ac9 100644 --- a/Telegram/SourceFiles/boxes/photosendbox.cpp +++ b/Telegram/SourceFiles/boxes/photosendbox.cpp @@ -19,7 +19,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "style.h" #include "lang.h" -#include "app.h" +#include "localstorage.h" + #include "mainwidget.h" #include "photosendbox.h" @@ -205,8 +206,10 @@ void PhotoSendBox::onSend(bool ctrlShiftEnter) { if (App::main()) App::main()->confirmShareContact(ctrlShiftEnter, _phone, _fname, _lname); } else { if (!_compressed.isHidden()) { - cSetCompressPastedImage(_compressed.checked()); - App::writeUserConfig(); + if (_compressed.checked() != cCompressPastedImage()) { + cSetCompressPastedImage(_compressed.checked()); + Local::writeUserSettings(); + } } if (_compressed.isHidden() || _compressed.checked()) { _img->ctrlShiftEnter = ctrlShiftEnter; diff --git a/Telegram/SourceFiles/config.h b/Telegram/SourceFiles/config.h index 46651e840..aade792c0 100644 --- a/Telegram/SourceFiles/config.h +++ b/Telegram/SourceFiles/config.h @@ -17,8 +17,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org */ #pragma once -static const int32 AppVersion = 7018; -static const wchar_t *AppVersionStr = L"0.7.18"; +static const int32 AppVersion = 7019; +static const wchar_t *AppVersionStr = L"0.7.19"; static const bool DevChannel = true; static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)"; @@ -123,6 +123,8 @@ enum { 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, }; inline bool isServiceUser(uint64 id) { diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index 33b50dc7a..8d0edaf24 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -1544,6 +1544,8 @@ bool DialogsWidget::addNewContact(int32 uid, bool show) { } void DialogsWidget::onListScroll() { +// if (!App::self()) return; + list.loadPeerPhotos(scroll.scrollTop()); if (list.state() == DialogsListWidget::SearchedState) { if (scroll.scrollTop() > (list.searchList().size() + list.filteredList().size() + list.peopleList().size()) * st::dlgHeight - PreloadHeightsCount * scroll.height()) { diff --git a/Telegram/SourceFiles/dropdown.cpp b/Telegram/SourceFiles/dropdown.cpp index d5cc525f0..f79317068 100644 --- a/Telegram/SourceFiles/dropdown.cpp +++ b/Telegram/SourceFiles/dropdown.cpp @@ -496,7 +496,7 @@ void EmojiPanInner::mouseReleaseEvent(QMouseEvent *e) { } void EmojiPanInner::onSaveConfig() { - App::writeUserConfig(); + Local::writeUserSettings(); } void EmojiPanInner::mouseMoveEvent(QMouseEvent *e) { @@ -871,7 +871,7 @@ void EmojiPan::onTabChange() { else if (_stickers.checked()) newTab = dbietStickers; if (newTab != cEmojiTab()) { cSetEmojiTab(newTab); - App::writeUserConfig(); + Local::writeUserSettings(); _scroll.scrollToY(0); } _inner.showEmojiPack(newTab); diff --git a/Telegram/SourceFiles/gui/filedialog.cpp b/Telegram/SourceFiles/gui/filedialog.cpp index 969833b78..0fc5348ae 100644 --- a/Telegram/SourceFiles/gui/filedialog.cpp +++ b/Telegram/SourceFiles/gui/filedialog.cpp @@ -18,7 +18,6 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "stdafx.h" #include "gui/filedialog.h" -#include "app.h" #include "application.h" void filedialogInit() { diff --git a/Telegram/SourceFiles/gui/text.cpp b/Telegram/SourceFiles/gui/text.cpp index fb14d77e8..cf32afb49 100644 --- a/Telegram/SourceFiles/gui/text.cpp +++ b/Telegram/SourceFiles/gui/text.cpp @@ -19,7 +19,6 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "text.h" #include "lang.h" -#include "app.h" #include diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index dc169aa8a..86f11b378 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -25,6 +25,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "boxes/photosendbox.h" #include "mainwidget.h" #include "window.h" +#include "passcodewidget.h" +#include "window.h" #include "fileuploader.h" #include "localstorage.h" @@ -554,7 +556,7 @@ void HistoryList::dragActionFinish(const QPoint &screenPos, Qt::MouseButton butt uint32 sel = _selected.cbegin().value(); if (sel != FullItemSel && (sel & 0xFFFF) == ((sel >> 16) & 0xFFFF)) { _selected.clear(); - App::main()->activate(); + App::wnd()->setInnerFocus(); } } } @@ -1734,6 +1736,7 @@ void HistoryWidget::activate() { return; } else { App::main()->dialogsActivate(); + return; } } if (_list) { @@ -1926,7 +1929,7 @@ void HistoryWidget::showPeer(const PeerId &peer, MsgId msgId, bool force, bool l clearLoadingAround(); emit peerShown(histPeer); - return activate(); + return App::wnd()->setInnerFocus(); } updateTyping(false); } @@ -2633,7 +2636,7 @@ bool HistoryWidget::animStep(float64 ms) { } onListScroll(); } - activate(); + App::wnd()->setInnerFocus(); } else { a_bgCoord.update(dt1, st::introHideFunc); a_bgAlpha.update(dt1, st::introAlphaHideFunc); @@ -2660,7 +2663,7 @@ void HistoryWidget::onPhotoSelect() { if (cDefaultAttach() != dbidaPhoto) { cSetDefaultAttach(dbidaPhoto); - App::writeUserConfig(); + Local::writeUserSettings(); } QStringList photoExtensions(cPhotoExtensions()); @@ -2688,7 +2691,7 @@ void HistoryWidget::onDocumentSelect() { if (cDefaultAttach() != dbidaDocument) { cSetDefaultAttach(dbidaDocument); - App::writeUserConfig(); + Local::writeUserSettings(); } QStringList photoExtensions(cPhotoExtensions()); diff --git a/Telegram/SourceFiles/intro/intro.cpp b/Telegram/SourceFiles/intro/intro.cpp index d4cb35db5..b4bb82b1d 100644 --- a/Telegram/SourceFiles/intro/intro.cpp +++ b/Telegram/SourceFiles/intro/intro.cpp @@ -19,7 +19,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "lang.h" #include "style.h" -#include "app.h" +#include "localstorage.h" #include "intro/intro.h" #include "intro/introsteps.h" @@ -89,7 +89,7 @@ void IntroWidget::langChangeTo(int32 langId) { void IntroWidget::onChangeLang() { cSetLang(_langChangeTo); - App::writeConfig(); + Local::writeSettings(); cSetRestarting(true); cSetRestartingToSettings(false); App::quit(); @@ -332,8 +332,7 @@ void IntroWidget::mousePressEvent(QMouseEvent *e) { } void IntroWidget::finish(const MTPUser &user, const QImage &photo) { - wnd->setupMain(true); - wnd->startMain(user); + wnd->setupMain(true, &user); if (!photo.isNull()) { App::app()->uploadProfilePhoto(photo, MTP::authedId()); } diff --git a/Telegram/SourceFiles/intro/intro.h b/Telegram/SourceFiles/intro/intro.h index 99914fd3f..87371a9a0 100644 --- a/Telegram/SourceFiles/intro/intro.h +++ b/Telegram/SourceFiles/intro/intro.h @@ -17,9 +17,6 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org */ #pragma once -#include -#include "gui/flatbutton.h" - class Window; class IntroSteps; class IntroPhone; @@ -39,7 +36,7 @@ public: void resizeEvent(QResizeEvent *e); void mousePressEvent(QMouseEvent *e); void keyPressEvent(QKeyEvent *e); - + void updateWideMode(); void animShow(const QPixmap &bgAnimCache, bool back = false); diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index fcf5c7530..f5ec61422 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -18,6 +18,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "stdafx.h" #include "localstorage.h" +#include "lang.h" + namespace { typedef quint64 FileKey; @@ -57,7 +59,7 @@ namespace { return result; } - QString _basePath; + QString _basePath, _userBasePath; bool _started = false; _local_inner::Manager *_manager = 0; @@ -66,47 +68,81 @@ namespace { return _manager && !_basePath.isEmpty(); } - bool keyAlreadyUsed(QString &name) { - name += '0'; - if (QFileInfo(name).exists()) return true; - name[name.size() - 1] = '1'; - return QFileInfo(name).exists(); + bool _userWorking() { + return _manager && !_basePath.isEmpty() && !_userBasePath.isEmpty(); } - FileKey genKey() { - if (!_working()) return 0; + enum FileOptions { + UserPath = 0x01, + SafePath = 0x02, + }; + + bool keyAlreadyUsed(QString &name, int options = UserPath | SafePath) { + name += '0'; + if (QFileInfo(name).exists()) return true; + if (options & SafePath) { + name[name.size() - 1] = '1'; + return QFileInfo(name).exists(); + } + return false; + } + + FileKey genKey(int options = UserPath | SafePath) { + if (options & UserPath) { + if (!_userWorking()) return 0; + } else { + if (!_working()) return 0; + } FileKey result; - QString path; - path.reserve(_basePath.size() + 0x11); - path += _basePath; + QString base = (options & UserPath) ? _userBasePath : _basePath, path; + path.reserve(base.size() + 0x11); + path += base; do { result = MTP::nonce(); - path.resize(_basePath.size()); + path.resize(base.size()); path += toFilePart(result); - } while (!result || keyAlreadyUsed(path)); + } while (!result || keyAlreadyUsed(path, options)); return result; } - void clearKey(const FileKey &key, bool safe = true) { - if (!_working()) return; + void clearKey(const FileKey &key, int options = UserPath | SafePath) { + if (options & UserPath) { + if (!_userWorking()) return; + } else { + if (!_working()) return; + } - QString name; - name.reserve(_basePath.size() + 0x11); - name += _basePath; - name += toFilePart(key); - name += '0'; + QString base = (options & UserPath) ? _userBasePath : _basePath, name; + name.reserve(base.size() + 0x11); + name.append(base).append(toFilePart(key)).append('0'); QFile::remove(name); - if (safe) { + if (options & SafePath) { name[name.size() - 1] = '1'; QFile::remove(name); } } - QByteArray _passKeySalt, _passKeyEncrypted; + bool _checkStreamStatus(QDataStream &stream) { + if (stream.status() != QDataStream::Ok) { + LOG(("Bad data stream status: %1").arg(stream.status())); + return false; + } + return true; + } - mtpAuthKey _oldKey, _passKey, _localKey; + uint32 _dateTimeSize() { + return (sizeof(qint64) + sizeof(quint32) + sizeof(qint8)); + } + + uint32 _stringSize(const QString &str) { + return sizeof(quint32) + str.size() * sizeof(ushort); + } + + QByteArray _settingsSalt, _passKeySalt, _passKeyEncrypted; + + mtpAuthKey _oldKey, _settingsKey, _passKey, _localKey; void createLocalKey(const QByteArray &pass, QByteArray *salt, mtpAuthKey *result) { uchar key[LocalEncryptKeySize] = { 0 }; int32 iterCount = pass.size() ? LocalEncryptIterCount : LocalEncryptNoPwdIterCount; // dont slow down for no password @@ -169,20 +205,24 @@ namespace { }; struct FileWriteDescriptor { - FileWriteDescriptor(const FileKey &key, bool safe = true) : dataSize(0) { - init(toFilePart(key), safe); + FileWriteDescriptor(const FileKey &key, int options = UserPath | SafePath) : dataSize(0) { + init(toFilePart(key), options); } - FileWriteDescriptor(const QString &name, bool safe = true) : dataSize(0) { - init(name, safe); + FileWriteDescriptor(const QString &name, int options = UserPath | SafePath) : dataSize(0) { + init(name, options); } - void init(const QString &name, bool safe) { - if (!_working()) return; + void init(const QString &name, int options) { + if (options & UserPath) { + if (!_userWorking()) return; + } else { + if (!_working()) return; + } // detect order of read attempts and file version QString toTry[2]; - toTry[0] = _basePath + name + '0'; - if (safe) { - toTry[1] = _basePath + name + '1'; + toTry[0] = ((options & UserPath) ? _userBasePath : _basePath) + name + '0'; + if (options & SafePath) { + toTry[1] = ((options & UserPath) ? _userBasePath : _basePath) + name + '1'; QFileInfo toTry0(toTry[0]); QFileInfo toTry1(toTry[1]); if (toTry0.exists()) { @@ -224,7 +264,7 @@ namespace { return true; } - QByteArray prepareEncrypted(EncryptedDescriptor &data, const mtpAuthKey &key = _localKey) { + static QByteArray prepareEncrypted(EncryptedDescriptor &data, const mtpAuthKey &key = _localKey) { data.finish(); QByteArray &toEncrypt(data.data); @@ -274,16 +314,20 @@ namespace { } }; - bool readFile(FileReadDescriptor &result, const QString &name, bool safe = true) { - if (!_working()) return false; - + bool readFile(FileReadDescriptor &result, const QString &name, int options = UserPath | SafePath) { + if (options & UserPath) { + if (!_userWorking()) return false; + } else { + if (!_working()) return false; + } + // detect order of read attempts QString toTry[2]; - toTry[0] = _basePath + name + '0'; - if (safe) { + toTry[0] = ((options & UserPath) ? _userBasePath : _basePath) + name + '0'; + if (options & SafePath) { QFileInfo toTry0(toTry[0]); if (toTry0.exists()) { - toTry[1] = _basePath + name + '1'; + toTry[1] = ((options & UserPath) ? _userBasePath : _basePath) + name + '1'; QFileInfo toTry1(toTry[1]); if (toTry1.exists()) { QDateTime mod0 = toTry0.lastModified(), mod1 = toTry1.lastModified(); @@ -380,7 +424,7 @@ namespace { aesDecryptLocal(encryptedData, decrypted.data(), fullLen, &key, encryptedKey); uchar sha1Buffer[20]; if (memcmp(hashSha1(decrypted.constData(), decrypted.size(), sha1Buffer), encryptedKey, 16)) { - LOG(("App Error: bad decrypt key, data not decrypted")); + LOG(("App Info: bad decrypt key, data not decrypted - incorrect password?")); return false; } @@ -402,16 +446,16 @@ namespace { return true; } - - bool readEncryptedFile(FileReadDescriptor &result, const QString &name, bool safe = true) { - if (!readFile(result, name, safe)) { + + bool readEncryptedFile(FileReadDescriptor &result, const QString &name, int options = UserPath | SafePath, const mtpAuthKey &key = _localKey) { + if (!readFile(result, name, options)) { return false; } QByteArray encrypted; result.stream >> encrypted; EncryptedDescriptor data; - if (!decryptLocal(data, encrypted)) { + if (!decryptLocal(data, encrypted, key)) { result.stream.setDevice(0); if (result.buffer.isOpen()) result.buffer.close(); result.buffer.setBuffer(0); @@ -433,6 +477,12 @@ namespace { return true; } + bool readEncryptedFile(FileReadDescriptor &result, const FileKey &fkey, int options = UserPath | SafePath, const mtpAuthKey &key = _localKey) { + return readEncryptedFile(result, toFilePart(fkey), options, key); + } + + FileKey _dataNameKey = 0; + enum { // Local Storage Keys lskUserMap = 0, lskDraft, // data: PeerId peer @@ -443,6 +493,7 @@ namespace { lskAudios, // data: StorageKey location lskRecentStickers, // no data lskBackground, // no data + lskUserSettings, // no data }; typedef QMap DraftsMap; @@ -462,6 +513,8 @@ namespace { FileKey _backgroundKey = 0; bool _backgroundWasRead = false; + FileKey _userSettingsKey = 0; + typedef QPair FileDesc; // file, size typedef QMap StorageMap; StorageMap _imagesMap, _stickersMap, _audiosMap; @@ -502,7 +555,7 @@ namespace { quint32 size = 0; for (FileLocations::const_iterator i = _fileLocations.cbegin(); i != _fileLocations.cend(); ++i) { // location + type + namelen + name + date + size - size += sizeof(quint64) * 2 + sizeof(quint32) + sizeof(quint32) + i.value().name.size() * sizeof(ushort) + (sizeof(qint64) + sizeof(quint32) + sizeof(qint8)) + sizeof(quint32); + size += sizeof(quint64) * 2 + sizeof(quint32) + _stringSize(i.value().name) + _dateTimeSize() + sizeof(quint32); } EncryptedDescriptor data(size); for (FileLocations::const_iterator i = _fileLocations.cbegin(); i != _fileLocations.cend(); ++i) { @@ -515,7 +568,7 @@ namespace { void _readLocations() { FileReadDescriptor locations; - if (!readEncryptedFile(locations, toFilePart(_locationsKey))) { + if (!readEncryptedFile(locations, _locationsKey)) { clearKey(_locationsKey); _locationsKey = 0; _writeMap(); @@ -540,24 +593,653 @@ namespace { } } + mtpDcOptions *_dcOpts = 0; + bool _readSetting(quint32 blockId, QDataStream &stream, int version) { + switch (blockId) { + case dbiDcOption: { + quint32 dcId, port; + QString host, ip; + stream >> dcId >> host >> ip >> port; + if (!_checkStreamStatus(stream)) return false; + + if (_dcOpts) _dcOpts->insert(dcId, mtpDcOption(dcId, host.toUtf8().constData(), ip.toUtf8().constData(), port)); + } break; + + case dbiMaxGroupCount: { + qint32 maxSize; + stream >> maxSize; + if (!_checkStreamStatus(stream)) return false; + + cSetMaxGroupCount(maxSize); + } break; + + case dbiUser: { + quint32 dcId; + qint32 uid; + stream >> uid >> dcId; + if (!_checkStreamStatus(stream)) return false; + + DEBUG_LOG(("MTP Info: user found, dc %1, uid %2").arg(dcId).arg(uid)); + MTP::configure(dcId, uid); + } break; + + case dbiKey: { + qint32 dcId; + quint32 key[64]; + stream >> dcId; + stream.readRawData((char*)key, 256); + if (!_checkStreamStatus(stream)) return false; + + DEBUG_LOG(("MTP Info: key found, dc %1, key: %2").arg(dcId).arg(mb(key, 256).str())); + dcId = dcId % _mtp_internal::dcShift; + mtpAuthKeyPtr keyPtr(new mtpAuthKey()); + keyPtr->setKey(key); + keyPtr->setDC(dcId); + + MTP::setKey(dcId, keyPtr); + } 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 dbiSoundNotify: { + qint32 v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + cSetSoundNotify(v == 1); + } break; + + case dbiDesktopNotify: { + qint32 v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + cSetDesktopNotify(v == 1); + } break; + + case dbiWorkMode: { + qint32 v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + switch (v) { + case dbiwmTrayOnly: cSetWorkMode(dbiwmTrayOnly); break; + case dbiwmWindowOnly: cSetWorkMode(dbiwmWindowOnly); break; + default: cSetWorkMode(dbiwmWindowAndTray); break; + }; + } break; + + case dbiConnectionType: { + qint32 v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + switch (v) { + case dbictHttpProxy: + case dbictTcpProxy: { + ConnectionProxy p; + qint32 port; + stream >> p.host >> port >> p.user >> p.password; + if (!_checkStreamStatus(stream)) return false; + + p.port = uint32(port); + cSetConnectionProxy(p); + } + cSetConnectionType(DBIConnectionType(v)); + break; + case dbictHttpAuto: + default: cSetConnectionType(dbictAuto); break; + }; + } 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); + } break; + + case dbiLastUpdateCheck: { + qint32 v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + cSetLastUpdateCheck(v); + } break; + + case dbiScale: { + qint32 v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + DBIScale s = cRealScale(); + switch (v) { + case dbisAuto: s = dbisAuto; break; + case dbisOne: s = dbisOne; break; + case dbisOneAndQuarter: s = dbisOneAndQuarter; break; + case dbisOneAndHalf: s = dbisOneAndHalf; break; + case dbisTwo: s = dbisTwo; break; + } + if (cRetina()) s = dbisOne; + cSetConfigScale(s); + cSetRealScale(s); + } break; + + case dbiLang: { + qint32 v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + if (v == languageTest || (v >= 0 && v < languageCount)) { + cSetLang(v); + } + } break; + + case dbiLangFile: { + QString v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + cSetLangFile(v); + } break; + + case dbiWindowPosition: { + TWindowPos pos; + stream >> pos.x >> pos.y >> pos.w >> pos.h >> pos.moncrc >> pos.maximized; + if (!_checkStreamStatus(stream)) return false; + + cSetWindowPos(pos); + } break; + + case dbiLoggedPhoneNumber: { + QString v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + cSetLoggedPhoneNumber(v); + } break; + + case dbiMutePeer: { // deprecated + quint64 peerId; + stream >> peerId; + if (!_checkStreamStatus(stream)) return false; + } break; + + case dbiMutedPeers: { // 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; + } break; + + case dbiSendKey: { + qint32 v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + cSetCtrlEnter(v == dbiskCtrlEnter); + } break; + + case dbiCatsAndDogs: { // deprecated + qint32 v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + } break; + + case dbiTileBackground: { + qint32 v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + cSetTileBackground(v == 1); + } break; + + case dbiAutoLock: { + qint32 v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + cSetAutoLock(v); + } break; + + case dbiReplaceEmojis: { + qint32 v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + cSetReplaceEmojis(v == 1); + } break; + + case dbiDefaultAttach: { + qint32 v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + switch (v) { + case dbidaPhoto: cSetDefaultAttach(dbidaPhoto); break; + default: cSetDefaultAttach(dbidaDocument); break; + } + } break; + + case dbiNotifyView: { + qint32 v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + switch (v) { + case dbinvShowNothing: cSetNotifyView(dbinvShowNothing); break; + case dbinvShowName: cSetNotifyView(dbinvShowName); break; + default: cSetNotifyView(dbinvShowPreview); break; + } + } break; + + case dbiAskDownloadPath: { + qint32 v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + cSetAskDownloadPath(v == 1); + } break; + + case dbiDownloadPath: { + QString v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + cSetDownloadPath(v); + } break; + + case dbiCompressPastedImage: { + qint32 v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + cSetCompressPastedImage(v == 1); + } break; + + case dbiEmojiTab: { + qint32 v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + switch (v) { + case dbietRecent: cSetEmojiTab(dbietRecent); break; + case dbietPeople: cSetEmojiTab(dbietPeople); break; + case dbietNature: cSetEmojiTab(dbietNature); break; + case dbietObjects: cSetEmojiTab(dbietObjects); break; + case dbietPlaces: cSetEmojiTab(dbietPlaces); break; + case dbietSymbols: cSetEmojiTab(dbietSymbols); break; + case dbietStickers: cSetEmojiTab(dbietStickers); break; + } + } break; + + case dbiRecentEmojis: { + RecentEmojiPreload v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + cSetRecentEmojisPreload(v); + } break; + + default: + LOG(("App Error: unknown blockId in _readSetting: %1").arg(blockId)); + return false; + } + + return true; + } + + bool _readOldSettings(bool remove = true) { + bool result = false; + QFile file(cWorkingDir() + qsl("tdata/config")); + if (file.open(QIODevice::ReadOnly)) { + LOG(("App Info: reading old config..")); + QDataStream stream(&file); + stream.setVersion(QDataStream::Qt_5_1); + + qint32 version = 0; + while (!stream.atEnd()) { + quint32 blockId; + stream >> blockId; + if (!_checkStreamStatus(stream)) break; + + if (blockId == dbiVersion) { + stream >> version; + if (!_checkStreamStatus(stream)) break; + + if (version > AppVersion) break; + } else if (!_readSetting(blockId, stream, version)) { + break; + } + } + file.close(); + result = true; + } + if (remove) file.remove(); + return result; + } + + void _readOldUserSettingsFields(QIODevice *device, qint32 &version) { + QDataStream stream(device); + stream.setVersion(QDataStream::Qt_5_1); + + while (!stream.atEnd()) { + quint32 blockId; + stream >> blockId; + if (!_checkStreamStatus(stream)) { + break; + } + + if (blockId == dbiVersion) { + stream >> version; + if (!_checkStreamStatus(stream)) { + break; + } + + if (version > AppVersion) return; + } else if (blockId == dbiEncryptedWithSalt) { + QByteArray salt, data, decrypted; + stream >> salt >> data; + if (!_checkStreamStatus(stream)) { + break; + } + + if (salt.size() != 32) { + LOG(("App Error: bad salt in old user config encrypted part, size: %1").arg(salt.size())); + continue; + } + + createLocalKey(QByteArray(), &salt, &_oldKey); + + if (data.size() <= 16 || (data.size() & 0x0F)) { + LOG(("App Error: bad encrypted part size in old user config: %1").arg(data.size())); + continue; + } + uint32 fullDataLen = data.size() - 16; + decrypted.resize(fullDataLen); + const char *dataKey = data.constData(), *encrypted = data.constData() + 16; + aesDecryptLocal(encrypted, decrypted.data(), fullDataLen, &_oldKey, dataKey); + uchar sha1Buffer[20]; + if (memcmp(hashSha1(decrypted.constData(), decrypted.size(), sha1Buffer), dataKey, 16)) { + LOG(("App Error: bad decrypt key, data from old user config not decrypted")); + continue; + } + uint32 dataLen = *(const uint32*)decrypted.constData(); + if (dataLen > uint32(decrypted.size()) || dataLen <= fullDataLen - 16 || dataLen < 4) { + LOG(("App Error: bad decrypted part size in old user config: %1, fullDataLen: %2, decrypted size: %3").arg(dataLen).arg(fullDataLen).arg(decrypted.size())); + continue; + } + decrypted.resize(dataLen); + QBuffer decryptedStream(&decrypted); + decryptedStream.open(QIODevice::ReadOnly); + decryptedStream.seek(4); // skip size + LOG(("App Info: reading encrypted old user config..")); + + _readOldUserSettingsFields(&decryptedStream, version); + } else if (!_readSetting(blockId, stream, version)) { + return; + } + } + } + + bool _readOldUserSettings(bool remove = true) { + bool result = false; + QFile file(cWorkingDir() + cDataFile() + qsl("_config")); + if (file.open(QIODevice::ReadOnly)) { + LOG(("App Info: reading old user config..")); + qint32 version = 0; + + mtpDcOptions dcOpts(cDcOptions()); + _dcOpts = &dcOpts; + _readOldUserSettingsFields(&file, version); + cSetDcOptions(dcOpts); + + file.close(); + result = true; + } + if (remove) file.remove(); + return result; + } + + void _readOldMtpDataFields(QIODevice *device, qint32 &version) { + QDataStream stream(device); + stream.setVersion(QDataStream::Qt_5_1); + + while (!stream.atEnd()) { + quint32 blockId; + stream >> blockId; + if (!_checkStreamStatus(stream)) { + break; + } + + if (blockId == dbiVersion) { + stream >> version; + if (!_checkStreamStatus(stream)) { + break; + } + + if (version > AppVersion) return; + } else if (blockId == dbiEncrypted) { + QByteArray data, decrypted; + stream >> data; + if (!_checkStreamStatus(stream)) { + break; + } + + if (!_oldKey.created()) { + LOG(("MTP Error: reading old encrypted keys without old key!")); + continue; + } + + if (data.size() <= 16 || (data.size() & 0x0F)) { + LOG(("MTP Error: bad encrypted part size in old keys: %1").arg(data.size())); + continue; + } + uint32 fullDataLen = data.size() - 16; + decrypted.resize(fullDataLen); + const char *dataKey = data.constData(), *encrypted = data.constData() + 16; + aesDecryptLocal(encrypted, decrypted.data(), fullDataLen, &_oldKey, dataKey); + uchar sha1Buffer[20]; + if (memcmp(hashSha1(decrypted.constData(), decrypted.size(), sha1Buffer), dataKey, 16)) { + LOG(("MTP Error: bad decrypt key, data from old keys not decrypted")); + continue; + } + uint32 dataLen = *(const uint32*)decrypted.constData(); + if (dataLen > uint32(decrypted.size()) || dataLen <= fullDataLen - 16 || dataLen < 4) { + LOG(("MTP Error: bad decrypted part size in old keys: %1, fullDataLen: %2, decrypted size: %3").arg(dataLen).arg(fullDataLen).arg(decrypted.size())); + continue; + } + decrypted.resize(dataLen); + QBuffer decryptedStream(&decrypted); + decryptedStream.open(QIODevice::ReadOnly); + decryptedStream.seek(4); // skip size + LOG(("App Info: reading encrypted old keys..")); + + _readOldMtpDataFields(&decryptedStream, version); + } else if (!_readSetting(blockId, stream, version)) { + return; + } + } + } + + bool _readOldMtpData(bool remove = true) { + bool result = false; + QFile file(cWorkingDir() + cDataFile()); + if (file.open(QIODevice::ReadOnly)) { + LOG(("App Info: reading old keys..")); + qint32 version = 0; + + mtpDcOptions dcOpts(cDcOptions()); + _dcOpts = &dcOpts; + _readOldMtpDataFields(&file, version); + cSetDcOptions(dcOpts); + + file.close(); + result = true; + } + if (remove) file.remove(); + return result; + } + + void _writeUserSettings() { + if (!_userSettingsKey) { + _userSettingsKey = genKey(); + _mapChanged = true; + _writeMap(WriteMapFast); + } + + uint32 size = 11 * (sizeof(quint32) + sizeof(qint32)); + size += sizeof(quint32) + _stringSize(cAskDownloadPath() ? QString() : cDownloadPath()); + size += sizeof(quint32) + sizeof(qint32) + cGetRecentEmojis().size() * (sizeof(uint32) + sizeof(ushort)); + + EncryptedDescriptor data(size); + data.stream << quint32(dbiSendKey) << qint32(cCtrlEnter() ? dbiskCtrlEnter : dbiskEnter); + data.stream << quint32(dbiTileBackground) << qint32(cTileBackground() ? 1 : 0); + data.stream << quint32(dbiAutoLock) << qint32(cAutoLock()); + data.stream << quint32(dbiReplaceEmojis) << qint32(cReplaceEmojis() ? 1 : 0); + data.stream << quint32(dbiDefaultAttach) << qint32(cDefaultAttach()); + data.stream << quint32(dbiSoundNotify) << qint32(cSoundNotify()); + data.stream << quint32(dbiDesktopNotify) << qint32(cDesktopNotify()); + data.stream << quint32(dbiNotifyView) << qint32(cNotifyView()); + data.stream << quint32(dbiAskDownloadPath) << qint32(cAskDownloadPath()); + data.stream << quint32(dbiDownloadPath) << (cAskDownloadPath() ? QString() : cDownloadPath()); + data.stream << quint32(dbiCompressPastedImage) << qint32(cCompressPastedImage()); + data.stream << quint32(dbiEmojiTab) << qint32(cEmojiTab()); + + RecentEmojiPreload v; + v.reserve(cGetRecentEmojis().size()); + for (RecentEmojiPack::const_iterator i = cGetRecentEmojis().cbegin(), e = cGetRecentEmojis().cend(); i != e; ++i) { + v.push_back(qMakePair(i->first->code, i->second)); + } + data.stream << quint32(dbiRecentEmojis) << v; + + FileWriteDescriptor file(_userSettingsKey); + file.writeEncrypted(data); + } + + void _readUserSettings() { + FileReadDescriptor userSettings; + if (!readEncryptedFile(userSettings, _userSettingsKey)) { + _readOldUserSettings(); + return _writeUserSettings(); + } + + LOG(("App Info: reading encrypted user settings..")); + while (!userSettings.stream.atEnd()) { + quint32 blockId; + userSettings.stream >> blockId; + if (!_checkStreamStatus(userSettings.stream)) { + return _writeUserSettings(); + } + + if (!_readSetting(blockId, userSettings.stream, userSettings.version)) { + return _writeUserSettings(); + } + } + } + + void _writeMtpData() { + FileWriteDescriptor mtp(toFilePart(_dataNameKey), SafePath); + if (!_localKey.created()) { + LOG(("App Error: localkey not created in _writeMtpData()")); + return; + } + + mtpKeysMap keys = MTP::getKeys(); + + quint32 size = sizeof(quint32) + sizeof(qint32) + sizeof(quint32); + size += keys.size() * (sizeof(quint32) + sizeof(quint32) + 256); + + EncryptedDescriptor data(size); + data.stream << quint32(dbiUser) << qint32(MTP::authedId()) << quint32(MTP::maindc()); + for (mtpKeysMap::const_iterator i = keys.cbegin(), e = keys.cend(); i != e; ++i) { + data.stream << quint32(dbiKey) << quint32((*i)->getDC()); + (*i)->write(data.stream); + } + + mtp.writeEncrypted(data, _localKey); + } + + void _readMtpData() { + FileReadDescriptor mtp; + if (!readEncryptedFile(mtp, toFilePart(_dataNameKey), SafePath)) { + if (_localKey.created()) { + _readOldMtpData(); + _writeMtpData(); + } + return; + } + + LOG(("App Info: reading encrypted mtp data..")); + while (!mtp.stream.atEnd()) { + quint32 blockId; + mtp.stream >> blockId; + if (!_checkStreamStatus(mtp.stream)) { + return _writeMtpData(); + } + + if (!_readSetting(blockId, mtp.stream, mtp.version)) { + return _writeMtpData(); + } + } + } + Local::ReadMapState _readMap(const QByteArray &pass) { uint64 ms = getms(); QByteArray dataNameUtf8 = cDataFile().toUtf8(); - uint64 dataNameHash[2]; + FileKey dataNameHash[2]; hashMd5(dataNameUtf8.constData(), dataNameUtf8.size(), dataNameHash); - _basePath = cWorkingDir() + qsl("tdata/") + toFilePart(dataNameHash[0]) + QChar('/'); + _dataNameKey = dataNameHash[0]; + _userBasePath = _basePath + toFilePart(_dataNameKey) + QChar('/'); FileReadDescriptor mapData; if (!readFile(mapData, qsl("map"))) { return Local::ReadMapFailed; } + LOG(("App Info: reading map..")); QByteArray salt, keyEncrypted, mapEncrypted; mapData.stream >> salt >> keyEncrypted >> mapEncrypted; - if (mapData.stream.status() != QDataStream::Ok) { - LOG(("App Error: could not read salt / key from map file - corrupted?..").arg(mapData.stream.status())); + if (!_checkStreamStatus(mapData.stream)) { return Local::ReadMapFailed; } + if (salt.size() != LocalEncryptSaltSize) { LOG(("App Error: bad salt in map file, size: %1").arg(salt.size())); return Local::ReadMapFailed; @@ -566,7 +1248,7 @@ namespace { EncryptedDescriptor keyData, map; if (!decryptLocal(keyData, keyEncrypted, _passKey)) { - LOG(("App Error: could not decrypt pass-protected key from map file, maybe bad password..")); + LOG(("App Info: could not decrypt pass-protected key from map file, maybe bad password..")); return Local::ReadMapPassNeeded; } uchar key[LocalEncryptKeySize] = { 0 }; @@ -583,12 +1265,13 @@ namespace { LOG(("App Error: could not decrypt map.")); return Local::ReadMapFailed; } + LOG(("App Info: reading encrypted map..")); DraftsMap draftsMap, draftsPositionsMap; DraftsNotReadMap draftsNotReadMap; StorageMap imagesMap, stickersMap, audiosMap; qint64 storageImagesSize = 0, storageStickersSize = 0, storageAudiosSize = 0; - quint64 locationsKey = 0, recentStickersKey = 0, backgroundKey = 0; + quint64 locationsKey = 0, recentStickersKey = 0, backgroundKey = 0, userSettingsKey = 0; while (!map.stream.atEnd()) { quint32 keyType; map.stream >> keyType; @@ -659,12 +1342,14 @@ namespace { case lskBackground: { map.stream >> backgroundKey; } break; + case lskUserSettings: { + map.stream >> userSettingsKey; + } break; default: LOG(("App Error: unknown key type in encrypted map: %1").arg(keyType)); return Local::ReadMapFailed; } - if (map.stream.status() != QDataStream::Ok) { - LOG(("App Error: reading encrypted map bad status: %1").arg(map.stream.status())); + if (!_checkStreamStatus(map.stream)) { return Local::ReadMapFailed; } } @@ -683,6 +1368,7 @@ namespace { _locationsKey = locationsKey; _recentStickersKey = recentStickersKey; _backgroundKey = backgroundKey; + _userSettingsKey = userSettingsKey; _oldMapVersion = mapData.version; if (_oldMapVersion < AppVersion) { _mapChanged = true; @@ -695,6 +1381,9 @@ namespace { _readLocations(); } + _readUserSettings(); + _readMtpData(); + LOG(("Map read time: %1").arg(getms() - ms)); return Local::ReadMapDone; } @@ -706,12 +1395,12 @@ namespace { } _manager->writingMap(); if (!_mapChanged) return; - if (_basePath.isEmpty()) { - LOG(("App Error: _basePath is empty in writeMap()")); + if (_userBasePath.isEmpty()) { + LOG(("App Error: _userBasePath is empty in writeMap()")); return; } - QDir().mkpath(_basePath); + if (!QDir().exists(_userBasePath)) QDir().mkpath(_userBasePath); FileWriteDescriptor map(qsl("map")); if (_passKeySalt.isEmpty() || _passKeyEncrypted.isEmpty()) { @@ -727,7 +1416,7 @@ namespace { EncryptedDescriptor passKeyData(LocalEncryptKeySize); _localKey.write(passKeyData.stream); - _passKeyEncrypted = map.prepareEncrypted(passKeyData, _passKey); + _passKeyEncrypted = FileWriteDescriptor::prepareEncrypted(passKeyData, _passKey); } map.writeData(_passKeySalt); map.writeData(_passKeyEncrypted); @@ -739,6 +1428,7 @@ namespace { if (!_stickersMap.isEmpty()) mapSize += sizeof(quint32) * 2 + _stickersMap.size() * (sizeof(quint64) * 3 + sizeof(qint32)); if (!_audiosMap.isEmpty()) mapSize += sizeof(quint32) * 2 + _audiosMap.size() * (sizeof(quint64) * 3 + sizeof(qint32)); if (_locationsKey) mapSize += sizeof(quint32) + sizeof(quint64); + if (_userSettingsKey) mapSize += sizeof(quint32) + sizeof(quint64); if (_recentStickersKey) mapSize += sizeof(quint32) + sizeof(quint64); if (_backgroundKey) mapSize += sizeof(quint32) + sizeof(quint64); EncryptedDescriptor mapData(mapSize); @@ -775,6 +1465,9 @@ namespace { if (_locationsKey) { mapData.stream << quint32(lskLocations) << quint64(_locationsKey); } + if (_userSettingsKey) { + mapData.stream << quint32(lskUserSettings) << quint64(_userSettingsKey); + } if (_recentStickersKey) { mapData.stream << quint32(lskRecentStickers) << quint64(_recentStickersKey); } @@ -783,8 +1476,6 @@ namespace { } map.writeEncrypted(mapData); - map.finish(); - _mapChanged = false; } @@ -844,14 +1535,6 @@ namespace _local_inner { namespace Local { - mtpAuthKey &oldKey() { - return _oldKey; - } - - void createOldKey(QByteArray *salt) { - createLocalKey(QByteArray(), salt, &_oldKey); - } - void start() { if (!_started) { _started = true; @@ -868,6 +1551,177 @@ namespace Local { } } + void readSettings() { + Local::start(); + + _basePath = cWorkingDir() + qsl("tdata/"); + if (!QDir().exists(_basePath)) QDir().mkpath(_basePath); + + FileReadDescriptor settingsData; + if (!readFile(settingsData, qsl("settings"), SafePath)) { + _readOldSettings(); + _readOldUserSettings(false); // needed further in _readUserSettings + _readOldMtpData(false); // needed further in _readMtpData + return writeSettings(); + } + LOG(("App Info: reading settings..")); + + QByteArray salt, settingsEncrypted; + settingsData.stream >> salt >> settingsEncrypted; + if (!_checkStreamStatus(settingsData.stream)) { + return writeSettings(); + } + + if (salt.size() != LocalEncryptSaltSize) { + LOG(("App Error: bad salt in settings file, size: %1").arg(salt.size())); + return writeSettings(); + } + createLocalKey(QByteArray(), &salt, &_settingsKey); + + EncryptedDescriptor settings; + if (!decryptLocal(settings, settingsEncrypted, _settingsKey)) { + LOG(("App Error: could not decrypt settings from settings file, maybe bad passcode..")); + return writeSettings(); + } + mtpDcOptions dcOpts(cDcOptions()); + _dcOpts = &dcOpts; + LOG(("App Info: reading encrypted settings..")); + while (!settings.stream.atEnd()) { + quint32 blockId; + settings.stream >> blockId; + if (!_checkStreamStatus(settings.stream)) { + return writeSettings(); + } + + if (!_readSetting(blockId, settings.stream, settingsData.version)) { + return writeSettings(); + } + } + if (dcOpts.isEmpty()) { + const BuiltInDc *bdcs = builtInDcs(); + for (int i = 0, l = builtInDcsCount(); i < l; ++i) { + dcOpts.insert(bdcs[i].id, mtpDcOption(bdcs[i].id, "", bdcs[i].ip, bdcs[i].port)); + DEBUG_LOG(("MTP Info: adding built in DC %1 connect option: %2:%3").arg(bdcs[i].id).arg(bdcs[i].ip).arg(bdcs[i].port)); + } + } + cSetDcOptions(dcOpts); + + _settingsSalt = salt; + } + + void writeSettings() { + if (_basePath.isEmpty()) { + LOG(("App Error: _basePath is empty in writeSettings()")); + return; + } + + if (!QDir().exists(_basePath)) QDir().mkpath(_basePath); + + FileWriteDescriptor settings(qsl("settings"), SafePath); + if (_settingsSalt.isEmpty() || !_settingsKey.created()) { + _settingsSalt.resize(LocalEncryptSaltSize); + memset_rand(_settingsSalt.data(), _settingsSalt.size()); + createLocalKey(QByteArray(), &_settingsSalt, &_settingsKey); + } + settings.writeData(_settingsSalt); + + mtpDcOptions dcOpts(cDcOptions()); + if (dcOpts.isEmpty()) { + const BuiltInDc *bdcs = builtInDcs(); + for (int i = 0, l = builtInDcsCount(); i < l; ++i) { + dcOpts.insert(bdcs[i].id, mtpDcOption(bdcs[i].id, "", bdcs[i].ip, bdcs[i].port)); + DEBUG_LOG(("MTP Info: adding built in DC %1 connect option: %2:%3").arg(bdcs[i].id).arg(bdcs[i].ip).arg(bdcs[i].port)); + } + cSetDcOptions(dcOpts); + } + + quint32 size = 10 * (sizeof(quint32) + sizeof(qint32)); + for (mtpDcOptions::const_iterator i = dcOpts.cbegin(), e = dcOpts.cend(); i != e; ++i) { + size += sizeof(quint32) + sizeof(quint32) + sizeof(quint32); + size += _stringSize(QString::fromUtf8(i->host.data(), i->host.size())) + _stringSize(QString::fromUtf8(i->ip.data(), i->ip.size())); + } + size += sizeof(quint32) + _stringSize(cLangFile()); + + size += sizeof(quint32) + sizeof(qint32); + if (cConnectionType() == dbictHttpProxy || cConnectionType() == dbictTcpProxy) { + const ConnectionProxy &proxy(cConnectionProxy()); + size += _stringSize(proxy.host) + sizeof(qint32) + _stringSize(proxy.user) + _stringSize(proxy.password); + } + + size += sizeof(quint32) + sizeof(qint32) * 6; + + EncryptedDescriptor data(size); + data.stream << quint32(dbiMaxGroupCount) << qint32(cMaxGroupCount()); + data.stream << quint32(dbiAutoStart) << qint32(cAutoStart()); + data.stream << quint32(dbiStartMinimized) << qint32(cStartMinimized()); + data.stream << quint32(dbiSendToMenu) << qint32(cSendToMenu()); + data.stream << quint32(dbiWorkMode) << qint32(cWorkMode()); + data.stream << quint32(dbiSeenTrayTooltip) << qint32(cSeenTrayTooltip()); + data.stream << quint32(dbiAutoUpdate) << qint32(cAutoUpdate()); + data.stream << quint32(dbiLastUpdateCheck) << qint32(cLastUpdateCheck()); + data.stream << quint32(dbiScale) << qint32(cConfigScale()); + data.stream << quint32(dbiLang) << qint32(cLang()); + for (mtpDcOptions::const_iterator i = dcOpts.cbegin(), e = dcOpts.cend(); i != e; ++i) { + data.stream << quint32(dbiDcOption) << quint32(i->id); + data.stream << QString::fromUtf8(i->host.data(), i->host.size()) << QString::fromUtf8(i->ip.data(), i->ip.size()); + data.stream << quint32(i->port); + } + data.stream << quint32(dbiLangFile) << cLangFile(); + + data.stream << quint32(dbiConnectionType) << qint32(cConnectionType()); + if (cConnectionType() == dbictHttpProxy || cConnectionType() == dbictTcpProxy) { + const ConnectionProxy &proxy(cConnectionProxy()); + data.stream << proxy.host << qint32(proxy.port) << proxy.user << proxy.password; + } + + TWindowPos pos(cWindowPos()); + data.stream << quint32(dbiWindowPosition) << qint32(pos.x) << qint32(pos.y) << qint32(pos.w) << qint32(pos.h) << qint32(pos.moncrc) << qint32(pos.maximized); + + settings.writeEncrypted(data, _settingsKey); + } + + void writeUserSettings() { + _writeUserSettings(); + } + + void writeMtpData() { + _writeMtpData(); + } + + void reset() { + _passKeySalt.clear(); // reset passcode, local key + _draftsMap.clear(); + _draftsPositionsMap.clear(); + _imagesMap.clear(); + _draftsNotReadMap.clear(); + _stickersMap.clear(); + _audiosMap.clear(); + _locationsKey = _userSettingsKey = _recentStickersKey = _backgroundKey = 0; + _mapChanged = true; + _writeMap(WriteMapNow); + + _writeMtpData(); + } + + bool checkPasscode(const QByteArray &passcode) { + mtpAuthKey tmp; + createLocalKey(passcode, &_passKeySalt, &tmp); + return (tmp == _passKey); + } + + void setPasscode(const QByteArray &passcode) { + createLocalKey(passcode, &_passKeySalt, &_passKey); + + EncryptedDescriptor passKeyData(LocalEncryptKeySize); + _localKey.write(passKeyData.stream); + _passKeyEncrypted = FileWriteDescriptor::prepareEncrypted(passKeyData, _passKey); + + _mapChanged = true; + _writeMap(WriteMapNow); + + cSetHasPasscode(!passcode.isEmpty()); + } + ReadMapState readMap(const QByteArray &pass) { ReadMapState result = _readMap(pass); if (result == ReadMapFailed) { @@ -901,8 +1755,7 @@ namespace Local { _mapChanged = true; _writeMap(WriteMapFast); } - QString to = _basePath + toFilePart(i.value()); - EncryptedDescriptor data(sizeof(quint64) + sizeof(quint32) + text.size() * sizeof(QChar)); + EncryptedDescriptor data(sizeof(quint64) + _stringSize(text)); data.stream << quint64(peer) << text; FileWriteDescriptor file(i.value()); file.writeEncrypted(data); @@ -919,7 +1772,7 @@ namespace Local { return QString(); } FileReadDescriptor draft; - if (!readEncryptedFile(draft, toFilePart(j.value()))) { + if (!readEncryptedFile(draft, j.value())) { clearKey(j.value()); _draftsMap.erase(j); return QString(); @@ -949,7 +1802,6 @@ namespace Local { _mapChanged = true; _writeMap(WriteMapFast); } - QString to = _basePath + toFilePart(i.value()); EncryptedDescriptor data(sizeof(quint64) + sizeof(qint32) * 3); data.stream << quint64(peer) << qint32(cur.position) << qint32(cur.anchor) << qint32(cur.scroll); FileWriteDescriptor file(i.value()); @@ -963,7 +1815,7 @@ namespace Local { return MessageCursor(); } FileReadDescriptor draft; - if (!readEncryptedFile(draft, toFilePart(j.value()))) { + if (!readEncryptedFile(draft, j.value())) { clearKey(j.value()); _draftsPositionsMap.erase(j); return MessageCursor(); @@ -1069,7 +1921,7 @@ namespace Local { qint32 size = _storageImageSize(image.data.size()); StorageMap::const_iterator i = _imagesMap.constFind(location); if (i == _imagesMap.cend()) { - i = _imagesMap.insert(location, FileDesc(genKey(), size)); + i = _imagesMap.insert(location, FileDesc(genKey(UserPath), size)); _storageImagesSize += size; _mapChanged = true; _writeMap(); @@ -1078,7 +1930,7 @@ namespace Local { } EncryptedDescriptor data(sizeof(quint64) * 2 + sizeof(quint32) + sizeof(quint32) + image.data.size()); data.stream << quint64(location.first) << quint64(location.second) << quint32(image.type) << image.data; - FileWriteDescriptor file(i.value().first, false); + FileWriteDescriptor file(i.value().first, UserPath); file.writeEncrypted(data); if (i.value().second != size) { _storageImagesSize += size; @@ -1093,8 +1945,8 @@ namespace Local { return StorageImageSaved(); } FileReadDescriptor draft; - if (!readEncryptedFile(draft, toFilePart(j.value().first), false)) { - clearKey(j.value().first, false); + if (!readEncryptedFile(draft, j.value().first, UserPath)) { + clearKey(j.value().first, UserPath); _storageImagesSize -= j.value().second; _imagesMap.erase(j); return StorageImageSaved(); @@ -1122,7 +1974,7 @@ namespace Local { qint32 size = _storageStickerSize(sticker.size()); StorageMap::const_iterator i = _stickersMap.constFind(location); if (i == _stickersMap.cend()) { - i = _stickersMap.insert(location, FileDesc(genKey(), size)); + i = _stickersMap.insert(location, FileDesc(genKey(UserPath), size)); _storageStickersSize += size; _mapChanged = true; _writeMap(); @@ -1131,7 +1983,7 @@ namespace Local { } EncryptedDescriptor data(sizeof(quint64) * 2 + sizeof(quint32) + sizeof(quint32) + sticker.size()); data.stream << quint64(location.first) << quint64(location.second) << sticker; - FileWriteDescriptor file(i.value().first, false); + FileWriteDescriptor file(i.value().first, UserPath); file.writeEncrypted(data); if (i.value().second != size) { _storageStickersSize += size; @@ -1146,8 +1998,8 @@ namespace Local { return QByteArray(); } FileReadDescriptor draft; - if (!readEncryptedFile(draft, toFilePart(j.value().first), false)) { - clearKey(j.value().first, false); + if (!readEncryptedFile(draft, j.value().first, UserPath)) { + clearKey(j.value().first, UserPath); _storageStickersSize -= j.value().second; _stickersMap.erase(j); return QByteArray(); @@ -1174,7 +2026,7 @@ namespace Local { qint32 size = _storageAudioSize(audio.size()); StorageMap::const_iterator i = _audiosMap.constFind(location); if (i == _audiosMap.cend()) { - i = _audiosMap.insert(location, FileDesc(genKey(), size)); + i = _audiosMap.insert(location, FileDesc(genKey(UserPath), size)); _storageAudiosSize += size; _mapChanged = true; _writeMap(); @@ -1183,7 +2035,7 @@ namespace Local { } EncryptedDescriptor data(sizeof(quint64) * 2 + sizeof(quint32) + sizeof(quint32) + audio.size()); data.stream << quint64(location.first) << quint64(location.second) << audio; - FileWriteDescriptor file(i.value().first, false); + FileWriteDescriptor file(i.value().first, UserPath); file.writeEncrypted(data); if (i.value().second != size) { _storageAudiosSize += size; @@ -1198,8 +2050,8 @@ namespace Local { return QByteArray(); } FileReadDescriptor draft; - if (!readEncryptedFile(draft, toFilePart(j.value().first), false)) { - clearKey(j.value().first, false); + if (!readEncryptedFile(draft, j.value().first, UserPath)) { + clearKey(j.value().first, UserPath); _storageAudiosSize -= j.value().second; _audiosMap.erase(j); return QByteArray(); @@ -1242,7 +2094,7 @@ namespace Local { DocumentData *doc = i->first; // id + value + access + date + namelen + name + mimelen + mime + dc + size + width + height + type - size += sizeof(quint64) + sizeof(qint16) + sizeof(quint64) + sizeof(qint32) + (sizeof(quint32) + doc->name.size() * sizeof(ushort)) + (sizeof(quint32) + doc->mime.size() * sizeof(ushort)) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32); + size += sizeof(quint64) + sizeof(qint16) + sizeof(quint64) + sizeof(qint32) + _stringSize(doc->name) + _stringSize(doc->mime) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32); } EncryptedDescriptor data(size); for (RecentStickerPack::const_iterator i = recent.cbegin(); i != recent.cend(); ++i) { @@ -1259,7 +2111,7 @@ namespace Local { if (!_recentStickersKey) return; FileReadDescriptor stickers; - if (!readEncryptedFile(stickers, toFilePart(_recentStickersKey))) { + if (!readEncryptedFile(stickers, _recentStickersKey)) { clearKey(_recentStickersKey); _recentStickersKey = 0; _writeMap(); @@ -1320,7 +2172,7 @@ namespace Local { _backgroundWasRead = true; FileReadDescriptor bg; - if (!readEncryptedFile(bg, toFilePart(_backgroundKey))) { + if (!readEncryptedFile(bg, _backgroundKey)) { clearKey(_backgroundKey); _backgroundKey = 0; _writeMap(); @@ -1491,21 +2343,34 @@ namespace Local { audios = data->audios; } switch (task) { - case ClearManagerAll: - result = (QDir(cTempDir()).removeRecursively() && QDir(_basePath).removeRecursively()); - break; + case ClearManagerAll: { + result = QDir(cTempDir()).removeRecursively(); + QDirIterator di(_userBasePath, QDir::AllEntries | QDir::Hidden | QDir::System | QDir::NoDotAndDotDot); + while (di.hasNext()) { + di.next(); + const QFileInfo& fi = di.fileInfo(); + if (fi.isDir() && !fi.isSymLink()) { + if (!QDir(di.filePath()).removeRecursively()) result = false; + } else { + QString path = di.filePath(); + if (!path.endsWith(QLatin1String("map0")) && !path.endsWith(QLatin1String("map1"))) { + if (!QFile::remove(di.filePath())) result = false; + } + } + } + } break; case ClearManagerDownloads: result = QDir(cTempDir()).removeRecursively(); break; case ClearManagerStorage: for (StorageMap::const_iterator i = images.cbegin(), e = images.cend(); i != e; ++i) { - clearKey(i.value().first, false); + clearKey(i.value().first, UserPath); } for (StorageMap::const_iterator i = stickers.cbegin(), e = stickers.cend(); i != e; ++i) { - clearKey(i.value().first, false); + clearKey(i.value().first, UserPath); } for (StorageMap::const_iterator i = audios.cbegin(), e = audios.cend(); i != e; ++i) { - clearKey(i.value().first, false); + clearKey(i.value().first, UserPath); } result = true; break; diff --git a/Telegram/SourceFiles/localstorage.h b/Telegram/SourceFiles/localstorage.h index 765a4477e..d9dc29628 100644 --- a/Telegram/SourceFiles/localstorage.h +++ b/Telegram/SourceFiles/localstorage.h @@ -50,11 +50,18 @@ namespace _local_inner { namespace Local { - mtpAuthKey &oldKey(); - void createOldKey(QByteArray *salt = 0); - void start(); void stop(); + + void readSettings(); + void writeSettings(); + void writeUserSettings(); + void writeMtpData(); + + void reset(); + + bool checkPasscode(const QByteArray &passcode); + void setPasscode(const QByteArray &passcode); enum ClearManagerTask { ClearManagerAll = 0xFFFF, diff --git a/Telegram/SourceFiles/main.cpp b/Telegram/SourceFiles/main.cpp index 68e15b3d1..33078488a 100644 --- a/Telegram/SourceFiles/main.cpp +++ b/Telegram/SourceFiles/main.cpp @@ -19,6 +19,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "application.h" #include "pspecific.h" +#include "localstorage.h" + int main(int argc, char *argv[]) { #ifdef _NEED_WIN_GENERATE_DUMP _oldWndExceptionFilter = SetUnhandledExceptionFilter(_exceptionFilter); @@ -34,9 +36,10 @@ int main(int argc, char *argv[]) { } logsInit(); - App::readConfig(); + Local::readSettings(); if (cFromAutoStart() && !cAutoStart()) { psAutoStart(false, true); + Local::stop(); return 0; } @@ -64,6 +67,7 @@ int main(int argc, char *argv[]) { } } psFinish(); + Local::stop(); DEBUG_LOG(("Application Info: Telegram done, result: %1").arg(result)); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 575a1d729..d22c33514 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -399,6 +399,8 @@ _failDifferenceTimeout(1), _lastUpdateTime(0), _cachedX(0), _cachedY(0), _backgr show(); setFocus(); + + App::initMedia(); } mtpRequestId MainWidget::onForward(const PeerId &peer, bool forwardSelected) { @@ -462,6 +464,8 @@ void MainWidget::noHider(HistoryHider *destroyed) { } void MainWidget::hiderLayer(HistoryHider *h) { + if (App::passcoded()) return; + hider = h; if (cWideMode()) { hider->show(); @@ -1249,6 +1253,7 @@ void MainWidget::onParentResize(const QSize &newSize) { } void MainWidget::updateOnlineDisplay() { + if (this != App::main()) return; history.updateOnlineDisplay(history.x(), width() - history.x() - st::sysBtnDelta * 2 - st::sysCls.img.pxWidth() - st::sysRes.img.pxWidth() - st::sysMin.img.pxWidth()); if (profile) profile->updateOnlineDisplay(); if (App::wnd()->settingsWidget()) App::wnd()->settingsWidget()->updateOnlineDisplay(); @@ -2091,6 +2096,7 @@ void MainWidget::onPeerShown(PeerData *peer) { } void MainWidget::onUpdateNotifySettings() { + if (this != App::main()) return; while (!updateNotifySettingPeers.isEmpty()) { PeerData *peer = *updateNotifySettingPeers.begin(); updateNotifySettingPeers.erase(updateNotifySettingPeers.begin()); @@ -2260,6 +2266,7 @@ void MainWidget::updUpdated(int32 pts, int32 seq) { } void MainWidget::feedDifference(const MTPVector &users, const MTPVector &chats, const MTPVector &msgs, const MTPVector &other) { + App::wnd()->checkAutoLock(); App::feedUsers(users); App::feedChats(chats); feedMessageIds(other); @@ -2283,6 +2290,8 @@ void MainWidget::getDifferenceForce() { } void MainWidget::getDifference() { + if (this != App::main()) return; + LOG(("Getting difference! no updates timer: %1, remains: %2").arg(noUpdatesTimer.isActive() ? 1 : 0).arg(noUpdatesTimer.remainingTime())); if (!updInited) return; @@ -2303,9 +2312,13 @@ void MainWidget::getDifference() { } void MainWidget::start(const MTPUser &user) { - MTP::authed(user.c_userSelf().vid.v); + int32 uid = user.c_userSelf().vid.v; + if (MTP::authedId() != uid) { + MTP::authed(uid); + Local::writeMtpData(); + } + cSetOtherOnline(0); - App::initMedia(); App::feedUsers(MTP_vector(1, user)); App::app()->startUpdateCheck(); MTP::send(MTPupdates_GetState(), rpcDone(&MainWidget::gotState)); @@ -2571,6 +2584,9 @@ MainWidget::~MainWidget() { } void MainWidget::updateOnline(bool gotOtherOffline) { + if (this != App::main()) return; + App::wnd()->checkAutoLock(); + bool isOnline = App::wnd()->isActive(); int updateIn = cOnlineUpdatePeriod(); if (isOnline) { @@ -2608,6 +2624,7 @@ void MainWidget::updateOnline(bool gotOtherOffline) { } void MainWidget::checkIdleFinish() { + if (this != App::main()) return; if (psIdleTime() < uint64(cOfflineIdleTimeout())) { _idleFinishTimer.stop(); _isIdle = false; @@ -2621,6 +2638,8 @@ void MainWidget::checkIdleFinish() { void MainWidget::updateReceived(const mtpPrime *from, const mtpPrime *end) { if (end <= from || !MTP::authedId()) return; + App::wnd()->checkAutoLock(); + if (mtpTypeId(*from) == mtpc_new_session_created) { MTPNewSession newSession(from, end); updSeq = 0; diff --git a/Telegram/SourceFiles/mtproto/mtp.cpp b/Telegram/SourceFiles/mtproto/mtp.cpp index 763da994a..8411ceed0 100644 --- a/Telegram/SourceFiles/mtproto/mtp.cpp +++ b/Telegram/SourceFiles/mtproto/mtp.cpp @@ -32,7 +32,7 @@ namespace { typedef QMap AuthExportRequests; // holds target dc for auth export request AuthExportRequests authExportRequests; - bool started = false; + bool _started = false; uint32 layer; @@ -161,7 +161,7 @@ namespace { DEBUG_LOG(("MTP Info: changing request %1 dc%2 to %3").arg(requestId).arg((dc > 0) ? "" : " and main dc").arg(newdc)); if (dc < 0) { - if (MTP::authedId()) { // import auth, set dc and resend + if (MTP::authedId() && !authExportRequests.contains(requestId)) { // import auth, set dc and resend DEBUG_LOG(("MTP Info: importing auth to dc %1").arg(newdc)); DCAuthWaiters &waiters(authWaiters[newdc]); if (!waiters.size()) { @@ -334,7 +334,7 @@ namespace { namespace _mtp_internal { MTProtoSessionPtr getSession(int32 dc) { - if (!started) return MTProtoSessionPtr(); + if (!_started) return MTProtoSessionPtr(); if (!dc) return mainSession; if (!(dc % _mtp_internal::dcShift)) { dc += mainSession->getDC(); @@ -588,19 +588,13 @@ namespace MTP { void start() { unixtimeInit(); - if (!Local::oldKey().created()) { - LOG(("App Error: trying to start MTP without local key!")); - return; - } - - mtpLoadData(); MTProtoDCMap &dcs(mtpDCMap()); mainSession = MTProtoSessionPtr(new MTProtoSession()); mainSession->start(mtpMainDC()); sessions[mainSession->getDC()] = mainSession; - started = true; + _started = true; resender = new _mtp_internal::RequestResender(); if (mtpNeedConfig()) { @@ -608,15 +602,19 @@ namespace MTP { } } + bool started() { + return _started; + } + void restart() { - if (!started) return; + if (!_started) return; for (Sessions::const_iterator i = sessions.cbegin(), e = sessions.cend(); i != e; ++i) { (*i)->restart(); } } void restart(int32 dcMask) { - if (!started) return; + if (!_started) return; for (Sessions::const_iterator i = sessions.cbegin(), e = sessions.cend(); i != e; ++i) { if ((*i)->getDC() % _mtp_internal::dcShift == dcMask % _mtp_internal::dcShift) { @@ -625,23 +623,27 @@ namespace MTP { } } - void setdc(int32 dc, bool fromZeroOnly) { - if (!started) return; - - int32 m = mainSession->getDC(); - if (!dc || m == dc || (m && fromZeroOnly)) return; + void configure(int32 dc, int32 user) { + if (_started) return; mtpSetDC(dc); - mainSession = _mtp_internal::getSession(dc); + mtpAuthed(user); + } + + void setdc(int32 dc, bool fromZeroOnly) { + if (!dc || !_started) return; + mtpSetDC(dc, fromZeroOnly); + if (dc != mainSession->getDC()) { + mainSession = _mtp_internal::getSession(dc); + } + Local::writeMtpData(); } int32 maindc() { - if (!started) return 0; - - return mainSession->getDC(); + return mtpMainDC(); } int32 dcstate(int32 dc) { - if (!started) return 0; + if (!_started) return 0; if (!dc) return mainSession->getState(); if (!(dc % _mtp_internal::dcShift)) { @@ -655,7 +657,7 @@ namespace MTP { } QString dctransport(int32 dc) { - if (!started) return QString(); + if (!_started) return QString(); if (!dc) return mainSession->transport(); if (!(dc % _mtp_internal::dcShift)) { @@ -669,7 +671,7 @@ namespace MTP { } void initdc(int32 dc) { - if (!started) return; + if (!_started) return; _mtp_internal::getSession(dc); } @@ -781,15 +783,15 @@ namespace MTP { void updateDcOptions(const QVector &options) { mtpUpdateDcOptions(options); - App::writeUserConfig(); + Local::writeSettings(); } - void writeConfig(QDataStream &stream) { - return mtpWriteConfig(stream); + mtpKeysMap getKeys() { + return mtpGetKeys(); } - bool readConfigElem(int32 blockId, QDataStream &stream) { - return mtpReadConfigElem(blockId, stream); + void setKey(int32 dc, mtpAuthKeyPtr key) { + return mtpSetKey(dc, key); } }; diff --git a/Telegram/SourceFiles/mtproto/mtp.h b/Telegram/SourceFiles/mtproto/mtp.h index e3f77da3e..5e4bc6cf7 100644 --- a/Telegram/SourceFiles/mtproto/mtp.h +++ b/Telegram/SourceFiles/mtproto/mtp.h @@ -78,11 +78,15 @@ namespace MTP { }; void start(); + bool started(); void restart(); void restart(int32 dcMask); + void configure(int32 dc, int32 user); + void setdc(int32 dc, bool fromZeroOnly = false); int32 maindc(); + int32 dcstate(int32 dc = 0); QString dctransport(int32 dc = 0); void initdc(int32 dc); @@ -131,8 +135,8 @@ namespace MTP { return result; } - void writeConfig(QDataStream &stream); - bool readConfigElem(int32 blockId, QDataStream &stream); + mtpKeysMap getKeys(); + void setKey(int32 dc, mtpAuthKeyPtr key); }; diff --git a/Telegram/SourceFiles/mtproto/mtpAuthKey.h b/Telegram/SourceFiles/mtproto/mtpAuthKey.h index 6b11a7ccf..e9431935f 100644 --- a/Telegram/SourceFiles/mtproto/mtpAuthKey.h +++ b/Telegram/SourceFiles/mtproto/mtpAuthKey.h @@ -91,6 +91,8 @@ public: static const uint64 RecreateKeyId = 0xFFFFFFFFFFFFFFFFL; + friend bool operator==(const mtpAuthKey &a, const mtpAuthKey &b); + private: char _key[256]; @@ -100,7 +102,12 @@ private: }; +inline bool operator==(const mtpAuthKey &a, const mtpAuthKey &b) { + return !memcmp(a._key, b._key, 256); +} + typedef QSharedPointer mtpAuthKeyPtr; +typedef QVector mtpKeysMap; inline void aesEncrypt(const void *src, void *dst, uint32 len, void *key, void *iv) { uchar aes_key[32], aes_iv[32]; diff --git a/Telegram/SourceFiles/mtproto/mtpConnection.cpp b/Telegram/SourceFiles/mtproto/mtpConnection.cpp index 83c6c20ef..0eba8dd12 100644 --- a/Telegram/SourceFiles/mtproto/mtpConnection.cpp +++ b/Telegram/SourceFiles/mtproto/mtpConnection.cpp @@ -180,12 +180,6 @@ namespace { return false; } - BN_sub_word(&bnPrime, 1); // (p - 1) / 2 - BN_div_word(&bnPrime, 2); - - if (BN_is_prime_ex(&bnPrime, MTPMillerRabinIterCount, ctx, NULL) == 0) { - return false; - } switch (g) { case 2: { int32 mod8 = BN_mod_word(&bnPrime, 8); @@ -226,7 +220,14 @@ namespace { default: LOG(("BigNum PT Error: bad g value: %1").arg(g)); return false; - break; + break; + } + + BN_sub_word(&bnPrime, 1); // (p - 1) / 2 + BN_div_word(&bnPrime, 2); + + if (BN_is_prime_ex(&bnPrime, MTPMillerRabinIterCount, ctx, NULL) == 0) { + return false; } return true; @@ -1105,13 +1106,13 @@ MTProtoConnectionPrivate::MTProtoConnectionPrivate(QThread *thread, MTProtoConne // createConn(); if (!dc) { - const mtpDcOptions &gDcOptions(mtpDCOptions()); - if (!gDcOptions.size()) { + const mtpDcOptions &options(cDcOptions()); + if (options.isEmpty()) { LOG(("MTP Error: connect failed, no DCs")); dc = 0; return; } - dc = gDcOptions.cbegin().value().id; + dc = options.cbegin().value().id; DEBUG_LOG(("MTP Info: searching for any DC, %1 selected..").arg(dc)); } @@ -1699,10 +1700,10 @@ void MTProtoConnectionPrivate::socketStart(bool afterConfig) { pingId = pingMsgId = toSendPingId = 0; const mtpDcOption *dcOption = 0; - const mtpDcOptions &gDcOptions(mtpDCOptions()); - mtpDcOptions::const_iterator dcIndex = gDcOptions.constFind(dc % _mtp_internal::dcShift); + const mtpDcOptions &options(cDcOptions()); + mtpDcOptions::const_iterator dcIndex = options.constFind(dc % _mtp_internal::dcShift); DEBUG_LOG(("MTP Info: connecting to DC %1..").arg(dc)); - if (dcIndex == gDcOptions.cend()) { + if (dcIndex == options.cend()) { if (afterConfig) { LOG(("MTP Error: DC %1 options not found right after config load!").arg(dc)); return restart(); diff --git a/Telegram/SourceFiles/mtproto/mtpDC.cpp b/Telegram/SourceFiles/mtproto/mtpDC.cpp index e698c3b5e..a90864d60 100644 --- a/Telegram/SourceFiles/mtproto/mtpDC.cpp +++ b/Telegram/SourceFiles/mtproto/mtpDC.cpp @@ -25,283 +25,13 @@ namespace { MTProtoDCMap gDCs; bool configLoadedOnce = false; + bool mainDCChanged = false; int32 mainDC = 2; - int userId = 0; - mtpDcOptions gDCOptions; + int32 userId = 0; typedef QMap _KeysMapForWrite; _KeysMapForWrite _keysMapForWrite; QMutex _keysMapForWriteMutex; - - int32 readAuthKeysFields(QIODevice *io) { - if (!io->isOpen()) io->open(QIODevice::ReadOnly); - - QDataStream stream(io); - stream.setVersion(QDataStream::Qt_5_1); - - int32 oldFound = 0; - - while (true) { - quint32 blockId; - stream >> blockId; - if (stream.status() == QDataStream::ReadPastEnd) { - DEBUG_LOG(("MTP Info: keys file read end")); - break; - } else if (stream.status() != QDataStream::Ok) { - LOG(("MTP Error: could not read block id, status: %1 - keys file is corrupted?..").arg(stream.status())); - break; - } - - if (blockId == dbiVersion) { - qint32 keysVersion; - stream >> keysVersion; - continue; // should not be in encrypted part, just ignore - } - - if (blockId != dbiEncrypted && blockId != dbiKey) { - oldFound = 2; - } - - switch (blockId) { - case dbiEncrypted: { - QByteArray data, decrypted; - stream >> data; - - if (!Local::oldKey().created()) { - LOG(("MTP Error: reading encrypted keys without local key!")); - continue; - } - - if (data.size() <= 16 || (data.size() & 0x0F)) { - LOG(("MTP Error: bad encrypted part size: %1").arg(data.size())); - continue; - } - uint32 fullDataLen = data.size() - 16; - decrypted.resize(fullDataLen); - const char *dataKey = data.constData(), *encrypted = data.constData() + 16; - aesDecryptLocal(encrypted, decrypted.data(), fullDataLen, &Local::oldKey(), dataKey); - uchar sha1Buffer[20]; - if (memcmp(hashSha1(decrypted.constData(), decrypted.size(), sha1Buffer), dataKey, 16)) { - LOG(("MTP Error: bad decrypt key, data from user-config not decrypted")); - continue; - } - uint32 dataLen = *(const uint32*)decrypted.constData(); - if (dataLen > uint32(decrypted.size()) || dataLen <= fullDataLen - 16 || dataLen < 4) { - LOG(("MTP Error: bad decrypted part size: %1, fullDataLen: %2, decrypted size: %3").arg(dataLen).arg(fullDataLen).arg(decrypted.size())); - continue; - } - decrypted.resize(dataLen); - QBuffer decryptedStream(&decrypted); - decryptedStream.open(QIODevice::ReadOnly); - decryptedStream.seek(4); // skip size - readAuthKeysFields(&decryptedStream); - } break; - - case dbiKey: { - qint32 dcId; - quint32 key[64]; - stream >> dcId; - stream.readRawData((char*)key, 256); - if (stream.status() == QDataStream::Ok) { - DEBUG_LOG(("MTP Info: key found, dc %1, key: %2").arg(dcId).arg(mb(key, 256).str())); - dcId = dcId % _mtp_internal::dcShift; - mtpAuthKeyPtr keyPtr(new mtpAuthKey()); - keyPtr->setKey(key); - keyPtr->setDC(dcId); - - MTProtoDCPtr dc(new MTProtoDC(dcId, keyPtr)); - gDCs.insert(dcId, dc); - } - } break; - - case dbiUser: { - quint32 dcId; - qint32 uid; - stream >> uid >> dcId; - if (stream.status() == QDataStream::Ok) { - DEBUG_LOG(("MTP Info: user found, dc %1, uid %2").arg(dcId).arg(uid)); - - userId = uid; - mainDC = dcId; - } - } break; - - case dbiDcOption: { - quint32 dcId, port; - QString host, ip; - stream >> dcId >> host >> ip >> port; - - if (stream.status() == QDataStream::Ok) { - gDCOptions.insert(dcId, mtpDcOption(dcId, host.toUtf8().constData(), ip.toUtf8().constData(), port)); - } - } break; - - case dbiConfig1: { - quint32 maxSize; - stream >> maxSize; - if (stream.status() == QDataStream::Ok) { - cSetMaxGroupCount(maxSize); - } - } break; - } - - if (stream.status() != QDataStream::Ok) { - LOG(("MTP Error: could not read data, status: %1 - keys file is corrupted?..").arg(stream.status())); - break; - } - } - - return oldFound; - } - - int32 readAuthKeys(QFile &file) { - QDataStream stream(&file); - stream.setVersion(QDataStream::Qt_5_1); - - int32 oldFound = 0; - quint32 blockId; - stream >> blockId; - if (stream.status() == QDataStream::ReadPastEnd) { - DEBUG_LOG(("MTP Info: keys file read end")); - return oldFound; - } else if (stream.status() != QDataStream::Ok) { - LOG(("MTP Error: could not read block id, status: %1 - keys file is corrupted?..").arg(stream.status())); - return oldFound; - } - - if (blockId == dbiVersion) { - qint32 keysVersion; - stream >> keysVersion; - if (keysVersion > AppVersion) return oldFound; - - stream >> blockId; - if (stream.status() == QDataStream::ReadPastEnd) { - DEBUG_LOG(("MTP Info: keys file read end")); - return oldFound; - } else if (stream.status() != QDataStream::Ok) { - LOG(("MTP Error: could not read block id, status: %1 - keys file is corrupted?..").arg(stream.status())); - return oldFound; - } - if (blockId != dbiEncrypted) { - oldFound = (blockId != dbiKey) ? 2 : 1; - } - } else { - oldFound = 2; - } - - file.reset(); - oldFound = qMax(oldFound, readAuthKeysFields(&file)); - - return oldFound; - } - - void writeAuthKeys(); - void readAuthKeys() { - QFile keysFile(cWorkingDir() + cDataFile()); - if (keysFile.open(QIODevice::ReadOnly)) { - DEBUG_LOG(("MTP Info: keys file opened for reading")); - int32 oldFound = readAuthKeys(keysFile); - if (gDCOptions.isEmpty()) { - const BuiltInDc *bdcs = builtInDcs(); - for (int i = 0, l = builtInDcsCount(); i < l; ++i) { - gDCOptions.insert(bdcs[i].id, mtpDcOption(bdcs[i].id, "", bdcs[i].ip, bdcs[i].port)); - DEBUG_LOG(("MTP Info: adding built in DC %1 connect option: %2:%3").arg(bdcs[i].id).arg(bdcs[i].ip).arg(bdcs[i].port)); - } - } - if (mainDC && gDCOptions.find(mainDC) == gDCOptions.cend()) { // load first dc info - userId = 0; - mainDC = (gDCOptions.constFind(2) == gDCOptions.cend()) ? gDCOptions.begin().key() : 2; - } else { - DEBUG_LOG(("MTP Info: config from local, dc option count: %1").arg(gDCOptions.size())); - } - - if (oldFound > 0) { - writeAuthKeys(); - if (oldFound > 1) { - App::writeUserConfig(); - } - DEBUG_LOG(("MTP Info: rewritten old data / config to new data and config")); - } - } else { - DEBUG_LOG(("MTP Info: could not open keys file for reading")); - const BuiltInDc *bdcs = builtInDcs(); - for (int i = 0, l = builtInDcsCount(); i < l; ++i) { - gDCOptions.insert(bdcs[i].id, mtpDcOption(bdcs[i].id, "", bdcs[i].ip, bdcs[i].port)); - DEBUG_LOG(("MTP Info: adding built in DC %1 connect option: %2:%3").arg(bdcs[i].id).arg(bdcs[i].ip).arg(bdcs[i].port)); - } - } - } - - typedef QVector _KeysToWrite; - void writeAuthKeys() { - _KeysToWrite keysToWrite; - { - QMutexLocker lock(&_keysMapForWriteMutex); - for (_KeysMapForWrite::const_iterator i = _keysMapForWrite.cbegin(), e = _keysMapForWrite.cend(); i != e; ++i) { - keysToWrite.push_back(i.value()); - } - } - - QFile keysFile(cWorkingDir() + cDataFile()); - if (keysFile.open(QIODevice::WriteOnly)) { - DEBUG_LOG(("MTP Info: writing keys data for encrypt")); - QByteArray toEncrypt; - toEncrypt.reserve(65536); - toEncrypt.resize(4); - { - QBuffer buffer(&toEncrypt); - buffer.open(QIODevice::Append); - - QDataStream stream(&buffer); - stream.setVersion(QDataStream::Qt_5_1); - - for (_KeysToWrite::const_iterator i = keysToWrite.cbegin(), e = keysToWrite.cend(); i != e; ++i) { - stream << quint32(dbiKey) << quint32((*i)->getDC()); - (*i)->write(stream); - } - - if (stream.status() != QDataStream::Ok) { - LOG(("MTP Error: could not write keys to memory buf, status: %1").arg(stream.status())); - } - } - *(uint32*)(toEncrypt.data()) = toEncrypt.size(); - - uint32 size = toEncrypt.size(), fullSize = size; - if (fullSize & 0x0F) { - fullSize += 0x10 - (fullSize & 0x0F); - toEncrypt.resize(fullSize); - memset_rand(toEncrypt.data() + size, fullSize - size); - } - QByteArray encrypted(16 + fullSize, Qt::Uninitialized); // 128bit of sha1 - key128, sizeof(data), data - hashSha1(toEncrypt.constData(), toEncrypt.size(), encrypted.data()); - aesEncryptLocal(toEncrypt.constData(), encrypted.data() + 16, fullSize, &Local::oldKey(), encrypted.constData()); - - DEBUG_LOG(("MTP Info: keys file opened for writing %1 keys").arg(keysToWrite.size())); - QDataStream keysStream(&keysFile); - keysStream.setVersion(QDataStream::Qt_5_1); - keysStream << quint32(dbiVersion) << qint32(AppVersion); - - keysStream << quint32(dbiEncrypted) << encrypted; // write all encrypted data - - if (keysStream.status() != QDataStream::Ok) { - LOG(("MTP Error: could not write keys, status: %1").arg(keysStream.status())); - } - } else { - LOG(("MTP Error: could not open keys file for writing")); - } - } - - class _KeysReader { - public: - _KeysReader() { - readAuthKeys(); - } - }; - -} - -void mtpLoadData() { - static _KeysReader keysReader; } int32 mtpAuthed() { @@ -309,9 +39,8 @@ int32 mtpAuthed() { } void mtpAuthed(int32 uid) { - if (userId != uid && mainDC) { + if (userId != uid) { userId = uid; - App::writeUserConfig(); } } @@ -319,10 +48,6 @@ MTProtoDCMap &mtpDCMap() { return gDCs; } -const mtpDcOptions &mtpDCOptions() { - return gDCOptions; -} - bool mtpNeedConfig() { return !configLoadedOnce; } @@ -344,12 +69,11 @@ void mtpLogoutOtherDCs() { } } -void mtpSetDC(int32 dc) { +void mtpSetDC(int32 dc, bool firstOnly) { + if (!dc || (firstOnly && mainDCChanged)) return; + mainDCChanged = true; if (dc != mainDC) { mainDC = dc; - if (userId) { - App::writeUserConfig(); - } } } @@ -367,7 +91,7 @@ MTProtoDC::MTProtoDC(int32 id, const mtpAuthKeyPtr &key) : _id(id), _key(key), _ void MTProtoDC::authKeyWrite() { DEBUG_LOG(("AuthKey Info: MTProtoDC::authKeyWrite() slot, dc %1").arg(_id)); if (_key) { - writeAuthKeys(); + Local::writeMtpData(); } } @@ -414,7 +138,7 @@ namespace { cSetMaxGroupCount(data.vchat_size_max.v); configLoadedOnce = true; - App::writeUserConfig(); + Local::writeSettings(); mtpConfigLoader()->done(); } @@ -427,18 +151,22 @@ namespace { void mtpUpdateDcOptions(const QVector &options) { QSet already, restart; - for (QVector::const_iterator i = options.cbegin(), e = options.cend(); i != e; ++i) { - const MTPDdcOption &optData(i->c_dcOption()); - if (already.constFind(optData.vid.v) == already.cend()) { - already.insert(optData.vid.v); - mtpDcOptions::const_iterator a = gDCOptions.constFind(optData.vid.v); - if (a != gDCOptions.cend()) { - if (a.value().ip != optData.vip_address.c_string().v || a.value().port != optData.vport.v) { - restart.insert(optData.vid.v); + { + mtpDcOptions opts(cDcOptions()); + for (QVector::const_iterator i = options.cbegin(), e = options.cend(); i != e; ++i) { + const MTPDdcOption &optData(i->c_dcOption()); + if (already.constFind(optData.vid.v) == already.cend()) { + already.insert(optData.vid.v); + mtpDcOptions::const_iterator a = opts.constFind(optData.vid.v); + if (a != opts.cend()) { + if (a.value().ip != optData.vip_address.c_string().v || a.value().port != optData.vport.v) { + restart.insert(optData.vid.v); + } } + opts.insert(optData.vid.v, mtpDcOption(optData.vid.v, optData.vhostname.c_string().v, optData.vip_address.c_string().v, optData.vport.v)); } - gDCOptions.insert(optData.vid.v, mtpDcOption(optData.vid.v, optData.vhostname.c_string().v, optData.vip_address.c_string().v, optData.vport.v)); } + cSetDcOptions(opts); } for (QSet::const_iterator i = restart.cbegin(), e = restart.cend(); i != e; ++i) { MTP::restart(*i); @@ -490,9 +218,10 @@ void MTProtoConfigLoader::enumDC() { } else { MTP::killSession(MTP::cfg + _enumCurrent); } - for (mtpDcOptions::const_iterator i = gDCOptions.cbegin(), e = gDCOptions.cend(); i != e; ++i) { + const mtpDcOptions &options(cDcOptions()); + for (mtpDcOptions::const_iterator i = options.cbegin(), e = options.cend(); i != e; ++i) { if (i.key() == _enumCurrent) { - _enumCurrent = (++i == e) ? gDCOptions.cbegin().key() : i.key(); + _enumCurrent = (++i == e) ? options.cbegin().key() : i.key(); break; } } @@ -512,51 +241,16 @@ void mtpDestroyConfigLoader() { configLoader = 0; } -void mtpWriteConfig(QDataStream &stream) { - if (userId) { - stream << quint32(dbiUser) << qint32(userId) << quint32(mainDC); +mtpKeysMap mtpGetKeys() { + mtpKeysMap result; + QMutexLocker lock(&_keysMapForWriteMutex); + for (_KeysMapForWrite::const_iterator i = _keysMapForWrite.cbegin(), e = _keysMapForWrite.cend(); i != e; ++i) { + result.push_back(i.value()); } - for (mtpDcOptions::const_iterator i = gDCOptions.cbegin(), e = gDCOptions.cend(); i != e; ++i) { - stream << quint32(dbiDcOption) << i->id << QString(i->host.c_str()) << QString(i->ip.c_str()) << i->port; - } - stream << quint32(dbiConfig1) << qint32(cMaxGroupCount()); + return result; } -bool mtpReadConfigElem(int32 blockId, QDataStream &stream) { - switch (blockId) { - case dbiUser: { - quint32 dcId; - qint32 uid; - stream >> uid >> dcId; - if (stream.status() == QDataStream::Ok) { - DEBUG_LOG(("MTP Info: user found, dc %1, uid %2").arg(dcId).arg(uid)); - - userId = uid; - mainDC = dcId; - return true; - } - } break; - - case dbiDcOption: { - quint32 dcId, port; - QString host, ip; - stream >> dcId >> host >> ip >> port; - - if (stream.status() == QDataStream::Ok) { - gDCOptions.insert(dcId, mtpDcOption(dcId, host.toUtf8().constData(), ip.toUtf8().constData(), port)); - return true; - } - } break; - - case dbiConfig1: { - quint32 maxSize; - stream >> maxSize; - if (stream.status() == QDataStream::Ok) { - cSetMaxGroupCount(maxSize); - return true; - } - } break; - } - - return false; +void mtpSetKey(int32 dcId, mtpAuthKeyPtr key) { + MTProtoDCPtr dc(new MTProtoDC(dcId, key)); + gDCs.insert(dcId, dc); } diff --git a/Telegram/SourceFiles/mtproto/mtpDC.h b/Telegram/SourceFiles/mtproto/mtpDC.h index 6f2111015..4a5bd2c0d 100644 --- a/Telegram/SourceFiles/mtproto/mtpDC.h +++ b/Telegram/SourceFiles/mtproto/mtpDC.h @@ -60,17 +60,6 @@ private: typedef QSharedPointer MTProtoDCPtr; typedef QMap MTProtoDCMap; -struct mtpDcOption { - mtpDcOption(int _id, const string &_host, const string &_ip, int _port) : id(_id), host(_host), ip(_ip), port(_port) { - } - - int id; - string host; - string ip; - int port; -}; -typedef QMap mtpDcOptions; - class MTProtoConfigLoader : public QObject { Q_OBJECT @@ -101,20 +90,17 @@ private: MTProtoConfigLoader *mtpConfigLoader(); void mtpDestroyConfigLoader(); -const mtpDcOptions &mtpDCOptions(); MTProtoDCMap &mtpDCMap(); bool mtpNeedConfig(); int32 mtpMainDC(); void mtpLogoutOtherDCs(); -void mtpSetDC(int32 dc); +void mtpSetDC(int32 dc, bool firstOnly = false); uint32 mtpMaxChatSize(); -void mtpWriteAuthKeys(); -void mtpLoadData(); int32 mtpAuthed(); void mtpAuthed(int32 uid); -void mtpWriteConfig(QDataStream &stream); -bool mtpReadConfigElem(int32 blockId, QDataStream &stream); +mtpKeysMap mtpGetKeys(); +void mtpSetKey(int32 dc, mtpAuthKeyPtr key); void mtpUpdateDcOptions(const QVector &options); diff --git a/Telegram/SourceFiles/passcodewidget.cpp b/Telegram/SourceFiles/passcodewidget.cpp new file mode 100644 index 000000000..6c66ea743 --- /dev/null +++ b/Telegram/SourceFiles/passcodewidget.cpp @@ -0,0 +1,216 @@ +/* +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. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "lang.h" +#include "style.h" + +#include "localstorage.h" + +#include "passcodewidget.h" +#include "window.h" +#include "application.h" +#include "gui/text.h" + +class LogOutLink : public ITextLink { +public: + + void onClick(Qt::MouseButton) const { + App::wnd()->onLogout(); + } + +}; + +PasscodeWidget::PasscodeWidget(QWidget *parent) : QWidget(parent), +_passcode(this, st::passcodeInput), +_submit(this, lang(lng_passcode_submit), st::passcodeSubmit), +_logout(this, lng_passcode_logout(lt_link_start, textcmdStartLink(1), lt_link_end, textcmdStopLink())) { + setGeometry(QRect(0, st::titleHeight, App::wnd()->width(), App::wnd()->height() - st::titleHeight)); + connect(App::wnd(), SIGNAL(resized(const QSize &)), this, SLOT(onParentResize(const QSize &))); + + _passcode.setEchoMode(QLineEdit::Password); + connect(&_submit, SIGNAL(clicked()), this, SLOT(onSubmit())); + + _errorTimer.setSingleShot(true); + connect(&_errorTimer, SIGNAL(timeout()), this, SLOT(onError())); + + _logout.setLink(1, TextLinkPtr(new LogOutLink())); + + connect(&_passcode, SIGNAL(changed()), this, SLOT(onChanged())); + connect(&_passcode, SIGNAL(accepted()), this, SLOT(onSubmit())); + + show(); + _passcode.setFocus(); +} + +void PasscodeWidget::onParentResize(const QSize &newSize) { + resize(newSize); +} + +void PasscodeWidget::onSubmit() { + if (_passcode.text().isEmpty()) { + _passcode.setFocus(); + _passcode.notaBene(); + return; + } + + if (App::main()) { + if (Local::checkPasscode(_passcode.text().toUtf8())) { + App::wnd()->clearPasscode(); + } else { + _error = QString(); + _passcode.setDisabled(true); + _errorTimer.start(WrongPasscodeTimeout); + return; + } + } else { + if (Local::readMap(_passcode.text().toUtf8()) != Local::ReadMapPassNeeded) { + App::app()->checkMapVersion(); + + MTP::start(); + if (MTP::authedId()) { + App::wnd()->setupMain(true); + } else { + App::wnd()->setupIntro(true); + } + } else { + _error = QString(); + _passcode.setDisabled(true); + _errorTimer.start(WrongPasscodeTimeout); + update(); + return; + } + } +} + +void PasscodeWidget::onError() { + _error = lang(lng_passcode_wrong); + _passcode.setDisabled(false); + _passcode.selectAll(); + _passcode.setFocus(); + _passcode.notaBene(); + update(); +} + +void PasscodeWidget::onChanged() { + if (!_error.isEmpty()) { + _error = QString(); + update(); + } +} + +void PasscodeWidget::animShow(const QPixmap &bgAnimCache, bool back) { + _bgAnimCache = bgAnimCache; + + anim::stop(this); + showAll(); + _animCache = myGrab(this, rect()); + + a_coord = back ? anim::ivalue(-st::introSlideShift, 0) : anim::ivalue(st::introSlideShift, 0); + a_alpha = anim::fvalue(0, 1); + a_bgCoord = back ? anim::ivalue(0, st::introSlideShift) : anim::ivalue(0, -st::introSlideShift); + a_bgAlpha = anim::fvalue(1, 0); + + hideAll(); + anim::start(this); + show(); +} + +bool PasscodeWidget::animStep(float64 ms) { + float64 fullDuration = st::introSlideDelta + st::introSlideDuration, dt = ms / fullDuration; + float64 dt1 = (ms > st::introSlideDuration) ? 1 : (ms / st::introSlideDuration), dt2 = (ms > st::introSlideDelta) ? (ms - st::introSlideDelta) / (st::introSlideDuration) : 0; + bool res = true; + if (dt2 >= 1) { + res = false; + a_bgCoord.finish(); + a_bgAlpha.finish(); + a_coord.finish(); + a_alpha.finish(); + + _animCache = _bgAnimCache = QPixmap(); + + showAll(); + setInnerFocus(); + } else { + a_bgCoord.update(dt1, st::introHideFunc); + a_bgAlpha.update(dt1, st::introAlphaHideFunc); + a_coord.update(dt2, st::introShowFunc); + a_alpha.update(dt2, st::introAlphaShowFunc); + } + update(); + return res; +} + +void PasscodeWidget::showAll() { + _passcode.show(); + _submit.show(); + _logout.show(); +} + +void PasscodeWidget::hideAll() { + _passcode.hide(); + _submit.hide(); + _logout.hide(); +} + +void PasscodeWidget::paintEvent(QPaintEvent *e) { + bool trivial = (rect() == e->rect()); + setMouseTracking(true); + + QPainter p(this); + if (!trivial) { + p.setClipRect(e->rect()); + } + + if (animating()) { + p.setOpacity(a_bgAlpha.current()); + p.drawPixmap(a_bgCoord.current(), 0, _bgAnimCache); + p.setOpacity(a_alpha.current()); + p.drawPixmap(a_coord.current(), 0, _animCache); + } else { + p.fillRect(rect(), st::setBG->b); + + p.setFont(st::passcodeHeaderFont->f); + p.drawText(QRect(0, _passcode.y() - st::passcodeHeaderHeight, width(), st::passcodeHeaderHeight), lang(lng_passcode_enter), style::al_center); + + if (!_error.isEmpty()) { + p.setFont(st::boxFont->f); + p.setPen(st::setErrColor->p); + p.drawText(QRect(0, _passcode.y() + _passcode.height(), width(), st::usernameSkip), _error, style::al_center); + } + } +} + +void PasscodeWidget::resizeEvent(QResizeEvent *e) { + _passcode.move((width() - _passcode.width()) / 2, (height() / 3)); + _submit.move(_passcode.x(), _passcode.y() + _passcode.height() + st::passcodeSkip); + _logout.move(_passcode.x() + (_passcode.width() - _logout.width()) / 2, _submit.y() + _submit.height() + st::linkFont->ascent); +} + +void PasscodeWidget::mousePressEvent(QMouseEvent *e) { + +} + +void PasscodeWidget::keyPressEvent(QKeyEvent *e) { +} + +void PasscodeWidget::setInnerFocus() { + _passcode.setFocus(); +} + +PasscodeWidget::~PasscodeWidget() { +} diff --git a/Telegram/SourceFiles/passcodewidget.h b/Telegram/SourceFiles/passcodewidget.h new file mode 100644 index 000000000..bdadbe62d --- /dev/null +++ b/Telegram/SourceFiles/passcodewidget.h @@ -0,0 +1,62 @@ +/* +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. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014 John Preston, https://desktop.telegram.org +*/ +#pragma once + +class PasscodeWidget : public QWidget, public Animated { + Q_OBJECT + +public: + + PasscodeWidget(QWidget *parent); + + void paintEvent(QPaintEvent *e); + void resizeEvent(QResizeEvent *e); + void mousePressEvent(QMouseEvent *e); + void keyPressEvent(QKeyEvent *e); + void setInnerFocus(); + + void animShow(const QPixmap &bgAnimCache, bool back = false); + bool animStep(float64 ms); + + ~PasscodeWidget(); + +public slots: + + void onParentResize(const QSize &newSize); + void onError(); + void onChanged(); + void onSubmit(); + +signals: + +private: + + void showAll(); + void hideAll(); + + QPixmap _animCache, _bgAnimCache; + anim::ivalue a_coord, a_bgCoord; + anim::fvalue a_alpha, a_bgAlpha; + + FlatButton _submit; + FlatInput _passcode; + FlatLabel _logout; + QString _error; + QTimer _errorTimer; + +}; diff --git a/Telegram/SourceFiles/pspecific_linux.cpp b/Telegram/SourceFiles/pspecific_linux.cpp index 5d71ed46c..20c8b70c7 100644 --- a/Telegram/SourceFiles/pspecific_linux.cpp +++ b/Telegram/SourceFiles/pspecific_linux.cpp @@ -22,6 +22,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "application.h" #include "mainwidget.h" +#include "localstorage.h" + #include #include #include @@ -703,7 +705,7 @@ void PsMainWindow::psSavePosition(Qt::WindowState state) { if (curPos.w >= st::wndMinWidth && curPos.h >= st::wndMinHeight) { if (curPos.x != pos.x || curPos.y != pos.y || curPos.w != pos.w || curPos.h != pos.h || curPos.moncrc != pos.moncrc || curPos.maximized != pos.maximized) { cSetWindowPos(curPos); - App::writeConfig(); + Local::writeSettings(); } } } @@ -1369,6 +1371,10 @@ void psUserActionDone() { _lastUserAction = getms(true); } +bool psIdleSupported() { + return false; +} + uint64 psIdleTime() { return getms(true) - _lastUserAction; } diff --git a/Telegram/SourceFiles/pspecific_linux.h b/Telegram/SourceFiles/pspecific_linux.h index ef4e5a56f..d03bd5cef 100644 --- a/Telegram/SourceFiles/pspecific_linux.h +++ b/Telegram/SourceFiles/pspecific_linux.h @@ -167,6 +167,7 @@ private: }; void psUserActionDone(); +bool psIdleSupported(); uint64 psIdleTime(); bool psSkipAudioNotify(); diff --git a/Telegram/SourceFiles/pspecific_mac.cpp b/Telegram/SourceFiles/pspecific_mac.cpp index 7b3a9d5e5..9aafcfc89 100644 --- a/Telegram/SourceFiles/pspecific_mac.cpp +++ b/Telegram/SourceFiles/pspecific_mac.cpp @@ -23,6 +23,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "mainwidget.h" #include "historywidget.h" +#include "localstorage.h" + namespace { QStringList _initLogs; @@ -61,9 +63,14 @@ void MacPrivate::notifyClicked(unsigned long long peer) { History *history = App::history(PeerId(peer)); App::wnd()->showFromTray(); - App::wnd()->hideSettings(); - App::main()->showPeer(history->peer->id, false, true); - App::wnd()->notifyClear(history); + if (App::passcoded()) { + App::wnd()->passcodeWidget()->setInnerFocus(); + App::wnd()->notifyClear(); + } else { + App::wnd()->hideSettings(); + App::main()->showPeer(history->peer->id, false, true); + App::wnd()->notifyClear(history); + } } void MacPrivate::notifyReplied(unsigned long long peer, const char *str) { @@ -268,7 +275,7 @@ void PsMainWindow::psSavePosition(Qt::WindowState state) { if (curPos.w >= st::wndMinWidth && curPos.h >= st::wndMinHeight) { if (curPos.x != pos.x || curPos.y != pos.y || curPos.w != pos.w || curPos.h != pos.h || curPos.moncrc != pos.moncrc || curPos.maximized != pos.maximized) { cSetWindowPos(curPos); - App::writeConfig(); + Local::writeSettings(); } } } @@ -475,12 +482,12 @@ void PsMainWindow::psNotifyShown(NotifyWindow *w) { } void PsMainWindow::psPlatformNotify(HistoryItem *item) { - QString title = (cNotifyView() <= dbinvShowName) ? item->history()->peer->name : qsl("Telegram Desktop"); - QString subtitle = (cNotifyView() <= dbinvShowName) ? item->notificationHeader() : QString(); - QPixmap pix = (cNotifyView() <= dbinvShowName) ? item->history()->peer->photo->pix(st::notifyMacPhotoSize) : QPixmap(); - QString msg = (cNotifyView() <= dbinvShowPreview) ? item->notificationText() : lang(lng_notification_preview); + QString title = (!App::passcoded() && cNotifyView() <= dbinvShowName) ? item->history()->peer->name : qsl("Telegram Desktop"); + QString subtitle = (!App::passcoded() && cNotifyView() <= dbinvShowName) ? item->notificationHeader() : QString(); + QPixmap pix = (!App::passcoded() && cNotifyView() <= dbinvShowName) ? item->history()->peer->photo->pix(st::notifyMacPhotoSize) : QPixmap(); + QString msg = (!App::passcoded() && cNotifyView() <= dbinvShowPreview) ? item->notificationText() : lang(lng_notification_preview); - _private.showNotify(item->history()->peer->id, pix, title, subtitle, msg, (cNotifyView() <= dbinvShowPreview)); + _private.showNotify(item->history()->peer->id, pix, title, subtitle, msg, !App::passcoded() && (cNotifyView() <= dbinvShowPreview)); } bool PsMainWindow::eventFilter(QObject *obj, QEvent *evt) { @@ -924,6 +931,10 @@ void psUserActionDone() { _lastUserAction = getms(true); } +bool psIdleSupported() { + return objc_idleSupported(); +} + uint64 psIdleTime() { int64 idleTime = 0; return objc_idleTime(idleTime) ? idleTime : (getms(true) - _lastUserAction); diff --git a/Telegram/SourceFiles/pspecific_mac.h b/Telegram/SourceFiles/pspecific_mac.h index 1fb495f9c..0afd935d4 100644 --- a/Telegram/SourceFiles/pspecific_mac.h +++ b/Telegram/SourceFiles/pspecific_mac.h @@ -195,6 +195,7 @@ private: }; void psUserActionDone(); +bool psIdleSupported(); uint64 psIdleTime(); bool psSkipAudioNotify(); diff --git a/Telegram/SourceFiles/pspecific_mac_p.h b/Telegram/SourceFiles/pspecific_mac_p.h index 0f9c637d9..1bb506cb1 100644 --- a/Telegram/SourceFiles/pspecific_mac_p.h +++ b/Telegram/SourceFiles/pspecific_mac_p.h @@ -57,6 +57,7 @@ void objc_activateWnd(WId winId); void objc_debugShowAlert(const QString &str); void objc_outputDebugString(const QString &str); +bool objc_idleSupported(); bool objc_idleTime(int64 &idleTime); bool objc_showOpenWithMenu(int x, int y, const QString &file); diff --git a/Telegram/SourceFiles/pspecific_mac_p.mm b/Telegram/SourceFiles/pspecific_mac_p.mm index 33ef8834a..b562192e8 100644 --- a/Telegram/SourceFiles/pspecific_mac_p.mm +++ b/Telegram/SourceFiles/pspecific_mac_p.mm @@ -149,14 +149,12 @@ public: void onNotifyClick(NSUserNotification *notification) { NSNumber *peerObj = [[notification userInfo] objectForKey:@"peer"]; unsigned long long peerLong = peerObj ? [peerObj unsignedLongLongValue] : 0; - LOG(("Received notification click with peer %1").arg(peerLong)); wnd->notifyClicked(peerLong); } void onNotifyReply(NSUserNotification *notification) { NSNumber *peerObj = [[notification userInfo] objectForKey:@"peer"]; unsigned long long peerLong = peerObj ? [peerObj unsignedLongLongValue] : 0; - LOG(("Received notification reply with peer %1").arg(peerLong)); wnd->notifyReplied(peerLong, [[[notification response] string] UTF8String]); } @@ -328,6 +326,11 @@ PsMacWindowPrivate::~PsMacWindowPrivate() { delete data; } +bool objc_idleSupported() { + int64 idleTime = 0; + return objc_idleTime(idleTime); +} + bool objc_idleTime(int64 &idleTime) { // taken from https://github.com/trueinteractions/tint/issues/53 CFMutableDictionaryRef properties = 0; CFTypeRef obj; diff --git a/Telegram/SourceFiles/pspecific_wnd.cpp b/Telegram/SourceFiles/pspecific_wnd.cpp index 03f8bd0fc..287b9987b 100644 --- a/Telegram/SourceFiles/pspecific_wnd.cpp +++ b/Telegram/SourceFiles/pspecific_wnd.cpp @@ -22,6 +22,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "application.h" #include "mainwidget.h" +#include "localstorage.h" + #include #include #include @@ -717,6 +719,10 @@ namespace { } switch (msg) { + case WM_TIMECHANGE: { + App::wnd()->checkAutoLockIn(100); + } return false; + case WM_WTSSESSION_CHANGE: { if (wParam == WTS_SESSION_LOGOFF || wParam == WTS_SESSION_LOCK) { sessionLoggedOff = true; @@ -1135,7 +1141,7 @@ void PsMainWindow::psSavePosition(Qt::WindowState state) { if (curPos.w >= st::wndMinWidth && curPos.h >= st::wndMinHeight) { if (curPos.x != pos.x || curPos.y != pos.y || curPos.w != pos.w || curPos.h != pos.h || curPos.moncrc != pos.moncrc || curPos.maximized != pos.maximized) { cSetWindowPos(curPos); - App::writeConfig(); + Local::writeSettings(); } } } @@ -1752,6 +1758,7 @@ namespace { if (len && len < nameBufSize) { if (QRegularExpression(qsl("^Telegram(\\s*\\(\\d+\\))?$")).match(QString::fromStdWString(nameBuf)).hasMatch()) { BOOL res = ::SetForegroundWindow(hWnd); + ::SetFocus(hWnd); return FALSE; } } @@ -1769,6 +1776,12 @@ void psUserActionDone() { if (sessionLoggedOff) sessionLoggedOff = false; } +bool psIdleSupported() { + LASTINPUTINFO lii; + lii.cbSize = sizeof(LASTINPUTINFO); + return GetLastInputInfo(&lii); +} + uint64 psIdleTime() { LASTINPUTINFO lii; lii.cbSize = sizeof(LASTINPUTINFO); diff --git a/Telegram/SourceFiles/pspecific_wnd.h b/Telegram/SourceFiles/pspecific_wnd.h index 311d512e7..8be2c9159 100644 --- a/Telegram/SourceFiles/pspecific_wnd.h +++ b/Telegram/SourceFiles/pspecific_wnd.h @@ -168,6 +168,7 @@ private: }; void psUserActionDone(); +bool psIdleSupported(); uint64 psIdleTime(); bool psSkipAudioNotify(); diff --git a/Telegram/SourceFiles/settings.cpp b/Telegram/SourceFiles/settings.cpp index 3d1733569..93cfa1afa 100644 --- a/Telegram/SourceFiles/settings.cpp +++ b/Telegram/SourceFiles/settings.cpp @@ -20,6 +20,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "settings.h" #include "lang.h" +mtpDcOptions gDcOptions; + bool gTestMode = false; bool gDebug = false; bool gManyInstance = false; @@ -76,6 +78,9 @@ bool gCompressPastedImage = true; QString gTimeFormat = qsl("hh:mm"); +int32 gAutoLock = 3600; +bool gHasPasscode = false; + DBIEmojiTab gEmojiTab = dbietRecent; RecentEmojiPack gRecentEmojis; RecentEmojiPreload gRecentEmojisPreload; diff --git a/Telegram/SourceFiles/settings.h b/Telegram/SourceFiles/settings.h index d6748ebae..d793fef5d 100644 --- a/Telegram/SourceFiles/settings.h +++ b/Telegram/SourceFiles/settings.h @@ -41,6 +41,18 @@ inline void cSet##Name(const Type &Name) { \ g##Name = Name; \ } +struct mtpDcOption { + mtpDcOption(int _id, const string &_host, const string &_ip, int _port) : id(_id), host(_host), ip(_ip), port(_port) { + } + + int id; + string host; + string ip; + int port; +}; +typedef QMap mtpDcOptions; +DeclareSetting(mtpDcOptions, DcOptions); + DeclareSetting(bool, TestMode); DeclareSetting(QString, LoggedPhoneNumber); DeclareReadSetting(uint32, ConnectionsInSession); @@ -108,6 +120,9 @@ DeclareSetting(DBIScale, ConfigScale); DeclareSetting(bool, CompressPastedImage); DeclareSetting(QString, TimeFormat); +DeclareSetting(int32, AutoLock); +DeclareSetting(bool, HasPasscode); + inline void cChangeTimeFormat(const QString &newFormat) { if (!newFormat.isEmpty()) cSetTimeFormat(newFormat); } diff --git a/Telegram/SourceFiles/settingswidget.cpp b/Telegram/SourceFiles/settingswidget.cpp index d4ce0095d..d753602f6 100644 --- a/Telegram/SourceFiles/settingswidget.cpp +++ b/Telegram/SourceFiles/settingswidget.cpp @@ -31,6 +31,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "boxes/downloadpathbox.h" #include "boxes/usernamebox.h" #include "boxes/languagebox.h" +#include "boxes/passcodebox.h" +#include "boxes/autolockbox.h" #include "langloaderplain.h" #include "gui/filedialog.h" @@ -169,7 +171,14 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent), _storageClearFailedWidth(st::linkFont->m.width(lang(lng_local_storage_clear_failed))), // advanced + _passcodeEdit(this, lang(cHasPasscode() ? lng_passcode_change : lng_passcode_turn_on)), + _passcodeTurnOff(this, lang(lng_passcode_turn_off)), + _autoLock(this, (cAutoLock() % 3600) ? lng_passcode_autolock_minutes(lt_count, cAutoLock() / 60) : lng_passcode_autolock_hours(lt_count, cAutoLock() / 3600)), + _autoLockText(lang(psIdleSupported() ? lng_passcode_autolock_away : lng_passcode_autolock_inactive) + ' '), + _autoLockWidth(st::linkFont->m.width(_autoLockText)), _connectionType(this, lng_connection_auto(lt_type, QString())), + _connectionTypeText(lang(lng_connection_type) + ' '), + _connectionTypeWidth(st::linkFont->m.width(_connectionTypeText)), _resetSessions(this, lang(lng_settings_reset)), _logOut(this, lang(lng_settings_logout), st::btnLogout), _resetDone(false) @@ -264,13 +273,13 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent), } // advanced + connect(&_passcodeEdit, SIGNAL(clicked()), this, SLOT(onPasscode())); + connect(&_passcodeTurnOff, SIGNAL(clicked()), this, SLOT(onPasscodeOff())); + connect(&_autoLock, SIGNAL(clicked()), this, SLOT(onAutoLock())); connect(&_connectionType, SIGNAL(clicked()), this, SLOT(onConnectionType())); connect(&_resetSessions, SIGNAL(clicked()), this, SLOT(onResetSessions())); connect(&_logOut, SIGNAL(clicked()), App::wnd(), SLOT(onLogout())); - _connectionTypeText = lang(lng_connection_type) + ' '; - _connectionTypeWidth = st::linkFont->m.width(_connectionTypeText); - if (App::main()) { connect(App::main(), SIGNAL(peerUpdated(PeerData*)), this, SLOT(peerUpdated(PeerData*))); } @@ -583,7 +592,15 @@ void SettingsInner::paintEvent(QPaintEvent *e) { p.setFont(st::linkFont->f); p.setPen(st::black->p); - p.drawText(_left + st::setHeaderLeft, _connectionType.y() + st::linkFont->ascent, _connectionTypeText); + if (self()) { + top += _passcodeEdit.height() + st::setLittleSkip; + if (cHasPasscode()) { + p.drawText(_left, top + st::linkFont->ascent, _autoLockText); + top += _autoLock.height() + st::setLittleSkip; + } + } + + p.drawText(_left, _connectionType.y() + st::linkFont->ascent, _connectionTypeText); if (self() && _resetDone) { p.drawText(_resetSessions.x(), _resetSessions.y() + st::linkFont->ascent, lang(lng_settings_reset_done)); @@ -681,7 +698,15 @@ void SettingsInner::resizeEvent(QResizeEvent *e) { // advanced top += st::setHeaderSkip; - _connectionType.move(_left + st::setHeaderLeft + _connectionTypeWidth, top); top += _connectionType.height() + st::setLittleSkip; + if (self()) { + _passcodeEdit.move(_left, top); + _passcodeTurnOff.move(_left + st::setWidth - _passcodeTurnOff.width(), top); top += _passcodeTurnOff.height() + st::setLittleSkip; + if (cHasPasscode()) { + _autoLock.move(_left + _autoLockWidth, top); top += _autoLock.height() + st::setLittleSkip; + } + } + + _connectionType.move(_left + _connectionTypeWidth, top); top += _connectionType.height() + st::setLittleSkip; if (self()) { _resetSessions.move(_left, top); top += _resetSessions.height() + st::setSectionSkip; _logOut.move(_left, top); @@ -775,6 +800,13 @@ void SettingsInner::updateConnectionType() { } } +void SettingsInner::passcodeChanged() { + resizeEvent(0); + _passcodeEdit.setText(lang(cHasPasscode() ? lng_passcode_change : lng_passcode_turn_on)); + _autoLock.setText((cAutoLock() % 3600) ? lng_passcode_autolock_minutes(lt_count, cAutoLock() / 60) : lng_passcode_autolock_hours(lt_count, cAutoLock() / 3600)); + showAll(); +} + void SettingsInner::updateBackgroundRect() { update(_left, _tileBackground.y() - st::setLittleSkip - st::setBackgroundSize, st::setBackgroundSize, st::setBackgroundSize); } @@ -918,6 +950,14 @@ void SettingsInner::showAll() { // advanced if (self()) { + _passcodeEdit.show(); + if (cHasPasscode()) { + _autoLock.show(); + _passcodeTurnOff.show(); + } else { + _autoLock.hide(); + _passcodeTurnOff.hide(); + } if (_resetDone) { _resetSessions.hide(); } else { @@ -925,6 +965,9 @@ void SettingsInner::showAll() { } _logOut.show(); } else { + _passcodeEdit.hide(); + _autoLock.hide(); + _passcodeTurnOff.hide(); _resetSessions.hide(); _logOut.hide(); } @@ -1020,7 +1063,7 @@ void SettingsInner::onChangeLanguage() { void SettingsInner::onSaveTestLang() { cSetLangFile(_testlang); cSetLang(languageTest); - App::writeConfig(); + Local::writeSettings(); cSetRestarting(true); App::quit(); } @@ -1033,7 +1076,7 @@ void SettingsInner::onUpdateLocalStorage() { void SettingsInner::onAutoUpdate() { cSetAutoUpdate(!cAutoUpdate()); - App::writeConfig(); + Local::writeSettings(); resizeEvent(0); if (cAutoUpdate()) { App::app()->startUpdateCheck(); @@ -1068,6 +1111,24 @@ void SettingsInner::onRestartNow() { App::quit(); } +void SettingsInner::onPasscode() { + PasscodeBox *box = new PasscodeBox(); + connect(box, SIGNAL(closed()), this, SLOT(passcodeChanged())); + App::wnd()->showLayer(box); +} + +void SettingsInner::onPasscodeOff() { + PasscodeBox *box = new PasscodeBox(true); + connect(box, SIGNAL(closed()), this, SLOT(passcodeChanged())); + App::wnd()->showLayer(box); +} + +void SettingsInner::onAutoLock() { + AutoLockBox *box = new AutoLockBox(); + connect(box, SIGNAL(closed()), this, SLOT(passcodeChanged())); + App::wnd()->showLayer(box); +} + void SettingsInner::onConnectionType() { ConnectionBox *box = new ConnectionBox(); connect(box, SIGNAL(closed()), this, SLOT(updateConnectionType()), Qt::QueuedConnection); @@ -1090,7 +1151,7 @@ void SettingsInner::onWorkmodeTray() { } cSetWorkMode(newMode); App::wnd()->psUpdateWorkmode(); - App::writeConfig(); + Local::writeSettings(); } void SettingsInner::onWorkmodeWindow() { @@ -1103,7 +1164,7 @@ void SettingsInner::onWorkmodeWindow() { } cSetWorkMode(newMode); App::wnd()->psUpdateWorkmode(); - App::writeConfig(); + Local::writeSettings(); } void SettingsInner::onAutoStart() { @@ -1114,19 +1175,19 @@ void SettingsInner::onAutoStart() { _startMinimized.setChecked(false); } else { psAutoStart(_autoStart.checked()); - App::writeConfig(); + Local::writeSettings(); } } void SettingsInner::onStartMinimized() { cSetStartMinimized(_startMinimized.checked()); - App::writeConfig(); + Local::writeSettings(); } void SettingsInner::onSendToMenu() { cSetSendToMenu(_sendToMenu.checked()); psSendToMenu(_sendToMenu.checked()); - App::writeConfig(); + Local::writeSettings(); } void SettingsInner::onScaleAuto() { @@ -1164,7 +1225,7 @@ void SettingsInner::setScale(DBIScale newScale) { if (cConfigScale() == newScale) return; cSetConfigScale(newScale); - App::writeConfig(); + Local::writeSettings(); App::wnd()->getTitle()->showUpdateBtn(); if (newScale == dbisAuto && !_dpiAutoScale.checked()) { _dpiAutoScale.setChecked(true); @@ -1184,7 +1245,7 @@ void SettingsInner::setScale(DBIScale newScale) { void SettingsInner::onSoundNotify() { cSetSoundNotify(_soundNotify.checked()); - App::writeUserConfig(); + Local::writeUserSettings(); } void SettingsInner::onDesktopNotify() { @@ -1193,11 +1254,11 @@ void SettingsInner::onDesktopNotify() { App::wnd()->notifyClear(); _senderName.setDisabled(true); _messagePreview.setDisabled(true); - App::writeUserConfig(); + Local::writeUserSettings(); } else { _senderName.setDisabled(false); _messagePreview.setDisabled(!_senderName.checked()); - App::writeUserConfig(); + Local::writeUserSettings(); } } @@ -1213,7 +1274,7 @@ void SettingsInner::onSenderName() { } else { cSetNotifyView(dbinvShowNothing); } - App::writeUserConfig(); + Local::writeUserSettings(); App::wnd()->notifyUpdateAll(); } } @@ -1226,13 +1287,13 @@ void SettingsInner::onMessagePreview() { } else { cSetNotifyView(dbinvShowNothing); } - App::writeUserConfig(); + Local::writeUserSettings(); App::wnd()->notifyUpdateAll(); } void SettingsInner::onReplaceEmojis() { cSetReplaceEmojis(_replaceEmojis.checked()); - App::writeUserConfig(); + Local::writeUserSettings(); if (_replaceEmojis.checked()) { _viewEmojis.show(); @@ -1248,14 +1309,14 @@ void SettingsInner::onViewEmojis() { void SettingsInner::onEnterSend() { if (_enterSend.checked()) { cSetCtrlEnter(false); - App::writeUserConfig(); + Local::writeUserSettings(); } } void SettingsInner::onCtrlEnterSend() { if (_ctrlEnterSend.checked()) { cSetCtrlEnter(true); - App::writeUserConfig(); + Local::writeUserSettings(); } } @@ -1323,13 +1384,13 @@ void SettingsInner::onTileBackground() { if (cTileBackground() != _tileBackground.checked()) { cSetTileBackground(_tileBackground.checked()); if (App::main()) App::main()->clearCachedBackground(); - App::writeUserConfig(); + Local::writeUserSettings(); } } void SettingsInner::onDontAskDownloadPath() { cSetAskDownloadPath(!_dontAskDownloadPath.checked()); - App::writeUserConfig(); + Local::writeUserSettings(); showAll(); resizeEvent(0); diff --git a/Telegram/SourceFiles/settingswidget.h b/Telegram/SourceFiles/settingswidget.h index d05afbbb5..851cde1c0 100644 --- a/Telegram/SourceFiles/settingswidget.h +++ b/Telegram/SourceFiles/settingswidget.h @@ -86,6 +86,8 @@ public slots: void usernameChanged(); void updateConnectionType(); + void passcodeChanged(); + void updateBackgroundRect(); void peerUpdated(PeerData *data); @@ -97,6 +99,10 @@ public slots: void onCheckNow(); void onRestartNow(); + void onPasscode(); + void onPasscodeOff(); + void onAutoLock(); + void onConnectionType(); void onUsername(); @@ -242,11 +248,14 @@ private: TempDirClearState _storageClearState; // advanced - LinkButton _connectionType, _resetSessions; - FlatButton _logOut; - + LinkButton _passcodeEdit, _passcodeTurnOff, _autoLock; + QString _autoLockText; + int32 _autoLockWidth; + LinkButton _connectionType; QString _connectionTypeText; int32 _connectionTypeWidth; + LinkButton _resetSessions; + FlatButton _logOut; bool _resetDone; diff --git a/Telegram/SourceFiles/sysbuttons.cpp b/Telegram/SourceFiles/sysbuttons.cpp index 3570178c8..6095ba43d 100644 --- a/Telegram/SourceFiles/sysbuttons.cpp +++ b/Telegram/SourceFiles/sysbuttons.cpp @@ -20,6 +20,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "lang.h" #include "sysbuttons.h" +#include "passcodewidget.h" #include "window.h" #include "application.h" @@ -78,6 +79,11 @@ void SysBtn::paintEvent(QPaintEvent *e) { } } +void SysBtn::setSysBtnStyle(const style::sysButton &st) { + _st = st; + update(); +} + HitTestType SysBtn::hitTest(const QPoint &p) const { int x(p.x()), y(p.y()), w(width()), h(height()); if (x >= 0 && y >= 0 && x < w && y < h && isVisible()) { @@ -145,3 +151,15 @@ void UpdateBtn::onClick() { } App::quit(); } + +LockBtn::LockBtn(QWidget *parent, Window *window) : SysBtn(parent, st::sysLock), wnd(window) { + connect(this, SIGNAL(clicked()), this, SLOT(onClick())); +} + +void LockBtn::onClick() { + if (App::passcoded()) { + App::wnd()->passcodeWidget()->onSubmit(); + } else { + App::wnd()->setupPasscode(true); + } +} diff --git a/Telegram/SourceFiles/sysbuttons.h b/Telegram/SourceFiles/sysbuttons.h index 584aa4f45..49174154d 100644 --- a/Telegram/SourceFiles/sysbuttons.h +++ b/Telegram/SourceFiles/sysbuttons.h @@ -32,6 +32,7 @@ public: void setText(const QString &text); void paintEvent(QPaintEvent *e); + void setSysBtnStyle(const style::sysButton &st); HitTestType hitTest(const QPoint &p) const; @@ -131,3 +132,19 @@ private: Window *wnd; }; + +class LockBtn : public SysBtn { + Q_OBJECT + +public: + + LockBtn(QWidget *parent, Window *window); + +public slots: + + void onClick(); + +private: + + Window *wnd; +}; diff --git a/Telegram/SourceFiles/title.cpp b/Telegram/SourceFiles/title.cpp index 7ec146d1e..564b7c7a5 100644 --- a/Telegram/SourceFiles/title.cpp +++ b/Telegram/SourceFiles/title.cpp @@ -56,6 +56,7 @@ TitleWidget::TitleWidget(Window *window) , _settings(this, lang(lng_menu_settings), st::titleTextButton) , _contacts(this, lang(lng_menu_contacts), st::titleTextButton) , _about(this, lang(lng_menu_about), st::titleTextButton) + , _lock(this, window) , _update(this, window, lang(lng_menu_update)) , _minimize(this, window) , _maximize(this, window) @@ -64,10 +65,11 @@ TitleWidget::TitleWidget(Window *window) , lastMaximized(!(window->windowState() & Qt::WindowMaximized)) { setGeometry(0, 0, wnd->width(), st::titleHeight); + _lock.hide(); _update.hide(); _cancel.hide(); _back.hide(); - if (App::app()->updatingState() == Application::UpdatingReady) { + if (App::app()->updatingState() == Application::UpdatingReady || cHasPasscode()) { showUpdateBtn(); } stateChanged(); @@ -155,6 +157,11 @@ void TitleWidget::resizeEvent(QResizeEvent *e) { if (!_update.isHidden()) { p.setX(p.x() - _update.width()); _update.move(p); + if (!_lock.isHidden()) { + p.setX(p.x() - _lock.width()); + _lock.move(p); + p.setX(p.x() + _lock.width()); + } p.setX(p.x() + _update.width()); } _cancel.move(p.x() - _cancel.width(), 0); @@ -169,15 +176,20 @@ void TitleWidget::resizeEvent(QResizeEvent *e) { p.setX(p.x() - _minimize.width()); _minimize.move(p); } + if (_update.isHidden() && !_lock.isHidden()) { + p.setX(p.x() - _lock.width()); + _lock.move(p); + } + _settings.move(st::titleMenuOffset, 0); _back.move(st::titleMenuOffset, 0); _back.resize((_minimize.isHidden() ? (_update.isHidden() ? width() : _update.x()) : _minimize.x()) - st::titleMenuOffset, _back.height()); - if (MTP::authedId() && _back.isHidden() && _cancel.isHidden()) { - _contacts.show(); + if (MTP::authedId() && _back.isHidden() && _cancel.isHidden() && !App::passcoded()) { + if (_contacts.isHidden()) _contacts.show(); _contacts.move(_settings.x() + _settings.width(), 0); _about.move(_contacts.x() + _contacts.width(), 0); } else { - _contacts.hide(); + if (!_contacts.isHidden()) _contacts.hide(); if (!MTP::authedId()) _about.move(_settings.x() + _settings.width(), 0); } @@ -185,31 +197,41 @@ void TitleWidget::resizeEvent(QResizeEvent *e) { } void TitleWidget::updateBackButton() { - if (!cWideMode() && App::main() && App::main()->selectingPeer()) { - _cancel.show(); + if (App::passcoded()) { + if (!_cancel.isHidden()) _cancel.hide(); if (!_back.isHidden()) _back.hide(); if (!_settings.isHidden()) _settings.hide(); if (!_contacts.isHidden()) _contacts.hide(); if (!_about.isHidden()) _about.hide(); + _lock.setSysBtnStyle(st::sysUnlock); } else { - if (!_cancel.isHidden()) _cancel.hide(); - bool authed = (MTP::authedId() > 0); - if (cWideMode()) { + _lock.setSysBtnStyle(st::sysLock); + if (!cWideMode() && App::main() && App::main()->selectingPeer()) { + _cancel.show(); if (!_back.isHidden()) _back.hide(); - if (_settings.isHidden()) _settings.show(); - if (authed && _contacts.isHidden()) _contacts.show(); - if (_about.isHidden()) _about.show(); + if (!_settings.isHidden()) _settings.hide(); + if (!_contacts.isHidden()) _contacts.hide(); + if (!_about.isHidden()) _about.hide(); } else { - if (App::wnd()->needBackButton()) { - if (_back.isHidden()) _back.show(); - if (!_settings.isHidden()) _settings.hide(); - if (!_contacts.isHidden()) _contacts.hide(); - if (!_about.isHidden()) _about.hide(); - } else { + if (!_cancel.isHidden()) _cancel.hide(); + bool authed = (MTP::authedId() > 0); + if (cWideMode()) { if (!_back.isHidden()) _back.hide(); if (_settings.isHidden()) _settings.show(); if (authed && _contacts.isHidden()) _contacts.show(); if (_about.isHidden()) _about.show(); + } else { + if (App::wnd()->needBackButton()) { + if (_back.isHidden()) _back.show(); + if (!_settings.isHidden()) _settings.hide(); + if (!_contacts.isHidden()) _contacts.hide(); + if (!_about.isHidden()) _about.hide(); + } else { + if (!_back.isHidden()) _back.hide(); + if (_settings.isHidden()) _settings.show(); + if (authed && _contacts.isHidden()) _contacts.show(); + if (_about.isHidden()) _about.show(); + } } } } @@ -281,6 +303,7 @@ void TitleWidget::stateChanged(Qt::WindowState state) { void TitleWidget::showUpdateBtn() { if (!cWideMode() && App::main() && App::main()->selectingPeer()) { _cancel.show(); + _lock.hide(); _update.hide(); _minimize.hide(); _restore.hide(); @@ -288,6 +311,11 @@ void TitleWidget::showUpdateBtn() { _close.hide(); return; } + if (cHasPasscode()) { + _lock.show(); + } else { + _lock.hide(); + } bool updateReady = App::app()->updatingState() == Application::UpdatingReady; if (updateReady || cEvalScale(cConfigScale()) != cEvalScale(cRealScale())) { _update.setText(lang(updateReady ? lng_menu_update : lng_menu_restart)); @@ -338,6 +366,7 @@ HitTestType TitleWidget::hitTest(const QPoint &p) { if (x >= st::titleIconPos.x() && y >= st::titleIconPos.y() && x < st::titleIconPos.x() + st::titleIconImg.pxWidth() && y < st::titleIconPos.y() + st::titleIconImg.pxHeight()) { return HitTestIcon; } else if (false + || (_lock.hitTest(p - _lock.geometry().topLeft()) == HitTestSysButton && _lock.isVisible()) || (_update.hitTest(p - _update.geometry().topLeft()) == HitTestSysButton && _update.isVisible()) || (_minimize.hitTest(p - _minimize.geometry().topLeft()) == HitTestSysButton) || (_maximize.hitTest(p - _maximize.geometry().topLeft()) == HitTestSysButton) diff --git a/Telegram/SourceFiles/title.h b/Telegram/SourceFiles/title.h index 3879d35ee..5a785ce09 100644 --- a/Telegram/SourceFiles/title.h +++ b/Telegram/SourceFiles/title.h @@ -87,6 +87,7 @@ private: MaskedButton _back; FlatButton _cancel, _settings, _contacts, _about; + LockBtn _lock; UpdateBtn _update; MinimizeBtn _minimize; MaximizeBtn _maximize; diff --git a/Telegram/SourceFiles/types.h b/Telegram/SourceFiles/types.h index 75821c3d9..2e3e33a82 100644 --- a/Telegram/SourceFiles/types.h +++ b/Telegram/SourceFiles/types.h @@ -226,7 +226,7 @@ enum DataBlockId { dbiKey = 0, dbiUser = 1, dbiDcOption = 2, - dbiConfig1 = 3, + dbiMaxGroupCount = 3, dbiMutePeer = 4, dbiSendKey = 5, dbiAutoStart = 6, @@ -257,6 +257,7 @@ enum DataBlockId { dbiLang = 31, dbiLangFile = 32, dbiTileBackground = 33, + dbiAutoLock = 34, dbiEncryptedWithSalt = 333, dbiEncrypted = 444, diff --git a/Telegram/SourceFiles/window.cpp b/Telegram/SourceFiles/window.cpp index f9099a1f6..77680becd 100644 --- a/Telegram/SourceFiles/window.cpp +++ b/Telegram/SourceFiles/window.cpp @@ -24,6 +24,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "pspecific.h" #include "title.h" +#include "passcodewidget.h" #include "intro/intro.h" #include "mainwidget.h" #include "layerwidget.h" @@ -156,7 +157,7 @@ void NotifyWindow::updateNotifyDisplay() { p.fillRect(st::notifyBorderWidth, h - st::notifyBorderWidth, w - st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder->b); p.fillRect(0, st::notifyBorderWidth, st::notifyBorderWidth, h - st::notifyBorderWidth, st::notifyBorder->b); - if (cNotifyView() <= dbinvShowName) { + if (!App::passcoded() && cNotifyView() <= dbinvShowName) { if (history->peer->photo->loaded()) { p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), history->peer->photo->pix(st::notifyPhotoSize)); } else { @@ -172,7 +173,7 @@ void NotifyWindow::updateNotifyDisplay() { int32 itemWidth = w - st::notifyPhotoPos.x() - st::notifyPhotoSize - st::notifyTextLeft - st::notifyClosePos.x() - st::notifyClose.width; QRect rectForName(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyTextTop, itemWidth, st::msgNameFont->height); - if (cNotifyView() <= dbinvShowName) { + if (!App::passcoded() && cNotifyView() <= dbinvShowName) { if (history->peer->chat) { p.drawPixmap(QPoint(rectForName.left() + st::dlgChatImgLeft, rectForName.top() + st::dlgChatImgTop), App::sprite(), st::dlgChatImg); rectForName.setLeft(rectForName.left() + st::dlgChatImgSkip); @@ -188,7 +189,7 @@ void NotifyWindow::updateNotifyDisplay() { p.setPen(st::dlgDateColor->p); p.drawText(rectForName.left() + rectForName.width() + st::dlgDateSkip, rectForName.top() + st::dlgHistFont->ascent, dt); - if (cNotifyView() <= dbinvShowPreview) { + if (!App::passcoded() && cNotifyView() <= dbinvShowPreview) { const HistoryItem *textCachedFor = 0; Text itemTextCache(itemWidth); bool active = false; @@ -200,7 +201,7 @@ void NotifyWindow::updateNotifyDisplay() { } p.setPen(st::dlgNameColor->p); - if (cNotifyView() <= dbinvShowName) { + if (!App::passcoded() && cNotifyView() <= dbinvShowName) { history->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); } else { p.setFont(st::msgNameFont->f); @@ -267,8 +268,13 @@ void NotifyWindow::mousePressEvent(QMouseEvent *e) { unlinkHistoryAndNotify(); } else if (history) { App::wnd()->showFromTray(); - App::wnd()->hideSettings(); - App::main()->showPeer(peer, 0, false, true); + if (App::passcoded()) { + App::wnd()->passcodeWidget()->setInnerFocus(); + App::wnd()->notifyClear(); + } else { + App::wnd()->hideSettings(); + App::main()->showPeer(peer, 0, false, true); + } e->ignore(); } } @@ -330,8 +336,8 @@ NotifyWindow::~NotifyWindow() { } Window::Window(QWidget *parent) : PsMainWindow(parent), _serviceHistoryRequest(0), title(0), -intro(0), main(0), settings(0), layerBG(0), _isActive(false), _topWidget(0), -_connecting(0), _clearManager(0), dragging(false), _inactivePress(false), _mediaView(0) { +_passcode(0), intro(0), main(0), settings(0), layerBG(0), _isActive(false), _topWidget(0), +_connecting(0), _clearManager(0), dragging(false), _inactivePress(false), _shouldLockAt(0), _mediaView(0) { icon16 = icon256.scaledToWidth(16, Qt::SmoothTransformation); icon32 = icon256.scaledToWidth(32, Qt::SmoothTransformation); @@ -359,6 +365,8 @@ _connecting(0), _clearManager(0), dragging(false), _inactivePress(false), _media _isActiveTimer.setSingleShot(true); connect(&_isActiveTimer, SIGNAL(timeout()), this, SLOT(updateIsActive())); + + connect(&_autoLockTimer, SIGNAL(timeout()), this, SLOT(checkAutoLock())); } void Window::inactivePress(bool inactive) { @@ -435,6 +443,11 @@ QWidget *Window::filedialogParent() { void Window::clearWidgets() { layerHidden(); + if (_passcode) { + _passcode->hide(); + _passcode->deleteLater(); + _passcode = 0; + } if (settings) { anim::stop(settings); settings->hide(); @@ -459,11 +472,72 @@ void Window::clearWidgets() { title->updateBackButton(); } +void Window::clearPasscode() { + if (!_passcode) return; + + QPixmap bg = myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)); + + anim::stop(_passcode); + _passcode->hide(); + _passcode->deleteLater(); + _passcode = 0; + if (intro) { + intro->animShow(bg, true); + } else { + main->animShow(bg, true); + } + notifyUpdateAll(); + title->updateBackButton(); +} + +void Window::setupPasscode(bool anim) { + QPixmap bg = myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)); + if (_passcode) { + anim::stop(_passcode); + _passcode->hide(); + _passcode->deleteLater(); + } + _passcode = new PasscodeWidget(this); + _passcode->move(0, st::titleHeight); + if (main) main->hide(); + if (settings) settings->hide(); + if (intro) intro->hide(); + if (anim) { + _passcode->animShow(bg); + } else { + _passcode->setInnerFocus(); + } + _shouldLockAt = 0; + notifyUpdateAll(); + title->updateBackButton(); +} + +void Window::checkAutoLockIn(int msec) { + if (_autoLockTimer.isActive()) { + int remain = _autoLockTimer.remainingTime(); + if (remain > 0 && remain <= msec) return; + } + _autoLockTimer.start(msec); +} + +void Window::checkAutoLock() { + if (!cHasPasscode() || App::passcoded()) return; + + App::app()->checkLocalTime(); + uint64 ms = getms(true), idle = psIdleTime(), should = cAutoLock() * 1000ULL; + if (idle >= should || (_shouldLockAt > 0 && ms > _shouldLockAt + 3000ULL)) { + setupPasscode(true); + } else { + _shouldLockAt = ms + (should - idle); + _autoLockTimer.start(should - idle); + } +} + void Window::setupIntro(bool anim) { cSetContactsReceived(false); if (intro && (intro->animating() || intro->isVisible()) && !main) return; - QPixmap bg = myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)); + QPixmap bg = anim ? myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)) : QPixmap(); clearWidgets(); intro = new IntroWidget(this); @@ -515,17 +589,22 @@ void Window::sendServiceHistoryRequest() { _serviceHistoryRequest = MTP::send(MTPmessages_GetHistory(user->input, MTP_int(0), MTP_int(0), MTP_int(1)), main->rpcDone(&MainWidget::serviceHistoryDone), main->rpcFail(&MainWidget::serviceHistoryFail)); } -void Window::setupMain(bool anim) { - QPixmap bg = myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)); +void Window::setupMain(bool anim, const MTPUser *self) { + QPixmap bg = anim ? myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)) : QPixmap(); clearWidgets(); main = new MainWidget(this); main->move(0, st::titleHeight); if (anim) { main->animShow(bg); } else { - MTP::send(MTPusers_GetUsers(MTP_vector(1, MTP_inputUserSelf())), main->rpcDone(&MainWidget::startFull)); main->activate(); } + if (self) { + main->start(*self); + } else { + MTP::send(MTPusers_GetUsers(MTP_vector(1, MTP_inputUserSelf())), main->rpcDone(&MainWidget::startFull)); + } + title->resizeEvent(0); fixOrder(); @@ -540,6 +619,8 @@ void Window::updateCounter() { } void Window::showSettings() { + if (_passcode) return; + if (isHidden()) showFromTray(); App::wnd()->hideLayer(); @@ -563,7 +644,7 @@ void Window::showSettings() { } void Window::hideSettings(bool fast) { - if (!settings) return; + if (!settings || _passcode) return; if (fast) { anim::stop(settings); @@ -595,11 +676,6 @@ void Window::hideSettings(bool fast) { fixOrder(); } -void Window::startMain(const MTPUser &user) { - if (main) main->start(user); - title->resizeEvent(0); -} - void Window::mtpStateChanged(int32 dc, int32 state) { if (dc == MTP::maindc()) { updateTitleStatus(); @@ -633,6 +709,10 @@ SettingsWidget *Window::settingsWidget() { return settings; } +PasscodeWidget *Window::passcodeWidget() { + return _passcode; +} + void Window::showPhoto(const PhotoLink *lnk, HistoryItem *item) { return lnk->peer() ? showPhoto(lnk->photo(), lnk->peer()) : showPhoto(lnk->photo(), item); } @@ -740,7 +820,13 @@ void Window::layerHidden() { } layerBG = 0; if (_mediaView && !_mediaView->isHidden()) _mediaView->hide(); - if (settings) { + setInnerFocus(); +} + +void Window::setInnerFocus() { + if (_passcode) { + _passcode->setInnerFocus(); + } else if (settings) { settings->setInnerFocus(); } else if (main) { main->setInnerFocus(); @@ -872,7 +958,7 @@ bool Window::minimizeToTray() { if (cPlatform() == dbipWindows && trayIcon && !cSeenTrayTooltip()) { trayIcon->showMessage(QString::fromStdWString(AppName), lang(lng_tray_icon_text), QSystemTrayIcon::Information, 10000); cSetSeenTrayTooltip(true); - App::writeConfig(); + Local::writeSettings(); } updateIsActive(cOfflineBlurTimeout()); updateTrayMenu(); @@ -1526,6 +1612,7 @@ QImage Window::iconWithCounter(int size, int count, style::color bg, bool smallI } void Window::sendPaths() { + if (App::passcoded()) return; if (_mediaView && !_mediaView->isHidden()) _mediaView->hide(); if (settings) { hideSettings(); diff --git a/Telegram/SourceFiles/window.h b/Telegram/SourceFiles/window.h index 374d7a473..df035006c 100644 --- a/Telegram/SourceFiles/window.h +++ b/Telegram/SourceFiles/window.h @@ -24,6 +24,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org class MediaView; class TitleWidget; +class PasscodeWidget; class IntroWidget; class MainWidget; class SettingsWidget; @@ -143,9 +144,11 @@ public: void updateWideMode(); bool needBackButton(); + void setupPasscode(bool anim); + void clearPasscode(); + void checkAutoLockIn(int msec); void setupIntro(bool anim); - void setupMain(bool anim); - void startMain(const MTPUser &user); + void setupMain(bool anim, const MTPUser *user = 0); void getNotifySetting(const MTPInputNotifyPeer &peer, uint32 msWait = 0); void serviceNotification(const QString &msg, bool unread = true, const MTPMessageMedia &media = MTP_messageMediaEmpty(), bool force = false); void sendServiceHistoryRequest(); @@ -164,6 +167,7 @@ public: IntroWidget *introWidget(); MainWidget *mainWidget(); SettingsWidget *settingsWidget(); + PasscodeWidget *passcodeWidget(); void showConnecting(const QString &text, const QString &reconnect = QString()); void hideConnecting(); @@ -234,10 +238,13 @@ public slots: void checkHistoryActivation(); void updateCounter(); + + void checkAutoLock(); void showSettings(); void hideSettings(bool fast = false); void layerHidden(); + void setInnerFocus(); void updateTitleStatus(); void quitFromTray(); @@ -279,6 +286,7 @@ private: mtpRequestId _serviceHistoryRequest; TitleWidget *title; + PasscodeWidget *_passcode; IntroWidget *intro; MainWidget *main; SettingsWidget *settings; @@ -300,6 +308,9 @@ private: bool _inactivePress; QTimer _inactiveTimer; + SingleTimer _autoLockTimer; + uint64 _shouldLockAt; + typedef QMap NotifyWhenMap; typedef QMap NotifyWhenMaps; NotifyWhenMaps notifyWhenMaps; diff --git a/Telegram/Telegram.plist b/Telegram/Telegram.plist index e51047c06..b419da83c 100644 --- a/Telegram/Telegram.plist +++ b/Telegram/Telegram.plist @@ -11,7 +11,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.7.18 + 0.7.19 CFBundleSignature ???? CFBundleURLTypes diff --git a/Telegram/Telegram.rc b/Telegram/Telegram.rc index 9fd03f866a5323dfd554506357c74053874d50c7..cea54adc6d6fb7315b0b1de941abbbf63297f1a4 100644 GIT binary patch delta 53 zcmZ3Yy+nIM5ig_V diff --git a/Telegram/Telegram.vcxproj b/Telegram/Telegram.vcxproj index e58af3357..6941e312b 100644 --- a/Telegram/Telegram.vcxproj +++ b/Telegram/Telegram.vcxproj @@ -170,6 +170,10 @@ true true + + true + true + true true @@ -318,6 +322,14 @@ true true + + true + true + + + true + true + true true @@ -334,6 +346,16 @@ true true + + true + true + true + + + true + true + true + true true @@ -398,6 +420,10 @@ true true + + true + true + true true @@ -546,6 +572,14 @@ true true + + true + true + + + true + true + true true @@ -562,6 +596,16 @@ true true + + true + true + true + + + true + true + true + true true @@ -635,6 +679,10 @@ true true + + true + true + true true @@ -783,6 +831,14 @@ true true + + true + true + + + true + true + true true @@ -799,6 +855,16 @@ true true + + true + true + true + + + true + true + true + true true @@ -846,6 +912,7 @@ + @@ -854,6 +921,7 @@ + @@ -905,7 +973,18 @@ + + + true + true + true + + + true + true + true + @@ -1190,6 +1269,34 @@ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DAL_LIBTYPE_STATIC -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui" "-fstdafx.h" "-f../../SourceFiles/boxes/backgroundbox.h" + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing autolockbox.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/boxes/autolockbox.h" -DAL_LIBTYPE_STATIC -DCUSTOM_API_ID -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing autolockbox.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/boxes/autolockbox.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing autolockbox.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/boxes/autolockbox.h" -DAL_LIBTYPE_STATIC -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui" + + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing passcodebox.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/boxes/passcodebox.h" -DAL_LIBTYPE_STATIC -DCUSTOM_API_ID -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing passcodebox.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/boxes/passcodebox.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing passcodebox.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/boxes/passcodebox.h" -DAL_LIBTYPE_STATIC -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui" + Moc%27ing animation.h... @@ -1745,7 +1852,60 @@ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DAL_LIBTYPE_STATIC -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui" "-fstdafx.h" "-f../../SourceFiles/overviewwidget.h" + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing passcodewidget.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/passcodewidget.h" -DAL_LIBTYPE_STATIC -DCUSTOM_API_ID -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing passcodewidget.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/passcodewidget.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing passcodewidget.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/passcodewidget.h" -DAL_LIBTYPE_STATIC -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui" + + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing pspecific_linux.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/pspecific_linux.h" -DAL_LIBTYPE_STATIC -DCUSTOM_API_ID -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing pspecific_linux.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/pspecific_linux.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing pspecific_linux.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/pspecific_linux.h" -DAL_LIBTYPE_STATIC -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui" + true + true + true + + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing pspecific_mac.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/pspecific_mac.h" -DAL_LIBTYPE_STATIC -DCUSTOM_API_ID -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing pspecific_mac.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/pspecific_mac.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing pspecific_mac.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/pspecific_mac.h" -DAL_LIBTYPE_STATIC -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui" + true + true + true + + + true + true + true + @@ -1808,6 +1968,11 @@ + + true + true + true + @@ -1817,4 +1982,4 @@ - + \ No newline at end of file diff --git a/Telegram/Telegram.vcxproj.filters b/Telegram/Telegram.vcxproj.filters index 9960516b1..9366f5704 100644 --- a/Telegram/Telegram.vcxproj.filters +++ b/Telegram/Telegram.vcxproj.filters @@ -786,6 +786,66 @@ Generated Files\Release + + Source Files + + + Generated Files\Deploy + + + Generated Files\Debug + + + Generated Files\Release + + + Source Files + + + Generated Files\Deploy + + + Generated Files\Debug + + + Generated Files\Release + + + Generated Files\Deploy + + + Generated Files\Debug + + + Generated Files\Release + + + Source Files + + + Generated Files\Deploy + + + Generated Files\Debug + + + Generated Files\Release + + + boxes + + + Generated Files\Deploy + + + Generated Files\Debug + + + Generated Files\Release + + + boxes + @@ -866,6 +926,9 @@ Source Files + + Source Files + @@ -1046,6 +1109,21 @@ boxes + + Source Files + + + Source Files + + + Source Files + + + boxes + + + boxes + @@ -1072,5 +1150,8 @@ langs + + Source Files + - + \ No newline at end of file diff --git a/Telegram/Telegram.xcodeproj/project.pbxproj b/Telegram/Telegram.xcodeproj/project.pbxproj index 8bc2a9fe4..eb8a1ef58 100644 --- a/Telegram/Telegram.xcodeproj/project.pbxproj +++ b/Telegram/Telegram.xcodeproj/project.pbxproj @@ -1627,7 +1627,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.7.18; + CURRENT_PROJECT_VERSION = 0.7.19; DEBUG_INFORMATION_FORMAT = dwarf; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; @@ -1645,7 +1645,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 0.7.18; + CURRENT_PROJECT_VERSION = 0.7.19; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_OPTIMIZATION_LEVEL = fast; GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h; @@ -1671,10 +1671,10 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.7.18; + CURRENT_PROJECT_VERSION = 0.7.19; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DYLIB_COMPATIBILITY_VERSION = 0.7; - DYLIB_CURRENT_VERSION = 0.7.18; + DYLIB_CURRENT_VERSION = 0.7.19; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; @@ -1812,10 +1812,10 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.7.18; + CURRENT_PROJECT_VERSION = 0.7.19; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 0.7; - DYLIB_CURRENT_VERSION = 0.7.18; + DYLIB_CURRENT_VERSION = 0.7.19; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; diff --git a/Telegram/Version.sh b/Telegram/Version.sh index 0238c680a..d02406862 100755 --- a/Telegram/Version.sh +++ b/Telegram/Version.sh @@ -1,2 +1,2 @@ -echo 7018 0.7.18 1 +echo 7019 0.7.19 1 # AppVersion AppVersionStr DevChannel