More bugfixes and rewriting

This commit is contained in:
Daniil Gentili 2019-04-29 14:42:08 +00:00
parent c21bcba681
commit e31555b7a7
6 changed files with 88 additions and 68 deletions

View File

@ -142,8 +142,6 @@ class MTProto implements TLCallback
public $setdem = false;
public $storage = [];
private $postpone_updates = false;
private $postpone_pwrchat = false;
private $pending_pwrchat = [];
private $altervista = false;
private $supportUser = 0;
public $referenceDatabase;
@ -210,7 +208,7 @@ class MTProto implements TLCallback
public function __sleep()
{
return ['supportUser', 'referenceDatabase', 'channel_participants', 'event_handler', 'event_handler_instance', 'loop_callback', 'web_template', 'encrypted_layer', 'settings', 'config', 'authorization', 'authorized', 'rsa_keys', 'last_recv', 'dh_config', 'chats', 'last_stored', 'qres', 'pending_updates', 'pending_pwrchat', 'postpone_pwrchat', 'updates_state', 'got_state', 'channels_state', 'updates', 'updates_key', 'full_chats', 'msg_ids', 'dialog_params', 'datacenter', 'v', 'constructors', 'td_constructors', 'methods', 'td_methods', 'td_descriptions', 'tl_callbacks', 'temp_requested_secret_chats', 'temp_rekeyed_secret_chats', 'secret_chats', 'hook_url', 'storage', 'authorized_dc', 'tos'];
return ['supportUser', 'referenceDatabase', 'channel_participants', 'event_handler', 'event_handler_instance', 'loop_callback', 'web_template', 'encrypted_layer', 'settings', 'config', 'authorization', 'authorized', 'rsa_keys', 'last_recv', 'dh_config', 'chats', 'last_stored', 'qres', 'pending_updates', 'updates_state', 'got_state', 'channels_state', 'updates', 'updates_key', 'full_chats', 'msg_ids', 'dialog_params', 'datacenter', 'v', 'constructors', 'td_constructors', 'methods', 'td_methods', 'td_descriptions', 'tl_callbacks', 'temp_requested_secret_chats', 'temp_rekeyed_secret_chats', 'secret_chats', 'hook_url', 'storage', 'authorized_dc', 'tos'];
}
public function isAltervista()
@ -277,7 +275,6 @@ class MTProto implements TLCallback
$this->channels_state[$key]['sync_loading'] = false;
}
$this->postpone_updates = false;
$this->postpone_pwrchat = false;
if ($this->event_handler && class_exists($this->event_handler) && is_subclass_of($this->event_handler, '\danog\MadelineProto\EventHandler')) {
$this->setEventHandler($this->event_handler);
}

View File

@ -257,6 +257,9 @@ trait CallHandler
if (isset($aargs['botAPI'])) {
$message['botAPI'] = $aargs['botAPI'];
}
if (isset($aargs['FloodWaitLimit'])) {
$message['FloodWaitLimit'] = $aargs['FloodWaitLimit'];
}
if (($method === 'users.getUsers' && $args === ['id' => [['_' => 'inputUserSelf']]]) || $method === 'auth.exportAuthorization' || $method === 'updates.getDifference') {
$message['user_related'] = true;
}

View File

@ -26,6 +26,10 @@ use Amp\Loop;
*/
trait PeerHandler
{
public $caching_simple = [];
public $caching_simple_username = [];
public $caching_possible_username = [];
public function to_supergroup($id)
{
return -($id + pow(10, (int) floor(log($id, 10) + 3)));
@ -43,51 +47,30 @@ trait PeerHandler
return ($log - intval($log)) * 1000 < 10;
}
public function handle_pending_pwrchat()
{
if ($this->postpone_pwrchat || empty($this->pending_pwrchat)) {
return false;
}
$this->postpone_pwrchat = true;
try {
$this->logger->logger('Handling pending pwrchat queries...', \danog\MadelineProto\Logger::VERBOSE);
foreach ($this->pending_pwrchat as $query => $params) {
unset($this->pending_pwrchat[$query]);
try {
$this->get_pwr_chat($query, ...$params);
} catch (\danog\MadelineProto\Exception $e) {
$this->logger->logger($e->getMessage(), \danog\MadelineProto\Logger::WARNING);
} catch (\danog\MadelineProto\RPCErrorException $e) {
$this->logger->logger($e->getMessage(), \danog\MadelineProto\Logger::WARNING);
}
}
} finally {
$this->postpone_pwrchat = false;
}
}
public function add_support($support)
{
$this->supportUser = $support['user']['id'];
}
public function add_users($users)
{
foreach ($users as $user) {
$this->add_user($user);
}
}
public function add_user($user)
{
if (!isset($user['access_hash'])) {
$this->logger->logger("No access hash with user {$user['id']}, trying to fetch by ID...");
$this->cache_pwr_chat($user['id'], false, true);
if (isset($user['username']) && !isset($this->chats[$user['id']])) {
/*if (isset($this->chats[$user['id']]['access_hash']) && $this->chats[$user['id']]['access_hash']) {
$this->logger->logger("No access hash with user {$user['id']}, using backup");
$user['access_hash'] = $this->chats[$user['id']]['access_hash'];
} else {
$this->logger->logger("No access hash with user {$user['id']}, not trying to fetch it");
$user['access_hash'] = 0;
}*/
if (!isset($this->caching_simple[$user['id']]) && !(isset($user['username']) && isset($this->caching_simple_username[$user['username']]))) {
$this->logger->logger("No access hash with user {$user['id']}, trying to fetch by ID...");
if (isset($user['username']) && !isset($this->caching_simple_username[$user['username']])) $this->caching_possible_username[$user['id']] = $user['username'];
$this->cache_pwr_chat($user['id'], false, true);
} else if (isset($user['username']) && !isset($this->chats[$user['id']]) && !isset($this->caching_simple_username[$user['username']])) {
$this->logger->logger("No access hash with user {$user['id']}, trying to fetch by username...");
$this->cache_pwr_chat($user['username'], false, true);
} else {
$this->logger->logger("No access hash with user {$user['id']}, tried and failed to fetch data...");
}
return;
@ -107,13 +90,6 @@ trait PeerHandler
}
}
public function add_chats($chats)
{
foreach ($chats as $chat) {
$this->add_chat($chat);
}
}
public function add_chat($chat)
{
switch ($chat['_']) {
@ -132,13 +108,17 @@ trait PeerHandler
case 'channelForbidden':
$bot_api_id = $this->to_supergroup($chat['id']);
if (!isset($chat['access_hash'])) {
$this->logger->logger("Chat $bot_api_id does not have access hash, fetching by ID...");
$this->cache_pwr_chat($bot_api_id, $this->settings['peer']['full_fetch'], true);
if (isset($chat['username']) && !isset($this->chats[$bot_api_id])) {
$this->logger->logger("Chat $bot_api_id does not have access hash, fetching by username...");
$this->cache_pwr_chat($chat['username'], $this->settings['peer']['full_fetch'], true);
}
if (!isset($this->caching_simple[$bot_api_id]) && !(isset($chat['username']) && isset($this->caching_simple_username[$chat['username']]))) {
$this->logger->logger("No access hash with {$chat['_']} {$bot_api_id}, trying to fetch by ID...");
if (isset($chat['username']) && !isset($this->caching_simple_username[$chat['username']])) $this->caching_possible_username[$bot_api_id] = $chat['username'];
$this->cache_pwr_chat($bot_api_id, false, true);
} else if (isset($chat['username']) && !isset($this->chats[$bot_api_id]) && !isset($this->caching_simple_username[$chat['username']])) {
$this->logger->logger("No access hash with {$chat['_']} {$bot_api_id}, trying to fetch by username...");
$this->cache_pwr_chat($chat['username'], false, true);
} else {
$this->logger->logger("No access hash with {$chat['_']} {$bot_api_id}, tried and failed to fetch data...");
}
return;
}
if (!isset($this->chats[$bot_api_id]) || $this->chats[$bot_api_id] !== $chat) {
@ -159,19 +139,15 @@ trait PeerHandler
public function cache_pwr_chat($id, $full_fetch, $send)
{
if ($this->postpone_pwrchat) {
$this->pending_pwrchat[$id] = [$full_fetch, $send];
} else {
Loop::defer(function () use ($id, $full_fetch, $send) {
try {
$this->get_pwr_chat($id, $full_fetch, $send);
} catch (\danog\MadelineProto\Exception $e) {
$this->logger->logger($e->getMessage(), \danog\MadelineProto\Logger::WARNING);
$this->logger->logger("While caching: ".$e->getMessage(), \danog\MadelineProto\Logger::WARNING);
} catch (\danog\MadelineProto\RPCErrorException $e) {
$this->logger->logger($e->getMessage(), \danog\MadelineProto\Logger::WARNING);
$this->logger->logger("While caching: ".$e->getMessage(), \danog\MadelineProto\Logger::WARNING);
}
});
}
}
public function peer_isset($id)
@ -370,9 +346,12 @@ trait PeerHandler
$try_id = $this->get_id($id);
if ($try_id !== false) $id = $try_id;
$tried_simple = false;
if (is_numeric($id)) {
if (!isset($this->chats[$id])) {
try {
$this->caching_simple[$id] = true;
if ($id < 0) {
if ($this->is_supergroup($id)) {
$this->method_call('channels.getChannels', ['id' => [['access_hash' => 0, 'channel_id' => $this->from_supergroup($id), '_' => 'inputChannel']]], ['datacenter' => $this->datacenter->curdc]);
@ -386,6 +365,9 @@ trait PeerHandler
$this->logger->logger($e->getMessage(), \danog\MadelineProto\Logger::WARNING);
} catch (\danog\MadelineProto\RPCErrorException $e) {
$this->logger->logger($e->getMessage(), \danog\MadelineProto\Logger::WARNING);
} finally {
if (isset($this->caching_simple[$id])) unset($this->caching_simple[$id]);
$tried_simple = true;
}
}
if (isset($this->chats[$id])) {
@ -407,7 +389,13 @@ trait PeerHandler
return $this->get_info($id, false);
}
}
if ($tried_simple && isset($this->caching_possible_username[$id])) {
$this->logger->logger("No access hash with $id, trying to fetch by username...");
$user = $this->caching_possible_username[$id];
unset($this->caching_possible_username[$id]);
return $this->get_info($user);
}
throw new \danog\MadelineProto\Exception('This peer is not present in the internal peer database');
}
if (preg_match('@(?:t|telegram)\.(?:me|dog)/(joinchat/)?([a-z0-9_-]*)@i', $id, $matches)) {
@ -860,6 +848,7 @@ trait PeerHandler
public function resolve_username($username)
{
try {
$this->caching_simple_username[$username] = true;
$res = $this->method_call('contacts.resolveUsername', ['username' => str_replace('@', '', $username)], ['datacenter' => $this->datacenter->curdc]);
} catch (\danog\MadelineProto\RPCErrorException $e) {
$this->logger->logger('Username resolution failed with error '.$e->getMessage(), \danog\MadelineProto\Logger::ERROR);
@ -868,6 +857,8 @@ trait PeerHandler
}
return false;
} finally {
if (isset($this->caching_simple_username[$username])) unset($this->caching_simple_username[$username]);
}
if ($res['_'] === 'contacts.resolvedPeer') {
return $res;

View File

@ -469,9 +469,12 @@ trait ResponseHandler
return;
case 420:
$seconds = preg_replace('/[^0-9]+/', '', $response['error_message']);
$limit = isset($aargs['FloodWaitLimit']) ? $aargs['FloodWaitLimit'] : $this->settings['flood_timeout']['wait_if_lt'];
$limit = isset($request['FloodWaitLimit']) ? $request['FloodWaitLimit'] : $this->settings['flood_timeout']['wait_if_lt'];
if (is_numeric($seconds) && $seconds < $limit) {
//$this->got_response_for_outgoing_message_id($request_id, $datacenter);
$this->logger->logger('Flood, waiting '.$seconds.' seconds before repeating async call...', \danog\MadelineProto\Logger::NOTICE);
$request['sent'] += $seconds;
Loop::delay($seconds * 1000, [$this, 'method_recall'], ['message_id' => $request_id, 'datacenter' => $datacenter]);
return;

View File

@ -632,7 +632,7 @@ trait UpdateHandler
if (isset($update['message']['from_id']) && $update['message']['from_id'] === $this->authorization['user']['id']) {
$update['message']['out'] = true;
}
$this->logger->logger('Saving an update of type '.$update['_'].'...', \danog\MadelineProto\Logger::VERBOSE);
//$this->logger->logger('Saving an update of type '.$update['_'].'...', \danog\MadelineProto\Logger::ULTRA_VERBOSE);
if (isset($this->settings['pwr']['strict']) && $this->settings['pwr']['strict'] && isset($this->settings['pwr']['update_handler'])) {
$this->pwr_update_handler($update);
} elseif ($this->settings['updates']['run_callback']) {

View File

@ -22,9 +22,13 @@ namespace danog\MadelineProto\Wrappers;
trait DialogHandler
{
public function get_dialogs($force = true)
{
return $this->wait($this->get_dialogs_async($force));
}
public function get_dialogs_async($force = true)
{
if ($force || !isset($this->dialog_params['offset_date']) || is_null($this->dialog_params['offset_date']) || !isset($this->dialog_params['offset_id']) || is_null($this->dialog_params['offset_id']) || !isset($this->dialog_params['offset_peer']) || is_null($this->dialog_params['offset_peer']) || !isset($this->dialog_params['count']) || is_null($this->dialog_params['count'])) {
$this->dialog_params = ['limit' => 100, 'offset_date' => 0, 'offset_id' => 0, 'offset_peer' => ['_' => 'inputPeerEmpty'], 'count' => 0];
$this->dialog_params = ['limit' => 100, 'offset_date' => 0, 'offset_id' => 0, 'offset_peer' => ['_' => 'inputPeerEmpty'], 'count' => 0, 'hash' => 0];
}
if (!isset($this->dialog_params['hash'])) {
$this->dialog_params['hash'] = 0;
@ -36,18 +40,40 @@ trait DialogHandler
$this->postpone_updates = true;
try {
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['getting_dialogs']);
while ($this->dialog_params['count'] < $res['count']) {
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['getting_dialogs']);
$res = $this->method_call('messages.getDialogs', $this->dialog_params, ['datacenter' => $datacenter, 'FloodWaitLimit' => 100]);
foreach ($res['dialogs'] as $dialog) {
$res = yield $this->method_call_async_read('messages.getDialogs', $this->dialog_params, ['datacenter' => $datacenter, 'FloodWaitLimit' => 100]);
$last_peer = [];
$last_date = 0;
$last_id = 0;
$res['messages'] = array_reverse($res['messages']);
foreach (array_reverse($res['dialogs']) as $dialog) {
if (!in_array($dialog['peer'], $peers)) {
$peers[] = $dialog['peer'];
}
if (!$last_date) {
if (!$last_peer) {
$last_peer = $dialog['peer'];
}
if (!$last_id) {
$last_id = $dialog['top_message'];
}
foreach ($res['messages'] as $message) {
if (yield $this->get_info($message)['Peer'] === $last_peer && $last_id === $message['id']) {
$last_date = $message['date'];
break;
}
}
}
}
if ($last_date) {
$this->dialog_params['offset_date'] = $last_date;
$this->dialog_params['offset_peer'] = $last_peer;
$this->dialog_params['offset_id'] = $last_id;
$this->dialog_params['count'] = count($peers);
} else {
break;
}
$this->dialog_params['count'] += count($res['dialogs']);
$this->dialog_params['offset_date'] = end($res['messages'])['date'];
$this->dialog_params['offset_peer'] = end($res['dialogs'])['peer'];
$this->dialog_params['offset_id'] = end($res['messages'])['id'] & 4294967296;
if (!isset($res['count'])) {
break;
}