diff --git a/bt/announce.php b/bt/announce.php
index 8b98fc756..1bccc6dca 100644
--- a/bt/announce.php
+++ b/bt/announce.php
@@ -188,7 +188,11 @@ 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'";
+ /**
+ * Поскольку торрент-клиенты в настоящее время обрезают инфо-хэш до 20 символов (независимо от его типа, как известно v1 = 20 символов, а v2 = 32 символа),
+ * то результатов $is_bt_v2 (исходя из длины строки определяем тип инфо-хэша) проверки нам будет мало, именно поэтому происходит поиск v2 хэша, если торрент является v1 (по длине) и если в tor.info_hash столбце нету v1 хэша.
+ */
+ $info_hash_where = $is_bt_v2 ? "WHERE tor.info_hash_v2 = '$info_hash_sql'" : "WHERE tor.info_hash = '$info_hash_sql' OR tor.info_hash_v2 LIKE '$info_hash_sql%'";
$passkey_sql = DB()->escape($passkey);
$sql = "
diff --git a/bt/scrape.php b/bt/scrape.php
index 531758a57..c82011e60 100644
--- a/bt/scrape.php
+++ b/bt/scrape.php
@@ -53,7 +53,11 @@ 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'";
+/**
+ * Поскольку торрент-клиенты в настоящее время обрезают инфо-хэш до 20 символов (независимо от его типа, как известно v1 = 20 символов, а v2 = 32 символа),
+ * то результатов $is_bt_v2 (исходя из длины строки определяем тип инфо-хэша) проверки нам будет мало, именно поэтому происходит поиск v2 хэша, если торрент является v1 (по длинне) и если в tor.info_hash столбце нету v1 хэша.
+ */
+$info_hash_where = $is_bt_v2 ? "WHERE tor.info_hash_v2 = '$info_hash_sql'" : "WHERE tor.info_hash = '$info_hash_sql' OR tor.info_hash_v2 LIKE '$info_hash_sql%'";
$row = DB()->fetch_row("
SELECT tor.complete_count, snap.seeders, snap.leechers
diff --git a/install/sql/mysql.sql b/install/sql/mysql.sql
index d93b6dbab..e4c6eca6a 100644
--- a/install/sql/mysql.sql
+++ b/install/sql/mysql.sql
@@ -291,7 +291,7 @@ CREATE TABLE IF NOT EXISTS `bb_bt_torrents`
`tor_type` TINYINT(1) NOT NULL DEFAULT '0',
`speed_up` INT(11) NOT NULL DEFAULT '0',
`speed_down` INT(11) NOT NULL DEFAULT '0',
- PRIMARY KEY (`info_hash`),
+ PRIMARY KEY (`topic_id`),
UNIQUE KEY `post_id` (`post_id`),
UNIQUE KEY `topic_id` (`topic_id`),
UNIQUE KEY `attach_id` (`attach_id`),
diff --git a/library/ajax/view_torrent.php b/library/ajax/view_torrent.php
index eb4ab4005..36b48d96a 100644
--- a/library/ajax/view_torrent.php
+++ b/library/ajax/view_torrent.php
@@ -37,6 +37,9 @@ if (!$tor = \SandFox\Bencode\Bencode::decode($file_contents)) {
}
$torrent = new TorrentPier\Legacy\TorrentFileList($tor);
-$tor_filelist = $torrent->get_filelist();
-
+if (($tor['info']['meta version'] ?? null) == 2 && is_array($tor['info']['file tree'] ?? null)) {
+ $tor_filelist = $torrent->fileTreeList($tor['info']['file tree'], $tor['info']['name'] ?? ''); // v2
+} else {
+ $tor_filelist = $torrent->get_filelist(); // v1
+}
$this->response['html'] = $tor_filelist;
diff --git a/library/attach_mod/displaying_torrent.php b/library/attach_mod/displaying_torrent.php
index a058b74db..5ebb8351b 100644
--- a/library/attach_mod/displaying_torrent.php
+++ b/library/attach_mod/displaying_torrent.php
@@ -211,7 +211,7 @@ if ($tor_reged && $tor_info) {
'DL_TITLE_CLASS' => (isset($bt_userdata['user_status'])) ? $dl_status_css[$bt_userdata['user_status']] : 'gen',
'FILESIZE' => $tor_file_size,
'MAGNET' => $tor_magnet,
- 'HASH' => strtoupper(bin2hex($tor_info['info_hash'])),
+ 'HASH' => !empty($tor_info['info_hash']) ? strtoupper(bin2hex($tor_info['info_hash'])) : false,
'HASH_V2' => !empty($tor_info['info_hash_v2']) ? strtoupper(bin2hex($tor_info['info_hash_v2'])) : false,
'DOWNLOAD_COUNT' => declension((int)$download_count, 'times'),
'REGED_TIME' => bb_date($tor_info['reg_time']),
diff --git a/library/config.php b/library/config.php
index b7cdd5b51..aea7df96c 100644
--- a/library/config.php
+++ b/library/config.php
@@ -647,8 +647,9 @@ $bb_cfg['tracker'] = [
'retracker_host' => 'http://retracker.local/announce',
'guest_tracker' => true,
'search_by_tor_status' => true,
- 'freeleech' => false, // freelech mode (If enabled, then disable "gold_silver_enabled")
- 'gold_silver_enabled' => true // golden / silver days mode (If enabled, then disable "freeleech")
+ 'freeleech' => false, // freeleech mode (If enabled, then disable "gold_silver_enabled")
+ 'gold_silver_enabled' => true, // golden / silver days mode (If enabled, then disable "freeleech")
+ 'disabled_v2_torrents' => false // allow registration of v2-only torrents
];
// Ratio settings
diff --git a/library/includes/functions.php b/library/includes/functions.php
index c64a417f2..dd25ecd68 100644
--- a/library/includes/functions.php
+++ b/library/includes/functions.php
@@ -1787,7 +1787,20 @@ function create_magnet(string $infohash, string $infohash_v2, string $auth_key):
return false;
}
- return '';
+ $magnet = 'magnet:?';
+
+ if (!empty($infohash)) {
+ $magnet .= 'xt=urn:btih:' . bin2hex($infohash);
+ }
+
+ if (!empty($infohash_v2)) {
+ if (!empty($infohash)) {
+ $magnet .= '&';
+ }
+ $magnet .= 'xt=urn:btmh:1220' . bin2hex($infohash_v2);
+ }
+
+ return '
';
}
function set_die_append_msg($forum_id = null, $topic_id = null, $group_id = null)
@@ -1876,20 +1889,17 @@ function profile_url($data)
return $profile;
}
-function get_avatar($user_id, $ext_id, $allow_avatar = true, $height = 100, $width = 100)
+function get_avatar($user_id, $ext_id, $allow_avatar = true)
{
global $bb_cfg;
- $height = $height ? 'height="' . $height . '"' : '';
- $width = $width ? 'width="' . $width . '"' : '';
-
- $user_avatar = '
';
+ $user_avatar = '
';
if ($user_id == BOT_UID && $bb_cfg['avatars']['bot_avatar']) {
- $user_avatar = '
';
+ $user_avatar = '
';
} elseif ($allow_avatar && $ext_id) {
if (file_exists(get_avatar_path($user_id, $ext_id))) {
- $user_avatar = '
';
+ $user_avatar = '
';
}
}
diff --git a/library/language/source/main.php b/library/language/source/main.php
index 1f406fa9c..2c5e0fbde 100644
--- a/library/language/source/main.php
+++ b/library/language/source/main.php
@@ -1082,8 +1082,6 @@ $lang['SEEDING'] = 'Seed';
$lang['LEECHING'] = 'Leech';
$lang['IS_REGISTERED'] = 'Registered';
$lang['MAGNET'] = 'Magnet';
-$lang['DC_MAGNET'] = 'Search in DC++ by filename';
-$lang['DC_MAGNET_EXT'] = 'Search in DC++ by extension';
//torrent status mod
$lang['TOR_STATUS'] = 'Status';
diff --git a/src/Legacy/Torrent.php b/src/Legacy/Torrent.php
index c082b7a67..91dfa8a89 100644
--- a/src/Legacy/Torrent.php
+++ b/src/Legacy/Torrent.php
@@ -287,8 +287,10 @@ class Torrent
$topic_id = $torrent['topic_id'];
$forum_id = $torrent['forum_id'];
$poster_id = $torrent['poster_id'];
+
$info_hash = $info_hash_v2 = null;
- $info_hash_sql = $info_hash_v2_sql = null;
+ $info_hash_sql = $info_hash_v2_sql = $info_hash_where = null;
+ $v2_hash = null;
if ($torrent['extension'] !== TORRENT_EXT) {
return self::torrent_error_exit($lang['NOT_TORRENT']);
@@ -331,7 +333,7 @@ class Torrent
if ($bb_cfg['bt_check_announce_url']) {
include INC_DIR . '/torrent_announce_urls.php';
- $ann = (@$tor['announce']) ? $tor['announce'] : '';
+ $ann = isset($tor['announce']) ? $tor['announce'] : '';
$announce_urls['main_url'] = $bb_cfg['bt_announce_url'];
if (!$ann || !\in_array($ann, $announce_urls)) {
@@ -340,35 +342,45 @@ class Torrent
}
}
- $info = (@$tor['info']) ? $tor['info'] : [];
+ $info = isset($tor['info']) ? $tor['info'] : [];
- if (!isset($info['name'], $info['piece length'], $info['pieces']) || \strlen($info['pieces']) % 20 != 0) {
+ if (!isset($info['name'], $info['piece length'])) {
return self::torrent_error_exit($lang['TORFILE_INVALID']);
}
- // Check if torrent contains info_hash v2
- $bt_v2 = false;
+ // Check if torrent contains info_hash v2 or v1
+ $bt_v1 = $bt_v2 = false;
if (($info['meta version'] ?? null) == 2 && is_array($info['file tree'] ?? null)) {
$bt_v2 = true;
}
+ if (isset($info['pieces'])) {
+ $bt_v1 = true;
+ }
+ if ($bb_cfg['tracker']['disabled_v2_torrents'] && $bt_v2 && !$bt_v1) {
+ return self::torrent_error_exit('v2-only torrents were disabled, allowed: v1 and hybrids');
+ }
// 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);
+ if ($bt_v1) {
+ $info_hash = pack('H*', sha1(\SandFox\Bencode\Bencode::encode($info)));
+ $info_hash_sql = rtrim(DB()->escape($info_hash), ' ');
+ $info_hash_where = "WHERE info_hash = '$info_hash_sql'";
+ }
// Getting info_hash v2
if ($bt_v2) {
- $info_hash_v2 = pack('H*', hash('sha256', \SandFox\Bencode\Bencode::encode($info)));
+ $v2_hash = hash('sha256', \SandFox\Bencode\Bencode::encode($info));
+ $info_hash_v2 = pack('H*', $v2_hash);
$info_hash_v2_sql = rtrim(DB()->escape($info_hash_v2), ' ');
+ $info_hash_where = "WHERE info_hash_v2 = '$info_hash_v2_sql'";
}
// Ocelot
if ($bb_cfg['ocelot']['enabled']) {
- self::ocelot_update_tracker('add_torrent', ['info_hash' => rawurlencode($info_hash), 'id' => $topic_id, 'freetorrent' => 0]);
+ self::ocelot_update_tracker('add_torrent', ['info_hash' => rawurlencode($info_hash ?? hex2bin(substr($v2_hash, 0, 40))), 'id' => $topic_id, 'freetorrent' => 0]);
}
- if ($row = DB()->fetch_row("SELECT topic_id FROM " . BB_BT_TORRENTS . " WHERE info_hash = '$info_hash_sql' LIMIT 1")) {
+ if ($row = DB()->fetch_row("SELECT topic_id FROM " . BB_BT_TORRENTS . " $info_hash_where LIMIT 1")) {
$msg = sprintf($lang['BT_REG_FAIL_SAME_HASH'], TOPIC_URL . $row['topic_id']);
bb_die($msg);
set_die_append_msg($forum_id, $topic_id);
@@ -378,13 +390,29 @@ class Torrent
if (isset($info['length'])) {
$totallen = (float)$info['length'];
- } elseif (isset($info['files']) && \is_array($info['files'])) {
+ } elseif ($bt_v1 && isset($info['files']) && \is_array($info['files'])) {
foreach ($info['files'] as $fn => $f) {
// Exclude padding files
if (($f['attr'] ?? null) !== 'p') {
$totallen += (float)$f['length'];
}
}
+ } elseif ($bt_v2) {
+ $fileTreeSize = function (array $array, string $name = '') use (&$fileTreeSize) {
+ $size = 0;
+
+ foreach ($array as $key => $value) {
+ if (!isset($value[''])) {
+ $size += $fileTreeSize($value);
+ } else {
+ $size += (int)$value['']['length'];
+ }
+ }
+
+ return $size;
+ };
+
+ $totallen = (float)$fileTreeSize($info['file tree']);
} else {
return self::torrent_error_exit($lang['TORFILE_INVALID']);
}
diff --git a/src/Legacy/TorrentFileList.php b/src/Legacy/TorrentFileList.php
index b9bc54ac7..fc294e465 100644
--- a/src/Legacy/TorrentFileList.php
+++ b/src/Legacy/TorrentFileList.php
@@ -43,45 +43,18 @@ class TorrentFileList
{
global $html;
- 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 = [];
+ $this->build_filelist_array();
- foreach ($array as $key => $value) {
- if (is_array($value) && !isset($value[''])) {
- $html_v2 = fileTree($value);
- $folders[] = "
$root
{postrow.attach.tor_reged.DOWNLOAD_NAME} {postrow.attach.tor_reged.MAGNET} | +{postrow.attach.tor_reged.DOWNLOAD_NAME} {postrow.attach.tor_reged.MAGNET} | ||||
---|---|---|---|---|---|
{postrow.attach.tor_reged.TRACKER_LINK}
[ {postrow.attach.tor_reged.REGED_TIME} ]
- info_hash: {postrow.attach.tor_reged.HASH} + info_hash: {postrow.attach.tor_reged.HASH} info_hash v2: {postrow.attach.tor_reged.HASH_V2} |
@@ -326,6 +326,7 @@ $('#tor-filelist-btn').click(function(){ } #tor-filelist i { color: #7A7A7A; padding-left: 4px; } #tor-filelist s { color: #0000FF; text-decoration: none; } +#tor-filelist p { color: #7C7C7C; text-decoration: none; } #tor-filelist .b > s { color: #800000; } #tor-filelist .b { font-weight: bold; padding-left: 20px; background: transparent url('styles/images/folder.gif') no-repeat 3px 50%;} #tor-filelist ul li span { padding-left: 20px; background: transparent url('styles/images/page.gif') no-repeat 3px 50%;} |