/** * @param $data * @return array|null */ protected function prepareData($data) { if (empty($data)) { return null; } try { $data = Bencode::decode($data); } catch (RuntimeException $e) { return null; } if (!(isset($data['files']) && is_array($data['files']))) { return null; } $prepared = ['files' => []]; foreach ($data['files'] as $key => $value) { if (ctype_print($key)) { $prepared['files'][$key] = $value; } else { $prepared['files'][bin2hex($key)] = $value; } } return $prepared; }
public function announce($tid, $uid) { // torrent klients (utorrent) atver šādu adresi // http://xxx/announce/2/2?info_hash=xxxx&peer_id=xxxx&numwant=50&event=started&port=123&left=0 // parametru skaidrojums // https://wiki.theory.org/BitTorrentSpecification (Tracker Request Parameters) $torrent = Torrent::findOrFail($tid); $user = User::findOrFail($uid); Eloquent::unguard(); // atlasa ierakstu vai izveido jaunu $data = TorrentUser::firstOrCreate(array('torrent_id' => $torrent->id, 'user_id' => $user->id, 'peer_id' => @$_GET['peer_id'])); $data->ip = $_SERVER['REMOTE_ADDR']; // utorrent ip adrese $data->port = (int) @$_GET['port']; // utorrent ports $data->peer_id = @$_GET['peer_id']; // utorrent kaut kāds id $data->seeding = @$_GET['left'] == 0; // cik baiti atlikuši lejuplādēt (0 = pabeigts) if (@$_GET['event'] == 'stopped') { $data->delete(); // nospieda stop pogu, dzēšam } else { $data->save(); } $numwant = isset($_GET['numwant']) ? (int) $_GET['numwant'] : 50; // cik datus par citiem lietotājiem grib $complete = TorrentUser::where('torrent_id', $torrent->id)->where('seeding', true)->count(); // saskaita šim torrentam seederus $incomplete = TorrentUser::where('torrent_id', $torrent->id)->where('seeding', false)->count(); // saskaita šim torrentam leecherus $peers = TorrentUser::where('torrent_id', $torrent->id)->select('peer_id', 'ip', 'port')->take($numwant)->get()->toArray(); // https://wiki.theory.org/BitTorrentSpecification (Tracker Response) $response = array('interval' => 60, 'tracker id' => 'tracker', 'complete' => $complete, 'incomplete' => $incomplete, 'peers' => $peers); $response = Response::make(Bencode::encode($response), 200); $response->header('Content-Type', 'text/plain'); return $response; }
public function getDownload($id) { $torrent = Torrent::find($id); if (!$torrent) { App::abort(404); } $torrent->downloads += 1; $torrent->save(); $decoded = Bencode::decode($torrent->file); $decoded['announce'] = Config::get('app.url') . '/announce/' . $torrent->id . '/' . Auth::user()->id; unset($decoded['announce-list']); $torrent->file = Bencode::encode($decoded); $response = Response::make($torrent->file, 200); $response->header('Content-Type', 'application/x-bittorrent'); // http://x-bittorrent.mime-application.com/ $response->header('Content-Disposition', 'attachment; filename=' . $torrent->name . '.torrent'); // http://stackoverflow.com/questions/93551/how-to-encode-the-filename-parameter-of-content-disposition-header-in-http return $response; }
/** * Декодує дані з torrent файла * @param TorrentFile $torrentFile * @param $data */ public static function decode(TorrentFile $torrentFile, $data) { $torrent = $torrentFile->getTorrent(); $data = \Rych\Bencode\Bencode::decode($data); foreach ($data as $itemKey => $item) { switch ($itemKey) { case 'announce-list': foreach ($item as $announceItem) { $announce = new Announce(); $announce->setAnnounce($announceItem[0]); $torrent->addAnnounce($announce); } break; case 'comment': $torrent->setComment($item); break; case 'created by': $torrent->setCreated_by($item); break; case 'creation date': $torrent->setCreation_date($item); break; case 'encoding': $torrent->setEncoding($item); break; case 'rss': $torrent->setRss($item); break; case 'similar_torrents': $torrent->setSimilar_torrents($item); break; case 'url-list': foreach ($item as $urlItem) { $url = new Url(); $url->setUrl($urlItem); $torrent->addUrl($url); } break; case 'website': $torrent->setWebsite($item); break; case 'info': foreach ($item as $infoKeyItem => $itemInfo) { switch ($infoKeyItem) { case 'files': foreach ($itemInfo as $fileItem) { $file = new File(); $file->setLength($fileItem['length']); $file->setPath(implode('/', $fileItem['path'])); $torrent->getInfo()->addFile($file); } break; case 'name': $torrent->getInfo()->setName($itemInfo); break; case 'piece length': $torrent->getInfo()->setPiece_length($itemInfo); break; case 'pieces': $torrent->getInfo()->setPieces($itemInfo); break; case 'private': $torrent->getInfo()->setPrivate($itemInfo); break; case 'length': $torrent->getInfo()->setPrivate($itemInfo); break; default: $torrent->getInfo()->addOtherItem($infoKeyItem, $itemInfo); } } break; default: $torrent->addOtherItem($itemKey, $item); } } }