diff --git a/.gitmodules b/.gitmodules index 570f29fe21..874ea8efc7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,9 @@ -[submodule "third_party/GSL"] - path = third_party/GSL - url = https://github.com/Microsoft/GSL.git -[submodule "third_party/variant"] - path = third_party/variant +[submodule "Telegram/ThirdParty/libtgvoip"] + path = Telegram/ThirdParty/libtgvoip + url = https://github.com/telegramdesktop/libtgvoip +[submodule "Telegram/ThirdParty/variant"] + path = Telegram/ThirdParty/variant url = https://github.com/mapbox/variant +[submodule "Telegram/ThirdParty/GSL"] + path = Telegram/ThirdParty/GSL + url = https://github.com/Microsoft/GSL.git diff --git a/Telegram/SourceFiles/auth_session.cpp b/Telegram/SourceFiles/auth_session.cpp index 1c8852b76f..66372fbf44 100644 --- a/Telegram/SourceFiles/auth_session.cpp +++ b/Telegram/SourceFiles/auth_session.cpp @@ -26,6 +26,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "storage/localstorage.h" #include "window/notifications_manager.h" #include "platform/platform_specific.h" +#include "calls/calls_instance.h" namespace { @@ -92,6 +93,7 @@ AuthSession::AuthSession(UserId userId) : _userId(userId) , _autoLockTimer([this] { checkAutoLock(); }) , _api(std::make_unique()) +, _calls(std::make_unique()) , _downloader(std::make_unique()) , _notifications(std::make_unique(this)) { Expects(_userId != 0); diff --git a/Telegram/SourceFiles/auth_session.h b/Telegram/SourceFiles/auth_session.h index e8636d7e8a..dda8b71640 100644 --- a/Telegram/SourceFiles/auth_session.h +++ b/Telegram/SourceFiles/auth_session.h @@ -32,6 +32,10 @@ class System; } // namespace Notifications } // namespace Window +namespace Calls { +class Instance; +} // namespace Calls + class ApiWrap; enum class EmojiPanelTab { @@ -144,6 +148,10 @@ public: return *_api; } + Calls::Instance &calls() { + return *_calls; + } + void checkAutoLock(); void checkAutoLockIn(TimeMs time); @@ -158,6 +166,7 @@ private: base::Timer _autoLockTimer; const std::unique_ptr _api; + const std::unique_ptr _calls; const std::unique_ptr _downloader; const std::unique_ptr _notifications; diff --git a/Telegram/SourceFiles/base/weak_unique_ptr.h b/Telegram/SourceFiles/base/weak_unique_ptr.h index b29a9be8f2..ce0b7b8ce3 100644 --- a/Telegram/SourceFiles/base/weak_unique_ptr.h +++ b/Telegram/SourceFiles/base/weak_unique_ptr.h @@ -86,3 +86,15 @@ private: }; } // namespace base + +#ifdef QT_VERSION +template +inline void InvokeQueued(base::enable_weak_from_this *context, Lambda &&lambda) { + QObject proxy; + QObject::connect(&proxy, &QObject::destroyed, QCoreApplication::instance(), [guard = base::weak_unique_ptr(context), lambda = std::forward(lambda)] { + if (guard) { + lambda(); + } + }, Qt::QueuedConnection); +} +#endif // QT_VERSION diff --git a/Telegram/SourceFiles/calls/calls_instance.cpp b/Telegram/SourceFiles/calls/calls_instance.cpp new file mode 100644 index 0000000000..679f541015 --- /dev/null +++ b/Telegram/SourceFiles/calls/calls_instance.cpp @@ -0,0 +1,248 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#include "calls/calls_instance.h" + +#include "mtproto/connection.h" +#include "auth_session.h" + +#include +#include +#include + +#ifdef slots +#undef slots +#define NEED_TO_RESTORE_SLOTS +#endif // slots + +#include +#include + +#ifdef NEED_TO_RESTORE_SLOTS +#define slots Q_SLOTS +#undef NEED_TO_RESTORE_SLOTS +#endif // NEED_TO_RESTORE_SLOTS + +namespace Calls { +namespace { + +constexpr auto kMinLayer = 65; +constexpr auto kMaxLayer = 65; // MTP::CurrentLayer? + +using tgvoip::Endpoint; + +void ConvertEndpoint(std::vector &ep, const MTPDphoneConnection &mtc) { + if (mtc.vpeer_tag.v.length() != 16) + return; + auto ipv4 = tgvoip::IPv4Address(std::string(mtc.vip.v.constData(), mtc.vip.v.size())); + auto ipv6 = tgvoip::IPv6Address(std::string(mtc.vipv6.v.constData(), mtc.vipv6.v.size())); + ep.push_back(Endpoint((int64_t)mtc.vid.v, (uint16_t)mtc.vport.v, ipv4, ipv6, EP_TYPE_UDP_RELAY, (unsigned char*)mtc.vpeer_tag.v.data())); +} + +} // namespace + +Instance::Instance() = default; + +void Instance::startOutgoingCall(gsl::not_null user) { + if (_controller) { + return; // Already in a call. + } + + _controller = std::make_unique(); + request(MTPmessages_GetDhConfig(MTP_int(_dhConfigVersion), MTP_int(256))).done([this, user](const MTPmessages_DhConfig &result) { + auto random = QByteArray(); + switch (result.type()) { + case mtpc_messages_dhConfig: { + auto &config = result.c_messages_dhConfig(); + if (!MTP::IsPrimeAndGood(config.vp.v, config.vg.v)) { + LOG(("API Error: bad p/g received in dhConfig.")); + callFailed(); + return; + } + _dhConfigG = config.vg.v; + _dhConfigP = config.vp.v; + random = qba(config.vrandom); + } break; + + case mtpc_messages_dhConfigNotModified: { + auto &config = result.c_messages_dhConfigNotModified(); + random = qba(config.vrandom); + if (!_dhConfigG || _dhConfigP.isEmpty()) { + LOG(("API Error: dhConfigNotModified on zero version.")); + callFailed(); + return; + } + } break; + + default: Unexpected("Type in messages.getDhConfig"); + } + if (random.size() != kSaltSize) { + LOG(("API Error: dhConfig random bytes wrong size: %1").arg(random.size())); + callFailed(); + return; + } + + auto randomBytes = reinterpret_cast(random.constData()); + RAND_bytes(_salt.data(), kSaltSize); + for (auto i = 0; i != kSaltSize; i++) { + _salt[i] ^= randomBytes[i]; + } + BN_CTX* ctx = BN_CTX_new(); + BN_CTX_init(ctx); + BIGNUM i_g_a; + BN_init(&i_g_a); + BN_set_word(&i_g_a, _dhConfigG); + BIGNUM tmp; + BN_init(&tmp); + BIGNUM saltBN; + BN_init(&saltBN); + BN_bin2bn(_salt.data(), kSaltSize, &saltBN); + BIGNUM pbytesBN; + BN_init(&pbytesBN); + BN_bin2bn(reinterpret_cast(_dhConfigP.constData()), _dhConfigP.size(), &pbytesBN); + BN_mod_exp(&tmp, &i_g_a, &saltBN, &pbytesBN, ctx); + auto g_a_length = BN_num_bytes(&tmp); + _g_a = QByteArray(g_a_length, Qt::Uninitialized); + BN_bn2bin(&tmp, reinterpret_cast(_g_a.data())); + constexpr auto kMaxGASize = 256; + if (g_a_length > kMaxGASize) { + _g_a = _g_a.mid(1, kMaxGASize); + } + BN_CTX_free(ctx); + + auto randomID = rand_value(); + QByteArray g_a_hash; + g_a_hash.resize(SHA256_DIGEST_LENGTH); + SHA256(reinterpret_cast(_g_a.constData()), _g_a.size(), reinterpret_cast(g_a_hash.data())); + + request(MTPphone_RequestCall(user->inputUser, MTP_int(randomID), MTP_bytes(g_a_hash), MTP_phoneCallProtocol(MTP_flags(MTPDphoneCallProtocol::Flag::f_udp_p2p | MTPDphoneCallProtocol::Flag::f_udp_reflector), MTP_int(kMinLayer), MTP_int(kMaxLayer)))).done([this](const MTPphone_PhoneCall &result) { + Expects(result.type() == mtpc_phone_phoneCall); + auto &call = result.c_phone_phoneCall(); + App::feedUsers(call.vusers); + if (call.vphone_call.type() != mtpc_phoneCallWaiting) { + LOG(("API Error: Expected phoneCallWaiting in response to phone.requestCall()")); + callFailed(); + return; + } + auto &phoneCall = call.vphone_call.c_phoneCallWaiting(); + _callId = phoneCall.vid.v; + _accessHash = phoneCall.vaccess_hash.v; + }).fail([this](const RPCError &error) { + callFailed(); + }).send(); + }).fail([this](const RPCError &error) { + callFailed(); + }).send(); +} + +void Instance::handleUpdate(const MTPDupdatePhoneCall& update) { + // TODO check call id + switch (update.vphone_call.type()) { + case mtpc_phoneCallAccepted: { + // state changed STATE_EXCHANGING_KEYS + auto &call = update.vphone_call.c_phoneCallAccepted(); + // TODO check isGoodGaAndGb + + BN_CTX *ctx = BN_CTX_new(); + BN_CTX_init(ctx); + BIGNUM p; + BIGNUM i_authKey; + BIGNUM res; + BIGNUM salt; + BN_init(&p); + BN_init(&i_authKey); + BN_init(&res); + BN_init(&salt); + BN_bin2bn(reinterpret_cast(_dhConfigP.constData()), _dhConfigP.size(), &p); + BN_bin2bn((const unsigned char*)call.vg_b.v.constData(), call.vg_b.v.length(), &i_authKey); + BN_bin2bn(_salt.data(), kSaltSize, &salt); + + BN_mod_exp(&res, &i_authKey, &salt, &p, ctx); + BN_CTX_free(ctx); + auto realAuthKeyLength = BN_num_bytes(&res); + auto realAuthKeyBytes = QByteArray(realAuthKeyLength, Qt::Uninitialized); + BN_bn2bin(&res, reinterpret_cast(realAuthKeyBytes.data())); + + if (realAuthKeyLength > kAuthKeySize) { + memcpy(_authKey.data(), realAuthKeyBytes.constData() + (realAuthKeyLength - kAuthKeySize), kAuthKeySize); + } else if (realAuthKeyLength < kAuthKeySize) { + memset(_authKey.data(), 0, kAuthKeySize - realAuthKeyLength); + memcpy(_authKey.data() + (kAuthKeySize - realAuthKeyLength), realAuthKeyBytes.constData(), realAuthKeyLength); + } else { + memcpy(_authKey.data(), realAuthKeyBytes.constData(), kAuthKeySize); + } + + unsigned char authKeyHash[SHA_DIGEST_LENGTH]; + SHA1(_authKey.data(), _authKey.size(), authKeyHash); + + _keyFingerprint = ((uint64)authKeyHash[19] << 56) + | ((uint64)authKeyHash[18] << 48) + | ((uint64)authKeyHash[17] << 40) + | ((uint64)authKeyHash[16] << 32) + | ((uint64)authKeyHash[15] << 24) + | ((uint64)authKeyHash[14] << 16) + | ((uint64)authKeyHash[13] << 8) + | ((uint64)authKeyHash[12]); + + request(MTPphone_ConfirmCall(MTP_inputPhoneCall(MTP_long(_callId), MTP_long(_accessHash)), MTP_bytes(_g_a), MTP_long(_keyFingerprint), MTP_phoneCallProtocol(MTP_flags(MTPDphoneCallProtocol::Flag::f_udp_p2p | MTPDphoneCallProtocol::Flag::f_udp_reflector), MTP_int(kMinLayer), MTP_int(kMaxLayer)))).done([this](const MTPphone_PhoneCall &result) { + auto &call = result.c_phone_phoneCall().vphone_call.c_phoneCall(); + + std::vector endpoints; + ConvertEndpoint(endpoints, call.vconnection.c_phoneConnection()); + for (int i = 0; i < call.valternative_connections.v.length(); i++) { + ConvertEndpoint(endpoints, call.valternative_connections.v[i].c_phoneConnection()); + } + _controller->SetRemoteEndpoints(endpoints, true); + + initiateActualCall(); + }).fail([this](const RPCError &error) { + callFailed(); + }).send(); + } break; + } +} + +void Instance::callFailed() { + InvokeQueued(this, [this] { + _controller.reset(); + }); +} + +void Instance::initiateActualCall() { + voip_config_t config; + config.data_saving = DATA_SAVING_NEVER; + config.enableAEC = true; + config.enableNS = true; + config.enableAGC = true; + config.init_timeout = 30; + config.recv_timeout = 10; + _controller->SetConfig(&config); + _controller->SetEncryptionKey(reinterpret_cast(_authKey.data()), true); + _controller->Start(); + _controller->Connect(); +} + +Instance::~Instance() = default; + +Instance &Current() { + return AuthSession::Current().calls(); +} + +} // namespace Calls diff --git a/Telegram/SourceFiles/calls/calls_instance.h b/Telegram/SourceFiles/calls/calls_instance.h new file mode 100644 index 0000000000..50f1cd40eb --- /dev/null +++ b/Telegram/SourceFiles/calls/calls_instance.h @@ -0,0 +1,68 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include "mtproto/sender.h" +#include "base/weak_unique_ptr.h" + +class AuthSession; + +namespace tgvoip { +class VoIPController; +} // namespace tgvoip + +namespace Calls { + +class Instance : public base::enable_weak_from_this, private MTP::Sender { +public: + Instance(); + + void startOutgoingCall(gsl::not_null user); + + void handleUpdate(const MTPDupdatePhoneCall &update); + + ~Instance(); + +private: + void initiateActualCall(); + void callFailed(); + + static constexpr auto kSaltSize = 256; + static constexpr auto kAuthKeySize = 256; + + int32 _dhConfigVersion = 0; + int32 _dhConfigG = 0; + QByteArray _dhConfigP; + + QByteArray _g_a; + std::array _salt; + std::array _authKey; + uint64 _callId = 0; + uint64 _accessHash = 0; + uint64 _keyFingerprint = 0; + + std::unique_ptr _controller; + +}; + +Instance &Current(); + +} // namespace Calls diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index ce9223b35c..e189ef6569 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -67,6 +67,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "auth_session.h" #include "window/notifications_manager.h" #include "window/window_controller.h" +#include "calls/calls_instance.h" StackItemSection::StackItemSection(std::unique_ptr &&memento) : StackItem(nullptr) , _memento(std::move(memento)) { @@ -4854,7 +4855,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { } break; case mtpc_updatePhoneCall: { - auto &d = update.c_updatePhoneCall(); + Calls::Current().handleUpdate(update.c_updatePhoneCall()); } break; case mtpc_updateUserBlocked: { diff --git a/Telegram/ThirdParty/GSL b/Telegram/ThirdParty/GSL new file mode 160000 index 0000000000..c5851a8161 --- /dev/null +++ b/Telegram/ThirdParty/GSL @@ -0,0 +1 @@ +Subproject commit c5851a8161938798c5594a66420cb814fea92711 diff --git a/Telegram/ThirdParty/libtgvoip b/Telegram/ThirdParty/libtgvoip new file mode 160000 index 0000000000..ccf715b626 --- /dev/null +++ b/Telegram/ThirdParty/libtgvoip @@ -0,0 +1 @@ +Subproject commit ccf715b626246990bf57068102bc04014f4ac385 diff --git a/Telegram/ThirdParty/variant b/Telegram/ThirdParty/variant new file mode 160000 index 0000000000..550ac2f159 --- /dev/null +++ b/Telegram/ThirdParty/variant @@ -0,0 +1 @@ +Subproject commit 550ac2f159ca883d360c196149b466955c77a573 diff --git a/Telegram/gyp/Telegram.gyp b/Telegram/gyp/Telegram.gyp index 5b7ead4df4..cee607fe82 100644 --- a/Telegram/gyp/Telegram.gyp +++ b/Telegram/gyp/Telegram.gyp @@ -30,10 +30,9 @@ 'libs_loc': '<(libs_loc)', 'src_loc': '../SourceFiles', 'res_loc': '../Resources', - 'submodules_loc': '../../third_party', - 'third_party_loc': '../ThirdParty', - 'minizip_loc': '<(third_party_loc)/minizip', - 'sp_media_key_tap_loc': '<(third_party_loc)/SPMediaKeyTap', + 'submodules_loc': '../ThirdParty', + 'minizip_loc': '<(submodules_loc)/minizip', + 'sp_media_key_tap_loc': '<(submodules_loc)/SPMediaKeyTap', 'style_files': [ '<(res_loc)/colors.palette', '<(res_loc)/basic.style', @@ -79,10 +78,12 @@ 'codegen.gyp:codegen_numbers', 'codegen.gyp:codegen_style', 'utils.gyp:Updater', + '../ThirdParty/libtgvoip/libtgvoip.gyp:libtgvoip', ], 'defines': [ 'AL_LIBTYPE_STATIC', + 'TGVOIP_USE_CXX11_LIB', ' 1 and sys.argv[1] == '--read-target': - target_path = my_path + '/../build/target' - if os.path.isfile(target_path): - with open(target_path) as f: - for line in f: - cleanline = re.sub(r'^\s*|\s*$', '', line); - if cleanline != '': - print(cleanline); -else: - print('This is a helper script, it should not be called directly.') diff --git a/Telegram/gyp/qt.gypi b/Telegram/gyp/qt.gypi index c12e450b0b..81c13a1822 100644 --- a/Telegram/gyp/qt.gypi +++ b/Telegram/gyp/qt.gypi @@ -130,7 +130,7 @@ 'qt_version%': '<(qt_version)', 'conditions': [ [ 'build_win', { - 'qt_loc': '../../../Libraries/qt<(qt_version_loc)/qtbase', + 'qt_loc': '<(DEPTH)/../../../Libraries/qt<(qt_version_loc)/qtbase', }, { 'qt_loc': '<(qt_loc_unix)', }], diff --git a/Telegram/gyp/refresh.bat b/Telegram/gyp/refresh.bat index 78caadc883..4f29651c76 100644 --- a/Telegram/gyp/refresh.bat +++ b/Telegram/gyp/refresh.bat @@ -6,6 +6,12 @@ set "FullExecPath=%cd%" set "Silence=>nul" if "%1" == "-v" set "Silence=" +if exist "%FullScriptPath%..\build\target" ( + FOR /F "tokens=1* delims= " %%i in (%FullScriptPath%..\build\target) do set "BuildTarget=%%i" +) else ( + set "BuildTarget=" +) + rem strangely linking of Release Telegram build complains about the absence of lib.pdb if exist "%FullScriptPath%..\..\..\Libraries\openssl\tmp32\lib.pdb" ( if not exist "%FullScriptPath%..\..\..\Libraries\openssl\Release\lib\lib.pdb" ( @@ -22,9 +28,9 @@ if not "%TDESKTOP_BUILD_DEFINES%" == "" ( set GYP_MSVS_VERSION=2015 cd "%FullScriptPath%" -call gyp --depth=. --generator-output=../.. -Goutput_dir=out !BUILD_DEFINES! Telegram.gyp --format=ninja +call gyp --depth=. --generator-output=../.. -Goutput_dir=out !BUILD_DEFINES! -Dofficial_build_target=%BuildTarget% Telegram.gyp --format=ninja if %errorlevel% neq 0 goto error -call gyp --depth=. --generator-output=../.. -Goutput_dir=out !BUILD_DEFINES! Telegram.gyp --format=msvs-ninja +call gyp --depth=. --generator-output=../.. -Goutput_dir=out !BUILD_DEFINES! -Dofficial_build_target=%BuildTarget% Telegram.gyp --format=msvs-ninja if %errorlevel% neq 0 goto error cd ../.. diff --git a/Telegram/gyp/refresh.sh b/Telegram/gyp/refresh.sh index 87f16da88b..cd96456c9f 100755 --- a/Telegram/gyp/refresh.sh +++ b/Telegram/gyp/refresh.sh @@ -5,11 +5,19 @@ pushd `dirname $0` > /dev/null FullScriptPath=`pwd` popd > /dev/null +if [ -f "$FullScriptPath/../build/target" ]; then + while IFS='' read -r line || [[ -n "$line" ]]; do + BuildTarget="$line" + done < "$FullScriptPath/../build/target" +else + BuildTarget="" +fi + MySystem=`uname -s` cd $FullScriptPath if [ "$MySystem" == "Linux" ]; then - ../../../Libraries/gyp/gyp --depth=. --generator-output=../.. -Goutput_dir=out Telegram.gyp --format=cmake + ../../../Libraries/gyp/gyp --depth=. --generator-output=../.. -Goutput_dir=out -Dofficial_build_target=$BuildTarget Telegram.gyp --format=cmake cd ../../out/Debug ../../../Libraries/cmake-3.6.2/bin/cmake . cd ../Release @@ -20,7 +28,7 @@ else #gyp --depth=. --generator-output=../.. -Goutput_dir=out Telegram.gyp --format=xcode-ninja #gyp --depth=. --generator-output=../.. -Goutput_dir=out Telegram.gyp --format=xcode # use patched gyp with Xcode project generator - ../../../Libraries/gyp/gyp --depth=. --generator-output=../.. -Goutput_dir=out Telegram.gyp -Gxcode_upgrade_check_project_version=830 --format=xcode + ../../../Libraries/gyp/gyp --depth=. --generator-output=../.. -Goutput_dir=out -Gxcode_upgrade_check_project_version=830 -Dofficial_build_target=$BuildTarget Telegram.gyp --format=xcode fi cd ../.. diff --git a/Telegram/gyp/settings_win.gypi b/Telegram/gyp/settings_win.gypi index 2bcb0797eb..521a850ce5 100644 --- a/Telegram/gyp/settings_win.gypi +++ b/Telegram/gyp/settings_win.gypi @@ -55,25 +55,25 @@ '$(ProjectName)', ], 'libraries': [ - 'winmm', - 'imm32', - 'ws2_32', - 'kernel32', - 'user32', - 'gdi32', - 'winspool', - 'comdlg32', - 'advapi32', - 'shell32', - 'ole32', - 'oleaut32', - 'uuid', - 'odbc32', - 'odbccp32', - 'Shlwapi', - 'Iphlpapi', - 'Gdiplus', - 'Strmiids', + '-lwinmm', + '-limm32', + '-lws2_32', + '-lkernel32', + '-luser32', + '-lgdi32', + '-lwinspool', + '-lcomdlg32', + '-ladvapi32', + '-lshell32', + '-lole32', + '-loleaut32', + '-luuid', + '-lodbc32', + '-lodbccp32', + '-lShlwapi', + '-lIphlpapi', + '-lGdiplus', + '-lStrmiids', ], 'configurations': { diff --git a/Telegram/gyp/telegram_sources.txt b/Telegram/gyp/telegram_sources.txt index a08b77b7db..c52b382681 100644 --- a/Telegram/gyp/telegram_sources.txt +++ b/Telegram/gyp/telegram_sources.txt @@ -79,6 +79,8 @@ <(src_loc)/boxes/stickers_box.h <(src_loc)/boxes/username_box.cpp <(src_loc)/boxes/username_box.h +<(src_loc)/calls/calls_instance.cpp +<(src_loc)/calls/calls_instance.h <(src_loc)/chat_helpers/bot_keyboard.cpp <(src_loc)/chat_helpers/bot_keyboard.h <(src_loc)/chat_helpers/emoji_list_widget.cpp diff --git a/third_party/GSL b/third_party/GSL deleted file mode 160000 index f9c47dd63f..0000000000 --- a/third_party/GSL +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f9c47dd63fe25cc216294fbe7e2fbe4f9a302ca3 diff --git a/third_party/variant b/third_party/variant deleted file mode 160000 index 916139a2e5..0000000000 --- a/third_party/variant +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 916139a2e51e125816efce6e19d428385601273f