This is an example of semi refactorised code i am working on for TBDev 1.05 Release, this could be a month off.. Anyway I have for example done most of my first file at the top of the code.
This is announce.php
<?php /* +------------------------------------------------ | TBDev.net BitTorrent Tracker PHP for XOOPS | ============================================= | by CoLdFuSiOn | (c) 2003 - 2009 TBDev.Net | http://www.tbdev.net | ============================================= | svn: http://sourceforge.net/projects/tbdevnet/ | Licence Info: GPL +------------------------------------------------ | 2011-09-01 | 0.01 | Wishcraft | http://chronolabs.coop/ +------------------------------------------------ */ error_reporting(0); require_once '../../mainfile.php'; $GLOBALS['xoopsLogger']->activated = false; require_once 'include/config.php'; $users_handler = xoops_getmodulehandler('users', 'td'); $torrents_handler = xoops_getmodulehandler('torrents', 'td'); $peers_handler = xoops_getmodulehandler('peers', 'td'); define ('UC_VIP', 2); // DO NOT EDIT BELOW UNLESS YOU KNOW WHAT YOU'RE DOING!! $agent = $_SERVER["HTTP_USER_AGENT"]; // Deny access made with a browser... if ( ereg("^Mozilla\/", $agent) || ereg("^Opera\/", $agent) || ereg("^Links ", $agent) || ereg("^Lynx\/", $agent) || isset($_SERVER['HTTP_COOKIE']) || isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) || isset($_SERVER['HTTP_ACCEPT_CHARSET']) ) err("torrent not registered with this tracker CODE 1"); /////////////////////// FUNCTION DEFS /////////////////////////////////// function err($msg) { $torrents_handler->benc_resp(array('failure reason' => array('type' => 'string', 'value' => $msg))); exit(); } function hash_where($name, $hash) { $shhash = preg_replace('/ *$/s', "", $hash); return "($name = " . sqlesc($hash) . " OR $name = " . sqlesc($shhash) . ")"; } function portblacklisted($port) { // direct connect if ($port >= 411 && $port <= 413) return true; // bittorrent if ($port >= 6881 && $port <= 6889) return true; // kazaa if ($port == 1214) return true; // gnutella if ($port >= 6346 && $port <= 6347) return true; // emule if ($port == 4662) return true; // winmx if ($port == 6699) return true; return false; } /////////////////////// FUNCTION DEFS END /////////////////////////////// $parts = array(); $pattern = '[0-9a-fA-F]{32}'; if( !isset($_GET['passkey']) OR !ereg($pattern, $_GET['passkey'], $parts) ) err("Invalid Passkey"); else $GLOBALS['passkey'] = $parts[0]; foreach (array("info_hash","peer_id","event","ip","localip") as $x) { if(isset($_GET["$x"])) $GLOBALS[$x] = "" . $_GET[$x]; } foreach (array("port","downloaded","uploaded","left") as $x) { $GLOBALS[$x] = 0 + $_GET[$x]; } foreach (array("passkey","info_hash","peer_id","port","downloaded","uploaded","left") as $x) if (!isset($x)) err("Missing key: $x"); foreach (array("info_hash","peer_id") as $x) if (strlen($GLOBALS[$x]) != 20) err("Invalid $x (" . strlen($GLOBALS[$x]) . " - " . urlencode($GLOBALS[$x]) . ")"); unset($x); $info_hash = bin2hex($info_hash); $ip = $_SERVER['REMOTE_ADDR']; $port = 0 + $port; $downloaded = 0 + $downloaded; $uploaded = 0 + $uploaded; $left = 0 + $left; $rsize = 50; foreach(array("num want", "numwant", "num_want") as $k) { if (isset($_GET[$k])) { $rsize = 0 + $_GET[$k]; break; } } if (!$port || $port > 0xffff) err("invalid port"); if (!isset($event)) $event = ""; $seeder = ($left == 0) ? "yes" : "no"; $criteria = new CriteriaCompo(new Criteria('passkey', $passkey)); if ( $users_handler->getCount($criteria) != 1 ) err("Unknown passkey. Please redownload the torrent from {$GLOBALS['TBDEV']['baseurl']}."); $users = $users_handler->getObjects($criteria, false); if( $users[0]->getVar('enabled') == 'no' ) err('Permission denied, you're not enabled'); $criteria = new CriteriaCompo(new Criteria('info_hash', $info_hash)); //$res = $GLOBALS['xoopsDB']->queryF("SELECT id, banned, seeders + leechers AS numpeers, added AS ts FROM ".$GLOBALS['xoopsDB']->prefix("tb_torrents")." WHERE info_hash = " .sqlesc($info_hash));//" . hash_where("info_hash", $info_hash)); $torrents = $torrents_handler->getObjects($criteria, false); if (!is_object($torrents[0])) err("torrent not registered with this tracker CODE 2"); $torrentid = $torrents[0]->getVar("id"); $fields = "seeder, peer_id, ip, port, uploaded, downloaded, userid"; $numpeers = $torrents[0]->getVar("seeders")+$torrents[0]->getVar("leechers"); $criteria = new CriteriaCompo(new Criteria('torrent', $torrentid)); $criteria->add(new Criteria('connectable', 'yes')); if ($numpeers > $rsize) { $criteria->setSort('RAND()'); $criteria->setOrder('DESC'); $criteria->settLimit($rsize); } $peers = $peers_handler->getObjects($criteria, false); if($_GET['compact'] != 1){ $resp = "d" . $torrents_handler->benc_str("interval") . "i" . $GLOBALS['TBDEV']['announce_interval'] . "e" . $torrents_handler->benc_str("peers") . "l"; } else { $resp = "d" . $torrents_handler->benc_str("interval") . "i" . $GLOBALS['TBDEV']['announce_interval'] ."e" . $torrents_handler->benc_str("min interval") . "i" . 300 ."e5:"."peers" ; } $peer = array(); $peer_num = 0; foreach ($peers as $key => $peerobj) { if($_GET['compact'] != 1) { if (str_pad($peerobj->getVar("peer_id"), 20) === $peer_id) { $self = $peerobj; continue; } $resp .= "d" . $torrents_handler->benc_str("ip") . $torrents_handler->benc_str($peerobj->getVar("ip")); if (!$_GET['no_peer_id']) { $resp .= $torrents_handler->benc_str("peer id") . $torrents_handler->benc_str($peerobj->getVar("peer_id")); } $resp .= $torrents_handler->benc_str("port") . "i" . $peerobj->getVar("port") . "e" . "e"; } else { $peer_ip = explode('.', $peerobj->getVar("ip")); $peer_ip = pack("C*", $peer_ip[0], $peer_ip[1], $peer_ip[2], $peer_ip[3]); $peer_port = pack("n*", (int)$peerobj->getVar("port")); $time = intval((time() % 7680) / 60); if($_GET['left'] == 0) { $time += 128; } $time = pack("C", $time); $peer[] = $time . $peer_ip . $peer_port; $peer_num++; } } if ($_GET['compact']!=1) $resp .= "ee"; else { $o = ""; for($i=0;$i<$peer_num;$i++) { $o .= substr($peer[$i], 1, 6); } $resp .= strlen($o) . ':' . $o . 'e'; } $criteria = new CriteriaCompo(new Criteria('torrent', $torrentid)); $criteria->add(new Criteria('peer_id', $peer_id)); //////////////////////////// END NEW COMPACT MODE//////////////////////////////// if (!isset($self)) { $peers = $peers_handler->getObjects($criteria, false); if (is_object($peers[0])) { $userid = $peers[0]->getVar("userid"); $self = $peers[0]; } } //// Up/down stats //////////////////////////////////////////////////////////// if (!isset($self)) { $criteria = new CriteriaCompo(new Criteria('torrent', $torrentid)); $criteria->add(new Criteria('passkey', $passkey)); if ($peers_handler->getCount($criteria) >= 1 && $seeder == 'no') err("Connection limit exceeded! You may only leech from one location at a time."); if ($peers_handler->getCount($criteria) >= 3 && $seeder == 'yes') err("Connection limit exceeded!"); if ($left > 0 && $users[0]->getVar('class') < UC_VIP && $GLOBALS['TBDEV']['user_ratios']) { $gigs = $users[0]->getVar('uploaded') / (1024*1024*1024); $elapsed = floor((time() - $torrents[0]->getVar("ts")) / 3600); $ratio = (($users[0]->getVar('downloaded') > 0) ? ($users[0]->getVar('uploaded') / $users[0]->getVar('downloaded')) : 1); if ($ratio < 0.5 || $gigs < 5) $wait = 48; elseif ($ratio < 0.65 || $gigs < 6.5) $wait = 24; elseif ($ratio < 0.8 || $gigs < 8) $wait = 12; elseif ($ratio < 0.95 || $gigs < 9.5) $wait = 6; else $wait = 0; if ($elapsed < $wait) err("Not authorized (" . ($wait - $elapsed) . "h) - READ THE FAQ!"); } } else { $upthis = max(0, $uploaded - $self->getVar("uploaded")); $downthis = max(0, $downloaded - $self->getVar("downloaded")); if ($upthis > 0 || $downthis > 0) { $users[0]->setVar('uploaded', $users[0]->getVar('uploaded')+$upthis); $users[0]->setVar('downloaded', $users[0]->getVar('downloaded')+$downthis); $users_handler->insert($users[0], true); } } /////////////////////////////////////////////////////////////////////////////// $updateset = array(); if ($event == "stopped") { if (isset($self)) { $criteria = new CriteriaCompo(new Criteria('torrent', $torrentid)); $criteria->add(new Criteria('peer_id', $peer_id)); if ($peers_handler->deleteAll($criteria)) { if ($self["seeder"] == "yes") $torrents[0]->setVar('seeders', $torrents[0]->getVar('seeders')-1); else $torrents[0]->setVar('leechers', $torrents[0]->getVar('leechers')-1); } } } else { if ($event == "completed") $torrents[0]->setVar('times_completed', $torrents[0]->getVar('times_completed')+1); if (isset($self)) { $self->setVar('uploaded', $uploaded); $self->setVar('downloaded', $downloaded); $self->setVar('to_go', $left); $self->setVar('last_action', time()); $self->setVar('seeder', $seeder); if ($seeder == "yes" && $self->getVar("seeder") != $seeder ) $self->setVar('finishedat', time()); if ($peers_handler->insert($self, true) && $self->getVar("seeder") != $seeder) { if ($seeder == "yes") { $torrents[0]->setVar('seeders', $torrents[0]->getVar('seeders')+1); $torrents[0]->setVar('leechers', $torrents[0]->getVar('leechers')-1); } else { $torrents[0]->setVar('seeders', $torrents[0]->getVar('seeders')-1); $torrents[0]->setVar('leechers', $torrents[0]->getVar('leechers')+1); } } } else { if ($event != "started") err("Peer not found. ".$passkey." Restart the torrent."); if (portblacklisted($port)) { err("Port $port is blacklisted."); } elseif ( $GLOBALS['TBDEV']['connectable_check'] ) { $sockres = @fsockopen($ip, $port, $errno, $errstr, 5); if (!$sockres) $connectable = "no"; else { $connectable = "yes"; @fclose($sockres); } } else { $connectable = 'yes'; } $newpeer = $peers_handler->create(); $newpeer->setVar('connectable', $connectable); $newpeer->setVar('torrent', $torrentid); $newpeer->setVar('peer_id', $peer_id); $newpeer->setVar('ip', $ip); $newpeer->setVar('port', $port); $newpeer->setVar('uploaded', $uploaded); $newpeer->setVar('downloaded', $downloaded); $newpeer->setVar('to_go', $left); $newpeer->setVar('started', time()); $newpeer->setVar('last_action', time()); $newpeer->setVar('seeder', $seeder); $newpeer->setVar('userid', $user[0]->getVar('id')); $newpeer->setVar('agent', $agent); $newpeer->setVar('passkey', $passkey); if ($peers_handler->insert($newpeer, true)) { if ($seeder == "yes") $torrents[0]->setVar('seeders', $torrents[0]->getVar('seeders')+1); else $torrents[0]->setVar('leechers', $torrents[0]->getVar('leechers')+1); } } } if ($seeder == "yes") { if ($torrents[0]->getVar("banned") != "yes") $torrents[0]->setVar('visible', 'yes'); $torrents[0]->setVar('last_action', time()); } $torrents_handler->insert($torrents[0], true); $torrents_handler->benc_resp_raw($resp); ?>
it links to class/torrents.php which are all built for the database structure.
// class/torrents.php so far - code edited 11:56 PM 1/09/2011 AEST. <?php defined('XOOPS_ROOT_PATH') or die("XOOPS root path not defined"); class TbTorrents extends XoopsObject { function __construct() { $this->initVar('id', XOBJ_DTYPE_INT, null, false); $this->initVar('info_hash', XOBJ_DTYPE_TXTBOX, null, false, 40); $this->initVar('name', XOBJ_DTYPE_TXTBOX, null, false, 255); $this->initVar('filename', XOBJ_DTYPE_TXTBOX, null, false, 255); $this->initVar('save_as', XOBJ_DTYPE_TXTBOX, null, false, 255); $this->initVar('search_text', XOBJ_DTYPE_OTHER, null, false); $this->initVar('descr', XOBJ_DTYPE_OTHER, null, false); $this->initVar('ori_descr', XOBJ_DTYPE_OTHER, null, false); $this->initVar('category', XOBJ_DTYPE_INT, null, false); $this->initVar('size', XOBJ_DTYPE_INT, null, false); $this->initVar('added', XOBJ_DTYPE_INT, null, false); $this->initVar('type', XOBJ_DTYPE_ENUM, null, false, false, false, array('single','multi')); $this->initVar('numfiles', XOBJ_DTYPE_INT, null, false); $this->initVar('comments', XOBJ_DTYPE_INT, null, false); $this->initVar('views', XOBJ_DTYPE_INT, null, false); $this->initVar('hits', XOBJ_DTYPE_INT, null, false); $this->initVar('times_completed', XOBJ_DTYPE_INT, null, false); $this->initVar('leechers', XOBJ_DTYPE_INT, null, false); $this->initVar('seeders', XOBJ_DTYPE_INT, null, false); $this->initVar('last_action', XOBJ_DTYPE_INT, null, false); $this->initVar('visible', XOBJ_DTYPE_ENUM, null, false, false, false, array('yes', 'no')); $this->initVar('banned', XOBJ_DTYPE_ENUM, null, false, false, false, array('yes', 'no')); $this->initVar('owner', XOBJ_DTYPE_INT, null, false); $this->initVar('numratings', XOBJ_DTYPE_INT, null, false); $this->initVar('ratingsum', XOBJ_DTYPE_INT, null, false); $this->initVar('nfo', XOBJ_DTYPE_OTHER, null, false); $this->initVar('client_created_by', XOBJ_DTYPE_TXTBOX, null, false, 50); } function TbTorrents() { $this->__construct(); } } class TbTorrentsHandler extends XoopsPersistableObjectHandler { function TbTorrentsHandler(&$db) { $this->__construct($db); } function __construct(&$db) { parent::__construct($db, "tb_torrents", 'TbTorrents', "id"); } function benc_resp($d) { $this->benc_resp_raw($this->benc(array('type' => 'dictionary', 'value' => $d))); } function benc_resp_raw($x) { header( "Content-Type: text/plain" ); header( "Pragma: no-cache" ); if ( $_SERVER['HTTP_ACCEPT_ENCODING'] == 'gzip' ) { header( "Content-Encoding: gzip" ); echo gzencode( $x, 9, FORCE_GZIP ); } else echo $x ; } function benc($obj) { if (!is_array($obj) || !isset($obj["type"]) || !isset($obj["value"])) return; $c = $obj["value"]; switch ($obj["type"]) { case "string": return $this->benc_str($c); case "integer": return $this->benc_int($c); case "list": return $this->benc_list($c); case "dictionary": return $this->benc_dict($c); default: return; } } function benc_str($s) { return strlen($s) . ":$s"; } function benc_int($i) { return "i" . $i . "e"; } function benc_list($a) { $s = "l"; foreach ($a as $e) { $s .= $this->benc($e); } $s .= "e"; return $s; } function benc_dict($d) { $s = "d"; $keys = array_keys($d); sort($keys); foreach ($keys as $k) { $v = $d[$k]; $s .= $this->benc_str($k); $s .= $this->benc($v); } $s .= "e"; return $s; } } ?>