Merge remote-tracking branch 'td/master' into dev
This commit is contained in:
commit
2c77e82300
@ -13,6 +13,7 @@
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/crypto.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
#if TD_MSVC
|
||||
#pragma comment(linker, "/STACK:16777216")
|
||||
|
@ -8,10 +8,10 @@
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/crypto.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/port/thread.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/UInt.h"
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "td/utils/port/Stat.h"
|
||||
#include "td/utils/port/thread.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
#include "td/telegram/telegram_api.h"
|
||||
#include "td/telegram/telegram_api.hpp"
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "td/utils/filesystem.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/TsCerr.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "td/utils/port/thread.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/Time.h"
|
||||
|
||||
|
@ -101,7 +101,10 @@ static constexpr jint JAVA_VERSION = JNI_VERSION_1_6;
|
||||
static JavaVM *java_vm;
|
||||
static jclass log_class;
|
||||
|
||||
static void on_fatal_error(const char *error_message) {
|
||||
static void on_log_message(int verbosity_level, const char *error_message) {
|
||||
if (verbosity_level != 0) {
|
||||
return;
|
||||
}
|
||||
auto env = td::jni::get_jni_env(java_vm, JAVA_VERSION);
|
||||
if (env == nullptr) {
|
||||
return;
|
||||
@ -154,7 +157,7 @@ static jint register_native(JavaVM *vm) {
|
||||
td::jni::init_vars(env, PACKAGE_NAME);
|
||||
td::td_api::Object::init_jni_vars(env, PACKAGE_NAME);
|
||||
td::td_api::Function::init_jni_vars(env, PACKAGE_NAME);
|
||||
td::Log::set_fatal_error_callback(on_fatal_error);
|
||||
td::ClientManager::set_log_message_callback(0, on_log_message);
|
||||
|
||||
return JAVA_VERSION;
|
||||
}
|
||||
|
@ -34,16 +34,17 @@ _td_execute = tdjson.td_execute
|
||||
_td_execute.restype = c_char_p
|
||||
_td_execute.argtypes = [c_char_p]
|
||||
|
||||
fatal_error_callback_type = CFUNCTYPE(None, c_char_p)
|
||||
log_message_callback_type = CFUNCTYPE(None, c_int, c_char_p)
|
||||
|
||||
_td_set_log_fatal_error_callback = tdjson.td_set_log_fatal_error_callback
|
||||
_td_set_log_fatal_error_callback.restype = None
|
||||
_td_set_log_fatal_error_callback.argtypes = [fatal_error_callback_type]
|
||||
_td_set_log_message_callback = tdjson.td_set_log_message_callback
|
||||
_td_set_log_message_callback.restype = None
|
||||
_td_set_log_message_callback.argtypes = [c_int, log_message_callback_type]
|
||||
|
||||
# initialize TDLib log with desired parameters
|
||||
def on_fatal_error_callback(error_message):
|
||||
print('TDLib fatal error: ', error_message)
|
||||
sys.stdout.flush()
|
||||
def on_log_message_callback(verbosity_level, message):
|
||||
if verbosity_level == 0:
|
||||
print('TDLib fatal error: ', message)
|
||||
sys.stdout.flush()
|
||||
|
||||
def td_execute(query):
|
||||
query = json.dumps(query).encode('utf-8')
|
||||
@ -52,8 +53,8 @@ def td_execute(query):
|
||||
result = json.loads(result.decode('utf-8'))
|
||||
return result
|
||||
|
||||
c_on_fatal_error_callback = fatal_error_callback_type(on_fatal_error_callback)
|
||||
_td_set_log_fatal_error_callback(c_on_fatal_error_callback)
|
||||
c_on_log_message_callback = log_message_callback_type(on_log_message_callback)
|
||||
_td_set_log_message_callback(2, c_on_log_message_callback)
|
||||
|
||||
# setting TDLib log verbosity level to 1 (errors)
|
||||
print(str(td_execute({'@type': 'setLogVerbosityLevel', 'new_verbosity_level': 1, '@extra': 1.01234})).encode('utf-8'))
|
||||
|
@ -29,6 +29,7 @@ namespace TdApp
|
||||
|
||||
Td.Client.Execute(new TdApi.SetLogVerbosityLevel(0));
|
||||
Td.Client.Execute(new TdApi.SetLogStream(new TdApi.LogStreamFile(Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "log"), 1 << 27, false)));
|
||||
Td.Client.SetLogMessageCallback(100, LogMessageCallback);
|
||||
|
||||
System.Threading.Tasks.Task.Run(() =>
|
||||
{
|
||||
@ -63,6 +64,14 @@ namespace TdApp
|
||||
});
|
||||
}
|
||||
|
||||
private void LogMessageCallback(int verbosity_level, String str)
|
||||
{
|
||||
if (verbosity_level < 0) {
|
||||
return;
|
||||
}
|
||||
Print(verbosity_level + ": " + str);
|
||||
}
|
||||
|
||||
private Td.Client _client;
|
||||
|
||||
private void AcceptCommand(String command)
|
||||
@ -107,6 +116,12 @@ namespace TdApp
|
||||
AcceptCommand(command);
|
||||
_client.Send(new TdApi.CheckAuthenticationPassword(args[1]), _handler);
|
||||
}
|
||||
else if (command.StartsWith("alm"))
|
||||
{
|
||||
var args = command.Split(" ".ToCharArray(), 3);
|
||||
AcceptCommand(command);
|
||||
_client.Send(new TdApi.AddLogMessage(Int32.Parse(args[1]), args[2]), _handler);
|
||||
}
|
||||
else if (command.StartsWith("gco"))
|
||||
{
|
||||
var args = command.Split(" ".ToCharArray(), 2);
|
||||
|
@ -2,7 +2,8 @@ param (
|
||||
[string]$vcpkg_root = $(throw "-vcpkg_root=<path to vcpkg> is required"),
|
||||
[string]$arch = "",
|
||||
[string]$mode = "all",
|
||||
[string]$compress = "7z"
|
||||
[string]$compress = "7z",
|
||||
[switch]$release_only = $false
|
||||
)
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
@ -13,6 +14,11 @@ $arch_list = @( "x86", "x64", "ARM" )
|
||||
if ($arch) {
|
||||
$arch_list = @(, $arch)
|
||||
}
|
||||
$config_list = @( "Debug", "Release" )
|
||||
if ($release_only) {
|
||||
$config_list = @(, "RelWithDebInfo")
|
||||
}
|
||||
$targets = @{ Debug = "Debug"; Release = "Retail"; RelWithDebInfo = "CommonConfiguration"}
|
||||
|
||||
$td_root = Resolve-Path "../.."
|
||||
|
||||
@ -47,7 +53,7 @@ function config {
|
||||
New-Item -ItemType Directory -Force -Path build-uwp
|
||||
cd build-uwp
|
||||
|
||||
ForEach($arch in $arch_list) {
|
||||
ForEach ($arch in $arch_list) {
|
||||
echo "Config Arch = [$arch]"
|
||||
New-Item -ItemType Directory -Force -Path $arch
|
||||
cd $arch
|
||||
@ -66,11 +72,12 @@ function config {
|
||||
|
||||
function build {
|
||||
cd build-uwp
|
||||
ForEach($arch in $arch_list) {
|
||||
ForEach ($arch in $arch_list) {
|
||||
echo "Build Arch = [$arch]"
|
||||
cd $arch
|
||||
cmake --build . --config Release --target tddotnet
|
||||
cmake --build . --config Debug --target tddotnet
|
||||
ForEach ($config in $config_list) {
|
||||
cmake --build . --config $config --target tddotnet
|
||||
}
|
||||
cd ..
|
||||
}
|
||||
cd ..
|
||||
@ -85,23 +92,19 @@ function export {
|
||||
cp '../`[Content_Types`].xml' vsix
|
||||
cp ../LICENSE_1_0.txt vsix
|
||||
|
||||
ForEach($arch in $arch_list) {
|
||||
New-Item -ItemType Directory -Force -Path vsix/DesignTime/Debug/${arch}
|
||||
New-Item -ItemType Directory -Force -Path vsix/DesignTime/Retail/${arch}
|
||||
New-Item -ItemType Directory -Force -Path vsix/Redist/Debug/${arch}
|
||||
New-Item -ItemType Directory -Force -Path vsix/Redist/Retail/${arch}
|
||||
ForEach ($arch in $arch_list) {
|
||||
New-Item -ItemType Directory -Force -Path vsix/References/CommonConfiguration/${arch}
|
||||
ForEach ($config in $config_list) {
|
||||
$target = $targets[$config]
|
||||
|
||||
cp ${arch}/Debug/* -include "SSLEAY*","LIBEAY*","libcrypto*","libssl*","zlib*" vsix/Redist/Debug/${arch}/
|
||||
cp ${arch}/Release/* -include "SSLEAY*","LIBEAY*","libcrypto*","libssl*","zlib*" vsix/Redist/Retail/${arch}/
|
||||
New-Item -ItemType Directory -Force -Path vsix/DesignTime/${target}/${arch}
|
||||
cp ${arch}/${config}/Telegram.Td.lib vsix/DesignTime/${target}/${arch}/
|
||||
|
||||
cp ${arch}/Debug/* -filter "Telegram.Td.*" -include "*.lib" vsix/DesignTime/Debug/${arch}/
|
||||
cp ${arch}/Release/* -filter "Telegram.Td.*" -include "*.lib" vsix/DesignTime/Retail/${arch}/
|
||||
New-Item -ItemType Directory -Force -Path vsix/Redist/${target}/${arch}
|
||||
cp ${arch}/${config}/* -include "SSLEAY*","LIBEAY*","libcrypto*","libssl*","zlib*","Telegram.Td.pdb","Telegram.Td.dll" vsix/Redist/${target}/${arch}/
|
||||
|
||||
cp ${arch}/Debug/* -filter "Telegram.Td.*" -include "*.pdb","*.dll" vsix/Redist/Debug/${arch}/
|
||||
cp ${arch}/Release/* -filter "Telegram.Td.*" -include "*.pdb","*.dll" vsix/Redist/Retail/${arch}/
|
||||
|
||||
cp ${arch}/Release/* -filter "Telegram.Td.*" -include "*.pri","*.winmd","*.xml" vsix/References/CommonConfiguration/${arch}/
|
||||
cp ${arch}/${config}/* -include "Telegram.Td.pri","Telegram.Td.winmd","Telegram.Td.xml" vsix/References/CommonConfiguration/${arch}/
|
||||
}
|
||||
}
|
||||
|
||||
cd vsix
|
||||
|
@ -1,3 +1,3 @@
|
||||
./src.ps1 | Select-String -NotMatch "CxCli.h" | Select-String -NotMatch "dotnet" | ForEach-Object {
|
||||
./src.ps1 | Select-String -NotMatch "CxCli.h" | Select-String -NotMatch "DotNet" | ForEach-Object {
|
||||
clang-format -verbose -style=file -i $_
|
||||
}
|
||||
|
@ -11,8 +11,8 @@
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/filesystem.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
|
||||
#include <utility>
|
||||
|
@ -23,6 +23,7 @@ std::string TD_TL_writer_cpp::gen_output_begin() const {
|
||||
"#include \"td/utils/common.h\"\n"
|
||||
"#include \"td/utils/format.h\"\n"
|
||||
"#include \"td/utils/logging.h\"\n"
|
||||
"#include \"td/utils/SliceBuilder.h\"\n"
|
||||
"#include \"td/utils/tl_parsers.h\"\n"
|
||||
"#include \"td/utils/tl_storers.h\"\n\n"
|
||||
"namespace td {\n"
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Time.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/Time.h"
|
||||
#include "td/utils/tl_parsers.h"
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "td/mtproto/HandshakeConnection.h"
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
// TODO: do I need \r\n as delimiter?
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "td/actor/actor.h"
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "td/utils/MpscPollableQueue.h"
|
||||
#include "td/utils/port/EventFd.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/StorerBase.h"
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/ScopeGuard.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Time.h"
|
||||
#include "td/utils/tl_parsers.h"
|
||||
|
||||
|
@ -12,8 +12,8 @@
|
||||
#include "td/utils/BigNum.h"
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/crypto.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Span.h"
|
||||
#include "td/utils/Time.h"
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
#include <array>
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "td/telegram/Version.h"
|
||||
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
@ -19,15 +20,33 @@ static string get_color_hex_string(int32 color) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static BackgroundFill get_background_fill(const td_api::BackgroundFill *fill) {
|
||||
CHECK(fill != nullptr);
|
||||
static bool is_valid_color(int32 color) {
|
||||
return 0 <= color && color <= 0xFFFFFF;
|
||||
}
|
||||
|
||||
static Result<BackgroundFill> get_background_fill(const td_api::BackgroundFill *fill) {
|
||||
if (fill == nullptr) {
|
||||
return Status::Error(400, "Background fill info must be non-empty");
|
||||
}
|
||||
switch (fill->get_id()) {
|
||||
case td_api::backgroundFillSolid::ID: {
|
||||
auto solid = static_cast<const td_api::backgroundFillSolid *>(fill);
|
||||
if (!is_valid_color(solid->color_)) {
|
||||
return Status::Error(400, "Invalid solid fill color value");
|
||||
}
|
||||
return BackgroundFill(solid->color_);
|
||||
}
|
||||
case td_api::backgroundFillGradient::ID: {
|
||||
auto gradient = static_cast<const td_api::backgroundFillGradient *>(fill);
|
||||
if (!is_valid_color(gradient->top_color_)) {
|
||||
return Status::Error(400, "Invalid top gradient color value");
|
||||
}
|
||||
if (!is_valid_color(gradient->bottom_color_)) {
|
||||
return Status::Error(400, "Invalid bottom gradient color value");
|
||||
}
|
||||
if (!BackgroundFill::is_valid_rotation_angle(gradient->rotation_angle_)) {
|
||||
return Status::Error(400, "Invalid rotation angle value");
|
||||
}
|
||||
return BackgroundFill(gradient->top_color_, gradient->bottom_color_, gradient->rotation_angle_);
|
||||
}
|
||||
default:
|
||||
@ -37,21 +56,23 @@ static BackgroundFill get_background_fill(const td_api::BackgroundFill *fill) {
|
||||
}
|
||||
|
||||
static string get_background_fill_color_hex_string(const BackgroundFill &fill, bool is_first) {
|
||||
if (fill.is_solid()) {
|
||||
return get_color_hex_string(fill.top_color);
|
||||
} else {
|
||||
string colors = PSTRING() << get_color_hex_string(fill.top_color) << '-' << get_color_hex_string(fill.bottom_color);
|
||||
if (fill.rotation_angle != 0) {
|
||||
colors += (PSTRING() << (is_first ? '?' : '&') << "rotation=" << fill.rotation_angle);
|
||||
switch (fill.get_type()) {
|
||||
case BackgroundFill::Type::Solid:
|
||||
return get_color_hex_string(fill.top_color);
|
||||
case BackgroundFill::Type::Gradient: {
|
||||
string colors = PSTRING() << get_color_hex_string(fill.top_color) << '-'
|
||||
<< get_color_hex_string(fill.bottom_color);
|
||||
if (fill.rotation_angle != 0) {
|
||||
colors += (PSTRING() << (is_first ? '?' : '&') << "rotation=" << fill.rotation_angle);
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
return colors;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return string();
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_valid_color(int32 color) {
|
||||
return 0 <= color && color <= 0xFFFFFF;
|
||||
}
|
||||
|
||||
static bool is_valid_intensity(int32 intensity) {
|
||||
return 0 <= intensity && intensity <= 100;
|
||||
}
|
||||
@ -60,10 +81,16 @@ int64 BackgroundFill::get_id() const {
|
||||
CHECK(is_valid_color(top_color));
|
||||
CHECK(is_valid_color(bottom_color));
|
||||
CHECK(is_valid_rotation_angle(rotation_angle));
|
||||
if (is_solid()) {
|
||||
return static_cast<int64>(top_color) + 1;
|
||||
switch (get_type()) {
|
||||
case Type::Solid:
|
||||
return static_cast<int64>(top_color) + 1;
|
||||
case Type::Gradient:
|
||||
return (rotation_angle / 45) * 0x1000001000001 + (static_cast<int64>(top_color) << 24) + bottom_color +
|
||||
(1 << 24) + 1;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
return (rotation_angle / 45) * 0x1000001000001 + (static_cast<int64>(top_color) << 24) + bottom_color + (1 << 24) + 1;
|
||||
}
|
||||
|
||||
bool BackgroundFill::is_valid_id(int64 id) {
|
||||
@ -148,35 +175,22 @@ Result<BackgroundType> get_background_type(const td_api::BackgroundType *type) {
|
||||
}
|
||||
case td_api::backgroundTypePattern::ID: {
|
||||
auto pattern = static_cast<const td_api::backgroundTypePattern *>(type);
|
||||
if (pattern->fill_ == nullptr) {
|
||||
return Status::Error(400, "Fill info must be non-empty");
|
||||
TRY_RESULT(background_fill, get_background_fill(pattern->fill_.get()));
|
||||
if (!is_valid_intensity(pattern->intensity_)) {
|
||||
return Status::Error(400, "Wrong intensity value");
|
||||
}
|
||||
result = BackgroundType(pattern->is_moving_, get_background_fill(pattern->fill_.get()), pattern->intensity_);
|
||||
result = BackgroundType(pattern->is_moving_, std::move(background_fill), pattern->intensity_);
|
||||
break;
|
||||
}
|
||||
case td_api::backgroundTypeFill::ID: {
|
||||
auto fill = static_cast<const td_api::backgroundTypeFill *>(type);
|
||||
if (fill->fill_ == nullptr) {
|
||||
return Status::Error(400, "Fill info must be non-empty");
|
||||
}
|
||||
result = BackgroundType(get_background_fill(fill->fill_.get()));
|
||||
TRY_RESULT(background_fill, get_background_fill(fill->fill_.get()));
|
||||
result = BackgroundType(std::move(background_fill));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
if (!is_valid_intensity(result.intensity)) {
|
||||
return Status::Error(400, "Wrong intensity value");
|
||||
}
|
||||
if (!is_valid_color(result.fill.top_color)) {
|
||||
return Status::Error(400, result.fill.is_solid() ? Slice("Wrong color value") : ("Wrong top color value"));
|
||||
}
|
||||
if (!is_valid_color(result.fill.bottom_color)) {
|
||||
return Status::Error(400, "Wrong bottom color value");
|
||||
}
|
||||
if (!BackgroundFill::is_valid_rotation_angle(result.fill.rotation_angle)) {
|
||||
return Status::Error(400, "Wrong rotation angle value");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -233,10 +247,16 @@ BackgroundType get_background_type(bool is_pattern,
|
||||
}
|
||||
|
||||
static td_api::object_ptr<td_api::BackgroundFill> get_background_fill_object(const BackgroundFill &fill) {
|
||||
if (fill.is_solid()) {
|
||||
return td_api::make_object<td_api::backgroundFillSolid>(fill.top_color);
|
||||
switch (fill.get_type()) {
|
||||
case BackgroundFill::Type::Solid:
|
||||
return td_api::make_object<td_api::backgroundFillSolid>(fill.top_color);
|
||||
case BackgroundFill::Type::Gradient:
|
||||
return td_api::make_object<td_api::backgroundFillGradient>(fill.top_color, fill.bottom_color,
|
||||
fill.rotation_angle);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
}
|
||||
return td_api::make_object<td_api::backgroundFillGradient>(fill.top_color, fill.bottom_color, fill.rotation_angle);
|
||||
}
|
||||
|
||||
td_api::object_ptr<td_api::BackgroundType> get_background_type_object(const BackgroundType &type) {
|
||||
@ -255,6 +275,8 @@ td_api::object_ptr<td_api::BackgroundType> get_background_type_object(const Back
|
||||
}
|
||||
|
||||
telegram_api::object_ptr<telegram_api::wallPaperSettings> get_input_wallpaper_settings(const BackgroundType &type) {
|
||||
CHECK(type.is_server());
|
||||
|
||||
int32 flags = 0;
|
||||
if (type.is_blurred) {
|
||||
flags |= telegram_api::wallPaperSettings::BLUR_MASK;
|
||||
@ -262,23 +284,22 @@ telegram_api::object_ptr<telegram_api::wallPaperSettings> get_input_wallpaper_se
|
||||
if (type.is_moving) {
|
||||
flags |= telegram_api::wallPaperSettings::MOTION_MASK;
|
||||
}
|
||||
if (type.fill.top_color != 0 || type.fill.bottom_color != 0) {
|
||||
flags |= telegram_api::wallPaperSettings::BACKGROUND_COLOR_MASK;
|
||||
switch (type.fill.get_type()) {
|
||||
case BackgroundFill::Type::Gradient:
|
||||
flags |= telegram_api::wallPaperSettings::SECOND_BACKGROUND_COLOR_MASK;
|
||||
// fallthrough
|
||||
case BackgroundFill::Type::Solid:
|
||||
flags |= telegram_api::wallPaperSettings::BACKGROUND_COLOR_MASK;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
if (!type.fill.is_solid()) {
|
||||
flags |= telegram_api::wallPaperSettings::SECOND_BACKGROUND_COLOR_MASK;
|
||||
}
|
||||
if (type.intensity) {
|
||||
if (type.intensity != 0) {
|
||||
flags |= telegram_api::wallPaperSettings::INTENSITY_MASK;
|
||||
}
|
||||
if (type.is_server()) {
|
||||
return telegram_api::make_object<telegram_api::wallPaperSettings>(flags, false /*ignored*/, false /*ignored*/,
|
||||
type.fill.top_color, type.fill.bottom_color,
|
||||
type.intensity, type.fill.rotation_angle);
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
return telegram_api::make_object<telegram_api::wallPaperSettings>(flags, false /*ignored*/, false /*ignored*/,
|
||||
type.fill.top_color, type.fill.bottom_color,
|
||||
type.intensity, type.fill.rotation_angle);
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
@ -27,8 +27,12 @@ struct BackgroundFill {
|
||||
: top_color(top_color), bottom_color(bottom_color), rotation_angle(rotation_angle) {
|
||||
}
|
||||
|
||||
bool is_solid() const {
|
||||
return top_color == bottom_color;
|
||||
enum class Type : int32 { Solid, Gradient };
|
||||
Type get_type() const {
|
||||
if (top_color == bottom_color) {
|
||||
return Type::Solid;
|
||||
}
|
||||
return Type::Gradient;
|
||||
}
|
||||
|
||||
int64 get_id() const;
|
||||
|
@ -16,7 +16,8 @@ template <class StorerT>
|
||||
void store(const BackgroundType &type, StorerT &storer) {
|
||||
bool has_fill = type.fill.top_color != 0 || type.fill.bottom_color != 0;
|
||||
bool has_intensity = type.intensity != 0;
|
||||
bool is_gradient = !type.fill.is_solid();
|
||||
auto fill_type = type.fill.get_type();
|
||||
bool is_gradient = fill_type == BackgroundFill::Type::Gradient;
|
||||
BEGIN_STORE_FLAGS();
|
||||
STORE_FLAG(type.is_blurred);
|
||||
STORE_FLAG(type.is_moving);
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "td/utils/crypto.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
#include <tuple>
|
||||
#include <unordered_set>
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
#include "td/telegram/telegram_api.hpp"
|
||||
|
||||
|
@ -660,6 +660,25 @@ td_api::object_ptr<td_api::Object> ClientManager::execute(td_api::object_ptr<td_
|
||||
return Td::static_request(std::move(request));
|
||||
}
|
||||
|
||||
static std::atomic<ClientManager::LogMessageCallbackPtr> log_message_callback;
|
||||
|
||||
static void log_message_callback_wrapper(int verbosity_level, CSlice message) {
|
||||
auto callback = log_message_callback.load(std::memory_order_relaxed);
|
||||
if (callback != nullptr) {
|
||||
callback(verbosity_level, message.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void ClientManager::set_log_message_callback(int max_verbosity_level, LogMessageCallbackPtr callback) {
|
||||
if (callback == nullptr) {
|
||||
::td::set_log_message_callback(max_verbosity_level, nullptr);
|
||||
log_message_callback = nullptr;
|
||||
} else {
|
||||
log_message_callback = callback;
|
||||
::td::set_log_message_callback(max_verbosity_level, log_message_callback_wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
ClientManager::~ClientManager() = default;
|
||||
ClientManager::ClientManager(ClientManager &&other) = default;
|
||||
ClientManager &ClientManager::operator=(ClientManager &&other) = default;
|
||||
|
@ -238,6 +238,27 @@ class ClientManager final {
|
||||
*/
|
||||
static td_api::object_ptr<td_api::Object> execute(td_api::object_ptr<td_api::Function> &&request);
|
||||
|
||||
/**
|
||||
* A type of callback function that will be called when a message is added to the internal TDLib log.
|
||||
*
|
||||
* \param verbosity_level Log verbosity level with which the message was added (-1 - 1024).
|
||||
* If 0, then TDLib will crash as soon as the callback returns.
|
||||
* None of the TDLib methods can be called from the callback.
|
||||
* \param message Null-terminated string with the message added to the log.
|
||||
*/
|
||||
using LogMessageCallbackPtr = void (*)(int verbosity_level, const char *message);
|
||||
|
||||
/**
|
||||
* Sets the callback that will be called when a message is added to the internal TDLib log.
|
||||
* None of the TDLib methods can be called from the callback.
|
||||
* By default the callback is not set.
|
||||
*
|
||||
* \param[in] max_verbosity_level Maximum verbosity level of messages for which the callback will be called.
|
||||
* \param[in] callback Callback that will be called when a message is added to the internal TDLib log.
|
||||
* Pass nullptr to remove the callback.
|
||||
*/
|
||||
static void set_log_message_callback(int max_verbosity_level, LogMessageCallbackPtr callback);
|
||||
|
||||
/**
|
||||
* Destroys the client manager and all TDLib client instances managed by it.
|
||||
*/
|
||||
|
@ -21,6 +21,17 @@ namespace Td {
|
||||
|
||||
using namespace CxCli;
|
||||
|
||||
#if !TD_CLI
|
||||
/// <summary>
|
||||
/// A type of callback function that will be called when a message is added to the internal TDLib log.
|
||||
/// </summary>
|
||||
/// <param name="verbosityLevel">Log verbosity level with which the message was added (-1 - 1024).
|
||||
/// If 0, then TDLib will crash as soon as the callback returns.
|
||||
/// None of the TDLib methods can be called from the callback.</param>
|
||||
/// <param name="message">Null-terminated string with the message added to the log.</param>
|
||||
public delegate void LogMessageCallback(int verbosityLevel, String^ message);
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Interface for handler for results of queries to TDLib and incoming updates from TDLib.
|
||||
/// </summary>
|
||||
@ -105,6 +116,26 @@ public:
|
||||
return REF_NEW Client(updateHandler);
|
||||
}
|
||||
|
||||
#if !TD_CLI
|
||||
/// <summary>
|
||||
/// Sets the callback that will be called when a message is added to the internal TDLib log.
|
||||
/// None of the TDLib methods can be called from the callback.
|
||||
/// </summary>
|
||||
/// <param name="max_verbosity_level">Maximum verbosity level of messages for which the callback will be called.</param>
|
||||
/// <param name="callback">Callback that will be called when a message is added to the internal TDLib log.
|
||||
/// Pass null to remove the callback.</param>
|
||||
static void SetLogMessageCallback(std::int32_t max_verbosity_level, LogMessageCallback^ callback) {
|
||||
std::lock_guard<std::mutex> lock(logMutex);
|
||||
if (callback == nullptr) {
|
||||
::td::ClientManager::set_log_message_callback(max_verbosity_level, nullptr);
|
||||
logMessageCallback = nullptr;
|
||||
} else {
|
||||
logMessageCallback = callback;
|
||||
::td::ClientManager::set_log_message_callback(max_verbosity_level, LogMessageCallbackWrapper);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
Client(ClientResultHandler^ updateHandler) {
|
||||
client = new td::Client();
|
||||
@ -127,7 +158,24 @@ private:
|
||||
handler->OnResult(object);
|
||||
}
|
||||
}
|
||||
|
||||
#if !TD_CLI
|
||||
static std::mutex logMutex;
|
||||
static LogMessageCallback^ logMessageCallback;
|
||||
|
||||
static void LogMessageCallbackWrapper(int verbosity_level, const char *message) {
|
||||
auto callback = logMessageCallback;
|
||||
if (callback != nullptr) {
|
||||
callback(verbosity_level, string_from_unmanaged(message));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !TD_CLI
|
||||
std::mutex Client::logMutex;
|
||||
LogMessageCallback^ Client::logMessageCallback;
|
||||
#endif
|
||||
|
||||
} // namespace Td
|
||||
} // namespace Telegram
|
||||
|
@ -11,8 +11,8 @@
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/JsonBuilder.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/port/thread_local.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/StackAllocator.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
namespace td {
|
||||
|
||||
// TODO can be made private in TDLib 2.0
|
||||
class ClientJson final {
|
||||
public:
|
||||
void send(Slice request);
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include "td/utils/Parser.h"
|
||||
#include "td/utils/port/Clocks.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Time.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
#include "td/utils/tl_parsers.h"
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
|
@ -62,6 +62,7 @@
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
#include "td/utils/Time.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
@ -8597,6 +8598,7 @@ void ContactsManager::save_chat_to_database(Chat *c, ChatId chat_id) {
|
||||
void ContactsManager::save_chat_to_database_impl(Chat *c, ChatId chat_id, string value) {
|
||||
CHECK(c != nullptr);
|
||||
CHECK(load_chat_from_database_queries_.count(chat_id) == 0);
|
||||
CHECK(!c->is_being_saved);
|
||||
c->is_being_saved = true;
|
||||
c->is_saved = true;
|
||||
LOG(INFO) << "Trying to save to database " << chat_id;
|
||||
@ -8833,6 +8835,7 @@ void ContactsManager::save_channel_to_database(Channel *c, ChannelId channel_id)
|
||||
void ContactsManager::save_channel_to_database_impl(Channel *c, ChannelId channel_id, string value) {
|
||||
CHECK(c != nullptr);
|
||||
CHECK(load_channel_from_database_queries_.count(channel_id) == 0);
|
||||
CHECK(!c->is_being_saved);
|
||||
c->is_being_saved = true;
|
||||
c->is_saved = true;
|
||||
LOG(INFO) << "Trying to save to database " << channel_id;
|
||||
@ -8941,10 +8944,12 @@ void ContactsManager::on_load_channel_from_database(ChannelId channel_id, string
|
||||
temp_c.status.update_restrictions();
|
||||
if (temp_c.status != c->status) {
|
||||
on_channel_status_changed(c, channel_id, temp_c.status, c->status);
|
||||
CHECK(!c->is_being_saved);
|
||||
}
|
||||
|
||||
if (temp_c.username != c->username) {
|
||||
on_channel_username_changed(c, channel_id, temp_c.username, c->username);
|
||||
CHECK(!c->is_being_saved);
|
||||
}
|
||||
}
|
||||
auto new_value = get_channel_database_value(c);
|
||||
@ -9083,6 +9088,7 @@ void ContactsManager::save_secret_chat_to_database(SecretChat *c, SecretChatId s
|
||||
void ContactsManager::save_secret_chat_to_database_impl(SecretChat *c, SecretChatId secret_chat_id, string value) {
|
||||
CHECK(c != nullptr);
|
||||
CHECK(load_secret_chat_from_database_queries_.count(secret_chat_id) == 0);
|
||||
CHECK(!c->is_being_saved);
|
||||
c->is_being_saved = true;
|
||||
c->is_saved = true;
|
||||
LOG(INFO) << "Trying to save to database " << secret_chat_id;
|
||||
@ -9622,6 +9628,11 @@ void ContactsManager::on_load_channel_full_from_database(ChannelId channel_id, s
|
||||
}
|
||||
}
|
||||
|
||||
if (invalidated_channels_full_.erase(channel_id) > 0 ||
|
||||
(!c->is_slow_mode_enabled && channel_full->slow_mode_delay != 0)) {
|
||||
do_invalidate_channel_full(channel_full, !c->is_slow_mode_enabled);
|
||||
}
|
||||
|
||||
td_->group_call_manager_->on_update_dialog_about(DialogId(channel_id), channel_full->description, false);
|
||||
|
||||
send_closure_later(G()->messages_manager(), &MessagesManager::on_dialog_bots_updated, DialogId(channel_id),
|
||||
@ -10457,6 +10468,8 @@ void ContactsManager::on_get_chat_full(tl_object_ptr<telegram_api::ChatFull> &&c
|
||||
return promise.set_value(Unit());
|
||||
}
|
||||
|
||||
invalidated_channels_full_.erase(channel_id);
|
||||
|
||||
if (!G()->close_flag()) {
|
||||
auto channel_full = get_channel_full(channel_id, "on_get_channel_full");
|
||||
if (channel_full != nullptr) {
|
||||
@ -12045,17 +12058,26 @@ void ContactsManager::drop_channel_photos(ChannelId channel_id, bool is_empty, b
|
||||
|
||||
void ContactsManager::invalidate_channel_full(ChannelId channel_id, bool need_drop_slow_mode_delay) {
|
||||
LOG(INFO) << "Invalidate supergroup full for " << channel_id;
|
||||
// drop channel full cache
|
||||
auto channel_full = get_channel_full_force(channel_id, "invalidate_channel_full");
|
||||
auto channel_full = get_channel_full(channel_id, "invalidate_channel_full"); // must not load ChannelFull
|
||||
if (channel_full != nullptr) {
|
||||
channel_full->expires_at = 0.0;
|
||||
if (need_drop_slow_mode_delay && channel_full->slow_mode_delay != 0) {
|
||||
channel_full->slow_mode_delay = 0;
|
||||
channel_full->slow_mode_next_send_date = 0;
|
||||
channel_full->is_slow_mode_next_send_date_changed = true;
|
||||
channel_full->is_changed = true;
|
||||
}
|
||||
do_invalidate_channel_full(channel_full, need_drop_slow_mode_delay);
|
||||
update_channel_full(channel_full, channel_id);
|
||||
} else {
|
||||
invalidated_channels_full_.insert(channel_id);
|
||||
}
|
||||
}
|
||||
|
||||
void ContactsManager::do_invalidate_channel_full(ChannelFull *channel_full, bool need_drop_slow_mode_delay) {
|
||||
CHECK(channel_full != nullptr);
|
||||
if (channel_full->expires_at >= Time::now()) {
|
||||
channel_full->expires_at = 0.0;
|
||||
channel_full->need_save_to_database = true;
|
||||
}
|
||||
if (need_drop_slow_mode_delay && channel_full->slow_mode_delay != 0) {
|
||||
channel_full->slow_mode_delay = 0;
|
||||
channel_full->slow_mode_next_send_date = 0;
|
||||
channel_full->is_slow_mode_next_send_date_changed = true;
|
||||
channel_full->is_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -13039,17 +13061,18 @@ void ContactsManager::on_update_channel_status(Channel *c, ChannelId channel_id,
|
||||
}
|
||||
}
|
||||
|
||||
void ContactsManager::on_channel_status_changed(Channel *c, ChannelId channel_id,
|
||||
void ContactsManager::on_channel_status_changed(const Channel *c, ChannelId channel_id,
|
||||
const DialogParticipantStatus &old_status,
|
||||
const DialogParticipantStatus &new_status) {
|
||||
CHECK(c->is_update_supergroup_sent);
|
||||
bool have_channel_full = get_channel_full(channel_id) != nullptr;
|
||||
|
||||
bool need_reload_group_call = old_status.can_manage_calls() != new_status.can_manage_calls();
|
||||
if (old_status.can_manage_invite_links() && !new_status.can_manage_invite_links()) {
|
||||
auto channel_full = get_channel_full_force(channel_id, "on_channel_status_changed");
|
||||
if (channel_full != nullptr) {
|
||||
auto channel_full = get_channel_full(channel_id, "on_channel_status_changed");
|
||||
if (channel_full != nullptr) { // otherwise invite_link will be dropped when the channel is loaded
|
||||
on_update_channel_full_invite_link(channel_full, nullptr);
|
||||
invalidate_channel_full(channel_id, !c->is_slow_mode_enabled);
|
||||
do_invalidate_channel_full(channel_full, !c->is_slow_mode_enabled);
|
||||
update_channel_full(channel_full, channel_id);
|
||||
}
|
||||
} else {
|
||||
@ -13078,6 +13101,9 @@ void ContactsManager::on_channel_status_changed(Channel *c, ChannelId channel_id
|
||||
send_closure_later(G()->messages_manager(), &MessagesManager::on_update_dialog_group_call_rights,
|
||||
DialogId(channel_id));
|
||||
}
|
||||
|
||||
// must not load ChannelFull, because must not change the Channel
|
||||
CHECK(have_channel_full == (get_channel_full(channel_id) != nullptr));
|
||||
}
|
||||
|
||||
void ContactsManager::on_update_channel_default_permissions(Channel *c, ChannelId channel_id,
|
||||
@ -13119,12 +13145,16 @@ void ContactsManager::on_update_channel_username(Channel *c, ChannelId channel_i
|
||||
}
|
||||
}
|
||||
|
||||
void ContactsManager::on_channel_username_changed(Channel *c, ChannelId channel_id, const string &old_username,
|
||||
void ContactsManager::on_channel_username_changed(const Channel *c, ChannelId channel_id, const string &old_username,
|
||||
const string &new_username) {
|
||||
bool have_channel_full = get_channel_full(channel_id) != nullptr;
|
||||
if (old_username.empty() || new_username.empty()) {
|
||||
// moving channel from private to public can change availability of chat members
|
||||
invalidate_channel_full(channel_id, !c->is_slow_mode_enabled);
|
||||
}
|
||||
|
||||
// must not load ChannelFull, because must not change the Channel
|
||||
CHECK(have_channel_full == (get_channel_full(channel_id) != nullptr));
|
||||
}
|
||||
|
||||
void ContactsManager::on_update_channel_description(ChannelId channel_id, string &&description) {
|
||||
|
@ -1250,9 +1250,9 @@ class ContactsManager : public Actor {
|
||||
void on_update_channel_full_bot_user_ids(ChannelFull *channel_full, ChannelId channel_id,
|
||||
vector<UserId> &&bot_user_ids);
|
||||
|
||||
void on_channel_status_changed(Channel *c, ChannelId channel_id, const DialogParticipantStatus &old_status,
|
||||
void on_channel_status_changed(const Channel *c, ChannelId channel_id, const DialogParticipantStatus &old_status,
|
||||
const DialogParticipantStatus &new_status);
|
||||
void on_channel_username_changed(Channel *c, ChannelId channel_id, const string &old_username,
|
||||
void on_channel_username_changed(const Channel *c, ChannelId channel_id, const string &old_username,
|
||||
const string &new_username);
|
||||
|
||||
void remove_linked_channel_id(ChannelId channel_id);
|
||||
@ -1270,6 +1270,8 @@ class ContactsManager : public Actor {
|
||||
|
||||
void drop_channel_photos(ChannelId channel_id, bool is_empty, bool drop_channel_full_photo, const char *source);
|
||||
|
||||
void do_invalidate_channel_full(ChannelFull *channel_full, bool need_drop_slow_mode_delay);
|
||||
|
||||
void update_user_online_member_count(User *u);
|
||||
void update_chat_online_member_count(const ChatFull *chat_full, ChatId chat_id, bool is_from_server);
|
||||
void update_channel_online_member_count(ChannelId channel_id, bool is_from_server);
|
||||
@ -1595,6 +1597,7 @@ class ContactsManager : public Actor {
|
||||
std::unordered_map<ChannelId, unique_ptr<Channel>, ChannelIdHash> channels_;
|
||||
std::unordered_map<ChannelId, unique_ptr<ChannelFull>, ChannelIdHash> channels_full_;
|
||||
mutable std::unordered_set<ChannelId, ChannelIdHash> unknown_channels_;
|
||||
std::unordered_set<ChannelId, ChannelIdHash> invalidated_channels_full_;
|
||||
std::unordered_map<ChannelId, FileSourceId, ChannelIdHash> channel_full_file_source_ids_;
|
||||
|
||||
std::unordered_map<SecretChatId, unique_ptr<SecretChat>, SecretChatIdHash> secret_chats_;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "td/utils/JsonBuilder.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/ScopeGuard.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Time.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -6,8 +6,8 @@
|
||||
//
|
||||
#include "td/telegram/DialogSource.h"
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/overloaded.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Time.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
#include <map>
|
||||
#include <unordered_set>
|
||||
@ -1932,7 +1933,7 @@ void GroupCallManager::process_group_call_participants(
|
||||
}
|
||||
|
||||
auto min_order = GroupCallParticipantOrder::max();
|
||||
DialogId min_order_dialog_id;
|
||||
DialogId debug_min_order_dialog_id;
|
||||
bool can_self_unmute = get_group_call_can_self_unmute(input_group_call_id);
|
||||
bool joined_date_asc = get_group_call_joined_date_asc(input_group_call_id);
|
||||
for (auto &group_call_participant : participants) {
|
||||
@ -1952,11 +1953,11 @@ void GroupCallManager::process_group_call_participants(
|
||||
if (is_load) {
|
||||
auto real_order = participant.get_real_order(can_self_unmute, joined_date_asc, true);
|
||||
if (real_order > min_order) {
|
||||
LOG(ERROR) << "Receive call participant " << participant.dialog_id << " with order " << real_order
|
||||
<< " after call participant " << min_order_dialog_id << " with order " << min_order;
|
||||
LOG(ERROR) << "Receive group call participant " << participant.dialog_id << " with order " << real_order
|
||||
<< " after group call participant " << debug_min_order_dialog_id << " with order " << min_order;
|
||||
} else {
|
||||
min_order = real_order;
|
||||
min_order_dialog_id = participant.dialog_id;
|
||||
debug_min_order_dialog_id = participant.dialog_id;
|
||||
}
|
||||
}
|
||||
if (is_sync) {
|
||||
@ -1964,6 +1965,13 @@ void GroupCallManager::process_group_call_participants(
|
||||
}
|
||||
process_group_call_participant(input_group_call_id, std::move(participant));
|
||||
}
|
||||
if (is_load && participants.empty() && !joined_date_asc) {
|
||||
// If loaded 0 participants and new participants are added to the beginning of the list,
|
||||
// then the end of the list was reached.
|
||||
// Set min_order to the minimum possible value to send updates about all participants with order less than
|
||||
// the current min_order. There can be such participants if the last loaded participant had a fake active_date.
|
||||
min_order = GroupCallParticipantOrder::min();
|
||||
}
|
||||
if (is_sync) {
|
||||
auto participants_it = group_call_participants_.find(input_group_call_id);
|
||||
if (participants_it != group_call_participants_.end()) {
|
||||
@ -1972,6 +1980,7 @@ void GroupCallManager::process_group_call_participants(
|
||||
for (auto participant_it = group_participants.begin(); participant_it != group_participants.end();) {
|
||||
auto &participant = *participant_it;
|
||||
if (old_participant_dialog_ids.count(participant.dialog_id) == 0) {
|
||||
// successfully synced old user
|
||||
++participant_it;
|
||||
continue;
|
||||
}
|
||||
@ -1997,6 +2006,8 @@ void GroupCallManager::process_group_call_participants(
|
||||
}
|
||||
if (participants_it->second->min_order < min_order) {
|
||||
// if previously known more users, adjust min_order
|
||||
LOG(INFO) << "Decrease min_order from " << participants_it->second->min_order << " to " << min_order << " in "
|
||||
<< input_group_call_id;
|
||||
participants_it->second->min_order = min_order;
|
||||
}
|
||||
}
|
||||
@ -2008,11 +2019,17 @@ void GroupCallManager::process_group_call_participants(
|
||||
auto old_min_order = participants_it->second->min_order;
|
||||
if (old_min_order > min_order) {
|
||||
participants_it->second->min_order = min_order;
|
||||
LOG(INFO) << "Increase min_order from " << old_min_order << " to " << min_order << " in "
|
||||
<< input_group_call_id;
|
||||
|
||||
for (auto &participant : participants_it->second->participants) {
|
||||
auto real_order = get_real_participant_order(can_self_unmute, participant, participants_it->second.get());
|
||||
if (old_min_order > real_order && real_order >= min_order) {
|
||||
CHECK(!participant.order.is_valid() || participant.is_self);
|
||||
LOG_CHECK(!participant.order.is_valid() || participant.is_self)
|
||||
<< participant << ' ' << old_min_order << ' ' << real_order << ' ' << min_order << ' '
|
||||
<< participant.joined_date << ' ' << participant.active_date << ' ' << participant.raise_hand_rating
|
||||
<< ' ' << participant.local_active_date << ' ' << G()->unix_time() << ' ' << can_self_unmute << ' '
|
||||
<< participants_it->second->joined_date_asc;
|
||||
participant.order = real_order;
|
||||
send_update_group_call_participant(input_group_call_id, participant,
|
||||
"process_group_call_participants load");
|
||||
|
@ -272,7 +272,7 @@ bool operator!=(const GroupCallParticipant &lhs, const GroupCallParticipant &rhs
|
||||
}
|
||||
|
||||
StringBuilder &operator<<(StringBuilder &string_builder, const GroupCallParticipant &group_call_participant) {
|
||||
return string_builder << '[' << group_call_participant.dialog_id << " with source "
|
||||
return string_builder << "GroupCallParticipant[" << group_call_participant.dialog_id << " with source "
|
||||
<< group_call_participant.audio_source << " and order " << group_call_participant.order << ']';
|
||||
}
|
||||
|
||||
|
@ -6,14 +6,18 @@
|
||||
//
|
||||
#include "td/telegram/GroupCallParticipantOrder.h"
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
#include <limits>
|
||||
#include <tuple>
|
||||
|
||||
namespace td {
|
||||
|
||||
GroupCallParticipantOrder GroupCallParticipantOrder::min() {
|
||||
return GroupCallParticipantOrder(0, 0, 1);
|
||||
}
|
||||
|
||||
GroupCallParticipantOrder GroupCallParticipantOrder::max() {
|
||||
return GroupCallParticipantOrder(std::numeric_limits<int32>::max(), std::numeric_limits<int64>::max(),
|
||||
std::numeric_limits<int32>::max());
|
||||
|
@ -30,6 +30,8 @@ class GroupCallParticipantOrder {
|
||||
: active_date(active_date), joined_date(joined_date), raise_hand_rating(raise_hand_rating) {
|
||||
}
|
||||
|
||||
static GroupCallParticipantOrder min();
|
||||
|
||||
static GroupCallParticipantOrder max();
|
||||
|
||||
bool is_valid() const;
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Time.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
#include "td/utils/tl_parsers.h"
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "td/utils/ExitGuard.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
#include <atomic>
|
||||
|
@ -6,6 +6,7 @@
|
||||
//
|
||||
#include "td/telegram/Log.h"
|
||||
|
||||
#include "td/telegram/Client.h"
|
||||
#include "td/telegram/Logging.h"
|
||||
|
||||
#include "td/telegram/td_api.h"
|
||||
@ -23,9 +24,13 @@ static string log_file_path;
|
||||
static int64 max_log_file_size = 10 << 20;
|
||||
static Log::FatalErrorCallbackPtr fatal_error_callback;
|
||||
|
||||
static void fatal_error_callback_wrapper(CSlice message) {
|
||||
CHECK(fatal_error_callback != nullptr);
|
||||
fatal_error_callback(message.c_str());
|
||||
static void fatal_error_callback_wrapper(int verbosity_level, const char *message) {
|
||||
if (verbosity_level == 0) {
|
||||
auto callback = fatal_error_callback;
|
||||
if (callback != nullptr) {
|
||||
callback(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Log::set_file_path(string file_path) {
|
||||
@ -59,11 +64,11 @@ void Log::set_verbosity_level(int new_verbosity_level) {
|
||||
void Log::set_fatal_error_callback(FatalErrorCallbackPtr callback) {
|
||||
std::lock_guard<std::mutex> lock(log_mutex);
|
||||
if (callback == nullptr) {
|
||||
ClientManager::set_log_message_callback(0, nullptr);
|
||||
fatal_error_callback = nullptr;
|
||||
set_log_fatal_error_callback(nullptr);
|
||||
} else {
|
||||
fatal_error_callback = callback;
|
||||
set_log_fatal_error_callback(fatal_error_callback_wrapper);
|
||||
ClientManager::set_log_message_callback(0, fatal_error_callback_wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,6 +76,7 @@ class Log {
|
||||
* The TDLib will crash as soon as callback returns.
|
||||
* By default the callback is not set.
|
||||
*
|
||||
* \deprecated Use ClientManager::set_log_message_callback instead.
|
||||
* \param[in] callback Callback that will be called when a fatal error happens.
|
||||
* Pass nullptr to remove the callback.
|
||||
*/
|
||||
|
@ -32,9 +32,11 @@
|
||||
#include "td/utils/algorithm.h"
|
||||
#include "td/utils/ExitGuard.h"
|
||||
#include "td/utils/FileLog.h"
|
||||
#include "td/utils/NullLog.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/port/detail/NativeFd.h"
|
||||
#include "td/utils/TsLog.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <map>
|
||||
|
@ -81,6 +81,7 @@
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/PathView.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
#include "td/utils/utf8.h"
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/unicode.h"
|
||||
#include "td/utils/utf8.h"
|
||||
|
||||
@ -628,7 +629,7 @@ static vector<Slice> match_urls(Slice str) {
|
||||
}
|
||||
path_end_ptr = next_ptr;
|
||||
}
|
||||
while (bad_path_end_chars.find(path_end_ptr[-1]) < bad_path_end_chars.size()) {
|
||||
while (path_end_ptr > url_end_ptr + 1 && bad_path_end_chars.find(path_end_ptr[-1]) < bad_path_end_chars.size()) {
|
||||
path_end_ptr--;
|
||||
}
|
||||
if (url_end_ptr[0] == '/' || path_end_ptr > url_end_ptr + 1) {
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/ScopeGuard.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/StackAllocator.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
#include "td/utils/Time.h"
|
||||
|
@ -69,6 +69,7 @@
|
||||
#include "td/utils/PathView.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Time.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
#include "td/utils/utf8.h"
|
||||
@ -9463,9 +9464,11 @@ void MessagesManager::after_get_difference() {
|
||||
auto *list = get_dialog_list(dialog_list_id);
|
||||
CHECK(list != nullptr);
|
||||
if (!list->is_dialog_unread_count_inited_) {
|
||||
get_dialogs(dialog_list_id, MIN_DIALOG_DATE, static_cast<int32>(list->pinned_dialogs_.size() + 2), false,
|
||||
PromiseCreator::lambda([dialog_list_id](Unit) {
|
||||
if (!G()->close_flag()) {
|
||||
int32 limit = list->are_pinned_dialogs_inited_ ? static_cast<int32>(list->pinned_dialogs_.size())
|
||||
: get_pinned_dialogs_limit(dialog_list_id);
|
||||
get_dialogs(dialog_list_id, MIN_DIALOG_DATE, limit + 2, false,
|
||||
PromiseCreator::lambda([dialog_list_id](Result<Unit> result) {
|
||||
if (!G()->close_flag() && result.is_ok()) {
|
||||
LOG(INFO) << "Inited total chat count in " << dialog_list_id;
|
||||
}
|
||||
}));
|
||||
@ -13305,6 +13308,10 @@ void MessagesManager::on_get_secret_message(SecretChatId secret_chat_id, UserId
|
||||
message_info.ttl = message->ttl_;
|
||||
|
||||
Dialog *d = get_dialog_force(message_info.dialog_id, "on_get_secret_message");
|
||||
if (d == nullptr && have_dialog_info_force(message_info.dialog_id)) {
|
||||
force_create_dialog(message_info.dialog_id, "on_get_secret_message", true, true);
|
||||
d = get_dialog(message_info.dialog_id);
|
||||
}
|
||||
if (d == nullptr) {
|
||||
LOG(ERROR) << "Ignore secret message in unknown " << message_info.dialog_id;
|
||||
pending_secret_message->success_promise.set_error(Status::Error(500, "Chat not found"));
|
||||
@ -13395,6 +13402,10 @@ void MessagesManager::on_secret_chat_screenshot_taken(SecretChatId secret_chat_i
|
||||
message_info.content = create_screenshot_taken_message_content();
|
||||
|
||||
Dialog *d = get_dialog_force(message_info.dialog_id, "on_secret_chat_screenshot_taken");
|
||||
if (d == nullptr && have_dialog_info_force(message_info.dialog_id)) {
|
||||
force_create_dialog(message_info.dialog_id, "on_get_secret_message", true, true);
|
||||
d = get_dialog(message_info.dialog_id);
|
||||
}
|
||||
if (d == nullptr) {
|
||||
LOG(ERROR) << "Ignore secret message in unknown " << message_info.dialog_id;
|
||||
pending_secret_message->success_promise.set_error(Status::Error(500, "Chat not found"));
|
||||
@ -13429,6 +13440,10 @@ void MessagesManager::on_secret_chat_ttl_changed(SecretChatId secret_chat_id, Us
|
||||
message_info.content = create_chat_set_ttl_message_content(ttl);
|
||||
|
||||
Dialog *d = get_dialog_force(message_info.dialog_id, "on_secret_chat_ttl_changed");
|
||||
if (d == nullptr && have_dialog_info_force(message_info.dialog_id)) {
|
||||
force_create_dialog(message_info.dialog_id, "on_get_secret_message", true, true);
|
||||
d = get_dialog(message_info.dialog_id);
|
||||
}
|
||||
if (d == nullptr) {
|
||||
LOG(ERROR) << "Ignore secret message in unknown " << message_info.dialog_id;
|
||||
pending_secret_message->success_promise.set_error(Status::Error(500, "Chat not found"));
|
||||
@ -14274,12 +14289,29 @@ void MessagesManager::set_dialog_is_empty(Dialog *d, const char *source) {
|
||||
update_dialog_pos(d, source);
|
||||
}
|
||||
|
||||
bool MessagesManager::is_dialog_pinned(DialogListId dialog_list_id, DialogId dialog_id) const {
|
||||
if (get_dialog_pinned_order(dialog_list_id, dialog_id) != DEFAULT_ORDER) {
|
||||
return true;
|
||||
}
|
||||
if (dialog_list_id.is_filter()) {
|
||||
const auto *filter = get_dialog_filter(dialog_list_id.get_filter_id());
|
||||
if (filter != nullptr) {
|
||||
for (const auto &input_dialog_id : filter->pinned_dialog_ids) {
|
||||
if (input_dialog_id.get_dialog_id() == dialog_id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int64 MessagesManager::get_dialog_pinned_order(DialogListId dialog_list_id, DialogId dialog_id) const {
|
||||
return get_dialog_pinned_order(get_dialog_list(dialog_list_id), dialog_id);
|
||||
}
|
||||
|
||||
int64 MessagesManager::get_dialog_pinned_order(const DialogList *list, DialogId dialog_id) {
|
||||
if (list != nullptr && !list->pinned_dialogs_.empty()) {
|
||||
if (list != nullptr && !list->pinned_dialog_id_orders_.empty()) {
|
||||
auto it = list->pinned_dialog_id_orders_.find(dialog_id);
|
||||
if (it != list->pinned_dialog_id_orders_.end()) {
|
||||
return it->second;
|
||||
@ -14301,6 +14333,7 @@ bool MessagesManager::set_dialog_is_pinned(DialogId dialog_id, bool is_pinned) {
|
||||
return set_dialog_is_pinned(DialogListId(d->folder_id), d, is_pinned);
|
||||
}
|
||||
|
||||
// only removes the Dialog from the dialog list, but changes nothing in the corresponding DialogFilter
|
||||
bool MessagesManager::set_dialog_is_pinned(DialogListId dialog_list_id, Dialog *d, bool is_pinned,
|
||||
bool need_update_dialog_lists) {
|
||||
if (td_->auth_manager_->is_bot()) {
|
||||
@ -14812,7 +14845,7 @@ void MessagesManager::on_get_dialogs(FolderId folder_id, vector<tl_object_ptr<te
|
||||
if (!td_->auth_manager_->is_bot() && !from_pinned_dialog_list) {
|
||||
// set is_pinned only after updating dialog pos to ensure that order is initialized
|
||||
bool is_pinned = (dialog->flags_ & DIALOG_FLAG_IS_PINNED) != 0;
|
||||
bool was_pinned = get_dialog_pinned_order(DialogListId(d->folder_id), dialog_id) != DEFAULT_ORDER;
|
||||
bool was_pinned = is_dialog_pinned(DialogListId(d->folder_id), dialog_id);
|
||||
if (is_pinned != was_pinned) {
|
||||
set_dialog_is_pinned(DialogListId(d->folder_id), d, is_pinned);
|
||||
}
|
||||
@ -15909,7 +15942,7 @@ std::pair<int32, vector<DialogId>> MessagesManager::get_dialogs(DialogListId dia
|
||||
auto *filter = get_dialog_filter(dialog_list_id.get_filter_id());
|
||||
CHECK(filter != nullptr);
|
||||
vector<InputDialogId> input_dialog_ids;
|
||||
for (auto &input_dialog_id : filter->pinned_dialog_ids) {
|
||||
for (const auto &input_dialog_id : filter->pinned_dialog_ids) {
|
||||
auto dialog_id = input_dialog_id.get_dialog_id();
|
||||
if (!have_dialog_force(dialog_id, "get_dialogs")) {
|
||||
if (dialog_id.get_type() == DialogType::SecretChat) {
|
||||
@ -16223,6 +16256,14 @@ void MessagesManager::preload_folder_dialog_list(FolderId folder_id) {
|
||||
|
||||
vector<DialogId> MessagesManager::get_pinned_dialog_ids(DialogListId dialog_list_id) const {
|
||||
CHECK(!td_->auth_manager_->is_bot());
|
||||
if (dialog_list_id.is_filter()) {
|
||||
const auto *filter = get_dialog_filter(dialog_list_id.get_filter_id());
|
||||
if (filter == nullptr) {
|
||||
return {};
|
||||
}
|
||||
return transform(filter->pinned_dialog_ids, [](auto &input_dialog) { return input_dialog.get_dialog_id(); });
|
||||
}
|
||||
|
||||
auto *list = get_dialog_list(dialog_list_id);
|
||||
if (list == nullptr || !list->are_pinned_dialogs_inited_) {
|
||||
return {};
|
||||
@ -18109,9 +18150,7 @@ void MessagesManager::sort_dialog_filter_input_dialog_ids(DialogFilter *dialog_f
|
||||
{&dialog_filter->pinned_dialog_ids, &dialog_filter->excluded_dialog_ids, &dialog_filter->included_dialog_ids}) {
|
||||
for (auto input_dialog_id : *input_dialog_ids) {
|
||||
LOG_CHECK(all_dialog_ids.insert(input_dialog_id.get_dialog_id()).second)
|
||||
<< source << ' ' << td::contains(dialog_filter->pinned_dialog_ids, input_dialog_id) << ' '
|
||||
<< td::contains(dialog_filter->excluded_dialog_ids, input_dialog_id) << ' '
|
||||
<< td::contains(dialog_filter->included_dialog_ids, input_dialog_id);
|
||||
<< source << ' ' << input_dialog_id.get_dialog_id() << ' ' << dialog_filter;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -18463,7 +18502,7 @@ void MessagesManager::add_dialog_filter(unique_ptr<DialogFilter> dialog_filter,
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &input_dialog_id : reversed(dialog_filters_.back()->pinned_dialog_ids)) {
|
||||
for (const auto &input_dialog_id : reversed(dialog_filters_.back()->pinned_dialog_ids)) {
|
||||
auto dialog_id = input_dialog_id.get_dialog_id();
|
||||
auto order = get_next_pinned_dialog_order();
|
||||
list.pinned_dialogs_.emplace_back(order, dialog_id);
|
||||
@ -18507,7 +18546,7 @@ void MessagesManager::edit_dialog_filter(unique_ptr<DialogFilter> new_dialog_fil
|
||||
new_list.dialog_list_id = dialog_list_id;
|
||||
|
||||
auto old_it = old_list.pinned_dialogs_.rbegin();
|
||||
for (auto &input_dialog_id : reversed(new_dialog_filter->pinned_dialog_ids)) {
|
||||
for (const auto &input_dialog_id : reversed(new_dialog_filter->pinned_dialog_ids)) {
|
||||
auto dialog_id = input_dialog_id.get_dialog_id();
|
||||
while (old_it < old_list.pinned_dialogs_.rend()) {
|
||||
if (old_it->get_dialog_id() == dialog_id) {
|
||||
@ -18979,7 +19018,7 @@ Status MessagesManager::toggle_dialog_is_pinned(DialogListId dialog_list_id, Dia
|
||||
return Status::Error(6, "Pinned chats must be loaded first");
|
||||
}
|
||||
|
||||
bool was_pinned = get_dialog_pinned_order(dialog_list_id, dialog_id) != DEFAULT_ORDER;
|
||||
bool was_pinned = is_dialog_pinned(dialog_list_id, dialog_id);
|
||||
if (is_pinned == was_pinned) {
|
||||
return Status::OK();
|
||||
}
|
||||
@ -18999,7 +19038,8 @@ Status MessagesManager::toggle_dialog_is_pinned(DialogListId dialog_list_id, Dia
|
||||
td::remove_if(new_dialog_filter->included_dialog_ids, is_changed_dialog);
|
||||
td::remove_if(new_dialog_filter->excluded_dialog_ids, is_changed_dialog);
|
||||
} else {
|
||||
td::remove_if(new_dialog_filter->pinned_dialog_ids, is_changed_dialog);
|
||||
bool is_removed = td::remove_if(new_dialog_filter->pinned_dialog_ids, is_changed_dialog);
|
||||
CHECK(is_removed);
|
||||
new_dialog_filter->included_dialog_ids.push_back(get_input_dialog_id(dialog_id));
|
||||
}
|
||||
|
||||
@ -27417,8 +27457,9 @@ MessagesManager::MessageNotificationGroup MessagesManager::get_message_notificat
|
||||
d = get_dialog(it->second);
|
||||
CHECK(d != nullptr);
|
||||
} else if (G()->parameters().use_message_db) {
|
||||
G()->td_db()->get_dialog_db_sync()->begin_transaction().ensure();
|
||||
auto r_value = G()->td_db()->get_dialog_db_sync()->get_notification_group(group_id);
|
||||
auto *dialog_db = G()->td_db()->get_dialog_db_sync();
|
||||
dialog_db->begin_transaction().ensure(); // read transaction
|
||||
auto r_value = dialog_db->get_notification_group(group_id);
|
||||
if (r_value.is_ok()) {
|
||||
VLOG(notifications) << "Loaded " << r_value.ok() << " from database by " << group_id;
|
||||
d = get_dialog_force(r_value.ok().dialog_id, "get_message_notification_group_force");
|
||||
@ -27426,7 +27467,7 @@ MessagesManager::MessageNotificationGroup MessagesManager::get_message_notificat
|
||||
CHECK(r_value.error().message() == "Not found");
|
||||
VLOG(notifications) << "Failed to load " << group_id << " from database";
|
||||
}
|
||||
G()->td_db()->get_dialog_db_sync()->commit_transaction().ensure();
|
||||
dialog_db->commit_transaction().ensure();
|
||||
}
|
||||
|
||||
if (d == nullptr) {
|
||||
@ -27712,9 +27753,10 @@ vector<NotificationGroupKey> MessagesManager::get_message_notification_group_key
|
||||
VLOG(notifications) << "Trying to load " << limit << " message notification groups from database from "
|
||||
<< from_group_key;
|
||||
|
||||
G()->td_db()->get_dialog_db_sync()->begin_transaction().ensure();
|
||||
auto *dialog_db = G()->td_db()->get_dialog_db_sync();
|
||||
dialog_db->begin_transaction().ensure(); // read transaction
|
||||
Result<vector<NotificationGroupKey>> r_notification_group_keys =
|
||||
G()->td_db()->get_dialog_db_sync()->get_notification_groups_by_last_notification_date(from_group_key, limit);
|
||||
dialog_db->get_notification_groups_by_last_notification_date(from_group_key, limit);
|
||||
r_notification_group_keys.ensure();
|
||||
auto group_keys = r_notification_group_keys.move_as_ok();
|
||||
|
||||
@ -27733,7 +27775,7 @@ vector<NotificationGroupKey> MessagesManager::get_message_notification_group_key
|
||||
VLOG(notifications) << "Loaded " << group_key << " from database";
|
||||
result.push_back(group_key);
|
||||
}
|
||||
G()->td_db()->get_dialog_db_sync()->commit_transaction().ensure();
|
||||
dialog_db->commit_transaction().ensure();
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -29281,14 +29323,13 @@ void MessagesManager::on_send_message_fail(int64 random_id, Status error) {
|
||||
if (td_->auth_manager_->is_bot()) {
|
||||
switch (dialog_id.get_type()) {
|
||||
case DialogType::User:
|
||||
case DialogType::SecretChat:
|
||||
error_message = "Bot was blocked by the user";
|
||||
break;
|
||||
case DialogType::Chat:
|
||||
case DialogType::Channel:
|
||||
error_message = "Bot was kicked from the chat";
|
||||
break;
|
||||
case DialogType::SecretChat:
|
||||
break;
|
||||
case DialogType::None:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -29296,14 +29337,13 @@ void MessagesManager::on_send_message_fail(int64 random_id, Status error) {
|
||||
} else {
|
||||
switch (dialog_id.get_type()) {
|
||||
case DialogType::User:
|
||||
case DialogType::SecretChat:
|
||||
error_message = "User was blocked by the other user";
|
||||
break;
|
||||
case DialogType::Chat:
|
||||
case DialogType::Channel:
|
||||
error_message = "User is not in the chat";
|
||||
break;
|
||||
case DialogType::SecretChat:
|
||||
break;
|
||||
case DialogType::None:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -29311,7 +29351,8 @@ void MessagesManager::on_send_message_fail(int64 random_id, Status error) {
|
||||
}
|
||||
// TODO add check to send_message
|
||||
} else if (error.message() == "USER_IS_BOT") {
|
||||
if (td_->auth_manager_->is_bot() && dialog_id.get_type() == DialogType::User) {
|
||||
if (td_->auth_manager_->is_bot() &&
|
||||
(dialog_id.get_type() == DialogType::User || dialog_id.get_type() == DialogType::SecretChat)) {
|
||||
error_code = 403;
|
||||
if (td_->contacts_manager_->is_user_bot(dialog_id.get_user_id())) {
|
||||
error_message = "Bot can't send messages to bots";
|
||||
@ -29322,7 +29363,8 @@ void MessagesManager::on_send_message_fail(int64 random_id, Status error) {
|
||||
}
|
||||
} else if (error.message() == "PEER_ID_INVALID") {
|
||||
error_code = 403;
|
||||
if (td_->auth_manager_->is_bot()) {
|
||||
if (td_->auth_manager_->is_bot() &&
|
||||
(dialog_id.get_type() == DialogType::User || dialog_id.get_type() == DialogType::SecretChat)) {
|
||||
error_message = "Bot can't initiate conversation with a user";
|
||||
}
|
||||
} else if (error.message() == "WC_CONVERT_URL_INVALID" || error.message() == "EXTERNAL_URL_INVALID") {
|
||||
@ -33943,7 +33985,9 @@ MessagesManager::Dialog *MessagesManager::get_dialog_by_message_id(MessageId mes
|
||||
r_value.ok().second, false, "get_dialog_by_message_id");
|
||||
if (m != nullptr) {
|
||||
CHECK(m->message_id == message_id);
|
||||
CHECK(message_id_to_dialog_id_[message_id] == dialog_id);
|
||||
LOG_CHECK(message_id_to_dialog_id_[message_id] == dialog_id)
|
||||
<< message_id << ' ' << dialog_id << ' ' << message_id_to_dialog_id_[message_id] << ' '
|
||||
<< m->debug_source;
|
||||
Dialog *d = get_dialog(dialog_id);
|
||||
if (d == nullptr) {
|
||||
LOG(ERROR) << "Unknown dialog " << dialog_id;
|
||||
@ -34523,13 +34567,9 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr<Message> &&last_datab
|
||||
<< ", max_notification_message_id = " << d->max_notification_message_id;
|
||||
|
||||
if (d->messages != nullptr) {
|
||||
auto get_debug_source = [](const unique_ptr<Message> &message) {
|
||||
return message->debug_source != nullptr ? message->debug_source : "null";
|
||||
};
|
||||
LOG_CHECK(d->messages->message_id == last_message_id)
|
||||
<< d->messages->message_id << ' ' << last_message_id << ' ' << get_debug_source(d->messages);
|
||||
LOG_CHECK(d->messages->left == nullptr) << get_debug_source(d->messages->left);
|
||||
LOG_CHECK(d->messages->right == nullptr) << get_debug_source(d->messages->right);
|
||||
CHECK(d->messages->message_id == last_message_id);
|
||||
CHECK(d->messages->left == nullptr);
|
||||
CHECK(d->messages->right == nullptr);
|
||||
}
|
||||
|
||||
// must be after update_dialog_pos, because uses d->order
|
||||
@ -34839,7 +34879,7 @@ bool MessagesManager::set_dialog_order(Dialog *d, int64 new_order, bool need_sen
|
||||
if (new_order == DEFAULT_ORDER) {
|
||||
// first addition of a new left dialog
|
||||
if (folder.ordered_dialogs_.insert(new_date).second) {
|
||||
for (auto &dialog_list : dialog_lists_) {
|
||||
for (const auto &dialog_list : dialog_lists_) {
|
||||
if (get_dialog_pinned_order(&dialog_list.second, d->dialog_id) != DEFAULT_ORDER) {
|
||||
set_dialog_is_pinned(dialog_list.first, d, false);
|
||||
}
|
||||
@ -35502,7 +35542,7 @@ MessagesManager::get_dialog_positions(const Dialog *d) const {
|
||||
CHECK(d != nullptr);
|
||||
std::unordered_map<DialogListId, MessagesManager::DialogPositionInList, DialogListIdHash> positions;
|
||||
if (!td_->auth_manager_->is_bot()) {
|
||||
for (auto &dialog_list : dialog_lists_) {
|
||||
for (const auto &dialog_list : dialog_lists_) {
|
||||
positions.emplace(dialog_list.first, get_dialog_position_in_list(&dialog_list.second, d));
|
||||
}
|
||||
}
|
||||
@ -36164,7 +36204,7 @@ void MessagesManager::on_get_channel_difference(
|
||||
if (!td_->auth_manager_->is_bot()) {
|
||||
// set is_pinned only after updating dialog pos to ensure that order is initialized
|
||||
bool is_pinned = (dialog->flags_ & DIALOG_FLAG_IS_PINNED) != 0;
|
||||
bool was_pinned = get_dialog_pinned_order(DialogListId(d->folder_id), dialog_id) != DEFAULT_ORDER;
|
||||
bool was_pinned = is_dialog_pinned(DialogListId(d->folder_id), dialog_id);
|
||||
if (is_pinned != was_pinned) {
|
||||
set_dialog_is_pinned(DialogListId(d->folder_id), d, is_pinned);
|
||||
}
|
||||
|
@ -1107,7 +1107,7 @@ class MessagesManager : public Actor {
|
||||
|
||||
int32 last_edit_pts = 0;
|
||||
|
||||
const char *debug_source = nullptr;
|
||||
const char *debug_source = "null";
|
||||
|
||||
unique_ptr<Message> left;
|
||||
unique_ptr<Message> right;
|
||||
@ -1722,6 +1722,8 @@ class MessagesManager : public Actor {
|
||||
|
||||
bool is_dialog_mention_notifications_disabled(const Dialog *d) const;
|
||||
|
||||
bool is_dialog_pinned(DialogListId dialog_list_id, DialogId dialog_id) const;
|
||||
|
||||
int64 get_dialog_pinned_order(DialogListId dialog_list_id, DialogId dialog_id) const;
|
||||
|
||||
static int64 get_dialog_pinned_order(const DialogList *list, DialogId dialog_id);
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Time.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
#include "td/utils/tl_parsers.h"
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Time.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "td/telegram/PhotoSizeSource.h"
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "td/utils/overloaded.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/ScopeGuard.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/StorerBase.h"
|
||||
#include "td/utils/Time.h"
|
||||
#include "td/utils/tl_parsers.h"
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "td/db/KeyValueSyncInterface.h"
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/Time.h"
|
||||
|
||||
@ -352,44 +353,44 @@ unique_ptr<SecretChatActor::Context> SecretChatsManager::make_secret_chat_contex
|
||||
void on_inbound_message(UserId user_id, MessageId message_id, int32 date,
|
||||
tl_object_ptr<telegram_api::encryptedFile> file,
|
||||
tl_object_ptr<secret_api::decryptedMessage> message, Promise<> promise) override {
|
||||
send_closure(G()->messages_manager(), &MessagesManager::on_get_secret_message, secret_chat_id_, user_id,
|
||||
message_id, date, std::move(file), std::move(message), std::move(promise));
|
||||
send_closure_later(G()->messages_manager(), &MessagesManager::on_get_secret_message, secret_chat_id_, user_id,
|
||||
message_id, date, std::move(file), std::move(message), std::move(promise));
|
||||
}
|
||||
|
||||
void on_send_message_error(int64 random_id, Status error, Promise<> promise) override {
|
||||
send_closure(G()->messages_manager(), &MessagesManager::on_send_secret_message_error, random_id, std::move(error),
|
||||
std::move(promise));
|
||||
send_closure_later(G()->messages_manager(), &MessagesManager::on_send_secret_message_error, random_id,
|
||||
std::move(error), std::move(promise));
|
||||
}
|
||||
|
||||
void on_send_message_ack(int64 random_id) override {
|
||||
send_closure(G()->messages_manager(), &MessagesManager::on_send_message_get_quick_ack, random_id);
|
||||
send_closure_later(G()->messages_manager(), &MessagesManager::on_send_message_get_quick_ack, random_id);
|
||||
}
|
||||
void on_send_message_ok(int64 random_id, MessageId message_id, int32 date,
|
||||
tl_object_ptr<telegram_api::EncryptedFile> file, Promise<> promise) override {
|
||||
send_closure(G()->messages_manager(), &MessagesManager::on_send_secret_message_success, random_id, message_id,
|
||||
date, std::move(file), std::move(promise));
|
||||
send_closure_later(G()->messages_manager(), &MessagesManager::on_send_secret_message_success, random_id,
|
||||
message_id, date, std::move(file), std::move(promise));
|
||||
}
|
||||
void on_delete_messages(std::vector<int64> random_ids, Promise<> promise) override {
|
||||
send_closure(G()->messages_manager(), &MessagesManager::delete_secret_messages, secret_chat_id_,
|
||||
std::move(random_ids), std::move(promise));
|
||||
send_closure_later(G()->messages_manager(), &MessagesManager::delete_secret_messages, secret_chat_id_,
|
||||
std::move(random_ids), std::move(promise));
|
||||
}
|
||||
void on_flush_history(bool remove_from_dialog_list, MessageId message_id, Promise<> promise) override {
|
||||
send_closure(G()->messages_manager(), &MessagesManager::delete_secret_chat_history, secret_chat_id_,
|
||||
remove_from_dialog_list, message_id, std::move(promise));
|
||||
send_closure_later(G()->messages_manager(), &MessagesManager::delete_secret_chat_history, secret_chat_id_,
|
||||
remove_from_dialog_list, message_id, std::move(promise));
|
||||
}
|
||||
void on_read_message(int64 random_id, Promise<> promise) override {
|
||||
send_closure(G()->messages_manager(), &MessagesManager::open_secret_message, secret_chat_id_, random_id,
|
||||
std::move(promise));
|
||||
send_closure_later(G()->messages_manager(), &MessagesManager::open_secret_message, secret_chat_id_, random_id,
|
||||
std::move(promise));
|
||||
}
|
||||
void on_screenshot_taken(UserId user_id, MessageId message_id, int32 date, int64 random_id,
|
||||
Promise<> promise) override {
|
||||
send_closure(G()->messages_manager(), &MessagesManager::on_secret_chat_screenshot_taken, secret_chat_id_, user_id,
|
||||
message_id, date, random_id, std::move(promise));
|
||||
send_closure_later(G()->messages_manager(), &MessagesManager::on_secret_chat_screenshot_taken, secret_chat_id_,
|
||||
user_id, message_id, date, random_id, std::move(promise));
|
||||
}
|
||||
void on_set_ttl(UserId user_id, MessageId message_id, int32 date, int32 ttl, int64 random_id,
|
||||
Promise<> promise) override {
|
||||
send_closure(G()->messages_manager(), &MessagesManager::on_secret_chat_ttl_changed, secret_chat_id_, user_id,
|
||||
message_id, date, ttl, random_id, std::move(promise));
|
||||
send_closure_later(G()->messages_manager(), &MessagesManager::on_secret_chat_ttl_changed, secret_chat_id_,
|
||||
user_id, message_id, date, ttl, random_id, std::move(promise));
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/optional.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "td/utils/port/FileFd.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/SharedSlice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
namespace td {
|
||||
namespace secure_storage {
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/overloaded.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/utf8.h"
|
||||
|
||||
#include <limits>
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
#include <limits>
|
||||
|
@ -6,9 +6,9 @@
|
||||
//
|
||||
#include "td/telegram/SpecialStickerSetType.h"
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "td/utils/PathView.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/StackAllocator.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
#include "td/utils/Time.h"
|
||||
@ -6452,6 +6453,9 @@ void StickersManager::on_get_emoji_keywords_difference(
|
||||
version = keywords->version_;
|
||||
auto *pmc = G()->td_db()->get_sqlite_sync_pmc();
|
||||
pmc->begin_transaction().ensure();
|
||||
// set must be the first operation to start a write transaction
|
||||
pmc->set(get_emoji_language_code_version_database_key(language_code), to_string(version));
|
||||
pmc->set(get_emoji_language_code_last_difference_time_database_key(language_code), to_string(G()->unix_time()));
|
||||
for (auto &keyword_ptr : keywords->keywords_) {
|
||||
switch (keyword_ptr->get_id()) {
|
||||
case telegram_api::emojiKeyword::ID: {
|
||||
@ -6504,8 +6508,6 @@ void StickersManager::on_get_emoji_keywords_difference(
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
pmc->set(get_emoji_language_code_version_database_key(language_code), to_string(version));
|
||||
pmc->set(get_emoji_language_code_last_difference_time_database_key(language_code), to_string(G()->unix_time()));
|
||||
pmc->commit_transaction().ensure();
|
||||
emoji_language_code_versions_[language_code] = version;
|
||||
emoji_language_code_last_difference_times_[language_code] = static_cast<int32>(Time::now_cached());
|
||||
|
@ -96,6 +96,7 @@
|
||||
#include "td/telegram/TopDialogCategory.h"
|
||||
#include "td/telegram/TopDialogManager.h"
|
||||
#include "td/telegram/UpdatesManager.h"
|
||||
#include "td/telegram/Version.h"
|
||||
#include "td/telegram/VideoNotesManager.h"
|
||||
#include "td/telegram/VideosManager.h"
|
||||
#include "td/telegram/VoiceNotesManager.h"
|
||||
@ -131,6 +132,7 @@
|
||||
#include "td/utils/port/uname.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/Timer.h"
|
||||
#include "td/utils/tl_parsers.h"
|
||||
@ -3005,6 +3007,8 @@ class SetBackgroundRequest : public RequestActor<> {
|
||||
Td::Td(unique_ptr<TdCallback> callback, Options options)
|
||||
: callback_(std::move(callback)), td_options_(std::move(options)) {
|
||||
CHECK(callback_ != nullptr);
|
||||
LOG(INFO) << "Create Td with layer " << MTPROTO_LAYER << ", database version " << current_db_version()
|
||||
<< " and version " << static_cast<int32>(Version::Next) - 1;
|
||||
}
|
||||
|
||||
Td::~Td() = default;
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/port/path.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "td/utils/port/Clocks.h"
|
||||
#include "td/utils/ScopeGuard.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "td/telegram/DialogAction.h"
|
||||
#include "td/telegram/DialogId.h"
|
||||
#include "td/telegram/DialogInviteLink.h"
|
||||
#include "td/telegram/DialogParticipant.h"
|
||||
#include "td/telegram/FolderId.h"
|
||||
#include "td/telegram/Global.h"
|
||||
#include "td/telegram/GroupCallManager.h"
|
||||
@ -56,6 +57,7 @@
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
#include "td/utils/Time.h"
|
||||
@ -2618,7 +2620,7 @@ void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateChatDefaultBann
|
||||
case DialogType::User:
|
||||
case DialogType::SecretChat:
|
||||
default:
|
||||
LOG(ERROR) << "Receive updateChatDefaultBannedRights in the " << dialog_id;
|
||||
LOG(ERROR) << "Receive updateChatDefaultBannedRights in " << dialog_id;
|
||||
break;
|
||||
}
|
||||
promise.set_value(Unit());
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
|
||||
#include <type_traits>
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
#include "td/utils/utf8.h"
|
||||
|
@ -13,13 +13,14 @@
|
||||
#include "td/net/HttpReader.h"
|
||||
|
||||
#include "td/telegram/ClientActor.h"
|
||||
#include "td/telegram/Log.h"
|
||||
#include "td/telegram/Client.h"
|
||||
#include "td/telegram/Td.h" // for VERBOSITY_NAME(td_requests)
|
||||
#include "td/telegram/td_api_json.h"
|
||||
|
||||
#include "td/utils/algorithm.h"
|
||||
#include "td/utils/base64.h"
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/CombinedLog.h"
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/crypto.h"
|
||||
#include "td/utils/ExitGuard.h"
|
||||
@ -29,6 +30,7 @@
|
||||
#include "td/utils/JsonBuilder.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/NullLog.h"
|
||||
#include "td/utils/OptionParser.h"
|
||||
#include "td/utils/port/FileFd.h"
|
||||
#include "td/utils/port/PollFlags.h"
|
||||
@ -39,9 +41,11 @@
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/ScopeGuard.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
#include "td/utils/Time.h"
|
||||
#include "td/utils/TsLog.h"
|
||||
#include "td/utils/utf8.h"
|
||||
|
||||
#ifndef USE_READLINE
|
||||
@ -188,28 +192,19 @@ static char **tg_cli_completion(const char *text, int start, int end) {
|
||||
#endif
|
||||
|
||||
class CliLog : public LogInterface {
|
||||
public:
|
||||
void append(CSlice slice, int log_level) override {
|
||||
void do_append(int log_level, CSlice slice) final {
|
||||
#ifdef USE_READLINE
|
||||
deactivate_readline();
|
||||
SCOPE_EXIT {
|
||||
reactivate_readline();
|
||||
};
|
||||
#endif
|
||||
if (log_level == VERBOSITY_NAME(PLAIN)) {
|
||||
#if TD_WINDOWS
|
||||
TsCerr() << slice;
|
||||
#else
|
||||
TsCerr() << TC_GREEN << slice << TC_EMPTY;
|
||||
#endif
|
||||
} else {
|
||||
default_log_interface->append(slice, log_level);
|
||||
}
|
||||
}
|
||||
void rotate() override {
|
||||
default_log_interface->do_append(log_level, slice);
|
||||
}
|
||||
};
|
||||
|
||||
static CombinedLog combined_log;
|
||||
|
||||
struct SendMessageInfo {
|
||||
double start_time = 0;
|
||||
double quick_ack_time = 0;
|
||||
@ -740,7 +735,7 @@ class CliClient final : public Actor {
|
||||
}
|
||||
}
|
||||
|
||||
if (id > 0 && GET_VERBOSITY_LEVEL() < VERBOSITY_NAME(td_requests)) {
|
||||
if (id > 0 && combined_log.get_first_verbosity_level() < VERBOSITY_NAME(td_requests)) {
|
||||
LOG(ERROR) << "Receive result [" << generation << "][id=" << id << "] " << result_str;
|
||||
}
|
||||
|
||||
@ -859,7 +854,7 @@ class CliClient final : public Actor {
|
||||
}
|
||||
|
||||
void on_error(uint64 generation, uint64 id, td_api::object_ptr<td_api::error> error) {
|
||||
if (id > 0 && GET_VERBOSITY_LEVEL() < VERBOSITY_NAME(td_requests)) {
|
||||
if (id > 0 && combined_log.get_first_verbosity_level() < VERBOSITY_NAME(td_requests)) {
|
||||
LOG(ERROR) << "Receive error [" << generation << "][id=" << id << "] " << to_string(error);
|
||||
}
|
||||
}
|
||||
@ -1561,11 +1556,11 @@ class CliClient final : public Actor {
|
||||
}
|
||||
|
||||
static td_api::object_ptr<td_api::Object> execute(td_api::object_ptr<td_api::Function> f) {
|
||||
if (GET_VERBOSITY_LEVEL() < VERBOSITY_NAME(td_requests)) {
|
||||
if (combined_log.get_first_verbosity_level() < VERBOSITY_NAME(td_requests)) {
|
||||
LOG(ERROR) << "Execute request: " << to_string(f);
|
||||
}
|
||||
auto res = ClientActor::execute(std::move(f));
|
||||
if (GET_VERBOSITY_LEVEL() < VERBOSITY_NAME(td_requests)) {
|
||||
if (combined_log.get_first_verbosity_level() < VERBOSITY_NAME(td_requests)) {
|
||||
LOG(ERROR) << "Execute response: " << to_string(res);
|
||||
}
|
||||
return res;
|
||||
@ -4165,12 +4160,10 @@ class CliClient final : public Actor {
|
||||
<< ", user ticks = " << stats.process_user_ticks_
|
||||
<< ", system ticks = " << stats.process_system_ticks_;
|
||||
}
|
||||
} else if (op == "SetVerbosity" || op == "SV") {
|
||||
Log::set_verbosity_level(to_integer<int>(args));
|
||||
} else if (op[0] == 'v' && op[1] == 'v') {
|
||||
Log::set_verbosity_level(static_cast<int>(op.size()));
|
||||
} else if (op[0] == 'v' && ('0' <= op[1] && op[1] <= '9')) {
|
||||
Log::set_verbosity_level(to_integer<int>(op.substr(1)));
|
||||
} else if (op[0] == 'v' && (op[1] == 'v' || is_digit(op[1]))) {
|
||||
int new_verbosity_level = op[1] == 'v' ? static_cast<int>(op.size()) : to_integer<int>(op.substr(1));
|
||||
SET_VERBOSITY_LEVEL(td::max(new_verbosity_level, VERBOSITY_NAME(DEBUG)));
|
||||
combined_log.set_first_verbosity_level(new_verbosity_level);
|
||||
} else if (op == "slse") {
|
||||
execute(td_api::make_object<td_api::setLogStream>(td_api::make_object<td_api::logStreamEmpty>()));
|
||||
} else if (op == "slsd") {
|
||||
@ -4370,8 +4363,11 @@ static void fail_signal(int sig) {
|
||||
}
|
||||
}
|
||||
|
||||
static void on_fatal_error(const char *error) {
|
||||
std::cerr << "Fatal error: " << error << std::endl;
|
||||
static void on_log_message(int verbosity_level, const char *message) {
|
||||
if (verbosity_level == 0) {
|
||||
std::cerr << "Fatal error: " << message;
|
||||
}
|
||||
std::cerr << "Log message: " << message;
|
||||
}
|
||||
|
||||
void main(int argc, char **argv) {
|
||||
@ -4380,7 +4376,7 @@ void main(int argc, char **argv) {
|
||||
ignore_signal(SignalType::Pipe).ensure();
|
||||
set_signal_handler(SignalType::Error, fail_signal).ensure();
|
||||
set_signal_handler(SignalType::Abort, fail_signal).ensure();
|
||||
Log::set_fatal_error_callback(on_fatal_error);
|
||||
ClientManager::set_log_message_callback(0, on_log_message);
|
||||
init_openssl_threads();
|
||||
|
||||
const char *locale_name = (std::setlocale(LC_ALL, "fr-FR") == nullptr ? "C" : "fr-FR");
|
||||
@ -4393,11 +4389,14 @@ void main(int argc, char **argv) {
|
||||
};
|
||||
|
||||
CliLog cli_log;
|
||||
log_interface = &cli_log;
|
||||
|
||||
FileLog file_log;
|
||||
TsLog ts_log(&file_log);
|
||||
|
||||
combined_log.set_first(&cli_log);
|
||||
|
||||
log_interface = &combined_log;
|
||||
|
||||
int new_verbosity_level = VERBOSITY_NAME(INFO);
|
||||
bool use_test_dc = false;
|
||||
bool get_chat_list = false;
|
||||
@ -4432,7 +4431,7 @@ void main(int argc, char **argv) {
|
||||
options.add_option('l', "log", "Log to file", [&](Slice file_name) {
|
||||
if (file_log.init(file_name.str()).is_ok() && file_log.init(file_name.str()).is_ok() &&
|
||||
file_log.init(file_name.str(), 1000 << 20).is_ok()) {
|
||||
log_interface = &ts_log;
|
||||
combined_log.set_first(&ts_log);
|
||||
}
|
||||
});
|
||||
options.add_option('W', "", "Preload chat list", [&] { get_chat_list = true; });
|
||||
@ -4454,7 +4453,15 @@ void main(int argc, char **argv) {
|
||||
return;
|
||||
}
|
||||
|
||||
SET_VERBOSITY_LEVEL(new_verbosity_level);
|
||||
SET_VERBOSITY_LEVEL(td::max(new_verbosity_level, VERBOSITY_NAME(DEBUG)));
|
||||
combined_log.set_first_verbosity_level(new_verbosity_level);
|
||||
|
||||
if (combined_log.get_first() == &cli_log) {
|
||||
file_log.init("tg_cli.log", 1000 << 20).ensure();
|
||||
file_log.lazy_rotate();
|
||||
combined_log.set_second(&ts_log);
|
||||
combined_log.set_second_verbosity_level(VERBOSITY_NAME(DEBUG));
|
||||
}
|
||||
|
||||
{
|
||||
ConcurrentScheduler scheduler;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/ScopeGuard.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/StackAllocator.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "td/utils/port/path.h"
|
||||
#include "td/utils/port/Stat.h"
|
||||
#include "td/utils/ScopeGuard.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/UInt.h"
|
||||
|
||||
#include <tuple>
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "td/utils/port/path.h"
|
||||
#include "td/utils/port/Stat.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/filesystem.h"
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "td/utils/port/FileFd.h"
|
||||
#include "td/utils/port/path.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
|
||||
#include <tuple>
|
||||
@ -66,9 +67,9 @@ Result<std::pair<FileFd, string>> open_temp_file(FileType file_type) {
|
||||
pmc->set("tmp_file_id", to_string(file_id + 1));
|
||||
|
||||
auto temp_dir = get_files_temp_dir(file_type);
|
||||
auto res = try_create_new_file(PSLICE_SAFE() << temp_dir << file_id);
|
||||
auto res = try_create_new_file(PSLICE() << temp_dir << file_id);
|
||||
if (res.is_error()) {
|
||||
res = try_create_new_file(PSLICE_SAFE() << temp_dir << file_id << "_" << RandSuff{6});
|
||||
res = try_create_new_file(PSLICE() << temp_dir << file_id << "_" << RandSuff{6});
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@ -88,20 +89,20 @@ bool for_suggested_file_name(CSlice name, bool use_pmc, bool use_random, F &&cal
|
||||
auto ext = path_view.extension();
|
||||
bool active = true;
|
||||
if (!stem.empty() && !G()->parameters().ignore_file_names) {
|
||||
active = try_callback(PSLICE_SAFE() << stem << Ext{ext});
|
||||
active = try_callback(PSLICE() << stem << Ext{ext});
|
||||
for (int i = 0; active && i < 10; i++) {
|
||||
active = try_callback(PSLICE_SAFE() << stem << "_(" << i << ")" << Ext{ext});
|
||||
active = try_callback(PSLICE() << stem << "_(" << i << ")" << Ext{ext});
|
||||
}
|
||||
for (int i = 2; active && i < 12 && use_random; i++) {
|
||||
active = try_callback(PSLICE_SAFE() << stem << "_(" << RandSuff{i} << ")" << Ext{ext});
|
||||
active = try_callback(PSLICE() << stem << "_(" << RandSuff{i} << ")" << Ext{ext});
|
||||
}
|
||||
} else if (use_pmc) {
|
||||
auto pmc = G()->td_db()->get_binlog_pmc();
|
||||
int32 file_id = to_integer<int32>(pmc->get("perm_file_id"));
|
||||
pmc->set("perm_file_id", to_string(file_id + 1));
|
||||
active = try_callback(PSLICE_SAFE() << "file_" << file_id << Ext{ext});
|
||||
active = try_callback(PSLICE() << "file_" << file_id << Ext{ext});
|
||||
if (active) {
|
||||
active = try_callback(PSLICE_SAFE() << "file_" << file_id << "_" << RandSuff{6} << Ext{ext});
|
||||
active = try_callback(PSLICE() << "file_" << file_id << "_" << RandSuff{6} << Ext{ext});
|
||||
}
|
||||
}
|
||||
return active;
|
||||
@ -112,7 +113,7 @@ Result<string> create_from_temp(CSlice temp_path, CSlice dir, CSlice name) {
|
||||
<< temp_path;
|
||||
Result<std::pair<FileFd, string>> res = Status::Error(500, "Can't find suitable file name");
|
||||
for_suggested_file_name(name, true, true, [&](CSlice suggested_name) {
|
||||
res = try_create_new_file(PSLICE_SAFE() << dir << suggested_name);
|
||||
res = try_create_new_file(PSLICE() << dir << suggested_name);
|
||||
return res.is_error();
|
||||
});
|
||||
TRY_RESULT(tmp, std::move(res));
|
||||
@ -125,7 +126,7 @@ Result<string> create_from_temp(CSlice temp_path, CSlice dir, CSlice name) {
|
||||
Result<string> search_file(CSlice dir, CSlice name, int64 expected_size) {
|
||||
Result<std::string> res = Status::Error(500, "Can't find suitable file name");
|
||||
for_suggested_file_name(name, false, false, [&](CSlice suggested_name) {
|
||||
auto r_pair = try_open_file(PSLICE_SAFE() << dir << suggested_name);
|
||||
auto r_pair = try_open_file(PSLICE() << dir << suggested_name);
|
||||
if (r_pair.is_error()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "td/utils/port/path.h"
|
||||
#include "td/utils/port/Stat.h"
|
||||
#include "td/utils/ScopeGuard.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
#include "td/utils/Time.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "td/utils/port/path.h"
|
||||
#include "td/utils/port/Stat.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/Time.h"
|
||||
#include "td/utils/tl_parsers.h"
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
#include <limits>
|
||||
#include <numeric>
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/StorerBase.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
|
@ -9,9 +9,9 @@
|
||||
#include "td/utils/algorithm.h"
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/HttpUrl.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/utf8.h"
|
||||
|
||||
#include <cstring>
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/port/RwMutex.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "td/utils/port/IPAddress.h"
|
||||
#include "td/utils/Random.h"
|
||||
#include "td/utils/ScopeGuard.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Time.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "td/utils/algorithm.h"
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
#include "td/utils/as.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
|
@ -25,7 +25,7 @@ NetQueryPtr NetQueryCreator::create(const telegram_api::Function &function, DcId
|
||||
|
||||
NetQueryPtr NetQueryCreator::create(uint64 id, const telegram_api::Function &function, DcId dc_id, NetQuery::Type type,
|
||||
NetQuery::AuthFlag auth_flag) {
|
||||
LOG(DEBUG) << "Create query " << to_string(function);
|
||||
LOG(INFO) << "Create query " << to_string(function);
|
||||
auto storer = DefaultStorer<telegram_api::Function>(function);
|
||||
BufferSlice slice(storer.size());
|
||||
auto real_size = storer.store(slice.as_slice().ubegin());
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/port/thread.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Time.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
|
||||
namespace td {
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user