Merge remote-tracking branch 'upstream/master' into merge-upstream

This commit is contained in:
Giuseppe Marino 2022-02-01 18:28:35 +01:00
commit f2e7e45fc0
No known key found for this signature in database
GPG Key ID: 2BC70C5463357449
18 changed files with 620 additions and 407 deletions

View File

@ -3,17 +3,20 @@ Language: Cpp
# BasedOnStyle: Google
AccessModifierOffset: -1
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignArrayOfStructures: None
AlignConsecutiveMacros: None
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignEscapedNewlines: Left
AlignOperands: true
AlignOperands: Align
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: None # All
AllowShortIfStatementsOnASingleLine: Never # WithoutElse
AllowShortLambdasOnASingleLine: Inline # All
@ -24,10 +27,11 @@ AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
BitFieldColonSpacing: Both
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
@ -37,12 +41,15 @@ BraceWrapping:
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeConceptDeclarations: true
BreakBeforeInheritanceComma: true # false
BreakInheritanceList: BeforeComma # BeforeColon
BreakBeforeTernaryOperators: true
@ -60,21 +67,30 @@ Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: true
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- Q_FOREACH_THIS_LIST_MUST_BE_NON_EMPTY
IncludeBlocks: Preserve
#IndentCaseBlocks: false
IncludeCategories:
- Regex: '.*'
Priority: 0
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: true
IndentExternBlock: AfterExternBlock
IndentGotoLabels: true
IndentPPDirectives: None
IndentRequires: false
IndentWidth: 2
IndentWrappedFunctionNames: false
# InsertTrailingCommas: None
# JavaScriptQuotes: Leave
# JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
LambdaBodyIndentation: Signature
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
@ -91,15 +107,22 @@ PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyIndentedWhitespace: 0
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Right
PPIndentWidth: -1
ReferenceAlignment: Pointer
ReflowComments: false # true
SortIncludes: false # disabled, because we need case insensitive sort
ShortNamespaceLines: 0 # 1
SortIncludes: CaseInsensitive # CaseSensitive
# SortJavaStaticImport: Before
SortUsingDeclarations: false # true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
@ -109,10 +132,13 @@ SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInAngles: Never
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: 1 # -1
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto

View File

@ -6,7 +6,7 @@ if (POLICY CMP0065)
cmake_policy(SET CMP0065 NEW)
endif()
project(TelegramBotApi VERSION 5.5.1 LANGUAGES CXX)
project(TelegramBotApi VERSION 5.7 LANGUAGES CXX)
if (POLICY CMP0069)
option(TELEGRAM_BOT_API_ENABLE_LTO "Use \"ON\" to enable Link Time Optimization.")

View File

@ -72,7 +72,7 @@ The maximum number of messages to be deleted in a single batch is determined by
###### Returns `true`
##### Command `ping`
Send an MTProto ping message to the telegram servers.
Send an MTProto ping message to the telegram servers.
Useful to detect the delay of the bot api server.
###### Parameters
@ -149,7 +149,7 @@ The bot will now receive Updates for all received media, even if a destruction t
<a name="user-mode"></a>
### User Mode
You can allow user accounts to access the bot api with the command-line option `--allow-users` or set the env variable
You can allow user accounts to access the bot api with the command-line option `--allow-users` or set the env variable
`TELEGRAM_ALLOW_USERS` to `1` when using docker. User Mode is disabled by default, so only bots can access the api.
You can now log into the bot api with user accounts to create userbots running on your account.
@ -161,37 +161,37 @@ Note: Never send your 2fa password over a plain http connection. Make sure https
Parameters:
- `phone_number`: `string`. The phone number of your Telegram Account.
Returns your `user_token` as `string`. You can use this just like a normal bot token on the `/user` endpoint
2. Send the received code to `{api_url}/user{user_token}/authcode`
Parameters:
- `code`: `int`. The code send to you by Telegram In-App or by SMS
Will send `{"ok": true, "result": true}` on success.
Will send `{"ok": true, "result": true}` on success.
3. Optional: Send your 2fa password to `{api_url}/user{user_token}/2fapassword`
Parameters:
- `password`: `string`. Password for 2fa authentication
Will send `{"ok": true, "result": true}` on success.
4. Optional: Register the user by calling `{api_url}/user{user_token}/registerUser`.
Will send `{"ok": true, "result": true}` on success.
4. Optional: Register the user by calling `{api_url}/user{user_token}/registerUser`.
User registration is disabled by default. You can enable it with the `--allow-users-registration` command line
option or the env variable `TELEGRAM_ALLOW_USERS_REGISTRATION` set to `1` when using docker.
Parameters:
- `first_name`: `string`. First name for the new account.
- `last_name`: `string`, optional. Last name for the new account.
Will send `{"ok": true, "result": true}` on success.
You are now logged in and can use all methods like in the bot api, just replace the
`/bot{bot_token}/` in your urls with `/user{token}/`.
Will send `{"ok": true, "result": true}` on success.
You are now logged in and can use all methods like in the bot api, just replace the
`/bot{bot_token}/` in your urls with `/user{token}/`.
You only need to authenticate once, the account will stay logged in. You can use the `logOut` method to log out
or simply close the session in your account settings.
@ -226,7 +226,7 @@ It is possible to have multiple user-tokens to multiple client instances on the
The simplest way to use it is with this docker command:
```bash
docker run -p 8081:8081 --env TELEGRAM_API_ID=API_ID --env TELEGRAM_API_HASH=API_HASH tdlight/tdlightbotapi
docker run -p 8081:8081 --env TELEGRAM_API_ID=API_ID --env TELEGRAM_API_HASH=API_HASH tdlight/tdlightbotapi
```
The simplest way to build `Telegram Bot API server` is to use our [Telegram Bot API server build instructions generator](https://tdlight-team.github.io/tdlight-telegram-bot-api/build.html).

View File

@ -3,17 +3,184 @@
<head>
<title>Telegram Bot API server build instructions</title>
<style>
.hide { display: none; }
div.main { max-width:1200px; margin: auto; font-size: x-large; }
select.large { font-size: large; }
</style>
<style>
:root {
--background: #fafafa;
--color: black;
--color-primary: #0088ff;
--color-code-block: #ebf9ff;
--color-select-border: rgb(211, 211, 211);
--color-checkbox-background: rgb(211, 211, 211);
--color-checkbox-tick: #ffffff;
--color-copy-success-background: #c1ffc6;
--color-copy-success-border: rgb(0, 255, 0);
--color-copy-fail-background: #ffcbcb;
--color-copy-fail-border: rgb(255, 0, 0);
color: var(--color);
background: var(--background);
}
@media (prefers-color-scheme: dark) {
:root {
--background: #0e0e0e;
--color: rgb(190, 190, 190);
--color-primary: #0088ff;
--color-code-block: #101315;
--color-select-border: rgb(54, 54, 54);
--color-checkbox-background: rgb(51, 51, 51);
--color-checkbox-tick: #ffffff;
--color-copy-success-background: #001f00;
--color-copy-success-border: rgb(0, 255, 0);
--color-copy-fail-background: #1f0000;
--color-copy-fail-border: rgb(255, 0, 0);
}
}
body {
font-family: 'Segoe UI', Arial, Helvetica, sans-serif;
}
.hide {
display: none;
}
div.main {
max-width: 1250px;
padding: 25px;
margin: auto;
font-size: 16px;
}
p {
margin: 0;
}
.main > div {
margin-bottom: 20px;
}
#buildCommands {
font-family: Consolas, monospace;
margin-left: 40px;
background: var(--color-code-block);
padding: 5px;
margin-bottom: 0;
display: block;
}
#buildCommands ul {
list-style: '$ ';
}
a {
color: var(--color-primary);
text-decoration-color: transparent;
transition: text-decoration-color 200ms;
}
a:hover {
text-decoration: underline;
}
select, button {
border: 1px solid var(--color-select-border);
background-color: var(--background);
color: var(--color);
padding: 5px;
margin-top: 5px;
transition: border 200ms, padding 200ms;
border-radius: 999em;
font-size: 16px;
cursor: pointer;
}
select:focus, button:focus {
outline: none;
border-color: var(--color-primary);
border-width: 2px;
padding: 4px;
}
label * {
vertical-align: middle;
}
input[type=checkbox] {
margin-right: 5px;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
background-color: var(--color-checkbox-background);
height: 20px;
width: 20px;
border-radius: 3px;
position: relative;
transition: background-color 200ms;
}
input[type=checkbox]::after {
content: "";
transition: border-color 200ms;
position: absolute;
left: 6px;
top: 2px;
width: 5px;
height: 10px;
border: solid transparent;
border-width: 0 3px 3px 0;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
input[type=checkbox]:checked {
background-color: var(--color-primary);
}
input[type=checkbox]:checked::after {
border-color: var(--color-checkbox-tick);
}
input[type=radio] {
margin-right: 5px;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
background-color: var(--color-checkbox-background);
height: 20px;
width: 20px;
border-radius: 100%;
position: relative;
transition: background-color 200ms;
}
input[type=radio]::after {
content: "";
transition: border-color 200ms;
position: absolute;
left: 10px;
top: 10px;
width: 0;
height: 0;
border-radius: 100%;
background-color: transparent;
transition: width 200ms, height 200ms, left 200ms, top 200ms, background-color 100ms;
}
input[type=radio]:checked::after {
background-color: var(--color-primary);
left: 2px;
top: 2px;
width: 16px;
height: 16px;
}
#copyBuildCommandsButton {
margin-left: 40px;
}
#copyBuildCommandsButton.success {
background: var(--color-copy-success-background);
border-color: var(--color-copy-success-border);
}
#copyBuildCommandsButton.fail {
background: var(--color-copy-fail-background);
border-color: var(--color-copy-fail-border);
}
</style>
</head>
<body onload="onLoad(true)" onpopstate="onLoad(false)">
<div class="main">
<div id="osSelectDiv" class="large" style="text-align:center;">
<div id="osSelectDiv" class="large">
<p>Choose an operating system, on which you want to use the Telegram Bot API server:</p>
<select id="osSelect" onchange="onOsChanged(false)" autofocus class="large">
<option>Choose an operating system:</option>
@ -27,7 +194,7 @@ select.large { font-size: large; }
<p></p>
</div>
<div id="linuxSelectDiv" class="hide" style="text-align:center;">
<div id="linuxSelectDiv" class="hide">
<p>Choose a Linux distro, on which you want to use the Telegram Bot API server:</p>
<select id="linuxSelect" onchange="onOsChanged(false)" class="large">
<option>Choose a Linux distro:</option>
@ -45,7 +212,7 @@ select.large { font-size: large; }
<p></p>
</div>
<div id="buildOptionsDiv" class="hide" style="text-align:center;">
<div id="buildOptionsDiv" class="hide">
<div id="buildDebugDiv" class="hide">
<label><input type="checkbox" id="buildDebugCheckbox" onchange="onOptionsChanged()"/>Build the debug binary. Debug binaries are much larger and slower than the release one.</label>
</div>
@ -77,6 +244,13 @@ select.large { font-size: large; }
<p></p>
</div>
<div id="buildMacOsHostDiv" class="hide">
<span>Choose host architecture:</span><br>
<label><input type="radio" id="buildMacOsHostRadioAppleSilicon" name="buildMacOsHostRadio" onchange="onOptionsChanged()" checked/>Apple silicon</label>
<label><input type="radio" id="buildMacOsHostRadioIntel" name="buildMacOsHostRadio" onchange="onOptionsChanged()"/>Intel</label>
<p></p>
</div>
<div id="buildBitnessDiv" class="hide">
<span>Choose for which bitness you want to build the Telegram Bot API server:</span><br>
<label><input type="radio" id="buildBitnessRadio64" name="buildBitnessRadio" onchange="onOptionsChanged()" checked/>64</label>
@ -91,13 +265,16 @@ select.large { font-size: large; }
<p></p>
</div>
<div id="buildTextDiv" class="hide" style="text-align:center;">
<div id="buildTextDiv" class="hide">
<p id="buildText">Hidden text</p>
</div>
<div id="buildCommandsDiv" class="hide" style="text-align:left;">
<div id="buildCommandsDiv" class="hide">
<p id="buildPre">Hidden text</p>
<code id="buildCommands">Empty commands</code>
<button id="copyBuildCommandsButton" onclick="copyBuildInstructions()">
<span id="copyBuildCommandsText">Copy</span>
</button>
</div>
</div>
@ -193,6 +370,8 @@ function onOptionsChanged() {
var use_powershell = false;
var use_cmd = false;
var use_csh = false;
var homebrew_install_dir = '';
var os_mac_host_name = '';
if (os_windows) {
document.getElementById('buildShellDiv').style.display = 'block';
use_powershell = document.getElementById('buildShellRadioPowerShell').checked;
@ -205,6 +384,18 @@ function onOptionsChanged() {
} else {
document.getElementById('buildShellBsdDiv').style.display = 'none';
}
if (os_mac) {
document.getElementById('buildMacOsHostDiv').style.display = 'block';
if (document.getElementById('buildMacOsHostRadioAppleSilicon').checked) {
homebrew_install_dir = '/opt/homebrew';
os_mac_host_name = 'Apple silicon';
} else {
homebrew_install_dir = '/usr/local';
os_mac_host_name = 'Intel';
}
} else {
document.getElementById('buildMacOsHostDiv').style.display = 'none';
}
var use_msvc = os_windows;
var use_vcpkg = os_windows;
@ -312,7 +503,7 @@ function onOptionsChanged() {
var cmake = 'cmake';
if (os_mac) {
commands.push('xcode-select --install');
commands.push('/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"');
commands.push('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"');
commands.push('brew install gperf cmake openssl');
} else if (os_linux && linux_distro !== 'Other') {
switch (linux_distro) {
@ -435,7 +626,7 @@ function onOptionsChanged() {
cmake_init_options = getBacicCmakeInitOptions();
if (os_mac) {
cmake_init_options.push('-DOPENSSL_ROOT_DIR=/usr/local/opt/openssl/');
cmake_init_options.push('-DOPENSSL_ROOT_DIR=' + homebrew_install_dir + '/opt/openssl/');
}
cmake_init_options.push('-DCMAKE_INSTALL_PREFIX:PATH=' + install_dir);
if (use_vcpkg) {
@ -485,6 +676,26 @@ function onOptionsChanged() {
}
commands.push((use_powershell ? 'dir ' : 'ls -l ') + install_dir + '/bin/tdlight-telegram-bot-api*');
document.getElementById('buildCommands').innerHTML = '<ul><li>' + commands.join('</li><li>') + '</li></ul>';
document.getElementById('copyBuildCommandsButton').style.display = commands.includes('exit') ? 'none' : 'block';
}
function copyBuildInstructions() {
var text = document.getElementById('buildCommands').innerText;
function resetButtonState (state) {
document.getElementById('copyBuildCommandsButton').classList.remove(state);
document.getElementById('copyBuildCommandsText').innerText = "Copy";
}
navigator.clipboard.writeText(text).then(result => {
document.getElementById('copyBuildCommandsButton').classList.add('success');
document.getElementById('copyBuildCommandsText').innerText = "Copied!";
setTimeout(() => resetButtonState('success'), 5000);
}, error => {
document.getElementById('copyBuildCommandsButton').classList.add('fail');
document.getElementById('copyBuildCommandsText').innerText = "Couldn't copy :(";
setTimeout(() => resetButtonState('fail'), 5000);
})
}
</script>

2
td

@ -1 +1 @@
Subproject commit 5a76413990ff96653bfda32d37f38ee825be65d8
Subproject commit 1e1ab5d1b0e4811e6d9e1584a82da08448d0cada

File diff suppressed because it is too large Load Diff

View File

@ -11,11 +11,11 @@
#include "telegram-bot-api/WebhookActor.h"
#include "td/telegram/ClientActor.h"
#include "td/telegram/td_api.h"
#include "td/actor/actor.h"
#include "td/actor/PromiseFuture.h"
#include "td/actor/SignalSlot.h"
#include "td/actor/Timeout.h"
#include "td/utils/common.h"
#include "td/utils/Container.h"
@ -36,12 +36,12 @@ struct ClientParameters;
namespace td_api = td::td_api;
class Client : public WebhookActor::Callback {
class Client final : public WebhookActor::Callback {
public:
Client(td::ActorShared<> parent, const td::string &bot_token, bool is_user, bool is_test_dc, td::int64 tqueue_id,
std::shared_ptr<const ClientParameters> parameters, td::ActorId<BotStatActor> stat_actor);
void send(PromisedQueryPtr query) override;
void send(PromisedQueryPtr query) final;
void close();
@ -65,8 +65,6 @@ class Client : public WebhookActor::Callback {
static constexpr int32 MAX_CONCURRENTLY_SENT_CHAT_MESSAGES = 1000; // some unreasonably big value
static constexpr int32 MESSAGES_CACHE_TIME = 3600;
static constexpr std::size_t MIN_PENDING_UPDATES_WARNING = 200;
static constexpr int64 GREAT_MINDS_SET_ID = 1842540969984001;
@ -413,7 +411,7 @@ class Client : public WebhookActor::Callback {
static object_ptr<td_api::MaskPoint> mask_index_to_point(int32 index);
td::Result<td::vector<object_ptr<td_api::InputSticker>>> get_input_stickers(const Query *query) const;
td::Result<td::vector<object_ptr<td_api::inputSticker>>> get_input_stickers(const Query *query, bool is_masks) const;
static td::Result<td::string> get_passport_element_hash(Slice encoded_hash);
@ -459,7 +457,9 @@ class Client : public WebhookActor::Callback {
td::Result<td::vector<object_ptr<td_api::InputMessageContent>>> get_input_message_contents(
const Query *query, td::JsonValue &&value) const;
static object_ptr<td_api::messageSendOptions> get_message_send_options(bool disable_notification, object_ptr<td_api::MessageSchedulingState> &&scheduling_state);
static object_ptr<td_api::messageSendOptions> get_message_send_options(bool disable_notification,
bool protect_content,
object_ptr<td_api::MessageSchedulingState> &&scheduling_state);
static td::Result<td::vector<td::string>> get_poll_options(const Query *query);
@ -622,11 +622,11 @@ class Client : public WebhookActor::Callback {
void process_register_user_query(PromisedQueryPtr &query);
void webhook_verified(td::string cached_ip_address) override;
void webhook_success() override;
void webhook_error(Status status) override;
void webhook_closed(Status status) override;
void hangup_shared() override;
void webhook_verified(td::string cached_ip_address) final;
void webhook_success() final;
void webhook_error(Status status) final;
void webhook_closed(Status status) final;
void hangup_shared() final;
int32 get_webhook_max_connections(const Query *query) const;
static bool get_webhook_fix_ip_address(const Query *query);
void do_set_webhook(PromisedQueryPtr query, bool was_deleted);
@ -665,13 +665,13 @@ class Client : public WebhookActor::Callback {
void long_poll_wakeup(bool force_flag);
void start_up() override;
void start_up() final;
void raw_event(const td::Event::Raw &event) override;
void raw_event(const td::Event::Raw &event) final;
void loop() override;
void loop() final;
void timeout_expired() override;
void timeout_expired() final;
struct UserInfo {
enum class Type { Regular, Deleted, Bot, Unknown };
@ -768,10 +768,6 @@ class Client : public WebhookActor::Callback {
td::string get_chat_description(int64 chat_id) const;
struct MessageInfo {
mutable double access_time = 1e20;
mutable const MessageInfo *lru_next = nullptr;
mutable const MessageInfo *lru_prev = nullptr;
int64 id = 0;
int64 sender_user_id = 0;
int64 sender_chat_id = 0;
@ -842,9 +838,6 @@ class Client : public WebhookActor::Callback {
void remove_replies_to_message(int64 chat_id, int64 reply_to_message_id, bool only_from_cache);
void delete_message(int64 chat_id, int64 message_id, bool only_from_cache);
static void delete_messages_lru(void *client_void);
void schedule_next_delete_messages_lru();
void update_message_lru(const MessageInfo *message_info) const;
void add_new_message(object_ptr<td_api::message> &&message, bool is_edited);
void process_new_message_queue(int64 chat_id);
@ -995,7 +988,6 @@ class Client : public WebhookActor::Callback {
static std::unordered_map<td::string, Status (Client::*)(PromisedQueryPtr &query)> methods_;
MessageInfo messages_lru_root_;
std::unordered_map<FullMessageId, std::unique_ptr<MessageInfo>, FullMessageIdHash> messages_; // message cache
std::unordered_map<int64, UserInfo> users_; // user info cache
std::unordered_map<int64, GroupInfo> groups_; // group info cache
@ -1007,8 +999,6 @@ class Client : public WebhookActor::Callback {
std::unordered_map<FullMessageId, std::unordered_set<int64>, FullMessageIdHash>
yet_unsent_reply_message_ids_; // message -> replies to it
td::Timeout next_delete_messages_lru_timeout_;
std::unordered_map<int32, td::vector<PromisedQueryPtr>> file_download_listeners_;
std::unordered_set<int32> download_started_file_ids_;

View File

@ -12,6 +12,7 @@
#include "telegram-bot-api/StatsJson.h"
#include "td/telegram/ClientActor.h"
#include "td/telegram/td_api.h"
#include "td/db/binlog/Binlog.h"
#include "td/db/binlog/ConcurrentBinlog.h"

View File

@ -76,9 +76,9 @@ class ClientManager final : public td::Actor {
static PromisedQueryPtr get_webhook_restore_query(td::Slice token, bool is_user, td::Slice webhook_info,
std::shared_ptr<SharedData> shared_data);
void start_up() override;
void raw_event(const td::Event::Raw &event) override;
void hangup_shared() override;
void start_up() final;
void raw_event(const td::Event::Raw &event) final;
void hangup_shared() final;
void close_db();
void finish_close();
};

View File

@ -6,13 +6,13 @@
//
#pragma once
#include "td/actor/actor.h"
#include "td/db/KeyValueSyncInterface.h"
#include "td/db/TQueue.h"
#include "td/net/GetHostByNameActor.h"
#include "td/actor/actor.h"
#include "td/utils/common.h"
#include "td/utils/List.h"
#include "td/utils/port/IPAddress.h"
@ -23,7 +23,7 @@
namespace td {
class NetQueryStats;
}
} // namespace td
namespace telegram_bot_api {

View File

@ -9,12 +9,12 @@
#include "telegram-bot-api/ClientManager.h"
#include "telegram-bot-api/Query.h"
#include "td/actor/actor.h"
#include "td/actor/PromiseFuture.h"
#include "td/net/HttpInboundConnection.h"
#include "td/net/HttpQuery.h"
#include "td/actor/actor.h"
#include "td/actor/PromiseFuture.h"
#include "td/utils/buffer.h"
#include "td/utils/Slice.h"
@ -24,15 +24,15 @@ namespace telegram_bot_api {
struct SharedData;
class HttpConnection : public td::HttpInboundConnection::Callback {
class HttpConnection final : public td::HttpInboundConnection::Callback {
public:
explicit HttpConnection(td::ActorId<ClientManager> client_manager, std::shared_ptr<SharedData> shared_data)
: client_manager_(client_manager), shared_data_(std::move(shared_data)) {
}
void handle(td::unique_ptr<td::HttpQuery> http_query, td::ActorOwn<td::HttpInboundConnection> connection) override;
void handle(td::unique_ptr<td::HttpQuery> http_query, td::ActorOwn<td::HttpInboundConnection> connection) final;
void wakeup() override;
void wakeup() final;
private:
td::FutureActor<td::unique_ptr<Query>> result_;
@ -40,7 +40,7 @@ class HttpConnection : public td::HttpInboundConnection::Callback {
td::ActorOwn<td::HttpInboundConnection> connection_;
std::shared_ptr<SharedData> shared_data_;
void hangup() override {
void hangup() final {
connection_.release();
stop();
}

View File

@ -6,11 +6,11 @@
//
#pragma once
#include "td/actor/actor.h"
#include "td/net/HttpInboundConnection.h"
#include "td/net/TcpListener.h"
#include "td/actor/actor.h"
#include "td/utils/BufferedFd.h"
#include "td/utils/FloodControlFast.h"
#include "td/utils/format.h"
@ -23,7 +23,7 @@
namespace telegram_bot_api {
class HttpServer : public td::TcpListener::Callback {
class HttpServer final : public td::TcpListener::Callback {
public:
HttpServer(td::string ip_address, int port,
std::function<td::ActorOwn<td::HttpInboundConnection::Callback>()> creator)
@ -39,7 +39,7 @@ class HttpServer : public td::TcpListener::Callback {
td::ActorOwn<td::TcpListener> listener_;
td::FloodControlFast flood_control_;
void start_up() override {
void start_up() final {
auto now = td::Time::now();
auto wakeup_at = flood_control_.get_wakeup_at();
if (wakeup_at > now) {
@ -53,13 +53,13 @@ class HttpServer : public td::TcpListener::Callback {
actor_shared(this, 1), ip_address_);
}
void hangup_shared() override {
void hangup_shared() final {
LOG(ERROR) << "TCP listener was closed";
listener_.release();
yield();
}
void accept(td::SocketFd fd) override {
void accept(td::SocketFd fd) final {
auto scheduler_count = td::Scheduler::instance()->sched_count();
auto scheduler_id = scheduler_count - 1;
if (scheduler_id > 0) {
@ -70,7 +70,7 @@ class HttpServer : public td::TcpListener::Callback {
.release();
}
void loop() override {
void loop() final {
if (listener_.empty()) {
start_up();
}

View File

@ -8,23 +8,23 @@
#include "telegram-bot-api/ClientManager.h"
#include "td/actor/actor.h"
#include "td/actor/PromiseFuture.h"
#include "td/net/HttpInboundConnection.h"
#include "td/net/HttpQuery.h"
#include "td/actor/actor.h"
#include "td/actor/PromiseFuture.h"
#include "td/utils/buffer.h"
namespace telegram_bot_api {
class HttpStatConnection : public td::HttpInboundConnection::Callback {
class HttpStatConnection final : public td::HttpInboundConnection::Callback {
public:
explicit HttpStatConnection(td::ActorId<ClientManager> client_manager) : client_manager_(client_manager) {
}
void handle(td::unique_ptr<td::HttpQuery> http_query, td::ActorOwn<td::HttpInboundConnection> connection) override;
void handle(td::unique_ptr<td::HttpQuery> http_query, td::ActorOwn<td::HttpInboundConnection> connection) final;
void wakeup() override;
void wakeup() final;
private:
bool as_json_;
@ -32,7 +32,7 @@ class HttpStatConnection : public td::HttpInboundConnection::Callback {
td::ActorId<ClientManager> client_manager_;
td::ActorOwn<td::HttpInboundConnection> connection_;
void hangup() override {
void hangup() final {
connection_.release();
stop();
}

View File

@ -8,11 +8,11 @@
#include "telegram-bot-api/ClientParameters.h"
#include "td/net/HttpFile.h"
#include "td/actor/actor.h"
#include "td/actor/PromiseFuture.h"
#include "td/net/HttpFile.h"
#include "td/utils/buffer.h"
#include "td/utils/common.h"
#include "td/utils/JsonBuilder.h"
@ -30,7 +30,7 @@ namespace telegram_bot_api {
class BotStatActor;
class Query : public td::ListNode {
class Query final : public td::ListNode {
public:
enum class State : td::int8 { Query, OK, Error };
@ -170,7 +170,7 @@ td::StringBuilder &operator<<(td::StringBuilder &sb, const Query &query);
// https://stackoverflow.com/questions/26947704/implicit-conversion-failure-from-initializer-list
extern std::unordered_map<td::string, std::unique_ptr<td::VirtuallyJsonable>> empty_parameters;
class JsonParameters : public td::Jsonable {
class JsonParameters final : public td::Jsonable {
public:
explicit JsonParameters(const std::unordered_map<td::string, std::unique_ptr<td::VirtuallyJsonable>> &parameters)
: parameters_(parameters) {
@ -188,7 +188,7 @@ class JsonParameters : public td::Jsonable {
};
template <class T>
class JsonQueryOk : public td::Jsonable {
class JsonQueryOk final : public td::Jsonable {
public:
JsonQueryOk(const T &result, td::Slice description) : result_(result), description_(description) {
}
@ -206,7 +206,7 @@ class JsonQueryOk : public td::Jsonable {
td::Slice description_;
};
class JsonQueryError : public td::Jsonable {
class JsonQueryError final : public td::Jsonable {
public:
JsonQueryError(
int error_code, td::Slice description,

View File

@ -157,7 +157,7 @@ class BotStatActor final : public td::Actor {
BotStatActor(const BotStatActor &) = delete;
BotStatActor &operator=(const BotStatActor &other) = delete;
BotStatActor(BotStatActor &&) = default;
BotStatActor &operator=(BotStatActor &&other) {
BotStatActor &operator=(BotStatActor &&other) noexcept {
if (!empty()) {
do_stop();
}
@ -166,7 +166,7 @@ class BotStatActor final : public td::Actor {
parent_ = other.parent_;
return *this;
}
~BotStatActor() override = default;
~BotStatActor() final = default;
template <class EventT>
void add_event(const EventT &event, double now) {

View File

@ -152,11 +152,11 @@ td::Status WebhookActor::create_connection() {
}
VLOG(webhook) << "Create connection through proxy " << parameters_->webhook_proxy_ip_address_;
class Callback : public td::TransparentProxy::Callback {
class Callback final : public td::TransparentProxy::Callback {
public:
Callback(td::ActorId<WebhookActor> actor, td::int64 id) : actor_(actor), id_(id) {
}
void set_result(td::Result<td::BufferedFd<td::SocketFd>> result) override {
void set_result(td::Result<td::BufferedFd<td::SocketFd>> result) final {
send_closure(std::move(actor_), &WebhookActor::on_socket_ready_async, std::move(result), id_);
CHECK(actor_.empty());
}
@ -169,7 +169,7 @@ td::Status WebhookActor::create_connection() {
send_closure(std::move(actor_), &WebhookActor::on_socket_ready_async, td::Status::Error("Canceled"), id_);
}
}
void on_connected() override {
void on_connected() final {
// nothing to do
}
@ -356,7 +356,7 @@ void WebhookActor::load_updates() {
auto offset = tqueue_offset_;
auto limit = td::min(SharedData::TQUEUE_EVENT_BUFFER_SIZE, max_loaded_updates_ - queue_updates_.size());
auto updates = mutable_span(parameters_->shared_data_->event_buffer_, limit);
td::MutableSpan<td::TQueue::Event> updates(parameters_->shared_data_->event_buffer_, limit);
auto now = td::Time::now();
auto unix_time_now = parameters_->shared_data_->get_unix_time(now);

View File

@ -41,7 +41,7 @@ namespace telegram_bot_api {
struct ClientParameters;
class WebhookActor : public td::HttpOutboundConnection::Callback {
class WebhookActor final : public td::HttpOutboundConnection::Callback {
public:
class Callback : public td::Actor {
public:
@ -139,7 +139,7 @@ class WebhookActor : public td::HttpOutboundConnection::Callback {
double next_ip_address_resolve_time_ = 0;
td::FutureActor<td::IPAddress> future_ip_address_;
class Connection : public td::ListNode {
class Connection final : public td::ListNode {
public:
Connection() = default;
Connection(const Connection &) = delete;
@ -190,26 +190,26 @@ class WebhookActor : public td::HttpOutboundConnection::Callback {
td::Status send_update() TD_WARN_UNUSED_RESULT;
void send_updates();
void loop() override;
void handle(td::unique_ptr<td::HttpQuery> response) override;
void loop() final;
void handle(td::unique_ptr<td::HttpQuery> response) final;
void hangup_shared() override;
void hangup_shared() final;
void hangup() override;
void hangup() final;
void tear_down() override;
void tear_down() final;
void start_up() override;
void start_up() final;
bool check_ip_address(const td::IPAddress &addr) const;
void on_error(td::Status status);
void on_connection_error(td::Status error) override;
void on_connection_error(td::Status error) final;
void on_webhook_error(td::Slice error);
void on_webhook_verified();
};
class JsonUpdate : public td::Jsonable {
class JsonUpdate final : public td::Jsonable {
public:
JsonUpdate(td::int32 id, td::Slice update) : id_(id), update_(update) {
}

View File

@ -200,7 +200,7 @@ int main(int argc, char *argv[]) {
auto start_time = td::Time::now();
auto shared_data = std::make_shared<SharedData>();
auto parameters = std::make_unique<ClientParameters>();
parameters->version_ = "5.5.1";
parameters->version_ = "5.7";
parameters->shared_data_ = shared_data;
parameters->start_time_ = start_time;
auto net_query_stats = td::create_net_query_stats();
@ -320,22 +320,23 @@ int main(int argc, char *argv[]) {
options.add_checked_option('c', "max-connections", "maximum number of open file descriptors",
td::OptionParser::parse_integer(max_connections));
options.add_checked_option('\0', "max-batch-operations", PSLICE() << "maximum number of batch operations (default: " << parameters->max_batch_operations << ")",
td::OptionParser::parse_integer(parameters->max_batch_operations));
td::OptionParser::parse_integer(parameters->max_batch_operations));
options.add_checked_option('\0', "file-expiration-time",
PSLICE() << "downloaded files expire after this amount of seconds of not being used (defaults to " << parameters->file_expiration_timeout_seconds_ << ")",
td::OptionParser::parse_integer(parameters->file_expiration_timeout_seconds_));
options.add_checked_option(
'\0', "proxy", PSLICE() << "HTTP proxy server for outgoing webhook requests in the format http://host:port",
[&](td::Slice address) {
if (td::begins_with(address, "http://")) {
address.remove_prefix(7);
} else if (td::begins_with(address, "https://")) {
address.remove_prefix(8);
}
return parameters->webhook_proxy_ip_address_.init_host_port(address.str());
});
options.add_checked_option('\0', "proxy",
"HTTP proxy server for outgoing webhook requests in the format http://host:port",
[&](td::Slice address) {
if (td::begins_with(address, "http://")) {
address.remove_prefix(7);
} else if (td::begins_with(address, "https://")) {
address.remove_prefix(8);
}
return parameters->webhook_proxy_ip_address_.init_host_port(address.str());
});
options.add_check([&] {
if (parameters->api_id_ <= 0 || parameters->api_hash_.empty()) {
return td::Status::Error("You must provide valid api-id and api-hash obtained at https://my.telegram.org");