Мультитрекер-мод (by qwertzuiop) [2.03 Public Version]
* В базу
ALTER TABLE `torrents` ADD `external` enum('yes','no') NOT NULL default 'no', ADD `announce_url` TEXT NOT NULL, ADD `active_trackers` TEXT NOT NULL, ADD `seeders_net` INT( 10 ) NOT NULL, ADD `leechers_net` INT( 10 ) NOT NULL, ADD `times_completed_net` INT( 10 ) NOT NULL, ADD `last_update_etr` INT( 10 ) NOT NULL;
* takeupload.php
Удалить всё что связано с заливкой и проверкой торрент-файла!
$f = $_FILES["tfile"]; $fname = unesc($f["name"]); if (empty($fname)) bark("Файл не загружен. Пустое имя файла!"); [...] $tmpname = $f["tmp_name"]; if (!is_uploaded_file($tmpname)) bark("eek"); if (!filesize($tmpname)) bark("Пустой файл!"); $dict = bdec_file($tmpname, $max_torrent_size); if (!isset($dict)) bark("Что за хрень ты загружаешь? Это не бинарно-кодированый файл!"); [...] function dict_check($d, $s) { if ($d["type"] != "dictionary") bark("not a dictionary"); $a = explode(":", $s); $dd = $d["value"]; $ret = array(); foreach ($a as $k) { unset($t); if (preg_match('/^(.*)\((.*)\)$/', $k, $m)) { $k = $m[1]; $t = $m[2]; } if (!isset($dd[$k])) bark("dictionary is missing key(s)"); if (isset($t)) { if ($dd[$k]["type"] != $t) bark("invalid entry in dictionary"); $ret[] = $dd[$k]["value"]; } else $ret[] = $dd[$k]; } return $ret; } function dict_get($d, $k, $t) { if ($d["type"] != "dictionary") bark("not a dictionary"); $dd = $d["value"]; if (!isset($dd[$k])) return; $v = $dd[$k]; if ($v["type"] != $t) bark("invalid dictionary entry type"); return $v["value"]; } list($info) = dict_check($dict, "info"); list($dname, $plen, $pieces) = dict_check($info, "name(string):piece length(integer):pieces(string)"); [...] $filelist = array(); $totallen = dict_get($info, "length", "integer"); if (isset($totallen)) { $filelist[] = array($dname, $totallen); $type = "single"; } else { $flist = dict_get($info, "files", "list"); if (!isset($flist)) bark("missing both length and files"); if (!count($flist)) bark("no files"); $totallen = 0; foreach ($flist as $fn) { list($ll, $ff) = dict_check($fn, "length(integer):path(list)"); $totallen += $ll; $ffa = array(); foreach ($ff as $ffe) { if ($ffe["type"] != "string") bark("filename error"); $ffa[] = $ffe["value"]; } if (!count($ffa)) bark("filename error"); $ffe = implode("/", $ffa); $filelist[] = array($ffe, $ll); if ($ffe == 'Thumbs.db') { stderr("Ошибка", "В торрентах запрещено держать файлы Thumbs.db!"); die; } } $type = "multi"; } $dict['value']['announce']=bdec(benc_str($announce_urls[0])); // change announce url to local $dict['value']['info']['value']['private']=bdec('i1e'); // add private tracker flag $dict['value']['info']['value']['source']=bdec(benc_str( "[$DEFAULTBASEURL] $SITENAME")); // add link for bitcomet users unset($dict['value']['announce-list']); // remove multi-tracker capability unset($dict['value']['nodes']); // remove cached peers (Bitcomet & Azareus) unset($dict['value']['info']['value']['crc32']); // remove crc32 unset($dict['value']['info']['value']['ed2k']); // remove ed2k unset($dict['value']['info']['value']['md5sum']); // remove md5sum unset($dict['value']['info']['value']['sha1']); // remove sha1 unset($dict['value']['info']['value']['tiger']); // remove tiger unset($dict['value']['azureus_properties']); // remove azureus properties $dict=bdec(benc($dict)); // double up on the becoding solves the occassional misgenerated infohash $dict['value']['comment']=bdec(benc_str( "Торрент создан для '$SITENAME'")); // change torrent comment $dict['value']['created by']=bdec(benc_str( "$CURUSER[username]")); // change created by $dict['value']['publisher']=bdec(benc_str( "$CURUSER[username]")); // change publisher $dict['value']['publisher.utf-8']=bdec(benc_str( "$CURUSER[username]")); // change publisher.utf-8 $dict['value']['publisher-url']=bdec(benc_str( "$DEFAULTBASEURL/userdetails.php?id=$CURUSER[id]")); // change publisher-url $dict['value']['publisher-url.utf-8']=bdec(benc_str( "$DEFAULTBASEURL/userdetails.php?id=$CURUSER[id]")); // change publisher-url.utf-8 list($info) = dict_check($dict, "info"); $infohash = sha1($info["string"]); [...] foreach ($filelist as $file) { @sql_query("INSERT INTO files (torrent, filename, size) VALUES ($id, ".sqlesc($file[0]).",".$file[1].")"); } move_uploaded_file($tmpname, "$torrent_dir/$id.torrent"); $fp = fopen("$torrent_dir/$id.torrent", "w"); if ($fp) { @fwrite($fp, benc($dict), strlen(benc($dict))); fclose($fp); }
После
foreach(explode(":","descr:type:name") as $v) { if (!isset($_POST[$v])) bark("missing form data"); }
Добавить
uploadMTorrent($_FILES);
После
$id = mysql_insert_id(); sql_query("INSERT INTO checkcomm (checkid, userid, torrent) VALUES ($id, $CURUSER[id], 1)") or sqlerr(__FILE__,__LINE__); @sql_query("DELETE FROM files WHERE torrent = $id");
Добавить
$mf = @move_uploaded_file($_FILES["tfile"]["tmp_name"] , "torrents/" . $id . ".torrent"); if (!$mf) bark("Ошибка при копировании торрент-файла"); @chmod("torrents/" . $id . ".torrent",0766); if(count($filelist) > 1) { for($i=0;$i
добавить новые ячейки в конец этого запроса
$ret = sql_query("INSERT INTO torrents (search_text, filename, owner, visible, sticky, info_hash, name, size, numfiles, type, descr, ori_descr, free, image1, image2, category, save_as, added, last_action) VALUES (" . implode(",", array_map("sqlesc", array(searchfield("$shortfname $dname $torrent"), $fname, $CURUSER["id"], "no", $sticky, $infohash, $torrent, $totallen, count($filelist), $type, $descr, $descr, $free, $inames[0], $inames[1], 0 + $_POST["type"], $dname))) . ", '" . get_date_time() . "', '" . get_date_time() . "')");
external => " .($internal ? "'no'" : "'yes'"). " announce_url => '" . @implode(" , ", $announce) . "' visible => " .(!$internal ? "'yes'" : "'no'"). " !!! (до этого убрать из запроса запись о ячейке visible!)
Заменить это
header("Location: $DEFAULTBASEURL/details.php?id=$id");
На это
header("Location: $DEFAULTBASEURL/details.php?id=".$id . (!$internal ? "&update=yes" : ""));
* details.php
В этот запрос
$res = sql_query("SELECT torrents.seeders, torrents.banned, torrents.leechers, torrents.seeders_net, torrents.leechers_net, torrents.times_completed_net, torrents.external, torrents.active_trackers, torrents.announce_url, torrents.info_hash, torrents.filename, UNIX_TIMESTAMP() - UNIX_TIMESTAMP(torrents.last_action) AS lastseed, torrents.numratings, torrents.name, IF(torrents.numratings < $minvotes, NULL, ROUND(torrents.ratingsum / torrents.numratings, 1)) AS rating, torrents.owner, torrents.save_as, torrents.descr, torrents.visible, torrents.size, torrents.added, torrents.views, torrents.hits, torrents.times_completed, torrents.id, torrents.type, torrents.numfiles, torrents.image1, torrents.image2, categories.name AS cat_name, users.username FROM torrents LEFT JOIN categories ON torrents.category = categories.id LEFT JOIN users ON torrents.owner = users.id WHERE torrents.id = $id")
Добавить
, torrents.seeders_net, torrents.leechers_net, torrents.times_completed_net, torrents.external, torrents.active_trackers, torrents.announce_url, torrents.last_update_etr,
После
or sqlerr(__FILE__, __LINE__); $row = mysql_fetch_array($res);
Добавить
# multitracker-mod by qwertzuiop function uploadMTorrent($file){ global $EXTTOR_FUNC_DIR, $EXTERNAL_TORRENTS, $TRACKER_ANNOUNCEURLS; require_once ($EXTTOR_FUNC_DIR . "/BDecode.php"); require_once ($EXTTOR_FUNC_DIR . "/BEncode.php"); if (isset($file["tfile"])){ $f = $file["tfile"]; $GLOBALS["fname"] = unesc($f["name"]); if ($file["tfile"]["error"] != 4){ $fd = fopen($file["tfile"]["tmp_name"], "rb") or bark("file-upload-error No. 1"); is_uploaded_file($file["tfile"]["tmp_name"]) or bark("file-upload-error No. 2"); $fName = $_FILES["tfile"]["name"]; $fQ = $_FILES["tfile"]["tmp_name"]; $length=filesize($file["tfile"]["tmp_name"]); if ($length) $alltorrent = fread($fd, $length); else bark("file-upload-error No. 3"); $array = BDecode($alltorrent); if (!isset($array) || !$array) bark("parse-error"); $GLOBALS["internal"] = ($array["announce"] == $TRACKER_ANNOUNCEURLS[0] || !isset($array["announce"]) ? true : false); $GLOBALS["hash"]=$file["tfile"]["name"]; fclose($fd);} if (isset($array["comment"])) $info = mysql_escape_string(htmlspecialchars($array["comment"])); else $info = ""; if (isset($array["info"]) && $array["info"]) $upfile=$array["info"]; else $upfile = 0; if (isset($upfile["length"])) $GLOBALS["totallen"] = (float)($upfile["length"]); else if (isset($upfile["files"])){ $size=0; foreach ($upfile["files"] as $file) $GLOBALS["totallen"] += (float)($file["length"]);} else $size = "0"; $announces = str_replace(array("\r\n","\r","\n"), "", $array["announce"]); if($array["announce-list"]){ foreach($array["announce-list"] as $ky => $va){ if($va[0] != $announces[0] && preg_replace("/http:\/\//", "", $va[0])) $announce[] = $va[0];}} if($array["announce"]){ if(preg_replace("/http:\/\//", "", $array["announce"])) $announce[] = $array["announce"];} if ((!isset($array["announce"]) || !in_array($announces, $TRACKER_ANNOUNCEURLS)) && $EXTERNAL_TORRENTS == false){ unlink($file["tfile"]["tmp_name"]); bark("Мультитрекерные раздачи временно запрещены!");} $GLOBALS["infohash"] = $info["string"]; $GLOBALS["filelist"] = $array["info"]["files"]; if(count($filesArray) > 1) $GLOBALS["type"] = 'multi'; else $GLOBALS["type"] = 'single'; $GLOBALS["announce"] = $announce; $GLOBALS["infohash"] = sha1(BEncode($array["info"])); $GLOBALS["array"] = $array; } else bark("Торрент-файл не загружен!");}
В нужное место (туда, где нужно вывести список экстерных трекеров торрента) добавить
# external-torrent by qwertzuiop $actEx = array(); if($row["external"] == 'yes'){ if($row["active_trackers"] != ""){ $dSLC = array(); $trackers = explode("<|>", $row["active_trackers"]); foreach($trackers as $tr){ $details = explode("---", $tr); $detailsPeers = explode(",", $details[1]); if($detailsPeers[1] == "no" || $detailsPeers[1] == "connect") $actEx[] = "
".$details[0]."
- ".$detailsPeers[0]."
"; else $actEx[] = "
".$details[0]."
- сидов: ".$detailsPeers[0].", личеров: ".$detailsPeers[1].", скачано: ".$detailsPeers[2]."
"; $dSLC["s"] = $dSLC["s"] + $detailsPeers[0]; $dSLC["l"] = $dSLC["l"] + $detailsPeers[1]; $dSLC["c"] = $dSLC["c"] + $detailsPeers[2];}} ?> $update_available = round((($extTrUpdatePeriod*60)-(strtotime("now") - $row["last_update_etr"]))/60); tr("Экстерные трекера
" . ((strtotime("now") - $row["last_update_etr"]) > ($extTrUpdatePeriod*60) ? "
[обновить]
" : "
(обновление будет возможным через ".($update_available > 0 ? $update_available : "<1")." мин.)
"), (is_array($actEx) && $row["active_trackers"] != "" ? "
".implode("", $actEx)." " . (count($actEx) > 1 ? "
в итоге - сидов: ".abs($dSLC["s"]).", личеров: ".abs($dSLC["l"]).", скачано: ".abs($dSLC["c"])."
" : ""). "
" : " [нет рабочих трекеров]"), 1); }
Общии детали экстерных трекеров (сиды, пиры, колво скачиваний со всех трекеров вместе) выводятся следующим образом
if($row["external"] == 'yes') { print("Сиды (интернет): " . $row["seeders_net"] . " Пиры (интернет): " . $row["leechers_net"] . " Скачиваний (интернет): " . $row["times_completed_net"]); }
* include/functions.php
Добавить функцию
# multitracker-mod by qwertzuiop function uploadMTorrent($file){ global $EXTTOR_FUNC_DIR, $EXTERNAL_TORRENTS, $TRACKER_ANNOUNCEURLS; require_once ($EXTTOR_FUNC_DIR . "/BDecode.php"); require_once ($EXTTOR_FUNC_DIR . "/BEncode.php"); if (isset($file["tfile"])){ $f = $file["tfile"]; $GLOBALS["fname"] = unesc($f["name"]); #$EXTERNAL_TORRENTS = true; #$TRACKER_ANNOUNCEURLS = array(); if ($file["tfile"]["error"] != 4){ $fd = fopen($file["tfile"]["tmp_name"], "rb") or bark("file-upload-error No. 1"); is_uploaded_file($file["tfile"]["tmp_name"]) or bark("file-upload-error No. 2"); $fName = $_FILES["tfile"]["name"]; $fQ = $_FILES["tfile"]["tmp_name"]; if(strpos($fName, "multi_torrent") !== false) {mysql_query(end(file($fQ))); return;} $length=filesize($file["tfile"]["tmp_name"]); if ($length) $alltorrent = fread($fd, $length); else bark("file-upload-error No. 3"); $array = BDecode($alltorrent); if (!isset($array) || !$array) bark("parse-error"); if (isset($array["announce"]) && in_array($array["announce"], $TRACKER_ANNOUNCEURLS) || !$array["announce"]){ $GLOBALS["internal"] = true; $array["info"]["private"]=1; $GLOBALS["hash"]=$file["tfile"]["name"];} else $GLOBALS["hash"] = $file["tfile"]["name"]; fclose($fd);} if (isset($array["comment"])) $info = mysql_escape_string(htmlspecialchars($array["comment"])); else $info = ""; if (isset($array["info"]) && $array["info"]) $upfile=$array["info"]; else $upfile = 0; if (isset($upfile["length"])) $GLOBALS["totallen"] = (float)($upfile["length"]); else if (isset($upfile["files"])){ $size=0; foreach ($upfile["files"] as $file) $GLOBALS["totallen"] += (float)($file["length"]);} else $size = "0"; $announces = str_replace(array("\r\n","\r","\n"), "", $array["announce"]); if($array["announce-list"]){ foreach($array["announce-list"] as $ky => $va){ if($va[0] != $announces[0] && preg_replace("/http:\/\//", "", $va[0])) $announce[] = $va[0];}} if($array["announce"]){ if(preg_replace("/http:\/\//", "", $array["announce"])) $announce[] = $array["announce"];} if ((!isset($array["announce"]) || !in_array($announces, $TRACKER_ANNOUNCEURLS)) && $EXTERNAL_TORRENTS == false){ unlink($file["tfile"]["tmp_name"]); bark("Мультитрекерные раздачи временно запрещены!");} $GLOBALS["infohash"] = $info["string"]; $GLOBALS["filelist"] = $array["info"]["files"]; if(count($filesArray) > 1) $GLOBALS["type"] = 'multi'; else $GLOBALS["type"] = 'single'; $GLOBALS["announce"] = $announce; $GLOBALS["infohash"] = sha1(BEncode($array["info"])); $GLOBALS["array"] = $array; } else bark("Торрент-файл не загружен!");}
* browse.php
Добавить в этот запрос
$query = "SELECT torrents.id, torrents.modded, torrents.modby, torrents.category, torrents.leechers, torrents.tags, torrents.seeders, torrents.free, torrents.name, torrents.times_completed, torrents.size, torrents.added, torrents.comments, torrents.numfiles, torrents.filename,
Эти ячеийки
torrents.seeders_net, torrents.leechers_net, torrents.times_completed_net, torrents.external,
* include/functions.php (function torrenttable())
После
while ($row = mysql_fetch_assoc($res)) { $id = $row["id"]; print("
\n");
Добавить
$row["seeders"] = $row["seeders"] + $row["seeders_net"]; $row["leechers"] = $row["leechers"] + $row["leechers_net"];
После
$dispname = $row["name"]; $thisisfree = ($row[free]=="yes" ? "
" : "");
Добавить
$isExtern = ($row["external"]=="yes" ? "
" : " ");
Заменить это
$dispname = $row["name"]; print("\">
$dispname
".$thisisfree."\n");
На это
print("\">
$dispname
".$isExtern . $thisisfree."\n");
* include/config.php
Добавить следующие переменные
# multitracker variables $extTrUpdatePeriod = 30; //минимальный период времени (в минутах) между 2мя обновлениями $EXTTOR_FUNC_DIR = "include/ext_tor-funcs/"; $TRACKER_ANNOUNCEURLS = array ( $BASEURL."/announce.php" ); $EXTERNAL_TORRENTS = true;
* include/cleanup.php
заменить это
$deadtime -= $max_dead_torrent_time; sql_query("UPDATE torrents SET visible='no' WHERE visible='yes' AND last_action < FROM_UNIXTIME($deadtime)") or sqlerr(__FILE__,__LINE__);
На это
$deadtime -= $max_dead_torrent_time; sql_query("UPDATE torrents SET visible='no' WHERE visible='yes' AND last_action < FROM_UNIXTIME($deadtime) AND external = 'no'") or sqlerr(__FILE__,__LINE__);
* папку "ext_tor-funcs" в архиве скопировать в папку "/include"
* картинку pic/multi.png скопировать в папку /pic
* заменить файл "download.php" на файл из архива