diff --git a/bt/announce.php b/bt/announce.php
index 6848b65a..f6d10fc5 100644
--- a/bt/announce.php
+++ b/bt/announce.php
@@ -74,10 +74,25 @@ $passkey = isset($$passkey_key) ? $$passkey_key : null;
// Verify request
// Required params (info_hash, peer_id, port, uploaded, downloaded, left, passkey)
-if (!isset($info_hash) || strlen($info_hash) != 20)
+if (!isset($info_hash))
+{
+ msg_die('info_hash does not exist');
+}
+
+// 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($peer_id) || strlen($peer_id) != 20)
{
msg_die('Invalid peer_id');
@@ -225,13 +240,14 @@ 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
";
@@ -508,4 +524,4 @@ if (!$output)
echo bencode($output);
tracker_exit();
-exit;
\ No newline at end of file
+exit;
diff --git a/bt/scrape.php b/bt/scrape.php
index e09ebbb9..ce28a875 100644
--- a/bt/scrape.php
+++ b/bt/scrape.php
@@ -17,7 +17,28 @@ if (!isset($_GET['info_hash']) || strlen($_GET['info_hash']) != 20)
msg_die('Invalid info_hash');
}
-$info_hash = $_GET['info_hash'];
+$is_bt_v2 = null;
+$info_hash = isset($_GET['info_hash']) ? (string)$_GET['info_hash'] : null;
+
+// Verify info_hash
+if (!isset($info_hash))
+{
+ msg_die('info_hash does not exist');
+}
+
+// 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)
{
@@ -36,15 +57,21 @@ define('TR_ROOT', './');
require(TR_ROOT . '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] = array(
'complete' => (int) $row['seeders'],
'downloaded' => (int) $row['complete_count'],
@@ -54,4 +81,4 @@ $output['files'][$info_hash] = array(
echo bencode($output);
tracker_exit();
-exit;
\ No newline at end of file
+exit;
diff --git a/install/sql/mysql.sql b/install/sql/mysql.sql
index 7ddbb546..ce36ddb8 100644
--- a/install/sql/mysql.sql
+++ b/install/sql/mysql.sql
@@ -255,6 +255,7 @@ CREATE TABLE IF NOT EXISTS `bb_bt_torhelp` (
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',
diff --git a/install/upgrade/changes.txt b/install/upgrade/changes.txt
index 35c5442a..cfaa0616 100644
--- a/install/upgrade/changes.txt
+++ b/install/upgrade/changes.txt
@@ -99,3 +99,6 @@ DELETE FROM `bb_smilies` WHERE `code` = ':ad:';
INSERT INTO `bb_smilies` (`code`, `smile_url`, `emoticon`) VALUES (':cd:', 'cd.gif', 'cd');
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;
+
+// 2.1.5 (LTS 2023.08)
+ALTER TABLE `bb_bt_torrents` ADD COLUMN `info_hash_v2` VARBINARY(32) NOT NULL DEFAULT '';
diff --git a/library/ajax/view_torrent.php b/library/ajax/view_torrent.php
index 0a045021..afa68f32 100644
--- a/library/ajax/view_torrent.php
+++ b/library/ajax/view_torrent.php
@@ -103,6 +103,11 @@ class torrent
{
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;
diff --git a/library/attach_mod/displaying_torrent.php b/library/attach_mod/displaying_torrent.php
index 1ad72c4e..a812482a 100644
--- a/library/attach_mod/displaying_torrent.php
+++ b/library/attach_mod/displaying_torrent.php
@@ -154,7 +154,7 @@ if ($tor_reged && $tor_info)
// Magnet link
$passkey = DB()->fetch_row("SELECT auth_key FROM ". BB_BT_USERS ." WHERE user_id = ". (int) $bt_user_id ." LIMIT 1");
- $tor_magnet = create_magnet($tor_info['info_hash'], $passkey['auth_key']);
+ $tor_magnet = create_magnet($tor_info['info_hash'], $tor_info['info_hash_v2'], $passkey['auth_key']);
// ratio limits
$min_ratio_dl = $bb_cfg['bt_min_ratio_allow_dl_tor'];
@@ -231,6 +231,7 @@ if ($tor_reged && $tor_info)
'FILESIZE' => $tor_file_size,
'MAGNET' => $tor_magnet,
'HASH' => strtoupper(bin2hex($tor_info['info_hash'])),
+ 'HASH_V2' => !empty($tor_info['info_hash_v2']) ? strtoupper(bin2hex($tor_info['info_hash_v2'])) : false,
'DOWNLOAD_COUNT' => sprintf($lang['DOWNLOAD_NUMBER'], $download_count),
'REGED_TIME' => bb_date($tor_info['reg_time']),
'REGED_DELTA' => delta_time($tor_info['reg_time']),
diff --git a/library/includes/functions.php b/library/includes/functions.php
index e4e0aabc..9601c321 100644
--- a/library/includes/functions.php
+++ b/library/includes/functions.php
@@ -2574,7 +2574,7 @@ function pad_with_space ($str)
return ($str) ? " $str " : $str;
}
-function create_magnet ($infohash, $auth_key)
+function create_magnet ($infohash, $infohash_v2, $auth_key)
{
global $bb_cfg, $images, $lang, $userdata;
@@ -2597,7 +2597,7 @@ function create_magnet ($infohash, $auth_key)
}
$passkey_url = $passkey ? "?{$bb_cfg['passkey_key']}=$auth_key" : '';
- return '';
+ return '
';
}
function set_die_append_msg ($forum_id = null, $topic_id = null, $group_id = null)
@@ -2795,15 +2795,30 @@ function hash_search ($hash)
global $lang;
$hash = htmlCHR(trim($hash));
+ $info_hash_where = null;
- if (!isset($hash) || mb_strlen($hash, 'UTF-8') != 40)
+ if (!isset($hash))
{
bb_die(sprintf($lang['HASH_INVALID'], $hash));
}
$info_hash = DB()->escape(pack("H*", $hash));
- if ($row = DB()->fetch_row("SELECT topic_id FROM " . BB_BT_TORRENTS . " WHERE info_hash = '$info_hash'"))
+ // Check info_hash version
+ if (mb_strlen($hash, 'UTF-8') == 40)
+ {
+ $info_hash_where = "WHERE info_hash = '$info_hash'";
+ }
+ elseif (mb_strlen($hash, 'UTF-8') == 64)
+ {
+ $info_hash_where = "WHERE info_hash_v2 = '$info_hash'";
+ }
+ else
+ {
+ bb_die(sprintf($lang['HASH_INVALID'], $hash));
+ }
+
+ if ($row = DB()->fetch_row("SELECT topic_id FROM " . BB_BT_TORRENTS . " $info_hash_where"))
{
redirect(TOPIC_URL . $row['topic_id']);
}
diff --git a/library/includes/functions_torrent.php b/library/includes/functions_torrent.php
index 7c391262..e0b041de 100644
--- a/library/includes/functions_torrent.php
+++ b/library/includes/functions_torrent.php
@@ -249,7 +249,8 @@ function tracker_register ($attach_id, $mode = '', $tor_status = TOR_NOT_APPROVE
$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 torrent_error_exit($lang['NOT_TORRENT']);
if (!$torrent['allow_reg_tracker']) return torrent_error_exit($lang['REG_NOT_ALLOWED_IN_THIS_FORUM']);
@@ -294,10 +295,25 @@ function tracker_register ($attach_id, $mode = '', $tor_status = TOR_NOT_APPROVE
return 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(bencode($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', bencode($info)));
+ $info_hash_v2_sql = rtrim(DB()->escape($info_hash_v2), ' ');
+ }
+
// Ocelot
if ($bb_cfg['ocelot']['enabled'])
{
@@ -321,7 +337,11 @@ function tracker_register ($attach_id, $mode = '', $tor_status = TOR_NOT_APPROVE
{
foreach ($info['files'] as $fn => $f)
{
- $totallen += (float) $f['length'];
+ // Exclude padding files
+ if (($f['attr'] ?? null) !== 'p')
+ {
+ $totallen += (float) $f['length'];
+ }
}
}
else
@@ -331,8 +351,8 @@ function tracker_register ($attach_id, $mode = '', $tor_status = TOR_NOT_APPROVE
$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, post_id, poster_id, topic_id, forum_id, attach_id, size, reg_time, tor_status, info_hash_v2';
+ $values = "'$info_hash_sql', $post_id, $poster_id, $topic_id, $forum_id, $attach_id, '$size', $reg_time, $tor_status, '$info_hash_v2_sql'";
$sql = "INSERT INTO ". BB_BT_TORRENTS ." ($columns) VALUES ($values)";
diff --git a/styles/templates/default/tracker.tpl b/styles/templates/default/tracker.tpl
index 09fbf791..283e8df7 100644
--- a/styles/templates/default/tracker.tpl
+++ b/styles/templates/default/tracker.tpl
@@ -277,7 +277,7 @@ $(function(){