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

View File

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

View File

@ -3,17 +3,184 @@
<head> <head>
<title>Telegram Bot API server build instructions</title> <title>Telegram Bot API server build instructions</title>
<style> <style>
.hide { display: none; } :root {
div.main { max-width:1200px; margin: auto; font-size: x-large; } --background: #fafafa;
select.large { font-size: large; } --color: black;
</style> --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> </head>
<body onload="onLoad(true)" onpopstate="onLoad(false)"> <body onload="onLoad(true)" onpopstate="onLoad(false)">
<div class="main"> <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> <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"> <select id="osSelect" onchange="onOsChanged(false)" autofocus class="large">
<option>Choose an operating system:</option> <option>Choose an operating system:</option>
@ -27,7 +194,7 @@ select.large { font-size: large; }
<p></p> <p></p>
</div> </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> <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"> <select id="linuxSelect" onchange="onOsChanged(false)" class="large">
<option>Choose a Linux distro:</option> <option>Choose a Linux distro:</option>
@ -45,7 +212,7 @@ select.large { font-size: large; }
<p></p> <p></p>
</div> </div>
<div id="buildOptionsDiv" class="hide" style="text-align:center;"> <div id="buildOptionsDiv" class="hide">
<div id="buildDebugDiv" 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> <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> </div>
@ -77,6 +244,13 @@ select.large { font-size: large; }
<p></p> <p></p>
</div> </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"> <div id="buildBitnessDiv" class="hide">
<span>Choose for which bitness you want to build the Telegram Bot API server:</span><br> <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> <label><input type="radio" id="buildBitnessRadio64" name="buildBitnessRadio" onchange="onOptionsChanged()" checked/>64</label>
@ -91,13 +265,16 @@ select.large { font-size: large; }
<p></p> <p></p>
</div> </div>
<div id="buildTextDiv" class="hide" style="text-align:center;"> <div id="buildTextDiv" class="hide">
<p id="buildText">Hidden text</p> <p id="buildText">Hidden text</p>
</div> </div>
<div id="buildCommandsDiv" class="hide" style="text-align:left;"> <div id="buildCommandsDiv" class="hide">
<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()">
<span id="copyBuildCommandsText">Copy</span>
</button>
</div> </div>
</div> </div>
@ -193,6 +370,8 @@ function onOptionsChanged() {
var use_powershell = false; var use_powershell = false;
var use_cmd = false; var use_cmd = false;
var use_csh = false; var use_csh = false;
var homebrew_install_dir = '';
var os_mac_host_name = '';
if (os_windows) { if (os_windows) {
document.getElementById('buildShellDiv').style.display = 'block'; document.getElementById('buildShellDiv').style.display = 'block';
use_powershell = document.getElementById('buildShellRadioPowerShell').checked; use_powershell = document.getElementById('buildShellRadioPowerShell').checked;
@ -205,6 +384,18 @@ function onOptionsChanged() {
} else { } else {
document.getElementById('buildShellBsdDiv').style.display = 'none'; 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_msvc = os_windows;
var use_vcpkg = os_windows; var use_vcpkg = os_windows;
@ -312,7 +503,7 @@ function onOptionsChanged() {
var cmake = 'cmake'; var cmake = 'cmake';
if (os_mac) { if (os_mac) {
commands.push('xcode-select --install'); 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'); commands.push('brew install gperf cmake openssl');
} else if (os_linux && linux_distro !== 'Other') { } else if (os_linux && linux_distro !== 'Other') {
switch (linux_distro) { switch (linux_distro) {
@ -435,7 +626,7 @@ function onOptionsChanged() {
cmake_init_options = getBacicCmakeInitOptions(); cmake_init_options = getBacicCmakeInitOptions();
if (os_mac) { 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); cmake_init_options.push('-DCMAKE_INSTALL_PREFIX:PATH=' + install_dir);
if (use_vcpkg) { if (use_vcpkg) {
@ -485,6 +676,26 @@ function onOptionsChanged() {
} }
commands.push((use_powershell ? 'dir ' : 'ls -l ') + install_dir + '/bin/tdlight-telegram-bot-api*'); 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('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> </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 "telegram-bot-api/WebhookActor.h"
#include "td/telegram/ClientActor.h" #include "td/telegram/ClientActor.h"
#include "td/telegram/td_api.h"
#include "td/actor/actor.h" #include "td/actor/actor.h"
#include "td/actor/PromiseFuture.h" #include "td/actor/PromiseFuture.h"
#include "td/actor/SignalSlot.h" #include "td/actor/SignalSlot.h"
#include "td/actor/Timeout.h"
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/Container.h" #include "td/utils/Container.h"
@ -36,12 +36,12 @@ struct ClientParameters;
namespace td_api = td::td_api; namespace td_api = td::td_api;
class Client : public WebhookActor::Callback { class Client final : public WebhookActor::Callback {
public: public:
Client(td::ActorShared<> parent, const td::string &bot_token, bool is_user, bool is_test_dc, td::int64 tqueue_id, 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); std::shared_ptr<const ClientParameters> parameters, td::ActorId<BotStatActor> stat_actor);
void send(PromisedQueryPtr query) override; void send(PromisedQueryPtr query) final;
void close(); 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 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 std::size_t MIN_PENDING_UPDATES_WARNING = 200;
static constexpr int64 GREAT_MINDS_SET_ID = 1842540969984001; 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); 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); 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( td::Result<td::vector<object_ptr<td_api::InputMessageContent>>> get_input_message_contents(
const Query *query, td::JsonValue &&value) const; 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); 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 process_register_user_query(PromisedQueryPtr &query);
void webhook_verified(td::string cached_ip_address) override; void webhook_verified(td::string cached_ip_address) final;
void webhook_success() override; void webhook_success() final;
void webhook_error(Status status) override; void webhook_error(Status status) final;
void webhook_closed(Status status) override; void webhook_closed(Status status) final;
void hangup_shared() override; void hangup_shared() final;
int32 get_webhook_max_connections(const Query *query) const; int32 get_webhook_max_connections(const Query *query) const;
static bool get_webhook_fix_ip_address(const Query *query); static bool get_webhook_fix_ip_address(const Query *query);
void do_set_webhook(PromisedQueryPtr query, bool was_deleted); 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 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 { struct UserInfo {
enum class Type { Regular, Deleted, Bot, Unknown }; 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; td::string get_chat_description(int64 chat_id) const;
struct MessageInfo { struct MessageInfo {
mutable double access_time = 1e20;
mutable const MessageInfo *lru_next = nullptr;
mutable const MessageInfo *lru_prev = nullptr;
int64 id = 0; int64 id = 0;
int64 sender_user_id = 0; int64 sender_user_id = 0;
int64 sender_chat_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 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); 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 add_new_message(object_ptr<td_api::message> &&message, bool is_edited);
void process_new_message_queue(int64 chat_id); 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_; 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<FullMessageId, std::unique_ptr<MessageInfo>, FullMessageIdHash> messages_; // message cache
std::unordered_map<int64, UserInfo> users_; // user info cache std::unordered_map<int64, UserInfo> users_; // user info cache
std::unordered_map<int64, GroupInfo> groups_; // group 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> std::unordered_map<FullMessageId, std::unordered_set<int64>, FullMessageIdHash>
yet_unsent_reply_message_ids_; // message -> replies to it 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_map<int32, td::vector<PromisedQueryPtr>> file_download_listeners_;
std::unordered_set<int32> download_started_file_ids_; std::unordered_set<int32> download_started_file_ids_;

View File

@ -12,6 +12,7 @@
#include "telegram-bot-api/StatsJson.h" #include "telegram-bot-api/StatsJson.h"
#include "td/telegram/ClientActor.h" #include "td/telegram/ClientActor.h"
#include "td/telegram/td_api.h"
#include "td/db/binlog/Binlog.h" #include "td/db/binlog/Binlog.h"
#include "td/db/binlog/ConcurrentBinlog.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, static PromisedQueryPtr get_webhook_restore_query(td::Slice token, bool is_user, td::Slice webhook_info,
std::shared_ptr<SharedData> shared_data); std::shared_ptr<SharedData> shared_data);
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 hangup_shared() override; void hangup_shared() final;
void close_db(); void close_db();
void finish_close(); void finish_close();
}; };

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -157,7 +157,7 @@ class BotStatActor final : public td::Actor {
BotStatActor(const BotStatActor &) = delete; BotStatActor(const BotStatActor &) = delete;
BotStatActor &operator=(const BotStatActor &other) = delete; BotStatActor &operator=(const BotStatActor &other) = delete;
BotStatActor(BotStatActor &&) = default; BotStatActor(BotStatActor &&) = default;
BotStatActor &operator=(BotStatActor &&other) { BotStatActor &operator=(BotStatActor &&other) noexcept {
if (!empty()) { if (!empty()) {
do_stop(); do_stop();
} }
@ -166,7 +166,7 @@ class BotStatActor final : public td::Actor {
parent_ = other.parent_; parent_ = other.parent_;
return *this; return *this;
} }
~BotStatActor() override = default; ~BotStatActor() final = default;
template <class EventT> template <class EventT>
void add_event(const EventT &event, double now) { 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_; 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: public:
Callback(td::ActorId<WebhookActor> actor, td::int64 id) : actor_(actor), id_(id) { 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_); send_closure(std::move(actor_), &WebhookActor::on_socket_ready_async, std::move(result), id_);
CHECK(actor_.empty()); 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_); 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 // nothing to do
} }
@ -356,7 +356,7 @@ void WebhookActor::load_updates() {
auto offset = tqueue_offset_; auto offset = tqueue_offset_;
auto limit = td::min(SharedData::TQUEUE_EVENT_BUFFER_SIZE, max_loaded_updates_ - queue_updates_.size()); 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 now = td::Time::now();
auto unix_time_now = parameters_->shared_data_->get_unix_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; struct ClientParameters;
class WebhookActor : public td::HttpOutboundConnection::Callback { class WebhookActor final : public td::HttpOutboundConnection::Callback {
public: public:
class Callback : public td::Actor { class Callback : public td::Actor {
public: public:
@ -139,7 +139,7 @@ class WebhookActor : public td::HttpOutboundConnection::Callback {
double next_ip_address_resolve_time_ = 0; double next_ip_address_resolve_time_ = 0;
td::FutureActor<td::IPAddress> future_ip_address_; td::FutureActor<td::IPAddress> future_ip_address_;
class Connection : public td::ListNode { class Connection final : public td::ListNode {
public: public:
Connection() = default; Connection() = default;
Connection(const Connection &) = delete; Connection(const Connection &) = delete;
@ -190,26 +190,26 @@ class WebhookActor : public td::HttpOutboundConnection::Callback {
td::Status send_update() TD_WARN_UNUSED_RESULT; td::Status send_update() TD_WARN_UNUSED_RESULT;
void send_updates(); void send_updates();
void loop() override; void loop() final;
void handle(td::unique_ptr<td::HttpQuery> response) override; 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; bool check_ip_address(const td::IPAddress &addr) const;
void on_error(td::Status status); 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_error(td::Slice error);
void on_webhook_verified(); void on_webhook_verified();
}; };
class JsonUpdate : public td::Jsonable { class JsonUpdate final : public td::Jsonable {
public: public:
JsonUpdate(td::int32 id, td::Slice update) : id_(id), update_(update) { 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 start_time = td::Time::now();
auto shared_data = std::make_shared<SharedData>(); auto shared_data = std::make_shared<SharedData>();
auto parameters = std::make_unique<ClientParameters>(); auto parameters = std::make_unique<ClientParameters>();
parameters->version_ = "5.5.1"; parameters->version_ = "5.7";
parameters->shared_data_ = shared_data; parameters->shared_data_ = shared_data;
parameters->start_time_ = start_time; parameters->start_time_ = start_time;
auto net_query_stats = td::create_net_query_stats(); 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", options.add_checked_option('c', "max-connections", "maximum number of open file descriptors",
td::OptionParser::parse_integer(max_connections)); 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 << ")", 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", 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_ << ")", 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_)); td::OptionParser::parse_integer(parameters->file_expiration_timeout_seconds_));
options.add_checked_option( options.add_checked_option('\0', "proxy",
'\0', "proxy", PSLICE() << "HTTP proxy server for outgoing webhook requests in the format http://host:port", "HTTP proxy server for outgoing webhook requests in the format http://host:port",
[&](td::Slice address) { [&](td::Slice address) {
if (td::begins_with(address, "http://")) { if (td::begins_with(address, "http://")) {
address.remove_prefix(7); address.remove_prefix(7);
} else if (td::begins_with(address, "https://")) { } else if (td::begins_with(address, "https://")) {
address.remove_prefix(8); address.remove_prefix(8);
} }
return parameters->webhook_proxy_ip_address_.init_host_port(address.str()); return parameters->webhook_proxy_ip_address_.init_host_port(address.str());
}); });
options.add_check([&] { options.add_check([&] {
if (parameters->api_id_ <= 0 || parameters->api_hash_.empty()) { 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"); return td::Status::Error("You must provide valid api-id and api-hash obtained at https://my.telegram.org");