mirror of
https://github.com/danog/MadelineProto.git
synced 2024-11-30 10:19:00 +01:00
Fixed threading, fixed APIFactory, started working on calls
This commit is contained in:
parent
564009cda9
commit
cd1040ec19
7
a.php
Normal file
7
a.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
$payload = base64_decode('NAAAAAAAAAAAAAAAAAAAAAAAAAC06N5YFAAAAHiXRmAwx9DuB28gQszy/RHjhN2RdLkYdQ==');
|
||||
$socket = fsockopen('tcp://149.154.167.91:443'); // DC 4
|
||||
$socket = fsockopen('tcp://149.154.167.50:443'); // DC 2
|
||||
stream_set_timeout($socket, 5);
|
||||
echo 'Wrote '.fwrite($socket, $payload).' bytes'.PHP_EOL;
|
||||
if (strlen(fread($socket, 100))) echo 'Read 100 bytes from socket'.PHP_EOL; else echo 'No data could be read from socket'.PHP_EOL;
|
@ -1,23 +1,8 @@
|
||||
---
|
||||
title: DataJSON
|
||||
description: constructors and methods of type DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to types index](index.md)
|
||||
|
||||
|
||||
|
||||
### Possible values (constructors):
|
||||
|
||||
[dataJSON](../constructors/dataJSON.md)
|
||||
|
||||
|
||||
|
||||
### Methods that return an object of this type (methods):
|
||||
|
||||
[$MadelineProto->bots->sendCustomRequest](../methods/bots_sendCustomRequest.md)
|
||||
|
||||
[$MadelineProto->phone->getCallConfig](../methods/phone_getCallConfig.md)
|
||||
|
||||
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.
|
8
docs/MTProto_docs/types/DataJSON.md
Normal file
8
docs/MTProto_docs/types/DataJSON.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.
|
8
docs/TD_docs/types/DataJSON.md
Normal file
8
docs/TD_docs/types/DataJSON.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.
|
8
old_docs/API_docs_v18/types/DataJSON.md
Normal file
8
old_docs/API_docs_v18/types/DataJSON.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.
|
8
old_docs/API_docs_v23/types/DataJSON.md
Normal file
8
old_docs/API_docs_v23/types/DataJSON.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.
|
8
old_docs/API_docs_v25/types/DataJSON.md
Normal file
8
old_docs/API_docs_v25/types/DataJSON.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.
|
8
old_docs/API_docs_v27/types/DataJSON.md
Normal file
8
old_docs/API_docs_v27/types/DataJSON.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.
|
8
old_docs/API_docs_v33/types/DataJSON.md
Normal file
8
old_docs/API_docs_v33/types/DataJSON.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.
|
8
old_docs/API_docs_v38/types/DataJSON.md
Normal file
8
old_docs/API_docs_v38/types/DataJSON.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.
|
8
old_docs/API_docs_v40/types/DataJSON.md
Normal file
8
old_docs/API_docs_v40/types/DataJSON.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.
|
8
old_docs/API_docs_v41/types/DataJSON.md
Normal file
8
old_docs/API_docs_v41/types/DataJSON.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.
|
8
old_docs/API_docs_v42/types/DataJSON.md
Normal file
8
old_docs/API_docs_v42/types/DataJSON.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.
|
8
old_docs/API_docs_v44/types/DataJSON.md
Normal file
8
old_docs/API_docs_v44/types/DataJSON.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.
|
8
old_docs/API_docs_v45/types/DataJSON.md
Normal file
8
old_docs/API_docs_v45/types/DataJSON.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.
|
8
old_docs/API_docs_v46/types/DataJSON.md
Normal file
8
old_docs/API_docs_v46/types/DataJSON.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.
|
8
old_docs/API_docs_v51/types/DataJSON.md
Normal file
8
old_docs/API_docs_v51/types/DataJSON.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.
|
8
old_docs/API_docs_v53/types/DataJSON.md
Normal file
8
old_docs/API_docs_v53/types/DataJSON.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.
|
8
old_docs/API_docs_v55/types/DataJSON.md
Normal file
8
old_docs/API_docs_v55/types/DataJSON.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.
|
8
old_docs/API_docs_v57/types/DataJSON.md
Normal file
8
old_docs/API_docs_v57/types/DataJSON.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.
|
8
old_docs/API_docs_v62/types/DataJSON.md
Normal file
8
old_docs/API_docs_v62/types/DataJSON.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.
|
@ -35,6 +35,7 @@ class API extends APIFactory
|
||||
//$this->future_salts = $this->get_future_salts(['num' => 3]);
|
||||
$this->API->v = $this->API->getV();
|
||||
\danog\MadelineProto\Logger::log(['MadelineProto is ready!'], Logger::NOTICE);
|
||||
$this->setup_threads();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -45,11 +46,57 @@ class API extends APIFactory
|
||||
return ['API'];
|
||||
}
|
||||
*/
|
||||
public function setup_threads()
|
||||
{
|
||||
if ($this->API->threads = $this->API->run_workers = class_exists('\Pool') && php_sapi_name() == 'cli' && $this->API->settings['threading']['allow_threading']) {
|
||||
\danog\MadelineProto\Logger::log(['THREADING IS ENABLED'], \danog\MadelineProto\Logger::NOTICE);
|
||||
$this->start_threads();
|
||||
}
|
||||
}
|
||||
|
||||
public function start_threads()
|
||||
{
|
||||
if ($this->API->threads) {
|
||||
$dcs = $this->API->datacenter->get_dcs();
|
||||
if (!isset($this->reader_pool)) {
|
||||
$this->reader_pool = new \Pool(count($dcs));
|
||||
}
|
||||
if (!isset($this->readers)) {
|
||||
$this->readers = [];
|
||||
}
|
||||
foreach ($dcs as $dc) {
|
||||
if (!isset($this->readers[$dc])) {
|
||||
$this->readers[$dc] = new \danog\MadelineProto\Threads\SocketReader($this->API, $dc);
|
||||
}
|
||||
if (!$this->readers[$dc]->isRunning()) {
|
||||
$this->readers[$dc]->garbage = false;
|
||||
$this->reader_pool->submit($this->readers[$dc]);
|
||||
Logger::log(['Socket reader on DC '.$dc.': RESTARTED'], Logger::WARNING);
|
||||
} else {
|
||||
Logger::log(['Socket reader on DC '.$dc.': WORKING'], Logger::NOTICE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
$t = get_object_vars($this);
|
||||
if (isset($t['reader_pool'])) {
|
||||
unset($t['reader_pool']);
|
||||
}
|
||||
if (isset($t['readers'])) {
|
||||
unset($t['readers']);
|
||||
}
|
||||
|
||||
return array_keys($t);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
set_error_handler(['\danog\MadelineProto\Exception', 'ExceptionErrorHandler']);
|
||||
//$this->APIFactory();
|
||||
$this->setup_threads();
|
||||
if (!isset($this->messages)) $this->APIFactory();
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
|
@ -142,7 +142,7 @@ class Connection
|
||||
throw new Exception("Connection: couldn't connect to socket.");
|
||||
}
|
||||
if (($wrote = fwrite($this->sock, $what)) !== strlen($what)) {
|
||||
throw new \danog\MadelineProto\Exception("WARNING: Wrong length was read (should've written ".strlen($what).', wrote '.$wrote.')!');
|
||||
throw new \danog\MadelineProto\Exception("WARNING: Wrong length was written (should've written ".strlen($what).', wrote '.$wrote.')!');
|
||||
}
|
||||
|
||||
return $wrote;
|
||||
|
@ -694,6 +694,16 @@ description: Represents a boolean.
|
||||
|
||||
Represents a boolean.');
|
||||
|
||||
file_put_contents('types/DataJSON.md', '---
|
||||
title: DataJSON
|
||||
description: Any json-encodable data
|
||||
---
|
||||
## Type: DataJSON
|
||||
[Back to constructor index](index.md)
|
||||
|
||||
Any json-encodable data.');
|
||||
|
||||
|
||||
\danog\MadelineProto\Logger::log(['Done!'], \danog\MadelineProto\Logger::NOTICE);
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ class MTProto
|
||||
use \danog\MadelineProto\TL\Conversion\Extension;
|
||||
use \danog\MadelineProto\TL\Conversion\TD;
|
||||
use \danog\MadelineProto\Tools;
|
||||
use \danog\MadelineProto\VoIP\AuthKeyHandler;
|
||||
|
||||
public $settings = [];
|
||||
public $config = ['expires' => -1];
|
||||
@ -102,51 +103,6 @@ class MTProto
|
||||
$this->should_serialize = true;
|
||||
}
|
||||
|
||||
public function setup_threads()
|
||||
{
|
||||
if ($this->threads = $this->run_workers = class_exists('\Pool') && php_sapi_name() == 'cli' && $this->settings['threading']['allow_threading']) {
|
||||
\danog\MadelineProto\Logger::log(['THREADING IS ENABLED'], \danog\MadelineProto\Logger::NOTICE);
|
||||
$this->start_threads();
|
||||
}
|
||||
}
|
||||
|
||||
public function start_threads()
|
||||
{
|
||||
if ($this->threads) {
|
||||
$dcs = $this->datacenter->get_dcs();
|
||||
if (!isset($this->reader_pool)) {
|
||||
$this->reader_pool = new \Pool(count($dcs));
|
||||
}
|
||||
if (!isset($this->readers)) {
|
||||
$this->readers = [];
|
||||
}
|
||||
foreach ($dcs as $dc) {
|
||||
if (!isset($this->readers[$dc])) {
|
||||
$this->readers[$dc] = new \danog\MadelineProto\Threads\SocketReader($this, $dc);
|
||||
}
|
||||
if (!$this->readers[$dc]->isRunning()) {
|
||||
$this->readers[$dc]->garbage = false;
|
||||
$this->reader_pool->submit($this->readers[$dc]);
|
||||
Logger::log(['Socket reader on DC '.$dc.': RESTARTED'], Logger::WARNING);
|
||||
} else {
|
||||
Logger::log(['Socket reader on DC '.$dc.': WORKING'], Logger::NOTICE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
$t = get_object_vars($this);
|
||||
if (isset($t['reader_pool'])) {
|
||||
unset($t['reader_pool']);
|
||||
}
|
||||
if (isset($t['readers'])) {
|
||||
unset($t['readers']);
|
||||
}
|
||||
|
||||
return array_keys($t);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
@ -160,7 +116,6 @@ class MTProto
|
||||
\danog\MadelineProto\Logger::log(['Serialization is out of date, reconstructing object!'], Logger::WARNING);
|
||||
$this->__construct($this->settings);
|
||||
}
|
||||
$this->setup_threads();
|
||||
$this->datacenter->__construct($this->settings['connection'], $this->settings['connection_settings']);
|
||||
if ($this->authorized && $this->settings['updates']['handle_updates']) {
|
||||
\danog\MadelineProto\Logger::log(['Getting updates after deserialization...'], Logger::NOTICE);
|
||||
@ -329,7 +284,7 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
|
||||
'accept_calls' => true, // Should I accept calls? Can be true, false or on array of user ids from which to accept calls
|
||||
],
|
||||
'threading' => [
|
||||
'allow_threading' => false, // Should I use threading, if it is enabled?
|
||||
'allow_threading' => true, // Should I use threading, if it is enabled?
|
||||
'handler_workers' => 10, // How many workers should every message handler pool of each socket reader have
|
||||
],
|
||||
'pwr' => ['pwr' => false, 'db_token' => false, 'strict' => false],
|
||||
@ -389,7 +344,6 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
|
||||
$this->datacenter->dc_connect($new_dc);
|
||||
}
|
||||
}
|
||||
$this->setup_threads();
|
||||
$this->init_authorization();
|
||||
if ($old !== $this->datacenter->get_dcs()) {
|
||||
$this->connect_to_all_dcs();
|
||||
|
@ -508,85 +508,6 @@ trait AuthKeyHandler
|
||||
return $this->dh_config = $dh_config;
|
||||
}
|
||||
|
||||
private $temp_requested_calls = [];
|
||||
private $calls = [];
|
||||
|
||||
public function accept_call($params)
|
||||
{
|
||||
$dh_config = $this->get_dh_config();
|
||||
\danog\MadelineProto\Logger::log(['Generating b...'], \danog\MadelineProto\Logger::VERBOSE);
|
||||
$b = new \phpseclib\Math\BigInteger($this->random(256), 256);
|
||||
$params['g_a'] = new \phpseclib\Math\BigInteger($params['g_a'], 256);
|
||||
$this->check_G($params['g_a'], $dh_config['p']);
|
||||
$key = ['auth_key' => str_pad($params['g_a']->powMod($b, $dh_config['p'])->toBytes(), 256, chr(0), \STR_PAD_LEFT)];
|
||||
$key['fingerprint'] = substr(sha1($key['auth_key'], true), -8);
|
||||
$key['visualization_orig'] = substr(sha1($key['auth_key'], true), 16);
|
||||
$key['visualization_46'] = substr(hash('sha256', $key['auth_key'], true), 20);
|
||||
$this->secret_chats[$params['id']] = ['key' => $key, 'admin' => false, 'user_id' => $params['admin_id'], 'InputPhoneCall' => ['id' => $params['id'], 'access_hash' => $params['access_hash'], '_' => 'inputPhoneCall'], 'in_seq_no_x' => 0, 'out_seq_no_x' => 1, 'layer' => 65, 'ttr' => 100, 'updated' => time(), 'incoming' => [], 'outgoing' => [], 'created' => time(), 'rekeying' => [0], 'protocol' => $params['protocol'], 'connection' => $params['connection'], 'alternative_connections' => $params['alternative_connections']];
|
||||
//$this->secret_chats[$params['id']] = ['key' => $key, 'admin' => false, 'user_id' => $params['admin_id'], 'InputEncryptedChat' => ['_' => 'inputEncryptedChat', 'chat_id' => $params['id'], 'access_hash' => $params['access_hash']], 'in_seq_no_x' => 1, 'out_seq_no_x' => 0, 'layer' => 8, 'ttl' => PHP_INT_MAX, 'ttr' => 100, 'updated' => time(), 'incoming' => [], 'outgoing' => [], 'created' => time(), 'rekeying' => [0]];
|
||||
$g_b = $dh_config['g']->powMod($b, $dh_config['p']);
|
||||
$this->check_G($g_b, $dh_config['p']);
|
||||
$this->handle_pending_updates();
|
||||
}
|
||||
|
||||
public function request_call($user)
|
||||
{
|
||||
$user = $this->get_info($user)['InputUser'];
|
||||
\danog\MadelineProto\Logger::log(['Calling '.$user['user_id'].'...'], \danog\MadelineProto\Logger::VERBOSE);
|
||||
$dh_config = $this->get_dh_config();
|
||||
\danog\MadelineProto\Logger::log(['Generating a...'], \danog\MadelineProto\Logger::VERBOSE);
|
||||
$a = new \phpseclib\Math\BigInteger($this->random(256), 256);
|
||||
\danog\MadelineProto\Logger::log(['Generating g_a...'], \danog\MadelineProto\Logger::VERBOSE);
|
||||
$g_a = $dh_config['g']->powMod($a, $dh_config['p']);
|
||||
$this->check_G($g_a, $dh_config['p']);
|
||||
// $res = $this->method_call('phone.requestCall', ['user_id' => $user, 'g_a' => $g_a->toBytes(), 'protocol' => ['_' => 'phoneCallProtocol', 'min_layer' => $this->settings['tl_schema']['layer'], 'max_layer' => $this->settings['tl_schema']['layer']]], ['datacenter' => $this->datacenter->curdc]);
|
||||
$res = $this->method_call('phone.requestCall', ['user_id' => $user, 'g_a' => $g_a->toBytes(), 'protocol' => ['_' => 'phoneCallProtocol', 'min_layer' => 65, 'max_layer' => 65, 'udp_reflector' => true]], ['datacenter' => $this->datacenter->curdc]);
|
||||
$this->temp_requested_calls[$res['phone_call']['id']] = $a;
|
||||
$this->handle_pending_updates();
|
||||
$this->get_updates_difference();
|
||||
|
||||
return $res['phone_call']['id'];
|
||||
}
|
||||
|
||||
public function complete_call($params)
|
||||
{
|
||||
if ($this->call_status($params['id']) !== 1) {
|
||||
\danog\MadelineProto\Logger::log(['Could not find and complete secret chat '.$params['id']]);
|
||||
|
||||
return false;
|
||||
}
|
||||
$dh_config = $this->get_dh_config();
|
||||
$params['g_a_or_b'] = new \phpseclib\Math\BigInteger($params['g_a_or_b'], 256);
|
||||
$this->check_G($params['g_a_or_b'], $dh_config['p']);
|
||||
$key = ['auth_key' => str_pad($params['g_a_or_b']->powMod($this->temp_requested_secret_chats[$params['id']], $dh_config['p'])->toBytes(), 256, chr(0), \STR_PAD_LEFT)];
|
||||
unset($this->temp_requested_calls[$params['id']]);
|
||||
$key['fingerprint'] = substr(sha1($key['auth_key'], true), -8);
|
||||
if ($key['fingerprint'] !== $params['key_fingerprint']) {
|
||||
throw new \danog\MadelineProto\SecurityException('Invalid key fingerprint!');
|
||||
}
|
||||
$key['visualization_orig'] = substr(sha1($key['auth_key'], true), 16);
|
||||
$key['visualization_46'] = substr(hash('sha256', $key['auth_key'], true), 20);
|
||||
$this->secret_chats[$params['id']] = ['key' => $key, 'admin' => true, 'user_id' => $params['participant_id'], 'InputPhoneCall' => ['id' => $params['id'], 'access_hash' => $params['access_hash'], '_' => 'inputPhoneCall'], 'in_seq_no_x' => 0, 'out_seq_no_x' => 1, 'layer' => 65, 'ttr' => 100, 'updated' => time(), 'incoming' => [], 'outgoing' => [], 'created' => time(), 'rekeying' => [0], 'protocol' => $params['protocol'], 'connection' => $params['connection'], 'alternative_connections' => $params['alternative_connections']];
|
||||
$this->handle_pending_updates();
|
||||
}
|
||||
|
||||
public function call_status($id)
|
||||
{
|
||||
if (isset($this->calls[$id])) {
|
||||
return 2;
|
||||
}
|
||||
if (isset($this->temp_requested_calls[$id])) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function get_secret_chat($chat)
|
||||
{
|
||||
return $this->secret_chats[$chat];
|
||||
}
|
||||
|
||||
public function bind_temp_auth_key($expires_in, $datacenter)
|
||||
{
|
||||
for ($retry_id_total = 1; $retry_id_total <= $this->settings['max_tries']['authorization']; $retry_id_total++) {
|
||||
|
@ -52,7 +52,7 @@ trait CallHandler
|
||||
while ($server_answer === null && $res_count++ < $this->settings['max_tries']['response'] + 1) { // Loop until we get a response, loop for a max of $this->settings['max_tries']['response'] times
|
||||
try {
|
||||
\danog\MadelineProto\Logger::log(['Getting response (try number '.$res_count.' for '.$method.')...'], \danog\MadelineProto\Logger::ULTRA_VERBOSE);
|
||||
$this->start_threads();
|
||||
//$this->start_threads();
|
||||
if (!isset($this->datacenter->sockets[$aargs['datacenter']]->outgoing_messages[$int_message_id]['response']) || !isset($this->datacenter->sockets[$aargs['datacenter']]->incoming_messages[$this->datacenter->sockets[$aargs['datacenter']]->outgoing_messages[$int_message_id]['response']]['content'])) { // Checks if I have received the response to the called method, if not continue looping
|
||||
if ($only_updates) {
|
||||
if ($update_count > 50) {
|
||||
@ -86,7 +86,7 @@ trait CallHandler
|
||||
throw new \danog\MadelineProto\Exception("Couldn't get response");
|
||||
}
|
||||
if (!isset($server_answer['_'])) {
|
||||
\danog\MadelineProto\Logger::log(['Response does not have a type!', $server_answer], \danog\MadelineProto\Logger::FATAL_ERROR);
|
||||
return $server_answer;
|
||||
}
|
||||
switch ($server_answer['_']) {
|
||||
case 'rpc_error':
|
||||
|
@ -340,6 +340,9 @@ trait TL
|
||||
if ($constructorData['predicate'] === 'messageEntityMentionName') {
|
||||
$constructorData = $this->constructors->find_by_predicate('inputMessageEntityMentionName');
|
||||
}
|
||||
if ($constructorData['predicate'] === 'dataJSON') {
|
||||
$object['data'] = json_encode($object['data']);
|
||||
}
|
||||
if (!$bare) {
|
||||
$concat .= \danog\PHP\Struct::pack('<i', $constructorData['id']);
|
||||
}
|
||||
@ -444,7 +447,7 @@ trait TL
|
||||
} elseif (!is_object($bytes_io)) {
|
||||
throw new Exception('An invalid bytes_io handle was provided.');
|
||||
}
|
||||
//\danog\MadelineProto\Logger::log(['Deserializing '.$type['type'].' at byte '.$bytes_io->pos);
|
||||
//\danog\MadelineProto\Logger::log(['Deserializing '.$type['type'].' at byte '.$bytes_io->pos]);
|
||||
switch ($type['type']) {
|
||||
case 'Bool':
|
||||
return $this->deserialize_bool($bytes_io->read(4));
|
||||
@ -570,7 +573,9 @@ trait TL
|
||||
if (isset($x['flags'])) { // I don't think we need this anymore
|
||||
unset($x['flags']);
|
||||
}
|
||||
|
||||
if ($x['_'] === 'dataJSON') {
|
||||
return json_decode($x['data'], true);
|
||||
}
|
||||
return $x;
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ class SocketReader extends \Threaded implements \Collectable
|
||||
try {
|
||||
$this->API->recv_message($this->current);
|
||||
$handler_pool->submit(new SocketHandler($this->API, $this->current));
|
||||
} catch (\danog\MadelineProto\Exception $e) {
|
||||
} catch (\danog\MadelineProto\NothingInTheSocketException $e) {
|
||||
}
|
||||
}
|
||||
while ($handler_pool->collect());
|
||||
|
102
src/danog/MadelineProto/VoIP/AuthKeyHandler.php
Normal file
102
src/danog/MadelineProto/VoIP/AuthKeyHandler.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
/*
|
||||
Copyright 2016-2017 Daniil Gentili
|
||||
(https://daniil.it)
|
||||
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/>.
|
||||
*/
|
||||
|
||||
namespace danog\MadelineProto\VoIP;
|
||||
|
||||
/**
|
||||
* Manages the creation of the authorization key.
|
||||
*
|
||||
* https://core.telegram.org/mtproto/auth_key
|
||||
* https://core.telegram.org/mtproto/samples-auth_key
|
||||
*/
|
||||
trait AuthKeyHandler
|
||||
{
|
||||
private $temp_requested_calls = [];
|
||||
private $calls = [];
|
||||
|
||||
public function accept_call($params)
|
||||
{
|
||||
$dh_config = $this->get_dh_config();
|
||||
$phone_config = $this->method_call('phone.getCallConfig');
|
||||
$b = new \phpseclib\Math\BigInteger($this->random(256), 256);
|
||||
$params['g_a'] = new \phpseclib\Math\BigInteger($params['g_a'], 256);
|
||||
$this->check_G($params['g_a'], $dh_config['p']);
|
||||
$key = ['auth_key' => str_pad($params['g_a']->powMod($b, $dh_config['p'])->toBytes(), 256, chr(0), \STR_PAD_LEFT)];
|
||||
$key['fingerprint'] = substr(sha1($key['auth_key'], true), -8);
|
||||
$key['visualization_orig'] = substr(sha1($key['auth_key'], true), 16);
|
||||
$key['visualization_46'] = substr(hash('sha256', $key['auth_key'], true), 20);
|
||||
$this->calls[$params['id']] = ['key' => $key, 'admin' => false, 'user_id' => $params['admin_id'], 'InputPhoneCall' => ['id' => $params['id'], 'access_hash' => $params['access_hash'], '_' => 'inputPhoneCall'], 'in_seq_no_x' => 0, 'out_seq_no_x' => 1, 'layer' => 65, 'ttr' => 100, 'updated' => time(), 'incoming' => [], 'outgoing' => [], 'created' => time(), 'rekeying' => [0], 'protocol' => $params['protocol'], 'connection' => $params['connection'], 'alternative_connections' => $params['alternative_connections']];
|
||||
//$this->calls[$params['id']] = ['key' => $key, 'admin' => false, 'user_id' => $params['admin_id'], 'InputEncryptedChat' => ['_' => 'inputEncryptedChat', 'chat_id' => $params['id'], 'access_hash' => $params['access_hash']], 'in_seq_no_x' => 1, 'out_seq_no_x' => 0, 'layer' => 8, 'ttl' => PHP_INT_MAX, 'ttr' => 100, 'updated' => time(), 'incoming' => [], 'outgoing' => [], 'created' => time(), 'rekeying' => [0]];
|
||||
$g_b = $dh_config['g']->powMod($b, $dh_config['p']);
|
||||
$this->check_G($g_b, $dh_config['p']);
|
||||
$this->handle_pending_updates();
|
||||
}
|
||||
|
||||
public function request_call($user)
|
||||
{
|
||||
$user = $this->get_info($user)['InputUser'];
|
||||
\danog\MadelineProto\Logger::log(['Calling '.$user['user_id'].'...'], \danog\MadelineProto\Logger::VERBOSE);
|
||||
$dh_config = $this->get_dh_config();
|
||||
$phone_config = $this->method_call('phone.getCallConfig', [], ['datacenter' => $this->datacenter->curdc]);
|
||||
\danog\MadelineProto\Logger::log(['Generating a...'], \danog\MadelineProto\Logger::VERBOSE);
|
||||
$a = new \phpseclib\Math\BigInteger($this->random(256), 256);
|
||||
\danog\MadelineProto\Logger::log(['Generating g_a...'], \danog\MadelineProto\Logger::VERBOSE);
|
||||
$g_a = $dh_config['g']->powMod($a, $dh_config['p']);
|
||||
$this->check_G($g_a, $dh_config['p']);
|
||||
$res = $this->method_call('phone.requestCall', ['user_id' => $user, 'g_a_hash' => hash('sha256', $g_a->toBytes(), true), 'protocol' => ['_' => 'phoneCallProtocol', 'udp_reflector' => true, 'min_layer' => $this->settings['tl_schema']['layer'], 'max_layer' => $this->settings['tl_schema']['layer']]], ['datacenter' => $this->datacenter->curdc]);
|
||||
$this->temp_requested_calls[$res['phone_call']['id']] = $a;
|
||||
$this->handle_pending_updates();
|
||||
$this->get_updates_difference();
|
||||
|
||||
return $res['phone_call']['id'];
|
||||
}
|
||||
|
||||
public function complete_call($params)
|
||||
{
|
||||
if ($this->call_status($params['id']) !== 1) {
|
||||
\danog\MadelineProto\Logger::log(['Could not find and complete secret chat '.$params['id']]);
|
||||
|
||||
return false;
|
||||
}
|
||||
$dh_config = $this->get_dh_config();
|
||||
$params['g_a_or_b'] = new \phpseclib\Math\BigInteger($params['g_a_or_b'], 256);
|
||||
$this->check_G($params['g_a_or_b'], $dh_config['p']);
|
||||
$key = ['auth_key' => str_pad($params['g_a_or_b']->powMod($this->temp_requested_calls[$params['id']], $dh_config['p'])->toBytes(), 256, chr(0), \STR_PAD_LEFT)];
|
||||
unset($this->temp_requested_calls[$params['id']]);
|
||||
$key['fingerprint'] = substr(sha1($key['auth_key'], true), -8);
|
||||
if ($key['fingerprint'] !== $params['key_fingerprint']) {
|
||||
throw new \danog\MadelineProto\SecurityException('Invalid key fingerprint!');
|
||||
}
|
||||
$key['visualization_orig'] = substr(sha1($key['auth_key'], true), 16);
|
||||
$key['visualization_46'] = substr(hash('sha256', $key['auth_key'], true), 20);
|
||||
$this->calls[$params['id']] = ['key' => $key, 'admin' => true, 'user_id' => $params['participant_id'], 'InputPhoneCall' => ['id' => $params['id'], 'access_hash' => $params['access_hash'], '_' => 'inputPhoneCall'], 'in_seq_no_x' => 0, 'out_seq_no_x' => 1, 'layer' => 65, 'ttr' => 100, 'updated' => time(), 'incoming' => [], 'outgoing' => [], 'created' => time(), 'rekeying' => [0], 'protocol' => $params['protocol'], 'connection' => $params['connection'], 'alternative_connections' => $params['alternative_connections']];
|
||||
$this->handle_pending_updates();
|
||||
}
|
||||
|
||||
public function call_status($id)
|
||||
{
|
||||
if (isset($this->calls[$id])) {
|
||||
return 2;
|
||||
}
|
||||
if (isset($this->temp_requested_calls[$id])) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function get_secret_chat($chat)
|
||||
{
|
||||
return $this->calls[$chat];
|
||||
}
|
||||
|
||||
}
|
@ -66,7 +66,7 @@ if ($MadelineProto === false) {
|
||||
}
|
||||
$message = (getenv('TRAVIS_COMMIT') == '') ? 'I iz works always (io laborare sembre) (yo lavorar siempre) (mi labori ĉiam) (я всегда работать) (Ik werkuh altijd)' : ('Travis ci tests in progress: commit '.getenv('TRAVIS_COMMIT').', job '.getenv('TRAVIS_JOB_NUMBER').', PHP version: '.getenv('TRAVIS_PHP_VERSION'));
|
||||
|
||||
//$MadelineProto->API->request_secret_chat('@Harold_Saxon');
|
||||
//$MadelineProto->API->request_call('@danogentili');
|
||||
echo 'Serializing MadelineProto to session.madeline...'.PHP_EOL;
|
||||
echo 'Wrote '.\danog\MadelineProto\Serialization::serialize('session.madeline', $MadelineProto).' bytes'.PHP_EOL;
|
||||
echo 'Size of MadelineProto instance is '.strlen(serialize($MadelineProto)).' bytes'.PHP_EOL;
|
||||
|
Loading…
Reference in New Issue
Block a user