From c638ad10acf420fbbe57d280dae74813a54dde7c Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Sat, 3 Mar 2018 23:41:26 +0000 Subject: [PATCH] Performance improvements and documentation fixes --- docs/FullInfo.md | 12 ++++- .../MTProtoTools/PeerHandler.php | 28 ++++++---- .../MadelineProto/TL/Conversion/BotAPI.php | 52 ++++++++++++++----- src/danog/MadelineProto/TL/TL.php | 12 ++--- src/danog/MadelineProto/TL/TLParams.php | 19 +++---- 5 files changed, 77 insertions(+), 46 deletions(-) diff --git a/docs/FullInfo.md b/docs/FullInfo.md index e306f56f..690dcf8e 100644 --- a/docs/FullInfo.md +++ b/docs/FullInfo.md @@ -10,6 +10,14 @@ description: chat attributes, type and example | Name | Type | Required |Description| |----------|---------------|----------|-----------| -|partial|[Info](Info.md) | Yes|Info object| -|last_update|[int](API_docs/types/int.md) | Yes|unixdate| +|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| +|last_update|[int](API_docs/types/int.md) | Yes|When was info about this peer cached| |full|[ChatFull](API_docs/types/ChatFull.md) or [UserFull](API_docs/types/UserFull.md) | Yes|full info| diff --git a/src/danog/MadelineProto/MTProtoTools/PeerHandler.php b/src/danog/MadelineProto/MTProtoTools/PeerHandler.php index 102bbc00..9f25aba2 100644 --- a/src/danog/MadelineProto/MTProtoTools/PeerHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/PeerHandler.php @@ -18,6 +18,16 @@ namespace danog\MadelineProto\MTProtoTools; */ trait PeerHandler { + + public function to_supergroup($id) + { + return -($id + pow(10, (int) floor(log($id, 10) + 3))); + } + public function is_supergroup($id) + { + $log = log(-$id, 10); + return ($log-intval($log))*1000<10; + } public function add_users($users) { foreach ($users as $key => $user) { @@ -185,21 +195,21 @@ trait PeerHandler } } if (is_string($id) && strpos($id, '#') !== false) { - if (preg_match('/^channel#/', $id)) { - $id = $this->to_supergroup(preg_replace('|\\D+|', '', $id)); + if (preg_match('/^channel#(\d*)/', $id, $matches)) { + $id = $this->to_supergroup($matches[1]); } - if (preg_match('/^chat#/', $id)) { - $id = preg_replace('|\\D+|', '-', $id); + if (preg_match('/^chat#(\d*)/', $id, $matches)) { + $id = '-'.$matches[1]; } - if (preg_match('/^user#/', $id)) { - $id = preg_replace('|\\D+|', '', $id); + if (preg_match('/^user#(\d*)/', $id, $marches)) { + $id = $matches[1]; } } if (is_numeric($id)) { if (is_string($id)) { $id = \danog\MadelineProto\Logger::$bigint ? (float) $id : (int) $id; } - if (!isset($this->chats[$id]) && $id < 0 && !preg_match('/^-100/', $id)) { + if (!isset($this->chats[$id]) && $id < 0 && !$this->is_supergroup($id)) { $this->method_call('messages.getFullChat', ['chat_id' => -$id], ['datacenter' => $this->datacenter->curdc]); } if (isset($this->chats[$id])) { @@ -572,8 +582,4 @@ trait PeerHandler return false; } - public function to_supergroup($id) - { - return -($id + pow(10, (int) floor(log($id, 10) + 3))); - } } diff --git a/src/danog/MadelineProto/TL/Conversion/BotAPI.php b/src/danog/MadelineProto/TL/Conversion/BotAPI.php index 7471b37e..38cd0574 100644 --- a/src/danog/MadelineProto/TL/Conversion/BotAPI.php +++ b/src/danog/MadelineProto/TL/Conversion/BotAPI.php @@ -23,8 +23,9 @@ trait BotAPI public function mb_strlen($text) { $length = 0; - foreach (str_split($text) as $char) { - $char = ord($char); + $textlength = strlen($text); + for ($x = 0; $x < $textlength; $x++) { + $char = ord($text[$x]); if (($char & 0xC0) != 0x80) { $length += 1 + ($char >= 0xf0); } @@ -347,69 +348,91 @@ trait BotAPI return $arguments; } - public function parse_node($node, &$entities, &$new_message, $recursive = true) + public function parse_node($node, &$entities, &$new_message, &$offset) { switch ($node->nodeName) { case 'br': $new_message .= "\n"; + $offset++; break; case 'b': case 'strong': $text = $this->html_entity_decode($node->textContent); - $entities[] = ['_' => 'messageEntityBold', 'offset' => $this->mb_strlen($new_message), 'length' => $this->mb_strlen($text)]; + + $length = $this->mb_strlen($text); + $entities[] = ['_' => 'messageEntityBold', 'offset' => $offset, 'length' => $length]; + $new_message .= $text; + $offset += $length; break; case 'i': case 'em': $text = $this->html_entity_decode($node->textContent); - $entities[] = ['_' => 'messageEntityItalic', 'offset' => $this->mb_strlen($new_message), 'length' => $this->mb_strlen($text)]; + + $length = $this->mb_strlen($text); + $entities[] = ['_' => 'messageEntityItalic', 'offset' => $offset, 'length' => $length]; + $new_message .= $text; + $offset += $length; break; case 'code': $text = $this->html_entity_decode($node->textContent); - $entities[] = ['_' => 'messageEntityCode', 'offset' => $this->mb_strlen($new_message), 'length' => $this->mb_strlen($text)]; + + $length = $this->mb_strlen($text); + $entities[] = ['_' => 'messageEntityCode', 'offset' => $offset, 'length' => $length]; + $new_message .= $text; + $offset += $length; break; case 'pre': $text = $this->html_entity_decode($node->textContent); + + $length = $this->mb_strlen($text); + $language = $node->getAttribute('language'); if ($language === null) { $language = ''; } - $entities[] = ['_' => 'messageEntityPre', 'offset' => $this->mb_strlen($new_message), 'length' => $this->mb_strlen($text), 'language' => $language]; + $entities[] = ['_' => 'messageEntityPre', 'offset' => $offset, 'length' => $length, 'language' => $language]; $new_message .= $text; + $offset += $length; break; case 'p': foreach ($node->childNodes as $node) { - $this->parse_node($node, $entities, $new_message); + $this->parse_node($node, $entities, $new_message, $offset); } break; case 'a': $text = $this->html_entity_decode($node->textContent); + $length = $this->mb_strlen($text); $href = $node->getAttribute('href'); if (preg_match('|mention:(.*)|', $href, $matches) || preg_match('|tg://user\?id=(.*)|', $href, $matches)) { $mention = $this->get_info($matches[1]); if (!isset($mention['InputUser'])) { throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['peer_not_in_db']); } - $entities[] = ['_' => 'inputMessageEntityMentionName', 'offset' => $this->mb_strlen($new_message), 'length' => $this->mb_strlen($text), 'user_id' => $mention['InputUser']]; + $entities[] = ['_' => 'inputMessageEntityMentionName', 'offset' => $offset, 'length' => $length, 'user_id' => $mention['InputUser']]; } elseif (preg_match('|buttonurl:(.*)|', $href)) { if (!isset($entities['buttons'])) { $entities['buttons'] = []; } - if (preg_match('|:new|', substr($href, -4))) { - $entities['buttons'][] = ['_' => 'keyboardButtonUrl', 'text' => $text, 'url' => str_replace('buttonurl:', '', str_replace(':new', '', $href)), 'new' => true]; + if (strpos(substr($href, -4), '|:new|') !== false) { + $entities['buttons'][] = ['_' => 'keyboardButtonUrl', 'text' => $text, 'url' => str_replace(['buttonurl:', ':new'], '', $href), 'new' => true]; } else { $entities['buttons'][] = ['_' => 'keyboardButtonUrl', 'text' => $text, 'url' => str_replace('buttonurl:', '', $href)]; } break; } else { - $entities[] = ['_' => 'messageEntityTextUrl', 'offset' => $this->mb_strlen($new_message), 'length' => $this->mb_strlen($text), 'url' => $href]; + $entities[] = ['_' => 'messageEntityTextUrl', 'offset' => $offset, 'length' => $length, 'url' => $href]; } $new_message .= $text; + $offset += $length; break; default: - $new_message .= $this->html_entity_decode($node->nodeValue); + $text = $this->html_entity_decode($node->textContent); + $length = $this->mb_strlen($text); + $new_message .= $text; + $offset += $length; break; } } @@ -432,8 +455,9 @@ trait BotAPI if (!isset($arguments['entities'])) { $arguments['entities'] = []; } + $offset = 0; foreach ($dom->getElementsByTagName('body')->item(0)->childNodes as $node) { - $this->parse_node($node, $arguments['entities'], $new_message); + $this->parse_node($node, $arguments['entities'], $new_message, $offset); } if (isset($arguments['entities']['buttons'])) { $arguments['reply_markup'] = $this->build_rows($arguments['entities']['buttons']); diff --git a/src/danog/MadelineProto/TL/TL.php b/src/danog/MadelineProto/TL/TL.php index 55fde0b7..8031de4e 100644 --- a/src/danog/MadelineProto/TL/TL.php +++ b/src/danog/MadelineProto/TL/TL.php @@ -85,14 +85,14 @@ trait TL $type = 'constructors'; continue; } - if (preg_match('|^===\\d*===|', $line)) { - $layer = (int) preg_replace('|\\D*|', '', $line); + if (preg_match('|^===(\d*)===|', $line, $matches)) { + $layer = (int) $matches[1]; continue; } - if (preg_match('/^vector#/', $line)) { + if (strpos($line, 'vector#') === 0) { continue; } - if (preg_match('/ \\?= /', $line)) { + if (strpos($line, ' ?= ') !== false) { continue; } $name = preg_replace(['/#.*/', '/\\s.*/'], '', $line); @@ -101,8 +101,8 @@ trait TL } $clean = preg_replace(['/:bytes /', '/;/', '/#[a-f0-9]+ /', '/ [a-zA-Z0-9_]+\\:flags\\.[0-9]+\\?true/', '/[<]/', '/[>]/', '/ /', '/^ /', '/ $/', '/\\?bytes /', '/{/', '/}/'], [':string ', '', ' ', '', ' ', ' ', ' ', '', '', '?string ', '', ''], $line); $id = hash('crc32b', $clean); - if (preg_match('/^[^\\s]+#/', $line)) { - $nid = str_pad(preg_replace(['/^[^#]+#/', '/\\s.+/'], '', $line), 8, '0', \STR_PAD_LEFT); + if (preg_match('/^[^#]+#([a-f0-9]*)/i', $line, $matches)) { + $nid = str_pad($matches[1], 8, '0', \STR_PAD_LEFT); if ($id !== $nid && $scheme_type !== 'botAPI') { \danog\MadelineProto\Logger::log(sprintf(\danog\MadelineProto\Lang::$current_lang['crc32_mismatch'], $id, $nid, $line), \danog\MadelineProto\Logger::ERROR); } diff --git a/src/danog/MadelineProto/TL/TLParams.php b/src/danog/MadelineProto/TL/TLParams.php index 8c774ca3..d9e0ef8b 100644 --- a/src/danog/MadelineProto/TL/TLParams.php +++ b/src/danog/MadelineProto/TL/TLParams.php @@ -18,20 +18,13 @@ trait TLParams public function parse_params($key, $mtproto = false) { foreach ($this->by_id[$key]['params'] as $kkey => $param) { - if (preg_match('/^flags\\.\\d*\\?/', $param['type'])) { - $flag = explode('?', explode('flags.', $param['type'])[1]); - $param['pow'] = pow(2, $flag[0]); - $param['type'] = $flag[1]; + if (preg_match('/^flags\.(\d*)\?(.*)/', $param['type'], $matches)) { + $param['pow'] = pow(2, $matches[1]); + $param['type'] = $matches[2]; } - if (preg_match('/vector<.*>/i', $param['type'])) { - if (preg_match('/vector/', $param['type'])) { - $param['subtype'] = preg_replace(['/.*$/'], '', $param['type']); - $param['type'] = 'vector'; - } - if (preg_match('/Vector/', $param['type'])) { - $param['subtype'] = preg_replace(['/.*$/'], '', $param['type']); - $param['type'] = 'Vector t'; - } + if (preg_match('/(v)ector<(.*)>/i', $param['type'], $matches)) { + $param['type'] = $matches[1] === 'v' ? 'vector': 'Vector t'; + $param['subtype'] = $matches[2]; $param['subtype'] = ($mtproto && $param['subtype'] === 'Message' ? 'MT' : '').$param['subtype']; $param['subtype'] = $mtproto && $param['subtype'] === '%Message' ? '%MTMessage' : $param['subtype']; }