Clean up
This commit is contained in:
parent
17e85d361c
commit
e147fe3695
7
.gitignore
vendored
7
.gitignore
vendored
@ -124,3 +124,10 @@ coverage
|
||||
tempConv
|
||||
extracted.json
|
||||
.phpunit.result.cache
|
||||
|
||||
src/danog/MadelineProto/VoIP.php
|
||||
src/danog/MadelineProto/VoIP/AckHandler.php
|
||||
src/danog/MadelineProto/VoIP/MessageHandler.php
|
||||
src/danog/MadelineProto/OpusStream.php
|
||||
|
||||
ponyScripts
|
||||
|
356
.phan/config.php
Normal file
356
.phan/config.php
Normal file
@ -0,0 +1,356 @@
|
||||
<?php
|
||||
|
||||
use Phan\Issue;
|
||||
|
||||
/**
|
||||
* This configuration file was automatically generated by 'phan --init --init-level=3'
|
||||
*
|
||||
* TODOs (added by 'phan --init'):
|
||||
*
|
||||
* - Go through this file and verify that there are no missing/unnecessary files/directories.
|
||||
* (E.g. this only includes direct composer dependencies - You may have to manually add indirect composer dependencies to 'directory_list')
|
||||
* - Look at 'plugins' and add or remove plugins if appropriate (see https://github.com/phan/phan/tree/master/.phan/plugins#plugins)
|
||||
* - Add global suppressions for pre-existing issues to suppress_issue_types (https://github.com/phan/phan/wiki/Tutorial-for-Analyzing-a-Large-Sloppy-Code-Base)
|
||||
*
|
||||
* This configuration will be read and overlaid on top of the
|
||||
* default configuration. Command line arguments will be applied
|
||||
* after this file is read.
|
||||
*
|
||||
* @see src/Phan/Config.php
|
||||
* See Config for all configurable options.
|
||||
*
|
||||
* A Note About Paths
|
||||
* ==================
|
||||
*
|
||||
* Files referenced from this file should be defined as
|
||||
*
|
||||
* ```
|
||||
* Config::projectPath('relative_path/to/file')
|
||||
* ```
|
||||
*
|
||||
* where the relative path is relative to the root of the
|
||||
* project which is defined as either the working directory
|
||||
* of the phan executable or a path passed in via the CLI
|
||||
* '-d' flag.
|
||||
*/
|
||||
return [
|
||||
|
||||
// Supported values: `'5.6'`, `'7.0'`, `'7.1'`, `'7.2'`, `'7.3'`, `'7.4'`, `null`.
|
||||
// If this is set to `null`,
|
||||
// then Phan assumes the PHP version which is closest to the minor version
|
||||
// of the php executable used to execute Phan.
|
||||
//
|
||||
// Note that the **only** effect of choosing `'5.6'` is to infer that functions removed in php 7.0 exist.
|
||||
// (See `backward_compatibility_checks` for additional options)
|
||||
// Automatically inferred from composer.json requirement for "php" of ">=7.4.0"
|
||||
'target_php_version' => '7.4',
|
||||
|
||||
// If enabled, missing properties will be created when
|
||||
// they are first seen. If false, we'll report an
|
||||
// error message if there is an attempt to write
|
||||
// to a class property that wasn't explicitly
|
||||
// defined.
|
||||
'allow_missing_properties' => false,
|
||||
|
||||
// If enabled, null can be cast to any type and any
|
||||
// type can be cast to null. Setting this to true
|
||||
// will cut down on false positives.
|
||||
'null_casts_as_any_type' => false,
|
||||
|
||||
// If enabled, allow null to be cast as any array-like type.
|
||||
//
|
||||
// This is an incremental step in migrating away from `null_casts_as_any_type`.
|
||||
// If `null_casts_as_any_type` is true, this has no effect.
|
||||
'null_casts_as_array' => true,
|
||||
|
||||
// If enabled, allow any array-like type to be cast to null.
|
||||
// This is an incremental step in migrating away from `null_casts_as_any_type`.
|
||||
// If `null_casts_as_any_type` is true, this has no effect.
|
||||
'array_casts_as_null' => true,
|
||||
|
||||
// If enabled, scalars (int, float, bool, string, null)
|
||||
// are treated as if they can cast to each other.
|
||||
// This does not affect checks of array keys. See `scalar_array_key_cast`.
|
||||
'scalar_implicit_cast' => false,
|
||||
|
||||
// If enabled, any scalar array keys (int, string)
|
||||
// are treated as if they can cast to each other.
|
||||
// E.g. `array<int,stdClass>` can cast to `array<string,stdClass>` and vice versa.
|
||||
// Normally, a scalar type such as int could only cast to/from int and mixed.
|
||||
'scalar_array_key_cast' => true,
|
||||
|
||||
// If this has entries, scalars (int, float, bool, string, null)
|
||||
// are allowed to perform the casts listed.
|
||||
//
|
||||
// E.g. `['int' => ['float', 'string'], 'float' => ['int'], 'string' => ['int'], 'null' => ['string']]`
|
||||
// allows casting null to a string, but not vice versa.
|
||||
// (subset of `scalar_implicit_cast`)
|
||||
'scalar_implicit_partial' => [],
|
||||
|
||||
// If enabled, Phan will warn if **any** type in a method invocation's object
|
||||
// is definitely not an object,
|
||||
// or if **any** type in an invoked expression is not a callable.
|
||||
// Setting this to true will introduce numerous false positives
|
||||
// (and reveal some bugs).
|
||||
'strict_method_checking' => false,
|
||||
|
||||
// If enabled, Phan will warn if **any** type of the object expression for a property access
|
||||
// does not contain that property.
|
||||
'strict_object_checking' => false,
|
||||
|
||||
// If enabled, Phan will warn if **any** type in the argument's union type
|
||||
// cannot be cast to a type in the parameter's expected union type.
|
||||
// Setting this to true will introduce numerous false positives
|
||||
// (and reveal some bugs).
|
||||
'strict_param_checking' => false,
|
||||
|
||||
// If enabled, Phan will warn if **any** type in a property assignment's union type
|
||||
// cannot be cast to a type in the property's declared union type.
|
||||
// Setting this to true will introduce numerous false positives
|
||||
// (and reveal some bugs).
|
||||
'strict_property_checking' => false,
|
||||
|
||||
// If enabled, Phan will warn if **any** type in a returned value's union type
|
||||
// cannot be cast to the declared return type.
|
||||
// Setting this to true will introduce numerous false positives
|
||||
// (and reveal some bugs).
|
||||
'strict_return_checking' => false,
|
||||
|
||||
// If true, seemingly undeclared variables in the global
|
||||
// scope will be ignored.
|
||||
//
|
||||
// This is useful for projects with complicated cross-file
|
||||
// globals that you have no hope of fixing.
|
||||
'ignore_undeclared_variables_in_global_scope' => true,
|
||||
|
||||
// Set this to false to emit `PhanUndeclaredFunction` issues for internal functions that Phan has signatures for,
|
||||
// but aren't available in the codebase, or from Reflection.
|
||||
// (may lead to false positives if an extension isn't loaded)
|
||||
//
|
||||
// If this is true(default), then Phan will not warn.
|
||||
//
|
||||
// Even when this is false, Phan will still infer return values and check parameters of internal functions
|
||||
// if Phan has the signatures.
|
||||
'ignore_undeclared_functions_with_known_signatures' => true,
|
||||
|
||||
// Backwards Compatibility Checking. This is slow
|
||||
// and expensive, but you should consider running
|
||||
// it before upgrading your version of PHP to a
|
||||
// new version that has backward compatibility
|
||||
// breaks.
|
||||
//
|
||||
// If you are migrating from PHP 5 to PHP 7,
|
||||
// you should also look into using
|
||||
// [php7cc (no longer maintained)](https://github.com/sstalle/php7cc)
|
||||
// and [php7mar](https://github.com/Alexia/php7mar),
|
||||
// which have different backwards compatibility checks.
|
||||
'backward_compatibility_checks' => false,
|
||||
|
||||
// If true, check to make sure the return type declared
|
||||
// in the doc-block (if any) matches the return type
|
||||
// declared in the method signature.
|
||||
'check_docblock_signature_return_type_match' => false,
|
||||
|
||||
// This setting maps case-insensitive strings to union types.
|
||||
//
|
||||
// This is useful if a project uses phpdoc that differs from the phpdoc2 standard.
|
||||
//
|
||||
// If the corresponding value is the empty string,
|
||||
// then Phan will ignore that union type (E.g. can ignore 'the' in `@return the value`)
|
||||
//
|
||||
// If the corresponding value is not empty,
|
||||
// then Phan will act as though it saw the corresponding UnionTypes(s)
|
||||
// when the keys show up in a UnionType of `@param`, `@return`, `@var`, `@property`, etc.
|
||||
//
|
||||
// This matches the **entire string**, not parts of the string.
|
||||
// (E.g. `@return the|null` will still look for a class with the name `the`, but `@return the` will be ignored with the below setting)
|
||||
//
|
||||
// (These are not aliases, this setting is ignored outside of doc comments).
|
||||
// (Phan does not check if classes with these names exist)
|
||||
//
|
||||
// Example setting: `['unknown' => '', 'number' => 'int|float', 'char' => 'string', 'long' => 'int', 'the' => '']`
|
||||
'phpdoc_type_mapping' => [],
|
||||
|
||||
// Set to true in order to attempt to detect dead
|
||||
// (unreferenced) code. Keep in mind that the
|
||||
// results will only be a guess given that classes,
|
||||
// properties, constants and methods can be referenced
|
||||
// as variables (like `$class->$property` or
|
||||
// `$class->$method()`) in ways that we're unable
|
||||
// to make sense of.
|
||||
'dead_code_detection' => false,
|
||||
|
||||
// Set to true in order to attempt to detect unused variables.
|
||||
// `dead_code_detection` will also enable unused variable detection.
|
||||
//
|
||||
// This has a few known false positives, e.g. for loops or branches.
|
||||
'unused_variable_detection' => false,
|
||||
|
||||
// Set to true in order to attempt to detect redundant and impossible conditions.
|
||||
//
|
||||
// This has some false positives involving loops,
|
||||
// variables set in branches of loops, and global variables.
|
||||
'redundant_condition_detection' => false,
|
||||
|
||||
// If enabled, Phan will act as though it's certain of real return types of a subset of internal functions,
|
||||
// even if those return types aren't available in reflection (real types were taken from php 7.3 or 8.0-dev, depending on target_php_version).
|
||||
//
|
||||
// Note that with php 7 and earlier, php would return null or false for many internal functions if the argument types or counts were incorrect.
|
||||
// As a result, enabling this setting with target_php_version 8.0 may result in false positives for `--redundant-condition-detection` when codebases also support php 7.x.
|
||||
'assume_real_types_for_internal_functions' => false,
|
||||
|
||||
// If true, this runs a quick version of checks that takes less
|
||||
// time at the cost of not running as thorough
|
||||
// of an analysis. You should consider setting this
|
||||
// to true only when you wish you had more **undiagnosed** issues
|
||||
// to fix in your code base.
|
||||
//
|
||||
// In quick-mode the scanner doesn't rescan a function
|
||||
// or a method's code block every time a call is seen.
|
||||
// This means that the problem here won't be detected:
|
||||
//
|
||||
// ```php
|
||||
// <?php
|
||||
// function test($arg):int {
|
||||
// return $arg;
|
||||
// }
|
||||
// test("abc");
|
||||
// ```
|
||||
//
|
||||
// This would normally generate:
|
||||
//
|
||||
// ```
|
||||
// test.php:3 PhanTypeMismatchReturn Returning type string but test() is declared to return int
|
||||
// ```
|
||||
//
|
||||
// The initial scan of the function's code block has no
|
||||
// type information for `$arg`. It isn't until we see
|
||||
// the call and rescan `test()`'s code block that we can
|
||||
// detect that it is actually returning the passed in
|
||||
// `string` instead of an `int` as declared.
|
||||
'quick_mode' => false,
|
||||
|
||||
// Override to hardcode existence and types of (non-builtin) globals in the global scope.
|
||||
// Class names should be prefixed with `\`.
|
||||
//
|
||||
// (E.g. `['_FOO' => '\FooClass', 'page' => '\PageClass', 'userId' => 'int']`)
|
||||
'globals_type_map' => [],
|
||||
|
||||
// The minimum severity level to report on. This can be
|
||||
// set to `Issue::SEVERITY_LOW`, `Issue::SEVERITY_NORMAL` or
|
||||
// `Issue::SEVERITY_CRITICAL`. Setting it to only
|
||||
// critical issues is a good place to start on a big
|
||||
// sloppy mature code base.
|
||||
'minimum_severity' => Issue::SEVERITY_LOW,
|
||||
|
||||
// Add any issue types (such as `'PhanUndeclaredMethod'`)
|
||||
// to this black-list to inhibit them from being reported.
|
||||
'suppress_issue_types' => [],
|
||||
|
||||
// A regular expression to match files to be excluded
|
||||
// from parsing and analysis and will not be read at all.
|
||||
//
|
||||
// This is useful for excluding groups of test or example
|
||||
// directories/files, unanalyzable files, or files that
|
||||
// can't be removed for whatever reason.
|
||||
// (e.g. `'@Test\.php$@'`, or `'@vendor/.*/(tests|Tests)/@'`)
|
||||
'exclude_file_regex' => '@^vendor/.*/(tests?|Tests?)/@',
|
||||
|
||||
// A list of files that will be excluded from parsing and analysis
|
||||
// and will not be read at all.
|
||||
//
|
||||
// This is useful for excluding hopelessly unanalyzable
|
||||
// files that can't be removed for whatever reason.
|
||||
'exclude_file_list' => [],
|
||||
|
||||
// A directory list that defines files that will be excluded
|
||||
// from static analysis, but whose class and method
|
||||
// information should be included.
|
||||
//
|
||||
// Generally, you'll want to include the directories for
|
||||
// third-party code (such as "vendor/") in this list.
|
||||
//
|
||||
// n.b.: If you'd like to parse but not analyze 3rd
|
||||
// party code, directories containing that code
|
||||
// should be added to the `directory_list` as well as
|
||||
// to `exclude_analysis_directory_list`.
|
||||
'exclude_analysis_directory_list' => [
|
||||
'vendor/',
|
||||
],
|
||||
|
||||
// Enable this to enable checks of require/include statements referring to valid paths.
|
||||
// The settings `include_paths` and `warn_about_relative_include_statement` affect the checks.
|
||||
'enable_include_path_checks' => true,
|
||||
|
||||
// The number of processes to fork off during the analysis
|
||||
// phase.
|
||||
'processes' => 1,
|
||||
|
||||
// List of case-insensitive file extensions supported by Phan.
|
||||
// (e.g. `['php', 'html', 'htm']`)
|
||||
'analyzed_file_extensions' => [
|
||||
'php',
|
||||
],
|
||||
|
||||
// You can put paths to stubs of internal extensions in this config option.
|
||||
// If the corresponding extension is **not** loaded, then Phan will use the stubs instead.
|
||||
// Phan will continue using its detailed type annotations,
|
||||
// but load the constants, classes, functions, and classes (and their Reflection types)
|
||||
// from these stub files (doubling as valid php files).
|
||||
// Use a different extension from php to avoid accidentally loading these.
|
||||
// The `tools/make_stubs` script can be used to generate your own stubs (compatible with php 7.0+ right now)
|
||||
//
|
||||
// (e.g. `['xdebug' => '.phan/internal_stubs/xdebug.phan_php']`)
|
||||
'autoload_internal_extension_signatures' => [],
|
||||
|
||||
// A list of plugin files to execute.
|
||||
//
|
||||
// Plugins which are bundled with Phan can be added here by providing their name (e.g. `'AlwaysReturnPlugin'`)
|
||||
//
|
||||
// Documentation about available bundled plugins can be found [here](https://github.com/phan/phan/tree/master/.phan/plugins).
|
||||
//
|
||||
// Alternately, you can pass in the full path to a PHP file with the plugin's implementation (e.g. `'vendor/phan/phan/.phan/plugins/AlwaysReturnPlugin.php'`)
|
||||
'plugins' => [
|
||||
'AlwaysReturnPlugin',
|
||||
'PregRegexCheckerPlugin',
|
||||
'UnreachableCodePlugin',
|
||||
],
|
||||
|
||||
// A list of directories that should be parsed for class and
|
||||
// method information. After excluding the directories
|
||||
// defined in `exclude_analysis_directory_list`, the remaining
|
||||
// files will be statically analyzed for errors.
|
||||
//
|
||||
// Thus, both first-party and third-party code being used by
|
||||
// your application should be included in this list.
|
||||
'directory_list' => [
|
||||
'src/danog/MadelineProto',
|
||||
'vendor/amphp/amp/lib',
|
||||
'vendor/amphp/byte-stream/lib',
|
||||
'vendor/amphp/dns/lib',
|
||||
'vendor/amphp/file/src',
|
||||
'vendor/amphp/http-client-cookies/src',
|
||||
'vendor/amphp/http-client/src',
|
||||
'vendor/amphp/http-server/src',
|
||||
'vendor/amphp/http/src',
|
||||
'vendor/amphp/php-cs-fixer-config/src',
|
||||
'vendor/amphp/socket/src',
|
||||
'vendor/amphp/websocket-client/src',
|
||||
'vendor/amphp/websocket/src',
|
||||
'vendor/danog/7to5/src',
|
||||
'vendor/danog/7to70/src',
|
||||
'vendor/danog/dns-over-https/lib',
|
||||
'vendor/danog/ipc/lib',
|
||||
'vendor/danog/magicalserializer/src',
|
||||
'vendor/danog/primemodule/lib',
|
||||
'vendor/danog/tg-file-decoder/src',
|
||||
'vendor/danog/tgseclib/phpseclib',
|
||||
'vendor/erusev/parsedown',
|
||||
'vendor/league/uri/src'
|
||||
],
|
||||
|
||||
// A list of individual files to include in analysis
|
||||
// with a path relative to the root directory of the
|
||||
// project.
|
||||
'file_list' => [],
|
||||
];
|
@ -33,7 +33,8 @@
|
||||
"danog/magicalserializer": "^1.0",
|
||||
"league/uri": "^6",
|
||||
"danog/ipc": "^0.1",
|
||||
"tivie/htaccess-parser": "^0.2.3"
|
||||
"tivie/htaccess-parser": "^0.2.3",
|
||||
"amphp/log": "^1.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"vlucas/phpdotenv": "^3",
|
||||
|
@ -102,7 +102,7 @@ $settings = [
|
||||
],
|
||||
'serialization' => [
|
||||
'serialization_interval' => 30,
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
$MadelineProto = new API('bot.madeline', $settings);
|
||||
|
102
legacy/danog/MadelineProto/Server.php
Normal file
102
legacy/danog/MadelineProto/Server.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Server module.
|
||||
*
|
||||
* This file is part of MadelineProto.
|
||||
* MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Affero General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License along with MadelineProto.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @copyright 2016-2020 Daniil Gentili <daniil@daniil.it>
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
|
||||
*
|
||||
* @link https://docs.madelineproto.xyz MadelineProto documentation
|
||||
*/
|
||||
|
||||
namespace danog\MadelineProto;
|
||||
|
||||
/*
|
||||
* Socket server for multi-language API
|
||||
*/
|
||||
class Server
|
||||
{
|
||||
private $settings;
|
||||
private $pids = [];
|
||||
private $mypid;
|
||||
public function __construct($settings)
|
||||
{
|
||||
\set_error_handler(['\\danog\\MadelineProto\\Exception', 'ExceptionErrorHandler']);
|
||||
\danog\MadelineProto\Logger::constructor(3);
|
||||
if (!\extension_loaded('sockets')) {
|
||||
throw new Exception(['extension', 'sockets']);
|
||||
}
|
||||
if (!\extension_loaded('pcntl')) {
|
||||
throw new Exception(['extension', 'pcntl']);
|
||||
}
|
||||
$this->settings = $settings;
|
||||
$this->mypid = \getmypid();
|
||||
}
|
||||
public function start()
|
||||
{
|
||||
\pcntl_signal(SIGTERM, [$this, 'sigHandler']);
|
||||
\pcntl_signal(SIGINT, [$this, 'sigHandler']);
|
||||
\pcntl_signal(SIGCHLD, [$this, 'sigHandler']);
|
||||
$this->sock = new \Socket($this->settings['type'], SOCK_STREAM, $this->settings['protocol']);
|
||||
$this->sock->bind($this->settings['address'], $this->settings['port']);
|
||||
$this->sock->listen();
|
||||
$this->sock->setBlocking(true);
|
||||
$timeout = 2;
|
||||
$this->sock->setOption(\SOL_SOCKET, \SO_RCVTIMEO, $timeout);
|
||||
$this->sock->setOption(\SOL_SOCKET, \SO_SNDTIMEO, $timeout);
|
||||
\danog\MadelineProto\Logger::log('Server started! Listening on ' . $this->settings['address'] . ':' . $this->settings['port']);
|
||||
while (true) {
|
||||
\pcntl_signal_dispatch();
|
||||
try {
|
||||
if ($sock = $this->sock->accept()) {
|
||||
$this->handle($sock);
|
||||
}
|
||||
} catch (\danog\MadelineProto\Exception $e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
private function handle($socket)
|
||||
{
|
||||
$pid = \pcntl_fork();
|
||||
if ($pid == -1) {
|
||||
die('could not fork');
|
||||
} elseif ($pid) {
|
||||
return $this->pids[] = $pid;
|
||||
}
|
||||
$handler = new $this->settings['handler']($socket, $this->settings['extra'], null, null, null, null, null);
|
||||
$handler->loop();
|
||||
die;
|
||||
}
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->mypid === \getmypid()) {
|
||||
\danog\MadelineProto\Logger::log('Shutting main process ' . $this->mypid . ' down');
|
||||
unset($this->sock);
|
||||
foreach ($this->pids as $pid) {
|
||||
\danog\MadelineProto\Logger::log("Waiting for {$pid}");
|
||||
\pcntl_wait($pid);
|
||||
}
|
||||
\danog\MadelineProto\Logger::log('Done, closing main process');
|
||||
return;
|
||||
}
|
||||
}
|
||||
public function sigHandler($sig)
|
||||
{
|
||||
switch ($sig) {
|
||||
case SIGTERM:
|
||||
case SIGINT:
|
||||
exit;
|
||||
case SIGCHLD:
|
||||
\pcntl_waitpid(-1, $status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
18
psalm.xml
Normal file
18
psalm.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0"?>
|
||||
<psalm
|
||||
totallyTyped="false"
|
||||
errorLevel="6"
|
||||
resolveFromConfigFile="true"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="https://getpsalm.org/schema/config"
|
||||
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
||||
>
|
||||
<projectFiles>
|
||||
<directory name="src" />
|
||||
<ignoreFiles>
|
||||
<directory name="vendor" />
|
||||
<file name="src/danog/MadelineProto/InternalDoc.php" />
|
||||
<file name="src/danog/MadelineProto/TON/InternalDoc.php" />
|
||||
</ignoreFiles>
|
||||
</projectFiles>
|
||||
</psalm>
|
@ -271,7 +271,7 @@ class API extends InternalDoc
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
private function startAndLoopAsync(string $eventHandler): \Generator
|
||||
public function startAndLoopAsync(string $eventHandler): \Generator
|
||||
{
|
||||
$this->async(true);
|
||||
while (true) {
|
||||
|
@ -39,6 +39,7 @@ use Amp\Websocket\Client\Rfc6455Connector;
|
||||
use danog\MadelineProto\MTProto\PermAuthKey;
|
||||
use danog\MadelineProto\MTProto\TempAuthKey;
|
||||
use danog\MadelineProto\Stream\Common\BufferedRawStream;
|
||||
use danog\MadelineProto\Stream\Common\UdpBufferedStream;
|
||||
use danog\MadelineProto\Stream\ConnectionContext;
|
||||
use danog\MadelineProto\Stream\MTProtoTransport\AbridgedStream;
|
||||
use danog\MadelineProto\Stream\MTProtoTransport\FullStream;
|
||||
@ -212,7 +213,7 @@ class DataCenter
|
||||
$this->settings = $settings;
|
||||
foreach ($this->sockets as $key => $socket) {
|
||||
if ($socket instanceof DataCenterConnection && !\strpos($key, '_bk')) {
|
||||
//$this->API->logger->logger(\sprintf(Lang::$current_lang['dc_con_stop'], $key), \danog\MadelineProto\Logger::VERBOSE);
|
||||
//$this->API->logger->logger(\sprintf(Lang::$current_lang['dc_con_stop'], $key), Logger::VERBOSE);
|
||||
if ($reconnectAll || isset($changed[$id])) {
|
||||
$this->API->logger->logger("Disconnecting all before reconnect!");
|
||||
$socket->needReconnect(true);
|
||||
@ -238,6 +239,24 @@ class DataCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Set VoIP endpoints.
|
||||
*
|
||||
* @param array $endpoints Endpoints
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setVoIPEndpoints(array $endpoints): void
|
||||
{
|
||||
}
|
||||
/**
|
||||
* Connect to specified DC.
|
||||
*
|
||||
* @param string $dc_number DC to connect to
|
||||
* @param integer $id Connection ID to re-establish (optional)
|
||||
*
|
||||
* @return \Generator<bool>
|
||||
*/
|
||||
public function dcConnect(string $dc_number, int $id = -1): \Generator
|
||||
{
|
||||
$old = isset($this->sockets[$dc_number]) && ($this->sockets[$dc_number]->shouldReconnect() || $id !== -1 && $this->sockets[$dc_number]->hasConnection($id) && $this->sockets[$dc_number]->getConnection($id)->shouldReconnect());
|
||||
@ -252,30 +271,36 @@ class DataCenter
|
||||
foreach ($ctxs as $ctx) {
|
||||
try {
|
||||
if ($old) {
|
||||
$this->API->logger->logger("Reconnecting to DC {$dc_number} ({$id}) from existing", \danog\MadelineProto\Logger::WARNING);
|
||||
$this->API->logger->logger("Reconnecting to DC {$dc_number} ({$id}) from existing", Logger::WARNING);
|
||||
$this->sockets[$dc_number]->setExtra($this->API);
|
||||
yield from $this->sockets[$dc_number]->connect($ctx, $id);
|
||||
} else {
|
||||
$this->API->logger->logger("Connecting to DC {$dc_number} from scratch", \danog\MadelineProto\Logger::WARNING);
|
||||
$this->API->logger->logger("Connecting to DC {$dc_number} from scratch", Logger::WARNING);
|
||||
$this->sockets[$dc_number] = new DataCenterConnection();
|
||||
$this->sockets[$dc_number]->setExtra($this->API);
|
||||
yield from $this->sockets[$dc_number]->connect($ctx);
|
||||
}
|
||||
$this->API->logger->logger('OK!', \danog\MadelineProto\Logger::WARNING);
|
||||
$this->API->logger->logger('OK!', Logger::WARNING);
|
||||
return true;
|
||||
} catch (\Throwable $e) {
|
||||
if (@\constant("MADELINEPROTO_TEST") === 'pony') {
|
||||
throw $e;
|
||||
}
|
||||
$this->API->logger->logger("Connection failed ({$dc_number}): ".$e->getMessage(), \danog\MadelineProto\Logger::ERROR);
|
||||
$this->API->logger->logger("Connection failed ({$dc_number}): ".$e->getMessage(), Logger::ERROR);
|
||||
}
|
||||
}
|
||||
throw new Exception("Could not connect to DC {$dc_number}");
|
||||
}
|
||||
/**
|
||||
* @param int|string $dc_number
|
||||
* Generate contexts.
|
||||
*
|
||||
* @param integer $dc_number DC ID to generate contexts for
|
||||
* @param string $uri URI
|
||||
* @param ConnectContext $context Connection context
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function generateContexts($dc_number = 0, string $uri = '', ConnectContext $context = null)
|
||||
public function generateContexts($dc_number = 0, string $uri = '', ConnectContext $context = null): array
|
||||
{
|
||||
$ctxs = [];
|
||||
$combos = [];
|
||||
@ -309,6 +334,9 @@ class DataCenter
|
||||
case 'https':
|
||||
$default = [[DefaultStream::getName(), []], [BufferedRawStream::getName(), []], [HttpsStream::getName(), []]];
|
||||
break;
|
||||
case 'udp':
|
||||
$default = [[DefaultStream::getName(), []], [UdpBufferedStream::getName(), []]];
|
||||
break;
|
||||
default:
|
||||
throw new Exception(Lang::$current_lang['protocol_invalid']);
|
||||
}
|
||||
@ -490,7 +518,7 @@ class DataCenter
|
||||
}
|
||||
if (empty($ctxs)) {
|
||||
unset($this->sockets[$dc_number]);
|
||||
$this->API->logger->logger("No info for DC {$dc_number}", \danog\MadelineProto\Logger::ERROR);
|
||||
$this->API->logger->logger("No info for DC {$dc_number}", Logger::ERROR);
|
||||
} elseif (@\constant("MADELINEPROTO_TEST") === 'pony') {
|
||||
return [$ctxs[0]];
|
||||
}
|
||||
|
@ -621,7 +621,7 @@ class Lang
|
||||
{
|
||||
if (!isset(\danog\MadelineProto\Lang::$lang['en'][$key]) || $force) {
|
||||
\danog\MadelineProto\Lang::$lang['en'][$key] = $value;
|
||||
\file_put_contents(__DIR__.'/Lang.php', \sprintf(self::$template, \var_export(\danog\MadelineProto\Lang::$lang, true), \var_export(\danog\MadelineProto\Lang::$lang['en'], true)));
|
||||
//\file_put_contents(__DIR__.'/Lang.php', \sprintf(self::$template, \var_export(\danog\MadelineProto\Lang::$lang, true), \var_export(\danog\MadelineProto\Lang::$lang['en'], true)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -87,7 +87,7 @@ class ReadLoop extends SignalLoop
|
||||
Tools::callForkDefer((function () use ($error, $shared, $connection, $datacenter, $API): \Generator {
|
||||
if ($error === -404) {
|
||||
if ($shared->hasTempAuthKey()) {
|
||||
$API->logger->logger("WARNING: Resetting auth key in DC {$datacenter}...", \danog\MadelineProto\Logger::WARNING);
|
||||
$API->logger->logger("WARNING: Resetting auth key in DC {$datacenter}...", Logger::WARNING);
|
||||
$shared->setTempAuthKey(null);
|
||||
$shared->resetSession();
|
||||
foreach ($connection->new_outgoing as $message_id) {
|
||||
@ -99,13 +99,13 @@ class ReadLoop extends SignalLoop
|
||||
yield from $connection->reconnect();
|
||||
}
|
||||
} elseif ($error === -1) {
|
||||
$API->logger->logger("WARNING: Got quick ack from DC {$datacenter}", \danog\MadelineProto\Logger::WARNING);
|
||||
$API->logger->logger("WARNING: Got quick ack from DC {$datacenter}", Logger::WARNING);
|
||||
yield from $connection->reconnect();
|
||||
} elseif ($error === 0) {
|
||||
$API->logger->logger("Got NOOP from DC {$datacenter}", \danog\MadelineProto\Logger::WARNING);
|
||||
$API->logger->logger("Got NOOP from DC {$datacenter}", Logger::WARNING);
|
||||
yield from $connection->reconnect();
|
||||
} elseif ($error === -429) {
|
||||
$API->logger->logger("Got -429 from DC {$datacenter}", \danog\MadelineProto\Logger::WARNING);
|
||||
$API->logger->logger("Got -429 from DC {$datacenter}", Logger::WARNING);
|
||||
yield Tools::sleep(1);
|
||||
yield from $connection->reconnect();
|
||||
} else {
|
||||
@ -138,14 +138,14 @@ class ReadLoop extends SignalLoop
|
||||
$API->logger->logger($e->getReason());
|
||||
if (\strpos($e->getReason(), ' ') === 0) {
|
||||
$payload = -\substr($e->getReason(), 7);
|
||||
$API->logger->logger("Received {$payload} from DC ".$datacenter, \danog\MadelineProto\Logger::ERROR);
|
||||
$API->logger->logger("Received {$payload} from DC ".$datacenter, Logger::ERROR);
|
||||
return $payload;
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
if ($payload_length === 4) {
|
||||
$payload = \danog\MadelineProto\Tools::unpackSignedInt(yield $buffer->bufferRead(4));
|
||||
$API->logger->logger("Received {$payload} from DC ".$datacenter, \danog\MadelineProto\Logger::ULTRA_VERBOSE);
|
||||
$API->logger->logger("Received {$payload} from DC ".$datacenter, Logger::ULTRA_VERBOSE);
|
||||
return $payload;
|
||||
}
|
||||
$connection->reading(true);
|
||||
@ -160,9 +160,9 @@ class ReadLoop extends SignalLoop
|
||||
$message_data = yield $buffer->bufferRead($message_length);
|
||||
$left = $payload_length - $message_length - 4 - 8 - 8;
|
||||
if ($left) {
|
||||
$API->logger->logger('Padded unencrypted message', \danog\MadelineProto\Logger::ULTRA_VERBOSE);
|
||||
$API->logger->logger('Padded unencrypted message', Logger::ULTRA_VERBOSE);
|
||||
if ($left < (-$message_length & 15)) {
|
||||
$API->logger->logger('Protocol padded unencrypted message', \danog\MadelineProto\Logger::ULTRA_VERBOSE);
|
||||
$API->logger->logger('Protocol padded unencrypted message', Logger::ULTRA_VERBOSE);
|
||||
}
|
||||
yield $buffer->bufferRead($left);
|
||||
}
|
||||
@ -179,7 +179,7 @@ class ReadLoop extends SignalLoop
|
||||
/*
|
||||
$server_salt = substr($decrypted_data, 0, 8);
|
||||
if ($server_salt != $shared->getTempAuthKey()->getServerSalt()) {
|
||||
$API->logger->logger('WARNING: Server salt mismatch (my server salt '.$shared->getTempAuthKey()->getServerSalt().' is not equal to server server salt '.$server_salt.').', \danog\MadelineProto\Logger::WARNING);
|
||||
$API->logger->logger('WARNING: Server salt mismatch (my server salt '.$shared->getTempAuthKey()->getServerSalt().' is not equal to server server salt '.$server_salt.').', Logger::WARNING);
|
||||
}
|
||||
*/
|
||||
$session_id = \substr($decrypted_data, 8, 8);
|
||||
@ -213,16 +213,18 @@ class ReadLoop extends SignalLoop
|
||||
}
|
||||
$connection->incoming_messages[$message_id] = ['seq_no' => $seq_no];
|
||||
} else {
|
||||
$API->logger->logger('Got unknown auth_key id', \danog\MadelineProto\Logger::ERROR);
|
||||
$API->logger->logger('Got unknown auth_key id', Logger::ERROR);
|
||||
return -404;
|
||||
}
|
||||
$deserialized = $API->getTL()->deserialize($message_data, ['type' => '', 'connection' => $connection]);
|
||||
if (isset($API->referenceDatabase)) {
|
||||
$API->referenceDatabase->reset();
|
||||
}
|
||||
$connection->incoming_messages[$message_id]['content'] = $deserialized;
|
||||
$connection->incoming_messages[$message_id]['response'] = -1;
|
||||
$connection->new_incoming[$message_id] = $message_id;
|
||||
//$connection->last_http_wait = 0;
|
||||
$API->logger->logger('Received payload from DC '.$datacenter, \danog\MadelineProto\Logger::ULTRA_VERBOSE);
|
||||
$API->logger->logger('Received payload from DC '.$datacenter, Logger::ULTRA_VERBOSE);
|
||||
} finally {
|
||||
$connection->reading(false);
|
||||
}
|
||||
|
@ -349,7 +349,7 @@ trait ResponseHandler
|
||||
$this->methodRecall('', ['message_id' => $request_id, 'postpone' => true]);
|
||||
return;
|
||||
}
|
||||
if (\in_array($response['error_message'], ['MSGID_DECREASE_RETRY', 'HISTORY_GET_FAILED', 'RPC_CALL_FAIL', 'PERSISTENT_TIMESTAMP_OUTDATED', 'RPC_MCGET_FAIL', 'no workers running', 'No workers running'])) {
|
||||
if (\in_array($response['error_message'], ['MSGID_DECREASE_RETRY', 'HISTORY_GET_FAILED', 'RPC_CONNECT_FAILED', 'RPC_CALL_FAIL', 'PERSISTENT_TIMESTAMP_OUTDATED', 'RPC_MCGET_FAIL', 'no workers running', 'No workers running'])) {
|
||||
Loop::delay(1 * 1000, [$this, 'methodRecall'], ['message_id' => $request_id]);
|
||||
return;
|
||||
}
|
||||
|
@ -19,29 +19,11 @@
|
||||
|
||||
namespace danog\MadelineProto\Stream;
|
||||
|
||||
use Amp\Promise;
|
||||
|
||||
/**
|
||||
* Buffer interface.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
*/
|
||||
interface BufferInterface
|
||||
interface BufferInterface extends ReadBufferInterface, WriteBufferInterface
|
||||
{
|
||||
/**
|
||||
* Read data asynchronously.
|
||||
*
|
||||
* @param int $length How much data to read
|
||||
*
|
||||
* @return Promise
|
||||
*/
|
||||
public function bufferRead(int $length): Promise;
|
||||
/**
|
||||
* Write data asynchronously.
|
||||
*
|
||||
* @param string $data Data to write
|
||||
*
|
||||
* @return Promise
|
||||
*/
|
||||
public function bufferWrite(string $data): Promise;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ interface BufferedStreamInterface extends StreamInterface
|
||||
*
|
||||
* @param int $length Length of payload, as detected by this layer
|
||||
*
|
||||
* @return Promise
|
||||
* @return Promise<BufferInterface>
|
||||
*/
|
||||
public function getReadBuffer(&$length): Promise;
|
||||
/**
|
||||
|
@ -207,6 +207,21 @@ class BufferedRawStream implements BufferedStreamInterface, BufferInterface, Raw
|
||||
}
|
||||
return $this->write($data);
|
||||
}
|
||||
/**
|
||||
* Get remaining data from buffer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function bufferClear(): string
|
||||
{
|
||||
$size = \fstat($this->memory_stream)['size'];
|
||||
$offset = \ftell($this->memory_stream);
|
||||
$buffer_length = $size - $offset;
|
||||
$data = fread($this->memory_stream, $buffer_length);
|
||||
fclose($this->memory_stream);
|
||||
$this->memory_stream = null;
|
||||
return $data;
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
|
201
src/danog/MadelineProto/Stream/Common/UdpBufferedStream.php
Normal file
201
src/danog/MadelineProto/Stream/Common/UdpBufferedStream.php
Normal file
@ -0,0 +1,201 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* UDP stream wrapper.
|
||||
*
|
||||
* This file is part of MadelineProto.
|
||||
* MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Affero General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License along with MadelineProto.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @copyright 2016-2020 Daniil Gentili <daniil@daniil.it>
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
|
||||
*
|
||||
* @link https://docs.madelineproto.xyz MadelineProto documentation
|
||||
*/
|
||||
|
||||
namespace danog\MadelineProto\Stream\Common;
|
||||
|
||||
use Amp\ByteStream\ClosedException;
|
||||
use Amp\Failure;
|
||||
use Amp\Promise;
|
||||
use Amp\Socket\EncryptableSocket;
|
||||
use Amp\Success;
|
||||
use danog\MadelineProto\Exception;
|
||||
use danog\MadelineProto\Stream\Async\BufferedStream;
|
||||
use danog\MadelineProto\Stream\BufferedStreamInterface;
|
||||
use danog\MadelineProto\Stream\ConnectionContext;
|
||||
use danog\MadelineProto\Stream\RawStreamInterface;
|
||||
use danog\MadelineProto\Stream\ReadBufferInterface;
|
||||
use danog\MadelineProto\Stream\StreamInterface;
|
||||
use danog\MadelineProto\Stream\Transport\DefaultStream;
|
||||
use danog\MadelineProto\Stream\WriteBufferInterface;
|
||||
|
||||
/**
|
||||
* UDP stream wrapper.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
*/
|
||||
class UdpBufferedStream extends DefaultStream implements BufferedStreamInterface
|
||||
{
|
||||
use BufferedStream;
|
||||
private RawStreamInterface $stream;
|
||||
/**
|
||||
* Connect to stream.
|
||||
*
|
||||
* @param ConnectionContext $ctx The connection context
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function connect(ConnectionContext $ctx, string $header = ''): \Generator
|
||||
{
|
||||
$this->stream = (yield from $ctx->getStream($header));
|
||||
}
|
||||
/**
|
||||
* Async close.
|
||||
*
|
||||
* @return Promise
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
return $this->stream->disconnect();
|
||||
}
|
||||
/**
|
||||
* Get read buffer asynchronously.
|
||||
*
|
||||
* @param int $length Length of payload, as detected by this layer
|
||||
*
|
||||
* @return Promise
|
||||
*/
|
||||
public function getReadBuffer(&$length): Promise
|
||||
{
|
||||
if (!$this->stream) {
|
||||
return new Failure(new ClosedException("MadelineProto stream was disconnected"));
|
||||
}
|
||||
$chunk = yield $this->read();
|
||||
if ($chunk === null) {
|
||||
$this->disconnect();
|
||||
throw new \danog\MadelineProto\NothingInTheSocketException();
|
||||
}
|
||||
$length = \strlen($chunk);
|
||||
return new Success(new class($chunk) implements ReadBufferInterface {
|
||||
/**
|
||||
* Buffer.
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
private $buffer;
|
||||
/**
|
||||
* Constructor function.
|
||||
*
|
||||
* @param string $buf Buffer
|
||||
*/
|
||||
public function __construct(string $buf)
|
||||
{
|
||||
$this->buffer = \fopen('php://memory', 'r+');
|
||||
\fwrite($this->buffer, $buf);
|
||||
\fseek($this->buffer, 0);
|
||||
}
|
||||
/**
|
||||
* Read data from buffer.
|
||||
*
|
||||
* @param integer $length Length
|
||||
*
|
||||
* @return Promise<string>
|
||||
*/
|
||||
public function bufferRead(int $length): Promise
|
||||
{
|
||||
return new Success(\fread($this->buffer, $length));
|
||||
}
|
||||
/**
|
||||
* Destructor function.
|
||||
*/
|
||||
public function __destruct(): void
|
||||
{
|
||||
\fclose($this->buffer);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Get write buffer asynchronously.
|
||||
*
|
||||
* @param int $length Total length of data that is going to be piped in the buffer
|
||||
*
|
||||
* @return Promise
|
||||
*/
|
||||
public function getWriteBuffer(int $length, string $append = ''): Promise
|
||||
{
|
||||
return new Success(new class($length, $append, $this) implements WriteBufferInterface {
|
||||
private int $length;
|
||||
private string $append;
|
||||
private int $append_after;
|
||||
private RawStreamInterface $stream;
|
||||
private string $data = '';
|
||||
/**
|
||||
* Constructor function
|
||||
*
|
||||
* @param integer $length
|
||||
* @param string $append
|
||||
* @param RawStreamInterface $rawStreamInterface
|
||||
*/
|
||||
public function __construct(int $length, string $append, RawStreamInterface $rawStreamInterface)
|
||||
{
|
||||
$this->stream = $rawStreamInterface;
|
||||
$this->length = $length;
|
||||
if (\strlen($append)) {
|
||||
$this->append = $append;
|
||||
$this->append_after = $length - \strlen($append);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Async write.
|
||||
*
|
||||
* @param string $data Data to write
|
||||
*
|
||||
* @return Promise
|
||||
*/
|
||||
public function bufferWrite(string $data): Promise
|
||||
{
|
||||
$this->data .= $data;
|
||||
if ($this->append_after) {
|
||||
$this->append_after -= \strlen($data);
|
||||
if ($this->append_after === 0) {
|
||||
$this->data .= $this->append;
|
||||
$this->append = '';
|
||||
return $this->stream->write($this->data);
|
||||
} elseif ($this->append_after < 0) {
|
||||
$this->append_after = 0;
|
||||
$this->append = '';
|
||||
throw new Exception('Tried to send too much out of frame data, cannot append');
|
||||
}
|
||||
}
|
||||
return new Success(strlen($data));
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return EncryptableSocket
|
||||
*/
|
||||
public function getSocket(): EncryptableSocket
|
||||
{
|
||||
return $this->stream->getSocket();
|
||||
}
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @return RawStreamInterface
|
||||
*/
|
||||
public function getStream(): RawStreamInterface
|
||||
{
|
||||
return $this->stream;
|
||||
}
|
||||
public static function getName(): string
|
||||
{
|
||||
return __CLASS__;
|
||||
}
|
||||
}
|
@ -411,9 +411,7 @@ class ConnectionContext
|
||||
/**
|
||||
* Get a stream from the stream chain.
|
||||
*
|
||||
* @internal Generator func
|
||||
*
|
||||
* @return \Generator
|
||||
* @return \Generator<StreamInterface>
|
||||
*/
|
||||
public function getStream(string $buffer = ''): \Generator
|
||||
{
|
||||
|
39
src/danog/MadelineProto/Stream/ReadBufferInterface.php
Normal file
39
src/danog/MadelineProto/Stream/ReadBufferInterface.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Buffer interface.
|
||||
*
|
||||
* This file is part of MadelineProto.
|
||||
* MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Affero General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License along with MadelineProto.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @copyright 2016-2020 Daniil Gentili <daniil@daniil.it>
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
|
||||
*
|
||||
* @link https://docs.madelineproto.xyz MadelineProto documentation
|
||||
*/
|
||||
|
||||
namespace danog\MadelineProto\Stream;
|
||||
|
||||
use Amp\Promise;
|
||||
|
||||
/**
|
||||
* Read buffer interface.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
*/
|
||||
interface ReadBufferInterface
|
||||
{
|
||||
/**
|
||||
* Read data asynchronously.
|
||||
*
|
||||
* @param int $length How much data to read
|
||||
*
|
||||
* @return Promise
|
||||
*/
|
||||
public function bufferRead(int $length): Promise;
|
||||
}
|
@ -46,7 +46,7 @@ class DefaultStream implements RawStreamInterface, ProxyStreamInterface
|
||||
*
|
||||
* @var EncryptableSocket
|
||||
*/
|
||||
private $stream;
|
||||
protected $stream;
|
||||
/**
|
||||
* Connector.
|
||||
*
|
||||
|
39
src/danog/MadelineProto/Stream/WriteBufferInterface.php
Normal file
39
src/danog/MadelineProto/Stream/WriteBufferInterface.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Buffer interface.
|
||||
*
|
||||
* This file is part of MadelineProto.
|
||||
* MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Affero General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License along with MadelineProto.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @copyright 2016-2020 Daniil Gentili <daniil@daniil.it>
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
|
||||
*
|
||||
* @link https://docs.madelineproto.xyz MadelineProto documentation
|
||||
*/
|
||||
|
||||
namespace danog\MadelineProto\Stream;
|
||||
|
||||
use Amp\Promise;
|
||||
|
||||
/**
|
||||
* Write buffer interface.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
*/
|
||||
interface WriteBufferInterface
|
||||
{
|
||||
/**
|
||||
* Write data asynchronously.
|
||||
*
|
||||
* @param string $data Data to write
|
||||
*
|
||||
* @return Promise
|
||||
*/
|
||||
public function bufferWrite(string $data): Promise;
|
||||
}
|
Loading…
Reference in New Issue
Block a user