*/
- public function uploadEncrypted($file, string $fileName = '', $cb = null): \Generator
+ public function uploadEncrypted($file, string $fileName = '', $cb = null): \Generator
{
return $this->upload($file, $fileName, $cb, true);
}
-
/**
* Reupload telegram file.
*
@@ -394,15 +357,13 @@ trait Files
$cb = $media;
$media = $media->getFile();
}
- $media = yield $this->getDownloadInfo($media);
+ $media = (yield from $this->getDownloadInfo($media));
if (!isset($media['size'], $media['mime'])) {
throw new Exception('Wrong file provided!');
}
$size = $media['size'];
$mime = $media['mime'];
-
$chunk_size = $this->settings['upload']['part_size'];
-
$bridge = new class($size, $chunk_size, $cb) {
/**
* Read promises.
@@ -440,7 +401,6 @@ trait Files
* @var ?callable
*/
private $cb;
-
/**
* Constructor.
*
@@ -451,9 +411,9 @@ trait Files
public function __construct(int $size, int $partSize, ?callable $cb)
{
for ($x = 0; $x < $size; $x += $partSize) {
- $this->read []= new Deferred;
- $this->write []= new Deferred;
- $this->wrote []= $size - $x < $partSize ? $size - $x : $partSize;
+ $this->read[] = new Deferred();
+ $this->write[] = new Deferred();
+ $this->wrote[] = $size - $x < $partSize ? $size - $x : $partSize;
}
$this->partSize = $partSize;
$this->cb = $cb;
@@ -504,16 +464,12 @@ trait Files
$reader = [$bridge, 'read'];
$writer = [$bridge, 'write'];
$cb = [$bridge, 'callback'];
-
$read = $this->uploadFromCallable($reader, $size, $mime, '', $cb, true, $encrypted);
$write = $this->downloadToCallable($media, $writer, null, true, 0, -1, $chunk_size);
-
list($res) = yield \danog\MadelineProto\Tools::all([$read, $write]);
-
return $res;
}
-
- private function genAllFile($media)
+ private function genAllFile($media): \Generator
{
$res = [$this->TL->getConstructors()->findByPredicate($media['_'])['type'] => $media];
switch ($media['_']) {
@@ -531,15 +487,7 @@ trait Files
throw new \danog\MadelineProto\Exception('No access hash');
}
$res['Photo'] = $media['photo'];
- $res['InputPhoto'] = [
- '_' => 'inputPhoto',
- 'id' => $media['photo']['id'],
- 'access_hash' => $media['photo']['access_hash'],
- 'file_reference' => yield $this->referenceDatabase->getReference(
- ReferenceDatabase::PHOTO_LOCATION,
- $media['photo']
- ),
- ];
+ $res['InputPhoto'] = ['_' => 'inputPhoto', 'id' => $media['photo']['id'], 'access_hash' => $media['photo']['access_hash'], 'file_reference' => yield $this->referenceDatabase->getReference(ReferenceDatabase::PHOTO_LOCATION, $media['photo'])];
$res['InputMedia'] = ['_' => 'inputMediaPhoto', 'id' => $res['InputPhoto']];
if (isset($media['ttl_seconds'])) {
$res['InputMedia']['ttl_seconds'] = $media['ttl_seconds'];
@@ -550,15 +498,7 @@ trait Files
throw new \danog\MadelineProto\Exception('No access hash');
}
$res['Document'] = $media['document'];
- $res['InputDocument'] = [
- '_' => 'inputDocument',
- 'id' => $media['document']['id'],
- 'access_hash' => $media['document']['access_hash'],
- 'file_reference' => yield $this->referenceDatabase->getReference(
- ReferenceDatabase::DOCUMENT_LOCATION,
- $media['document']
- ),
- ];
+ $res['InputDocument'] = ['_' => 'inputDocument', 'id' => $media['document']['id'], 'access_hash' => $media['document']['access_hash'], 'file_reference' => yield $this->referenceDatabase->getReference(ReferenceDatabase::DOCUMENT_LOCATION, $media['document'])];
$res['InputMedia'] = ['_' => 'inputMediaDocument', 'id' => $res['InputDocument']];
if (isset($media['ttl_seconds'])) {
$res['InputMedia']['ttl_seconds'] = $media['ttl_seconds'];
@@ -571,15 +511,7 @@ trait Files
if (!isset($media['access_hash'])) {
throw new \danog\MadelineProto\Exception('No access hash');
}
- $res['InputDocument'] = [
- '_' => 'inputDocument',
- 'id' => $media['id'],
- 'access_hash' => $media['access_hash'],
- 'file_reference' => yield $this->referenceDatabase->getReference(
- ReferenceDatabase::DOCUMENT_LOCATION,
- $media
- ),
- ];
+ $res['InputDocument'] = ['_' => 'inputDocument', 'id' => $media['id'], 'access_hash' => $media['access_hash'], 'file_reference' => yield $this->referenceDatabase->getReference(ReferenceDatabase::DOCUMENT_LOCATION, $media)];
$res['InputMedia'] = ['_' => 'inputMediaDocument', 'id' => $res['InputDocument']];
$res['MessageMedia'] = ['_' => 'messageMediaDocument', 'document' => $media];
break;
@@ -587,25 +519,15 @@ trait Files
if (!isset($media['access_hash'])) {
throw new \danog\MadelineProto\Exception('No access hash');
}
- $res['InputPhoto'] = [
- '_' => 'inputPhoto',
- 'id' => $media['id'],
- 'access_hash' => $media['access_hash'],
- 'file_reference' => yield $this->referenceDatabase->getReference(
- ReferenceDatabase::PHOTO_LOCATION,
- $media
- ),
- ];
+ $res['InputPhoto'] = ['_' => 'inputPhoto', 'id' => $media['id'], 'access_hash' => $media['access_hash'], 'file_reference' => yield $this->referenceDatabase->getReference(ReferenceDatabase::PHOTO_LOCATION, $media)];
$res['InputMedia'] = ['_' => 'inputMediaPhoto', 'id' => $res['InputPhoto']];
$res['MessageMedia'] = ['_' => 'messageMediaPhoto', 'photo' => $media];
break;
default:
throw new \danog\MadelineProto\Exception("Could not convert media object of type {$media['_']}");
}
-
return $res;
}
-
/**
* Get info about file.
*
@@ -632,13 +554,11 @@ trait Files
case 'updateEditMessage':
case 'updateEditChannelMessage':
$constructor = $constructor['message'];
-
- // no break
+ // no break
case 'message':
$constructor = $constructor['media'];
}
-
- return yield $this->genAllFile($constructor);
+ return yield from $this->genAllFile($constructor);
}
/**
* Get download info of the propic of a user
@@ -655,7 +575,7 @@ trait Files
*/
public function getPropicInfo($data): \Generator
{
- return yield $this->getDownloadInfo($this->chats[(yield $this->getInfo($data))['bot_api_id']]);
+ return yield from $this->getDownloadInfo($this->chats[(yield $this->getInfo($data))['bot_api_id']]);
}
/**
* Get download info of file
@@ -688,17 +608,16 @@ trait Files
case 'updateNewMessage':
case 'updateNewChannelMessage':
$message_media = $message_media['message'];
- // no break
+ // no break
case 'message':
- return yield $this->getDownloadInfo($message_media['media']);
+ return yield from $this->getDownloadInfo($message_media['media']);
case 'updateNewEncryptedMessage':
$message_media = $message_media['message'];
-
// Secret media
// no break
case 'encryptedMessage':
if ($message_media['decrypted_message']['media']['_'] === 'decryptedMessageMediaExternalDocument') {
- return yield $this->getDownloadInfo($message_media['decrypted_message']['media']);
+ return yield from $this->getDownloadInfo($message_media['decrypted_message']['media']);
}
$res['InputFileLocation'] = ['_' => 'inputEncryptedFileLocation', 'id' => $message_media['file']['id'], 'access_hash' => $message_media['file']['access_hash'], 'dc_id' => $message_media['file']['dc_id']];
$res['size'] = $message_media['decrypted_message']['media']['size'];
@@ -708,7 +627,7 @@ trait Files
if (isset($message_media['decrypted_message']['media']['file_name'])) {
$pathinfo = \pathinfo($message_media['decrypted_message']['media']['file_name']);
if (isset($pathinfo['extension'])) {
- $res['ext'] = '.'.$pathinfo['extension'];
+ $res['ext'] = '.' . $pathinfo['extension'];
}
$res['name'] = $pathinfo['filename'];
}
@@ -723,7 +642,7 @@ trait Files
case 'documentAttributeFilename':
$pathinfo = \pathinfo($attribute['file_name']);
if (isset($pathinfo['extension'])) {
- $res['ext'] = '.'.$pathinfo['extension'];
+ $res['ext'] = '.' . $pathinfo['extension'];
}
$res['name'] = $pathinfo['filename'];
break;
@@ -736,7 +655,7 @@ trait Files
if (isset($audio) && isset($audio['title']) && !isset($res['name'])) {
$res['name'] = $audio['title'];
if (isset($audio['performer'])) {
- $res['name'] .= ' - '.$audio['performer'];
+ $res['name'] .= ' - ' . $audio['performer'];
}
}
if (!isset($res['ext']) || $res['ext'] === '') {
@@ -748,7 +667,6 @@ trait Files
if (!isset($res['name']) || $res['name'] === '') {
$res['name'] = Tools::unpackSignedLongString($message_media['file']['access_hash']);
}
-
return $res;
// Wallpapers
case 'wallPaper':
@@ -762,132 +680,89 @@ trait Files
$res['MessageMedia'] = $message_media;
$message_media = $message_media['photo'];
$size = \end($message_media['sizes']);
-
- $res = \array_merge($res, yield $this->getDownloadInfo($size));
-
- $res['InputFileLocation'] = [
- '_' => 'inputPhotoFileLocation',
- 'thumb_size' => $res['thumb_size'] ?? 'x',
- 'dc_id' => $message_media['dc_id'],
- 'access_hash' => $message_media['access_hash'],
- 'id' => $message_media['id'],
- 'file_reference' => yield $this->referenceDatabase->getReference(
- ReferenceDatabase::PHOTO_LOCATION,
- $message_media
- ),
- ];
-
+ $res = \array_merge($res, yield from $this->getDownloadInfo($size));
+ $res['InputFileLocation'] = ['_' => 'inputPhotoFileLocation', 'thumb_size' => $res['thumb_size'] ?? 'x', 'dc_id' => $message_media['dc_id'], 'access_hash' => $message_media['access_hash'], 'id' => $message_media['id'], 'file_reference' => yield $this->referenceDatabase->getReference(ReferenceDatabase::PHOTO_LOCATION, $message_media)];
return $res;
case 'user':
case 'folder':
case 'channel':
case 'chat':
case 'updateUserPhoto':
- $res = yield $this->getDownloadInfo($message_media['photo']);
-
- if (\is_array($message_media) && ($message_media['min'] ?? false) && isset($message_media['access_hash'])) { // bot API file ID
+ $res = (yield from $this->getDownloadInfo($message_media['photo']));
+ if (\is_array($message_media) && ($message_media['min'] ?? false) && isset($message_media['access_hash'])) {
+ // bot API file ID
$message_media['min'] = false;
$peer = $this->genAll($message_media)['InputPeer'];
} else {
$peer = (yield $this->getInfo($message_media))['InputPeer'];
}
- $res['InputFileLocation'] = [
- '_' => 'inputPeerPhotoFileLocation',
- 'big' => $res['big'],
- 'dc_id' => $res['InputFileLocation']['dc_id'],
- 'peer' => $peer,
- 'volume_id' => $res['InputFileLocation']['volume_id'],
- 'local_id' => $res['InputFileLocation']['local_id'],
- // The peer field will be added later
- ];
+ $res['InputFileLocation'] = ['_' => 'inputPeerPhotoFileLocation', 'big' => $res['big'], 'dc_id' => $res['InputFileLocation']['dc_id'], 'peer' => $peer, 'volume_id' => $res['InputFileLocation']['volume_id'], 'local_id' => $res['InputFileLocation']['local_id']];
return $res;
-
case 'userProfilePhoto':
case 'chatPhoto':
$size = $message_media['photo_big'] ?? $message_media['photo_small'];
-
- $res = yield $this->getDownloadInfo($size);
+ $res = (yield from $this->getDownloadInfo($size));
$res['big'] = isset($message_media['photo_big']);
$res['InputFileLocation']['dc_id'] = $message_media['dc_id'];
-
return $res;
case 'photoStrippedSize':
$res['size'] = \strlen($message_media['bytes']);
$res['data'] = $message_media['bytes'];
$res['thumb_size'] = 'JPG';
return $res;
-
case 'photoCachedSize':
$res['size'] = \strlen($message_media['bytes']);
$res['data'] = $message_media['bytes'];
//$res['thumb_size'] = $res['data'];
$res['thumb_size'] = $message_media['type'];
-
if ($message_media['location']['_'] === 'fileLocationUnavailable') {
- $res['name'] = Tools::unpackSignedLongString($message_media['volume_id']).'_'.$message_media['local_id'];
+ $res['name'] = Tools::unpackSignedLongString($message_media['volume_id']) . '_' . $message_media['local_id'];
$res['mime'] = $this->getMimeFromBuffer($res['data']);
$res['ext'] = $this->getExtensionFromMime($res['mime']);
} else {
- $res = \array_merge($res, yield $this->getDownloadInfo($message_media['location']));
+ $res = \array_merge($res, yield from $this->getDownloadInfo($message_media['location']));
}
-
return $res;
case 'photoSize':
- $res = yield $this->getDownloadInfo($message_media['location']);
-
+ $res = (yield from $this->getDownloadInfo($message_media['location']));
$res['thumb_size'] = $message_media['type'];
//$res['thumb_size'] = $size;
if (isset($message_media['size'])) {
$res['size'] = $message_media['size'];
}
-
return $res;
-
case 'fileLocationUnavailable':
throw new \danog\MadelineProto\Exception('File location unavailable');
case 'fileLocation':
- $res['name'] = Tools::unpackSignedLongString($message_media['volume_id']).'_'.$message_media['local_id'];
- $res['InputFileLocation'] = [
- '_' => 'inputFileLocation',
- 'volume_id' => $message_media['volume_id'],
- 'local_id' => $message_media['local_id'],
- 'secret' => $message_media['secret'],
- 'dc_id' => $message_media['dc_id'],
- 'file_reference' => yield $this->referenceDatabase->getReference(
- ReferenceDatabase::PHOTO_LOCATION_LOCATION,
- $message_media
- ),
- ];
+ $res['name'] = Tools::unpackSignedLongString($message_media['volume_id']) . '_' . $message_media['local_id'];
+ $res['InputFileLocation'] = ['_' => 'inputFileLocation', 'volume_id' => $message_media['volume_id'], 'local_id' => $message_media['local_id'], 'secret' => $message_media['secret'], 'dc_id' => $message_media['dc_id'], 'file_reference' => yield $this->referenceDatabase->getReference(ReferenceDatabase::PHOTO_LOCATION_LOCATION, $message_media)];
$res['ext'] = $this->getExtensionFromLocation($res['InputFileLocation'], '.jpg');
$res['mime'] = $this->getMimeFromExtension($res['ext'], 'image/jpeg');
-
return $res;
case 'fileLocationToBeDeprecated':
- $res['name'] = Tools::unpackSignedLongString($message_media['volume_id']).'_'.$message_media['local_id'];
+ $res['name'] = Tools::unpackSignedLongString($message_media['volume_id']) . '_' . $message_media['local_id'];
$res['ext'] = '.jpg';
$res['mime'] = $this->getMimeFromExtension($res['ext'], 'image/jpeg');
$res['InputFileLocation'] = [
- '_' => 'inputFileLocationTemp', // Will be overwritten
+ '_' => 'inputFileLocationTemp',
+ // Will be overwritten
'volume_id' => $message_media['volume_id'],
'local_id' => $message_media['local_id'],
];
-
return $res;
-
// Documents
case 'decryptedMessageMediaExternalDocument':
case 'document':
$message_media = ['_' => 'messageMediaDocument', 'ttl_seconds' => 0, 'document' => $message_media];
- // no break
+ // no break
case 'messageMediaDocument':
$res['MessageMedia'] = $message_media;
-
foreach ($message_media['document']['attributes'] as $attribute) {
switch ($attribute['_']) {
case 'documentAttributeFilename':
$pathinfo = \pathinfo($attribute['file_name']);
if (isset($pathinfo['extension'])) {
- $res['ext'] = '.'.$pathinfo['extension'];
+ $res['ext'] = '.' . $pathinfo['extension'];
}
$res['name'] = $pathinfo['filename'];
break;
@@ -899,22 +774,10 @@ trait Files
if (isset($audio) && isset($audio['title']) && !isset($res['name'])) {
$res['name'] = $audio['title'];
if (isset($audio['performer'])) {
- $res['name'] .= ' - '.$audio['performer'];
+ $res['name'] .= ' - ' . $audio['performer'];
}
}
-
- $res['InputFileLocation'] = [
- '_' => 'inputDocumentFileLocation',
- 'id' => $message_media['document']['id'],
- 'access_hash' => $message_media['document']['access_hash'],
- 'version' => isset($message_media['document']['version']) ? $message_media['document']['version'] : 0,
- 'dc_id' => $message_media['document']['dc_id'],
- 'file_reference' => yield $this->referenceDatabase->getReference(
- ReferenceDatabase::DOCUMENT_LOCATION,
- $message_media['document']
- ),
- ];
-
+ $res['InputFileLocation'] = ['_' => 'inputDocumentFileLocation', 'id' => $message_media['document']['id'], 'access_hash' => $message_media['document']['access_hash'], 'version' => isset($message_media['document']['version']) ? $message_media['document']['version'] : 0, 'dc_id' => $message_media['document']['dc_id'], 'file_reference' => yield $this->referenceDatabase->getReference(ReferenceDatabase::DOCUMENT_LOCATION, $message_media['document'])];
if (!isset($res['ext']) || $res['ext'] === '') {
$res['ext'] = $this->getExtensionFromLocation($res['InputFileLocation'], $this->getExtensionFromMime($message_media['document']['mime_type']));
}
@@ -924,107 +787,106 @@ trait Files
if (isset($message_media['document']['size'])) {
$res['size'] = $message_media['document']['size'];
}
- $res['name'] .= '_'.$message_media['document']['id'];
+ $res['name'] .= '_' . $message_media['document']['id'];
$res['mime'] = $message_media['document']['mime_type'];
-
return $res;
default:
- throw new \danog\MadelineProto\Exception('Invalid constructor provided: '.$message_media['_']);
+ throw new \danog\MadelineProto\Exception('Invalid constructor provided: ' . $message_media['_']);
}
}
/*
- public function download_to_browser_single_async($message_media, $cb = null)
- {
- if (php_sapi_name() === 'cli') {
- throw new Exception('Cannot download file to browser from command line: start this script from a browser');
- }
- if (headers_sent()) {
- throw new Exception('Headers already sent, cannot stream file to browser!');
- }
+ public function download_to_browser_single_async($message_media, $cb = null)
+ {
+ if (php_sapi_name() === 'cli') {
+ throw new Exception('Cannot download file to browser from command line: start this script from a browser');
+ }
+ if (headers_sent()) {
+ throw new Exception('Headers already sent, cannot stream file to browser!');
+ }
- if (is_object($message_media) && $message_media instanceof FileCallbackInterface) {
- $cb = $message_media;
- $message_media = $message_media->getFile();
- }
+ if (is_object($message_media) && $message_media instanceof FileCallbackInterface) {
+ $cb = $message_media;
+ $message_media = $message_media->getFile();
+ }
- $message_media = yield $this->getDownloadInfo($message_media);
+ $message_media = yield $this->getDownloadInfo($message_media);
- $servefile = $_SERVER['REQUEST_METHOD'] !== 'HEAD';
+ $servefile = $_SERVER['REQUEST_METHOD'] !== 'HEAD';
- if (isset($_SERVER['HTTP_RANGE'])) {
- $range = explode('=', $_SERVER['HTTP_RANGE'], 2);
- if (count($range) == 1) {
- $range[1] = '';
- }
- list($size_unit, $range_orig) = $range;
- if ($size_unit == 'bytes') {
- //multiple ranges could be specified at the same time, but for simplicity only serve the first range
- //http://tools.ietf.org/id/draft-ietf-http-range-retrieval-00.txt
- $list = explode(',', $range_orig, 2);
- if (count($list) == 1) {
- $list[1] = '';
- }
- list($range, $extra_ranges) = $list;
- } else {
- $range = '';
- return Tools::noCache(416, '416 Requested Range Not Satisfiable.
Could not use selected range.
');
- }
- } else {
- $range = '';
- }
- $listseek = explode('-', $range, 2);
- if (count($listseek) == 1) {
- $listseek[1] = '';
- }
- list($seek_start, $seek_end) = $listseek;
+ if (isset($_SERVER['HTTP_RANGE'])) {
+ $range = explode('=', $_SERVER['HTTP_RANGE'], 2);
+ if (count($range) == 1) {
+ $range[1] = '';
+ }
+ list($size_unit, $range_orig) = $range;
+ if ($size_unit == 'bytes') {
+ //multiple ranges could be specified at the same time, but for simplicity only serve the first range
+ //http://tools.ietf.org/id/draft-ietf-http-range-retrieval-00.txt
+ $list = explode(',', $range_orig, 2);
+ if (count($list) == 1) {
+ $list[1] = '';
+ }
+ list($range, $extra_ranges) = $list;
+ } else {
+ $range = '';
+ return Tools::noCache(416, '416 Requested Range Not Satisfiable.
Could not use selected range.
');
+ }
+ } else {
+ $range = '';
+ }
+ $listseek = explode('-', $range, 2);
+ if (count($listseek) == 1) {
+ $listseek[1] = '';
+ }
+ list($seek_start, $seek_end) = $listseek;
- $seek_end = empty($seek_end) ? ($message_media['size'] - 1) : min(abs(intval($seek_end)), $message_media['size'] - 1);
+ $seek_end = empty($seek_end) ? ($message_media['size'] - 1) : min(abs(intval($seek_end)), $message_media['size'] - 1);
- if (!empty($seek_start) && $seek_end < abs(intval($seek_start))) {
- return Tools::noCache(416, '416 Requested Range Not Satisfiable.
Could not use selected range.
');
- }
- $seek_start = empty($seek_start) ? 0 : abs(intval($seek_start));
- if ($servefile) {
- if ($seek_start > 0 || $seek_end < $select['file_size'] - 1) {
- header('HTTP/1.1 206 Partial Content');
- header('Content-Range: bytes '.$seek_start.'-'.$seek_end.'/'.$select['file_size']);
- header('Content-Length: '.($seek_end - $seek_start + 1));
- } else {
- header('Content-Length: '.$select['file_size']);
- }
- header('Content-Type: '.$select['mime']);
- header('Cache-Control: max-age=31556926;');
- header('Content-Transfer-Encoding: Binary');
- header('Accept-Ranges: bytes');
- //header('Content-disposition: attachment: filename="'.basename($select['file_path']).'"');
- $MadelineProto->downloadToStream($select['file_id'], fopen('php://output', 'w'), function ($percent) {
- flush();
- ob_flush();
- \danog\MadelineProto\Logger::log('Download status: '.$percent.'%');
- }, $seek_start, $seek_end + 1);
- //analytics(true, $file_path, $MadelineProto->getSelf()['id'], $dbuser, $dbpassword);
- $MadelineProto->API->getting_state = false;
- $MadelineProto->API->storeDb([], true);
- $MadelineProto->API->resetSession();
- } else {
- if ($seek_start > 0 || $seek_end < $select['file_size'] - 1) {
- header('HTTP/1.1 206 Partial Content');
- header('Content-Range: bytes '.$seek_start.'-'.$seek_end.'/'.$select['file_size']);
- header('Content-Length: '.($seek_end - $seek_start + 1));
- } else {
- header('Content-Length: '.$select['file_size']);
- }
- header('Content-Type: '.$select['mime']);
- header('Cache-Control: max-age=31556926;');
- header('Content-Transfer-Encoding: Binary');
- header('Accept-Ranges: bytes');
- analytics(true, $file_path, null, $dbuser, $dbpassword);
- //header('Content-disposition: attachment: filename="'.basename($select['file_path']).'"');
- }
+ if (!empty($seek_start) && $seek_end < abs(intval($seek_start))) {
+ return Tools::noCache(416, '416 Requested Range Not Satisfiable.
Could not use selected range.
');
+ }
+ $seek_start = empty($seek_start) ? 0 : abs(intval($seek_start));
+ if ($servefile) {
+ if ($seek_start > 0 || $seek_end < $select['file_size'] - 1) {
+ header('HTTP/1.1 206 Partial Content');
+ header('Content-Range: bytes '.$seek_start.'-'.$seek_end.'/'.$select['file_size']);
+ header('Content-Length: '.($seek_end - $seek_start + 1));
+ } else {
+ header('Content-Length: '.$select['file_size']);
+ }
+ header('Content-Type: '.$select['mime']);
+ header('Cache-Control: max-age=31556926;');
+ header('Content-Transfer-Encoding: Binary');
+ header('Accept-Ranges: bytes');
+ //header('Content-disposition: attachment: filename="'.basename($select['file_path']).'"');
+ $MadelineProto->downloadToStream($select['file_id'], fopen('php://output', 'w'), function ($percent) {
+ flush();
+ ob_flush();
+ \danog\MadelineProto\Logger::log('Download status: '.$percent.'%');
+ }, $seek_start, $seek_end + 1);
+ //analytics(true, $file_path, $MadelineProto->getSelf()['id'], $dbuser, $dbpassword);
+ $MadelineProto->API->getting_state = false;
+ $MadelineProto->API->storeDb([], true);
+ $MadelineProto->API->resetSession();
+ } else {
+ if ($seek_start > 0 || $seek_end < $select['file_size'] - 1) {
+ header('HTTP/1.1 206 Partial Content');
+ header('Content-Range: bytes '.$seek_start.'-'.$seek_end.'/'.$select['file_size']);
+ header('Content-Length: '.($seek_end - $seek_start + 1));
+ } else {
+ header('Content-Length: '.$select['file_size']);
+ }
+ header('Content-Type: '.$select['mime']);
+ header('Cache-Control: max-age=31556926;');
+ header('Content-Transfer-Encoding: Binary');
+ header('Accept-Ranges: bytes');
+ analytics(true, $file_path, null, $dbuser, $dbpassword);
+ //header('Content-disposition: attachment: filename="'.basename($select['file_path']).'"');
+ }
- header('Content-Length: '.$info['size']);
- header('Content-Type: '.$info['mime']);
- }*/
+ header('Content-Length: '.$info['size']);
+ header('Content-Type: '.$info['mime']);
+ }*/
/**
* Extract photo size.
*
@@ -1052,12 +914,9 @@ trait Files
$cb = $dir;
$dir = $dir->getFile();
}
-
- $message_media = yield $this->getDownloadInfo($message_media);
-
- return yield $this->downloadToFile($message_media, $dir.'/'.$message_media['name'].$message_media['ext'], $cb);
+ $message_media = (yield from $this->getDownloadInfo($message_media));
+ return yield from $this->downloadToFile($message_media, $dir . '/' . $message_media['name'] . $message_media['ext'], $cb);
}
-
/**
* Download file.
*
@@ -1078,25 +937,20 @@ trait Files
yield \touch($file);
}
$file = \realpath($file);
- $message_media = yield $this->getDownloadInfo($message_media);
-
+ $message_media = (yield from $this->getDownloadInfo($message_media));
StatCache::clear($file);
-
$size = (yield \stat($file))['size'];
$stream = yield open($file, 'cb');
-
$this->logger->logger('Waiting for lock of file to download...');
$unlock = yield \danog\MadelineProto\Tools::flock($file, LOCK_EX);
$this->logger->logger('Got lock of file to download');
-
try {
- yield $this->downloadToStream($message_media, $stream, $cb, $size, -1);
+ yield from $this->downloadToStream($message_media, $stream, $cb, $size, -1);
} finally {
$unlock();
yield $stream->close();
StatCache::clear($file);
}
-
return $file;
}
/**
@@ -1112,13 +966,11 @@ trait Files
*/
public function downloadToStream($message_media, $stream, $cb = null, int $offset = 0, int $end = -1): \Generator
{
- $message_media = yield $this->getDownloadInfo($message_media);
-
+ $message_media = (yield from $this->getDownloadInfo($message_media));
if (\is_object($stream) && $stream instanceof FileCallbackInterface) {
$cb = $stream;
$stream = $stream->getFile();
}
-
/** @var $stream \Amp\ByteStream\OutputStream */
if (!\is_object($stream)) {
$stream = new ResourceOutputStream($stream);
@@ -1134,7 +986,7 @@ trait Files
} catch (StreamException $e) {
}
}
- $callable = static function (string $payload, int $offset) use ($stream, $seekable) {
+ $callable = static function (string $payload, int $offset) use ($stream, $seekable): \Generator {
if ($seekable) {
while ($stream->tell() !== $offset) {
yield $stream->seek($offset);
@@ -1142,8 +994,7 @@ trait Files
}
return yield $stream->write($payload);
};
-
- return yield $this->downloadToCallable($message_media, $callable, $cb, $seekable, $offset, $end);
+ return yield from $this->downloadToCallable($message_media, $callable, $cb, $seekable, $offset, $end);
}
/**
* Download file to callable.
@@ -1163,36 +1014,30 @@ trait Files
*/
public function downloadToCallable($message_media, $callable, $cb = null, bool $seekable = true, int $offset = 0, int $end = -1, int $part_size = null): \Generator
{
- $message_media = yield $this->getDownloadInfo($message_media);
-
+ $message_media = (yield from $this->getDownloadInfo($message_media));
if (\is_object($callable) && $callable instanceof FileCallbackInterface) {
$cb = $callable;
$callable = $callable->getFile();
}
-
if (!\is_callable($callable)) {
throw new Exception('Wrong callable provided');
}
if ($cb === null) {
$cb = function ($percent) {
- $this->logger->logger('Download status: '.$percent.'%', \danog\MadelineProto\Logger::NOTICE);
+ $this->logger->logger('Download status: ' . $percent . '%', \danog\MadelineProto\Logger::NOTICE);
};
}
-
if ($end === -1 && isset($message_media['size'])) {
$end = $message_media['size'];
}
-
$part_size = $part_size ?? $this->settings['download']['part_size'];
$parallel_chunks = $this->settings['download']['parallel_chunks'] ? $this->settings['download']['parallel_chunks'] : 3000;
-
$datacenter = isset($message_media['InputFileLocation']['dc_id']) ? $message_media['InputFileLocation']['dc_id'] : $this->settings['connection_settings']['default_dc'];
- if ($this->datacenter->has($datacenter.'_media')) {
+ if ($this->datacenter->has($datacenter . '_media')) {
$datacenter .= '_media';
}
-
if (isset($message_media['key'])) {
- $digest = \hash('md5', $message_media['key'].$message_media['iv'], true);
+ $digest = \hash('md5', $message_media['key'] . $message_media['iv'], true);
$fingerprint = \danog\MadelineProto\Tools::unpackSignedInt(\substr($digest, 0, 4) ^ \substr($digest, 4, 4));
if ($fingerprint !== $message_media['key_fingerprint']) {
throw new \danog\MadelineProto\Exception('Fingerprint mismatch!');
@@ -1203,7 +1048,6 @@ trait Files
$ige->enableContinuousBuffer();
$seekable = false;
}
-
if ($offset === $end) {
$cb(100, 0, 0);
return true;
@@ -1211,35 +1055,24 @@ trait Files
$params = [];
$start_at = $offset % $part_size;
$probable_end = $end !== -1 ? $end : 512 * 1024 * 3000;
-
$breakOut = false;
for ($x = $offset - $start_at; $x < $probable_end; $x += $part_size) {
$end_at = $part_size;
-
if ($end !== -1 && $x + $part_size > $end) {
$end_at = $end % $part_size;
$breakOut = true;
}
-
- $params[] = [
- 'offset' => $x,
- 'limit' => $part_size,
- 'part_start_at' => $start_at,
- 'part_end_at' => $end_at,
- ];
-
+ $params[] = ['offset' => $x, 'limit' => $part_size, 'part_start_at' => $start_at, 'part_end_at' => $end_at];
$start_at = 0;
if ($breakOut) {
break;
}
}
-
if (!$params) {
$cb(100, 0, 0);
return true;
}
$count = \count($params);
-
$time = 0;
$speed = 0;
$origCb = $cb;
@@ -1248,21 +1081,17 @@ trait Files
$cur++;
\danog\MadelineProto\Tools::callFork($cb($cur * 100 / $count, $time, $speed));
};
-
$cdn = false;
-
$params[0]['previous_promise'] = new Success(true);
-
$start = \microtime(true);
- $size = yield $this->downloadPart($message_media, $cdn, $datacenter, $old_dc, $ige, $cb, $initParam = \array_shift($params), $callable, $seekable);
- if ($initParam['part_end_at'] - $initParam['part_start_at'] !== $size) { // Premature end for undefined length files
+ $size = (yield from $this->downloadPart($message_media, $cdn, $datacenter, $old_dc, $ige, $cb, $initParam = \array_shift($params), $callable, $seekable));
+ if ($initParam['part_end_at'] - $initParam['part_start_at'] !== $size) {
+ // Premature end for undefined length files
$origCb(100, 0, 0);
return true;
}
-
if ($params) {
$previous_promise = new Success(true);
-
$promises = [];
foreach ($params as $key => $param) {
$param['previous_promise'] = $previous_promise;
@@ -1272,10 +1101,9 @@ trait Files
$size += $res;
}
});
-
$promises[] = $previous_promise;
-
- if (!($key % $parallel_chunks)) { // 20 mb at a time, for a typical bandwidth of 1gbps
+ if (!($key % $parallel_chunks)) {
+ // 20 mb at a time, for a typical bandwidth of 1gbps
$res = yield \danog\MadelineProto\Tools::all($promises);
$promises = [];
foreach ($res as $r) {
@@ -1283,11 +1111,10 @@ trait Files
break 2;
}
}
-
$time = \microtime(true) - $start;
- $speed = (int) (($size * 8) / $time) / 1000000;
- $this->logger->logger("Partial download time: $time");
- $this->logger->logger("Partial download speed: $speed mbps");
+ $speed = (int) ($size * 8 / $time) / 1000000;
+ $this->logger->logger("Partial download time: {$time}");
+ $this->logger->logger("Partial download speed: {$speed} mbps");
}
}
if ($promises) {
@@ -1295,21 +1122,17 @@ trait Files
}
}
$time = \microtime(true) - $start;
- $speed = (int) (($size * 8) / $time) / 1000000;
- $this->logger->logger("Total download time: $time");
- $this->logger->logger("Total download speed: $speed mbps");
-
+ $speed = (int) ($size * 8 / $time) / 1000000;
+ $this->logger->logger("Total download time: {$time}");
+ $this->logger->logger("Total download speed: {$speed} mbps");
if ($cdn) {
$this->clearCdnHashes($message_media['file_token']);
}
-
if (!isset($message_media['size'])) {
$origCb(100, $time, $speed);
}
-
return true;
}
-
/**
* Download file part.
*
@@ -1329,34 +1152,20 @@ trait Files
private function downloadPart(&$message_media, bool &$cdn, &$datacenter, &$old_dc, &$ige, $cb, array $offset, $callable, bool $seekable, bool $postpone = false): \Generator
{
static $method = [
- false => 'upload.getFile', // non-cdn
- true => 'upload.getCdnFile', // cdn
+ false => 'upload.getFile',
+ // non-cdn
+ true => 'upload.getCdnFile',
];
do {
if (!$cdn) {
- $basic_param = [
- 'location' => $message_media['InputFileLocation'],
- ];
+ $basic_param = ['location' => $message_media['InputFileLocation']];
} else {
- $basic_param = [
- 'file_token' => $message_media['file_token'],
- ];
+ $basic_param = ['file_token' => $message_media['file_token']];
}
-
//$x = 0;
while (true) {
try {
- $res = yield $this->methodCallAsyncRead(
- $method[$cdn],
- $basic_param + $offset,
- [
- 'heavy' => true,
- 'file' => true,
- 'FloodWaitLimit' => 0,
- 'datacenter' => &$datacenter,
- 'postpone' => $postpone,
- ]
- );
+ $res = yield $this->methodCallAsyncRead($method[$cdn], $basic_param + $offset, ['heavy' => true, 'file' => true, 'FloodWaitLimit' => 0, 'datacenter' => &$datacenter, 'postpone' => $postpone]);
break;
} catch (\danog\MadelineProto\RPCErrorException $e) {
if (\strpos($e->rpc, 'FLOOD_WAIT_') === 0) {
@@ -1372,14 +1181,13 @@ trait Files
}
}
}
-
if ($res['_'] === 'upload.fileCdnRedirect') {
$cdn = true;
$message_media['file_token'] = $res['file_token'];
$message_media['cdn_key'] = $res['encryption_key'];
$message_media['cdn_iv'] = $res['encryption_iv'];
$old_dc = $datacenter;
- $datacenter = $res['dc_id'].'_cdn';
+ $datacenter = $res['dc_id'] . '_cdn';
if (!$this->datacenter->has($datacenter)) {
$this->config['expires'] = -1;
yield $this->getConfig([], ['datacenter' => $this->datacenter->curdc]);
@@ -1388,7 +1196,6 @@ trait Files
} elseif ($res['_'] === 'upload.cdnFileReuploadNeeded') {
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['cdn_reupload'], \danog\MadelineProto\Logger::NOTICE);
yield $this->getConfig([], ['datacenter' => $this->datacenter->curdc]);
-
try {
$this->addCdnHashes($message_media['file_token'], yield $this->methodCallAsyncRead('upload.reuploadCdnFile', ['file_token' => $message_media['file_token'], 'request_token' => $res['request_token']], ['heavy' => true, 'datacenter' => $old_dc]));
} catch (\danog\MadelineProto\RPCErrorException $e) {
@@ -1404,24 +1211,17 @@ trait Files
continue;
}
$res['bytes'] = (string) $res['bytes'];
-
if ($cdn === false && $res['type']['_'] === 'storage.fileUnknown' && $res['bytes'] === '') {
$datacenter = 0;
}
- while ($cdn === false &&
- $res['type']['_'] === 'storage.fileUnknown' &&
- $res['bytes'] === '' &&
- $this->datacenter->has(++$datacenter)
- ) {
+ while ($cdn === false && $res['type']['_'] === 'storage.fileUnknown' && $res['bytes'] === '' && $this->datacenter->has(++$datacenter)) {
$res = yield $this->methodCallAsyncRead('upload.getFile', $basic_param + $offset, ['heavy' => true, 'file' => true, 'FloodWaitLimit' => 0, 'datacenter' => $datacenter]);
}
-
if ($res['bytes'] === '') {
return 0;
}
-
if (isset($message_media['cdn_key'])) {
- $ivec = \substr($message_media['cdn_iv'], 0, 12).\pack('N', $offset['offset'] >> 4);
+ $ivec = \substr($message_media['cdn_iv'], 0, 12) . \pack('N', $offset['offset'] >> 4);
$res['bytes'] = $this->ctrEncrypt($res['bytes'], $message_media['cdn_key'], $ivec);
$this->checkCdnHash($message_media['file_token'], $offset['offset'], $res['bytes'], $old_dc);
}
@@ -1431,18 +1231,15 @@ trait Files
if ($offset['part_start_at'] || $offset['part_end_at'] !== $offset['limit']) {
$res['bytes'] = \substr($res['bytes'], $offset['part_start_at'], $offset['part_end_at'] - $offset['part_start_at']);
}
-
if (!$seekable) {
- yield $offset['previous_promise'];
+ yield from $offset['previous_promise'];
}
$res = yield $callable($res['bytes'], $offset['offset'] + $offset['part_start_at']);
$cb();
return $res;
} while (true);
}
-
private $cdn_hashes = [];
-
private function addCdnHashes($file, $hashes)
{
if (!isset($this->cdn_hashes[$file])) {
@@ -1452,30 +1249,26 @@ trait Files
$this->cdn_hashes[$file][$hash['offset']] = ['limit' => $hash['limit'], 'hash' => (string) $hash['hash']];
}
}
-
- private function checkCdnHash($file, $offset, $data, &$datacenter)
+ private function checkCdnHash($file, $offset, $data, &$datacenter): \Generator
{
while (\strlen($data)) {
if (!isset($this->cdn_hashes[$file][$offset])) {
$this->addCdnHashes($file, yield $this->methodCallAsyncRead('upload.getCdnFileHashes', ['file_token' => $file, 'offset' => $offset], ['datacenter' => $datacenter]));
}
if (!isset($this->cdn_hashes[$file][$offset])) {
- throw new \danog\MadelineProto\Exception('Could not fetch CDN hashes for offset '.$offset);
+ throw new \danog\MadelineProto\Exception('Could not fetch CDN hashes for offset ' . $offset);
}
if (\hash('sha256', \substr($data, 0, $this->cdn_hashes[$file][$offset]['limit']), true) !== $this->cdn_hashes[$file][$offset]['hash']) {
- throw new \danog\MadelineProto\SecurityException('CDN hash mismatch for offset '.$offset);
+ throw new \danog\MadelineProto\SecurityException('CDN hash mismatch for offset ' . $offset);
}
$data = \substr($data, $this->cdn_hashes[$file][$offset]['limit']);
$offset += $this->cdn_hashes[$file][$offset]['limit'];
}
-
return true;
}
-
private function clearCdnHashes($file)
{
unset($this->cdn_hashes[$file]);
-
return true;
}
}
diff --git a/src/danog/MadelineProto/MTProtoTools/MinDatabase.php b/src/danog/MadelineProto/MTProtoTools/MinDatabase.php
index 224ae0be..90434ecb 100644
--- a/src/danog/MadelineProto/MTProtoTools/MinDatabase.php
+++ b/src/danog/MadelineProto/MTProtoTools/MinDatabase.php
@@ -29,26 +29,8 @@ use danog\MadelineProto\Tools;
class MinDatabase implements TLCallback
{
use Tools;
-
- const SWITCH_CONSTRUCTORS = [
- 'inputChannel',
- 'inputUser',
- 'inputPeerUser',
- 'inputPeerChannel',
- ];
- const CATCH_PEERS = [
- 'message',
- 'messageService',
- 'peerUser',
- 'peerChannel',
- 'messageEntityMentionName',
-
- 'messageFwdHeader',
- 'messageActionChatCreate',
- 'messageActionChatAddUser',
- 'messageActionChatDeleteUser',
- 'messageActionChatJoinedByLink',
- ];
+ const SWITCH_CONSTRUCTORS = ['inputChannel', 'inputUser', 'inputPeerUser', 'inputPeerChannel'];
+ const CATCH_PEERS = ['message', 'messageService', 'peerUser', 'peerChannel', 'messageEntityMentionName', 'messageFwdHeader', 'messageActionChatCreate', 'messageActionChatAddUser', 'messageActionChatDeleteUser', 'messageActionChatJoinedByLink'];
const ORIGINS = ['message', 'messageService'];
/**
* References indexed by location.
@@ -68,23 +50,19 @@ class MinDatabase implements TLCallback
* @var \danog\MadelineProto\MTProto
*/
private $API;
-
public function __construct(MTProto $API)
{
$this->API = $API;
$this->init();
}
-
public function __wakeup()
{
$this->init();
}
-
public function __sleep()
{
return ['db', 'API'];
}
-
public function init()
{
foreach ($this->db as $id => $origin) {
@@ -93,48 +71,37 @@ class MinDatabase implements TLCallback
}
}
}
-
public function getMethodCallbacks(): array
{
return [];
}
-
public function getMethodBeforeCallbacks(): array
{
return [];
}
-
public function getConstructorCallbacks(): array
{
- return \array_merge(
- \array_fill_keys(self::CATCH_PEERS, [[$this, 'addPeer']]),
- \array_fill_keys(self::ORIGINS, [[$this, 'addOrigin']])
- );
+ return \array_merge(\array_fill_keys(self::CATCH_PEERS, [[$this, 'addPeer']]), \array_fill_keys(self::ORIGINS, [[$this, 'addOrigin']]));
}
-
public function getConstructorBeforeCallbacks(): array
{
return \array_fill_keys(self::ORIGINS, [[$this, 'addOriginContext']]);
}
-
public function getConstructorSerializeCallbacks(): array
{
return \array_fill_keys(self::SWITCH_CONSTRUCTORS, [$this, 'populateFrom']);
}
-
public function getTypeMismatchCallbacks(): array
{
return [];
}
-
public function reset()
{
if ($this->cache) {
- $this->API->logger->logger('Found '.\count($this->cache).' pending contexts', \danog\MadelineProto\Logger::ERROR);
+ $this->API->logger->logger('Found ' . \count($this->cache) . ' pending contexts', \danog\MadelineProto\Logger::ERROR);
$this->cache = [];
}
}
-
public function addPeer(array $location)
{
if (!$this->cache) {
@@ -148,18 +115,15 @@ class MinDatabase implements TLCallback
if ($frame['args'][1]['subtype'] === $previous) {
continue;
}
-
$frames[] = $frame['args'][1]['subtype'];
$previous = $frame['args'][1]['subtype'];
} elseif (isset($frame['args'][1]['type'])) {
if ($frame['args'][1]['type'] === '') {
break;
}
-
if ($frame['args'][1]['type'] === $previous) {
continue;
}
-
$frames[] = $frame['args'][1]['type'];
$previous = $frame['args'][1]['type'];
}
@@ -168,10 +132,9 @@ class MinDatabase implements TLCallback
$frames = \array_reverse($frames);
$tl_trace = \array_shift($frames);
foreach ($frames as $frame) {
- $tl_trace .= "['".$frame."']";
+ $tl_trace .= "['" . $frame . "']";
}
$this->API->logger->logger($tl_trace, \danog\MadelineProto\Logger::ERROR);
-
return false;
}
$peers = [];
@@ -204,16 +167,13 @@ class MinDatabase implements TLCallback
foreach ($peers as $id => $true) {
$this->cache[$key][$id] = $id;
}
-
return true;
}
-
public function addOriginContext(string $type)
{
$this->API->logger->logger("Adding peer origin context for {$type}!", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
$this->cache[] = [];
}
-
public function addOrigin(array $data = [])
{
$cache = \array_pop($this->cache);
@@ -236,10 +196,9 @@ class MinDatabase implements TLCallback
}
$this->db[$id] = $origin;
}
- $this->API->logger->logger("Added origin ({$data['_']}) to ".\count($cache).' peer locations', \danog\MadelineProto\Logger::ULTRA_VERBOSE);
+ $this->API->logger->logger("Added origin ({$data['_']}) to " . \count($cache) . ' peer locations', \danog\MadelineProto\Logger::ULTRA_VERBOSE);
}
-
- public function populateFrom(array $object)
+ public function populateFrom(array $object): \Generator
{
if (!($object['min'] ?? false)) {
return $object;
@@ -250,17 +209,14 @@ class MinDatabase implements TLCallback
$new['_'] .= 'FromMessage';
$new['peer'] = (yield $this->API->getInfo($new['peer']))['InputPeer'];
if ($new['peer']['min']) {
- $this->API->logger->logger("Don't have origin peer subinfo with min peer $id, this may fail");
+ $this->API->logger->logger("Don't have origin peer subinfo with min peer {$id}, this may fail");
return $object;
}
return $new;
}
- $this->API->logger->logger("Don't have origin info with min peer $id, this may fail");
-
-
+ $this->API->logger->logger("Don't have origin info with min peer {$id}, this may fail");
return $object;
}
-
/**
* Check if location info is available for peer.
*
@@ -274,6 +230,6 @@ class MinDatabase implements TLCallback
}
public function __debugInfo()
{
- return ['MinDatabase instance '.\spl_object_hash($this)];
+ return ['MinDatabase instance ' . \spl_object_hash($this)];
}
}
diff --git a/src/danog/MadelineProto/MTProtoTools/PasswordCalculator.php b/src/danog/MadelineProto/MTProtoTools/PasswordCalculator.php
index 4a01e5b6..b2b489b5 100644
--- a/src/danog/MadelineProto/MTProtoTools/PasswordCalculator.php
+++ b/src/danog/MadelineProto/MTProtoTools/PasswordCalculator.php
@@ -1,4 +1,5 @@
logger = $logger;
}
-
/**
* Popupate 2FA configuration.
*
@@ -115,7 +111,6 @@ class PasswordCalculator
$this->checkPG($object['current_algo']['p'], $object['current_algo']['g']);
$object['current_algo']['gForHash'] = \str_pad($object['current_algo']['g']->toBytes(), 256, \chr(0), \STR_PAD_LEFT);
$object['current_algo']['pForHash'] = \str_pad($object['current_algo']['p']->toBytes(), 256, \chr(0), \STR_PAD_LEFT);
-
break;
default:
throw new Exception("Unknown KDF algo {$object['current_algo']['_']}");
@@ -146,7 +141,6 @@ class PasswordCalculator
$this->checkPG($object['new_algo']['p'], $object['new_algo']['g']);
$object['new_algo']['gForHash'] = \str_pad($object['new_algo']['g']->toBytes(), 256, \chr(0), \STR_PAD_LEFT);
$object['new_algo']['pForHash'] = \str_pad($object['new_algo']['p']->toBytes(), 256, \chr(0), \STR_PAD_LEFT);
-
break;
default:
throw new Exception("Unknown KDF algo {$object['new_algo']['_']}");
@@ -154,7 +148,6 @@ class PasswordCalculator
$this->new_algo = $object['new_algo'];
$this->secure_random = $object['secure_random'];
}
-
/**
* Create a random string (eventually prefixed by the specified string).
*
@@ -163,9 +156,8 @@ class PasswordCalculator
*/
public function createSalt(string $prefix = ''): string
{
- return $prefix.\danog\MadelineProto\Tools::random(32);
+ return $prefix . \danog\MadelineProto\Tools::random(32);
}
-
/**
* Hash specified data using the salt with SHA256.
*
@@ -177,9 +169,8 @@ class PasswordCalculator
*/
public function hashSha256(string $data, string $salt): string
{
- return \hash('sha256', $salt.$data.$salt, true);
+ return \hash('sha256', $salt . $data . $salt, true);
}
-
/**
* Hashes the specified password.
*
@@ -193,10 +184,8 @@ class PasswordCalculator
$buf = $this->hashSha256($password, $client_salt);
$buf = $this->hashSha256($buf, $server_salt);
$hash = \hash_pbkdf2('sha512', $buf, $client_salt, 100000, 0, true);
-
return $this->hashSha256($hash, $server_salt);
}
-
/**
* Get the InputCheckPassword object for checking the validity of a password using account.checkPassword.
*
@@ -214,42 +203,30 @@ class PasswordCalculator
$gForHash = $this->current_algo['gForHash'];
$p = $this->current_algo['p'];
$pForHash = $this->current_algo['pForHash'];
-
$B = $this->srp_B;
$BForHash = $this->srp_BForHash;
$id = $this->srp_id;
-
$x = new BigInteger($this->hashPassword($password, $client_salt, $server_salt), 256);
$g_x = $g->powMod($x, $p);
-
- $k = new BigInteger(\hash('sha256', $pForHash.$gForHash, true), 256);
+ $k = new BigInteger(\hash('sha256', $pForHash . $gForHash, true), 256);
$kg_x = $k->multiply($g_x)->powMod(Magic::$one, $p);
-
$a = new BigInteger(\danog\MadelineProto\Tools::random(2048 / 8), 256);
$A = $g->powMod($a, $p);
$this->checkG($A, $p);
$AForHash = \str_pad($A->toBytes(), 256, \chr(0), \STR_PAD_LEFT);
-
$b_kg_x = $B->powMod(Magic::$one, $p)->subtract($kg_x);
-
- $u = new BigInteger(\hash('sha256', $AForHash.$BForHash, true), 256);
+ $u = new BigInteger(\hash('sha256', $AForHash . $BForHash, true), 256);
$ux = $u->multiply($x);
$a_ux = $a->add($ux);
-
$S = $b_kg_x->powMod($a_ux, $p);
-
$SForHash = \str_pad($S->toBytes(), 256, \chr(0), \STR_PAD_LEFT);
$K = \hash('sha256', $SForHash, true);
-
$h1 = \hash('sha256', $pForHash, true);
$h2 = \hash('sha256', $gForHash, true);
$h1 ^= $h2;
-
- $M1 = \hash('sha256', $h1.\hash('sha256', $client_salt, true).\hash('sha256', $server_salt, true).$AForHash.$BForHash.$K, true);
-
+ $M1 = \hash('sha256', $h1 . \hash('sha256', $client_salt, true) . \hash('sha256', $server_salt, true) . $AForHash . $BForHash . $K, true);
return ['_' => 'inputCheckPasswordSRP', 'srp_id' => $id, 'A' => $AForHash, 'M1' => $M1];
}
-
/**
* Get parameters to be passed to the account.updatePasswordSettings to update/set a 2FA password.
*
@@ -261,36 +238,24 @@ class PasswordCalculator
public function getPassword(array $params): array
{
$oldPassword = $this->getCheckPassword($params['password'] ?? '');
-
$return = ['password' => $oldPassword, 'new_settings' => ['_' => 'account.passwordInputSettings', 'new_algo' => ['_' => 'passwordKdfAlgoUnknown'], 'new_password_hash' => '', 'hint' => '']];
-
- $new_settings = &$return['new_settings'];
-
+ $new_settings =& $return['new_settings'];
if (isset($params['new_password']) && $params['new_password'] !== '') {
$client_salt = $this->createSalt($this->new_algo['salt1']);
$server_salt = $this->new_algo['salt2'];
$g = $this->new_algo['g'];
$p = $this->new_algo['p'];
$pForHash = $this->new_algo['pForHash'];
-
$x = new BigInteger($this->hashPassword($params['new_password'], $client_salt, $server_salt), 256);
$v = $g->powMod($x, $p);
$vForHash = \str_pad($v->toBytes(), 256, \chr(0), \STR_PAD_LEFT);
-
- $new_settings['new_algo'] = [
- '_' => 'passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow',
- 'salt1' => $client_salt,
- 'salt2' => $server_salt,
- 'g' => (int) $g->toString(),
- 'p' => $pForHash,
- ];
+ $new_settings['new_algo'] = ['_' => 'passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow', 'salt1' => $client_salt, 'salt2' => $server_salt, 'g' => (int) $g->toString(), 'p' => $pForHash];
$new_settings['new_password_hash'] = $vForHash;
$new_settings['hint'] = $params['hint'] ?? '';
if (isset($params['email'])) {
$new_settings['email'] = $params['email'];
}
}
-
return $return;
}
}
diff --git a/src/danog/MadelineProto/MTProtoTools/PeerHandler.php b/src/danog/MadelineProto/MTProtoTools/PeerHandler.php
index 2d5af9d0..43bff35e 100644
--- a/src/danog/MadelineProto/MTProtoTools/PeerHandler.php
+++ b/src/danog/MadelineProto/MTProtoTools/PeerHandler.php
@@ -29,9 +29,7 @@ trait PeerHandler
public $caching_simple = [];
public $caching_simple_username = [];
public $caching_possible_username = [];
-
public $caching_full_info = [];
-
/**
* Convert MTProto channel ID to bot API channel ID.
*
@@ -43,7 +41,6 @@ trait PeerHandler
{
return -($id + \pow(10, (int) \floor(\log($id, 10) + 3)));
}
-
/**
* Convert bot API channel ID to MTProto channel ID.
*
@@ -55,7 +52,6 @@ trait PeerHandler
{
return -$id - \pow(10, (int) \floor(\log(-$id, 10)));
}
-
/**
* Check whether provided bot API ID is a channel.
*
@@ -66,10 +62,8 @@ trait PeerHandler
public static function isSupergroup($id): bool
{
$log = \log(-$id, 10);
-
return ($log - \intval($log)) * 1000 < 10;
}
-
/**
* Set support info.
*
@@ -83,7 +77,6 @@ trait PeerHandler
{
$this->supportUser = $support['user']['id'];
}
-
/**
* Add user info.
*
@@ -109,14 +102,12 @@ trait PeerHandler
} else {
$this->logger->logger("No access hash with user {$user['id']}, tried and failed to fetch data...");
}
-
return;
}
switch ($user['_']) {
case 'user':
if (!isset($this->chats[$user['id']]) || $this->chats[$user['id']] !== $user) {
$this->logger->logger("Updated user {$user['id']}", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
-
if (($user['min'] ?? false) && isset($this->chats[$user['id']]) && !($this->chats[$user['id']]['min'] ?? false)) {
$this->logger->logger("{$user['id']} is min, filling missing fields", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
if (isset($this->chats[$user['id']]['access_hash'])) {
@@ -124,7 +115,6 @@ trait PeerHandler
$user['access_hash'] = $this->chats[$user['id']]['access_hash'];
}
}
-
$this->chats[$user['id']] = $user;
$this->cachePwrChat($user['id'], false, true);
}
@@ -135,7 +125,6 @@ trait PeerHandler
throw new \danog\MadelineProto\Exception('Invalid user provided', $user);
}
}
-
/**
* Add chat to database.
*
@@ -168,7 +157,6 @@ trait PeerHandler
if (isset($chat['username']) && !isset($this->caching_simple_username[$chat['username']])) {
$this->caching_possible_username[$bot_api_id] = $chat['username'];
}
-
$this->cachePwrChat($bot_api_id, false, true);
} elseif (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...");
@@ -176,14 +164,12 @@ trait PeerHandler
} 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) {
- $this->logger->logger("Updated chat $bot_api_id", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
-
+ $this->logger->logger("Updated chat {$bot_api_id}", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
if (($chat['min'] ?? false) && isset($this->chats[$bot_api_id]) && !($this->chats[$bot_api_id]['min'] ?? false)) {
- $this->logger->logger("$bot_api_id is min, filling missing fields", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
+ $this->logger->logger("{$bot_api_id} is min, filling missing fields", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
$newchat = $this->chats[$bot_api_id];
foreach (['title', 'username', 'photo', 'banned_rights', 'megagroup', 'verified'] as $field) {
if (isset($chat[$field])) {
@@ -192,33 +178,29 @@ trait PeerHandler
}
$chat = $newchat;
}
-
$this->chats[$bot_api_id] = $chat;
-
- if ($this->settings['peer']['full_fetch'] && (!isset($this->full_chats[$bot_api_id]) || $this->full_chats[$bot_api_id]['full']['participants_count'] !== (yield $this->getFullInfo($bot_api_id))['full']['participants_count'])) {
+ if ($this->settings['peer']['full_fetch'] && (!isset($this->full_chats[$bot_api_id]) || $this->full_chats[$bot_api_id]['full']['participants_count'] !== (yield from $this->getFullInfo($bot_api_id))['full']['participants_count'])) {
$this->cachePwrChat($bot_api_id, $this->settings['peer']['full_fetch'], true);
}
}
break;
default:
- throw new \danog\MadelineProto\Exception('Invalid chat provided at key '.$key.': '.\var_export($chat, true));
+ throw new \danog\MadelineProto\Exception('Invalid chat provided at key ' . $key . ': ' . \var_export($chat, true));
break;
}
}
-
private function cachePwrChat($id, $full_fetch, $send)
{
- \danog\MadelineProto\Tools::callFork((function () use ($id, $full_fetch, $send) {
+ \danog\MadelineProto\Tools::callFork((function () use ($id, $full_fetch, $send): \Generator {
try {
- yield $this->getPwrChat($id, $full_fetch, $send);
+ yield from $this->getPwrChat($id, $full_fetch, $send);
} catch (\danog\MadelineProto\Exception $e) {
- $this->logger->logger('While caching: '.$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('While caching: '.$e->getMessage(), \danog\MadelineProto\Logger::WARNING);
+ $this->logger->logger('While caching: ' . $e->getMessage(), \danog\MadelineProto\Logger::WARNING);
}
})());
}
-
/**
* Check if peer is present in internal peer database.
*
@@ -229,7 +211,7 @@ trait PeerHandler
public function peerIsset($id): \Generator
{
try {
- return isset($this->chats[(yield $this->getInfo($id))['bot_api_id']]);
+ return isset($this->chats[(yield from $this->getInfo($id))['bot_api_id']]);
} catch (\danog\MadelineProto\Exception $e) {
return false;
} catch (\danog\MadelineProto\RPCErrorException $e) {
@@ -239,11 +221,9 @@ trait PeerHandler
if ($e->rpc === 'CHANNEL_PRIVATE') {
return true;
}
-
return false;
}
}
-
/**
* Check if all peer entities are in db.
*
@@ -258,7 +238,7 @@ trait PeerHandler
try {
foreach ($entities as $entity) {
if ($entity['_'] === 'messageEntityMentionName' || $entity['_'] === 'inputMessageEntityMentionName') {
- if (!yield $this->peerIsset($entity['user_id'])) {
+ if (!(yield from $this->peerIsset($entity['user_id']))) {
return false;
}
}
@@ -266,10 +246,8 @@ trait PeerHandler
} catch (\danog\MadelineProto\Exception $e) {
return false;
}
-
return true;
}
-
/**
* Check if fwd peer is set.
*
@@ -282,19 +260,17 @@ trait PeerHandler
public function fwdPeerIsset(array $fwd): \Generator
{
try {
- if (isset($fwd['user_id']) && !yield $this->peerIsset($fwd['user_id'])) {
+ if (isset($fwd['user_id']) && !(yield from $this->peerIsset($fwd['user_id']))) {
return false;
}
- if (isset($fwd['channel_id']) && !yield $this->peerIsset($this->toSupergroup($fwd['channel_id']))) {
+ if (isset($fwd['channel_id']) && !(yield from $this->peerIsset($this->toSupergroup($fwd['channel_id'])))) {
return false;
}
} catch (\danog\MadelineProto\Exception $e) {
return false;
}
-
return true;
}
-
/**
* Get folder ID from object.
*
@@ -327,7 +303,7 @@ trait PeerHandler
case 'updateDialogUnreadMark':
case 'updateNotifySettings':
$id = $id['peer'];
- // no break
+ // no break
case 'updateDraftMessage':
case 'inputDialogPeer':
case 'dialogPeer':
@@ -339,15 +315,12 @@ trait PeerHandler
case 'folderPeer':
case 'inputFolderPeer':
return $this->getId($id['peer']);
-
case 'inputUserFromMessage':
case 'inputPeerUserFromMessage':
return $id['user_id'];
-
case 'inputChannelFromMessage':
case 'inputPeerChannelFromMessage':
return $this->toSupergroup($id['channel_id']);
-
case 'inputUserSelf':
case 'inputPeerSelf':
return $this->authorization['user']['id'];
@@ -383,9 +356,7 @@ trait PeerHandler
if (!isset($id['from_id']) || $id['to_id']['_'] !== 'peerUser' || $id['to_id']['user_id'] !== $this->authorization['user']['id']) {
return $this->getId($id['to_id']);
}
-
return $id['from_id'];
-
case 'updateChannelReadMessagesContents':
case 'updateChannelAvailableMessages':
case 'updateChannel':
@@ -399,7 +370,7 @@ trait PeerHandler
return $this->toSupergroup($id['channel_id']);
case 'updateChatParticipants':
$id = $id['participants'];
- // no break
+ // no break
case 'updateChatUserTyping':
case 'updateChatParticipantAdd':
case 'updateChatParticipantDelete':
@@ -434,18 +405,18 @@ trait PeerHandler
case 'updateEditChannelMessage':
return $this->getId($id['message']);
default:
- throw new \danog\MadelineProto\Exception('Invalid constructor given '.\var_export($id, true));
+ throw new \danog\MadelineProto\Exception('Invalid constructor given ' . \var_export($id, true));
}
}
if (\is_string($id)) {
if (\strpos($id, '#') !== false) {
- if (\preg_match('/^channel#(\d*)/', $id, $matches)) {
+ if (\preg_match('/^channel#(\\d*)/', $id, $matches)) {
return $this->toSupergroup($matches[1]);
}
- if (\preg_match('/^chat#(\d*)/', $id, $matches)) {
- $id = '-'.$matches[1];
+ if (\preg_match('/^chat#(\\d*)/', $id, $matches)) {
+ $id = '-' . $matches[1];
}
- if (\preg_match('/^user#(\d*)/', $id, $matches)) {
+ if (\preg_match('/^user#(\\d*)/', $id, $matches)) {
return $matches[1];
}
}
@@ -454,13 +425,10 @@ trait PeerHandler
if (\is_string($id)) {
$id = \danog\MadelineProto\Magic::$bigint ? (float) $id : (int) $id;
}
-
return $id;
}
-
return false;
}
-
/**
* Get info about peer, returns an Info object.
*
@@ -483,14 +451,13 @@ trait PeerHandler
return $this->getSecretChat($id['chat_id']);
case 'updateNewEncryptedMessage':
$id = $id['message'];
- // no break
+ // no break
case 'encryptedMessage':
case 'encryptedMessageService':
$id = $id['chat_id'];
if (!isset($this->secret_chats[$id])) {
throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['sec_peer_not_in_db']);
}
-
return $this->secret_chats[$id];
}
}
@@ -499,13 +466,11 @@ trait PeerHandler
if ($try_id !== false) {
$id = $try_id;
}
-
$tried_simple = false;
-
if (\is_numeric($id)) {
if (!isset($this->chats[$id])) {
try {
- $this->logger->logger("Try fetching $id with access hash 0");
+ $this->logger->logger("Try fetching {$id} with access hash 0");
$this->caching_simple[$id] = true;
if ($id < 0) {
if ($this->isSupergroup($id)) {
@@ -530,7 +495,7 @@ trait PeerHandler
if (isset($this->chats[$id])) {
if (($this->chats[$id]['min'] ?? false) && $this->minDatabase->hasPeer($id) && !isset($this->caching_full_info[$id])) {
$this->caching_full_info[$id] = true;
- $this->logger->logger("Only have min peer for $id in database, trying to fetch full info");
+ $this->logger->logger("Only have min peer for {$id} in database, trying to fetch full info");
try {
if ($id < 0) {
yield $this->methodCallAsyncRead('channels.getChannels', ['id' => [$this->genAll($this->chats[$id], $folder_id)['InputChannel']]], ['datacenter' => $this->datacenter->curdc]);
@@ -545,7 +510,6 @@ trait PeerHandler
unset($this->caching_full_info[$id]);
}
}
-
try {
return $this->genAll($this->chats[$id], $folder_id);
} catch (\danog\MadelineProto\Exception $e) {
@@ -558,56 +522,50 @@ trait PeerHandler
}
if (!isset($this->settings['pwr']['requests']) || $this->settings['pwr']['requests'] === true && $recursive) {
$dbres = [];
-
try {
- $dbres = \json_decode(yield $this->datacenter->fileGetContents('https://id.pwrtelegram.xyz/db/getusername?id='.$id), true);
+ $dbres = \json_decode(yield $this->datacenter->fileGetContents('https://id.pwrtelegram.xyz/db/getusername?id=' . $id), true);
} catch (\Throwable $e) {
$this->logger->logger($e);
}
if (isset($dbres['ok']) && $dbres['ok']) {
- yield $this->resolveUsername('@'.$dbres['result']);
-
- return yield $this->getInfo($id, false);
+ yield from $this->resolveUsername('@' . $dbres['result']);
+ return yield from $this->getInfo($id, false);
}
}
if ($tried_simple && isset($this->caching_possible_username[$id])) {
- $this->logger->logger("No access hash with $id, trying to fetch by username...");
-
+ $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 yield $this->getInfo($user);
+ return yield from $this->getInfo($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)) {
+ if (\preg_match('@(?:t|telegram)\\.(?:me|dog)/(joinchat/)?([a-z0-9_-]*)@i', $id, $matches)) {
if ($matches[1] === '') {
$id = $matches[2];
} else {
$invite = yield $this->methodCallAsyncRead('messages.checkChatInvite', ['hash' => $matches[2]], ['datacenter' => $this->datacenter->curdc]);
if (isset($invite['chat'])) {
- return yield $this->getInfo($invite['chat']);
+ return yield from $this->getInfo($invite['chat']);
}
throw new \danog\MadelineProto\Exception('You have not joined this chat');
}
}
$id = \strtolower(\str_replace('@', '', $id));
if ($id === 'me') {
- return yield $this->getInfo($this->authorization['user']['id']);
+ return yield from $this->getInfo($this->authorization['user']['id']);
}
if ($id === 'support') {
if (!$this->supportUser) {
yield $this->methodCallAsyncRead('help.getSupport', [], ['datacenter' => $this->settings['connection_settings']['default_dc']]);
}
-
- return yield $this->getInfo($this->supportUser);
+ return yield from $this->getInfo($this->supportUser);
}
foreach ($this->chats as $bot_api_id => $chat) {
if (isset($chat['username']) && \strtolower($chat['username']) === $id) {
if ($chat['min'] ?? false && !isset($this->caching_full_info[$bot_api_id])) {
$this->caching_full_info[$bot_api_id] = true;
- $this->logger->logger("Only have min peer for $bot_api_id in database, trying to fetch full info");
+ $this->logger->logger("Only have min peer for {$bot_api_id} in database, trying to fetch full info");
try {
if ($bot_api_id < 0) {
yield $this->methodCallAsyncRead('channels.getChannels', ['id' => [$this->genAll($this->chats[$bot_api_id], $folder_id)['InputChannel']]], ['datacenter' => $this->datacenter->curdc]);
@@ -622,19 +580,15 @@ trait PeerHandler
unset($this->caching_full_info[$bot_api_id]);
}
}
-
return $this->genAll($this->chats[$bot_api_id], $folder_id);
}
}
if ($recursive) {
- yield $this->resolveUsername($id);
-
- return yield $this->getInfo($id, false);
+ yield from $this->resolveUsername($id);
+ return yield from $this->getInfo($id, false);
}
-
throw new \danog\MadelineProto\Exception('This peer is not present in the internal peer database');
}
-
private function genAll($constructor, $folder_id = null)
{
$res = [$this->TL->getConstructors()->findByPredicate($constructor['_'])['type'] => $constructor];
@@ -656,7 +610,7 @@ trait PeerHandler
$res['InputNotifyPeer'] = ['_' => 'inputNotifyPeer', 'peer' => $res['InputPeer']];
$res['user_id'] = $constructor['id'];
$res['bot_api_id'] = $constructor['id'];
- $res['type'] = ($constructor['bot'] ?? false) ? 'bot' : 'user';
+ $res['type'] = $constructor['bot'] ?? false ? 'bot' : 'user';
break;
case 'chat':
case 'chatForbidden':
@@ -683,12 +637,12 @@ trait PeerHandler
$res['InputChannel'] = ['_' => 'inputChannel', 'channel_id' => $constructor['id'], 'access_hash' => $constructor['access_hash'], 'min' => $constructor['min']];
$res['channel_id'] = $constructor['id'];
$res['bot_api_id'] = $this->toSupergroup($constructor['id']);
- $res['type'] = ($constructor['megagroup'] ?? false) ? 'supergroup' : 'channel';
+ $res['type'] = $constructor['megagroup'] ?? false ? 'supergroup' : 'channel';
break;
case 'channelForbidden':
throw new \danog\MadelineProto\Exception('This peer is not present in the internal peer database');
default:
- throw new \danog\MadelineProto\Exception('Invalid constructor given '.\var_export($constructor, true));
+ throw new \danog\MadelineProto\Exception('Invalid constructor given ' . \var_export($constructor, true));
}
if ($folder_id) {
$res['FolderPeer'] = ['_' => 'folderPeer', 'peer' => $res['Peer'], 'folder_id' => $folder_id];
@@ -696,7 +650,6 @@ trait PeerHandler
}
return $res;
}
-
/**
* When were full info for this chat last cached.
*
@@ -708,7 +661,6 @@ trait PeerHandler
{
return isset($this->full_chats[$id]['last_update']) ? $this->full_chats[$id]['last_update'] : 0;
}
-
/**
* Get full info about peer, returns an FullInfo object.
*
@@ -720,7 +672,7 @@ trait PeerHandler
*/
public function getFullInfo($id): \Generator
{
- $partial = yield $this->getInfo($id);
+ $partial = (yield from $this->getInfo($id));
if (\time() - $this->fullChatLastUpdated($partial['bot_api_id']) < (isset($this->settings['peer']['full_info_cache_time']) ? $this->settings['peer']['full_info_cache_time'] : 0)) {
return \array_merge($partial, $this->full_chats[$partial['bot_api_id']]);
}
@@ -737,17 +689,13 @@ trait PeerHandler
$full = (yield $this->methodCallAsyncRead('channels.getFullChannel', ['channel' => $partial['InputChannel']], ['datacenter' => $this->datacenter->curdc]))['full_chat'];
break;
}
-
$res = [];
$res['full'] = $full;
$res['last_update'] = \time();
$this->full_chats[$partial['bot_api_id']] = $res;
-
- $partial = yield $this->getInfo($id);
-
+ $partial = (yield from $this->getInfo($id));
return \array_merge($partial, $res);
}
-
/**
* Get full info about peer (including full list of channel members), returns a Chat object.
*
@@ -759,7 +707,7 @@ trait PeerHandler
*/
public function getPwrChat($id, $fullfetch = true, $send = true): \Generator
{
- $full = $fullfetch ? yield $this->getFullInfo($id) : yield $this->getInfo($id);
+ $full = $fullfetch ? yield from $this->getFullInfo($id) : (yield from $this->getInfo($id));
$res = ['id' => $full['bot_api_id'], 'type' => $full['type']];
switch ($full['type']) {
case 'user':
@@ -828,15 +776,15 @@ trait PeerHandler
if (isset($res['participants']) && $fullfetch) {
foreach ($res['participants'] as $key => $participant) {
$newres = [];
- $newres['user'] = yield $this->getPwrChat($participant['user_id'], false, true);
+ $newres['user'] = (yield from $this->getPwrChat($participant['user_id'], false, true));
if (isset($participant['inviter_id'])) {
- $newres['inviter'] = yield $this->getPwrChat($participant['inviter_id'], false, true);
+ $newres['inviter'] = (yield from $this->getPwrChat($participant['inviter_id'], false, true));
}
if (isset($participant['promoted_by'])) {
- $newres['promoted_by'] = yield $this->getPwrChat($participant['promoted_by'], false, true);
+ $newres['promoted_by'] = (yield from $this->getPwrChat($participant['promoted_by'], false, true));
}
if (isset($participant['kicked_by'])) {
- $newres['kicked_by'] = yield $this->getPwrChat($participant['kicked_by'], false, true);
+ $newres['kicked_by'] = (yield from $this->getPwrChat($participant['kicked_by'], false, true));
}
if (isset($participant['date'])) {
$newres['date'] = $participant['date'];
@@ -873,15 +821,14 @@ trait PeerHandler
$limit = 200;
$filters = ['channelParticipantsAdmins', 'channelParticipantsBots'];
foreach ($filters as $filter) {
- yield $this->fetchParticipants($full['InputChannel'], $filter, '', $total_count, $res);
+ yield from $this->fetchParticipants($full['InputChannel'], $filter, '', $total_count, $res);
}
$q = '';
-
$filters = ['channelParticipantsSearch', 'channelParticipantsKicked', 'channelParticipantsBanned'];
foreach ($filters as $filter) {
- yield $this->recurseAlphabetSearchParticipants($full['InputChannel'], $filter, $q, $total_count, $res);
+ yield from $this->recurseAlphabetSearchParticipants($full['InputChannel'], $filter, $q, $total_count, $res);
}
- $this->logger->logger('Fetched '.\count($res['participants'])." out of $total_count");
+ $this->logger->logger('Fetched ' . \count($res['participants']) . " out of {$total_count}");
$res['participants'] = \array_values($res['participants']);
}
if (!$fullfetch) {
@@ -890,64 +837,55 @@ trait PeerHandler
if ($fullfetch || $send) {
$this->storeDb($res);
}
-
return $res;
}
-
- private function recurseAlphabetSearchParticipants($channel, $filter, $q, $total_count, &$res)
+ private function recurseAlphabetSearchParticipants($channel, $filter, $q, $total_count, &$res): \Generator
{
- if (!yield $this->fetchParticipants($channel, $filter, $q, $total_count, $res)) {
+ if (!(yield from $this->fetchParticipants($channel, $filter, $q, $total_count, $res))) {
return false;
}
-
for ($x = 'a'; $x !== 'aa' && $total_count > \count($res['participants']); $x++) {
- yield $this->recurseAlphabetSearchParticipants($channel, $filter, $q.$x, $total_count, $res);
+ yield from $this->recurseAlphabetSearchParticipants($channel, $filter, $q . $x, $total_count, $res);
}
}
-
- private function fetchParticipants($channel, $filter, $q, $total_count, &$res)
+ private function fetchParticipants($channel, $filter, $q, $total_count, &$res): \Generator
{
$offset = 0;
$limit = 200;
$has_more = false;
$cached = false;
$last_count = -1;
-
do {
try {
$gres = yield $this->methodCallAsyncRead('channels.getParticipants', ['channel' => $channel, 'filter' => ['_' => $filter, 'q' => $q], 'offset' => $offset, 'limit' => $limit, 'hash' => $hash = $this->getParticipantsHash($channel, $filter, $q, $offset, $limit)], ['datacenter' => $this->datacenter->curdc, 'heavy' => true]);
} catch (\danog\MadelineProto\RPCErrorException $e) {
if ($e->rpc === 'CHAT_ADMIN_REQUIRED') {
$this->logger->logger($e->rpc);
-
return $has_more;
}
throw $e;
}
-
if ($cached = $gres['_'] === 'channels.channelParticipantsNotModified') {
$gres = $this->fetchParticipantsCache($channel, $filter, $q, $offset, $limit);
} else {
$this->storeParticipantsCache($gres, $channel, $filter, $q, $offset, $limit);
}
-
if ($last_count !== -1 && $last_count !== $gres['count']) {
$has_more = true;
} else {
$last_count = $gres['count'];
}
-
foreach ($gres['participants'] as $participant) {
$newres = [];
- $newres['user'] = yield $this->getPwrChat($participant['user_id'], false, true);
+ $newres['user'] = (yield from $this->getPwrChat($participant['user_id'], false, true));
if (isset($participant['inviter_id'])) {
- $newres['inviter'] = yield $this->getPwrChat($participant['inviter_id'], false, true);
+ $newres['inviter'] = (yield from $this->getPwrChat($participant['inviter_id'], false, true));
}
if (isset($participant['kicked_by'])) {
- $newres['kicked_by'] = yield $this->getPwrChat($participant['kicked_by'], false, true);
+ $newres['kicked_by'] = (yield from $this->getPwrChat($participant['kicked_by'], false, true));
}
if (isset($participant['promoted_by'])) {
- $newres['promoted_by'] = yield $this->getPwrChat($participant['promoted_by'], false, true);
+ $newres['promoted_by'] = (yield from $this->getPwrChat($participant['promoted_by'], false, true));
}
if (isset($participant['date'])) {
$newres['date'] = $participant['date'];
@@ -980,22 +918,18 @@ trait PeerHandler
}
$res['participants'][$participant['user_id']] = $newres;
}
- $this->logger->logger('Fetched '.\count($gres['participants'])." channel participants with filter $filter, query $q, offset $offset, limit $limit, hash $hash: ".($cached ? 'cached' : 'not cached').', '.($offset + \count($gres['participants'])).' participants out of '.$gres['count'].', in total fetched '.\count($res['participants']).' out of '.$total_count);
+ $this->logger->logger('Fetched ' . \count($gres['participants']) . " channel participants with filter {$filter}, query {$q}, offset {$offset}, limit {$limit}, hash {$hash}: " . ($cached ? 'cached' : 'not cached') . ', ' . ($offset + \count($gres['participants'])) . ' participants out of ' . $gres['count'] . ', in total fetched ' . \count($res['participants']) . ' out of ' . $total_count);
$offset += \count($gres['participants']);
} while (\count($gres['participants']));
-
if ($offset === $limit) {
return true;
}
-
return $has_more;
}
-
private function fetchParticipantsCache($channel, $filter, $q, $offset, $limit)
{
return $this->channel_participants[$channel['channel_id']][$filter][$q][$offset][$limit];
}
-
private function storeParticipantsCache($gres, $channel, $filter, $q, $offset, $limit)
{
//return;
@@ -1008,13 +942,11 @@ trait PeerHandler
$gres['hash'] = \danog\MadelineProto\Tools::genVectorHash($ids);
$this->channel_participants[$channel['channel_id']][$filter][$q][$offset][$limit] = $gres;
}
-
private function getParticipantsHash($channel, $filter, $q, $offset, $limit)
{
return isset($this->channel_participants[$channel['channel_id']][$filter][$q][$offset][$limit]) ? $this->channel_participants[$channel['channel_id']][$filter][$q][$offset][$limit]['hash'] : 0;
}
-
- private function storeDb($res, $force = false)
+ private function storeDb($res, $force = false): \Generator
{
$settings = isset($this->settings['connection_settings'][$this->datacenter->curdc]) ? $this->settings['connection_settings'][$this->datacenter->curdc] : $this->settings['connection_settings']['all'];
if (!isset($this->settings['pwr']) || $this->settings['pwr']['pwr'] === false || $settings['test_mode']) {
@@ -1033,29 +965,22 @@ trait PeerHandler
if (empty($this->qres)) {
return false;
}
-
try {
$payload = \json_encode($this->qres);
//$path = '/tmp/ids'.hash('sha256', $payload);
//file_put_contents($path, $payload);
$id = isset($this->authorization['user']['username']) ? $this->authorization['user']['username'] : $this->authorization['user']['id'];
-
- $request = new Request('https://id.pwrtelegram.xyz/db'.$this->settings['pwr']['db_token'].'/addnewmadeline?d=pls&from='.$id, 'POST');
+ $request = new Request('https://id.pwrtelegram.xyz/db' . $this->settings['pwr']['db_token'] . '/addnewmadeline?d=pls&from=' . $id, 'POST');
$request->setHeader('content-type', 'application/json');
$request->setBody($payload);
-
- $result = yield (
- yield $this->datacenter->getHTTPClient()->request($request)
- )->getBody()->buffer();
-
- $this->logger->logger("============ $result =============", \danog\MadelineProto\Logger::VERBOSE);
+ $result = yield (yield $this->datacenter->getHTTPClient()->request($request))->getBody()->buffer();
+ $this->logger->logger("============ {$result} =============", \danog\MadelineProto\Logger::VERBOSE);
$this->qres = [];
$this->last_stored = \time() + 10;
} catch (\danog\MadelineProto\Exception $e) {
- $this->logger->logger('======= COULD NOT STORE IN DB DUE TO '.$e->getMessage().' =============', \danog\MadelineProto\Logger::VERBOSE);
+ $this->logger->logger('======= COULD NOT STORE IN DB DUE TO ' . $e->getMessage() . ' =============', \danog\MadelineProto\Logger::VERBOSE);
}
}
-
/**
* Resolve username (use getInfo instead).
*
@@ -1069,11 +994,10 @@ trait PeerHandler
$this->caching_simple_username[$username] = true;
$res = yield $this->methodCallAsyncRead('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);
+ $this->logger->logger('Username resolution failed with error ' . $e->getMessage(), \danog\MadelineProto\Logger::ERROR);
if (\strpos($e->rpc, 'FLOOD_WAIT_') === 0 || $e->rpc === 'AUTH_KEY_UNREGISTERED' || $e->rpc === 'USERNAME_INVALID') {
throw $e;
}
-
return false;
} finally {
if (isset($this->caching_simple_username[$username])) {
@@ -1083,7 +1007,6 @@ trait PeerHandler
if ($res['_'] === 'contacts.resolvedPeer') {
return $res;
}
-
return false;
}
}
diff --git a/src/danog/MadelineProto/MTProtoTools/ReferenceDatabase.php b/src/danog/MadelineProto/MTProtoTools/ReferenceDatabase.php
index 8f41fb69..dc3faa15 100644
--- a/src/danog/MadelineProto/MTProtoTools/ReferenceDatabase.php
+++ b/src/danog/MadelineProto/MTProtoTools/ReferenceDatabase.php
@@ -38,7 +38,6 @@ class ReferenceDatabase implements TLCallback
const PHOTO_LOCATION_LOCATION = 2;
// DEPRECATED: Reference from a location (can only be document location)
const DOCUMENT_LOCATION_LOCATION = 0;
-
// Peer + photo ID
const USER_PHOTO_ORIGIN = 0;
// Peer (default photo ID)
@@ -57,42 +56,15 @@ class ReferenceDatabase implements TLCallback
const STICKER_SET_EMOTICON_ORIGIN = 8;
//
const WALLPAPER_ORIGIN = 9;
-
const LOCATION_CONTEXT = [
//'inputFileLocation' => self::PHOTO_LOCATION_LOCATION, // DEPRECATED
'inputDocumentFileLocation' => self::DOCUMENT_LOCATION,
- 'inputPhotoFileLocation' => self::PHOTO_LOCATION,
- 'inputPhoto' => self::PHOTO_LOCATION,
- 'inputDocument' => self::DOCUMENT_LOCATION,
- ];
- const METHOD_CONTEXT = [
- 'photos.updateProfilePhoto' => self::USER_PHOTO_ORIGIN,
- 'photos.getUserPhotos' => self::USER_PHOTO_ORIGIN,
- 'photos.uploadProfilePhoto' => self::USER_PHOTO_ORIGIN,
- 'messages.getStickers' => self::STICKER_SET_EMOTICON_ORIGIN,
- ];
- const CONSTRUCTOR_CONTEXT = [
- 'message' => self::MESSAGE_ORIGIN,
- 'messageService' => self::MESSAGE_ORIGIN,
-
- 'chatFull' => self::PEER_PHOTO_ORIGIN,
- 'channelFull' => self::PEER_PHOTO_ORIGIN,
- 'chat' => self::PEER_PHOTO_ORIGIN,
- 'channel' => self::PEER_PHOTO_ORIGIN,
-
- 'updateUserPhoto' => self::USER_PHOTO_ORIGIN,
- 'user' => self::USER_PHOTO_ORIGIN,
- 'userFull' => self::USER_PHOTO_ORIGIN,
-
- 'wallPaper' => self::WALLPAPER_ORIGIN,
-
- 'messages.savedGifs' => self::SAVED_GIFS_ORIGIN,
-
- 'messages.recentStickers' => self::STICKER_SET_RECENT_ORIGIN,
- 'messages.favedStickers' => self::STICKER_SET_FAVED_ORIGIN,
- 'messages.stickerSet' => self::STICKER_SET_ID_ORIGIN,
- 'document' => self::STICKER_SET_ID_ORIGIN,
+ 'inputPhotoFileLocation' => self::PHOTO_LOCATION,
+ 'inputPhoto' => self::PHOTO_LOCATION,
+ 'inputDocument' => self::DOCUMENT_LOCATION,
];
+ const METHOD_CONTEXT = ['photos.updateProfilePhoto' => self::USER_PHOTO_ORIGIN, 'photos.getUserPhotos' => self::USER_PHOTO_ORIGIN, 'photos.uploadProfilePhoto' => self::USER_PHOTO_ORIGIN, 'messages.getStickers' => self::STICKER_SET_EMOTICON_ORIGIN];
+ const CONSTRUCTOR_CONTEXT = ['message' => self::MESSAGE_ORIGIN, 'messageService' => self::MESSAGE_ORIGIN, 'chatFull' => self::PEER_PHOTO_ORIGIN, 'channelFull' => self::PEER_PHOTO_ORIGIN, 'chat' => self::PEER_PHOTO_ORIGIN, 'channel' => self::PEER_PHOTO_ORIGIN, 'updateUserPhoto' => self::USER_PHOTO_ORIGIN, 'user' => self::USER_PHOTO_ORIGIN, 'userFull' => self::USER_PHOTO_ORIGIN, 'wallPaper' => self::WALLPAPER_ORIGIN, 'messages.savedGifs' => self::SAVED_GIFS_ORIGIN, 'messages.recentStickers' => self::STICKER_SET_RECENT_ORIGIN, 'messages.favedStickers' => self::STICKER_SET_FAVED_ORIGIN, 'messages.stickerSet' => self::STICKER_SET_ID_ORIGIN, 'document' => self::STICKER_SET_ID_ORIGIN];
/**
* References indexed by location.
*
@@ -105,70 +77,56 @@ class ReferenceDatabase implements TLCallback
private $API;
private $refresh = false;
private $refreshCount = 0;
-
public function __construct(MTProto $API)
{
$this->API = $API;
$this->init();
}
-
public function __wakeup()
{
$this->init();
}
-
public function __sleep()
{
return ['db', 'API'];
}
-
public function init()
{
foreach ($this->db as $key => $value) {
- if ($key[0] === "0") { // Unsetting deprecated DOCUMENT_LOCATION_LOCATION
+ if ($key[0] === "0") {
+ // Unsetting deprecated DOCUMENT_LOCATION_LOCATION
unset($this->db[$key]);
}
}
}
-
public function getMethodCallbacks(): array
{
return \array_fill_keys(\array_keys(self::METHOD_CONTEXT), [[$this, 'addOriginMethod']]);
}
-
public function getMethodBeforeCallbacks(): array
{
return \array_fill_keys(\array_keys(self::METHOD_CONTEXT), [[$this, 'addOriginMethodContext']]);
}
-
public function getConstructorCallbacks(): array
{
- return \array_merge(
- \array_fill_keys(['document', 'photo', 'fileLocation'], [[$this, 'addReference']]),
- \array_fill_keys(\array_keys(self::CONSTRUCTOR_CONTEXT), [[$this, 'addOrigin']]),
- ['document' => [[$this, 'addReference'], [$this, 'addOrigin']]]
- );
+ return \array_merge(\array_fill_keys(['document', 'photo', 'fileLocation'], [[$this, 'addReference']]), \array_fill_keys(\array_keys(self::CONSTRUCTOR_CONTEXT), [[$this, 'addOrigin']]), ['document' => [[$this, 'addReference'], [$this, 'addOrigin']]]);
}
-
public function getConstructorBeforeCallbacks(): array
{
return \array_fill_keys(\array_keys(self::CONSTRUCTOR_CONTEXT), [[$this, 'addOriginContext']]);
}
-
public function getConstructorSerializeCallbacks(): array
{
return \array_fill_keys(\array_keys(self::LOCATION_CONTEXT), [$this, 'populateReference']);
}
-
public function getTypeMismatchCallbacks(): array
{
return [];
}
-
public function reset()
{
if ($this->cacheContexts) {
- $this->API->logger->logger('Found '.\count($this->cacheContexts).' pending contexts', \danog\MadelineProto\Logger::ERROR);
+ $this->API->logger->logger('Found ' . \count($this->cacheContexts) . ' pending contexts', \danog\MadelineProto\Logger::ERROR);
$this->cacheContexts = [];
}
if ($this->cache) {
@@ -176,7 +134,6 @@ class ReferenceDatabase implements TLCallback
$this->cache = [];
}
}
-
public function addReference(array $location)
{
if (!$this->cacheContexts) {
@@ -189,18 +146,15 @@ class ReferenceDatabase implements TLCallback
if ($frame['args'][1]['subtype'] === $previous) {
continue;
}
-
$frames[] = $frame['args'][1]['subtype'];
$previous = $frame['args'][1]['subtype'];
} elseif (isset($frame['args'][1]['type'])) {
if ($frame['args'][1]['type'] === '') {
break;
}
-
if ($frame['args'][1]['type'] === $previous) {
continue;
}
-
$frames[] = $frame['args'][1]['type'];
$previous = $frame['args'][1]['type'];
}
@@ -209,15 +163,13 @@ class ReferenceDatabase implements TLCallback
$frames = \array_reverse($frames);
$tl_trace = \array_shift($frames);
foreach ($frames as $frame) {
- $tl_trace .= "['".$frame."']";
+ $tl_trace .= "['" . $frame . "']";
}
$this->API->logger->logger($tl_trace, \danog\MadelineProto\Logger::ERROR);
-
return false;
}
if (!isset($location['file_reference'])) {
$this->API->logger->logger("Object {$location['_']} does not have reference", \danog\MadelineProto\Logger::ERROR);
-
return false;
}
$key = \count($this->cacheContexts) - 1;
@@ -232,27 +184,24 @@ class ReferenceDatabase implements TLCallback
$locationType = self::PHOTO_LOCATION_LOCATION;
break;
default:
- throw new Exception('Unknown location type provided: '.$location['_']);
+ throw new Exception('Unknown location type provided: ' . $location['_']);
}
- $this->API->logger->logger("Caching reference from location of type $locationType from {$location['_']}", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
+ $this->API->logger->logger("Caching reference from location of type {$locationType} from {$location['_']}", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
if (!isset($this->cache[$key])) {
$this->cache[$key] = [];
}
$this->cache[$key][$this->serializeLocation($locationType, $location)] = (string) $location['file_reference'];
-
return true;
}
-
public function addOriginContext(string $type)
{
if (!isset(self::CONSTRUCTOR_CONTEXT[$type])) {
- throw new \danog\MadelineProto\Exception("Unknown origin type provided: $type");
+ throw new \danog\MadelineProto\Exception("Unknown origin type provided: {$type}");
}
$originContext = self::CONSTRUCTOR_CONTEXT[$type];
- $this->API->logger->logger("Adding origin context $originContext for {$type}!", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
+ $this->API->logger->logger("Adding origin context {$originContext} for {$type}!", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
$this->cacheContexts[] = $originContext;
}
-
public function addOrigin(array $data = [])
{
$key = \count($this->cacheContexts) - 1;
@@ -261,8 +210,7 @@ class ReferenceDatabase implements TLCallback
}
$originType = \array_pop($this->cacheContexts);
if (!isset($this->cache[$key])) {
- $this->API->logger->logger("Removing origin context $originType for {$data['_']}, nothing in the reference cache!", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
-
+ $this->API->logger->logger("Removing origin context {$originType} for {$data['_']}, nothing in the reference cache!", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
return;
}
$cache = $this->cache[$key];
@@ -316,12 +264,10 @@ class ReferenceDatabase implements TLCallback
if (!isset($this->cache[$key])) {
$this->cache[$key] = [];
}
-
foreach ($cache as $location => $reference) {
$this->cache[$key][$location] = $reference;
}
- $this->API->logger->logger("Skipped origin $originType ({$data['_']}) for ".\count($cache).' references', \danog\MadelineProto\Logger::ULTRA_VERBOSE);
-
+ $this->API->logger->logger("Skipped origin {$originType} ({$data['_']}) for " . \count($cache) . ' references', \danog\MadelineProto\Logger::ULTRA_VERBOSE);
return;
}
break;
@@ -334,19 +280,17 @@ class ReferenceDatabase implements TLCallback
foreach ($cache as $location => $reference) {
$this->storeReference($location, $reference, $originType, $origin);
}
- $this->API->logger->logger("Added origin $originType ({$data['_']}) to ".\count($cache).' references', \danog\MadelineProto\Logger::ULTRA_VERBOSE);
+ $this->API->logger->logger("Added origin {$originType} ({$data['_']}) to " . \count($cache) . ' references', \danog\MadelineProto\Logger::ULTRA_VERBOSE);
}
-
public function addOriginMethodContext(string $type)
{
if (!isset(self::METHOD_CONTEXT[$type])) {
throw new \danog\MadelineProto\Exception("Unknown origin type provided: {$type}");
}
$originContext = self::METHOD_CONTEXT[$type];
- $this->API->logger->logger("Adding origin context $originContext for {$type}!", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
+ $this->API->logger->logger("Adding origin context {$originContext} for {$type}!", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
$this->cacheContexts[] = $originContext;
}
-
public function addOriginMethod(array $data, array $res)
{
$key = \count($this->cacheContexts) - 1;
@@ -355,8 +299,7 @@ class ReferenceDatabase implements TLCallback
}
$originType = \array_pop($this->cacheContexts);
if (!isset($this->cache[$key])) {
- $this->API->logger->logger("Removing origin context $originType for {$data['_']}, nothing in the reference cache!", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
-
+ $this->API->logger->logger("Removing origin context {$originType} for {$data['_']}, nothing in the reference cache!", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
return;
}
$cache = $this->cache[$key];
@@ -384,16 +327,13 @@ class ReferenceDatabase implements TLCallback
foreach ($res['photos'] as $photo) {
$origin['max_id'] = $photo['id'];
$dc_id = $photo['dc_id'];
-
$location = $this->serializeLocation(self::PHOTO_LOCATION, $photo);
if (isset($cache[$location])) {
$reference = $cache[$location];
unset($cache[$location]);
-
$this->storeReference($location, $reference, $originType, $origin);
$count++;
}
-
if (isset($photo['sizes'])) {
foreach ($photo['sizes'] as $size) {
if (isset($size['location'])) {
@@ -409,8 +349,7 @@ class ReferenceDatabase implements TLCallback
}
}
}
- $this->API->logger->logger("Added origin $originType ({$data['_']}) to $count references", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
-
+ $this->API->logger->logger("Added origin {$originType} ({$data['_']}) to {$count} references", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
return;
case 'messages.getStickers':
$origin['emoticon'] = $body['emoticon'];
@@ -421,9 +360,8 @@ class ReferenceDatabase implements TLCallback
foreach ($cache as $location => $reference) {
$this->storeReference($location, $reference, $originType, $origin);
}
- $this->API->logger->logger("Added origin $originType ({$data['_']}) to ".\count($cache).' references', \danog\MadelineProto\Logger::ULTRA_VERBOSE);
+ $this->API->logger->logger("Added origin {$originType} ({$data['_']}) to " . \count($cache) . ' references', \danog\MadelineProto\Logger::ULTRA_VERBOSE);
}
-
public function storeReference(string $location, string $reference, int $originType, array $origin)
{
if (!isset($this->db[$location])) {
@@ -431,17 +369,14 @@ class ReferenceDatabase implements TLCallback
}
$this->db[$location]['reference'] = $reference;
$this->db[$location]['origins'][$originType] = $origin;
-
if ($this->refresh) {
$this->refreshed[$location] = true;
}
-
$key = \count($this->cacheContexts) - 1;
if ($key >= 0) {
$this->cache[$key][$location] = $reference;
}
}
-
public function refreshNext($refresh = false)
{
if ($this->refreshCount === 1 && !$refresh) {
@@ -459,23 +394,18 @@ class ReferenceDatabase implements TLCallback
$this->refreshCount--;
}
}
-
public function refreshReference(int $locationType, array $location)
{
return $this->refreshReferenceInternal($this->serializeLocation($locationType, $location));
}
-
- public function refreshReferenceInternal(string $location)
+ public function refreshReferenceInternal(string $location): \Generator
{
if (isset($this->refreshed[$location])) {
$this->API->logger->logger('Reference already refreshed!', \danog\MadelineProto\Logger::VERBOSE);
-
return $this->db[$location]['reference'];
}
-
\ksort($this->db[$location]['origins']);
$count = 0;
-
foreach ($this->db[$location]['origins'] as $originType => &$origin) {
$count++;
$this->API->logger->logger("Try {$count} refreshing file reference with origin type {$originType}", \danog\MadelineProto\Logger::VERBOSE);
@@ -521,67 +451,54 @@ class ReferenceDatabase implements TLCallback
yield $this->API->methodCallAsyncRead('account.getWallPapers', $origin, ['datacenter' => $this->API->settings['connection_settings']['default_dc']]);
break;
default:
- throw new \danog\MadelineProto\Exception("Unknown origin type $originType");
+ throw new \danog\MadelineProto\Exception("Unknown origin type {$originType}");
}
if (isset($this->refreshed[$location])) {
return $this->db[$location]['reference'];
}
}
-
throw new Exception('Did not refresh reference');
}
-
- public function populateReference(array $object)
+ public function populateReference(array $object): \Generator
{
$object['file_reference'] = yield $this->getReference(self::LOCATION_CONTEXT[$object['_']], $object);
-
return $object;
}
-
public function getReference(int $locationType, array $location)
{
$locationString = $this->serializeLocation($locationType, $location);
if (!isset($this->db[$locationString]['reference'])) {
if (isset($location['file_reference'])) {
- $this->API->logger->logger("Using outdated file reference for location of type $locationType object {$location['_']}", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
-
+ $this->API->logger->logger("Using outdated file reference for location of type {$locationType} object {$location['_']}", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
return $location['file_reference'];
}
-
if (!$this->refresh) {
- $this->API->logger->logger("Using null file reference for location of type $locationType object {$location['_']}", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
-
+ $this->API->logger->logger("Using null file reference for location of type {$locationType} object {$location['_']}", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
return '';
}
-
- throw new \danog\MadelineProto\Exception("Could not find file reference for location of type $locationType object {$location['_']}");
+ throw new \danog\MadelineProto\Exception("Could not find file reference for location of type {$locationType} object {$location['_']}");
}
- $this->API->logger->logger("Getting file reference for location of type $locationType object {$location['_']}", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
-
+ $this->API->logger->logger("Getting file reference for location of type {$locationType} object {$location['_']}", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
if ($this->refresh) {
return $this->refreshReferenceInternal($locationString);
}
-
return $this->db[$locationString]['reference'];
}
-
private function serializeLocation(int $locationType, array $location)
{
switch ($locationType) {
case self::DOCUMENT_LOCATION:
case self::PHOTO_LOCATION:
- return $locationType.(\is_int($location['id']) ? \danog\MadelineProto\Tools::packSignedLong($location['id']) : $location['id']);
+ return $locationType . (\is_int($location['id']) ? \danog\MadelineProto\Tools::packSignedLong($location['id']) : $location['id']);
case self::PHOTO_LOCATION_LOCATION:
$dc_id = \danog\MadelineProto\Tools::packSignedInt($location['dc_id']);
$volume_id = \is_int($location['volume_id']) ? \danog\MadelineProto\Tools::packSignedLong($location['volume_id']) : $location['volume_id'];
$local_id = \danog\MadelineProto\Tools::packSignedInt($location['local_id']);
-
- return $locationType.$dc_id.$volume_id.$local_id;
+ return $locationType . $dc_id . $volume_id . $local_id;
}
}
-
public function __debugInfo()
{
- return ['ReferenceDatabase instance '.\spl_object_hash($this)];
+ return ['ReferenceDatabase instance ' . \spl_object_hash($this)];
}
}
diff --git a/src/danog/MadelineProto/MTProtoTools/UpdateHandler.php b/src/danog/MadelineProto/MTProtoTools/UpdateHandler.php
index 2fa3f2eb..219dbadb 100644
--- a/src/danog/MadelineProto/MTProtoTools/UpdateHandler.php
+++ b/src/danog/MadelineProto/MTProtoTools/UpdateHandler.php
@@ -34,7 +34,6 @@ trait UpdateHandler
private $channels_state;
public $updates = [];
public $updates_key = 0;
-
/**
* PWR update handler.
*
@@ -56,7 +55,6 @@ trait UpdateHandler
\in_array($this->settings['pwr']['updateHandler'], [['danog\\MadelineProto\\API', 'getUpdatesUpdateHandler'], 'getUpdatesUpdateHandler']) ? $this->getUpdatesUpdateHandler($update) : $this->settings['pwr']['updateHandler']($update);
}
}
-
/**
* Getupdates update handler.
*
@@ -73,7 +71,6 @@ trait UpdateHandler
}
$this->updates[$this->updates_key++] = $update;
}
-
/**
* Get updates.
*
@@ -92,9 +89,7 @@ trait UpdateHandler
if (!$this->settings['updates']['run_callback']) {
$this->settings['updates']['run_callback'] = true;
}
-
$params = \array_merge(self::DEFAULT_GETUPDATES_PARAMS, $params);
-
if (empty($this->updates)) {
$this->update_deferred = new Deferred();
if (!$params['timeout']) {
@@ -102,11 +97,9 @@ trait UpdateHandler
}
yield \danog\MadelineProto\Tools::first([$this->waitUpdate(), \danog\MadelineProto\Tools::sleep($params['timeout'])]);
}
-
if (empty($this->updates)) {
return [];
}
-
if ($params['offset'] < 0) {
$params['offset'] = \array_reverse(\array_keys((array) $this->updates))[\abs($params['offset']) - 1];
}
@@ -118,13 +111,10 @@ trait UpdateHandler
$updates[] = ['update_id' => $key, 'update' => $value];
}
}
-
return $updates;
}
-
public $update_resolved = false;
public $update_deferred;
-
/**
* Wait for update.
*
@@ -141,7 +131,6 @@ trait UpdateHandler
$this->update_resolved = false;
$this->update_deferred = new Deferred();
}
-
/**
* Signal update.
*
@@ -161,8 +150,6 @@ trait UpdateHandler
}
});
}
-
-
/**
* Check message ID.
*
@@ -177,7 +164,6 @@ trait UpdateHandler
if (!isset($message['to_id'])) {
return true;
}
-
try {
$peer_id = $this->getId($message['to_id']);
} catch (\danog\MadelineProto\Exception $e) {
@@ -188,13 +174,10 @@ trait UpdateHandler
$message_id = $message['id'];
if (!isset($this->msg_ids[$peer_id]) || $message_id > $this->msg_ids[$peer_id]) {
$this->msg_ids[$peer_id] = $message_id;
-
return true;
}
-
return false;
}
-
/**
* Get channel state.
*
@@ -202,16 +185,14 @@ trait UpdateHandler
*
* @return UpdatesState|UpdatesState[]
*/
- public function loadUpdateState()
+ public function loadUpdateState(): \Generator
{
if (!$this->got_state) {
$this->got_state = true;
- $this->channels_state->get(false, yield $this->getUpdatesState());
+ $this->channels_state->get(false, yield from $this->getUpdatesState());
}
-
return $this->channels_state->get(false);
}
-
/**
* Load channel state.
*
@@ -226,7 +207,6 @@ trait UpdateHandler
{
return $this->channels_state->get($channelId, $init);
}
-
/**
* Get channel states.
*
@@ -238,7 +218,6 @@ trait UpdateHandler
{
return $this->channels_state;
}
-
/**
* Get update state.
*
@@ -250,11 +229,8 @@ trait UpdateHandler
{
$data = yield $this->methodCallAsyncRead('updates.getState', [], ['datacenter' => $this->settings['connection_settings']['default_dc']]);
yield $this->getCdnConfig($this->settings['connection_settings']['default_dc']);
-
return $data;
}
-
-
/**
* Undocumented function.
*
@@ -273,16 +249,13 @@ trait UpdateHandler
if ($actual_updates) {
$updates = $actual_updates;
}
- $this->logger->logger('Parsing updates ('.$updates['_'].') received via the socket...', \danog\MadelineProto\Logger::VERBOSE);
+ $this->logger->logger('Parsing updates (' . $updates['_'] . ') received via the socket...', \danog\MadelineProto\Logger::VERBOSE);
switch ($updates['_']) {
case 'updates':
case 'updatesCombined':
$result = [];
foreach ($updates['updates'] as $key => $update) {
- if ($update['_'] === 'updateNewMessage' || $update['_'] === 'updateReadMessagesContents' ||
- $update['_'] === 'updateEditMessage' || $update['_'] === 'updateDeleteMessages' ||
- $update['_'] === 'updateReadHistoryInbox' || $update['_'] === 'updateReadHistoryOutbox' ||
- $update['_'] === 'updateWebPage' || $update['_'] === 'updateMessageID') {
+ if ($update['_'] === 'updateNewMessage' || $update['_'] === 'updateReadMessagesContents' || $update['_'] === 'updateEditMessage' || $update['_'] === 'updateDeleteMessages' || $update['_'] === 'updateReadHistoryInbox' || $update['_'] === 'updateReadHistoryOutbox' || $update['_'] === 'updateWebPage' || $update['_'] === 'updateMessageID') {
$result[yield $this->feeders[false]->feedSingle($update)] = true;
unset($updates['updates'][$key]);
}
@@ -308,20 +281,18 @@ trait UpdateHandler
$updates['user_id'] = (yield $this->getInfo($updates['request']['body']['peer']))['bot_api_id'];
$updates['message'] = $updates['request']['body']['message'];
unset($updates['request']);
- // no break
+ // no break
case 'updateShortMessage':
case 'updateShortChatMessage':
$from_id = isset($updates['from_id']) ? $updates['from_id'] : ($updates['out'] ? $this->authorization['user']['id'] : $updates['user_id']);
$to_id = isset($updates['chat_id']) ? -$updates['chat_id'] : ($updates['out'] ? $updates['user_id'] : $this->authorization['user']['id']);
- if (!yield $this->peerIsset($from_id) || !yield $this->peerIsset($to_id) || isset($updates['via_bot_id']) && !yield $this->peerIsset($updates['via_bot_id']) || isset($updates['entities']) && !yield $this->entitiesPeerIsset($updates['entities']) || isset($updates['fwd_from']) && !yield $this->fwdPeerIsset($updates['fwd_from'])) {
+ if (!(yield from $this->peerIsset($from_id) || !(yield from $this->peerIsset($to_id) || isset($updates['via_bot_id']) && !(yield from $this->peerIsset($updates['via_bot_id']) || isset($updates['entities']) && !(yield from $this->entitiesPeerIsset($updates['entities']) || isset($updates['fwd_from']) && !yield $this->fwdPeerIsset($updates['fwd_from'])))))) {
yield $this->updaters[false]->resume();
-
return;
}
$message = $updates;
$message['_'] = 'message';
$message['from_id'] = $from_id;
-
try {
$message['to_id'] = (yield $this->getInfo($to_id))['Peer'];
} catch (\danog\MadelineProto\Exception $e) {
@@ -340,7 +311,7 @@ trait UpdateHandler
$this->updaters[false]->resume();
break;
default:
- throw new \danog\MadelineProto\ResponseException('Unrecognized update received: '.\var_export($updates, true));
+ throw new \danog\MadelineProto\ResponseException('Unrecognized update received: ' . \var_export($updates, true));
break;
}
}
@@ -368,13 +339,11 @@ trait UpdateHandler
$this->logger->logger('Got new dc options', \danog\MadelineProto\Logger::VERBOSE);
$this->config['dc_options'] = $update['dc_options'];
yield $this->parseConfig();
-
return;
}
if ($update['_'] === 'updatePhoneCall') {
if (!\class_exists('\\danog\\MadelineProto\\VoIP')) {
$this->logger->logger('The php-libtgvoip extension is required to accept and manage calls. See daniil.it/MadelineProto for more info.', \danog\MadelineProto\Logger::WARNING);
-
return;
}
switch ($update['phone_call']['_']) {
@@ -403,54 +372,50 @@ trait UpdateHandler
if (!isset($this->calls[$update['phone_call']['id']])) {
return;
}
-
return $this->calls[$update['phone_call']['id']]->discard($update['phone_call']['reason'], [], $update['phone_call']['need_debug']);
}
}
if ($update['_'] === 'updateNewEncryptedMessage' && !isset($update['message']['decrypted_message'])) {
if (isset($update['qts'])) {
- $cur_state = yield $this->loadUpdateState();
+ $cur_state = (yield from $this->loadUpdateState());
if ($cur_state->qts() === -1) {
$cur_state->qts($update['qts']);
}
if ($update['qts'] < $cur_state->qts()) {
- $this->logger->logger('Duplicate update. update qts: '.$update['qts'].' <= current qts '.$cur_state->qts().', chat id: '.$update['message']['chat_id'], \danog\MadelineProto\Logger::ERROR);
-
+ $this->logger->logger('Duplicate update. update qts: ' . $update['qts'] . ' <= current qts ' . $cur_state->qts() . ', chat id: ' . $update['message']['chat_id'], \danog\MadelineProto\Logger::ERROR);
return false;
}
if ($update['qts'] > $cur_state->qts() + 1) {
- $this->logger->logger('Qts hole. Fetching updates manually: update qts: '.$update['qts'].' > current qts '.$cur_state->qts().'+1, chat id: '.$update['message']['chat_id'], \danog\MadelineProto\Logger::ERROR);
+ $this->logger->logger('Qts hole. Fetching updates manually: update qts: ' . $update['qts'] . ' > current qts ' . $cur_state->qts() . '+1, chat id: ' . $update['message']['chat_id'], \danog\MadelineProto\Logger::ERROR);
$this->updaters[false]->resumeDefer();
-
return false;
}
- $this->logger->logger('Applying qts: '.$update['qts'].' over current qts '.$cur_state->qts().', chat id: '.$update['message']['chat_id'], \danog\MadelineProto\Logger::VERBOSE);
+ $this->logger->logger('Applying qts: ' . $update['qts'] . ' over current qts ' . $cur_state->qts() . ', chat id: ' . $update['message']['chat_id'], \danog\MadelineProto\Logger::VERBOSE);
yield $this->methodCallAsyncRead('messages.receivedQueue', ['max_qts' => $cur_state->qts($update['qts'])], ['datacenter' => $this->settings['connection_settings']['default_dc']]);
}
yield $this->handleEncryptedUpdate($update);
-
return;
}
/*
- if ($update['_'] === 'updateEncryptedChatTyping') {
- $update = ['_' => 'updateUserTyping', 'user_id' => $this->encrypted_chats[$update['chat_id']]['user_id'], 'action' => ['_' => 'sendMessageTypingAction']];
- }
- */
+ if ($update['_'] === 'updateEncryptedChatTyping') {
+ $update = ['_' => 'updateUserTyping', 'user_id' => $this->encrypted_chats[$update['chat_id']]['user_id'], 'action' => ['_' => 'sendMessageTypingAction']];
+ }
+ */
if ($update['_'] === 'updateEncryption') {
switch ($update['chat']['_']) {
case 'encryptedChatRequested':
if ($this->settings['secret_chats']['accept_chats'] === false || \is_array($this->settings['secret_chats']['accept_chats']) && !\in_array($update['chat']['admin_id'], $this->settings['secret_chats']['accept_chats'])) {
return;
}
- $this->logger->logger('Accepting secret chat '.$update['chat']['id'], \danog\MadelineProto\Logger::NOTICE);
+ $this->logger->logger('Accepting secret chat ' . $update['chat']['id'], \danog\MadelineProto\Logger::NOTICE);
try {
yield $this->acceptSecretChat($update['chat']);
} catch (RPCErrorException $e) {
- $this->logger->logger("Error while accepting secret chat: $e", Logger::FATAL_ERROR);
+ $this->logger->logger("Error while accepting secret chat: {$e}", Logger::FATAL_ERROR);
}
break;
case 'encryptedChatDiscarded':
- $this->logger->logger('Deleting secret chat '.$update['chat']['id'].' because it was revoked by the other user', \danog\MadelineProto\Logger::NOTICE);
+ $this->logger->logger('Deleting secret chat ' . $update['chat']['id'] . ' because it was revoked by the other user', \danog\MadelineProto\Logger::NOTICE);
if (isset($this->secret_chats[$update['chat']['id']])) {
unset($this->secret_chats[$update['chat']['id']]);
}
@@ -460,17 +425,15 @@ trait UpdateHandler
if (isset($this->temp_rekeyed_secret_chats[$update['chat']['id']])) {
unset($this->temp_rekeyed_secret_chats[$update['chat']['id']]);
}
-
break;
case 'encryptedChat':
- $this->logger->logger('Completing creation of secret chat '.$update['chat']['id'], \danog\MadelineProto\Logger::NOTICE);
+ $this->logger->logger('Completing creation of secret chat ' . $update['chat']['id'], \danog\MadelineProto\Logger::NOTICE);
yield $this->completeSecretChat($update['chat']);
break;
}
//$this->logger->logger($update, \danog\MadelineProto\Logger::NOTICE);
}
//if ($update['_'] === 'updateServiceNotification' && strpos($update['type'], 'AUTH_KEY_DROP_') === 0) {
-
//}
if (!$this->settings['updates']['handle_updates']) {
return;
@@ -488,7 +451,6 @@ trait UpdateHandler
$this->getUpdatesUpdateHandler($update);
}
}
-
/**
* Send update to webhook.
*
@@ -502,23 +464,20 @@ trait UpdateHandler
//$this->logger->logger($update, $payload, json_last_error());
if ($payload === '') {
$this->logger->logger('EMPTY UPDATE');
-
return;
}
- \danog\MadelineProto\Tools::callFork((function () use ($payload) {
+ \danog\MadelineProto\Tools::callFork((function () use ($payload): \Generator {
$request = new Request($this->hook_url, 'POST');
$request->setHeader('content-type', 'application/json');
$request->setBody($payload);
-
$result = yield (yield $this->datacenter->getHTTPClient()->request($request))->getBody()->buffer();
-
- $this->logger->logger('Result of webhook query is '.$result, \danog\MadelineProto\Logger::NOTICE);
+ $this->logger->logger('Result of webhook query is ' . $result, \danog\MadelineProto\Logger::NOTICE);
$result = \json_decode($result, true);
if (\is_array($result) && isset($result['method']) && $result['method'] != '' && \is_string($result['method'])) {
try {
$this->logger->logger('Reverse webhook command returned', yield $this->methodCallAsyncRead($result['method'], $result, ['datacenter' => $this->datacenter->curdc]));
} catch (\Throwable $e) {
- $this->logger->logger("Reverse webhook command returned: $e");
+ $this->logger->logger("Reverse webhook command returned: {$e}");
}
}
})());
diff --git a/src/danog/MadelineProto/MTProtoTools/UpdatesState.php b/src/danog/MadelineProto/MTProtoTools/UpdatesState.php
index a992a734..2fc58d2a 100644
--- a/src/danog/MadelineProto/MTProtoTools/UpdatesState.php
+++ b/src/danog/MadelineProto/MTProtoTools/UpdatesState.php
@@ -48,21 +48,18 @@ class UpdatesState
* @var int
*/
private $date = 1;
-
/**
* Channel ID.
*
* @var int|bool
*/
private $channelId;
-
/**
* Is busy?
*
* @var bool
*/
private $syncLoading = false;
-
/**
* Init function.
*
@@ -74,7 +71,6 @@ class UpdatesState
$this->channelId = $channelId;
$this->update($init);
}
-
/**
* Sleep function.
*
@@ -84,7 +80,6 @@ class UpdatesState
{
return $this->channelId ? ['pts', 'channelId'] : ['pts', 'qts', 'seq', 'date', 'channelId'];
}
-
/**
* Is this state relative to a channel?
*
@@ -94,7 +89,6 @@ class UpdatesState
{
return (bool) $this->channelId;
}
-
/**
* Get the channel ID.
*
@@ -104,7 +98,6 @@ class UpdatesState
{
return $this->channelId;
}
-
/**
* Are we currently busy?
*
@@ -117,10 +110,8 @@ class UpdatesState
if ($set !== null) {
$this->syncLoading = $set;
}
-
return $this->syncLoading;
}
-
/**
* Update multiple parameters.
*
@@ -135,10 +126,8 @@ class UpdatesState
$this->{$param}($init[$param]);
}
}
-
return $this;
}
-
/**
* Get/set PTS.
*
@@ -151,10 +140,8 @@ class UpdatesState
if ($set !== 0 && $set > $this->pts) {
$this->pts = $set;
}
-
return $this->pts;
}
-
/**
* Get/set QTS.
*
@@ -167,10 +154,8 @@ class UpdatesState
if ($set !== 0 && $set > $this->qts) {
$this->qts = $set;
}
-
return $this->qts;
}
-
/**
* Get/set seq.
*
@@ -183,10 +168,8 @@ class UpdatesState
if ($set !== 0 && $set > $this->seq) {
$this->seq = $set;
}
-
return $this->seq;
}
-
/**
* Get/set date.
*
@@ -199,10 +182,8 @@ class UpdatesState
if ($set !== 0 && $set > $this->date) {
$this->date = $set;
}
-
return $this->date;
}
-
/**
* Check validity of PTS contained in update.
*
@@ -214,7 +195,6 @@ class UpdatesState
{
return $update['pts'] - ($this->pts + $update['pts_count']);
}
-
/**
* Check validity of seq contained in update.
*
diff --git a/src/danog/MadelineProto/Magic.php b/src/danog/MadelineProto/Magic.php
index c558edbf..9ff784c0 100644
--- a/src/danog/MadelineProto/Magic.php
+++ b/src/danog/MadelineProto/Magic.php
@@ -25,7 +25,6 @@ use Amp\DoH\Rfc8484StubResolver;
use Amp\Loop;
use Amp\Loop\Driver;
use ReflectionClass;
-
use function Amp\ByteStream\getInputBufferStream;
use function Amp\ByteStream\getStdin;
use function Amp\Dns\resolver;
@@ -105,7 +104,6 @@ class Magic
* @var int
*/
public static $pid;
-
/**
* Whether we've inited all static constants.
*
@@ -208,21 +206,18 @@ class Magic
* @var boolean
*/
public static $zerowebhost = false;
-
/**
* Whether a signal was sent to the processand the system must shut down.
*
* @var boolean
*/
public static $signaled = false;
-
/**
* Encoded emojis.
*
* @var string
*/
const JSON_EMOJIS = '["\\ud83d\\ude09","\\ud83d\\ude0d","\\ud83d\\ude1b","\\ud83d\\ude2d","\\ud83d\\ude31","\\ud83d\\ude21","\\ud83d\\ude0e","\\ud83d\\ude34","\\ud83d\\ude35","\\ud83d\\ude08","\\ud83d\\ude2c","\\ud83d\\ude07","\\ud83d\\ude0f","\\ud83d\\udc6e","\\ud83d\\udc77","\\ud83d\\udc82","\\ud83d\\udc76","\\ud83d\\udc68","\\ud83d\\udc69","\\ud83d\\udc74","\\ud83d\\udc75","\\ud83d\\ude3b","\\ud83d\\ude3d","\\ud83d\\ude40","\\ud83d\\udc7a","\\ud83d\\ude48","\\ud83d\\ude49","\\ud83d\\ude4a","\\ud83d\\udc80","\\ud83d\\udc7d","\\ud83d\\udca9","\\ud83d\\udd25","\\ud83d\\udca5","\\ud83d\\udca4","\\ud83d\\udc42","\\ud83d\\udc40","\\ud83d\\udc43","\\ud83d\\udc45","\\ud83d\\udc44","\\ud83d\\udc4d","\\ud83d\\udc4e","\\ud83d\\udc4c","\\ud83d\\udc4a","\\u270c","\\u270b","\\ud83d\\udc50","\\ud83d\\udc46","\\ud83d\\udc47","\\ud83d\\udc49","\\ud83d\\udc48","\\ud83d\\ude4f","\\ud83d\\udc4f","\\ud83d\\udcaa","\\ud83d\\udeb6","\\ud83c\\udfc3","\\ud83d\\udc83","\\ud83d\\udc6b","\\ud83d\\udc6a","\\ud83d\\udc6c","\\ud83d\\udc6d","\\ud83d\\udc85","\\ud83c\\udfa9","\\ud83d\\udc51","\\ud83d\\udc52","\\ud83d\\udc5f","\\ud83d\\udc5e","\\ud83d\\udc60","\\ud83d\\udc55","\\ud83d\\udc57","\\ud83d\\udc56","\\ud83d\\udc59","\\ud83d\\udc5c","\\ud83d\\udc53","\\ud83c\\udf80","\\ud83d\\udc84","\\ud83d\\udc9b","\\ud83d\\udc99","\\ud83d\\udc9c","\\ud83d\\udc9a","\\ud83d\\udc8d","\\ud83d\\udc8e","\\ud83d\\udc36","\\ud83d\\udc3a","\\ud83d\\udc31","\\ud83d\\udc2d","\\ud83d\\udc39","\\ud83d\\udc30","\\ud83d\\udc38","\\ud83d\\udc2f","\\ud83d\\udc28","\\ud83d\\udc3b","\\ud83d\\udc37","\\ud83d\\udc2e","\\ud83d\\udc17","\\ud83d\\udc34","\\ud83d\\udc11","\\ud83d\\udc18","\\ud83d\\udc3c","\\ud83d\\udc27","\\ud83d\\udc25","\\ud83d\\udc14","\\ud83d\\udc0d","\\ud83d\\udc22","\\ud83d\\udc1b","\\ud83d\\udc1d","\\ud83d\\udc1c","\\ud83d\\udc1e","\\ud83d\\udc0c","\\ud83d\\udc19","\\ud83d\\udc1a","\\ud83d\\udc1f","\\ud83d\\udc2c","\\ud83d\\udc0b","\\ud83d\\udc10","\\ud83d\\udc0a","\\ud83d\\udc2b","\\ud83c\\udf40","\\ud83c\\udf39","\\ud83c\\udf3b","\\ud83c\\udf41","\\ud83c\\udf3e","\\ud83c\\udf44","\\ud83c\\udf35","\\ud83c\\udf34","\\ud83c\\udf33","\\ud83c\\udf1e","\\ud83c\\udf1a","\\ud83c\\udf19","\\ud83c\\udf0e","\\ud83c\\udf0b","\\u26a1","\\u2614","\\u2744","\\u26c4","\\ud83c\\udf00","\\ud83c\\udf08","\\ud83c\\udf0a","\\ud83c\\udf93","\\ud83c\\udf86","\\ud83c\\udf83","\\ud83d\\udc7b","\\ud83c\\udf85","\\ud83c\\udf84","\\ud83c\\udf81","\\ud83c\\udf88","\\ud83d\\udd2e","\\ud83c\\udfa5","\\ud83d\\udcf7","\\ud83d\\udcbf","\\ud83d\\udcbb","\\u260e","\\ud83d\\udce1","\\ud83d\\udcfa","\\ud83d\\udcfb","\\ud83d\\udd09","\\ud83d\\udd14","\\u23f3","\\u23f0","\\u231a","\\ud83d\\udd12","\\ud83d\\udd11","\\ud83d\\udd0e","\\ud83d\\udca1","\\ud83d\\udd26","\\ud83d\\udd0c","\\ud83d\\udd0b","\\ud83d\\udebf","\\ud83d\\udebd","\\ud83d\\udd27","\\ud83d\\udd28","\\ud83d\\udeaa","\\ud83d\\udeac","\\ud83d\\udca3","\\ud83d\\udd2b","\\ud83d\\udd2a","\\ud83d\\udc8a","\\ud83d\\udc89","\\ud83d\\udcb0","\\ud83d\\udcb5","\\ud83d\\udcb3","\\u2709","\\ud83d\\udceb","\\ud83d\\udce6","\\ud83d\\udcc5","\\ud83d\\udcc1","\\u2702","\\ud83d\\udccc","\\ud83d\\udcce","\\u2712","\\u270f","\\ud83d\\udcd0","\\ud83d\\udcda","\\ud83d\\udd2c","\\ud83d\\udd2d","\\ud83c\\udfa8","\\ud83c\\udfac","\\ud83c\\udfa4","\\ud83c\\udfa7","\\ud83c\\udfb5","\\ud83c\\udfb9","\\ud83c\\udfbb","\\ud83c\\udfba","\\ud83c\\udfb8","\\ud83d\\udc7e","\\ud83c\\udfae","\\ud83c\\udccf","\\ud83c\\udfb2","\\ud83c\\udfaf","\\ud83c\\udfc8","\\ud83c\\udfc0","\\u26bd","\\u26be","\\ud83c\\udfbe","\\ud83c\\udfb1","\\ud83c\\udfc9","\\ud83c\\udfb3","\\ud83c\\udfc1","\\ud83c\\udfc7","\\ud83c\\udfc6","\\ud83c\\udfca","\\ud83c\\udfc4","\\u2615","\\ud83c\\udf7c","\\ud83c\\udf7a","\\ud83c\\udf77","\\ud83c\\udf74","\\ud83c\\udf55","\\ud83c\\udf54","\\ud83c\\udf5f","\\ud83c\\udf57","\\ud83c\\udf71","\\ud83c\\udf5a","\\ud83c\\udf5c","\\ud83c\\udf61","\\ud83c\\udf73","\\ud83c\\udf5e","\\ud83c\\udf69","\\ud83c\\udf66","\\ud83c\\udf82","\\ud83c\\udf70","\\ud83c\\udf6a","\\ud83c\\udf6b","\\ud83c\\udf6d","\\ud83c\\udf6f","\\ud83c\\udf4e","\\ud83c\\udf4f","\\ud83c\\udf4a","\\ud83c\\udf4b","\\ud83c\\udf52","\\ud83c\\udf47","\\ud83c\\udf49","\\ud83c\\udf53","\\ud83c\\udf51","\\ud83c\\udf4c","\\ud83c\\udf50","\\ud83c\\udf4d","\\ud83c\\udf46","\\ud83c\\udf45","\\ud83c\\udf3d","\\ud83c\\udfe1","\\ud83c\\udfe5","\\ud83c\\udfe6","\\u26ea","\\ud83c\\udff0","\\u26fa","\\ud83c\\udfed","\\ud83d\\uddfb","\\ud83d\\uddfd","\\ud83c\\udfa0","\\ud83c\\udfa1","\\u26f2","\\ud83c\\udfa2","\\ud83d\\udea2","\\ud83d\\udea4","\\u2693","\\ud83d\\ude80","\\u2708","\\ud83d\\ude81","\\ud83d\\ude82","\\ud83d\\ude8b","\\ud83d\\ude8e","\\ud83d\\ude8c","\\ud83d\\ude99","\\ud83d\\ude97","\\ud83d\\ude95","\\ud83d\\ude9b","\\ud83d\\udea8","\\ud83d\\ude94","\\ud83d\\ude92","\\ud83d\\ude91","\\ud83d\\udeb2","\\ud83d\\udea0","\\ud83d\\ude9c","\\ud83d\\udea6","\\u26a0","\\ud83d\\udea7","\\u26fd","\\ud83c\\udfb0","\\ud83d\\uddff","\\ud83c\\udfaa","\\ud83c\\udfad","\\ud83c\\uddef\\ud83c\\uddf5","\\ud83c\\uddf0\\ud83c\\uddf7","\\ud83c\\udde9\\ud83c\\uddea","\\ud83c\\udde8\\ud83c\\uddf3","\\ud83c\\uddfa\\ud83c\\uddf8","\\ud83c\\uddeb\\ud83c\\uddf7","\\ud83c\\uddea\\ud83c\\uddf8","\\ud83c\\uddee\\ud83c\\uddf9","\\ud83c\\uddf7\\ud83c\\uddfa","\\ud83c\\uddec\\ud83c\\udde7","1\\u20e3","2\\u20e3","3\\u20e3","4\\u20e3","5\\u20e3","6\\u20e3","7\\u20e3","8\\u20e3","9\\u20e3","0\\u20e3","\\ud83d\\udd1f","\\u2757","\\u2753","\\u2665","\\u2666","\\ud83d\\udcaf","\\ud83d\\udd17","\\ud83d\\udd31","\\ud83d\\udd34","\\ud83d\\udd35","\\ud83d\\udd36","\\ud83d\\udd37"]';
-
/**
* Initialize magic constants.
*
@@ -265,7 +260,6 @@ class Magic
self::$twoe2048 = new \tgseclib\Math\BigInteger('32317006071311007300714876688669951960444102669715484032130345427524655138867890893197201411522913463688717960921898019494119559150490921095088152386448283120630877367300996091750197750389652106796057638384067568276792218642619756161838094338476170470581645852036305042887575891541065808607552399123930385521914333389668342420684974786564569494856176035326322058077805659331026192708460314150258592864177116725943603718461857357598351152301645904403697613233287231227125684710820209725157101726931323469678542580656697935045997268352998638215525166389437335543602135433229604645318478604952148193555853611059596230656');
self::$twozerotwosixone = new \tgseclib\Math\BigInteger(20261);
self::$zeroeight = new \tgseclib\Math\BigInteger('2147483648');
-
try {
self::$isatty = \defined('STDOUT') && \function_exists('posix_isatty') && \posix_isatty(STDOUT);
} catch (\danog\MadelineProto\Exception $e) {
@@ -273,14 +267,14 @@ class Magic
self::$altervista = isset($_SERVER['SERVER_ADMIN']) && \strpos($_SERVER['SERVER_ADMIN'], 'altervista.org');
self::$zerowebhost = isset($_SERVER['SERVER_ADMIN']) && \strpos($_SERVER['SERVER_ADMIN'], '000webhost.io');
self::$can_getmypid = !self::$altervista && !self::$zerowebhost;
- self::$revision = @\file_get_contents(__DIR__.'/../../../.git/refs/heads/master');
+ self::$revision = @\file_get_contents(__DIR__ . '/../../../.git/refs/heads/master');
if (self::$revision) {
self::$revision = \trim(self::$revision);
$latest = @\file_get_contents('https://phar.madelineproto.xyz/release');
if ($latest) {
$latest = self::$revision === \trim($latest) ? '' : ' (AN UPDATE IS REQUIRED)';
}
- self::$revision = 'Revision: '.self::$revision.$latest;
+ self::$revision = 'Revision: ' . self::$revision . $latest;
}
self::$can_parallel = false;
if (PHP_SAPI === 'cli' && !(\class_exists(\Phar::class) && \Phar::running())) {
@@ -308,7 +302,6 @@ class Magic
}
$backtrace = \debug_backtrace(0);
self::$script_cwd = self::$cwd = \dirname(\end($backtrace)['file']);
-
try {
self::$cwd = \getcwd();
self::$can_getcwd = true;
@@ -327,25 +320,24 @@ class Magic
}));
}
/*if (!self::$altervista && !self::$zerowebhost) {
- $DohConfig = new DoHConfig(
- [
- new Nameserver('https://mozilla.cloudflare-dns.com/dns-query'),
- new Nameserver('https://dns.google/resolve'),
- ]
- );
- resolver(new Rfc8484StubResolver($DohConfig));
- }*/
+ $DohConfig = new DoHConfig(
+ [
+ new Nameserver('https://mozilla.cloudflare-dns.com/dns-query'),
+ new Nameserver('https://dns.google/resolve'),
+ ]
+ );
+ resolver(new Rfc8484StubResolver($DohConfig));
+ }*/
if (PHP_SAPI !== 'cli') {
try {
\error_reporting(E_ALL);
\ini_set('log_errors', 1);
- \ini_set('error_log', Magic::$script_cwd.'/MadelineProto.log');
+ \ini_set('error_log', Magic::$script_cwd . '/MadelineProto.log');
\error_log('Enabled PHP logging');
} catch (\danog\MadelineProto\Exception $e) {
//$this->logger->logger('Could not enable PHP logging');
}
}
-
$res = \json_decode(@\file_get_contents('https://rpc.madelineproto.xyz/v3.json'), true);
if (isset($res['ok']) && $res['ok']) {
RPCErrorException::$errorMethodMap = $res['result'];
@@ -354,7 +346,6 @@ class Magic
self::$inited = true;
}
}
-
/**
* Check if this is a POSIX fork of the main PHP process.
*
@@ -368,18 +359,15 @@ class Magic
if (!self::$can_getmypid) {
return false;
}
-
try {
if (self::$pid === null) {
self::$pid = \getmypid();
}
-
return self::$isFork = self::$pid !== \getmypid();
} catch (\danog\MadelineProto\Exception $e) {
return self::$can_getmypid = false;
}
}
-
/**
* Get current working directory.
*
@@ -389,7 +377,6 @@ class Magic
{
return self::$can_getcwd ? \getcwd() : self::$cwd;
}
-
/**
* Shutdown system.
*
@@ -406,7 +393,6 @@ class Magic
getInputBufferStream()->unreference();
if ($code !== 0) {
$driver = Loop::get();
-
$reflectionClass = new ReflectionClass(Driver::class);
$reflectionProperty = $reflectionClass->getProperty('watchers');
$reflectionProperty->setAccessible(true);
diff --git a/src/danog/MadelineProto/MyTelegramOrgWrapper.php b/src/danog/MadelineProto/MyTelegramOrgWrapper.php
index 3a5d5ddb..35444aa3 100644
--- a/src/danog/MadelineProto/MyTelegramOrgWrapper.php
+++ b/src/danog/MadelineProto/MyTelegramOrgWrapper.php
@@ -1,4 +1,5 @@
settings = MTProto::getSettings($settings, $this->settings);
$this->__wakeup();
}
-
public function __wakeup()
{
if ($this->settings === null) {
$this->settings = [];
}
- if (!$this->jar || !($this->jar instanceof InMemoryCookieJar)) {
- $this->jar = new InMemoryCookieJar;
+ if (!$this->jar || !$this->jar instanceof InMemoryCookieJar) {
+ $this->jar = new InMemoryCookieJar();
}
$this->settings = MTProto::getSettings($this->settings);
- $this->datacenter = new DataCenter(
- new class($this->settings) {
- public function __construct($settings)
- {
- $this->logger = Logger::getLoggerFromSettings($settings);
- }
- public function getLogger()
- {
- return $this->logger;
- }
- },
- [],
- $this->settings['connection_settings'],
- true,
- $this->jar
- );
+ $this->datacenter = new DataCenter(new class($this->settings) {
+ public function __construct($settings)
+ {
+ $this->logger = Logger::getLoggerFromSettings($settings);
+ }
+ public function getLogger()
+ {
+ return $this->logger;
+ }
+ }, [], $this->settings['connection_settings'], true, $this->jar);
}
-
- public function login($number)
+ public function login($number): \Generator
{
$this->number = $number;
- $request = new Request(self::MY_TELEGRAM_URL.'/auth/send_password', 'POST');
+ $request = new Request(self::MY_TELEGRAM_URL . '/auth/send_password', 'POST');
$request->setBody(\http_build_query(['phone' => $number]));
$request->setHeaders($this->getHeaders('origin'));
$response = yield $this->datacenter->getHTTPClient()->request($request);
$result = yield $response->getBody()->buffer();
$resulta = \json_decode($result, true);
-
if (!isset($resulta['random_hash'])) {
throw new Exception($result);
}
$this->hash = $resulta['random_hash'];
}
-
- public function completeLogin($password)
+ public function completeLogin($password): \Generator
{
if ($this->logged) {
throw new Exception('Already logged in!');
}
-
- $request = new Request(self::MY_TELEGRAM_URL.'/auth/login', 'POST');
+ $request = new Request(self::MY_TELEGRAM_URL . '/auth/login', 'POST');
$request->setBody(\http_build_query(['phone' => $this->number, 'random_hash' => $this->hash, 'password' => $password]));
$request->setHeaders($this->getHeaders('origin'));
$request->setHeader('user-agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
$response = yield $this->datacenter->getHTTPClient()->request($request);
$result = yield $response->getBody()->buffer();
-
-
switch ($result) {
case 'true':
//Logger::log(['Login OK'], Logger::VERBOSE);
@@ -112,52 +97,41 @@ class MyTelegramOrgWrapper
default:
throw new Exception($result);
}
-
return $this->logged = true;
}
-
public function loggedIn()
{
return $this->logged;
}
-
- public function hasApp()
+ public function hasApp(): \Generator
{
if (!$this->logged) {
throw new Exception('Not logged in!');
}
-
- $request = new Request(self::MY_TELEGRAM_URL.'/apps');
+ $request = new Request(self::MY_TELEGRAM_URL . '/apps');
$request->setHeaders($this->getHeaders('refer'));
$response = yield $this->datacenter->getHTTPClient()->request($request);
$result = yield $response->getBody()->buffer();
-
$title = \explode('', \explode('', $result)[1])[0];
switch ($title) {
case 'App configuration':
return true;
case 'Create new application':
$this->creation_hash = \explode('"/>', \explode('App api_id:
', $result);
@@ -168,41 +142,33 @@ class MyTelegramOrgWrapper
', $result);
$asd = \explode('', $cose[1]);
$api_hash = $asd[0];
-
return ['api_id' => (int) $api_id, 'api_hash' => $api_hash];
}
-
- public function createApp($settings)
+ public function createApp($settings): \Generator
{
if (!$this->logged) {
throw new Exception('Not logged in!');
}
- if (yield $this->hasApp()) {
+ if (yield from $this->hasApp()) {
throw new Exception('The app was already created!');
}
-
- $request = new Request(self::MY_TELEGRAM_URL.'/apps/create', 'POST');
+ $request = new Request(self::MY_TELEGRAM_URL . '/apps/create', 'POST');
$request->setHeaders($this->getHeaders('app'));
$request->setBody(\http_build_query(['hash' => $this->creation_hash, 'app_title' => $settings['app_title'], 'app_shortname' => $settings['app_shortname'], 'app_url' => $settings['app_url'], 'app_platform' => $settings['app_platform'], 'app_desc' => $settings['app_desc']]));
$response = yield $this->datacenter->getHTTPClient()->request($request);
$result = yield $response->getBody()->buffer();
-
if ($result) {
throw new Exception(\html_entity_decode($result));
}
-
- $request = new Request(self::MY_TELEGRAM_URL.'/apps');
+ $request = new Request(self::MY_TELEGRAM_URL . '/apps');
$request->setHeaders($this->getHeaders('refer'));
$response = yield $this->datacenter->getHTTPClient()->request($request);
$result = yield $response->getBody()->buffer();
-
$title = \explode('', \explode('', $result)[1])[0];
if ($title === 'Create new application') {
$this->creation_hash = \explode('"/>', \explode('App api_id:
', $result);
@@ -213,10 +179,8 @@ class MyTelegramOrgWrapper
', $result);
$asd = \explode('', $cose['1']);
$api_hash = $asd['0'];
-
return ['api_id' => (int) $api_id, 'api_hash' => $api_hash];
}
-
/**
* Function for generating curl request headers.
*/
@@ -228,43 +192,39 @@ class MyTelegramOrgWrapper
$headers[] = 'Connection: keep-alive';
$headers[] = 'Accept-Language: it-IT,it;q=0.8,en-US;q=0.6,en;q=0.4';
$headers[] = 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36';
-
// Add additional headers based on the type of request.
switch ($httpType) {
case 'origin':
- $headers[] = 'Origin: '.self::MY_TELEGRAM_URL;
+ $headers[] = 'Origin: ' . self::MY_TELEGRAM_URL;
//$headers[] = 'Accept-Encoding: gzip, deflate, br';
$headers[] = 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8';
$headers[] = 'Accept: application/json, text/javascript, */*; q=0.01';
- $headers[] = 'Referer: '.self::MY_TELEGRAM_URL.'/auth';
+ $headers[] = 'Referer: ' . self::MY_TELEGRAM_URL . '/auth';
$headers[] = 'X-Requested-With: XMLHttpRequest';
break;
case 'refer':
//$headers[] = 'Accept-Encoding: gzip, deflate, sdch, br';
$headers[] = 'Upgrade-Insecure-Requests: 1';
$headers[] = 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8';
- $headers[] = 'Referer: '.self::MY_TELEGRAM_URL;
+ $headers[] = 'Referer: ' . self::MY_TELEGRAM_URL;
$headers[] = 'Cache-Control: max-age=0';
break;
case 'app':
- $headers[] = 'Origin: '.self::MY_TELEGRAM_URL;
+ $headers[] = 'Origin: ' . self::MY_TELEGRAM_URL;
//$headers[] = 'Accept-Encoding: gzip, deflate, br';
$headers[] = 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8';
$headers[] = 'Accept: */*';
- $headers[] = 'Referer: '.self::MY_TELEGRAM_URL.'/apps';
+ $headers[] = 'Referer: ' . self::MY_TELEGRAM_URL . '/apps';
$headers[] = 'X-Requested-With: XMLHttpRequest';
break;
}
-
$final_headers = [];
foreach ($headers as $header) {
list($key, $value) = \explode(':', $header, 2);
$final_headers[\trim($key)] = \trim($value);
}
-
return $final_headers;
}
-
public function async($async)
{
$this->async = $async;
@@ -277,9 +237,8 @@ class MyTelegramOrgWrapper
{
$name .= '_async';
$async = \is_array(\end($arguments)) && isset(\end($arguments)['async']) ? \end($arguments)['async'] : $this->async;
-
if (!\method_exists($this, $name)) {
- throw new Exception("$name does not exist!");
+ throw new Exception("{$name} does not exist!");
}
return $async ? $this->{$name}(...$arguments) : Tools::wait($this->{$name}(...$arguments));
}
diff --git a/src/danog/MadelineProto/PTSException.php b/src/danog/MadelineProto/PTSException.php
index 91ab6f70..986a0256 100644
--- a/src/danog/MadelineProto/PTSException.php
+++ b/src/danog/MadelineProto/PTSException.php
@@ -22,12 +22,10 @@ namespace danog\MadelineProto;
class PTSException extends \Exception
{
use TL\PrettyException;
-
public function __toString()
{
- return \get_class($this).($this->message !== '' ? ': ' : '').$this->message.PHP_EOL.'TL Trace:'.PHP_EOL.PHP_EOL.$this->getTLTrace().PHP_EOL;
+ return \get_class($this) . ($this->message !== '' ? ': ' : '') . $this->message . PHP_EOL . 'TL Trace:' . PHP_EOL . PHP_EOL . $this->getTLTrace() . PHP_EOL;
}
-
public function __construct($message, $file = '')
{
parent::__construct($message);
diff --git a/src/danog/MadelineProto/PredefinedConnector.php b/src/danog/MadelineProto/PredefinedConnector.php
index e69de29b..b3d9bbc7 100644
--- a/src/danog/MadelineProto/PredefinedConnector.php
+++ b/src/danog/MadelineProto/PredefinedConnector.php
@@ -0,0 +1 @@
+ 'Telegram is having internal issues, please try again later.',
- 'RPC_CALL_FAIL' => 'Telegram is having internal issues, please try again later.',
- 'USER_PRIVACY_RESTRICTED' => "The user's privacy settings do not allow you to do this",
- 'CHANNEL_PRIVATE' => "You haven't joined this channel/supergroup",
- 'USER_IS_BOT' => "Bots can't send messages to other bots",
- 'BOT_METHOD_INVALID' => 'This method cannot be run by a bot',
- 'PHONE_CODE_EXPIRED' => 'The phone code you provided has expired, this may happen if it was sent to any chat on telegram (if the code is sent through a telegram chat (not the official account) to avoid it append or prepend to the code some chars)',
- 'USERNAME_INVALID' => 'The provided username is not valid',
- 'ACCESS_TOKEN_INVALID' => 'The provided token is not valid',
- 'ACTIVE_USER_REQUIRED' => 'The method is only available to already activated users',
- 'FIRSTNAME_INVALID' => 'The first name is invalid',
- 'LASTNAME_INVALID' => 'The last name is invalid',
- 'PHONE_NUMBER_INVALID' => 'The phone number is invalid',
- 'PHONE_CODE_HASH_EMPTY' => 'phone_code_hash is missing',
- 'PHONE_CODE_EMPTY' => 'phone_code is missing',
- 'PHONE_CODE_EXPIRED' => 'The confirmation code has expired',
- 'API_ID_INVALID' => 'The api_id/api_hash combination is invalid',
- 'PHONE_NUMBER_OCCUPIED' => 'The phone number is already in use',
- 'PHONE_NUMBER_UNOCCUPIED' => 'The phone number is not yet being used',
- 'USERS_TOO_FEW' => 'Not enough users (to create a chat, for example)',
- 'USERS_TOO_MUCH' => 'The maximum number of users has been exceeded (to create a chat, for example)',
- 'TYPE_CONSTRUCTOR_INVALID' => 'The type constructor is invalid',
- 'FILE_PART_INVALID' => 'The file part number is invalid',
- 'FILE_PARTS_INVALID' => 'The number of file parts is invalid',
- 'MD5_CHECKSUM_INVALID' => 'The MD5 checksums do not match',
- 'PHOTO_INVALID_DIMENSIONS' => 'The photo dimensions are invalid',
- 'FIELD_NAME_INVALID' => 'The field with the name FIELD_NAME is invalid',
- 'FIELD_NAME_EMPTY' => 'The field with the name FIELD_NAME is missing',
- 'MSG_WAIT_FAILED' => 'A waiting call returned an error',
- 'USERNAME_NOT_OCCUPIED' => 'The provided username is not occupied',
- 'PHONE_NUMBER_BANNED' => 'The provided phone number is banned from telegram',
- 'AUTH_KEY_UNREGISTERED' => 'The authorization key has expired',
- 'INVITE_HASH_EXPIRED' => 'The invite link has expired',
- 'USER_DEACTIVATED' => 'The user was deactivated',
- 'USER_ALREADY_PARTICIPANT' => 'The user is already in the group',
- 'MESSAGE_ID_INVALID' => 'The provided message id is invalid',
- 'PEER_ID_INVALID' => 'The provided peer id is invalid',
- 'CHAT_ID_INVALID' => 'The provided chat id is invalid',
- 'MESSAGE_DELETE_FORBIDDEN' => "You can't delete one of the messages you tried to delete, most likely because it is a service message.",
- 'CHAT_ADMIN_REQUIRED' => 'You must be an admin in this chat to do this',
- -429 => 'Too many requests',
- 'PEER_FLOOD' => "You are spamreported, you can't do this",
- ];
+ public static $descriptions = ['RPC_MCGET_FAIL' => 'Telegram is having internal issues, please try again later.', 'RPC_CALL_FAIL' => 'Telegram is having internal issues, please try again later.', 'USER_PRIVACY_RESTRICTED' => "The user's privacy settings do not allow you to do this", 'CHANNEL_PRIVATE' => "You haven't joined this channel/supergroup", 'USER_IS_BOT' => "Bots can't send messages to other bots", 'BOT_METHOD_INVALID' => 'This method cannot be run by a bot', 'PHONE_CODE_EXPIRED' => 'The phone code you provided has expired, this may happen if it was sent to any chat on telegram (if the code is sent through a telegram chat (not the official account) to avoid it append or prepend to the code some chars)', 'USERNAME_INVALID' => 'The provided username is not valid', 'ACCESS_TOKEN_INVALID' => 'The provided token is not valid', 'ACTIVE_USER_REQUIRED' => 'The method is only available to already activated users', 'FIRSTNAME_INVALID' => 'The first name is invalid', 'LASTNAME_INVALID' => 'The last name is invalid', 'PHONE_NUMBER_INVALID' => 'The phone number is invalid', 'PHONE_CODE_HASH_EMPTY' => 'phone_code_hash is missing', 'PHONE_CODE_EMPTY' => 'phone_code is missing', 'PHONE_CODE_EXPIRED' => 'The confirmation code has expired', 'API_ID_INVALID' => 'The api_id/api_hash combination is invalid', 'PHONE_NUMBER_OCCUPIED' => 'The phone number is already in use', 'PHONE_NUMBER_UNOCCUPIED' => 'The phone number is not yet being used', 'USERS_TOO_FEW' => 'Not enough users (to create a chat, for example)', 'USERS_TOO_MUCH' => 'The maximum number of users has been exceeded (to create a chat, for example)', 'TYPE_CONSTRUCTOR_INVALID' => 'The type constructor is invalid', 'FILE_PART_INVALID' => 'The file part number is invalid', 'FILE_PARTS_INVALID' => 'The number of file parts is invalid', 'MD5_CHECKSUM_INVALID' => 'The MD5 checksums do not match', 'PHOTO_INVALID_DIMENSIONS' => 'The photo dimensions are invalid', 'FIELD_NAME_INVALID' => 'The field with the name FIELD_NAME is invalid', 'FIELD_NAME_EMPTY' => 'The field with the name FIELD_NAME is missing', 'MSG_WAIT_FAILED' => 'A waiting call returned an error', 'USERNAME_NOT_OCCUPIED' => 'The provided username is not occupied', 'PHONE_NUMBER_BANNED' => 'The provided phone number is banned from telegram', 'AUTH_KEY_UNREGISTERED' => 'The authorization key has expired', 'INVITE_HASH_EXPIRED' => 'The invite link has expired', 'USER_DEACTIVATED' => 'The user was deactivated', 'USER_ALREADY_PARTICIPANT' => 'The user is already in the group', 'MESSAGE_ID_INVALID' => 'The provided message id is invalid', 'PEER_ID_INVALID' => 'The provided peer id is invalid', 'CHAT_ID_INVALID' => 'The provided chat id is invalid', 'MESSAGE_DELETE_FORBIDDEN' => "You can't delete one of the messages you tried to delete, most likely because it is a service message.", 'CHAT_ADMIN_REQUIRED' => 'You must be an admin in this chat to do this', -429 => 'Too many requests', 'PEER_FLOOD' => "You are spamreported, you can't do this"];
public static $errorMethodMap = [];
-
private $caller = '';
public static function localizeMessage($method, $code, $error)
{
if (!$method || !$code || !$error) {
return $error;
}
-
- $error = \preg_replace('/\d+$/', "X", $error);
-
+ $error = \preg_replace('/\\d+$/', "X", $error);
$description = self::$descriptions[$error] ?? '';
-
-
- if (!isset(self::$errorMethodMap[$code][$method][$error])
- || !isset(self::$descriptions[$error])
- || $code === 500
- ) {
- $res = \json_decode(@\file_get_contents('https://rpc.pwrtelegram.xyz/?method='.$method.'&code='.$code.'&error='.$error, false, \stream_context_create(['http'=>['timeout' => 3]])), true);
+ if (!isset(self::$errorMethodMap[$code][$method][$error]) || !isset(self::$descriptions[$error]) || $code === 500) {
+ $res = \json_decode(@\file_get_contents('https://rpc.pwrtelegram.xyz/?method=' . $method . '&code=' . $code . '&error=' . $error, false, \stream_context_create(['http' => ['timeout' => 3]])), true);
if (isset($res['ok']) && $res['ok'] && isset($res['result'])) {
$description = $res['result'];
-
self::$descriptions[$error] = $description;
self::$errorMethodMap[$code][$method][$error] = $error;
}
}
-
if (!$description) {
return $error;
}
return $description;
}
-
public function __toString()
{
- $result = \sprintf(\danog\MadelineProto\Lang::$current_lang['rpc_tg_error'], self::localizeMessage($this->caller, $this->code, $this->message)." ({$this->code})", $this->rpc, $this->file, $this->line.PHP_EOL, \danog\MadelineProto\Magic::$revision.PHP_EOL.PHP_EOL).PHP_EOL.$this->getTLTrace().PHP_EOL;
+ $result = \sprintf(\danog\MadelineProto\Lang::$current_lang['rpc_tg_error'], self::localizeMessage($this->caller, $this->code, $this->message) . " ({$this->code})", $this->rpc, $this->file, $this->line . PHP_EOL, \danog\MadelineProto\Magic::$revision . PHP_EOL . PHP_EOL) . PHP_EOL . $this->getTLTrace() . PHP_EOL;
if (PHP_SAPI !== 'cli') {
- $result = \str_replace(PHP_EOL, '
'.PHP_EOL, $result);
+ $result = \str_replace(PHP_EOL, '
' . PHP_EOL, $result);
}
-
return $result;
}
-
public function __construct($message = null, $code = 0, $caller = '', Exception $previous = null)
{
$this->rpc = $message;
parent::__construct($message, $code, $previous);
$this->prettifyTL($caller);
$this->caller = $caller;
-
$additional = [];
foreach ($this->getTrace() as $level) {
if (isset($level['function']) && $level['function'] === 'methodCall') {
diff --git a/src/danog/MadelineProto/RSA.php b/src/danog/MadelineProto/RSA.php
index b338baf3..dc655750 100644
--- a/src/danog/MadelineProto/RSA.php
+++ b/src/danog/MadelineProto/RSA.php
@@ -1,4 +1,5 @@
n = Tools::getVar($key, 'modulus');
$this->e = Tools::getVar($key, 'exponent');
\danog\MadelineProto\Logger::log(\danog\MadelineProto\Lang::$current_lang['computing_fingerprint'], Logger::ULTRA_VERBOSE);
- $this->fp = \substr(\sha1((yield $TL->serializeObject(['type' => 'bytes'], $this->n->toBytes(), 'key')).(yield $TL->serializeObject(['type' => 'bytes'], $this->e->toBytes(), 'key')), true), -8);
-
+ $this->fp = \substr(\sha1(yield $TL->serializeObject(['type' => 'bytes'], $this->n->toBytes(), 'key') . yield $TL->serializeObject(['type' => 'bytes'], $this->e->toBytes(), 'key'), true), -8);
return $this;
}
-
/**
* Sleep function.
*
@@ -76,7 +74,6 @@ class RSA
{
return ['e', 'n', 'fp'];
}
-
/**
* Encrypt data.
*
@@ -87,7 +84,6 @@ class RSA
public function encrypt($data): string
{
\danog\MadelineProto\Logger::log(\danog\MadelineProto\Lang::$current_lang['rsa_encrypting'], Logger::VERBOSE);
-
return (new \tgseclib\Math\BigInteger((string) $data, 256))->powMod($this->e, $this->n)->toBytes();
}
}
diff --git a/src/danog/MadelineProto/SecretChats/AuthKeyHandler.php b/src/danog/MadelineProto/SecretChats/AuthKeyHandler.php
index 51d0cc51..d7f0d5ce 100644
--- a/src/danog/MadelineProto/SecretChats/AuthKeyHandler.php
+++ b/src/danog/MadelineProto/SecretChats/AuthKeyHandler.php
@@ -40,7 +40,6 @@ trait AuthKeyHandler
* @var array
*/
protected $secret_chats = [];
-
/**
* Accept secret chat.
*
@@ -53,8 +52,7 @@ trait AuthKeyHandler
//$this->logger->logger($params['id'],$this->secretChatStatus($params['id']));
if ($this->secretChatStatus($params['id']) !== 0) {
//$this->logger->logger($this->secretChatStatus($params['id']));
- $this->logger->logger("I've already accepted secret chat ".$params['id']);
-
+ $this->logger->logger("I've already accepted secret chat " . $params['id']);
return false;
}
$dh_config = yield $this->getDhConfig();
@@ -71,10 +69,9 @@ trait AuthKeyHandler
$g_b = $dh_config['g']->powMod($b, $dh_config['p']);
$this->checkG($g_b, $dh_config['p']);
yield $this->methodCallAsyncRead('messages.acceptEncryption', ['peer' => $params['id'], 'g_b' => $g_b->toBytes(), 'key_fingerprint' => $key['fingerprint']], ['datacenter' => $this->datacenter->curdc]);
- yield $this->notifyLayer($params['id']);
- $this->logger->logger('Secret chat '.$params['id'].' accepted successfully!', \danog\MadelineProto\Logger::NOTICE);
+ yield from $this->notifyLayer($params['id']);
+ $this->logger->logger('Secret chat ' . $params['id'] . ' accepted successfully!', \danog\MadelineProto\Logger::NOTICE);
}
-
/**
* Request secret chat.
*
@@ -89,7 +86,7 @@ trait AuthKeyHandler
throw new \danog\MadelineProto\Exception('This peer is not present in the internal peer database');
}
$user = $user['InputUser'];
- $this->logger->logger('Creating secret chat with '.$user['user_id'].'...', \danog\MadelineProto\Logger::VERBOSE);
+ $this->logger->logger('Creating secret chat with ' . $user['user_id'] . '...', \danog\MadelineProto\Logger::VERBOSE);
$dh_config = yield $this->getDhConfig();
$this->logger->logger('Generating a...', \danog\MadelineProto\Logger::VERBOSE);
$a = new \tgseclib\Math\BigInteger(\danog\MadelineProto\Tools::random(256), 256);
@@ -99,11 +96,9 @@ trait AuthKeyHandler
$res = yield $this->methodCallAsyncRead('messages.requestEncryption', ['user_id' => $user, 'g_a' => $g_a->toBytes()], ['datacenter' => $this->datacenter->curdc]);
$this->temp_requested_secret_chats[$res['id']] = $a;
$this->updaters[false]->resume();
- $this->logger->logger('Secret chat '.$res['id'].' requested successfully!', \danog\MadelineProto\Logger::NOTICE);
-
+ $this->logger->logger('Secret chat ' . $res['id'] . ' requested successfully!', \danog\MadelineProto\Logger::NOTICE);
return $res['id'];
}
-
/**
* Complete secret chat.
*
@@ -115,8 +110,7 @@ trait AuthKeyHandler
{
if ($this->secretChatStatus($params['id']) !== 1) {
//$this->logger->logger($this->secretChatStatus($params['id']));
- $this->logger->logger('Could not find and complete secret chat '.$params['id']);
-
+ $this->logger->logger('Could not find and complete secret chat ' . $params['id']);
return false;
}
$dh_config = yield $this->getDhConfig();
@@ -127,29 +121,25 @@ trait AuthKeyHandler
$key['fingerprint'] = \substr(\sha1($key['auth_key'], true), -8);
//$this->logger->logger($key);
if ($key['fingerprint'] !== $params['key_fingerprint']) {
- yield $this->discardSecretChat($params['id']);
-
+ yield from $this->discardSecretChat($params['id']);
throw new \danog\MadelineProto\SecurityException('Invalid key fingerprint!');
}
$key['visualization_orig'] = \substr(\sha1($key['auth_key'], true), 16);
$key['visualization_46'] = \substr(\hash('sha256', $key['auth_key'], true), 20);
$this->secret_chats[$params['id']] = ['key' => $key, 'admin' => true, 'user_id' => $params['participant_id'], 'InputEncryptedChat' => ['chat_id' => $params['id'], 'access_hash' => $params['access_hash'], '_' => 'inputEncryptedChat'], 'in_seq_no_x' => 0, 'out_seq_no_x' => 1, 'in_seq_no' => 0, 'out_seq_no' => 0, 'layer' => 8, 'ttl' => 0, 'ttr' => 100, 'updated' => \time(), 'incoming' => [], 'outgoing' => [], 'created' => \time(), 'rekeying' => [0], 'key_x' => 'to server', 'mtproto' => 1];
- yield $this->notifyLayer($params['id']);
- $this->logger->logger('Secret chat '.$params['id'].' completed successfully!', \danog\MadelineProto\Logger::NOTICE);
+ yield from $this->notifyLayer($params['id']);
+ $this->logger->logger('Secret chat ' . $params['id'] . ' completed successfully!', \danog\MadelineProto\Logger::NOTICE);
}
-
private function notifyLayer($chat): \Generator
{
yield $this->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionNotifyLayer', 'layer' => $this->TL->getSecretLayer()]]], ['datacenter' => $this->datacenter->curdc]);
}
-
/**
* Temporary rekeyed secret chats.
*
* @var array
*/
protected $temp_rekeyed_secret_chats = [];
-
/**
* Rekey secret chat.
*
@@ -162,7 +152,7 @@ trait AuthKeyHandler
if ($this->secret_chats[$chat]['rekeying'][0] !== 0) {
return;
}
- $this->logger->logger('Rekeying secret chat '.$chat.'...', \danog\MadelineProto\Logger::VERBOSE);
+ $this->logger->logger('Rekeying secret chat ' . $chat . '...', \danog\MadelineProto\Logger::VERBOSE);
$dh_config = yield $this->getDhConfig();
$this->logger->logger('Generating a...', \danog\MadelineProto\Logger::VERBOSE);
$a = new \tgseclib\Math\BigInteger(\danog\MadelineProto\Tools::random(256), 256);
@@ -174,10 +164,8 @@ trait AuthKeyHandler
$this->secret_chats[$chat]['rekeying'] = [1, $e];
yield $this->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionRequestKey', 'g_a' => $g_a->toBytes(), 'exchange_id' => $e]]], ['datacenter' => $this->datacenter->curdc]);
$this->updaters[false]->resume();
-
return $e;
}
-
/**
* Accept rekeying.
*
@@ -197,11 +185,10 @@ trait AuthKeyHandler
}
if ($my_exchange_id->compare($other_exchange_id) === 0) {
$this->secret_chats[$chat]['rekeying'] = [0];
-
return;
}
}
- $this->logger->logger('Accepting rekeying of secret chat '.$chat.'...', \danog\MadelineProto\Logger::VERBOSE);
+ $this->logger->logger('Accepting rekeying of secret chat ' . $chat . '...', \danog\MadelineProto\Logger::VERBOSE);
$dh_config = yield $this->getDhConfig();
$this->logger->logger('Generating b...', \danog\MadelineProto\Logger::VERBOSE);
$b = new \tgseclib\Math\BigInteger(\danog\MadelineProto\Tools::random(256), 256);
@@ -218,7 +205,6 @@ trait AuthKeyHandler
yield $this->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionAcceptKey', 'g_b' => $g_b->toBytes(), 'exchange_id' => $params['exchange_id'], 'key_fingerprint' => $key['fingerprint']]]], ['datacenter' => $this->datacenter->curdc]);
$this->updaters[false]->resume();
}
-
/**
* Commit rekeying of secret chat.
*
@@ -231,10 +217,9 @@ trait AuthKeyHandler
{
if ($this->secret_chats[$chat]['rekeying'][0] !== 1 || !isset($this->temp_rekeyed_secret_chats[$params['exchange_id']])) {
$this->secret_chats[$chat]['rekeying'] = [0];
-
return;
}
- $this->logger->logger('Committing rekeying of secret chat '.$chat.'...', \danog\MadelineProto\Logger::VERBOSE);
+ $this->logger->logger('Committing rekeying of secret chat ' . $chat . '...', \danog\MadelineProto\Logger::VERBOSE);
$dh_config = yield $this->getDhConfig();
$params['g_b'] = new \tgseclib\Math\BigInteger((string) $params['g_b'], 256);
$this->checkG($params['g_b'], $dh_config['p']);
@@ -244,7 +229,6 @@ trait AuthKeyHandler
$key['visualization_46'] = \substr(\hash('sha256', $key['auth_key'], true), 20);
if ($key['fingerprint'] !== $params['key_fingerprint']) {
yield $this->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionAbortKey', 'exchange_id' => $params['exchange_id']]]], ['datacenter' => $this->datacenter->curdc]);
-
throw new \danog\MadelineProto\SecurityException('Invalid key fingerprint!');
}
yield $this->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionCommitKey', 'exchange_id' => $params['exchange_id'], 'key_fingerprint' => $key['fingerprint']]]], ['datacenter' => $this->datacenter->curdc]);
@@ -256,7 +240,6 @@ trait AuthKeyHandler
$this->secret_chats[$chat]['updated'] = \time();
$this->updaters[false]->resume();
}
-
/**
* Complete rekeying.
*
@@ -272,10 +255,9 @@ trait AuthKeyHandler
}
if ($this->temp_rekeyed_secret_chats[$params['exchange_id']]['fingerprint'] !== $params['key_fingerprint']) {
yield $this->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionAbortKey', 'exchange_id' => $params['exchange_id']]]], ['datacenter' => $this->datacenter->curdc]);
-
throw new \danog\MadelineProto\SecurityException('Invalid key fingerprint!');
}
- $this->logger->logger('Completing rekeying of secret chat '.$chat.'...', \danog\MadelineProto\Logger::VERBOSE);
+ $this->logger->logger('Completing rekeying of secret chat ' . $chat . '...', \danog\MadelineProto\Logger::VERBOSE);
$this->secret_chats[$chat]['rekeying'] = [0];
$this->secret_chats[$chat]['old_key'] = $this->secret_chats[$chat]['key'];
$this->secret_chats[$chat]['key'] = $this->temp_rekeyed_secret_chats[$params['exchange_id']];
@@ -283,11 +265,9 @@ trait AuthKeyHandler
$this->secret_chats[$chat]['updated'] = \time();
unset($this->temp_rekeyed_secret_chats[$params['exchange_id']]);
yield $this->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionNoop']]], ['datacenter' => $this->datacenter->curdc]);
- $this->logger->logger('Secret chat '.$chat.' rekeyed successfully!', \danog\MadelineProto\Logger::VERBOSE);
-
+ $this->logger->logger('Secret chat ' . $chat . ' rekeyed successfully!', \danog\MadelineProto\Logger::VERBOSE);
return true;
}
-
/**
* Get secret chat status.
*
@@ -303,10 +283,8 @@ trait AuthKeyHandler
if (isset($this->temp_requested_secret_chats[$chat])) {
return MTProto::SECRET_REQUESTED;
}
-
return MTProto::SECRET_EMPTY;
}
-
/**
* Get secret chat.
*
@@ -318,7 +296,6 @@ trait AuthKeyHandler
{
return $this->secret_chats[\is_array($chat) ? $chat['chat_id'] : $chat];
}
-
/**
* Check whether secret chat exists.
*
@@ -330,7 +307,6 @@ trait AuthKeyHandler
{
return isset($this->secret_chats[\is_array($chat) ? $chat['chat_id'] : $chat]);
}
-
/**
* Discard secret chat.
*
@@ -340,15 +316,13 @@ trait AuthKeyHandler
*/
public function discardSecretChat(int $chat): \Generator
{
- $this->logger->logger('Discarding secret chat '.$chat.'...', \danog\MadelineProto\Logger::VERBOSE);
+ $this->logger->logger('Discarding secret chat ' . $chat . '...', \danog\MadelineProto\Logger::VERBOSE);
if (isset($this->secret_chats[$chat])) {
unset($this->secret_chats[$chat]);
}
if (isset($this->temp_requested_secret_chats[$chat])) {
unset($this->temp_requested_secret_chats[$chat]);
}
-
-
try {
yield $this->methodCallAsyncRead('messages.discardEncryption', ['chat_id' => $chat], ['datacenter' => $this->datacenter->curdc]);
} catch (\danog\MadelineProto\RPCErrorException $e) {
diff --git a/src/danog/MadelineProto/SecretChats/MessageHandler.php b/src/danog/MadelineProto/SecretChats/MessageHandler.php
index a1485f9d..eace87b4 100644
--- a/src/danog/MadelineProto/SecretChats/MessageHandler.php
+++ b/src/danog/MadelineProto/SecretChats/MessageHandler.php
@@ -38,7 +38,6 @@ trait MessageHandler
{
if (!isset($this->secret_chats[$chat_id])) {
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['secret_chat_skipping'], $chat_id));
-
return false;
}
$message['random_id'] = \danog\MadelineProto\Tools::random(8);
@@ -52,30 +51,27 @@ trait MessageHandler
}
$this->secret_chats[$chat_id]['outgoing'][$this->secret_chats[$chat_id]['out_seq_no']] = $message;
$message = yield $this->TL->serializeObject(['type' => $constructor = $this->secret_chats[$chat_id]['layer'] === 8 ? 'DecryptedMessage' : 'DecryptedMessageLayer'], $message, $constructor, $this->secret_chats[$chat_id]['layer']);
- $message = \danog\MadelineProto\Tools::packUnsignedInt(\strlen($message)).$message;
+ $message = \danog\MadelineProto\Tools::packUnsignedInt(\strlen($message)) . $message;
if ($this->secret_chats[$chat_id]['mtproto'] === 2) {
$padding = \danog\MadelineProto\Tools::posmod(-\strlen($message), 16);
if ($padding < 12) {
$padding += 16;
}
$message .= \danog\MadelineProto\Tools::random($padding);
- $message_key = \substr(\hash('sha256', \substr($this->secret_chats[$chat_id]['key']['auth_key'], 88 + ($this->secret_chats[$chat_id]['admin'] ? 0 : 8), 32).$message, true), 8, 16);
+ $message_key = \substr(\hash('sha256', \substr($this->secret_chats[$chat_id]['key']['auth_key'], 88 + ($this->secret_chats[$chat_id]['admin'] ? 0 : 8), 32) . $message, true), 8, 16);
list($aes_key, $aes_iv) = $this->aesCalculate($message_key, $this->secret_chats[$chat_id]['key']['auth_key'], $this->secret_chats[$chat_id]['admin']);
} else {
$message_key = \substr(\sha1($message, true), -16);
list($aes_key, $aes_iv) = $this->oldAesCalculate($message_key, $this->secret_chats[$chat_id]['key']['auth_key'], true);
$message .= \danog\MadelineProto\Tools::random(\danog\MadelineProto\Tools::posmod(-\strlen($message), 16));
}
- $message = $this->secret_chats[$chat_id]['key']['fingerprint'].$message_key.$this->igeEncrypt($message, $aes_key, $aes_iv);
-
+ $message = $this->secret_chats[$chat_id]['key']['fingerprint'] . $message_key . $this->igeEncrypt($message, $aes_key, $aes_iv);
return $message;
}
-
private function handleEncryptedUpdate(array $message): \Generator
{
if (!isset($this->secret_chats[$message['message']['chat_id']])) {
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['secret_chat_skipping'], $message['message']['chat_id']));
-
return false;
}
$auth_key_id = \substr($message['message']['bytes'], 0, 8);
@@ -84,40 +80,36 @@ trait MessageHandler
if (isset($this->secret_chats[$message['message']['chat_id']]['old_key']['fingerprint'])) {
if ($auth_key_id !== $this->secret_chats[$message['message']['chat_id']]['old_key']['fingerprint']) {
yield $this->discardSecretChat($message['message']['chat_id']);
-
throw new \danog\MadelineProto\SecurityException(\danog\MadelineProto\Lang::$current_lang['fingerprint_mismatch']);
}
$old = true;
} else {
yield $this->discardSecretChat($message['message']['chat_id']);
-
throw new \danog\MadelineProto\SecurityException(\danog\MadelineProto\Lang::$current_lang['fingerprint_mismatch']);
}
}
$message_key = \substr($message['message']['bytes'], 8, 16);
$encrypted_data = \substr($message['message']['bytes'], 24);
if ($this->secret_chats[$message['message']['chat_id']]['mtproto'] === 2) {
- $this->logger->logger('Trying MTProto v2 decryption for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE);
-
+ $this->logger->logger('Trying MTProto v2 decryption for chat ' . $message['message']['chat_id'] . '...', \danog\MadelineProto\Logger::NOTICE);
try {
$message_data = $this->tryMTProtoV2Decrypt($message_key, $message['message']['chat_id'], $old, $encrypted_data);
- $this->logger->logger('MTProto v2 decryption OK for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE);
+ $this->logger->logger('MTProto v2 decryption OK for chat ' . $message['message']['chat_id'] . '...', \danog\MadelineProto\Logger::NOTICE);
} catch (\danog\MadelineProto\SecurityException $e) {
- $this->logger->logger('MTProto v2 decryption failed with message '.$e->getMessage().', trying MTProto v1 decryption for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE);
+ $this->logger->logger('MTProto v2 decryption failed with message ' . $e->getMessage() . ', trying MTProto v1 decryption for chat ' . $message['message']['chat_id'] . '...', \danog\MadelineProto\Logger::NOTICE);
$message_data = $this->tryMTProtoV1Decrypt($message_key, $message['message']['chat_id'], $old, $encrypted_data);
- $this->logger->logger('MTProto v1 decryption OK for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE);
+ $this->logger->logger('MTProto v1 decryption OK for chat ' . $message['message']['chat_id'] . '...', \danog\MadelineProto\Logger::NOTICE);
$this->secret_chats[$message['message']['chat_id']]['mtproto'] = 1;
}
} else {
- $this->logger->logger('Trying MTProto v1 decryption for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE);
-
+ $this->logger->logger('Trying MTProto v1 decryption for chat ' . $message['message']['chat_id'] . '...', \danog\MadelineProto\Logger::NOTICE);
try {
$message_data = $this->tryMTProtoV1Decrypt($message_key, $message['message']['chat_id'], $old, $encrypted_data);
- $this->logger->logger('MTProto v1 decryption OK for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE);
+ $this->logger->logger('MTProto v1 decryption OK for chat ' . $message['message']['chat_id'] . '...', \danog\MadelineProto\Logger::NOTICE);
} catch (\danog\MadelineProto\SecurityException $e) {
- $this->logger->logger('MTProto v1 decryption failed with message '.$e->getMessage().', trying MTProto v2 decryption for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE);
+ $this->logger->logger('MTProto v1 decryption failed with message ' . $e->getMessage() . ', trying MTProto v2 decryption for chat ' . $message['message']['chat_id'] . '...', \danog\MadelineProto\Logger::NOTICE);
$message_data = $this->tryMTProtoV2Decrypt($message_key, $message['message']['chat_id'], $old, $encrypted_data);
- $this->logger->logger('MTProto v2 decryption OK for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE);
+ $this->logger->logger('MTProto v2 decryption OK for chat ' . $message['message']['chat_id'] . '...', \danog\MadelineProto\Logger::NOTICE);
$this->secret_chats[$message['message']['chat_id']]['mtproto'] = 2;
}
}
@@ -131,7 +123,6 @@ trait MessageHandler
$this->secret_chats[$message['message']['chat_id']]['incoming'][$this->secret_chats[$message['message']['chat_id']]['in_seq_no']] = $message['message'];
yield $this->handleDecryptedUpdate($message);
}
-
private function tryMTProtoV1Decrypt($message_key, $chat_id, $old, $encrypted_data)
{
list($aes_key, $aes_iv) = $this->oldAesCalculate($message_key, $this->secret_chats[$chat_id][$old ? 'old_key' : 'key']['auth_key'], true);
@@ -150,10 +141,8 @@ trait MessageHandler
if (\strlen($decrypted_data) % 16 != 0) {
throw new \danog\MadelineProto\SecurityException(\danog\MadelineProto\Lang::$current_lang['length_not_divisible_16']);
}
-
return $message_data;
}
-
private function tryMTProtoV2Decrypt($message_key, $chat_id, $old, $encrypted_data)
{
list($aes_key, $aes_iv) = $this->aesCalculate($message_key, $this->secret_chats[$chat_id][$old ? 'old_key' : 'key']['auth_key'], !$this->secret_chats[$chat_id]['admin']);
@@ -163,7 +152,7 @@ trait MessageHandler
if ($message_data_length > \strlen($decrypted_data)) {
throw new \danog\MadelineProto\SecurityException(\danog\MadelineProto\Lang::$current_lang['msg_data_length_too_big']);
}
- if ($message_key != \substr(\hash('sha256', \substr($this->secret_chats[$chat_id][$old ? 'old_key' : 'key']['auth_key'], 88 + ($this->secret_chats[$chat_id]['admin'] ? 8 : 0), 32).$decrypted_data, true), 8, 16)) {
+ if ($message_key != \substr(\hash('sha256', \substr($this->secret_chats[$chat_id][$old ? 'old_key' : 'key']['auth_key'], 88 + ($this->secret_chats[$chat_id]['admin'] ? 8 : 0), 32) . $decrypted_data, true), 8, 16)) {
throw new \danog\MadelineProto\SecurityException(\danog\MadelineProto\Lang::$current_lang['msg_key_mismatch']);
}
if (\strlen($decrypted_data) - 4 - $message_data_length < 12) {
@@ -175,7 +164,6 @@ trait MessageHandler
if (\strlen($decrypted_data) % 16 != 0) {
throw new \danog\MadelineProto\SecurityException(\danog\MadelineProto\Lang::$current_lang['length_not_divisible_16']);
}
-
return $message_data;
}
}
diff --git a/src/danog/MadelineProto/SecretChats/ResponseHandler.php b/src/danog/MadelineProto/SecretChats/ResponseHandler.php
index 8fadebb8..05ecb477 100644
--- a/src/danog/MadelineProto/SecretChats/ResponseHandler.php
+++ b/src/danog/MadelineProto/SecretChats/ResponseHandler.php
@@ -24,7 +24,7 @@ namespace danog\MadelineProto\SecretChats;
*/
trait ResponseHandler
{
- private function handleDecryptedUpdate($update)
+ private function handleDecryptedUpdate($update): \Generator
{
/*if (isset($update['message']['decrypted_message']['random_bytes']) && strlen($update['message']['decrypted_message']['random_bytes']) < 15) {
throw new \danog\MadelineProto\ResponseException(\danog\MadelineProto\Lang::$current_lang['rand_bytes_too_short']);
@@ -35,15 +35,12 @@ trait ResponseHandler
switch ($update['message']['decrypted_message']['action']['_']) {
case 'decryptedMessageActionRequestKey':
yield $this->acceptRekey($update['message']['chat_id'], $update['message']['decrypted_message']['action']);
-
return;
case 'decryptedMessageActionAcceptKey':
yield $this->commitRekey($update['message']['chat_id'], $update['message']['decrypted_message']['action']);
-
return;
case 'decryptedMessageActionCommitKey':
yield $this->completeRekey($update['message']['chat_id'], $update['message']['decrypted_message']['action']);
-
return;
case 'decryptedMessageActionNotifyLayer':
$this->secret_chats[$update['message']['chat_id']]['layer'] = $update['message']['decrypted_message']['action']['layer'];
@@ -53,13 +50,10 @@ trait ResponseHandler
if ($update['message']['decrypted_message']['action']['layer'] >= 73) {
$this->secret_chats[$update['message']['chat_id']]['mtproto'] = 2;
}
-
return;
case 'decryptedMessageActionSetMessageTTL':
$this->secret_chats[$update['message']['chat_id']]['ttl'] = $update['message']['decrypted_message']['action']['ttl_seconds'];
-
yield $this->saveUpdate($update);
-
return;
case 'decryptedMessageActionNoop':
return;
@@ -68,14 +62,13 @@ trait ResponseHandler
$update['message']['decrypted_message']['action']['end_seq_no'] -= $this->secret_chats[$update['message']['chat_id']]['out_seq_no_x'];
$update['message']['decrypted_message']['action']['start_seq_no'] /= 2;
$update['message']['decrypted_message']['action']['end_seq_no'] /= 2;
- $this->logger->logger('Resending messages for secret chat '.$update['message']['chat_id'], \danog\MadelineProto\Logger::WARNING);
+ $this->logger->logger('Resending messages for secret chat ' . $update['message']['chat_id'], \danog\MadelineProto\Logger::WARNING);
foreach ($this->secret_chats[$update['message']['chat_id']]['outgoing'] as $seq => $message) {
if ($seq >= $update['message']['decrypted_message']['action']['start_seq_no'] && $seq <= $update['message']['decrypted_message']['action']['end_seq_no']) {
//throw new \danog\MadelineProto\ResponseException(\danog\MadelineProto\Lang::$current_lang['resending_unsupported']);
yield $this->methodCallAsyncRead('messages.sendEncrypted', ['peer' => $update['message']['chat_id'], 'message' => $update['message']['decrypted_message']], ['datacenter' => $this->datacenter->curdc]);
}
}
-
return;
default:
// yield $this->saveUpdate(['_' => 'updateNewDecryptedMessage', 'peer' => $this->secret_chats[$update['message']['chat_id']]['InputEncryptedChat'], 'in_seq_no' => $this->get_in_seq_no($update['message']['chat_id']), 'out_seq_no' => $this->get_out_seq_no($update['message']['chat_id']), 'message' => $update['message']['decrypted_message']]);
@@ -95,11 +88,11 @@ trait ResponseHandler
}
}
$update['message']['decrypted_message'] = $update['message']['decrypted_message']['message'];
- yield $this->handleDecryptedUpdate($update);
+ yield from $this->handleDecryptedUpdate($update);
}
break;
default:
- throw new \danog\MadelineProto\ResponseException(\danog\MadelineProto\Lang::$current_lang['unrecognized_dec_msg'].\var_export($update, true));
+ throw new \danog\MadelineProto\ResponseException(\danog\MadelineProto\Lang::$current_lang['unrecognized_dec_msg'] . \var_export($update, true));
break;
}
}
diff --git a/src/danog/MadelineProto/SecretChats/SeqNoHandler.php b/src/danog/MadelineProto/SecretChats/SeqNoHandler.php
index 6dda54c4..ec468655 100644
--- a/src/danog/MadelineProto/SecretChats/SeqNoHandler.php
+++ b/src/danog/MadelineProto/SecretChats/SeqNoHandler.php
@@ -24,7 +24,7 @@ namespace danog\MadelineProto\SecretChats;
*/
trait SeqNoHandler
{
- private function checkSecretInSeqNo($chat_id, $seqno)
+ private function checkSecretInSeqNo($chat_id, $seqno): \Generator
{
$seqno = ($seqno - $this->secret_chats[$chat_id]['out_seq_no_x']) / 2;
$last = 0;
@@ -32,7 +32,6 @@ trait SeqNoHandler
if (isset($message['decrypted_message']['in_seq_no'])) {
if (($message['decrypted_message']['in_seq_no'] - $this->secret_chats[$chat_id]['out_seq_no_x']) / 2 < $last) {
yield $this->discardSecretChat($chat_id);
-
throw new \danog\MadelineProto\SecurityException('in_seq_no is not increasing');
}
$last = ($message['decrypted_message']['in_seq_no'] - $this->secret_chats[$chat_id]['out_seq_no_x']) / 2;
@@ -40,14 +39,11 @@ trait SeqNoHandler
}
if ($seqno > $this->secret_chats[$chat_id]['out_seq_no'] + 1) {
yield $this->discardSecretChat($chat_id);
-
throw new \danog\MadelineProto\SecurityException('in_seq_no is too big');
}
-
return true;
}
-
- private function checkSecretOutSeqNo($chat_id, $seqno)
+ private function checkSecretOutSeqNo($chat_id, $seqno): \Generator
{
$seqno = ($seqno - $this->secret_chats[$chat_id]['in_seq_no_x']) / 2;
$C = 0;
@@ -55,8 +51,7 @@ trait SeqNoHandler
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) {
yield $this->discardSecretChat($chat_id);
-
- throw new \danog\MadelineProto\SecurityException('out_seq_no hole: should be '.$C.', is '.($message['decrypted_message']['out_seq_no'] - $this->secret_chats[$chat_id]['in_seq_no_x']) / 2);
+ throw new \danog\MadelineProto\SecurityException('out_seq_no hole: should be ' . $C . ', is ' . ($message['decrypted_message']['out_seq_no'] - $this->secret_chats[$chat_id]['in_seq_no_x']) / 2);
}
$C++;
}
@@ -64,25 +59,20 @@ trait SeqNoHandler
//$this->logger->logger($C, $seqno);
if ($seqno < $C) {
// <= C
- $this->logger->logger('WARNING: dropping repeated message with seqno '.$seqno);
-
+ $this->logger->logger('WARNING: dropping repeated message with seqno ' . $seqno);
return false;
}
if ($seqno > $C) {
// > C+1
yield $this->discardSecretChat($chat_id);
-
- throw new \danog\MadelineProto\SecurityException('WARNING: out_seq_no gap detected ('.$seqno.' > '.$C.')!');
+ throw new \danog\MadelineProto\SecurityException('WARNING: out_seq_no gap detected (' . $seqno . ' > ' . $C . ')!');
}
-
return true;
}
-
private function generateSecretInSeqNo($chat)
{
return $this->secret_chats[$chat]['layer'] > 8 ? $this->secret_chats[$chat]['in_seq_no'] * 2 + $this->secret_chats[$chat]['in_seq_no_x'] : -1;
}
-
private function generateSecretOutSeqNo($chat)
{
return $this->secret_chats[$chat]['layer'] > 8 ? $this->secret_chats[$chat]['out_seq_no'] * 2 + $this->secret_chats[$chat]['out_seq_no_x'] : -1;
diff --git a/src/danog/MadelineProto/Serialization.php b/src/danog/MadelineProto/Serialization.php
index bb36adaa..ee4c9874 100644
--- a/src/danog/MadelineProto/Serialization.php
+++ b/src/danog/MadelineProto/Serialization.php
@@ -27,7 +27,6 @@ class Serialization
public static function realpaths($file)
{
$file = Absolute::absolute($file);
-
- return ['file' => $file, 'lockfile' => $file.'.lock', 'tempfile' => $file.'.temp.session'];
+ return ['file' => $file, 'lockfile' => $file . '.lock', 'tempfile' => $file . '.temp.session'];
}
}
diff --git a/src/danog/MadelineProto/Server.php b/src/danog/MadelineProto/Server.php
index 53ce99ab..f8cf6988 100644
--- a/src/danog/MadelineProto/Server.php
+++ b/src/danog/MadelineProto/Server.php
@@ -27,41 +27,34 @@ class Server
private $settings;
private $pids = [];
private $mypid;
-
public function __construct($settings)
{
\set_error_handler(['\\danog\\MadelineProto\\Exception', 'ExceptionErrorHandler']);
\danog\MadelineProto\Logger::constructor(3);
-
if (!\extension_loaded('sockets')) {
throw new Exception(['extension', 'sockets']);
}
-
if (!\extension_loaded('pcntl')) {
throw new Exception(['extension', 'pcntl']);
}
$this->settings = $settings;
$this->mypid = \getmypid();
}
-
public function start()
{
\pcntl_signal(SIGTERM, [$this, 'sigHandler']);
\pcntl_signal(SIGINT, [$this, 'sigHandler']);
\pcntl_signal(SIGCHLD, [$this, 'sigHandler']);
-
$this->sock = new \Socket($this->settings['type'], SOCK_STREAM, $this->settings['protocol']);
$this->sock->bind($this->settings['address'], $this->settings['port']);
$this->sock->listen();
$this->sock->setBlocking(true);
-
$timeout = 2;
$this->sock->setOption(\SOL_SOCKET, \SO_RCVTIMEO, $timeout);
$this->sock->setOption(\SOL_SOCKET, \SO_SNDTIMEO, $timeout);
- \danog\MadelineProto\Logger::log('Server started! Listening on '.$this->settings['address'].':'.$this->settings['port']);
+ \danog\MadelineProto\Logger::log('Server started! Listening on ' . $this->settings['address'] . ':' . $this->settings['port']);
while (true) {
\pcntl_signal_dispatch();
-
try {
if ($sock = $this->sock->accept()) {
$this->handle($sock);
@@ -70,7 +63,6 @@ class Server
}
}
}
-
private function handle($socket)
{
$pid = \pcntl_fork();
@@ -83,29 +75,25 @@ class Server
$handler->loop();
die;
}
-
public function __destruct()
{
if ($this->mypid === \getmypid()) {
- \danog\MadelineProto\Logger::log('Shutting main process '.$this->mypid.' down');
+ \danog\MadelineProto\Logger::log('Shutting main process ' . $this->mypid . ' down');
unset($this->sock);
foreach ($this->pids as $pid) {
- \danog\MadelineProto\Logger::log("Waiting for $pid");
+ \danog\MadelineProto\Logger::log("Waiting for {$pid}");
\pcntl_wait($pid);
}
\danog\MadelineProto\Logger::log('Done, closing main process');
-
return;
}
}
-
public function sigHandler($sig)
{
switch ($sig) {
case SIGTERM:
case SIGINT:
- exit();
-
+ exit;
case SIGCHLD:
\pcntl_waitpid(-1, $status);
break;
diff --git a/src/danog/MadelineProto/Shutdown.php b/src/danog/MadelineProto/Shutdown.php
index 26345eb8..cf2b93e3 100644
--- a/src/danog/MadelineProto/Shutdown.php
+++ b/src/danog/MadelineProto/Shutdown.php
@@ -1,4 +1,5 @@
stream = yield $ctx->getStream($header);
}
-
/**
* Async close.
*
@@ -61,7 +59,6 @@ class ADNLStream implements BufferedStreamInterface, MTProtoBufferInterface
{
return $this->stream->disconnect();
}
-
/**
* Get write buffer asynchronously.
*
@@ -77,10 +74,8 @@ class ADNLStream implements BufferedStreamInterface, MTProtoBufferInterface
$this->stream->startWriteHash();
$this->stream->checkWriteHash($length - 32);
yield $buffer->bufferWrite(Tools::random(32));
-
return $buffer;
}
-
/**
* Get read buffer asynchronously.
*
@@ -96,10 +91,8 @@ class ADNLStream implements BufferedStreamInterface, MTProtoBufferInterface
$this->stream->checkReadHash($length);
yield $buffer->bufferRead(32);
$length -= 32;
-
return $buffer;
}
-
/**
* {@inheritdoc}
*
@@ -118,8 +111,6 @@ class ADNLStream implements BufferedStreamInterface, MTProtoBufferInterface
{
return $this->stream;
}
-
-
public static function getName(): string
{
return __CLASS__;
diff --git a/src/danog/MadelineProto/Stream/Async/Buffer.php b/src/danog/MadelineProto/Stream/Async/Buffer.php
index f799ea2e..cfe7fcc3 100644
--- a/src/danog/MadelineProto/Stream/Async/Buffer.php
+++ b/src/danog/MadelineProto/Stream/Async/Buffer.php
@@ -1,4 +1,5 @@
bufferReadGenerator($length));
}
-
public function bufferWrite(string $data): Promise
{
return \danog\MadelineProto\Tools::call($this->bufferWriteGenerator($data));
diff --git a/src/danog/MadelineProto/Stream/Async/BufferedStream.php b/src/danog/MadelineProto/Stream/Async/BufferedStream.php
index 6693e4f2..5cba6395 100644
--- a/src/danog/MadelineProto/Stream/Async/BufferedStream.php
+++ b/src/danog/MadelineProto/Stream/Async/BufferedStream.php
@@ -1,4 +1,5 @@
getReadBufferGenerator($length));
}
-
/**
* Get write buffer asynchronously.
*
diff --git a/src/danog/MadelineProto/Stream/Async/RawStream.php b/src/danog/MadelineProto/Stream/Async/RawStream.php
index 8c0c6a39..162943ff 100644
--- a/src/danog/MadelineProto/Stream/Async/RawStream.php
+++ b/src/danog/MadelineProto/Stream/Async/RawStream.php
@@ -1,4 +1,5 @@
readGenerator());
}
-
public function write(string $data): Promise
{
return \danog\MadelineProto\Tools::call($this->writeGenerator($data));
}
-
public function end(string $finalData = ''): Promise
{
return \danog\MadelineProto\Tools::call($this->endGenerator($finalData));
diff --git a/src/danog/MadelineProto/Stream/Async/Stream.php b/src/danog/MadelineProto/Stream/Async/Stream.php
index 63b6fe5b..590b79c8 100644
--- a/src/danog/MadelineProto/Stream/Async/Stream.php
+++ b/src/danog/MadelineProto/Stream/Async/Stream.php
@@ -1,4 +1,5 @@
stream = yield $ctx->getStream($header);
$this->memory_stream = \fopen('php://memory', 'r+');
-
return true;
}
-
/**
* Async chunked read.
*
@@ -71,7 +67,6 @@ class BufferedRawStream implements BufferedStreamInterface, BufferInterface, Raw
}
return $this->stream->read();
}
-
/**
* Async write.
*
@@ -86,7 +81,6 @@ class BufferedRawStream implements BufferedStreamInterface, BufferInterface, Raw
}
return $this->stream->write($data);
}
-
/**
* Async close.
*
@@ -103,7 +97,6 @@ class BufferedRawStream implements BufferedStreamInterface, BufferInterface, Raw
$this->stream = null;
}
}
-
/**
* Get read buffer asynchronously.
*
@@ -128,10 +121,8 @@ class BufferedRawStream implements BufferedStreamInterface, BufferInterface, Raw
\fclose($this->memory_stream);
$this->memory_stream = $new_memory_stream;
}
-
return new \Amp\Success($this);
}
-
/**
* Get write buffer asynchronously.
*
@@ -145,10 +136,8 @@ class BufferedRawStream implements BufferedStreamInterface, BufferInterface, Raw
$this->append = $append;
$this->append_after = $length - \strlen($append);
}
-
return new \Amp\Success($this);
}
-
/**
* Read data asynchronously.
*
@@ -169,7 +158,6 @@ class BufferedRawStream implements BufferedStreamInterface, BufferInterface, Raw
}
return \danog\MadelineProto\Tools::call($this->bufferReadGenerator($length));
}
-
/**
* Read data asynchronously.
*
@@ -185,22 +173,18 @@ class BufferedRawStream implements BufferedStreamInterface, BufferInterface, Raw
if ($buffer_length < $length && $buffer_length) {
\fseek($this->memory_stream, $offset + $buffer_length);
}
-
while ($buffer_length < $length) {
$chunk = yield $this->read();
if ($chunk === null) {
$this->disconnect();
-
throw new \danog\MadelineProto\NothingInTheSocketException();
}
\fwrite($this->memory_stream, $chunk);
$buffer_length += \strlen($chunk);
}
\fseek($this->memory_stream, $offset);
-
return \fread($this->memory_stream, $length);
}
-
/**
* Async write.
*
@@ -218,14 +202,11 @@ class BufferedRawStream implements BufferedStreamInterface, BufferInterface, Raw
} elseif ($this->append_after < 0) {
$this->append_after = 0;
$this->append = '';
-
throw new Exception('Tried to send too much out of frame data, cannot append');
}
}
-
return $this->write($data);
}
-
/**
* {@inheritdoc}
*
@@ -244,7 +225,6 @@ class BufferedRawStream implements BufferedStreamInterface, BufferInterface, Raw
{
return $this->stream;
}
-
/**
* Get class name.
*
diff --git a/src/danog/MadelineProto/Stream/Common/CtrStream.php b/src/danog/MadelineProto/Stream/Common/CtrStream.php
index 8e52a891..f9cc347e 100644
--- a/src/danog/MadelineProto/Stream/Common/CtrStream.php
+++ b/src/danog/MadelineProto/Stream/Common/CtrStream.php
@@ -1,4 +1,5 @@
encrypt->enableContinuousBuffer();
$this->encrypt->setKey($this->extra['encrypt']['key']);
$this->encrypt->setIV($this->extra['encrypt']['iv']);
-
$this->decrypt = new \tgseclib\Crypt\AES('ctr');
$this->decrypt->enableContinuousBuffer();
$this->decrypt->setKey($this->extra['decrypt']['key']);
$this->decrypt->setIV($this->extra['decrypt']['iv']);
-
$this->stream = yield $ctx->getStream($header);
}
-
/**
* Async close.
*
@@ -80,7 +76,6 @@ class CtrStream implements BufferedProxyStreamInterface, BufferInterface
{
return $this->stream->disconnect();
}
-
/**
* Get write buffer asynchronously.
*
@@ -95,10 +90,8 @@ class CtrStream implements BufferedProxyStreamInterface, BufferInterface
$this->append = $append;
$this->append_after = $length - \strlen($append);
}
-
return $this;
}
-
/**
* Get read buffer asynchronously.
*
@@ -109,10 +102,8 @@ class CtrStream implements BufferedProxyStreamInterface, BufferInterface
public function getReadBufferGenerator(&$length): \Generator
{
$this->read_buffer = yield $this->stream->getReadBuffer($length);
-
return $this;
}
-
/**
* Decrypts read data asynchronously.
*
@@ -126,7 +117,6 @@ class CtrStream implements BufferedProxyStreamInterface, BufferInterface
{
return @$this->decrypt->encrypt(yield $this->read_buffer->bufferRead($length));
}
-
/**
* Writes data to the stream.
*
@@ -146,14 +136,11 @@ class CtrStream implements BufferedProxyStreamInterface, BufferInterface
} elseif ($this->append_after < 0) {
$this->append_after = 0;
$this->append = '';
-
throw new \danog\MadelineProto\Exception('Tried to send too much out of frame data, cannot append');
}
}
-
return $this->write_buffer->bufferWrite(@$this->encrypt->encrypt($data));
}
-
/**
* Set obfuscation keys/IVs.
*
@@ -165,7 +152,6 @@ class CtrStream implements BufferedProxyStreamInterface, BufferInterface
{
$this->extra = $data;
}
-
/**
* {@inheritdoc}
*
@@ -175,7 +161,6 @@ class CtrStream implements BufferedProxyStreamInterface, BufferInterface
{
return $this->stream->getSocket();
}
-
/**
* {@inheritDoc}
*
@@ -193,7 +178,6 @@ class CtrStream implements BufferedProxyStreamInterface, BufferInterface
{
return $this->decrypt;
}
-
public static function getName(): string
{
return __CLASS__;
diff --git a/src/danog/MadelineProto/Stream/Common/HashedBufferedStream.php b/src/danog/MadelineProto/Stream/Common/HashedBufferedStream.php
index 9fe74be8..1fddad5a 100644
--- a/src/danog/MadelineProto/Stream/Common/HashedBufferedStream.php
+++ b/src/danog/MadelineProto/Stream/Common/HashedBufferedStream.php
@@ -1,4 +1,5 @@
read_hash = \hash_init($this->hash_name);
}
-
/**
* Check the read hash after N bytes are read.
*
@@ -67,7 +65,6 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
{
$this->read_check_after = $after;
}
-
/**
* Stop read hashing and get final hash.
*
@@ -82,10 +79,8 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
$this->read_hash = null;
$this->read_check_after = 0;
$this->read_check_pos = 0;
-
return $hash;
}
-
/**
* Check if we are read hashing.
*
@@ -95,7 +90,6 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
{
return $this->read_hash !== null;
}
-
/**
* Enable write hashing.
*
@@ -105,7 +99,6 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
{
$this->write_hash = \hash_init($this->hash_name);
}
-
/**
* Write the write hash after N bytes are read.
*
@@ -117,7 +110,6 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
{
$this->write_check_after = $after;
}
-
/**
* Stop write hashing and get final hash.
*
@@ -132,10 +124,8 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
$this->write_hash = null;
$this->write_check_after = 0;
$this->write_check_pos = 0;
-
return $hash;
}
-
/**
* Check if we are write hashing.
*
@@ -145,7 +135,6 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
{
return $this->write_hash !== null;
}
-
/**
* Hashes read data asynchronously.
*
@@ -167,7 +156,6 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
if ($hash !== yield $this->read_buffer->bufferRead(\strlen($hash))) {
throw new \danog\MadelineProto\Exception('Hash mismatch');
}
-
return $data;
}
$data = yield $this->read_buffer->bufferRead($length);
@@ -175,10 +163,8 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
if ($this->read_check_after) {
$this->read_check_pos += $length;
}
-
return $data;
}
-
/**
* Set the hash algorithm.
*
@@ -196,7 +182,6 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
}
$this->hash_name = $hash;
}
-
/**
* Connect to stream.
*
@@ -212,10 +197,8 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
$this->read_hash = null;
$this->read_check_after = 0;
$this->read_check_pos = 0;
-
$this->stream = yield $ctx->getStream($header);
}
-
/**
* Async close.
*
@@ -225,7 +208,6 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
{
return $this->stream->disconnect();
}
-
/**
* Get read buffer asynchronously.
*
@@ -237,13 +219,10 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
{
//if ($this->read_hash) {
$this->read_buffer = yield $this->stream->getReadBuffer($length);
-
return $this;
//}
-
//return yield $this->stream->getReadBuffer($length);
}
-
/**
* Get write buffer asynchronously.
*
@@ -255,13 +234,10 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
{
//if ($this->write_hash) {
$this->write_buffer = yield $this->stream->getWriteBuffer($length, $append);
-
return $this;
//}
-
//return yield $this->stream->getWriteBuffer($length, $append);
}
-
/**
* Reads data from the stream.
*
@@ -274,10 +250,8 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
if ($this->read_hash === null) {
return $this->read_buffer->bufferRead($length);
}
-
return \danog\MadelineProto\Tools::call($this->bufferReadGenerator($length));
}
-
/**
* Writes data to the stream.
*
@@ -292,15 +266,13 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
if ($this->write_hash === null) {
return $this->write_buffer->bufferWrite($data);
}
-
$length = \strlen($data);
if ($this->write_check_after && $length + $this->write_check_pos >= $this->write_check_after) {
if ($length + $this->write_check_pos > $this->write_check_after) {
throw new \danog\MadelineProto\Exception('Too much out of frame data was sent, cannot check hash');
}
\hash_update($this->write_hash, $data);
-
- return $this->write_buffer->bufferWrite($data.$this->getWriteHash());
+ return $this->write_buffer->bufferWrite($data . $this->getWriteHash());
}
if ($this->write_check_after) {
$this->write_check_pos += $length;
@@ -308,10 +280,8 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
if ($this->write_hash) {
\hash_update($this->write_hash, $data);
}
-
return $this->write_buffer->bufferWrite($data);
}
-
/**
* {@inheritdoc}
*
@@ -321,7 +291,6 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
{
return $this->stream->getSocket();
}
-
/**
* {@inheritDoc}
*
diff --git a/src/danog/MadelineProto/Stream/Common/SimpleBufferedRawStream.php b/src/danog/MadelineProto/Stream/Common/SimpleBufferedRawStream.php
index ce528f62..ffb350a2 100644
--- a/src/danog/MadelineProto/Stream/Common/SimpleBufferedRawStream.php
+++ b/src/danog/MadelineProto/Stream/Common/SimpleBufferedRawStream.php
@@ -1,4 +1,5 @@
memory_stream, $offset + $buffer_length);
}
-
while ($buffer_length < $length) {
$chunk = yield $this->read();
if ($chunk === null) {
@@ -55,7 +55,6 @@ class SimpleBufferedRawStream extends BufferedRawStream implements BufferedStrea
$buffer_length += \strlen($chunk);
}
\fseek($this->memory_stream, $offset);
-
return \fread($this->memory_stream, $length);
}
/**
@@ -67,7 +66,6 @@ class SimpleBufferedRawStream extends BufferedRawStream implements BufferedStrea
{
return $this->stream;
}
-
/**
* Get class name.
*
diff --git a/src/danog/MadelineProto/Stream/ConnectionContext.php b/src/danog/MadelineProto/Stream/ConnectionContext.php
index f026e078..a317cd94 100644
--- a/src/danog/MadelineProto/Stream/ConnectionContext.php
+++ b/src/danog/MadelineProto/Stream/ConnectionContext.php
@@ -1,4 +1,5 @@
socketContext = $socketContext;
-
return $this;
}
-
/**
* Get the socket context.
*
@@ -138,7 +135,6 @@ class ConnectionContext
{
return $this->socketContext;
}
-
/**
* Set the connection URI.
*
@@ -149,10 +145,8 @@ class ConnectionContext
public function setUri($uri): self
{
$this->uri = $uri instanceof Uri ? $uri : new Uri($uri);
-
return $this;
}
-
/**
* Get the URI as a string.
*
@@ -162,7 +156,6 @@ class ConnectionContext
{
return (string) $this->uri;
}
-
/**
* Get the URI.
*
@@ -172,7 +165,6 @@ class ConnectionContext
{
return $this->uri;
}
-
/**
* Set the cancellation token.
*
@@ -183,10 +175,8 @@ class ConnectionContext
public function setCancellationToken($cancellationToken): self
{
$this->cancellationToken = $cancellationToken;
-
return $this;
}
-
/**
* Get the cancellation token.
*
@@ -215,10 +205,8 @@ class ConnectionContext
public function setTest(bool $test): self
{
$this->test = $test;
-
return $this;
}
-
/**
* Whether this is a test connection.
*
@@ -237,7 +225,6 @@ class ConnectionContext
{
return $this->media;
}
-
/**
* Whether this is a CDN connection.
*
@@ -247,7 +234,6 @@ class ConnectionContext
{
return $this->cdn;
}
-
/**
* Whether this connection context will only be used by the DNS client.
*
@@ -257,7 +243,6 @@ class ConnectionContext
{
return $this->isDns;
}
-
/**
* Whether this connection context will only be used by the DNS client.
*
@@ -279,10 +264,8 @@ class ConnectionContext
public function secure(bool $secure): self
{
$this->secure = $secure;
-
return $this;
}
-
/**
* Whether to use TLS with socket connections.
*
@@ -292,7 +275,6 @@ class ConnectionContext
{
return $this->secure;
}
-
/**
* Set the DC ID.
*
@@ -304,15 +286,13 @@ class ConnectionContext
{
$int = \intval($dc);
if (!(1 <= $int && $int <= 1000)) {
- throw new Exception("Invalid DC id provided: $dc");
+ throw new Exception("Invalid DC id provided: {$dc}");
}
$this->dc = $dc;
$this->media = \strpos($dc, '_media') !== false;
$this->cdn = \strpos($dc, '_cdn') !== false;
-
return $this;
}
-
/**
* Get the DC ID.
*
@@ -322,7 +302,6 @@ class ConnectionContext
{
return $this->dc;
}
-
/**
* Get the int DC ID.
*
@@ -337,10 +316,8 @@ class ConnectionContext
if ($this->media) {
$dc = -$dc;
}
-
return $dc;
}
-
/**
* Whether to use ipv6.
*
@@ -351,10 +328,8 @@ class ConnectionContext
public function setIpv6(bool $ipv6): self
{
$this->ipv6 = $ipv6;
-
return $this;
}
-
/**
* Whether to use ipv6.
*
@@ -364,7 +339,6 @@ class ConnectionContext
{
return $this->ipv6;
}
-
/**
* Add a stream to the stream chain.
*
@@ -377,10 +351,8 @@ class ConnectionContext
{
$this->nextStreams[] = [$streamName, $extra];
$this->key = \count($this->nextStreams) - 1;
-
return $this;
}
-
/**
* Set read callback, called every time the socket reads at least a byte.
*
@@ -392,7 +364,6 @@ class ConnectionContext
{
$this->readCallback = $callable;
}
-
/**
* Check if a read callback is present.
*
@@ -402,7 +373,6 @@ class ConnectionContext
{
return $this->readCallback !== null;
}
-
/**
* Get read callback.
*
@@ -412,7 +382,6 @@ class ConnectionContext
{
return $this->readCallback;
}
-
/**
* Get the current stream name from the stream chain.
*
@@ -422,7 +391,6 @@ class ConnectionContext
{
return $this->nextStreams[$this->key][0];
}
-
/**
* Check if has stream within stream chain.
*
@@ -439,7 +407,6 @@ class ConnectionContext
}
return false;
}
-
/**
* Get a stream from the stream chain.
*
@@ -455,11 +422,8 @@ class ConnectionContext
$obj->setExtra($extra);
}
yield $obj->connect($this, $buffer);
-
return $obj;
}
-
-
/**
* Get the inputClientProxy proxy MTProto object.
*
@@ -499,13 +463,11 @@ class ConnectionContext
}
$string .= \preg_replace('/.*\\\\/', '', $stream[0]);
if ($stream[1] && $stream[0] !== DefaultStream::getName()) {
- $string .= ' ('.\json_encode($stream[1]).')';
+ $string .= ' (' . \json_encode($stream[1]) . ')';
}
}
-
return $string;
}
-
/**
* Returns a representation of the context.
*
diff --git a/src/danog/MadelineProto/Stream/MTProtoBufferInterface.php b/src/danog/MadelineProto/Stream/MTProtoBufferInterface.php
index b2155d78..138bdecb 100644
--- a/src/danog/MadelineProto/Stream/MTProtoBufferInterface.php
+++ b/src/danog/MadelineProto/Stream/MTProtoBufferInterface.php
@@ -1,4 +1,5 @@
stream = yield $ctx->getStream(\chr(239).$header);
+ $this->stream = yield $ctx->getStream(\chr(239) . $header);
}
-
/**
* Async close.
*
@@ -58,7 +56,6 @@ class AbridgedStream implements BufferedStreamInterface, MTProtoBufferInterface
{
return $this->stream->disconnect();
}
-
/**
* Get write buffer asynchronously.
*
@@ -72,14 +69,12 @@ class AbridgedStream implements BufferedStreamInterface, MTProtoBufferInterface
if ($length < 127) {
$message = \chr($length);
} else {
- $message = \chr(127).\substr(\pack('V', $length), 0, 3);
+ $message = \chr(127) . \substr(\pack('V', $length), 0, 3);
}
$buffer = yield $this->stream->getWriteBuffer(\strlen($message) + $length, $append);
yield $buffer->bufferWrite($message);
-
return $buffer;
}
-
/**
* Get read buffer asynchronously.
*
@@ -92,13 +87,11 @@ class AbridgedStream implements BufferedStreamInterface, MTProtoBufferInterface
$buffer = yield $this->stream->getReadBuffer($l);
$length = \ord(yield $buffer->bufferRead(1));
if ($length >= 127) {
- $length = \unpack('V', (yield $buffer->bufferRead(3))."\0")[1];
+ $length = \unpack('V', yield $buffer->bufferRead(3) . "\0")[1];
}
$length <<= 2;
-
return $buffer;
}
-
/**
* {@inheritdoc}
*
@@ -108,7 +101,6 @@ class AbridgedStream implements BufferedStreamInterface, MTProtoBufferInterface
{
return $this->stream->getSocket();
}
-
/**
* {@inheritDoc}
*
diff --git a/src/danog/MadelineProto/Stream/MTProtoTransport/FullStream.php b/src/danog/MadelineProto/Stream/MTProtoTransport/FullStream.php
index af06fbe3..a92178d6 100644
--- a/src/danog/MadelineProto/Stream/MTProtoTransport/FullStream.php
+++ b/src/danog/MadelineProto/Stream/MTProtoTransport/FullStream.php
@@ -1,4 +1,5 @@
out_seq_no = -1;
$this->stream = new HashedBufferedStream();
$this->stream->setExtra('crc32b_rev');
-
return $this->stream->connect($ctx, $header);
}
-
/**
* Async close.
*
@@ -67,7 +65,6 @@ class FullStream implements BufferedStreamInterface, MTProtoBufferInterface
{
return $this->stream->disconnect();
}
-
/**
* Get write buffer asynchronously.
*
@@ -82,10 +79,8 @@ class FullStream implements BufferedStreamInterface, MTProtoBufferInterface
$buffer = yield $this->stream->getWriteBuffer($length + 12, $append);
$this->out_seq_no++;
$buffer->bufferWrite(\pack('VV', $length + 12, $this->out_seq_no));
-
return $buffer;
}
-
/**
* Get read buffer asynchronously.
*
@@ -105,10 +100,8 @@ class FullStream implements BufferedStreamInterface, MTProtoBufferInterface
if ($in_seq_no != $this->in_seq_no) {
throw new \danog\MadelineProto\Exception('Incoming seq_no mismatch');
}
-
return $buffer;
}
-
/**
* {@inheritdoc}
*
@@ -118,7 +111,6 @@ class FullStream implements BufferedStreamInterface, MTProtoBufferInterface
{
return $this->stream->getSocket();
}
-
/**
* {@inheritDoc}
*
diff --git a/src/danog/MadelineProto/Stream/MTProtoTransport/HttpStream.php b/src/danog/MadelineProto/Stream/MTProtoTransport/HttpStream.php
index 9bd3973e..285da0e7 100644
--- a/src/danog/MadelineProto/Stream/MTProtoTransport/HttpStream.php
+++ b/src/danog/MadelineProto/Stream/MTProtoTransport/HttpStream.php
@@ -1,4 +1,5 @@
stream = yield $ctx->getStream($header);
$this->uri = $ctx->getUri();
}
-
/**
* Set proxy data.
*
@@ -70,10 +69,9 @@ class HttpStream implements MTProtoBufferInterface, BufferedProxyStreamInterface
public function setExtra($extra)
{
if (isset($extra['user']) && isset($extra['password'])) {
- $this->header = \base64_encode($extra['user'].':'.$extra['password'])."\r\n";
+ $this->header = \base64_encode($extra['user'] . ':' . $extra['password']) . "\r\n";
}
}
-
/**
* Async close.
*
@@ -83,7 +81,6 @@ class HttpStream implements MTProtoBufferInterface, BufferedProxyStreamInterface
{
return $this->stream->disconnect();
}
-
/**
* Get write buffer asynchronously.
*
@@ -93,13 +90,11 @@ class HttpStream implements MTProtoBufferInterface, BufferedProxyStreamInterface
*/
public function getWriteBufferGenerator(int $length, string $append = ''): \Generator
{
- $headers = 'POST '.$this->uri->getPath()." HTTP/1.1\r\nHost: ".$this->uri->getHost().':'.$this->uri->getPort()."\r\n"."Content-Type: application/x-www-form-urlencoded\r\nConnection: keep-alive\r\nKeep-Alive: timeout=100000, max=10000000\r\nContent-Length: ".$length.$this->header."\r\n\r\n";
+ $headers = 'POST ' . $this->uri->getPath() . " HTTP/1.1\r\nHost: " . $this->uri->getHost() . ':' . $this->uri->getPort() . "\r\n" . "Content-Type: application/x-www-form-urlencoded\r\nConnection: keep-alive\r\nKeep-Alive: timeout=100000, max=10000000\r\nContent-Length: " . $length . $this->header . "\r\n\r\n";
$buffer = yield $this->stream->getWriteBuffer(\strlen($headers) + $length, $append);
yield $buffer->bufferWrite($headers);
-
return $buffer;
}
-
/**
* Get read buffer asynchronously.
*
@@ -115,7 +110,8 @@ class HttpStream implements MTProtoBufferInterface, BufferedProxyStreamInterface
while (true) {
$piece = yield $buffer->bufferRead(2);
$headers .= $piece;
- if ($piece === "\n\r") { // Assume end of headers with \r\n\r\n
+ if ($piece === "\n\r") {
+ // Assume end of headers with \r\n\r\n
$headers .= yield $buffer->bufferRead(1);
break;
}
@@ -125,7 +121,6 @@ class HttpStream implements MTProtoBufferInterface, BufferedProxyStreamInterface
$was_crlf = $piece === "\r\n";
}
$headers = \explode("\r\n", $headers);
-
list($protocol, $code, $description) = \explode(' ', $headers[0], 3);
list($protocol, $protocol_version) = \explode('/', $protocol);
if ($protocol !== 'HTTP') {
@@ -133,7 +128,7 @@ class HttpStream implements MTProtoBufferInterface, BufferedProxyStreamInterface
}
$code = (int) $code;
unset($headers[0]);
- if (\array_pop($headers).\array_pop($headers) !== '') {
+ if (\array_pop($headers) . \array_pop($headers) !== '') {
throw new \danog\MadelineProto\Exception('Wrong last header');
}
foreach ($headers as $key => $current_header) {
@@ -141,31 +136,24 @@ class HttpStream implements MTProtoBufferInterface, BufferedProxyStreamInterface
$current_header = \explode(':', $current_header, 2);
$headers[\strtolower($current_header[0])] = \trim($current_header[1]);
}
-
$close = $protocol === 'HTTP/1.0';
if (isset($headers['connection'])) {
$close = \strtolower($headers['connection']) === 'close';
}
-
if ($code !== 200) {
$read = '';
if (isset($headers['content-length'])) {
$read = yield $buffer->bufferRead((int) $headers['content-length']);
}
-
if ($close) {
$this->disconnect();
yield $this->connect($this->ctx);
}
-
\danog\MadelineProto\Logger::log($read);
-
$this->code = \danog\MadelineProto\Tools::packSignedInt(-$code);
$length = 4;
-
return $this;
}
-
if ($close) {
$this->stream->disconnect();
yield $this->stream->connect($this->ctx);
@@ -173,15 +161,12 @@ class HttpStream implements MTProtoBufferInterface, BufferedProxyStreamInterface
if (isset($headers['content-length'])) {
$length = (int) $headers['content-length'];
}
-
return $buffer;
}
-
public function bufferRead(int $length): Promise
{
return new Success($this->code);
}
-
/**
* {@inheritdoc}
*
@@ -200,7 +185,6 @@ class HttpStream implements MTProtoBufferInterface, BufferedProxyStreamInterface
{
return $this->stream;
}
-
public static function getName(): string
{
return __CLASS__;
diff --git a/src/danog/MadelineProto/Stream/MTProtoTransport/HttpsStream.php b/src/danog/MadelineProto/Stream/MTProtoTransport/HttpsStream.php
index e46c539f..0ce77b05 100644
--- a/src/danog/MadelineProto/Stream/MTProtoTransport/HttpsStream.php
+++ b/src/danog/MadelineProto/Stream/MTProtoTransport/HttpsStream.php
@@ -1,4 +1,5 @@
getCtx()->secure(true), $header);
}
-
/**
* {@inheritDoc}
*
diff --git a/src/danog/MadelineProto/Stream/MTProtoTransport/IntermediatePaddedStream.php b/src/danog/MadelineProto/Stream/MTProtoTransport/IntermediatePaddedStream.php
index 56d66e12..9940adac 100644
--- a/src/danog/MadelineProto/Stream/MTProtoTransport/IntermediatePaddedStream.php
+++ b/src/danog/MadelineProto/Stream/MTProtoTransport/IntermediatePaddedStream.php
@@ -1,4 +1,5 @@
stream = yield $ctx->getStream(\str_repeat(\chr(221), 4).$header);
+ $this->stream = yield $ctx->getStream(\str_repeat(\chr(221), 4) . $header);
}
-
/**
* Async close.
*
@@ -60,7 +58,6 @@ class IntermediatePaddedStream implements BufferedStreamInterface, MTProtoBuffer
{
return $this->stream->disconnect();
}
-
/**
* Get write buffer asynchronously.
*
@@ -71,12 +68,10 @@ class IntermediatePaddedStream implements BufferedStreamInterface, MTProtoBuffer
public function getWriteBufferGenerator(int $length, string $append = ''): \Generator
{
$padding_length = \danog\MadelineProto\Tools::randomInt($modulus = 16);
- $buffer = yield $this->stream->getWriteBuffer(4 + $length + $padding_length, $append.\danog\MadelineProto\Tools::random($padding_length));
+ $buffer = yield $this->stream->getWriteBuffer(4 + $length + $padding_length, $append . \danog\MadelineProto\Tools::random($padding_length));
yield $buffer->bufferWrite(\pack('V', $padding_length + $length));
-
return $buffer;
}
-
/**
* Get read buffer asynchronously.
*
@@ -88,10 +83,8 @@ class IntermediatePaddedStream implements BufferedStreamInterface, MTProtoBuffer
{
$buffer = yield $this->stream->getReadBuffer($l);
$length = \unpack('V', yield $buffer->bufferRead(4))[1];
-
return $buffer;
}
-
/**
* {@inheritdoc}
*
@@ -110,7 +103,6 @@ class IntermediatePaddedStream implements BufferedStreamInterface, MTProtoBuffer
{
return $this->stream;
}
-
public static function getName(): string
{
return __CLASS__;
diff --git a/src/danog/MadelineProto/Stream/MTProtoTransport/IntermediateStream.php b/src/danog/MadelineProto/Stream/MTProtoTransport/IntermediateStream.php
index 818e426a..3cc8ec11 100644
--- a/src/danog/MadelineProto/Stream/MTProtoTransport/IntermediateStream.php
+++ b/src/danog/MadelineProto/Stream/MTProtoTransport/IntermediateStream.php
@@ -1,4 +1,5 @@
stream = yield $ctx->getStream(\str_repeat(\chr(238), 4).$header);
+ $this->stream = yield $ctx->getStream(\str_repeat(\chr(238), 4) . $header);
}
-
/**
* Async close.
*
@@ -60,7 +58,6 @@ class IntermediateStream implements BufferedStreamInterface, MTProtoBufferInterf
{
return $this->stream->disconnect();
}
-
/**
* Get write buffer asynchronously.
*
@@ -72,10 +69,8 @@ class IntermediateStream implements BufferedStreamInterface, MTProtoBufferInterf
{
$buffer = yield $this->stream->getWriteBuffer($length + 4, $append);
yield $buffer->bufferWrite(\pack('V', $length));
-
return $buffer;
}
-
/**
* Get read buffer asynchronously.
*
@@ -87,10 +82,8 @@ class IntermediateStream implements BufferedStreamInterface, MTProtoBufferInterf
{
$buffer = yield $this->stream->getReadBuffer($l);
$length = \unpack('V', yield $buffer->bufferRead(4))[1];
-
return $buffer;
}
-
/**
* {@inheritdoc}
*
@@ -109,8 +102,6 @@ class IntermediateStream implements BufferedStreamInterface, MTProtoBufferInterf
{
return $this->stream;
}
-
-
public static function getName(): string
{
return __CLASS__;
diff --git a/src/danog/MadelineProto/Stream/MTProtoTransport/ObfuscatedStream.php b/src/danog/MadelineProto/Stream/MTProtoTransport/ObfuscatedStream.php
index e2f6e7c0..c629d5f8 100644
--- a/src/danog/MadelineProto/Stream/MTProtoTransport/ObfuscatedStream.php
+++ b/src/danog/MadelineProto/Stream/MTProtoTransport/ObfuscatedStream.php
@@ -1,4 +1,5 @@
extra['address'])) {
$ctx = $ctx->getCtx();
- $ctx->setUri('tcp://'.$this->extra['address'].':'.$this->extra['port']);
+ $ctx->setUri('tcp://' . $this->extra['address'] . ':' . $this->extra['port']);
}
-
do {
$random = \danog\MadelineProto\Tools::random(64);
} while (\in_array(\substr($random, 0, 4), ['PVrG', 'GET ', 'POST', 'HEAD', \str_repeat(\chr(238), 4), \str_repeat(\chr(221), 4)]) || $random[0] === \chr(0xef) || \substr($random, 4, 4) === "\0\0\0\0");
-
if (\strlen($header) === 1) {
$header = \str_repeat($header, 4);
}
- $random = \substr_replace($random, $header.\substr($random, 56 + \strlen($header)), 56);
- $random = \substr_replace($random, \pack('s', $ctx->getIntDc()).\substr($random, 60 + 2), 60);
-
+ $random = \substr_replace($random, $header . \substr($random, 56 + \strlen($header)), 56);
+ $random = \substr_replace($random, \pack('s', $ctx->getIntDc()) . \substr($random, 60 + 2), 60);
$reversed = \strrev($random);
-
$key = \substr($random, 8, 32);
$keyRev = \substr($reversed, 8, 32);
-
if (isset($this->extra['secret'])) {
- $key = \hash('sha256', $key.$this->extra['secret'], true);
- $keyRev = \hash('sha256', $keyRev.$this->extra['secret'], true);
+ $key = \hash('sha256', $key . $this->extra['secret'], true);
+ $keyRev = \hash('sha256', $keyRev . $this->extra['secret'], true);
}
-
$iv = \substr($random, 40, 16);
$ivRev = \substr($reversed, 40, 16);
-
- parent::setExtra(
- [
- 'encrypt' => [
- 'key' => $key,
- 'iv' => $iv
- ],
- 'decrypt' => [
- 'key' => $keyRev,
- 'iv' => $ivRev
- ]
- ]
- );
+ parent::setExtra(['encrypt' => ['key' => $key, 'iv' => $iv], 'decrypt' => ['key' => $keyRev, 'iv' => $ivRev]]);
yield from parent::connectGenerator($ctx);
-
$random = \substr_replace($random, \substr(@$this->getEncryptor()->encrypt($random), 56, 8), 56, 8);
-
yield $this->getStream()->write($random);
}
-
-
/**
* Does nothing.
*
@@ -111,7 +88,6 @@ class ObfuscatedStream extends CtrStream implements BufferedProxyStreamInterface
$extra['secret'] = \substr($extra['secret'], 1, 16);
}
}
-
$this->extra = $extra;
}
public static function getName(): string
diff --git a/src/danog/MadelineProto/Stream/Proxy/HttpProxy.php b/src/danog/MadelineProto/Stream/Proxy/HttpProxy.php
index 913f9efc..47057048 100644
--- a/src/danog/MadelineProto/Stream/Proxy/HttpProxy.php
+++ b/src/danog/MadelineProto/Stream/Proxy/HttpProxy.php
@@ -1,4 +1,5 @@
getCtx();
$uri = $ctx->getUri();
$secure = $ctx->isSecure();
-
if ($secure) {
$ctx->setSocketContext($ctx->getSocketContext()->withTlsContext(new ClientTlsContext($uri->getHost())));
}
-
- $ctx->setUri('tcp://'.$this->extra['address'].':'.$this->extra['port'])->secure(false);
-
+ $ctx->setUri('tcp://' . $this->extra['address'] . ':' . $this->extra['port'])->secure(false);
$this->stream = yield $ctx->getStream();
$address = $uri->getHost();
$port = $uri->getPort();
-
try {
if (\strlen(\inet_pton($address) === 16)) {
- $address = '['.$address.']';
+ $address = '[' . $address . ']';
}
} catch (\danog\MadelineProto\Exception $e) {
}
-
- yield $this->stream->write("CONNECT $address:$port HTTP/1.1\r\nHost: $address:$port\r\nAccept: */*\r\n".$this->getProxyAuthHeader()."Connection: keep-Alive\r\n\r\n");
-
+ yield $this->stream->write("CONNECT {$address}:{$port} HTTP/1.1\r\nHost: {$address}:{$port}\r\nAccept: */*\r\n" . $this->getProxyAuthHeader() . "Connection: keep-Alive\r\n\r\n");
$buffer = yield $this->stream->getReadBuffer($l);
$headers = '';
$was_crlf = false;
while (true) {
$piece = yield $buffer->bufferRead(2);
$headers .= $piece;
- if ($piece === "\n\r") { // Assume end of headers with \r\n\r\n
+ if ($piece === "\n\r") {
+ // Assume end of headers with \r\n\r\n
$headers .= yield $buffer->bufferRead(1);
break;
}
@@ -86,7 +80,6 @@ class HttpProxy implements RawProxyStreamInterface, BufferedProxyStreamInterface
$was_crlf = $piece === "\r\n";
}
$headers = \explode("\r\n", $headers);
-
list($protocol, $code, $description) = \explode(' ', $headers[0], 3);
list($protocol, $protocol_version) = \explode('/', $protocol);
if ($protocol !== 'HTTP') {
@@ -94,7 +87,7 @@ class HttpProxy implements RawProxyStreamInterface, BufferedProxyStreamInterface
}
$code = (int) $code;
unset($headers[0]);
- if (\array_pop($headers).\array_pop($headers) !== '') {
+ if (\array_pop($headers) . \array_pop($headers) !== '') {
throw new \danog\MadelineProto\Exception('Wrong last header');
}
foreach ($headers as $key => $current_header) {
@@ -102,28 +95,22 @@ class HttpProxy implements RawProxyStreamInterface, BufferedProxyStreamInterface
$current_header = \explode(':', $current_header, 2);
$headers[\strtolower($current_header[0])] = \trim($current_header[1]);
}
-
$close = $protocol === 'HTTP/1.0';
if (isset($headers['connection'])) {
$close = \strtolower($headers['connection']) === 'close';
}
-
if ($code !== 200) {
$read = '';
if (isset($headers['content-length'])) {
$read = yield $buffer->bufferRead((int) $headers['content-length']);
}
-
if ($close) {
$this->disconnect();
yield $this->connect($ctx);
}
-
\danog\MadelineProto\Logger::log(\trim($read));
-
throw new \danog\MadelineProto\Exception($description, $code);
}
-
if ($close) {
yield $this->stream->disconnect();
yield $this->stream->connect($ctx);
@@ -132,17 +119,14 @@ class HttpProxy implements RawProxyStreamInterface, BufferedProxyStreamInterface
$length = (int) $headers['content-length'];
$read = yield $buffer->bufferRead($length);
}
-
if ($secure) {
yield $this->getSocket()->setupTls();
}
- \danog\MadelineProto\Logger::log('Connected to '.$address.':'.$port.' via http');
-
+ \danog\MadelineProto\Logger::log('Connected to ' . $address . ':' . $port . ' via http');
if (\strlen($header)) {
yield (yield $this->stream->getWriteBuffer(\strlen($header)))->bufferWrite($header);
}
}
-
/**
* Async close.
*
@@ -152,7 +136,6 @@ class HttpProxy implements RawProxyStreamInterface, BufferedProxyStreamInterface
{
return $this->stream->disconnect();
}
-
/**
* Get write buffer asynchronously.
*
@@ -164,7 +147,6 @@ class HttpProxy implements RawProxyStreamInterface, BufferedProxyStreamInterface
{
return $this->stream->getWriteBuffer($length, $append);
}
-
/**
* Get read buffer asynchronously.
*
@@ -176,26 +158,21 @@ class HttpProxy implements RawProxyStreamInterface, BufferedProxyStreamInterface
{
return $this->stream->getReadBuffer($length);
}
-
public function read(): Promise
{
return $this->stream->read();
}
-
public function write(string $data): Promise
{
return $this->stream->write($data);
}
-
private function getProxyAuthHeader()
{
if (!isset($this->extra['username']) || !isset($this->extra['password'])) {
return '';
}
-
- return 'Proxy-Authorization: Basic '.\base64_encode($this->extra['username'].':'.$this->extra['password'])."\r\n";
+ return 'Proxy-Authorization: Basic ' . \base64_encode($this->extra['username'] . ':' . $this->extra['password']) . "\r\n";
}
-
/**
* Sets proxy data.
*
@@ -207,7 +184,6 @@ class HttpProxy implements RawProxyStreamInterface, BufferedProxyStreamInterface
{
$this->extra = $extra;
}
-
/**
* {@inheritdoc}
*
@@ -217,7 +193,6 @@ class HttpProxy implements RawProxyStreamInterface, BufferedProxyStreamInterface
{
return $this->stream->getSocket();
}
-
/**
* {@inheritDoc}
*
diff --git a/src/danog/MadelineProto/Stream/Proxy/SocksProxy.php b/src/danog/MadelineProto/Stream/Proxy/SocksProxy.php
index 162a6689..e54a4af2 100644
--- a/src/danog/MadelineProto/Stream/Proxy/SocksProxy.php
+++ b/src/danog/MadelineProto/Stream/Proxy/SocksProxy.php
@@ -1,4 +1,5 @@
'succeeded',
- 1 => 'general SOCKS server failure',
- 2 => 'connection not allowed by ruleset',
- 3 => 'Network unreachable',
- 4 => 'Host unreachable',
- 5 => 'Connection refused',
- 6 => 'TTL expired',
- 7 => 'Command not supported',
- 8 => 'Address type not supported'
- ];
+ const REPS = [0 => 'succeeded', 1 => 'general SOCKS server failure', 2 => 'connection not allowed by ruleset', 3 => 'Network unreachable', 4 => 'Host unreachable', 5 => 'Connection refused', 6 => 'TTL expired', 7 => 'Command not supported', 8 => 'Address type not supported'];
use RawStream;
private $extra;
-
/**
* Connect to stream.
*
@@ -61,78 +50,61 @@ class SocksProxy implements RawProxyStreamInterface, BufferedProxyStreamInterfac
$ctx = $ctx->getCtx();
$uri = $ctx->getUri();
$secure = $ctx->isSecure();
-
if ($secure) {
$ctx->setSocketContext($ctx->getSocketContext()->withTlsContext(new ClientTlsContext($uri->getHost())));
}
-
- $ctx->setUri('tcp://'.$this->extra['address'].':'.$this->extra['port'])->secure(false);
-
+ $ctx->setUri('tcp://' . $this->extra['address'] . ':' . $this->extra['port'])->secure(false);
$methods = \chr(0);
if (isset($this->extra['username']) && isset($this->extra['password'])) {
$methods .= \chr(2);
}
- $this->stream = yield $ctx->getStream(\chr(5).\chr(\strlen($methods)).$methods);
-
+ $this->stream = yield $ctx->getStream(\chr(5) . \chr(\strlen($methods)) . $methods);
$l = 2;
-
$buffer = yield $this->stream->getReadBuffer($l);
-
$version = \ord(yield $buffer->bufferRead(1));
$method = \ord(yield $buffer->bufferRead(1));
-
if ($version !== 5) {
- throw new \danog\MadelineProto\Exception("Wrong SOCKS5 version: $version");
+ throw new \danog\MadelineProto\Exception("Wrong SOCKS5 version: {$version}");
}
if ($method === 2) {
- $auth = \chr(1).\chr(\strlen($this->extra['username'])).$this->extra['username'].\chr(\strlen($this->extra['password'])).$this->extra['password'];
+ $auth = \chr(1) . \chr(\strlen($this->extra['username'])) . $this->extra['username'] . \chr(\strlen($this->extra['password'])) . $this->extra['password'];
yield $this->stream->write($auth);
-
$buffer = yield $this->stream->getReadBuffer($l);
-
$version = \ord(yield $buffer->bufferRead(1));
$result = \ord(yield $buffer->bufferRead(1));
-
if ($version !== 1) {
- throw new \danog\MadelineProto\Exception("Wrong authorized SOCKS version: $version");
+ throw new \danog\MadelineProto\Exception("Wrong authorized SOCKS version: {$version}");
}
if ($result !== 0) {
- throw new \danog\MadelineProto\Exception("Wrong authorization status: $version");
+ throw new \danog\MadelineProto\Exception("Wrong authorization status: {$version}");
}
} elseif ($method !== 0) {
- throw new \danog\MadelineProto\Exception("Wrong method: $method");
+ throw new \danog\MadelineProto\Exception("Wrong method: {$method}");
}
- $payload = \pack('C3', 0x05, 0x01, 0x00);
-
+ $payload = \pack('C3', 0x5, 0x1, 0x0);
try {
$ip = \inet_pton($uri->getHost());
- $payload .= $ip ? \pack('C1', \strlen($ip) === 4 ? 0x01 : 0x04).$ip : \pack('C2', 0x03, \strlen($uri->getHost())).$uri->getHost();
+ $payload .= $ip ? \pack('C1', \strlen($ip) === 4 ? 0x1 : 0x4) . $ip : \pack('C2', 0x3, \strlen($uri->getHost())) . $uri->getHost();
} catch (\danog\MadelineProto\Exception $e) {
- $payload .= \pack('C2', 0x03, \strlen($uri->getHost())).$uri->getHost();
+ $payload .= \pack('C2', 0x3, \strlen($uri->getHost())) . $uri->getHost();
}
-
$payload .= \pack('n', $uri->getPort());
yield $this->stream->write($payload);
-
$l = 4;
$buffer = yield $this->stream->getReadBuffer($l);
-
$version = \ord(yield $buffer->bufferRead(1));
if ($version !== 5) {
- throw new \danog\MadelineProto\Exception("Wrong SOCKS5 version: $version");
+ throw new \danog\MadelineProto\Exception("Wrong SOCKS5 version: {$version}");
}
-
$rep = \ord(yield $buffer->bufferRead(1));
if ($rep !== 0) {
$rep = self::REPS[$rep] ?? $rep;
- throw new \danog\MadelineProto\Exception("Wrong SOCKS5 rep: $rep");
+ throw new \danog\MadelineProto\Exception("Wrong SOCKS5 rep: {$rep}");
}
-
$rsv = \ord(yield $buffer->bufferRead(1));
if ($rsv !== 0) {
- throw new \danog\MadelineProto\Exception("Wrong socks5 final RSV: $rsv");
+ throw new \danog\MadelineProto\Exception("Wrong socks5 final RSV: {$rsv}");
}
-
switch (\ord(yield $buffer->bufferRead(1))) {
case 1:
$buffer = yield $this->stream->getReadBuffer($l);
@@ -147,7 +119,6 @@ class SocksProxy implements RawProxyStreamInterface, BufferedProxyStreamInterfac
$l = 1;
$buffer = yield $this->stream->getReadBuffer($l);
$length = \ord(yield $buffer->bufferRead(1));
-
$buffer = yield $this->stream->getReadBuffer($length);
$ip = yield $buffer->bufferRead($length);
break;
@@ -155,9 +126,7 @@ class SocksProxy implements RawProxyStreamInterface, BufferedProxyStreamInterfac
$l = 2;
$buffer = yield $this->stream->getReadBuffer($l);
$port = \unpack('n', yield $buffer->bufferRead(2))[1];
-
- \danog\MadelineProto\Logger::log(['Connected to '.$ip.':'.$port.' via socks5']);
-
+ \danog\MadelineProto\Logger::log(['Connected to ' . $ip . ':' . $port . ' via socks5']);
if ($secure) {
yield $this->getSocket()->setupTls();
}
@@ -165,7 +134,6 @@ class SocksProxy implements RawProxyStreamInterface, BufferedProxyStreamInterfac
yield (yield $this->stream->getWriteBuffer(\strlen($header)))->bufferWrite($header);
}
}
-
/**
* Async close.
*
@@ -175,7 +143,6 @@ class SocksProxy implements RawProxyStreamInterface, BufferedProxyStreamInterfac
{
return $this->stream->disconnect();
}
-
/**
* Get write buffer asynchronously.
*
@@ -187,7 +154,6 @@ class SocksProxy implements RawProxyStreamInterface, BufferedProxyStreamInterfac
{
return $this->stream->getWriteBuffer($length, $append);
}
-
/**
* Get read buffer asynchronously.
*
@@ -199,17 +165,14 @@ class SocksProxy implements RawProxyStreamInterface, BufferedProxyStreamInterfac
{
return $this->stream->getReadBuffer($length);
}
-
public function read(): Promise
{
return $this->stream->read();
}
-
public function write(string $data): Promise
{
return $this->stream->write($data);
}
-
/**
* Sets proxy data.
*
@@ -230,7 +193,6 @@ class SocksProxy implements RawProxyStreamInterface, BufferedProxyStreamInterfac
{
return $this->stream;
}
-
/**
* {@inheritdoc}
*
@@ -240,7 +202,6 @@ class SocksProxy implements RawProxyStreamInterface, BufferedProxyStreamInterfac
{
return $this->stream->getSocket();
}
-
public static function getName(): string
{
return __CLASS__;
diff --git a/src/danog/MadelineProto/Stream/ProxyStreamInterface.php b/src/danog/MadelineProto/Stream/ProxyStreamInterface.php
index f948608f..6a90bcdd 100644
--- a/src/danog/MadelineProto/Stream/ProxyStreamInterface.php
+++ b/src/danog/MadelineProto/Stream/ProxyStreamInterface.php
@@ -1,4 +1,5 @@
*/
-class DefaultStream implements
- RawStreamInterface,
- ProxyStreamInterface
+class DefaultStream implements RawStreamInterface, ProxyStreamInterface
{
use RawStream;
/**
@@ -48,44 +46,34 @@ class DefaultStream implements
* @var EncryptableSocket
*/
private $stream;
-
/**
* Connector.
*
* @var Connector
*/
private $connector;
-
public function setupTls(?CancellationToken $cancellationToken = null): \Amp\Promise
{
return $this->stream->setupTls($cancellationToken);
}
-
public function getStream()
{
return $this->stream;
}
-
public function connectGenerator(\danog\MadelineProto\Stream\ConnectionContext $ctx, string $header = ''): \Generator
{
$ctx = $ctx->getCtx();
$uri = $ctx->getUri();
$secure = $ctx->isSecure();
if ($secure) {
- $ctx->setSocketContext(
- $ctx->getSocketContext()->withTlsContext(
- new ClientTlsContext($uri->getHost())
- )
- );
+ $ctx->setSocketContext($ctx->getSocketContext()->withTlsContext(new ClientTlsContext($uri->getHost())));
}
-
$this->stream = yield ($this->connector ?? connector())->connect((string) $uri, $ctx->getSocketContext(), $ctx->getCancellationToken());
if ($secure) {
yield $this->stream->setupTls();
}
yield $this->stream->write($header);
}
-
/**
* Async chunked read.
*
@@ -95,7 +83,6 @@ class DefaultStream implements
{
return $this->stream ? $this->stream->read() : new \Amp\Success(null);
}
-
/**
* Async write.
*
@@ -110,7 +97,6 @@ class DefaultStream implements
}
return $this->stream->write($data);
}
-
/**
* Close.
*
@@ -124,10 +110,9 @@ class DefaultStream implements
$this->stream = null;
}
} catch (\Throwable $e) {
- \danog\MadelineProto\Logger::log('Got exception while closing stream: '.$e->getMessage());
+ \danog\MadelineProto\Logger::log('Got exception while closing stream: ' . $e->getMessage());
}
}
-
/**
* Close.
*
@@ -137,7 +122,6 @@ class DefaultStream implements
{
$this->disconnect();
}
-
/**
* {@inheritdoc}
*
@@ -147,12 +131,10 @@ class DefaultStream implements
{
return $this->stream;
}
-
public function setExtra($extra)
{
$this->connector = $extra;
}
-
public static function getName(): string
{
return __CLASS__;
diff --git a/src/danog/MadelineProto/Stream/Transport/PremadeStream.php b/src/danog/MadelineProto/Stream/Transport/PremadeStream.php
index d1f8ab2a..f6def9c4 100644
--- a/src/danog/MadelineProto/Stream/Transport/PremadeStream.php
+++ b/src/danog/MadelineProto/Stream/Transport/PremadeStream.php
@@ -1,4 +1,5 @@
stream->setupTls($cancellationToken);
}
-
-
public function getStream()
{
return $this->stream;
}
-
public function connectGenerator(ConnectionContext $ctx, string $header = ''): \Generator
{
if ($header !== '') {
yield $this->stream->write($header);
}
}
-
/**
* Async chunked read.
*
@@ -70,7 +65,6 @@ class PremadeStream implements RawStreamInterface, ProxyStreamInterface
{
return $this->stream ? $this->stream->read() : new \Amp\Success(null);
}
-
/**
* Async write.
*
@@ -85,7 +79,6 @@ class PremadeStream implements RawStreamInterface, ProxyStreamInterface
}
return $this->stream->write($data);
}
-
/**
* Async close.
*
@@ -101,15 +94,13 @@ class PremadeStream implements RawStreamInterface, ProxyStreamInterface
$this->stream = null;
}
} catch (\Throwable $e) {
- \danog\MadelineProto\Logger::log('Got exception while closing stream: '.$e->getMessage());
+ \danog\MadelineProto\Logger::log('Got exception while closing stream: ' . $e->getMessage());
}
}
-
public function close()
{
$this->disconnect();
}
-
/**
* {@inheritdoc}
*
@@ -119,7 +110,6 @@ class PremadeStream implements RawStreamInterface, ProxyStreamInterface
{
return $this->stream;
}
-
/**
* {@inheritdoc}
*/
diff --git a/src/danog/MadelineProto/Stream/Transport/WsStream.php b/src/danog/MadelineProto/Stream/Transport/WsStream.php
index f2b64557..32b6d351 100644
--- a/src/danog/MadelineProto/Stream/Transport/WsStream.php
+++ b/src/danog/MadelineProto/Stream/Transport/WsStream.php
@@ -1,4 +1,5 @@
dc = $ctx->getIntDc();
-
$handshake = new Handshake(\str_replace('tcp://', $ctx->isSecure() ? 'wss://' : 'ws://', $ctx->getStringUri()));
-
$this->stream = yield ($this->connector ?? connector())->connect($handshake, $ctx->getCancellationToken());
-
if (\strlen($header)) {
yield $this->write($header);
}
}
-
/**
* Async close.
*/
@@ -91,7 +84,6 @@ class WsStream implements RawStreamInterface, ProxyStreamInterface
} catch (\Throwable $e) {
}
}
-
public function readGenerator(): \Generator
{
try {
@@ -107,12 +99,10 @@ class WsStream implements RawStreamInterface, ProxyStreamInterface
if ($e->getReason() !== 'Client closed the underlying TCP connection') {
throw $e;
}
-
return null;
}
return $data;
}
-
/**
* Async write.
*
@@ -124,7 +114,6 @@ class WsStream implements RawStreamInterface, ProxyStreamInterface
{
return $this->stream->sendBinary($data);
}
-
/**
* {@inheritdoc}
*
@@ -140,7 +129,6 @@ class WsStream implements RawStreamInterface, ProxyStreamInterface
$this->connector = $extra;
}
}
-
public static function getName(): string
{
return __CLASS__;
diff --git a/src/danog/MadelineProto/Stream/Transport/WssStream.php b/src/danog/MadelineProto/Stream/Transport/WssStream.php
index 52fe8657..38475d66 100644
--- a/src/danog/MadelineProto/Stream/Transport/WssStream.php
+++ b/src/danog/MadelineProto/Stream/Transport/WssStream.php
@@ -1,4 +1,5 @@
getCtx()->secure(true), $header);
}
-
public static function getName(): string
{
return __CLASS__;
diff --git a/src/danog/MadelineProto/TL/Conversion/BotAPI.php b/src/danog/MadelineProto/TL/Conversion/BotAPI.php
index d250f428..0377848f 100644
--- a/src/danog/MadelineProto/TL/Conversion/BotAPI.php
+++ b/src/danog/MadelineProto/TL/Conversion/BotAPI.php
@@ -27,7 +27,6 @@ trait BotAPI
{
return \html_entity_decode(\preg_replace('#< *br */? *>#', "\n", $stuff));
}
-
/**
* Get Telegram UTF-8 length of string.
*
@@ -41,14 +40,12 @@ trait BotAPI
$textlength = \strlen($text);
for ($x = 0; $x < $textlength; $x++) {
$char = \ord($text[$x]);
- if (($char & 0xC0) != 0x80) {
+ if (($char & 0xc0) != 0x80) {
$length += 1 + ($char >= 0xf0);
}
}
-
return $length;
}
-
/**
* Telegram UTF-8 multibyte substring.
*
@@ -65,7 +62,7 @@ trait BotAPI
$offset = $mb_text_length + $offset;
}
if ($length < 0) {
- $length = ($mb_text_length - $offset) + $length;
+ $length = $mb_text_length - $offset + $length;
} elseif ($length === null) {
$length = $mb_text_length - $offset;
}
@@ -75,7 +72,7 @@ trait BotAPI
$text_length = \strlen($text);
for ($x = 0; $x < $text_length; $x++) {
$char = \ord($text[$x]);
- if (($char & 0xC0) != 0x80) {
+ if (($char & 0xc0) != 0x80) {
$current_offset += 1 + ($char >= 0xf0);
if ($current_offset > $offset) {
$current_length += 1 + ($char >= 0xf0);
@@ -87,10 +84,8 @@ trait BotAPI
}
}
}
-
return $new_text;
}
-
/**
* Telegram UTF-8 multibyte split.
*
@@ -106,10 +101,8 @@ trait BotAPI
for ($x = 0; $x < $tlength; $x += $length) {
$result[] = \mb_substr($text, $x, $length, 'UTF-8');
}
-
return $result;
}
-
private function parseButtons($rows)
{
$newrows = [];
@@ -145,10 +138,8 @@ trait BotAPI
}
$key++;
}
-
return $newrows;
}
-
private function parseReplyMarkup($markup)
{
if (isset($markup['force_reply']) && $markup['force_reply']) {
@@ -177,10 +168,8 @@ trait BotAPI
$markup['rows'] = $this->parseButtons($markup['inline_keyboard']);
unset($markup['inline_keyboard']);
}
-
return $markup;
}
-
/**
* Convert MTProto parameters to bot API parameters.
*
@@ -194,9 +183,8 @@ trait BotAPI
$newd = [];
if (!isset($data['_'])) {
foreach ($data as $key => $element) {
- $newd[$key] = yield $this->MTProtoToBotAPI($element, $sent_arguments);
+ $newd[$key] = (yield from $this->MTProtoToBotAPI($element, $sent_arguments));
}
-
return $newd;
}
switch ($data['_']) {
@@ -209,16 +197,15 @@ trait BotAPI
}
$newd['chat'] = yield $this->getPwrChat($sent_arguments['peer']);
if (isset($data['entities'])) {
- $newd['entities'] = yield $this->MTProtoToBotAPI($data['entities'], $sent_arguments);
+ $newd['entities'] = (yield from $this->MTProtoToBotAPI($data['entities'], $sent_arguments));
}
if (isset($data['media'])) {
- $newd = \array_merge($newd, yield $this->MTProtoToBotAPI($data['media'], $sent_arguments));
+ $newd = \array_merge($newd, yield from $this->MTProtoToBotAPI($data['media'], $sent_arguments));
}
-
return $newd;
case 'updateNewChannelMessage':
case 'updateNewMessage':
- return yield $this->MTProtoToBotAPI($data['message']);
+ return yield from $this->MTProtoToBotAPI($data['message']);
case 'message':
$newd['message_id'] = $data['id'];
$newd['date'] = $data['date'];
@@ -230,7 +217,7 @@ trait BotAPI
}
$newd['chat'] = yield $this->getPwrChat($data['to_id']);
if (isset($data['entities'])) {
- $newd['entities'] = yield $this->MTProtoToBotAPI($data['entities'], $sent_arguments);
+ $newd['entities'] = (yield from $this->MTProtoToBotAPI($data['entities'], $sent_arguments));
}
if (isset($data['views'])) {
$newd['views'] = $data['views'];
@@ -254,66 +241,54 @@ trait BotAPI
$newd['forward_from_message_id'] = $data['fwd_from']['channel_post'];
}
if (isset($data['media'])) {
- $newd = \array_merge($newd, yield $this->MTProtoToBotAPI($data['media'], $sent_arguments));
+ $newd = \array_merge($newd, yield from $this->MTProtoToBotAPI($data['media'], $sent_arguments));
}
-
return $newd;
case 'messageEntityMention':
unset($data['_']);
$data['type'] = 'mention';
-
return $data;
case 'messageEntityHashtag':
unset($data['_']);
$data['type'] = 'hashtag';
-
return $data;
case 'messageEntityBotCommand':
unset($data['_']);
$data['type'] = 'bot_command';
-
return $data;
case 'messageEntityUrl':
unset($data['_']);
$data['type'] = 'url';
-
return $data;
case 'messageEntityEmail':
unset($data['_']);
$data['type'] = 'email';
-
return $data;
case 'messageEntityBold':
unset($data['_']);
$data['type'] = 'bold';
-
return $data;
case 'messageEntityItalic':
unset($data['_']);
$data['type'] = 'italic';
-
return $data;
case 'messageEntityCode':
unset($data['_']);
$data['type'] = 'code';
-
return $data;
case 'messageEntityPre':
unset($data['_']);
$data['type'] = 'pre';
-
return $data;
case 'messageEntityTextUrl':
unset($data['_']);
$data['type'] = 'text_url';
-
return $data;
case 'messageEntityMentionName':
unset($data['_']);
$data['type'] = 'text_mention';
$data['user'] = yield $this->getPwrChat($data['user_id']);
unset($data['user_id']);
-
return $data;
case 'messageMediaPhoto':
if (isset($data['caption'])) {
@@ -325,7 +300,6 @@ trait BotAPI
$res['photo'][$key] = yield $this->photosizeToBotAPI($photo, $data['photo']);
}
}
-
return $res;
case 'messageMediaEmpty':
return [];
@@ -339,7 +313,7 @@ trait BotAPI
switch ($attribute['_']) {
case 'documentAttributeFilename':
$pathinfo = \pathinfo($attribute['file_name']);
- $res['ext'] = isset($pathinfo['extension']) ? '.'.$pathinfo['extension'] : '';
+ $res['ext'] = isset($pathinfo['extension']) ? '.' . $pathinfo['extension'] : '';
$res['file_name'] = $pathinfo['filename'];
break;
case 'documentAttributeAudio':
@@ -390,30 +364,28 @@ trait BotAPI
if (isset($audio) && isset($audio['title']) && !isset($res['file_name'])) {
$res['file_name'] = $audio['title'];
if (isset($audio['performer'])) {
- $res['file_name'] .= ' - '.$audio['performer'];
+ $res['file_name'] .= ' - ' . $audio['performer'];
}
}
if (!isset($res['file_name'])) {
$res['file_name'] = $data['document']['access_hash'];
}
- $res['file_name'] .= '_'.$data['document']['id'];
+ $res['file_name'] .= '_' . $data['document']['id'];
if (isset($res['ext'])) {
$res['file_name'] .= $res['ext'];
unset($res['ext']);
} else {
$res['file_name'] .= $this->getExtensionFromMime($data['document']['mime_type']);
}
- $data['document']['_'] = 'bot_'.$type_name;
+ $data['document']['_'] = 'bot_' . $type_name;
$res['file_size'] = $data['document']['size'];
$res['mime_type'] = $data['document']['mime_type'];
- $res['file_id'] = \danog\MadelineProto\Tools::base64urlEncode(\danog\MadelineProto\Tools::rleEncode((yield $this->TL->serializeObject(['type' => 'File'], $data['document'], 'File')).\chr(2)));
-
+ $res['file_id'] = \danog\MadelineProto\Tools::base64urlEncode(\danog\MadelineProto\Tools::rleEncode(yield $this->TL->serializeObject(['type' => 'File'], $data['document'], 'File') . \chr(2)));
return [$type_name => $res, 'caption' => isset($data['caption']) ? $data['caption'] : ''];
default:
throw new Exception(\sprintf(\danog\MadelineProto\Lang::$current_lang['botapi_conversion_error'], $data['_']));
}
}
-
/**
* Convert bot API parameters to MTProto parameters.
*
@@ -433,13 +405,11 @@ trait BotAPI
$arguments['reply_markup'] = $this->parseReplyMarkup($arguments['reply_markup']);
}
if (isset($arguments['parse_mode'])) {
- $arguments = yield $this->parseMode($arguments);
+ $arguments = (yield from $this->parseMode($arguments));
}
-
return $arguments;
}
-
- private function parseNode($node, &$entities, &$new_message, &$offset)
+ private function parseNode($node, &$entities, &$new_message, &$offset): \Generator
{
switch ($node->nodeName) {
case 'br':
@@ -450,65 +420,51 @@ trait BotAPI
case 'strike':
case 'del':
$text = $this->htmlEntityDecode($node->textContent);
-
$length = $this->mbStrlen($text);
$entities[] = ['_' => 'messageEntityStrike', 'offset' => $offset, 'length' => $length];
-
$new_message .= $text;
$offset += $length;
break;
case 'u':
$text = $this->htmlEntityDecode($node->textContent);
-
$length = $this->mbStrlen($text);
$entities[] = ['_' => 'messageEntityUnderline', 'offset' => $offset, 'length' => $length];
-
$new_message .= $text;
$offset += $length;
break;
case 'blockquote':
$text = $this->htmlEntityDecode($node->textContent);
-
$length = $this->mbStrlen($text);
$entities[] = ['_' => 'messageEntityBlockquote', 'offset' => $offset, 'length' => $length];
-
$new_message .= $text;
$offset += $length;
break;
case 'b':
case 'strong':
$text = $this->htmlEntityDecode($node->textContent);
-
$length = $this->mbStrlen($text);
$entities[] = ['_' => 'messageEntityBold', 'offset' => $offset, 'length' => $length];
-
$new_message .= $text;
$offset += $length;
break;
case 'i':
case 'em':
$text = $this->htmlEntityDecode($node->textContent);
-
$length = $this->mbStrlen($text);
$entities[] = ['_' => 'messageEntityItalic', 'offset' => $offset, 'length' => $length];
-
$new_message .= $text;
$offset += $length;
break;
case 'code':
$text = $this->htmlEntityDecode($node->textContent);
-
$length = $this->mbStrlen($text);
$entities[] = ['_' => 'messageEntityCode', 'offset' => $offset, 'length' => $length];
-
$new_message .= $text;
$offset += $length;
break;
case 'pre':
$text = $this->htmlEntityDecode($node->textContent);
-
$length = $this->mbStrlen($text);
-
$language = $node->getAttribute('language');
if ($language === null) {
$language = '';
@@ -519,14 +475,14 @@ trait BotAPI
break;
case 'p':
foreach ($node->childNodes as $node) {
- yield $this->parseNode($node, $entities, $new_message, $offset);
+ yield from $this->parseNode($node, $entities, $new_message, $offset);
}
break;
case 'a':
$text = $this->htmlEntityDecode($node->textContent);
$length = $this->mbStrlen($text);
$href = $node->getAttribute('href');
- if (\preg_match('|mention:(.*)|', $href, $matches) || \preg_match('|tg://user\?id=(.*)|', $href, $matches)) {
+ if (\preg_match('|mention:(.*)|', $href, $matches) || \preg_match('|tg://user\\?id=(.*)|', $href, $matches)) {
$mention = yield $this->getInfo($matches[1]);
if (!isset($mention['InputUser'])) {
throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['peer_not_in_db']);
@@ -579,9 +535,7 @@ trait BotAPI
}
if (\stripos($arguments['parse_mode'], 'html') !== false) {
$new_message = '';
-
$arguments['message'] = \trim($this->htmlFixtags($arguments['message']));
-
$dom = new \DOMDocument();
$dom->loadHTML(\mb_convert_encoding($arguments['message'], 'HTML-ENTITIES', 'UTF-8'));
if (!isset($arguments['entities'])) {
@@ -589,7 +543,7 @@ trait BotAPI
}
$offset = 0;
foreach ($dom->getElementsByTagName('body')->item(0)->childNodes as $node) {
- yield $this->parseNode($node, $arguments['entities'], $new_message, $offset);
+ yield from $this->parseNode($node, $arguments['entities'], $new_message, $offset);
}
if (isset($arguments['entities']['buttons'])) {
$arguments['reply_markup'] = $this->buildRows($arguments['entities']['buttons']);
@@ -598,10 +552,8 @@ trait BotAPI
unset($arguments['parse_mode']);
$arguments['message'] = $new_message;
}
-
return $arguments;
}
-
/**
* Split too long message into chunks.
*
@@ -613,15 +565,13 @@ trait BotAPI
*/
public function splitToChunks($args): \Generator
{
- $args = yield $this->parseMode($args);
+ $args = (yield from $this->parseMode($args));
if (!isset($args['entities'])) {
$args['entities'] = [];
}
-
$max_length = isset($args['media']) ? $this->config['caption_length_max'] : $this->config['message_length_max'];
$max_entity_length = 100;
$max_entity_size = 8110;
-
$text_arr = [];
foreach ($this->multipleExplodeKeepDelimiters(["\n"], $args['message']) as $word) {
if (\mb_strlen($word, 'UTF-8') > $max_length) {
@@ -632,12 +582,11 @@ trait BotAPI
$text_arr[] = $word;
}
}
-
$multiple_args_base = \array_merge($args, ['entities' => [], 'parse_mode' => 'text', 'message' => '']);
$multiple_args = [$multiple_args_base];
$i = 0;
foreach ($text_arr as $word) {
- if ($this->mbStrlen($multiple_args[$i]['message'].$word) <= $max_length) {
+ if ($this->mbStrlen($multiple_args[$i]['message'] . $word) <= $max_length) {
$multiple_args[$i]['message'] .= $word;
} else {
$i++;
@@ -645,7 +594,6 @@ trait BotAPI
$multiple_args[$i]['message'] .= $word;
}
}
-
$i = 0;
$offset = 0;
for ($k = 0; $k < \count($args['entities']); $k++) {
@@ -656,19 +604,16 @@ trait BotAPI
$i++;
}
$entity['offset'] -= $offset;
-
if ($entity['offset'] + $entity['length'] > $this->mbStrlen($multiple_args[$i]['message'])) {
$newentity = $entity;
$newentity['length'] = $entity['length'] - ($this->mbStrlen($multiple_args[$i]['message']) - $entity['offset']);
$entity['length'] = $this->mbStrlen($multiple_args[$i]['message']) - $entity['offset'];
-
- $offset += $entity['length']; //$this->mbStrlen($multiple_args[$i]['message']);
+ $offset += $entity['length'];
+ //$this->mbStrlen($multiple_args[$i]['message']);
$newentity['offset'] = $offset;
-
$prev_length = $this->mbStrlen($multiple_args[$i]['message']);
$multiple_args[$i]['message'] = \rtrim($multiple_args[$i]['message']);
$diff = $prev_length - $this->mbStrlen($multiple_args[$i]['message']);
-
if ($diff) {
$entity['length'] -= $diff;
foreach ($args['entities'] as $key => &$eentity) {
@@ -677,11 +622,9 @@ trait BotAPI
}
}
}
-
$multiple_args[$i]['entities'][] = $entity;
$i++;
$entity = $newentity;
-
continue;
}
$prev_length = $this->mbStrlen($multiple_args[$i]['message']);
@@ -715,12 +658,10 @@ trait BotAPI
}
}
if ($total) {
- $this->logger->logger("Too many entities, $total entities will be truncated", Logger::FATAL_ERROR);
+ $this->logger->logger("Too many entities, {$total} entities will be truncated", Logger::FATAL_ERROR);
}
-
return $multiple_args;
}
-
private function multipleExplodeKeepDelimiters($delimiters, $string)
{
$initialArray = \explode(\chr(1), \str_replace($delimiters, \chr(1), $string));
@@ -729,57 +670,47 @@ trait BotAPI
foreach ($initialArray as $item) {
$delimOffset += $this->mbStrlen($item);
//if ($this->mbStrlen($item) > 0) {
- $finalArray[] = $item.($delimOffset < $this->mbStrlen($string) ? $string[$delimOffset] : '');
+ $finalArray[] = $item . ($delimOffset < $this->mbStrlen($string) ? $string[$delimOffset] : '');
//}
$delimOffset++;
}
-
return $finalArray;
}
-
private function htmlFixtags($text)
{
$diff = 0;
- \preg_match_all('#(.*?)(<(\bu\b|\bs\b|\ba\b|\bb\b|\bstrong\b|\bblockquote\b|\bstrike\b|\bdel\b|\bem\b|i|\bcode\b|\bpre\b)[^>]*>)(.*?)([<]\s*/\s*\3[>])#is', $text, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
+ \preg_match_all('#(.*?)(<(\\bu\\b|\\bs\\b|\\ba\\b|\\bb\\b|\\bstrong\\b|\\bblockquote\\b|\\bstrike\\b|\\bdel\\b|\\bem\\b|i|\\bcode\\b|\\bpre\\b)[^>]*>)(.*?)([<]\\s*/\\s*\\3[>])#is', $text, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
if ($matches) {
foreach ($matches as $match) {
if (\trim($match[1][0]) != '') {
$mod = \htmlentities($match[1][0]);
-
$temp = \substr($text, 0, $match[1][1] + $diff);
$temp .= $mod;
$temp .= \substr($text, $match[1][1] + $diff + \strlen($match[1][0]));
-
$diff += \strlen($mod) - \strlen($match[1][0]);
-
$text = $temp;
}
$mod = \htmlentities($match[4][0]);
-
$temp = \substr($text, 0, $match[4][1] + $diff);
$temp .= $mod;
$temp .= \substr($text, $match[4][1] + $diff + \strlen($match[4][0]));
-
$diff += \strlen($mod) - \strlen($match[4][0]);
$text = $temp;
}
$diff = 0;
- \preg_match_all('##is', $text, $matches, PREG_OFFSET_CAPTURE);
+ \preg_match_all('##is', $text, $matches, PREG_OFFSET_CAPTURE);
foreach ($matches[2] as $match) {
$mod = \htmlentities($match[0]);
$temp = \substr($text, 0, $match[1] + $diff);
$temp .= $mod;
$temp .= \substr($text, $match[1] + $diff + \strlen($match[0]));
-
$diff += \strlen($mod) - \strlen($match[0]);
$text = $temp;
}
-
return $text;
}
return \htmlentities($text);
}
-
private function buildRows($button_list)
{
$end = false;
@@ -804,7 +735,6 @@ trait BotAPI
$row = ['_' => 'keyboardButtonRow', 'buttons' => $buttons];
$rows[] = $row;
}
-
return ['_' => 'replyInlineMarkup', 'rows' => $rows];
}
}
diff --git a/src/danog/MadelineProto/TL/Conversion/BotAPIFiles.php b/src/danog/MadelineProto/TL/Conversion/BotAPIFiles.php
index 35e5599f..599821e0 100644
--- a/src/danog/MadelineProto/TL/Conversion/BotAPIFiles.php
+++ b/src/danog/MadelineProto/TL/Conversion/BotAPIFiles.php
@@ -27,24 +27,16 @@ trait BotAPIFiles
{
private function photosizeToBotAPI($photoSize, $photo, $thumbnail = false): \Generator
{
- $ext = '.jpg';//$this->getExtensionFromLocation(['_' => 'inputFileLocation', 'volume_id' => $photoSize['location']['volume_id'], 'local_id' => $photoSize['location']['local_id'], 'secret' => $photoSize['location']['secret'], 'dc_id' => $photoSize['location']['dc_id']], '.jpg');
+ $ext = '.jpg';
+ //$this->getExtensionFromLocation(['_' => 'inputFileLocation', 'volume_id' => $photoSize['location']['volume_id'], 'local_id' => $photoSize['location']['local_id'], 'secret' => $photoSize['location']['secret'], 'dc_id' => $photoSize['location']['dc_id']], '.jpg');
$photoSize['location']['access_hash'] = $photo['access_hash'] ?? 0;
$photoSize['location']['id'] = $photo['id'] ?? 0;
$photoSize['location']['secret'] = $photo['location']['secret'] ?? 0;
$photoSize['location']['dc_id'] = $photo['dc_id'] ?? 0;
$photoSize['location']['_'] = $thumbnail ? 'bot_thumbnail' : 'bot_photo';
- $data = (yield $this->TL->serializeObject(['type' => 'File'], $photoSize['location'], 'File')).\chr(2);
-
- return [
- 'file_id' => \danog\MadelineProto\Tools::base64urlEncode(\danog\MadelineProto\Tools::rleEncode($data)),
- 'width' => $photoSize['w'],
- 'height' => $photoSize['h'],
- 'file_size' => isset($photoSize['size']) ? $photoSize['size'] : \strlen($photoSize['bytes']),
- 'mime_type' => 'image/jpeg',
- 'file_name' => $photoSize['location']['volume_id'].'_'.$photoSize['location']['local_id'].$ext
- ];
+ $data = yield $this->TL->serializeObject(['type' => 'File'], $photoSize['location'], 'File') . \chr(2);
+ return ['file_id' => \danog\MadelineProto\Tools::base64urlEncode(\danog\MadelineProto\Tools::rleEncode($data)), 'width' => $photoSize['w'], 'height' => $photoSize['h'], 'file_size' => isset($photoSize['size']) ? $photoSize['size'] : \strlen($photoSize['bytes']), 'mime_type' => 'image/jpeg', 'file_name' => $photoSize['location']['volume_id'] . '_' . $photoSize['location']['local_id'] . $ext];
}
-
/**
* Unpack bot API file ID.
*
@@ -57,15 +49,14 @@ trait BotAPIFiles
$file_id = Tools::rleDecode(Tools::base64urlDecode($file_id));
$version = \ord($file_id[\strlen($file_id) - 1]);
$subVersion = $version === 4 ? \ord($file_id[\strlen($file_id) - 2]) : 0;
- $this->logger("Got file ID with version $version.$subVersion");
+ $this->logger("Got file ID with version {$version}.{$subVersion}");
if (!\in_array($version, [2, 4])) {
- throw new Exception("Invalid bot API file ID version $version");
+ throw new Exception("Invalid bot API file ID version {$version}");
}
$res = \fopen('php://memory', 'rw+b');
\fwrite($res, $file_id);
\fseek($res, 0);
$file_id = $res;
-
$deserialized = $this->TL->deserialize($file_id);
$res = ['type' => \str_replace('bot_', '', $deserialized['_'])];
if (\in_array($res['type'], ['profile_photo', 'thumbnail', 'photo'])) {
@@ -96,134 +87,64 @@ trait BotAPIFiles
switch ($deserialized['_']) {
case 'bot_profile_photo':
if ($deserialized['dialog_id'] < 0) {
- $res['Chat'] = [
- '_' => $deserialized['dialog_id'] < -1000000000000 ? 'channel' : 'chat',
- 'id' => $deserialized['dialog_id'] < -1000000000000 ? PeerHandler::fromSupergroup($deserialized['dialog_id']) : -$deserialized['dialog_id'],
- 'access_hash' => $deserialized['dialog_access_hash'],
- 'photo' => [
- '_' => 'chatPhoto',
- 'dc_id' => $deserialized['dc_id'],
- $deserialized['photo_size'] => [
- '_' => 'fileLocationToBeDeprecated',
- 'volume_id' => $deserialized['volume_id'],
- 'local_id' => $deserialized['local_id'],
- ]
- ],
- 'min' => true
- ];
+ $res['Chat'] = ['_' => $deserialized['dialog_id'] < -1000000000000 ? 'channel' : 'chat', 'id' => $deserialized['dialog_id'] < -1000000000000 ? PeerHandler::fromSupergroup($deserialized['dialog_id']) : -$deserialized['dialog_id'], 'access_hash' => $deserialized['dialog_access_hash'], 'photo' => ['_' => 'chatPhoto', 'dc_id' => $deserialized['dc_id'], $deserialized['photo_size'] => ['_' => 'fileLocationToBeDeprecated', 'volume_id' => $deserialized['volume_id'], 'local_id' => $deserialized['local_id']]], 'min' => true];
return $res;
}
- $res['User'] = [
- '_' => 'user',
- 'id' => $deserialized['dialog_id'],
- 'access_hash' => $deserialized['dialog_access_hash'],
- 'photo' => [
- '_' => 'userProfilePhoto',
- 'dc_id' => $deserialized['dc_id'],
- 'photo_id' => $deserialized['id'],
- $deserialized['photo_size'] => [
- '_' => 'fileLocationToBeDeprecated',
- 'volume_id' => $deserialized['volume_id'],
- 'local_id' => $deserialized['local_id'],
- ]
- ],
- 'min' => true
- ];
+ $res['User'] = ['_' => 'user', 'id' => $deserialized['dialog_id'], 'access_hash' => $deserialized['dialog_access_hash'], 'photo' => ['_' => 'userProfilePhoto', 'dc_id' => $deserialized['dc_id'], 'photo_id' => $deserialized['id'], $deserialized['photo_size'] => ['_' => 'fileLocationToBeDeprecated', 'volume_id' => $deserialized['volume_id'], 'local_id' => $deserialized['local_id']]], 'min' => true];
return $res;
-
case 'bot_thumbnail':
- $res['InputFileLocation'] = [
- '_' => $deserialized['file_type'] >= 3 ? 'inputDocumentFileLocation' : 'inputPhotoFileLocation',
- 'id' => $deserialized['id'],
- 'access_hash' => $deserialized['access_hash'],
- 'file_reference' => '',
- 'thumb_size' => (string) $deserialized['thumbnail_type']
- ];
- $res['name'] = $deserialized['id'].'_'.$deserialized['thumbnail_type'];
+ $res['InputFileLocation'] = ['_' => $deserialized['file_type'] >= 3 ? 'inputDocumentFileLocation' : 'inputPhotoFileLocation', 'id' => $deserialized['id'], 'access_hash' => $deserialized['access_hash'], 'file_reference' => '', 'thumb_size' => (string) $deserialized['thumbnail_type']];
+ $res['name'] = $deserialized['id'] . '_' . $deserialized['thumbnail_type'];
$res['ext'] = 'jpg';
$res['mime'] = 'image/jpeg';
-
- $res['InputMedia'] = [
- '_' => $deserialized['file_type'] >= 3 ? 'inputMediaDocument' : 'inputMediaPhoto',
- 'id' => [
- '_' => $deserialized['file_type'] >= 3 ? 'inputDocument' : 'inputPhoto',
- 'id' => $deserialized['id'],
- 'access_hash' => $deserialized['access_hash'],
- ]
- ];
+ $res['InputMedia'] = ['_' => $deserialized['file_type'] >= 3 ? 'inputMediaDocument' : 'inputMediaPhoto', 'id' => ['_' => $deserialized['file_type'] >= 3 ? 'inputDocument' : 'inputPhoto', 'id' => $deserialized['id'], 'access_hash' => $deserialized['access_hash']]];
return $res;
-
case 'bot_photo':
if ($deserialized['photosize_source'] === 0) {
$constructor['id'] = $deserialized['id'];
$constructor['access_hash'] = $deserialized['access_hash'];
unset($deserialized['id'], $deserialized['access_hash']);
-
$deserialized['_'] = $deserialized['secret'] ? 'fileLocation' : 'fileLocationToBeDeprecated';
$constructor['sizes'][0] = ['_' => 'photoSize', 'type' => '', 'location' => $deserialized];
$res['MessageMedia'] = ['_' => 'messageMediaPhoto', 'photo' => $constructor, 'caption' => ''];
-
return $res;
}
- $res['MessageMedia'] = [
- '_' => 'photo',
- 'id' => $deserialized['id'],
- 'access_hash' => $deserialized['access_hash'],
- 'sizes' => [
- [
- '_' => 'photoSize',
- 'type' => $deserialized['thumbnail_type'],
- 'location' => [
- '_' => 'fileLocationToBeDeprecated',
- 'local_id' => $deserialized['local_id'],
- 'volume_id' => $deserialized['local_id'],
- ]
- ]
- ],
- 'dc_id' => $deserialized['dc_id']
- ];
+ $res['MessageMedia'] = ['_' => 'photo', 'id' => $deserialized['id'], 'access_hash' => $deserialized['access_hash'], 'sizes' => [['_' => 'photoSize', 'type' => $deserialized['thumbnail_type'], 'location' => ['_' => 'fileLocationToBeDeprecated', 'local_id' => $deserialized['local_id'], 'volume_id' => $deserialized['local_id']]]], 'dc_id' => $deserialized['dc_id']];
return $res;
case 'bot_voice':
unset($deserialized['_']);
$constructor = \array_merge($deserialized, ['_' => 'document', 'mime_type' => '', 'attributes' => [['_' => 'documentAttributeAudio', 'voice' => true]]]);
$res['MessageMedia'] = ['_' => 'messageMediaDocument', 'document' => $constructor, 'caption' => ''];
-
return $res;
case 'bot_video':
unset($deserialized['_']);
$constructor = \array_merge($deserialized, ['_' => 'document', 'mime_type' => '', 'attributes' => [['_' => 'documentAttributeVideo', 'round_message' => false]]]);
$res['MessageMedia'] = ['_' => 'messageMediaDocument', 'document' => $constructor, 'caption' => ''];
-
return $res;
case 'bot_document':
unset($deserialized['_']);
$constructor = \array_merge($deserialized, ['_' => 'document', 'mime_type' => '', 'attributes' => []]);
$res['MessageMedia'] = ['_' => 'messageMediaDocument', 'document' => $constructor, 'caption' => ''];
-
return $res;
case 'bot_sticker':
unset($deserialized['_']);
$constructor = \array_merge($deserialized, ['_' => 'document', 'mime_type' => '', 'attributes' => [['_' => 'documentAttributeSticker']]]);
$res['MessageMedia'] = ['_' => 'messageMediaDocument', 'document' => $constructor, 'caption' => ''];
-
return $res;
case 'bot_audio':
unset($deserialized['_']);
$constructor = \array_merge($deserialized, ['_' => 'document', 'mime_type' => '', 'attributes' => [['_' => 'documentAttributeAudio', 'voice' => false]]]);
$res['MessageMedia'] = ['_' => 'messageMediaDocument', 'document' => $constructor, 'caption' => ''];
-
return $res;
case 'bot_gif':
unset($deserialized['_']);
$constructor = \array_merge($deserialized, ['_' => 'document', 'mime_type' => '', 'attributes' => [['_' => 'documentAttributeAnimated']]]);
$res['MessageMedia'] = ['_' => 'messageMediaDocument', 'document' => $constructor, 'caption' => ''];
-
return $res;
case 'bot_video_note':
unset($deserialized['_']);
$constructor = \array_merge($deserialized, ['_' => 'document', 'mime_type' => '', 'attributes' => [['_' => 'documentAttributeVideo', 'round_message' => true]]]);
$res['MessageMedia'] = ['_' => 'messageMediaDocument', 'document' => $constructor, 'caption' => ''];
-
return $res;
default:
throw new Exception(\sprintf(\danog\MadelineProto\Lang::$current_lang['file_type_invalid'], $type));
diff --git a/src/danog/MadelineProto/TL/Conversion/Exception.php b/src/danog/MadelineProto/TL/Conversion/Exception.php
index b6e47a74..05e6c622 100644
--- a/src/danog/MadelineProto/TL/Conversion/Exception.php
+++ b/src/danog/MadelineProto/TL/Conversion/Exception.php
@@ -22,17 +22,14 @@ namespace danog\MadelineProto\TL\Conversion;
class Exception extends \Exception
{
use \danog\MadelineProto\TL\PrettyException;
-
public function __toString()
{
- $result = \get_class($this).($this->message !== '' ? ': ' : '').$this->message.PHP_EOL.\danog\MadelineProto\Magic::$revision.PHP_EOL.'TL Trace (YOU ABSOLUTELY MUST READ THE TEXT BELOW):'.PHP_EOL.PHP_EOL.$this->getTLTrace().PHP_EOL;
+ $result = \get_class($this) . ($this->message !== '' ? ': ' : '') . $this->message . PHP_EOL . \danog\MadelineProto\Magic::$revision . PHP_EOL . 'TL Trace (YOU ABSOLUTELY MUST READ THE TEXT BELOW):' . PHP_EOL . PHP_EOL . $this->getTLTrace() . PHP_EOL;
if (PHP_SAPI !== 'cli') {
- $result = \str_replace(PHP_EOL, '
'.PHP_EOL, $result);
+ $result = \str_replace(PHP_EOL, '
' . PHP_EOL, $result);
}
-
return $result;
}
-
public function __construct($message, $file = '')
{
parent::__construct($message);
diff --git a/src/danog/MadelineProto/TL/Conversion/Extension.php b/src/danog/MadelineProto/TL/Conversion/Extension.php
index 0b1557a4..998a07d4 100644
--- a/src/danog/MadelineProto/TL/Conversion/Extension.php
+++ b/src/danog/MadelineProto/TL/Conversion/Extension.php
@@ -35,10 +35,8 @@ trait Extension
if (isset(MTProto::ALL_MIMES[$ext])) {
return MTProto::ALL_MIMES[$ext][0];
}
-
return $default;
}
-
/**
* Get extension from mime type.
*
@@ -50,13 +48,11 @@ trait Extension
{
foreach (self::ALL_MIMES as $key => $value) {
if (\array_search($mime, $value) !== false) {
- return '.'.$key;
+ return '.' . $key;
}
}
-
return '';
}
-
/**
* Get extension from file location.
*
@@ -93,7 +89,6 @@ trait Extension
return $default;
}
}
-
/**
* Get mime type of file.
*
@@ -104,10 +99,8 @@ trait Extension
public static function getMimeFromFile(string $file): string
{
$finfo = new \finfo(FILEINFO_MIME_TYPE);
-
return $finfo->file($file);
}
-
/**
* Get mime type from buffer.
*
@@ -118,7 +111,6 @@ trait Extension
public static function getMimeFromBuffer(string $buffer): string
{
$finfo = new \finfo(FILEINFO_MIME_TYPE);
-
return $finfo->buffer($buffer);
}
}
diff --git a/src/danog/MadelineProto/TL/Conversion/TD.php b/src/danog/MadelineProto/TL/Conversion/TD.php
index 1b45b0aa..a26ec164 100644
--- a/src/danog/MadelineProto/TL/Conversion/TD.php
+++ b/src/danog/MadelineProto/TL/Conversion/TD.php
@@ -36,7 +36,6 @@ trait TD
}
if (!isset($params['ID'])) {
\array_walk($params, [$this, 'tdcliToTd']);
-
return $params;
}
foreach ($params as $key => $value) {
@@ -48,10 +47,8 @@ trait TD
}
$params['_'] = \lcfirst($params['ID']);
unset($params['ID']);
-
return $params;
}
-
/**
* Convert TD to MTProto parameters.
*
@@ -81,15 +78,13 @@ trait TD
default:
$newparams[$mtproto[0]] = isset($params[$td]) ? $params[$td] : null;
if (\is_array($newparams[$mtproto[0]])) {
- $newparams[$mtproto[0]] = yield $this->MTProtoToTd($newparams[$mtproto[0]]);
+ $newparams[$mtproto[0]] = (yield from $this->MTProtoToTd($newparams[$mtproto[0]]));
}
}
}
}
-
return $newparams;
}
-
/**
* MTProto to TDCLI params.
*
@@ -99,9 +94,8 @@ trait TD
*/
public function MTProtoToTdcli($params): \Generator
{
- return $this->tdToTdcli(yield $this->MTProtoToTd($params));
+ return $this->tdToTdcli(yield from $this->MTProtoToTd($params));
}
-
/**
* MTProto to TD params.
*
@@ -116,7 +110,6 @@ trait TD
}
if (!isset($params['_'])) {
\array_walk($params, [$this, 'mtprotoToTd']);
-
return $params;
}
$newparams = ['_' => $params['_']];
@@ -144,7 +137,7 @@ trait TD
if (isset($params['fwd_from'])) {
$newparams[$td] = ['_' => 'messageForwardedFromUser'];
if (isset($params['fwd_from']['channel_id'])) {
- $newparams[$td] = ['_' => 'messageForwardedPost', 'chat_id' => '-100'.$params['fwd_from']['channel_id']];
+ $newparams[$td] = ['_' => 'messageForwardedPost', 'chat_id' => '-100' . $params['fwd_from']['channel_id']];
}
$newparams[$td]['date'] = $params['fwd_from']['date'];
if (isset($params['fwd_from']['channel_post'])) {
@@ -167,7 +160,7 @@ trait TD
if ($params['message'] !== '') {
$newparams[$td] = ['_' => 'messageText', 'text' => $params['message']];
if (isset($params['media']['_']) && $params['media']['_'] === 'messageMediaWebPage') {
- $newparams[$td]['web_page'] = yield $this->MTProtoToTd($params['media']['webpage']);
+ $newparams[$td]['web_page'] = (yield from $this->MTProtoToTd($params['media']['webpage']));
}
if (isset($params['entities'])) {
$newparams[$td]['entities'] = $params['entities'];
@@ -183,15 +176,13 @@ trait TD
$newparams[$td] = isset($params[$mtproto[0]]) ? $params[$mtproto[0]] : null;
}
if (\is_array($newparams[$td])) {
- $newparams[$td] = yield $this->MTProtoToTd($newparams[$td]);
+ $newparams[$td] = (yield from $this->MTProtoToTd($newparams[$td]));
}
}
}
}
-
return $newparams;
}
-
/**
* Convert TD parameters to tdcli.
*
@@ -210,12 +201,11 @@ trait TD
$newparams['ID'] = \ucfirst($value);
} else {
if (!\is_numeric($key) && !\preg_match('/_^/', $key)) {
- $key = $key.'_';
+ $key = $key . '_';
}
$newparams[$key] = $this->tdToTdcli($value);
}
}
-
return $newparams;
}
}
diff --git a/src/danog/MadelineProto/TL/Exception.php b/src/danog/MadelineProto/TL/Exception.php
index 137fda80..54b00517 100644
--- a/src/danog/MadelineProto/TL/Exception.php
+++ b/src/danog/MadelineProto/TL/Exception.php
@@ -22,17 +22,14 @@ namespace danog\MadelineProto\TL;
class Exception extends \Exception
{
use PrettyException;
-
public function __toString()
{
- $result = \get_class($this).($this->message !== '' ? ': ' : '').$this->message.PHP_EOL.\danog\MadelineProto\Magic::$revision.PHP_EOL.'TL Trace (YOU ABSOLUTELY MUST READ THE TEXT BELOW):'.PHP_EOL.PHP_EOL.$this->getTLTrace().PHP_EOL;
+ $result = \get_class($this) . ($this->message !== '' ? ': ' : '') . $this->message . PHP_EOL . \danog\MadelineProto\Magic::$revision . PHP_EOL . 'TL Trace (YOU ABSOLUTELY MUST READ THE TEXT BELOW):' . PHP_EOL . PHP_EOL . $this->getTLTrace() . PHP_EOL;
if (PHP_SAPI !== 'cli') {
- $result = \str_replace(PHP_EOL, '
'.PHP_EOL, $result);
+ $result = \str_replace(PHP_EOL, '
' . PHP_EOL, $result);
}
-
return $result;
}
-
public function __construct($message, $file = '')
{
parent::__construct($message);
diff --git a/src/danog/MadelineProto/TL/PrettyException.php b/src/danog/MadelineProto/TL/PrettyException.php
index 9013a84e..0633b4d8 100644
--- a/src/danog/MadelineProto/TL/PrettyException.php
+++ b/src/danog/MadelineProto/TL/PrettyException.php
@@ -30,14 +30,12 @@ trait PrettyException
* @var string
*/
public $tl_trace = '';
-
/**
* Method name.
*
* @var string
*/
private $method = '';
-
/**
* Whether the TL trace was updated.
*
@@ -67,7 +65,6 @@ trait PrettyException
{
return $this->tl_trace;
}
-
/**
* Generate async trace.
*
@@ -81,16 +78,15 @@ trait PrettyException
$this->method = $init;
$previous_trace = $this->tl_trace;
$this->tl_trace = '';
-
$eol = PHP_EOL;
if (PHP_SAPI !== 'cli') {
- $eol = '
'.PHP_EOL;
+ $eol = '
' . PHP_EOL;
}
$tl = false;
foreach (\array_reverse($trace ?? $this->getTrace()) as $k => $frame) {
if (isset($frame['function']) && \in_array($frame['function'], ['serializeParams', 'serializeObject'])) {
if (($frame['args'][2] ?? '') !== '') {
- $this->tl_trace .= $tl ? "['".$frame['args'][2]."']" : "While serializing: \t".$frame['args'][2];
+ $this->tl_trace .= $tl ? "['" . $frame['args'][2] . "']" : "While serializing: \t" . $frame['args'][2];
$tl = true;
}
} else {
@@ -100,20 +96,19 @@ trait PrettyException
if (isset($frame['function']) && ($frame['function'] === 'handle_rpc_error' && $k === \count($this->getTrace()) - 1) || $frame['function'] === 'unserialize') {
continue;
}
- $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['file']) ? \str_pad(\basename($frame['file']) . '(' . $frame['line'] . '):', 20) . "\t" : '';
+ $this->tl_trace .= isset($frame['function']) ? $frame['function'] . '(' : '';
$this->tl_trace .= isset($frame['args']) ? \substr(\json_encode($frame['args']), 1, -1) : '';
$this->tl_trace .= ')';
$this->tl_trace .= $eol;
$tl = false;
}
}
- $this->tl_trace .= $init !== '' ? "['".$init."']" : '';
+ $this->tl_trace .= $init !== '' ? "['" . $init . "']" : '';
$this->tl_trace = \implode($eol, \array_reverse(\explode($eol, $this->tl_trace)));
-
if ($previous_trace) {
- $this->tl_trace .= $eol.$eol;
- $this->tl_trace .= "Previous TL trace:$eol";
+ $this->tl_trace .= $eol . $eol;
+ $this->tl_trace .= "Previous TL trace:{$eol}";
$this->tl_trace .= $previous_trace;
}
}
diff --git a/src/danog/MadelineProto/TL/TL.php b/src/danog/MadelineProto/TL/TL.php
index d268f183..dcb6f1fe 100644
--- a/src/danog/MadelineProto/TL/TL.php
+++ b/src/danog/MadelineProto/TL/TL.php
@@ -83,7 +83,6 @@ class TL
{
$this->API = $API;
}
-
/**
* Get secret chat layer version.
*
@@ -93,7 +92,6 @@ class TL
{
return $this->secretLayer;
}
-
/**
* Get constructors.
*
@@ -105,7 +103,6 @@ class TL
{
return $td ? $this->tdConstructors : $this->constructors;
}
-
/**
* Get methods.
*
@@ -117,7 +114,6 @@ class TL
{
return $td ? $this->tdMethods : $this->methods;
}
-
/**
* Get TL descriptions.
*
@@ -127,7 +123,6 @@ class TL
{
return $this->tdDescriptions;
}
-
/**
* Initialize TL parser.
*
@@ -201,7 +196,7 @@ class TL
$type = 'constructors';
continue;
}
- if (\preg_match('|^===(\d*)===|', $line, $matches)) {
+ if (\preg_match('|^===(\\d*)===|', $line, $matches)) {
$layer = (int) $matches[1];
continue;
}
@@ -211,7 +206,7 @@ class TL
if (\strpos($line, ' ?= ') !== false) {
continue;
}
- $line = \preg_replace(['/[(]([\w\.]+) ([\w\.]+)[)]/', '/\s+/'], ['$1<$2>', ' '], $line);
+ $line = \preg_replace(['/[(]([\\w\\.]+) ([\\w\\.]+)[)]/', '/\\s+/'], ['$1<$2>', ' '], $line);
if (\strpos($line, ';') === false) {
$lineBuf .= $line;
continue;
@@ -220,12 +215,11 @@ class TL
$line = $lineBuf;
$lineBuf = '';
}
-
$name = \preg_replace(['/#.*/', '/\\s.*/'], '', $line);
if (\in_array($name, ['bytes', 'int128', 'int256', 'int512', 'int', 'long', 'double', 'string', 'bytes', 'object', 'function'])) {
/*if (!(\in_array($scheme_type, ['ton_api', 'lite_api']) && $name === 'bytes')) {
- continue;
- }*/
+ continue;
+ }*/
continue;
}
if (\in_array($scheme_type, ['ton_api', 'lite_api'])) {
@@ -233,9 +227,8 @@ class TL
} else {
$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]+#([a-f0-9]*)/i', $line, $matches)) {
+ if (\preg_match('/^[^\\s]+#([a-f0-9]*)/i', $line, $matches)) {
$nid = \str_pad($matches[1], 8, '0', \STR_PAD_LEFT);
if ($id !== $nid && $scheme_type !== 'botAPI') {
$this->API->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['crc32_mismatch'], $id, $nid, $line), \danog\MadelineProto\Logger::ERROR);
@@ -269,7 +262,6 @@ class TL
$TL_dict[$type][$key]['params'][] = ['name' => $explode[0], 'type' => $explode[1]];
}
}
-
$key++;
}
} else {
@@ -280,9 +272,8 @@ class TL
$TL_dict['methods'][$key]['id'] = \danog\MadelineProto\Tools::packSignedInt($TL_dict['methods'][$key]['id']);
}
}
-
if (empty($TL_dict) || empty($TL_dict['constructors']) || !isset($TL_dict['methods'])) {
- throw new Exception(\danog\MadelineProto\Lang::$current_lang['src_file_invalid'].$file);
+ throw new Exception(\danog\MadelineProto\Lang::$current_lang['src_file_invalid'] . $file);
}
$this->API->logger->logger(\danog\MadelineProto\Lang::$current_lang['translating_obj'], \danog\MadelineProto\Logger::ULTRA_VERBOSE);
foreach ($TL_dict['constructors'] as $elem) {
@@ -325,7 +316,6 @@ class TL
}
}
}
-
/**
* Get TL namespaces.
*
@@ -338,10 +328,8 @@ class TL
$a = \key($pair);
$res[$a] = $a;
}
-
return $res;
}
-
/**
* Get namespaced methods (method => namespace).
*
@@ -351,7 +339,6 @@ class TL
{
return $this->methods->method_namespace;
}
-
/**
* Update TL callbacks.
*
@@ -366,14 +353,7 @@ class TL
if (!isset(\class_implements(\get_class($object))[TLCallback::class])) {
throw new Exception('Invalid callback object provided!');
}
- $new = [
- TLCallback::METHOD_BEFORE_CALLBACK => $object->getMethodBeforeCallbacks(),
- TLCallback::METHOD_CALLBACK => $object->getMethodCallbacks(),
- TLCallback::CONSTRUCTOR_BEFORE_CALLBACK => $object->getConstructorBeforeCallbacks(),
- TLCallback::CONSTRUCTOR_CALLBACK => $object->getConstructorCallbacks(),
- TLCallback::CONSTRUCTOR_SERIALIZE_CALLBACK => $object->getConstructorSerializeCallbacks(),
- TLCallback::TYPE_MISMATCH_CALLBACK => $object->getTypeMismatchCallbacks(),
- ];
+ $new = [TLCallback::METHOD_BEFORE_CALLBACK => $object->getMethodBeforeCallbacks(), TLCallback::METHOD_CALLBACK => $object->getMethodCallbacks(), TLCallback::CONSTRUCTOR_BEFORE_CALLBACK => $object->getConstructorBeforeCallbacks(), TLCallback::CONSTRUCTOR_CALLBACK => $object->getConstructorCallbacks(), TLCallback::CONSTRUCTOR_SERIALIZE_CALLBACK => $object->getConstructorSerializeCallbacks(), TLCallback::TYPE_MISMATCH_CALLBACK => $object->getTypeMismatchCallbacks()];
foreach ($new as $type => $values) {
foreach ($values as $match => $callback) {
if (!isset($this->callbacks[$type][$match])) {
@@ -401,10 +381,8 @@ class TL
if ($tl_elem === false) {
throw new Exception(\danog\MadelineProto\Lang::$current_lang['bool_error']);
}
-
return $tl_elem['predicate'] === 'boolTrue';
}
-
/**
* Serialize TL object.
*
@@ -426,13 +404,11 @@ class TL
throw new Exception(\danog\MadelineProto\Lang::$current_lang['not_numeric']);
}
}
-
return \danog\MadelineProto\Tools::packSignedInt($object);
case '#':
if (!\is_numeric($object)) {
throw new Exception(\danog\MadelineProto\Lang::$current_lang['not_numeric']);
}
-
return \danog\MadelineProto\Tools::packUnsignedInt($object);
case 'long':
if (\is_object($object)) {
@@ -447,7 +423,6 @@ class TL
if (!\is_numeric($object)) {
throw new Exception(\danog\MadelineProto\Lang::$current_lang['not_numeric']);
}
-
return \danog\MadelineProto\Tools::packSignedLong($object);
case 'int128':
if (\strlen($object) !== 16) {
@@ -456,7 +431,6 @@ class TL
throw new Exception(\danog\MadelineProto\Lang::$current_lang['long_not_16']);
}
}
-
return (string) $object;
case 'int256':
if (\strlen($object) !== 32) {
@@ -465,7 +439,6 @@ class TL
throw new Exception(\danog\MadelineProto\Lang::$current_lang['long_not_32']);
}
}
-
return (string) $object;
case 'int512':
if (\strlen($object) !== 64) {
@@ -474,7 +447,6 @@ class TL
throw new Exception(\danog\MadelineProto\Lang::$current_lang['long_not_64']);
}
}
-
return (string) $object;
case 'double':
return \danog\MadelineProto\Tools::packDouble($object);
@@ -488,14 +460,13 @@ class TL
if ($l <= 253) {
$concat .= \chr($l);
$concat .= $object;
- $concat .= \pack('@'.\danog\MadelineProto\Tools::posmod(-$l - 1, 4));
+ $concat .= \pack('@' . \danog\MadelineProto\Tools::posmod(-$l - 1, 4));
} else {
$concat .= \chr(254);
$concat .= \substr(\danog\MadelineProto\Tools::packSignedInt($l), 0, 3);
$concat .= $object;
- $concat .= \pack('@'.\danog\MadelineProto\Tools::posmod(-$l, 4));
+ $concat .= \pack('@' . \danog\MadelineProto\Tools::posmod(-$l, 4));
}
-
return $concat;
case 'bytes':
if (\is_array($object) && isset($object['_']) && $object['_'] === 'bytes') {
@@ -509,14 +480,13 @@ class TL
if ($l <= 253) {
$concat .= \chr($l);
$concat .= $object;
- $concat .= \pack('@'.\danog\MadelineProto\Tools::posmod(-$l - 1, 4));
+ $concat .= \pack('@' . \danog\MadelineProto\Tools::posmod(-$l - 1, 4));
} else {
$concat .= \chr(254);
$concat .= \substr(\danog\MadelineProto\Tools::packSignedInt($l), 0, 3);
$concat .= $object;
- $concat .= \pack('@'.\danog\MadelineProto\Tools::posmod(-$l, 4));
+ $concat .= \pack('@' . \danog\MadelineProto\Tools::posmod(-$l, 4));
}
-
return $concat;
case 'Bool':
return $this->constructors->findByPredicate((bool) $object ? 'boolTrue' : 'boolFalse')['id'];
@@ -529,14 +499,13 @@ class TL
throw new Exception(\danog\MadelineProto\Lang::$current_lang['array_invalid']);
}
if (isset($object['_'])) {
- throw new Exception('You must provide an array of '.$type['subtype'].' objects, not a '.$type['subtype']." object. Example: [['_' => ".$type['subtype'].', ... ]]');
+ throw new Exception('You must provide an array of ' . $type['subtype'] . ' objects, not a ' . $type['subtype'] . " object. Example: [['_' => " . $type['subtype'] . ', ... ]]');
}
$concat = $this->constructors->findByPredicate('vector')['id'];
$concat .= \danog\MadelineProto\Tools::packUnsignedInt(\count($object));
foreach ($object as $k => $current_object) {
- $concat .= yield $this->serializeObject(['type' => $type['subtype']], $current_object, $k);
+ $concat .= (yield from $this->serializeObject(['type' => $type['subtype']], $current_object, $k));
}
-
return $concat;
case 'vector':
if (!\is_array($object)) {
@@ -544,9 +513,8 @@ class TL
}
$concat = \danog\MadelineProto\Tools::packUnsignedInt(\count($object));
foreach ($object as $k => $current_object) {
- $concat .= yield $this->serializeObject(['type' => $type['subtype']], $current_object, $k);
+ $concat .= (yield from $this->serializeObject(['type' => $type['subtype']], $current_object, $k));
}
-
return $concat;
case 'Object':
if (\is_string($object)) {
@@ -554,7 +522,6 @@ class TL
}
}
$auto = false;
-
if ($type['type'] === 'InputMessage' && !\is_array($object)) {
$object = ['_' => 'inputMessageID', 'id' => $object];
} elseif (isset($this->callbacks[TLCallback::TYPE_MISMATCH_CALLBACK][$type['type']]) && (!\is_array($object) || isset($object['_']) && $this->constructors->findByPredicate($object['_'])['type'] !== $type['type'])) {
@@ -575,29 +542,25 @@ class TL
if (isset($this->callbacks[TLCallback::CONSTRUCTOR_SERIALIZE_CALLBACK][$object['_']])) {
$object = yield $this->callbacks[TLCallback::CONSTRUCTOR_SERIALIZE_CALLBACK][$object['_']]($object);
}
-
$predicate = $object['_'];
$constructorData = $this->constructors->findByPredicate($predicate, $layer);
if ($constructorData === false) {
$this->API->logger->logger($object, \danog\MadelineProto\Logger::FATAL_ERROR);
-
throw new Exception(\sprintf(\danog\MadelineProto\Lang::$current_lang['type_extract_error'], $predicate));
}
if ($bare = $type['type'] != '' && $type['type'][0] === '%') {
$type['type'] = \substr($type['type'], 1);
}
- if ($predicate === $type['type']) {//} && !$auto) {
+ if ($predicate === $type['type']) {
+ //} && !$auto) {
$bare = true;
}
if ($predicate === 'messageEntityMentionName') {
$constructorData = $this->constructors->findByPredicate('inputMessageEntityMentionName');
}
-
$concat = $bare ? '' : $constructorData['id'];
-
- return $concat.yield $this->serializeParams($constructorData, $object, '', $layer);
+ return $concat . (yield from $this->serializeParams($constructorData, $object, '', $layer));
}
-
/**
* Serialize method.
*
@@ -608,16 +571,16 @@ class TL
*/
public function serializeMethod(string $method, $arguments): \Generator
{
- if ($method === 'messages.importChatInvite' && isset($arguments['hash']) && \is_string($arguments['hash']) && \preg_match('@(?:t|telegram)\.(?:me|dog)/(joinchat/)?([a-z0-9_-]*)@i', $arguments['hash'], $matches)) {
+ if ($method === 'messages.importChatInvite' && isset($arguments['hash']) && \is_string($arguments['hash']) && \preg_match('@(?:t|telegram)\\.(?:me|dog)/(joinchat/)?([a-z0-9_-]*)@i', $arguments['hash'], $matches)) {
if ($matches[1] === '') {
$method = 'channels.joinChannel';
$arguments['channel'] = $matches[2];
} else {
$arguments['hash'] = $matches[2];
}
- } elseif ($method === 'messages.checkChatInvite' && isset($arguments['hash']) && \is_string($arguments['hash']) && \preg_match('@(?:t|telegram)\.(?:me|dog)/joinchat/([a-z0-9_-]*)@i', $arguments['hash'], $matches)) {
+ } elseif ($method === 'messages.checkChatInvite' && isset($arguments['hash']) && \is_string($arguments['hash']) && \preg_match('@(?:t|telegram)\\.(?:me|dog)/joinchat/([a-z0-9_-]*)@i', $arguments['hash'], $matches)) {
$arguments['hash'] = $matches[1];
- } elseif ($method === 'channels.joinChannel' && isset($arguments['channel']) && \is_string($arguments['channel']) && \preg_match('@(?:t|telegram)\.(?:me|dog)/(joinchat/)?([a-z0-9_-]*)@i', $arguments['channel'], $matches)) {
+ } elseif ($method === 'channels.joinChannel' && isset($arguments['channel']) && \is_string($arguments['channel']) && \preg_match('@(?:t|telegram)\\.(?:me|dog)/(joinchat/)?([a-z0-9_-]*)@i', $arguments['channel'], $matches)) {
if ($matches[1] !== '') {
$method = 'messages.importChatInvite';
$arguments['hash'] = $matches[2];
@@ -636,12 +599,7 @@ class TL
}
} elseif ($method === 'messages.sendEncryptedFile') {
if (isset($arguments['file'])) {
- if ((
- !\is_array($arguments['file']) ||
- !(isset($arguments['file']['_']) && $this->constructors->findByPredicate($arguments['file']['_']) === 'InputEncryptedFile')
- ) &&
- $this->API->settings['upload']['allow_automatic_upload']
- ) {
+ if ((!\is_array($arguments['file']) || !(isset($arguments['file']['_']) && $this->constructors->findByPredicate($arguments['file']['_']) === 'InputEncryptedFile')) && $this->API->settings['upload']['allow_automatic_upload']) {
$arguments['file'] = yield $this->API->uploadEncrypted($arguments['file']);
}
if (isset($arguments['file']['key'])) {
@@ -676,15 +634,12 @@ class TL
$method = 'photos.updateProfilePhoto';
}
}
-
$tl = $this->methods->findByMethod($method);
if ($tl === false) {
- throw new Exception(\danog\MadelineProto\Lang::$current_lang['method_not_found'].$method);
+ throw new Exception(\danog\MadelineProto\Lang::$current_lang['method_not_found'] . $method);
}
-
- return $tl['id'].yield $this->serializeParams($tl, $arguments, $method);
+ return $tl['id'] . (yield from $this->serializeParams($tl, $arguments, $method));
}
-
/**
* Serialize parameters.
*
@@ -728,11 +683,11 @@ class TL
continue;
}
if ($current_argument['name'] === 'random_bytes') {
- $serialized .= yield $this->serializeObject(['type' => 'bytes'], \danog\MadelineProto\Tools::random(15 + 4 * \danog\MadelineProto\Tools::randomInt($modulus = 3)), 'random_bytes');
+ $serialized .= (yield from $this->serializeObject(['type' => 'bytes'], \danog\MadelineProto\Tools::random(15 + 4 * \danog\MadelineProto\Tools::randomInt($modulus = 3)), 'random_bytes'));
continue;
}
if ($current_argument['name'] === 'data' && isset($tl['method']) && \in_array($tl['method'], ['messages.sendEncrypted', 'messages.sendEncryptedFile', 'messages.sendEncryptedService']) && isset($arguments['message'])) {
- $serialized .= yield $this->serializeObject($current_argument, yield $this->API->encryptSecretMessage($arguments['peer']['chat_id'], $arguments['message']), 'data');
+ $serialized .= (yield from $this->serializeObject($current_argument, yield $this->API->encryptSecretMessage($arguments['peer']['chat_id'], $arguments['message']), 'data'));
continue;
}
if ($current_argument['name'] === 'random_id') {
@@ -757,7 +712,7 @@ class TL
continue;
}
if ($tl['type'] === 'InputMedia' && $current_argument['name'] === 'mime_type') {
- $serialized .= yield $this->serializeObject($current_argument, $arguments['file']['mime_type'], $current_argument['name'], $layer);
+ $serialized .= (yield from $this->serializeObject($current_argument, $arguments['file']['mime_type'], $current_argument['name'], $layer));
continue;
}
if ($tl['type'] === 'DocumentAttribute' && \in_array($current_argument['name'], ['w', 'h', 'duration'])) {
@@ -768,11 +723,11 @@ class TL
$serialized .= \pack('@4');
continue;
}
- if (($id = $this->constructors->findByPredicate(\lcfirst($current_argument['type']).'Empty', isset($tl['layer']) ? $tl['layer'] : -1)) && $id['type'] === $current_argument['type']) {
+ if (($id = $this->constructors->findByPredicate(\lcfirst($current_argument['type']) . 'Empty', isset($tl['layer']) ? $tl['layer'] : -1)) && $id['type'] === $current_argument['type']) {
$serialized .= $id['id'];
continue;
}
- if (($id = $this->constructors->findByPredicate('input'.$current_argument['type'].'Empty', isset($tl['layer']) ? $tl['layer'] : -1)) && $id['type'] === $current_argument['type']) {
+ if (($id = $this->constructors->findByPredicate('input' . $current_argument['type'] . 'Empty', isset($tl['layer']) ? $tl['layer'] : -1)) && $id['type'] === $current_argument['type']) {
$serialized .= $id['id'];
continue;
}
@@ -781,47 +736,19 @@ class TL
case 'vector':
$arguments[$current_argument['name']] = [];
break;
- /*
- case 'long':
- $serialized .= \danog\MadelineProto\Tools::random(8);
- continue 2;
- case 'int':
- $serialized .= \danog\MadelineProto\Tools::random(4);
- continue 2;
- case 'string':
- case 'bytes':
- $arguments[$current_argument['name']] = '';
- break;
- case 'Bool':
- $arguments[$current_argument['name']] = false;
- break;
- default:
- $arguments[$current_argument['name']] = ['_' => $this->constructors->findByType($current_argument['type'])['predicate']];
- break;*/
}
}
if (\in_array($current_argument['type'], ['DataJSON', '%DataJSON'])) {
$arguments[$current_argument['name']] = ['_' => 'dataJSON', 'data' => \json_encode($arguments[$current_argument['name']])];
}
-
if (isset($current_argument['subtype']) && \in_array($current_argument['subtype'], ['DataJSON', '%DataJSON'])) {
\array_walk($arguments[$current_argument['name']], function (&$arg) {
$arg = ['_' => 'dataJSON', 'data' => \json_encode($arg)];
});
}
-
- if ($current_argument['type'] === 'InputFile'
- && (
- !\is_array($arguments[$current_argument['name']])
- || !(
- isset($arguments[$current_argument['name']]['_'])
- && $this->constructors->findByPredicate($arguments[$current_argument['name']]['_'])['type'] === 'InputFile'
- )
- )
- ) {
+ if ($current_argument['type'] === 'InputFile' && (!\is_array($arguments[$current_argument['name']]) || !(isset($arguments[$current_argument['name']]['_']) && $this->constructors->findByPredicate($arguments[$current_argument['name']]['_'])['type'] === 'InputFile'))) {
$arguments[$current_argument['name']] = yield $this->API->upload($arguments[$current_argument['name']]);
}
-
if ($current_argument['type'] === 'InputEncryptedChat' && (!\is_array($arguments[$current_argument['name']]) || isset($arguments[$current_argument['name']]['_']) && $this->constructors->findByPredicate($arguments[$current_argument['name']]['_'])['type'] !== $current_argument['type'])) {
if (\is_array($arguments[$current_argument['name']])) {
$arguments[$current_argument['name']] = (yield $this->API->getInfo($arguments[$current_argument['name']]))['InputEncryptedChat'];
@@ -833,12 +760,10 @@ class TL
}
}
//$this->API->logger->logger('Serializing '.$current_argument['name'].' of type '.$current_argument['type');
- $serialized .= yield $this->serializeObject($current_argument, $arguments[$current_argument['name']], $current_argument['name'], $layer);
+ $serialized .= (yield from $this->serializeObject($current_argument, $arguments[$current_argument['name']], $current_argument['name'], $layer));
}
-
return $serialized;
}
-
/**
* Get length of TL payload.
*
@@ -858,11 +783,8 @@ class TL
throw new Exception(\danog\MadelineProto\Lang::$current_lang['stream_handle_invalid']);
}
$this->deserialize($stream, $type);
-
return \ftell($stream);
}
-
-
/**
* Deserialize TL object.
*
@@ -892,7 +814,6 @@ class TL
if (isset($type['idstrlong'])) {
return \stream_get_contents($stream, 8);
}
-
return \danog\MadelineProto\Magic::$bigint || isset($type['strlong']) ? \stream_get_contents($stream, 8) : \danog\MadelineProto\Tools::unpackSignedLong(\stream_get_contents($stream, 8));
case 'double':
return \danog\MadelineProto\Tools::unpackDouble(\stream_get_contents($stream, 8));
@@ -909,7 +830,7 @@ class TL
throw new Exception(\danog\MadelineProto\Lang::$current_lang['length_too_big']);
}
if ($l === 254) {
- $long_len = \unpack('V', \stream_get_contents($stream, 3).\chr(0))[1];
+ $long_len = \unpack('V', \stream_get_contents($stream, 3) . \chr(0))[1];
$x = \stream_get_contents($stream, $long_len);
$resto = \danog\MadelineProto\Tools::posmod(-$long_len, 4);
if ($resto > 0) {
@@ -925,14 +846,13 @@ class TL
if (!\is_string($x)) {
throw new Exception(\danog\MadelineProto\Lang::$current_lang['deserialize_not_str']);
}
-
return $type['type'] === 'bytes' ? new Types\Bytes($x) : $x;
case 'Vector t':
$id = \stream_get_contents($stream, 4);
$constructorData = $this->constructors->findById($id);
if ($constructorData === false) {
$constructorData = $this->methods->findById($id);
- $constructorData['predicate'] = 'method_'.$constructorData['method'];
+ $constructorData['predicate'] = 'method_' . $constructorData['method'];
}
if ($constructorData === false) {
throw new Exception(\sprintf(\danog\MadelineProto\Lang::$current_lang['type_extract_error_id'], $type['type'], \bin2hex(\strrev($id))));
@@ -944,9 +864,9 @@ class TL
case 'vector':
break;
default:
- throw new Exception(\danog\MadelineProto\Lang::$current_lang['vector_invalid'].$constructorData['predicate']);
+ throw new Exception(\danog\MadelineProto\Lang::$current_lang['vector_invalid'] . $constructorData['predicate']);
}
- // no break
+ // no break
case 'vector':
$count = \unpack('V', \stream_get_contents($stream, 4))[1];
$result = [];
@@ -954,14 +874,13 @@ class TL
for ($i = 0; $i < $count; $i++) {
$result[] = $this->deserialize($stream, $type);
}
-
return $result;
}
if ($type['type'] != '' && $type['type'][0] === '%') {
$checkType = \substr($type['type'], 1);
$constructorData = $this->constructors->findByType($checkType);
if ($constructorData === false) {
- throw new Exception(\danog\MadelineProto\Lang::$current_lang['constructor_not_found'].$checkType);
+ throw new Exception(\danog\MadelineProto\Lang::$current_lang['constructor_not_found'] . $checkType);
}
} else {
$constructorData = $this->constructors->findByPredicate($type['type']);
@@ -973,12 +892,11 @@ class TL
if ($constructorData === false) {
throw new Exception(\sprintf(\danog\MadelineProto\Lang::$current_lang['type_extract_error_id'], $type['type'], \bin2hex(\strrev($id))));
}
- $constructorData['predicate'] = 'method_'.$constructorData['method'];
+ $constructorData['predicate'] = 'method_' . $constructorData['method'];
}
}
}
//var_dump($constructorData);
-
if ($constructorData['predicate'] === 'gzip_packed') {
if (!isset($type['subtype'])) {
$type['subtype'] = '';
@@ -989,7 +907,6 @@ class TL
$constructorData['connection'] = $type['connection'];
$constructorData['subtype'] = $type['subtype'] ?? '';
$constructorData['type'] = 'vector';
-
return $this->deserialize($stream, $constructorData);
}
if ($constructorData['predicate'] === 'boolTrue') {
@@ -1016,7 +933,7 @@ class TL
$x[$arg['name']] = false;
continue 2;
}
- // no break
+ // no break
default:
if (($x['flags'] & $arg['pow']) === 0) {
continue 2;
@@ -1033,17 +950,12 @@ class TL
$arg['type'] = 'string';
}
if ($x['_'] === 'rpc_result' && $arg['name'] === 'result') {
- if (isset($type['connection']->outgoing_messages[$x['req_msg_id']]['_'])
- && isset($this->callbacks[TLCallback::METHOD_BEFORE_CALLBACK][$type['connection']->outgoing_messages[$x['req_msg_id']]['_']])
- ) {
+ if (isset($type['connection']->outgoing_messages[$x['req_msg_id']]['_']) && isset($this->callbacks[TLCallback::METHOD_BEFORE_CALLBACK][$type['connection']->outgoing_messages[$x['req_msg_id']]['_']])) {
foreach ($this->callbacks[TLCallback::METHOD_BEFORE_CALLBACK][$type['connection']->outgoing_messages[$x['req_msg_id']]['_']] as $callback) {
$callback($type['connection']->outgoing_messages[$x['req_msg_id']]['_']);
}
}
-
- if (isset($type['connection']->outgoing_messages[$x['req_msg_id']]['type'])
- && \stripos($type['connection']->outgoing_messages[$x['req_msg_id']]['type'], '<') !== false
- ) {
+ if (isset($type['connection']->outgoing_messages[$x['req_msg_id']]['type']) && \stripos($type['connection']->outgoing_messages[$x['req_msg_id']]['type'], '<') !== false) {
$arg['subtype'] = \str_replace(['Vector<', '>'], '', $type['connection']->outgoing_messages[$x['req_msg_id']]['type']);
}
}
@@ -1073,26 +985,20 @@ class TL
foreach ($x['value'] as $pair) {
$res[$pair['key']] = $pair['value'];
}
-
return $res;
default:
return $x['value'];
}
}
-
if (isset($this->callbacks[TLCallback::CONSTRUCTOR_CALLBACK][$x['_']])) {
foreach ($this->callbacks[TLCallback::CONSTRUCTOR_CALLBACK][$x['_']] as $callback) {
\danog\MadelineProto\Tools::callFork($callback($x));
}
- } elseif ($x['_'] === 'rpc_result'
- && isset($type['connection']->outgoing_messages[$x['req_msg_id']]['_'])
- && isset($this->callbacks[TLCallback::METHOD_CALLBACK][$type['connection']->outgoing_messages[$x['req_msg_id']]['_']])
- ) {
+ } elseif ($x['_'] === 'rpc_result' && isset($type['connection']->outgoing_messages[$x['req_msg_id']]['_']) && isset($this->callbacks[TLCallback::METHOD_CALLBACK][$type['connection']->outgoing_messages[$x['req_msg_id']]['_']])) {
foreach ($this->callbacks[TLCallback::METHOD_CALLBACK][$type['connection']->outgoing_messages[$x['req_msg_id']]['_']] as $callback) {
$callback($type['connection']->outgoing_messages[$x['req_msg_id']], $x['result']);
}
}
-
if ($x['_'] === 'message' && isset($x['reply_markup']['rows'])) {
foreach ($x['reply_markup']['rows'] as $key => $row) {
foreach ($row['buttons'] as $bkey => $button) {
@@ -1100,7 +1006,6 @@ class TL
}
}
}
-
return $x;
}
}
diff --git a/src/danog/MadelineProto/TL/TLCallback.php b/src/danog/MadelineProto/TL/TLCallback.php
index 1102ad8f..a8c3f50a 100644
--- a/src/danog/MadelineProto/TL/TLCallback.php
+++ b/src/danog/MadelineProto/TL/TLCallback.php
@@ -1,4 +1,5 @@
by_id[$json_dict['id']]) && (!isset($this->by_id[$json_dict['id']]['layer']) || $this->by_id[$json_dict['id']]['layer'] > $json_dict['layer'])) {
return false;
}
-
- $predicate = (string) (($scheme_type === 'mtproto' && $json_dict['predicate'] === 'message' ? 'MT' : '').$json_dict['predicate']);
-
- $this->by_id[$json_dict['id']] = ['predicate' => $predicate, 'params' => $json_dict['params'], 'type' => ($scheme_type === 'mtproto' && $json_dict['type'] === 'Message' ? 'MT' : '').$json_dict['type']];
+ $predicate = (string) (($scheme_type === 'mtproto' && $json_dict['predicate'] === 'message' ? 'MT' : '') . $json_dict['predicate']);
+ $this->by_id[$json_dict['id']] = ['predicate' => $predicate, 'params' => $json_dict['params'], 'type' => ($scheme_type === 'mtproto' && $json_dict['type'] === 'Message' ? 'MT' : '') . $json_dict['type']];
if ($scheme_type === 'secret') {
$this->by_id[$json_dict['id']]['layer'] = $json_dict['layer'];
$this->layers[$json_dict['layer']] = $json_dict['layer'];
@@ -49,33 +45,29 @@ class TLConstructors
} else {
$json_dict['layer'] = '';
}
- $this->by_predicate_and_layer[$predicate.$json_dict['layer']] = $json_dict['id'];
+ $this->by_predicate_and_layer[$predicate . $json_dict['layer']] = $json_dict['id'];
$this->parseParams($json_dict['id'], $scheme_type === 'mtproto');
}
-
public function findByType($type)
{
foreach ($this->by_id as $id => $constructor) {
if ($constructor['type'] === $type) {
$constructor['id'] = $id;
-
return $constructor;
}
}
-
return false;
}
-
public function findByPredicate($predicate, $layer = -1)
{
if ($layer !== -1) {
foreach ($this->layers as $alayer) {
if ($alayer <= $layer) {
- if (isset($this->by_predicate_and_layer[$predicate.$alayer])) {
- $chosenid = $this->by_predicate_and_layer[$predicate.$alayer];
+ if (isset($this->by_predicate_and_layer[$predicate . $alayer])) {
+ $chosenid = $this->by_predicate_and_layer[$predicate . $alayer];
}
} elseif (!isset($chosenid)) {
- $chosenid = $this->by_predicate_and_layer[$predicate.$alayer];
+ $chosenid = $this->by_predicate_and_layer[$predicate . $alayer];
}
}
if (!isset($chosenid)) {
@@ -83,19 +75,15 @@ class TLConstructors
}
$constructor = $this->by_id[$chosenid];
$constructor['id'] = $chosenid;
-
return $constructor;
}
if (isset($this->by_predicate_and_layer[$predicate])) {
$constructor = $this->by_id[$this->by_predicate_and_layer[$predicate]];
$constructor['id'] = $this->by_predicate_and_layer[$predicate];
-
return $constructor;
}
-
return false;
}
-
/**
* Find constructor by ID.
*
@@ -108,10 +96,8 @@ class TLConstructors
if (isset($this->by_id[$id])) {
$constructor = $this->by_id[$id];
$constructor['id'] = $id;
-
return $constructor;
}
-
return false;
}
}
diff --git a/src/danog/MadelineProto/TL/TLMethods.php b/src/danog/MadelineProto/TL/TLMethods.php
index 84eeb23a..cbfe12b6 100644
--- a/src/danog/MadelineProto/TL/TLMethods.php
+++ b/src/danog/MadelineProto/TL/TLMethods.php
@@ -27,12 +27,10 @@ class TLMethods
public $by_id = [];
public $by_method = [];
public $method_namespace = [];
-
public function __sleep()
{
return ['by_id', 'by_method', 'method_namespace'];
}
-
public function add($json_dict)
{
$this->by_id[$json_dict['id']] = ['method' => $json_dict['method'], 'type' => $json_dict['type'], 'params' => $json_dict['params']];
@@ -43,28 +41,22 @@ class TLMethods
}
$this->parseParams($json_dict['id']);
}
-
public function findById($id)
{
if (isset($this->by_id[$id])) {
$method = $this->by_id[$id];
$method['id'] = $id;
-
return $method;
}
-
return false;
}
-
public function findByMethod($method_name)
{
if (isset($this->by_method[$method_name])) {
$method = $this->by_id[$this->by_method[$method_name]];
$method['id'] = $this->by_method[$method_name];
-
return $method;
}
-
return false;
}
}
diff --git a/src/danog/MadelineProto/TL/TLParams.php b/src/danog/MadelineProto/TL/TLParams.php
index a6100eb1..ce2a353e 100644
--- a/src/danog/MadelineProto/TL/TLParams.php
+++ b/src/danog/MadelineProto/TL/TLParams.php
@@ -24,17 +24,17 @@ trait TLParams
public function parseParams($key, $mtproto = false)
{
foreach ($this->by_id[$key]['params'] as $kkey => $param) {
- if (\preg_match('/(\w*)\.(\d*)\?(.*)/', $param['type'], $matches)) {
+ if (\preg_match('/(\\w*)\\.(\\d*)\\?(.*)/', $param['type'], $matches)) {
$param['pow'] = \pow(2, $matches[2]);
$param['type'] = $matches[3];
}
- if (\preg_match('/^(v|V)ector\<(.*)\>$/', $param['type'], $matches)) {
+ if (\preg_match('/^(v|V)ector\\<(.*)\\>$/', $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' ? 'MT' : '') . $param['subtype'];
$param['subtype'] = $mtproto && $param['subtype'] === '%Message' ? '%MTMessage' : $param['subtype'];
}
- $param['type'] = ($mtproto && $param['type'] === 'Message' ? 'MT' : '').$param['type'];
+ $param['type'] = ($mtproto && $param['type'] === 'Message' ? 'MT' : '') . $param['type'];
$param['type'] = $mtproto && $param['type'] === '%Message' ? '%MTMessage' : $param['type'];
$this->by_id[$key]['params'][$kkey] = $param;
}
diff --git a/src/danog/MadelineProto/TL/Types/Button.php b/src/danog/MadelineProto/TL/Types/Button.php
index 6e609d37..1e13caba 100644
--- a/src/danog/MadelineProto/TL/Types/Button.php
+++ b/src/danog/MadelineProto/TL/Types/Button.php
@@ -25,7 +25,6 @@ class Button implements \JsonSerializable, \ArrayAccess
use \danog\MadelineProto\Tools;
private $info = [];
private $data = [];
-
public function __magic_construct($API, $message, $button)
{
$this->data = $button;
@@ -33,12 +32,10 @@ class Button implements \JsonSerializable, \ArrayAccess
$this->info['id'] = $message['id'];
$this->info['API'] = $API;
}
-
public function __sleep()
{
return ['data', 'info'];
}
-
public function click($donotwait = false, $params = [])
{
if (\is_array($donotwait)) {
@@ -56,26 +53,22 @@ class Button implements \JsonSerializable, \ArrayAccess
$res = $this->info['API']->methodCallAsyncRead('messages.sendMessage', ['peer' => $this->info['peer'], 'message' => $this->data['text'], 'reply_to_msg_id' => $this->info['id']], ['datacenter' => $this->info['API']->datacenter->curdc]);
break;
case 'keyboardButtonCallback':
- $res = $this->info['API']->$method('messages.getBotCallbackAnswer', ['peer' => $this->info['peer'], 'msg_id' => $this->info['id'], 'data' => $this->data['data']], ['datacenter' => $this->info['API']->datacenter->curdc]);
+ $res = $this->info['API']->{$method}('messages.getBotCallbackAnswer', ['peer' => $this->info['peer'], 'msg_id' => $this->info['id'], 'data' => $this->data['data']], ['datacenter' => $this->info['API']->datacenter->curdc]);
break;
case 'keyboardButtonGame':
- $res = $this->info['API']->$method('messages.getBotCallbackAnswer', ['peer' => $this->info['peer'], 'msg_id' => $this->info['id'], 'game' => true], ['datacenter' => $this->info['API']->datacenter->curdc]);
+ $res = $this->info['API']->{$method}('messages.getBotCallbackAnswer', ['peer' => $this->info['peer'], 'msg_id' => $this->info['id'], 'game' => true], ['datacenter' => $this->info['API']->datacenter->curdc]);
break;
}
-
return $async ? $res : \danog\MadelineProto\Tools::wait($res);
}
-
public function __debugInfo()
{
return ['data' => $this->data, 'info' => ['peer' => $this->info['peer'], 'id' => $this->info['id']]];
}
-
public function jsonSerialize()
{
return (array) $this->data;
}
-
public function offsetSet($name, $value)
{
if ($name === null) {
@@ -84,17 +77,14 @@ class Button implements \JsonSerializable, \ArrayAccess
$this->data[$name] = $value;
}
}
-
public function offsetGet($name)
{
return $this->data[$name];
}
-
public function offsetUnset($name)
{
unset($this->data[$name]);
}
-
public function offsetExists($name)
{
return isset($this->data[$name]);
diff --git a/src/danog/MadelineProto/TL/Types/Bytes.php b/src/danog/MadelineProto/TL/Types/Bytes.php
index 658bd4c7..282ce4c6 100644
--- a/src/danog/MadelineProto/TL/Types/Bytes.php
+++ b/src/danog/MadelineProto/TL/Types/Bytes.php
@@ -23,27 +23,22 @@ class Bytes implements \JsonSerializable, \ArrayAccess
{
use \danog\Serializable;
private $bytes = [];
-
public function __magic_construct($bytes)
{
$this->bytes = $bytes;
}
-
public function __sleep()
{
return ['bytes'];
}
-
public function __toString()
{
return $this->bytes;
}
-
public function jsonSerialize()
{
return ['_' => 'bytes', 'bytes' => \base64_encode($this->bytes)];
}
-
public function offsetSet($name, $value)
{
if ($name === null) {
@@ -52,17 +47,14 @@ class Bytes implements \JsonSerializable, \ArrayAccess
$this->bytes[$name] = $value;
}
}
-
public function offsetGet($name)
{
return $this->bytes[$name];
}
-
public function offsetUnset($name)
{
unset($this->bytes[$name]);
}
-
public function offsetExists($name)
{
return isset($this->bytes[$name]);
diff --git a/src/danog/MadelineProto/TON/ADNLConnection.php b/src/danog/MadelineProto/TON/ADNLConnection.php
index f18a3ead..e5b48070 100644
--- a/src/danog/MadelineProto/TON/ADNLConnection.php
+++ b/src/danog/MadelineProto/TON/ADNLConnection.php
@@ -83,38 +83,23 @@ class ADNLConnection
if ($endpoint['id']['_'] !== 'pub.ed25519') {
throw new \InvalidArgumentException('Only ECDH is supported at the moment!');
}
-
$random = Tools::random(256 - 32 - 64);
//$random = strrev(hex2bin(strrev('9E7C27765D12CE634414F0875D55CE5C58E7A9D58CD45C57CAB516D1241B7864691E5B0AFC4ECB54BFF2CEFC2060F1D45F5B5DEB76A9EF6471D75816AAAEC83CD7DE39EE99B9E980B6C0D4565A916D00908613E63657D5539118F89A14FD73ABB8ECD3AC26C287EEBD0FA44F52B315F01DD60F486EFF4C5B4D71EA6F443358FF141E7294BBBB5D7C079F16BD46C28A12507E1948722E7121B94C3B5C7832ADE7')));
$s1 = \substr($random, 0, 32);
$s2 = \substr($random, 32, 32);
$v1 = \substr($random, 64, 16);
$v2 = \substr($random, 80, 16);
-
- $obf = [
- 'decrypt' => [
- 'key' => $s1,
- 'iv' => $v1
- ],
- 'encrypt' => [
- 'key' => $s2,
- 'iv' => $v2
- ],
- ];
+ $obf = ['decrypt' => ['key' => $s1, 'iv' => $v1], 'encrypt' => ['key' => $s2, 'iv' => $v2]];
// Generating new private/public params
$private = EC::createKey('Ed25519');
-
$public = $private->getPublicKey();
$public = \strrev(Tools::getVar($public, 'QA')[1]->toBytes());
-
$private = \strrev(Tools::getVar($private, 'dA')->toBytes());
$private = PrivateKey::loadFormat('MontgomeryPrivate', $private);
-
// Transpose their public
$key = $endpoint['id']['key'];
$key[31] = $key[31] & \chr(127);
-
- $curve = new Curve25519;
+ $curve = new Curve25519();
$modulo = Tools::getVar($curve, "modulo");
$y = new BigInteger(\strrev($key), 256);
$y2 = clone $y;
@@ -122,41 +107,25 @@ class ADNLConnection
$y2 = $y2->subtract(Magic::$one);
$y2 = $modulo->subtract($y2)->powMod(Magic::$one, $modulo);
$y2 = $y2->modInverse($modulo);
-
$key = \strrev($y->multiply($y2)->powMod(Magic::$one, $modulo)->toBytes());
$peerPublic = PublicKey::loadFormat('MontgomeryPublic', $key);
-
// Generate secret
$secret = DH::computeSecret($private, $peerPublic);
-
// Encrypting random with obf keys
$digest = \hash('sha256', $random, true);
-
- $key = \substr($secret, 0, 16).\substr($digest, 16, 16);
- $iv = \substr($digest, 0, 4).\substr($secret, 20, 12);
-
+ $key = \substr($secret, 0, 16) . \substr($digest, 16, 16);
+ $iv = \substr($digest, 0, 4) . \substr($secret, 20, 12);
$encryptedRandom = Crypt::ctrEncrypt($random, $key, $iv);
-
// Generating plaintext init payload
$payload = \hash('sha256', yield $this->TL->serializeObject(['type' => ''], $endpoint['id'], 'key'), true);
$payload .= $public;
$payload .= $digest;
$payload .= $encryptedRandom;
-
$ip = \long2ip(\unpack('V', Tools::packSignedInt($endpoint['ip']))[1]);
$port = $endpoint['port'];
- $ctx = (new ConnectionContext())
- ->setSocketContext(new ConnectContext)
- ->setUri("tcp://$ip:$port")
- ->addStream(DefaultStream::getName())
- ->addStream(BufferedRawStream::getName())
- ->addStream(CtrStream::getName(), $obf)
- ->addStream(HashedBufferedStream::getName(), 'sha256')
- ->addStream(ADNLStream::getName());
-
+ $ctx = (new ConnectionContext())->setSocketContext(new ConnectContext())->setUri("tcp://{$ip}:{$port}")->addStream(DefaultStream::getName())->addStream(BufferedRawStream::getName())->addStream(CtrStream::getName(), $obf)->addStream(HashedBufferedStream::getName(), 'sha256')->addStream(ADNLStream::getName());
$this->stream = yield $ctx->getStream($payload);
-
- Tools::callFork((function () {
+ Tools::callFork((function (): \Generator {
//yield Tools::sleep(1);
while (true) {
$buffer = yield $this->stream->getReadBuffer($length);
@@ -164,14 +133,13 @@ class ADNLConnection
$data = yield $buffer->bufferRead($length);
$data = yield $this->TL->deserialize($data);
if ($data['_'] !== 'adnl.message.answer') {
- throw new Exception('Wrong answer type: '.$data['_']);
+ throw new Exception('Wrong answer type: ' . $data['_']);
}
$this->requests[$data['query_id']]->resolve(yield $this->TL->deserialize((string) $data['answer']));
}
}
})());
}
-
/**
* Send ADNL query.
*
@@ -181,18 +149,9 @@ class ADNLConnection
*/
public function query(string $payload): \Generator
{
- $data = yield $this->TL->serializeObject(
- ['type' => ''],
- [
- '_' => 'adnl.message.query',
- 'query_id' => $id = Tools::random(32),
- 'query' => $payload
- ],
- ''
- );
+ $data = yield $this->TL->serializeObject(['type' => ''], ['_' => 'adnl.message.query', 'query_id' => $id = Tools::random(32), 'query' => $payload], '');
(yield $this->stream->getWriteBuffer(\strlen($data)))->bufferWrite($data);
- $this->requests[$id] = new Deferred;
-
+ $this->requests[$id] = new Deferred();
return $this->requests[$id]->promise();
}
}
diff --git a/src/danog/MadelineProto/TON/API.php b/src/danog/MadelineProto/TON/API.php
index 5b277ec9..c7694302 100644
--- a/src/danog/MadelineProto/TON/API.php
+++ b/src/danog/MadelineProto/TON/API.php
@@ -34,7 +34,6 @@ class API extends InternalDoc
public function __construct(array $settings)
{
Magic::classExists();
-
$this->API = new Lite($settings);
foreach (\get_class_methods($this->API) as $method) {
$this->methods[$method] = [$this->API, \strtolower($method)];
diff --git a/src/danog/MadelineProto/TON/APIFactory.php b/src/danog/MadelineProto/TON/APIFactory.php
index 34a18525..544fc4be 100644
--- a/src/danog/MadelineProto/TON/APIFactory.php
+++ b/src/danog/MadelineProto/TON/APIFactory.php
@@ -77,7 +77,6 @@ class APIFactory extends AbstractAPIFactory
* @var liteServer
*/
public $liteServer;
-
/**
* Just proxy async requests to API.
*
@@ -90,11 +89,10 @@ class APIFactory extends AbstractAPIFactory
{
$lower_name = \strtolower($name);
if ($this->namespace !== '' || !isset($this->methods[$lower_name])) {
- $name = $this->namespace.$name;
+ $name = $this->namespace . $name;
$aargs = isset($arguments[1]) && \is_array($arguments[1]) ? $arguments[1] : [];
$aargs['apifactory'] = true;
$args = isset($arguments[0]) && \is_array($arguments[0]) ? $arguments[0] : [];
-
return yield $this->API->methodCall($name, $args, $aargs);
}
return yield $this->methods[$lower_name](...$arguments);
diff --git a/src/danog/MadelineProto/TON/Lite.php b/src/danog/MadelineProto/TON/Lite.php
index 82c0f6ae..63df6ff4 100644
--- a/src/danog/MadelineProto/TON/Lite.php
+++ b/src/danog/MadelineProto/TON/Lite.php
@@ -22,7 +22,6 @@ namespace danog\MadelineProto\TON;
use danog\MadelineProto\Logger;
use danog\MadelineProto\TL\TL;
use danog\MadelineProto\Tools;
-
use function Amp\File\get;
/**
@@ -70,12 +69,7 @@ class Lite
$this->settings = $settings;
$this->logger = Logger::getLoggerFromSettings($this->settings);
$this->TL = new TL($this);
- $this->TL->init(
- [
- 'lite_api' => __DIR__.'/schemes/lite_api.tl',
- 'ton_api' => __DIR__.'/schemes/ton_api.tl',
- ]
- );
+ $this->TL->init(['lite_api' => __DIR__ . '/schemes/lite_api.tl', 'ton_api' => __DIR__ . '/schemes/ton_api.tl']);
}
/**
* Connect to the lite endpoints specified in the config file.
@@ -90,18 +84,10 @@ class Lite
$config['_'] = 'liteclient.config.global';
$config = Tools::convertJsonTL($config);
$config['validator']['init_block'] = $config['validator']['init_block'] ?? $config['validator']['zero_state'];
-
- $this->config = yield $this->TL->deserialize(
- yield $this->TL->serializeObject(
- ['type' => ''],
- $config,
- 'cleanup'
- )
- );
-
+ $this->config = yield $this->TL->deserialize(yield $this->TL->serializeObject(['type' => ''], $config, 'cleanup'));
foreach ($this->config['liteservers'] as $lite) {
$this->connections[] = $connection = new ADNLConnection($this->TL);
- yield $connection->connect($lite);
+ yield from $connection->connect($lite);
}
}
/**
@@ -118,11 +104,8 @@ class Lite
if ($file === null) {
$file = \basename(\debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1)[0]['file'], '.php');
}
-
isset($this->logger) ? $this->logger->logger($param, $level, $file) : Logger::$default->logger($param, $level, $file);
}
-
-
/**
* Call lite method.
*
@@ -137,7 +120,6 @@ class Lite
$data = yield $this->TL->serializeMethod('liteServer.query', ['data' => $data]);
return yield $this->connections[\rand(0, \count($this->connections) - 1)]->query($data);
}
-
/**
* Asynchronously run async callable.
*
@@ -149,7 +131,6 @@ class Lite
{
return yield $func();
}
-
/**
* Convert parameters.
*
@@ -161,7 +142,6 @@ class Lite
{
return $parameters;
}
-
/**
* Get TL method namespaces.
*
diff --git a/src/danog/MadelineProto/Tools.php b/src/danog/MadelineProto/Tools.php
index 42069c83..45e1575e 100644
--- a/src/danog/MadelineProto/Tools.php
+++ b/src/danog/MadelineProto/Tools.php
@@ -1,4 +1,5 @@
logger) ? $zis->logger : Logger::$default;
if ($file) {
- $file = " started @ $file";
+ $file = " started @ {$file}";
}
if ($logger) {
- $logger->logger("Got the following exception within a forked strand$file, trying to rethrow");
+ $logger->logger("Got the following exception within a forked strand{$file}, trying to rethrow");
}
-
if ($e->getMessage() === "Cannot get return value of a generator that hasn't returned") {
$logger->logger("Well you know, this might actually not be the actual exception, scroll up in the logs to see the actual exception");
if (!$zis || !$zis->destructing) {
@@ -515,11 +471,9 @@ trait Tools
if ($logger) {
$logger->logger($e);
}
-
Promise\rethrow(new Failure($e));
}
}
-
/**
* Call promise $b after promise $a.
*
@@ -554,7 +508,6 @@ trait Tools
$deferred->resolve($res);
});
});
-
return $deferred->promise();
}
/**
@@ -573,7 +526,6 @@ trait Tools
\http_response_code($status);
return self::echo($message);
}
-
/**
* Asynchronously lock a file
* Resolves with a callbable that MUST eventually be called in order to release the lock.
@@ -581,7 +533,7 @@ trait Tools
* @param string $file File to lock
* @param integer $operation Locking mode
* @param float $polling Polling interval
- *
+ *
* @return Promise
*/
public static function flock(string $file, int $operation, float $polling = 0.1): Promise
@@ -613,7 +565,6 @@ trait Tools
yield self::sleep($polling);
}
} while (!$result);
-
return static function () use (&$res) {
if ($res) {
\flock($res, LOCK_UN);
@@ -633,7 +584,6 @@ trait Tools
{
return new \Amp\Delayed($time * 1000);
}
-
/**
* Asynchronously read line.
*
@@ -669,7 +619,6 @@ trait Tools
}
return \array_shift($lines);
}
-
/**
* Asynchronously write to stdout/browser.
*
@@ -690,12 +639,8 @@ trait Tools
*/
public static function isArrayOrAlike($var): bool
{
- return \is_array($var) ||
- ($var instanceof \ArrayAccess &&
- $var instanceof \Traversable &&
- $var instanceof \Countable);
+ return \is_array($var) || $var instanceof \ArrayAccess && $var instanceof \Traversable && $var instanceof \Countable;
}
-
/**
* Convert to camelCase.
*
@@ -721,10 +666,8 @@ trait Tools
foreach ($ret as &$match) {
$match = $match == \strtoupper($match) ? \strtolower($match) : \lcfirst($match);
}
-
return \implode('_', $ret);
}
-
/**
* Create array.
*
@@ -758,7 +701,6 @@ trait Tools
{
return \rtrim(\strtr(\base64_encode($data), '+/', '-_'), '=');
}
-
/**
* null-byte RLE decode.
*
@@ -780,11 +722,9 @@ trait Tools
$last = $cur;
}
}
- $string = $new.$last;
-
+ $string = $new . $last;
return $string;
}
-
/**
* null-byte RLE encode.
*
@@ -802,16 +742,14 @@ trait Tools
$count++;
} else {
if ($count > 0) {
- $new .= $null.\chr($count);
+ $new .= $null . \chr($count);
$count = 0;
}
$new .= $cur;
}
}
-
return $new;
}
-
/**
* Get final element of array.
*
@@ -823,7 +761,6 @@ trait Tools
{
return \end($what);
}
-
/**
* Escape string for markdown.
*
@@ -835,7 +772,6 @@ trait Tools
{
return \str_replace('_', '\\_', $hwat);
}
-
/**
* Whether this is altervista.
*
@@ -845,8 +781,6 @@ trait Tools
{
return Magic::$altervista;
}
-
-
/**
* Accesses a private variable from an object.
*
diff --git a/src/danog/MadelineProto/VoIP/AuthKeyHandler.php b/src/danog/MadelineProto/VoIP/AuthKeyHandler.php
index 04cca6b3..3201d6d7 100644
--- a/src/danog/MadelineProto/VoIP/AuthKeyHandler.php
+++ b/src/danog/MadelineProto/VoIP/AuthKeyHandler.php
@@ -28,7 +28,6 @@ namespace danog\MadelineProto\VoIP;
trait AuthKeyHandler
{
private $calls = [];
-
/**
* Request call (synchronous).
*
@@ -42,7 +41,6 @@ trait AuthKeyHandler
{
return \danog\MadelineProto\Tools::wait($this->requestCallAsync($user));
}
-
/**
* Accept call (synchronous).
*
@@ -56,7 +54,6 @@ trait AuthKeyHandler
{
return \danog\MadelineProto\Tools::wait($this->acceptCallAsync($user));
}
-
/**
* Discard call (synchronous).
*
@@ -71,7 +68,6 @@ trait AuthKeyHandler
{
\danog\MadelineProto\Tools::wait($this->discardCallAsync($call, $reason, $rating, $need_debug));
}
-
/**
* Request VoIP call.
*
@@ -102,10 +98,8 @@ trait AuthKeyHandler
$controller->setCall($res['phone_call']);
$this->calls[$res['phone_call']['id']] = $controller;
yield $this->updaters[false]->resume();
-
return $controller;
}
-
/**
* Accept call.
*
@@ -120,7 +114,6 @@ trait AuthKeyHandler
}
if ($this->callStatus($call['id']) !== \danog\MadelineProto\VoIP::CALL_STATE_ACCEPTED) {
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_error_1'], $call['id']));
-
return false;
}
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['accepting_call'], $this->calls[$call['id']]->getOtherID()), \danog\MadelineProto\Logger::VERBOSE);
@@ -129,30 +122,24 @@ trait AuthKeyHandler
$b = \tgseclib\Math\BigInteger::randomRange(\danog\MadelineProto\Magic::$two, $dh_config['p']->subtract(\danog\MadelineProto\Magic::$two));
$g_b = $dh_config['g']->powMod($b, $dh_config['p']);
$this->checkG($g_b, $dh_config['p']);
-
try {
$res = yield $this->methodCallAsyncRead('phone.acceptCall', ['peer' => $call, 'g_b' => $g_b->toBytes(), 'protocol' => ['_' => 'phoneCallProtocol', 'udp_reflector' => true, 'udp_p2p' => true, 'min_layer' => 65, 'max_layer' => \danog\MadelineProto\VoIP::getConnectionMaxLayer()]], ['datacenter' => $this->datacenter->curdc]);
} catch (\danog\MadelineProto\RPCErrorException $e) {
if ($e->rpc === 'CALL_ALREADY_ACCEPTED') {
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_already_accepted'], $call['id']));
-
return true;
}
if ($e->rpc === 'CALL_ALREADY_DECLINED') {
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['call_already_declined']);
- yield $this->discardCallAsync($call['id'], 'phoneCallDiscardReasonHangup');
-
+ yield from $this->discardCallAsync($call['id'], 'phoneCallDiscardReasonHangup');
return false;
}
-
throw $e;
}
$this->calls[$res['phone_call']['id']]->storage['b'] = $b;
yield $this->updaters[false]->resume();
-
return true;
}
-
/**
* Confirm call.
*
@@ -167,7 +154,6 @@ trait AuthKeyHandler
}
if ($this->callStatus($params['id']) !== \danog\MadelineProto\VoIP::CALL_STATE_REQUESTED) {
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_error_2'], $params['id']));
-
return false;
}
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_confirming'], $this->calls[$params['id']]->getOtherID()), \danog\MadelineProto\Logger::VERBOSE);
@@ -180,35 +166,28 @@ trait AuthKeyHandler
} catch (\danog\MadelineProto\RPCErrorException $e) {
if ($e->rpc === 'CALL_ALREADY_ACCEPTED') {
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_already_accepted'], $call['id']));
-
return true;
}
if ($e->rpc === 'CALL_ALREADY_DECLINED') {
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['call_already_declined']);
- yield $this->discardCallAsync($call['id'], 'phoneCallDiscardReasonHangup');
-
+ yield from $this->discardCallAsync($call['id'], 'phoneCallDiscardReasonHangup');
return false;
}
-
throw $e;
}
-
$visualization = [];
$length = new \tgseclib\Math\BigInteger(\count(\danog\MadelineProto\Magic::$emojis));
- foreach (\str_split(\hash('sha256', $key.\str_pad($this->calls[$params['id']]->storage['g_a'], 256, \chr(0), \STR_PAD_LEFT), true), 8) as $number) {
+ foreach (\str_split(\hash('sha256', $key . \str_pad($this->calls[$params['id']]->storage['g_a'], 256, \chr(0), \STR_PAD_LEFT), true), 8) as $number) {
$number[0] = \chr(\ord($number[0]) & 0x7f);
$visualization[] = \danog\MadelineProto\Magic::$emojis[(int) (new \tgseclib\Math\BigInteger($number, 256))->divide($length)[1]->toString()];
}
$this->calls[$params['id']]->setVisualization($visualization);
-
$this->calls[$params['id']]->configuration['endpoints'] = \array_merge($res['connections'], $this->calls[$params['id']]->configuration['endpoints']);
$this->calls[$params['id']]->configuration = \array_merge(['recv_timeout' => $this->config['call_receive_timeout_ms'] / 1000, 'init_timeout' => $this->config['call_connect_timeout_ms'] / 1000, 'data_saving' => \danog\MadelineProto\VoIP::DATA_SAVING_NEVER, 'enable_NS' => true, 'enable_AEC' => true, 'enable_AGC' => true, 'auth_key' => $key, 'auth_key_id' => \substr(\sha1($key, true), -8), 'call_id' => \substr(\hash('sha256', $key, true), -16), 'network_type' => \danog\MadelineProto\VoIP::NET_TYPE_ETHERNET], $this->calls[$params['id']]->configuration);
$this->calls[$params['id']]->parseConfig();
$res = $this->calls[$params['id']]->startTheMagic();
-
return $res;
}
-
/**
* Complete call handshake.
*
@@ -223,7 +202,6 @@ trait AuthKeyHandler
}
if ($this->callStatus($params['id']) !== \danog\MadelineProto\VoIP::CALL_STATE_ACCEPTED || !isset($this->calls[$params['id']]->storage['b'])) {
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_error_3'], $params['id']));
-
return false;
}
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_completing'], $this->calls[$params['id']]->getOtherID()), \danog\MadelineProto\Logger::VERBOSE);
@@ -239,7 +217,7 @@ trait AuthKeyHandler
}
$visualization = [];
$length = new \tgseclib\Math\BigInteger(\count(\danog\MadelineProto\Magic::$emojis));
- foreach (\str_split(\hash('sha256', $key.\str_pad($params['g_a_or_b']->toBytes(), 256, \chr(0), \STR_PAD_LEFT), true), 8) as $number) {
+ foreach (\str_split(\hash('sha256', $key . \str_pad($params['g_a_or_b']->toBytes(), 256, \chr(0), \STR_PAD_LEFT), true), 8) as $number) {
$number[0] = \chr(\ord($number[0]) & 0x7f);
$visualization[] = \danog\MadelineProto\Magic::$emojis[(int) (new \tgseclib\Math\BigInteger($number, 256))->divide($length)[1]->toString()];
}
@@ -247,10 +225,8 @@ trait AuthKeyHandler
$this->calls[$params['id']]->configuration['endpoints'] = \array_merge($params['connections'], $this->calls[$params['id']]->configuration['endpoints']);
$this->calls[$params['id']]->configuration = \array_merge(['recv_timeout' => $this->config['call_receive_timeout_ms'] / 1000, 'init_timeout' => $this->config['call_connect_timeout_ms'] / 1000, 'data_saving' => \danog\MadelineProto\VoIP::DATA_SAVING_NEVER, 'enable_NS' => true, 'enable_AEC' => true, 'enable_AGC' => true, 'auth_key' => $key, 'auth_key_id' => \substr(\sha1($key, true), -8), 'call_id' => \substr(\hash('sha256', $key, true), -16), 'network_type' => \danog\MadelineProto\VoIP::NET_TYPE_ETHERNET], $this->calls[$params['id']]->configuration);
$this->calls[$params['id']]->parseConfig();
-
return $this->calls[$params['id']]->startTheMagic();
}
-
/**
* Get call status.
*
@@ -266,10 +242,8 @@ trait AuthKeyHandler
if (isset($this->calls[$id])) {
return $this->calls[$id]->getCallState();
}
-
return \danog\MadelineProto\VoIP::CALL_STATE_NONE;
}
-
/**
* Get call info.
*
@@ -282,10 +256,8 @@ trait AuthKeyHandler
if (!\class_exists('\\danog\\MadelineProto\\VoIP')) {
throw \danog\MadelineProto\Exception::extension('libtgvoip');
}
-
return $this->calls[$call];
}
-
/**
* Discard call.
*
@@ -305,7 +277,6 @@ trait AuthKeyHandler
return;
}
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_discarding'], $call['id']), \danog\MadelineProto\Logger::VERBOSE);
-
try {
$res = yield $this->methodCallAsyncRead('phone.discardCall', ['peer' => $call, 'duration' => \time() - $this->calls[$call['id']]->whenCreated(), 'connection_id' => $this->calls[$call['id']]->getPreferredRelayID(), 'reason' => $reason], ['datacenter' => $this->datacenter->curdc]);
} catch (\danog\MadelineProto\RPCErrorException $e) {
diff --git a/src/danog/MadelineProto/VoIPServerConfig.php b/src/danog/MadelineProto/VoIPServerConfig.php
index 45701098..7232f571 100644
--- a/src/danog/MadelineProto/VoIPServerConfig.php
+++ b/src/danog/MadelineProto/VoIPServerConfig.php
@@ -1,4 +1,5 @@
write('You did not define a valid API ID/API hash. Do you want to define it now manually, or automatically? (m/a)
-Note that you can also provide the API parameters directly in the code using the settings: https://docs.madelineproto.xyz/docs/SETTINGS.html#settingsapp_infoapi_id'.PHP_EOL);
+Note that you can also provide the API parameters directly in the code using the settings: https://docs.madelineproto.xyz/docs/SETTINGS.html#settingsapp_infoapi_id' . PHP_EOL);
if (\strpos(yield Tools::readLine('Your choice (m/a): '), 'm') !== false) {
yield $stdout->write('1) Login to my.telegram.org
2) Go to API development tools
@@ -42,10 +41,9 @@ Note that you can also provide the API parameters directly in the code using the
URL: your app/website\'s URL, or t.me/yourusername
Platform: anything
Description: Describe your app here
-4) Click on create application'.PHP_EOL);
+4) Click on create application' . PHP_EOL);
$app['api_id'] = yield Tools::readLine('5) Enter your API ID: ');
$app['api_hash'] = yield Tools::readLine('6) Enter your API hash: ');
-
return $app;
}
$this->my_telegram_org_wrapper = new \danog\MadelineProto\MyTelegramOrgWrapper($settings);
@@ -60,7 +58,6 @@ Note that you can also provide the API parameters directly in the code using the
} else {
$app = yield $this->my_telegram_org_wrapper->getApp();
}
-
return $app;
}
$this->getting_api_id = true;
@@ -69,16 +66,15 @@ Note that you can also provide the API parameters directly in the code using the
$app['api_id'] = (int) $_POST['api_id'];
$app['api_hash'] = $_POST['api_hash'];
$this->getting_api_id = false;
-
return $app;
} elseif (isset($_POST['phone_number'])) {
- yield $this->webAPIPhoneLogin($settings);
+ yield from $this->webAPIPhoneLogin($settings);
} else {
yield $this->webAPIEcho();
}
} elseif (!$this->my_telegram_org_wrapper->loggedIn()) {
if (isset($_POST['code'])) {
- yield $this->webAPICompleteLogin();
+ yield from $this->webAPICompleteLogin();
if (yield $this->my_telegram_org_wrapper->hasApp()) {
return yield $this->my_telegram_org_wrapper->getApp();
}
@@ -87,19 +83,17 @@ Note that you can also provide the API parameters directly in the code using the
$app['api_id'] = (int) $_POST['api_id'];
$app['api_hash'] = $_POST['api_hash'];
$this->getting_api_id = false;
-
return $app;
} elseif (isset($_POST['phone_number'])) {
- yield $this->webAPIPhoneLogin($settings);
+ yield from $this->webAPIPhoneLogin($settings);
} else {
$this->my_telegram_org_wrapper = null;
yield $this->webAPIEcho();
}
} else {
if (isset($_POST['app_title'], $_POST['app_shortname'], $_POST['app_url'], $_POST['app_platform'], $_POST['app_desc'])) {
- $app = yield $this->webAPICreateApp();
+ $app = (yield from $this->webAPICreateApp());
$this->getting_api_id = false;
-
return $app;
}
yield $this->webAPIEcho("You didn't provide all of the required parameters!");
@@ -107,41 +101,37 @@ Note that you can also provide the API parameters directly in the code using the
$this->asyncInitPromise = null;
exit;
}
-
- private function webAPIPhoneLogin($settings)
+ private function webAPIPhoneLogin($settings): \Generator
{
try {
$this->my_telegram_org_wrapper = new \danog\MadelineProto\MyTelegramOrgWrapper($settings);
yield $this->my_telegram_org_wrapper->login($_POST['phone_number']);
yield $this->webAPIEcho();
} catch (\Throwable $e) {
- yield $this->webAPIEcho('ERROR: '.$e->getMessage().'. Try again.');
+ yield $this->webAPIEcho('ERROR: ' . $e->getMessage() . '. Try again.');
}
}
-
- private function webAPICompleteLogin()
+ private function webAPICompleteLogin(): \Generator
{
try {
yield $this->my_telegram_org_wrapper->completeLogin($_POST['code']);
} catch (\danog\MadelineProto\RPCErrorException $e) {
- yield $this->webAPIEcho('ERROR: '.$e->getMessage().'. Try again.');
+ yield $this->webAPIEcho('ERROR: ' . $e->getMessage() . '. Try again.');
} catch (\danog\MadelineProto\Exception $e) {
- yield $this->webAPIEcho('ERROR: '.$e->getMessage().'. Try again.');
+ yield $this->webAPIEcho('ERROR: ' . $e->getMessage() . '. Try again.');
}
}
-
- private function webAPICreateApp()
+ private function webAPICreateApp(): \Generator
{
try {
$params = $_POST;
unset($params['creating_app']);
$app = yield $this->my_telegram_org_wrapper->createApp($params);
-
return $app;
} catch (\danog\MadelineProto\RPCErrorException $e) {
- yield $this->webAPIEcho('ERROR: '.$e->getMessage().' Try again.');
+ yield $this->webAPIEcho('ERROR: ' . $e->getMessage() . ' Try again.');
} catch (\danog\MadelineProto\Exception $e) {
- yield $this->webAPIEcho('ERROR: '.$e->getMessage().' Try again.');
+ yield $this->webAPIEcho('ERROR: ' . $e->getMessage() . ' Try again.');
}
}
}
diff --git a/src/danog/MadelineProto/Wrappers/ApiTemplates.php b/src/danog/MadelineProto/Wrappers/ApiTemplates.php
index dc5eb723..c92c8ae7 100644
--- a/src/danog/MadelineProto/Wrappers/ApiTemplates.php
+++ b/src/danog/MadelineProto/Wrappers/ApiTemplates.php
@@ -37,12 +37,10 @@ trait ApiTemplates