public function updateTorrentPeer(PwTorrentPeerDm $dm, $fetchmode = self::FETCH_MAIN) { if (($result = $dm->beforeUpdate()) !== true) { return $result; } return $this->_getDao($fetchmode)->updateTorrentPeer($dm->id, $dm->getData(), $dm->getIncreaseData()); }
public function announceAction() { $passkey = $this->getInput('passkey'); $infoHash = $this->getInput('info_hash'); $peerId = $this->getInput('peer_id'); $event = $this->getInput('event'); $port = $this->getInput('port'); $downloaded = $this->getInput('downloaded'); $uploaded = $this->getInput('uploaded'); $left = $this->getInput('left'); $compact = $this->getInput('compact'); $no_peer_id = $this->getInput('no_peer_id'); $agent = $_SERVER['HTTP_USER_AGENT']; $ip = Wind::getComponent('request')->getClientIp(); $status = $left > 0 ? 'do' : 'done'; $seeder = $left > 0 ? 'no' : 'yes'; Wind::import('EXT:torrent.service.srv.helper.PwAnnounce'); // Check if a BitTorrent client $allowed = false; $allowedClients = $this->_getTorrentAgentDS()->fetchTorrentAgent(); if (is_array($allowedClients)) { foreach ($allowedClients as $allowedClient) { if (!preg_match($allowedClient['agent_pattern'], $agent)) { continue; } if ($allowedClient['peer_id_pattern'] == '' || preg_match($allowedClient['peer_id_pattern'], $peerId)) { $allowed = true; } break; } } if (!$allowed) { header('Location: ' . WindUrlHelper::createUrl('/')); PwAnnounce::showError('This a a bittorrent application and can\'t be loaded into a browser!'); } header('Content-Type: text/plain; charset=utf-8'); header('Pragma: no-cache'); // Verify passkey $user = $this->_getTorrentUserDS()->getTorrentUserByPasskey($passkey); if (!$user) { PwAnnounce::showError('Invalid passkey! Re-download the torrent file!'); } // Check if user was banned $userBan = $this->__getUserBanDS()->getBanInfo($user['uid']); if ($userBan) { PwAnnounce::showError('User was banned!'); } // Get torrent information by infoHash $torrent = $this->_getTorrentDS()->getTorrentByInfoHash($infoHash); if (!$torrent) { PwAnnounce::showError('Torrent not registered with this tracker!'); } // Check if torrent was removed $topic = $this->__getThreadDS()->getThread($torrent['tid']); if ($topic['disabled'] > 0 && !(in_array($user['groupid'], array(3, 4, 5)) || $topic['created_userid'] == $user['uid'])) { PwAnnounce::showError('Torrent removed!'); } // Get peers list $peers = PwAnnounce::getPeersByTorrentId($torrent['id'], $self['peer_id']); // Get this peer $self = $this->_getTorrentPeerDS()->getTorrentPeerByTorrentAndUid($torrent['id'], $user['uid']); Wind::import('EXT:torrent.service.dm.PwTorrentPeerDm'); if (!empty($self)) { // Check if already started if ($ip != $self['ip']) { PwAnnounce::showError('You have already started downloading this torrent!'); } $dm = new PwTorrentPeerDm($self['id']); switch ($event) { case '': case 'started': $dm->setIp($ip)->setPort($port)->setUploaded($uploaded)->setDownloaded($downloaded)->setToGo($left)->setPrevAction(Pw::time2str(Pw::getTime(), 'Y-m-d H:i:s'))->setLastAction(Pw::time2str(Pw::getTime(), 'Y-m-d H:i:s'))->setSeeder($seeder)->setAgent($agent); $this->_getTorrentPeerDS()->updateTorrentPeer($dm); break; case 'stopped': $this->_getTorrentPeerDS()->deleteTorrentPeer($self['id']); $status = 'stop'; break; case 'completed': $dm->setFinishedAt(Pw::getTime())->setIp($ip)->setPort($port)->setUploaded($uploaded)->setDownloaded($downloaded)->setToGo($left)->setPrevAction(Pw::time2str(Pw::getTime(), 'Y-m-d H:i:s'))->setLastAction(Pw::time2str(Pw::getTime(), 'Y-m-d H:i:s'))->setSeeder($seeder)->setAgent($agent); $this->_getTorrentPeerDS()->updateTorrentPeer($dm); $status = 'done'; break; default: PwAnnounce::showError('Invalid event from client!'); } } else { $sockres = @pfsockopen($ip, $port, $errno, $errstr, 5); if ($errno == '111') { $connectable = 'no'; } else { $connectable = 'yes'; } @fclose($sockres); $dm = new PwTorrentPeerDm(); $dm->setTorrent($torrent['id'])->setUserid($user['uid'])->setPeerId($peerId)->setIp($ip)->setPort($port)->setConnectable($connectable)->setUploaded($uploaded)->setDownloaded($downloaded)->setToGo($left)->setStarted(Pw::time2str(Pw::getTime(), 'Y-m-d H:i:s'))->setLastAction(Pw::time2str(Pw::getTime(), 'Y-m-d H:i:s'))->setSeeder($seeder)->setAgent($agent)->setPasskey($passkey); $this->_getTorrentPeerDS()->addTorrentPeer($dm); $self = $this->_getTorrentPeerDS()->getTorrentPeerByTorrentAndUid($torrent['id'], $user['uid']); } // Update user's history about this torrent $history = $this->_getTorrentHistoryDs()->getTorrentHistoryByTorrentAndUid($torrent['id'], $user['uid']); Wind::import('EXT:torrent.service.dm.PwTorrentHistoryDm'); if (!$history) { $dm = new PwTorrentHistoryDm(); $dm->setUid($user['uid'])->setTorrent($torrent['id'])->setUploaded($uploaded)->setDownloaded($downloaded); $this->_getTorrentHistoryDs()->addTorrentHistory($dm); if ($downloaded != 0) { $rotio = round($uploaded / $downloaded, 2); } else { $rotio = 1; } } else { $uploaded_add = max(0, $uploaded - $history['uploaded_last']); $downloaded_add = max(0, $downloaded - $history['downloaded_last']); $uploaded_total = $history['uploaded'] + $uploaded_add; $downloaded_total = $history['downloaded'] + $downloaded_add; if ($downloaded_total != 0) { $rotio = round($uploaded_total / $downloaded_total, 2); } else { $rotio = 1; } $dm = new PwTorrentHistoryDm($history['id']); $dm->setUid($user['uid'])->setTorrent($torrent['id'])->setUploaded($uploaded_total)->setUploadedLast($uploaded)->setDownloaded($downloaded_total)->setDownloadedLast($downloaded)->setStatus($status); $this->_getTorrentHistoryDs()->updateTorrentHistory($dm); } // Count Peers $torrent = PwAnnounce::updatePeerCount($torrent, $peers); // Update user's credits if (Wekit::C('site', 'app.torrent.creditifopen') == 1) { $changed = 0; $WindApi = WindidApi::api('user'); $crdtits = $WindApi->getUserCredit($user['uid']); $user_torrents = count($this->_getTorrentDS()->fetchTorrentByUid($user['uid'])); $histories = $this->_getTorrentHistoryDs()->fetchTorrentHistoryByUid($user['uid']); if (is_array($histories)) { foreach ($histories as $history) { $downloaded_total += $history['downloaded']; $uploaded_total += $history['uploaded']; } } if ($downloaded_total != 0) { $rotio_total = round($uploaded_total / $downloaded_total, 2); } else { $rotio_total = 1; } $userpeers = $this->_getTorrentPeerDS()->fetchTorrentPeerByUid($user['uid']); if (is_array($userpeers)) { foreach ($userpeers as $p) { if ($p['seeder'] == 'yes') { $seeding++; } else { $leeching++; } } } $tAlive = (time() - strtotime($torrent['created_time'])) / 86400; $timeUsed = time() - strtotime($self['started']); $timeLa = time() - strtotime($self['last_action']); $m = Wekit::load('EXT:torrent.service.srv.helper.PwEvalmath'); $m->e('alive = ' . round($tAlive)); $m->e('seeders = ' . round($torrent['seeders'])); $m->e('leechers = ' . round($torrent['leechers'])); $m->e('size = ' . round($torrent['size'])); $m->e('seeding = ' . round($seeding)); $m->e('leeching = ' . round($leeching)); $m->e('downloaded_add = ' . round($downloaded_add)); $m->e('downloaded_total = ' . round($downloaded_total)); $m->e('uploaded_add = ' . round($uploaded_add)); $m->e('uploaded_total = ' . round($uploaded_total)); $m->e('rotio = ' . round($rotio)); $m->e('rotio_total = ' . round($rotio_total)); $m->e('time = ' . round($timeUsed)); $m->e('time_la = ' . round($timeLa)); $m->e('torrents = ' . round($user_torrents)); $_credits = Wekit::C('site', 'app.torrent.credits'); if (is_array($_credits)) { foreach ($_credits as $key => $value) { if ($value['enabled'] != '1') { continue; } $m->e('credit = ' . round($crdtits['credit' . $key])); $c = round($m->e($value['exp'])); if ($c >= 1) { $changes[$key] = $c; $changed++; } } } if ($changed) { Wind::import('SRV:credit.bo.PwCreditBo'); Wind::import('SRV:user.bo.PwUserBo'); $creditBo = PwCreditBo::getInstance(); $creditBo->addLog('app_torrent', $changes, new PwUserBo($user['uid']), array('torrent' => $topic['subject'])); $creditBo->sets($user['uid'], $changes); } } // Update peer Wind::import('EXT:torrent.service.dm.PwTorrentDm'); $dm = new PwTorrentDm($torrent['id']); $dm->setSeeders($torrent['seeders'])->setLeechers($torrent['leechers'])->setLastAction(Pw::time2str(Pw::getTime(), 'Y-m-d H:i:s')); $this->_getTorrentDS()->updateTorrent($dm); // Output peers list to client $peer_string = PwAnnounce::buildPeerList($torrent, $peers, $compact, $no_peer_id); exit($peer_string); }