%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /data/www_bck/varak.cloud_bck/tracker.varak.cloud/bt/
Upload File :
Create Path :
Current File : //data/www_bck/varak.cloud_bck/tracker.varak.cloud/bt/announce.php

<?php
/**
 * TorrentPier – Bull-powered BitTorrent tracker engine
 *
 * @copyright Copyright (c) 2005-2018 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 (empty($_SERVER['HTTP_USER_AGENT'])) {
    header('Location: http://127.0.0.1', true, 301);
    die;
}

// Ignore 'completed' event
if (isset($_GET['event']) && $_GET['event'] === 'completed') {
    dummy_exit(random_int(600, 1200));
}

$announce_interval = $bb_cfg['announce_interval'];
$passkey_key = $bb_cfg['passkey_key'];
$max_left_val = 536870912000;   // 500 GB
$max_up_down_val = 5497558138880;  // 5 TB
$max_up_add_val = 85899345920;    // 80 GB
$max_down_add_val = 85899345920;    // 80 GB

// Recover info_hash
if (isset($_GET['?info_hash']) && !isset($_GET['info_hash'])) {
    $_GET['info_hash'] = $_GET['?info_hash'];
}

// Initial request verification
if (strpos($_SERVER['REQUEST_URI'], 'scrape') !== false) {
    msg_die('Please disable SCRAPE!');
}
if (!isset($_GET[$passkey_key]) || !is_string($_GET[$passkey_key]) || strlen($_GET[$passkey_key]) != BT_AUTH_KEY_LENGTH) {
    msg_die('Please LOG IN and REDOWNLOAD this torrent (passkey not found)');
}

// Input var names
// String
$input_vars_str = array(
    'info_hash',
    'peer_id',
    'event',
    $passkey_key,
);
// Numeric
$input_vars_num = array(
    'port',
    'uploaded',
    'downloaded',
    'left',
    'numwant',
    'compact',
);

// Init received data
// String
foreach ($input_vars_str as $var_name) {
    $$var_name = isset($_GET[$var_name]) ? (string)$_GET[$var_name] : null;
}
// Numeric
foreach ($input_vars_num as $var_name) {
    $$var_name = isset($_GET[$var_name]) ? (float)$_GET[$var_name] : null;
}
// Passkey
$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($peer_id) || strlen($peer_id) != 20) {
    msg_die('Invalid peer_id');
}
if (!isset($port) || $port < 0 || $port > 0xFFFF) {
    msg_die('Invalid port');
}
if (!isset($uploaded) || $uploaded < 0 || $uploaded > $max_up_down_val || $uploaded == 1844674407370) {
    msg_die('Invalid uploaded value');
}
if (!isset($downloaded) || $downloaded < 0 || $downloaded > $max_up_down_val || $downloaded == 1844674407370) {
    msg_die('Invalid downloaded value');
}
if (!isset($left) || $left < 0 || $left > $max_left_val) {
    msg_die('Invalid left value');
}
if (!verify_id($passkey, BT_AUTH_KEY_LENGTH)) {
    msg_die('Invalid passkey');
}

// IP
$ip = $_SERVER['REMOTE_ADDR'];

if (!$bb_cfg['ignore_reported_ip'] && isset($_GET['ip']) && $ip !== $_GET['ip']) {
    if (!$bb_cfg['verify_reported_ip']) {
        $ip = $_GET['ip'];
    } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
        foreach ($matches[0] as $x_ip) {
            if ($x_ip === $_GET['ip']) {
                if (!$bb_cfg['allow_internal_ip'] && preg_match("#^(10|172\.16|192\.168)\.#", $x_ip)) {
                    break;
                }
                $ip = $x_ip;
                break;
            }
        }
    }
}
// Check that IP format is valid
if (!verify_ip($ip)) {
    msg_die("Invalid IP: $ip");
}
// Convert IP to HEX format
$ip_sql = encode_ip($ip);

// Peer unique id
$peer_hash = md5(
    rtrim($info_hash, ' ') . $passkey . $ip . $port
);

// Get cached peer info from previous announce (last peer info)
$lp_info = CACHE('tr_cache')->get(PEER_HASH_PREFIX . $peer_hash);

// Drop fast announce
if ($lp_info && (!isset($event) || $event !== 'stopped')) {
    drop_fast_announce($lp_info);
}

// Functions
function drop_fast_announce($lp_info)
{
    global $announce_interval;

    if ($lp_info['update_time'] < (TIMENOW - $announce_interval + 60)) {
        return;  // if announce interval correct
    }

    $new_ann_intrv = $lp_info['update_time'] + $announce_interval - TIMENOW;

    dummy_exit($new_ann_intrv);
}

function msg_die($msg)
{
    $output = \Rych\Bencode\Bencode::encode([
        'min interval' => (int)1800,
        'failure reason' => (string)$msg,
        'warning message' => (string)$msg,
    ]);

    die($output);
}

// Start announcer
require __DIR__ . '/includes/init_tr.php';

$seeder = ($left == 0) ? 1 : 0;
$stopped = ($event === 'stopped');

// Stopped event
if ($stopped) {
    CACHE('tr_cache')->rm(PEER_HASH_PREFIX . $peer_hash);
}

// Get last peer info from DB
if (!CACHE('tr_cache')->used && !$lp_info) {
    $lp_info = DB()->fetch_row("
		SELECT * FROM " . BB_BT_TRACKER . " WHERE peer_hash = '$peer_hash' LIMIT 1
	");
}

if ($lp_info) {
    if (!$stopped) {
        drop_fast_announce($lp_info);
    }

    $user_id = $lp_info['user_id'];
    $topic_id = $lp_info['topic_id'];
    $releaser = $lp_info['releaser'];
    $tor_type = $lp_info['tor_type'];
} else {
    // Verify if torrent registered on tracker and user authorized
    $info_hash_sql = rtrim(DB()->escape($info_hash), ' ');
    $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'
		LIMIT 1
	";

    $row = DB()->fetch_row($sql);

    if (empty($row['topic_id'])) {
        msg_die('Torrent not registered, info_hash = ' . bin2hex($info_hash_sql));
    }
    if (empty($row['user_id'])) {
        msg_die('Please LOG IN and REDOWNLOAD this torrent (user not found)');
    }

    $user_id = $row['user_id'];
    $topic_id = $row['topic_id'];
    $releaser = (int)($user_id == $row['poster_id']);
    $tor_type = $row['tor_type'];

    // Ratio limits
    if ((TR_RATING_LIMITS || $bb_cfg['tracker']['limit_concurrent_ips']) && !$stopped) {
        $user_ratio = ($row['u_down_total'] && $row['u_down_total'] > MIN_DL_FOR_RATIO) ? ($row['u_up_total'] + $row['u_up_release'] + $row['u_up_bonus']) / $row['u_down_total'] : 1;
        $rating_msg = '';

        if (!$seeder) {
            foreach ($bb_cfg['rating'] as $ratio => $limit) {
                if ($user_ratio < $ratio) {
                    $bb_cfg['tracker']['limit_active_tor'] = 1;
                    $bb_cfg['tracker']['limit_leech_count'] = $limit;
                    $rating_msg = " (ratio < $ratio)";
                    break;
                }
            }
        }

        // Limit active torrents
        if (!isset($bb_cfg['unlimited_users'][$user_id]) && $bb_cfg['tracker']['limit_active_tor'] && (($bb_cfg['tracker']['limit_seed_count'] && $seeder) || ($bb_cfg['tracker']['limit_leech_count'] && !$seeder))) {
            $sql = "SELECT COUNT(DISTINCT topic_id) AS active_torrents
				FROM " . BB_BT_TRACKER . "
				WHERE user_id = $user_id
					AND seeder = $seeder
					AND topic_id != $topic_id";

            if (!$seeder && $bb_cfg['tracker']['leech_expire_factor'] && $user_ratio < 0.5) {
                $sql .= " AND update_time > " . (TIMENOW - 60 * $bb_cfg['tracker']['leech_expire_factor']);
            }
            $sql .= "	GROUP BY user_id";

            if ($row = DB()->fetch_row($sql)) {
                if ($seeder && $bb_cfg['tracker']['limit_seed_count'] && $row['active_torrents'] >= $bb_cfg['tracker']['limit_seed_count']) {
                    msg_die('Only ' . $bb_cfg['tracker']['limit_seed_count'] . ' torrent(s) allowed for seeding');
                } elseif (!$seeder && $bb_cfg['tracker']['limit_leech_count'] && $row['active_torrents'] >= $bb_cfg['tracker']['limit_leech_count']) {
                    msg_die('Only ' . $bb_cfg['tracker']['limit_leech_count'] . ' torrent(s) allowed for leeching' . $rating_msg);
                }
            }
        }

        // Limit concurrent IPs
        if ($bb_cfg['tracker']['limit_concurrent_ips'] && (($bb_cfg['tracker']['limit_seed_ips'] && $seeder) || ($bb_cfg['tracker']['limit_leech_ips'] && !$seeder))) {
            $sql = "SELECT COUNT(DISTINCT ip) AS ips
				FROM " . BB_BT_TRACKER . "
				WHERE topic_id = $topic_id
					AND user_id = $user_id
					AND seeder = $seeder
					AND ip != '$ip_sql'";

            if (!$seeder && $bb_cfg['tracker']['leech_expire_factor']) {
                $sql .= " AND update_time > " . (TIMENOW - 60 * $bb_cfg['tracker']['leech_expire_factor']);
            }
            $sql .= "	GROUP BY topic_id";

            if ($row = DB()->fetch_row($sql)) {
                if ($seeder && $bb_cfg['tracker']['limit_seed_ips'] && $row['ips'] >= $bb_cfg['tracker']['limit_seed_ips']) {
                    msg_die('You can seed only from ' . $bb_cfg['tracker']['limit_seed_ips'] . " IP's");
                } elseif (!$seeder && $bb_cfg['tracker']['limit_leech_ips'] && $row['ips'] >= $bb_cfg['tracker']['limit_leech_ips']) {
                    msg_die('You can leech only from ' . $bb_cfg['tracker']['limit_leech_ips'] . " IP's");
                }
            }
        }
    }
}

// Up/Down speed
$speed_up = $speed_down = 0;

if ($lp_info && $lp_info['update_time'] < TIMENOW) {
    if ($uploaded > $lp_info['uploaded']) {
        $speed_up = ceil(($uploaded - $lp_info['uploaded']) / (TIMENOW - $lp_info['update_time']));
    }
    if ($downloaded > $lp_info['downloaded']) {
        $speed_down = ceil(($downloaded - $lp_info['downloaded']) / (TIMENOW - $lp_info['update_time']));
    }
}

// Up/Down addition
$up_add = ($lp_info && $uploaded > $lp_info['uploaded']) ? $uploaded - $lp_info['uploaded'] : 0;
$down_add = ($lp_info && $downloaded > $lp_info['downloaded']) ? $downloaded - $lp_info['downloaded'] : 0;

// Gold/Silver releases
if ($bb_cfg['tracker']['gold_silver_enabled'] && $down_add) {
    if ($tor_type == TOR_TYPE_GOLD) {
        $down_add = 0;
    } // Silver releases
    elseif ($tor_type == TOR_TYPE_SILVER) {
        $down_add = ceil($down_add / 2);
    }
}

// Freeleech
if ($bb_cfg['tracker']['freeleech'] && $down_add) {
    $down_add = 0;
}

// Insert / update peer info
$peer_info_updated = false;
$update_time = ($stopped) ? 0 : TIMENOW;

if ($lp_info) {
    $sql = "UPDATE " . BB_BT_TRACKER . " SET update_time = $update_time";

    $sql .= ", seeder = $seeder";
    $sql .= ($releaser != $lp_info['releaser']) ? ", releaser = $releaser" : '';

    $sql .= ($tor_type != $lp_info['tor_type']) ? ", tor_type = $tor_type" : '';

    $sql .= ($uploaded != $lp_info['uploaded']) ? ", uploaded = $uploaded" : '';
    $sql .= ($downloaded != $lp_info['downloaded']) ? ", downloaded = $downloaded" : '';
    $sql .= ", remain = $left";

    $sql .= $up_add ? ", up_add = up_add + $up_add" : '';
    $sql .= $down_add ? ", down_add = down_add + $down_add" : '';

    $sql .= ", speed_up = $speed_up";
    $sql .= ", speed_down = $speed_down";

    $sql .= " WHERE peer_hash = '$peer_hash'";
    $sql .= " LIMIT 1";

    DB()->query($sql);

    $peer_info_updated = DB()->affected_rows();
}

if (!$lp_info || !$peer_info_updated) {
    $columns = 'peer_hash,    topic_id,  user_id,   ip,       port,  seeder,  releaser, tor_type,  uploaded,  downloaded, remain, speed_up,  speed_down,  up_add,  down_add,  update_time';
    $values = "'$peer_hash', $topic_id, $user_id, '$ip_sql', $port, $seeder, $releaser, $tor_type, $uploaded, $downloaded, $left, $speed_up, $speed_down, $up_add, $down_add, $update_time";

    DB()->query("REPLACE INTO " . BB_BT_TRACKER . " ($columns) VALUES ($values)");
}

// Exit if stopped
if ($stopped) {
    silent_exit();
}

// Store peer info in cache
$lp_info = array(
    'downloaded' => (float)$downloaded,
    'releaser' => (int)$releaser,
    'seeder' => (int)$seeder,
    'topic_id' => (int)$topic_id,
    'update_time' => (int)TIMENOW,
    'uploaded' => (float)$uploaded,
    'user_id' => (int)$user_id,
    'tor_type' => (int)$tor_type,
);

$lp_info_cached = CACHE('tr_cache')->set(PEER_HASH_PREFIX . $peer_hash, $lp_info, PEER_HASH_EXPIRE);

// Get cached output
$output = CACHE('tr_cache')->get(PEERS_LIST_PREFIX . $topic_id);

if (!$output) {
    // Retrieve peers
    $numwant = (int)$bb_cfg['tracker']['numwant'];
    $compact_mode = ($bb_cfg['tracker']['compact_mode'] || !empty($compact));

    $rowset = DB()->fetch_rowset("
		SELECT ip, port
		FROM " . BB_BT_TRACKER . "
		WHERE topic_id = $topic_id
		ORDER BY RAND()
		LIMIT $numwant
	");

    if ($compact_mode) {
        $peers = '';

        foreach ($rowset as $peer) {
            $peers .= pack('Nn', ip2long(decode_ip($peer['ip'])), $peer['port']);
        }
    } else {
        $peers = array();

        foreach ($rowset as $peer) {
            $peers[] = array(
                'ip' => decode_ip($peer['ip']),
                'port' => (int)$peer['port'],
            );
        }
    }

    $seeders = 0;
    $leechers = 0;

    if ($bb_cfg['tracker']['scrape']) {
        $row = DB()->fetch_row("
			SELECT seeders, leechers
			FROM " . BB_BT_TRACKER_SNAP . "
			WHERE topic_id = $topic_id
			LIMIT 1
		");

        $seeders = $row['seeders'];
        $leechers = $row['leechers'];
    }

    $output = array(
        'interval' => (int)$announce_interval,
        'min interval' => (int)$announce_interval,
        'peers' => $peers,
        'complete' => (int)$seeders,
        'incomplete' => (int)$leechers,
    );

    $peers_list_cached = CACHE('tr_cache')->set(PEERS_LIST_PREFIX . $topic_id, $output, PEERS_LIST_EXPIRE);
}

// Return data to client
echo \Rych\Bencode\Bencode::encode($output);

exit;

Zerion Mini Shell 1.0