2017-02-16 04:55:10 +01:00
#!/usr/bin/env php
< ? php
/*
2019-05-31 12:18:10 +02:00
Copyright 2016 - 2019 Daniil Gentili
2017-02-16 04:55:10 +01:00
( https :// daniil . it )
This file is part of MadelineProto .
MadelineProto is free software : you can redistribute it and / or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation , either version 3 of the License , or ( at your option ) any later version .
MadelineProto is distributed in the hope that it will be useful , but WITHOUT ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
See the GNU Affero General Public License for more details .
You should have received a copy of the GNU General Public License along with MadelineProto .
If not , see < http :// www . gnu . org / licenses />.
*/
2018-10-13 17:16:10 +02:00
2019-10-28 22:39:23 +01:00
if ( \file_exists ( __DIR__ . '/vendor/autoload.php' )) {
include 'vendor/autoload.php' ;
} else {
2019-09-02 17:08:36 +02:00
if ( ! \file_exists ( 'madeline.php' )) {
\copy ( 'https://phar.madelineproto.xyz/madeline.php' , 'madeline.php' );
2018-10-13 17:16:10 +02:00
}
include 'madeline.php' ;
}
2018-05-08 21:08:09 +02:00
$settings = [];
2017-02-22 20:45:20 +01:00
include_once 'token.php' ;
2017-08-13 18:52:32 +02:00
2017-02-16 04:55:10 +01:00
try {
2017-11-03 13:02:01 +01:00
$MadelineProto = new \danog\MadelineProto\API ( 'b.madeline' );
2017-02-16 04:55:10 +01:00
} catch ( \danog\MadelineProto\Exception $e ) {
2017-02-16 04:55:47 +01:00
$MadelineProto = new \danog\MadelineProto\API ( $settings );
2017-02-22 20:45:20 +01:00
$authorization = $MadelineProto -> bot_login ( $pwrtelegram_debug_token );
2018-03-02 01:38:10 +01:00
\danog\MadelineProto\Logger :: log ( $authorization , \danog\MadelineProto\Logger :: NOTICE );
2017-02-16 04:55:10 +01:00
}
function base64url_decode ( $data )
{
2019-09-02 17:08:36 +02:00
return \base64_decode ( \str_pad ( \strtr ( $data , '-_' , '+/' ), \strlen ( $data ) % 4 , '=' , STR_PAD_RIGHT ));
2017-02-16 04:55:10 +01:00
}
2017-02-16 04:55:47 +01:00
function rle_decode ( $string )
{
2017-02-16 04:55:10 +01:00
$base256 = '' ;
$last = '' ;
2019-09-02 17:08:36 +02:00
foreach ( \str_split ( $string ) as $cur ) {
if ( $last === \chr ( 0 )) {
$base256 .= \str_repeat ( $last , \ord ( $cur ));
2017-02-16 04:55:10 +01:00
$last = '' ;
} else {
$base256 .= $last ;
$last = $cur ;
}
}
$string = $base256 . $last ;
2017-02-16 04:55:47 +01:00
2017-02-16 04:55:10 +01:00
return $string ;
}
function foreach_offset_length ( $string )
{
2017-02-16 04:55:47 +01:00
/* $a = [];
2017-02-16 04:55:10 +01:00
$b = [];
foreach ([ 2 , 3 , 4 ] as $r ) {
$a [] = chr ( 0 ) . chr ( $r );
$b [] = str_repeat ( chr ( 0 ), $r );
}
$string = str_replace ( $a , $b , $string ); */
$res = [];
2019-09-02 17:08:36 +02:00
$strlen = \strlen ( $string );
for ( $offset = 0 ; $offset < \strlen ( $string ); $offset ++ ) {
2017-02-16 04:55:47 +01:00
// for ($length = $strlen - $offset; $length > 0; $length--) {
2017-02-16 04:55:10 +01:00
foreach ([ 'i' => 4 , 'q' => 8 ] as $c => $length ) {
2019-09-02 17:08:36 +02:00
$s = \substr ( $string , $offset , $length );
if ( \strlen ( $s ) === $length ) {
2017-02-16 04:55:10 +01:00
$number = \danog\PHP\Struct :: unpack ( '<' . $c , $s )[ 0 ];
//$number = ord($s);
$res [] = [ 'number' => $number , 'offset' => $offset , 'length' => $length ];
}
}
}
return $res ;
}
$res = [ 'offset' => 0 , 'files' => []];
2017-02-16 04:55:47 +01:00
function getfiles ( $token , & $params )
{
2019-09-02 17:08:36 +02:00
foreach ( \json_decode ( \file_get_contents ( 'https://api.telegram.org/bot' . $token . '/getupdates?offset=' . $params [ 'offset' ]), true )[ 'result' ] as $update ) {
2017-02-16 04:55:47 +01:00
$params [ 'offset' ] = $update [ 'update_id' ] + 1 ;
2017-02-16 04:55:10 +01:00
if ( isset ( $update [ 'message' ][ 'audio' ])) {
$params [ 'files' ][ $update [ 'message' ][ 'message_id' ]] = $update [ 'message' ][ 'audio' ][ 'file_id' ];
}
if ( isset ( $update [ 'message' ][ 'document' ])) {
$params [ 'files' ][ $update [ 'message' ][ 'message_id' ]] = $update [ 'message' ][ 'document' ][ 'file_id' ];
}
if ( isset ( $update [ 'message' ][ 'video' ])) {
$params [ 'files' ][ $update [ 'message' ][ 'message_id' ]] = $update [ 'message' ][ 'video' ][ 'file_id' ];
}
if ( isset ( $update [ 'message' ][ 'sticker' ])) {
$params [ 'files' ][ $update [ 'message' ][ 'message_id' ]] = $update [ 'message' ][ 'sticker' ][ 'file_id' ];
}
if ( isset ( $update [ 'message' ][ 'voice' ])) {
$params [ 'files' ][ $update [ 'message' ][ 'message_id' ]] = $update [ 'message' ][ 'voice' ][ 'file_id' ];
}
if ( isset ( $update [ 'message' ][ 'photo' ])) {
2019-09-02 17:08:36 +02:00
$params [ 'files' ][ $update [ 'message' ][ 'message_id' ]] = \end ( $update [ 'message' ][ 'photo' ])[ 'file_id' ];
2017-02-16 04:55:10 +01:00
}
}
}
2017-06-11 11:35:25 +02:00
function recurse ( $array , $prefix = '' )
{
2017-06-11 11:34:44 +02:00
$res = [];
foreach ( $array as $k => $v ) {
2019-09-02 17:08:36 +02:00
if ( \is_array ( $v )) {
$res = \array_merge ( recurse ( $v , $prefix . $k . '->' ), $res );
} elseif ( \is_int ( $v )) {
2017-06-11 11:35:25 +02:00
$res [ $prefix . $k ] = $v ;
}
2017-06-11 11:34:44 +02:00
}
2017-06-11 11:35:25 +02:00
2017-06-11 11:34:44 +02:00
return $res ;
}
2017-02-16 04:55:10 +01:00
$offset = 0 ;
while ( true ) {
2018-03-04 17:42:48 +01:00
$updates = $MadelineProto -> get_updates ([ 'offset' => $offset , 'limit' => 50 , 'timeout' => 0 ]); // Just like in the bot API, you can specify an offset, a limit and a timeout
2017-02-16 04:55:10 +01:00
foreach ( $updates as $update ) {
$offset = $update [ 'update_id' ] + 1 ; // Just like in the bot API, the offset must be set to the last update_id
switch ( $update [ 'update' ][ '_' ]) {
case 'updateNewMessage' :
if ( isset ( $update [ 'update' ][ 'message' ][ 'out' ]) && $update [ 'update' ][ 'message' ][ 'out' ]) {
continue ;
}
2017-02-22 20:45:20 +01:00
2017-02-16 04:55:10 +01:00
try {
if ( isset ( $update [ 'update' ][ 'message' ][ 'media' ])) {
2017-02-22 20:45:20 +01:00
getfiles ( $pwrtelegram_debug_token , $res );
2017-02-16 04:55:10 +01:00
$bot_api_id = $message = $res [ 'files' ][ $update [ 'update' ][ 'message' ][ 'id' ]];
$bot_api_id_b256 = base64url_decode ( $bot_api_id );
$bot_api_id_rledecoded = rle_decode ( $bot_api_id_b256 );
2017-06-11 11:34:44 +02:00
$message .= PHP_EOL . PHP_EOL ;
2019-09-02 17:08:36 +02:00
for ( $x = 0 ; $x < \strlen ( $bot_api_id_rledecoded ) - 3 ; $x ++ ) {
$message .= 'Bytes ' . $x . '-' . ( $x + 4 ) . ': ' . \danog\PHP\Struct :: unpack ( '<i' , \substr ( $bot_api_id_rledecoded , $x , 4 ))[ 0 ] . PHP_EOL ;
2017-06-11 11:34:44 +02:00
}
2017-02-16 04:55:10 +01:00
$message .= PHP_EOL . PHP_EOL .
2019-09-02 17:08:36 +02:00
'First 4 bytes: ' . \ord ( $bot_api_id_rledecoded [ 0 ]) . ' ' . \ord ( $bot_api_id_rledecoded [ 1 ]) . ' ' . \ord ( $bot_api_id_rledecoded [ 2 ]) . ' ' . \ord ( $bot_api_id_rledecoded [ 3 ]) . PHP_EOL .
'First 4 bytes (single integer): ' . ( \danog\PHP\Struct :: unpack ( '<i' , \substr ( $bot_api_id_rledecoded , 0 , 4 ))[ 0 ]) . PHP_EOL .
'bytes 8-16: ' . ( \danog\PHP\Struct :: unpack ( '<q' , \substr ( $bot_api_id_rledecoded , 8 , 8 ))[ 0 ]) . PHP_EOL .
'bytes 16-24: ' . ( \danog\PHP\Struct :: unpack ( '<q' , \substr ( $bot_api_id_rledecoded , 16 , 8 ))[ 0 ]) . PHP_EOL .
'Last byte: ' . \ord ( \substr ( $bot_api_id_rledecoded , - 1 )) . PHP_EOL .
'Total length: ' . \strlen ( $bot_api_id_b256 ) . PHP_EOL .
'Total length (rledecoded): ' . \strlen ( $bot_api_id_rledecoded ) . PHP_EOL .
2017-06-11 11:34:44 +02:00
PHP_EOL . '<b>param (value): start-end (length)</b>' . PHP_EOL . PHP_EOL ;
2017-02-16 04:55:10 +01:00
$bot_api = foreach_offset_length ( $bot_api_id_rledecoded );
2017-06-11 11:34:44 +02:00
//$mtproto = $MadelineProto->get_download_info($update['update']['message']['media'])['InputFileLocation'];
//unset($mtproto['_']);
2017-02-16 04:55:10 +01:00
$m = [];
2017-06-11 11:34:44 +02:00
$mtproto = recurse ( $update [ 'update' ][ 'message' ]);
/*
2017-02-16 04:55:47 +01:00
if ( isset ( $mtproto [ 'version' ])) {
unset ( $mtproto [ 'version' ]);
}
if ( isset ( $update [ 'update' ][ 'message' ][ 'media' ][ 'photo' ])) {
$mtproto [ 'id' ] = $update [ 'update' ][ 'message' ][ 'media' ][ 'photo' ][ 'id' ];
}
2017-06-11 11:34:44 +02:00
$mtproto [ 'sender_id' ] = $update [ 'update' ][ 'message' ][ 'from_id' ];
2017-02-16 04:55:47 +01:00
if ( isset ( $update [ 'update' ][ 'message' ][ 'media' ][ 'photo' ])) {
$mtproto [ 'access_hash' ] = $update [ 'update' ][ 'message' ][ 'media' ][ 'photo' ][ 'access_hash' ];
}
if ( isset ( $update [ 'update' ][ 'message' ][ 'media' ][ 'document' ])) {
$mtproto [ 'id' ] = $update [ 'update' ][ 'message' ][ 'media' ][ 'document' ][ 'id' ];
}
if ( isset ( $update [ 'update' ][ 'message' ][ 'media' ][ 'document' ])) {
$mtproto [ 'access_hash' ] = $update [ 'update' ][ 'message' ][ 'media' ][ 'document' ][ 'access_hash' ];
2017-06-11 11:34:44 +02:00
} */
2017-02-16 04:55:10 +01:00
foreach ( $mtproto as $key => $n ) {
foreach ( $bot_api as $bn ) {
if ( $bn [ 'number' ] === $n ) {
2017-06-11 11:34:44 +02:00
$m [ $bn [ 'offset' ] + $bn [ 'length' ]] = $key . ' (' . $n . '): ' . $bn [ 'offset' ] . '-' . ( $bn [ 'offset' ] + $bn [ 'length' ]) . ' (' . $bn [ 'length' ] . ') <b>FOUND</b>' . PHP_EOL ;
2017-02-16 04:55:10 +01:00
unset ( $mtproto [ $key ]);
}
}
}
2019-09-02 17:08:36 +02:00
\ksort ( $m );
2017-02-16 04:55:10 +01:00
foreach ( $m as $key => $bn ) {
$message .= $bn ;
}
foreach ( $mtproto as $key => $n ) {
2017-02-16 04:55:47 +01:00
$message .= $key . ' (' . $n . '): not found' . PHP_EOL ;
2017-02-16 04:55:10 +01:00
}
2019-09-02 17:08:36 +02:00
$message .= PHP_EOL . PHP_EOL . 'File number: ' . \danog\PHP\Struct :: unpack ( '<i' , \substr ( $bot_api_id_rledecoded , 8 , 4 ))[ 0 ];
2017-06-11 11:35:25 +02:00
if ( $update [ 'update' ][ 'message' ][ 'from_id' ] === 101374607 ) {
2019-09-02 17:08:36 +02:00
$message = \danog\PHP\Struct :: unpack ( '<i' , \substr ( $bot_api_id_rledecoded , 8 , 4 ))[ 0 ];
2017-06-11 11:35:25 +02:00
}
2017-02-22 23:55:37 +01:00
$MadelineProto -> messages -> sendMessage ([ 'peer' => $update [ 'update' ][ 'message' ][ 'from_id' ], 'message' => $message , 'reply_to_msg_id' => $update [ 'update' ][ 'message' ][ 'id' ], 'parse_mode' => 'markdown' ]);
2017-02-16 04:55:10 +01:00
}
} catch ( \danog\MadelineProto\RPCErrorException $e ) {
$MadelineProto -> messages -> sendMessage ([ 'peer' => '@danogentili' , 'message' => $e -> getCode () . ': ' . $e -> getMessage () . PHP_EOL . $e -> getTraceAsString ()]);
} catch ( \danog\MadelineProto\Exception $e ) {
$MadelineProto -> messages -> sendMessage ([ 'peer' => '@danogentili' , 'message' => $e -> getCode () . ': ' . $e -> getMessage () . PHP_EOL . $e -> getTraceAsString ()]);
}
2017-08-13 18:52:32 +02:00
2017-02-16 04:55:10 +01:00
try {
if ( isset ( $update [ 'update' ][ 'message' ][ 'media' ]) && $update [ 'update' ][ 'message' ][ 'media' ] == 'messageMediaPhoto' && $update [ 'update' ][ 'message' ][ 'media' ] == 'messageMediaDocument' ) {
2019-09-02 17:08:36 +02:00
$time = \time ();
2017-08-13 18:52:32 +02:00
// $file = $MadelineProto->download_to_dir($update['update']['message']['media'], '/tmp');
2017-02-16 04:55:10 +01:00
// $MadelineProto->messages->sendMessage(['peer' => $update['update']['message']['from_id'], 'message' => 'Downloaded to '.$file.' in '.(time() - $time).' seconds', 'reply_to_msg_id' => $update['update']['message']['id'], 'entities' => [['_' => 'messageEntityPre', 'offset' => 0, 'length' => strlen($res), 'language' => 'json']]]);
}
} catch ( \danog\MadelineProto\RPCErrorException $e ) {
$MadelineProto -> messages -> sendMessage ([ 'peer' => '@danogentili' , 'message' => $e -> getCode () . ': ' . $e -> getMessage () . PHP_EOL . $e -> getTraceAsString ()]);
}
}
}
echo 'Wrote ' . \danog\MadelineProto\Serialization :: serialize ( 'b.madeline' , $MadelineProto ) . ' bytes' . PHP_EOL ;
}