Fixes to dialog fetching, participant list fetching, exceptions, documentation, and lotsa other stuff

This commit is contained in:
Daniil Gentili 2017-07-26 18:38:10 +02:00
parent 4b1af4d274
commit d79ffc1349
18 changed files with 263 additions and 62 deletions

View File

@ -579,6 +579,7 @@ var_dump($authorization);
See tests/testing.php for more examples. See tests/testing.php for more examples.
Use `get_pwr_chat` to get chat info, see [here for the parameters and the result](https://daniil.it/MadelineProto/get_pwr_chat.html). Use `get_pwr_chat` to get chat info, see [here for the parameters and the result](https://daniil.it/MadelineProto/get_pwr_chat.html).
You can also use `get_info` to get chat info, see [here for the parameters and the result](https://daniil.it/MadelineProto/get_info.html)You can also use `get_full_info` to get chat info, see [here for the parameters and the result](https://daniil.it/MadelineProto/get_full_info.html).
Methods that allow sending message entities (messages.sendMessage for example) also have an additional parse_mode parameter that enables or disables html/markdown parsing of the message to be sent. See the method-specific documentation for more info. Methods that allow sending message entities (messages.sendMessage for example) also have an additional parse_mode parameter that enables or disables html/markdown parsing of the message to be sent. See the method-specific documentation for more info.

View File

@ -27,6 +27,7 @@ try {
die; die;
} }
} }
var_dump($a);
//var_dump($MadelineProto->API->get_config([], ['datacenter' => $MadelineProto->API->datacenter->curdc])); //var_dump($MadelineProto->API->get_config([], ['datacenter' => $MadelineProto->API->datacenter->curdc]));
//var_dump($MadelineProto->API->settings['connection']); //var_dump($MadelineProto->API->settings['connection']);
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

@ -22,6 +22,7 @@ description: chat attributes, type and example
|restriction\_reason|[string](API_docs/types/string.md) | Optional|Restriction reason| |restriction\_reason|[string](API_docs/types/string.md) | Optional|Restriction reason|
|status|[UserStatus](API_docs/types/UserStatus.md) | Optional|Describes last time user was online| |status|[UserStatus](API_docs/types/UserStatus.md) | Optional|Describes last time user was online|
|bot\_inline\_placeholder|[string](API_docs/types/string.md) | Optional|Inline placeholder of inline bot| |bot\_inline\_placeholder|[string](API_docs/types/string.md) | Optional|Inline placeholder of inline bot|
|bot\_nochats|[Bool](API_docs/types/Bool.md) | Optional|Can the bot be added to a group|
|about|[string](API_docs/types/string.md) | Optional|Description of supergroups/channels or bios of users| |about|[string](API_docs/types/string.md) | Optional|Description of supergroups/channels or bios of users|
|bot\_info|[BotInfo](API_docs/types/BotInfo.md) | Optional|Bot info of bots| |bot\_info|[BotInfo](API_docs/types/BotInfo.md) | Optional|Bot info of bots|
|phone\_calls\_available|[Bool](API_docs/types/Bool.md) | Optional|Are phone calls available for that user?| |phone\_calls\_available|[Bool](API_docs/types/Bool.md) | Optional|Are phone calls available for that user?|

15
docs/FullInfo.md Normal file
View File

@ -0,0 +1,15 @@
---
title: full chat info
description: chat attributes, type and example
---
## Constructor: FullInfo
### Attributes:
| Name | Type | Required |Description|
|----------|:-------------:|:--------:|----------:|
|partial|[Info](Info.md) | Yes|Info object|
|last_update|[int](API_docs/types/int.md) | Yes|unixdate|
|full|[ChatFull](API_docs/types/ChatFull.md) or [UserFull](API_docs/types/UserFull.md) | Yes|full info|

23
docs/Info.md Normal file
View File

@ -0,0 +1,23 @@
---
title: chat info
description: chat attributes, type and example
---
## Constructor: Info
### Attributes:
| Name | Type | Required |Description|
|----------|:-------------:|:--------:|----------:|
|type|[string](API_docs/types/string.md) | Yes|bot, user, channel, supergroup or chat|
|bot\_api\_id|[long](API_docs/types/long.md) | Yes|bot API chat id|
|InputPeer|[InputPeer](API_docs/types/InputPeer.md) | Yes|InputPeer object|
|Peer|[Peer](API_docs/types/Peer.md) | Optional|Peer object|
|user\_id|[int](API_docs/types/int.md) | Optional|MTProto user id|
|chat\_id|[int](API_docs/types/int.md) | Optional|MTProto chat id|
|channel\_id|[int](API_docs/types/int.md) | Optional|MTProto channel id|
|InputUser|[InputUser](API_docs/types/InputUser.md) | Optional|InputUser object|
|InputChannel|[InputChannel](API_docs/types/InputChannel.md) | Optional|InputChannel object|

View File

@ -12,6 +12,11 @@ description: PWRTelegram participant attributes, type and example
|----------|:-------------:|:--------:|-----------:| |----------|:-------------:|:--------:|-----------:|
|user|[Chat](Chat.md) | Yes| The participant| |user|[Chat](Chat.md) | Yes| The participant|
|inviter|[Chat](Chat.md) | Optional|The user that invited this participant| |inviter|[Chat](Chat.md) | Optional|The user that invited this participant|
|promoted_by|[Chat](Chat.md) | Optional|The user that promoted this participant|
|kicked_by|[Chat](Chat.md) | Optional|The user that kicked this participant|
|date|[int](API_docs/types/int.md) | Yes|When was the user invited| |date|[int](API_docs/types/int.md) | Yes|When was the user invited|
|role|[string](API_docs/types/int.md) | Yes|user, admin, creator, moderator, editor, creator, kicked| |role|[string](API_docs/types/string.md) | Yes|user, admin, creator, moderator, editor, creator, kicked|
|can_edit|[Bool](API_docs/types/Bool.md) | Optional|Can the user edit messages in the channel|
|left|[Bool](API_docs/types/Bool.md) | Optional|Has this user left|
|admin_rights|[ChannelAdminRights](API_docs/types/ChannelAdminRights.md) | Optional|Admin rights|
|banned_rights|[ChannelBannedRights](API_docs/types/ChannelBannedRights.md) | Optional|Banned rights|

42
docs/get_full_info.md Normal file
View File

@ -0,0 +1,42 @@
---
title: get_full_info
description: get_full_info parameters, return type and example
---
## Method: get_full_info
### Parameters:
| Name | Type |
|----------|:-------------:|
|id| A username, a bot API chat id, a tg-cli chat id, a [Chat](API_docs/types/Chat.md), a [User](API_docs/types/User.md), an [InputPeer](API_docs/types/InputPeer.md), an [InputUser](API_docs/types/InputUser.md), an [InputChannel](API_docs/types/InputChannel.md), a [Peer](API_docs/types/Peer.md), or a [Chat](API_docs/types/Chat.md) object|
### Return type: [FullInfo](FullInfo.md)
### Example:
```
$MadelineProto = new \danog\MadelineProto\API();
if (isset($token)) {
$this->bot_login($token);
}
if (isset($number)) {
$sentCode = $MadelineProto->phone_login($number);
echo 'Enter the code you received: ';
$code = '';
for ($x = 0; $x < $sentCode['type']['length']; $x++) {
$code .= fgetc(STDIN);
}
$MadelineProto->complete_phone_login($code);
}
$Chat = $MadelineProto->get_full_info($id);
```
Or, if you're into Lua:
```
Chat = get_full_info(id)
```

42
docs/get_info.md Normal file
View File

@ -0,0 +1,42 @@
---
title: get_info
description: get_info parameters, return type and example
---
## Method: get_info
### Parameters:
| Name | Type |
|----------|:-------------:|
|id| A username, a bot API chat id, a tg-cli chat id, a [Chat](API_docs/types/Chat.md), a [User](API_docs/types/User.md), an [InputPeer](API_docs/types/InputPeer.md), an [InputUser](API_docs/types/InputUser.md), an [InputChannel](API_docs/types/InputChannel.md), a [Peer](API_docs/types/Peer.md), or a [Chat](API_docs/types/Chat.md) object|
### Return type: [Info](Info.md)
### Example:
```
$MadelineProto = new \danog\MadelineProto\API();
if (isset($token)) {
$this->bot_login($token);
}
if (isset($number)) {
$sentCode = $MadelineProto->phone_login($number);
echo 'Enter the code you received: ';
$code = '';
for ($x = 0; $x < $sentCode['type']['length']; $x++) {
$code .= fgetc(STDIN);
}
$MadelineProto->complete_phone_login($code);
}
$Chat = $MadelineProto->get_info($id);
```
Or, if you're into Lua:
```
Chat = get_info(id)
```

View File

@ -583,6 +583,7 @@ var_dump($authorization);
See tests/testing.php for more examples. See tests/testing.php for more examples.
Use `get_pwr_chat` to get chat info, see [here for the parameters and the result](https://daniil.it/MadelineProto/get_pwr_chat.html). Use `get_pwr_chat` to get chat info, see [here for the parameters and the result](https://daniil.it/MadelineProto/get_pwr_chat.html).
You can also use `get_info` to get chat info, see [here for the parameters and the result](https://daniil.it/MadelineProto/get_info.html)You can also use `get_full_info` to get chat info, see [here for the parameters and the result](https://daniil.it/MadelineProto/get_full_info.html).
Methods that allow sending message entities (messages.sendMessage for example) also have an additional parse_mode parameter that enables or disables html/markdown parsing of the message to be sent. See the method-specific documentation for more info. Methods that allow sending message entities (messages.sendMessage for example) also have an additional parse_mode parameter that enables or disables html/markdown parsing of the message to be sent. See the method-specific documentation for more info.

View File

@ -36,16 +36,16 @@ class Exception extends \Exception
} }
parent::__construct($message, $code, $previous); parent::__construct($message, $code, $previous);
/* if (\danog\MadelineProto\Logger::$constructed) { if (\danog\MadelineProto\Logger::$constructed) {
\danog\MadelineProto\Logger::log([$message.' in '.basename($this->file).':'.$this->line], \danog\MadelineProto\Logger::FATAL_ERROR); \danog\MadelineProto\Logger::log([$message.' in '.basename($this->file).':'.$this->line], \danog\MadelineProto\Logger::FATAL_ERROR);
}*/ }
if (in_array($message, ['Re-executing query...', 'I had to recreate the temporary authorization key', 'This peer is not present in the internal peer database', "Couldn't get response", 'Chat forbidden', 'The php-libtgvoip extension is required to accept and manage calls. See daniil.it/MadelineProto for more info.'])) { if (in_array($message, ['Re-executing query...', 'I had to recreate the temporary authorization key', 'This peer is not present in the internal peer database', "Couldn't get response", 'Chat forbidden', 'The php-libtgvoip extension is required to accept and manage calls. See daniil.it/MadelineProto for more info.', 'File does not exist'])) {
return; return;
} }
if (strpos($message, 'socket_write') !== false || strpos($message, 'socket_read') !== false || strpos($message, 'Received request to switch to DC ') !== false || strpos($message, "Couldn't get response") !== false || strpos($message, 'Re-executing query...') !== false || strpos($message, "Couldn't find peer by provided") !== false || strpos($message, 'id.pwrtelegram.xyz') !== false || strpos($message, 'Please update ') !== false || strpos($message, 'posix_isatty') !== false) { if (strpos($message, 'socket_write') !== false || strpos($message, 'socket_read') !== false || strpos($message, 'Received request to switch to DC ') !== false || strpos($message, "Couldn't get response") !== false || strpos($message, 'Re-executing query...') !== false || strpos($message, "Couldn't find peer by provided") !== false || strpos($message, 'id.pwrtelegram.xyz') !== false || strpos($message, 'Please update ') !== false || strpos($message, 'posix_isatty') !== false) {
return; return;
} }
// \Rollbar\Rollbar::log(\Rollbar\Payload\Level::error(), $this, debug_backtrace(0)); \Rollbar\Rollbar::log(\Rollbar\Payload\Level::error(), $this, debug_backtrace(0));
} }
/** /**

View File

@ -81,8 +81,15 @@ class Lua
$cb($result, $cb_extra); $cb($result, $cb_extra);
} }
array_walk_recursive($result, function (&$value, $key) { array_walk_recursive($result, function (&$value, $key) {
if ($value instanceof \danog\MadelineProto\TL\Types\Button) { if (is_object($value)) {
$value = $value->jsonSerialize(); $newval = [];
foreach (get_class_methods($value) as $key => $name) {
$newval[$key] = [$value, $name];
}
foreach ($value as $key => $name) {
$newval[$key] = $name;
}
$value = $newval;
} }
}); });

View File

@ -44,7 +44,7 @@ class MTProto extends \Volatile
use \danog\MadelineProto\Wrappers\DialogHandler; use \danog\MadelineProto\Wrappers\DialogHandler;
use \danog\MadelineProto\Wrappers\Login; use \danog\MadelineProto\Wrappers\Login;
const V = 61; const V = 63;
const NOT_LOGGED_IN = 0; const NOT_LOGGED_IN = 0;
const WAITING_CODE = 1; const WAITING_CODE = 1;
@ -315,7 +315,7 @@ class MTProto extends \Volatile
$this->updates_state['sync_loading'] = isset($trace['args'][1]) && $trace['args'][1]; $this->updates_state['sync_loading'] = isset($trace['args'][1]) && $trace['args'][1];
} }
} }
$force = false;
$this->reset_session(); $this->reset_session();
if (!isset($this->v) || $this->v !== self::V) { if (!isset($this->v) || $this->v !== self::V) {
\danog\MadelineProto\Logger::log(['Serialization is out of date, reconstructing object!'], Logger::WARNING); \danog\MadelineProto\Logger::log(['Serialization is out of date, reconstructing object!'], Logger::WARNING);
@ -347,6 +347,7 @@ class MTProto extends \Volatile
$this->reset_session(true, true); $this->reset_session(true, true);
$this->config = ['expires' => -1]; $this->config = ['expires' => -1];
$this->__construct($settings); $this->__construct($settings);
$force = true;
} }
$this->setup_threads(); $this->setup_threads();
$this->datacenter->__construct($this->settings['connection'], $this->settings['connection_settings']); $this->datacenter->__construct($this->settings['connection'], $this->settings['connection_settings']);
@ -355,7 +356,7 @@ class MTProto extends \Volatile
$this->get_cdn_config($this->datacenter->curdc); $this->get_cdn_config($this->datacenter->curdc);
} }
if ($this->authorized === self::LOGGED_IN && !$this->authorization['user']['bot']) { if ($this->authorized === self::LOGGED_IN && !$this->authorization['user']['bot']) {
$this->get_dialogs(); $this->get_dialogs($force);
} }
if ($this->authorized === self::LOGGED_IN && $this->settings['updates']['handle_updates'] && !$this->updates_state['sync_loading']) { if ($this->authorized === self::LOGGED_IN && $this->settings['updates']['handle_updates'] && !$this->updates_state['sync_loading']) {
\danog\MadelineProto\Logger::log(['Getting updates after deserialization...'], Logger::NOTICE); \danog\MadelineProto\Logger::log(['Getting updates after deserialization...'], Logger::NOTICE);

View File

@ -287,10 +287,15 @@ trait Files
try { try {
$res = $cdn ? $this->method_call('upload.getCdnFile', ['file_token' => $message_media['file_token'], 'offset' => $offset, 'limit' => $part_size], ['heavy' => true, 'datacenter' => $datacenter]) : $this->method_call('upload.getFile', ['location' => $message_media['InputFileLocation'], 'offset' => $offset, 'limit' => $part_size], ['heavy' => true, 'datacenter' => &$datacenter]); $res = $cdn ? $this->method_call('upload.getCdnFile', ['file_token' => $message_media['file_token'], 'offset' => $offset, 'limit' => $part_size], ['heavy' => true, 'datacenter' => $datacenter]) : $this->method_call('upload.getFile', ['location' => $message_media['InputFileLocation'], 'offset' => $offset, 'limit' => $part_size], ['heavy' => true, 'datacenter' => &$datacenter]);
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
if ($e->rpc === 'OFFSET_INVALID') { switch ($e->rpc) {
case 'OFFSET_INVALID':
\Rollbar\Rollbar::log(\Rollbar\Payload\Level::error(), $e->rpc, ['info' => $message_media, 'offset' => $offset]); \Rollbar\Rollbar::log(\Rollbar\Payload\Level::error(), $e->rpc, ['info' => $message_media, 'offset' => $offset]);
break; break;
} else { case 'FILE_TOKEN_INVALID':
$cdn = false;
continue 2;
default:
throw $e; throw $e;
} }
} }
@ -306,7 +311,20 @@ trait Files
} }
if ($res['_'] === 'upload.cdnFileReuploadNeeded') { if ($res['_'] === 'upload.cdnFileReuploadNeeded') {
\danog\MadelineProto\Logger::log(['File is not stored on CDN, requesting reupload!'], \danog\MadelineProto\Logger::NOTICE); \danog\MadelineProto\Logger::log(['File is not stored on CDN, requesting reupload!'], \danog\MadelineProto\Logger::NOTICE);
try {
$this->add_cdn_hashes($message_media['file_token'], $this->method_call('upload.reuploadCdnFile', ['file_token' => $message_media['file_token'], 'request_token' => $res['request_token']], ['heavy' => true, 'datacenter' => $old_dc])); $this->add_cdn_hashes($message_media['file_token'], $this->method_call('upload.reuploadCdnFile', ['file_token' => $message_media['file_token'], 'request_token' => $res['request_token']], ['heavy' => true, 'datacenter' => $old_dc]));
} catch (\danog\MadelineProto\RPCErrorException $e) {
switch ($e->rpc) {
case 'FILE_TOKEN_INVALID':
case 'REQUEST_TOKEN_INVALID':
$cdn = false;
continue 2;
default:
throw $e;
}
}
continue; continue;
} }
if ($cdn === false && $res['type']['_'] === 'storage.fileUnknown' && $res['bytes'] === '') { if ($cdn === false && $res['type']['_'] === 'storage.fileUnknown' && $res['bytes'] === '') {

View File

@ -326,7 +326,7 @@ trait PeerHandler
switch ($full['type']) { switch ($full['type']) {
case 'user': case 'user':
case 'bot': case 'bot':
foreach (['first_name', 'last_name', 'username', 'verified', 'restricted', 'restriction_reason', 'status', 'bot_inline_placeholder', 'access_hash', 'phone', 'lang_code'] as $key) { foreach (['first_name', 'last_name', 'username', 'verified', 'restricted', 'restriction_reason', 'status', 'bot_inline_placeholder', 'access_hash', 'phone', 'lang_code', 'bot_nochats'] as $key) {
if (isset($full['User'][$key])) { if (isset($full['User'][$key])) {
$res[$key] = $full['User'][$key]; $res[$key] = $full['User'][$key];
} }
@ -412,9 +412,27 @@ trait PeerHandler
if (isset($participant['inviter_id'])) { if (isset($participant['inviter_id'])) {
$newres['inviter'] = $this->get_pwr_chat($participant['inviter_id'], false, false); $newres['inviter'] = $this->get_pwr_chat($participant['inviter_id'], false, false);
} }
if (isset($participant['promoted_by'])) {
$newres['promoted_by'] = $this->get_pwr_chat($participant['promoted_by'], false, false);
}
if (isset($participant['kicked_by'])) {
$newres['kicked_by'] = $this->get_pwr_chat($participant['kicked_by'], false, false);
}
if (isset($participant['date'])) { if (isset($participant['date'])) {
$newres['date'] = $participant['date']; $newres['date'] = $participant['date'];
} }
if (isset($participant['admin_rights'])) {
$newres['admin_rights'] = $participant['admin_rights'];
}
if (isset($participant['banned_rights'])) {
$newres['banned_rights'] = $participant['banned_rights'];
}
if (isset($participant['can_edit'])) {
$newres['can_edit'] = $participant['can_edit'];
}
if (isset($participant['left'])) {
$newres['left'] = $participant['left'];
}
switch ($participant['_']) { switch ($participant['_']) {
case 'chatParticipant': case 'chatParticipant':
$newres['role'] = 'user'; $newres['role'] = 'user';
@ -435,49 +453,67 @@ trait PeerHandler
$res['participants'] = []; $res['participants'] = [];
$limit = 200; $limit = 200;
$offset = -$limit; $offset = -$limit;
$filters = ['channelParticipantsBanned', 'channelParticipantsAdmins', 'channelParticipantsKicked', 'channelParticipantsBots', 'channelParticipantsRecent'];
$gres = $this->method_call('channels.getParticipants', ['channel' => $full['InputChannel'], 'filter' => ['_' => 'channelParticipantsRecent'], 'offset' => $offset += $limit, 'limit' => $limit], ['datacenter' => $this->datacenter->curdc]); $gres = $this->method_call('channels.getParticipants', ['channel' => $full['InputChannel'], 'filter' => ['_' => 'channelParticipantsRecent'], 'offset' => $offset += $limit, 'limit' => $limit], ['datacenter' => $this->datacenter->curdc]);
$count = $gres['count']; $count = $gres['count'];
$key = -1; while (count($filters)) {
$filter = array_pop($filters);
while ($offset <= $count) { while ($offset <= $count) {
foreach ($gres['participants'] as $participant) { foreach ($gres['participants'] as $participant) {
$newres = []; $newres = [];
$newres['user'] = $this->get_pwr_chat($participant['user_id'], false, false); $newres['user'] = $this->get_pwr_chat($participant['user_id'], false, false);
$key++;
if (isset($participant['inviter_id'])) { if (isset($participant['inviter_id'])) {
$newres['inviter'] = $this->get_pwr_chat($participant['inviter_id'], false, false); $newres['inviter'] = $this->get_pwr_chat($participant['inviter_id'], false, false);
} }
if (isset($participant['kicked_by'])) {
$newres['kicked_by'] = $this->get_pwr_chat($participant['kicked_by'], false, false);
}
if (isset($participant['promoted_by'])) {
$newres['promoted_by'] = $this->get_pwr_chat($participant['promoted_by'], false, false);
}
if (isset($participant['date'])) { if (isset($participant['date'])) {
$newres['date'] = $participant['date']; $newres['date'] = $participant['date'];
} }
switch ($participant['_']) { switch ($participant['_']) {
case 'channelParticipantSelf':
$newres['role'] = 'user';
if (isset($newres['admin_rights'])) {
$newres['admin_rights'] = $full['Chat']['admin_rights'];
}
if (isset($newres['banned_rights'])) {
$newres['banned_rights'] = $full['Chat']['banned_rights'];
}
break;
case 'channelParticipant': case 'channelParticipant':
$newres['role'] = 'user'; $newres['role'] = 'user';
break; break;
case 'channelParticipantModerator':
$newres['role'] = 'moderator';
break;
case 'channelParticipantEditor':
$newres['role'] = 'editor';
break;
case 'channelParticipantCreator': case 'channelParticipantCreator':
$newres['role'] = 'creator'; $newres['role'] = 'creator';
break; break;
case 'channelParticipantKicked': case 'channelParticipantAdmin':
$newres['role'] = 'kicked'; $newres['role'] = 'admin';
break;
case 'channelParticipantBanned':
$newres['role'] = 'banned';
break; break;
} }
$res['participants'][$key] = $newres; $res['participants'][$participant['user_id']] = $newres;
} }
$gres = $this->method_call('channels.getParticipants', ['channel' => $full['InputChannel'], 'filter' => ['_' => 'channelParticipantsRecent'], 'offset' => $offset += $limit, 'limit' => $limit], ['datacenter' => $this->datacenter->curdc]); $gres = $this->method_call('channels.getParticipants', ['channel' => $full['InputChannel'], 'filter' => ['_' => $filter, 'q' => ''], 'offset' => $offset += $limit, 'limit' => $limit], ['datacenter' => $this->datacenter->curdc]);
if (empty($gres['participants'])) { if (empty($gres['participants'])) {
break; break;
} }
} }
if ($offset >= $count) {
break;
}
}
} }
if ($fullfetch || $send) { if ($fullfetch || $send) {
$this->store_db($res); $this->store_db($res);

View File

@ -408,7 +408,10 @@ trait BotAPI
$text = $this->html_entity_decode($node->textContent); $text = $this->html_entity_decode($node->textContent);
$href = $node->getAttribute('href'); $href = $node->getAttribute('href');
if (preg_match('|mention:|', $href)) { if (preg_match('|mention:|', $href)) {
$entities[] = ['_' => 'inputMessageEntityMentionName', 'offset' => mb_strlen($nmessage), 'length' => mb_strlen($text), 'user_id' => $this->get_info(str_replace('mention:', '', $href))['InputUser']]; if (!isset(($mention = $this->get_info(str_replace('mention:', '', $href)))['InputUser'])) {
throw new \danog\MadelineProto\Exception('This peer is not present in the internal peer database');
}
$entities[] = ['_' => 'inputMessageEntityMentionName', 'offset' => mb_strlen($nmessage), 'length' => mb_strlen($text), 'user_id' => $mention['InputUser']];
} elseif (preg_match('|buttonurl:|', $href)) { } elseif (preg_match('|buttonurl:|', $href)) {
if (!isset($entities['buttons'])) { if (!isset($entities['buttons'])) {
$entities['buttons'] = []; $entities['buttons'] = [];

View File

@ -34,10 +34,10 @@ trait PrettyException
if ($tl) { if ($tl) {
$this->tl_trace .= PHP_EOL; $this->tl_trace .= PHP_EOL;
} }
if (isset($frame['function']) && $frame['function'] === 'handle_rpc_error' && $k === count($this->getTrace()) - 1) { if (isset($frame['function']) && ($frame['function'] === 'handle_rpc_error' && $k === count($this->getTrace()) - 1) || $frame['function'] === 'unserialize') {
continue; continue;
} }
$this->tl_trace .= isset($frame['file']) ? str_pad(basename($frame['file']).'('.$frame['line'].'):', 16)."\t" : ''; $this->tl_trace .= isset($frame['file']) ? str_pad(basename($frame['file']).'('.$frame['line'].'):', 20)."\t" : '';
$this->tl_trace .= isset($frame['function']) ? $frame['function'].'(' : ''; $this->tl_trace .= isset($frame['function']) ? $frame['function'].'(' : '';
$this->tl_trace .= isset($frame['args']) ? substr(json_encode($frame['args']), 1, -1) : ''; $this->tl_trace .= isset($frame['args']) ? substr(json_encode($frame['args']), 1, -1) : '';
$this->tl_trace .= ')'; $this->tl_trace .= ')';

View File

@ -73,7 +73,14 @@ trait AuthKeyHandler
$b = \phpseclib\Math\BigInteger::randomRange($this->two, $dh_config['p']->subtract($this->two)); $b = \phpseclib\Math\BigInteger::randomRange($this->two, $dh_config['p']->subtract($this->two));
$g_b = $dh_config['g']->powMod($b, $dh_config['p']); $g_b = $dh_config['g']->powMod($b, $dh_config['p']);
$this->check_G($g_b, $dh_config['p']); $this->check_G($g_b, $dh_config['p']);
try {
$res = $this->method_call('phone.acceptCall', ['peer' => $call, 'g_b' => $g_b->toBytes(), 'protocol' => ['_' => 'phoneCallProtocol', 'udp_reflector' => true, 'udp_p2p' => true, 'min_layer' => 65, 'max_layer' => 65]], ['datacenter' => $this->datacenter->curdc]); $res = $this->method_call('phone.acceptCall', ['peer' => $call, 'g_b' => $g_b->toBytes(), 'protocol' => ['_' => 'phoneCallProtocol', 'udp_reflector' => true, 'udp_p2p' => true, 'min_layer' => 65, 'max_layer' => 65]], ['datacenter' => $this->datacenter->curdc]);
} catch (\danog\MadelineProto\RPCErrorException $e) {
if ($e->RPC === 'CALL_ALREADY_ACCEPTED') {
return true;
}
throw $e;
}
$this->calls[$res['phone_call']['id']]->storage['b'] = $b; $this->calls[$res['phone_call']['id']]->storage['b'] = $b;
$this->handle_pending_updates(); $this->handle_pending_updates();

View File

@ -16,22 +16,20 @@ trait DialogHandler
{ {
public function get_dialogs($force = false) public function get_dialogs($force = false)
{ {
if (!isset($this->dialog_params['offset_date']) || $force) { if (!isset($this->dialog_params['offset_date']) || $force || is_null($this->dialog_params['offset_date'])) {
$this->dialog_params = ['limit' => 0, 'offset_date' => 0, 'offset_id' => 0, 'offset_peer' => ['_' => 'inputPeerEmpty']]; $this->dialog_params = ['limit' => 0, 'offset_date' => 0, 'offset_id' => 0, 'offset_peer' => ['_' => 'inputPeerEmpty'], 'count' => 0];
} }
$this->updates_state['sync_loading'] = true; $this->updates_state['sync_loading'] = true;
$res = ['dialogs' => [0], 'count' => 1]; $res = ['dialogs' => [0], 'count' => 1];
$datacenter = $this->datacenter->curdc; $datacenter = $this->datacenter->curdc;
$count = 0; while ($this->dialog_params['count'] < $res['count']) {
while ($count < $res['count']) {
\danog\MadelineProto\Logger::log(['Getting dialogs...']); \danog\MadelineProto\Logger::log(['Getting dialogs...']);
$res = $this->method_call('messages.getDialogs', $this->dialog_params, ['datacenter' => $datacenter, 'FloodWaitLimit' => 100]); $res = $this->method_call('messages.getDialogs', $this->dialog_params, ['datacenter' => $datacenter, 'FloodWaitLimit' => 100]);
$count += count($res['dialogs']); $this->dialog_params['count'] += count($res['dialogs']);
$old_params = $this->dialog_params;
$this->dialog_params['offset_date'] = end($res['messages'])['date']; $this->dialog_params['offset_date'] = end($res['messages'])['date'];
$this->dialog_params['offset_peer'] = end($res['dialogs'])['peer']; $this->dialog_params['offset_peer'] = end($res['dialogs'])['peer'];
$this->dialog_params['offset_id'] = end($res['messages'])['id']; $this->dialog_params['offset_id'] = end($res['messages'])['id'];
if ($this->dialog_params === $old_params) { if (!isset($res['count'])) {
break; break;
} }
} }