Apply tdlight patch
This commit is contained in:
parent
b41f3219dc
commit
13648d1fca
50
.github/workflows/build.yaml
vendored
Normal file
50
.github/workflows/build.yaml
vendored
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
name: Build TDLib
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * 0' # weekly
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
arch: [linux/386, linux/amd64, linux/arm/v6, linux/arm/v7, linux/arm64, linux/ppc64le]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Setup variables
|
||||||
|
run: |
|
||||||
|
ARCH=${{ matrix.arch }}
|
||||||
|
SAFE_ARCH=$(echo $ARCH | sed 's/\//\-/g')
|
||||||
|
echo "SAFE_ARCH=$SAFE_ARCH" >> $GITHUB_ENV
|
||||||
|
- name: Install sudo package
|
||||||
|
run: |
|
||||||
|
(apt-get update || true) 2>/dev/null
|
||||||
|
(apt-get install -y sudo || true) 2>/dev/null
|
||||||
|
sudo apt update
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: "recursive"
|
||||||
|
- name: Cache ccache
|
||||||
|
id: cache-ccache
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ~/.ccache
|
||||||
|
key: ${{ runner.os }}-${{ env.SAFE_ARCH }}-ccache-all
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-${{ env.SAFE_ARCH }}-ccache-
|
||||||
|
- name: Install build tools
|
||||||
|
run: sudo apt-get install -y make git zlib1g-dev libssl-dev gperf php-cli cmake clang-6.0 libc++-dev libc++abi-dev ccache
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
CXXFLAGS="-stdlib=libc++" CC=/usr/bin/clang-10 CXX=/usr/bin/clang++-10 cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=../tdlib ..
|
||||||
|
cmake --build . --target install -- -j4
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: tdlight-${{ env.SAFE_ARCH }}
|
||||||
|
path: tdlib/lib
|
||||||
|
|
8
.gitignore
vendored
8
.gitignore
vendored
@ -4,4 +4,12 @@
|
|||||||
**/auto/
|
**/auto/
|
||||||
docs/
|
docs/
|
||||||
tdlib/
|
tdlib/
|
||||||
|
.idea/
|
||||||
vcpkg/
|
vcpkg/
|
||||||
|
*.tlo
|
||||||
|
|
||||||
|
td.binlog
|
||||||
|
|
||||||
|
tg_cli.log
|
||||||
|
|
||||||
|
tg_cli.log.old
|
||||||
|
@ -1024,7 +1024,7 @@ Changes in 1.5.0 (9 Sep 2019):
|
|||||||
* Added the class `chatEventPollStopped` representing the closing of a poll in a message in the chat event log.
|
* Added the class `chatEventPollStopped` representing the closing of a poll in a message in the chat event log.
|
||||||
* Added ability to specify the exact types of problems with a call in the method `sendCallRating` and
|
* Added ability to specify the exact types of problems with a call in the method `sendCallRating` and
|
||||||
the new class `CallProblem`.
|
the new class `CallProblem`.
|
||||||
* Changes in [tdweb](https://github.com/tdlib/td/blob/master/example/web/):
|
* Changes in [tdweb](https://github.com/tdlight-team/tdlight/blob/master/example/web/):
|
||||||
- Supported non-zero `offset` and `limit` in `readFilePart`.
|
- Supported non-zero `offset` and `limit` in `readFilePart`.
|
||||||
|
|
||||||
-----------------------------------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------------------------------
|
||||||
@ -1034,7 +1034,7 @@ Changes in 1.4.0 (1 May 2019):
|
|||||||
* Added a [TDLib build instructions generator](https://tdlib.github.io/td/build.html), covering in details
|
* Added a [TDLib build instructions generator](https://tdlib.github.io/td/build.html), covering in details
|
||||||
TDLib building on the most popular operating systems.
|
TDLib building on the most popular operating systems.
|
||||||
* Added an example of TDLib building and usage from a browser.
|
* Added an example of TDLib building and usage from a browser.
|
||||||
See https://github.com/tdlib/td/blob/master/example/web/ for more details.
|
See https://github.com/tdlight-team/tdlight/blob/master/example/web/ for more details.
|
||||||
* Allowed to pass NULL pointer to `td_json_client_execute` instead of a previously created JSON client.
|
* Allowed to pass NULL pointer to `td_json_client_execute` instead of a previously created JSON client.
|
||||||
Now you can use synchronous TDLib methods through a JSON interface before creating a TDLib JSON client.
|
Now you can use synchronous TDLib methods through a JSON interface before creating a TDLib JSON client.
|
||||||
* Added support for media streaming by allowing to download any part of a file:
|
* Added support for media streaming by allowing to download any part of a file:
|
||||||
@ -1285,7 +1285,7 @@ Changes in 1.4.0 (1 May 2019):
|
|||||||
|
|
||||||
Changes in 1.3.0 (5 Sep 2018):
|
Changes in 1.3.0 (5 Sep 2018):
|
||||||
|
|
||||||
* Added a review of existing TDLib based [frameworks](https://github.com/tdlib/td/blob/master/example/README.md)
|
* Added a review of existing TDLib based [frameworks](https://github.com/tdlight-team/tdlight/blob/master/example/README.md)
|
||||||
in different programming languages.
|
in different programming languages.
|
||||||
* Added a [Getting started](https://core.telegram.org/tdlib/getting-started) guide describing the main TDLib concepts
|
* Added a [Getting started](https://core.telegram.org/tdlib/getting-started) guide describing the main TDLib concepts
|
||||||
and basic principles required for library usage.
|
and basic principles required for library usage.
|
||||||
|
@ -207,9 +207,13 @@ add_subdirectory(sqlite)
|
|||||||
|
|
||||||
add_subdirectory(tddb)
|
add_subdirectory(tddb)
|
||||||
|
|
||||||
add_subdirectory(test)
|
option(TD_SKIP_TEST "Use \"ON\" to skip building/running the test harness.")
|
||||||
|
if (NOT TD_SKIP_TEST)
|
||||||
|
add_subdirectory(test)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (NOT CMAKE_CROSSCOMPILING)
|
option(TD_SKIP_BENCHMARK "Use \"ON\" to skip building/running the benchmarks.")
|
||||||
|
if (NOT CMAKE_CROSSCOMPILING AND NOT TD_SKIP_BENCHMARK)
|
||||||
add_subdirectory(benchmark)
|
add_subdirectory(benchmark)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -505,6 +509,7 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/StickersManager.cpp
|
td/telegram/StickersManager.cpp
|
||||||
td/telegram/StickerType.cpp
|
td/telegram/StickerType.cpp
|
||||||
td/telegram/StorageManager.cpp
|
td/telegram/StorageManager.cpp
|
||||||
|
td/telegram/MemoryManager.cpp
|
||||||
td/telegram/StoryContent.cpp
|
td/telegram/StoryContent.cpp
|
||||||
td/telegram/StoryContentType.cpp
|
td/telegram/StoryContentType.cpp
|
||||||
td/telegram/StoryDb.cpp
|
td/telegram/StoryDb.cpp
|
||||||
@ -850,6 +855,7 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/StickersManager.h
|
td/telegram/StickersManager.h
|
||||||
td/telegram/StickerType.h
|
td/telegram/StickerType.h
|
||||||
td/telegram/StorageManager.h
|
td/telegram/StorageManager.h
|
||||||
|
td/telegram/MemoryManager.h
|
||||||
td/telegram/StoryContent.h
|
td/telegram/StoryContent.h
|
||||||
td/telegram/StoryContentType.h
|
td/telegram/StoryContentType.h
|
||||||
td/telegram/StoryDb.h
|
td/telegram/StoryDb.h
|
||||||
@ -1124,6 +1130,8 @@ endif()
|
|||||||
|
|
||||||
#EXECUTABLES
|
#EXECUTABLES
|
||||||
if (NOT CMAKE_CROSSCOMPILING)
|
if (NOT CMAKE_CROSSCOMPILING)
|
||||||
|
option(TD_SKIP_TG_CLI "Use \"ON\" to skip building tg_cli.")
|
||||||
|
if (NOT CMAKE_CROSSCOMPILING AND NOT TD_SKIP_TG_CLI)
|
||||||
add_executable(tg_cli td/telegram/cli.cpp ${TL_TD_JSON_SOURCE})
|
add_executable(tg_cli td/telegram/cli.cpp ${TL_TD_JSON_SOURCE})
|
||||||
|
|
||||||
if (NOT READLINE_FOUND)
|
if (NOT READLINE_FOUND)
|
||||||
@ -1152,6 +1160,7 @@ if (NOT CMAKE_CROSSCOMPILING)
|
|||||||
target_link_libraries(tg_cli PRIVATE memprof tdclient tdcore)
|
target_link_libraries(tg_cli PRIVATE memprof tdclient tdcore)
|
||||||
add_dependencies(tg_cli tl_generate_json)
|
add_dependencies(tg_cli tl_generate_json)
|
||||||
endif()
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
#Exported libraries
|
#Exported libraries
|
||||||
add_library(TdStatic INTERFACE)
|
add_library(TdStatic INTERFACE)
|
||||||
|
54
README.md
54
README.md
@ -1,9 +1,12 @@
|
|||||||
# TDLib
|
# TDLight
|
||||||
|
|
||||||
TDLib (Telegram Database library) is a cross-platform library for building [Telegram](https://telegram.org) clients. It can be easily used from almost any programming language.
|
TDLight is a fork of TDLib, a cross-platform library for building [Telegram](https://telegram.org) clients. It can be easily used from almost any programming language.
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
- [Features](#features)
|
- [Features](#features)
|
||||||
|
- [TDLight extra features](#tdlight-extra-features)
|
||||||
|
- [TDLight extra API functions](#tdlight-extra-api-functions)
|
||||||
|
- [TDLight recommended options](#tdlight-recommended-options)
|
||||||
- [Examples and documentation](#usage)
|
- [Examples and documentation](#usage)
|
||||||
- [Dependencies](#dependencies)
|
- [Dependencies](#dependencies)
|
||||||
- [Building](#building)
|
- [Building](#building)
|
||||||
@ -28,17 +31,42 @@ TDLib (Telegram Database library) is a cross-platform library for building [Tele
|
|||||||
* **Secure**: all local data is encrypted using a user-provided encryption key.
|
* **Secure**: all local data is encrypted using a user-provided encryption key.
|
||||||
* **Fully-asynchronous**: requests to `TDLib` don't block each other or anything else, responses are sent when they are available.
|
* **Fully-asynchronous**: requests to `TDLib` don't block each other or anything else, responses are sent when they are available.
|
||||||
|
|
||||||
|
<a name="tdlight-extra-features"></a>
|
||||||
|
### TDLight extra features
|
||||||
|
#### TDLight extra options
|
||||||
|
* **disable_minithumbnails** (true/**false**) This setting removes minithumbnails everywhere. It reduces memory usage because tdlib keeps them in RAM
|
||||||
|
* **disable_document_filenames** (true/**false**) If you don't care about having the original filenames of every file stored in RAM, you can disable them using this option. It reduces memory usage
|
||||||
|
* **disable_notifications** (true/**false**) In TDLib pending notification updates are stored in ram until you "read" them. This option disables completely notifications and keeps the pending notifications queue empty, reducing memory usage
|
||||||
|
* **ignore_update_chat_last_message** (true/**false**) If you don't care about have updateChatLastMessage updates enable this
|
||||||
|
* **ignore_update_chat_read_inbox** (true/**false**) If you don't care about have updateChatReadInbox updates enable this
|
||||||
|
* **ignore_update_user_chat_action** (true/**false**) If you don't care about have updateUserChatAction updates enable this
|
||||||
|
* **ignore_server_deletes_and_reads** (true/**false**) If you don't care about receiving read receipts and remote deletes from other users, enable this, it will reduce memory usage
|
||||||
|
* **receive_access_hashes** (true/**false**) Receive chats and users access hash as updates
|
||||||
|
* **disable_auto_download** (true/**false**) Forcefully ignore auto download settings of all sessions
|
||||||
|
<a name="tdlight-extra-api-functions"></a>
|
||||||
|
### TDLight extra API functions
|
||||||
|
#### TdApi.GetMemoryStatistics
|
||||||
|
This method is used to read the size of all the internal TDLib data structures.
|
||||||
|
The output contains a string that can be parsed as a JSON.
|
||||||
|
<a name="tdlight-recommended-options"></a>
|
||||||
|
## TDLight recommended options
|
||||||
|
* Options:
|
||||||
|
* ignore_inline_thumbnails: true
|
||||||
|
* disable_top_chats: true
|
||||||
|
* ignore_platform_restrictions: true
|
||||||
|
* ignore_sensitive_content_restrictions: true
|
||||||
|
* Disable all the databases (messages_db, users_db, files_db)
|
||||||
<a name="usage"></a>
|
<a name="usage"></a>
|
||||||
## Examples and documentation
|
## Examples and documentation
|
||||||
See our [Getting Started](https://core.telegram.org/tdlib/getting-started) tutorial for a description of basic TDLib concepts.
|
See our [Getting Started](https://core.telegram.org/tdlib/getting-started) tutorial for a description of basic TDLib concepts.
|
||||||
|
|
||||||
Take a look at our [examples](https://github.com/tdlib/td/blob/master/example/README.md#tdlib-usage-and-build-examples).
|
Take a look at our [examples](https://github.com/tdlight-team/tdlight/blob/master/example/README.md#tdlib-usage-and-build-examples).
|
||||||
|
|
||||||
See a [TDLib build instructions generator](https://tdlib.github.io/td/build.html) for detailed instructions on how to build TDLib.
|
See a [TDLight build instructions generator](https://tdlight-team.github.io/tdlight/build.html) for detailed instructions on how to build TDLib.
|
||||||
|
|
||||||
See description of our [JSON](#using-json), [C++](#using-cxx), [Java](#using-java) and [.NET](#using-dotnet) interfaces.
|
See description of our [JSON](#using-json), [C++](#using-cxx), [Java](#using-java) and [.NET](#using-dotnet) interfaces.
|
||||||
|
|
||||||
See the [td_api.tl](https://github.com/tdlib/td/blob/master/td/generate/scheme/td_api.tl) scheme or the automatically generated [HTML documentation](https://core.telegram.org/tdlib/docs/td__api_8h.html)
|
See the [td_api.tl](https://github.com/tdlight-team/tdlight/blob/master/td/generate/scheme/td_api.tl) scheme or the automatically generated [HTML documentation](https://core.telegram.org/tdlib/docs/td__api_8h.html)
|
||||||
for a list of all available `TDLib` [methods](https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_function.html) and [classes](https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_object.html).
|
for a list of all available `TDLib` [methods](https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_function.html) and [classes](https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_object.html).
|
||||||
|
|
||||||
<a name="dependencies"></a>
|
<a name="dependencies"></a>
|
||||||
@ -55,7 +83,7 @@ for a list of all available `TDLib` [methods](https://core.telegram.org/tdlib/do
|
|||||||
<a name="building"></a>
|
<a name="building"></a>
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
The simplest way to build `TDLib` is to use our [TDLib build instructions generator](https://tdlib.github.io/td/build.html).
|
The simplest way to build `TDLight` is to use our [TDLight build instructions generator](https://tdlight-team.github.io/tdlight/build.html).
|
||||||
You need only to choose your programming language and target operating system to receive complete build instructions.
|
You need only to choose your programming language and target operating system to receive complete build instructions.
|
||||||
|
|
||||||
In general, you need to install all `TDLib` [dependencies](#dependencies), enter directory containing `TDLib` sources and compile them using CMake:
|
In general, you need to install all `TDLib` [dependencies](#dependencies), enter directory containing `TDLib` sources and compile them using CMake:
|
||||||
@ -67,7 +95,7 @@ cmake -DCMAKE_BUILD_TYPE=Release ..
|
|||||||
cmake --build .
|
cmake --build .
|
||||||
```
|
```
|
||||||
|
|
||||||
To build `TDLib` on low memory devices you can run [SplitSource.php](https://github.com/tdlib/td/blob/master/SplitSource.php) script
|
To build `TDLib` on low memory devices you can run [SplitSource.php](https://github.com/tdlight-team/tdlight/blob/master/SplitSource.php) script
|
||||||
before compiling main `TDLib` source code and compile only needed targets:
|
before compiling main `TDLib` source code and compile only needed targets:
|
||||||
```
|
```
|
||||||
mkdir build
|
mkdir build
|
||||||
@ -106,21 +134,21 @@ Or you could install `TDLib` and then reference it in your CMakeLists.txt like t
|
|||||||
find_package(Td 1.8.26 REQUIRED)
|
find_package(Td 1.8.26 REQUIRED)
|
||||||
target_link_libraries(YourTarget PRIVATE Td::TdStatic)
|
target_link_libraries(YourTarget PRIVATE Td::TdStatic)
|
||||||
```
|
```
|
||||||
See [example/cpp/CMakeLists.txt](https://github.com/tdlib/td/blob/master/example/cpp/CMakeLists.txt).
|
See [example/cpp/CMakeLists.txt](https://github.com/tdlight-team/tdlight/blob/master/example/cpp/CMakeLists.txt).
|
||||||
|
|
||||||
<a name="using-java"></a>
|
<a name="using-java"></a>
|
||||||
## Using in Java projects
|
## Using in Java projects
|
||||||
`TDLib` provides native Java interface through JNI. To enable it, specify option `-DTD_ENABLE_JNI=ON` to CMake.
|
`TDLib` provides native Java interface through JNI. To enable it, specify option `-DTD_ENABLE_JNI=ON` to CMake.
|
||||||
|
|
||||||
See [example/java](https://github.com/tdlib/td/tree/master/example/java) for example of using `TDLib` from Java and detailed build and usage instructions.
|
See [example/java](https://github.com/tdlight-team/tdlight/tree/master/example/java) for example of using `TDLib` from Java and detailed build and usage instructions.
|
||||||
|
|
||||||
<a name="using-dotnet"></a>
|
<a name="using-dotnet"></a>
|
||||||
## Using in .NET projects
|
## Using in .NET projects
|
||||||
`TDLib` provides native .NET interface through `C++/CLI` and `C++/CX`. To enable it, specify option `-DTD_ENABLE_DOTNET=ON` to CMake.
|
`TDLib` provides native .NET interface through `C++/CLI` and `C++/CX`. To enable it, specify option `-DTD_ENABLE_DOTNET=ON` to CMake.
|
||||||
.NET Core supports `C++/CLI` only since version 3.1 and only on Windows, so if older .NET Core is used or portability is needed, then `TDLib` JSON interface should be used through P/Invoke instead.
|
.NET Core supports `C++/CLI` only since version 3.1 and only on Windows, so if older .NET Core is used or portability is needed, then `TDLib` JSON interface should be used through P/Invoke instead.
|
||||||
|
|
||||||
See [example/csharp](https://github.com/tdlib/td/tree/master/example/csharp) for example of using `TDLib` from C# and detailed build and usage instructions.
|
See [example/csharp](https://github.com/tdlight-team/tdlight/tree/master/example/csharp) for example of using `TDLib` from C# and detailed build and usage instructions.
|
||||||
See [example/uwp](https://github.com/tdlib/td/tree/master/example/uwp) for example of using `TDLib` from C# UWP application and detailed build and usage instructions for Visual Studio Extension "TDLib for Universal Windows Platform".
|
See [example/uwp](https://github.com/tdlight-team/tdlight/tree/master/example/uwp) for example of using `TDLib` from C# UWP application and detailed build and usage instructions for Visual Studio Extension "TDLib for Universal Windows Platform".
|
||||||
|
|
||||||
When `TDLib` is built with `TD_ENABLE_DOTNET` option enabled, `C++` documentation is removed from some files. You need to checkout these files to return `C++` documentation back:
|
When `TDLib` is built with `TD_ENABLE_DOTNET` option enabled, `C++` documentation is removed from some files. You need to checkout these files to return `C++` documentation back:
|
||||||
```
|
```
|
||||||
@ -132,13 +160,13 @@ git checkout td/telegram/Client.h td/telegram/Log.h td/tl/TlObject.h
|
|||||||
`TDLib` provides efficient native C++, Java, and .NET interfaces.
|
`TDLib` provides efficient native C++, Java, and .NET interfaces.
|
||||||
But for most use cases we suggest to use the JSON interface, which can be easily used with any programming language that is able to execute C functions.
|
But for most use cases we suggest to use the JSON interface, which can be easily used with any programming language that is able to execute C functions.
|
||||||
See [td_json_client](https://core.telegram.org/tdlib/docs/td__json__client_8h.html) documentation for detailed JSON interface description,
|
See [td_json_client](https://core.telegram.org/tdlib/docs/td__json__client_8h.html) documentation for detailed JSON interface description,
|
||||||
the [td_api.tl](https://github.com/tdlib/td/blob/master/td/generate/scheme/td_api.tl) scheme or the automatically generated [HTML documentation](https://core.telegram.org/tdlib/docs/td__api_8h.html) for a list of
|
the [td_api.tl](https://github.com/tdlight-team/tdlight/blob/master/td/generate/scheme/td_api.tl) scheme or the automatically generated [HTML documentation](https://core.telegram.org/tdlib/docs/td__api_8h.html) for a list of
|
||||||
all available `TDLib` [methods](https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_function.html) and [classes](https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_object.html).
|
all available `TDLib` [methods](https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_function.html) and [classes](https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_object.html).
|
||||||
|
|
||||||
`TDLib` JSON interface adheres to semantic versioning and versions with the same major version number are binary and backward compatible, but the underlying `TDLib` API can be different for different minor and even patch versions.
|
`TDLib` JSON interface adheres to semantic versioning and versions with the same major version number are binary and backward compatible, but the underlying `TDLib` API can be different for different minor and even patch versions.
|
||||||
If you need to support different `TDLib` versions, then you can use a value of the `version` option to find exact `TDLib` version to use appropriate API methods.
|
If you need to support different `TDLib` versions, then you can use a value of the `version` option to find exact `TDLib` version to use appropriate API methods.
|
||||||
|
|
||||||
See [example/python/tdjson_example.py](https://github.com/tdlib/td/blob/master/example/python/tdjson_example.py) for an example of such usage.
|
See [example/python/tdjson_example.py](https://github.com/tdlight-team/tdlight/tree/master/example/python/tdjson_example.py) for an example of such usage.
|
||||||
|
|
||||||
<a name="license"></a>
|
<a name="license"></a>
|
||||||
## License
|
## License
|
||||||
|
50
build.html
50
build.html
@ -2,7 +2,7 @@
|
|||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>TDLib build instructions</title>
|
<title>TDLight build instructions</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
@ -193,7 +193,7 @@
|
|||||||
|
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<div id="languageSelectDiv">
|
<div id="languageSelectDiv">
|
||||||
<p>Choose a programming language from which you want to use TDLib:</p>
|
<p>Choose a programming language from which you want to use TDLight:</p>
|
||||||
<select id="languageSelect" onchange="onLanguageChanged(false)" autofocus class="large">
|
<select id="languageSelect" onchange="onLanguageChanged(false)" autofocus class="large">
|
||||||
<option>Choose a programming language:</option>
|
<option>Choose a programming language:</option>
|
||||||
<option>Python</option>
|
<option>Python</option>
|
||||||
@ -226,7 +226,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="osSelectDiv" class="hide">
|
<div id="osSelectDiv" class="hide">
|
||||||
<p>Choose an operating system on which you want to use TDLib:</p>
|
<p>Choose an operating system on which you want to use TDLight:</p>
|
||||||
<select id="osSelect" onchange="onOsChanged()" class="large">
|
<select id="osSelect" onchange="onOsChanged()" class="large">
|
||||||
<option>Choose an operating system:</option>
|
<option>Choose an operating system:</option>
|
||||||
</select>
|
</select>
|
||||||
@ -234,7 +234,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="linuxSelectDiv" class="hide">
|
<div id="linuxSelectDiv" class="hide">
|
||||||
<p>Choose a Linux distro on which you want to use TDLib:</p>
|
<p>Choose a Linux distro on which you want to use TDLight:</p>
|
||||||
<select id="linuxSelect" onchange="onOsChanged()" class="large">
|
<select id="linuxSelect" onchange="onOsChanged()" class="large">
|
||||||
<option>Choose a Linux distro:</option>
|
<option>Choose a Linux distro:</option>
|
||||||
<option>Alpine</option>
|
<option>Alpine</option>
|
||||||
@ -263,13 +263,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="buildInstallLocalDiv" class="hide">
|
<div id="buildInstallLocalDiv" class="hide">
|
||||||
<label><input type="checkbox" id="buildInstallLocalCheckbox" onchange="onOptionsChanged()"/>Install built TDLib to /usr/local instead of placing the files to td/tdlib.</label>
|
<label><input type="checkbox" id="buildInstallLocalCheckbox" onchange="onOptionsChanged()"/>Install built TDLight to /usr/local instead of placing the files to td/tdlib.</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p></p>
|
<p></p>
|
||||||
|
|
||||||
<div id="buildCompilerDiv" class="hide">
|
<div id="buildCompilerDiv" class="hide">
|
||||||
<span>Choose which compiler you want to use to build TDLib:</span><br>
|
<span>Choose which compiler you want to use to build TDLight:</span><br>
|
||||||
<label><input type="radio" id="buildCompilerRadioGcc" name="buildCompilerRadio" onchange="onOptionsChanged()" checked/>g++</label>
|
<label><input type="radio" id="buildCompilerRadioGcc" name="buildCompilerRadio" onchange="onOptionsChanged()" checked/>g++</label>
|
||||||
<label><input type="radio" id="buildCompilerRadioClang" name="buildCompilerRadio" onchange="onOptionsChanged()"/>clang (recommended)</label>
|
<label><input type="radio" id="buildCompilerRadioClang" name="buildCompilerRadio" onchange="onOptionsChanged()"/>clang (recommended)</label>
|
||||||
<p></p>
|
<p></p>
|
||||||
@ -305,7 +305,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="buildBitnessDiv" class="hide">
|
<div id="buildBitnessDiv" class="hide">
|
||||||
<span>Choose for which bitness you want to build TDLib:</span><br>
|
<span>Choose for which bitness you want to build TDLight:</span><br>
|
||||||
<label><input type="radio" id="buildBitnessRadio32" name="buildBitnessRadio" onchange="onOptionsChanged()" checked/>32</label>
|
<label><input type="radio" id="buildBitnessRadio32" name="buildBitnessRadio" onchange="onOptionsChanged()" checked/>32</label>
|
||||||
<label><input type="radio" id="buildBitnessRadio64" name="buildBitnessRadio" onchange="onOptionsChanged()"/>64</label>
|
<label><input type="radio" id="buildBitnessRadio64" name="buildBitnessRadio" onchange="onOptionsChanged()"/>64</label>
|
||||||
<p></p>
|
<p></p>
|
||||||
@ -327,7 +327,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="buildCommandsDiv" class="hide">
|
<div id="buildCommandsDiv" class="hide">
|
||||||
<p id="buildCommandsHeader">Here is complete instruction for TDLib binaries building:</p>
|
<p id="buildCommandsHeader">Here is complete instruction for TDLight binaries building:</p>
|
||||||
<p id="buildPre">Hidden text</p>
|
<p id="buildPre">Hidden text</p>
|
||||||
<code id="buildCommands">Empty commands</code>
|
<code id="buildCommands">Empty commands</code>
|
||||||
<button id="copyBuildCommandsButton" onclick="copyBuildInstructions()">
|
<button id="copyBuildCommandsButton" onclick="copyBuildInstructions()">
|
||||||
@ -494,14 +494,14 @@ function getTargetName(target) {
|
|||||||
case 'tdjson':
|
case 'tdjson':
|
||||||
case 'WebAssembly':
|
case 'WebAssembly':
|
||||||
case 'iOS':
|
case 'iOS':
|
||||||
return '<a href="https://github.com/tdlib/td#using-json">JSON</a>';
|
return '<a href="https://github.com/tdlight-team/tdlight#using-json">JSON</a>';
|
||||||
case 'tdclient':
|
case 'tdclient':
|
||||||
return '<a href="https://github.com/tdlib/td#using-cxx">a simple and convenient C++11-interface</a>';
|
return '<a href="https://github.com/tdlight-team/tdlight#using-cxx">a simple and convenient C++11-interface</a>';
|
||||||
case 'JNI':
|
case 'JNI':
|
||||||
case 'Android':
|
case 'Android':
|
||||||
return '<a href="https://github.com/tdlib/td#using-java">native ' + target + '</a>';
|
return '<a href="https://github.com/tdlight-team/tdlight#using-java">native ' + target + '</a>';
|
||||||
default:
|
default:
|
||||||
return '<a href="https://github.com/tdlib/td#using-dotnet">native ' + target + '</a>';
|
return '<a href="https://github.com/tdlight-team/tdlight#using-dotnet">native ' + target + '</a>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -515,17 +515,17 @@ function onOsChanged() {
|
|||||||
if (language === 'Other') {
|
if (language === 'Other') {
|
||||||
language = 'any other programming language';
|
language = 'any other programming language';
|
||||||
}
|
}
|
||||||
var text = 'TDLib can be used from ' + language + ' on ' + os + ' through the ' + getTargetName(target) + ' interface.<br>' +
|
var text = 'TDLight can be used from ' + language + ' on ' + os + ' through the ' + getTargetName(target) + ' interface.<br>' +
|
||||||
'See <a href="https://github.com/tdlib/td/blob/master/example/README.md#' + getExampleAnchor(language) + '">examples</a> of such usage and already available third-party frameworks.<br>';
|
'See <a href="https://github.com/tdlight-team/tdlight/blob/master/example/README.md#' + getExampleAnchor(language) + '">examples</a> of such usage and already available third-party frameworks.<br>';
|
||||||
|
|
||||||
if (target === 'WebAssembly') {
|
if (target === 'WebAssembly') {
|
||||||
text = 'TDLib is available in a prebuilt form as an <a href="https://www.npmjs.com/">NPM</a> package <a href="https://www.npmjs.com/package/tdweb">tdweb</a>.<br>' +
|
text = 'TDLight is available in a prebuilt form as an <a href="https://www.npmjs.com/">NPM</a> package <a href="https://www.npmjs.com/package/tdweb">tdweb</a>.<br>' +
|
||||||
'If you want to build it manually, take a look at our <a href="https://github.com/tdlib/td/tree/master/example/web">example</a>.';
|
'If you want to build it manually, take a look at our <a href="https://github.com/tdlight-team/tdlight/tree/master/example/web">example</a>.';
|
||||||
target = '';
|
target = '';
|
||||||
}
|
}
|
||||||
if (target === 'Android') {
|
if (target === 'Android') {
|
||||||
text = 'TDLib for Android is available in a prebuilt form and can be downloaded from <a href="https://core.telegram.org/tdlib/tdlib.zip">there</a>.<br>' +
|
text = 'TDLight for Android is available in a prebuilt form and can be downloaded from <a href="https://core.telegram.org/tdlight-team/tdlightlib.zip">there</a>.<br>' +
|
||||||
'See <a href="https://github.com/tdlib/td/issues/77#issuecomment-640719893">build instructions</a> if you want to build the latest TDLib version or want to build TDLib with different interface.';
|
'See <a href="https://github.com/tdlight-team/tdlight/issues/77#issuecomment-640719893">build instructions</a> if you want to build the latest TDLight version or want to build TDLight with different interface.';
|
||||||
target = '';
|
target = '';
|
||||||
}
|
}
|
||||||
if (target === 'iOS') {
|
if (target === 'iOS') {
|
||||||
@ -590,7 +590,7 @@ function onOptionsChanged() {
|
|||||||
if (os_linux || os_freebsd || os_netbsd) {
|
if (os_linux || os_freebsd || os_netbsd) {
|
||||||
low_memory = document.getElementById('buildLowMemoryCheckbox').checked;
|
low_memory = document.getElementById('buildLowMemoryCheckbox').checked;
|
||||||
document.getElementById('buildLowMemoryText').innerHTML = 'I have less than ' + (use_clang ? '1.5' : '3.5') +' GB of RAM.' +
|
document.getElementById('buildLowMemoryText').innerHTML = 'I have less than ' + (use_clang ? '1.5' : '3.5') +' GB of RAM.' +
|
||||||
(low_memory ? ' Now you will need only ' + (use_clang ? '0.5' : '1') +' GB of RAM to build TDLib.' : '');
|
(low_memory ? ' Now you will need only ' + (use_clang ? '0.5' : '1') +' GB of RAM to build TDLight.' : '');
|
||||||
document.getElementById('buildLowMemoryDiv').style.display = 'block';
|
document.getElementById('buildLowMemoryDiv').style.display = 'block';
|
||||||
} else {
|
} else {
|
||||||
if (os_openbsd) {
|
if (os_openbsd) {
|
||||||
@ -751,8 +751,8 @@ function onOptionsChanged() {
|
|||||||
pre_text.push('Note that the following instruction is for NetBSD 8+ and default SH shell.');
|
pre_text.push('Note that the following instruction is for NetBSD 8+ and default SH shell.');
|
||||||
}
|
}
|
||||||
if (os_mac) {
|
if (os_mac) {
|
||||||
pre_text.push('Note that the following instruction will build TDLib only for ' + os_mac_host_name + '.');
|
pre_text.push('Note that the following instruction will build TDLight only for ' + os_mac_host_name + '.');
|
||||||
pre_text.push('If you want to create a universal XCFramework, take a look at our <a href="https://github.com/tdlib/td/tree/master/example/ios">example</a> instead.');
|
pre_text.push('If you want to create a universal XCFramework, take a look at our <a href="https://github.com/tdlight-team/tdlight/tree/master/example/ios">example</a> instead.');
|
||||||
}
|
}
|
||||||
|
|
||||||
var terminal_name = (function () {
|
var terminal_name = (function () {
|
||||||
@ -776,12 +776,12 @@ function onOptionsChanged() {
|
|||||||
if (os_windows) {
|
if (os_windows) {
|
||||||
pre_text.push('Close and re-open ' + terminal_name + ' if the PATH environment variable was changed.');
|
pre_text.push('Close and re-open ' + terminal_name + ' if the PATH environment variable was changed.');
|
||||||
}
|
}
|
||||||
pre_text.push('Run these commands in ' + terminal_name + ' to build TDLib and to install it to ' + install_dir + ':');
|
pre_text.push('Run these commands in ' + terminal_name + ' to build TDLight and to install it to ' + install_dir + ':');
|
||||||
document.getElementById('buildPre').innerHTML = '<ul><li>' + pre_text.join('</li><li>') + '</li></ul>';
|
document.getElementById('buildPre').innerHTML = '<ul><li>' + pre_text.join('</li><li>') + '</li></ul>';
|
||||||
document.getElementById('buildPre').style.display = 'block';
|
document.getElementById('buildPre').style.display = 'block';
|
||||||
|
|
||||||
if (install_dir && install_dir !== '/usr/local') {
|
if (install_dir && install_dir !== '/usr/local') {
|
||||||
install_dir = '../tdlib';
|
install_dir = '../tdlight';
|
||||||
if (target === 'JNI' || target === 'C++/CX') {
|
if (target === 'JNI' || target === 'C++/CX') {
|
||||||
install_dir = '../../' + install_dir;
|
install_dir = '../../' + install_dir;
|
||||||
}
|
}
|
||||||
@ -926,9 +926,9 @@ function onOptionsChanged() {
|
|||||||
commands.push('exit');
|
commands.push('exit');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
commands.push('git clone https://github.com/tdlib/td.git');
|
commands.push('git clone https://github.com/tdlight-team/tdlight.git');
|
||||||
|
|
||||||
commands.push('cd td');
|
commands.push('cd tdlight');
|
||||||
// commands.push('git checkout v1.8.0');
|
// commands.push('git checkout v1.8.0');
|
||||||
|
|
||||||
if (use_vcpkg) {
|
if (use_vcpkg) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# TDLib usage and build examples
|
# TDLib usage and build examples
|
||||||
|
|
||||||
This directory contains basic examples of TDLib usage from different programming languages and examples of library building for different platforms.
|
This directory contains basic examples of TDLib usage from different programming languages and examples of library building for different platforms.
|
||||||
If you are looking for documentation of all available TDLib methods, see the [td_api.tl](https://github.com/tdlib/td/blob/master/td/generate/scheme/td_api.tl) scheme or the
|
If you are looking for documentation of all available TDLib methods, see the [td_api.tl](https://github.com/tdlight-team/tdlight/blob/master/td/generate/scheme/td_api.tl) scheme or the
|
||||||
automatically generated [HTML documentation](https://core.telegram.org/tdlib/docs/td__api_8h.html) for a list of all available TDLib
|
automatically generated [HTML documentation](https://core.telegram.org/tdlib/docs/td__api_8h.html) for a list of all available TDLib
|
||||||
[methods](https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_function.html) and [classes](https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_object.html).
|
[methods](https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_function.html) and [classes](https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_object.html).
|
||||||
Also, take a look at our [Getting Started](https://core.telegram.org/tdlib/getting-started) tutorial for a description of basic TDLib concepts.
|
Also, take a look at our [Getting Started](https://core.telegram.org/tdlib/getting-started) tutorial for a description of basic TDLib concepts.
|
||||||
@ -54,13 +54,13 @@ If you want to use TDLib with asyncio and Python >= 3.9, take a look at [aiotdli
|
|||||||
For older Python versions you can use [pytdlib](https://github.com/pytdlib/pytdlib).
|
For older Python versions you can use [pytdlib](https://github.com/pytdlib/pytdlib).
|
||||||
This wrapper contains generator for TDLib API classes and basic interface for interaction with TDLib.
|
This wrapper contains generator for TDLib API classes and basic interface for interaction with TDLib.
|
||||||
|
|
||||||
You can also check out [example/python/tdjson_example.py](https://github.com/tdlib/td/blob/master/example/python/tdjson_example.py),
|
You can also check out [example/python/tdjson_example.py](https://github.com/tdlight-team/tdlight/blob/master/example/python/tdjson_example.py),
|
||||||
[tdlib-python](https://github.com/JunaidBabu/tdlib-python), or [Python Wrapper TDLib](https://github.com/alvhix/pywtdlib) for some basic examples of TDLib JSON interface integration with Python.
|
[tdlib-python](https://github.com/JunaidBabu/tdlib-python), or [Python Wrapper TDLib](https://github.com/alvhix/pywtdlib) for some basic examples of TDLib JSON interface integration with Python.
|
||||||
|
|
||||||
<a name="javascript"></a>
|
<a name="javascript"></a>
|
||||||
## Using TDLib in JavaScript projects
|
## Using TDLib in JavaScript projects
|
||||||
|
|
||||||
TDLib can be compiled to WebAssembly or asm.js and used in a browser from JavaScript. See [tdweb](https://github.com/tdlib/td/tree/master/example/web) as a convenient wrapper for TDLib in a browser
|
TDLib can be compiled to WebAssembly or asm.js and used in a browser from JavaScript. See [tdweb](https://github.com/tdlight-team/tdlight/tree/master/example/web) as a convenient wrapper for TDLib in a browser
|
||||||
and [telegram-react](https://github.com/evgeny-nadymov/telegram-react) as an example of a TDLib-based Telegram client.
|
and [telegram-react](https://github.com/evgeny-nadymov/telegram-react) as an example of a TDLib-based Telegram client.
|
||||||
|
|
||||||
See also [Svelte-tdweb-starter](https://github.com/gennadypolakov/svelte-tdweb-starter) - Svelte wrapper for tdweb, and [Telegram-Photoframe](https://github.com/lukefx/telegram-photoframe) - a web application that displays your preferred group or channel as Photoframe.
|
See also [Svelte-tdweb-starter](https://github.com/gennadypolakov/svelte-tdweb-starter) - Svelte wrapper for tdweb, and [Telegram-Photoframe](https://github.com/lukefx/telegram-photoframe) - a web application that displays your preferred group or channel as Photoframe.
|
||||||
@ -95,7 +95,7 @@ You can also see [github.com/aliforever/go-tdlib](https://github.com/aliforever/
|
|||||||
TDLib can be used from the Java programming language through native [JNI](https://github.com/tdlib/td#using-java) binding.
|
TDLib can be used from the Java programming language through native [JNI](https://github.com/tdlib/td#using-java) binding.
|
||||||
|
|
||||||
We provide a generator for JNI bridge methods and Java classes for all TDLib API methods and objects.
|
We provide a generator for JNI bridge methods and Java classes for all TDLib API methods and objects.
|
||||||
See [example/java](https://github.com/tdlib/td/tree/master/example/java) for an example of using TDLib from desktop Java along with detailed building and usage instructions.
|
See [example/java](https://github.com/tdlight-team/tdlight/tree/master/example/java) for an example of using TDLib from desktop Java along with detailed building and usage instructions.
|
||||||
To use TDLib to create Android Java applications, use our [prebuilt library for Android](https://core.telegram.org/tdlib/tdlib.zip).
|
To use TDLib to create Android Java applications, use our [prebuilt library for Android](https://core.telegram.org/tdlib/tdlib.zip).
|
||||||
|
|
||||||
<a name="kotlin"></a>
|
<a name="kotlin"></a>
|
||||||
@ -112,8 +112,8 @@ See also [td-ktx](https://github.com/tdlibx/td-ktx) - Kotlin coroutines wrapper
|
|||||||
|
|
||||||
TDLib provides a native [.NET](https://github.com/tdlib/td#using-dotnet) interface through `C++/CLI` and `C++/CX`.
|
TDLib provides a native [.NET](https://github.com/tdlib/td#using-dotnet) interface through `C++/CLI` and `C++/CX`.
|
||||||
See [tdlib-netcore](https://github.com/dantmnf/tdlib-netcore) for a SWIG-like binding with automatically generated classes for TDLib API.
|
See [tdlib-netcore](https://github.com/dantmnf/tdlib-netcore) for a SWIG-like binding with automatically generated classes for TDLib API.
|
||||||
See [example/uwp](https://github.com/tdlib/td/tree/master/example/uwp) for an example of building TDLib SDK for the Universal Windows Platform and an example of its usage from C#.
|
See [example/uwp](https://github.com/tdlight-team/tdlight/tree/master/example/uwp) for an example of building TDLib SDK for the Universal Windows Platform and an example of its usage from C#.
|
||||||
See [example/csharp](https://github.com/tdlib/td/tree/master/example/csharp) for an example of building TDLib with `C++/CLI` support and an example of TDLib usage from C# on Windows.
|
See [example/csharp](https://github.com/tdlight-team/tdlight/tree/master/example/csharp) for an example of building TDLib with `C++/CLI` support and an example of TDLib usage from C# on Windows.
|
||||||
|
|
||||||
If you want to write a cross-platform C# application using .NET Core, see [tdsharp](https://github.com/egramtel/tdsharp). It uses our [JSON](https://github.com/tdlib/td#using-json) interface,
|
If you want to write a cross-platform C# application using .NET Core, see [tdsharp](https://github.com/egramtel/tdsharp). It uses our [JSON](https://github.com/tdlib/td#using-json) interface,
|
||||||
provides an asynchronous interface for interaction with TDLib, automatically generated classes for TDLib API and has some examples.
|
provides an asynchronous interface for interaction with TDLib, automatically generated classes for TDLib API and has some examples.
|
||||||
@ -127,8 +127,8 @@ Also, see [Unigram](https://github.com/UnigramDev/Unigram), which is a full-feat
|
|||||||
|
|
||||||
TDLib has a simple and convenient C++11-interface for sending and receiving requests and can be statically linked to your application.
|
TDLib has a simple and convenient C++11-interface for sending and receiving requests and can be statically linked to your application.
|
||||||
|
|
||||||
See [example/cpp](https://github.com/tdlib/td/tree/master/example/cpp) for an example of TDLib usage from C++.
|
See [example/cpp](https://github.com/tdlight-team/tdlight/tree/master/example/cpp) for an example of TDLib usage from C++.
|
||||||
[td_example.cpp](https://github.com/tdlib/td/blob/master/example/cpp/td_example.cpp) contains an example of authorization, processing new incoming messages, getting a list of chats and sending a text message.
|
[td_example.cpp](https://github.com/tdlight-team/tdlight/blob/master/example/cpp/td_example.cpp) contains an example of authorization, processing new incoming messages, getting a list of chats and sending a text message.
|
||||||
|
|
||||||
See also the source code of [Fernschreiber](https://github.com/Wunderfitz/harbour-fernschreiber) and [Depecher](https://github.com/blacksailer/depecher) – Telegram apps for Sailfish OS,
|
See also the source code of [Fernschreiber](https://github.com/Wunderfitz/harbour-fernschreiber) and [Depecher](https://github.com/blacksailer/depecher) – Telegram apps for Sailfish OS,
|
||||||
[TELEports](https://gitlab.com/ubports/development/apps/teleports) – a Qt-client for Ubuntu Touch, [tdlib-purple](https://github.com/ars3niy/tdlib-purple) - Telegram plugin for Pidgin,
|
[TELEports](https://gitlab.com/ubports/development/apps/teleports) – a Qt-client for Ubuntu Touch, [tdlib-purple](https://github.com/ars3niy/tdlib-purple) - Telegram plugin for Pidgin,
|
||||||
@ -140,20 +140,20 @@ or [MeeGram](https://github.com/qtinsider/meegram2) - a Telegram client for Noki
|
|||||||
|
|
||||||
TDLib can be used from the Swift programming language through the [JSON](https://github.com/tdlib/td#using-json) interface and can be linked statically or dynamically.
|
TDLib can be used from the Swift programming language through the [JSON](https://github.com/tdlib/td#using-json) interface and can be linked statically or dynamically.
|
||||||
|
|
||||||
See [example/ios](https://github.com/tdlib/td/tree/master/example/ios) for an example of building TDLib for iOS, watchOS, tvOS, visionOS, and macOS.
|
See [example/ios](https://github.com/tdlight-team/tdlight/tree/master/example/ios) for an example of building TDLib for iOS, watchOS, tvOS, visionOS, and macOS.
|
||||||
|
|
||||||
See [TDLibKit](https://github.com/Swiftgram/TDLibKit), [tdlib-swift](https://github.com/modestman/tdlib-swift), or [TDLib-iOS](https://github.com/leoMehlig/TDLib-iOS), which provide convenient TDLib clients with automatically generated and fully-documented classes for all TDLib API methods and objects.
|
See [TDLibKit](https://github.com/Swiftgram/TDLibKit), [tdlib-swift](https://github.com/modestman/tdlib-swift), or [TDLib-iOS](https://github.com/leoMehlig/TDLib-iOS), which provide convenient TDLib clients with automatically generated and fully-documented classes for all TDLib API methods and objects.
|
||||||
|
|
||||||
See also the source code of [Moc](https://github.com/mock-foundation/moc) - a native and powerful macOS and iPadOS Telegram client, optimized for moderating large communities and personal use.
|
See also the source code of [Moc](https://github.com/mock-foundation/moc) - a native and powerful macOS and iPadOS Telegram client, optimized for moderating large communities and personal use.
|
||||||
|
|
||||||
See [example/swift](https://github.com/tdlib/td/tree/master/example/swift) for an example of a macOS Swift application.
|
See [example/swift](https://github.com/tdlight-team/tdlight/tree/master/example/swift) for an example of a macOS Swift application.
|
||||||
|
|
||||||
<a name="objective-c"></a>
|
<a name="objective-c"></a>
|
||||||
## Using TDLib in Objective-C projects
|
## Using TDLib in Objective-C projects
|
||||||
|
|
||||||
TDLib can be used from the Objective-C programming language through [JSON](https://github.com/tdlib/td#using-json) interface and can be linked statically or dynamically.
|
TDLib can be used from the Objective-C programming language through [JSON](https://github.com/tdlib/td#using-json) interface and can be linked statically or dynamically.
|
||||||
|
|
||||||
See [example/ios](https://github.com/tdlib/td/tree/master/example/ios) for an example of building TDLib for iOS, watchOS, tvOS, visionOS, and macOS.
|
See [example/ios](https://github.com/tdlight-team/tdlight/tree/master/example/ios) for an example of building TDLib for iOS, watchOS, tvOS, visionOS, and macOS.
|
||||||
|
|
||||||
<a name="object-pascal"></a>
|
<a name="object-pascal"></a>
|
||||||
## Using TDLib in Object Pascal projects with Delphi and Lazarus
|
## Using TDLib in Object Pascal projects with Delphi and Lazarus
|
||||||
@ -300,7 +300,7 @@ TDLib can be used from the C programming language through the [JSON](https://git
|
|||||||
|
|
||||||
See [easy-tg](https://github.com/Trumeet/easy-tg) for an example of such usage.
|
See [easy-tg](https://github.com/Trumeet/easy-tg) for an example of such usage.
|
||||||
|
|
||||||
You can also try to use our [C](https://github.com/tdlib/td/blob/master/td/telegram/td_c_client.h) client, which was used by the private TDLib-based version of [telegram-cli](https://github.com/vysheng/tg).
|
You can also try to use our [C](https://github.com/tdlight-team/tdlight/blob/master/td/telegram/td_c_client.h) client, which was used by the private TDLib-based version of [telegram-cli](https://github.com/vysheng/tg).
|
||||||
|
|
||||||
<a name="g"></a>
|
<a name="g"></a>
|
||||||
## Using TDLib from G projects
|
## Using TDLib from G projects
|
||||||
|
@ -4,7 +4,7 @@ Below are instructions for building TDLib for iOS, watchOS, tvOS, visionOS, and
|
|||||||
|
|
||||||
If you need only a macOS build for the current architecture, take a look at [TDLib build instructions generator](https://tdlib.github.io/td/build.html).
|
If you need only a macOS build for the current architecture, take a look at [TDLib build instructions generator](https://tdlib.github.io/td/build.html).
|
||||||
|
|
||||||
For example of usage take a look at our [Swift example](https://github.com/tdlib/td/tree/master/example/swift).
|
For example of usage take a look at our [Swift example](https://github.com/tdlight-team/tdlight/tree/master/example/swift).
|
||||||
|
|
||||||
To compile `TDLib` you will need to:
|
To compile `TDLib` you will need to:
|
||||||
* Install the latest Xcode via `xcode-select --install` or downloading it from [Xcode website](https://developer.apple.com/xcode/).
|
* Install the latest Xcode via `xcode-select --install` or downloading it from [Xcode website](https://developer.apple.com/xcode/).
|
||||||
@ -37,7 +37,7 @@ cd <path to TDLib sources>/example/ios
|
|||||||
```
|
```
|
||||||
This may take a while, because TDLib will be built about 16 times.
|
This may take a while, because TDLib will be built about 16 times.
|
||||||
Resulting XCFramework will work on any architecture and even on a simulator.
|
Resulting XCFramework will work on any architecture and even on a simulator.
|
||||||
We use [CMake/iOS.cmake](https://github.com/tdlib/td/blob/master/CMake/iOS.cmake) toolchain, other toolchains may work too.
|
We use [CMake/iOS.cmake](https://github.com/tdlight-team/tdlight/blob/master/CMake/iOS.cmake) toolchain, other toolchains may work too.
|
||||||
|
|
||||||
Built libraries and XCFramework will be stored in `tdjson` directory.
|
Built libraries and XCFramework will be stored in `tdjson` directory.
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
To run this example, you will need installed JDK >= 1.6.
|
To run this example, you will need installed JDK >= 1.6.
|
||||||
For Javadoc documentation generation PHP is needed.
|
For Javadoc documentation generation PHP is needed.
|
||||||
|
|
||||||
You can find complete build instructions for your operating system at https://tdlib.github.io/td/build.html?language=Java.
|
You can find complete build instructions for your operating system at https://tdlight-team.github.io/tdlight/build.html?language=Java.
|
||||||
|
|
||||||
In general, the build process looks as follows.
|
In general, the build process looks as follows.
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<MoreInfo>https://core.telegram.org/tdlib</MoreInfo>
|
<MoreInfo>https://core.telegram.org/tdlib</MoreInfo>
|
||||||
<Tags>Telegram, TDLib, library, client, API</Tags>
|
<Tags>Telegram, TDLib, library, client, API</Tags>
|
||||||
<License>LICENSE_1_0.txt</License>
|
<License>LICENSE_1_0.txt</License>
|
||||||
<ReleaseNotes>https://github.com/tdlib/td/blob/master/CHANGELOG.md</ReleaseNotes>
|
<ReleaseNotes>https://github.com/tdlight-team/tdlight/blob/master/CHANGELOG.md</ReleaseNotes>
|
||||||
</Metadata>
|
</Metadata>
|
||||||
<Installation Scope="Global">
|
<Installation Scope="Global">
|
||||||
<InstallationTarget Id="Microsoft.ExtensionSDK" TargetPlatformIdentifier="UAP" TargetPlatformVersion="v0.8.0.0" SdkName="Telegram.Td.UWP" SdkVersion="1.0" />
|
<InstallationTarget Id="Microsoft.ExtensionSDK" TargetPlatformIdentifier="UAP" TargetPlatformVersion="v0.8.0.0" SdkName="Telegram.Td.UWP" SdkVersion="1.0" />
|
||||||
|
@ -26,4 +26,4 @@ cd <path to TDLib sources>/example/web
|
|||||||
|
|
||||||
## Using tdweb NPM package
|
## Using tdweb NPM package
|
||||||
|
|
||||||
See [tdweb](https://www.npmjs.com/package/tdweb) or [README.md](https://github.com/tdlib/td/tree/master/example/web/tdweb/README.md) for package documentation.
|
See [tdweb](https://www.npmjs.com/package/tdweb) or [README.md](https://github.com/tdlight-team/tdlight/tree/master/example/web/tdweb/README.md) for package documentation.
|
||||||
|
@ -8,11 +8,11 @@ Once this is done, you can send queries to the TDLib instance using the method `
|
|||||||
|
|
||||||
See [Getting Started](https://core.telegram.org/tdlib/getting-started) for a description of basic TDLib concepts and a short introduction to TDLib usage.
|
See [Getting Started](https://core.telegram.org/tdlib/getting-started) for a description of basic TDLib concepts and a short introduction to TDLib usage.
|
||||||
|
|
||||||
See the [td_api.tl](https://github.com/tdlib/td/blob/master/td/generate/scheme/td_api.tl) scheme or
|
See the [td_api.tl](https://github.com/tdlight-team/tdlight/blob/master/td/generate/scheme/td_api.tl) scheme or
|
||||||
the automatically generated [HTML documentation](https://core.telegram.org/tdlib/docs/td__api_8h.html) for a list of all available
|
the automatically generated [HTML documentation](https://core.telegram.org/tdlib/docs/td__api_8h.html) for a list of all available
|
||||||
TDLib [methods](https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_function.html) and [classes](https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_object.html).
|
TDLib [methods](https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_function.html) and [classes](https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_object.html).
|
||||||
The JSON representation of TDLib API objects is straightforward: all API objects are represented as JSON objects with the same keys as the API object field names in the
|
The JSON representation of TDLib API objects is straightforward: all API objects are represented as JSON objects with the same keys as the API object field names in the
|
||||||
[td_api.tl](https://github.com/tdlib/td/blob/master/td/generate/scheme/td_api.tl) scheme. Note that in the automatically generated C++ documentation all fields have an additional terminating underscore
|
[td_api.tl](https://github.com/tdlight-team/tdlight/blob/master/td/generate/scheme/td_api.tl) scheme. Note that in the automatically generated C++ documentation all fields have an additional terminating underscore
|
||||||
which shouldn't be used in the JSON interface. The object type name is stored in the special field '@type' which is optional in places where type is uniquely determined by the context.
|
which shouldn't be used in the JSON interface. The object type name is stored in the special field '@type' which is optional in places where type is uniquely determined by the context.
|
||||||
Fields of Bool type are stored as Boolean, fields of int32, int53, and double types are stored as Number, fields of int64 and string types are stored as String,
|
Fields of Bool type are stored as Boolean, fields of int32, int53, and double types are stored as Number, fields of int64 and string types are stored as String,
|
||||||
fields of bytes type are base64 encoded and then stored as String, fields of array type are stored as Array.
|
fields of bytes type are base64 encoded and then stored as String, fields of array type are stored as Array.
|
||||||
|
@ -65,7 +65,7 @@ class TdClient {
|
|||||||
*
|
*
|
||||||
* If the query contains the field '@extra', the same field will be added into the result.
|
* If the query contains the field '@extra', the same field will be added into the result.
|
||||||
*
|
*
|
||||||
* @param {Object} query - The query for TDLib. See the [td_api.tl]{@link https://github.com/tdlib/td/blob/master/td/generate/scheme/td_api.tl} scheme or
|
* @param {Object} query - The query for TDLib. See the [td_api.tl]{@link https://github.com/tdlight-team/tdlight/blob/master/td/generate/scheme/td_api.tl} scheme or
|
||||||
* the automatically generated [HTML documentation]{@link https://core.telegram.org/tdlib/docs/td__api_8h.html}
|
* the automatically generated [HTML documentation]{@link https://core.telegram.org/tdlib/docs/td__api_8h.html}
|
||||||
* for a list of all available TDLib [methods]{@link https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_function.html} and
|
* for a list of all available TDLib [methods]{@link https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_function.html} and
|
||||||
* [classes]{@link https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_object.html}.
|
* [classes]{@link https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_object.html}.
|
||||||
|
1
td/generate/scheme/.gitignore
vendored
Normal file
1
td/generate/scheme/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.tlo
|
@ -561,6 +561,21 @@ userTypeBot can_be_edited:Bool can_join_groups:Bool can_read_all_group_messages:
|
|||||||
//@description No information on the user besides the user identifier is available, yet this user has not been deleted. This object is extremely rare and must be handled like a deleted user. It is not possible to perform any actions on users of this type
|
//@description No information on the user besides the user identifier is available, yet this user has not been deleted. This object is extremely rare and must be handled like a deleted user. It is not possible to perform any actions on users of this type
|
||||||
userTypeUnknown = UserType;
|
userTypeUnknown = UserType;
|
||||||
|
|
||||||
|
//@class AccessHashType @description Represents the type of an access hash. The following types are possible: user, channel
|
||||||
|
|
||||||
|
//@description An access hash of an user
|
||||||
|
accessHashTypeUser = AccessHashType;
|
||||||
|
|
||||||
|
//@description An access hash of a channel
|
||||||
|
accessHashTypeChannel = AccessHashType;
|
||||||
|
|
||||||
|
|
||||||
|
//@description Access hash
|
||||||
|
//@chat_id Chat identifier
|
||||||
|
//@type Access hash type
|
||||||
|
//@access_hash Access hash
|
||||||
|
accessHash chat_id:int53 type:AccessHashType access_hash:int64 = AccessHash;
|
||||||
|
|
||||||
|
|
||||||
//@description Represents a command supported by a bot @command Text of the bot command @param_description Description of the bot command
|
//@description Represents a command supported by a bot @command Text of the bot command @param_description Description of the bot command
|
||||||
botCommand command:string description:string = BotCommand;
|
botCommand command:string description:string = BotCommand;
|
||||||
@ -6049,6 +6064,10 @@ storageStatisticsFast files_size:int53 file_count:int32 database_size:int53 lang
|
|||||||
//@statistics Database statistics in an unspecified human-readable format
|
//@statistics Database statistics in an unspecified human-readable format
|
||||||
databaseStatistics statistics:string = DatabaseStatistics;
|
databaseStatistics statistics:string = DatabaseStatistics;
|
||||||
|
|
||||||
|
//@description Contains memory statistics
|
||||||
|
//@statistics Memory statistics in an unspecified human-readable format
|
||||||
|
memoryStatistics statistics:string = MemoryStatistics;
|
||||||
|
|
||||||
|
|
||||||
//@class NetworkType @description Represents the type of a network
|
//@class NetworkType @description Represents the type of a network
|
||||||
|
|
||||||
@ -6708,6 +6727,9 @@ updateUserStatus user_id:int53 status:UserStatus = Update;
|
|||||||
//@description Some data of a user has changed. This update is guaranteed to come before the user identifier is returned to the application @user New data about the user
|
//@description Some data of a user has changed. This update is guaranteed to come before the user identifier is returned to the application @user New data about the user
|
||||||
updateUser user:user = Update;
|
updateUser user:user = Update;
|
||||||
|
|
||||||
|
//@description Some data of a user or a chat has changed. This update is guaranteed to come before the user or chat identifier is returned to the application @access_hash Access hash
|
||||||
|
updateAccessHash access_hash:accessHash = Update;
|
||||||
|
|
||||||
//@description Some data of a basic group has changed. This update is guaranteed to come before the basic group identifier is returned to the application @basic_group New data about the group
|
//@description Some data of a basic group has changed. This update is guaranteed to come before the basic group identifier is returned to the application @basic_group New data about the group
|
||||||
updateBasicGroup basic_group:basicGroup = Update;
|
updateBasicGroup basic_group:basicGroup = Update;
|
||||||
|
|
||||||
@ -9872,6 +9894,10 @@ getStorageStatisticsFast = StorageStatisticsFast;
|
|||||||
//@description Returns database statistics
|
//@description Returns database statistics
|
||||||
getDatabaseStatistics = DatabaseStatistics;
|
getDatabaseStatistics = DatabaseStatistics;
|
||||||
|
|
||||||
|
//@description Returns memory statistics
|
||||||
|
//@full Full memory statistics calculation
|
||||||
|
getMemoryStatistics full:Bool = MemoryStatistics;
|
||||||
|
|
||||||
//@description Optimizes storage usage, i.e. deletes some files and returns new storage usage statistics. Secret thumbnails can't be deleted
|
//@description Optimizes storage usage, i.e. deletes some files and returns new storage usage statistics. Secret thumbnails can't be deleted
|
||||||
//@size Limit on the total size of files after deletion, in bytes. Pass -1 to use the default limit
|
//@size Limit on the total size of files after deletion, in bytes. Pass -1 to use the default limit
|
||||||
//@ttl Limit on the time that has passed since the last time a file was accessed (or creation time for some filesystems). Pass -1 to use the default limit
|
//@ttl Limit on the time that has passed since the last time a file was accessed (or creation time for some filesystems). Pass -1 to use the default limit
|
||||||
|
@ -185,7 +185,7 @@ void tl_print_parse_error (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *parse_lex (void) {
|
char *parse_lex (void) {
|
||||||
while (1) {
|
while (1) {
|
||||||
while (curch && is_whitespace (curch)) { nextch (); }
|
while (curch && is_whitespace (curch)) { nextch (); }
|
||||||
if (curch == '/' && nextch () == '/') {
|
if (curch == '/' && nextch () == '/') {
|
||||||
while (nextch () != 10);
|
while (nextch () != 10);
|
||||||
@ -235,7 +235,7 @@ char *parse_lex (void) {
|
|||||||
case '.':
|
case '.':
|
||||||
nextch ();
|
nextch ();
|
||||||
parse.lex.len = 1;
|
parse.lex.len = 1;
|
||||||
parse.lex.type = lex_char;
|
parse.lex.type = lex_char;
|
||||||
return (parse.lex.ptr = p);
|
return (parse.lex.ptr = p);
|
||||||
case 'a':
|
case 'a':
|
||||||
case 'b':
|
case 'b':
|
||||||
@ -334,10 +334,10 @@ char *parse_lex (void) {
|
|||||||
int ok = 1;
|
int ok = 1;
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
if (!is_hexdigit (nextch())) {
|
if (!is_hexdigit (nextch())) {
|
||||||
if (curch == ' ' && i >= 5) {
|
if (curch == ' ' && i >= 5) {
|
||||||
ok = 2;
|
ok = 2;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
parse_error ("Hex digit expected");
|
parse_error ("Hex digit expected");
|
||||||
parse.lex.type = lex_error;
|
parse.lex.type = lex_error;
|
||||||
return (parse.lex.ptr = (void *)-1);
|
return (parse.lex.ptr = (void *)-1);
|
||||||
@ -370,7 +370,7 @@ char *parse_lex (void) {
|
|||||||
parse.lex.type = lex_error;
|
parse.lex.type = lex_error;
|
||||||
return (parse.lex.ptr = (void *)-1);
|
return (parse.lex.ptr = (void *)-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int expect (char *s) {
|
int expect (char *s) {
|
||||||
@ -453,7 +453,7 @@ struct tree *parse_full_combinator_id (void) {
|
|||||||
} else {
|
} else {
|
||||||
parse_error ("Can not parse full combinator id");
|
parse_error ("Can not parse full combinator id");
|
||||||
PARSE_FAIL;
|
PARSE_FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tree *parse_combinator_id (void) {
|
struct tree *parse_combinator_id (void) {
|
||||||
@ -467,7 +467,7 @@ struct tree *parse_combinator_id (void) {
|
|||||||
} else {
|
} else {
|
||||||
parse_error ("Can not parse combinator id");
|
parse_error ("Can not parse combinator id");
|
||||||
PARSE_FAIL;
|
PARSE_FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tree *parse_var_ident (void) {
|
struct tree *parse_var_ident (void) {
|
||||||
@ -595,7 +595,7 @@ struct tree *parse_subexpr (void) {
|
|||||||
was_term = 1;
|
was_term = 1;
|
||||||
PARSE_TRY (parse_term);
|
PARSE_TRY (parse_term);
|
||||||
if (S) {
|
if (S) {
|
||||||
tree_add_child (T, S);
|
tree_add_child (T, S);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -714,7 +714,7 @@ struct tree *parse_args4 (void) {
|
|||||||
if (S) {
|
if (S) {
|
||||||
tree_add_child (T, S);
|
tree_add_child (T, S);
|
||||||
} else {
|
} else {
|
||||||
load_parse (so);
|
load_parse (so);
|
||||||
}
|
}
|
||||||
if (LEX_CHAR ('!')) {
|
if (LEX_CHAR ('!')) {
|
||||||
PARSE_ADD (type_exclam);
|
PARSE_ADD (type_exclam);
|
||||||
@ -733,7 +733,7 @@ struct tree *parse_args3 (void) {
|
|||||||
if (S) {
|
if (S) {
|
||||||
tree_add_child (T, S);
|
tree_add_child (T, S);
|
||||||
} else {
|
} else {
|
||||||
load_parse (so);
|
load_parse (so);
|
||||||
}
|
}
|
||||||
if (LEX_CHAR ('!')) {
|
if (LEX_CHAR ('!')) {
|
||||||
PARSE_ADD (type_exclam);
|
PARSE_ADD (type_exclam);
|
||||||
@ -757,7 +757,7 @@ struct tree *parse_args2 (void) {
|
|||||||
if (S) {
|
if (S) {
|
||||||
tree_add_child (T, S);
|
tree_add_child (T, S);
|
||||||
} else {
|
} else {
|
||||||
load_parse (so);
|
load_parse (so);
|
||||||
}
|
}
|
||||||
struct parse save2 = save_parse ();
|
struct parse save2 = save_parse ();
|
||||||
PARSE_TRY (parse_multiplicity);
|
PARSE_TRY (parse_multiplicity);
|
||||||
@ -789,7 +789,7 @@ struct tree *parse_args1 (void) {
|
|||||||
if (S) {
|
if (S) {
|
||||||
tree_add_child (T, S);
|
tree_add_child (T, S);
|
||||||
} else {
|
} else {
|
||||||
load_parse (so);
|
load_parse (so);
|
||||||
}
|
}
|
||||||
if (LEX_CHAR ('!')) {
|
if (LEX_CHAR ('!')) {
|
||||||
PARSE_ADD (type_exclam);
|
PARSE_ADD (type_exclam);
|
||||||
@ -1041,7 +1041,7 @@ int tl_add_field (char *id) {
|
|||||||
|
|
||||||
void tl_clear_fields (void) {
|
void tl_clear_fields (void) {
|
||||||
// tree_act_tl_field (fields[namespace_level], (void *)free);
|
// tree_act_tl_field (fields[namespace_level], (void *)free);
|
||||||
fields[namespace_level] = tree_clear_tl_field (fields[namespace_level]);
|
fields[namespace_level] = tree_clear_tl_field (fields[namespace_level]);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tl_var *tl_add_var (char *id, struct tl_combinator_tree *ptr, int type) {
|
struct tl_var *tl_add_var (char *id, struct tl_combinator_tree *ptr, int type) {
|
||||||
@ -1151,9 +1151,9 @@ struct tl_type *tl_add_type (const char *_id, int len, int params_num, long long
|
|||||||
|
|
||||||
void tl_add_type_param (struct tl_type *t, int x) {
|
void tl_add_type_param (struct tl_type *t, int x) {
|
||||||
assert (t->flags & 4);
|
assert (t->flags & 4);
|
||||||
assert (t->params_num <= 64);
|
assert (t->params_num <= 64);
|
||||||
if (x) {
|
if (x) {
|
||||||
t->params_types |= (1ull << (t->params_num ++));
|
t->params_types |= (1ull << (t->params_num ++));
|
||||||
} else {
|
} else {
|
||||||
t->params_num ++;
|
t->params_num ++;
|
||||||
}
|
}
|
||||||
@ -1222,7 +1222,7 @@ struct tl_constructor *tl_add_constructor (struct tl_type *a, const char *_id, i
|
|||||||
struct tl_constructor *t = talloc (sizeof (*t));
|
struct tl_constructor *t = talloc (sizeof (*t));
|
||||||
t->type = a;
|
t->type = a;
|
||||||
t->name = magic;
|
t->name = magic;
|
||||||
t->id = id;
|
t->id = id;
|
||||||
t->print_id = tstrdup (id);
|
t->print_id = tstrdup (id);
|
||||||
t->real_id = 0;
|
t->real_id = 0;
|
||||||
|
|
||||||
@ -1282,7 +1282,7 @@ struct tl_constructor *tl_add_function (struct tl_type *a, const char *_id, int
|
|||||||
struct tl_constructor *t = talloc (sizeof (*t));
|
struct tl_constructor *t = talloc (sizeof (*t));
|
||||||
t->type = a;
|
t->type = a;
|
||||||
t->name = magic;
|
t->name = magic;
|
||||||
t->id = id;
|
t->id = id;
|
||||||
t->print_id = tstrdup (id);
|
t->print_id = tstrdup (id);
|
||||||
t->real_id = 0;
|
t->real_id = 0;
|
||||||
|
|
||||||
@ -1455,7 +1455,7 @@ void tl_buf_add_tree (struct tl_combinator_tree *T, int x) {
|
|||||||
tl_buf_add_tree (T->right, 0);
|
tl_buf_add_tree (T->right, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf (stderr, "%s %s\n", TL_ACT (T->act), TL_TYPE (T->type));
|
fprintf (stderr, "%s %s\n", TL_ACT (T->act), TL_TYPE (T->type));
|
||||||
assert (0);
|
assert (0);
|
||||||
@ -1549,7 +1549,7 @@ struct tl_combinator_tree *tl_union (struct tl_combinator_tree *L, struct tl_com
|
|||||||
tfree (v, sizeof (*v));
|
tfree (v, sizeof (*v));
|
||||||
R->type_flags += L->type_flags;
|
R->type_flags += L->type_flags;
|
||||||
return R;
|
return R;
|
||||||
case type_list_item:
|
case type_list_item:
|
||||||
case type_list:
|
case type_list:
|
||||||
if (R->type != type_list_item) {
|
if (R->type != type_list_item) {
|
||||||
TL_ERROR ("Union: type mistmatch\n");
|
TL_ERROR ("Union: type mistmatch\n");
|
||||||
@ -1561,7 +1561,7 @@ struct tl_combinator_tree *tl_union (struct tl_combinator_tree *L, struct tl_com
|
|||||||
case type_type:
|
case type_type:
|
||||||
if (L->type_len == 0) {
|
if (L->type_len == 0) {
|
||||||
TL_ERROR ("Arguments number exceeds type arity\n");
|
TL_ERROR ("Arguments number exceeds type arity\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (R->type != type_num && R->type != type_type && R->type != type_num_value) {
|
if (R->type != type_num && R->type != type_type && R->type != type_num_value) {
|
||||||
TL_ERROR ("Union: type mistmatch\n");
|
TL_ERROR ("Union: type mistmatch\n");
|
||||||
@ -1574,7 +1574,7 @@ struct tl_combinator_tree *tl_union (struct tl_combinator_tree *L, struct tl_com
|
|||||||
}
|
}
|
||||||
if (R->type_len > 0) {
|
if (R->type_len > 0) {
|
||||||
TL_ERROR ("Argument type must have full number of arguments\n");
|
TL_ERROR ("Argument type must have full number of arguments\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (L->type_len > 0 && ((L->type_flags & 1) != (R->type == type_num || R->type == type_num_value))) {
|
if (L->type_len > 0 && ((L->type_flags & 1) != (R->type == type_num || R->type == type_num_value))) {
|
||||||
TL_ERROR ("Argument types mistmatch: L->type_flags = %lld, R->type = %s\n", L->flags, TL_TYPE (R->type));
|
TL_ERROR ("Argument types mistmatch: L->type_flags = %lld, R->type = %s\n", L->flags, TL_TYPE (R->type));
|
||||||
@ -1595,7 +1595,7 @@ struct tl_combinator_tree *tl_parse_any_term (struct tree *T, int s);
|
|||||||
struct tl_combinator_tree *tl_parse_term (struct tree *T, int s) {
|
struct tl_combinator_tree *tl_parse_term (struct tree *T, int s) {
|
||||||
assert (T->type == type_term);
|
assert (T->type == type_term);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < T->nc && T->c[i]->type == type_percent) { i ++; s ++; }
|
while (i < T->nc && T->c[i]->type == type_percent) { i ++; s ++; }
|
||||||
assert (i < T->nc);
|
assert (i < T->nc);
|
||||||
TL_INIT (L);
|
TL_INIT (L);
|
||||||
while (i < T->nc) {
|
while (i < T->nc) {
|
||||||
@ -1610,7 +1610,7 @@ struct tl_combinator_tree *tl_parse_term (struct tree *T, int s) {
|
|||||||
struct tl_combinator_tree *tl_parse_type_term (struct tree *T, int s) {
|
struct tl_combinator_tree *tl_parse_type_term (struct tree *T, int s) {
|
||||||
assert (T->type == type_type_term);
|
assert (T->type == type_type_term);
|
||||||
assert (T->nc == 1);
|
assert (T->nc == 1);
|
||||||
struct tl_combinator_tree *Z = tl_parse_term (T->c[0], s);
|
struct tl_combinator_tree *Z = tl_parse_term (T->c[0], s);
|
||||||
if (!Z || Z->type != type_type) { if (Z) { TL_ERROR ("type_term: found type %s\n", TL_TYPE (Z->type)); } TL_FAIL; }
|
if (!Z || Z->type != type_type) { if (Z) { TL_ERROR ("type_term: found type %s\n", TL_TYPE (Z->type)); } TL_FAIL; }
|
||||||
return Z;
|
return Z;
|
||||||
}
|
}
|
||||||
@ -1674,7 +1674,7 @@ struct tl_combinator_tree *tl_parse_ident (struct tree *T, int s) {
|
|||||||
assert (!T->nc);
|
assert (!T->nc);
|
||||||
struct tl_var *v = tl_get_var (T->text, T->len);
|
struct tl_var *v = tl_get_var (T->text, T->len);
|
||||||
TL_INIT (L);
|
TL_INIT (L);
|
||||||
if (v) {
|
if (v) {
|
||||||
L = alloc_ctree_node ();
|
L = alloc_ctree_node ();
|
||||||
L->act = act_var;
|
L->act = act_var;
|
||||||
L->type = v->type ? type_num : type_type;
|
L->type = v->type ? type_num : type_type;
|
||||||
@ -1733,7 +1733,7 @@ struct tl_combinator_tree *tl_parse_ident (struct tree *T, int s) {
|
|||||||
L->data = t;
|
L->data = t;
|
||||||
L->type = type_type;
|
L->type = type_type;
|
||||||
L->type_len = t->params_num;
|
L->type_len = t->params_num;
|
||||||
L->type_flags = t->params_types;
|
L->type_flags = t->params_types;
|
||||||
return L;
|
return L;
|
||||||
} else {
|
} else {
|
||||||
TL_ERROR ("Not a type/var ident `%.*s`\n", T->len, T->text);
|
TL_ERROR ("Not a type/var ident `%.*s`\n", T->len, T->text);
|
||||||
@ -1761,7 +1761,7 @@ struct tl_combinator_tree *tl_parse_any_term (struct tree *T, int s) {
|
|||||||
default:
|
default:
|
||||||
fprintf (stderr, "type = %d\n", T->type);
|
fprintf (stderr, "type = %d\n", T->type);
|
||||||
assert (0);
|
assert (0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1834,11 +1834,11 @@ struct tl_combinator_tree *tl_parse_args2 (struct tree *T) {
|
|||||||
if (T->c[x]->type == type_var_ident_opt || T->c[x]->type == type_var_ident) {
|
if (T->c[x]->type == type_var_ident_opt || T->c[x]->type == type_var_ident) {
|
||||||
field_name = mystrdup (T->c[x]->text, T->c[x]->len);
|
field_name = mystrdup (T->c[x]->text, T->c[x]->len);
|
||||||
if (!tl_add_field (field_name)) {
|
if (!tl_add_field (field_name)) {
|
||||||
TL_ERROR ("Duplicate field name %s\n", field_name);
|
TL_ERROR ("Duplicate field name %s\n", field_name);
|
||||||
TL_FAIL;
|
TL_FAIL;
|
||||||
}
|
}
|
||||||
x ++;
|
x ++;
|
||||||
}
|
}
|
||||||
//fprintf (stderr, "%d %d\n", x, T->nc);
|
//fprintf (stderr, "%d %d\n", x, T->nc);
|
||||||
if (T->c[x]->type == type_multiplicity) {
|
if (T->c[x]->type == type_multiplicity) {
|
||||||
L = tl_parse_multiplicity (T->c[x]);
|
L = tl_parse_multiplicity (T->c[x]);
|
||||||
@ -1846,7 +1846,7 @@ struct tl_combinator_tree *tl_parse_args2 (struct tree *T) {
|
|||||||
x ++;
|
x ++;
|
||||||
} else {
|
} else {
|
||||||
struct tl_var *v = tl_get_last_num_var ();
|
struct tl_var *v = tl_get_last_num_var ();
|
||||||
if (!v) {
|
if (!v) {
|
||||||
TL_ERROR ("Expected multiplicity or nat var\n");
|
TL_ERROR ("Expected multiplicity or nat var\n");
|
||||||
TL_FAIL;
|
TL_FAIL;
|
||||||
}
|
}
|
||||||
@ -1880,7 +1880,7 @@ struct tl_combinator_tree *tl_parse_args2 (struct tree *T) {
|
|||||||
H->right = 0;
|
H->right = 0;
|
||||||
H->data = field_name;
|
H->data = field_name;
|
||||||
H->type_len = 0;
|
H->type_len = 0;
|
||||||
|
|
||||||
return H;
|
return H;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1971,7 +1971,7 @@ struct tl_combinator_tree *tl_parse_args134 (struct tree *T) {
|
|||||||
if (!v) {TL_FAIL;}
|
if (!v) {TL_FAIL;}
|
||||||
v->flags |= 2;
|
v->flags |= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
H = tl_union (H, S);
|
H = tl_union (H, S);
|
||||||
}
|
}
|
||||||
return H;
|
return H;
|
||||||
@ -1993,7 +1993,7 @@ struct tl_combinator_tree *tl_parse_args (struct tree *T) {
|
|||||||
default:
|
default:
|
||||||
assert (0);
|
assert (0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tl_mark_vars (struct tl_combinator_tree *T) {
|
void tl_mark_vars (struct tl_combinator_tree *T) {
|
||||||
@ -2012,7 +2012,7 @@ struct tl_combinator_tree *tl_parse_result_type (struct tree *T) {
|
|||||||
assert (T->type == type_result_type);
|
assert (T->type == type_result_type);
|
||||||
assert (T->nc >= 1);
|
assert (T->nc >= 1);
|
||||||
assert (T->nc <= 64);
|
assert (T->nc <= 64);
|
||||||
|
|
||||||
TL_INIT (L);
|
TL_INIT (L);
|
||||||
|
|
||||||
if (tl_get_var (T->c[0]->text, T->c[0]->len)) {
|
if (tl_get_var (T->c[0]->text, T->c[0]->len)) {
|
||||||
@ -2043,7 +2043,7 @@ struct tl_combinator_tree *tl_parse_result_type (struct tree *T) {
|
|||||||
int i;
|
int i;
|
||||||
for (i = 1; i < T->nc; i++) {
|
for (i = 1; i < T->nc; i++) {
|
||||||
TL_TRY (tl_parse_any_term (T->c[i], 0), L);
|
TL_TRY (tl_parse_any_term (T->c[i], 0), L);
|
||||||
assert (L->right);
|
assert (L->right);
|
||||||
assert (L->right->type == type_num || L->right->type == type_num_value || (L->right->type == type_type && L->right->type_len == 0));
|
assert (L->right->type == type_num || L->right->type == type_num_value || (L->right->type == type_type && L->right->type_len == 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2090,7 +2090,7 @@ int tl_parse_combinator_decl (struct tree *T, int fun) {
|
|||||||
TL_ERROR ("Only functions can return variables\n");
|
TL_ERROR ("Only functions can return variables\n");
|
||||||
}
|
}
|
||||||
assert (t || fun);
|
assert (t || fun);
|
||||||
|
|
||||||
assert (namespace_level == 0);
|
assert (namespace_level == 0);
|
||||||
__ok = 1;
|
__ok = 1;
|
||||||
tree_act_tl_var (vars[0], tl_var_check_used);
|
tree_act_tl_var (vars[0], tl_var_check_used);
|
||||||
@ -2098,7 +2098,7 @@ int tl_parse_combinator_decl (struct tree *T, int fun) {
|
|||||||
TL_ERROR ("Not all variables are used in right side\n");
|
TL_ERROR ("Not all variables are used in right side\n");
|
||||||
TL_FAIL;
|
TL_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tl_get_constructor (T->c[0]->text, T->c[0]->len) || tl_get_function (T->c[0]->text, T->c[0]->len)) {
|
if (tl_get_constructor (T->c[0]->text, T->c[0]->len) || tl_get_function (T->c[0]->text, T->c[0]->len)) {
|
||||||
TL_ERROR ("Duplicate combinator id %.*s\n", T->c[0]->len, T->c[0]->text);
|
TL_ERROR ("Duplicate combinator id %.*s\n", T->c[0]->len, T->c[0]->text);
|
||||||
return 0;
|
return 0;
|
||||||
@ -2107,7 +2107,7 @@ int tl_parse_combinator_decl (struct tree *T, int fun) {
|
|||||||
if (!c) { TL_FAIL; }
|
if (!c) { TL_FAIL; }
|
||||||
c->left = L;
|
c->left = L;
|
||||||
c->right = R;
|
c->right = R;
|
||||||
|
|
||||||
if (!c->name) {
|
if (!c->name) {
|
||||||
tl_count_combinator_name (c);
|
tl_count_combinator_name (c);
|
||||||
}
|
}
|
||||||
@ -2163,7 +2163,7 @@ struct tl_combinator_tree *change_first_var (struct tl_combinator_tree *O, struc
|
|||||||
if (O->data == *X) {
|
if (O->data == *X) {
|
||||||
struct tl_combinator_tree *R = tl_tree_dup (Y);
|
struct tl_combinator_tree *R = tl_tree_dup (Y);
|
||||||
if (O->type == type_num || O->type == type_num_value) { R->type_flags += O->type_flags; }
|
if (O->type == type_num || O->type == type_num_value) { R->type_flags += O->type_flags; }
|
||||||
return R;
|
return R;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
struct tl_combinator_tree *t;
|
struct tl_combinator_tree *t;
|
||||||
@ -2174,7 +2174,7 @@ struct tl_combinator_tree *change_first_var (struct tl_combinator_tree *O, struc
|
|||||||
if (!t) { return 0;}
|
if (!t) { return 0;}
|
||||||
if (t == (void *)-1l) { return (void *)-1l; }
|
if (t == (void *)-1l) { return (void *)-1l; }
|
||||||
if (t != (void *)-2l) { return t;}
|
if (t != (void *)-2l) { return t;}
|
||||||
return (void *)-1l;
|
return (void *)-1l;
|
||||||
}
|
}
|
||||||
if (t != (void *)-2l) {
|
if (t != (void *)-2l) {
|
||||||
O->left = t;
|
O->left = t;
|
||||||
@ -2182,7 +2182,7 @@ struct tl_combinator_tree *change_first_var (struct tl_combinator_tree *O, struc
|
|||||||
t = change_first_var (O->right, X, Y);
|
t = change_first_var (O->right, X, Y);
|
||||||
if (!t) { return 0;}
|
if (!t) { return 0;}
|
||||||
if (t == (void *)-1l) {
|
if (t == (void *)-1l) {
|
||||||
return O->left;
|
return O->left;
|
||||||
}
|
}
|
||||||
if (t != (void *)-2l) {
|
if (t != (void *)-2l) {
|
||||||
O->right = t;
|
O->right = t;
|
||||||
@ -2267,7 +2267,7 @@ struct tl_combinator_tree *change_value_var (struct tl_combinator_tree *O, struc
|
|||||||
if (!t) { return 0;}
|
if (!t) { return 0;}
|
||||||
if (t == (void *)-1l) { return (void *)-1l; }
|
if (t == (void *)-1l) { return (void *)-1l; }
|
||||||
if (t != (void *)-2l) { return t;}
|
if (t != (void *)-2l) { return t;}
|
||||||
return (void *)-1l;
|
return (void *)-1l;
|
||||||
}
|
}
|
||||||
if (t != (void *)-2l) {
|
if (t != (void *)-2l) {
|
||||||
O->left = t;
|
O->left = t;
|
||||||
@ -2275,7 +2275,7 @@ struct tl_combinator_tree *change_value_var (struct tl_combinator_tree *O, struc
|
|||||||
t = change_value_var (O->right, X);
|
t = change_value_var (O->right, X);
|
||||||
if (!t) { return 0;}
|
if (!t) { return 0;}
|
||||||
if (t == (void *)-1l) {
|
if (t == (void *)-1l) {
|
||||||
return O->left;
|
return O->left;
|
||||||
}
|
}
|
||||||
if (t != (void *)-2l) {
|
if (t != (void *)-2l) {
|
||||||
O->right = t;
|
O->right = t;
|
||||||
@ -2324,7 +2324,7 @@ int tl_parse_partial_type_app_decl (struct tree *T) {
|
|||||||
assert (nt);
|
assert (nt);
|
||||||
//snprintf (_buf, 100000, "%s #", t->id);
|
//snprintf (_buf, 100000, "%s #", t->id);
|
||||||
//nt->real_id = strdup (_buf);
|
//nt->real_id = strdup (_buf);
|
||||||
|
|
||||||
for (i = 0; i < t->constructors_num; i++) {
|
for (i = 0; i < t->constructors_num; i++) {
|
||||||
struct tl_constructor *c = t->constructors[i];
|
struct tl_constructor *c = t->constructors[i];
|
||||||
struct tree_var_value *V = 0;
|
struct tree_var_value *V = 0;
|
||||||
@ -2332,7 +2332,7 @@ int tl_parse_partial_type_app_decl (struct tree *T) {
|
|||||||
TL_INIT (B);
|
TL_INIT (B);
|
||||||
A = tl_tree_dup (c->left);
|
A = tl_tree_dup (c->left);
|
||||||
B = tl_tree_dup (c->right);
|
B = tl_tree_dup (c->right);
|
||||||
|
|
||||||
struct tree_var_value *W = 0;
|
struct tree_var_value *W = 0;
|
||||||
change_var_ptrs (c->left, A, &W);
|
change_var_ptrs (c->left, A, &W);
|
||||||
change_var_ptrs (c->right, B, &W);
|
change_var_ptrs (c->right, B, &W);
|
||||||
@ -2349,7 +2349,7 @@ int tl_parse_partial_type_app_decl (struct tree *T) {
|
|||||||
struct tl_constructor *r = tl_add_constructor (nt, _buf, strlen (_buf), 1);
|
struct tl_constructor *r = tl_add_constructor (nt, _buf, strlen (_buf), 1);
|
||||||
snprintf (_buf, 100000, "%s", c->id);
|
snprintf (_buf, 100000, "%s", c->id);
|
||||||
r->real_id = tstrdup (_buf);
|
r->real_id = tstrdup (_buf);
|
||||||
|
|
||||||
r->left = A;
|
r->left = A;
|
||||||
r->right = B;
|
r->right = B;
|
||||||
if (!r->name) {
|
if (!r->name) {
|
||||||
@ -2377,8 +2377,8 @@ int tl_parse_partial_comb_app_decl (struct tree *T, int fun) {
|
|||||||
TL_INIT (R);
|
TL_INIT (R);
|
||||||
L = tl_tree_dup (c->left);
|
L = tl_tree_dup (c->left);
|
||||||
R = tl_tree_dup (c->right);
|
R = tl_tree_dup (c->right);
|
||||||
|
|
||||||
|
|
||||||
struct tree_var_value *V = 0;
|
struct tree_var_value *V = 0;
|
||||||
change_var_ptrs (c->left, L, &V);
|
change_var_ptrs (c->left, L, &V);
|
||||||
change_var_ptrs (c->right, R, &V);
|
change_var_ptrs (c->right, R, &V);
|
||||||
@ -2391,7 +2391,7 @@ int tl_parse_partial_comb_app_decl (struct tree *T, int fun) {
|
|||||||
TL_INIT (Z);
|
TL_INIT (Z);
|
||||||
X = tl_parse_any_term (T->c[i], 0);
|
X = tl_parse_any_term (T->c[i], 0);
|
||||||
struct tl_combinator_tree *K = 0;
|
struct tl_combinator_tree *K = 0;
|
||||||
if (!(Z = change_first_var (L, &K, X))) {
|
if (!(Z = change_first_var (L, &K, X))) {
|
||||||
TL_FAIL;
|
TL_FAIL;
|
||||||
}
|
}
|
||||||
L = Z;
|
L = Z;
|
||||||
@ -2516,7 +2516,7 @@ int tl_parse_builtin_combinator_decl (struct tree *T, int fun) {
|
|||||||
if (!c) {
|
if (!c) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
c->left = alloc_ctree_node ();
|
c->left = alloc_ctree_node ();
|
||||||
c->left->act = act_question_mark;
|
c->left->act = act_question_mark;
|
||||||
c->left->type = type_list_item;
|
c->left->type = type_list_item;
|
||||||
@ -2615,7 +2615,7 @@ int uniformize (struct tl_combinator_tree *L, struct tl_combinator_tree *R, stru
|
|||||||
if (R->act == act_var) {
|
if (R->act == act_var) {
|
||||||
struct tl_combinator_tree *_ = R; R = L; L = _;
|
struct tl_combinator_tree *_ = R; R = L; L = _;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (L->type == type_type) {
|
if (L->type == type_type) {
|
||||||
if (R->type != type_type || L->type_len != R->type_len || L->type_flags != R->type_flags) {
|
if (R->type != type_type || L->type_len != R->type_len || L->type_flags != R->type_flags) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -2695,14 +2695,14 @@ int uniformize (struct tl_combinator_tree *L, struct tl_combinator_tree *R, stru
|
|||||||
M = tl_get_var_value (T, M->data);
|
M = tl_get_var_value (T, M->data);
|
||||||
}
|
}
|
||||||
if (K->type == type_num_value && M->type == type_num_value) {
|
if (K->type == type_num_value && M->type == type_num_value) {
|
||||||
return x == y;
|
return x == y;
|
||||||
}
|
}
|
||||||
if (M->type == type_num_value) {
|
if (M->type == type_num_value) {
|
||||||
tl_set_var_value_num (T, K->data, M, -(x - y + M->type_flags));
|
tl_set_var_value_num (T, K->data, M, -(x - y + M->type_flags));
|
||||||
return 1;
|
return 1;
|
||||||
} else if (K->type == type_num_value) {
|
} else if (K->type == type_num_value) {
|
||||||
tl_set_var_value_num (T, M->data, K, -(y - x + K->type_flags));
|
tl_set_var_value_num (T, M->data, K, -(y - x + K->type_flags));
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
if (x >= y) {
|
if (x >= y) {
|
||||||
tl_set_var_value_num (T, K->data, M, -(x - y + M->type_flags));
|
tl_set_var_value_num (T, K->data, M, -(x - y + M->type_flags));
|
||||||
@ -2720,7 +2720,7 @@ void tl_type_check (struct tl_type *t) {
|
|||||||
if (!__ok) return;
|
if (!__ok) return;
|
||||||
if (!strcmp (t->id, "#")) { t->name = 0x70659eff; return; }
|
if (!strcmp (t->id, "#")) { t->name = 0x70659eff; return; }
|
||||||
if (!strcmp (t->id, "Type")) { t->name = 0x2cecf817; return; }
|
if (!strcmp (t->id, "Type")) { t->name = 0x2cecf817; return; }
|
||||||
if (t->constructors_num <= 0 && !(t->flags & FLAG_EMPTY)) {
|
if (t->constructors_num <= 0 && !(t->flags & FLAG_EMPTY)) {
|
||||||
TL_ERROR ("Type %s has no constructors\n", t->id);
|
TL_ERROR ("Type %s has no constructors\n", t->id);
|
||||||
__ok = 0;
|
__ok = 0;
|
||||||
return;
|
return;
|
||||||
@ -2739,7 +2739,7 @@ void tl_type_check (struct tl_type *t) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((t->flags & 24) == 24) {
|
if ((t->flags & 24) == 24) {
|
||||||
TL_WARNING ("Warning: Type %s has overlapping costructors, but it is used with `%%`\n", t->id);
|
TL_WARNING ("Warning: Type %s has overlapping costructors, but it is used with `%%`\n", t->id);
|
||||||
}
|
}
|
||||||
int z = 0;
|
int z = 0;
|
||||||
int sid = 0;
|
int sid = 0;
|
||||||
@ -2907,7 +2907,7 @@ void write_args (struct tl_combinator_tree *T, struct tree_var_value **v, int *l
|
|||||||
tl_set_var_value_num (v, T, 0, (*last_var) - 1);
|
tl_set_var_value_num (v, T, 0, (*last_var) - 1);
|
||||||
} else {
|
} else {
|
||||||
write_field_flags (f);
|
write_field_flags (f);
|
||||||
}
|
}
|
||||||
write_tree (T->left, 0, v, last_var);
|
write_tree (T->left, 0, v, last_var);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ int main (int argc, char **argv) {
|
|||||||
if (argc != optind + 1) {
|
if (argc != optind + 1) {
|
||||||
usage ();
|
usage ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct parse *P = tl_init_parse_file (argv[optind]);
|
struct parse *P = tl_init_parse_file (argv[optind]);
|
||||||
if (!P) {
|
if (!P) {
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "td/telegram/DialogId.h"
|
#include "td/telegram/DialogId.h"
|
||||||
#include "td/telegram/Document.h"
|
#include "td/telegram/Document.h"
|
||||||
#include "td/telegram/DocumentsManager.h"
|
#include "td/telegram/DocumentsManager.h"
|
||||||
|
#include "td/telegram/MemoryManager.h"
|
||||||
#include "td/telegram/FileReferenceManager.h"
|
#include "td/telegram/FileReferenceManager.h"
|
||||||
#include "td/telegram/files/FileManager.h"
|
#include "td/telegram/files/FileManager.h"
|
||||||
#include "td/telegram/files/FileType.h"
|
#include "td/telegram/files/FileType.h"
|
||||||
@ -191,8 +192,10 @@ FileId AnimationsManager::on_get_animation(unique_ptr<Animation> new_animation,
|
|||||||
LOG(DEBUG) << "Animation " << file_id << " duration has changed";
|
LOG(DEBUG) << "Animation " << file_id << " duration has changed";
|
||||||
a->duration = new_animation->duration;
|
a->duration = new_animation->duration;
|
||||||
}
|
}
|
||||||
if (a->minithumbnail != new_animation->minithumbnail) {
|
if (!G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
a->minithumbnail = std::move(new_animation->minithumbnail);
|
if (a->minithumbnail != new_animation->minithumbnail) {
|
||||||
|
a->minithumbnail = std::move(new_animation->minithumbnail);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (a->thumbnail != new_animation->thumbnail) {
|
if (a->thumbnail != new_animation->thumbnail) {
|
||||||
if (!a->thumbnail.file_id.is_valid()) {
|
if (!a->thumbnail.file_id.is_valid()) {
|
||||||
@ -295,8 +298,10 @@ void AnimationsManager::create_animation(FileId file_id, string minithumbnail, P
|
|||||||
a->mime_type = std::move(mime_type);
|
a->mime_type = std::move(mime_type);
|
||||||
a->duration = max(duration, 0);
|
a->duration = max(duration, 0);
|
||||||
a->dimensions = dimensions;
|
a->dimensions = dimensions;
|
||||||
if (!td_->auth_manager_->is_bot()) {
|
if (!G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
a->minithumbnail = std::move(minithumbnail);
|
if (!td_->auth_manager_->is_bot()) {
|
||||||
|
a->minithumbnail = std::move(minithumbnail);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
a->thumbnail = std::move(thumbnail);
|
a->thumbnail = std::move(thumbnail);
|
||||||
a->animated_thumbnail = std::move(animated_thumbnail);
|
a->animated_thumbnail = std::move(animated_thumbnail);
|
||||||
@ -831,7 +836,7 @@ void AnimationsManager::send_update_saved_animations(bool from_database) {
|
|||||||
if (animation->animated_thumbnail.file_id.is_valid()) {
|
if (animation->animated_thumbnail.file_id.is_valid()) {
|
||||||
new_saved_animation_file_ids.push_back(animation->animated_thumbnail.file_id);
|
new_saved_animation_file_ids.push_back(animation->animated_thumbnail.file_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::sort(new_saved_animation_file_ids.begin(), new_saved_animation_file_ids.end());
|
std::sort(new_saved_animation_file_ids.begin(), new_saved_animation_file_ids.end());
|
||||||
if (new_saved_animation_file_ids != saved_animation_file_ids_) {
|
if (new_saved_animation_file_ids != saved_animation_file_ids_) {
|
||||||
td_->file_manager_->change_files_source(get_saved_animations_file_source_id(), saved_animation_file_ids_,
|
td_->file_manager_->change_files_source(get_saved_animations_file_source_id(), saved_animation_file_ids_,
|
||||||
@ -882,4 +887,12 @@ void AnimationsManager::get_current_state(vector<td_api::object_ptr<td_api::Upda
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AnimationsManager::memory_stats(vector<string> &output) {
|
||||||
|
output.push_back("\"animations_\":"); output.push_back(std::to_string(animations_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"saved_animation_ids_\":"); output.push_back(std::to_string(this->saved_animation_ids_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"saved_animation_file_ids_\":"); output.push_back(std::to_string(this->saved_animation_file_ids_.size()));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -35,6 +35,8 @@ class AnimationsManager final : public Actor {
|
|||||||
AnimationsManager &operator=(AnimationsManager &&) = delete;
|
AnimationsManager &operator=(AnimationsManager &&) = delete;
|
||||||
~AnimationsManager() final;
|
~AnimationsManager() final;
|
||||||
|
|
||||||
|
void memory_stats(vector<string> &output);
|
||||||
|
|
||||||
int32 get_animation_duration(FileId file_id) const;
|
int32 get_animation_duration(FileId file_id) const;
|
||||||
|
|
||||||
tl_object_ptr<td_api::animation> get_animation_object(FileId file_id) const;
|
tl_object_ptr<td_api::animation> get_animation_object(FileId file_id) const;
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "td/utils/common.h"
|
#include "td/utils/common.h"
|
||||||
#include "td/utils/tl_helpers.h"
|
#include "td/utils/tl_helpers.h"
|
||||||
|
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
template <class StorerT>
|
template <class StorerT>
|
||||||
@ -55,10 +56,27 @@ FileId AnimationsManager::parse_animation(ParserT &parser) {
|
|||||||
parse(animation->duration, parser);
|
parse(animation->duration, parser);
|
||||||
}
|
}
|
||||||
parse(animation->dimensions, parser);
|
parse(animation->dimensions, parser);
|
||||||
parse(animation->file_name, parser);
|
|
||||||
|
string tmp_filename;
|
||||||
|
parse(tmp_filename, parser);
|
||||||
|
|
||||||
parse(animation->mime_type, parser);
|
parse(animation->mime_type, parser);
|
||||||
|
|
||||||
|
if ( G()->get_option_boolean("disable_document_filenames") && (
|
||||||
|
animation->mime_type.rfind("image/") == 0 ||
|
||||||
|
animation->mime_type.rfind("video/") == 0 ||
|
||||||
|
animation->mime_type.rfind("audio/") == 0)) {
|
||||||
|
animation->file_name = "0";
|
||||||
|
} else {
|
||||||
|
animation->file_name = tmp_filename;
|
||||||
|
}
|
||||||
|
|
||||||
if (parser.version() >= static_cast<int32>(Version::SupportMinithumbnails)) {
|
if (parser.version() >= static_cast<int32>(Version::SupportMinithumbnails)) {
|
||||||
parse(animation->minithumbnail, parser);
|
string tmp_minithumbnail;
|
||||||
|
parse(tmp_minithumbnail, parser);
|
||||||
|
if (!G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
|
animation->minithumbnail = tmp_minithumbnail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
parse(animation->thumbnail, parser);
|
parse(animation->thumbnail, parser);
|
||||||
parse(animation->file_id, parser);
|
parse(animation->file_id, parser);
|
||||||
|
@ -309,4 +309,9 @@ tl_object_ptr<telegram_api::InputMedia> AudiosManager::get_input_media(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudiosManager::memory_stats(vector<string> &output) {
|
||||||
|
output.push_back("\"audios_\":"); output.push_back(std::to_string(audios_.calc_size()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -29,6 +29,8 @@ class AudiosManager {
|
|||||||
AudiosManager &operator=(AudiosManager &&) = delete;
|
AudiosManager &operator=(AudiosManager &&) = delete;
|
||||||
~AudiosManager();
|
~AudiosManager();
|
||||||
|
|
||||||
|
void memory_stats(vector<string> &output);
|
||||||
|
|
||||||
int32 get_audio_duration(FileId file_id) const;
|
int32 get_audio_duration(FileId file_id) const;
|
||||||
|
|
||||||
tl_object_ptr<td_api::audio> get_audio_object(FileId file_id) const;
|
tl_object_ptr<td_api::audio> get_audio_object(FileId file_id) const;
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "td/utils/common.h"
|
#include "td/utils/common.h"
|
||||||
#include "td/utils/tl_helpers.h"
|
#include "td/utils/tl_helpers.h"
|
||||||
|
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
template <class StorerT>
|
template <class StorerT>
|
||||||
@ -99,7 +100,13 @@ FileId AudiosManager::parse_audio(ParserT &parser) {
|
|||||||
has_date = false;
|
has_date = false;
|
||||||
}
|
}
|
||||||
if (has_file_name) {
|
if (has_file_name) {
|
||||||
parse(audio->file_name, parser);
|
string tmp_filename;
|
||||||
|
parse(tmp_filename, parser);
|
||||||
|
if (G()->get_option_boolean("disable_document_filenames")) {
|
||||||
|
audio->file_name = "0";
|
||||||
|
} else {
|
||||||
|
audio->file_name = tmp_filename;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (has_mime_type) {
|
if (has_mime_type) {
|
||||||
parse(audio->mime_type, parser);
|
parse(audio->mime_type, parser);
|
||||||
@ -114,7 +121,11 @@ FileId AudiosManager::parse_audio(ParserT &parser) {
|
|||||||
parse(audio->performer, parser);
|
parse(audio->performer, parser);
|
||||||
}
|
}
|
||||||
if (has_minithumbnail) {
|
if (has_minithumbnail) {
|
||||||
parse(audio->minithumbnail, parser);
|
string tmp_minithumbnail;
|
||||||
|
parse(tmp_minithumbnail, parser);
|
||||||
|
if (!G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
|
audio->minithumbnail = tmp_minithumbnail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (has_thumbnail) {
|
if (has_thumbnail) {
|
||||||
parse(audio->thumbnail, parser);
|
parse(audio->thumbnail, parser);
|
||||||
|
@ -126,14 +126,27 @@ class SaveAutoDownloadSettingsQuery final : public Td::ResultHandler {
|
|||||||
AutoDownloadSettings get_auto_download_settings(const td_api::object_ptr<td_api::autoDownloadSettings> &settings) {
|
AutoDownloadSettings get_auto_download_settings(const td_api::object_ptr<td_api::autoDownloadSettings> &settings) {
|
||||||
CHECK(settings != nullptr);
|
CHECK(settings != nullptr);
|
||||||
AutoDownloadSettings result;
|
AutoDownloadSettings result;
|
||||||
result.max_photo_file_size = settings->max_photo_file_size_;
|
if (G()->get_option_boolean("disable_auto_download")) {
|
||||||
result.max_video_file_size = settings->max_video_file_size_;
|
result.max_photo_file_size = -1;
|
||||||
result.max_other_file_size = settings->max_other_file_size_;
|
result.max_video_file_size = -1;
|
||||||
|
result.max_other_file_size = -1;
|
||||||
|
} else {
|
||||||
|
result.max_photo_file_size = settings->max_photo_file_size_;
|
||||||
|
result.max_video_file_size = settings->max_video_file_size_;
|
||||||
|
result.max_other_file_size = settings->max_other_file_size_;
|
||||||
|
}
|
||||||
result.video_upload_bitrate = settings->video_upload_bitrate_;
|
result.video_upload_bitrate = settings->video_upload_bitrate_;
|
||||||
result.is_enabled = settings->is_auto_download_enabled_;
|
if (G()->get_option_boolean("disable_auto_download")) {
|
||||||
result.preload_large_videos = settings->preload_large_videos_;
|
result.is_enabled = false;
|
||||||
result.preload_next_audio = settings->preload_next_audio_;
|
result.preload_large_videos = false;
|
||||||
result.preload_stories = settings->preload_stories_;
|
result.preload_next_audio = false;
|
||||||
|
result.preload_stories = false;
|
||||||
|
} else {
|
||||||
|
result.is_enabled = settings->is_auto_download_enabled_;
|
||||||
|
result.preload_large_videos = settings->preload_large_videos_;
|
||||||
|
result.preload_next_audio = settings->preload_next_audio_;
|
||||||
|
result.preload_stories = settings->preload_stories_;
|
||||||
|
}
|
||||||
result.use_less_data_for_calls = settings->use_less_data_for_calls_;
|
result.use_less_data_for_calls = settings->use_less_data_for_calls_;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1491,4 +1491,18 @@ void BackgroundManager::get_current_state(vector<td_api::object_ptr<td_api::Upda
|
|||||||
updates.push_back(get_update_default_background_object(true));
|
updates.push_back(get_update_default_background_object(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BackgroundManager::memory_stats(vector<string> &output) {
|
||||||
|
output.push_back("\"backgrounds_\":"); output.push_back(std::to_string(backgrounds_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"background_id_to_file_source_id_\":"); output.push_back(std::to_string(background_id_to_file_source_id_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"name_to_background_id_\":"); output.push_back(std::to_string(name_to_background_id_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"file_id_to_background_id_\":"); output.push_back(std::to_string(file_id_to_background_id_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"loaded_from_database_backgrounds_\":"); output.push_back(std::to_string(loaded_from_database_backgrounds_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"installed_backgrounds_\":"); output.push_back(std::to_string(installed_backgrounds_.size()));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -35,6 +35,8 @@ class BackgroundManager final : public Actor {
|
|||||||
public:
|
public:
|
||||||
BackgroundManager(Td *td, ActorShared<> parent);
|
BackgroundManager(Td *td, ActorShared<> parent);
|
||||||
|
|
||||||
|
void memory_stats(vector<string> &output);
|
||||||
|
|
||||||
void get_backgrounds(bool for_dark_theme, Promise<td_api::object_ptr<td_api::backgrounds>> &&promise);
|
void get_backgrounds(bool for_dark_theme, Promise<td_api::object_ptr<td_api::backgrounds>> &&promise);
|
||||||
|
|
||||||
void reload_background(BackgroundId background_id, int64 access_hash, Promise<Unit> &&promise);
|
void reload_background(BackgroundId background_id, int64 access_hash, Promise<Unit> &&promise);
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include "td/telegram/LinkManager.h"
|
#include "td/telegram/LinkManager.h"
|
||||||
#include "td/telegram/logevent/LogEvent.h"
|
#include "td/telegram/logevent/LogEvent.h"
|
||||||
#include "td/telegram/logevent/LogEventHelper.h"
|
#include "td/telegram/logevent/LogEventHelper.h"
|
||||||
|
#include "td/telegram/MemoryManager.h"
|
||||||
#include "td/telegram/MessageSender.h"
|
#include "td/telegram/MessageSender.h"
|
||||||
#include "td/telegram/MessagesManager.h"
|
#include "td/telegram/MessagesManager.h"
|
||||||
#include "td/telegram/MessageTtl.h"
|
#include "td/telegram/MessageTtl.h"
|
||||||
@ -8605,10 +8606,18 @@ class ContactsManager::UserLogEvent {
|
|||||||
|
|
||||||
void ContactsManager::save_user(User *u, UserId user_id, bool from_binlog) {
|
void ContactsManager::save_user(User *u, UserId user_id, bool from_binlog) {
|
||||||
if (!G()->use_chat_info_database()) {
|
if (!G()->use_chat_info_database()) {
|
||||||
|
if (u != nullptr && G()->get_option_boolean("receive_access_hashes", false)) {
|
||||||
|
send_closure(G()->td(), &Td::send_update,
|
||||||
|
make_tl_object<td_api::updateAccessHash>(get_user_access_hash_object(user_id, u)));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CHECK(u != nullptr);
|
CHECK(u != nullptr);
|
||||||
if (!u->is_saved || !u->is_status_saved) { // TODO more effective handling of !u->is_status_saved
|
if (!u->is_saved || !u->is_status_saved) { // TODO more effective handling of !u->is_status_saved
|
||||||
|
if (u != nullptr && G()->get_option_boolean("receive_access_hashes", false)) {
|
||||||
|
send_closure(G()->td(), &Td::send_update,
|
||||||
|
make_tl_object<td_api::updateAccessHash>(get_user_access_hash_object(user_id, u)));
|
||||||
|
}
|
||||||
if (!from_binlog) {
|
if (!from_binlog) {
|
||||||
auto log_event = UserLogEvent(user_id, u);
|
auto log_event = UserLogEvent(user_id, u);
|
||||||
auto storer = get_log_event_storer(log_event);
|
auto storer = get_log_event_storer(log_event);
|
||||||
@ -9184,10 +9193,18 @@ class ContactsManager::ChannelLogEvent {
|
|||||||
|
|
||||||
void ContactsManager::save_channel(Channel *c, ChannelId channel_id, bool from_binlog) {
|
void ContactsManager::save_channel(Channel *c, ChannelId channel_id, bool from_binlog) {
|
||||||
if (!G()->use_chat_info_database()) {
|
if (!G()->use_chat_info_database()) {
|
||||||
|
if (c != nullptr && G()->get_option_boolean("receive_access_hashes", false)) {
|
||||||
|
send_closure(G()->td(), &Td::send_update,
|
||||||
|
make_tl_object<td_api::updateAccessHash>(get_channel_access_hash_object(channel_id, c)));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CHECK(c != nullptr);
|
CHECK(c != nullptr);
|
||||||
if (!c->is_saved) {
|
if (!c->is_saved) {
|
||||||
|
if (c != nullptr && G()->get_option_boolean("receive_access_hashes", false)) {
|
||||||
|
send_closure(G()->td(), &Td::send_update,
|
||||||
|
make_tl_object<td_api::updateAccessHash>(get_channel_access_hash_object(channel_id, c)));
|
||||||
|
}
|
||||||
if (!from_binlog) {
|
if (!from_binlog) {
|
||||||
auto log_event = ChannelLogEvent(channel_id, c);
|
auto log_event = ChannelLogEvent(channel_id, c);
|
||||||
auto storer = get_log_event_storer(log_event);
|
auto storer = get_log_event_storer(log_event);
|
||||||
@ -16581,6 +16598,32 @@ tl_object_ptr<td_api::user> ContactsManager::get_user_object(UserId user_id) con
|
|||||||
return get_user_object(user_id, get_user(user_id));
|
return get_user_object(user_id, get_user(user_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tl_object_ptr<td_api::accessHash> ContactsManager::get_user_access_hash_object(UserId user_id, const User *u) const {
|
||||||
|
if (u == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (!u->is_min_access_hash && u->access_hash != 0) {
|
||||||
|
tl_object_ptr<td_api::AccessHashType> type = make_tl_object<td_api::accessHashTypeUser>();
|
||||||
|
DialogId dialog_id(user_id);
|
||||||
|
return make_tl_object<td_api::accessHash>(dialog_id.get(), std::move(type), u->access_hash);
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tl_object_ptr<td_api::accessHash> ContactsManager::get_channel_access_hash_object(ChannelId channel_id, const Channel *c) const {
|
||||||
|
if (c == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (c->access_hash != 0) {
|
||||||
|
tl_object_ptr<td_api::AccessHashType> type = make_tl_object<td_api::accessHashTypeChannel>();
|
||||||
|
DialogId dialog_id(channel_id);
|
||||||
|
return make_tl_object<td_api::accessHash>(dialog_id.get(), std::move(type), c->access_hash);
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tl_object_ptr<td_api::user> ContactsManager::get_user_object(UserId user_id, const User *u) const {
|
tl_object_ptr<td_api::user> ContactsManager::get_user_object(UserId user_id, const User *u) const {
|
||||||
if (u == nullptr) {
|
if (u == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -16994,4 +17037,102 @@ void ContactsManager::get_current_state(vector<td_api::object_ptr<td_api::Update
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ContactsManager::memory_stats(vector<string> &output) {
|
||||||
|
|
||||||
|
output.push_back("\"users_\":"); output.push_back(std::to_string(users_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"users_full_\":"); output.push_back(std::to_string(users_full_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"user_photos_\":"); output.push_back(std::to_string(user_photos_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"unknown_users_\":"); output.push_back(std::to_string(unknown_users_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"pending_user_photos_\":"); output.push_back(std::to_string(pending_user_photos_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"user_profile_photo_file_source_ids_\":"); output.push_back(std::to_string(user_profile_photo_file_source_ids_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"my_photo_file_id_\":"); output.push_back(std::to_string(my_photo_file_id_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"chats_\":"); output.push_back(std::to_string(chats_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"chats_full_\":"); output.push_back(std::to_string(chats_full_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"unknown_chats_\":"); output.push_back(std::to_string(unknown_chats_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"chat_full_file_source_ids_\":"); output.push_back(std::to_string(chat_full_file_source_ids_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"min_channels_\":"); output.push_back(std::to_string(min_channels_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"channels_\":"); output.push_back(std::to_string(channels_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"channels_full_\":"); output.push_back(std::to_string(channels_full_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"unknown_channels_\":"); output.push_back(std::to_string(unknown_channels_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"channel_full_file_source_ids_\":"); output.push_back(std::to_string(channel_full_file_source_ids_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"secret_chats_\":"); output.push_back(std::to_string(secret_chats_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"unknown_secret_chats_\":"); output.push_back(std::to_string(unknown_secret_chats_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"secret_chats_with_user_\":"); output.push_back(std::to_string(secret_chats_with_user_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"invite_link_infos_\":"); output.push_back(std::to_string(invite_link_infos_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"dialog_access_by_invite_link_\":"); output.push_back(std::to_string(dialog_access_by_invite_link_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"load_user_from_database_queries_\":"); output.push_back(std::to_string(load_user_from_database_queries_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"loaded_from_database_users_\":"); output.push_back(std::to_string(loaded_from_database_users_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"unavailable_user_fulls_\":"); output.push_back(std::to_string(unavailable_user_fulls_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"load_chat_from_database_queries_\":"); output.push_back(std::to_string(load_chat_from_database_queries_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"loaded_from_database_chats_\":"); output.push_back(std::to_string(loaded_from_database_chats_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"unavailable_chat_fulls_\":"); output.push_back(std::to_string(unavailable_chat_fulls_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"load_channel_from_database_queries_\":"); output.push_back(std::to_string(load_channel_from_database_queries_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"loaded_from_database_channels_\":"); output.push_back(std::to_string(loaded_from_database_channels_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"unavailable_channel_fulls_\":"); output.push_back(std::to_string(unavailable_channel_fulls_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"load_secret_chat_from_database_queries_\":"); output.push_back(std::to_string(load_secret_chat_from_database_queries_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"loaded_from_database_secret_chats_\":"); output.push_back(std::to_string(loaded_from_database_secret_chats_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"dialog_administrators_\":"); output.push_back(std::to_string(dialog_administrators_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"uploaded_profile_photos_\":"); output.push_back(std::to_string(uploaded_profile_photos_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"imported_contacts_\":"); output.push_back(std::to_string(imported_contacts_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"cached_channel_participants_\":"); output.push_back(std::to_string(cached_channel_participants_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"load_contacts_queries_\":"); output.push_back(std::to_string(load_contacts_queries_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"load_imported_contacts_queries_\":"); output.push_back(std::to_string(load_imported_contacts_queries_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"all_imported_contacts_\":"); output.push_back(std::to_string(all_imported_contacts_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"users_nearby_\":"); output.push_back(std::to_string(users_nearby_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"channels_nearby_\":"); output.push_back(std::to_string(channels_nearby_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"all_users_nearby_\":"); output.push_back(std::to_string(all_users_nearby_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"linked_channel_ids_\":"); output.push_back(std::to_string(linked_channel_ids_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"restricted_user_ids_\":"); output.push_back(std::to_string(restricted_user_ids_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"restricted_channel_ids_\":"); output.push_back(std::to_string(restricted_channel_ids_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"next_all_imported_contacts_\":"); output.push_back(std::to_string(next_all_imported_contacts_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"imported_contact_user_ids_\":"); output.push_back(std::to_string(imported_contact_user_ids_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"unimported_contact_invites_\":"); output.push_back(std::to_string(unimported_contact_invites_.size()));
|
||||||
|
}
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -83,6 +83,8 @@ class ContactsManager final : public Actor {
|
|||||||
|
|
||||||
static UserId load_my_id();
|
static UserId load_my_id();
|
||||||
|
|
||||||
|
void memory_stats(vector<string> &output);
|
||||||
|
|
||||||
static UserId get_user_id(const tl_object_ptr<telegram_api::User> &user);
|
static UserId get_user_id(const tl_object_ptr<telegram_api::User> &user);
|
||||||
static ChatId get_chat_id(const tl_object_ptr<telegram_api::Chat> &chat);
|
static ChatId get_chat_id(const tl_object_ptr<telegram_api::Chat> &chat);
|
||||||
static ChannelId get_channel_id(const tl_object_ptr<telegram_api::Chat> &chat);
|
static ChannelId get_channel_id(const tl_object_ptr<telegram_api::Chat> &chat);
|
||||||
@ -1687,6 +1689,10 @@ class ContactsManager final : public Actor {
|
|||||||
|
|
||||||
tl_object_ptr<td_api::user> get_user_object(UserId user_id, const User *u) const;
|
tl_object_ptr<td_api::user> get_user_object(UserId user_id, const User *u) const;
|
||||||
|
|
||||||
|
tl_object_ptr<td_api::accessHash> get_user_access_hash_object(UserId user_id, const User *u) const;
|
||||||
|
|
||||||
|
tl_object_ptr<td_api::accessHash> get_channel_access_hash_object(ChannelId channel_id, const Channel *c) const;
|
||||||
|
|
||||||
tl_object_ptr<td_api::userFullInfo> get_user_full_info_object(UserId user_id, const UserFull *user_full) const;
|
tl_object_ptr<td_api::userFullInfo> get_user_full_info_object(UserId user_id, const UserFull *user_full) const;
|
||||||
|
|
||||||
td_api::object_ptr<td_api::updateBasicGroup> get_update_basic_group_object(ChatId chat_id, const Chat *c);
|
td_api::object_ptr<td_api::updateBasicGroup> get_update_basic_group_object(ChatId chat_id, const Chat *c);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "td/telegram/Td.h"
|
#include "td/telegram/Td.h"
|
||||||
#include "td/telegram/VideoNotesManager.h"
|
#include "td/telegram/VideoNotesManager.h"
|
||||||
#include "td/telegram/VideosManager.h"
|
#include "td/telegram/VideosManager.h"
|
||||||
|
#include "td/telegram/Global.h"
|
||||||
|
|
||||||
#include "td/utils/algorithm.h"
|
#include "td/utils/algorithm.h"
|
||||||
|
|
||||||
@ -36,24 +37,26 @@ void Document::append_file_ids(const Td *td, vector<FileId> &file_ids) const {
|
|||||||
|
|
||||||
file_ids.push_back(file_id);
|
file_ids.push_back(file_id);
|
||||||
|
|
||||||
FileId thumbnail_file_id = [&] {
|
if (!G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
switch (type) {
|
FileId thumbnail_file_id = [&] {
|
||||||
case Type::Animation:
|
switch (type) {
|
||||||
return td->animations_manager_->get_animation_thumbnail_file_id(file_id);
|
case Type::Animation:
|
||||||
case Type::Audio:
|
return td->animations_manager_->get_animation_thumbnail_file_id(file_id);
|
||||||
return td->audios_manager_->get_audio_thumbnail_file_id(file_id);
|
case Type::Audio:
|
||||||
case Type::General:
|
return td->audios_manager_->get_audio_thumbnail_file_id(file_id);
|
||||||
return td->documents_manager_->get_document_thumbnail_file_id(file_id);
|
case Type::General:
|
||||||
case Type::Video:
|
return td->documents_manager_->get_document_thumbnail_file_id(file_id);
|
||||||
return td->videos_manager_->get_video_thumbnail_file_id(file_id);
|
case Type::Video:
|
||||||
case Type::VideoNote:
|
return td->videos_manager_->get_video_thumbnail_file_id(file_id);
|
||||||
return td->video_notes_manager_->get_video_note_thumbnail_file_id(file_id);
|
case Type::VideoNote:
|
||||||
default:
|
return td->video_notes_manager_->get_video_note_thumbnail_file_id(file_id);
|
||||||
return FileId();
|
default:
|
||||||
|
return FileId();
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
if (thumbnail_file_id.is_valid()) {
|
||||||
|
file_ids.push_back(thumbnail_file_id);
|
||||||
}
|
}
|
||||||
}();
|
|
||||||
if (thumbnail_file_id.is_valid()) {
|
|
||||||
file_ids.push_back(thumbnail_file_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileId animated_thumbnail_file_id = [&] {
|
FileId animated_thumbnail_file_id = [&] {
|
||||||
|
@ -757,6 +757,10 @@ void DocumentsManager::merge_documents(FileId new_id, FileId old_id) {
|
|||||||
LOG_STATUS(td_->file_manager_->merge(new_id, old_id));
|
LOG_STATUS(td_->file_manager_->merge(new_id, old_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DocumentsManager::memory_stats(vector<string> &output) {
|
||||||
|
output.push_back("\"documents_\":"); output.push_back(std::to_string(documents_.calc_size()));
|
||||||
|
}
|
||||||
|
|
||||||
string DocumentsManager::get_document_search_text(FileId file_id) const {
|
string DocumentsManager::get_document_search_text(FileId file_id) const {
|
||||||
auto document = get_document(file_id);
|
auto document = get_document(file_id);
|
||||||
CHECK(document);
|
CHECK(document);
|
||||||
|
@ -82,6 +82,7 @@ class DocumentsManager {
|
|||||||
|
|
||||||
tl_object_ptr<td_api::document> get_document_object(FileId file_id, PhotoFormat thumbnail_format) const;
|
tl_object_ptr<td_api::document> get_document_object(FileId file_id, PhotoFormat thumbnail_format) const;
|
||||||
|
|
||||||
|
void memory_stats(vector<string> &output);
|
||||||
enum class Subtype : int32 { Background, Pattern, Ringtone, Story, Other };
|
enum class Subtype : int32 { Background, Pattern, Ringtone, Story, Other };
|
||||||
|
|
||||||
Document on_get_document(RemoteDocument remote_document, DialogId owner_dialog_id,
|
Document on_get_document(RemoteDocument remote_document, DialogId owner_dialog_id,
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
#include "td/utils/tl_helpers.h"
|
#include "td/utils/tl_helpers.h"
|
||||||
|
|
||||||
|
#include "td/telegram/ConfigManager.h"
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
template <class StorerT>
|
template <class StorerT>
|
||||||
@ -66,13 +68,25 @@ FileId DocumentsManager::parse_document(ParserT &parser) {
|
|||||||
has_thumbnail = true;
|
has_thumbnail = true;
|
||||||
}
|
}
|
||||||
if (has_file_name) {
|
if (has_file_name) {
|
||||||
parse(document->file_name, parser);
|
string tmp_filename;
|
||||||
|
parse(tmp_filename, parser);
|
||||||
|
if (G()->get_option_boolean("disable_document_filenames") &&
|
||||||
|
(document->mime_type.rfind("image/") == 0 || document->mime_type.rfind("video/") == 0 ||
|
||||||
|
document->mime_type.rfind("audio/") == 0)) {
|
||||||
|
document->file_name = "0";
|
||||||
|
} else {
|
||||||
|
document->file_name = tmp_filename;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (has_mime_type) {
|
if (has_mime_type) {
|
||||||
parse(document->mime_type, parser);
|
parse(document->mime_type, parser);
|
||||||
}
|
}
|
||||||
if (has_minithumbnail) {
|
if (has_minithumbnail) {
|
||||||
parse(document->minithumbnail, parser);
|
string tmp_minithumbnail;
|
||||||
|
parse(tmp_minithumbnail, parser);
|
||||||
|
if (!G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
|
document->minithumbnail = tmp_minithumbnail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (has_thumbnail) {
|
if (has_thumbnail) {
|
||||||
parse(document->thumbnail, parser);
|
parse(document->thumbnail, parser);
|
||||||
|
@ -507,4 +507,10 @@ td_api::object_ptr<td_api::message> FileReferenceManager::get_message_object(Fil
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileReferenceManager::memory_stats(vector<string> &output) {
|
||||||
|
output.push_back("\"nodes_\":"); output.push_back(std::to_string(nodes_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"file_sources_\":"); output.push_back(std::to_string(file_sources_.size()));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -94,6 +94,8 @@ class FileReferenceManager final : public Actor {
|
|||||||
template <class ParserT>
|
template <class ParserT>
|
||||||
FileSourceId parse_file_source(Td *td, ParserT &parser);
|
FileSourceId parse_file_source(Td *td, ParserT &parser);
|
||||||
|
|
||||||
|
void memory_stats(vector<string> &output);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Destination {
|
struct Destination {
|
||||||
NodeId node_id;
|
NodeId node_id;
|
||||||
|
@ -160,6 +160,10 @@ bool Global::use_message_database() const {
|
|||||||
return td_db_->use_message_database();
|
return td_db_->use_message_database();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Global::use_custom_database_format() const {
|
||||||
|
return td_db_->use_custom_database_format();
|
||||||
|
}
|
||||||
|
|
||||||
int32 Global::get_retry_after(int32 error_code, Slice error_message) {
|
int32 Global::get_retry_after(int32 error_code, Slice error_message) {
|
||||||
if (error_code != 429) {
|
if (error_code != 429) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -71,6 +71,7 @@ class SponsoredMessageManager;
|
|||||||
class StateManager;
|
class StateManager;
|
||||||
class StickersManager;
|
class StickersManager;
|
||||||
class StorageManager;
|
class StorageManager;
|
||||||
|
class MemoryManager;
|
||||||
class StoryManager;
|
class StoryManager;
|
||||||
class Td;
|
class Td;
|
||||||
class TdDb;
|
class TdDb;
|
||||||
@ -108,6 +109,52 @@ class Global final : public ActorContext {
|
|||||||
|
|
||||||
Status init(ActorId<Td> td, unique_ptr<TdDb> td_db_ptr) TD_WARN_UNUSED_RESULT;
|
Status init(ActorId<Td> td, unique_ptr<TdDb> td_db_ptr) TD_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
static bool get_use_custom_database(const std::string &database_directory) {
|
||||||
|
auto s = get_database_directory_opts(database_directory);
|
||||||
|
size_t qmarkpos;
|
||||||
|
std::string token;
|
||||||
|
size_t find_start_index = 0;
|
||||||
|
while ((qmarkpos = s.find_first_of('&'), find_start_index) != std::string::npos) {
|
||||||
|
token = s.substr(find_start_index, qmarkpos - find_start_index);
|
||||||
|
find_start_index = qmarkpos;
|
||||||
|
if ((qmarkpos = token.find_first_of('=')) != std::string::npos) {
|
||||||
|
std::string propkey = token.substr(0, qmarkpos), propval = token.substr(qmarkpos + 1);
|
||||||
|
if (propkey == "use_custom_database_format" && propval == "true") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string get_database_directory_path(const std::string &database_directory) {
|
||||||
|
if (database_directory.empty()) {
|
||||||
|
return database_directory;
|
||||||
|
}
|
||||||
|
size_t qmarkpos;
|
||||||
|
if ((qmarkpos = database_directory.find_first_of('?')) != std::string::npos) {
|
||||||
|
std::string path = database_directory.substr(0, qmarkpos),
|
||||||
|
opts = database_directory.substr(qmarkpos + 1);
|
||||||
|
return path;
|
||||||
|
} else {
|
||||||
|
return database_directory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string get_database_directory_opts(const std::string &database_directory) {
|
||||||
|
if (database_directory.empty()) {
|
||||||
|
return database_directory;
|
||||||
|
}
|
||||||
|
size_t qmarkpos;
|
||||||
|
if ((qmarkpos = database_directory.find_first_of('?')) != std::string::npos) {
|
||||||
|
std::string path = database_directory.substr(0, qmarkpos),
|
||||||
|
opts = database_directory.substr(qmarkpos + 1);
|
||||||
|
return opts;
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Slice get_dir() const;
|
Slice get_dir() const;
|
||||||
|
|
||||||
Slice get_secure_files_dir() const {
|
Slice get_secure_files_dir() const {
|
||||||
@ -448,6 +495,13 @@ class Global final : public ActorContext {
|
|||||||
storage_manager_ = storage_manager;
|
storage_manager_ = storage_manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ActorId<MemoryManager> memory_manager() const {
|
||||||
|
return memory_manager_;
|
||||||
|
}
|
||||||
|
void set_memory_manager(ActorId<MemoryManager> memory_manager) {
|
||||||
|
memory_manager_ = memory_manager;
|
||||||
|
}
|
||||||
|
|
||||||
ActorId<StoryManager> story_manager() const {
|
ActorId<StoryManager> story_manager() const {
|
||||||
return story_manager_;
|
return story_manager_;
|
||||||
}
|
}
|
||||||
@ -517,6 +571,8 @@ class Global final : public ActorContext {
|
|||||||
|
|
||||||
bool use_message_database() const;
|
bool use_message_database() const;
|
||||||
|
|
||||||
|
bool use_custom_database_format() const;
|
||||||
|
|
||||||
bool keep_media_order() const {
|
bool keep_media_order() const {
|
||||||
return use_file_database();
|
return use_file_database();
|
||||||
}
|
}
|
||||||
@ -653,6 +709,7 @@ class Global final : public ActorContext {
|
|||||||
ActorId<SponsoredMessageManager> sponsored_message_manager_;
|
ActorId<SponsoredMessageManager> sponsored_message_manager_;
|
||||||
ActorId<StickersManager> stickers_manager_;
|
ActorId<StickersManager> stickers_manager_;
|
||||||
ActorId<StorageManager> storage_manager_;
|
ActorId<StorageManager> storage_manager_;
|
||||||
|
ActorId<MemoryManager> memory_manager_;
|
||||||
ActorId<StoryManager> story_manager_;
|
ActorId<StoryManager> story_manager_;
|
||||||
ActorId<ThemeManager> theme_manager_;
|
ActorId<ThemeManager> theme_manager_;
|
||||||
ActorId<TimeZoneManager> time_zone_manager_;
|
ActorId<TimeZoneManager> time_zone_manager_;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "td/telegram/AccessRights.h"
|
#include "td/telegram/AccessRights.h"
|
||||||
#include "td/telegram/AuthManager.h"
|
#include "td/telegram/AuthManager.h"
|
||||||
|
#include "td/telegram/ConfigManager.h"
|
||||||
#include "td/telegram/ContactsManager.h"
|
#include "td/telegram/ContactsManager.h"
|
||||||
#include "td/telegram/DialogAction.h"
|
#include "td/telegram/DialogAction.h"
|
||||||
#include "td/telegram/DialogActionManager.h"
|
#include "td/telegram/DialogActionManager.h"
|
||||||
@ -16,6 +17,7 @@
|
|||||||
#include "td/telegram/DialogParticipantManager.h"
|
#include "td/telegram/DialogParticipantManager.h"
|
||||||
#include "td/telegram/Global.h"
|
#include "td/telegram/Global.h"
|
||||||
#include "td/telegram/MessageId.h"
|
#include "td/telegram/MessageId.h"
|
||||||
|
#include "td/telegram/MemoryManager.h"
|
||||||
#include "td/telegram/MessageSender.h"
|
#include "td/telegram/MessageSender.h"
|
||||||
#include "td/telegram/MessagesManager.h"
|
#include "td/telegram/MessagesManager.h"
|
||||||
#include "td/telegram/misc.h"
|
#include "td/telegram/misc.h"
|
||||||
@ -1004,6 +1006,18 @@ void GroupCallManager::tear_down() {
|
|||||||
parent_.reset();
|
parent_.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GroupCallManager::memory_stats(vector<string> &output) {
|
||||||
|
output.push_back("\"group_call_participants_\":"); output.push_back(std::to_string(group_call_participants_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"group_call_recent_speakers_\":"); output.push_back(std::to_string(group_call_recent_speakers_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"group_calls_\":"); output.push_back(std::to_string(group_calls_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"input_group_call_ids_\":"); output.push_back(std::to_string(input_group_call_ids_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"pending_join_requests_\":"); output.push_back(std::to_string(pending_join_requests_.size()));
|
||||||
|
}
|
||||||
|
|
||||||
void GroupCallManager::on_update_group_call_participant_order_timeout_callback(void *group_call_manager_ptr,
|
void GroupCallManager::on_update_group_call_participant_order_timeout_callback(void *group_call_manager_ptr,
|
||||||
int64 group_call_id_int) {
|
int64 group_call_id_int) {
|
||||||
if (G()->close_flag()) {
|
if (G()->close_flag()) {
|
||||||
@ -1163,7 +1177,7 @@ bool GroupCallManager::is_group_call_joined(InputGroupCallId input_group_call_id
|
|||||||
}
|
}
|
||||||
|
|
||||||
GroupCallId GroupCallManager::get_group_call_id(InputGroupCallId input_group_call_id, DialogId dialog_id) {
|
GroupCallId GroupCallManager::get_group_call_id(InputGroupCallId input_group_call_id, DialogId dialog_id) {
|
||||||
if (td_->auth_manager_->is_bot() || !input_group_call_id.is_valid()) {
|
if (G()->get_option_boolean("disable_group_calls") || td_->auth_manager_->is_bot() || !input_group_call_id.is_valid()) {
|
||||||
return GroupCallId();
|
return GroupCallId();
|
||||||
}
|
}
|
||||||
return add_group_call(input_group_call_id, dialog_id)->group_call_id;
|
return add_group_call(input_group_call_id, dialog_id)->group_call_id;
|
||||||
@ -4167,7 +4181,7 @@ void GroupCallManager::on_update_group_call_connection(string &&connection_param
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GroupCallManager::on_update_group_call(tl_object_ptr<telegram_api::GroupCall> group_call_ptr, DialogId dialog_id) {
|
void GroupCallManager::on_update_group_call(tl_object_ptr<telegram_api::GroupCall> group_call_ptr, DialogId dialog_id) {
|
||||||
if (td_->auth_manager_->is_bot()) {
|
if (G()->get_option_boolean("disable_group_calls") || td_->auth_manager_->is_bot()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (dialog_id != DialogId() && !dialog_id.is_valid()) {
|
if (dialog_id != DialogId() && !dialog_id.is_valid()) {
|
||||||
@ -4875,18 +4889,27 @@ tl_object_ptr<td_api::updateGroupCallParticipant> GroupCallManager::get_update_g
|
|||||||
|
|
||||||
void GroupCallManager::send_update_group_call(const GroupCall *group_call, const char *source) {
|
void GroupCallManager::send_update_group_call(const GroupCall *group_call, const char *source) {
|
||||||
LOG(INFO) << "Send update about " << group_call->group_call_id << " from " << source;
|
LOG(INFO) << "Send update about " << group_call->group_call_id << " from " << source;
|
||||||
|
if (G()->get_option_boolean("disable_group_calls")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
send_closure(G()->td(), &Td::send_update,
|
send_closure(G()->td(), &Td::send_update,
|
||||||
get_update_group_call_object(group_call, get_recent_speakers(group_call, true)));
|
get_update_group_call_object(group_call, get_recent_speakers(group_call, true)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GroupCallManager::send_update_group_call_participant(GroupCallId group_call_id,
|
void GroupCallManager::send_update_group_call_participant(GroupCallId group_call_id,
|
||||||
const GroupCallParticipant &participant, const char *source) {
|
const GroupCallParticipant &participant, const char *source) {
|
||||||
|
if (G()->get_option_boolean("disable_group_calls")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
LOG(INFO) << "Send update about " << participant << " in " << group_call_id << " from " << source;
|
LOG(INFO) << "Send update about " << participant << " in " << group_call_id << " from " << source;
|
||||||
send_closure(G()->td(), &Td::send_update, get_update_group_call_participant_object(group_call_id, participant));
|
send_closure(G()->td(), &Td::send_update, get_update_group_call_participant_object(group_call_id, participant));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GroupCallManager::send_update_group_call_participant(InputGroupCallId input_group_call_id,
|
void GroupCallManager::send_update_group_call_participant(InputGroupCallId input_group_call_id,
|
||||||
const GroupCallParticipant &participant, const char *source) {
|
const GroupCallParticipant &participant, const char *source) {
|
||||||
|
if (G()->get_option_boolean("disable_group_calls")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
auto group_call = get_group_call(input_group_call_id);
|
auto group_call = get_group_call(input_group_call_id);
|
||||||
CHECK(group_call != nullptr && group_call->is_inited);
|
CHECK(group_call != nullptr && group_call->is_inited);
|
||||||
send_update_group_call_participant(group_call->group_call_id, participant, source);
|
send_update_group_call_participant(group_call->group_call_id, participant, source);
|
||||||
|
@ -39,6 +39,10 @@ class GroupCallManager final : public Actor {
|
|||||||
GroupCallManager &operator=(GroupCallManager &&) = delete;
|
GroupCallManager &operator=(GroupCallManager &&) = delete;
|
||||||
~GroupCallManager() final;
|
~GroupCallManager() final;
|
||||||
|
|
||||||
|
void memory_stats(vector<string> &output);
|
||||||
|
|
||||||
|
DialogId get_group_call_participant_id(const td_api::object_ptr<td_api::MessageSender> &message_sender);
|
||||||
|
|
||||||
bool is_group_call_being_joined(InputGroupCallId input_group_call_id) const;
|
bool is_group_call_being_joined(InputGroupCallId input_group_call_id) const;
|
||||||
|
|
||||||
bool is_group_call_joined(InputGroupCallId input_group_call_id) const;
|
bool is_group_call_joined(InputGroupCallId input_group_call_id) const;
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "td/telegram/ContactsManager.h"
|
#include "td/telegram/ContactsManager.h"
|
||||||
#include "td/telegram/DialogManager.h"
|
#include "td/telegram/DialogManager.h"
|
||||||
#include "td/telegram/Document.h"
|
#include "td/telegram/Document.h"
|
||||||
|
#include "td/telegram/MemoryManager.h"
|
||||||
#include "td/telegram/DocumentsManager.h"
|
#include "td/telegram/DocumentsManager.h"
|
||||||
#include "td/telegram/files/FileManager.h"
|
#include "td/telegram/files/FileManager.h"
|
||||||
#include "td/telegram/files/FileType.h"
|
#include "td/telegram/files/FileType.h"
|
||||||
@ -2219,4 +2220,14 @@ void InlineQueriesManager::remove_recent_inline_bot(UserId bot_user_id, Promise<
|
|||||||
promise.set_value(Unit());
|
promise.set_value(Unit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InlineQueriesManager::memory_stats(vector<string> &output) {
|
||||||
|
output.push_back("\"recently_used_bot_user_ids_\":"); output.push_back(std::to_string(recently_used_bot_user_ids_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"inline_query_results_\":"); output.push_back(std::to_string(inline_query_results_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"inline_message_contents_\":"); output.push_back(std::to_string(inline_message_contents_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"query_id_to_bot_user_id_\":"); output.push_back(std::to_string(query_id_to_bot_user_id_.size()));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -38,6 +38,8 @@ class InlineQueriesManager final : public Actor {
|
|||||||
public:
|
public:
|
||||||
InlineQueriesManager(Td *td, ActorShared<> parent);
|
InlineQueriesManager(Td *td, ActorShared<> parent);
|
||||||
|
|
||||||
|
void memory_stats(vector<string> &output);
|
||||||
|
|
||||||
void after_get_difference();
|
void after_get_difference();
|
||||||
|
|
||||||
void answer_inline_query(int64 inline_query_id, bool is_personal,
|
void answer_inline_query(int64 inline_query_id, bool is_personal,
|
||||||
|
196
td/telegram/MemoryManager.cpp
Normal file
196
td/telegram/MemoryManager.cpp
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
//
|
||||||
|
// Copyright Andrea Cavalli (nospam@warp.ovh) 2020
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#include "td/telegram/MemoryManager.h"
|
||||||
|
|
||||||
|
#include "td/telegram/secret_api.h"
|
||||||
|
#include "td/telegram/td_api.h"
|
||||||
|
#include "td/telegram/telegram_api.h"
|
||||||
|
|
||||||
|
#include "td/telegram/AccessRights.h"
|
||||||
|
#include "td/telegram/AuthManager.h"
|
||||||
|
#include "td/telegram/ConfigManager.h"
|
||||||
|
#include "td/telegram/ContactsManager.h"
|
||||||
|
#include "td/telegram/DialogId.h"
|
||||||
|
#include "td/telegram/Document.h"
|
||||||
|
#include "td/telegram/DocumentsManager.h"
|
||||||
|
#include "td/telegram/FileReferenceManager.h"
|
||||||
|
#include "td/telegram/files/FileLocation.h"
|
||||||
|
#include "td/telegram/files/FileManager.h"
|
||||||
|
#include "td/telegram/WebPagesManager.h"
|
||||||
|
#include "td/telegram/StickersManager.h"
|
||||||
|
#include "td/telegram/VideoNotesManager.h"
|
||||||
|
#include "td/telegram/VideosManager.h"
|
||||||
|
#include "td/telegram/AudiosManager.h"
|
||||||
|
#include "td/telegram/AnimationsManager.h"
|
||||||
|
#include "td/telegram/GroupCallManager.h"
|
||||||
|
#include "td/telegram/BackgroundManager.h"
|
||||||
|
#include "td/telegram/PollManager.h"
|
||||||
|
#include "td/telegram/InlineQueriesManager.h"
|
||||||
|
#include "td/telegram/files/FileType.h"
|
||||||
|
#include "td/telegram/Global.h"
|
||||||
|
#include "td/telegram/LanguagePackManager.h"
|
||||||
|
#include "td/telegram/logevent/LogEvent.h"
|
||||||
|
#include "td/telegram/MessagesManager.h"
|
||||||
|
#include "td/telegram/misc.h"
|
||||||
|
#include "td/telegram/net/DcId.h"
|
||||||
|
#include "td/telegram/net/MtprotoHeader.h"
|
||||||
|
#include "td/telegram/Td.h"
|
||||||
|
#include "td/telegram/TdDb.h"
|
||||||
|
|
||||||
|
#include "td/actor/MultiPromise.h"
|
||||||
|
#include "td/actor/PromiseFuture.h"
|
||||||
|
#include "td/actor/SleepActor.h"
|
||||||
|
|
||||||
|
#include "td/db/SqliteKeyValue.h"
|
||||||
|
#include "td/db/SqliteKeyValueAsync.h"
|
||||||
|
|
||||||
|
#include "td/utils/format.h"
|
||||||
|
#include "td/utils/logging.h"
|
||||||
|
#include "td/utils/misc.h"
|
||||||
|
#include "td/utils/PathView.h"
|
||||||
|
#include "td/utils/Random.h"
|
||||||
|
#include "td/utils/Slice.h"
|
||||||
|
#include "td/utils/Time.h"
|
||||||
|
#include "td/utils/tl_helpers.h"
|
||||||
|
#include "td/utils/utf8.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <limits>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
tl_object_ptr<td_api::memoryStatistics> MemoryStats::get_memory_statistics_object() const {
|
||||||
|
return make_tl_object<td_api::memoryStatistics>(debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryManager::MemoryManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryManager::start_up() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryManager::tear_down() {
|
||||||
|
parent_.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryManager::get_memory_stats(bool full, Promise<MemoryStats> promise) const {
|
||||||
|
vector<string> output = {"{"};
|
||||||
|
|
||||||
|
output.push_back("\"memory_stats\":{");
|
||||||
|
|
||||||
|
output.push_back("\"messages_manager_\":{");
|
||||||
|
td_->messages_manager_->memory_stats(output);
|
||||||
|
output.push_back("}");
|
||||||
|
|
||||||
|
output.push_back(",");
|
||||||
|
|
||||||
|
output.push_back("\"contacts_manager_\":{");
|
||||||
|
td_->contacts_manager_->memory_stats(output);
|
||||||
|
output.push_back("}");
|
||||||
|
|
||||||
|
output.push_back(",");
|
||||||
|
|
||||||
|
output.push_back("\"web_pages_manager_\":{");
|
||||||
|
td_->web_pages_manager_->memory_stats(output);
|
||||||
|
output.push_back("}");
|
||||||
|
|
||||||
|
output.push_back(",");
|
||||||
|
|
||||||
|
output.push_back("\"stickers_manager_\":{");
|
||||||
|
td_->stickers_manager_->memory_stats(output);
|
||||||
|
output.push_back("}");
|
||||||
|
|
||||||
|
output.push_back(",");
|
||||||
|
|
||||||
|
output.push_back("\"documents_manager_\":{");
|
||||||
|
td_->documents_manager_->memory_stats(output);
|
||||||
|
output.push_back("}");
|
||||||
|
|
||||||
|
output.push_back(",");
|
||||||
|
|
||||||
|
output.push_back("\"video_notes_manager_\":{");
|
||||||
|
td_->video_notes_manager_->memory_stats(output);
|
||||||
|
output.push_back("}");
|
||||||
|
|
||||||
|
output.push_back(",");
|
||||||
|
|
||||||
|
output.push_back("\"videos_manager_\":{");
|
||||||
|
td_->videos_manager_->memory_stats(output);
|
||||||
|
output.push_back("}");
|
||||||
|
|
||||||
|
output.push_back(",");
|
||||||
|
|
||||||
|
output.push_back("\"audios_manager_\":{");
|
||||||
|
td_->audios_manager_->memory_stats(output);
|
||||||
|
output.push_back("}");
|
||||||
|
|
||||||
|
output.push_back(",");
|
||||||
|
|
||||||
|
output.push_back("\"animations_manager_\":{");
|
||||||
|
td_->animations_manager_->memory_stats(output);
|
||||||
|
output.push_back("}");
|
||||||
|
|
||||||
|
output.push_back(",");
|
||||||
|
|
||||||
|
output.push_back("\"file_manager_\":{");
|
||||||
|
td_->file_manager_->memory_stats(output);
|
||||||
|
output.push_back("}");
|
||||||
|
|
||||||
|
output.push_back(",");
|
||||||
|
|
||||||
|
output.push_back("\"file_reference_manager_\":{");
|
||||||
|
td_->file_reference_manager_->memory_stats(output);
|
||||||
|
output.push_back("}");
|
||||||
|
|
||||||
|
output.push_back(",");
|
||||||
|
|
||||||
|
output.push_back("\"group_call_manager_\":{");
|
||||||
|
td_->group_call_manager_->memory_stats(output);
|
||||||
|
output.push_back("}");
|
||||||
|
|
||||||
|
output.push_back(",");
|
||||||
|
|
||||||
|
output.push_back("\"background_manager_\":{");
|
||||||
|
td_->background_manager_->memory_stats(output);
|
||||||
|
output.push_back("}");
|
||||||
|
|
||||||
|
output.push_back(",");
|
||||||
|
|
||||||
|
output.push_back("\"inline_queries_manager_\":{");
|
||||||
|
td_->inline_queries_manager_->memory_stats(output);
|
||||||
|
output.push_back("}");
|
||||||
|
|
||||||
|
|
||||||
|
output.push_back(",");
|
||||||
|
|
||||||
|
output.push_back("\"poll_manager_\":{");
|
||||||
|
td_->poll_manager_->memory_stats(output);
|
||||||
|
output.push_back("}");
|
||||||
|
|
||||||
|
output.push_back("}");
|
||||||
|
|
||||||
|
output.push_back("}");
|
||||||
|
|
||||||
|
string s;
|
||||||
|
s = accumulate(output.begin(), output.end(), s);
|
||||||
|
auto value = MemoryStats(s);
|
||||||
|
|
||||||
|
promise.set_value(std::move(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryManager::get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const {
|
||||||
|
if (td_->auth_manager_->is_bot()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Never return updates
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace td
|
63
td/telegram/MemoryManager.h
Normal file
63
td/telegram/MemoryManager.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
//
|
||||||
|
// Copyright Andrea Cavalli (nospam@warp.ovh) 2020
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/actor/actor.h"
|
||||||
|
#include "td/actor/MultiPromise.h"
|
||||||
|
#include "td/actor/PromiseFuture.h"
|
||||||
|
#include "td/actor/Timeout.h"
|
||||||
|
|
||||||
|
#include "td/telegram/files/FileId.h"
|
||||||
|
#include "td/telegram/files/FileSourceId.h"
|
||||||
|
#include "td/telegram/Photo.h"
|
||||||
|
#include "td/telegram/SecretInputMedia.h"
|
||||||
|
|
||||||
|
#include "td/utils/buffer.h"
|
||||||
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/Hints.h"
|
||||||
|
#include "td/utils/Slice.h"
|
||||||
|
#include "td/utils/Status.h"
|
||||||
|
|
||||||
|
#include "td/telegram/td_api.h"
|
||||||
|
#include "td/telegram/telegram_api.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <tuple>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class Td;
|
||||||
|
|
||||||
|
struct MemoryStats {
|
||||||
|
string debug;
|
||||||
|
MemoryStats() = default;
|
||||||
|
explicit MemoryStats(string debug) : debug(std::move(debug)) {
|
||||||
|
}
|
||||||
|
tl_object_ptr<td_api::memoryStatistics> get_memory_statistics_object() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MemoryManager : public Actor {
|
||||||
|
public:
|
||||||
|
MemoryManager(Td *td, ActorShared<> parent);
|
||||||
|
|
||||||
|
void get_memory_stats(bool full, Promise<MemoryStats> promise) const;
|
||||||
|
|
||||||
|
void get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void start_up() override;
|
||||||
|
|
||||||
|
void tear_down() override;
|
||||||
|
|
||||||
|
Td *td_;
|
||||||
|
ActorShared<> parent_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace td
|
@ -7464,6 +7464,7 @@ void update_message_content_file_id_remote(MessageContent *content, FileId file_
|
|||||||
}
|
}
|
||||||
|
|
||||||
FileId get_message_content_thumbnail_file_id(const MessageContent *content, const Td *td) {
|
FileId get_message_content_thumbnail_file_id(const MessageContent *content, const Td *td) {
|
||||||
|
if (!G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
switch (content->get_type()) {
|
switch (content->get_type()) {
|
||||||
case MessageContentType::Animation:
|
case MessageContentType::Animation:
|
||||||
return td->animations_manager_->get_animation_thumbnail_file_id(
|
return td->animations_manager_->get_animation_thumbnail_file_id(
|
||||||
@ -7489,6 +7490,7 @@ FileId get_message_content_thumbnail_file_id(const MessageContent *content, cons
|
|||||||
return FileId();
|
return FileId();
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return FileId();
|
return FileId();
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
#include "td/telegram/LinkManager.h"
|
#include "td/telegram/LinkManager.h"
|
||||||
#include "td/telegram/Location.h"
|
#include "td/telegram/Location.h"
|
||||||
#include "td/telegram/logevent/LogEvent.h"
|
#include "td/telegram/logevent/LogEvent.h"
|
||||||
|
#include "td/telegram/MemoryManager.h"
|
||||||
#include "td/telegram/MessageContent.h"
|
#include "td/telegram/MessageContent.h"
|
||||||
#include "td/telegram/MessageDb.h"
|
#include "td/telegram/MessageDb.h"
|
||||||
#include "td/telegram/MessageEntity.h"
|
#include "td/telegram/MessageEntity.h"
|
||||||
@ -5697,6 +5698,82 @@ void MessagesManager::update_message_reply_count(Dialog *d, MessageId message_id
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MessagesManager::memory_stats(vector<string> &output) {
|
||||||
|
output.push_back("\"being_sent_messages_\":"); output.push_back(std::to_string(this->being_sent_messages_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"being_loaded_secret_thumbnails_\":"); output.push_back(std::to_string(this->being_loaded_secret_thumbnails_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"being_uploaded_dialog_photos_\":"); output.push_back(std::to_string(this->being_uploaded_dialog_photos_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"being_uploaded_files_\":"); output.push_back(std::to_string(this->being_uploaded_files_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"being_uploaded_thumbnails_\":"); output.push_back(std::to_string(this->being_uploaded_thumbnails_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"active_dialog_actions_\":"); output.push_back(std::to_string(this->active_dialog_actions_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"created_dialogs_\":"); output.push_back(std::to_string(this->created_dialogs_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"dialog_folders_\":"); output.push_back(std::to_string(this->dialog_folders_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"dialog_lists_\":"); output.push_back(std::to_string(this->dialog_lists_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"dialog_online_member_counts_\":"); output.push_back(std::to_string(this->dialog_online_member_counts_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"dialogs_\":"); output.push_back(std::to_string(this->dialogs_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"found_call_messages_\":"); output.push_back(std::to_string(this->found_call_messages_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"found_common_dialogs_\":"); output.push_back(std::to_string(this->found_common_dialogs_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"found_dialog_messages_\":"); output.push_back(std::to_string(this->found_dialog_messages_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"found_dialog_messages_dialog_id_\":"); output.push_back(std::to_string(this->found_dialog_messages_dialog_id_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"found_fts_messages_\":"); output.push_back(std::to_string(this->found_fts_messages_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"postponed_channel_updates_\":"); output.push_back(std::to_string(this->postponed_channel_updates_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"is_channel_difference_finished_\":"); output.push_back(std::to_string(this->is_channel_difference_finished_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"get_dialogs_tasks_\":"); output.push_back(std::to_string(this->get_dialogs_tasks_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"dialog_bot_command_message_ids_\":"); output.push_back(std::to_string(this->dialog_bot_command_message_ids_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"pending_message_imports_\":"); output.push_back(std::to_string(this->pending_message_imports_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"found_messages_\":"); output.push_back(std::to_string(this->found_messages_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"found_on_server_dialogs_\":"); output.push_back(std::to_string(this->found_on_server_dialogs_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"found_public_dialogs_\":"); output.push_back(std::to_string(this->found_public_dialogs_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"loaded_dialogs_\":"); output.push_back(std::to_string(this->loaded_dialogs_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"search_public_dialogs_queries_\":"); output.push_back(std::to_string(this->search_public_dialogs_queries_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"message_embedding_codes_\":"); output.push_back(std::to_string(this->message_embedding_codes_->size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"message_full_id_to_file_source_id_\":"); output.push_back(std::to_string(this->message_full_id_to_file_source_id_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"get_dialog_message_by_date_results_\":"); output.push_back(std::to_string(this->get_dialog_message_by_date_results_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"get_dialog_query_log_event_id_\":"); output.push_back(std::to_string(this->get_dialog_query_log_event_id_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"get_channel_difference_to_log_event_id_\":"); output.push_back(std::to_string(this->get_channel_difference_to_log_event_id_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"last_clear_history_message_id_to_dialog_id_\":"); output.push_back(std::to_string(this->last_clear_history_message_id_to_dialog_id_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"last_outgoing_forwarded_message_date_\":"); output.push_back(std::to_string(this->last_outgoing_forwarded_message_date_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"load_active_live_location_messages_queries_\":"); output.push_back(std::to_string(this->load_active_live_location_messages_queries_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"notification_group_id_to_dialog_id_\":"); output.push_back(std::to_string(this->notification_group_id_to_dialog_id_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"previous_repaired_read_inbox_max_message_id_\":"); output.push_back(std::to_string(this->previous_repaired_read_inbox_max_message_id_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"channel_get_difference_retry_timeouts_\":"); output.push_back(std::to_string(this->channel_get_difference_retry_timeouts_.size()));
|
||||||
|
}
|
||||||
|
|
||||||
bool MessagesManager::have_dialog_scheduled_messages_in_memory(const Dialog *d) {
|
bool MessagesManager::have_dialog_scheduled_messages_in_memory(const Dialog *d) {
|
||||||
return d->scheduled_messages != nullptr && !d->scheduled_messages->scheduled_messages_.empty();
|
return d->scheduled_messages != nullptr && !d->scheduled_messages->scheduled_messages_.empty();
|
||||||
}
|
}
|
||||||
@ -9378,6 +9455,9 @@ void MessagesManager::on_get_recent_locations(DialogId dialog_id, int32 limit, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MessagesManager::delete_messages_from_updates(const vector<MessageId> &message_ids, bool is_permanent) {
|
void MessagesManager::delete_messages_from_updates(const vector<MessageId> &message_ids, bool is_permanent) {
|
||||||
|
if (G()->get_option_boolean("ignore_server_deletes_and_reads", false)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
FlatHashMap<DialogId, vector<int64>, DialogIdHash> deleted_message_ids;
|
FlatHashMap<DialogId, vector<int64>, DialogIdHash> deleted_message_ids;
|
||||||
FlatHashMap<DialogId, bool, DialogIdHash> need_update_dialog_pos;
|
FlatHashMap<DialogId, bool, DialogIdHash> need_update_dialog_pos;
|
||||||
vector<unique_ptr<Message>> deleted_messages;
|
vector<unique_ptr<Message>> deleted_messages;
|
||||||
@ -10992,6 +11072,9 @@ void MessagesManager::read_all_dialog_reactions_on_server(DialogId dialog_id, ui
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MessagesManager::read_message_content_from_updates(MessageId message_id, int32 read_date) {
|
void MessagesManager::read_message_content_from_updates(MessageId message_id, int32 read_date) {
|
||||||
|
if (G()->get_option_boolean("ignore_server_deletes_and_reads", false)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!message_id.is_valid() || !message_id.is_server()) {
|
if (!message_id.is_valid() || !message_id.is_server()) {
|
||||||
LOG(ERROR) << "Incoming update tries to read content of " << message_id;
|
LOG(ERROR) << "Incoming update tries to read content of " << message_id;
|
||||||
return;
|
return;
|
||||||
@ -14696,7 +14779,8 @@ void MessagesManager::on_get_dialogs(FolderId folder_id, vector<tl_object_ptr<te
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool MessagesManager::is_message_unload_enabled() const {
|
bool MessagesManager::is_message_unload_enabled() const {
|
||||||
return G()->use_message_database() || td_->auth_manager_->is_bot();
|
auto has_custom_unload_time = G()->have_option("message_unload_delay");
|
||||||
|
return G()->use_message_database() || td_->auth_manager_->is_bot() || has_custom_unload_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MessagesManager::can_unload_message(const Dialog *d, const Message *m) const {
|
bool MessagesManager::can_unload_message(const Dialog *d, const Message *m) const {
|
||||||
@ -15218,7 +15302,9 @@ void MessagesManager::on_message_deleted(Dialog *d, Message *m, bool is_permanen
|
|||||||
case DialogType::User:
|
case DialogType::User:
|
||||||
case DialogType::Chat:
|
case DialogType::Chat:
|
||||||
if (m->message_id.is_server()) {
|
if (m->message_id.is_server()) {
|
||||||
message_id_to_dialog_id_.erase(m->message_id);
|
if (!G()->get_option_boolean("ignore_server_deletes_and_reads", false)) {
|
||||||
|
message_id_to_dialog_id_.erase(m->message_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DialogType::Channel:
|
case DialogType::Channel:
|
||||||
@ -28642,6 +28728,10 @@ void MessagesManager::send_update_chat_last_message_impl(const Dialog *d, const
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (G()->get_option_boolean("ignore_update_chat_last_message")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CHECK(d != nullptr);
|
CHECK(d != nullptr);
|
||||||
LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id << " in send_update_chat_last_message from "
|
LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id << " in send_update_chat_last_message from "
|
||||||
<< source;
|
<< source;
|
||||||
@ -28786,10 +28876,12 @@ void MessagesManager::send_update_chat_read_inbox(const Dialog *d, bool force, c
|
|||||||
LOG(INFO) << "Send updateChatReadInbox in " << d->dialog_id << "("
|
LOG(INFO) << "Send updateChatReadInbox in " << d->dialog_id << "("
|
||||||
<< td_->dialog_manager_->get_dialog_title(d->dialog_id) << ") to " << d->server_unread_count << " + "
|
<< td_->dialog_manager_->get_dialog_title(d->dialog_id) << ") to " << d->server_unread_count << " + "
|
||||||
<< d->local_unread_count << " from " << source;
|
<< d->local_unread_count << " from " << source;
|
||||||
|
if (!G()->get_option_boolean("ignore_update_chat_read_inbox")) {
|
||||||
send_closure(G()->td(), &Td::send_update,
|
send_closure(G()->td(), &Td::send_update,
|
||||||
td_api::make_object<td_api::updateChatReadInbox>(
|
td_api::make_object<td_api::updateChatReadInbox>(
|
||||||
get_chat_id_object(d->dialog_id, "updateChatReadInbox"), d->last_read_inbox_message_id.get(),
|
get_chat_id_object(d->dialog_id, "updateChatReadInbox"), d->last_read_inbox_message_id.get(),
|
||||||
d->server_unread_count + d->local_unread_count));
|
d->server_unread_count + d->local_unread_count));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37933,6 +38025,10 @@ void MessagesManager::suffix_load_query_ready(DialogId dialog_id) {
|
|||||||
|
|
||||||
LOG(INFO) << "Finished suffix load query in " << dialog_id;
|
LOG(INFO) << "Finished suffix load query in " << dialog_id;
|
||||||
auto *d = get_dialog(dialog_id);
|
auto *d = get_dialog(dialog_id);
|
||||||
|
if (d == nullptr) {
|
||||||
|
LOG(ERROR) << "Unknown dialog " << dialog_id;
|
||||||
|
return;
|
||||||
|
}
|
||||||
bool is_unchanged = queries->suffix_load_first_message_id_ == queries->suffix_load_query_message_id_;
|
bool is_unchanged = queries->suffix_load_first_message_id_ == queries->suffix_load_query_message_id_;
|
||||||
suffix_load_update_first_message_id(d, queries);
|
suffix_load_update_first_message_id(d, queries);
|
||||||
if (is_unchanged && queries->suffix_load_first_message_id_ == queries->suffix_load_query_message_id_) {
|
if (is_unchanged && queries->suffix_load_first_message_id_ == queries->suffix_load_query_message_id_) {
|
||||||
@ -38198,7 +38294,10 @@ void MessagesManager::set_sponsored_dialog(DialogId dialog_id, DialogSource sour
|
|||||||
CHECK(sponsored_dialog_id_.is_valid());
|
CHECK(sponsored_dialog_id_.is_valid());
|
||||||
sponsored_dialog_source_ = std::move(source);
|
sponsored_dialog_source_ = std::move(source);
|
||||||
const Dialog *d = get_dialog(sponsored_dialog_id_);
|
const Dialog *d = get_dialog(sponsored_dialog_id_);
|
||||||
CHECK(d != nullptr);
|
if (d == nullptr) {
|
||||||
|
LOG(ERROR) << "Unknown dialog " << dialog_id;
|
||||||
|
return;
|
||||||
|
}
|
||||||
send_update_chat_position(DialogListId(FolderId::main()), d, "set_sponsored_dialog");
|
send_update_chat_position(DialogListId(FolderId::main()), d, "set_sponsored_dialog");
|
||||||
save_sponsored_dialog();
|
save_sponsored_dialog();
|
||||||
}
|
}
|
||||||
@ -38208,7 +38307,10 @@ void MessagesManager::set_sponsored_dialog(DialogId dialog_id, DialogSource sour
|
|||||||
bool need_update_total_chat_count = false;
|
bool need_update_total_chat_count = false;
|
||||||
if (sponsored_dialog_id_.is_valid()) {
|
if (sponsored_dialog_id_.is_valid()) {
|
||||||
const Dialog *d = get_dialog(sponsored_dialog_id_);
|
const Dialog *d = get_dialog(sponsored_dialog_id_);
|
||||||
CHECK(d != nullptr);
|
if (d == nullptr) {
|
||||||
|
LOG(ERROR) << "Unknown dialog " << dialog_id;
|
||||||
|
return;
|
||||||
|
}
|
||||||
bool was_sponsored = is_dialog_sponsored(d);
|
bool was_sponsored = is_dialog_sponsored(d);
|
||||||
sponsored_dialog_id_ = DialogId();
|
sponsored_dialog_id_ = DialogId();
|
||||||
sponsored_dialog_source_ = DialogSource();
|
sponsored_dialog_source_ = DialogSource();
|
||||||
@ -38221,7 +38323,10 @@ void MessagesManager::set_sponsored_dialog(DialogId dialog_id, DialogSource sour
|
|||||||
if (dialog_id.is_valid()) {
|
if (dialog_id.is_valid()) {
|
||||||
force_create_dialog(dialog_id, "set_sponsored_dialog_id");
|
force_create_dialog(dialog_id, "set_sponsored_dialog_id");
|
||||||
const Dialog *d = get_dialog(dialog_id);
|
const Dialog *d = get_dialog(dialog_id);
|
||||||
CHECK(d != nullptr);
|
if (d == nullptr) {
|
||||||
|
LOG(ERROR) << "Unknown dialog " << dialog_id;
|
||||||
|
return;
|
||||||
|
}
|
||||||
add_sponsored_dialog(d, std::move(source));
|
add_sponsored_dialog(d, std::move(source));
|
||||||
if (is_dialog_sponsored(d)) {
|
if (is_dialog_sponsored(d)) {
|
||||||
need_update_total_chat_count = !need_update_total_chat_count;
|
need_update_total_chat_count = !need_update_total_chat_count;
|
||||||
|
@ -143,6 +143,8 @@ class MessagesManager final : public Actor {
|
|||||||
|
|
||||||
static bool is_invalid_poll_message(const telegram_api::Message *message);
|
static bool is_invalid_poll_message(const telegram_api::Message *message);
|
||||||
|
|
||||||
|
void memory_stats(vector<string> &output);
|
||||||
|
|
||||||
static int32 get_message_date(const tl_object_ptr<telegram_api::Message> &message_ptr);
|
static int32 get_message_date(const tl_object_ptr<telegram_api::Message> &message_ptr);
|
||||||
|
|
||||||
void on_get_empty_messages(DialogId dialog_id, const vector<MessageId> &empty_message_ids);
|
void on_get_empty_messages(DialogId dialog_id, const vector<MessageId> &empty_message_ids);
|
||||||
|
@ -166,7 +166,11 @@ void NotificationManager::on_flush_pending_updates_timeout_callback(void *notifi
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool NotificationManager::is_disabled() const {
|
bool NotificationManager::is_disabled() const {
|
||||||
|
if ( G()->get_option_boolean("disable_notifications")) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
return G()->close_flag() || !td_->auth_manager_->is_authorized() || td_->auth_manager_->is_bot();
|
return G()->close_flag() || !td_->auth_manager_->is_authorized() || td_->auth_manager_->is_bot();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder &operator<<(StringBuilder &string_builder, const NotificationManager::ActiveNotificationsUpdate &update) {
|
StringBuilder &operator<<(StringBuilder &string_builder, const NotificationManager::ActiveNotificationsUpdate &update) {
|
||||||
|
@ -797,6 +797,26 @@ void OptionManager::set_option(const string &name, td_api::object_ptr<td_api::Op
|
|||||||
if (set_boolean_option("disable_time_adjustment_protection")) {
|
if (set_boolean_option("disable_time_adjustment_protection")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Start TDLight options
|
||||||
|
if (set_boolean_option("disable_document_filenames")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (set_boolean_option("disable_minithumbnails")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (set_boolean_option("disable_notifications")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (set_boolean_option("disable_group_calls")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (set_boolean_option("disable_auto_download")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// End TDLight options
|
||||||
|
if (set_boolean_option("disable_persistent_network_statistics")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!is_bot && set_boolean_option("disable_top_chats")) {
|
if (!is_bot && set_boolean_option("disable_top_chats")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -822,6 +842,20 @@ void OptionManager::set_option(const string &name, td_api::object_ptr<td_api::Op
|
|||||||
if (set_boolean_option("ignore_platform_restrictions")) {
|
if (set_boolean_option("ignore_platform_restrictions")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Start TDLight options
|
||||||
|
if (set_boolean_option("ignore_server_deletes_and_reads")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (set_boolean_option("ignore_update_chat_last_message")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (set_boolean_option("ignore_update_chat_read_inbox")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (set_boolean_option("ignore_update_user_chat_action")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// End TDLight options
|
||||||
if (set_boolean_option("is_emulator")) {
|
if (set_boolean_option("is_emulator")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -905,6 +939,11 @@ void OptionManager::set_option(const string &name, td_api::object_ptr<td_api::Op
|
|||||||
if (set_boolean_option("reuse_uploaded_photos_by_hash")) {
|
if (set_boolean_option("reuse_uploaded_photos_by_hash")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Start TDLight options
|
||||||
|
if (set_boolean_option("receive_access_hashes")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// End TDLight options
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
if (set_integer_option("storage_max_files_size")) {
|
if (set_integer_option("storage_max_files_size")) {
|
||||||
|
@ -55,7 +55,9 @@ ProfilePhoto get_profile_photo(FileManager *file_manager, UserId user_id, int64
|
|||||||
result.has_animation = profile_photo->has_video_;
|
result.has_animation = profile_photo->has_video_;
|
||||||
result.is_personal = profile_photo->personal_;
|
result.is_personal = profile_photo->personal_;
|
||||||
result.id = profile_photo->photo_id_;
|
result.id = profile_photo->photo_id_;
|
||||||
result.minithumbnail = profile_photo->stripped_thumb_.as_slice().str();
|
if (!G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
|
result.minithumbnail = profile_photo->stripped_thumb_.as_slice().str();
|
||||||
|
}
|
||||||
result.small_file_id =
|
result.small_file_id =
|
||||||
register_photo_size(file_manager, PhotoSizeSource::dialog_photo(DialogId(user_id), user_access_hash, false),
|
register_photo_size(file_manager, PhotoSizeSource::dialog_photo(DialogId(user_id), user_access_hash, false),
|
||||||
result.id, 0 /*access_hash*/, "" /*file_reference*/, DialogId(), 0 /*file_size*/, dc_id,
|
result.id, 0 /*access_hash*/, "" /*file_reference*/, DialogId(), 0 /*file_size*/, dc_id,
|
||||||
@ -333,7 +335,11 @@ Photo get_photo(Td *td, tl_object_ptr<telegram_api::photo> &&photo, DialogId own
|
|||||||
}
|
}
|
||||||
res.photos.push_back(std::move(size));
|
res.photos.push_back(std::move(size));
|
||||||
} else {
|
} else {
|
||||||
res.minithumbnail = std::move(photo_size.get<1>());
|
if (G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
|
res.minithumbnail = "";
|
||||||
|
} else {
|
||||||
|
res.minithumbnail = std::move(photo_size.get<1>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,14 +23,14 @@ void store(const DialogPhoto &dialog_photo, StorerT &storer) {
|
|||||||
BEGIN_STORE_FLAGS();
|
BEGIN_STORE_FLAGS();
|
||||||
STORE_FLAG(has_file_ids);
|
STORE_FLAG(has_file_ids);
|
||||||
STORE_FLAG(dialog_photo.has_animation);
|
STORE_FLAG(dialog_photo.has_animation);
|
||||||
STORE_FLAG(has_minithumbnail);
|
STORE_FLAG(!G()->get_option_boolean("disable_minithumbnails") && has_minithumbnail);
|
||||||
STORE_FLAG(dialog_photo.is_personal);
|
STORE_FLAG(dialog_photo.is_personal);
|
||||||
END_STORE_FLAGS();
|
END_STORE_FLAGS();
|
||||||
if (has_file_ids) {
|
if (has_file_ids) {
|
||||||
store(dialog_photo.small_file_id, storer);
|
store(dialog_photo.small_file_id, storer);
|
||||||
store(dialog_photo.big_file_id, storer);
|
store(dialog_photo.big_file_id, storer);
|
||||||
}
|
}
|
||||||
if (has_minithumbnail) {
|
if (!G()->get_option_boolean("disable_minithumbnails") && has_minithumbnail) {
|
||||||
store(dialog_photo.minithumbnail, storer);
|
store(dialog_photo.minithumbnail, storer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,7 +52,11 @@ void parse(DialogPhoto &dialog_photo, ParserT &parser) {
|
|||||||
parse(dialog_photo.big_file_id, parser);
|
parse(dialog_photo.big_file_id, parser);
|
||||||
}
|
}
|
||||||
if (has_minithumbnail) {
|
if (has_minithumbnail) {
|
||||||
parse(dialog_photo.minithumbnail, parser);
|
std::basic_string<char> minithumbnail;
|
||||||
|
parse(minithumbnail, parser);
|
||||||
|
if (!G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
|
dialog_photo.minithumbnail = minithumbnail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +79,7 @@ void store(const Photo &photo, StorerT &storer) {
|
|||||||
bool has_sticker_photo_size = photo.sticker_photo_size != nullptr;
|
bool has_sticker_photo_size = photo.sticker_photo_size != nullptr;
|
||||||
BEGIN_STORE_FLAGS();
|
BEGIN_STORE_FLAGS();
|
||||||
STORE_FLAG(photo.has_stickers);
|
STORE_FLAG(photo.has_stickers);
|
||||||
STORE_FLAG(has_minithumbnail);
|
STORE_FLAG(!G()->get_option_boolean("disable_minithumbnails") && has_minithumbnail);
|
||||||
STORE_FLAG(has_animations);
|
STORE_FLAG(has_animations);
|
||||||
STORE_FLAG(has_sticker_photo_size);
|
STORE_FLAG(has_sticker_photo_size);
|
||||||
END_STORE_FLAGS();
|
END_STORE_FLAGS();
|
||||||
@ -85,7 +89,7 @@ void store(const Photo &photo, StorerT &storer) {
|
|||||||
if (photo.has_stickers) {
|
if (photo.has_stickers) {
|
||||||
store(photo.sticker_file_ids, storer);
|
store(photo.sticker_file_ids, storer);
|
||||||
}
|
}
|
||||||
if (has_minithumbnail) {
|
if (!G()->get_option_boolean("disable_minithumbnails") && has_minithumbnail) {
|
||||||
store(photo.minithumbnail, storer);
|
store(photo.minithumbnail, storer);
|
||||||
}
|
}
|
||||||
if (has_animations) {
|
if (has_animations) {
|
||||||
@ -116,7 +120,11 @@ void parse(Photo &photo, ParserT &parser) {
|
|||||||
parse(photo.sticker_file_ids, parser);
|
parse(photo.sticker_file_ids, parser);
|
||||||
}
|
}
|
||||||
if (has_minithumbnail) {
|
if (has_minithumbnail) {
|
||||||
parse(photo.minithumbnail, parser);
|
std::basic_string<char> minithumbnail;
|
||||||
|
parse(minithumbnail, parser);
|
||||||
|
if (!G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
|
photo.minithumbnail = minithumbnail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (has_animations) {
|
if (has_animations) {
|
||||||
parse(photo.animations, parser);
|
parse(photo.animations, parser);
|
||||||
|
@ -46,6 +46,9 @@ bool need_update_dialog_photo_minithumbnail(const string &from, const string &to
|
|||||||
}
|
}
|
||||||
|
|
||||||
td_api::object_ptr<td_api::minithumbnail> get_minithumbnail_object(const string &packed) {
|
td_api::object_ptr<td_api::minithumbnail> get_minithumbnail_object(const string &packed) {
|
||||||
|
if (G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
if (packed.size() < 3) {
|
if (packed.size() < 3) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -195,11 +198,23 @@ Variant<PhotoSize, string> get_photo_size(FileManager *file_manager, PhotoSizeSo
|
|||||||
case telegram_api::photoStrippedSize::ID: {
|
case telegram_api::photoStrippedSize::ID: {
|
||||||
auto size = move_tl_object_as<telegram_api::photoStrippedSize>(size_ptr);
|
auto size = move_tl_object_as<telegram_api::photoStrippedSize>(size_ptr);
|
||||||
if (format != PhotoFormat::Jpeg) {
|
if (format != PhotoFormat::Jpeg) {
|
||||||
LOG(ERROR) << "Receive unexpected JPEG minithumbnail in photo " << id << " from " << source << " of format "
|
if (G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
<< format;
|
LOG(DEBUG) << "Receive unexpected JPEG minithumbnail";
|
||||||
return std::move(res);
|
} else {
|
||||||
|
LOG(ERROR) << "Receive unexpected JPEG minithumbnail in photo " << id << " from " << source << " of format "
|
||||||
|
<< format;
|
||||||
|
}
|
||||||
|
if (G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
|
return std::string("");
|
||||||
|
} else {
|
||||||
|
return std::move(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
|
return std::string("");
|
||||||
|
} else {
|
||||||
|
return size->bytes_.as_slice().str();
|
||||||
}
|
}
|
||||||
return size->bytes_.as_slice().str();
|
|
||||||
}
|
}
|
||||||
case telegram_api::photoSizeProgressive::ID: {
|
case telegram_api::photoSizeProgressive::ID: {
|
||||||
auto size = move_tl_object_as<telegram_api::photoSizeProgressive>(size_ptr);
|
auto size = move_tl_object_as<telegram_api::photoSizeProgressive>(size_ptr);
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#include "td/telegram/DialogManager.h"
|
#include "td/telegram/DialogManager.h"
|
||||||
#include "td/telegram/Global.h"
|
#include "td/telegram/Global.h"
|
||||||
#include "td/telegram/logevent/LogEvent.h"
|
#include "td/telegram/logevent/LogEvent.h"
|
||||||
|
#include "td/telegram/logevent/LogEventHelper.h"
|
||||||
|
#include "td/telegram/MemoryManager.h"
|
||||||
#include "td/telegram/MessageId.h"
|
#include "td/telegram/MessageId.h"
|
||||||
#include "td/telegram/MessageSender.h"
|
#include "td/telegram/MessageSender.h"
|
||||||
#include "td/telegram/MessagesManager.h"
|
#include "td/telegram/MessagesManager.h"
|
||||||
@ -1967,4 +1969,16 @@ void PollManager::on_binlog_events(vector<BinlogEvent> &&events) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PollManager::memory_stats(vector<string> &output) {
|
||||||
|
output.push_back("\"polls_\":"); output.push_back(std::to_string(polls_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"pending_answers_\":"); output.push_back(std::to_string(pending_answers_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"poll_voters_\":"); output.push_back(std::to_string(poll_voters_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"loaded_from_database_polls_\":"); output.push_back(std::to_string(loaded_from_database_polls_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"being_closed_polls_\":"); output.push_back(std::to_string(being_closed_polls_.size()));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -47,6 +47,8 @@ class PollManager final : public Actor {
|
|||||||
PollManager &operator=(PollManager &&) = delete;
|
PollManager &operator=(PollManager &&) = delete;
|
||||||
~PollManager() final;
|
~PollManager() final;
|
||||||
|
|
||||||
|
void memory_stats(vector<string> &output);
|
||||||
|
|
||||||
static bool is_local_poll_id(PollId poll_id);
|
static bool is_local_poll_id(PollId poll_id);
|
||||||
|
|
||||||
PollId create_poll(string &&question, vector<string> &&options, bool is_anonymous, bool allow_multiple_answers,
|
PollId create_poll(string &&question, vector<string> &&options, bool is_anonymous, bool allow_multiple_answers,
|
||||||
|
@ -10149,4 +10149,30 @@ void StickersManager::get_current_state(vector<td_api::object_ptr<td_api::Update
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StickersManager::memory_stats(vector<string> &output) {
|
||||||
|
output.push_back("\"found_sticker_sets_\":"); output.push_back(std::to_string(found_sticker_sets_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"archived_sticker_set_ids_\":"); output.push_back(std::to_string(archived_sticker_set_ids_->size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"attached_sticker_sets_\":"); output.push_back(std::to_string(attached_sticker_sets_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"favorite_sticker_file_ids_\":"); output.push_back(std::to_string(favorite_sticker_file_ids_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"favorite_sticker_ids_\":"); output.push_back(std::to_string(favorite_sticker_ids_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"installed_sticker_set_ids_\":"); output.push_back(std::to_string(installed_sticker_set_ids_->size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"recent_sticker_file_ids_\":"); output.push_back(std::to_string(recent_sticker_file_ids_->size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"recent_sticker_ids_\":"); output.push_back(std::to_string(recent_sticker_ids_->size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"short_name_to_sticker_set_id_\":"); output.push_back(std::to_string(short_name_to_sticker_set_id_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"special_sticker_sets_\":"); output.push_back(std::to_string(special_sticker_sets_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"sticker_sets_\":"); output.push_back(std::to_string(sticker_sets_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"stickers_\":"); output.push_back(std::to_string(stickers_.calc_size()));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -57,6 +57,8 @@ class StickersManager final : public Actor {
|
|||||||
public:
|
public:
|
||||||
static constexpr int64 GREAT_MINDS_SET_ID = 1842540969984001;
|
static constexpr int64 GREAT_MINDS_SET_ID = 1842540969984001;
|
||||||
|
|
||||||
|
void memory_stats(vector<string> &output);
|
||||||
|
|
||||||
static vector<StickerSetId> convert_sticker_set_ids(const vector<int64> &sticker_set_ids);
|
static vector<StickerSetId> convert_sticker_set_ids(const vector<int64> &sticker_set_ids);
|
||||||
static vector<int64> convert_sticker_set_ids(const vector<StickerSetId> &sticker_set_ids);
|
static vector<int64> convert_sticker_set_ids(const vector<StickerSetId> &sticker_set_ids);
|
||||||
|
|
||||||
|
@ -143,6 +143,7 @@
|
|||||||
#include "td/telegram/StickersManager.h"
|
#include "td/telegram/StickersManager.h"
|
||||||
#include "td/telegram/StickerType.h"
|
#include "td/telegram/StickerType.h"
|
||||||
#include "td/telegram/StorageManager.h"
|
#include "td/telegram/StorageManager.h"
|
||||||
|
#include "td/telegram/MemoryManager.h"
|
||||||
#include "td/telegram/StoryId.h"
|
#include "td/telegram/StoryId.h"
|
||||||
#include "td/telegram/StoryListId.h"
|
#include "td/telegram/StoryListId.h"
|
||||||
#include "td/telegram/StoryManager.h"
|
#include "td/telegram/StoryManager.h"
|
||||||
@ -2850,6 +2851,7 @@ bool Td::is_preauthentication_request(int32 id) {
|
|||||||
case td_api::getStorageStatistics::ID:
|
case td_api::getStorageStatistics::ID:
|
||||||
case td_api::getStorageStatisticsFast::ID:
|
case td_api::getStorageStatisticsFast::ID:
|
||||||
case td_api::getDatabaseStatistics::ID:
|
case td_api::getDatabaseStatistics::ID:
|
||||||
|
case td_api::getMemoryStatistics::ID:
|
||||||
case td_api::setNetworkType::ID:
|
case td_api::setNetworkType::ID:
|
||||||
case td_api::getNetworkStatistics::ID:
|
case td_api::getNetworkStatistics::ID:
|
||||||
case td_api::addNetworkStatistics::ID:
|
case td_api::addNetworkStatistics::ID:
|
||||||
@ -2902,12 +2904,15 @@ vector<td_api::object_ptr<td_api::Update>> Td::get_fake_current_state() const {
|
|||||||
return updates;
|
return updates;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbKey Td::as_db_key(string key) {
|
DbKey Td::as_db_key(string key, bool custom_db) {
|
||||||
// Database will still be effectively not encrypted, but
|
// Database will still be effectively not encrypted, but
|
||||||
// 1. SQLite database will be protected from corruption, because that's how sqlcipher works
|
// 1. SQLite database will be protected from corruption, because that's how sqlcipher works
|
||||||
// 2. security through obscurity
|
// 2. security through obscurity
|
||||||
// 3. no need for reencryption of SQLite database
|
// 3. no need for reencryption of SQLite database
|
||||||
if (key.empty()) {
|
if (key.empty()) {
|
||||||
|
if (custom_db) {
|
||||||
|
return DbKey::empty();
|
||||||
|
}
|
||||||
return DbKey::raw_key("cucumber");
|
return DbKey::raw_key("cucumber");
|
||||||
}
|
}
|
||||||
return DbKey::raw_key(std::move(key));
|
return DbKey::raw_key(std::move(key));
|
||||||
@ -3262,9 +3267,20 @@ void Td::dec_actor_refcnt() {
|
|||||||
close_flag_ = 4;
|
close_flag_ = 4;
|
||||||
} else if (close_flag_ == 4) {
|
} else if (close_flag_ == 4) {
|
||||||
on_closed();
|
on_closed();
|
||||||
|
#ifdef __linux__
|
||||||
|
#if defined(__GLIBC__) && !defined(__UCLIBC__) && !defined(__MUSL__)
|
||||||
|
malloc_trim(0);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
#ifdef __linux__
|
||||||
|
#if defined(__GLIBC__) && !defined(__UCLIBC__) && !defined(__MUSL__)
|
||||||
|
malloc_trim(0);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3953,6 +3969,9 @@ void Td::init_managers() {
|
|||||||
stickers_manager_ = make_unique<StickersManager>(this, create_reference());
|
stickers_manager_ = make_unique<StickersManager>(this, create_reference());
|
||||||
stickers_manager_actor_ = register_actor("StickersManager", stickers_manager_.get());
|
stickers_manager_actor_ = register_actor("StickersManager", stickers_manager_.get());
|
||||||
G()->set_stickers_manager(stickers_manager_actor_.get());
|
G()->set_stickers_manager(stickers_manager_actor_.get());
|
||||||
|
memory_manager_ = make_unique<MemoryManager>(this, create_reference());
|
||||||
|
memory_manager_actor_ = register_actor("MemoryManager", memory_manager_.get());
|
||||||
|
G()->set_memory_manager(memory_manager_actor_.get());
|
||||||
story_manager_ = make_unique<StoryManager>(this, create_reference());
|
story_manager_ = make_unique<StoryManager>(this, create_reference());
|
||||||
story_manager_actor_ = register_actor("StoryManager", story_manager_.get());
|
story_manager_actor_ = register_actor("StoryManager", story_manager_.get());
|
||||||
G()->set_story_manager(story_manager_actor_.get());
|
G()->set_story_manager(story_manager_actor_.get());
|
||||||
@ -4149,8 +4168,9 @@ Result<std::pair<Td::Parameters, TdDb::Parameters>> Td::get_parameters(
|
|||||||
result.first.api_hash_ = std::move(parameters->api_hash_);
|
result.first.api_hash_ = std::move(parameters->api_hash_);
|
||||||
result.first.use_secret_chats_ = parameters->use_secret_chats_;
|
result.first.use_secret_chats_ = parameters->use_secret_chats_;
|
||||||
|
|
||||||
result.second.encryption_key_ = as_db_key(std::move(parameters->database_encryption_key_));
|
result.second.encryption_key_ = as_db_key(std::move(parameters->database_encryption_key_), Global::get_use_custom_database(parameters->database_directory_));
|
||||||
result.second.database_directory_ = std::move(parameters->database_directory_);
|
result.second.database_directory_ = Global::get_database_directory_path(parameters->database_directory_);
|
||||||
|
result.second.use_custom_database_format_ = Global::get_use_custom_database(parameters->database_directory_);
|
||||||
result.second.files_directory_ = std::move(parameters->files_directory_);
|
result.second.files_directory_ = std::move(parameters->files_directory_);
|
||||||
result.second.is_test_dc_ = parameters->use_test_dc_;
|
result.second.is_test_dc_ = parameters->use_test_dc_;
|
||||||
result.second.use_file_database_ = parameters->use_file_database_;
|
result.second.use_file_database_ = parameters->use_file_database_;
|
||||||
@ -4197,7 +4217,7 @@ void Td::on_request(uint64 id, const td_api::setTdlibParameters &request) {
|
|||||||
|
|
||||||
void Td::on_request(uint64 id, td_api::setDatabaseEncryptionKey &request) {
|
void Td::on_request(uint64 id, td_api::setDatabaseEncryptionKey &request) {
|
||||||
CREATE_OK_REQUEST_PROMISE();
|
CREATE_OK_REQUEST_PROMISE();
|
||||||
G()->td_db()->get_binlog()->change_key(as_db_key(std::move(request.new_encryption_key_)), std::move(promise));
|
G()->td_db()->get_binlog()->change_key(as_db_key(std::move(request.new_encryption_key_), G()->use_custom_database_format()), std::move(promise));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Td::on_request(uint64 id, const td_api::getAuthorizationState &request) {
|
void Td::on_request(uint64 id, const td_api::getAuthorizationState &request) {
|
||||||
@ -4328,6 +4348,7 @@ void Td::on_request(uint64 id, const td_api::getCurrentState &request) {
|
|||||||
|
|
||||||
dialog_filter_manager_->get_current_state(updates);
|
dialog_filter_manager_->get_current_state(updates);
|
||||||
|
|
||||||
|
memory_manager_->get_current_state(updates);
|
||||||
messages_manager_->get_current_state(updates);
|
messages_manager_->get_current_state(updates);
|
||||||
|
|
||||||
dialog_participant_manager_->get_current_state(updates);
|
dialog_participant_manager_->get_current_state(updates);
|
||||||
@ -4884,6 +4905,18 @@ void Td::on_request(uint64 id, td_api::getDatabaseStatistics &request) {
|
|||||||
});
|
});
|
||||||
send_closure(storage_manager_, &StorageManager::get_database_stats, std::move(query_promise));
|
send_closure(storage_manager_, &StorageManager::get_database_stats, std::move(query_promise));
|
||||||
}
|
}
|
||||||
|
void Td::on_request(uint64 id, td_api::getMemoryStatistics &request) {
|
||||||
|
CREATE_REQUEST_PROMISE();
|
||||||
|
auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result<MemoryStats> result) mutable {
|
||||||
|
if (result.is_error()) {
|
||||||
|
promise.set_error(result.move_as_error());
|
||||||
|
} else {
|
||||||
|
promise.set_value(result.ok().get_memory_statistics_object());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
memory_manager_->get_memory_stats(request.full_, std::move(query_promise));
|
||||||
|
}
|
||||||
|
|
||||||
void Td::on_request(uint64 id, td_api::optimizeStorage &request) {
|
void Td::on_request(uint64 id, td_api::optimizeStorage &request) {
|
||||||
std::vector<FileType> file_types;
|
std::vector<FileType> file_types;
|
||||||
|
@ -31,6 +31,12 @@
|
|||||||
#include "td/utils/Slice.h"
|
#include "td/utils/Slice.h"
|
||||||
#include "td/utils/Status.h"
|
#include "td/utils/Status.h"
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <malloc.h>
|
||||||
|
#endif
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <malloc.h>
|
||||||
|
#endif
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -91,6 +97,7 @@ class StateManager;
|
|||||||
class StatisticsManager;
|
class StatisticsManager;
|
||||||
class StickersManager;
|
class StickersManager;
|
||||||
class StorageManager;
|
class StorageManager;
|
||||||
|
class MemoryManager;
|
||||||
class StoryManager;
|
class StoryManager;
|
||||||
class ThemeManager;
|
class ThemeManager;
|
||||||
class TimeZoneManager;
|
class TimeZoneManager;
|
||||||
@ -257,6 +264,8 @@ class Td final : public Actor {
|
|||||||
ActorOwn<VideoNotesManager> video_notes_manager_actor_;
|
ActorOwn<VideoNotesManager> video_notes_manager_actor_;
|
||||||
unique_ptr<VoiceNotesManager> voice_notes_manager_;
|
unique_ptr<VoiceNotesManager> voice_notes_manager_;
|
||||||
ActorOwn<VoiceNotesManager> voice_notes_manager_actor_;
|
ActorOwn<VoiceNotesManager> voice_notes_manager_actor_;
|
||||||
|
unique_ptr<MemoryManager> memory_manager_;
|
||||||
|
ActorOwn<MemoryManager> memory_manager_actor_;
|
||||||
unique_ptr<WebPagesManager> web_pages_manager_;
|
unique_ptr<WebPagesManager> web_pages_manager_;
|
||||||
ActorOwn<WebPagesManager> web_pages_manager_actor_;
|
ActorOwn<WebPagesManager> web_pages_manager_actor_;
|
||||||
|
|
||||||
@ -654,6 +663,8 @@ class Td final : public Actor {
|
|||||||
|
|
||||||
void on_request(uint64 id, td_api::getDatabaseStatistics &request);
|
void on_request(uint64 id, td_api::getDatabaseStatistics &request);
|
||||||
|
|
||||||
|
void on_request(uint64 id, td_api::getMemoryStatistics &request);
|
||||||
|
|
||||||
void on_request(uint64 id, td_api::optimizeStorage &request);
|
void on_request(uint64 id, td_api::optimizeStorage &request);
|
||||||
|
|
||||||
void on_request(uint64 id, td_api::getNetworkStatistics &request);
|
void on_request(uint64 id, td_api::getNetworkStatistics &request);
|
||||||
@ -1906,7 +1917,7 @@ class Td final : public Actor {
|
|||||||
static td_api::object_ptr<td_api::Object> do_static_request(const td_api::addLogMessage &request);
|
static td_api::object_ptr<td_api::Object> do_static_request(const td_api::addLogMessage &request);
|
||||||
static td_api::object_ptr<td_api::Object> do_static_request(td_api::testReturnError &request);
|
static td_api::object_ptr<td_api::Object> do_static_request(td_api::testReturnError &request);
|
||||||
|
|
||||||
static DbKey as_db_key(string key);
|
static DbKey as_db_key(string key, bool custom_db);
|
||||||
|
|
||||||
struct Parameters {
|
struct Parameters {
|
||||||
int32 api_id_ = 0;
|
int32 api_id_ = 0;
|
||||||
|
@ -374,8 +374,16 @@ Status TdDb::init_sqlite(const Parameters ¶meters, const DbKey &key, const D
|
|||||||
sql_connection_ = std::make_shared<SqliteConnectionSafe>(sql_database_path, key, db_instance.get_cipher_version());
|
sql_connection_ = std::make_shared<SqliteConnectionSafe>(sql_database_path, key, db_instance.get_cipher_version());
|
||||||
sql_connection_->set(std::move(db_instance));
|
sql_connection_->set(std::move(db_instance));
|
||||||
auto &db = sql_connection_->get();
|
auto &db = sql_connection_->get();
|
||||||
TRY_STATUS(db.exec("PRAGMA journal_mode=WAL"));
|
if (parameters.use_custom_database_format_) {
|
||||||
TRY_STATUS(db.exec("PRAGMA secure_delete=1"));
|
TRY_STATUS(db.exec("PRAGMA journal_mode=OFF"));
|
||||||
|
TRY_STATUS(db.exec("PRAGMA synchronous=OFF"))
|
||||||
|
TRY_STATUS(db.exec("PRAGMA temp_store=MEMORY"));
|
||||||
|
TRY_STATUS(db.exec("PRAGMA secure_delete=0"));
|
||||||
|
TRY_STATUS(db.exec("PRAGMA mmap_size=30000000000"));
|
||||||
|
} else {
|
||||||
|
TRY_STATUS(db.exec("PRAGMA journal_mode=WAL"));
|
||||||
|
TRY_STATUS(db.exec("PRAGMA secure_delete=1"));
|
||||||
|
}
|
||||||
|
|
||||||
// Init databases
|
// Init databases
|
||||||
// Do initialization once and before everything else to avoid "database is locked" error.
|
// Do initialization once and before everything else to avoid "database is locked" error.
|
||||||
|
@ -60,6 +60,7 @@ class TdDb {
|
|||||||
bool use_file_database_ = false;
|
bool use_file_database_ = false;
|
||||||
bool use_chat_info_database_ = false;
|
bool use_chat_info_database_ = false;
|
||||||
bool use_message_database_ = false;
|
bool use_message_database_ = false;
|
||||||
|
bool use_custom_database_format_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OpenedDatabase {
|
struct OpenedDatabase {
|
||||||
@ -117,6 +118,10 @@ class TdDb {
|
|||||||
return was_dialog_db_created_;
|
return was_dialog_db_created_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool use_custom_database_format() const {
|
||||||
|
return parameters_.use_custom_database_format_;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<FileDbInterface> get_file_db_shared();
|
std::shared_ptr<FileDbInterface> get_file_db_shared();
|
||||||
std::shared_ptr<SqliteConnectionSafe> &get_sqlite_connection_safe();
|
std::shared_ptr<SqliteConnectionSafe> &get_sqlite_connection_safe();
|
||||||
#define get_binlog() get_binlog_impl(__FILE__, __LINE__)
|
#define get_binlog() get_binlog_impl(__FILE__, __LINE__)
|
||||||
|
@ -82,8 +82,10 @@ FileId VideoNotesManager::on_get_video_note(unique_ptr<VideoNote> new_video_note
|
|||||||
v->dimensions = new_video_note->dimensions;
|
v->dimensions = new_video_note->dimensions;
|
||||||
v->waveform = std::move(new_video_note->waveform);
|
v->waveform = std::move(new_video_note->waveform);
|
||||||
}
|
}
|
||||||
if (v->minithumbnail != new_video_note->minithumbnail) {
|
if (!G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
v->minithumbnail = std::move(new_video_note->minithumbnail);
|
if (v->minithumbnail != new_video_note->minithumbnail) {
|
||||||
|
v->minithumbnail = std::move(new_video_note->minithumbnail);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (v->thumbnail != new_video_note->thumbnail) {
|
if (v->thumbnail != new_video_note->thumbnail) {
|
||||||
if (!v->thumbnail.file_id.is_valid()) {
|
if (!v->thumbnail.file_id.is_valid()) {
|
||||||
@ -169,7 +171,7 @@ void VideoNotesManager::create_video_note(FileId file_id, string minithumbnail,
|
|||||||
LOG(INFO) << "Receive wrong video note dimensions " << dimensions;
|
LOG(INFO) << "Receive wrong video note dimensions " << dimensions;
|
||||||
}
|
}
|
||||||
v->waveform = std::move(waveform);
|
v->waveform = std::move(waveform);
|
||||||
if (!td_->auth_manager_->is_bot()) {
|
if (!td_->auth_manager_->is_bot() && !G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
v->minithumbnail = std::move(minithumbnail);
|
v->minithumbnail = std::move(minithumbnail);
|
||||||
}
|
}
|
||||||
v->thumbnail = std::move(thumbnail);
|
v->thumbnail = std::move(thumbnail);
|
||||||
@ -262,4 +264,8 @@ tl_object_ptr<telegram_api::InputMedia> VideoNotesManager::get_input_media(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VideoNotesManager::memory_stats(vector<string> &output) {
|
||||||
|
output.push_back("\"video_notes_\":"); output.push_back(std::to_string(video_notes_.calc_size()));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -33,6 +33,8 @@ class VideoNotesManager final : public Actor {
|
|||||||
VideoNotesManager &operator=(VideoNotesManager &&) = delete;
|
VideoNotesManager &operator=(VideoNotesManager &&) = delete;
|
||||||
~VideoNotesManager() final;
|
~VideoNotesManager() final;
|
||||||
|
|
||||||
|
void memory_stats(vector<string> &output);
|
||||||
|
|
||||||
int32 get_video_note_duration(FileId file_id) const;
|
int32 get_video_note_duration(FileId file_id) const;
|
||||||
|
|
||||||
TranscriptionInfo *get_video_note_transcription_info(FileId file_id, bool allow_creation);
|
TranscriptionInfo *get_video_note_transcription_info(FileId file_id, bool allow_creation);
|
||||||
|
@ -96,8 +96,10 @@ FileId VideosManager::on_get_video(unique_ptr<Video> new_video, bool replace) {
|
|||||||
LOG(DEBUG) << "Video " << file_id << " file name has changed";
|
LOG(DEBUG) << "Video " << file_id << " file name has changed";
|
||||||
v->file_name = std::move(new_video->file_name);
|
v->file_name = std::move(new_video->file_name);
|
||||||
}
|
}
|
||||||
if (v->minithumbnail != new_video->minithumbnail) {
|
if (!G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
v->minithumbnail = std::move(new_video->minithumbnail);
|
if (v->minithumbnail != new_video->minithumbnail) {
|
||||||
|
v->minithumbnail = std::move(new_video->minithumbnail);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (v->thumbnail != new_video->thumbnail) {
|
if (v->thumbnail != new_video->thumbnail) {
|
||||||
if (!v->thumbnail.file_id.is_valid()) {
|
if (!v->thumbnail.file_id.is_valid()) {
|
||||||
@ -198,7 +200,7 @@ void VideosManager::create_video(FileId file_id, string minithumbnail, PhotoSize
|
|||||||
v->duration = max(duration, 0);
|
v->duration = max(duration, 0);
|
||||||
v->precise_duration = duration == 0 ? 0.0 : clamp(precise_duration, duration - 1.0, duration + 0.0);
|
v->precise_duration = duration == 0 ? 0.0 : clamp(precise_duration, duration - 1.0, duration + 0.0);
|
||||||
v->dimensions = dimensions;
|
v->dimensions = dimensions;
|
||||||
if (!td_->auth_manager_->is_bot()) {
|
if (!td_->auth_manager_->is_bot() && G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
v->minithumbnail = std::move(minithumbnail);
|
v->minithumbnail = std::move(minithumbnail);
|
||||||
}
|
}
|
||||||
v->thumbnail = std::move(thumbnail);
|
v->thumbnail = std::move(thumbnail);
|
||||||
@ -332,4 +334,8 @@ string VideosManager::get_video_search_text(FileId file_id) const {
|
|||||||
return video->file_name;
|
return video->file_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VideosManager::memory_stats(vector<string> &output) {
|
||||||
|
output.push_back("\"videos_\":"); output.push_back(std::to_string(videos_.calc_size()));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -30,6 +30,8 @@ class VideosManager {
|
|||||||
VideosManager &operator=(VideosManager &&) = delete;
|
VideosManager &operator=(VideosManager &&) = delete;
|
||||||
~VideosManager();
|
~VideosManager();
|
||||||
|
|
||||||
|
void memory_stats(vector<string> &output);
|
||||||
|
|
||||||
int32 get_video_duration(FileId file_id) const;
|
int32 get_video_duration(FileId file_id) const;
|
||||||
|
|
||||||
td_api::object_ptr<td_api::video> get_video_object(FileId file_id) const;
|
td_api::object_ptr<td_api::video> get_video_object(FileId file_id) const;
|
||||||
|
@ -67,12 +67,29 @@ FileId VideosManager::parse_video(ParserT &parser) {
|
|||||||
PARSE_FLAG(has_precise_duration);
|
PARSE_FLAG(has_precise_duration);
|
||||||
PARSE_FLAG(video->is_animation);
|
PARSE_FLAG(video->is_animation);
|
||||||
END_PARSE_FLAGS();
|
END_PARSE_FLAGS();
|
||||||
parse(video->file_name, parser);
|
|
||||||
|
string tmp_filename;
|
||||||
|
parse(tmp_filename, parser);
|
||||||
|
|
||||||
parse(video->mime_type, parser);
|
parse(video->mime_type, parser);
|
||||||
|
|
||||||
|
if ( G()->get_option_boolean("disable_document_filenames") && (
|
||||||
|
video->mime_type.rfind("image/") == 0 ||
|
||||||
|
video->mime_type.rfind("video/") == 0 ||
|
||||||
|
video->mime_type.rfind("audio/") == 0)) {
|
||||||
|
video->file_name = "0";
|
||||||
|
} else {
|
||||||
|
video->file_name = tmp_filename;
|
||||||
|
}
|
||||||
|
|
||||||
parse(video->duration, parser);
|
parse(video->duration, parser);
|
||||||
parse(video->dimensions, parser);
|
parse(video->dimensions, parser);
|
||||||
if (parser.version() >= static_cast<int32>(Version::SupportMinithumbnails)) {
|
if (parser.version() >= static_cast<int32>(Version::SupportMinithumbnails)) {
|
||||||
parse(video->minithumbnail, parser);
|
string tmp_minithumbnail;
|
||||||
|
parse(tmp_minithumbnail, parser);
|
||||||
|
if (!G()->get_option_boolean("disable_minithumbnails")) {
|
||||||
|
video->minithumbnail = tmp_minithumbnail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
parse(video->thumbnail, parser);
|
parse(video->thumbnail, parser);
|
||||||
parse(video->file_id, parser);
|
parse(video->file_id, parser);
|
||||||
|
@ -1959,4 +1959,17 @@ vector<FileId> WebPagesManager::get_web_page_file_ids(const WebPage *web_page) c
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebPagesManager::memory_stats(vector<string> &output) {
|
||||||
|
output.push_back("\"web_pages_\":"); output.push_back(std::to_string(web_pages_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"loaded_from_database_web_pages_\":"); output.push_back(std::to_string(loaded_from_database_web_pages_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"web_page_messages_\":"); output.push_back(std::to_string(web_page_messages_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"url_to_web_page_id_\":"); output.push_back(std::to_string(url_to_web_page_id_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"url_to_file_source_id_\":"); output.push_back(std::to_string(url_to_file_source_id_.size()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -40,6 +40,8 @@ class WebPagesManager final : public Actor {
|
|||||||
public:
|
public:
|
||||||
WebPagesManager(Td *td, ActorShared<> parent);
|
WebPagesManager(Td *td, ActorShared<> parent);
|
||||||
|
|
||||||
|
void memory_stats(vector<string> &output);
|
||||||
|
|
||||||
WebPagesManager(const WebPagesManager &) = delete;
|
WebPagesManager(const WebPagesManager &) = delete;
|
||||||
WebPagesManager &operator=(const WebPagesManager &) = delete;
|
WebPagesManager &operator=(const WebPagesManager &) = delete;
|
||||||
WebPagesManager(WebPagesManager &&) = delete;
|
WebPagesManager(WebPagesManager &&) = delete;
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "td/telegram/files/FileLoaderUtils.h"
|
#include "td/telegram/files/FileLoaderUtils.h"
|
||||||
#include "td/telegram/files/FileLocation.h"
|
#include "td/telegram/files/FileLocation.h"
|
||||||
#include "td/telegram/files/FileLocation.hpp"
|
#include "td/telegram/files/FileLocation.hpp"
|
||||||
|
#include "td/telegram/MemoryManager.h"
|
||||||
#include "td/telegram/Global.h"
|
#include "td/telegram/Global.h"
|
||||||
#include "td/telegram/logevent/LogEvent.h"
|
#include "td/telegram/logevent/LogEvent.h"
|
||||||
#include "td/telegram/misc.h"
|
#include "td/telegram/misc.h"
|
||||||
@ -879,8 +880,8 @@ FileManager::FileManager(unique_ptr<Context> context) : context_(std::move(conte
|
|||||||
}
|
}
|
||||||
|
|
||||||
parent_ = context_->create_reference();
|
parent_ = context_->create_reference();
|
||||||
next_file_id();
|
next_file_id();
|
||||||
next_file_node_id();
|
next_file_node_id();
|
||||||
|
|
||||||
G()->td_db()->with_db_path([bad_paths = &bad_paths_](CSlice path) { bad_paths->insert(path.str()); });
|
G()->td_db()->with_db_path([bad_paths = &bad_paths_](CSlice path) { bad_paths->insert(path.str()); });
|
||||||
}
|
}
|
||||||
@ -4172,6 +4173,16 @@ void FileManager::hangup() {
|
|||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileManager::memory_stats(vector<string> &output) {
|
||||||
|
output.push_back("\"file_id_info_\":"); output.push_back(std::to_string(file_id_info_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"file_nodes_\":"); output.push_back(std::to_string(file_nodes_.size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"file_hash_to_file_id_\":"); output.push_back(std::to_string(file_hash_to_file_id_.calc_size()));
|
||||||
|
output.push_back(",");
|
||||||
|
output.push_back("\"empty_file_ids_\":"); output.push_back(std::to_string(empty_file_ids_.size()));
|
||||||
|
}
|
||||||
|
|
||||||
void FileManager::tear_down() {
|
void FileManager::tear_down() {
|
||||||
parent_.reset();
|
parent_.reset();
|
||||||
|
|
||||||
|
@ -378,6 +378,8 @@ class FileView {
|
|||||||
|
|
||||||
class FileManager final : public FileLoadManager::Callback {
|
class FileManager final : public FileLoadManager::Callback {
|
||||||
public:
|
public:
|
||||||
|
void memory_stats(vector<string> &output);
|
||||||
|
|
||||||
static constexpr int64 KEEP_DOWNLOAD_LIMIT = -1;
|
static constexpr int64 KEEP_DOWNLOAD_LIMIT = -1;
|
||||||
static constexpr int64 KEEP_DOWNLOAD_OFFSET = -1;
|
static constexpr int64 KEEP_DOWNLOAD_OFFSET = -1;
|
||||||
static constexpr int64 IGNORE_DOWNLOAD_LIMIT = -2;
|
static constexpr int64 IGNORE_DOWNLOAD_LIMIT = -2;
|
||||||
|
@ -395,7 +395,7 @@ if (WIN32)
|
|||||||
target_link_libraries(tdutils PRIVATE ws2_32 Mswsock Normaliz psapi)
|
target_link_libraries(tdutils PRIVATE ws2_32 Mswsock Normaliz psapi)
|
||||||
endif()
|
endif()
|
||||||
if (NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
|
if (NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
|
||||||
target_link_libraries(tdutils PRIVATE shell32)
|
target_link_libraries(tdutils PRIVATE shell32 crypt32)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -238,6 +238,18 @@ static DefaultLog default_log;
|
|||||||
LogInterface *const default_log_interface = &default_log;
|
LogInterface *const default_log_interface = &default_log;
|
||||||
LogInterface *log_interface = default_log_interface;
|
LogInterface *log_interface = default_log_interface;
|
||||||
|
|
||||||
|
static OnFatalErrorCallback on_fatal_error_callback = nullptr;
|
||||||
|
|
||||||
|
static bool use_death_handler = true;
|
||||||
|
|
||||||
|
void set_log_fatal_error_callback(OnFatalErrorCallback callback) {
|
||||||
|
on_fatal_error_callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_log_disable_death_handler(bool disabled) {
|
||||||
|
use_death_handler = !disabled;
|
||||||
|
}
|
||||||
|
|
||||||
void process_fatal_error(CSlice message) {
|
void process_fatal_error(CSlice message) {
|
||||||
if (0 <= max_callback_verbosity_level.load(std::memory_order_relaxed)) {
|
if (0 <= max_callback_verbosity_level.load(std::memory_order_relaxed)) {
|
||||||
auto callback = on_log_message_callback.load(std::memory_order_relaxed);
|
auto callback = on_log_message_callback.load(std::memory_order_relaxed);
|
||||||
|
@ -173,6 +173,10 @@ class LogInterface {
|
|||||||
extern LogInterface *const default_log_interface;
|
extern LogInterface *const default_log_interface;
|
||||||
extern LogInterface *log_interface;
|
extern LogInterface *log_interface;
|
||||||
|
|
||||||
|
using OnFatalErrorCallback = void (*)(CSlice message);
|
||||||
|
void set_log_fatal_error_callback(OnFatalErrorCallback callback);
|
||||||
|
void set_log_disable_death_handler(bool disabled);
|
||||||
|
|
||||||
[[noreturn]] void process_fatal_error(CSlice message);
|
[[noreturn]] void process_fatal_error(CSlice message);
|
||||||
|
|
||||||
using OnLogMessageCallback = void (*)(int verbosity_level, CSlice message);
|
using OnLogMessageCallback = void (*)(int verbosity_level, CSlice message);
|
||||||
|
Loading…
Reference in New Issue
Block a user