mirror of
https://github.com/torrentpier/torrentpier
synced 2025-08-21 13:54:02 -07:00
BitTorrent v2 support 🐸 (#866)
* BitTorrent v2 support * Update TorrentFileList.php * BitTorrent v2 support Added support for BitTorrent v2 file hash displaying, magnet links * Updated * Updated * Update changes.txt * Update Torrent.php * Update Torrent.php * Updated * Added support in announcer * Update announce.php * Update scrape.php * Update scrape.php * Update scrape.php * Changed the condition for single files * Update scrape.php * Update displaying_torrent.php * Update displaying_torrent.php * Update displaying_torrent.php --------- Co-authored-by: Roman Kelesidis <roman25052006.kelesh@gmail.com>
This commit is contained in:
parent
a2e8817b5f
commit
fadce7a297
10 changed files with 104 additions and 27 deletions
|
@ -63,12 +63,22 @@ $passkey = ${$passkey_key} ?? null;
|
|||
|
||||
// Verify request
|
||||
// Required params (info_hash, peer_id, port, uploaded, downloaded, left, passkey)
|
||||
if (!isset($info_hash) || strlen($info_hash) != 20) {
|
||||
msg_die('Invalid info_hash');
|
||||
if (!isset($info_hash)) {
|
||||
msg_die('info_hash does not exists');
|
||||
}
|
||||
if (!isset($peer_id) || strlen($peer_id) != 20) {
|
||||
msg_die('Invalid peer_id');
|
||||
}
|
||||
|
||||
// Check info_hash version
|
||||
if (strlen($info_hash) == 32) {
|
||||
$is_bt_v2 = true;
|
||||
} elseif (strlen($info_hash) == 20) {
|
||||
$is_bt_v2 = false;
|
||||
} else {
|
||||
msg_die('Invalid info_hash');
|
||||
}
|
||||
|
||||
if (!isset($port) || $port < 0 || $port > 0xFFFF) {
|
||||
msg_die('Invalid port');
|
||||
}
|
||||
|
@ -178,13 +188,14 @@ if ($lp_info) {
|
|||
} else {
|
||||
// Verify if torrent registered on tracker and user authorized
|
||||
$info_hash_sql = rtrim(DB()->escape($info_hash), ' ');
|
||||
$info_hash_where = $is_bt_v2 ? "WHERE tor.info_hash_v2 = '$info_hash_sql'" : "WHERE tor.info_hash = '$info_hash_sql'";
|
||||
$passkey_sql = DB()->escape($passkey);
|
||||
|
||||
$sql = "
|
||||
SELECT tor.topic_id, tor.poster_id, tor.tor_type, u.*
|
||||
FROM " . BB_BT_TORRENTS . " tor
|
||||
LEFT JOIN " . BB_BT_USERS . " u ON u.auth_key = '$passkey_sql'
|
||||
WHERE tor.info_hash = '$info_hash_sql'
|
||||
$info_hash_where
|
||||
LIMIT 1
|
||||
";
|
||||
|
||||
|
|
|
@ -22,11 +22,21 @@ if (isset($_GET['?info_hash']) && !isset($_GET['info_hash'])) {
|
|||
$_GET['info_hash'] = $_GET['?info_hash'];
|
||||
}
|
||||
|
||||
if (!isset($_GET['info_hash']) || strlen($_GET['info_hash']) != 20) {
|
||||
msg_die('Invalid info_hash');
|
||||
$is_bt_v2 = null;
|
||||
$info_hash = isset($_GET['info_hash']) ? (string)$_GET['info_hash'] : null;
|
||||
|
||||
if (!isset($info_hash)) {
|
||||
msg_die('info_hash does not exists');
|
||||
}
|
||||
|
||||
$info_hash = $_GET['info_hash'];
|
||||
// Check info_hash version
|
||||
if (strlen($info_hash) == 32) {
|
||||
$is_bt_v2 = true;
|
||||
} elseif (strlen($info_hash) == 20) {
|
||||
$is_bt_v2 = false;
|
||||
} else {
|
||||
msg_die('Invalid info_hash');
|
||||
}
|
||||
|
||||
function msg_die($msg)
|
||||
{
|
||||
|
@ -42,15 +52,20 @@ function msg_die($msg)
|
|||
require __DIR__ . '/includes/init_tr.php';
|
||||
|
||||
$info_hash_sql = rtrim(DB()->escape($info_hash), ' ');
|
||||
$info_hash_where = $is_bt_v2 ? "WHERE tor.info_hash_v2 = '$info_hash_sql'" : "WHERE tor.info_hash = '$info_hash_sql'";
|
||||
|
||||
$row = DB()->fetch_row("
|
||||
SELECT 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 tor.info_hash = '$info_hash_sql'
|
||||
$info_hash_where
|
||||
LIMIT 1
|
||||
");
|
||||
|
||||
if (!$row) {
|
||||
msg_die('Torrent not registered, info_hash = ' . bin2hex($info_hash_sql));
|
||||
}
|
||||
|
||||
$output['files'][$info_hash] = [
|
||||
'complete' => (int)$row['seeders'],
|
||||
'downloaded' => (int)$row['complete_count'],
|
||||
|
|
|
@ -274,6 +274,7 @@ DROP TABLE IF EXISTS `bb_bt_torrents`;
|
|||
CREATE TABLE IF NOT EXISTS `bb_bt_torrents`
|
||||
(
|
||||
`info_hash` VARBINARY(20) NOT NULL DEFAULT '',
|
||||
`info_hash_v2` VARBINARY(32) NOT NULL DEFAULT '',
|
||||
`post_id` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`poster_id` MEDIUMINT(9) NOT NULL DEFAULT '0',
|
||||
`topic_id` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
|
||||
|
|
|
@ -67,3 +67,4 @@ INSERT INTO `bb_cron` (`cron_active`, `cron_title`, `cron_script`, `schedule`, `
|
|||
`disable_board`, `run_counter`) VALUES ('1', 'PM cleanup', 'clean_pm.php', 'daily', '', '05:00:00', '70', '', '', '', '1', '', '0', '1', '0');
|
||||
ALTER TABLE `bb_posts_text` CHANGE `post_text` `post_text` MEDIUMTEXT NOT NULL;
|
||||
ALTER TABLE `bb_privmsgs_text` CHANGE `privmsgs_text` `privmsgs_text` MEDIUMTEXT NOT NULL;
|
||||
ALTER TABLE `bb_bt_torrents` ADD COLUMN `info_hash_v2` VARBINARY(32) NOT NULL DEFAULT '';
|
||||
|
|
|
@ -155,7 +155,7 @@ if ($tor_reged && $tor_info) {
|
|||
$tor_type = $tor_info['tor_type'];
|
||||
|
||||
// Magnet link
|
||||
$tor_magnet = create_magnet($tor_info['info_hash'], $user_passkey);
|
||||
$tor_magnet = create_magnet($tor_info['info_hash'], $tor_info['info_hash_v2'], $user_passkey);
|
||||
|
||||
// ratio limits
|
||||
$min_ratio_dl = $bb_cfg['bt_min_ratio_allow_dl_tor'];
|
||||
|
|
|
@ -1760,11 +1760,12 @@ function decode_text_match($txt)
|
|||
* Create magnet link
|
||||
*
|
||||
* @param string $infohash
|
||||
* @param string $infohash_v2
|
||||
* @param string|bool $auth_key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function create_magnet($infohash, $auth_key): string
|
||||
function create_magnet(string $infohash, string $infohash_v2, $auth_key): string
|
||||
{
|
||||
global $bb_cfg, $images;
|
||||
|
||||
|
@ -1778,7 +1779,7 @@ function create_magnet($infohash, $auth_key): string
|
|||
return false;
|
||||
}
|
||||
|
||||
return '<a href="magnet:?xt=urn:btih:' . bin2hex($infohash) . '&tr=' . urlencode($bb_cfg['bt_announce_url'] . "?{$bb_cfg['passkey_key']}=$auth_key") . '"><img src="' . $images['icon_magnet'] . '" width="12" height="12" border="0" /></a>';
|
||||
return '<a href="magnet:?xt=urn:btih:' . bin2hex($infohash) . (!empty($infohash_v2) ? '&xt=urn:btmh:1220' . bin2hex($infohash_v2) : '') . '&tr=' . urlencode($bb_cfg['bt_announce_url'] . "?{$bb_cfg['passkey_key']}=$auth_key") . '"><img src="' . $images['icon_magnet'] . '" width="12" height="12" border="0" /></a>';
|
||||
}
|
||||
|
||||
function set_die_append_msg($forum_id = null, $topic_id = null, $group_id = null)
|
||||
|
|
|
@ -287,7 +287,8 @@ class Torrent
|
|||
$topic_id = $torrent['topic_id'];
|
||||
$forum_id = $torrent['forum_id'];
|
||||
$poster_id = $torrent['poster_id'];
|
||||
$info_hash = null;
|
||||
$info_hash = $info_hash_v2 = null;
|
||||
$info_hash_sql = $info_hash_v2_sql = null;
|
||||
|
||||
if ($torrent['extension'] !== TORRENT_EXT) {
|
||||
return self::torrent_error_exit($lang['NOT_TORRENT']);
|
||||
|
@ -345,10 +346,23 @@ class Torrent
|
|||
return self::torrent_error_exit($lang['TORFILE_INVALID']);
|
||||
}
|
||||
|
||||
// Check if torrent contains info_hash v2
|
||||
$bt_v2 = false;
|
||||
if (($info['meta version'] ?? null) == 2 && is_array($info['file tree'] ?? null)) {
|
||||
$bt_v2 = true;
|
||||
}
|
||||
|
||||
// Getting info_hash v1
|
||||
$info_hash = pack('H*', sha1(\SandFox\Bencode\Bencode::encode($info)));
|
||||
$info_hash_sql = rtrim(DB()->escape($info_hash), ' ');
|
||||
$info_hash_md5 = md5($info_hash);
|
||||
|
||||
// Getting info_hash v2
|
||||
if ($bt_v2) {
|
||||
$info_hash_v2 = pack('H*', hash('sha256', \SandFox\Bencode\Bencode::encode($info)));
|
||||
$info_hash_v2_sql = rtrim(DB()->escape($info_hash_v2), ' ');
|
||||
}
|
||||
|
||||
// Ocelot
|
||||
if ($bb_cfg['ocelot']['enabled']) {
|
||||
self::ocelot_update_tracker('add_torrent', ['info_hash' => rawurlencode($info_hash), 'id' => $topic_id, 'freetorrent' => 0]);
|
||||
|
@ -366,7 +380,10 @@ class Torrent
|
|||
$totallen = (float)$info['length'];
|
||||
} elseif (isset($info['files']) && \is_array($info['files'])) {
|
||||
foreach ($info['files'] as $fn => $f) {
|
||||
$totallen += (float)$f['length'];
|
||||
// Exclude padding files
|
||||
if (($f['attr'] ?? null) !== 'p') {
|
||||
$totallen += (float)$f['length'];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return self::torrent_error_exit($lang['TORFILE_INVALID']);
|
||||
|
@ -374,8 +391,8 @@ class Torrent
|
|||
|
||||
$size = sprintf('%.0f', (float)$totallen);
|
||||
|
||||
$columns = ' info_hash, post_id, poster_id, topic_id, forum_id, attach_id, size, reg_time, tor_status';
|
||||
$values = "'$info_hash_sql', $post_id, $poster_id, $topic_id, $forum_id, $attach_id, '$size', $reg_time, $tor_status";
|
||||
$columns = 'info_hash, info_hash_v2, post_id, poster_id, topic_id, forum_id, attach_id, size, reg_time, tor_status';
|
||||
$values = "'$info_hash_sql', '$info_hash_v2_sql', $post_id, $poster_id, $topic_id, $forum_id, $attach_id, '$size', $reg_time, $tor_status";
|
||||
|
||||
$sql = "INSERT INTO " . BB_BT_TORRENTS . " ($columns) VALUES ($values)";
|
||||
|
||||
|
|
|
@ -43,18 +43,45 @@ class TorrentFileList
|
|||
{
|
||||
global $html;
|
||||
|
||||
$this->build_filelist_array();
|
||||
if (($this->tor_decoded['info']['meta version'] ?? null) == 2 && is_array($this->tor_decoded['info']['file tree'] ?? null)) {
|
||||
// v2
|
||||
function fileTree($array, $name = '')
|
||||
{
|
||||
$folders = [];
|
||||
$rootFiles = [];
|
||||
|
||||
if ($this->multiple) {
|
||||
if ($this->files_ary['/'] !== '') {
|
||||
$this->files_ary = array_merge($this->files_ary, $this->files_ary['/']);
|
||||
unset($this->files_ary['/']);
|
||||
foreach ($array as $key => $value) {
|
||||
if (is_array($value) && !isset($value[''])) {
|
||||
$html_v2 = fileTree($value);
|
||||
$folders[] = "<li><span class=\"b\">$key</span><ul>$html_v2</ul></li>";
|
||||
} else {
|
||||
$length = $value['']['length'];
|
||||
$root = bin2hex($value['']['pieces root'] ?? '');
|
||||
$rootFiles[] = "<li><span>$key<i>$length</i> <h style='color:gray;'>$root</h></span></li>";
|
||||
}
|
||||
}
|
||||
|
||||
$allItems = array_merge($folders, $rootFiles);
|
||||
|
||||
return '<div class="tor-root-dir">' . (empty($folders) ? '' : $name) . '</div><ul class="tree-root">' . implode('', $allItems) . '</ul>';
|
||||
}
|
||||
$filelist = $html->array2html($this->files_ary);
|
||||
return "<div class=\"tor-root-dir\">{$this->root_dir}</div>$filelist";
|
||||
}
|
||||
|
||||
return implode('', $this->files_ary['/']);
|
||||
return fileTree($this->tor_decoded['info']['file tree'], $this->tor_decoded['info']['name']);
|
||||
} else {
|
||||
// v1
|
||||
$this->build_filelist_array();
|
||||
|
||||
if ($this->multiple) {
|
||||
if ($this->files_ary['/'] !== '') {
|
||||
$this->files_ary = array_merge($this->files_ary, $this->files_ary['/']);
|
||||
unset($this->files_ary['/']);
|
||||
}
|
||||
$filelist = $html->array2html($this->files_ary);
|
||||
return "<div class=\"tor-root-dir\">{$this->root_dir}</div>$filelist";
|
||||
}
|
||||
|
||||
return implode('', $this->files_ary['/']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -81,6 +108,10 @@ class TorrentFileList
|
|||
if (!isset($f['path']) || !\is_array($f['path'])) {
|
||||
continue;
|
||||
}
|
||||
// Exclude padding files
|
||||
if (($f['attr'] ?? null) === 'p') {
|
||||
continue;
|
||||
}
|
||||
array_deep($f['path'], 'clean_tor_dirname');
|
||||
|
||||
$length = isset($f['length']) ? (float)$f['length'] : 0;
|
||||
|
|
|
@ -645,7 +645,7 @@ if ($allowed_forums) {
|
|||
$select = "
|
||||
SELECT
|
||||
tor.topic_id, tor.post_id, tor.attach_id, tor.size, tor.reg_time, tor.complete_count, tor.seeder_last_seen, tor.tor_status, tor.tor_type,
|
||||
t.topic_title, t.topic_time, t.topic_replies, t.topic_views, sn.seeders, sn.leechers, tor.info_hash
|
||||
t.topic_title, t.topic_time, t.topic_replies, t.topic_views, sn.seeders, sn.leechers, tor.info_hash, tor.info_hash_v2
|
||||
";
|
||||
$select .= (!$hide_speed) ? ", sn.speed_up, sn.speed_down" : '';
|
||||
$select .= (!$hide_forum) ? ", tor.forum_id" : '';
|
||||
|
@ -702,7 +702,7 @@ if ($allowed_forums) {
|
|||
$s_last = $tor['seeder_last_seen'];
|
||||
$att_id = $tor['attach_id'];
|
||||
$size = $tor['size'];
|
||||
$tor_magnet = create_magnet($tor['info_hash'], \TorrentPier\Legacy\Torrent::getPasskey($user_id));
|
||||
$tor_magnet = create_magnet($tor['info_hash'], $tor['info_hash_v2'], \TorrentPier\Legacy\Torrent::getPasskey($user_id));
|
||||
$compl = $tor['complete_count'];
|
||||
$dl_sp = ($dl) ? humn_size($dl, 0, 'KB') . '/s' : '0 KB/s';
|
||||
$ul_sp = ($ul) ? humn_size($ul, 0, 'KB') . '/s' : '0 KB/s';
|
||||
|
|
|
@ -285,7 +285,7 @@ if ($forum_data['allow_reg_tracker']) {
|
|||
}
|
||||
|
||||
$select_tor_sql = ',
|
||||
bt.auth_key, tor.info_hash, tor.size AS tor_size, tor.reg_time, tor.complete_count, tor.seeder_last_seen, tor.attach_id, tor.tor_status, tor.tor_type,
|
||||
bt.auth_key, tor.info_hash, tor.info_hash_v2, tor.size AS tor_size, tor.reg_time, tor.complete_count, tor.seeder_last_seen, tor.attach_id, tor.tor_status, tor.tor_type,
|
||||
sn.seeders, sn.leechers
|
||||
';
|
||||
$select_tor_sql .= ($join_dl) ? ', dl.user_status AS dl_status' : '';
|
||||
|
@ -470,7 +470,7 @@ foreach ($topic_rowset as $topic) {
|
|||
));
|
||||
|
||||
if (isset($topic['tor_size'])) {
|
||||
$tor_magnet = create_magnet($topic['info_hash'], ($topic['auth_key'] ?? false));
|
||||
$tor_magnet = create_magnet($topic['info_hash'], $topic['info_hash_v2'], ($topic['auth_key'] ?? false));
|
||||
|
||||
$template->assign_block_vars('t.tor', array(
|
||||
'SEEDERS' => (int)$topic['seeders'],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue