public function Read($Length = 1400) { $this->Buffer->Set(FRead($this->Socket, $Length)); if ($this->Buffer->Remaining() === 0) { // TODO: Should we throw an exception here? return; } $Header = $this->Buffer->GetLong(); if ($Header === -1) { // We don't have to do anything } else { if ($Header === -2) { $Packets = array(); $IsCompressed = false; $ReadMore = false; do { $RequestID = $this->Buffer->GetLong(); switch ($this->Engine) { case SourceQuery::GOLDSOURCE: $PacketCountAndNumber = $this->Buffer->GetByte(); $PacketCount = $PacketCountAndNumber & 0xf; $PacketNumber = $PacketCountAndNumber >> 4; break; case SourceQuery::SOURCE: $IsCompressed = ($RequestID & 0x80000000) !== 0; $PacketCount = $this->Buffer->GetByte(); $PacketNumber = $this->Buffer->GetByte() + 1; if ($IsCompressed) { $this->Buffer->GetLong(); // Split size $PacketChecksum = $this->Buffer->GetUnsignedLong(); } else { $this->Buffer->GetShort(); // Split size } break; } $Packets[$PacketNumber] = $this->Buffer->Get(); $ReadMore = $PacketCount > sizeof($Packets); } while ($ReadMore && $this->Sherlock($Length)); $Buffer = Implode($Packets); // TODO: Test this if ($IsCompressed) { // Let's make sure this function exists, it's not included in PHP by default if (!Function_Exists('bzdecompress')) { throw new RuntimeException('Received compressed packet, PHP doesn\'t have Bzip2 library installed, can\'t decompress.'); } $Data = bzdecompress($Data); if (CRC32($Data) !== $PacketChecksum) { throw new SourceQueryException('CRC32 checksum mismatch of uncompressed packet data.'); } } $this->Buffer->Set(SubStr($Buffer, 4)); } else { throw new SourceQueryException('Socket read: Raw packet header mismatch. (0x' . DecHex($Header) . ')'); } } }
/** * Get rules (cvars) from the server * * @throws SourceQueryException * * @return bool|array Returns array with rules on success, false on failure */ public function GetRules() { if (!$this->Connected) { return false; } switch ($this->GetChallenge(self::A2S_RULES, self::S2A_RULES)) { case self::GETCHALLENGE_FAILED: return false; case self::GETCHALLENGE_ALL_CLEAR: $this->Socket->Write(self::A2S_RULES, $this->Challenge); $this->Socket->Read(); $Type = $this->Buffer->GetByte(); if ($Type == 0) { return false; } else { if ($Type != self::S2A_RULES) { throw new SourceQueryException('GetRules: Packet header mismatch. (0x' . DecHex($Type) . ')'); } } break; } $Rules = array(); $Count = $this->Buffer->GetShort(); while ($Count-- > 0 && $this->Buffer->Remaining() > 0) { $Rule = $this->Buffer->GetString(); $Value = $this->Buffer->GetString(); if (!empty($Rule)) { $Rules[$Rule] = $Value; } } return $Rules; }