Update to layer 100

This commit is contained in:
Daniil Gentili 2019-06-22 18:22:38 +02:00
parent 2d2a3bd01f
commit 5468858298
8 changed files with 1554 additions and 39 deletions

View File

@ -46,7 +46,7 @@ class EventHandler extends \danog\MadelineProto\EventHandler
yield $this->messages->sendMessage(['peer' => $update, 'message' => "<code>$res</code>", 'reply_to_msg_id' => isset($update['message']['id']) ? $update['message']['id'] : null, 'parse_mode' => 'HTML']); //'entities' => [['_' => 'messageEntityPre', 'offset' => 0, 'length' => strlen($res), 'language' => 'json']]]);
if (isset($update['message']['media']) && $update['message']['media']['_'] !== 'messageMediaGame') {
yield $this->messages->sendMedia(['peer' => $update, 'message' => $update['message']['message'], 'media' => $update]);
//yield $this->download_to_dir($update, '/tmp')
//yield $this->download_to_dir($update, '/tmp');
}
} catch (\danog\MadelineProto\RPCErrorException $e) {
$this->logger((string) $e, \danog\MadelineProto\Logger::FATAL_ERROR);

View File

@ -136,6 +136,9 @@ class UpdateLoop extends ResumableSignalLoop
unset($difference);
break 2;
case 'updates.channelDifferenceTooLong':
if (isset($difference['dialog']['pts'])) {
$difference['pts'] = $difference['dialog']['pts'];
}
$state->update($difference);
$feeder->saveMessages($difference['messages']);
unset($difference);

View File

@ -73,7 +73,7 @@ class MTProto extends AsyncConstruct implements TLCallback
/*
const V = 71;
*/
const V = 122;
const V = 123;
const RELEASE = '4.0';
const NOT_LOGGED_IN = 0;
const WAITING_CODE = 1;
@ -718,12 +718,12 @@ class MTProto extends AsyncConstruct implements TLCallback
'lang_pack' => $lang_pack,
], 'tl_schema' => [
// TL scheme files
'layer' => 97,
'layer' => 100,
// layer version
'src' => [
'mtproto' => __DIR__.'/TL_mtproto_v1.tl',
// mtproto TL scheme
'telegram' => __DIR__.'/TL_telegram_v97.tl',
'telegram' => __DIR__.'/TL_telegram_v100.tl',
// telegram TL scheme
'secret' => __DIR__.'/TL_secret.tl',
// secret chats TL scheme

View File

@ -164,7 +164,15 @@ 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'];
@ -175,7 +183,15 @@ 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'];
@ -188,7 +204,15 @@ 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;
@ -196,7 +220,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;
@ -302,29 +334,68 @@ trait Files
return $res;
// Wallpapers
case 'wallPaper':
$photo = end($message_media['sizes']);
return array_merge($res, yield $this->get_download_info_async($photo));
return $this->get_download_info_async($res['document']);
// Photos
case 'photo':
case 'messageMediaPhoto':
if ($message_media['_'] == 'photo') {
$res['MessageMedia'] = ['_' => 'messageMediaPhoto', 'photo' => $message_media, 'ttl_seconds' => 0];
$photo = end($message_media['sizes']);
} else {
$res['MessageMedia'] = $message_media;
$photo = end($message_media['photo']['sizes']);
$message_media = ['_' => 'messageMediaPhoto', 'photo' => $message_media, 'ttl_seconds' => 0];
}
$res['MessageMedia'] = $message_media;
$message_media = $message_media['photo'];
$size = end($message_media['sizes']);
return array_merge($res, yield $this->get_download_info_async($photo));
$res = array_merge($res, yield $this->get_download_info_async($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->get_download_info_async($message_media['photo']);
$res['InputFileLocation'] = [
'_' => 'inputPeerPhotoFileLocation',
'big' => true,
'dc_id' => $res['InputFileLocation']['dc_id'],
'peer' => (yield $this->get_info_async($message_media))['InputPeer'],
'volume_id' => $res['InputFileLocation']['volume_id'],
'local_id' => $res['InputFileLocation']['local_id'],
// The peer field will be added later
];
return $res;
case 'userProfilePhoto':
case 'chatPhoto':
return array_merge($res, yield $this->get_download_info_async($message_media['photo_big']));
$size = $message_media['photo_big'];
$res = yield $this->get_download_info_async($size);
$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'] = $message_media['volume_id'].'_'.$message_media['local_id'];
@ -336,7 +407,12 @@ trait Files
return $res;
case 'photoSize':
$size = $res['size'];
$res = yield $this->get_download_info_async($message_media['location']);
$res['thumb_size'] = $message_media['type'];
//$res['thumb_size'] = $size;
if (isset($message_media['size'])) {
$res['size'] = $message_media['size'];
}
@ -347,10 +423,31 @@ trait Files
throw new \danog\MadelineProto\Exception('File location unavailable');
case 'fileLocation':
$res['name'] = $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['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->get_extension_from_location($res['InputFileLocation'], '.jpg');
$res['mime'] = $this->get_mime_from_extension($res['ext'], 'image/jpeg');
return $res;
case 'fileLocationToBeDeprecated':
$res['name'] = $message_media['volume_id'].'_'.$message_media['local_id'];
$res['ext'] = '.jpg';
$res['mime'] = $this->get_mime_from_extension($res['ext'], 'image/jpeg');
$res['InputFileLocation'] = [
'_' => 'inputFileLocationTemp', // Will be overwritten
'volume_id' => $message_media['volume_id'],
'local_id' => $message_media['local_id'],
];
return $res;
// Documents
@ -380,7 +477,19 @@ trait Files
$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_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'] = $this->get_extension_from_location($res['InputFileLocation'], $this->get_extension_from_mime($message_media['document']['mime_type']));
}
@ -426,7 +535,12 @@ trait Files
$stream = fopen($file, 'r+b');
$size = fstat($stream)['size'];
$this->logger->logger('Waiting for lock of file to download...');
flock($stream, LOCK_EX);
do {
$res = flock($stream, LOCK_EX|LOCK_NB);
if (!$res) {
yield $this->sleep(0.1);
}
} while (!$res);
try {
yield $this->download_to_stream_async($message_media, $stream, $cb, $size, -1);

View File

@ -56,11 +56,11 @@ trait PeerHandler
{
if (!isset($user['access_hash'])) {
/*if (isset($this->chats[$user['id']]['access_hash']) && $this->chats[$user['id']]['access_hash']) {
$this->logger->logger("No access hash with user {$user['id']}, using backup");
$user['access_hash'] = $this->chats[$user['id']]['access_hash'];
$this->logger->logger("No access hash with user {$user['id']}, using backup");
$user['access_hash'] = $this->chats[$user['id']]['access_hash'];
} else {
$this->logger->logger("No access hash with user {$user['id']}, not trying to fetch it");
$user['access_hash'] = 0;
$this->logger->logger("No access hash with user {$user['id']}, not trying to fetch it");
$user['access_hash'] = 0;
}*/
if (!isset($this->caching_simple[$user['id']]) && !(isset($user['username']) && isset($this->caching_simple_username[$user['username']]))) {
$this->logger->logger("No access hash with user {$user['id']}, trying to fetch by ID...");
@ -206,6 +206,16 @@ trait PeerHandler
return true;
}
public function get_folder_id($id)
{
if (!is_array($id)) {
return null;
}
if (!isset($id['folder_id'])) {
return null;
}
return $id['folder_id'];
}
public function get_id($id)
{
if (is_array($id)) {
@ -222,7 +232,18 @@ trait PeerHandler
case 'dialog':
case 'help.proxyDataPromo':
case 'updateChatDefaultBannedRights':
case 'folderPeer':
case 'inputFolderPeer':
return $this->get_id($id['peer']);
case 'inputUserFromMessage':
case 'inputPeerUserFromMessage':
return $id['user_id'];
case 'inputChannelFromMessage':
case 'inputPeerChannelFromMessage':
return $this->to_supergroup($id['channel_id']);
case 'inputUserSelf':
case 'inputPeerSelf':
return $this->authorization['user']['id'];
@ -352,6 +373,7 @@ trait PeerHandler
return $this->secret_chats[$id];
}
}
$folder_id = $this->get_folder_id($id);
$try_id = $this->get_id($id);
if ($try_id !== false) {
$id = $try_id;
@ -385,7 +407,7 @@ trait PeerHandler
}
if (isset($this->chats[$id])) {
try {
return $this->gen_all($this->chats[$id]);
return $this->gen_all($this->chats[$id], $folder_id);
} catch (\danog\MadelineProto\Exception $e) {
if ($e->getMessage() === 'This peer is not present in the internal peer database') {
unset($this->chats[$id]);
@ -444,7 +466,7 @@ trait PeerHandler
}
foreach ($this->chats as $chat) {
if (isset($chat['username']) && strtolower($chat['username']) === $id) {
return $this->gen_all($chat);
return $this->gen_all($chat, $folder_id);
}
}
if ($recursive) {
@ -456,7 +478,7 @@ trait PeerHandler
throw new \danog\MadelineProto\Exception('This peer is not present in the internal peer database');
}
public function gen_all($constructor)
public function gen_all($constructor, $folder_id = null)
{
$res = [$this->constructors->find_by_predicate($constructor['_'])['type'] => $constructor];
switch ($constructor['_']) {
@ -511,7 +533,10 @@ trait PeerHandler
default:
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];
$res['InputFolderPeer'] = ['_' => 'inputFolderPeer', 'peer' => $res['InputPeer'], 'folder_id' => $folder_id];
}
return $res;
}

View File

@ -33,9 +33,9 @@ class ReferenceDatabase implements TLCallback
const DOCUMENT_LOCATION = 0;
// Reference from a photo
const PHOTO_LOCATION = 1;
// Reference from a location (can only be photo location)
// Reference from a photo location (can only be photo location)
const PHOTO_LOCATION_LOCATION = 2;
// Reference from a location (can only be document location)
// DEPRECATED: Reference from a location (can only be document location)
const DOCUMENT_LOCATION_LOCATION = 0;
// Peer + photo ID
@ -58,8 +58,9 @@ class ReferenceDatabase implements TLCallback
const WALLPAPER_ORIGIN = 9;
const LOCATION_CONTEXT = [
'inputFileLocation' => self::PHOTO_LOCATION_LOCATION,
'inputDocumentFileLocation' => self::DOCUMENT_LOCATION_LOCATION,
//'inputFileLocation' => self::PHOTO_LOCATION_LOCATION, // DEPRECATED
'inputDocumentFileLocation' => self::DOCUMENT_LOCATION,
'inputPhotoFileLocation' => self::PHOTO_LOCATION,
'inputPhoto' => self::PHOTO_LOCATION,
'inputDocument' => self::DOCUMENT_LOCATION,
];
@ -122,6 +123,11 @@ class ReferenceDatabase implements TLCallback
public function init()
{
foreach ($this->db as $key => $value) {
if ($key[0] === "0") { // Unsetting deprecated DOCUMENT_LOCATION_LOCATION
unset($this->db[$key]);
}
}
}
public function getMethodCallbacks(): array
@ -560,7 +566,6 @@ class ReferenceDatabase implements TLCallback
{
switch ($locationType) {
case self::DOCUMENT_LOCATION:
case self::DOCUMENT_LOCATION_LOCATION:
case self::PHOTO_LOCATION:
return $locationType.(is_int($location['id']) ? $this->pack_signed_long($location['id']) : $location['id']);
case self::PHOTO_LOCATION_LOCATION:

View File

@ -72,13 +72,22 @@ trait BotAPIFiles
public function photosize_to_botapi_async($photoSize, $photo, $thumbnail = false)
{
$ext = $this->get_extension_from_location(['_' => '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'] = isset($photo['access_hash']) ? $photo['access_hash'] : 0;
$photoSize['location']['id'] = isset($photo['id']) ? $photo['id'] : 0;
$ext = '.jpg';//$this->get_extension_from_location(['_' => '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'];
$photoSize['location']['_'] = $thumbnail ? 'bot_thumbnail' : 'bot_photo';
$data = (yield $this->serialize_object_async(['type' => 'File'], $photoSize['location'], 'File')).chr(2);
return ['file_id' => $this->base64url_encode($this->rle_encode($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];
return [
'file_id' => $this->base64url_encode($this->rle_encode($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
];
}
public function unpack_file_id($file_id)
@ -92,7 +101,7 @@ trait BotAPIFiles
switch ($deserialized['_']) {
case 'bot_thumbnail':
case 'bot_photo':
$constructor = ['_' => 'photo', 'sizes' => []];
$constructor = ['_' => 'photo', 'sizes' => [], 'dc_id' => $deserialized['dc_id']];
$constructor['id'] = $deserialized['id'];
$constructor['access_hash'] = $deserialized['access_hash'];
unset($deserialized['id']);

File diff suppressed because it is too large Load Diff