mirror of
https://github.com/torrentpier/torrentpier.git
synced 2024-12-24 21:11:18 -08:00
106 lines
3.6 KiB
PHP
106 lines
3.6 KiB
PHP
<?php
|
||
/**
|
||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||
*
|
||
* @copyright Copyright (c) 2005-2024 TorrentPier (https://torrentpier.com)
|
||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||
*/
|
||
|
||
define('IN_TRACKER', true);
|
||
define('BB_ROOT', './../');
|
||
require dirname(__DIR__) . '/common.php';
|
||
|
||
global $bb_cfg;
|
||
|
||
if (!$bb_cfg['tracker']['scrape']) {
|
||
msg_die('Please disable SCRAPE!');
|
||
}
|
||
|
||
// Recover info_hash
|
||
if (isset($_GET['?info_hash']) && !isset($_GET['info_hash'])) {
|
||
$_GET['info_hash'] = $_GET['?info_hash'];
|
||
}
|
||
|
||
$info_hash = isset($_GET['info_hash']) ? (string)$_GET['info_hash'] : null;
|
||
|
||
// Verify info_hash
|
||
if (!isset($info_hash)) {
|
||
msg_die('info_hash was not provided');
|
||
}
|
||
|
||
// Store info hash in hex format
|
||
$info_hash_hex = bin2hex($info_hash);
|
||
|
||
// Check info_hash length
|
||
if (strlen($info_hash) !== 20) {
|
||
msg_die('Invalid info_hash: ' . (mb_check_encoding($info_hash, 'UTF8') ? $info_hash : $info_hash_hex));
|
||
}
|
||
|
||
// Handle multiple hashes
|
||
preg_match_all('/info_hash=([^&]*)/i', $_SERVER['QUERY_STRING'], $info_hash_array);
|
||
|
||
$torrents = [];
|
||
$info_hashes = [];
|
||
|
||
foreach ($info_hash_array[1] as $hash) {
|
||
$decoded_hash = urldecode($hash);
|
||
|
||
if (strlen($decoded_hash) !== 20) {
|
||
continue;
|
||
}
|
||
|
||
if ($scrape_cache = CACHE('tr_cache')->get(SCRAPE_LIST_PREFIX . bin2hex($decoded_hash))) {
|
||
$torrents['files'][$info_key = array_key_first($scrape_cache)] = $scrape_cache[$info_key];
|
||
} else {
|
||
$info_hashes[] = DB()->escape(($decoded_hash));
|
||
}
|
||
}
|
||
|
||
$info_hash_count = count($info_hashes);
|
||
|
||
if (!empty($info_hash_count)) {
|
||
if ($info_hash_count > $bb_cfg['max_scrapes']) {
|
||
$info_hashes = array_slice($info_hashes, 0, $bb_cfg['max_scrapes']);
|
||
}
|
||
|
||
$info_hashes_sql = implode('\', \'', $info_hashes);
|
||
|
||
/**
|
||
* Currently torrent clients send truncated v2 hashes (the design raises questions).
|
||
* https://github.com/bittorrent/bittorrent.org/issues/145#issuecomment-1720040343
|
||
*/
|
||
$info_hash_where = "tor.info_hash IN ('$info_hashes_sql') OR SUBSTRING(tor.info_hash_v2, 1, 20) IN ('$info_hashes_sql')";
|
||
|
||
$sql = "
|
||
SELECT tor.info_hash, tor.info_hash_v2, tor.complete_count, snap.seeders, snap.leechers
|
||
FROM " . BB_BT_TORRENTS . " tor
|
||
LEFT JOIN " . BB_BT_TRACKER_SNAP . " snap ON (snap.topic_id = tor.topic_id)
|
||
WHERE $info_hash_where
|
||
";
|
||
|
||
$scrapes = DB()->fetch_rowset($sql);
|
||
|
||
if (!empty($scrapes)) {
|
||
foreach ($scrapes as $scrape) {
|
||
$hash_v1 = !empty($scrape['info_hash']) ? $scrape['info_hash'] : '';
|
||
$hash_v2 = !empty($scrape['info_hash_v2']) ? substr($scrape['info_hash_v2'], 0, 20) : '';
|
||
$info_hash_scrape = (in_array(urlencode($hash_v1), $info_hash_array[1])) ? $hash_v1 : $hash_v2; // Replace logic to prioritize $hash_v2, in case of future prioritization of v2
|
||
|
||
$torrents['files'][$info_hash_scrape] = [
|
||
'complete' => (int)$scrape['seeders'],
|
||
'downloaded' => (int)$scrape['complete_count'],
|
||
'incomplete' => (int)$scrape['leechers']
|
||
];
|
||
CACHE('tr_cache')->set(SCRAPE_LIST_PREFIX . bin2hex($info_hash_scrape), array_slice($torrents['files'], -1, null, true), SCRAPE_LIST_EXPIRE);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Verify if torrent registered on tracker
|
||
if (empty($torrents)) {
|
||
msg_die('Torrent not registered, info_hash = ' . (mb_check_encoding($info_hash, 'UTF8') ? $info_hash : $info_hash_hex));
|
||
}
|
||
|
||
die(\Arokettu\Bencode\Bencode::encode($torrents));
|