Compare commits
284 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df9ec4b466 | ||
|
|
4f9507ed97 | ||
|
|
f761b6aa9e | ||
|
|
168a7ce2e5 | ||
|
|
4b763a76df | ||
|
|
8764da787b | ||
|
|
7d8ba15252 | ||
|
|
96c0c30f7c | ||
|
|
bb6ab5314c | ||
|
|
e3c6abfc3d | ||
|
|
5c5bccae0b | ||
|
|
296e009808 | ||
|
|
4d84781a65 | ||
|
|
710b9bf454 | ||
|
|
0f54315495 | ||
|
|
c3fc91a6fc | ||
|
|
d2048f3c25 | ||
|
|
cc2c13d018 | ||
|
|
48c1576d7f | ||
|
|
d2fa8ef0b0 | ||
|
|
97b576f446 | ||
|
|
257dfa6b3f | ||
|
|
678d2a58c5 | ||
|
|
e0431d270b | ||
|
|
7797e5a3b7 | ||
|
|
d15b0cdb08 | ||
|
|
1af2769209 | ||
|
|
e6906b84f3 | ||
|
|
ca0f6c7ded | ||
|
|
f9ff676e57 | ||
|
|
db7041f2dc | ||
|
|
ad1f089802 | ||
|
|
62c812858e | ||
|
|
4bf66cb6e9 | ||
|
|
95fee543ec | ||
|
|
df4daca15b | ||
|
|
f794d8dbd8 | ||
|
|
9935a36c3d | ||
|
|
a7c77682d7 | ||
|
|
8bbea976ea | ||
|
|
900d1ddb36 | ||
|
|
8e99135f37 | ||
|
|
dc9483e07a | ||
|
|
48e913bf2c | ||
|
|
993cb987a6 | ||
|
|
65f968ec1b | ||
|
|
93f6d4b6e7 | ||
|
|
7482025c10 | ||
|
|
909acb25fd | ||
|
|
4a9db99082 | ||
|
|
a2606c4fc4 | ||
|
|
647c609bf8 | ||
|
|
cf98025177 | ||
|
|
e0f20e9f82 | ||
|
|
597a5c9d75 | ||
|
|
d055908f4f | ||
|
|
f3eac6b259 | ||
|
|
87d6081408 | ||
|
|
dd53bd1c55 | ||
|
|
3ff033cdf3 | ||
|
|
c1c3b6a7e5 | ||
|
|
64d5a6acd5 | ||
|
|
e5b2e0a6b5 | ||
|
|
9895b45293 | ||
|
|
811fc43b63 | ||
|
|
9dcfa3ad6e | ||
|
|
67bda19458 | ||
|
|
6c38919c3d | ||
|
|
ce9445287c | ||
|
|
d4bd8862bd | ||
|
|
6904e023d3 | ||
|
|
91a7a77bb0 | ||
|
|
d9306e3e30 | ||
|
|
efdd3df129 | ||
|
|
63098d3c7d | ||
|
|
aa5781b550 | ||
|
|
d6e1862c08 | ||
|
|
9aa2831fef | ||
|
|
70eb29c1a9 | ||
|
|
13e07b1623 | ||
|
|
27ce1f8d44 | ||
|
|
38c20fc3c2 | ||
|
|
4a32b00068 | ||
|
|
3406f88fdc | ||
|
|
c96cb37680 | ||
|
|
0d415837a0 | ||
|
|
9dc48522d8 | ||
|
|
31b82a5d92 | ||
|
|
87ab4d9dd1 | ||
|
|
b6e7625016 | ||
|
|
c5e6bfce95 | ||
|
|
7a849b2899 | ||
|
|
999fa39d7c | ||
|
|
7de15ce5cf | ||
|
|
f792b0052f | ||
|
|
57d0b1d215 | ||
|
|
7691654cb8 | ||
|
|
c76e4b6b3c | ||
|
|
bda39cc6f6 | ||
|
|
060cdfea86 | ||
|
|
b1cc7b25ba | ||
|
|
1e0fe70dc3 | ||
|
|
8ed167c5fa | ||
|
|
dabf8414be | ||
|
|
a0eb64428e | ||
|
|
dd1beb1d91 | ||
|
|
bb35d71fdc | ||
|
|
42a7e86e51 | ||
|
|
2f3540dadc | ||
|
|
eb00641dfa | ||
|
|
bfe7bf2c11 | ||
|
|
e88c575d4a | ||
|
|
0de9c62675 | ||
|
|
9dc3847dbe | ||
|
|
9dc03c4f0f | ||
|
|
def21367a3 | ||
|
|
33fe1b6389 | ||
|
|
76cb5677b2 | ||
|
|
8c3b7f6417 | ||
|
|
e6c0f0f774 | ||
|
|
6bd5301828 | ||
|
|
73c0c4507a | ||
|
|
506b0806d6 | ||
|
|
054459d327 | ||
|
|
66ac4d6150 | ||
|
|
ab8e7897cc | ||
|
|
2b9133be90 | ||
|
|
56fece6216 | ||
|
|
d381836f01 | ||
|
|
c6efb588dc | ||
|
|
5404dfef08 | ||
|
|
cba12980f9 | ||
|
|
61700577d0 | ||
|
|
321f5d879d | ||
|
|
f98fdeab3f | ||
|
|
90179188b9 | ||
|
|
ccef155f7a | ||
|
|
f0a95032a5 | ||
|
|
c3ff5f2603 | ||
|
|
ee182ea684 | ||
|
|
7f73cc3085 | ||
|
|
dcf70b2847 | ||
|
|
cb5ba7edda | ||
|
|
7940ef24ab | ||
|
|
0f901b3728 | ||
|
|
09aba596ac | ||
|
|
b930ac7bf9 | ||
|
|
7f1bc4635a | ||
|
|
d4253d2025 | ||
|
|
b007fcb537 | ||
|
|
e6dd7d7684 | ||
|
|
128663d95b | ||
|
|
ef8b6d1a3d | ||
|
|
b4baebc230 | ||
|
|
b4581a7bbf | ||
|
|
a285dca39e | ||
|
|
00aa6d5ac3 | ||
|
|
027db285bc | ||
|
|
c3c9ba7e51 | ||
|
|
a1be63f890 | ||
|
|
f066f3f139 | ||
|
|
e17dcbb8eb | ||
|
|
1ae22c8606 | ||
|
|
d5569487a4 | ||
|
|
336e691dbc | ||
|
|
17a4d19beb | ||
|
|
74aa1ad71e | ||
|
|
f8c2f339a0 | ||
|
|
1dd66184a1 | ||
|
|
ddab8c1473 | ||
|
|
49d2c97ceb | ||
|
|
351a423337 | ||
|
|
07528be1e6 | ||
|
|
bc171f625a | ||
|
|
0f775e1e66 | ||
|
|
98fb874b29 | ||
|
|
cfd5c2a650 | ||
|
|
22a5b7faf6 | ||
|
|
fe262701c0 | ||
|
|
e1f71d3919 | ||
|
|
906cb95e67 | ||
|
|
f23c23f696 | ||
|
|
99c686e3e1 | ||
|
|
a144e35f84 | ||
|
|
5a5c5782a9 | ||
|
|
a2a5c30e60 | ||
|
|
3c4c466f8e | ||
|
|
6726826c17 | ||
|
|
e102cb1469 | ||
|
|
11671e85da | ||
|
|
b8614c60f9 | ||
|
|
269defa82d | ||
|
|
8bacc74d8b | ||
|
|
0c5efb935d | ||
|
|
a7f67c4bc9 | ||
|
|
edcaccba1f | ||
|
|
5ebecb4de3 | ||
|
|
9f3048c1dc | ||
|
|
2586268b81 | ||
|
|
280ddb4629 | ||
|
|
20889d7003 | ||
|
|
d4f4698c69 | ||
|
|
adcce61b52 | ||
|
|
17b913fb13 | ||
|
|
366ea1edc3 | ||
|
|
3a5a002be2 | ||
|
|
533fba8c70 | ||
|
|
7435bd7fb0 | ||
|
|
681b9b5ba3 | ||
|
|
600737c44f | ||
|
|
e5f3bed801 | ||
|
|
2fdc3169ce | ||
|
|
722264f634 | ||
|
|
a858ab5d0b | ||
|
|
63c1212ef1 | ||
|
|
2aa477176c | ||
|
|
6bb39451ea | ||
|
|
099a3c4642 | ||
|
|
9515520088 | ||
|
|
fe1a90bd39 | ||
|
|
65df137610 | ||
|
|
ced0c4d8f0 | ||
|
|
f3804429e4 | ||
|
|
a47981054f | ||
|
|
b9ad8bb700 | ||
|
|
47ad5ea98a | ||
|
|
840b42934b | ||
|
|
4527c03c0d | ||
|
|
89941a8e83 | ||
|
|
ebd4651ac2 | ||
|
|
861ab85ca1 | ||
|
|
f9154c4ed0 | ||
|
|
b91ebad8be | ||
|
|
e6baf8ef5b | ||
|
|
d326c7e3fa | ||
|
|
950126865e | ||
|
|
91f369a0b3 | ||
|
|
d1a9d3992b | ||
|
|
2dd2ad5cdb | ||
|
|
04c8c95634 | ||
|
|
8a56ede187 | ||
|
|
7425e80f05 | ||
|
|
97a9089ebf | ||
|
|
bee474f6e9 | ||
|
|
4740d44159 | ||
|
|
062b0b2165 | ||
|
|
8060cb7426 | ||
|
|
794e31505b | ||
|
|
50b120bc22 | ||
|
|
f0b2e445f6 | ||
|
|
782e70b171 | ||
|
|
9d2239291d | ||
|
|
a2891807f8 | ||
|
|
6a9556d42c | ||
|
|
724fe65d72 | ||
|
|
46612ef128 | ||
|
|
139ef5411a | ||
|
|
ac57000437 | ||
|
|
31234cb487 | ||
|
|
05e36a064f | ||
|
|
f88cbf3d4b | ||
|
|
7814ee0f7a | ||
|
|
9f4e5e4603 | ||
|
|
810fb45750 | ||
|
|
55e56a6788 | ||
|
|
ea7441ae77 | ||
|
|
f65e8824fb | ||
|
|
2868899d81 | ||
|
|
54dd05c556 | ||
|
|
6b25160e3f | ||
|
|
0ef3e19bc2 | ||
|
|
e89350d4b7 | ||
|
|
95399bef2b | ||
|
|
06c724df01 | ||
|
|
3325106837 | ||
|
|
9c72470c17 | ||
|
|
94cf307ae0 | ||
|
|
2cc1fde5e4 | ||
|
|
6796ac688a | ||
|
|
9551cfaf9b | ||
|
|
8ef9ec0567 | ||
|
|
af552fb4c0 | ||
|
|
ae7e5be5cd | ||
|
|
74b126f309 |
@@ -486,6 +486,9 @@ buildOpenAL() {
|
||||
-D CMAKE_INSTALL_PREFIX=$OPENAL_PATH \
|
||||
-D CMAKE_BUILD_TYPE=Release \
|
||||
-D LIBTYPE=STATIC \
|
||||
-D ALSOFT_EXAMPLES=OFF \
|
||||
-D ALSOFT_TESTS=OFF \
|
||||
-D ALSOFT_UTILS=OFF \
|
||||
..
|
||||
make $MAKE_ARGS
|
||||
sudo make install
|
||||
@@ -608,7 +611,7 @@ buildCustomQt() {
|
||||
./configure -prefix $QT_PATH -release -opensource -confirm-license -qt-zlib \
|
||||
-qt-libpng -qt-libjpeg -qt-freetype -qt-harfbuzz -qt-pcre -qt-xcb \
|
||||
-qt-xkbcommon-x11 -no-opengl -no-gtkstyle -static \
|
||||
-nomake examples -nomake tests \
|
||||
-nomake examples -nomake tests -no-mirclient \
|
||||
-dbus-runtime -no-gstreamer -no-mtdev # <- Not sure about these
|
||||
make $MAKE_ARGS
|
||||
sudo make install
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Copyright (c) 2014-2018 John Preston, https://desktop.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
|
||||
@@ -15,27 +16,6 @@ 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.
|
||||
|
||||
More information about the Telegram project: https://telegram.org
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/flat_map.h"
|
||||
|
||||
namespace Dialogs {
|
||||
|
||||
class Row;
|
||||
using RowsByLetter = base::flat_map<QChar, Row*>;
|
||||
|
||||
enum class SortMode {
|
||||
Date = 0x00,
|
||||
Name = 0x01,
|
||||
Add = 0x02,
|
||||
};
|
||||
|
||||
enum class Mode {
|
||||
All = 0x00,
|
||||
Important = 0x01,
|
||||
};
|
||||
|
||||
} // namespace Dialogs
|
||||
1
LICENSE
@@ -4,6 +4,7 @@ version 3 with the addition of the following special exception:
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the OpenSSL
|
||||
library.
|
||||
|
||||
You must obey the GNU General Public License in all respects for all of
|
||||
the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the file(s),
|
||||
|
||||
@@ -15,7 +15,7 @@ The source code is published under GPLv3 with OpenSSL exception, the license is
|
||||
* Windows XP - Windows 10 (**not** RT)
|
||||
* Mac OS X 10.8 - Mac OS X 10.11
|
||||
* Mac OS X 10.6 - Mac OS X 10.7 (separate build)
|
||||
* Ubuntu 12.04 - Ubuntu 16.04
|
||||
* Ubuntu 12.04 - Ubuntu 18.04
|
||||
* Fedora 22 - Fedora 24
|
||||
|
||||
## Third-party
|
||||
|
||||
107
Telegram/Patches/crashpad.diff
Normal file
@@ -0,0 +1,107 @@
|
||||
diff --git a/client/capture_context_mac_test.cc b/client/capture_context_mac_test.cc
|
||||
index 436ac5ad..8e14fb9c 100644
|
||||
--- a/client/capture_context_mac_test.cc
|
||||
+++ b/client/capture_context_mac_test.cc
|
||||
@@ -34,11 +34,11 @@ namespace {
|
||||
// gtest assertions.
|
||||
void SanityCheckContext(const NativeCPUContext& context) {
|
||||
#if defined(ARCH_CPU_X86)
|
||||
- ASSERT_EQ(x86_THREAD_STATE32, context.tsh.flavor);
|
||||
- ASSERT_EQ(implicit_cast<int>(x86_THREAD_STATE32_COUNT), context.tsh.count);
|
||||
+ ASSERT_EQ(implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE32), implicit_cast<thread_state_flavor_t>(context.tsh.flavor));
|
||||
+ ASSERT_EQ(implicit_cast<uint32_t>(x86_THREAD_STATE32_COUNT), implicit_cast<uint32_t>(context.tsh.count));
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
- ASSERT_EQ(x86_THREAD_STATE64, context.tsh.flavor);
|
||||
- ASSERT_EQ(implicit_cast<int>(x86_THREAD_STATE64_COUNT), context.tsh.count);
|
||||
+ ASSERT_EQ(implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE64), implicit_cast<thread_state_flavor_t>(context.tsh.flavor));
|
||||
+ ASSERT_EQ(implicit_cast<uint32_t>(x86_THREAD_STATE64_COUNT), implicit_cast<uint32_t>(context.tsh.count));
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
diff --git a/client/simulate_crash_mac.cc b/client/simulate_crash_mac.cc
|
||||
index 7e279015..27864388 100644
|
||||
--- a/client/simulate_crash_mac.cc
|
||||
+++ b/client/simulate_crash_mac.cc
|
||||
@@ -177,12 +177,12 @@ bool DeliverException(thread_t thread,
|
||||
|
||||
void SimulateCrash(const NativeCPUContext& cpu_context) {
|
||||
#if defined(ARCH_CPU_X86)
|
||||
- DCHECK_EQ(cpu_context.tsh.flavor,
|
||||
+ DCHECK_EQ(implicit_cast<thread_state_flavor_t>(cpu_context.tsh.flavor),
|
||||
implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE32));
|
||||
DCHECK_EQ(implicit_cast<mach_msg_type_number_t>(cpu_context.tsh.count),
|
||||
x86_THREAD_STATE32_COUNT);
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
- DCHECK_EQ(cpu_context.tsh.flavor,
|
||||
+ DCHECK_EQ(implicit_cast<thread_state_flavor_t>(cpu_context.tsh.flavor),
|
||||
implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE64));
|
||||
DCHECK_EQ(implicit_cast<mach_msg_type_number_t>(cpu_context.tsh.count),
|
||||
x86_THREAD_STATE64_COUNT);
|
||||
diff --git a/client/simulate_crash_mac_test.cc b/client/simulate_crash_mac_test.cc
|
||||
index 87c5f845..ca813e4c 100644
|
||||
--- a/client/simulate_crash_mac_test.cc
|
||||
+++ b/client/simulate_crash_mac_test.cc
|
||||
@@ -130,12 +130,12 @@ class TestSimulateCrashMac final : public MachMultiprocess,
|
||||
reinterpret_cast<const x86_thread_state*>(old_state);
|
||||
switch (state->tsh.flavor) {
|
||||
case x86_THREAD_STATE32:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_THREAD_STATE32_COUNT),
|
||||
- state->tsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_THREAD_STATE32_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->tsh.count));
|
||||
break;
|
||||
case x86_THREAD_STATE64:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_THREAD_STATE64_COUNT),
|
||||
- state->tsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_THREAD_STATE64_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->tsh.count));
|
||||
break;
|
||||
default:
|
||||
ADD_FAILURE() << "unexpected tsh.flavor " << state->tsh.flavor;
|
||||
@@ -149,12 +149,12 @@ class TestSimulateCrashMac final : public MachMultiprocess,
|
||||
reinterpret_cast<const x86_float_state*>(old_state);
|
||||
switch (state->fsh.flavor) {
|
||||
case x86_FLOAT_STATE32:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_FLOAT_STATE32_COUNT),
|
||||
- state->fsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_FLOAT_STATE32_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->fsh.count));
|
||||
break;
|
||||
case x86_FLOAT_STATE64:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_FLOAT_STATE64_COUNT),
|
||||
- state->fsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_FLOAT_STATE64_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->fsh.count));
|
||||
break;
|
||||
default:
|
||||
ADD_FAILURE() << "unexpected fsh.flavor " << state->fsh.flavor;
|
||||
@@ -168,12 +168,12 @@ class TestSimulateCrashMac final : public MachMultiprocess,
|
||||
reinterpret_cast<const x86_debug_state*>(old_state);
|
||||
switch (state->dsh.flavor) {
|
||||
case x86_DEBUG_STATE32:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_DEBUG_STATE32_COUNT),
|
||||
- state->dsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_DEBUG_STATE32_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->dsh.count));
|
||||
break;
|
||||
case x86_DEBUG_STATE64:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_DEBUG_STATE64_COUNT),
|
||||
- state->dsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_DEBUG_STATE64_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->dsh.count));
|
||||
break;
|
||||
default:
|
||||
ADD_FAILURE() << "unexpected dsh.flavor " << state->dsh.flavor;
|
||||
diff --git a/crashpad.gyp b/crashpad.gyp
|
||||
index 42fe0a26..d8af1bf1 100644
|
||||
--- a/crashpad.gyp
|
||||
+++ b/crashpad.gyp
|
||||
@@ -25,7 +25,7 @@
|
||||
'minidump/minidump.gyp:*',
|
||||
'minidump/minidump_test.gyp:*',
|
||||
'snapshot/snapshot.gyp:*',
|
||||
- 'snapshot/snapshot_test.gyp:*',
|
||||
+# 'snapshot/snapshot_test.gyp:*',
|
||||
'test/test.gyp:*',
|
||||
'test/test_test.gyp:*',
|
||||
'tools/tools.gyp:*',
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/build/crashpad.gypi b/build/crashpad.gypi
|
||||
index 027c7b6..4bfdfb5 100644
|
||||
index 027c7b68..4bfdfb5a 100644
|
||||
--- a/build/crashpad.gypi
|
||||
+++ b/build/crashpad.gypi
|
||||
@@ -25,5 +25,15 @@
|
||||
@@ -18,3 +18,110 @@ index 027c7b6..4bfdfb5 100644
|
||||
+ ],
|
||||
},
|
||||
}
|
||||
diff --git a/client/capture_context_mac_test.cc b/client/capture_context_mac_test.cc
|
||||
index 436ac5ad..8e14fb9c 100644
|
||||
--- a/client/capture_context_mac_test.cc
|
||||
+++ b/client/capture_context_mac_test.cc
|
||||
@@ -34,11 +34,11 @@ namespace {
|
||||
// gtest assertions.
|
||||
void SanityCheckContext(const NativeCPUContext& context) {
|
||||
#if defined(ARCH_CPU_X86)
|
||||
- ASSERT_EQ(x86_THREAD_STATE32, context.tsh.flavor);
|
||||
- ASSERT_EQ(implicit_cast<int>(x86_THREAD_STATE32_COUNT), context.tsh.count);
|
||||
+ ASSERT_EQ(implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE32), implicit_cast<thread_state_flavor_t>(context.tsh.flavor));
|
||||
+ ASSERT_EQ(implicit_cast<uint32_t>(x86_THREAD_STATE32_COUNT), implicit_cast<uint32_t>(context.tsh.count));
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
- ASSERT_EQ(x86_THREAD_STATE64, context.tsh.flavor);
|
||||
- ASSERT_EQ(implicit_cast<int>(x86_THREAD_STATE64_COUNT), context.tsh.count);
|
||||
+ ASSERT_EQ(implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE64), implicit_cast<thread_state_flavor_t>(context.tsh.flavor));
|
||||
+ ASSERT_EQ(implicit_cast<uint32_t>(x86_THREAD_STATE64_COUNT), implicit_cast<uint32_t>(context.tsh.count));
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
diff --git a/client/simulate_crash_mac.cc b/client/simulate_crash_mac.cc
|
||||
index 7e279015..27864388 100644
|
||||
--- a/client/simulate_crash_mac.cc
|
||||
+++ b/client/simulate_crash_mac.cc
|
||||
@@ -177,12 +177,12 @@ bool DeliverException(thread_t thread,
|
||||
|
||||
void SimulateCrash(const NativeCPUContext& cpu_context) {
|
||||
#if defined(ARCH_CPU_X86)
|
||||
- DCHECK_EQ(cpu_context.tsh.flavor,
|
||||
+ DCHECK_EQ(implicit_cast<thread_state_flavor_t>(cpu_context.tsh.flavor),
|
||||
implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE32));
|
||||
DCHECK_EQ(implicit_cast<mach_msg_type_number_t>(cpu_context.tsh.count),
|
||||
x86_THREAD_STATE32_COUNT);
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
- DCHECK_EQ(cpu_context.tsh.flavor,
|
||||
+ DCHECK_EQ(implicit_cast<thread_state_flavor_t>(cpu_context.tsh.flavor),
|
||||
implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE64));
|
||||
DCHECK_EQ(implicit_cast<mach_msg_type_number_t>(cpu_context.tsh.count),
|
||||
x86_THREAD_STATE64_COUNT);
|
||||
diff --git a/client/simulate_crash_mac_test.cc b/client/simulate_crash_mac_test.cc
|
||||
index 87c5f845..ca813e4c 100644
|
||||
--- a/client/simulate_crash_mac_test.cc
|
||||
+++ b/client/simulate_crash_mac_test.cc
|
||||
@@ -130,12 +130,12 @@ class TestSimulateCrashMac final : public MachMultiprocess,
|
||||
reinterpret_cast<const x86_thread_state*>(old_state);
|
||||
switch (state->tsh.flavor) {
|
||||
case x86_THREAD_STATE32:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_THREAD_STATE32_COUNT),
|
||||
- state->tsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_THREAD_STATE32_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->tsh.count));
|
||||
break;
|
||||
case x86_THREAD_STATE64:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_THREAD_STATE64_COUNT),
|
||||
- state->tsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_THREAD_STATE64_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->tsh.count));
|
||||
break;
|
||||
default:
|
||||
ADD_FAILURE() << "unexpected tsh.flavor " << state->tsh.flavor;
|
||||
@@ -149,12 +149,12 @@ class TestSimulateCrashMac final : public MachMultiprocess,
|
||||
reinterpret_cast<const x86_float_state*>(old_state);
|
||||
switch (state->fsh.flavor) {
|
||||
case x86_FLOAT_STATE32:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_FLOAT_STATE32_COUNT),
|
||||
- state->fsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_FLOAT_STATE32_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->fsh.count));
|
||||
break;
|
||||
case x86_FLOAT_STATE64:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_FLOAT_STATE64_COUNT),
|
||||
- state->fsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_FLOAT_STATE64_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->fsh.count));
|
||||
break;
|
||||
default:
|
||||
ADD_FAILURE() << "unexpected fsh.flavor " << state->fsh.flavor;
|
||||
@@ -168,12 +168,12 @@ class TestSimulateCrashMac final : public MachMultiprocess,
|
||||
reinterpret_cast<const x86_debug_state*>(old_state);
|
||||
switch (state->dsh.flavor) {
|
||||
case x86_DEBUG_STATE32:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_DEBUG_STATE32_COUNT),
|
||||
- state->dsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_DEBUG_STATE32_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->dsh.count));
|
||||
break;
|
||||
case x86_DEBUG_STATE64:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_DEBUG_STATE64_COUNT),
|
||||
- state->dsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_DEBUG_STATE64_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->dsh.count));
|
||||
break;
|
||||
default:
|
||||
ADD_FAILURE() << "unexpected dsh.flavor " << state->dsh.flavor;
|
||||
diff --git a/crashpad.gyp b/crashpad.gyp
|
||||
index 42fe0a26..d8af1bf1 100644
|
||||
--- a/crashpad.gyp
|
||||
+++ b/crashpad.gyp
|
||||
@@ -25,7 +25,7 @@
|
||||
'minidump/minidump.gyp:*',
|
||||
'minidump/minidump_test.gyp:*',
|
||||
'snapshot/snapshot.gyp:*',
|
||||
- 'snapshot/snapshot_test.gyp:*',
|
||||
+# 'snapshot/snapshot_test.gyp:*',
|
||||
'test/test.gyp:*',
|
||||
'test/test_test.gyp:*',
|
||||
'tools/tools.gyp:*',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/configure b/configure
|
||||
index cb8d78f..cadb3f0 100755
|
||||
index cb8d78fd3cb..cadb3f0a880 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -511,7 +511,8 @@ if [ "$BUILD_ON_MAC" = "yes" ]; then
|
||||
@@ -13,7 +13,7 @@ index cb8d78f..cadb3f0 100755
|
||||
echo " Xcode not set up properly. You may need to confirm the license" >&2
|
||||
echo " agreement by running /usr/bin/xcodebuild without arguments." >&2
|
||||
diff --git a/mkspecs/common/g++-macx.conf b/mkspecs/common/g++-macx.conf
|
||||
index 086510d..c485967 100644
|
||||
index 086510dd963..c485967863d 100644
|
||||
--- a/mkspecs/common/g++-macx.conf
|
||||
+++ b/mkspecs/common/g++-macx.conf
|
||||
@@ -14,7 +14,13 @@ QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -gdwarf-2
|
||||
@@ -32,7 +32,7 @@ index 086510d..c485967 100644
|
||||
QMAKE_XCODE_GCC_VERSION = com.apple.compilers.llvmgcc42
|
||||
|
||||
diff --git a/mkspecs/features/mac/default_pre.prf b/mkspecs/features/mac/default_pre.prf
|
||||
index 0cc8cd6..ca9725b 100644
|
||||
index 0cc8cd6dfdd..ca9725b7791 100644
|
||||
--- a/mkspecs/features/mac/default_pre.prf
|
||||
+++ b/mkspecs/features/mac/default_pre.prf
|
||||
@@ -12,7 +12,9 @@ isEmpty(QMAKE_XCODE_DEVELOPER_PATH) {
|
||||
@@ -47,7 +47,7 @@ index 0cc8cd6..ca9725b 100644
|
||||
}
|
||||
|
||||
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
|
||||
index bb79a13..5d595bc 100644
|
||||
index bb79a139b3c..5d595bc3b34 100644
|
||||
--- a/src/gui/image/qbmphandler.cpp
|
||||
+++ b/src/gui/image/qbmphandler.cpp
|
||||
@@ -220,6 +220,10 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
|
||||
@@ -74,7 +74,7 @@ index bb79a13..5d595bc 100644
|
||||
if (ncols > 0) { // read color table
|
||||
uchar rgb[4];
|
||||
diff --git a/src/gui/painting/qpaintengine_p.h b/src/gui/painting/qpaintengine_p.h
|
||||
index ebff950..4300ca4 100644
|
||||
index ebff9509ab2..4300ca4c0f0 100644
|
||||
--- a/src/gui/painting/qpaintengine_p.h
|
||||
+++ b/src/gui/painting/qpaintengine_p.h
|
||||
@@ -87,8 +87,18 @@ public:
|
||||
@@ -98,7 +98,7 @@ index ebff950..4300ca4 100644
|
||||
|
||||
// Make sure we're inside the viewport.
|
||||
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
|
||||
index 4879ae5..56cdcba 100644
|
||||
index 4879ae51d7d..56cdcbaf01c 100644
|
||||
--- a/src/gui/text/qtextlayout.cpp
|
||||
+++ b/src/gui/text/qtextlayout.cpp
|
||||
@@ -654,6 +654,9 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
|
||||
@@ -175,7 +175,7 @@ index 4879ae5..56cdcba 100644
|
||||
|
||||
inline void resetRightBearing()
|
||||
diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h
|
||||
index cbe42c3..b273db7 100644
|
||||
index cbe42c38444..b273db7e78c 100644
|
||||
--- a/src/gui/text/qtextlayout.h
|
||||
+++ b/src/gui/text/qtextlayout.h
|
||||
@@ -194,6 +194,9 @@ private:
|
||||
@@ -188,8 +188,21 @@ index cbe42c3..b273db7 100644
|
||||
};
|
||||
|
||||
|
||||
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
|
||||
index 360f9722c70..f28f289ef6a 100644
|
||||
--- a/src/network/access/qhttpnetworkconnection.cpp
|
||||
+++ b/src/network/access/qhttpnetworkconnection.cpp
|
||||
@@ -118,6 +118,8 @@ QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate()
|
||||
{
|
||||
for (int i = 0; i < channelCount; ++i) {
|
||||
if (channels[i].socket) {
|
||||
+ // Patch: backport critical bugfix from '4f959b6b30' commit.
|
||||
+ QObject::disconnect(channels[i].socket, Q_NULLPTR, &channels[i], Q_NULLPTR);
|
||||
channels[i].socket->close();
|
||||
delete channels[i].socket;
|
||||
}
|
||||
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
|
||||
index ca7afb7..25ae500 100644
|
||||
index ca7afb7d1b9..25ae50008db 100644
|
||||
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
|
||||
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
|
||||
@@ -256,6 +256,13 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
|
||||
@@ -206,8 +219,22 @@ index ca7afb7..25ae500 100644
|
||||
fd->styleName = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontStyleNameAttribute);
|
||||
fd->weight = QFont::Normal;
|
||||
fd->style = QFont::StyleNormal;
|
||||
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
|
||||
index 6e2c8a2a9af..3cace8abcbc 100644
|
||||
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
|
||||
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
|
||||
@@ -717,7 +717,8 @@ void QCoreTextFontEngine::getUnscaledGlyph(glyph_t, QPainterPath *, glyph_metric
|
||||
|
||||
QFixed QCoreTextFontEngine::emSquareSize() const
|
||||
{
|
||||
- return QFixed::QFixed(int(CTFontGetUnitsPerEm(ctfont)));
|
||||
+ // Patch: Fix build for Xcode 9.3.1.
|
||||
+ return QFixed(int(CTFontGetUnitsPerEm(ctfont)));
|
||||
}
|
||||
|
||||
QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
|
||||
index 92358ec..694fee7 100644
|
||||
index 92358ecc745..694fee73507 100644
|
||||
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
|
||||
@@ -213,7 +213,8 @@ static void cleanupCocoaApplicationDelegate()
|
||||
@@ -244,7 +271,7 @@ index 92358ec..694fee7 100644
|
||||
|
||||
- (void)appleEventQuit:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm
|
||||
index b81b9a0..4e59e83 100644
|
||||
index b81b9a0b1c2..4e59e833b1d 100644
|
||||
--- a/src/plugins/platforms/cocoa/qcocoacursor.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoacursor.mm
|
||||
@@ -81,7 +81,7 @@ void QCocoaCursor::setPos(const QPoint &position)
|
||||
@@ -256,8 +283,41 @@ index b81b9a0..4e59e83 100644
|
||||
CGEventPost(kCGHIDEventTap, e);
|
||||
CFRelease(e);
|
||||
}
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
|
||||
index 9850f83dea8..b2e1d3dfda7 100644
|
||||
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
|
||||
@@ -649,9 +649,10 @@ OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGIm
|
||||
// Verbatim copy if HIViewDrawCGImage (as shown on Carbon-Dev)
|
||||
OSStatus err = noErr;
|
||||
|
||||
- require_action(inContext != NULL, InvalidContext, err = paramErr);
|
||||
- require_action(inBounds != NULL, InvalidBounds, err = paramErr);
|
||||
- require_action(inImage != NULL, InvalidImage, err = paramErr);
|
||||
+ // Patch: Fix build on latest Xcode.
|
||||
+ //require_action(inContext != NULL, InvalidContext, err = paramErr);
|
||||
+ //require_action(inBounds != NULL, InvalidBounds, err = paramErr);
|
||||
+ //require_action(inImage != NULL, InvalidImage, err = paramErr);
|
||||
|
||||
CGContextSaveGState( inContext );
|
||||
CGContextTranslateCTM (inContext, 0, inBounds->origin.y + CGRectGetMaxY(*inBounds));
|
||||
@@ -660,9 +661,11 @@ OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGIm
|
||||
CGContextDrawImage(inContext, *inBounds, inImage);
|
||||
|
||||
CGContextRestoreGState(inContext);
|
||||
-InvalidImage:
|
||||
-InvalidBounds:
|
||||
-InvalidContext:
|
||||
+
|
||||
+// Patch: Fix build on latest Xcode.
|
||||
+//InvalidImage:
|
||||
+//InvalidBounds:
|
||||
+//InvalidContext:
|
||||
return err;
|
||||
}
|
||||
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
|
||||
index 9fd05a6..dea6072 100644
|
||||
index 9fd05a65ee9..dea60720e78 100644
|
||||
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
|
||||
@@ -402,14 +402,24 @@ void QCocoaIntegration::updateScreens()
|
||||
@@ -288,7 +348,7 @@ index 9fd05a6..dea6072 100644
|
||||
|
||||
QCocoaScreen *QCocoaIntegration::screenAtIndex(int index)
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoakeymapper.mm b/src/plugins/platforms/cocoa/qcocoakeymapper.mm
|
||||
index e46eaff..c62db53 100644
|
||||
index e46eaff6be3..c62db534a2d 100644
|
||||
--- a/src/plugins/platforms/cocoa/qcocoakeymapper.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoakeymapper.mm
|
||||
@@ -382,6 +382,12 @@ bool QCocoaKeyMapper::updateKeyboard()
|
||||
@@ -315,7 +375,7 @@ index e46eaff..c62db53 100644
|
||||
}
|
||||
return ret;
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
|
||||
index 83c960d..03ae969 100755
|
||||
index 83c960d9317..03ae9696afe 100755
|
||||
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
|
||||
@@ -102,7 +102,10 @@ QT_USE_NAMESPACE
|
||||
@@ -483,7 +543,7 @@ index 83c960d..03ae969 100755
|
||||
}
|
||||
@end
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
|
||||
index 4d0458a..3357a5e 100644
|
||||
index 4d0458a4aa2..3357a5ef817 100644
|
||||
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
|
||||
@@ -167,7 +167,8 @@ static bool isMouseEvent(NSEvent *ev)
|
||||
@@ -546,7 +606,7 @@ index 4d0458a..3357a5e 100644
|
||||
[iconButton setImage:image];
|
||||
[image release];
|
||||
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
|
||||
index a18ee7f..1f91feb 100644
|
||||
index a18ee7ff71d..1f91feb0ae8 100644
|
||||
--- a/src/plugins/platforms/cocoa/qnsview.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qnsview.mm
|
||||
@@ -393,7 +393,9 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
|
||||
@@ -615,7 +675,7 @@ index a18ee7f..1f91feb 100644
|
||||
}
|
||||
return [super performKeyEquivalent:nsevent];
|
||||
diff --git a/src/tools/qlalr/lalr.cpp b/src/tools/qlalr/lalr.cpp
|
||||
index c680764..e2a7aaf 100644
|
||||
index c68076477f3..e2a7aafa586 100644
|
||||
--- a/src/tools/qlalr/lalr.cpp
|
||||
+++ b/src/tools/qlalr/lalr.cpp
|
||||
@@ -246,11 +246,13 @@ void Grammar::buildExtendedGrammar ()
|
||||
@@ -655,7 +715,7 @@ index c680764..e2a7aaf 100644
|
||||
continue;
|
||||
|
||||
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
|
||||
index 7396808..7178aec 100644
|
||||
index 7396808442e..7178aecf800 100644
|
||||
--- a/src/widgets/kernel/qwidget.cpp
|
||||
+++ b/src/widgets/kernel/qwidget.cpp
|
||||
@@ -4722,6 +4722,17 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
|
||||
@@ -708,7 +768,7 @@ index 7396808..7178aec 100644
|
||||
|| (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier)))
|
||||
res = focusNextPrevChild(false);
|
||||
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
|
||||
index 0845a5e..5735cb6 100644
|
||||
index 0845a5eb02f..5735cb6b396 100644
|
||||
--- a/src/widgets/styles/qmacstyle_mac.mm
|
||||
+++ b/src/widgets/styles/qmacstyle_mac.mm
|
||||
@@ -3667,9 +3667,11 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
|
||||
@@ -726,7 +786,7 @@ index 0845a5e..5735cb6 100644
|
||||
}
|
||||
|
||||
diff --git a/src/widgets/util/qsystemtrayicon_qpa.cpp b/src/widgets/util/qsystemtrayicon_qpa.cpp
|
||||
index f98aeaf..00c0734 100644
|
||||
index f98aeaf6782..00c0734129e 100644
|
||||
--- a/src/widgets/util/qsystemtrayicon_qpa.cpp
|
||||
+++ b/src/widgets/util/qsystemtrayicon_qpa.cpp
|
||||
@@ -99,13 +99,18 @@ void QSystemTrayIconPrivate::updateIcon_sys()
|
||||
@@ -755,7 +815,7 @@ index f98aeaf..00c0734 100644
|
||||
}
|
||||
|
||||
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
|
||||
index 75f3059..980f2be 100644
|
||||
index 75f30599be4..980f2be1e93 100644
|
||||
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
|
||||
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
|
||||
@@ -1867,7 +1867,8 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event)
|
||||
@@ -769,7 +829,7 @@ index 75f3059..980f2be 100644
|
||||
#ifndef QT_NO_COMPLETER
|
||||
complete(event->key());
|
||||
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
|
||||
index 96438a0..b0b7206 100644
|
||||
index 96438a0bdf7..b0b72064056 100644
|
||||
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
|
||||
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
|
||||
@@ -1342,7 +1342,8 @@ void QWidgetTextControlPrivate::keyPressEvent(QKeyEvent *e)
|
||||
|
||||
@@ -221,6 +221,19 @@ index f74d4d4229..8ad672c9fe 100644
|
||||
};
|
||||
|
||||
|
||||
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
|
||||
index c4cb8e65c0..45793e364f 100644
|
||||
--- a/src/network/access/qhttpnetworkconnection.cpp
|
||||
+++ b/src/network/access/qhttpnetworkconnection.cpp
|
||||
@@ -110,6 +110,8 @@ QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate()
|
||||
{
|
||||
for (int i = 0; i < channelCount; ++i) {
|
||||
if (channels[i].socket) {
|
||||
+ // Patch: backport critical bugfix from '4f959b6b30' commit.
|
||||
+ QObject::disconnect(channels[i].socket, Q_NULLPTR, &channels[i], Q_NULLPTR);
|
||||
channels[i].socket->close();
|
||||
delete channels[i].socket;
|
||||
}
|
||||
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
|
||||
index 41834b21ae..8cdf4ab145 100644
|
||||
--- a/src/network/socket/qnativesocketengine_win.cpp
|
||||
@@ -417,6 +430,20 @@ index 566abf2126..5b9c714ffa 100644
|
||||
fd->styleName = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontStyleNameAttribute);
|
||||
fd->weight = QFont::Normal;
|
||||
fd->style = QFont::StyleNormal;
|
||||
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
|
||||
index 7b459584ea..2ed2fd9b3b 100644
|
||||
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
|
||||
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
|
||||
@@ -764,7 +764,8 @@ void QCoreTextFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, gl
|
||||
|
||||
QFixed QCoreTextFontEngine::emSquareSize() const
|
||||
{
|
||||
- return QFixed::QFixed(int(CTFontGetUnitsPerEm(ctfont)));
|
||||
+ // Patch: Fix build for Xcode 9.3.1.
|
||||
+ return QFixed(int(CTFontGetUnitsPerEm(ctfont)));
|
||||
}
|
||||
|
||||
QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const
|
||||
diff --git a/src/plugins/platforminputcontexts/compose/compose.pro b/src/plugins/platforminputcontexts/compose/compose.pro
|
||||
index 86bdd4729b..9b9c8ded08 100644
|
||||
--- a/src/plugins/platforminputcontexts/compose/compose.pro
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
using "colors.palette";
|
||||
|
||||
@@ -228,8 +215,6 @@ emojiReplaceHeight: 56px;
|
||||
emojiReplaceInnerHeight: 42px;
|
||||
emojiReplacePadding: 14px;
|
||||
|
||||
connectingPadding: margins(5px, 5px, 5px, 5px);
|
||||
|
||||
dragFont: font(28px semibold);
|
||||
dragSubfont: font(20px semibold);
|
||||
dragColor: windowSubTextFg;
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
|
||||
// basic
|
||||
|
||||
BIN
Telegram/Resources/icons/connecting_body.png
Normal file
|
After Width: | Height: | Size: 95 B |
BIN
Telegram/Resources/icons/connecting_body@2x.png
Normal file
|
After Width: | Height: | Size: 112 B |
BIN
Telegram/Resources/icons/connecting_body_shadow.png
Normal file
|
After Width: | Height: | Size: 117 B |
BIN
Telegram/Resources/icons/connecting_body_shadow@2x.png
Normal file
|
After Width: | Height: | Size: 151 B |
BIN
Telegram/Resources/icons/connecting_left.png
Normal file
|
After Width: | Height: | Size: 357 B |
BIN
Telegram/Resources/icons/connecting_left@2x.png
Normal file
|
After Width: | Height: | Size: 717 B |
BIN
Telegram/Resources/icons/connecting_left_shadow.png
Normal file
|
After Width: | Height: | Size: 550 B |
BIN
Telegram/Resources/icons/connecting_left_shadow@2x.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/Resources/icons/connecting_right.png
Normal file
|
After Width: | Height: | Size: 347 B |
BIN
Telegram/Resources/icons/connecting_right@2x.png
Normal file
|
After Width: | Height: | Size: 679 B |
BIN
Telegram/Resources/icons/connecting_right_shadow.png
Normal file
|
After Width: | Height: | Size: 573 B |
BIN
Telegram/Resources/icons/connecting_right_shadow@2x.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/Resources/icons/dialogs_feed.png
Normal file
|
After Width: | Height: | Size: 328 B |
BIN
Telegram/Resources/icons/dialogs_feed@2x.png
Normal file
|
After Width: | Height: | Size: 626 B |
BIN
Telegram/Resources/icons/info_feed.png
Normal file
|
After Width: | Height: | Size: 748 B |
BIN
Telegram/Resources/icons/info_feed@2x.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
Telegram/Resources/icons/passport_ready.png
Normal file
|
After Width: | Height: | Size: 369 B |
BIN
Telegram/Resources/icons/passport_ready@2x.png
Normal file
|
After Width: | Height: | Size: 655 B |
BIN
Telegram/Resources/icons/proxy_off.png
Normal file
|
After Width: | Height: | Size: 529 B |
BIN
Telegram/Resources/icons/proxy_off@2x.png
Normal file
|
After Width: | Height: | Size: 1012 B |
BIN
Telegram/Resources/icons/proxy_on.png
Normal file
|
After Width: | Height: | Size: 584 B |
BIN
Telegram/Resources/icons/proxy_on@2x.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/Resources/icons/stickers_empty.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
Telegram/Resources/icons/stickers_empty@2x.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
Telegram/Resources/icons/stickers_search.png
Normal file
|
After Width: | Height: | Size: 493 B |
BIN
Telegram/Resources/icons/stickers_search@2x.png
Normal file
|
After Width: | Height: | Size: 926 B |
@@ -1,17 +1,7 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
|
||||
@@ -1,17 +1,7 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
|
||||
@@ -1,17 +1,7 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
|
||||
@@ -1,17 +1,7 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
|
||||
@@ -1,17 +1,7 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
"lng_language_name" = "English";
|
||||
"lng_switch_to_this" = "Continue in English";
|
||||
@@ -309,6 +296,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_settings_section_chat_settings" = "Chat Settings";
|
||||
"lng_settings_replace_emojis" = "Replace emoji";
|
||||
"lng_settings_suggest_emoji" = "Suggest emoji replacements";
|
||||
"lng_settings_suggest_by_emoji" = "Suggest popular stickers by emoji";
|
||||
"lng_settings_view_emojis" = "View list";
|
||||
"lng_settings_send_enter" = "Send by Enter";
|
||||
"lng_settings_send_ctrlenter" = "Send by Ctrl+Enter";
|
||||
@@ -430,8 +419,30 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_connection_port_ph" = "Port";
|
||||
"lng_connection_user_ph" = "Username";
|
||||
"lng_connection_password_ph" = "Password";
|
||||
"lng_connection_proxy_secret_ph" = "Secret";
|
||||
"lng_connection_save" = "Save";
|
||||
|
||||
"lng_proxy_settings" = "Proxy settings";
|
||||
"lng_proxy_use" = "Use proxy";
|
||||
"lng_proxy_use_for_calls" = "Use proxy for calls";
|
||||
"lng_proxy_about" = "Proxy servers may be helpful in accessing Telegram if there is no connection in a specific region.";
|
||||
"lng_proxy_add" = "Add proxy";
|
||||
"lng_proxy_share" = "Share";
|
||||
"lng_proxy_online" = "online";
|
||||
"lng_proxy_checking" = "checking";
|
||||
"lng_proxy_connecting" = "connecting";
|
||||
"lng_proxy_available" = "available (ping: {ping}ms)";
|
||||
"lng_proxy_unavailable" = "not available";
|
||||
"lng_proxy_edit" = "Edit proxy";
|
||||
"lng_proxy_menu_edit" = "Edit";
|
||||
"lng_proxy_menu_delete" = "Delete";
|
||||
"lng_proxy_menu_restore" = "Restore";
|
||||
"lng_proxy_edit_share" = "Share";
|
||||
"lng_proxy_address_label" = "Socket address";
|
||||
"lng_proxy_credentials_optional" = "Credentials (optional)";
|
||||
"lng_proxy_credentials" = "Credentials";
|
||||
"lng_proxy_description" = "Your saved proxy list will be here.";
|
||||
|
||||
"lng_settings_blocked_users" = "Blocked users";
|
||||
"lng_settings_last_seen_privacy" = "Last seen privacy";
|
||||
"lng_settings_calls_privacy" = "Phone calls privacy";
|
||||
@@ -680,6 +691,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_report_title" = "Report channel";
|
||||
"lng_report_group_title" = "Report group";
|
||||
"lng_report_bot_title" = "Report bot";
|
||||
"lng_report_message_title" = "Report message";
|
||||
"lng_report_reason_spam" = "Spam";
|
||||
"lng_report_reason_violence" = "Violence";
|
||||
"lng_report_reason_pornography" = "Pornography";
|
||||
@@ -806,6 +818,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_action_payment_done_for" = "You have just successfully transferred {amount} to {user} for {invoice}";
|
||||
"lng_action_took_screenshot" = "{from} took a screenshot!";
|
||||
"lng_action_you_took_screenshot" = "You took a screenshot!";
|
||||
"lng_action_bot_allowed_from_domain" = "You allowed this bot to message you when you logged in on {domain}.";
|
||||
|
||||
"lng_ttl_photo_received" = "{from} sent you a self-destructing photo. Please view it on your mobile.";
|
||||
"lng_ttl_photo_sent" = "You sent a self-destructing photo.";
|
||||
@@ -831,6 +844,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_channel_not_accessible" = "Sorry, this channel is not accessible.";
|
||||
"lng_group_not_accessible" = "Sorry, this group is not accessible.";
|
||||
"lng_group_full" = "Sorry, this group is full.";
|
||||
|
||||
"lng_channels_too_much_public_about" = "Sorry, you have reserved too many public usernames. You can revoke the link from one of your older groups or channels.";
|
||||
"lng_channels_too_much_public_revoke_confirm_group" = "Are you sure you want to revoke the link {link}?\n\nThe group «{group}» will become private.";
|
||||
@@ -863,6 +877,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_edited" = "edited";
|
||||
"lng_edited_date" = "Edited: {date}";
|
||||
"lng_admin_badge" = "admin";
|
||||
"lng_fast_reply" = "Reply";
|
||||
"lng_cancel_edit_post_sure" = "Cancel editing?";
|
||||
"lng_cancel_edit_post_yes" = "Yes";
|
||||
"lng_cancel_edit_post_no" = "No";
|
||||
@@ -937,6 +952,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_stickers_remove_group_set" = "Remove group sticker set?";
|
||||
"lng_stickers_group_from_your" = "Choose from your stickers";
|
||||
"lng_stickers_group_from_featured" = "Choose from trending stickers";
|
||||
"lng_stickers_search_sets" = "Search sticker sets";
|
||||
"lng_stickers_nothing_found" = "No stickers found";
|
||||
"lng_stickers_remove_pack_confirm" = "Remove";
|
||||
|
||||
"lng_in_dlg_photo" = "Photo";
|
||||
"lng_in_dlg_album" = "Album";
|
||||
@@ -1036,6 +1054,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_user_action_upload_file" = "{user} is sending a file";
|
||||
"lng_unread_bar#one" = "{count} unread message";
|
||||
"lng_unread_bar#other" = "{count} unread messages";
|
||||
"lng_unread_bar_some" = "Unread messages";
|
||||
|
||||
"lng_maps_point" = "Location";
|
||||
"lng_save_photo" = "Save image";
|
||||
@@ -1054,6 +1073,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_context_view_profile" = "View profile";
|
||||
"lng_context_view_group" = "View group info";
|
||||
"lng_context_view_channel" = "View channel info";
|
||||
"lng_context_view_feed_info" = "View feed info";
|
||||
"lng_context_pin_to_top" = "Pin to top";
|
||||
"lng_context_unpin_from_top" = "Unpin from top";
|
||||
|
||||
@@ -1087,6 +1107,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_context_forward_msg" = "Forward Message";
|
||||
"lng_context_delete_msg" = "Delete Message";
|
||||
"lng_context_select_msg" = "Select Message";
|
||||
"lng_context_report_msg" = "Report Message";
|
||||
"lng_context_pin_msg" = "Pin Message";
|
||||
"lng_context_unpin_msg" = "Unpin Message";
|
||||
"lng_context_cancel_upload" = "Cancel Upload";
|
||||
@@ -1427,6 +1448,33 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_admin_log_admin_pin_messages" = "Pin messages";
|
||||
"lng_admin_log_admin_add_admins" = "Add new admins";
|
||||
|
||||
"lng_feed_name" = "Feed";
|
||||
"lng_feed_show_next" = "Show Next";
|
||||
|
||||
"lng_feed_group" = "Group in feed";
|
||||
"lng_feed_ungroup" = "Ungroup from feed";
|
||||
"lng_feed_channel_added" = "Channel added to your feed.";
|
||||
"lng_feed_channel_removed" = "Channel removed from your feed.";
|
||||
"lng_feed_no_messages" = "No messages in this feed yet";
|
||||
"lng_feed_channels#one" = "{count} channel";
|
||||
"lng_feed_channels#other" = "{count} channels";
|
||||
"lng_feed_notifications" = "Feed notifications";
|
||||
"lng_feed_ungroup_all" = "Ungroup all channels";
|
||||
"lng_feed_sure_ungroup_all" = "Are you sure you want to ungroup all channels from this feed?";
|
||||
"lng_feed_ungroup_sure" = "Ungroup";
|
||||
"lng_feed_create_new" = "New feed";
|
||||
"lng_feed_too_few_channels#one" = "You need at least {count} channel to create a feed.";
|
||||
"lng_feed_too_few_channels#other" = "You need at least {count} channels to create a feed.";
|
||||
"lng_feed_select_more_channels#one" = "Select {count} channel or more.";
|
||||
"lng_feed_select_more_channels#other" = "Select {count} channels or more.";
|
||||
"lng_feed_create" = "Create";
|
||||
"lng_feed_edit_title" = "Edit feed";
|
||||
"lng_feed_channels_not_found" = "No channels found";
|
||||
|
||||
"lng_info_feed_title" = "Feed Info";
|
||||
"lng_info_feed_is_default" = "Group new channels";
|
||||
"lng_info_feed_channels" = "Channels";
|
||||
|
||||
// Wnd specific
|
||||
|
||||
"lng_wnd_choose_program_menu" = "Choose Default Program...";
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
"lng_language_name" = "Deutsch";
|
||||
"lng_switch_to_this" = "Auf Deutsch zurücksetzen";
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
"lng_language_name" = "Español";
|
||||
"lng_switch_to_this" = "Cambiar a español";
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
"lng_language_name" = "Italiano";
|
||||
"lng_switch_to_this" = "Passa all'Italiano";
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
"lng_language_name" = "영어";
|
||||
"lng_switch_to_this" = "영어로 변경";
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
"lng_language_name" = "Nederlands";
|
||||
"lng_switch_to_this" = "Overschakelen naar Nederlands";
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
"lng_language_name" = "Português (Brasil)";
|
||||
"lng_switch_to_this" = "Trocar para Português (Brasil)";
|
||||
|
||||
@@ -1,17 +1,7 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
|
||||
@@ -1,17 +1,7 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
|
||||
@@ -54,6 +54,7 @@ destroy_auth_key_fail#ea109b13 = DestroyAuthKeyRes;
|
||||
---functions---
|
||||
|
||||
req_pq#60469778 nonce:int128 = ResPQ;
|
||||
req_pq_multi#be7e8ef1 nonce:int128 = ResPQ;
|
||||
|
||||
req_DH_params#d712e4be nonce:int128 server_nonce:int128 p:string q:string public_key_fingerprint:long encrypted_data:string = Server_DH_Params;
|
||||
|
||||
@@ -106,8 +107,13 @@ new_session_created#9ec20908 first_msg_id:long unique_id:long server_salt:long =
|
||||
|
||||
http_wait#9299359f max_delay:int wait_after:int max_wait:int = HttpWait;
|
||||
|
||||
ipPort ipv4:int port:int = IpPort;
|
||||
help.configSimple#d997c3c5 date:int expires:int dc_id:int ip_port_list:Vector<ipPort> = help.ConfigSimple;
|
||||
//ipPort ipv4:int port:int = IpPort;
|
||||
//help.configSimple#d997c3c5 date:int expires:int dc_id:int ip_port_list:Vector<ipPort> = help.ConfigSimple;
|
||||
|
||||
ipPort#d433ad73 ipv4:int port:int = IpPort;
|
||||
ipPortSecret#37982646 ipv4:int port:int secret:bytes = IpPort;
|
||||
accessPointRule#4679b65f phone_prefix_rules:string dc_id:int ips:vector<IpPort> = AccessPointRule;
|
||||
help.configSimple#5a592a6c date:int expires:int rules:vector<AccessPointRule> = help.ConfigSimple;
|
||||
|
||||
---functions---
|
||||
|
||||
@@ -155,16 +161,16 @@ inputFile#f52ff27f id:long parts:int name:string md5_checksum:string = InputFile
|
||||
inputFileBig#fa4f0bb5 id:long parts:int name:string = InputFile;
|
||||
|
||||
inputMediaEmpty#9664f57f = InputMedia;
|
||||
inputMediaUploadedPhoto#2f37e231 flags:# file:InputFile caption:string stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
|
||||
inputMediaPhoto#81fa373a flags:# id:InputPhoto caption:string ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaUploadedPhoto#1e287d04 flags:# file:InputFile stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
|
||||
inputMediaPhoto#b3ba0635 flags:# id:InputPhoto ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia;
|
||||
inputMediaContact#a6e45987 phone_number:string first_name:string last_name:string = InputMedia;
|
||||
inputMediaUploadedDocument#e39621fd flags:# nosound_video:flags.3?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector<DocumentAttribute> caption:string stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
|
||||
inputMediaDocument#5acb668e flags:# id:InputDocument caption:string ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaUploadedDocument#5b38c6c1 flags:# nosound_video:flags.3?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector<DocumentAttribute> stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
|
||||
inputMediaDocument#23ab23d2 flags:# id:InputDocument ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaVenue#c13d1c11 geo_point:InputGeoPoint title:string address:string provider:string venue_id:string venue_type:string = InputMedia;
|
||||
inputMediaGifExternal#4843b0fd url:string q:string = InputMedia;
|
||||
inputMediaPhotoExternal#922aec1 flags:# url:string caption:string ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaDocumentExternal#b6f74335 flags:# url:string caption:string ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaPhotoExternal#e5bbfe1a flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaGame#d33f43f3 id:InputGame = InputMedia;
|
||||
inputMediaInvoice#f4e096c3 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:string = InputMedia;
|
||||
inputMediaGeoLive#7b1a118f geo_point:InputGeoPoint period:int = InputMedia;
|
||||
@@ -219,7 +225,7 @@ userStatusLastMonth#77ebc742 = UserStatus;
|
||||
chatEmpty#9ba2d800 id:int = Chat;
|
||||
chat#d91cdd54 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true admins_enabled:flags.3?true admin:flags.4?true deactivated:flags.5?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel = Chat;
|
||||
chatForbidden#7328bdb id:int title:string = Chat;
|
||||
channel#450b7115 flags:# creator:flags.0?true left:flags.2?true editor:flags.3?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true democracy:flags.10?true signatures:flags.11?true min:flags.12?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string admin_rights:flags.14?ChannelAdminRights banned_rights:flags.15?ChannelBannedRights participants_count:flags.17?int = Chat;
|
||||
channel#c88974ac flags:# creator:flags.0?true left:flags.2?true editor:flags.3?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true democracy:flags.10?true signatures:flags.11?true min:flags.12?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string admin_rights:flags.14?ChannelAdminRights banned_rights:flags.15?ChannelBannedRights participants_count:flags.17?int = Chat;
|
||||
channelForbidden#289da732 flags:# broadcast:flags.5?true megagroup:flags.8?true id:int access_hash:long title:string until_date:flags.16?int = Chat;
|
||||
|
||||
chatFull#2e02a614 id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> = ChatFull;
|
||||
@@ -240,11 +246,11 @@ message#44f9b43d flags:# out:flags.1?true mentioned:flags.4?true media_unread:fl
|
||||
messageService#9e19a1f6 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true id:int from_id:flags.8?int to_id:Peer reply_to_msg_id:flags.3?int date:int action:MessageAction = Message;
|
||||
|
||||
messageMediaEmpty#3ded6320 = MessageMedia;
|
||||
messageMediaPhoto#b5223b0f flags:# photo:flags.0?Photo caption:flags.1?string ttl_seconds:flags.2?int = MessageMedia;
|
||||
messageMediaPhoto#695150d7 flags:# photo:flags.0?Photo ttl_seconds:flags.2?int = MessageMedia;
|
||||
messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
|
||||
messageMediaContact#5e7d2f39 phone_number:string first_name:string last_name:string user_id:int = MessageMedia;
|
||||
messageMediaUnsupported#9f84f49e = MessageMedia;
|
||||
messageMediaDocument#7c4414d3 flags:# document:flags.0?Document caption:flags.1?string ttl_seconds:flags.2?int = MessageMedia;
|
||||
messageMediaDocument#9cb070d7 flags:# document:flags.0?Document ttl_seconds:flags.2?int = MessageMedia;
|
||||
messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia;
|
||||
messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia;
|
||||
messageMediaGame#fdb19008 game:Game = MessageMedia;
|
||||
@@ -270,6 +276,7 @@ messageActionPaymentSent#40699cd0 currency:string total_amount:long = MessageAct
|
||||
messageActionPhoneCall#80e11a7f flags:# call_id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = MessageAction;
|
||||
messageActionScreenshotTaken#4792929b = MessageAction;
|
||||
messageActionCustomAction#fae69f56 message:string = MessageAction;
|
||||
messageActionBotAllowed#abe9affe domain:string = MessageAction;
|
||||
|
||||
dialog#e4def5db flags:# pinned:flags.2?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage = Dialog;
|
||||
|
||||
@@ -304,7 +311,6 @@ inputPeerNotifySettings#38935eb2 flags:# show_previews:flags.0?true silent:flags
|
||||
peerNotifyEventsEmpty#add53cb3 = PeerNotifyEvents;
|
||||
peerNotifyEventsAll#6d1ded88 = PeerNotifyEvents;
|
||||
|
||||
peerNotifySettingsEmpty#70a68512 = PeerNotifySettings;
|
||||
peerNotifySettings#9acda4c0 flags:# show_previews:flags.0?true silent:flags.1?true mute_until:int sound:string = PeerNotifySettings;
|
||||
|
||||
peerSettings#818426cd flags:# report_spam:flags.0?true = PeerSettings;
|
||||
@@ -422,8 +428,8 @@ updateRecentStickers#9a422c20 = Update;
|
||||
updateConfig#a229dd06 = Update;
|
||||
updatePtsChanged#3354678f = Update;
|
||||
updateChannelWebPage#40771900 channel_id:int webpage:WebPage pts:int pts_count:int = Update;
|
||||
updateDialogPinned#d711a2cc flags:# pinned:flags.0?true peer:Peer = Update;
|
||||
updatePinnedDialogs#d8caf68d flags:# order:flags.0?Vector<Peer> = Update;
|
||||
updateDialogPinned#19d27f3c flags:# pinned:flags.0?true peer:DialogPeer = Update;
|
||||
updatePinnedDialogs#ea4cb65b flags:# order:flags.0?Vector<DialogPeer> = Update;
|
||||
updateBotWebhookJSON#8317c0c3 data:DataJSON = Update;
|
||||
updateBotWebhookJSONQuery#9b9240a6 query_id:long data:DataJSON timeout:int = Update;
|
||||
updateBotShippingQuery#e0cdc940 query_id:long user_id:int payload:bytes shipping_address:PostAddress = Update;
|
||||
@@ -457,11 +463,11 @@ photos.photosSlice#15051f54 count:int photos:Vector<Photo> users:Vector<User> =
|
||||
photos.photo#20212ca8 photo:Photo users:Vector<User> = photos.Photo;
|
||||
|
||||
upload.file#96a18d5 type:storage.FileType mtime:int bytes:bytes = upload.File;
|
||||
upload.fileCdnRedirect#ea52fe5a dc_id:int file_token:bytes encryption_key:bytes encryption_iv:bytes cdn_file_hashes:Vector<CdnFileHash> = upload.File;
|
||||
upload.fileCdnRedirect#f18cda44 dc_id:int file_token:bytes encryption_key:bytes encryption_iv:bytes file_hashes:Vector<FileHash> = upload.File;
|
||||
|
||||
dcOption#5d8c6cc flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true static:flags.4?true id:int ip_address:string port:int = DcOption;
|
||||
dcOption#18b7a10d flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true static:flags.4?true id:int ip_address:string port:int secret:flags.10?bytes = DcOption;
|
||||
|
||||
config#9c840964 flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int chat_big_size:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string suggested_lang_code:flags.2?string lang_pack_version:flags.2?int disabled_features:Vector<DisabledFeature> = Config;
|
||||
config#eb7bb160 flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true blocked_mode:flags.8?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string autoupdate_url_prefix:flags.7?string suggested_lang_code:flags.2?string lang_pack_version:flags.2?int = Config;
|
||||
|
||||
nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc;
|
||||
|
||||
@@ -522,7 +528,7 @@ sendMessageGamePlayAction#dd6a8f48 = SendMessageAction;
|
||||
sendMessageRecordRoundAction#88f27fbc = SendMessageAction;
|
||||
sendMessageUploadRoundAction#243e1c66 progress:int = SendMessageAction;
|
||||
|
||||
contacts.found#1aa1f784 results:Vector<Peer> chats:Vector<Chat> users:Vector<User> = contacts.Found;
|
||||
contacts.found#b3134d9d my_results:Vector<Peer> results:Vector<Peer> chats:Vector<Chat> users:Vector<User> = contacts.Found;
|
||||
|
||||
inputPrivacyKeyStatusTimestamp#4f96cb18 = InputPrivacyKey;
|
||||
inputPrivacyKeyChatInvite#bdfb0426 = InputPrivacyKey;
|
||||
@@ -553,7 +559,7 @@ accountDaysTTL#b8d0afdf days:int = AccountDaysTTL;
|
||||
documentAttributeImageSize#6c37c15c w:int h:int = DocumentAttribute;
|
||||
documentAttributeAnimated#11b58939 = DocumentAttribute;
|
||||
documentAttributeSticker#6319d612 flags:# mask:flags.1?true alt:string stickerset:InputStickerSet mask_coords:flags.0?MaskCoords = DocumentAttribute;
|
||||
documentAttributeVideo#ef02ce6 flags:# round_message:flags.0?true duration:int w:int h:int = DocumentAttribute;
|
||||
documentAttributeVideo#ef02ce6 flags:# round_message:flags.0?true supports_streaming:flags.1?true duration:int w:int h:int = DocumentAttribute;
|
||||
documentAttributeAudio#9852f9c6 flags:# voice:flags.10?true duration:int title:flags.0?string performer:flags.1?string waveform:flags.2?bytes = DocumentAttribute;
|
||||
documentAttributeFilename#15590068 file_name:string = DocumentAttribute;
|
||||
documentAttributeHasStickers#9801d2f7 = DocumentAttribute;
|
||||
@@ -566,8 +572,6 @@ stickerPack#12b299d4 emoticon:string documents:Vector<long> = StickerPack;
|
||||
messages.allStickersNotModified#e86602c3 = messages.AllStickers;
|
||||
messages.allStickers#edfd405f hash:int sets:Vector<StickerSet> = messages.AllStickers;
|
||||
|
||||
disabledFeature#ae636f24 feature:string description:string = DisabledFeature;
|
||||
|
||||
messages.affectedMessages#84d19185 pts:int pts_count:int = messages.AffectedMessages;
|
||||
|
||||
contactLinkUnknown#5f4f9247 = ContactLink;
|
||||
@@ -605,7 +609,7 @@ inputStickerSetEmpty#ffb62b95 = InputStickerSet;
|
||||
inputStickerSetID#9de7a269 id:long access_hash:long = InputStickerSet;
|
||||
inputStickerSetShortName#861cc8a0 short_name:string = InputStickerSet;
|
||||
|
||||
stickerSet#cd303b41 flags:# installed:flags.0?true archived:flags.1?true official:flags.2?true masks:flags.3?true id:long access_hash:long title:string short_name:string count:int hash:int = StickerSet;
|
||||
stickerSet#5585a139 flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string count:int hash:int = StickerSet;
|
||||
|
||||
messages.stickerSet#b60a24a6 set:StickerSet packs:Vector<StickerPack> documents:Vector<Document> = messages.StickerSet;
|
||||
|
||||
@@ -642,6 +646,8 @@ messageEntityPre#73924be0 offset:int length:int language:string = MessageEntity;
|
||||
messageEntityTextUrl#76a6d327 offset:int length:int url:string = MessageEntity;
|
||||
messageEntityMentionName#352dca58 offset:int length:int user_id:int = MessageEntity;
|
||||
inputMessageEntityMentionName#208e68c9 offset:int length:int user_id:InputUser = MessageEntity;
|
||||
messageEntityPhone#9b69e34b offset:int length:int = MessageEntity;
|
||||
messageEntityCashtag#4c4e743f offset:int length:int = MessageEntity;
|
||||
|
||||
inputChannelEmpty#ee8c1e86 = InputChannel;
|
||||
inputChannel#afeb712e channel_id:int access_hash:long = InputChannel;
|
||||
@@ -685,30 +691,30 @@ messages.foundGifs#450a1c0a next_offset:int results:Vector<FoundGif> = messages.
|
||||
messages.savedGifsNotModified#e8025ca2 = messages.SavedGifs;
|
||||
messages.savedGifs#2e0709a5 hash:int gifs:Vector<Document> = messages.SavedGifs;
|
||||
|
||||
inputBotInlineMessageMediaAuto#292fed13 flags:# caption:string reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
inputBotInlineMessageMediaAuto#3380c786 flags:# message:string entities:flags.1?Vector<MessageEntity> reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
inputBotInlineMessageText#3dcd7a87 flags:# no_webpage:flags.0?true message:string entities:flags.1?Vector<MessageEntity> reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
inputBotInlineMessageMediaGeo#c1b15d65 flags:# geo_point:InputGeoPoint period:int reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
inputBotInlineMessageMediaVenue#aaafadc8 flags:# geo_point:InputGeoPoint title:string address:string provider:string venue_id:string reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
inputBotInlineMessageMediaContact#2daf01a7 flags:# phone_number:string first_name:string last_name:string reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
inputBotInlineMessageGame#4b425864 flags:# reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
|
||||
inputBotInlineResult#2cbbe15a flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb_url:flags.4?string content_url:flags.5?string content_type:flags.5?string w:flags.6?int h:flags.6?int duration:flags.7?int send_message:InputBotInlineMessage = InputBotInlineResult;
|
||||
inputBotInlineResult#88bf9319 flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb:flags.4?InputWebDocument content:flags.5?InputWebDocument send_message:InputBotInlineMessage = InputBotInlineResult;
|
||||
inputBotInlineResultPhoto#a8d864a7 id:string type:string photo:InputPhoto send_message:InputBotInlineMessage = InputBotInlineResult;
|
||||
inputBotInlineResultDocument#fff8fdc4 flags:# id:string type:string title:flags.1?string description:flags.2?string document:InputDocument send_message:InputBotInlineMessage = InputBotInlineResult;
|
||||
inputBotInlineResultGame#4fa417f2 id:string short_name:string send_message:InputBotInlineMessage = InputBotInlineResult;
|
||||
|
||||
botInlineMessageMediaAuto#a74b15b flags:# caption:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
botInlineMessageMediaAuto#764cf810 flags:# message:string entities:flags.1?Vector<MessageEntity> reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
botInlineMessageText#8c7f65e2 flags:# no_webpage:flags.0?true message:string entities:flags.1?Vector<MessageEntity> reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
botInlineMessageMediaGeo#b722de65 flags:# geo:GeoPoint period:int reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
botInlineMessageMediaVenue#4366232e flags:# geo:GeoPoint title:string address:string provider:string venue_id:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
botInlineMessageMediaContact#35edb4d4 flags:# phone_number:string first_name:string last_name:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
|
||||
botInlineResult#9bebaeb9 flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb_url:flags.4?string content_url:flags.5?string content_type:flags.5?string w:flags.6?int h:flags.6?int duration:flags.7?int send_message:BotInlineMessage = BotInlineResult;
|
||||
botInlineResult#11965f3a flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb:flags.4?WebDocument content:flags.5?WebDocument send_message:BotInlineMessage = BotInlineResult;
|
||||
botInlineMediaResult#17db940b flags:# id:string type:string photo:flags.0?Photo document:flags.1?Document title:flags.2?string description:flags.3?string send_message:BotInlineMessage = BotInlineResult;
|
||||
|
||||
messages.botResults#947ca848 flags:# gallery:flags.0?true query_id:long next_offset:flags.1?string switch_pm:flags.2?InlineBotSwitchPM results:Vector<BotInlineResult> cache_time:int users:Vector<User> = messages.BotResults;
|
||||
|
||||
exportedMessageLink#1f486803 link:string = ExportedMessageLink;
|
||||
exportedMessageLink#5dab1af4 link:string html:string = ExportedMessageLink;
|
||||
|
||||
messageFwdHeader#559ebe6d flags:# from_id:flags.0?int date:int channel_id:flags.1?int channel_post:flags.2?int post_author:flags.3?string saved_from_peer:flags.4?Peer saved_from_msg_id:flags.4?int = MessageFwdHeader;
|
||||
|
||||
@@ -752,7 +758,7 @@ messages.featuredStickersNotModified#4ede3cf = messages.FeaturedStickers;
|
||||
messages.featuredStickers#f89d88e5 hash:int sets:Vector<StickerSetCovered> unread:Vector<long> = messages.FeaturedStickers;
|
||||
|
||||
messages.recentStickersNotModified#b17f890 = messages.RecentStickers;
|
||||
messages.recentStickers#5ce20970 hash:int stickers:Vector<Document> = messages.RecentStickers;
|
||||
messages.recentStickers#22f3afb3 hash:int packs:Vector<StickerPack> stickers:Vector<Document> dates:Vector<int> = messages.RecentStickers;
|
||||
|
||||
messages.archivedStickers#4fcba9c8 count:int sets:Vector<StickerSetCovered> = messages.ArchivedStickers;
|
||||
|
||||
@@ -834,6 +840,7 @@ paymentRequestedInfo#909c3f94 flags:# name:flags.0?string phone:flags.1?string e
|
||||
paymentSavedCredentialsCard#cdc27a1f id:string title:string = PaymentSavedCredentials;
|
||||
|
||||
webDocument#c61acbd8 url:string access_hash:long size:int mime_type:string attributes:Vector<DocumentAttribute> dc_id:int = WebDocument;
|
||||
webDocumentNoProxy#f9c8bcc6 url:string size:int mime_type:string attributes:Vector<DocumentAttribute> = WebDocument;
|
||||
|
||||
inputWebDocument#9bed434d url:string size:int mime_type:string attributes:Vector<DocumentAttribute> = InputWebDocument;
|
||||
|
||||
@@ -855,7 +862,7 @@ payments.savedInfo#fb8fe43c flags:# has_saved_credentials:flags.1?true saved_inf
|
||||
inputPaymentCredentialsSaved#c10eb2cf id:string tmp_password:bytes = InputPaymentCredentials;
|
||||
inputPaymentCredentials#3417d728 flags:# save:flags.0?true data:DataJSON = InputPaymentCredentials;
|
||||
inputPaymentCredentialsApplePay#aa1c39f payment_data:DataJSON = InputPaymentCredentials;
|
||||
inputPaymentCredentialsAndroidPay#795667a6 payment_token:DataJSON = InputPaymentCredentials;
|
||||
inputPaymentCredentialsAndroidPay#ca05d50e payment_token:DataJSON google_transaction_id:string = InputPaymentCredentials;
|
||||
|
||||
account.tmpPassword#db64fd34 tmp_password:bytes valid_until:int = account.TmpPassword;
|
||||
|
||||
@@ -893,7 +900,7 @@ langPackDifference#f385c1f6 lang_code:string from_version:int version:int string
|
||||
|
||||
langPackLanguage#117698f1 name:string native_name:string lang_code:string = LangPackLanguage;
|
||||
|
||||
channelAdminRights#5d7ceba5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true invite_link:flags.6?true pin_messages:flags.7?true add_admins:flags.9?true = ChannelAdminRights;
|
||||
channelAdminRights#5d7ceba5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true invite_link:flags.6?true pin_messages:flags.7?true add_admins:flags.9?true manage_call:flags.10?true = ChannelAdminRights;
|
||||
|
||||
channelBannedRights#58cf4249 flags:# view_messages:flags.0?true send_messages:flags.1?true send_media:flags.2?true send_stickers:flags.3?true send_gifs:flags.4?true send_games:flags.5?true send_inline:flags.6?true embed_links:flags.7?true until_date:int = ChannelBannedRights;
|
||||
|
||||
@@ -922,8 +929,6 @@ channelAdminLogEventsFilter#ea107ae4 flags:# join:flags.0?true leave:flags.1?tru
|
||||
|
||||
popularContact#5ce14175 client_id:long importers:int = PopularContact;
|
||||
|
||||
cdnFileHash#77eec38f offset:int limit:int hash:bytes = CdnFileHash;
|
||||
|
||||
messages.favedStickersNotModified#9e8fa6d3 = messages.FavedStickers;
|
||||
messages.favedStickers#f37f2f16 hash:int packs:Vector<StickerPack> stickers:Vector<Document> = messages.FavedStickers;
|
||||
|
||||
@@ -935,7 +940,24 @@ recentMeUrlStickerSet#bc0a57dc url:string set:StickerSetCovered = RecentMeUrl;
|
||||
|
||||
help.recentMeUrls#e0310d7 urls:Vector<RecentMeUrl> chats:Vector<Chat> users:Vector<User> = help.RecentMeUrls;
|
||||
|
||||
inputSingleMedia#5eaa7809 media:InputMedia random_id:long = InputSingleMedia;
|
||||
inputSingleMedia#1cc6e91f flags:# media:InputMedia random_id:long message:string entities:flags.0?Vector<MessageEntity> = InputSingleMedia;
|
||||
|
||||
webAuthorization#cac943f2 hash:long bot_id:int domain:string browser:string platform:string date_created:int date_active:int ip:string region:string = WebAuthorization;
|
||||
|
||||
account.webAuthorizations#ed56c9fc authorizations:Vector<WebAuthorization> users:Vector<User> = account.WebAuthorizations;
|
||||
|
||||
inputMessageID#a676a322 id:int = InputMessage;
|
||||
inputMessageReplyTo#bad88395 id:int = InputMessage;
|
||||
inputMessagePinned#86872538 = InputMessage;
|
||||
|
||||
inputDialogPeer#fcaafeb7 peer:InputPeer = InputDialogPeer;
|
||||
|
||||
dialogPeer#e56dbf05 peer:Peer = DialogPeer;
|
||||
|
||||
messages.foundStickerSetsNotModified#d54b65d = messages.FoundStickerSets;
|
||||
messages.foundStickerSets#5108d648 hash:int sets:Vector<StickerSetCovered> = messages.FoundStickerSets;
|
||||
|
||||
fileHash#6242c773 offset:int limit:int hash:bytes = FileHash;
|
||||
|
||||
---functions---
|
||||
|
||||
@@ -963,8 +985,8 @@ auth.resendCode#3ef1a9bf phone_number:string phone_code_hash:string = auth.SentC
|
||||
auth.cancelCode#1f040578 phone_number:string phone_code_hash:string = Bool;
|
||||
auth.dropTempAuthKeys#8e48a188 except_auth_keys:Vector<long> = Bool;
|
||||
|
||||
account.registerDevice#637ea878 token_type:int token:string = Bool;
|
||||
account.unregisterDevice#65c55b40 token_type:int token:string = Bool;
|
||||
account.registerDevice#5cbea590 token_type:int token:string app_sandbox:Bool secret:bytes other_uids:Vector<int> = Bool;
|
||||
account.unregisterDevice#3076c4bf token_type:int token:string other_uids:Vector<int> = Bool;
|
||||
account.updateNotifySettings#84be5b93 peer:InputNotifyPeer settings:InputPeerNotifySettings = Bool;
|
||||
account.getNotifySettings#12b3ad31 peer:InputNotifyPeer = PeerNotifySettings;
|
||||
account.resetNotifySettings#db7e1747 = Bool;
|
||||
@@ -990,6 +1012,9 @@ account.updatePasswordSettings#fa7c4b86 current_password_hash:bytes new_settings
|
||||
account.sendConfirmPhoneCode#1516d7bd flags:# allow_flashcall:flags.0?true hash:string current_number:flags.0?Bool = auth.SentCode;
|
||||
account.confirmPhone#5f2178c3 phone_code_hash:string phone_code:string = Bool;
|
||||
account.getTmpPassword#4a82327e password_hash:bytes period:int = account.TmpPassword;
|
||||
account.getWebAuthorizations#182e6d6f = account.WebAuthorizations;
|
||||
account.resetWebAuthorization#2d01b9ef hash:long = Bool;
|
||||
account.resetWebAuthorizations#682d2594 = Bool;
|
||||
|
||||
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
|
||||
users.getFullUser#ca30a5b1 id:InputUser = UserFull;
|
||||
@@ -1010,21 +1035,22 @@ contacts.getTopPeers#d4982db5 flags:# correspondents:flags.0?true bots_pm:flags.
|
||||
contacts.resetTopPeerRating#1ae373ac category:TopPeerCategory peer:InputPeer = Bool;
|
||||
contacts.resetSaved#879537f1 = Bool;
|
||||
|
||||
messages.getMessages#4222fa74 id:Vector<int> = messages.Messages;
|
||||
messages.getMessages#63c66506 id:Vector<InputMessage> = messages.Messages;
|
||||
messages.getDialogs#191ba9c5 flags:# exclude_pinned:flags.0?true offset_date:int offset_id:int offset_peer:InputPeer limit:int = messages.Dialogs;
|
||||
messages.getHistory#dcbb8260 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
|
||||
messages.search#39e9ea0 flags:# peer:InputPeer q:string from_id:flags.0?InputUser filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
||||
messages.search#8614ef68 flags:# peer:InputPeer q:string from_id:flags.0?InputUser filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
|
||||
messages.readHistory#e306d3a peer:InputPeer max_id:int = messages.AffectedMessages;
|
||||
messages.deleteHistory#1c015b09 flags:# just_clear:flags.0?true peer:InputPeer max_id:int = messages.AffectedHistory;
|
||||
messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector<int> = messages.AffectedMessages;
|
||||
messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
|
||||
messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool;
|
||||
messages.sendMessage#fa88427a flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Updates;
|
||||
messages.sendMedia#c8f16791 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia random_id:long reply_markup:flags.2?ReplyMarkup = Updates;
|
||||
messages.sendMedia#b8d1262b flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Updates;
|
||||
messages.forwardMessages#708e0195 flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true grouped:flags.9?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer = Updates;
|
||||
messages.reportSpam#cf1592db peer:InputPeer = Bool;
|
||||
messages.hideReportSpam#a8f1709b peer:InputPeer = Bool;
|
||||
messages.getPeerSettings#3672e09c peer:InputPeer = PeerSettings;
|
||||
messages.report#bd82b658 peer:InputPeer id:Vector<int> reason:ReportReason = Bool;
|
||||
messages.getChats#3c6aa187 id:Vector<int> = messages.Chats;
|
||||
messages.getFullChat#3b831c66 chat_id:int = messages.ChatFull;
|
||||
messages.editChatTitle#dc452855 chat_id:int title:string = Updates;
|
||||
@@ -1032,7 +1058,6 @@ messages.editChatPhoto#ca4c79d8 chat_id:int photo:InputChatPhoto = Updates;
|
||||
messages.addChatUser#f9a0aa09 chat_id:int user_id:InputUser fwd_limit:int = Updates;
|
||||
messages.deleteChatUser#e0611f16 chat_id:int user_id:InputUser = Updates;
|
||||
messages.createChat#9cb126e users:Vector<InputUser> title:string = Updates;
|
||||
messages.forwardMessage#33963bf9 peer:InputPeer id:int random_id:long = Updates;
|
||||
messages.getDhConfig#26cf8950 version:int random_length:int = messages.DhConfig;
|
||||
messages.requestEncryption#f64daf43 user_id:InputUser random_id:int g_a:bytes = EncryptedChat;
|
||||
messages.acceptEncryption#3dbc0415 peer:InputEncryptedChat g_b:bytes key_fingerprint:long = EncryptedChat;
|
||||
@@ -1045,8 +1070,9 @@ messages.sendEncryptedService#32d439a4 peer:InputEncryptedChat random_id:long da
|
||||
messages.receivedQueue#55a5bb66 max_qts:int = Vector<long>;
|
||||
messages.reportEncryptedSpam#4b0c8c0f peer:InputEncryptedChat = Bool;
|
||||
messages.readMessageContents#36a73f77 id:Vector<int> = messages.AffectedMessages;
|
||||
messages.getStickers#85cb5182 flags:# exclude_featured:flags.0?true emoticon:string hash:string = messages.Stickers;
|
||||
messages.getAllStickers#1c9618b1 hash:int = messages.AllStickers;
|
||||
messages.getWebPagePreview#25223e24 message:string = MessageMedia;
|
||||
messages.getWebPagePreview#8b68b0cc flags:# message:string entities:flags.3?Vector<MessageEntity> = MessageMedia;
|
||||
messages.exportChatInvite#7d885289 chat_id:int = ExportedChatInvite;
|
||||
messages.checkChatInvite#3eadb1bb hash:string = ChatInvite;
|
||||
messages.importChatInvite#6c50051c hash:string = Updates;
|
||||
@@ -1072,7 +1098,7 @@ messages.editMessage#5d1b8dd flags:# no_webpage:flags.1?true stop_geo_live:flags
|
||||
messages.editInlineBotMessage#b0e08243 flags:# no_webpage:flags.1?true stop_geo_live:flags.12?true id:InputBotInlineMessageID message:flags.11?string reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> geo_point:flags.13?InputGeoPoint = Bool;
|
||||
messages.getBotCallbackAnswer#810a9fec flags:# game:flags.1?true peer:InputPeer msg_id:int data:flags.0?bytes = messages.BotCallbackAnswer;
|
||||
messages.setBotCallbackAnswer#d58f130a flags:# alert:flags.1?true query_id:long message:flags.0?string url:flags.2?string cache_time:int = Bool;
|
||||
messages.getPeerDialogs#2d9776b9 peers:Vector<InputPeer> = messages.PeerDialogs;
|
||||
messages.getPeerDialogs#e470bcfd peers:Vector<InputDialogPeer> = messages.PeerDialogs;
|
||||
messages.saveDraft#bc39e14b flags:# no_webpage:flags.1?true reply_to_msg_id:flags.0?int peer:InputPeer message:string entities:flags.3?Vector<MessageEntity> = Bool;
|
||||
messages.getAllDrafts#6a3f8d65 = Updates;
|
||||
messages.getFeaturedStickers#2dacca4f hash:int = messages.FeaturedStickers;
|
||||
@@ -1090,8 +1116,8 @@ messages.getInlineGameHighScores#f635e1b id:InputBotInlineMessageID user_id:Inpu
|
||||
messages.getCommonChats#d0a48c4 user_id:InputUser max_id:int limit:int = messages.Chats;
|
||||
messages.getAllChats#eba80ff0 except_ids:Vector<int> = messages.Chats;
|
||||
messages.getWebPage#32ca8f91 url:string hash:int = WebPage;
|
||||
messages.toggleDialogPin#3289be6a flags:# pinned:flags.0?true peer:InputPeer = Bool;
|
||||
messages.reorderPinnedDialogs#959ff644 flags:# force:flags.0?true order:Vector<InputPeer> = Bool;
|
||||
messages.toggleDialogPin#a731e257 flags:# pinned:flags.0?true peer:InputDialogPeer = Bool;
|
||||
messages.reorderPinnedDialogs#5b51d63f flags:# force:flags.0?true order:Vector<InputDialogPeer> = Bool;
|
||||
messages.getPinnedDialogs#e254d64e = messages.PeerDialogs;
|
||||
messages.setBotShippingResults#e5f672fa flags:# query_id:long error:flags.0?string shipping_options:flags.1?Vector<ShippingOption> = Bool;
|
||||
messages.setBotPrecheckoutResults#9c2dd95 flags:# success:flags.1?true query_id:long error:flags.0?string = Bool;
|
||||
@@ -1101,9 +1127,10 @@ messages.getFavedStickers#21ce0b0e hash:int = messages.FavedStickers;
|
||||
messages.faveSticker#b9ffc55b id:InputDocument unfave:Bool = Bool;
|
||||
messages.getUnreadMentions#46578472 peer:InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
||||
messages.readMentions#f0189d3 peer:InputPeer = messages.AffectedHistory;
|
||||
messages.getRecentLocations#249431e2 peer:InputPeer limit:int = messages.Messages;
|
||||
messages.getRecentLocations#bbc45b09 peer:InputPeer limit:int hash:int = messages.Messages;
|
||||
messages.sendMultiMedia#2095512f flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int multi_media:Vector<InputSingleMedia> = Updates;
|
||||
messages.uploadEncryptedFile#5057c497 peer:InputEncryptedChat file:InputEncryptedFile = EncryptedFile;
|
||||
messages.searchStickerSets#c2b7d08b flags:# exclude_featured:flags.0?true q:string hash:int = messages.FoundStickerSets;
|
||||
|
||||
updates.getState#edd4882a = updates.State;
|
||||
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
||||
@@ -1119,8 +1146,9 @@ upload.getFile#e3a6cfb5 location:InputFileLocation offset:int limit:int = upload
|
||||
upload.saveBigFilePart#de7b673d file_id:long file_part:int file_total_parts:int bytes:bytes = Bool;
|
||||
upload.getWebFile#24e6818d location:InputWebFileLocation offset:int limit:int = upload.WebFile;
|
||||
upload.getCdnFile#2000bcc3 file_token:bytes offset:int limit:int = upload.CdnFile;
|
||||
upload.reuploadCdnFile#1af91c09 file_token:bytes request_token:bytes = Vector<CdnFileHash>;
|
||||
upload.getCdnFileHashes#f715c87b file_token:bytes offset:int = Vector<CdnFileHash>;
|
||||
upload.reuploadCdnFile#9b2754a8 file_token:bytes request_token:bytes = Vector<FileHash>;
|
||||
upload.getCdnFileHashes#4da54231 file_token:bytes offset:int = Vector<FileHash>;
|
||||
upload.getFileHashes#c7025931 location:InputFileLocation offset:int = Vector<FileHash>;
|
||||
|
||||
help.getConfig#c4f9186b = Config;
|
||||
help.getNearestDc#1fb33026 = NearestDc;
|
||||
@@ -1138,7 +1166,7 @@ channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool;
|
||||
channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages;
|
||||
channels.deleteUserHistory#d10dd71b channel:InputChannel user_id:InputUser = messages.AffectedHistory;
|
||||
channels.reportSpam#fe087810 channel:InputChannel user_id:InputUser id:Vector<int> = Bool;
|
||||
channels.getMessages#93d7b347 channel:InputChannel id:Vector<int> = messages.Messages;
|
||||
channels.getMessages#ad8c9a23 channel:InputChannel id:Vector<InputMessage> = messages.Messages;
|
||||
channels.getParticipants#123e05e9 channel:InputChannel filter:ChannelParticipantsFilter offset:int limit:int hash:int = channels.ChannelParticipants;
|
||||
channels.getParticipant#546dd7a6 channel:InputChannel user_id:InputUser = channels.ChannelParticipant;
|
||||
channels.getChannels#a7f6bbb id:Vector<InputChannel> = messages.Chats;
|
||||
@@ -1156,7 +1184,7 @@ channels.inviteToChannel#199f3a6c channel:InputChannel users:Vector<InputUser> =
|
||||
channels.exportInvite#c7560885 channel:InputChannel = ExportedChatInvite;
|
||||
channels.deleteChannel#c0111fe3 channel:InputChannel = Updates;
|
||||
channels.toggleInvites#49609307 channel:InputChannel enabled:Bool = Updates;
|
||||
channels.exportMessageLink#c846d22d channel:InputChannel id:int = ExportedMessageLink;
|
||||
channels.exportMessageLink#ceb77163 channel:InputChannel id:int grouped:Bool = ExportedMessageLink;
|
||||
channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates;
|
||||
channels.updatePinnedMessage#a72ded52 flags:# silent:flags.0?true channel:InputChannel id:int = Updates;
|
||||
channels.getAdminedPublicChannels#8d8d82d7 = messages.Chats;
|
||||
@@ -1196,4 +1224,4 @@ langpack.getStrings#2e1ee318 lang_code:string keys:Vector<string> = Vector<LangP
|
||||
langpack.getDifference#b2e4d7d from_version:int = LangPackDifference;
|
||||
langpack.getLanguages#800fd57d = Vector<LangPackLanguage>;
|
||||
|
||||
// LAYER 73
|
||||
// LAYER 78
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
|
||||
ProcessorArchitecture="ARCHITECTURE"
|
||||
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
|
||||
Version="1.2.6.0" />
|
||||
Version="1.2.20.0" />
|
||||
<Properties>
|
||||
<DisplayName>Telegram Desktop</DisplayName>
|
||||
<PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName>
|
||||
|
||||
@@ -34,8 +34,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,2,6,0
|
||||
PRODUCTVERSION 1,2,6,0
|
||||
FILEVERSION 1,2,20,0
|
||||
PRODUCTVERSION 1,2,20,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -52,10 +52,10 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||
VALUE "FileDescription", "Telegram Desktop"
|
||||
VALUE "FileVersion", "1.2.6.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2017"
|
||||
VALUE "FileVersion", "1.2.20.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2018"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "1.2.6.0"
|
||||
VALUE "ProductVersion", "1.2.20.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,2,6,0
|
||||
PRODUCTVERSION 1,2,6,0
|
||||
FILEVERSION 1,2,20,0
|
||||
PRODUCTVERSION 1,2,20,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -43,10 +43,10 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||
VALUE "FileDescription", "Telegram Desktop Updater"
|
||||
VALUE "FileVersion", "1.2.6.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2017"
|
||||
VALUE "FileVersion", "1.2.20.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2018"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "1.2.6.0"
|
||||
VALUE "ProductVersion", "1.2.20.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "packer.h"
|
||||
|
||||
@@ -493,7 +480,7 @@ int main(int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString countBetaVersionSignature(quint64 version) { // duplicated in autoupdate.cpp
|
||||
QString countBetaVersionSignature(quint64 version) { // duplicated in autoupdater.cpp
|
||||
QByteArray cBetaPrivateKey(BetaPrivateKey);
|
||||
if (cBetaPrivateKey.isEmpty()) {
|
||||
cout << "Error: Trying to count beta version signature without beta private key!\n";
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "updater.h"
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include <cstdio>
|
||||
#include <sys/stat.h>
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@@ -1,45 +1,36 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <rpl/event_stream.h>
|
||||
#include "base/timer.h"
|
||||
#include "core/single_timer.h"
|
||||
#include "mtproto/sender.h"
|
||||
#include "base/flat_map.h"
|
||||
#include "base/flat_set.h"
|
||||
#include "core/single_timer.h"
|
||||
#include "mtproto/sender.h"
|
||||
#include "chat_helpers/stickers.h"
|
||||
#include "data/data_messages.h"
|
||||
|
||||
class TaskQueue;
|
||||
class AuthSession;
|
||||
enum class SparseIdsLoadDirection;
|
||||
struct MessageGroupId;
|
||||
struct SendingAlbum;
|
||||
enum class SendMediaType;
|
||||
|
||||
namespace Storage {
|
||||
enum class SharedMediaType : char;
|
||||
enum class SharedMediaType : signed char;
|
||||
struct PreparedList;
|
||||
} // namespace Storage
|
||||
|
||||
namespace Dialogs {
|
||||
class Key;
|
||||
} // namespace Dialogs
|
||||
|
||||
namespace Api {
|
||||
|
||||
inline const MTPVector<MTPChat> *getChatsFromMessagesChats(const MTPmessages_Chats &chats) {
|
||||
@@ -50,6 +41,16 @@ inline const MTPVector<MTPChat> *getChatsFromMessagesChats(const MTPmessages_Cha
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename IntRange>
|
||||
inline int32 CountHash(IntRange &&range) {
|
||||
uint32 acc = 0;
|
||||
for (auto value : range) {
|
||||
acc += (acc * 20261) + uint32(value);
|
||||
}
|
||||
return int32(acc & 0x7FFFFFFF);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Api
|
||||
|
||||
class ApiWrap : private MTP::Sender, private base::Subscriber {
|
||||
@@ -58,8 +59,27 @@ public:
|
||||
|
||||
void applyUpdates(const MTPUpdates &updates, uint64 sentMessageRandomId = 0);
|
||||
|
||||
void savePinnedOrder();
|
||||
//void toggleChannelGrouping( // #feed
|
||||
// not_null<ChannelData*> channel,
|
||||
// bool group,
|
||||
// base::lambda<void()> callback);
|
||||
//void ungroupAllFromFeed(not_null<Data::Feed*> feed);
|
||||
|
||||
using RequestMessageDataCallback = base::lambda<void(ChannelData*, MsgId)>;
|
||||
void requestMessageData(ChannelData *channel, MsgId msgId, RequestMessageDataCallback callback);
|
||||
void requestMessageData(
|
||||
ChannelData *channel,
|
||||
MsgId msgId,
|
||||
RequestMessageDataCallback callback);
|
||||
|
||||
void requestContacts();
|
||||
void requestDialogEntry(not_null<Data::Feed*> feed);
|
||||
//void requestFeedDialogsEntries(not_null<Data::Feed*> feed);
|
||||
void requestDialogEntry(not_null<History*> history);
|
||||
//void applyFeedSources(const MTPDchannels_feedSources &data); // #feed
|
||||
//void setFeedChannels(
|
||||
// not_null<Data::Feed*> feed,
|
||||
// const std::vector<not_null<ChannelData*>> &channels);
|
||||
|
||||
void requestFullPeer(PeerData *peer);
|
||||
void requestPeer(PeerData *peer);
|
||||
@@ -68,6 +88,7 @@ public:
|
||||
void requestBots(not_null<ChannelData*> channel);
|
||||
void requestAdmins(not_null<ChannelData*> channel);
|
||||
void requestParticipantsCountDelayed(not_null<ChannelData*> channel);
|
||||
void requestChannelRangeDifference(not_null<History*> history);
|
||||
|
||||
void requestChangelog(
|
||||
const QString &sinceVersion,
|
||||
@@ -79,6 +100,9 @@ public:
|
||||
void processFullPeer(PeerData *peer, const MTPmessages_ChatFull &result);
|
||||
void processFullPeer(UserData *user, const MTPUserFull &result);
|
||||
|
||||
void markMediaRead(const base::flat_set<not_null<HistoryItem*>> &items);
|
||||
void markMediaRead(not_null<HistoryItem*> item);
|
||||
|
||||
void requestSelfParticipant(ChannelData *channel);
|
||||
void kickParticipant(not_null<ChatData*> chat, not_null<UserData*> user);
|
||||
void kickParticipant(
|
||||
@@ -88,6 +112,9 @@ public:
|
||||
void unblockParticipant(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<UserData*> user);
|
||||
void deleteAllFromUser(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<UserData*> from);
|
||||
|
||||
void requestWebPageDelayed(WebPageData *page);
|
||||
void clearWebPageRequest(WebPageData *page);
|
||||
@@ -95,12 +122,19 @@ public:
|
||||
|
||||
void scheduleStickerSetRequest(uint64 setId, uint64 access);
|
||||
void requestStickerSets();
|
||||
void saveStickerSets(const Stickers::Order &localOrder, const Stickers::Order &localRemoved);
|
||||
void saveStickerSets(
|
||||
const Stickers::Order &localOrder,
|
||||
const Stickers::Order &localRemoved);
|
||||
void updateStickers();
|
||||
void setGroupStickerSet(not_null<ChannelData*> megagroup, const MTPInputStickerSet &set);
|
||||
void requestRecentStickersForce();
|
||||
void setGroupStickerSet(
|
||||
not_null<ChannelData*> megagroup,
|
||||
const MTPInputStickerSet &set);
|
||||
std::vector<not_null<DocumentData*>> *stickersByEmoji(
|
||||
not_null<EmojiPtr> emoji);
|
||||
|
||||
void joinChannel(ChannelData *channel);
|
||||
void leaveChannel(ChannelData *channel);
|
||||
void joinChannel(not_null<ChannelData*> channel);
|
||||
void leaveChannel(not_null<ChannelData*> channel);
|
||||
|
||||
void blockUser(UserData *user);
|
||||
void unblockUser(UserData *user);
|
||||
@@ -125,7 +159,7 @@ public:
|
||||
void applyUpdatesNoPtsCheck(const MTPUpdates &updates);
|
||||
void applyUpdateNoPtsCheck(const MTPUpdate &update);
|
||||
|
||||
void jumpToDate(not_null<PeerData*> peer, const QDate &date);
|
||||
void jumpToDate(Dialogs::Key chat, const QDate &date);
|
||||
|
||||
void preloadEnoughUnreadMentions(not_null<History*> history);
|
||||
void checkForUnreadMentions(const base::flat_set<MsgId> &possiblyReadMentions, ChannelData *channel = nullptr);
|
||||
@@ -135,7 +169,7 @@ public:
|
||||
bool adminsEnabled,
|
||||
base::flat_set<not_null<UserData*>> &&admins);
|
||||
|
||||
using SliceType = SparseIdsLoadDirection;
|
||||
using SliceType = Data::LoadDirection;
|
||||
void requestSharedMedia(
|
||||
not_null<PeerData*> peer,
|
||||
Storage::SharedMediaType type,
|
||||
@@ -149,6 +183,14 @@ public:
|
||||
not_null<UserData*> user,
|
||||
PhotoId afterId);
|
||||
|
||||
//void requestFeedChannels( // #feed
|
||||
// not_null<Data::Feed*> feed);
|
||||
//void requestFeedMessages(
|
||||
// not_null<Data::Feed*> feed,
|
||||
// Data::MessagePosition messageId,
|
||||
// SliceType slice);
|
||||
//void saveDefaultFeedId(FeedId id, bool isDefaultFeedId);
|
||||
|
||||
void stickerSetInstalled(uint64 setId) {
|
||||
_stickerSetInstalled.fire_copy(setId);
|
||||
}
|
||||
@@ -198,6 +240,9 @@ public:
|
||||
void shareContact(not_null<UserData*> user, const SendOptions &options);
|
||||
void readServerHistory(not_null<History*> history);
|
||||
void readServerHistoryForce(not_null<History*> history);
|
||||
void readFeed(
|
||||
not_null<Data::Feed*> feed,
|
||||
Data::MessagePosition position);
|
||||
|
||||
void sendVoiceMessage(
|
||||
QByteArray result,
|
||||
@@ -237,6 +282,12 @@ private:
|
||||
using MessageDataRequests = QMap<MsgId, MessageDataRequest>;
|
||||
using SharedMediaType = Storage::SharedMediaType;
|
||||
|
||||
struct StickersByEmoji {
|
||||
std::vector<not_null<DocumentData*>> list;
|
||||
QString hash;
|
||||
TimeMs received = 0;
|
||||
};
|
||||
|
||||
void updatesReceived(const MTPUpdates &updates);
|
||||
void checkQuitPreventFinished();
|
||||
|
||||
@@ -248,8 +299,13 @@ private:
|
||||
ChannelData *channel,
|
||||
mtpRequestId requestId);
|
||||
|
||||
QVector<MTPint> collectMessageIds(const MessageDataRequests &requests);
|
||||
QVector<MTPInputMessage> collectMessageIds(const MessageDataRequests &requests);
|
||||
MessageDataRequests *messageDataRequests(ChannelData *channel, bool onlyExisting = false);
|
||||
void applyPeerDialogs(const MTPmessages_PeerDialogs &dialogs);
|
||||
void historyDialogEntryApplied(not_null<History*> history);
|
||||
void applyFeedDialogs(
|
||||
not_null<Data::Feed*> feed,
|
||||
const MTPmessages_Dialogs &dialogs);
|
||||
|
||||
void gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mtpRequestId req);
|
||||
void gotUserFull(UserData *user, const MTPUserFull &result, mtpRequestId req);
|
||||
@@ -266,16 +322,31 @@ private:
|
||||
int availableCount,
|
||||
const QVector<MTPChannelParticipant> &list);
|
||||
void resolveWebPages();
|
||||
void gotWebPages(ChannelData *channel, const MTPmessages_Messages &result, mtpRequestId req);
|
||||
void gotWebPages(
|
||||
ChannelData *channel,
|
||||
const MTPmessages_Messages &result,
|
||||
mtpRequestId req);
|
||||
void gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result);
|
||||
|
||||
PeerData *notifySettingReceived(MTPInputNotifyPeer peer, const MTPPeerNotifySettings &settings);
|
||||
void channelRangeDifferenceSend(
|
||||
not_null<ChannelData*> channel,
|
||||
MsgRange range,
|
||||
int32 pts);
|
||||
void channelRangeDifferenceDone(
|
||||
not_null<ChannelData*> channel,
|
||||
MsgRange range,
|
||||
const MTPupdates_ChannelDifference &result);
|
||||
|
||||
PeerData *notifySettingReceived(
|
||||
MTPInputNotifyPeer peer,
|
||||
const MTPPeerNotifySettings &settings);
|
||||
|
||||
void stickerSetDisenabled(mtpRequestId requestId);
|
||||
void stickersSaveOrder();
|
||||
|
||||
void requestStickers(TimeId now);
|
||||
void requestRecentStickers(TimeId now);
|
||||
void requestRecentStickersWithHash(int32 hash);
|
||||
void requestFavedStickers(TimeId now);
|
||||
void requestFeaturedStickers(TimeId now);
|
||||
void requestSavedGifs(TimeId now);
|
||||
@@ -288,11 +359,19 @@ private:
|
||||
not_null<ChannelData*> channel,
|
||||
const QVector<MTPChannelParticipant> &participants);
|
||||
|
||||
|
||||
void jumpToHistoryDate(not_null<PeerData*> peer, const QDate &date);
|
||||
void jumpToFeedDate(not_null<Data::Feed*> feed, const QDate &date);
|
||||
template <typename Callback>
|
||||
void requestMessageAfterDate(
|
||||
not_null<PeerData*> peer,
|
||||
const QDate &date,
|
||||
Callback &&callback);
|
||||
template <typename Callback>
|
||||
void requestMessageAfterDate(
|
||||
not_null<Data::Feed*> feed,
|
||||
const QDate &date,
|
||||
Callback &&callback);
|
||||
|
||||
void sharedMediaDone(
|
||||
not_null<PeerData*> peer,
|
||||
@@ -306,6 +385,13 @@ private:
|
||||
PhotoId photoId,
|
||||
const MTPphotos_Photos &result);
|
||||
|
||||
//void feedChannelsDone(not_null<Data::Feed*> feed); // #feed
|
||||
//void feedMessagesDone(
|
||||
// not_null<Data::Feed*> feed,
|
||||
// Data::MessagePosition messageId,
|
||||
// SliceType slice,
|
||||
// const MTPmessages_FeedMessages &result);
|
||||
|
||||
void sendSharedContact(
|
||||
const QString &phone,
|
||||
const QString &firstName,
|
||||
@@ -321,6 +407,11 @@ private:
|
||||
void applyAffectedMessages(
|
||||
not_null<PeerData*> peer,
|
||||
const MTPmessages_AffectedMessages &result);
|
||||
|
||||
void deleteAllFromUserSend(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<UserData*> from);
|
||||
|
||||
void sendMessageFail(const RPCError &error);
|
||||
void uploadAlbumMedia(
|
||||
not_null<HistoryItem*> item,
|
||||
@@ -344,6 +435,8 @@ private:
|
||||
bool silent,
|
||||
uint64 randomId);
|
||||
|
||||
void readFeeds();
|
||||
|
||||
not_null<AuthSession*> _session;
|
||||
|
||||
MessageDataRequests _messageDataRequests;
|
||||
@@ -361,7 +454,11 @@ private:
|
||||
|
||||
ChannelData *_channelMembersForAdd = nullptr;
|
||||
mtpRequestId _channelMembersForAddRequestId = 0;
|
||||
base::lambda<void(const MTPchannels_ChannelParticipants&)> _channelMembersForAddCallback;
|
||||
base::lambda<void(
|
||||
const MTPchannels_ChannelParticipants&)> _channelMembersForAddCallback;
|
||||
base::flat_map<
|
||||
not_null<ChannelData*>,
|
||||
std::pair<mtpRequestId,base::lambda<void()>>> _channelGroupingRequests;
|
||||
|
||||
using KickRequest = std::pair<
|
||||
not_null<ChannelData*>,
|
||||
@@ -370,6 +467,10 @@ private:
|
||||
|
||||
QMap<ChannelData*, mtpRequestId> _selfParticipantRequests;
|
||||
|
||||
base::flat_map<
|
||||
not_null<ChannelData*>,
|
||||
mtpRequestId> _rangeDifferenceRequests;
|
||||
|
||||
QMap<WebPageData*, mtpRequestId> _webPagesPending;
|
||||
base::Timer _webPagesTimer;
|
||||
|
||||
@@ -398,9 +499,14 @@ private:
|
||||
base::Timer _featuredSetsReadTimer;
|
||||
base::flat_set<uint64> _featuredSetsRead;
|
||||
|
||||
QMap<mtpTypeId, mtpRequestId> _privacySaveRequests;
|
||||
base::flat_map<not_null<EmojiPtr>, StickersByEmoji> _stickersByEmoji;
|
||||
|
||||
base::flat_map<mtpTypeId, mtpRequestId> _privacySaveRequests;
|
||||
|
||||
mtpRequestId _contactsRequestId = 0;
|
||||
mtpRequestId _contactsStatusesRequestId = 0;
|
||||
base::flat_set<not_null<Data::Feed*>> _dialogFeedRequests;
|
||||
base::flat_set<not_null<History*>> _dialogRequests;
|
||||
|
||||
base::flat_map<not_null<History*>, mtpRequestId> _unreadMentionsRequests;
|
||||
|
||||
@@ -422,6 +528,20 @@ private:
|
||||
|
||||
base::flat_map<not_null<UserData*>, mtpRequestId> _userPhotosRequests;
|
||||
|
||||
base::flat_set<not_null<Data::Feed*>> _feedChannelsGetRequests;
|
||||
base::flat_map<
|
||||
not_null<Data::Feed*>,
|
||||
mtpRequestId> _feedChannelsSetRequests;
|
||||
base::flat_set<std::tuple<
|
||||
not_null<Data::Feed*>,
|
||||
Data::MessagePosition,
|
||||
SliceType>> _feedMessagesRequests;
|
||||
base::flat_set<std::tuple<
|
||||
not_null<Data::Feed*>,
|
||||
Data::MessagePosition,
|
||||
SliceType>> _feedMessagesRequestsPending;
|
||||
mtpRequestId _saveDefaultFeedIdRequest = 0;
|
||||
|
||||
rpl::event_stream<SendOptions> _sendActions;
|
||||
|
||||
struct ReadRequest {
|
||||
@@ -435,6 +555,7 @@ private:
|
||||
};
|
||||
base::flat_map<not_null<PeerData*>, ReadRequest> _readRequests;
|
||||
base::flat_map<not_null<PeerData*>, MsgId> _readRequestsPending;
|
||||
|
||||
std::unique_ptr<TaskQueue> _fileLoader;
|
||||
base::flat_map<uint64, std::shared_ptr<SendingAlbum>> _sendingAlbums;
|
||||
|
||||
@@ -442,4 +563,8 @@ private:
|
||||
|
||||
rpl::event_stream<uint64> _stickerSetInstalled;
|
||||
|
||||
base::flat_map<not_null<Data::Feed*>, TimeMs> _feedReadsDelayed;
|
||||
base::flat_map<not_null<Data::Feed*>, mtpRequestId> _feedReadRequests;
|
||||
base::Timer _feedReadTimer;
|
||||
|
||||
};
|
||||
|
||||
@@ -1,47 +1,67 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "core/basic_types.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
#include "layout.h"
|
||||
#include "data/data_types.h"
|
||||
#include "data/data_peer.h"
|
||||
|
||||
enum NewMessageType : char;
|
||||
class Messenger;
|
||||
class MainWindow;
|
||||
class MainWidget;
|
||||
|
||||
using HistoryItemsMap = OrderedSet<HistoryItem*>;
|
||||
using PhotoItems = QHash<PhotoData*, HistoryItemsMap>;
|
||||
using DocumentItems = QHash<DocumentData*, HistoryItemsMap>;
|
||||
using WebPageItems = QHash<WebPageData*, HistoryItemsMap>;
|
||||
using GameItems = QHash<GameData*, HistoryItemsMap>;
|
||||
using SharedContactItems = QHash<int32, HistoryItemsMap>;
|
||||
using GifItems = QHash<Media::Clip::Reader*, HistoryItem*>;
|
||||
|
||||
using PhotosData = QHash<PhotoId, PhotoData*>;
|
||||
using DocumentsData = QHash<DocumentId, DocumentData*>;
|
||||
|
||||
class LocationCoords;
|
||||
struct LocationData;
|
||||
class HistoryItem;
|
||||
class History;
|
||||
class Histories;
|
||||
namespace HistoryView {
|
||||
class Element;
|
||||
} // namespace HistoryView
|
||||
|
||||
using HistoryItemsMap = base::flat_set<not_null<HistoryItem*>>;
|
||||
using GifItems = QHash<Media::Clip::Reader*, HistoryItem*>;
|
||||
|
||||
enum RoundCorners {
|
||||
SmallMaskCorners = 0x00, // for images
|
||||
LargeMaskCorners,
|
||||
|
||||
BoxCorners,
|
||||
MenuCorners,
|
||||
BotKbOverCorners,
|
||||
StickerCorners,
|
||||
StickerSelectedCorners,
|
||||
SelectedOverlaySmallCorners,
|
||||
SelectedOverlayLargeCorners,
|
||||
DateCorners,
|
||||
DateSelectedCorners,
|
||||
ForwardCorners,
|
||||
MediaviewSaveCorners,
|
||||
EmojiHoverCorners,
|
||||
StickerHoverCorners,
|
||||
BotKeyboardCorners,
|
||||
PhotoSelectOverlayCorners,
|
||||
|
||||
Doc1Corners,
|
||||
Doc2Corners,
|
||||
Doc3Corners,
|
||||
Doc4Corners,
|
||||
|
||||
InShadowCorners, // for photos without bg
|
||||
InSelectedShadowCorners,
|
||||
|
||||
MessageInCorners, // with shadow
|
||||
MessageInSelectedCorners,
|
||||
MessageOutCorners,
|
||||
MessageOutSelectedCorners,
|
||||
|
||||
RoundCornersCount
|
||||
};
|
||||
|
||||
namespace App {
|
||||
MainWindow *wnd();
|
||||
@@ -75,18 +95,6 @@ namespace App {
|
||||
|
||||
ImagePtr image(const MTPPhotoSize &size);
|
||||
|
||||
PhotoData *feedPhoto(const MTPPhoto &photo, const PreparedPhotoThumbs &thumbs);
|
||||
PhotoData *feedPhoto(const MTPPhoto &photo, PhotoData *convert = nullptr);
|
||||
PhotoData *feedPhoto(const MTPDphoto &photo, PhotoData *convert = nullptr);
|
||||
DocumentData *feedDocument(const MTPdocument &document, const QPixmap &thumb);
|
||||
DocumentData *feedDocument(const MTPdocument &document, DocumentData *convert = nullptr);
|
||||
DocumentData *feedDocument(const MTPDdocument &document, DocumentData *convert = nullptr);
|
||||
WebPageData *feedWebPage(const MTPDwebPage &webpage, WebPageData *convert = nullptr);
|
||||
WebPageData *feedWebPage(const MTPDwebPagePending &webpage, WebPageData *convert = nullptr);
|
||||
WebPageData *feedWebPage(const MTPWebPage &webpage);
|
||||
WebPageData *feedWebPage(WebPageId webPageId, const QString &siteName, const TextWithEntities &content);
|
||||
GameData *feedGame(const MTPDgame &game, GameData *convert = nullptr);
|
||||
|
||||
PeerData *peer(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded);
|
||||
inline UserData *user(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded) {
|
||||
return asUser(peer(id, restriction));
|
||||
@@ -132,14 +140,7 @@ namespace App {
|
||||
UserData *self();
|
||||
PeerData *peerByName(const QString &username);
|
||||
QString peerName(const PeerData *peer, bool forDialogs = false);
|
||||
PhotoData *photo(const PhotoId &photo);
|
||||
PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const uint64 &access, int32 date, const ImagePtr &thumb, const ImagePtr &medium, const ImagePtr &full);
|
||||
DocumentData *document(const DocumentId &document);
|
||||
DocumentData *documentSet(const DocumentId &document, DocumentData *convert, const uint64 &access, int32 version, int32 date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size, const StorageImageLocation &thumbLocation);
|
||||
WebPageData *webPage(const WebPageId &webPage);
|
||||
WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const TextWithEntities &description, PhotoData *photo, DocumentData *doc, int32 duration, const QString &author, int32 pendingTill);
|
||||
GameData *game(const GameId &game);
|
||||
GameData *gameSet(const GameId &game, GameData *convert, const uint64 &accessHash, const QString &shortName, const QString &title, const QString &description, PhotoData *photo, DocumentData *doc);
|
||||
|
||||
LocationData *location(const LocationCoords &coords);
|
||||
void forgetMedia();
|
||||
|
||||
@@ -147,7 +148,6 @@ namespace App {
|
||||
|
||||
Histories &histories();
|
||||
not_null<History*> history(const PeerId &peer);
|
||||
History *historyFromDialog(const PeerId &peer, int32 unreadCnt, int32 maxInboxRead, int32 maxOutboxRead);
|
||||
History *historyLoaded(const PeerId &peer);
|
||||
HistoryItem *histItemById(ChannelId channelId, MsgId itemId);
|
||||
inline not_null<History*> history(const PeerData *peer) {
|
||||
@@ -163,10 +163,9 @@ namespace App {
|
||||
inline HistoryItem *histItemById(const FullMsgId &msgId) {
|
||||
return histItemById(msgId.channel, msgId.msg);
|
||||
}
|
||||
void historyRegItem(HistoryItem *item);
|
||||
void historyItemDetached(HistoryItem *item);
|
||||
void historyUnregItem(HistoryItem *item);
|
||||
void historyUpdateDependent(HistoryItem *item);
|
||||
void historyRegItem(not_null<HistoryItem*> item);
|
||||
void historyUnregItem(not_null<HistoryItem*> item);
|
||||
void historyUpdateDependent(not_null<HistoryItem*> item);
|
||||
void historyClearMsgs();
|
||||
void historyClearItems();
|
||||
void historyRegDependency(HistoryItem *dependent, HistoryItem *dependency);
|
||||
@@ -179,18 +178,16 @@ namespace App {
|
||||
void historyUnregSentData(uint64 randomId);
|
||||
void histSentDataByItem(uint64 randomId, PeerId &peerId, QString &text);
|
||||
|
||||
void hoveredItem(HistoryItem *item);
|
||||
HistoryItem *hoveredItem();
|
||||
void pressedItem(HistoryItem *item);
|
||||
HistoryItem *pressedItem();
|
||||
void hoveredLinkItem(HistoryItem *item);
|
||||
HistoryItem *hoveredLinkItem();
|
||||
void pressedLinkItem(HistoryItem *item);
|
||||
HistoryItem *pressedLinkItem();
|
||||
void contextItem(HistoryItem *item);
|
||||
HistoryItem *contextItem();
|
||||
void mousedItem(HistoryItem *item);
|
||||
HistoryItem *mousedItem();
|
||||
void hoveredItem(HistoryView::Element *item);
|
||||
HistoryView::Element *hoveredItem();
|
||||
void pressedItem(HistoryView::Element *item);
|
||||
HistoryView::Element *pressedItem();
|
||||
void hoveredLinkItem(HistoryView::Element *item);
|
||||
HistoryView::Element *hoveredLinkItem();
|
||||
void pressedLinkItem(HistoryView::Element *item);
|
||||
HistoryView::Element *pressedLinkItem();
|
||||
void mousedItem(HistoryView::Element *item);
|
||||
HistoryView::Element *mousedItem();
|
||||
void clearMousedItems();
|
||||
|
||||
const style::font &monofont();
|
||||
@@ -224,44 +221,10 @@ namespace App {
|
||||
QImage readImage(const QString &file, QByteArray *format = nullptr, bool opaque = true, bool *animated = nullptr, QByteArray *content = 0);
|
||||
QPixmap pixmapFromImageInPlace(QImage &&image);
|
||||
|
||||
void regPhotoItem(PhotoData *data, HistoryItem *item);
|
||||
void unregPhotoItem(PhotoData *data, HistoryItem *item);
|
||||
const PhotoItems &photoItems();
|
||||
const PhotosData &photosData();
|
||||
|
||||
void regDocumentItem(DocumentData *data, HistoryItem *item);
|
||||
void unregDocumentItem(DocumentData *data, HistoryItem *item);
|
||||
const DocumentItems &documentItems();
|
||||
const DocumentsData &documentsData();
|
||||
|
||||
void regWebPageItem(WebPageData *data, HistoryItem *item);
|
||||
void unregWebPageItem(WebPageData *data, HistoryItem *item);
|
||||
const WebPageItems &webPageItems();
|
||||
|
||||
void regGameItem(GameData *data, HistoryItem *item);
|
||||
void unregGameItem(GameData *data, HistoryItem *item);
|
||||
const GameItems &gameItems();
|
||||
|
||||
void regSharedContactItem(int32 userId, HistoryItem *item);
|
||||
void unregSharedContactItem(int32 userId, HistoryItem *item);
|
||||
const SharedContactItems &sharedContactItems();
|
||||
QString phoneFromSharedContact(int32 userId);
|
||||
|
||||
void regGifItem(Media::Clip::Reader *reader, HistoryItem *item);
|
||||
void unregGifItem(Media::Clip::Reader *reader);
|
||||
void stopRoundVideoPlayback();
|
||||
void stopGifItems();
|
||||
|
||||
void regMuted(not_null<PeerData*> peer, TimeMs changeIn);
|
||||
void unregMuted(not_null<PeerData*> peer);
|
||||
void updateMuted();
|
||||
|
||||
void setProxySettings(QNetworkAccessManager &manager);
|
||||
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
||||
QNetworkProxy getHttpProxySettings();
|
||||
#endif // !TDESKTOP_DISABLE_NETWORK_PROXY
|
||||
void setProxySettings(QTcpSocket &socket);
|
||||
|
||||
void complexOverlayRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners);
|
||||
void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners);
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "application.h"
|
||||
|
||||
@@ -24,11 +11,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "autoupdater.h"
|
||||
#include "window/notifications_manager.h"
|
||||
#include "core/crash_reports.h"
|
||||
#include "messenger.h"
|
||||
#include "base/timer.h"
|
||||
#include "core/update_checker.h"
|
||||
#include "core/crash_report_window.h"
|
||||
|
||||
namespace {
|
||||
@@ -78,7 +65,11 @@ Application::Application(
|
||||
int &argc,
|
||||
char **argv)
|
||||
: QApplication(argc, argv)
|
||||
, _launcher(launcher) {
|
||||
, _launcher(launcher)
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
, _updateChecker(std::make_unique<Core::UpdateChecker>())
|
||||
#endif // TDESKTOP_DISABLE_AUTOUPDATE
|
||||
{
|
||||
const auto d = QFile::encodeName(QDir(cWorkingDir()).absolutePath());
|
||||
char h[33] = { 0 };
|
||||
hashMd5Hex(d.constData(), d.size(), h);
|
||||
@@ -99,13 +90,6 @@ Application::Application(
|
||||
QTimer::singleShot(0, this, SLOT(startApplication()));
|
||||
connect(this, SIGNAL(aboutToQuit()), this, SLOT(closeApplication()));
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
_updateCheckTimer.create(this);
|
||||
connect(_updateCheckTimer, SIGNAL(timeout()), this, SLOT(updateCheck()));
|
||||
connect(this, SIGNAL(updateFailed()), this, SLOT(onUpdateFailed()));
|
||||
connect(this, SIGNAL(updateReady()), this, SLOT(onUpdateReady()));
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
if (cManyInstance()) {
|
||||
LOG(("Many instance allowed, starting..."));
|
||||
singleInstanceChecked();
|
||||
@@ -193,7 +177,7 @@ void Application::socketError(QLocalSocket::LocalSocketError e) {
|
||||
#endif // !Q_OS_WINRT
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
if (!cNoStartUpdate() && checkReadyUpdate()) {
|
||||
if (!cNoStartUpdate() && Core::checkReadyUpdate()) {
|
||||
cSetRestartingUpdate(true);
|
||||
DEBUG_LOG(("Application Info: installing update instead of starting app..."));
|
||||
return App::quit();
|
||||
@@ -209,6 +193,7 @@ void Application::singleInstanceChecked() {
|
||||
}
|
||||
|
||||
Sandbox::start();
|
||||
refreshGlobalProxy();
|
||||
|
||||
if (!Logs::started() || (!cManyInstance() && !Logs::instanceChecked())) {
|
||||
new NotStartedWindow();
|
||||
@@ -320,9 +305,29 @@ void Application::startApplication() {
|
||||
|
||||
void Application::createMessenger() {
|
||||
Expects(!App::quitting());
|
||||
|
||||
_messengerInstance = std::make_unique<Messenger>(_launcher);
|
||||
}
|
||||
|
||||
void Application::refreshGlobalProxy() {
|
||||
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
||||
const auto proxy = [&] {
|
||||
if (Global::started()) {
|
||||
return Global::UseProxy()
|
||||
? Global::SelectedProxy()
|
||||
: ProxyData();
|
||||
}
|
||||
return Sandbox::PreLaunchProxy();
|
||||
}();
|
||||
if (proxy.type == ProxyData::Type::Socks5
|
||||
|| proxy.type == ProxyData::Type::Http) {
|
||||
QNetworkProxy::setApplicationProxy(ToNetworkProxy(proxy));
|
||||
} else {
|
||||
QNetworkProxyFactory::setUseSystemConfiguration(true);
|
||||
}
|
||||
#endif // TDESKTOP_DISABLE_NETWORK_PROXY
|
||||
}
|
||||
|
||||
void Application::closeApplication() {
|
||||
if (App::launchState() == App::QuitProcessed) return;
|
||||
App::setLaunchState(App::QuitProcessed);
|
||||
@@ -341,169 +346,10 @@ void Application::closeApplication() {
|
||||
_localSocket.close();
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
delete _updateReply;
|
||||
_updateReply = 0;
|
||||
if (_updateChecker) _updateChecker->deleteLater();
|
||||
_updateChecker = 0;
|
||||
if (_updateThread) {
|
||||
_updateThread->quit();
|
||||
}
|
||||
_updateThread = 0;
|
||||
_updateChecker = nullptr;
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
}
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
void Application::updateCheck() {
|
||||
startUpdateCheck(false);
|
||||
}
|
||||
|
||||
void Application::updateGotCurrent() {
|
||||
if (!_updateReply || _updateThread) return;
|
||||
|
||||
cSetLastUpdateCheck(unixtime());
|
||||
QRegularExpressionMatch m = QRegularExpression(qsl("^\\s*(\\d+)\\s*:\\s*([\\x21-\\x7f]+)\\s*$")).match(QString::fromLatin1(_updateReply->readAll()));
|
||||
if (m.hasMatch()) {
|
||||
uint64 currentVersion = m.captured(1).toULongLong();
|
||||
QString url = m.captured(2);
|
||||
bool betaVersion = false;
|
||||
if (url.startsWith(qstr("beta_"))) {
|
||||
betaVersion = true;
|
||||
url = url.mid(5) + '_' + countBetaVersionSignature(currentVersion);
|
||||
}
|
||||
if ((!betaVersion || cBetaVersion()) && currentVersion > (betaVersion ? cBetaVersion() : uint64(AppVersion))) {
|
||||
_updateThread = new QThread();
|
||||
connect(_updateThread, SIGNAL(finished()), _updateThread, SLOT(deleteLater()));
|
||||
_updateChecker = new UpdateChecker(_updateThread, url);
|
||||
_updateThread->start();
|
||||
}
|
||||
}
|
||||
if (_updateReply) _updateReply->deleteLater();
|
||||
_updateReply = 0;
|
||||
if (!_updateThread) {
|
||||
QDir updates(cWorkingDir() + "tupdates");
|
||||
if (updates.exists()) {
|
||||
QFileInfoList list = updates.entryInfoList(QDir::Files);
|
||||
for (QFileInfoList::iterator i = list.begin(), e = list.end(); i != e; ++i) {
|
||||
if (QRegularExpression("^(tupdate|tmacupd|tmac32upd|tlinuxupd|tlinux32upd)\\d+(_[a-z\\d]+)?$", QRegularExpression::CaseInsensitiveOption).match(i->fileName()).hasMatch()) {
|
||||
QFile(i->absoluteFilePath()).remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
emit updateLatest();
|
||||
}
|
||||
startUpdateCheck(true);
|
||||
Local::writeSettings();
|
||||
}
|
||||
|
||||
void Application::updateFailedCurrent(QNetworkReply::NetworkError e) {
|
||||
LOG(("App Error: could not get current version (update check): %1").arg(e));
|
||||
if (_updateReply) _updateReply->deleteLater();
|
||||
_updateReply = 0;
|
||||
|
||||
emit updateFailed();
|
||||
startUpdateCheck(true);
|
||||
}
|
||||
|
||||
void Application::onUpdateReady() {
|
||||
if (_updateChecker) {
|
||||
_updateChecker->deleteLater();
|
||||
_updateChecker = nullptr;
|
||||
}
|
||||
_updateCheckTimer->stop();
|
||||
|
||||
cSetLastUpdateCheck(unixtime());
|
||||
Local::writeSettings();
|
||||
}
|
||||
|
||||
void Application::onUpdateFailed() {
|
||||
if (_updateChecker) {
|
||||
_updateChecker->deleteLater();
|
||||
_updateChecker = 0;
|
||||
if (_updateThread) _updateThread->quit();
|
||||
_updateThread = 0;
|
||||
}
|
||||
|
||||
cSetLastUpdateCheck(unixtime());
|
||||
Local::writeSettings();
|
||||
}
|
||||
|
||||
Application::UpdatingState Application::updatingState() {
|
||||
if (!_updateThread) return Application::UpdatingNone;
|
||||
if (!_updateChecker) return Application::UpdatingReady;
|
||||
return Application::UpdatingDownload;
|
||||
}
|
||||
|
||||
int32 Application::updatingSize() {
|
||||
if (!_updateChecker) return 0;
|
||||
return _updateChecker->size();
|
||||
}
|
||||
|
||||
int32 Application::updatingReady() {
|
||||
if (!_updateChecker) return 0;
|
||||
return _updateChecker->ready();
|
||||
}
|
||||
|
||||
void Application::stopUpdate() {
|
||||
if (_updateReply) {
|
||||
_updateReply->abort();
|
||||
_updateReply->deleteLater();
|
||||
_updateReply = 0;
|
||||
}
|
||||
if (_updateChecker) {
|
||||
_updateChecker->deleteLater();
|
||||
_updateChecker = 0;
|
||||
if (_updateThread) _updateThread->quit();
|
||||
_updateThread = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Application::startUpdateCheck(bool forceWait) {
|
||||
if (!Sandbox::started()) return;
|
||||
|
||||
_updateCheckTimer->stop();
|
||||
if (_updateThread || _updateReply || !cAutoUpdate() || cExeName().isEmpty()) return;
|
||||
|
||||
int32 constDelay = cBetaVersion() ? 600 : UpdateDelayConstPart, randDelay = cBetaVersion() ? 300 : UpdateDelayRandPart;
|
||||
int32 updateInSecs = cLastUpdateCheck() + constDelay + int32(rand() % randDelay) - unixtime();
|
||||
bool sendRequest = (updateInSecs <= 0 || updateInSecs > (constDelay + randDelay));
|
||||
if (!sendRequest && !forceWait) {
|
||||
QDir updates(cWorkingDir() + "tupdates");
|
||||
if (updates.exists()) {
|
||||
QFileInfoList list = updates.entryInfoList(QDir::Files);
|
||||
for (QFileInfoList::iterator i = list.begin(), e = list.end(); i != e; ++i) {
|
||||
if (QRegularExpression("^(tupdate|tmacupd|tmac32upd|tlinuxupd|tlinux32upd)\\d+(_[a-z\\d]+)?$", QRegularExpression::CaseInsensitiveOption).match(i->fileName()).hasMatch()) {
|
||||
sendRequest = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cManyInstance() && !cDebug()) return; // only main instance is updating
|
||||
|
||||
if (sendRequest) {
|
||||
QUrl url(cUpdateURL());
|
||||
if (cBetaVersion()) {
|
||||
url.setQuery(qsl("version=%1&beta=%2").arg(AppVersion).arg(cBetaVersion()));
|
||||
} else if (cAlphaVersion()) {
|
||||
url.setQuery(qsl("version=%1&alpha=1").arg(AppVersion));
|
||||
} else {
|
||||
url.setQuery(qsl("version=%1").arg(AppVersion));
|
||||
}
|
||||
QString u = url.toString();
|
||||
QNetworkRequest checkVersion(url);
|
||||
if (_updateReply) _updateReply->deleteLater();
|
||||
|
||||
App::setProxySettings(_updateManager);
|
||||
_updateReply = _updateManager.get(checkVersion);
|
||||
connect(_updateReply, SIGNAL(finished()), this, SLOT(updateGotCurrent()));
|
||||
connect(_updateReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(updateFailedCurrent(QNetworkReply::NetworkError)));
|
||||
emit updateChecking();
|
||||
} else {
|
||||
_updateCheckTimer->start((updateInSecs + 5) * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
inline Application *application() {
|
||||
return qobject_cast<Application*>(QApplication::instance());
|
||||
}
|
||||
@@ -555,73 +401,6 @@ void adjustSingleTimers() {
|
||||
base::Timer::Adjust();
|
||||
}
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
void startUpdateCheck() {
|
||||
if (auto a = application()) {
|
||||
return a->startUpdateCheck(false);
|
||||
}
|
||||
}
|
||||
|
||||
void stopUpdate() {
|
||||
if (auto a = application()) {
|
||||
return a->stopUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
Application::UpdatingState updatingState() {
|
||||
if (auto a = application()) {
|
||||
return a->updatingState();
|
||||
}
|
||||
return Application::UpdatingNone;
|
||||
}
|
||||
|
||||
int32 updatingSize() {
|
||||
if (auto a = application()) {
|
||||
return a->updatingSize();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 updatingReady() {
|
||||
if (auto a = application()) {
|
||||
return a->updatingReady();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void updateChecking() {
|
||||
if (auto a = application()) {
|
||||
emit a->updateChecking();
|
||||
}
|
||||
}
|
||||
|
||||
void updateLatest() {
|
||||
if (auto a = application()) {
|
||||
emit a->updateLatest();
|
||||
}
|
||||
}
|
||||
|
||||
void updateProgress(qint64 ready, qint64 total) {
|
||||
if (auto a = application()) {
|
||||
emit a->updateProgress(ready, total);
|
||||
}
|
||||
}
|
||||
|
||||
void updateFailed() {
|
||||
if (auto a = application()) {
|
||||
emit a->updateFailed();
|
||||
}
|
||||
}
|
||||
|
||||
void updateReady() {
|
||||
if (auto a = application()) {
|
||||
emit a->updateReady();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
void connect(const char *signal, QObject *object, const char *method) {
|
||||
if (auto a = application()) {
|
||||
a->connect(a, signal, object, method);
|
||||
@@ -661,4 +440,10 @@ void launch() {
|
||||
application()->createMessenger();
|
||||
}
|
||||
|
||||
void refreshGlobalProxy() {
|
||||
if (const auto instance = application()) {
|
||||
instance->refreshGlobalProxy();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Sandbox
|
||||
|
||||
@@ -1,29 +1,15 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
class UpdateChecker;
|
||||
|
||||
namespace Core {
|
||||
class Launcher;
|
||||
class UpdateChecker;
|
||||
} // namespace Core
|
||||
|
||||
class Application : public QApplication {
|
||||
@@ -35,6 +21,7 @@ public:
|
||||
bool event(QEvent *e) override;
|
||||
|
||||
void createMessenger();
|
||||
void refreshGlobalProxy();
|
||||
|
||||
~Application();
|
||||
|
||||
@@ -71,46 +58,11 @@ private:
|
||||
|
||||
void singleInstanceChecked();
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
// Autoupdating
|
||||
public:
|
||||
void startUpdateCheck(bool forceWait);
|
||||
void stopUpdate();
|
||||
|
||||
enum UpdatingState {
|
||||
UpdatingNone,
|
||||
UpdatingDownload,
|
||||
UpdatingReady,
|
||||
};
|
||||
UpdatingState updatingState();
|
||||
int32 updatingSize();
|
||||
int32 updatingReady();
|
||||
|
||||
signals:
|
||||
void updateChecking();
|
||||
void updateLatest();
|
||||
void updateProgress(qint64 ready, qint64 total);
|
||||
void updateReady();
|
||||
void updateFailed();
|
||||
|
||||
public slots:
|
||||
void updateCheck();
|
||||
|
||||
void updateGotCurrent();
|
||||
void updateFailedCurrent(QNetworkReply::NetworkError e);
|
||||
|
||||
void onUpdateReady();
|
||||
void onUpdateFailed();
|
||||
|
||||
private:
|
||||
object_ptr<SingleTimer> _updateCheckTimer = { nullptr };
|
||||
QNetworkReply *_updateReply = nullptr;
|
||||
QNetworkAccessManager _updateManager;
|
||||
QThread *_updateThread = nullptr;
|
||||
UpdateChecker *_updateChecker = nullptr;
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
std::unique_ptr<Core::UpdateChecker> _updateChecker;
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
};
|
||||
|
||||
namespace Sandbox {
|
||||
@@ -124,22 +76,7 @@ void execExternal(const QString &cmd);
|
||||
|
||||
void adjustSingleTimers();
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
void startUpdateCheck();
|
||||
void stopUpdate();
|
||||
|
||||
Application::UpdatingState updatingState();
|
||||
int32 updatingSize();
|
||||
int32 updatingReady();
|
||||
|
||||
void updateChecking();
|
||||
void updateLatest();
|
||||
void updateProgress(qint64 ready, qint64 total);
|
||||
void updateFailed();
|
||||
void updateReady();
|
||||
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
void refreshGlobalProxy();
|
||||
|
||||
void connect(const char *signal, QObject *object, const char *method);
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "auth_session.h"
|
||||
|
||||
@@ -28,7 +15,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "storage/localstorage.h"
|
||||
#include "storage/storage_facade.h"
|
||||
#include "storage/serialize_common.h"
|
||||
#include "history/history_item_components.h"
|
||||
#include "data/data_session.h"
|
||||
#include "window/notifications_manager.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
#include "platform/platform_specific.h"
|
||||
@@ -43,14 +30,14 @@ constexpr auto kAutoLockTimeoutLateMs = TimeMs(3000);
|
||||
|
||||
} // namespace
|
||||
|
||||
AuthSessionData::Variables::Variables()
|
||||
AuthSessionSettings::Variables::Variables()
|
||||
: sendFilesWay(SendFilesWay::Album)
|
||||
, selectorTab(ChatHelpers::SelectorTab::Emoji)
|
||||
, floatPlayerColumn(Window::Column::Second)
|
||||
, floatPlayerCorner(RectPart::TopRight) {
|
||||
}
|
||||
|
||||
QByteArray AuthSessionData::serialize() const {
|
||||
QByteArray AuthSessionSettings::serialize() const {
|
||||
auto size = sizeof(qint32) * 10;
|
||||
for (auto i = _variables.soundOverrides.cbegin(), e = _variables.soundOverrides.cend(); i != e; ++i) {
|
||||
size += Serialize::stringSize(i.key()) + Serialize::stringSize(i.value());
|
||||
@@ -89,7 +76,7 @@ QByteArray AuthSessionData::serialize() const {
|
||||
return result;
|
||||
}
|
||||
|
||||
void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
|
||||
void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized) {
|
||||
if (serialized.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -159,7 +146,8 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
|
||||
thirdSectionExtendedBy = value;
|
||||
}
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
LOG(("App Error: Bad data for AuthSessionData::constructFromSerialized()"));
|
||||
LOG(("App Error: "
|
||||
"Bad data for AuthSessionSettings::constructFromSerialized()"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -203,87 +191,7 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
|
||||
}
|
||||
}
|
||||
|
||||
void AuthSessionData::markItemLayoutChanged(not_null<const HistoryItem*> item) {
|
||||
_itemLayoutChanged.fire_copy(item);
|
||||
}
|
||||
|
||||
rpl::producer<not_null<const HistoryItem*>> AuthSessionData::itemLayoutChanged() const {
|
||||
return _itemLayoutChanged.events();
|
||||
}
|
||||
|
||||
void AuthSessionData::requestItemRepaint(not_null<const HistoryItem*> item) {
|
||||
_itemRepaintRequest.fire_copy(item);
|
||||
}
|
||||
|
||||
rpl::producer<not_null<const HistoryItem*>> AuthSessionData::itemRepaintRequest() const {
|
||||
return _itemRepaintRequest.events();
|
||||
}
|
||||
|
||||
void AuthSessionData::markItemRemoved(not_null<const HistoryItem*> item) {
|
||||
_itemRemoved.fire_copy(item);
|
||||
}
|
||||
|
||||
rpl::producer<not_null<const HistoryItem*>> AuthSessionData::itemRemoved() const {
|
||||
return _itemRemoved.events();
|
||||
}
|
||||
|
||||
void AuthSessionData::markHistoryUnloaded(not_null<const History*> history) {
|
||||
_historyUnloaded.fire_copy(history);
|
||||
}
|
||||
|
||||
rpl::producer<not_null<const History*>> AuthSessionData::historyUnloaded() const {
|
||||
return _historyUnloaded.events();
|
||||
}
|
||||
|
||||
void AuthSessionData::markHistoryCleared(not_null<const History*> history) {
|
||||
_historyCleared.fire_copy(history);
|
||||
}
|
||||
|
||||
rpl::producer<not_null<const History*>> AuthSessionData::historyCleared() const {
|
||||
return _historyCleared.events();
|
||||
}
|
||||
|
||||
void AuthSessionData::removeMegagroupParticipant(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<UserData*> user) {
|
||||
_megagroupParticipantRemoved.fire({ channel, user });
|
||||
}
|
||||
|
||||
auto AuthSessionData::megagroupParticipantRemoved() const -> rpl::producer<MegagroupParticipant> {
|
||||
return _megagroupParticipantRemoved.events();
|
||||
}
|
||||
|
||||
rpl::producer<not_null<UserData*>> AuthSessionData::megagroupParticipantRemoved(
|
||||
not_null<ChannelData*> channel) const {
|
||||
return megagroupParticipantRemoved(
|
||||
) | rpl::filter([channel](auto updateChannel, auto user) {
|
||||
return (updateChannel == channel);
|
||||
}) | rpl::map([](auto updateChannel, auto user) {
|
||||
return user;
|
||||
});
|
||||
}
|
||||
|
||||
void AuthSessionData::addNewMegagroupParticipant(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<UserData*> user) {
|
||||
_megagroupParticipantAdded.fire({ channel, user });
|
||||
}
|
||||
|
||||
auto AuthSessionData::megagroupParticipantAdded() const -> rpl::producer<MegagroupParticipant> {
|
||||
return _megagroupParticipantAdded.events();
|
||||
}
|
||||
|
||||
rpl::producer<not_null<UserData*>> AuthSessionData::megagroupParticipantAdded(
|
||||
not_null<ChannelData*> channel) const {
|
||||
return megagroupParticipantAdded(
|
||||
) | rpl::filter([channel](auto updateChannel, auto user) {
|
||||
return (updateChannel == channel);
|
||||
}) | rpl::map([](auto updateChannel, auto user) {
|
||||
return user;
|
||||
});
|
||||
}
|
||||
|
||||
void AuthSessionData::setTabbedSelectorSectionEnabled(bool enabled) {
|
||||
void AuthSessionSettings::setTabbedSelectorSectionEnabled(bool enabled) {
|
||||
_variables.tabbedSelectorSectionEnabled = enabled;
|
||||
if (enabled) {
|
||||
setThirdSectionInfoEnabled(false);
|
||||
@@ -291,12 +199,12 @@ void AuthSessionData::setTabbedSelectorSectionEnabled(bool enabled) {
|
||||
setTabbedReplacedWithInfo(false);
|
||||
}
|
||||
|
||||
rpl::producer<bool> AuthSessionData::tabbedReplacedWithInfoValue() const {
|
||||
rpl::producer<bool> AuthSessionSettings::tabbedReplacedWithInfoValue() const {
|
||||
return _tabbedReplacedWithInfoValue.events_starting_with(
|
||||
tabbedReplacedWithInfo());
|
||||
}
|
||||
|
||||
void AuthSessionData::setThirdSectionInfoEnabled(bool enabled) {
|
||||
void AuthSessionSettings::setThirdSectionInfoEnabled(bool enabled) {
|
||||
if (_variables.thirdSectionInfoEnabled != enabled) {
|
||||
_variables.thirdSectionInfoEnabled = enabled;
|
||||
if (enabled) {
|
||||
@@ -307,19 +215,19 @@ void AuthSessionData::setThirdSectionInfoEnabled(bool enabled) {
|
||||
}
|
||||
}
|
||||
|
||||
rpl::producer<bool> AuthSessionData::thirdSectionInfoEnabledValue() const {
|
||||
rpl::producer<bool> AuthSessionSettings::thirdSectionInfoEnabledValue() const {
|
||||
return _thirdSectionInfoEnabledValue.events_starting_with(
|
||||
thirdSectionInfoEnabled());
|
||||
}
|
||||
|
||||
void AuthSessionData::setTabbedReplacedWithInfo(bool enabled) {
|
||||
void AuthSessionSettings::setTabbedReplacedWithInfo(bool enabled) {
|
||||
if (_tabbedReplacedWithInfo != enabled) {
|
||||
_tabbedReplacedWithInfo = enabled;
|
||||
_tabbedReplacedWithInfoValue.fire_copy(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
QString AuthSessionData::getSoundPath(const QString &key) const {
|
||||
QString AuthSessionSettings::getSoundPath(const QString &key) const {
|
||||
auto it = _variables.soundOverrides.constFind(key);
|
||||
if (it != _variables.soundOverrides.end()) {
|
||||
return it.value();
|
||||
@@ -327,75 +235,30 @@ QString AuthSessionData::getSoundPath(const QString &key) const {
|
||||
return qsl(":/sounds/") + key + qsl(".mp3");
|
||||
}
|
||||
|
||||
void AuthSessionData::setDialogsWidthRatio(float64 ratio) {
|
||||
void AuthSessionSettings::setDialogsWidthRatio(float64 ratio) {
|
||||
_variables.dialogsWidthRatio = ratio;
|
||||
}
|
||||
|
||||
float64 AuthSessionData::dialogsWidthRatio() const {
|
||||
float64 AuthSessionSettings::dialogsWidthRatio() const {
|
||||
return _variables.dialogsWidthRatio.current();
|
||||
}
|
||||
|
||||
rpl::producer<float64> AuthSessionData::dialogsWidthRatioChanges() const {
|
||||
rpl::producer<float64> AuthSessionSettings::dialogsWidthRatioChanges() const {
|
||||
return _variables.dialogsWidthRatio.changes();
|
||||
}
|
||||
|
||||
void AuthSessionData::setThirdColumnWidth(int width) {
|
||||
void AuthSessionSettings::setThirdColumnWidth(int width) {
|
||||
_variables.thirdColumnWidth = width;
|
||||
}
|
||||
|
||||
int AuthSessionData::thirdColumnWidth() const {
|
||||
int AuthSessionSettings::thirdColumnWidth() const {
|
||||
return _variables.thirdColumnWidth.current();
|
||||
}
|
||||
|
||||
rpl::producer<int> AuthSessionData::thirdColumnWidthChanges() const {
|
||||
rpl::producer<int> AuthSessionSettings::thirdColumnWidthChanges() const {
|
||||
return _variables.thirdColumnWidth.changes();
|
||||
}
|
||||
|
||||
void AuthSessionData::markStickersUpdated() {
|
||||
_stickersUpdated.fire({});
|
||||
}
|
||||
|
||||
rpl::producer<> AuthSessionData::stickersUpdated() const {
|
||||
return _stickersUpdated.events();
|
||||
}
|
||||
|
||||
void AuthSessionData::markSavedGifsUpdated() {
|
||||
_savedGifsUpdated.fire({});
|
||||
}
|
||||
|
||||
rpl::producer<> AuthSessionData::savedGifsUpdated() const {
|
||||
return _savedGifsUpdated.events();
|
||||
}
|
||||
|
||||
HistoryItemsList AuthSessionData::idsToItems(
|
||||
const MessageIdsList &ids) const {
|
||||
return ranges::view::all(
|
||||
ids
|
||||
) | ranges::view::transform([](const FullMsgId &fullId) {
|
||||
return App::histItemById(fullId);
|
||||
}) | ranges::view::filter([](HistoryItem *item) {
|
||||
return item != nullptr;
|
||||
}) | ranges::view::transform([](HistoryItem *item) {
|
||||
return not_null<HistoryItem*>(item);
|
||||
}) | ranges::to_vector;
|
||||
}
|
||||
|
||||
MessageIdsList AuthSessionData::itemsToIds(
|
||||
const HistoryItemsList &items) const {
|
||||
return ranges::view::all(
|
||||
items
|
||||
) | ranges::view::transform([](not_null<HistoryItem*> item) {
|
||||
return item->fullId();
|
||||
}) | ranges::to_vector;
|
||||
}
|
||||
|
||||
MessageIdsList AuthSessionData::groupToIds(
|
||||
not_null<HistoryMessageGroup*> group) const {
|
||||
auto result = itemsToIds(group->others);
|
||||
result.push_back(group->leader->fullId());
|
||||
return result;
|
||||
}
|
||||
|
||||
AuthSession &Auth() {
|
||||
auto result = Messenger::Instance().authSession();
|
||||
Assert(result != nullptr);
|
||||
@@ -411,13 +274,14 @@ AuthSession::AuthSession(UserId userId)
|
||||
, _uploader(std::make_unique<Storage::Uploader>())
|
||||
, _storage(std::make_unique<Storage::Facade>())
|
||||
, _notifications(std::make_unique<Window::Notifications::System>(this))
|
||||
, _data(std::make_unique<Data::Session>(this))
|
||||
, _changelogs(Core::Changelogs::Create(this)) {
|
||||
Expects(_userId != 0);
|
||||
|
||||
_saveDataTimer.setCallback([this] {
|
||||
_saveDataTimer.setCallback([=] {
|
||||
Local::writeUserSettings();
|
||||
});
|
||||
subscribe(Messenger::Instance().passcodedChanged(), [this] {
|
||||
subscribe(Messenger::Instance().passcodedChanged(), [=] {
|
||||
_shouldLockAt = 0;
|
||||
notifications().updateAll();
|
||||
});
|
||||
@@ -440,7 +304,10 @@ base::Observable<void> &AuthSession::downloaderTaskFinished() {
|
||||
}
|
||||
|
||||
bool AuthSession::validateSelf(const MTPUser &user) {
|
||||
if (user.type() != mtpc_user || !user.c_user().is_self() || user.c_user().vid.v != userId()) {
|
||||
if (user.type() != mtpc_user || !user.c_user().is_self()) {
|
||||
LOG(("API Error: bad self user received."));
|
||||
return false;
|
||||
} else if (user.c_user().vid.v != userId()) {
|
||||
LOG(("Auth Error: wrong self user received."));
|
||||
App::logOutDelayed();
|
||||
return false;
|
||||
@@ -448,8 +315,9 @@ bool AuthSession::validateSelf(const MTPUser &user) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void AuthSession::saveDataDelayed(TimeMs delay) {
|
||||
void AuthSession::saveSettingsDelayed(TimeMs delay) {
|
||||
Expects(this == &Auth());
|
||||
|
||||
_saveDataTimer.callOnce(delay);
|
||||
}
|
||||
|
||||
@@ -460,7 +328,7 @@ void AuthSession::checkAutoLock() {
|
||||
auto now = getms(true);
|
||||
auto shouldLockInMs = Global::AutoLock() * 1000LL;
|
||||
auto idleForMs = psIdleTime();
|
||||
auto notPlayingVideoForMs = now - data().lastTimeVideoPlayedAt();
|
||||
auto notPlayingVideoForMs = now - settings().lastTimeVideoPlayedAt();
|
||||
auto checkTimeMs = qMin(idleForMs, notPlayingVideoForMs);
|
||||
if (checkTimeMs >= shouldLockInMs || (_shouldLockAt > 0 && now > _shouldLockAt + kAutoLockTimeoutLateMs)) {
|
||||
Messenger::Instance().setupPasscode();
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@@ -24,11 +11,14 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include <rpl/filter.h>
|
||||
#include <rpl/variable.h>
|
||||
#include "base/timer.h"
|
||||
#include "chat_helpers/stickers.h"
|
||||
|
||||
class ApiWrap;
|
||||
enum class SendFilesWay;
|
||||
|
||||
namespace Data {
|
||||
class Session;
|
||||
} // namespace Data
|
||||
|
||||
namespace Storage {
|
||||
class Downloader;
|
||||
class Uploader;
|
||||
@@ -54,65 +44,20 @@ namespace Core {
|
||||
class Changelogs;
|
||||
} // namespace Core
|
||||
|
||||
class AuthSessionData final {
|
||||
class AuthSessionSettings final {
|
||||
public:
|
||||
base::Variable<bool> &contactsLoaded() {
|
||||
return _contactsLoaded;
|
||||
}
|
||||
base::Variable<bool> &allChatsLoaded() {
|
||||
return _allChatsLoaded;
|
||||
}
|
||||
base::Observable<void> &moreChatsLoaded() {
|
||||
return _moreChatsLoaded;
|
||||
}
|
||||
base::Observable<void> &pendingHistoryResize() {
|
||||
return _pendingHistoryResize;
|
||||
}
|
||||
struct ItemVisibilityQuery {
|
||||
not_null<HistoryItem*> item;
|
||||
not_null<bool*> isVisible;
|
||||
};
|
||||
base::Observable<ItemVisibilityQuery> &queryItemVisibility() {
|
||||
return _queryItemVisibility;
|
||||
}
|
||||
void markItemLayoutChanged(not_null<const HistoryItem*> item);
|
||||
rpl::producer<not_null<const HistoryItem*>> itemLayoutChanged() const;
|
||||
void requestItemRepaint(not_null<const HistoryItem*> item);
|
||||
rpl::producer<not_null<const HistoryItem*>> itemRepaintRequest() const;
|
||||
void markItemRemoved(not_null<const HistoryItem*> item);
|
||||
rpl::producer<not_null<const HistoryItem*>> itemRemoved() const;
|
||||
void markHistoryUnloaded(not_null<const History*> history);
|
||||
rpl::producer<not_null<const History*>> historyUnloaded() const;
|
||||
void markHistoryCleared(not_null<const History*> history);
|
||||
rpl::producer<not_null<const History*>> historyCleared() const;
|
||||
using MegagroupParticipant = std::tuple<
|
||||
not_null<ChannelData*>,
|
||||
not_null<UserData*>>;
|
||||
void removeMegagroupParticipant(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<UserData*> user);
|
||||
rpl::producer<MegagroupParticipant> megagroupParticipantRemoved() const;
|
||||
rpl::producer<not_null<UserData*>> megagroupParticipantRemoved(
|
||||
not_null<ChannelData*> channel) const;
|
||||
void addNewMegagroupParticipant(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<UserData*> user);
|
||||
rpl::producer<MegagroupParticipant> megagroupParticipantAdded() const;
|
||||
rpl::producer<not_null<UserData*>> megagroupParticipantAdded(
|
||||
not_null<ChannelData*> channel) const;
|
||||
|
||||
void moveFrom(AuthSessionData &&other) {
|
||||
void moveFrom(AuthSessionSettings &&other) {
|
||||
_variables = std::move(other._variables);
|
||||
}
|
||||
QByteArray serialize() const;
|
||||
void constructFromSerialized(const QByteArray &serialized);
|
||||
|
||||
bool lastSeenWarningSeen() const {
|
||||
return _variables.lastSeenWarningSeen;
|
||||
}
|
||||
void setLastSeenWarningSeen(bool lastSeenWarningSeen) {
|
||||
_variables.lastSeenWarningSeen = lastSeenWarningSeen;
|
||||
}
|
||||
bool lastSeenWarningSeen() const {
|
||||
return _variables.lastSeenWarningSeen;
|
||||
}
|
||||
void setSendFilesWay(SendFilesWay way) {
|
||||
_variables.sendFilesWay = way;
|
||||
}
|
||||
@@ -189,10 +134,6 @@ public:
|
||||
int thirdColumnWidth() const;
|
||||
rpl::producer<int> thirdColumnWidthChanges() const;
|
||||
|
||||
void markStickersUpdated();
|
||||
rpl::producer<> stickersUpdated() const;
|
||||
void markSavedGifsUpdated();
|
||||
rpl::producer<> savedGifsUpdated() const;
|
||||
void setGroupStickersSectionHidden(PeerId peerId) {
|
||||
_variables.groupStickersSectionHidden.insert(peerId);
|
||||
}
|
||||
@@ -202,79 +143,6 @@ public:
|
||||
void removeGroupStickersSectionHidden(PeerId peerId) {
|
||||
_variables.groupStickersSectionHidden.remove(peerId);
|
||||
}
|
||||
bool stickersUpdateNeeded(TimeMs now) const {
|
||||
return stickersUpdateNeeded(_lastStickersUpdate, now);
|
||||
}
|
||||
void setLastStickersUpdate(TimeMs update) {
|
||||
_lastStickersUpdate = update;
|
||||
}
|
||||
bool recentStickersUpdateNeeded(TimeMs now) const {
|
||||
return stickersUpdateNeeded(_lastRecentStickersUpdate, now);
|
||||
}
|
||||
void setLastRecentStickersUpdate(TimeMs update) {
|
||||
_lastRecentStickersUpdate = update;
|
||||
}
|
||||
bool favedStickersUpdateNeeded(TimeMs now) const {
|
||||
return stickersUpdateNeeded(_lastFavedStickersUpdate, now);
|
||||
}
|
||||
void setLastFavedStickersUpdate(TimeMs update) {
|
||||
_lastFavedStickersUpdate = update;
|
||||
}
|
||||
bool featuredStickersUpdateNeeded(TimeMs now) const {
|
||||
return stickersUpdateNeeded(_lastFeaturedStickersUpdate, now);
|
||||
}
|
||||
void setLastFeaturedStickersUpdate(TimeMs update) {
|
||||
_lastFeaturedStickersUpdate = update;
|
||||
}
|
||||
bool savedGifsUpdateNeeded(TimeMs now) const {
|
||||
return stickersUpdateNeeded(_lastSavedGifsUpdate, now);
|
||||
}
|
||||
void setLastSavedGifsUpdate(TimeMs update) {
|
||||
_lastSavedGifsUpdate = update;
|
||||
}
|
||||
int featuredStickerSetsUnreadCount() const {
|
||||
return _featuredStickerSetsUnreadCount.current();
|
||||
}
|
||||
void setFeaturedStickerSetsUnreadCount(int count) {
|
||||
_featuredStickerSetsUnreadCount = count;
|
||||
}
|
||||
rpl::producer<int> featuredStickerSetsUnreadCountValue() const {
|
||||
return _featuredStickerSetsUnreadCount.value();
|
||||
}
|
||||
const Stickers::Sets &stickerSets() const {
|
||||
return _stickerSets;
|
||||
}
|
||||
Stickers::Sets &stickerSetsRef() {
|
||||
return _stickerSets;
|
||||
}
|
||||
const Stickers::Order &stickerSetsOrder() const {
|
||||
return _stickerSetsOrder;
|
||||
}
|
||||
Stickers::Order &stickerSetsOrderRef() {
|
||||
return _stickerSetsOrder;
|
||||
}
|
||||
const Stickers::Order &featuredStickerSetsOrder() const {
|
||||
return _featuredStickerSetsOrder;
|
||||
}
|
||||
Stickers::Order &featuredStickerSetsOrderRef() {
|
||||
return _featuredStickerSetsOrder;
|
||||
}
|
||||
const Stickers::Order &archivedStickerSetsOrder() const {
|
||||
return _archivedStickerSetsOrder;
|
||||
}
|
||||
Stickers::Order &archivedStickerSetsOrderRef() {
|
||||
return _archivedStickerSetsOrder;
|
||||
}
|
||||
const Stickers::SavedGifs &savedGifs() const {
|
||||
return _savedGifs;
|
||||
}
|
||||
Stickers::SavedGifs &savedGifsRef() {
|
||||
return _savedGifs;
|
||||
}
|
||||
|
||||
HistoryItemsList idsToItems(const MessageIdsList &ids) const;
|
||||
MessageIdsList itemsToIds(const HistoryItemsList &items) const;
|
||||
MessageIdsList groupToIds(not_null<HistoryMessageGroup*> group) const;
|
||||
|
||||
private:
|
||||
struct Variables {
|
||||
@@ -301,39 +169,6 @@ private:
|
||||
= kDefaultThirdColumnWidth; // per-window
|
||||
};
|
||||
|
||||
bool stickersUpdateNeeded(TimeMs lastUpdate, TimeMs now) const {
|
||||
constexpr auto kStickersUpdateTimeout = TimeMs(3600'000);
|
||||
return (lastUpdate == 0)
|
||||
|| (now >= lastUpdate + kStickersUpdateTimeout);
|
||||
}
|
||||
|
||||
base::Variable<bool> _contactsLoaded = { false };
|
||||
base::Variable<bool> _allChatsLoaded = { false };
|
||||
base::Observable<void> _moreChatsLoaded;
|
||||
base::Observable<void> _pendingHistoryResize;
|
||||
base::Observable<ItemVisibilityQuery> _queryItemVisibility;
|
||||
rpl::event_stream<not_null<const HistoryItem*>> _itemLayoutChanged;
|
||||
rpl::event_stream<not_null<const HistoryItem*>> _itemRepaintRequest;
|
||||
rpl::event_stream<not_null<const HistoryItem*>> _itemRemoved;
|
||||
rpl::event_stream<not_null<const History*>> _historyUnloaded;
|
||||
rpl::event_stream<not_null<const History*>> _historyCleared;
|
||||
rpl::event_stream<MegagroupParticipant> _megagroupParticipantRemoved;
|
||||
rpl::event_stream<MegagroupParticipant> _megagroupParticipantAdded;
|
||||
|
||||
rpl::event_stream<> _stickersUpdated;
|
||||
rpl::event_stream<> _savedGifsUpdated;
|
||||
TimeMs _lastStickersUpdate = 0;
|
||||
TimeMs _lastRecentStickersUpdate = 0;
|
||||
TimeMs _lastFavedStickersUpdate = 0;
|
||||
TimeMs _lastFeaturedStickersUpdate = 0;
|
||||
TimeMs _lastSavedGifsUpdate = 0;
|
||||
rpl::variable<int> _featuredStickerSetsUnreadCount = 0;
|
||||
Stickers::Sets _stickerSets;
|
||||
Stickers::Order _stickerSetsOrder;
|
||||
Stickers::Order _featuredStickerSetsOrder;
|
||||
Stickers::Order _archivedStickerSetsOrder;
|
||||
Stickers::SavedGifs _savedGifs;
|
||||
|
||||
rpl::event_stream<bool> _thirdSectionInfoEnabledValue;
|
||||
bool _tabbedReplacedWithInfo = false;
|
||||
rpl::event_stream<bool> _tabbedReplacedWithInfoValue;
|
||||
@@ -347,7 +182,9 @@ private:
|
||||
class AuthSession;
|
||||
AuthSession &Auth();
|
||||
|
||||
class AuthSession final : private base::Subscriber {
|
||||
class AuthSession final
|
||||
: public base::has_weak_ptr
|
||||
, private base::Subscriber {
|
||||
public:
|
||||
AuthSession(UserId userId);
|
||||
|
||||
@@ -381,10 +218,13 @@ public:
|
||||
return *_notifications;
|
||||
}
|
||||
|
||||
AuthSessionData &data() {
|
||||
return _data;
|
||||
Data::Session &data() {
|
||||
return *_data;
|
||||
}
|
||||
void saveDataDelayed(TimeMs delay = kDefaultSaveDelay);
|
||||
AuthSessionSettings &settings() {
|
||||
return _settings;
|
||||
}
|
||||
void saveSettingsDelayed(TimeMs delay = kDefaultSaveDelay);
|
||||
|
||||
ApiWrap &api() {
|
||||
return *_api;
|
||||
@@ -406,7 +246,7 @@ private:
|
||||
static constexpr auto kDefaultSaveDelay = TimeMs(1000);
|
||||
|
||||
const UserId _userId = 0;
|
||||
AuthSessionData _data;
|
||||
AuthSessionSettings _settings;
|
||||
base::Timer _saveDataTimer;
|
||||
|
||||
TimeMs _shouldLockAt = 0;
|
||||
@@ -418,6 +258,13 @@ private:
|
||||
const std::unique_ptr<Storage::Uploader> _uploader;
|
||||
const std::unique_ptr<Storage::Facade> _storage;
|
||||
const std::unique_ptr<Window::Notifications::System> _notifications;
|
||||
|
||||
// _data depends on _downloader / _uploader, including destructor.
|
||||
const std::unique_ptr<Data::Session> _data;
|
||||
|
||||
// _changelogs depends on _data, subscribes on chats loading event.
|
||||
const std::unique_ptr<Core::Changelogs> _changelogs;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
||||
@@ -1,627 +0,0 @@
|
||||
/*
|
||||
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 "autoupdater.h"
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#ifdef Q_OS_WIN // use Lzma SDK for win
|
||||
#include <LzmaLib.h>
|
||||
#else // Q_OS_WIN
|
||||
#include <lzma.h>
|
||||
#endif // else of Q_OS_WIN
|
||||
|
||||
#include "application.h"
|
||||
#include "platform/platform_specific.h"
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
typedef DWORD VerInt;
|
||||
typedef WCHAR VerChar;
|
||||
#else // Q_OS_WIN
|
||||
typedef int VerInt;
|
||||
typedef wchar_t VerChar;
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
UpdateChecker::UpdateChecker(QThread *thread, const QString &url) : reply(0), already(0), full(0) {
|
||||
updateUrl = url;
|
||||
moveToThread(thread);
|
||||
manager.moveToThread(thread);
|
||||
App::setProxySettings(manager);
|
||||
|
||||
connect(thread, SIGNAL(started()), this, SLOT(start()));
|
||||
initOutput();
|
||||
}
|
||||
|
||||
void UpdateChecker::initOutput() {
|
||||
QString fileName;
|
||||
QRegularExpressionMatch m = QRegularExpression(qsl("/([^/\\?]+)(\\?|$)")).match(updateUrl);
|
||||
if (m.hasMatch()) {
|
||||
fileName = m.captured(1).replace(QRegularExpression(qsl("[^a-zA-Z0-9_\\-]")), QString());
|
||||
}
|
||||
if (fileName.isEmpty()) {
|
||||
fileName = qsl("tupdate-%1").arg(rand_value<uint32>() % 1000000);
|
||||
}
|
||||
QString dirStr = cWorkingDir() + qsl("tupdates/");
|
||||
fileName = dirStr + fileName;
|
||||
QFileInfo file(fileName);
|
||||
|
||||
QDir dir(dirStr);
|
||||
if (dir.exists()) {
|
||||
QFileInfoList all = dir.entryInfoList(QDir::Files);
|
||||
for (QFileInfoList::iterator i = all.begin(), e = all.end(); i != e; ++i) {
|
||||
if (i->absoluteFilePath() != file.absoluteFilePath()) {
|
||||
QFile::remove(i->absoluteFilePath());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dir.mkdir(dir.absolutePath());
|
||||
}
|
||||
outputFile.setFileName(fileName);
|
||||
if (file.exists()) {
|
||||
uint64 fullSize = file.size();
|
||||
if (fullSize < INT_MAX) {
|
||||
int32 goodSize = (int32)fullSize;
|
||||
if (goodSize % UpdateChunk) {
|
||||
goodSize = goodSize - (goodSize % UpdateChunk);
|
||||
if (goodSize) {
|
||||
if (outputFile.open(QIODevice::ReadOnly)) {
|
||||
QByteArray goodData = outputFile.readAll().mid(0, goodSize);
|
||||
outputFile.close();
|
||||
if (outputFile.open(QIODevice::WriteOnly)) {
|
||||
outputFile.write(goodData);
|
||||
outputFile.close();
|
||||
|
||||
QMutexLocker lock(&mutex);
|
||||
already = goodSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
QMutexLocker lock(&mutex);
|
||||
already = goodSize;
|
||||
}
|
||||
}
|
||||
if (!already) {
|
||||
QFile::remove(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateChecker::start() {
|
||||
sendRequest();
|
||||
}
|
||||
|
||||
void UpdateChecker::sendRequest() {
|
||||
QNetworkRequest req(updateUrl);
|
||||
QByteArray rangeHeaderValue = "bytes=" + QByteArray::number(already) + "-";
|
||||
req.setRawHeader("Range", rangeHeaderValue);
|
||||
req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
|
||||
if (reply) reply->deleteLater();
|
||||
reply = manager.get(req);
|
||||
connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(partFinished(qint64,qint64)));
|
||||
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(partFailed(QNetworkReply::NetworkError)));
|
||||
connect(reply, SIGNAL(metaDataChanged()), this, SLOT(partMetaGot()));
|
||||
}
|
||||
|
||||
void UpdateChecker::partMetaGot() {
|
||||
typedef QList<QNetworkReply::RawHeaderPair> Pairs;
|
||||
Pairs pairs = reply->rawHeaderPairs();
|
||||
for (Pairs::iterator i = pairs.begin(), e = pairs.end(); i != e; ++i) {
|
||||
if (QString::fromUtf8(i->first).toLower() == "content-range") {
|
||||
QRegularExpressionMatch m = QRegularExpression(qsl("/(\\d+)([^\\d]|$)")).match(QString::fromUtf8(i->second));
|
||||
if (m.hasMatch()) {
|
||||
{
|
||||
QMutexLocker lock(&mutex);
|
||||
full = m.captured(1).toInt();
|
||||
}
|
||||
|
||||
Sandbox::updateProgress(already, full);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32 UpdateChecker::ready() {
|
||||
QMutexLocker lock(&mutex);
|
||||
return already;
|
||||
}
|
||||
|
||||
int32 UpdateChecker::size() {
|
||||
QMutexLocker lock(&mutex);
|
||||
return full;
|
||||
}
|
||||
|
||||
void UpdateChecker::partFinished(qint64 got, qint64 total) {
|
||||
if (!reply) return;
|
||||
|
||||
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
||||
if (statusCode.isValid()) {
|
||||
int status = statusCode.toInt();
|
||||
if (status != 200 && status != 206 && status != 416) {
|
||||
LOG(("Update Error: Bad HTTP status received in partFinished(): %1").arg(status));
|
||||
return fatalFail();
|
||||
}
|
||||
}
|
||||
|
||||
if (!already && !full) {
|
||||
QMutexLocker lock(&mutex);
|
||||
full = total;
|
||||
}
|
||||
DEBUG_LOG(("Update Info: part %1 of %2").arg(got).arg(total));
|
||||
|
||||
if (!outputFile.isOpen()) {
|
||||
if (!outputFile.open(QIODevice::Append)) {
|
||||
LOG(("Update Error: Could not open output file '%1' for appending").arg(outputFile.fileName()));
|
||||
return fatalFail();
|
||||
}
|
||||
}
|
||||
QByteArray r = reply->readAll();
|
||||
if (!r.isEmpty()) {
|
||||
outputFile.write(r);
|
||||
|
||||
QMutexLocker lock(&mutex);
|
||||
already += r.size();
|
||||
}
|
||||
if (got >= total) {
|
||||
reply->deleteLater();
|
||||
reply = 0;
|
||||
outputFile.close();
|
||||
unpackUpdate();
|
||||
} else {
|
||||
Sandbox::updateProgress(already, full);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateChecker::partFailed(QNetworkReply::NetworkError e) {
|
||||
if (!reply) return;
|
||||
|
||||
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
||||
reply->deleteLater();
|
||||
reply = 0;
|
||||
if (statusCode.isValid()) {
|
||||
int status = statusCode.toInt();
|
||||
if (status == 416) { // Requested range not satisfiable
|
||||
outputFile.close();
|
||||
unpackUpdate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
LOG(("Update Error: failed to download part starting from %1, error %2").arg(already).arg(e));
|
||||
Sandbox::updateFailed();
|
||||
}
|
||||
|
||||
void UpdateChecker::fatalFail() {
|
||||
clearAll();
|
||||
Sandbox::updateFailed();
|
||||
}
|
||||
|
||||
void UpdateChecker::clearAll() {
|
||||
psDeleteDir(cWorkingDir() + qsl("tupdates"));
|
||||
}
|
||||
|
||||
//QString winapiErrorWrap() {
|
||||
// WCHAR errMsg[2048];
|
||||
// DWORD errorCode = GetLastError();
|
||||
// LPTSTR errorText = NULL, errorTextDefault = L"(Unknown error)";
|
||||
// FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errorText, 0, 0);
|
||||
// if (!errorText) {
|
||||
// errorText = errorTextDefault;
|
||||
// }
|
||||
// StringCbPrintf(errMsg, sizeof(errMsg), L"Error code: %d, error message: %s", errorCode, errorText);
|
||||
// if (errorText != errorTextDefault) {
|
||||
// LocalFree(errorText);
|
||||
// }
|
||||
// return QString::fromWCharArray(errMsg);
|
||||
//}
|
||||
|
||||
void UpdateChecker::unpackUpdate() {
|
||||
QByteArray packed;
|
||||
if (!outputFile.open(QIODevice::ReadOnly)) {
|
||||
LOG(("Update Error: cant read updates file!"));
|
||||
return fatalFail();
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN // use Lzma SDK for win
|
||||
const int32 hSigLen = 128, hShaLen = 20, hPropsLen = LZMA_PROPS_SIZE, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hPropsLen + hOriginalSizeLen; // header
|
||||
#else // Q_OS_WIN
|
||||
const int32 hSigLen = 128, hShaLen = 20, hPropsLen = 0, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hOriginalSizeLen; // header
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
QByteArray compressed = outputFile.readAll();
|
||||
int32 compressedLen = compressed.size() - hSize;
|
||||
if (compressedLen <= 0) {
|
||||
LOG(("Update Error: bad compressed size: %1").arg(compressed.size()));
|
||||
return fatalFail();
|
||||
}
|
||||
outputFile.close();
|
||||
|
||||
QString tempDirPath = cWorkingDir() + qsl("tupdates/temp"), readyFilePath = cWorkingDir() + qsl("tupdates/temp/ready");
|
||||
psDeleteDir(tempDirPath);
|
||||
|
||||
QDir tempDir(tempDirPath);
|
||||
if (tempDir.exists() || QFile(readyFilePath).exists()) {
|
||||
LOG(("Update Error: cant clear tupdates/temp dir!"));
|
||||
return fatalFail();
|
||||
}
|
||||
|
||||
uchar sha1Buffer[20];
|
||||
bool goodSha1 = !memcmp(compressed.constData() + hSigLen, hashSha1(compressed.constData() + hSigLen + hShaLen, compressedLen + hPropsLen + hOriginalSizeLen, sha1Buffer), hShaLen);
|
||||
if (!goodSha1) {
|
||||
LOG(("Update Error: bad SHA1 hash of update file!"));
|
||||
return fatalFail();
|
||||
}
|
||||
|
||||
RSA *pbKey = PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<char*>(AppAlphaVersion ? UpdatesPublicAlphaKey : UpdatesPublicKey), -1), 0, 0, 0);
|
||||
if (!pbKey) {
|
||||
LOG(("Update Error: cant read public rsa key!"));
|
||||
return fatalFail();
|
||||
}
|
||||
if (RSA_verify(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (const uchar*)(compressed.constData()), hSigLen, pbKey) != 1) { // verify signature
|
||||
RSA_free(pbKey);
|
||||
if (cAlphaVersion() || cBetaVersion()) { // try other public key, if we are in alpha or beta version
|
||||
pbKey = PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<char*>(AppAlphaVersion ? UpdatesPublicKey : UpdatesPublicAlphaKey), -1), 0, 0, 0);
|
||||
if (!pbKey) {
|
||||
LOG(("Update Error: cant read public rsa key!"));
|
||||
return fatalFail();
|
||||
}
|
||||
if (RSA_verify(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (const uchar*)(compressed.constData()), hSigLen, pbKey) != 1) { // verify signature
|
||||
RSA_free(pbKey);
|
||||
LOG(("Update Error: bad RSA signature of update file!"));
|
||||
return fatalFail();
|
||||
}
|
||||
} else {
|
||||
LOG(("Update Error: bad RSA signature of update file!"));
|
||||
return fatalFail();
|
||||
}
|
||||
}
|
||||
RSA_free(pbKey);
|
||||
|
||||
QByteArray uncompressed;
|
||||
|
||||
int32 uncompressedLen;
|
||||
memcpy(&uncompressedLen, compressed.constData() + hSigLen + hShaLen + hPropsLen, hOriginalSizeLen);
|
||||
uncompressed.resize(uncompressedLen);
|
||||
|
||||
size_t resultLen = uncompressed.size();
|
||||
#ifdef Q_OS_WIN // use Lzma SDK for win
|
||||
SizeT srcLen = compressedLen;
|
||||
int uncompressRes = LzmaUncompress((uchar*)uncompressed.data(), &resultLen, (const uchar*)(compressed.constData() + hSize), &srcLen, (const uchar*)(compressed.constData() + hSigLen + hShaLen), LZMA_PROPS_SIZE);
|
||||
if (uncompressRes != SZ_OK) {
|
||||
LOG(("Update Error: could not uncompress lzma, code: %1").arg(uncompressRes));
|
||||
return fatalFail();
|
||||
}
|
||||
#else // Q_OS_WIN
|
||||
lzma_stream stream = LZMA_STREAM_INIT;
|
||||
|
||||
lzma_ret ret = lzma_stream_decoder(&stream, UINT64_MAX, LZMA_CONCATENATED);
|
||||
if (ret != LZMA_OK) {
|
||||
const char *msg;
|
||||
switch (ret) {
|
||||
case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
|
||||
case LZMA_OPTIONS_ERROR: msg = "Specified preset is not supported"; break;
|
||||
case LZMA_UNSUPPORTED_CHECK: msg = "Specified integrity check is not supported"; break;
|
||||
default: msg = "Unknown error, possibly a bug"; break;
|
||||
}
|
||||
LOG(("Error initializing the decoder: %1 (error code %2)").arg(msg).arg(ret));
|
||||
return fatalFail();
|
||||
}
|
||||
|
||||
stream.avail_in = compressedLen;
|
||||
stream.next_in = (uint8_t*)(compressed.constData() + hSize);
|
||||
stream.avail_out = resultLen;
|
||||
stream.next_out = (uint8_t*)uncompressed.data();
|
||||
|
||||
lzma_ret res = lzma_code(&stream, LZMA_FINISH);
|
||||
if (stream.avail_in) {
|
||||
LOG(("Error in decompression, %1 bytes left in _in of %2 whole.").arg(stream.avail_in).arg(compressedLen));
|
||||
return fatalFail();
|
||||
} else if (stream.avail_out) {
|
||||
LOG(("Error in decompression, %1 bytes free left in _out of %2 whole.").arg(stream.avail_out).arg(resultLen));
|
||||
return fatalFail();
|
||||
}
|
||||
lzma_end(&stream);
|
||||
if (res != LZMA_OK && res != LZMA_STREAM_END) {
|
||||
const char *msg;
|
||||
switch (res) {
|
||||
case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
|
||||
case LZMA_FORMAT_ERROR: msg = "The input data is not in the .xz format"; break;
|
||||
case LZMA_OPTIONS_ERROR: msg = "Unsupported compression options"; break;
|
||||
case LZMA_DATA_ERROR: msg = "Compressed file is corrupt"; break;
|
||||
case LZMA_BUF_ERROR: msg = "Compressed data is truncated or otherwise corrupt"; break;
|
||||
default: msg = "Unknown error, possibly a bug"; break;
|
||||
}
|
||||
LOG(("Error in decompression: %1 (error code %2)").arg(msg).arg(res));
|
||||
return fatalFail();
|
||||
}
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
tempDir.mkdir(tempDir.absolutePath());
|
||||
|
||||
quint32 version;
|
||||
{
|
||||
QDataStream stream(uncompressed);
|
||||
stream.setVersion(QDataStream::Qt_5_1);
|
||||
|
||||
stream >> version;
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
LOG(("Update Error: cant read version from downloaded stream, status: %1").arg(stream.status()));
|
||||
return fatalFail();
|
||||
}
|
||||
|
||||
quint64 betaVersion = 0;
|
||||
if (version == 0x7FFFFFFF) { // beta version
|
||||
stream >> betaVersion;
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
LOG(("Update Error: cant read beta version from downloaded stream, status: %1").arg(stream.status()));
|
||||
return fatalFail();
|
||||
}
|
||||
if (!cBetaVersion() || betaVersion <= cBetaVersion()) {
|
||||
LOG(("Update Error: downloaded beta version %1 is not greater, than mine %2").arg(betaVersion).arg(cBetaVersion()));
|
||||
return fatalFail();
|
||||
}
|
||||
} else if (int32(version) <= AppVersion) {
|
||||
LOG(("Update Error: downloaded version %1 is not greater, than mine %2").arg(version).arg(AppVersion));
|
||||
return fatalFail();
|
||||
}
|
||||
|
||||
quint32 filesCount;
|
||||
stream >> filesCount;
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
LOG(("Update Error: cant read files count from downloaded stream, status: %1").arg(stream.status()));
|
||||
return fatalFail();
|
||||
}
|
||||
if (!filesCount) {
|
||||
LOG(("Update Error: update is empty!"));
|
||||
return fatalFail();
|
||||
}
|
||||
for (uint32 i = 0; i < filesCount; ++i) {
|
||||
QString relativeName;
|
||||
quint32 fileSize;
|
||||
QByteArray fileInnerData;
|
||||
bool executable = false;
|
||||
|
||||
stream >> relativeName >> fileSize >> fileInnerData;
|
||||
#if defined Q_OS_MAC || defined Q_OS_LINUX
|
||||
stream >> executable;
|
||||
#endif // Q_OS_MAC || Q_OS_LINUX
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
LOG(("Update Error: cant read file from downloaded stream, status: %1").arg(stream.status()));
|
||||
return fatalFail();
|
||||
}
|
||||
if (fileSize != quint32(fileInnerData.size())) {
|
||||
LOG(("Update Error: bad file size %1 not matching data size %2").arg(fileSize).arg(fileInnerData.size()));
|
||||
return fatalFail();
|
||||
}
|
||||
|
||||
QFile f(tempDirPath + '/' + relativeName);
|
||||
if (!QDir().mkpath(QFileInfo(f).absolutePath())) {
|
||||
LOG(("Update Error: cant mkpath for file '%1'").arg(tempDirPath + '/' + relativeName));
|
||||
return fatalFail();
|
||||
}
|
||||
if (!f.open(QIODevice::WriteOnly)) {
|
||||
LOG(("Update Error: cant open file '%1' for writing").arg(tempDirPath + '/' + relativeName));
|
||||
return fatalFail();
|
||||
}
|
||||
auto writtenBytes = f.write(fileInnerData);
|
||||
if (writtenBytes != fileSize) {
|
||||
f.close();
|
||||
LOG(("Update Error: cant write file '%1', desiredSize: %2, write result: %3").arg(tempDirPath + '/' + relativeName).arg(fileSize).arg(writtenBytes));
|
||||
return fatalFail();
|
||||
}
|
||||
f.close();
|
||||
if (executable) {
|
||||
QFileDevice::Permissions p = f.permissions();
|
||||
p |= QFileDevice::ExeOwner | QFileDevice::ExeUser | QFileDevice::ExeGroup | QFileDevice::ExeOther;
|
||||
f.setPermissions(p);
|
||||
}
|
||||
}
|
||||
|
||||
// create tdata/version file
|
||||
tempDir.mkdir(QDir(tempDirPath + qsl("/tdata")).absolutePath());
|
||||
std::wstring versionString = ((version % 1000) ? QString("%1.%2.%3").arg(int(version / 1000000)).arg(int((version % 1000000) / 1000)).arg(int(version % 1000)) : QString("%1.%2").arg(int(version / 1000000)).arg(int((version % 1000000) / 1000))).toStdWString();
|
||||
|
||||
VerInt versionNum = VerInt(version), versionLen = VerInt(versionString.size() * sizeof(VerChar));
|
||||
VerChar versionStr[32];
|
||||
memcpy(versionStr, versionString.c_str(), versionLen);
|
||||
|
||||
QFile fVersion(tempDirPath + qsl("/tdata/version"));
|
||||
if (!fVersion.open(QIODevice::WriteOnly)) {
|
||||
LOG(("Update Error: cant write version file '%1'").arg(tempDirPath + qsl("/version")));
|
||||
return fatalFail();
|
||||
}
|
||||
fVersion.write((const char*)&versionNum, sizeof(VerInt));
|
||||
if (versionNum == 0x7FFFFFFF) { // beta version
|
||||
fVersion.write((const char*)&betaVersion, sizeof(quint64));
|
||||
} else {
|
||||
fVersion.write((const char*)&versionLen, sizeof(VerInt));
|
||||
fVersion.write((const char*)&versionStr[0], versionLen);
|
||||
}
|
||||
fVersion.close();
|
||||
}
|
||||
|
||||
QFile readyFile(readyFilePath);
|
||||
if (readyFile.open(QIODevice::WriteOnly)) {
|
||||
if (readyFile.write("1", 1)) {
|
||||
readyFile.close();
|
||||
} else {
|
||||
LOG(("Update Error: cant write ready file '%1'").arg(readyFilePath));
|
||||
return fatalFail();
|
||||
}
|
||||
} else {
|
||||
LOG(("Update Error: cant create ready file '%1'").arg(readyFilePath));
|
||||
return fatalFail();
|
||||
}
|
||||
outputFile.remove();
|
||||
|
||||
Sandbox::updateReady();
|
||||
}
|
||||
|
||||
UpdateChecker::~UpdateChecker() {
|
||||
delete reply;
|
||||
reply = 0;
|
||||
}
|
||||
|
||||
bool checkReadyUpdate() {
|
||||
QString readyFilePath = cWorkingDir() + qsl("tupdates/temp/ready"), readyPath = cWorkingDir() + qsl("tupdates/temp");
|
||||
if (!QFile(readyFilePath).exists() || cExeName().isEmpty()) {
|
||||
if (QDir(cWorkingDir() + qsl("tupdates/ready")).exists() || QDir(cWorkingDir() + qsl("tupdates/temp")).exists()) {
|
||||
UpdateChecker::clearAll();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// check ready version
|
||||
QString versionPath = readyPath + qsl("/tdata/version");
|
||||
{
|
||||
QFile fVersion(versionPath);
|
||||
if (!fVersion.open(QIODevice::ReadOnly)) {
|
||||
LOG(("Update Error: cant read version file '%1'").arg(versionPath));
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
VerInt versionNum;
|
||||
if (fVersion.read((char*)&versionNum, sizeof(VerInt)) != sizeof(VerInt)) {
|
||||
LOG(("Update Error: cant read version from file '%1'").arg(versionPath));
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
if (versionNum == 0x7FFFFFFF) { // beta version
|
||||
quint64 betaVersion = 0;
|
||||
if (fVersion.read((char*)&betaVersion, sizeof(quint64)) != sizeof(quint64)) {
|
||||
LOG(("Update Error: cant read beta version from file '%1'").arg(versionPath));
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
if (!cBetaVersion() || betaVersion <= cBetaVersion()) {
|
||||
LOG(("Update Error: cant install beta version %1 having beta version %2").arg(betaVersion).arg(cBetaVersion()));
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
} else if (versionNum <= AppVersion) {
|
||||
LOG(("Update Error: cant install version %1 having version %2").arg(versionNum).arg(AppVersion));
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
fVersion.close();
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
QString curUpdater = (cExeDir() + qsl("Updater.exe"));
|
||||
QFileInfo updater(cWorkingDir() + qsl("tupdates/temp/Updater.exe"));
|
||||
#elif defined Q_OS_MAC // Q_OS_WIN
|
||||
QString curUpdater = (cExeDir() + cExeName() + qsl("/Contents/Frameworks/Updater"));
|
||||
QFileInfo updater(cWorkingDir() + qsl("tupdates/temp/Telegram.app/Contents/Frameworks/Updater"));
|
||||
#elif defined Q_OS_LINUX // Q_OS_MAC
|
||||
QString curUpdater = (cExeDir() + qsl("Updater"));
|
||||
QFileInfo updater(cWorkingDir() + qsl("tupdates/temp/Updater"));
|
||||
#endif // Q_OS_LINUX
|
||||
if (!updater.exists()) {
|
||||
QFileInfo current(curUpdater);
|
||||
if (!current.exists()) {
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
if (!QFile(current.absoluteFilePath()).copy(updater.absoluteFilePath())) {
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#ifdef Q_OS_WIN
|
||||
if (CopyFile(updater.absoluteFilePath().toStdWString().c_str(), curUpdater.toStdWString().c_str(), FALSE) == FALSE) {
|
||||
DWORD errorCode = GetLastError();
|
||||
if (errorCode == ERROR_ACCESS_DENIED) { // we are in write-protected dir, like Program Files
|
||||
cSetWriteProtected(true);
|
||||
return true;
|
||||
} else {
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (DeleteFile(updater.absoluteFilePath().toStdWString().c_str()) == FALSE) {
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
#elif defined Q_OS_MAC // Q_OS_WIN
|
||||
QDir().mkpath(QFileInfo(curUpdater).absolutePath());
|
||||
DEBUG_LOG(("Update Info: moving %1 to %2...").arg(updater.absoluteFilePath()).arg(curUpdater));
|
||||
if (!objc_moveFile(updater.absoluteFilePath(), curUpdater)) {
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
#elif defined Q_OS_LINUX // Q_OS_MAC
|
||||
if (!linuxMoveFile(QFile::encodeName(updater.absoluteFilePath()).constData(), QFile::encodeName(curUpdater).constData())) {
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
#endif // Q_OS_LINUX
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
QString countBetaVersionSignature(uint64 version) { // duplicated in packer.cpp
|
||||
if (cBetaPrivateKey().isEmpty()) {
|
||||
LOG(("Error: Trying to count beta version signature without beta private key!"));
|
||||
return QString();
|
||||
}
|
||||
|
||||
QByteArray signedData = (qstr("TelegramBeta_") + QString::number(version, 16).toLower()).toUtf8();
|
||||
|
||||
static const int32 shaSize = 20, keySize = 128;
|
||||
|
||||
uchar sha1Buffer[shaSize];
|
||||
hashSha1(signedData.constData(), signedData.size(), sha1Buffer); // count sha1
|
||||
|
||||
uint32 siglen = 0;
|
||||
|
||||
RSA *prKey = PEM_read_bio_RSAPrivateKey(BIO_new_mem_buf(const_cast<char*>(cBetaPrivateKey().constData()), -1), 0, 0, 0);
|
||||
if (!prKey) {
|
||||
LOG(("Error: Could not read beta private key!"));
|
||||
return QString();
|
||||
}
|
||||
if (RSA_size(prKey) != keySize) {
|
||||
LOG(("Error: Bad beta private key size: %1").arg(RSA_size(prKey)));
|
||||
RSA_free(prKey);
|
||||
return QString();
|
||||
}
|
||||
QByteArray signature;
|
||||
signature.resize(keySize);
|
||||
if (RSA_sign(NID_sha1, (const uchar*)(sha1Buffer), shaSize, (uchar*)(signature.data()), &siglen, prKey) != 1) { // count signature
|
||||
LOG(("Error: Counting beta version signature failed!"));
|
||||
RSA_free(prKey);
|
||||
return QString();
|
||||
}
|
||||
RSA_free(prKey);
|
||||
|
||||
if (siglen != keySize) {
|
||||
LOG(("Error: Bad beta version signature length: %1").arg(siglen));
|
||||
return QString();
|
||||
}
|
||||
|
||||
signature = signature.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||
signature = signature.replace('-', '8').replace('_', 'B');
|
||||
return QString::fromUtf8(signature.mid(19, 32));
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
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
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
#include <QtNetwork/QLocalServer>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
|
||||
class UpdateChecker : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
UpdateChecker(QThread *thread, const QString &url);
|
||||
|
||||
void unpackUpdate();
|
||||
|
||||
int32 ready();
|
||||
int32 size();
|
||||
|
||||
static void clearAll();
|
||||
|
||||
~UpdateChecker();
|
||||
|
||||
public slots:
|
||||
|
||||
void start();
|
||||
void partMetaGot();
|
||||
void partFinished(qint64 got, qint64 total);
|
||||
void partFailed(QNetworkReply::NetworkError e);
|
||||
void sendRequest();
|
||||
|
||||
private:
|
||||
void initOutput();
|
||||
|
||||
void fatalFail();
|
||||
|
||||
QString updateUrl;
|
||||
QNetworkAccessManager manager;
|
||||
QNetworkReply *reply;
|
||||
int32 already, full;
|
||||
QFile outputFile;
|
||||
|
||||
QMutex mutex;
|
||||
|
||||
};
|
||||
|
||||
bool checkReadyUpdate();
|
||||
|
||||
#else // TDESKTOP_DISABLE_AUTOUPDATE
|
||||
class UpdateChecker : public QObject {
|
||||
Q_OBJECT
|
||||
};
|
||||
|
||||
#endif // TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
QString countBetaVersionSignature(uint64 version);
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "catch.hpp"
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@@ -60,6 +47,10 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#define ARCH_CPU_X86_FAMILY 1
|
||||
#define ARCH_CPU_X86 1
|
||||
#define ARCH_CPU_32_BITS 1
|
||||
#elif defined(__aarch64__)
|
||||
#define ARCH_CPU_64_BITS 1
|
||||
#elif defined(_M_ARM) || defined(__arm__)
|
||||
#define ARCH_CPU_32_BITS 1
|
||||
#else
|
||||
#error Please add support for your architecture in base/build_config.h
|
||||
#endif
|
||||
|
||||
137
Telegram/SourceFiles/base/bytes.h
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <gsl/gsl_byte>
|
||||
|
||||
namespace bytes {
|
||||
|
||||
using span = gsl::span<gsl::byte>;
|
||||
using const_span = gsl::span<const gsl::byte>;
|
||||
using vector = std::vector<gsl::byte>;
|
||||
|
||||
template <
|
||||
typename Container,
|
||||
typename = std::enable_if_t<!std::is_const_v<Container>>>
|
||||
inline span make_span(Container &container) {
|
||||
return gsl::as_writeable_bytes(gsl::make_span(container));
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
inline const_span make_span(const Container &container) {
|
||||
return gsl::as_bytes(gsl::make_span(container));
|
||||
}
|
||||
|
||||
template <typename Type, std::ptrdiff_t Extent>
|
||||
inline span make_span(gsl::span<Type, Extent> container) {
|
||||
return gsl::as_writeable_bytes(container);
|
||||
}
|
||||
|
||||
template <typename Type, std::ptrdiff_t Extent>
|
||||
inline const_span make_span(gsl::span<const Type, Extent> container) {
|
||||
return gsl::as_bytes(container);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline span make_span(Type *value, std::size_t count) {
|
||||
return gsl::as_writeable_bytes(gsl::make_span(value, count));
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline const_span make_span(const Type *value, std::size_t count) {
|
||||
return gsl::as_bytes(gsl::make_span(value, count));
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
inline vector make_vector(const Container &container) {
|
||||
const auto buffer = bytes::make_span(container);
|
||||
return { buffer.begin(), buffer.end() };
|
||||
}
|
||||
|
||||
inline void copy(span destination, const_span source) {
|
||||
Expects(destination.size() >= source.size());
|
||||
|
||||
memcpy(destination.data(), source.data(), source.size());
|
||||
}
|
||||
|
||||
inline void move(span destination, const_span source) {
|
||||
Expects(destination.size() >= source.size());
|
||||
|
||||
memmove(destination.data(), source.data(), source.size());
|
||||
}
|
||||
|
||||
inline void set_with_const(span destination, gsl::byte value) {
|
||||
memset(
|
||||
destination.data(),
|
||||
gsl::to_integer<unsigned char>(value),
|
||||
destination.size());
|
||||
}
|
||||
|
||||
inline int compare(const_span a, const_span b) {
|
||||
const auto aSize = a.size(), bSize = b.size();
|
||||
return (aSize > bSize)
|
||||
? 1
|
||||
: (aSize < bSize)
|
||||
? -1
|
||||
: memcmp(a.data(), b.data(), aSize);
|
||||
}
|
||||
|
||||
namespace details {
|
||||
|
||||
template <typename Arg>
|
||||
std::size_t spansLength(Arg &&arg) {
|
||||
return bytes::make_span(arg).size();
|
||||
}
|
||||
|
||||
template <typename Arg, typename ...Args>
|
||||
std::size_t spansLength(Arg &&arg, Args &&...args) {
|
||||
return bytes::make_span(arg).size() + spansLength(args...);
|
||||
}
|
||||
|
||||
template <typename Arg>
|
||||
void spansAppend(span destination, Arg &&arg) {
|
||||
bytes::copy(destination, bytes::make_span(arg));
|
||||
}
|
||||
|
||||
template <typename Arg, typename ...Args>
|
||||
void spansAppend(span destination, Arg &&arg, Args &&...args) {
|
||||
const auto data = bytes::make_span(arg);
|
||||
bytes::copy(destination, data);
|
||||
spansAppend(destination.subspan(data.size()), args...);
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
|
||||
template <
|
||||
typename ...Args,
|
||||
typename = std::enable_if_t<(sizeof...(Args) > 1)>>
|
||||
vector concatenate(Args &&...args) {
|
||||
const auto size = details::spansLength(args...);
|
||||
auto result = vector(size);
|
||||
details::spansAppend(make_span(result), args...);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <
|
||||
typename SpanRange>
|
||||
vector concatenate(SpanRange args) {
|
||||
auto size = std::size_t(0);
|
||||
for (const auto &arg : args) {
|
||||
size += bytes::make_span(arg).size();
|
||||
}
|
||||
auto result = vector(size);
|
||||
auto buffer = make_span(result);
|
||||
for (const auto &arg : args) {
|
||||
const auto part = bytes::make_span(arg);
|
||||
bytes::copy(buffer, part);
|
||||
buffer = buffer.subspan(part.size());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace bytes
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "catch.hpp"
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "catch.hpp"
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "catch.hpp"
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "base/observer.h"
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,28 +1,16 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "base/bytes.h"
|
||||
|
||||
namespace openssl {
|
||||
|
||||
@@ -236,3 +224,13 @@ inline int FillRandom(base::byte_span bytes) {
|
||||
}
|
||||
|
||||
} // namespace openssl
|
||||
|
||||
namespace bytes {
|
||||
|
||||
inline void set_random(span destination) {
|
||||
RAND_bytes(
|
||||
reinterpret_cast<unsigned char*>(destination.data()),
|
||||
destination.size());
|
||||
}
|
||||
|
||||
} // namespace bytes
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "base/parse_helper.h"
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "base/qthelp_url.h"
|
||||
|
||||
@@ -51,4 +38,10 @@ QMap<QString, QString> url_parse_params(
|
||||
return result;
|
||||
}
|
||||
|
||||
bool is_ipv6(const QString &ip) {
|
||||
//static const auto regexp = QRegularExpression("^[a-fA-F0-9:]+$");
|
||||
//return regexp.match(ip).hasMatch();
|
||||
return ip.indexOf(':') >= 0;
|
||||
}
|
||||
|
||||
} // namespace qthelp
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@@ -37,4 +24,6 @@ enum class UrlParamNameTransform {
|
||||
// Parses a string like "p1=v1&p2=v2&..&pn=vn" to a map.
|
||||
QMap<QString, QString> url_parse_params(const QString ¶ms, UrlParamNameTransform transform = UrlParamNameTransform::NoTransform);
|
||||
|
||||
bool is_ipv6(const QString &ip);
|
||||
|
||||
} // namespace qthelp
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "base/runtime_composer.h"
|
||||
|
||||
@@ -44,7 +31,7 @@ const RuntimeComposerMetadata *GetRuntimeComposerMetadata(uint64 mask) {
|
||||
return i.value();
|
||||
}
|
||||
|
||||
const RuntimeComposerMetadata *RuntimeComposer::ZeroRuntimeComposerMetadata = GetRuntimeComposerMetadata(0);
|
||||
const RuntimeComposerMetadata *RuntimeComposerBase::ZeroRuntimeComposerMetadata = GetRuntimeComposerMetadata(0);
|
||||
|
||||
RuntimeComponentWrapStruct RuntimeComponentWraps[64];
|
||||
|
||||
|
||||
@@ -1,27 +1,17 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
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
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
template <typename Base>
|
||||
class RuntimeComposer;
|
||||
typedef void(*RuntimeComponentConstruct)(void *location, RuntimeComposer *composer);
|
||||
|
||||
class RuntimeComposerBase;
|
||||
typedef void(*RuntimeComponentConstruct)(void *location, RuntimeComposerBase *composer);
|
||||
typedef void(*RuntimeComponentDestruct)(void *location);
|
||||
typedef void(*RuntimeComponentMove)(void *location, void *waslocation);
|
||||
|
||||
@@ -51,8 +41,10 @@ struct CeilDivideMinimumOne {
|
||||
extern RuntimeComponentWrapStruct RuntimeComponentWraps[64];
|
||||
extern QAtomicInt RuntimeComponentIndexLast;
|
||||
|
||||
template <typename Type>
|
||||
template <typename Type, typename Base>
|
||||
struct RuntimeComponent {
|
||||
using RuntimeComponentBase = Base;
|
||||
|
||||
RuntimeComponent() {
|
||||
// While there is no std::aligned_alloc().
|
||||
static_assert(alignof(Type) <= alignof(std::max_align_t), "Components should align to std::max_align_t!");
|
||||
@@ -89,7 +81,7 @@ struct RuntimeComponent {
|
||||
}
|
||||
|
||||
protected:
|
||||
static void RuntimeComponentConstruct(void *location, RuntimeComposer *composer) {
|
||||
static void RuntimeComponentConstruct(void *location, RuntimeComposerBase *composer) {
|
||||
new (location) Type();
|
||||
}
|
||||
static void RuntimeComponentDestruct(void *location) {
|
||||
@@ -147,9 +139,9 @@ private:
|
||||
|
||||
const RuntimeComposerMetadata *GetRuntimeComposerMetadata(uint64 mask);
|
||||
|
||||
class RuntimeComposer {
|
||||
class RuntimeComposerBase {
|
||||
public:
|
||||
RuntimeComposer(uint64 mask = 0) : _data(zerodata()) {
|
||||
RuntimeComposerBase(uint64 mask = 0) : _data(zerodata()) {
|
||||
if (mask) {
|
||||
auto meta = GetRuntimeComposerMetadata(mask);
|
||||
|
||||
@@ -182,9 +174,9 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
RuntimeComposer(const RuntimeComposer &other) = delete;
|
||||
RuntimeComposer &operator=(const RuntimeComposer &other) = delete;
|
||||
~RuntimeComposer() {
|
||||
RuntimeComposerBase(const RuntimeComposerBase &other) = delete;
|
||||
RuntimeComposerBase &operator=(const RuntimeComposerBase &other) = delete;
|
||||
~RuntimeComposerBase() {
|
||||
if (_data != zerodata()) {
|
||||
auto meta = _meta();
|
||||
for (int i = 0; i < meta->last; ++i) {
|
||||
@@ -197,45 +189,40 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
bool Has() const {
|
||||
return (_meta()->offsets[Type::Index()] >= sizeof(_meta()));
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
Type *Get() {
|
||||
return static_cast<Type*>(_dataptr(_meta()->offsets[Type::Index()]));
|
||||
}
|
||||
template <typename Type>
|
||||
const Type *Get() const {
|
||||
return static_cast<const Type*>(_dataptr(_meta()->offsets[Type::Index()]));
|
||||
}
|
||||
|
||||
protected:
|
||||
void UpdateComponents(uint64 mask = 0) {
|
||||
if (!_meta()->equals(mask)) {
|
||||
RuntimeComposer tmp(mask);
|
||||
tmp.swap(*this);
|
||||
if (_data != zerodata() && tmp._data != zerodata()) {
|
||||
auto meta = _meta(), wasmeta = tmp._meta();
|
||||
for (int i = 0; i < meta->last; ++i) {
|
||||
auto offset = meta->offsets[i];
|
||||
auto wasoffset = wasmeta->offsets[i];
|
||||
if (offset >= sizeof(_meta()) && wasoffset >= sizeof(_meta())) {
|
||||
RuntimeComponentWraps[i].Move(_dataptrunsafe(offset), tmp._dataptrunsafe(wasoffset));
|
||||
}
|
||||
bool UpdateComponents(uint64 mask = 0) {
|
||||
if (_meta()->equals(mask)) {
|
||||
return false;
|
||||
}
|
||||
RuntimeComposerBase result(mask);
|
||||
result.swap(*this);
|
||||
if (_data != zerodata() && result._data != zerodata()) {
|
||||
const auto meta = _meta();
|
||||
const auto wasmeta = result._meta();
|
||||
for (auto i = 0; i != meta->last; ++i) {
|
||||
const auto offset = meta->offsets[i];
|
||||
const auto wasoffset = wasmeta->offsets[i];
|
||||
if (offset >= sizeof(_meta())
|
||||
&& wasoffset >= sizeof(_meta())) {
|
||||
RuntimeComponentWraps[i].Move(
|
||||
_dataptrunsafe(offset),
|
||||
result._dataptrunsafe(wasoffset));
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void AddComponents(uint64 mask = 0) {
|
||||
UpdateComponents(_meta()->maskadd(mask));
|
||||
bool AddComponents(uint64 mask = 0) {
|
||||
return UpdateComponents(_meta()->maskadd(mask));
|
||||
}
|
||||
void RemoveComponents(uint64 mask = 0) {
|
||||
UpdateComponents(_meta()->maskremove(mask));
|
||||
bool RemoveComponents(uint64 mask = 0) {
|
||||
return UpdateComponents(_meta()->maskremove(mask));
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Base>
|
||||
friend class RuntimeComposer;
|
||||
|
||||
static const RuntimeComposerMetadata *ZeroRuntimeComposerMetadata;
|
||||
static void *zerodata() {
|
||||
return &ZeroRuntimeComposerMetadata;
|
||||
@@ -252,8 +239,41 @@ private:
|
||||
}
|
||||
void *_data = nullptr;
|
||||
|
||||
void swap(RuntimeComposer &other) {
|
||||
void swap(RuntimeComposerBase &other) {
|
||||
std::swap(_data, other._data);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Base>
|
||||
class RuntimeComposer : public RuntimeComposerBase {
|
||||
public:
|
||||
using RuntimeComposerBase::RuntimeComposerBase;
|
||||
|
||||
template <
|
||||
typename Type,
|
||||
typename = std::enable_if_t<std::is_same_v<
|
||||
typename Type::RuntimeComponentBase,
|
||||
Base>>>
|
||||
bool Has() const {
|
||||
return (_meta()->offsets[Type::Index()] >= sizeof(_meta()));
|
||||
}
|
||||
|
||||
template <
|
||||
typename Type,
|
||||
typename = std::enable_if_t<std::is_same_v<
|
||||
typename Type::RuntimeComponentBase,
|
||||
Base>>>
|
||||
Type *Get() {
|
||||
return static_cast<Type*>(_dataptr(_meta()->offsets[Type::Index()]));
|
||||
}
|
||||
template <
|
||||
typename Type,
|
||||
typename = std::enable_if_t<std::is_same_v<
|
||||
typename Type::RuntimeComponentBase,
|
||||
Base>>>
|
||||
const Type *Get() const {
|
||||
return static_cast<const Type*>(_dataptr(_meta()->offsets[Type::Index()]));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -1,393 +0,0 @@
|
||||
/*
|
||||
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 "base/task_queue.h"
|
||||
|
||||
#include <thread>
|
||||
#include <condition_variable>
|
||||
|
||||
namespace base {
|
||||
namespace {
|
||||
|
||||
auto MainThreadId = std::this_thread::get_id();
|
||||
const auto MaxThreadsCount = qMax(std::thread::hardware_concurrency(), 2U);
|
||||
|
||||
} // namespace
|
||||
|
||||
class TaskQueue::TaskQueueList {
|
||||
public:
|
||||
TaskQueueList();
|
||||
|
||||
void Register(TaskQueue *queue);
|
||||
void Unregister(TaskQueue *queue);
|
||||
bool IsInList(TaskQueue *queue) const;
|
||||
void Clear();
|
||||
bool Empty(int list_index_) const;
|
||||
TaskQueue *TakeFirst(int list_index_);
|
||||
|
||||
private:
|
||||
void Insert(TaskQueue *queue, int list_index_);
|
||||
void Remove(TaskQueue *queue, int list_index_);
|
||||
|
||||
TaskQueue *Tail() { return &tail_; }
|
||||
const TaskQueue *Tail() const { return &tail_; }
|
||||
|
||||
TaskQueue tail_ = { Type::Special, Priority::Normal };
|
||||
TaskQueue *(lists_[kQueuesListsCount]);
|
||||
|
||||
};
|
||||
|
||||
class TaskQueue::TaskThreadPool {
|
||||
struct Private {
|
||||
};
|
||||
|
||||
public:
|
||||
TaskThreadPool(const Private &) { }
|
||||
static const std::shared_ptr<TaskThreadPool> &Instance();
|
||||
|
||||
void AddQueueTask(TaskQueue *queue, Task &&task);
|
||||
void RemoveQueue(TaskQueue *queue);
|
||||
|
||||
~TaskThreadPool();
|
||||
|
||||
private:
|
||||
void ThreadFunction();
|
||||
|
||||
std::vector<std::thread> threads_;
|
||||
QMutex queues_mutex_;
|
||||
|
||||
// queues_mutex_ must be locked when working with the list.
|
||||
TaskQueueList queue_list_;
|
||||
|
||||
QWaitCondition thread_condition_;
|
||||
bool stopped_ = false;
|
||||
int tasks_in_process_ = 0;
|
||||
int background_tasks_in_process_ = 0;
|
||||
|
||||
};
|
||||
|
||||
TaskQueue::TaskQueueList::TaskQueueList() {
|
||||
for (auto &list : lists_) {
|
||||
list = &tail_;
|
||||
}
|
||||
}
|
||||
|
||||
void TaskQueue::TaskQueueList::Register(TaskQueue *queue) {
|
||||
Assert(!queue->SerialTaskInProcess());
|
||||
|
||||
Insert(queue, kAllQueuesList);
|
||||
if (queue->priority_ == Priority::Normal) {
|
||||
Insert(queue, kOnlyNormalQueuesList);
|
||||
}
|
||||
}
|
||||
|
||||
void TaskQueue::TaskQueueList::Unregister(TaskQueue *queue) {
|
||||
Remove(queue, kAllQueuesList);
|
||||
if (queue->priority_ == Priority::Normal) {
|
||||
Remove(queue, kOnlyNormalQueuesList);
|
||||
}
|
||||
}
|
||||
|
||||
void TaskQueue::TaskQueueList::Insert(TaskQueue *queue, int list_index_) {
|
||||
Assert(list_index_ < kQueuesListsCount);
|
||||
|
||||
auto tail = Tail();
|
||||
if (lists_[list_index_] == tail) {
|
||||
lists_[list_index_] = queue;
|
||||
}
|
||||
|
||||
auto &list_entry = queue->list_entries_[list_index_];
|
||||
Assert(list_entry.after == nullptr);
|
||||
if ((list_entry.before = tail->list_entries_[list_index_].before)) {
|
||||
list_entry.before->list_entries_[list_index_].after = queue;
|
||||
}
|
||||
list_entry.after = tail;
|
||||
tail->list_entries_[list_index_].before = queue;
|
||||
}
|
||||
|
||||
void TaskQueue::TaskQueueList::Remove(TaskQueue *queue, int list_index_) {
|
||||
Assert(list_index_ < kQueuesListsCount);
|
||||
|
||||
auto &list_entry = queue->list_entries_[list_index_];
|
||||
Assert(list_entry.after != nullptr);
|
||||
if (lists_[list_index_] == queue) {
|
||||
lists_[list_index_] = list_entry.after;
|
||||
} else {
|
||||
Assert(list_entry.before != nullptr);
|
||||
list_entry.before->list_entries_[list_index_].after = list_entry.after;
|
||||
}
|
||||
list_entry.after->list_entries_[list_index_].before = list_entry.before;
|
||||
list_entry.before = list_entry.after = nullptr;
|
||||
}
|
||||
|
||||
bool TaskQueue::TaskQueueList::IsInList(TaskQueue *queue) const {
|
||||
if (queue->list_entries_[kAllQueuesList].after) {
|
||||
return true;
|
||||
}
|
||||
Assert(queue->list_entries_[kOnlyNormalQueuesList].after == nullptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
void TaskQueue::TaskQueueList::Clear() {
|
||||
auto tail = Tail();
|
||||
for (int i = 0; i < kQueuesListsCount; ++i) {
|
||||
for (auto j = lists_[i], next = j; j != tail; j = next) {
|
||||
auto &list_entry = j->list_entries_[i];
|
||||
next = list_entry.after;
|
||||
list_entry.before = list_entry.after = nullptr;
|
||||
}
|
||||
lists_[i] = tail;
|
||||
}
|
||||
}
|
||||
|
||||
bool TaskQueue::TaskQueueList::Empty(int list_index_) const {
|
||||
Assert(list_index_ < kQueuesListsCount);
|
||||
|
||||
auto list = lists_[list_index_];
|
||||
Assert(list != nullptr);
|
||||
return (list->list_entries_[list_index_].after == nullptr);
|
||||
}
|
||||
|
||||
TaskQueue *TaskQueue::TaskQueueList::TakeFirst(int list_index_) {
|
||||
Assert(!Empty(list_index_));
|
||||
|
||||
auto queue = lists_[list_index_];
|
||||
Unregister(queue);
|
||||
// log_msgs.push_back("Unregistered from list in TakeFirst");
|
||||
return queue;
|
||||
}
|
||||
|
||||
void TaskQueue::TaskThreadPool::AddQueueTask(TaskQueue *queue, Task &&task) {
|
||||
QMutexLocker lock(&queues_mutex_);
|
||||
|
||||
queue->tasks_.push_back(std::move(task));
|
||||
auto list_was_empty = queue_list_.Empty(kAllQueuesList);
|
||||
auto threads_count = threads_.size();
|
||||
auto all_threads_processing = (threads_count == tasks_in_process_);
|
||||
auto some_threads_are_vacant = !all_threads_processing && list_was_empty;
|
||||
auto will_create_thread = !some_threads_are_vacant && (threads_count < MaxThreadsCount);
|
||||
|
||||
if (!queue->SerialTaskInProcess()) {
|
||||
if (!queue_list_.IsInList(queue)) {
|
||||
queue_list_.Register(queue);
|
||||
}
|
||||
}
|
||||
if (will_create_thread) {
|
||||
threads_.emplace_back([this]() {
|
||||
ThreadFunction();
|
||||
});
|
||||
} else if (some_threads_are_vacant) {
|
||||
Assert(threads_count > tasks_in_process_);
|
||||
thread_condition_.wakeOne();
|
||||
}
|
||||
}
|
||||
|
||||
void TaskQueue::TaskThreadPool::RemoveQueue(TaskQueue *queue) {
|
||||
QMutexLocker lock(&queues_mutex_);
|
||||
if (queue_list_.IsInList(queue)) {
|
||||
queue_list_.Unregister(queue);
|
||||
}
|
||||
if (queue->destroyed_flag_) {
|
||||
*queue->destroyed_flag_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
TaskQueue::TaskThreadPool::~TaskThreadPool() {
|
||||
{
|
||||
QMutexLocker lock(&queues_mutex_);
|
||||
queue_list_.Clear();
|
||||
stopped_ = true;
|
||||
}
|
||||
thread_condition_.wakeAll();
|
||||
for (auto &thread : threads_) {
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
const std::shared_ptr<TaskQueue::TaskThreadPool> &TaskQueue::TaskThreadPool::Instance() { // static
|
||||
static auto Pool = std::make_shared<TaskThreadPool>(Private());
|
||||
return Pool;
|
||||
}
|
||||
|
||||
void TaskQueue::TaskThreadPool::ThreadFunction() {
|
||||
// Flag marking that the previous processed task was
|
||||
// with a Background priority. We count all the background
|
||||
// tasks being processed.
|
||||
bool background_task = false;
|
||||
|
||||
// Saved serial queue pointer. When we process a serial
|
||||
// queue task we don't return the queue to the list until
|
||||
// the task is processed and we return it on the next cycle.
|
||||
TaskQueue *serial_queue = nullptr;
|
||||
bool serial_queue_destroyed = false;
|
||||
bool task_was_processed = false;
|
||||
while (true) {
|
||||
Task task;
|
||||
{
|
||||
QMutexLocker lock(&queues_mutex_);
|
||||
|
||||
// Finish the previous task processing.
|
||||
if (task_was_processed) {
|
||||
--tasks_in_process_;
|
||||
}
|
||||
if (background_task) {
|
||||
--background_tasks_in_process_;
|
||||
background_task = false;
|
||||
}
|
||||
if (serial_queue) {
|
||||
if (!serial_queue_destroyed) {
|
||||
serial_queue->destroyed_flag_ = nullptr;
|
||||
if (!serial_queue->tasks_.empty()) {
|
||||
queue_list_.Register(serial_queue);
|
||||
}
|
||||
}
|
||||
serial_queue = nullptr;
|
||||
serial_queue_destroyed = false;
|
||||
}
|
||||
|
||||
// Wait for a task to appear in the queues list.
|
||||
while (queue_list_.Empty(kAllQueuesList)) {
|
||||
if (stopped_) {
|
||||
return;
|
||||
}
|
||||
thread_condition_.wait(&queues_mutex_);
|
||||
}
|
||||
|
||||
// Select a task we will be processing.
|
||||
auto processing_background = (background_tasks_in_process_ > 0);
|
||||
auto take_only_normal = processing_background && !queue_list_.Empty(kOnlyNormalQueuesList);
|
||||
auto take_from_list_ = take_only_normal ? kOnlyNormalQueuesList : kAllQueuesList;
|
||||
auto queue = queue_list_.TakeFirst(take_from_list_);
|
||||
|
||||
Assert(!queue->tasks_.empty());
|
||||
|
||||
task = std::move(queue->tasks_.front());
|
||||
queue->tasks_.pop_front();
|
||||
|
||||
if (queue->type_ == Type::Serial) {
|
||||
// Serial queues are returned in the list for processing
|
||||
// only after the task is finished.
|
||||
serial_queue = queue;
|
||||
Assert(serial_queue->destroyed_flag_ == nullptr);
|
||||
serial_queue->destroyed_flag_ = &serial_queue_destroyed;
|
||||
} else if (!queue->tasks_.empty()) {
|
||||
queue_list_.Register(queue);
|
||||
}
|
||||
|
||||
++tasks_in_process_;
|
||||
task_was_processed = true;
|
||||
if (queue->priority_ == Priority::Background) {
|
||||
++background_tasks_in_process_;
|
||||
background_task = true;
|
||||
}
|
||||
}
|
||||
|
||||
task();
|
||||
}
|
||||
}
|
||||
|
||||
TaskQueue::TaskQueue(Type type, Priority priority)
|
||||
: type_(type)
|
||||
, priority_(priority) {
|
||||
if (type_ != Type::Main && type_ != Type::Special) {
|
||||
weak_thread_pool_ = TaskThreadPool::Instance();
|
||||
}
|
||||
}
|
||||
|
||||
TaskQueue::~TaskQueue() {
|
||||
if (type_ != Type::Main && type_ != Type::Special) {
|
||||
if (auto thread_pool = weak_thread_pool_.lock()) {
|
||||
thread_pool->RemoveQueue(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TaskQueue::Put(Task &&task) {
|
||||
if (type_ == Type::Main) {
|
||||
QMutexLocker lock(&tasks_mutex_);
|
||||
tasks_.push_back(std::move(task));
|
||||
|
||||
Sandbox::MainThreadTaskAdded();
|
||||
} else {
|
||||
Assert(type_ != Type::Special);
|
||||
TaskThreadPool::Instance()->AddQueueTask(this, std::move(task));
|
||||
}
|
||||
}
|
||||
|
||||
void TaskQueue::ProcessMainTasks() { // static
|
||||
Assert(std::this_thread::get_id() == MainThreadId);
|
||||
|
||||
while (ProcessOneMainTask()) {
|
||||
}
|
||||
}
|
||||
|
||||
void TaskQueue::ProcessMainTasks(TimeMs max_time_spent) { // static
|
||||
Assert(std::this_thread::get_id() == MainThreadId);
|
||||
|
||||
auto start_time = getms();
|
||||
while (ProcessOneMainTask()) {
|
||||
if (getms() >= start_time + max_time_spent) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TaskQueue::ProcessOneMainTask() { // static
|
||||
Task task;
|
||||
{
|
||||
QMutexLocker lock(&Main().tasks_mutex_);
|
||||
auto &tasks = Main().tasks_;
|
||||
if (tasks.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
task = std::move(tasks.front());
|
||||
tasks.pop_front();
|
||||
}
|
||||
|
||||
task();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TaskQueue::IsMyThread() const {
|
||||
if (type_ == Type::Main) {
|
||||
return (std::this_thread::get_id() == MainThreadId);
|
||||
}
|
||||
Assert(type_ != Type::Special);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Default queues.
|
||||
TaskQueue &TaskQueue::Main() { // static
|
||||
static TaskQueue MainQueue { Type::Main, Priority::Normal };
|
||||
return MainQueue;
|
||||
}
|
||||
|
||||
TaskQueue &TaskQueue::Normal() { // static
|
||||
static TaskQueue NormalQueue { Type::Concurrent, Priority::Normal };
|
||||
return NormalQueue;
|
||||
}
|
||||
|
||||
TaskQueue &TaskQueue::Background() { // static
|
||||
static TaskQueue BackgroundQueue { Type::Concurrent, Priority::Background };
|
||||
return BackgroundQueue;
|
||||
}
|
||||
|
||||
} // namespace base
|
||||