packetQueue = []; $this->type = $type; } public function getType(): int { return $this->type; } public function queue(string $data): void { $this->packetQueue[] = $data; } public function open(string $address, int $port, int $timeout): void { $this->timeout = $timeout; $this->port = $port; $this->address = $address; } /** * Close. */ public function close(): void { } /** * @throws InvalidPacketException */ public function read(int $length = 1400): Buffer { $buffer = new Buffer(); $packet = array_shift($this->packetQueue); if (!$packet) { throw new InvalidPacketException('Empty packet'); } $buffer->set($packet); $this->readInternal($buffer, $length, [$this, 'sherlock']); return $buffer; } public function write(int $header, string $string = ''): bool { return true; } /** * @throws InvalidPacketException */ public function sherlock(Buffer $buffer, int $length): bool { if (0 === count($this->packetQueue)) { return false; } $buffer->set(array_shift($this->packetQueue)); return -2 === $buffer->getLong(); } /** * @throws InvalidPacketException */ protected function readInternalPacketData( Buffer $buffer, int &$count, int &$number, bool &$isCompressed, ?int &$checksum ): void { switch ($this->type) { case SocketType::GOLDSOURCE: $this->readInternalPacketDataGoldSource( $buffer, $count, $number, $isCompressed, $checksum ); break; case SocketType::SOURCE: default: $this->readInternalPacketDataSource( $buffer, $count, $number, $isCompressed, $checksum ); } } /** * Same as GoldSourceSocket::readInternalPacketData. */ private function readInternalPacketDataGoldSource( Buffer $buffer, int &$count, int &$number, bool &$isCompressed, ?int &$checksum ): void { $packetCountAndNumber = $buffer->getByte(); $count = $packetCountAndNumber & 0xF; $number = $packetCountAndNumber >> 4; $isCompressed = false; } /** * Same as SourceSocket::readInternalPacketData. * * @throws InvalidPacketException */ private function readInternalPacketDataSource( Buffer $buffer, int &$count, int &$number, bool &$isCompressed, ?int &$checksum ): void { $count = $buffer->getByte(); $number = $buffer->getByte() + 1; if ($isCompressed) { $buffer->getLong(); // Split size. $checksum = $buffer->getUnsignedLong(); } else { $buffer->getShort(); // Split size. } } }