Implemented call queue

This commit is contained in:
Daniil Gentili 2017-06-02 14:43:30 +02:00
parent 5b869098b9
commit 658695ad67
8 changed files with 54 additions and 14 deletions

View File

@ -31,6 +31,7 @@ if (file_exists('.env')) {
echo 'Loading settings...'.PHP_EOL; echo 'Loading settings...'.PHP_EOL;
$settings = json_decode(getenv('MTPROTO_SETTINGS'), true) ?: []; $settings = json_decode(getenv('MTPROTO_SETTINGS'), true) ?: [];
if ($MadelineProto === false) { if ($MadelineProto === false) {
echo 'Loading MadelineProto...'.PHP_EOL; echo 'Loading MadelineProto...'.PHP_EOL;
$MadelineProto = new \danog\MadelineProto\API($settings); $MadelineProto = new \danog\MadelineProto\API($settings);
@ -71,6 +72,8 @@ $message = (getenv('TRAVIS_COMMIT') == '') ? 'I iz works always (io laborare sem
echo 'Serializing MadelineProto to s.madeline...'.PHP_EOL; echo 'Serializing MadelineProto to s.madeline...'.PHP_EOL;
echo 'Wrote '.\danog\MadelineProto\Serialization::serialize('s.madeline', $MadelineProto).' bytes'.PHP_EOL; echo 'Wrote '.\danog\MadelineProto\Serialization::serialize('s.madeline', $MadelineProto).' bytes'.PHP_EOL;
$sent = [-440592694=>true];
$offset = 0; $offset = 0;
while (true) { while (true) {
try { try {
@ -80,12 +83,16 @@ while (true) {
$offset = $update['update_id'] + 1; // Just like in the bot API, the offset must be set to the last update_id $offset = $update['update_id'] + 1; // Just like in the bot API, the offset must be set to the last update_id
switch ($update['update']['_']) { switch ($update['update']['_']) {
case 'updateNewEncryptedMessage': case 'updateNewEncryptedMessage':
if (isset($sent[$update['update']['message']['chat_id']])) continue;
$i = 0; $i = 0;
while (true) { while ($i < $argv[1]) {
echo "SENDING MESSAGE $i TO ".$update['update']['message']['chat_id'].PHP_EOL;
$MadelineProto->messages->sendEncrypted(['peer' => $update['update']['message']['chat_id'], 'message' => ['_' => 'decryptedMessage', 'ttl' => 0, 'message' => $i++]]); $MadelineProto->messages->sendEncrypted(['peer' => $update['update']['message']['chat_id'], 'message' => ['_' => 'decryptedMessage', 'ttl' => 0, 'message' => $i++]]);
} }
$sent[$update['update']['message']['chat_id']] = true;
} }
} }
} catch (\danog\MadelineProto\SecurityException $e) { ; } // } catch (\danog\MadelineProto\SecurityException $e) {
} catch (\danog\MadelineProto\Exception $e) { var_dump($e->getMessage()); }
echo 'Wrote '.\danog\MadelineProto\Serialization::serialize('bot.madeline', $MadelineProto).' bytes'.PHP_EOL; echo 'Wrote '.\danog\MadelineProto\Serialization::serialize('bot.madeline', $MadelineProto).' bytes'.PHP_EOL;
} }

View File

@ -508,6 +508,7 @@ class MTProto extends \Volatile
'msg_array_limit' => [ // How big should be the arrays containing the incoming and outgoing messages? 'msg_array_limit' => [ // How big should be the arrays containing the incoming and outgoing messages?
'incoming' => 200, 'incoming' => 200,
'outgoing' => 200, 'outgoing' => 200,
'call_queue' => 200
], ],
'peer' => ['full_info_cache_time' => 60], 'peer' => ['full_info_cache_time' => 60],
'updates' => [ 'updates' => [
@ -707,7 +708,7 @@ class MTProto extends \Volatile
public function getV() public function getV()
{ {
return 38; return 39;
} }
public function get_self() public function get_self()

View File

@ -17,6 +17,7 @@ namespace danog\MadelineProto\MTProtoTools;
*/ */
trait CallHandler trait CallHandler
{ {
public $call_queue = [];
public function method_call($method, $args = [], $aargs = ['message_id' => null, 'heavy' => false]) public function method_call($method, $args = [], $aargs = ['message_id' => null, 'heavy' => false])
{ {
if (!$this->is_array($args)) { if (!$this->is_array($args)) {
@ -50,9 +51,15 @@ trait CallHandler
} }
$args['chat_id'] = $res['chat_id']; $args['chat_id'] = $res['chat_id'];
} }
$queue = (isset($aargs['queue']) && $aargs['queue']) || in_array($method, ['messages.setEncryptedTyping', 'messages.readEncryptedHistory', 'messages.sendEncrypted', 'messages.sendEncryptedFile', 'messages.sendEncryptedService', 'messages.receivedQueue']);
$serialized = $this->serialize_method($method, $args); $serialized = $this->serialize_method($method, $args);
$content_related = $this->content_related($method); $content_related = $this->content_related($method);
$type = $this->methods->find_by_method($method)['type']; $type = $this->methods->find_by_method($method)['type'];
if ($queue) {
$serialized = $this->serialize_method('invokeAfterMsgs', ['msg_ids' => $this->call_queue, 'query' => $serialized]);
}
$last_recv = $this->last_recv; $last_recv = $this->last_recv;
if ($canunset = !$this->getting_state && !$this->threads && !$this->run_workers) { if ($canunset = !$this->getting_state && !$this->threads && !$this->run_workers) {
$this->getting_state = true; $this->getting_state = true;
@ -62,6 +69,17 @@ trait CallHandler
\danog\MadelineProto\Logger::log(['Calling method (try number '.$count.' for '.$method.')...'], \danog\MadelineProto\Logger::ULTRA_VERBOSE); \danog\MadelineProto\Logger::log(['Calling method (try number '.$count.' for '.$method.')...'], \danog\MadelineProto\Logger::ULTRA_VERBOSE);
$message_id = $this->send_message($serialized, $content_related, $aargs); $message_id = $this->send_message($serialized, $content_related, $aargs);
if ($queue) {
$this->call_queue[] = $message_id;
if (count($this->call_queue) > $this->settings['msg_array_limit']['call_queue']) {
reset($this->call_queue);
$key = key($this->call_queue);
if ($key[0] === "\0") {
$key = 'a'.$key;
}
unset($this->call_queue[$key]);
}
}
if ($method === 'http_wait' || (isset($aargs['noResponse']) && $aargs['noResponse'])) { if ($method === 'http_wait' || (isset($aargs['noResponse']) && $aargs['noResponse'])) {
return true; return true;
} }

View File

@ -132,14 +132,14 @@ trait AuthKeyHandler
public function accept_rekey($chat, $params) public function accept_rekey($chat, $params)
{ {
if ($this->secret_chats[$chat]['rekeying'][0] !== 0) { if ($this->secret_chats[$chat]['rekeying'][0] !== 0) {
$my = $this->temp_rekeyed_secret_chats[$this->secret_chats[$chat]['rekeying'][1]]; $my_exchange_id = new \phpseclib\Math\BigInteger($this->secret_chats[$chat]['rekeying'][1], -256);
$other_exchange_id = new \phpseclib\Math\BigInteger($params['exchange_id'], -256);
//var_dump($my, $params); //var_dump($my, $params);
if ($my['exchange_id'] > $params['exchange_id']) { if ($my_exchange_id > $other_exchange_id) {
return; return;
} }
if ($my['exchange_id'] === $params['exchange_id']) { if ($my_exchange_id === $other_exchange_id) {
$this->secret_chats[$chat]['rekeying'] = [0]; $this->secret_chats[$chat]['rekeying'] = [0];
return; return;
} }
} }
@ -232,6 +232,8 @@ trait AuthKeyHandler
} }
public function discard_secret_chat($chat) { public function discard_secret_chat($chat) {
\danog\MadelineProto\Logger::log(['Discarding secret chat '.$chat.'...'], \danog\MadelineProto\Logger::VERBOSE);
if (isset($this->secret_chats[$chat])) { if (isset($this->secret_chats[$chat])) {
unset($this->secret_chats[$chat]); unset($this->secret_chats[$chat]);
} }

View File

@ -71,6 +71,7 @@ trait ResponseHandler
$this->save_update($update); $this->save_update($update);
break; break;
case 'decryptedMessageLayer': case 'decryptedMessageLayer':
var_dump($update['message']);
if ($this->check_secret_out_seq_no($update['message']['chat_id'], $update['message']['decrypted_message']['out_seq_no']) && $this->check_secret_in_seq_no($update['message']['chat_id'], $update['message']['decrypted_message']['in_seq_no'])) { if ($this->check_secret_out_seq_no($update['message']['chat_id'], $update['message']['decrypted_message']['out_seq_no']) && $this->check_secret_in_seq_no($update['message']['chat_id'], $update['message']['decrypted_message']['in_seq_no'])) {
$this->secret_chats[$update['message']['chat_id']]['in_seq_no']++; $this->secret_chats[$update['message']['chat_id']]['in_seq_no']++;
if ($update['message']['decrypted_message']['layer'] >= 17) { if ($update['message']['decrypted_message']['layer'] >= 17) {

View File

@ -43,7 +43,6 @@ trait SeqNoHandler
$seqno = ($seqno - $this->secret_chats[$chat_id]['in_seq_no_x']) / 2; $seqno = ($seqno - $this->secret_chats[$chat_id]['in_seq_no_x']) / 2;
$C = 0; $C = 0;
foreach ($this->secret_chats[$chat_id]['incoming'] as $message) { foreach ($this->secret_chats[$chat_id]['incoming'] as $message) {
var_dump($message);
if (isset($message['decrypted_message']['out_seq_no']) && $C < $this->secret_chats[$chat_id]['in_seq_no']) { if (isset($message['decrypted_message']['out_seq_no']) && $C < $this->secret_chats[$chat_id]['in_seq_no']) {
if (($message['decrypted_message']['out_seq_no'] - $this->secret_chats[$chat_id]['in_seq_no_x']) / 2 !== $C) { if (($message['decrypted_message']['out_seq_no'] - $this->secret_chats[$chat_id]['in_seq_no_x']) / 2 !== $C) {
$this->discard_secret_chat($chat_id); $this->discard_secret_chat($chat_id);
@ -56,7 +55,6 @@ trait SeqNoHandler
var_dump($C, $seqno); var_dump($C, $seqno);
if ($seqno < $C) { // <= C if ($seqno < $C) { // <= C
\danog\MadelineProto\Logger::log(['WARNING: dropping repeated message with seqno '.$seqno]); \danog\MadelineProto\Logger::log(['WARNING: dropping repeated message with seqno '.$seqno]);
$this->secret_chats[$chat_id]['in_seq_no']--;
return false; return false;
} }

View File

@ -452,6 +452,9 @@ trait TL
throw new Exception('Missing required parameter ('.$current_argument['name'].')'); throw new Exception('Missing required parameter ('.$current_argument['name'].')');
} }
if (!$this->is_array($arguments[$current_argument['name']]) && $current_argument['type'] === 'InputEncryptedChat') { if (!$this->is_array($arguments[$current_argument['name']]) && $current_argument['type'] === 'InputEncryptedChat') {
if (!isset($this->secret_chats[$arguments[$current_argument['name']]])) {
throw new \danog\MadelineProto\Exception('This secret peer is not present in the internal peer database');
}
$arguments[$current_argument['name']] = $this->secret_chats[$arguments[$current_argument['name']]]['InputEncryptedChat']; $arguments[$current_argument['name']] = $this->secret_chats[$arguments[$current_argument['name']]]['InputEncryptedChat'];
} }
if ($current_argument['type'] === 'DataJSON') { if ($current_argument['type'] === 'DataJSON') {

View File

@ -89,11 +89,25 @@ var_dump($MadelineProto->get_call($call));
while ($MadelineProto->secret_chat_status($secret) !== 2) { while ($MadelineProto->secret_chat_status($secret) !== 2) {
$MadelineProto->get_updates(); $MadelineProto->get_updates();
} }
$MadelineProto->get_updates(['offset' => -1]); $offset = 0;
$InputEncryptedChat = $MadelineProto->get_secret_chat($secret)['InputEncryptedChat']; $InputEncryptedChat = $MadelineProto->get_secret_chat($secret)['InputEncryptedChat'];
$sentMessage = $MadelineProto->messages->sendEncrypted(['peer' => $InputEncryptedChat, 'message' => ['_' => 'decryptedMessage', 'media' => ['_' => 'decryptedMessageMediaEmpty'], 'ttl' => 10, 'message' => $message, 'entities' => [['_' => 'messageEntityCode', 'offset' => 0, 'length' => mb_strlen($message)]]]]); // should work with all layers $sentMessage = $MadelineProto->messages->sendEncrypted(['peer' => $InputEncryptedChat, 'message' => ['_' => 'decryptedMessage', 'media' => ['_' => 'decryptedMessageMediaEmpty'], 'ttl' => 10, 'message' => $message, 'entities' => [['_' => 'messageEntityCode', 'offset' => 0, 'length' => mb_strlen($message)]]]]); // should work with all layers
\danog\MadelineProto\Logger::log([$sentMessage], \danog\MadelineProto\Logger::NOTICE); \danog\MadelineProto\Logger::log([$sentMessage], \danog\MadelineProto\Logger::NOTICE);
while (true) {
$updates = $MadelineProto->API->get_updates(['offset' => $offset, 'limit' => 50, 'timeout' => 0]); // Just like in the bot API, you can specify an offset, a limit and a timeout
//\danog\MadelineProto\Logger::log([$updates]);
foreach ($updates as $update) {
$offset = $update['update_id'] + 1; // Just like in the bot API, the offset must be set to the last update_id
switch ($update['update']['_']) {
case 'updateNewEncryptedMessage':
var_dump($update);
}
}
echo 'Wrote '.\danog\MadelineProto\Serialization::serialize('bot.madeline', $MadelineProto).' bytes'.PHP_EOL;
}
$secret_media = []; $secret_media = [];
// Photo uploaded as document, secret chat // Photo uploaded as document, secret chat
@ -130,10 +144,6 @@ var_dump($MadelineProto->get_call($call));
foreach ($secret_media as $type => $smessage) { foreach ($secret_media as $type => $smessage) {
$type = $MadelineProto->messages->sendEncryptedFile($smessage); $type = $MadelineProto->messages->sendEncryptedFile($smessage);
} }
/*
while (true) {
var_dump($MadelineProto->get_updates());
}*/
} }
$mention = $MadelineProto->get_info(getenv('TEST_USERNAME')); // Returns an array with all of the constructors that can be extracted from a username or an id $mention = $MadelineProto->get_info(getenv('TEST_USERNAME')); // Returns an array with all of the constructors that can be extracted from a username or an id
$mention = $mention['user_id']; // Selects only the numeric user id $mention = $mention['user_id']; // Selects only the numeric user id