/**
  * @param int $Length
  * @throws AuthenticationException
  */
 public function Read($Length = 1400)
 {
     // GoldSource RCON has same structure as Query
     $this->Socket->Read();
     if ($this->Buffer->GetByte() !== SourceQuery::S2A_RCON) {
         return false;
     }
     $Buffer = $this->Buffer->Get();
     $Trimmed = Trim($Buffer);
     if ($Trimmed === 'Bad rcon_password.') {
         throw new AuthenticationException($Trimmed, AuthenticationException::BAD_PASSWORD);
     } else {
         if ($Trimmed === 'You have been banned from this server.') {
             throw new AuthenticationException($Trimmed, AuthenticationException::BANNED);
         }
     }
     $ReadMore = false;
     // There is no indentifier of the end, so we just need to continue reading
     // TODO: Needs to be looked again, it causes timeouts
     do {
         $this->Socket->Read();
         $ReadMore = $this->Buffer->Remaining() > 0 && $this->Buffer->GetByte() === SourceQuery::S2A_RCON;
         if ($ReadMore) {
             $Packet = $this->Buffer->Get();
             $Buffer .= SubStr($Packet, 0, -2);
             // Let's assume if this packet is not long enough, there are no more after this one
             $ReadMore = StrLen($Packet) > 1000;
             // use 1300?
         }
     } while ($ReadMore);
     $this->Buffer->Set(Trim($Buffer));
 }
Example #2
0
 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.');
                 }
                 $Buffer = bzdecompress($Buffer);
                 if (CRC32($Buffer) !== $PacketChecksum) {
                     throw new InvalidPacketException('CRC32 checksum mismatch of uncompressed packet data.', InvalidPacketException::CHECKSUM_MISMATCH);
                 }
             }
             $this->Buffer->Set(SubStr($Buffer, 4));
         } else {
             throw new InvalidPacketException('Socket read: Raw packet header mismatch. (0x' . DecHex($Header) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH);
         }
     }
 }
Example #3
0
 public function Read($Length = 1400)
 {
     $this->Buffer->Set(FRead($this->RconSocket, $Length));
     if ($this->Buffer->Remaining() < 4) {
         throw new InvalidPacketException('Rcon read: Failed to read any data from socket', InvalidPacketException::BUFFER_EMPTY);
     }
     $PacketSize = $this->Buffer->GetLong();
     $Buffer = $this->Buffer->Get();
     $Remaining = $PacketSize - StrLen($Buffer);
     while ($Remaining > 0) {
         $Buffer2 = FRead($this->RconSocket, $Length);
         $Buffer .= $Buffer2;
         $Remaining -= StrLen($Buffer2);
     }
     $this->Buffer->Set($Buffer);
 }
 /**
  * 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;
 }
 public function Read($Length = 1400)
 {
     $this->Buffer->Set(FRead($this->Socket, $Length));
     if ($this->Buffer->Remaining() > 0 && $this->Buffer->GetLong() == -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));
     }
 }
 public function Read()
 {
     $this->Buffer->Set(FRead($this->RconSocket, 4));
     if ($this->Buffer->Remaining() < 4) {
         throw new InvalidPacketException('Rcon read: Failed to read any data from socket', InvalidPacketException::BUFFER_EMPTY);
     }
     $PacketSize = $this->Buffer->GetLong();
     $this->Buffer->Set(FRead($this->RconSocket, $PacketSize));
     $Buffer = $this->Buffer->Get();
     $Remaining = $PacketSize - StrLen($Buffer);
     while ($Remaining > 0) {
         $Buffer2 = FRead($this->RconSocket, $Remaining);
         $PacketSize = StrLen($Buffer2);
         if ($PacketSize === 0) {
             throw new InvalidPacketException('Read ' . strlen($Buffer) . ' bytes from socket, ' . $Remaining . ' remaining', InvalidPacketException::BUFFER_EMPTY);
             break;
         }
         $Buffer .= $Buffer2;
         $Remaining -= $PacketSize;
     }
     $this->Buffer->Set($Buffer);
 }
Example #7
0
 public function Read($Length = 1400)
 {
     switch ($this->Socket->Engine) {
         case CI_SourceQuery::GOLDSOURCE:
             // GoldSource RCON has same structure as Query
             $this->Socket->Read();
             if ($this->Buffer->GetByte() != SourceQuery::S2A_RCON) {
                 return false;
             }
             $Buffer = $this->Buffer->Get();
             $Trimmed = Trim($Buffer);
             if ($Trimmed == 'Bad rcon_password.' || $Trimmed == 'You have been banned from this server.') {
                 throw new SourceQueryException($Trimmed);
             }
             $ReadMore = false;
             // There is no indentifier of the end, so we just need to continue reading
             // TODO: Needs to be looked again, it causes timeouts
             do {
                 $this->Socket->Read();
                 $ReadMore = $this->Buffer->Remaining() > 0 && $this->Buffer->GetByte() == SourceQuery::S2A_RCON;
                 if ($ReadMore) {
                     $Packet = $this->Buffer->Get();
                     $Buffer .= SubStr($Packet, 0, -2);
                     // Let's assume if this packet is not long enough, there are no more after this one
                     $ReadMore = StrLen($Packet) > 1000;
                     // use 1300?
                 }
             } while ($ReadMore);
             $this->Buffer->Set(Trim($Buffer));
             break;
         case CI_SourceQuery::SOURCE:
             $this->Buffer->Set(FRead($this->RconSocket, $Length));
             $Buffer = "";
             $PacketSize = $this->Buffer->GetLong();
             $Buffer .= $this->Buffer->Get();
             // TODO: multi packet reading
             $this->Buffer->Set($Buffer);
             break;
     }
 }