/** * Builds tracker announce response in bencoded format * * @param Torrent $torrent * @param PeerTorrent $peerTorrent * @param $compact * @param int $no_peer_id * @return string */ public static function buildAnnounceResponse(Torrent $torrent, PeerTorrent $peerTorrent, $compact, $no_peer_id = 0) { // Compact mode if ($compact != 1) { $resp = "d" . self::bencodeString("interval") . "i" . self::__INTERVAL . "e" . self::bencodeString("peers") . "l"; } else { $resp = "d" . self::bencodeString("interval") . "i" . self::__INTERVAL . "e" . self::bencodeString("min interval") . "i" . 300 . "e5:" . "peers"; } $peer = array(); $peer_num = 0; foreach ($torrent->getPeersArray() as $row) { if ($compact != 1) { if ($row["peer_id"] === $peerTorrent->peerInstance()->hash) { continue; } $resp .= "d" . self::bencodeString("ip") . self::bencodeString($row['ip']); if ($no_peer_id == 0) { $resp .= self::bencodeString("peer id") . self::bencodeString($row["peer_id"]); } $resp .= self::bencodeString("port") . "i" . $row["port"] . "e" . "e"; } else { $peer_ip = explode('.', $row["ip"]); $peer_ip = pack("C*", $peer_ip[0], $peer_ip[1], $peer_ip[2], $peer_ip[3]); $peer_port = pack("n*", (int) $row["port"]); $time = intval(time() % 7680 / 60); if ($peerTorrent->left == 0) { $time += 128; } $time = pack("C", $time); $peer[] = $time . $peer_ip . $peer_port; $peer_num++; } } if ($compact != 1) { $resp .= "ee"; } else { $o = ""; for ($i = 0; $i < $peer_num; $i++) { $o .= substr($peer[$i], 1, 6); } $resp .= strlen($o) . ':' . $o . 'e'; } return $resp; }