seria/src/Torrents/AnnounceInfo.php

78 lines
2.4 KiB
PHP

<?php
namespace Seria\Torrents;
use Index\Serialisation\IBencodeSerialisable;
class AnnounceInfo implements IBencodeSerialisable {
// todo: keep these in a field in ser_torrents so we don't need this slightly filthy hack anymore
// also useful for ipv6 peer support
private int $completePeers = 0;
private int $incompletePeers = 0;
public function __construct(
private array $peers,
private int $interval,
private int $minInterval,
private bool $compactPeers,
private bool $noPeerIds
) {}
private function createCompactPeersList(): string {
$peers = '';
foreach($this->peers as $peerInfo) {
$peerInfo->isSeed() ? ++$this->completePeers : ++$this->incompletePeers;
$peers .= $peerInfo->getAddressRaw() . pack('n', $peerInfo->getPort());
}
return $peers;
}
private function createPeersListWithIds(): array {
$peers = [];
foreach($this->peers as $peerInfo) {
$peerInfo->isSeed() ? ++$this->completePeers : ++$this->incompletePeers;
$peers[] = [
'peer id' => $peerInfo->getId(),
'ip' => $peerInfo->getAddress(),
'port' => $peerInfo->getPort(),
];
}
return $peers;
}
private function createPeersListWithoutIds(): array {
$peers = [];
foreach($this->peers as $peerInfo) {
$peerInfo->isSeed() ? ++$this->completePeers : ++$this->incompletePeers;
$peers[] = [
'ip' => $peerInfo->getAddress(),
'port' => $peerInfo->getPort(),
];
}
return $peers;
}
public function createPeersList(): array|string {
if($this->compactPeers)
return $this->createCompactPeersList();
if($this->noPeerIds)
return $this->createPeersListWithoutIds();
return $this->createPeersListWithIds();
}
public function bencodeSerialise(): mixed {
$peers = $this->createPeersList();
return [
'interval' => $this->interval,
'min interval' => $this->minInterval,
'complete' => $this->completePeers,
'incomplete' => $this->incompletePeers,
//'downloaded' => 0, todo: keep track of how many completes
'peers' => $peers,
//'peers6' => '', todo: support ipv6 someday
];
}
}