config = config('perfectpurple.tracker'); $this->userProfile = $userProfile; $this->torrentPeer = $torrentPeer; $this->torrentFile = $torrentFile; //$this->torrentHistory = $torrentHistory; $this->request = new stdClass(); } /** * @return bool */ public function checkAccess(): bool { return !preg_match('/' . $this->browsers . '/', $this->request->agent); } /** * @return bool */ public function checkClientValues(): bool { return !empty($this->request->port); } /** * @return bool */ public function checkTorrent(): bool { if(empty($this->request->infoHash)) { return false; } $this->currentTorrent = $this->torrentFile->readByInfoHash($this->request->infoHash); return !is_null($this->currentTorrent); } /** * @return bool */ public function checkPid(): bool { $userProfile = $this->userProfile->readByPid($this->request->pid); return !is_null($userProfile); } /** * @return bool */ public function checkSamePid(): bool { $data = $this->torrentPeer->status($this->request->pid, $this->currentTorrent->id); if(!$data->isEmpty()) { foreach($data as $set) { if($set->status == 'seeder' && $set->status_cnt >= $this->config['max_pid_seed']) return false; if($set->status == 'leecher' && $set->status_cnt >= $this->config['max_pid_leech']) return false; } return true; } return true; } /** * @return $this */ public function checkFirewalled(): Announce { $theError = ''; $fd = fsockopen($this->request->ip, $this->request->port, $errno, $theError, 10); $this->request->nat = !$fd; fclose($fd); return $this; } /** * @return bool|string */ public function checkClientEvent(): bool|string { $this->currentPeer = $this->torrentPeer->read($this->request->pid, $this->currentTorrent->uuid, ['profile']); return match ($this->request->event) { 'started' => $this->torrentStarted(), 'stopped' => $this->torrentStopped(), 'finished' => $this->torrentFinished(), empty($this->currentRequest->event) => $this->torrentNoEvent(), default => false, }; } /** * @return string */ private function torrentStarted(): string { if(!is_null($this->currentPeer)) { $this->torrentPeer->edit($this->currentPeer, $this->request); } else { $this->torrentPeer->add($this->request, $this->currentTorrent); $this->currentPeer = $this->torrentPeer; } /*$history = $this->torrentHistory->read($this->currentPeer->user->uid, $this->currentTorrent->id); if(!is_null($history)) { $this->torrentHistory->edit($history, $this->currentRequest, true); } elseif(is_null($history) && $this->currentRequest->left > 0) { $this->torrentHistory->add($this->currentPeer, $this->currentTorrent, $this->currentRequest, true); }*/ $this->torrentFile->setSeedersLeechers($this->currentTorrent, $this->request); return $this->getRandomPeers(); } /** * @return string */ private function torrentStopped(): string { $this->torrentPeer->kill($this->currentPeer, $this->currentTorrent); $this->userProfile->setTraffic($this->currentPeer->profile, $this->request); /*$history = $this->torrentHistory->read($this->currentPeer->user->uid, $this->currentTorrent->id); if(!is_null($history)) { $this->torrentHistory->edit($history, $this->currentRequest, false); }*/ return $this->getRandomPeers(); } /** * @return string */ private function torrentFinished(): string { if(is_null($this->currentPeer)) { $this->torrentPeer->add($this->request, $this->currentTorrent); $this->currentPeer = $this->torrentPeer; } $this->torrentPeer->complete($this->currentPeer, $this->request); $this->torrentFile->complete($this->currentTorrent); /*$history = $this->torrentHistory->read($this->currentPeer->user->uid, $this->currentTorrent->id); if(!is_null($history)) { $this->torrentHistory->edit($history, $this->currentRequest, true, true); } else { $this->torrentHistory->add($this->currentPeer, $this->currentTorrent, $this->currentRequest, true, true); }*/ return $this->getRandomPeers(); } /** * @return string */ private function torrentNoEvent(): string { if(is_null($this->currentPeer)) { $this->torrentPeer->add($this->request, $this->currentTorrent); $this->currentPeer = $this->torrentPeer; } if($this->currentPeer->bytes != 0 && $this->request->left == 0) { $this->torrentPeer->complete($this->currentPeer, $this->request); $this->torrentFile->complete($this->currentTorrent); } $this->collectBytes(); return $this->getRandomPeers(); } /** * @return void */ private function collectBytes(): void { $diff = bcsub($this->currentPeer->bytes, $this->currentPeer->left); $this->torrentPeer->setBytes($this->currentPeer, $this->request, $diff); } /** * @return string */ private function getRandomPeers(): string { $data = $this->torrentPeer->random($this->currentTorrent->uuid, $this->request->numWant); if(!is_null($data) && $this->request->compact) { $compactStr = ''; $data->map(function($set) use(&$compactStr) { $compactStr .= str_pad(pack('Nn', ip2long($set->ip), $set->port), 6); }); return $compactStr; } return $data; } }