예제 #1
0
 /**
  * deserialize 
  * 
  * This method deserializes a request. It requires an SabreAMF_InputStream with valid AMF data. After
  * deserialization the contents of the request can be found through the getBodies and getHeaders methods
  *
  * @param SabreAMF_InputStream $stream 
  * @return void
  */
 public function deserialize(SabreAMF_InputStream $stream)
 {
     $this->headers = array();
     $this->bodies = array();
     $this->InputStream = $stream;
     $stream->readByte();
     $this->clientType = $stream->readByte();
     $deserializer = new SabreAMF_AMF0_Deserializer($stream);
     $totalHeaders = $stream->readInt();
     for ($i = 0; $i < $totalHeaders; $i++) {
         $header = array('name' => $deserializer->readString(), 'required' => $stream->readByte() == true);
         $stream->readLong();
         $header['data'] = $deserializer->readAMFData(null, true);
         $this->headers[] = $header;
     }
     $totalBodies = $stream->readInt();
     for ($i = 0; $i < $totalBodies; $i++) {
         try {
             $target = $deserializer->readString();
         } catch (Exception $e) {
             // Could not fetch next body.. this happens with some versions of AMFPHP where the body
             // count isn't properly set. If this happens we simply stop decoding
             break;
         }
         $body = array('target' => $target, 'response' => $deserializer->readString(), 'length' => $stream->readLong(), 'data' => $deserializer->readAMFData(null, true));
         if (is_object($body['data']) && $body['data'] instanceof SabreAMF_AMF3_Wrapper) {
             $body['data'] = $body['data']->getData();
             $this->encoding = SabreAMF_Const::AMF3;
         } else {
             if (is_array($body['data']) && isset($body['data'][0]) && is_object($body['data'][0]) && $body['data'][0] instanceof SabreAMF_AMF3_Wrapper) {
                 $body['data'] = $body['data'][0]->getData();
                 $this->encoding = SabreAMF_Const::AMF3;
             }
         }
         $this->bodies[] = $body;
     }
 }
예제 #2
0
 /**
  * @return array
  *
  * @throws PacketException
  * @throws ClientKickedException
  */
 protected function parsePacket()
 {
     $packets = array();
     while (true) {
         $headerBasic = ord($this->socket->read(1));
         $channel = $headerBasic & 0x2f;
         $headerType = $headerBasic & 0xc0;
         $headerSize = 0;
         switch ($headerType) {
             case 0x0:
                 $headerSize = 12;
                 break;
             case 0x40:
                 $headerSize = 8;
                 break;
             case 0x80:
                 $headerSize = 4;
                 break;
             case 0xc0:
                 $headerSize = 1;
                 break;
         }
         if (!isset($packets[$channel])) {
             $packets[$channel] = array('data' => '');
         }
         $packet =& $packets[$channel];
         // Parse the header
         if ($headerSize > 1) {
             $header = $this->socket->read($headerSize - 1);
             if ($headerSize >= 8) {
                 $size = 0;
                 for ($i = 3; $i < 6; $i++) {
                     $size *= 256;
                     $size += ord(substr($header, $i, 1)) & 0xff;
                 }
                 $packet['size'] = $size;
                 $packet['type'] = ord($header[6]);
             }
         }
         // Parse the content
         for ($i = 0; $i < 128; $i++) {
             if (!feof($this->socket->getSocket())) {
                 $packet['data'] .= $this->socket->read(1);
             }
             if (strlen($packet['data']) == $packet['size']) {
                 break;
             }
         }
         if (!(strlen($packet['data']) == $packet['size'])) {
             continue;
         }
         // Remove the read packet
         unset($packets[$channel]);
         $result = array();
         $input = new \SabreAMF_InputStream($packet['data']);
         switch ($packet['type']) {
             case 0x14:
                 // decode connect
                 $decoder = new \SabreAMF_AMF0_Deserializer($input);
                 $result['result'] = $decoder->readAMFData();
                 $result['invokeId'] = $decoder->readAMFData();
                 $result['serviceCall'] = $decoder->readAMFData();
                 $result['data'] = $decoder->readAMFData();
                 try {
                     $input->readByte();
                     throw new PacketException('id not consume entire buffer');
                 } catch (\Exception $e) {
                     // good
                 }
                 break;
             case 0x11:
                 if ($input->readByte() == 0x0) {
                     $packet['data'] = substr($packet['data'], 1);
                     $result['version'] = 0x0;
                 }
                 $decoder = new \SabreAMF_AMF0_Deserializer($input);
                 $result['result'] = $decoder->readAMFData();
                 $result['invokeId'] = $decoder->readAMFData();
                 $result['serviceCall'] = $decoder->readAMFData();
                 $result['data'] = $decoder->readAMFData();
                 try {
                     $input->readByte();
                     throw new PacketException('id not consume entire buffer');
                 } catch (\Exception $e) {
                     // good
                 }
                 break;
             case 0x3:
                 // ack
             // ack
             case 0x6:
                 // bandwidth
                 continue 2;
             default:
                 throw new PacketException('Unknown message type');
         }
         if (!isset($result['invokeId'])) {
             // The client has been kicked, someone connect to the same account with another API instance or from the desktop launcher
             if ('receive' == $result['result'] && 'com.riotgames.platform.messaging.ClientLoginKickNotification' == $result['data']->getData()->getAMFData()['body']->getAMFClassName()) {
                 throw new ClientKickedException('Someone is connected with the same account, only one instance can running. Restarting client...');
             }
             throw new PacketException("Error after decoding packet");
         }
         $invokeId = $result['invokeId'];
         if ($invokeId == null || $invokeId == 0) {
             throw new PacketException('Unknown invokeId: ' . $invokeId);
         }
         return $result;
     }
 }
예제 #3
0
 private function readResponse()
 {
     $packets = array();
     while (true) {
         $headerBasic = ord($this->read(1));
         $channel = $headerBasic & 0x2f;
         $headerType = $headerBasic & 0xc0;
         $headerSize = 0;
         switch ($headerType) {
             case 0x0:
                 $headerSize = 12;
                 break;
             case 0x40:
                 $headerSize = 8;
                 break;
             case 0x80:
                 $headerSize = 4;
                 break;
             case 0xc0:
                 $headerSize = 1;
                 break;
         }
         if (!array_key_exists($channel, $packets)) {
             $packets[$channel] = array('data' => '');
         }
         $packet =& $packets[$channel];
         if ($headerSize > 1) {
             $header = $this->read($headerSize - 1);
             if ($headerSize >= 8) {
                 $size = 0;
                 for ($i = 3; $i < 6; $i++) {
                     $size *= 256;
                     $size += ord(substr($header, $i, 1)) & 0xff;
                 }
                 $packet['size'] = $size;
                 $packet['type'] = ord($header[6]);
             }
         }
         for ($i = 0; $i < 128; $i++) {
             if (!feof($this->socket)) {
                 $packet['data'] .= $this->read(1);
             }
             if (strlen($packet['data']) == $packet['size']) {
                 break;
             }
         }
         $len = strlen($packet['data']);
         if (!(strlen($packet['data']) == $packet['size'])) {
             continue;
         }
         unset($packets[$channel]);
         $result = null;
         if ($packet['type'] == 0x3 || $packet['type'] == 0x6) {
             continue;
         } elseif ($packet['type'] == 0x11) {
             $result = array();
             $stream = new \SabreAMF_InputStream($packet['data']);
             if ($stream->readByte() == 0x0) {
                 $result['version'] = 0x0;
                 $packet['data'] = substr($packet['data'], 1, strlen($packet['data']));
             }
             $deserializer = new \SabreAMF_AMF0_Deserializer($stream);
             $result['result'] = $deserializer->readAMFData();
             $result['invokeId'] = $deserializer->readAMFData();
             $result['serviceCall'] = $deserializer->readAMFData();
             $result['data'] = $deserializer->readAMFData();
         } elseif ($packet['type'] == 0x14) {
             $result = array();
             $stream = new \SabreAMF_InputStream($packet['data']);
             $deserializer = new \SabreAMF_AMF0_Deserializer($stream);
             $result['result'] = $deserializer->readAMFData();
             $result['invokeId'] = $deserializer->readAMFData();
             $result['serviceCall'] = $deserializer->readAMFData();
             $result['data'] = $deserializer->readAMFData();
         } else {
             //Unhandled Packet
         }
         if (!isset($result)) {
             throw new \Exception("Error after decoding packet");
         }
         $id = $result['invokeId'];
         if ($id == null || $id == 0) {
             //CALLBACK
         } elseif (false) {
             //CALLBACK2
         } else {
             return $result;
         }
     }
 }