Simple PHP class to retrieve torrent seed and peer number

Cancelado Publicado Jan 8, 2016 Pagado a la entrega
Cancelado Pagado a la entrega

Hello, I find on the internet that to get the number of peers for a specific torrent and tracker you I just have to bdecode the torrent file, compute the info_hash and send it to the tracker scrape url but I can't find a simple classe for that.

Also you just have to find one for me (or write one but I think there's some on the net).

I need it to be in PHP. No need to check all the tracker for multiple tracker torrents.

Thanks

I need a very cheap job also here is a code supposed working but doesn't on my ovh server.
Your job is just to tell what is wrong with this code, or if it works then I'll just check my server...

<?php

class Torrent
{
public function scrape(array $announce , $hash_info = null)
{

$r = [
'seeders' => 0 ,
'leechers' => 0
];

foreach ( $announce as $an ) {

$d = get_remote_peers($an , $hash_info);

if ( isset($d['seeders']) ) {
$r['seeders'] += $d['seeders'];
}

if ( isset($d['leechers']) ) {
$r['leechers'] += $d['leechers'];
}
}

return $r;
}

}


/**
* Gets amout of remote tracker peers. May be recursivity.
*
* @param string $url Announce url of request
* @param string $info_hash Info-hash of torrent to be parsed
* @param string $method Method of gathering amount of peers. May be scrape or announce. Default 'scrape'. If scrape fails, recursivety swithes to announce and executes again.
*
* @return array Result array ('tracker','seeders','leechers','state');
*/
function get_remote_peers($url , $info_hash , $method = 'scrape')
{

if ( $method == "announce" ) {
$get_params = array(
"info_hash" => pack("H*" , $info_hash) ,
"peer_id" => "-UT1820-5dmPcUOYGnrx" ,
"port" => rand(10000 , 65535) ,
"uploaded" => 0 ,
"no_peer_id" => 1 ,
"downloaded" => 0 ,
"compact" => 1 ,
"left" => 1 ,
"numwant" => 9999
);
} else {
$urlorig = $url;
$url = str_replace('announce' , 'scrape' , $url);
$get_params = array(
"info_hash" => pack("H*" , $info_hash)
);
}


$urlInfo = parse_url($url);
$http_host = $urlInfo['host'];
$http_port = getUrlPort($urlInfo);
$scheme = $urlInfo['scheme'];

if ( $http_port === 0 ) {
return array( 'tracker' => $http_host , 'state' => 'failed:no_port_detected' , 'method' => "$scheme:$method" , 'remote_method' => 'N/A' );
}

$http_path = $urlInfo['path'];
$get_request_params = @explode('&' , $urlInfo['query']);

$new_get_request_params = false;
foreach ( array_filter($get_request_params) as $array_value ) {
list($key , $value) = explode('=' , $array_value);
$new_get_request_params[$key] = $value;
}

if ( !$new_get_request_params ) {
$new_get_request_params = array();
}
// Params gathering complete

// Creating params
$http_params = http_build_query(@array_merge($new_get_request_params , $get_params));
$opts = array(
$scheme => array(
'method' => 'GET' ,
'header' => 'User-Agent: uTorrent/1820' ,
'timeout' => 3
//'Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2',
)
);

$req_uri = $scheme . '://' . $http_host . ':' . $http_port . $http_path . ($http_params ? '?' . $http_params : '');


if ( $scheme == 'udp' && $method == 'scrape' ) {

$transaction_id = mt_rand(0 , 65535);
$fp = fsockopen($scheme . '://' . $http_host , $http_port , $errno , $errstr); //sockets only
if ( !$fp ) {
return array( 'tracker' => $http_host , 'state' => 'failed:timeout' , 'method' => "$scheme:$method" , 'remote_method' => 'socket' );
}
stream_set_timeout($fp , 3);

$current_connid = "\x00\x00\x04\x17\x27\x10\x19\x80";

//Connection request
$packet = $current_connid . pack("N" , 0) . pack("N" , $transaction_id);
fwrite($fp , $packet);

//Connection response
$ret = fread($fp , 16);
if ( strlen($ret) < 1 ) {
return get_remote_peers($urlorig , $info_hash , "announce");
}
if ( strlen($ret) < 16 ) {
return array( 'tracker' => $http_host , 'state' => 'failed:invalid_udp_packet' , 'method' => "$scheme:$method" , 'remote_method' => 'socket' );
}
$retd = unpack("Naction/Ntransid" , $ret);
if ( $retd['action'] != 0 || $retd['transid'] != $transaction_id ) {
return array( 'tracker' => $http_host , 'state' => 'failed:invalid_udp_response' , 'method' => "$scheme:$method" , 'remote_method' => 'socket' );
}
$current_connid = substr($ret , 8 , 8);

//Scrape request
$packet = $current_connid . pack("N" , 2) . pack("N" , $transaction_id) . pack('H*' , $info_hash);
fwrite($fp , $packet);
//Scrape response
$readlength = 20; //8 + (12);
$ret = fread($fp , $readlength);
if ( strlen($ret) < 1 ) {
return get_remote_peers($urlorig , $info_hash , "announce");
}
if ( strlen($ret) < 8 ) {
array( 'tracker' => $http_host , 'state' => 'failed:invalid_udp_packet' , 'method' => "$scheme:$method" , 'remote_method' => 'socket' );
}
$retd = unpack("Naction/Ntransid" , $ret);
// Todo check for error string if response = 3
if ( $retd['action'] != 2 || $retd['transid'] != $transaction_id ) {
array( 'tracker' => $http_host , 'state' => 'failed:invalid_udp_response' , 'method' => "$scheme:$method" , 'remote_method' => 'socket' );
}
if ( strlen($ret) < $readlength ) {
return array( 'tracker' => $http_host , 'state' => 'failed:invalid_udp_packet' , 'method' => "$scheme:$method" , 'remote_method' => 'socket' );
}

$index = 8;
$retd = unpack("Nseeders/Ncompleted/Nleechers" , substr($ret , $index , 12));

return array( 'tracker' => $http_host , 'seeders' => $retd['seeders'] , 'leechers' => $retd['leechers'] , 'state' => 'ok' , 'method' => "$scheme:$method" , 'remote_method' => 'socket' );

} elseif ( $scheme == 'udp' && $method == 'announce' ) {
$transaction_id = mt_rand(0 , 65535);
$fp = fsockopen($scheme . '://' . $http_host , $http_port , $errno , $errstr); //sockets only
if ( !$fp ) {
return array( 'tracker' => $http_host , 'state' => 'failed:timeout' , 'method' => "$scheme:$method" , 'remote_method' => 'socket' );
}
stream_set_timeout($fp , 3);

$current_connid = "\x00\x00\x04\x17\x27\x10\x19\x80";

//Connection request
$packet = $current_connid . pack("N" , 0) . pack("N" , $transaction_id);
//var_dump($packet);
fwrite($fp , $packet);

//Connection response
$ret = fread($fp , 16);

if ( strlen($ret) < 1 ) {
return array( 'tracker' => $http_host , 'state' => 'failed:no_udp_data' , 'method' => "$scheme:$method" , 'remote_method' => 'socket' );
}
if ( strlen($ret) < 16 ) {
return array( 'tracker' => $http_host , 'state' => 'failed:invalid_udp_packet' , 'method' => "$scheme:$method" , 'remote_method' => 'socket' );
}
$retd = unpack("Naction/Ntransid" , $ret);
if ( $retd['action'] != 0 || $retd['transid'] != $transaction_id ) {
return array( 'tracker' => $http_host , 'state' => 'failed:invalid_udp_response' , 'method' => "$scheme:$method" , 'remote_method' => 'socket' );
}
$current_connid = substr($ret , 8 , 8);
//Announce request

$downloaded = "\x30\x30\x30\x30\x30\x30\x30\x30";
$left = $downloaded;
$uploaded = $downloaded;
$packet = $current_connid . pack("N" , 1) . pack("N" , $transaction_id) . pack('H*' , $info_hash) . pack(
'H*' ,
'ee3eb1acec1dc7adc73eda16d05a495bea1ddab1'
) . $downloaded . $left . $uploaded . pack("N" , 2) . pack("N" , ip2long($_SERVER['SERVER_ADDR'])) . pack("N" , 69) . pack("N" , 500) . pack("N" , rand(0 , 65535));

fwrite($fp , $packet);

//Announce response
$readlength = 20; //8 + (12);
$ret = fread($fp , $readlength);

if ( strlen($ret) < 1 ) {
return array( 'tracker' => $http_host , 'state' => 'failed:no_udp_data' , 'method' => "$scheme:$method" , 'remote_method' => 'socket' );
}
if ( strlen($ret) < $readlength ) {
array( 'tracker' => $http_host , 'state' => 'failed:invalid_udp_packet' , 'method' => "$scheme:$method" , 'remote_method' => 'socket' );
}
$retd = unpack("Naction/Ntransid" , $ret);
// Todo check for error string if response = 3
if ( $retd['action'] != 2 || $retd['transid'] != $transaction_id ) {
array( 'tracker' => $http_host , 'state' => 'failed:invalid_udp_response' , 'method' => "$scheme:$method" , 'remote_method' => 'socket' );
}

$index = 8;
$retd = unpack("Nleechers/Nseeders" , substr($ret , $index , 8));

return array( 'tracker' => $http_host , 'seeders' => $retd['seeders'] , 'leechers' => $retd['leechers'] , 'state' => 'ok' , 'method' => "$scheme:$method" , 'remote_method' => 'socket' );

} elseif ( function_exists('curl_init') ) {

if ( $ch = @curl_init() ) {
@curl_setopt($ch , CURLOPT_URL , $req_uri);
@curl_setopt($ch , CURLOPT_PORT , $http_port);
@curl_setopt($ch , CURLOPT_HEADER , false);
@curl_setopt($ch , CURLOPT_FOLLOWLOCATION , true);
@curl_setopt($ch , CURLOPT_RETURNTRANSFER , true);
@curl_setopt($ch , CURLOPT_CONNECTTIMEOUT , 3);
@curl_setopt($ch , CURLOPT_BUFFERSIZE , 1000);
@curl_setopt($ch , CURLOPT_USERAGENT , 'uTorrent/1820');

$result = @curl_exec($ch);
@curl_close($ch);
}
$remote_method = 'curl';
} elseif ( function_exists('fsockopen') ) {
if ( $fp = fsockopen($http_host , preg_replace("#[\D]#i" , "" , $http_port) , $errno , $errstr , 3) ) {
$h = "GET " . $http_path . ($http_params ? '?' . $http_params : '') . " HTTP/1.0
";
$h .= "Host: {$http_host}
";
$h .= "Connection: close
";
$h .= "User-Agent: uTorrent/1820

";
fputs($fp , $h);
$buff = '';
while ( !feof($fp) ) {
$buff .= fgets($fp , 128);
}
fclose($fp);
if ( $buff ) {
$data = explode("

" , $buff);
$result = $data[1];
}
}
$remote_method = 'socket';
} elseif ( function_exists('file_get_contents') && ini_get('allow_url_fopen') == 1 ) {
$context = @stream_context_create($opts);
$result = @file_get_contents($req_uri , false , $context);
$remote_method = 'file';
}
if ( !$result ) {
if ( $method == 'scrape' ) {
return get_remote_peers($urlorig , $info_hash , "announce");
} else {
return array( 'tracker' => $http_host , 'state' => 'failed:no_benc_result_or_timeout' , 'method' => "$scheme:$method" , 'remote_method' => $remote_method );
}

}


//var_dump($method);
$resulttemp = $result;
$result = bdec($result);

if ( !is_array($result) ) {
return array( 'tracker' => $http_host , 'state' => 'failed:unable_to_bdec:' . $resulttemp , 'method' => "$scheme:$method" , 'remote_method' => $remote_method );
}
unset($resulttemp);
// print('<pre>'); var_dump($result);
if ( $method == 'scrape' ) {

if ( $result['value']['files']['value'] ) {
$peersarray = @array_shift($result['value']['files']['value']);

return array(
'tracker' => $http_host ,
'seeders' => $peersarray['value']['complete']['value'] ,
'leechers' => $peersarray['value']['incomplete']['value'] ,
'state' => check_fail($result) ,
'method' => "$scheme:$method" ,
'remote_method' => $remote_method
);
} else {
return get_remote_peers($urlorig , $info_hash , "announce");
}
}

if ( $method == 'announce' ) {
return array(
'tracker' => $http_host ,
'seeders' => (is_array($result['value']['peers']['value']) ? count($result['value']['peers']['value']) : (strlen($result['value']['peers']['value']) / 6)) ,
'leechers' => 0 ,
'state' => check_fail($result) ,
'method' => "$scheme:$method" ,
'remote_method' => $remote_method
);
}

}

/**
* Gets port from adress
*
* @param string $urlInfo URL to be parsed
*
* @return int Port
*/
function getUrlPort($urlInfo)
{
if ( isset($urlInfo['port']) ) {
$port = $urlInfo['port'];
} else { // no port specified; get default port
if ( isset($urlInfo['scheme']) ) {
switch ( $urlInfo['scheme'] ) {
case 'http':
$port = 80; // default for http
break;
case 'udp': //default for udp
$port = 80;
break;
case 'https':
$port = 443; // default for https
break;

default:
$port = 0; // error; unsupported scheme
break;
}
} else {
$port = 80; // error; unknown scheme, using default 80 port
}
}

return $port;
}

/**
* Binary decodes a Value
*
* @param string $s Value to be decoded
*
* @return array Decoded value
*/
function bdec($s)
{
if ( preg_match('/^(\d+):/' , $s , $m) ) {
$l = $m[1];
$pl = strlen($l) + 1;
$v = substr($s , $pl , $l);
$ss = substr($s , 0 , $pl + $l);
if ( strlen($v) != $l ) {
return;
}

return array( 'type' => "string" , 'value' => $v , 'strlen' => strlen($ss) , 'string' => $ss );
}
if ( preg_match('/^i(-?\d+)e/' , $s , $m) ) {
$v = $m[1];
$ss = "i" . $v . "e";
if ( $v === "-0" ) {
return;
}
if ( $v[0] == "0" && strlen($v) != 1 ) {
return;
}

return array( 'type' => "integer" , 'value' => $v , 'strlen' => strlen($ss) , 'string' => $ss );
}
switch ( $s[0] ) {
case "l":
return bdec_list($s);
case "d":
return bdec_dict($s);
default:
return;
}
}

/**
* Binary decodes a dictionary
*
* @param string $s Dictionary to be decoded
*
* @return array Decoded dictionary
*/
function bdec_dict($s)
{
if ( $s[0] != "d" ) {
return;
}
$sl = strlen($s);
$i = 1;
$v = array();
$ss = "d";
for ( ; ; ) {
if ( $i >= $sl ) {
return;
}
if ( $s[$i] == "e" ) {
break;
}
$ret = bdec(substr($s , $i));
if ( !isset($ret) || !is_array($ret) || $ret["type"] != "string" ) {
return;
}
$k = $ret["value"];
$i += $ret["strlen"];
$ss .= $ret["string"];
if ( $i >= $sl ) {
return;
}
$ret = bdec(substr($s , $i));
if ( !isset($ret) || !is_array($ret) ) {
return;
}
$v[$k] = $ret;
$i += $ret["strlen"];
$ss .= $ret["string"];
}
$ss .= "e";

return array( 'type' => "dictionary" , 'value' => $v , 'strlen' => strlen($ss) , 'string' => $ss );
}

/**
* Checks that tracker returns failed event.
*
* @param string $result Bencoded result to be parsed
*
* @return string String to be used in remote tracker statistics
*/
function check_fail($result)
{
if ( isset($result['value']['failure reason']['value']) ) {
return 'failed:' . $result['value']['failure reason']['value'];
} elseif ( is_array($result) ) {
return 'failed';
} else {
return 'ok';

}
}

?>

<?php

include("torrent_functions.php");


$content = file_get_contents("torrent.torrent");
$content_d = bdecode($content);

if(empty($content_d))
exit('Something is wrong with the torrent. BDecode failed.');

$info_hash = sha1(BEncode($content_d['info']));

$meuObjeto = new Torrent();

for($j=0;$j<count($content_d['announce-list']);$j++)
{
$url=$content_d['announce-list'][$j][0];

print_r($meuObjeto->scrape(array($url), $info_hash));

}
?>

PHP

Nº del proyecto: #9264708

Sobre el proyecto

7 propuestas Proyecto remoto Activo Jan 10, 2016

7 freelancers están ofertando un promedio de $65 por este trabajo

waema

i can do this in an hour or less. i have done many php projects in the past. this should be easy for me. let me know once you are back so that we can talk.

$50 USD en 1 día
(165 comentarios)
7.2
anamaria1979

Propunerea nu a fost încă furnizată

$96 USD en 0 días
(152 comentarios)
6.6
mrnewict

Hi, I am an expert about PHP. I have read your project and confident that can handle it. I can help you . Please feel free to discuss with me. Best regards,

$77 USD en 3 días
(43 comentarios)
5.9
anupambaruah123

A proposal has not yet been provided

$88 USD en 1 día
(20 comentarios)
4.6
gopiande

A proposal has not yet been provided

$40 USD en 5 días
(11 comentarios)
2.8