mirror of
https://github.com/danog/MadelineProto.git
synced 2024-11-30 06:39:01 +01:00
Implemented VoIP wrapper
This commit is contained in:
parent
47243915ce
commit
a65b5b18c9
@ -41,6 +41,7 @@ class MTProto extends \Volatile
|
||||
use \danog\MadelineProto\TL\Conversion\TD;
|
||||
use \danog\MadelineProto\Tools;
|
||||
use \danog\MadelineProto\VoIP\AuthKeyHandler;
|
||||
use \danog\MadelineProto\VoIP\CallbackHandler;
|
||||
use \danog\MadelineProto\Wrappers\DialogHandler;
|
||||
use \danog\MadelineProto\Wrappers\Login;
|
||||
|
||||
@ -524,6 +525,10 @@ class MTProto extends \Volatile
|
||||
'calls' => [
|
||||
'accept_calls' => true, // Should I accept calls? Can be true, false or on array of user ids from which to accept calls
|
||||
'allow_p2p' => false, // Should I accept p2p calls?
|
||||
'incoming_callback' => 'default_incoming_call_callback',
|
||||
'network_type' => 7,
|
||||
'log_file_path' => '/dev/stdout',
|
||||
'stats_dump_file_path' => '/dev/stdout',
|
||||
],
|
||||
'threading' => [
|
||||
'allow_threading' => false, // Should I use threading, if it is enabled?
|
||||
|
@ -22,7 +22,7 @@ trait AuthKeyHandler
|
||||
{
|
||||
private $calls = [];
|
||||
|
||||
public function request_call($user)
|
||||
public function request_call($user, $callbacks)
|
||||
{
|
||||
$user = $this->get_info($user);
|
||||
if (!isset($user['InputUser'])) {
|
||||
@ -38,7 +38,7 @@ trait AuthKeyHandler
|
||||
$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->calls[$res['phone_call']['id']] = ['status' => self::REQUESTED, 'a' => $a, 'g_a' => $g_a];
|
||||
$this->calls[$res['phone_call']['id']] = ['status' => self::REQUESTED, 'a' => $a, 'g_a' => $g_a, 'callbacks' => $callbacks];
|
||||
$this->handle_pending_updates();
|
||||
$this->get_updates_difference();
|
||||
|
||||
@ -61,8 +61,8 @@ trait AuthKeyHandler
|
||||
$b = \phpseclib\Math\BigInteger::randomRange($this->two, $dh_config['p']->subtract($this->two));
|
||||
$g_b = $dh_config['g']->powMod($b, $dh_config['p']);
|
||||
$this->check_G($g_b, $dh_config['p']);
|
||||
$res = $this->method_call('phone.acceptCall', ['peer' => ['_' => 'inputPhoneCall', 'id' => $params['id'], 'access_hash' => $params['access_hash']], 'g_b' => $g_b->toBytes(), 'protocol' => ['_' => 'phoneCallProtocol', 'udp_reflector' => true, 'min_layer' => $this->settings['tl_schema']['layer'], 'max_layer' => $this->settings['tl_schema']['layer']]], ['datacenter' => $this->datacenter->curdc]);
|
||||
$this->calls[$res['phone_call']['id']] = ['status' => self::ACCEPTED, 'b' => $b, 'g_a_hash' => $params['g_a_hash']];
|
||||
$res = $this->method_call('phone.acceptCall', ['user_id' => $user, 'g_b' => $g_b->toBytes(), 'protocol' => ['_' => 'phoneCallProtocol', 'udp_reflector' => true, 'min_layer' => $this->settings['tl_schema']['layer'], 'max_layer' => $this->settings['tl_schema']['layer']]], ['datacenter' => $this->datacenter->curdc]);
|
||||
$this->handle_pending_updates();
|
||||
$this->get_updates_difference();
|
||||
}
|
||||
@ -79,14 +79,28 @@ trait AuthKeyHandler
|
||||
$this->check_G($params['g_b'], $dh_config['p']);
|
||||
$key = ['auth_key' => str_pad($params['g_b']->powMod($this->calls[$params['id']]['a'], $dh_config['p'])->toBytes(), 256, chr(0), \STR_PAD_LEFT)];
|
||||
$key['fingerprint'] = substr(sha1($key['auth_key'], true), -8);
|
||||
$res = $this->method_call('phone.confirmCall', ['user_id' => $user, 'g_a' => $this->calls[$params['id']]['g_a']->toBytes(), 'protocol' => ['_' => 'phoneCallProtocol', 'udp_reflector' => true, 'min_layer' => $this->settings['tl_schema']['layer'], 'max_layer' => $this->settings['tl_schema']['layer']]], ['datacenter' => $this->datacenter->curdc]);
|
||||
$res = $this->method_call('phone.confirmCall', ['key_fingerprint' => $key['fingerprint'], 'peer' => ['id' => $params['id'], 'access_hash' => $params['access_hash'], '_' => 'inputPhoneCall'], 'g_a' => $this->calls[$params['id']]['g_a']->toBytes(), 'protocol' => ['_' => 'phoneCallProtocol', 'udp_reflector' => true, 'min_layer' => $this->settings['tl_schema']['layer'], 'max_layer' => $this->settings['tl_schema']['layer']]], ['datacenter' => $this->datacenter->curdc])['phone_call'];
|
||||
$key['visualization'] = '';
|
||||
$length = new \phpseclib\Math\BigInteger(count(self::EMOJIS));
|
||||
foreach (str_split(strrev(substr(hash('sha256', $this->calls[$params['id']]['g_a']->toBytes().$key['auth_key'], true), 20)), 8) as $number) {
|
||||
$key['visualization'] .= self::EMOJIS[(int) ((new \phpseclib\Math\BigInteger($number, -256))->divide($length)[1]->toString())];
|
||||
}
|
||||
|
||||
$this->calls[$params['id']] = ['status' => self::READY, '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' => $this->settings['tl_scheme']['layer'], 'updated' => time(), 'incoming' => [], 'outgoing' => [], 'created' => time(), 'protocol' => $params['protocol']];
|
||||
$this->calls[$params['id']] = ['status' => self::READY, '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' => $this->settings['tl_schema']['layer'], 'updated' => time(), 'incoming' => [], 'outgoing' => [], 'created' => time(), 'protocol' => $params['protocol'], 'callbacks' => $this->calls[$params['id']]['callbacks']];
|
||||
$this->calls[$params['id']]['controller'] = new \danog\MadelineProto\VoIP($this->calls[$params['id']]['callbacks']['set_state'], $this->calls[$params['id']]['callbacks']['incoming'], $this->calls[$params['id']]['callbacks']['outgoing'], $this, $this->calls[$params['id']]['InputPhoneCall']);
|
||||
var_dump("key");
|
||||
$this->calls[$params['id']]['controller']->setEncryptionKey($key['auth_key'], true);
|
||||
var_dump("network");
|
||||
$this->calls[$params['id']]['controller']->setNetworkType($this->settings['calls']['network_type']);
|
||||
var_dump("config");
|
||||
$this->calls[$params['id']]['controller']->setConfig($this->config['call_receive_timeout_ms']/1000, $this->config['call_connect_timeout_ms']/1000, true, true, true, $this->settings['calls']['log_file_path'], $this->settings['calls']['stats_dump_file_path']);
|
||||
var_dump("shared config");
|
||||
$this->calls[$params['id']]['controller']->setSharedConfig($this->method_call('phone.getCallConfig', [], ['datacenter' => $this->datacenter->curdc]));
|
||||
var_dump("endpoints");
|
||||
$this->calls[$params['id']]['controller']->setRemoteEndpoints(array_merge([$res['connection']], $res['alternative_connections']), $this->settings['calls']['allow_p2p']);
|
||||
var_dump("start");
|
||||
$this->calls[$params['id']]['controller']->start();
|
||||
|
||||
$this->handle_pending_updates();
|
||||
}
|
||||
|
||||
@ -114,7 +128,15 @@ trait AuthKeyHandler
|
||||
$key['visualization'] .= $self::EMOJIS[(int) ((new \phpseclib\Math\BigInteger($number, -256))->divide($length)[1]->toString())];
|
||||
}
|
||||
|
||||
$this->calls[$params['id']] = ['status' => self::READY, 'key' => $key, 'admin' => false, 'user_id' => $params['admin_id'], 'InputPhoneCall' => ['id' => $params['id'], 'access_hash' => $params['access_hash'], '_' => 'inputPhoneCall'], 'in_seq_no_x' => 1, 'out_seq_no_x' => 0, 'layer' => $this->settings['tl_scheme']['layer'], 'updated' => time(), 'incoming' => [], 'outgoing' => [], 'created' => time(), 'protocol' => $params['protocol']];
|
||||
$this->calls[$params['id']] = ['status' => self::READY, 'key' => $key, 'admin' => false, 'user_id' => $params['admin_id'], 'InputPhoneCall' => ['id' => $params['id'], 'access_hash' => $params['access_hash'], '_' => 'inputPhoneCall'], 'in_seq_no_x' => 1, 'out_seq_no_x' => 0, 'layer' => $this->settings['tl_schema']['layer'], 'updated' => time(), 'incoming' => [], 'outgoing' => [], 'created' => time(), 'protocol' => $params['protocol'], 'callbacks' => $this->get_incoming_call_callbacks()];
|
||||
$this->calls[$params['id']]['controller'] = new \danog\MadelineProto\VoIP($this->calls[$params['id']]['callbacks']['set_state'], $this->calls[$params['id']]['callbacks']['incoming'], $this->calls[$params['id']]['callbacks']['outgoing'], $this, $this->calls[$params['id']]['InputPhoneCall']);
|
||||
$this->calls[$params['id']]['controller']->setEncryptionKey($key['auth_key'], false);
|
||||
$this->calls[$params['id']]['controller']->setNetworkType($this->settings['calls']['network_type']);
|
||||
$this->calls[$params['id']]['controller']->setConfig($this->config['call_receive_timeout_ms']/1000, $this->config['call_connect_timeout_ms']/1000, true, true, true, $this->settings['calls']['log_file_path'], $this->settings['calls']['stats_dump_file_path']);
|
||||
$this->calls[$params['id']]['controller']->setSharedConfig($this->method_call('phone.getCallConfig', [], ['datacenter' => $this->datacenter->curdc]));
|
||||
$this->calls[$params['id']]['controller']->setRemoteEndpoints(array_merge([$params['connection']], $params['alternative_connections']), $this->settings['calls']['allow_p2p']);
|
||||
$this->calls[$params['id']]['controller']->start();
|
||||
|
||||
}
|
||||
|
||||
public function call_status($id)
|
||||
|
@ -31,6 +31,7 @@ if (file_exists('.env')) {
|
||||
|
||||
echo 'Loading settings...'.PHP_EOL;
|
||||
$settings = json_decode(getenv('MTPROTO_SETTINGS'), true) ?: [];
|
||||
|
||||
var_dump($settings);
|
||||
if ($MadelineProto === false) {
|
||||
echo 'Loading MadelineProto...'.PHP_EOL;
|
||||
@ -69,8 +70,45 @@ if ($MadelineProto === false) {
|
||||
}
|
||||
$message = (getenv('TRAVIS_COMMIT') == '') ? 'I iz works always (io laborare sembre) (yo lavorar siempre) (mi labori ĉiam) (я всегда работать) (Ik werkuh altijd) (Ngimbonga ngaso sonke isikhathi ukusebenza)' : ('Travis ci tests in progress: commit '.getenv('TRAVIS_COMMIT').', job '.getenv('TRAVIS_JOB_NUMBER').', PHP version: '.getenv('TRAVIS_PHP_VERSION'));
|
||||
|
||||
echo 'Serializing MadelineProto to session.madeline...'.PHP_EOL;
|
||||
echo 'Wrote '.\danog\MadelineProto\Serialization::serialize('session.madeline', $MadelineProto).' bytes'.PHP_EOL;
|
||||
|
||||
echo 'Serializing MadelineProto to session.madeline...'.PHP_EOL; echo 'Wrote
|
||||
'.\danog\MadelineProto\Serialization::serialize('session.madeline', $MadelineProto).' bytes'.PHP_EOL;
|
||||
|
||||
var_dump($id = $MadelineProto->request_call('@danogentili', [
|
||||
'set_state' => function ($call, $state) {
|
||||
var_dump("SET STATE $state");
|
||||
},
|
||||
'incoming' => [
|
||||
'start' => function ($call) {
|
||||
var_dump("PLEASE START RECEIVING DATA");
|
||||
},
|
||||
'stop' => function ($call) {
|
||||
var_dump("PLEASE STOP RECEIVING DATA");
|
||||
},
|
||||
'configure' => function ($call, $sampleRate, $bitsPerSample, $channels) {
|
||||
var_dump("incoming sampleRate: $sampleRate, bitsPerSample: $bitsPerSample, channels: $channels");
|
||||
},
|
||||
],
|
||||
'outgoing' => [
|
||||
'start' => function ($call) {
|
||||
var_dump("PLEASE START SENDING DATA");
|
||||
},
|
||||
'stop' => function ($call) {
|
||||
var_dump("PLEASE STOP SENDING DATA");
|
||||
},
|
||||
'configure' => function ($call, $sampleRate, $bitsPerSample, $channels) {
|
||||
var_dump("outgoing sampleRate: $sampleRate, bitsPerSample: $bitsPerSample, channels: $channels");
|
||||
},
|
||||
'get_level' => function ($call) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
],
|
||||
]));
|
||||
|
||||
while ($MadelineProto->call_status($id) !== \danog\MadelineProto\MTProto::READY) {
|
||||
$MadelineProto->get_updates();
|
||||
}
|
||||
|
||||
if (stripos(readline('Do you want to make the secret chat tests? (y/n): '), 'y') !== false) {
|
||||
|
||||
@ -149,16 +187,18 @@ $mention = $MadelineProto->get_info(getenv('TEST_USERNAME')); // Returns an arra
|
||||
$mention = $mention['user_id']; // Selects only the numeric user id
|
||||
$media = [];
|
||||
|
||||
// Photo uploaded as document
|
||||
$inputFile = $MadelineProto->upload('tests/faust.jpg', 'fausticorn.jpg'); // This gets an inputFile object with file name magic
|
||||
$media['document_photo'] = ['_' => 'inputMediaUploadedDocument', 'file' => $inputFile, 'mime_type' => mime_content_type('tests/faust.jpg'), 'caption' => 'This file was uploaded using MadelineProto', 'attributes' => [['_' => 'documentAttributeImageSize', 'w' => 1280, 'h' => 914]]];
|
||||
foreach (glob('gifs/*') as $gif) {
|
||||
// GIF
|
||||
$inputFile = $MadelineProto->upload($gif);
|
||||
$media['gif'] = ['_' => 'inputMediaUploadedDocument', 'file' => $inputFile, 'mime_type' => mime_content_type($gif), 'caption' => '', 'attributes' => [['_' => 'documentAttributeAnimated']]];
|
||||
}
|
||||
|
||||
// Photo
|
||||
$media['photo'] = ['_' => 'inputMediaUploadedPhoto', 'file' => $inputFile, 'mime_type' => mime_content_type('tests/faust.jpg'), 'caption' => 'This photo was uploaded using MadelineProto'];
|
||||
|
||||
// GIF
|
||||
$inputFile = $MadelineProto->upload('tests/pony.mp4');
|
||||
$media['gif'] = ['_' => 'inputMediaUploadedDocument', 'file' => $inputFile, 'mime_type' => mime_content_type('tests/pony.mp4'), 'caption' => 'test', 'attributes' => [['_' => 'documentAttributeAnimated']]];
|
||||
foreach (glob('vids/*') as $vid) {
|
||||
// GIF
|
||||
$inputFile = $MadelineProto->upload($vid);
|
||||
$media['video'] = ['_' => 'inputMediaUploadedDocument', 'file' => $inputFile, 'mime_type' => mime_content_type('tests/swing.mp4'), 'caption' => 'test', 'attributes' => [['_' => 'documentAttributeVideo', 'duration' => 5, 'w' => 1280, 'h' => 720]]];
|
||||
$media['gif'] = ['_' => 'inputMediaUploadedDocument', 'file' => $inputFile, 'mime_type' => mime_content_type($gif), 'caption' => '', 'attributes' => [['_' => 'documentAttributeAnimated']]];
|
||||
}
|
||||
|
||||
// Sticker
|
||||
$inputFile = $MadelineProto->upload('tests/lel.webp');
|
||||
|
Loading…
Reference in New Issue
Block a user