View difference between Paste ID: PhKAPDJ1 and UY4nwN0c
SHOW: | | - or go back to the newest paste.
1
<?php
2-
//Подключаем главный системный файл
2+
3-
require 'functions.benc.php';
3+
/**
4
 * Converts String to Hex
5-
$dict = bdec_file('test.torrent', (1024 * 1024) );
5+
 * @param string $string String to be converted
6
 * @return string Converted string
7-
$v = $dict['value']['info']['value']['name']['value'];
7+
 */
8
function hex($string){
9-
print_r($dict);
9+
	$hex='';
10
	for ($i=0; $i < strlen($string); $i++){
11
		$hex .= dechex(ord($string[$i]));
12
	}
13
	return $hex;
14
}
15
16
/**
17
 * Makes magnet link e.g. instead of downloading .torrent
18
 * @param string $info_hash SHA1 infohash
19
 * @param string $filename Name to display
20
 * @param string|array $trackers Announce url or array of announce-urls of trackers
21
 * @return string
22
 */
23
function make_magnet($info_hash,$filename,$trackers){
24
	if (is_array($trackers)) $trackers = implode('&tr=',array_map('urlencode',$trackers)); else $trackers = urlencode($trackers);
25
	return 'magnet:?xt=urn:btih:'.$info_hash.'&dn='.urlencode($filename).'&tr='.$trackers;
26
27
}
28
29
30
31
/**
32
 * Makes magnet link to a DChub
33
 * @param string $tiger_hash TIGER infohash
34
 * @param string $filename Name to display
35
 * @param int $filesize Filesize in bytes
36
 * @param string|array $trackers Announce url or array of announce-urls of trackers
37
 * @return string
38
 */
39
function make_dc_magnet($tiger_hash,$filename,$filesize,$hubs){
40
	if (is_array($hubs)) $hubs = implode('&xs=',array_map('urlencode',$hubs)); else $hubs = urlencode($hubs);
41
	return 'magnet:?xt=urn:tree:tiger:'.$tiger_hash.'&xl='.$filesize.'&dn='.urlencode($filename).'&xs='.$hubs;
42
43
}
44
45
46
/**
47
 * Gets available retrackers (DChubs, and other stuff) by user's ip
48
 * @param boolean $all Get All Retrackers, ignoring subnet mask default false
49
 * @param string $table Table used to get stuff
50
 * @return array Array of retrackers or empty array if no retrackers present
51
 */
52
function get_retrackers($all = false, $table = 'retrackers') {
53
	// global $IPCHECK;
54
	global $db;
55
	$ip = getip();
56
	$row = $db->query("SELECT announce_url, mask FROM $table ORDER BY sort ASC");
57
	while ($res = $db->get_row() ) { $rtarray[] = $res; if ($all) $return[] = $res['announce_url']; }
58
59
	if (!$rtarray) return array();
60
61
	if ($all) return $return;
62
63
	foreach ($rtarray as $retracker) {
64
		
65
		if (!empty($retracker['mask'])) {
66
			$RTCHECK = new IPAddressSubnetSniffer(array($retracker['mask']));
67
68
			if ($RTCHECK->ip_is_allowed($ip)) $retrackers[] = $retracker['announce_url'];
69
		}
70
		else $retrackers[] = $retracker['announce_url'];
71
		// $retrackers[] = $retracker['announce_url'];
72
	}
73
74
	if ($retrackers) return $retrackers; else return array();
75
}
76
77
/**
78
 * Gets dictionary value
79
 * @param array $d torrent dictionary
80
 * @param string $k dictionary key
81
 * @param string $t value type
82
 * @return void|multiple Return value
83
 * @see bdec_dict()
84
 */
85
function dict_get($d, $k, $t) {
86
	if ($d["type"] != "dictionary")
87
	err("not a dictionary");
88
	$dd = $d["value"];
89
	if (!isset($dd[$k]))
90
	return;
91
	$v = $dd[$k];
92
	if ($v["type"] != $t)
93
	err("invalid dictionary entry type");
94
	return $v["value"];
95
}
96
97
/**
98
 * Check that dicitionary is valid
99
 * @param array $d Dictionary
100
 * @param string $s Undocumented
101
 * @return Ambigous <multitype:, unknown> Undocumented
102
 */
103
function dict_check($d, $s) {
104
	if ($d["type"] != "dictionary")
105
	err("not a dictionary");
106
	$a = explode(":", $s);
107
	$dd = $d["value"];
108
	$ret = array();
109
	foreach ($a as $k) {
110
		unset($t);
111
		if (preg_match('/^(.*)\((.*)\)$/', $k, $m)) {
112
			$k = $m[1];
113
			$t = $m[2];
114
		}
115
		if (!isset($dd[$k]))
116
		err("dictionary is missing key(s)");
117
		if (isset($t)) {
118
			if ($dd[$k]["type"] != $t)
119
			err("invalid entry in dictionary");
120
			$ret[] = $dd[$k]["value"];
121
		}
122
		else
123
		$ret[] = $dd[$k];
124
	}
125
	return $ret;
126
}
127
128
/**
129
 * Binary encodes an value
130
 * @param mixed $obj Value to be encoded
131
 * @return string Encoded value
132
 * @see benc_str()
133
 * @see benc_int()
134
 * @see benc_list()
135
 * @see benc_dict()
136
 */
137
function benc($obj) {
138
	if (!is_array($obj) || !isset($obj["type"]) || !isset($obj["value"]))
139
	return;
140
	$c = $obj["value"];
141
	switch ($obj["type"]) {
142
		case "string":
143
			return benc_str($c);
144
		case "integer":
145
			return benc_int($c);
146
		case "list":
147
			return benc_list($c);
148
		case "dictionary":
149
			return benc_dict($c);
150
		default:
151
			return;
152
	}
153
}
154
/**
155
 * Binary encodes a string
156
 * @param string $s String to be encoded
157
 * @return string Encoded string
158
 */
159
function benc_str($s) {
160
	return strlen($s) . ":$s";
161
}
162
/**
163
 * Binary encodes an integer
164
 * @param int $i Integer to be encoded
165
 * @return string Encoded Integer
166
 */
167
function benc_int($i) {
168
	return "i" . $i . "e";
169
}
170
/**
171
 * Binary encodes a list
172
 * @param array $a List to be encoded
173
 * @return string Encoded list
174
 */
175
function benc_list($a) {
176
	$s = "l";
177
	foreach ($a as $e) {
178
		$s .= benc($e);
179
	}
180
	$s .= "e";
181
	return $s;
182
}
183
184
/**
185
 * Binary encodes a dictionary
186
 * @param array $d Dictionary to be encoded
187
 * @return string Encoded dictionary
188
 * @see benc() benc_str()
189
 */
190
function benc_dict($d) {
191
	$s = "d";
192
	$keys = array_keys($d);
193
	sort($keys);
194
	foreach ($keys as $k) {
195
		$v = $d[$k];
196
		$s .= benc_str($k);
197
		$s .= benc($v);
198
	}
199
	$s .= "e";
200
	return $s;
201
}
202
/**
203
 * Binary decodes a torrent file
204
 * @param string $f File path to be decoded
205
 * @return array Decoded file
206
 * @see bdec()
207
 */
208
function bdec_file($f, $ms) {
209
	$fp = fopen($f, "rb");
210
211
	if (!$fp)
212
		return;
213
	$e = fread($fp, $ms);
214
	fclose($fp);
215
	return bdec($e);
216
}
217
/**
218
 * Binary decodes a Value
219
 * @param string $s Value to be decoded
220
 * @return array Decoded value
221
 */
222
function bdec($s) {
223
	if (preg_match('/^(\d+):/', $s, $m)) {
224
		$l = $m[1];
225
		$pl = strlen($l) + 1;
226
		$v = substr($s, $pl, $l);
227
		$ss = substr($s, 0, $pl + $l);
228
		if (strlen($v) != $l) return;
229
		return array('type' => "string", 'value' => $v, 'strlen' => strlen($ss), 'string' => $ss);
230
	}
231
	if (preg_match('/^i(\d+)e/', $s, $m)) {
232
		$v = $m[1];
233
		$ss = "i" . $v . "e";
234
		if ($v === "-0")
235
		return;
236
		if ($v[0] == "0" && strlen($v) != 1)
237
		return;
238
		return array('type' => "integer", 'value' => $v, 'strlen' => strlen($ss), 'string' => $ss);
239
	}
240
	switch ($s[0]) {
241
		case "l":
242
			return bdec_list($s);
243
		case "d":
244
			return bdec_dict($s);
245
		default:
246
			return;
247
	}
248
}
249
/**
250
 * Binary decodes a list
251
 * @param string $s List to be decoded
252
 * @return array Decoded list
253
 */
254
function bdec_list($s) {
255
	if ($s[0] != "l")
256
	return;
257
	$sl = strlen($s);
258
	$i = 1;
259
	$v = array();
260
	$ss = "l";
261
	for (;;) {
262
		if ($i >= $sl)
263
		return;
264
		if ($s[$i] == "e")
265
		break;
266
		$ret = bdec(substr($s, $i));
267
		if (!isset($ret) || !is_array($ret))
268
		return;
269
		$v[] = $ret;
270
		$i += $ret["strlen"];
271
		$ss .= $ret["string"];
272
	}
273
	$ss .= "e";
274
	return array('type' => "list", 'value' => $v, 'strlen' => strlen($ss), 'string' => $ss);
275
}
276
/**
277
 * Binary decodes a dictionary
278
 * @param string $s Dictionary to be decoded
279
 * @return array Decoded dictionary
280
 */
281
function bdec_dict($s) {
282
	if ($s[0] != "d")
283
	return;
284
	$sl = strlen($s);
285
	$i = 1;
286
	$v = array();
287
	$ss = "d";
288
	for (;;) {
289
		if ($i >= $sl)
290
		return;
291
		if ($s[$i] == "e")
292
		break;
293
		$ret = bdec(substr($s, $i));
294
		if (!isset($ret) || !is_array($ret) || $ret["type"] != "string")
295
		return;
296
		$k = $ret["value"];
297
		$i += $ret["strlen"];
298
		$ss .= $ret["string"];
299
		if ($i >= $sl)
300
		return;
301
		$ret = bdec(substr($s, $i));
302
		if (!isset($ret) || !is_array($ret))
303
		return;
304
		$v[$k] = $ret;
305
		$i += $ret["strlen"];
306
		$ss .= $ret["string"];
307
	}
308
	$ss .= "e";
309
	return array('type' => "dictionary", 'value' => $v, 'strlen' => strlen($ss), 'string' => $ss);
310
}
311
312
/**
313
 * Gets announce urls from DECODED torrent dicrionary
314
 * @param array $dict Decoded torrent dictionary
315
 * @return array|boolean Array of urls on success, false on fail
316
 */
317
function get_announce_urls($dict){
318
	if ($dict['value']['announce'] && !$dict['value']['announce-list']) {$anarray[0] = $dict['value']['announce']['value']; return $anarray; }
319
320
	if ($dict['value']['announce-list']) {
321
322
		if (!$dict['value']['announce-list']['value']) return false;
323
		$retrackers = get_retrackers(true);
324
		foreach ($dict['value']['announce-list']['value'] as $urls) {
325
			if (!in_array($urls['value'][0]['value'],$retrackers))
326
			$anarray[] = $urls['value'][0]['value'];
327
		}
328
329
		return $anarray;
330
331
	}
332
}
333
334
/**
335
 * Puts announce urls into DECODED dictionary. DICT is global.
336
 * @param array $dict Decoded dictionary to be processed
337
 * @param array $anarray Array of announce urls. First element good to be a local announce-url
338
 * @return void Uses global $dict
339
 */
340
function put_announce_urls($dict,$anarray){
341
	global $dict;
342
	$liststring = '';
343
	unset($dict['value']['announce']);
344
	unset($dict['value']['announce-list']);
345
	$dict['value']['announce'] = bdec(benc_str($anarray[0]));
346
347
348
	if (is_array($anarray))
349
	foreach ($anarray as $announce) {
350
		$announces[] = array('type' => 'list', 'value' => array(bdec(benc_str($announce))), 'strlen' => strlen("l".$announce."e"), 'string' => "l".$announce."e");
351
		$liststring .= "l".$announce."e";
352
	}
353
	$dict['value']['announce-list']['type'] = 'list';
354
	$dict['value']['announce-list']['value'] = $announces;
355
356
357
	$dict['value']['announce-list']['string'] = "l".$liststring."e";
358
	$dict['value']['announce-list']['strlen'] = strlen($dict['value']['announce-list']['string']);
359
360
}
361
362
/**
363
 * Gets port from adress
364
 * @param string $urlInfo URL to be parsed
365
 * @return int Port
366
 */
367
function getUrlPort($urlInfo) {
368
	if( isset($urlInfo['port']) ) {
369
		$port = $urlInfo['port'];
370
	} else { // no port specified; get default port
371
		if (isset($urlInfo['scheme'])) {
372
			switch($urlInfo['scheme']) {
373
				case 'http':
374
					$port = 80; // default for http
375
					break;
376
				case 'https':
377
					$port = 443; // default for https
378
					break;
379
				default:
380
					$port = 0; // error; unsupported scheme
381
					break;
382
			}
383
		} else {
384
			$port = 80; // error; unknown scheme, using default 80 port
385
		}
386
	}
387
	return $port;
388
}
389
390
/**
391
 * Checks that tracker returns failed event.
392
 * @param string $result Bencoded result to be parsed
393
 * @return string String to be used in remote tracker statistics
394
 */
395
function check_fail($result) {
396
	if ($result['value']['failure reason']['value']) return 'failed:'.$result['value']['failure reason']['value'].'_'; else return 'ok_';
397
}
398
399
/**
400
 * Gets amout of remote tracker peers. May be recursivity.
401
 * @param string $url Announce url of request
402
 * @param string $info_hash Info-hash of torrent to be parsed
403
 * @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.
404
 * @return array Result array ('tracker','seeders','leechers','state');
405
 */
406
function get_remote_peers($url, $info_hash, $method = 'scrape') {
407
	global $CRON;
408
	if ($method == "announce") {
409
		$get_params = array(
410
    			"info_hash" => pack("H*", $info_hash),
411
    			"peer_id" => "-UT1820-5dmPcUOYGnrx",
412
    			"port" => rand(10000, 65535),
413
    			"uploaded" => 0,
414
				"no_peer_id" => 1,
415
    			"downloaded" => 0,
416
				"compact" => 1,
417
    			"left" => 1,
418
    			"numwant" => 9999
419
		);
420
	} else {
421
		$urlorig=$url;
422
		$url = str_replace('announce', 'scrape', $url);
423
		$get_params = array(
424
    			"info_hash" => pack("H*", $info_hash)
425
		);
426
	}
427
428
429
	$urlInfo = @parse_url($url);
430
	$http_host = $urlInfo['host'];
431
	$http_port = getUrlPort($urlInfo);
432
433
	if ($http_port === 0)
434
	return array('tracker' => $http_host, 'state' => 'failed:no_port_detected_'.$method);
435
	else
436
	$http_port = ':' . $http_port;
437
438
	$http_path = $urlInfo['path'];
439
	$get_request_params = explode('&', $urlInfo['query']);
440
441
	foreach (array_filter($get_request_params) as $array_value) {
442
		list($key, $value) = explode('=', $array_value);
443
		$new_get_request_params[$key] = $value;
444
	}
445
446
	if (!$new_get_request_params) $new_get_request_params=array();
447
	// Params gathering complete
448
449
	// Creating params
450
	$http_params = @http_build_query(@array_merge($new_get_request_params, $get_params));
451
452
	$opts = array('http' =>
453
	array(
454
        'method' => 'GET',
455
    	'header' => 'User-Agent: uTorrent/1820',
456
    	'timeout' => $CRON['multi_timeout']
457
	//'Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2',
458
	)
459
	);
460
461
	$context = @stream_context_create($opts);
462
	$result = @file_get_contents('http://'.$http_host.$http_port.$http_path.($http_params ? '?'.$http_params : ''), false, $context);
463
	// $result = true;
464
	if (!$result)
465
	{
466
		if ($method=='scrape')
467
		return get_remote_peers($urlorig, $info_hash, "announce"); else
468
		return array('tracker' => $http_host, 'state' => 'failed:no_benc_result_or_timeout_'.$method);
469
470
	}
471
472
473
	//var_dump($method);
474
	$resulttemp=$result;
475
	$result = @bdec($result);
476
477
	if (!is_array($result)) return array('tracker' => $http_host, 'state' => 'failed:unable_to_bdec:'.$resulttemp.'_'.$method);
478
	unset($resulttemp);
479
	//    print('<pre>'); var_dump($result);
480
	if ($method == 'scrape') {
481
482
		if ($result['value']['files']['value']) {
483
			$peersarray = @array_shift($result['value']['files']['value']);
484
			return array('tracker' => $http_host, 'seeders' => $peersarray['value']['complete']['value'], 'leechers' => $peersarray['value']['incomplete']['value'], 'state' => check_fail($result).$method);
485
		} else return get_remote_peers($urlorig, $info_hash, "announce");
486
	}
487
488
	if($method == 'announce') {
489
		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);
490
	}
491
492
}
493
494
?>