diff --git a/admin/stats/tracker.php b/admin/stats/tracker.php index d7f5b9529..2e32f2661 100644 --- a/admin/stats/tracker.php +++ b/admin/stats/tracker.php @@ -82,29 +82,40 @@ $clients_percentage = []; $numwant = !empty($_GET['client_numwant']) ? (int)$_GET['client_numwant'] : 100; $client_full = !empty($_GET['client_length']) ? (int)$_GET['client_length'] : false; -$rowset = DB()->fetch_rowset('SELECT peer_id AS client FROM ' . TMP_TRACKER_TABLE); +if ($client_full || !$stats_cache = CACHE('tr_cache')->get('tracker_clients_stats')) { -if (!empty($rowset)) { + $rowset = DB()->fetch_rowset('SELECT peer_id AS client FROM ' . TMP_TRACKER_TABLE); - $client_count = 0; + if (!empty($rowset)) { - foreach ($rowset as $cnt => $row) { - $clientString = $client_full ? substr($row['client'], 0, $client_full) : substr($row['client'], 0, 3); - if (!isset($clients[$clientString])) { - $clients[$clientString] = 1; + $client_count = 0; + + foreach ($rowset as $cnt => $row) { + $clientString = $client_full ? substr($row['client'], 0, $client_full) : substr($row['client'], 0, 3); + if (!isset($clients[$clientString])) { + $clients[$clientString] = 1; + } + else { + $clients[$clientString]++; + } + $client_count++; } - else { - $clients[$clientString]++; + + foreach ($clients as $client => $count) { + $percentage = number_format(($count / $client_count) * 100, 2); + $clients_percentage[$client] = "[$count] => $percentage%"; } - $client_count++; - } - foreach ($clients as $client => $count) { - $percentage = number_format(($count / $client_count) * 100, 2); - $clients_percentage[] = ($client_full ? $client : get_user_torrent_client($client)) . " [$count] => $percentage%"; + if (!$client_full) { + CACHE('tr_cache')->set('tracker_clients_stats', $clients_percentage, 3600); + } } +} else { + $clients_percentage = $stats_cache; +} - $client_list = implode('
', array_slice($clients_percentage, 0, $numwant)); +foreach (array_slice($clients_percentage, 0, $numwant) as $client => $value) { + $client_list .= ($client_full) ? ("$client => $value
") : get_user_torrent_client($client) . " => $value
"; } function commify_callback($matches) @@ -157,6 +168,7 @@ echo (count($clients_percentage) > $numwant) ? ('Peer_ids with more length (version debugging)': ''); echo ''; echo ''; +echo !$client_full ? '

Simple stats for clients are being cached for one hour.

' : ''; echo '
';
 
 if ($l = sys('la')) {
diff --git a/library/includes/file_list_v2.php b/library/includes/file_list_v2.php
index 23ec87eb7..32d87fdf8 100644
--- a/library/includes/file_list_v2.php
+++ b/library/includes/file_list_v2.php
@@ -6,7 +6,12 @@ if (!defined('BB_ROOT')) {
 
 $user->session_start();
 
-$topic_id = (int)$_GET['t'];
+if ($bb_cfg['bt_disable_dht'] && IS_GUEST) {
+    http_response_code(403);
+    die($lang['BT_PRIVATE_TRACKER']);
+}
+
+$topic_id = !empty($_GET['t']) ? (int)$_GET['t'] : (http_response_code(404) && die($lang['INVALID_TOPIC_ID']));
 
 $sql = 'SELECT t.attach_id, t.info_hash_v2, ad.physical_filename
         FROM ' . BB_BT_TORRENTS . ' t
@@ -24,13 +29,13 @@ if (empty($row) || empty($row['physical_filename'])) {
 
 if (empty($row['info_hash_v2'])) {
     http_response_code(404);
-    die('Currently torrents with BitTorrent v2 support are enabled for file listing');
+    die($lang['BT_V2_FILE_LIST_ONLY']);
 }
 
 $file_path = get_attachments_dir() . '/' . $row['physical_filename'];
 
 if(!is_file($file_path)){
-    die($lang['INVALID_ATTACH_ID']);
+    die($lang['TOR_NOT_FOUND']);
 }
 
 $file_contents = file_get_contents($file_path);
@@ -39,29 +44,35 @@ if (!$tor = \Arokettu\Bencode\Bencode::decode($file_contents, dictType: \Arokett
     die($lang['TORFILE_INVALID']);
 }
 
+if (isset($tor['info']['private']) && IS_GUEST) {
+    die($lang['BT_PRIVATE_TORRENT']);
+}
+
 $torrent = new TorrentPier\Legacy\TorrentFileList($tor);
-$file_list = $torrent->fileTreeTable($tor['info']['file tree']);
+$files = $torrent->fileTreeTable($tor['info']['file tree']);
 
 $data = [
     'date' => '',
     'name' => htmlCHR($tor['info']['name'] ?? ''),
     'client' => htmlCHR(substr($tor['created by'] ?? 'unknown client', 0, 20)),
-    'size' => humn_size($file_list['size'])
+    'size' => humn_size($files['size']),
+    'hash' => bin2hex($row['info_hash_v2'])
 ];
 
 if (isset($tor['creation date']) && is_numeric($tor['creation date'])) {
     $data['date'] = date("d M Y | G:i:s T", $tor['creation date']);
 }
 
-echo "
+echo <<
 
-
-
-
+
+
+
 
-File list — {$data['name']} ({$data['size']})
+File information listing | {$data['name']} ({$data['size']}) | {$data['hash']}
 
-
+
 
 
-

Document name: {$data['name']} | Date: ({$data['date']}) | Size: {$data['size']} +

Document name: {$data['name']} | Date: ({$data['date']}) | Size: {$data['size']}

Created by: {$data['client']}


-"; +
PathSizeHash ?
+EOF; -echo implode('', $file_list['list']); +echo $files['list']; echo '
PathSizeHash ?
-

Generated by TorrentPier

+

Generated by TorrentPier

'; diff --git a/library/language/source/main.php b/library/language/source/main.php index fce63b4b1..eefdc08ae 100644 --- a/library/language/source/main.php +++ b/library/language/source/main.php @@ -1060,6 +1060,7 @@ $lang['BT_REG_ON_TRACKER'] = 'Register on tracker'; $lang['BT_REG_FAIL'] = 'Could not register torrent on tracker'; $lang['BT_REG_FAIL_SAME_HASH'] = 'Another torrent with same info_hash already registered'; $lang['BT_V2_ONLY_DISALLOWED'] = 'v2-only torrents have been disabled by the administrator at the moment, allowed: v1 and hybrids'; +$lang['BT_V2_FILE_LIST_ONLY'] = 'Currently, only torrents with BitTorrent version 2 support are enabled for separate file listing'; $lang['BT_UNREG_FROM_TRACKER'] = 'Remove from tracker'; $lang['BT_UNREGISTERED'] = 'Torrent unregistered'; $lang['BT_UNREGISTERED_ALREADY'] = 'Torrent already unregistered'; @@ -2321,6 +2322,8 @@ $lang['BT_ANNOUNCE_URL'] = 'Announce url'; $lang['BT_ANNOUNCE_URL_EXPL'] = 'you can define additional allowed urls in "includes/torrent_announce_urls.php"'; $lang['BT_DISABLE_DHT'] = 'Disable DHT network'; $lang['BT_DISABLE_DHT_EXPL'] = 'Disable Peer Exchange and DHT (recommended for private networks, only url announce)'; +$lang['BT_PRIVATE_TRACKER'] = 'This tracker is private: file listing (for guests), DHT | PEX are disabled'; +$lang['BT_PRIVATE_TORRENT'] = 'The creator of this torrent made it private'; $lang['BT_CHECK_ANNOUNCE_URL'] = 'Verify announce url'; $lang['BT_CHECK_ANNOUNCE_URL_EXPL'] = 'register on tracker only allowed urls'; $lang['BT_REPLACE_ANN_URL'] = 'Replace announce url'; diff --git a/src/Legacy/TorrentFileList.php b/src/Legacy/TorrentFileList.php index fcb58a5f8..ed411df9d 100644 --- a/src/Legacy/TorrentFileList.php +++ b/src/Legacy/TorrentFileList.php @@ -44,7 +44,7 @@ class TorrentFileList global $html; if (($this->tor_decoded['info']['meta version'] ?? 1) === 2) { if (is_array($this->tor_decoded['info']['file tree'] ?? null)) { - return $this->fileTreeList($this->tor_decoded['info']['file tree']); //v2 + return $this->fileTreeList($this->tor_decoded['info']['file tree'], $this->tor_decoded['info']['name'] ?? ''); //v2 } } @@ -139,24 +139,21 @@ class TorrentFileList */ public function fileTreeList(array $array, string $name = ''): string { - $folders = []; - $rootFiles = []; + $allItems = ''; foreach ($array as $key => $value) { $key = htmlCHR($key); if (!isset($value[''])) { $html_v2 = $this->fileTreeList($value); - $folders[] = "
  • $key
      $html_v2
  • "; + $allItems .= "
  • $key
      $html_v2
  • "; } else { $length = (int)$value['']['length']; $root = bin2hex($value['']['pieces root'] ?? ''); - $rootFiles[] = "
  • $key$length

    $root

  • "; + $allItems .= "
  • $key$length

    $root

  • "; } } - $allFiles = implode('', [...$folders, ...$rootFiles]); - - return '
    ' . (empty($folders) ? '' : htmlCHR($name)) . '
      ' . $allFiles . '
    '; + return '
    ' . (empty($allItems) ? '' : htmlCHR($name)) . '
      ' . $allItems . '
    '; } /** @@ -168,8 +165,7 @@ class TorrentFileList */ public function fileTreeTable(array $array, string $parent = ''): array { - $filesList = []; - $size = 0; + static $filesList = ['list' => '', 'size' => 0]; foreach ($array as $key => $value) { $key = htmlCHR($key); $current = "$parent/$key"; @@ -178,14 +174,11 @@ class TorrentFileList } else { $length = (int)$value['']['length']; $root = bin2hex($value['']['pieces root'] ?? ''); - $size += $length; - $filesList[] = '' . $current . '' . humn_size($length, 2) . '' . $root . ''; + $filesList['size'] += $length; + $filesList['list'] .= '' . $current . '' . humn_size($length, 2) . '' . $root . ''; } } - return [ - 'list' => $filesList, - 'size' => $size - ]; + return $filesList; } }