1
0
mirror of https://github.com/danog/MadelineProto.git synced 2025-01-22 05:12:01 +01:00

Fixed bugs, updated docs, fixed serialization and deserialization of class, improved TL class

This commit is contained in:
Daniil Gentili 2016-11-25 20:52:56 +00:00
parent 1dca7843a9
commit c6f1642264
9 changed files with 108 additions and 143 deletions

2
.gitignore vendored
View File

@ -66,3 +66,5 @@ vendor
number.php number.php
token.php token.php
*~uploading* *~uploading*
session.mad
*.madeline

124
README.md
View File

@ -17,7 +17,7 @@ This project is in beta state.
This project depends on [PHPStruct](https://github.com/danog/PHPStruct), [phpseclib](https://github.com/phpseclib/phpseclib), https://packagist.org/packages/paragonie/constant_time_encoding and https://packagist.org/packages/paragonie/random_compat This project depends on [PHPStruct](https://github.com/danog/PHPStruct), [phpseclib](https://github.com/phpseclib/phpseclib), https://packagist.org/packages/paragonie/constant_time_encoding and https://packagist.org/packages/paragonie/random_compat
To install them all simply run: To install dependencies install composer and run:
``` ```
composer update composer update
``` ```
@ -27,13 +27,13 @@ In the cloned repo.
### Instantiation ### Instantiation
``` ```
$madeline = new \danog\MadelineProto\API(); $MadelineProto = new \danog\MadelineProto\API();
``` ```
### Settings ### Settings
The constructor accepts an optional parameter, which is the settings array. The constructor accepts an optional parameter, which is the settings array. This array contains some other arrays, which are the settings for a specific MadelineProto function.
Here you can see its default value and explanations for every setting: Here you can see the default values for the settings\ arrays and explanations for every setting:
``` ```
$settings = [ $settings = [
'authorization' => [ // Authorization settings 'authorization' => [ // Authorization settings
@ -86,60 +86,53 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
2 => [ // The rest will be fetched using help.getConfig 2 => [ // The rest will be fetched using help.getConfig
'ip_address' => '2001:067c:04e8:f002:0000:0000:0000:000a', 'ip_address' => '2001:067c:04e8:f002:0000:0000:0000:000a',
'port' => 443, 'port' => 443,
'media_only' => false, 'media_only' => false,
'tcpo_only' => false 'tcpo_only' => false
] ]
] ]
], ],
], ],
'connection_settings' => [ // connection settings 'connection_settings' => [ // connection settings
'all' => [ // Connection settings will be applied on datacenter ids matching the key of these settings subarrays, if the key is equal to all like in this case that will match all datacenters that haven't a custom settings subarray... 'all' => [ // Connection settings will be applied on datacenter ids matching the key of these settings subarrays, if the key is equal to all like in this case that will match all datacenters that haven't a custom settings subarray...
'protocol' => 'tcp_full', // can be tcp_full, tcp_abridged, tcp_intermediate, http (unsupported), https (unsupported), udp (unsupported) 'protocol' => 'tcp_full', // can be tcp_full, tcp_abridged, tcp_intermediate, http (unsupported), https (unsupported), udp (unsupported)
'test_mode' => false, // decides whether to connect to the main telegram servers or to the testing servers (deep telegram) 'test_mode' => false, // decides whether to connect to the main telegram servers or to the testing servers (deep telegram)
'ipv6' => $this->ipv6, // decides whether to use ipv6, ipv6 attribute of API attribute of API class contains autodetected boolean 'ipv6' => $this->ipv6, // decides whether to use ipv6, ipv6 attribute of API attribute of API class contains autodetected boolean
'timeout' => 10 // timeout for sockets 'timeout' => 10 // timeout for sockets
], ],
], ],
'app_info' => [ // obtained in https://my.telegram.org 'app_info' => [ // obtained in https://my.telegram.org
'api_id' => 25628, 'api_id' => 25628,
'api_hash' => '1fe17cda7d355166cdaa71f04122873c', 'api_hash' => '1fe17cda7d355166cdaa71f04122873c',
'device_model' => php_uname('s'), 'device_model' => php_uname('s'),
'system_version' => php_uname('r'), 'system_version' => php_uname('r'),
'app_version' => 'Unicorn', // 🌚 'app_version' => 'Unicorn', // 🌚
'lang_code' => 'en', 'lang_code' => 'en',
], ],
'tl_schema' => [ // TL scheme files 'tl_schema' => [ // TL scheme files
'layer' => 57, // layer version 'layer' => 57, // layer version
'src' => [ 'src' => [
'mtproto' => __DIR__.'/TL_mtproto_v1.json', // mtproto TL scheme 'mtproto' => __DIR__.'/TL_mtproto_v1.json', // mtproto TL scheme
'telegram' => __DIR__.'/TL_telegram_v57.json', // telegram TL scheme 'telegram' => __DIR__.'/TL_telegram_v57.json', // telegram TL scheme
], ],
], ],
'logger' => [ // Logger settings 'logger' => [ // Logger settings
/* 'logger' => 1, // 0 - No logger, 1 - Log to the default logger destination, 2 - Log to file defined in logger_param, 3 - Echo logs
* logger modes: 'logger_param' => '/tmp/MadelineProto.log',
* 0 - No logger 'logger' => 3, // overwrite previous setting and echo logs
* 1 - Log to the default logger destination ],
* 2 - Log to file defined in second parameter 'max_tries' => [
* 3 - Echo logs 'query' => 5, // How many times should I try to call a method or send an object before throwing an exception
*/ 'authorization' => 5, // How many times should I try to generate an authorization key before throwing an exception
'logger' => 1, // write to 'response' => 5,// How many times should I try to get a response of a query before throwing an exception
'logger_param' => '/tmp/MadelineProto.log', ],
'logger' => 3, // overwrite previous setting and echo logs 'msg_array_limit' => [ // How big should be the arrays containing the incoming and outgoing messages?
], 'incoming' => 30,
'max_tries' => [ 'outgoing' => 30,
'query' => 5, // How many times should I try to call a method or send an object before throwing an exception ],
'authorization' => 5, // How many times should I try to generate an authorization key before throwing an exception ];
'response' => 5,// How many times should I try to get a response of a query before throwing an exception
],
'msg_array_limit' => [ // How big should be the arrays containing the incoming and outgoing messages?
'incoming' => 30,
'outgoing' => 30,
],
];
``` ```
You can provide only part of any of the subsettings array, the rest will be automagically set to the default values of the specified subsettings array. You can provide part of any subsetting array, that way the remaining arrays will be automagically set to default and undefined values of specified subsetting arrays will be set to the default values.
Example: Example:
``` ```
$settings = [ $settings = [
@ -162,17 +155,16 @@ Efzk2DWgkBluml8OREmvfraX3bkHZJTKX4EQSjBbbdJ2ZXIsRrYOXfaA+xayEGB+
Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
-----END RSA PUBLIC KEY-----', -----END RSA PUBLIC KEY-----',
] ]
// The remaining subsetting arrays are the set to the default ones // The remaining subsetting arrays are the set to default
] ]
``` ```
The rest of the settings array and of the authorization array will be set to the default values specified in the default array. Note that only settings arrays or values of a settings array will be set to default.
Note that only subsetting arrays or values of a subsetting array will be set to default.
The settings array can be accessed in the instantiated class like this: The settings array can be accessed in the instantiated class like this:
``` ```
$MadelineProto = new \danog\MadelineProto\API(); $MadelineProto = new \danog\MadelineProto\API();
$generated_settings = $MadelineProto->API->settings; var_dump($MadelineProto->API->settings);
``` ```
### Calling mtproto methods and available wrappers ### Calling mtproto methods and available wrappers
@ -205,6 +197,10 @@ $authorization = $MadelineProto->bot_login($token); // Note that every time you
var_dump($authorization); var_dump($authorization);
``` ```
### Storing sessions
An istance of MadelineProto can be safely serialized or unserialized.
### Exceptions ### Exceptions
MadelineProto can throw three different exceptions: MadelineProto can throw three different exceptions:
@ -233,16 +229,16 @@ src/danog/MadelineProto/
TL/ TL/
Exception - Handles exceptions in the TL namespace Exception - Handles exceptions in the TL namespace
TL - Handles TL serialization and deserialization TL - Handles TL serialization and deserialization
TLConstructor - Represents a TL Constructor TLConstructor - Stores TL constructors
TLMethod - Represents a TL method TLMethod - Stores TL methods
API - Wrapper class that istantiates the MTProto class, sets the error handler, provides a wrapper for calling mtproto methods directly as class submethods, and provides some simplified wrappers for logging in to telegram API - Wrapper class that instantiates the MTProto class, sets the error handler, provides a wrapper for calling mtproto methods directly as class submethods, and provides some simplified wrappers for logging in to telegram
APIFactory - Provides a wrapper for calling namespaced mtproto methods directly as class submethods APIFactory - Provides a wrapper for calling namespaced mtproto methods directly as class submethods
Connection - Handles tcp/udp/http connections and wrapping payloads generated by MTProtoTools/MessageHandler into the right message according to the protocol, stores authorization keys, session id and sequence number Connection - Handles tcp/udp/http connections and wrapping payloads generated by MTProtoTools/MessageHandler into the right message according to the protocol, stores authorization keys, session id and sequence number
DataCenter - Handles mtproto datacenters (is a wrapper for Connection classes) DataCenter - Handles mtproto datacenters (is a wrapper for Connection classes)
DebugTools - Various debugging tools DebugTools - Various debugging tools
Exception - Handles exceptions and PHP errors Exception - Handles exceptions and PHP errors
RPCErrorException - Handles RPC errors RPCErrorException - Handles RPC errors
MTProto - Extends MTProtoTools, handles initial connection, generation of authorization keys, istantiation of classes, writing of client info MTProto - Extends MTProtoTools, handles initial connection, generation of authorization keys, instantiation of classes, writing of client info
MTProtoTools - Extends all of the classes in MTProtoTools/ MTProtoTools - Extends all of the classes in MTProtoTools/
Logger - Static logging class Logger - Static logging class
prime.py and getpq.py - prime module (python) for p and q generation prime.py and getpq.py - prime module (python) for p and q generation

View File

@ -23,6 +23,7 @@ class API extends APIFactory
set_error_handler(['\danog\MadelineProto\Exception', 'ExceptionErrorHandler']); set_error_handler(['\danog\MadelineProto\Exception', 'ExceptionErrorHandler']);
$this->API = new MTProto($params); $this->API = new MTProto($params);
\danog\MadelineProto\Logger::log('Running APIFactory...');
$this->APIFactory(); $this->APIFactory();
\danog\MadelineProto\Logger::log('Ping...'); \danog\MadelineProto\Logger::log('Ping...');
@ -38,26 +39,28 @@ class API extends APIFactory
public function APIFactory() public function APIFactory()
{ {
\danog\MadelineProto\Logger::log('Running APIFactory...'); foreach ($this->API->tl->methods->method_namespace as $namespace) {
foreach ($this->API->tl->methods->method_namespace as $namespace => $method) { $this->{$namespace} = new APIFactory($namespace, $this->API);
$this->{$method} = new APIFactory($method, $this->API);
} }
} }
public function logout() public function logout()
{ {
$this->API->datacenter->authorized = false; set_error_handler(['\danog\MadelineProto\Exception', 'ExceptionErrorHandler']);
$this->API->datacenter->authorization = null;
if (!$this->API->method_call('auth.logOut')) { if (!$this->API->method_call('auth.logOut')) {
throw new Exception('An error occurred while logging out!'); throw new Exception('An error occurred while logging out!');
} }
$this->API->datacenter->authorized = false;
$this->API->datacenter->authorization = null;
\danog\MadelineProto\Logger::log('Logged out successfully!'); \danog\MadelineProto\Logger::log('Logged out successfully!');
restore_error_handler();
return true; return true;
} }
public function bot_login($token) public function bot_login($token)
{ {
set_error_handler(['\danog\MadelineProto\Exception', 'ExceptionErrorHandler']);
if ($this->API->datacenter->authorized) { if ($this->API->datacenter->authorized) {
\danog\MadelineProto\Logger::log('This instance of MadelineProto is already logged in. Logging out first...'); \danog\MadelineProto\Logger::log('This instance of MadelineProto is already logged in. Logging out first...');
$this->logout(); $this->logout();
@ -73,12 +76,14 @@ class API extends APIFactory
); );
$this->API->datacenter->authorized = true; $this->API->datacenter->authorized = true;
\danog\MadelineProto\Logger::log('Logged in successfully!'); \danog\MadelineProto\Logger::log('Logged in successfully!');
restore_error_handler();
return $this->API->datacenter->authorization; return $this->API->datacenter->authorization;
} }
public function phone_login($number, $sms_type = 5) public function phone_login($number, $sms_type = 5)
{ {
set_error_handler(['\danog\MadelineProto\Exception', 'ExceptionErrorHandler']);
if ($this->API->datacenter->authorized) { if ($this->API->datacenter->authorized) {
\danog\MadelineProto\Logger::log('This instance of MadelineProto is already logged in. Logging out first...'); \danog\MadelineProto\Logger::log('This instance of MadelineProto is already logged in. Logging out first...');
$this->logout(); $this->logout();
@ -97,12 +102,14 @@ class API extends APIFactory
$this->API->datacenter->authorization['phone_number'] = $number; $this->API->datacenter->authorization['phone_number'] = $number;
$this->API->datacenter->waiting_code = true; $this->API->datacenter->waiting_code = true;
\danog\MadelineProto\Logger::log('Code sent successfully! Once you receive the code you should use the complete_phone_login function.'); \danog\MadelineProto\Logger::log('Code sent successfully! Once you receive the code you should use the complete_phone_login function.');
restore_error_handler();
return $this->API->datacenter->authorization; return $this->API->datacenter->authorization;
} }
public function complete_phone_login($code) public function complete_phone_login($code)
{ {
set_error_handler(['\danog\MadelineProto\Exception', 'ExceptionErrorHandler']);
if (!$this->API->datacenter->waiting_code) { if (!$this->API->datacenter->waiting_code) {
throw new Exception("I'm not waiting for the code! Please call the phone_login method first"); throw new Exception("I'm not waiting for the code! Please call the phone_login method first");
} }
@ -118,10 +125,15 @@ class API extends APIFactory
$this->API->datacenter->waiting_code = false; $this->API->datacenter->waiting_code = false;
$this->API->datacenter->authorized = true; $this->API->datacenter->authorized = true;
\danog\MadelineProto\Logger::log('Logged in successfully!'); \danog\MadelineProto\Logger::log('Logged in successfully!');
restore_error_handler();
return $this->API->datacenter->authorization; return $this->API->datacenter->authorization;
} }
public function __sleep()
{
return ["API"];
}
public function __wakeup() public function __wakeup()
{ {
$this->APIFactory(); $this->APIFactory();

View File

@ -114,7 +114,7 @@ class Connection extends Tools
public function __wakeup() public function __wakeup()
{ {
$this->close_and_reopen(); $this->__construct($this->ip, $this->port, $this->protocol, $this->timeout);
} }
/** /**

View File

@ -159,7 +159,8 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
$this->setup_logger(); $this->setup_logger();
// Connect to servers // Connect to servers
$this->mk_datacenter(); \danog\MadelineProto\Logger::log('Istantiating DataCenter...');
$this->datacenter = new DataCenter($this->settings['connection'], $this->settings['connection_settings']);
// Load rsa key // Load rsa key
\danog\MadelineProto\Logger::log('Loading RSA key...'); \danog\MadelineProto\Logger::log('Loading RSA key...');
@ -176,14 +177,7 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
public function __wakeup() public function __wakeup()
{ {
$this->setup_logger(); $this->setup_logger();
$this->mk_datacenter(); $this->datacenter->__construct($this->settings['connection'], $this->settings['connection_settings']);
}
public function mk_datacenter()
{
// Connect to servers
\danog\MadelineProto\Logger::log('Istantiating DataCenter...');
$this->datacenter = new DataCenter($this->settings['connection'], $this->settings['connection_settings']);
} }
public function setup_logger() public function setup_logger()
@ -278,5 +272,6 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
$test .= (isset($this->settings['connection'][$test][$ipv6][$id]) && $this->settings['connection'][$test][$ipv6][$id]['ip_address'] != $dc['ip_address']) ? '_bk' : ''; $test .= (isset($this->settings['connection'][$test][$ipv6][$id]) && $this->settings['connection'][$test][$ipv6][$id]['ip_address'] != $dc['ip_address']) ? '_bk' : '';
$this->settings['connection'][$test][$ipv6][$id] = $dc; $this->settings['connection'][$test][$ipv6][$id] = $dc;
} }
unset($this->config['dc_options']);
} }
} }

View File

@ -80,21 +80,20 @@ class TL extends \danog\MadelineProto\Tools
$flags = 0; $flags = 0;
foreach ($tl['params'] as $cur_flag) { foreach ($tl['params'] as $cur_flag) {
if ($cur_flag['flag']) { if ($cur_flag['flag']) {
$flag_pow = pow(2, $cur_flag['pow']);
switch ($cur_flag['type']) { switch ($cur_flag['type']) {
case 'true': case 'true':
case 'false': case 'false':
$flags = (isset($arguments[$cur_flag['name']]) && $arguments[$cur_flag['name']]) ? ($flags | $flag_pow) : ($flags & ~$flag_pow); $flags = (isset($arguments[$cur_flag['name']]) && $arguments[$cur_flag['name']]) ? ($flags | $cur_flag['pow']) : ($flags & ~$cur_flag['pow']);
unset($arguments[$cur_flag['name']]); unset($arguments[$cur_flag['name']]);
break; break;
case 'Bool': case 'Bool':
$arguments[$cur_flag['name']] = (isset($arguments[$cur_flag['name']]) && $arguments[$cur_flag['name']]) && (($flags & $flag_pow) != 0); $arguments[$cur_flag['name']] = (isset($arguments[$cur_flag['name']]) && $arguments[$cur_flag['name']]) && (($flags & $cur_flag['pow']) != 0);
if (($flags & $flag_pow) == 0) { if (($flags & $cur_flag['pow']) == 0) {
unset($arguments[$cur_flag['name']]); unset($arguments[$cur_flag['name']]);
} }
break; break;
default: default:
$flags = (isset($arguments[$cur_flag['name']]) && $arguments[$cur_flag['name']] !== null) ? ($flags | $flag_pow) : ($flags & ~$flag_pow); $flags = (isset($arguments[$cur_flag['name']]) && $arguments[$cur_flag['name']] !== null) ? ($flags | $cur_flag['pow']) : ($flags & ~$cur_flag['pow']);
break; break;
} }
} }
@ -102,7 +101,7 @@ class TL extends \danog\MadelineProto\Tools
$arguments['flags'] = $flags; $arguments['flags'] = $flags;
foreach ($tl['params'] as $current_argument) { foreach ($tl['params'] as $current_argument) {
if (!isset($arguments[$current_argument['name']])) { if (!isset($arguments[$current_argument['name']])) {
if ($current_argument['flag'] && (in_array($current_argument['type'], ['true', 'false']) || ($flags & pow(2, $current_argument['pow'])) == 0)) { if ($current_argument['flag'] && (in_array($current_argument['type'], ['true', 'false']) || ($flags & $current_argument['pow']) == 0)) {
//\danog\MadelineProto\Logger::log('Skipping '.$current_argument['name'].' of type '.$current_argument['type'].'/'.$current_argument['subtype']); //\danog\MadelineProto\Logger::log('Skipping '.$current_argument['name'].' of type '.$current_argument['type'].'/'.$current_argument['subtype']);
continue; continue;
} }
@ -182,12 +181,7 @@ class TL extends \danog\MadelineProto\Tools
return $concat; return $concat;
default: default:
$tl_elem = $this->constructors->find_by_predicate($type); return $this->serialize_generic($type, $value);
if ($tl_elem === false) {
throw new Exception('Could not serialize type: '.$type);
}
return \danog\PHP\Struct::pack('<i', $tl_elem['id']);
break; break;
} }
} }
@ -286,19 +280,18 @@ class TL extends \danog\MadelineProto\Tools
$x = ['_' => $tl_elem['predicate']]; $x = ['_' => $tl_elem['predicate']];
foreach ($tl_elem['params'] as $arg) { foreach ($tl_elem['params'] as $arg) {
if ($arg['flag']) { if ($arg['flag']) {
$flag_pow = pow(2, $arg['pow']);
switch ($arg['type']) { switch ($arg['type']) {
case 'true': case 'true':
case 'false': case 'false':
$x[$arg['name']] = ($x['flags'] & $flag_pow) == 1; $x[$arg['name']] = ($x['flags'] & $arg['pow']) == 1;
continue 2; continue 2;
break; break;
case 'Bool': case 'Bool':
$default = false; $default = false;
default: default:
$default = null; $default = null;
if (($x['flags'] & $flag_pow) == 0) { if (($x['flags'] & $arg['pow']) == 0) {
$x[$arg['name']] = $default; $x[$arg['name']] = $default;
//\danog\MadelineProto\Logger::log('Skipping '.$arg['name'].' of type '.$arg['type'].'/'.$arg['subtype']); //\danog\MadelineProto\Logger::log('Skipping '.$arg['name'].' of type '.$arg['type'].'/'.$arg['subtype']);
continue 2; continue 2;

View File

@ -12,7 +12,7 @@ If not, see <http://www.gnu.org/licenses/>.
namespace danog\MadelineProto\TL; namespace danog\MadelineProto\TL;
class TLConstructor class TLConstructor extends TLParams
{ {
public $id = []; public $id = [];
public $predicate = []; public $predicate = [];
@ -20,35 +20,14 @@ class TLConstructor
public $params = []; public $params = [];
public $key = 0; public $key = 0;
public function add($json_dict, $mtproto) public function add($json_dict, $mtproto)
{ {
$this->id[$this->key] = (int) $json_dict['id']; $this->id[$this->key] = (int) $json_dict['id'];
$this->predicate[$this->key] = (string) ((($mtproto && $json_dict['predicate'] == 'message') ? 'MT' : '').$json_dict['predicate']); $this->predicate[$this->key] = (string) ((($mtproto && $json_dict['predicate'] == 'message') ? 'MT' : '').$json_dict['predicate']);
$this->type[$this->key] = $json_dict['type']; $this->type[$this->key] = $json_dict['type'];
$this->params[$this->key] = $json_dict['params']; $this->params[$this->key] = $json_dict['params'];
foreach ($this->params[$this->key] as &$param) { $this->parse_params($this->key, $mtproto);
$param['flag'] = false;
$param['subtype'] = null;
if (preg_match('/^flags\.\d*\?/', $param['type'])) {
$param['flag'] = true;
$param['pow'] = preg_replace(['/^flags\./', '/\?.*/'], '', $param['type']);
$param['type'] = preg_replace('/^flags\.\d*\?/', '', $param['type']);
}
if (preg_match('/vector<.*>/i', $param['type'])) {
if (preg_match('/vector/', $param['type'])) {
$param['subtype'] = preg_replace(['/.*</', '/>$/'], '', $param['type']);
$param['type'] = 'vector';
}
if (preg_match('/Vector/', $param['type'])) {
$param['subtype'] = preg_replace(['/.*</', '/>$/'], '', $param['type']);
$param['type'] = 'Vector t';
}
if (preg_match('/^\%/', $param['subtype'])) {
$param['subtype'] = lcfirst(preg_replace('/^\%/', '', $param['subtype']));
}
$param['subtype'] = (($mtproto && $param['subtype'] == 'message') ? 'MT' : '').$param['subtype'];
}
}
$this->key++; $this->key++;
} }

View File

@ -12,7 +12,7 @@ If not, see <http://www.gnu.org/licenses/>.
namespace danog\MadelineProto\TL; namespace danog\MadelineProto\TL;
class TLMethod class TLMethod extends TLParams
{ {
public $id = []; public $id = [];
public $method = []; public $method = [];
@ -32,28 +32,7 @@ class TLMethod
$this->method_namespace[$namespace[0]] = $namespace[0]; $this->method_namespace[$namespace[0]] = $namespace[0];
} }
foreach ($this->params[$this->key] as &$param) { $this->parse_params($this->key);
$param['flag'] = false;
$param['subtype'] = null;
if (preg_match('/^flags\.\d*\?/', $param['type'])) {
$param['flag'] = true;
$param['pow'] = preg_replace(['/^flags\./', '/\?.*/'], '', $param['type']);
$param['type'] = preg_replace('/^flags\.\d*\?/', '', $param['type']);
}
if (preg_match('/vector<.*>/i', $param['type'])) {
if (preg_match('/vector/', $param['type'])) {
$param['subtype'] = preg_replace(['/.*</', '/>$/'], '', $param['type']);
$param['type'] = 'vector';
}
if (preg_match('/Vector/', $param['type'])) {
$param['subtype'] = preg_replace(['/.*</', '/>$/'], '', $param['type']);
$param['type'] = 'Vector t';
}
if (preg_match('/^\%/', $param['subtype'])) {
$param['subtype'] = lcfirst(preg_replace('/^\%/', '', $param['subtype']));
}
}
}
$this->key++; $this->key++;
} }

View File

@ -34,8 +34,17 @@ if (file_exists('number.php')) {
$authorization = $MadelineProto->complete_phone_login($code); $authorization = $MadelineProto->complete_phone_login($code);
var_dump($authorization); var_dump($authorization);
} }
echo 'Serializing MadelineProto to session.madeline...'.PHP_EOL;
echo 'Wrote '.file_put_contents('session.madeline', serialize($MadelineProto)).' bytes'.PHP_EOL;
echo 'Deserializing MadelineProto from session.madeline...'.PHP_EOL;
$unserialized = unserialize(file_get_contents('session.madeline'));
if (file_exists('token.php')) { if (file_exists('token.php')) {
include_once 'token.php'; include_once 'token.php';
$MadelineProto->bot_login($token); $authorization = $unserialized->bot_login($token);
var_dump($authorization);
} }
echo 'Size of MadelineProto instance is '.strlen(var_export($MadelineProto, true)).' bytes'.PHP_EOL; echo 'Size of MadelineProto instance is '.strlen(serialize($unserialized)).' bytes'.PHP_EOL;