From c048564981bba419ee3ad089738b6a09cea00f50 Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Date: Fri, 7 Feb 2014 00:46:04 +0100 Subject: [PATCH] Server listing working --- src/PocketMinecraftServer.php | 2 +- src/network/raknet/RakNetCodec.php | 156 ++++++++++++++++++++++++++++ src/network/raknet/RakNetParser.php | 14 +-- 3 files changed, 161 insertions(+), 11 deletions(-) create mode 100644 src/network/raknet/RakNetCodec.php diff --git a/src/PocketMinecraftServer.php b/src/PocketMinecraftServer.php index a5da58f2e..57eb63915 100644 --- a/src/PocketMinecraftServer.php +++ b/src/PocketMinecraftServer.php @@ -511,7 +511,7 @@ class PocketMinecraftServer{ $pk = new RakNetPacket(RakNetInfo::UNCONNECTED_PONG); $pk->pingID = $packet->pingID; $pk->serverID = $this->serverID; - $pk->serverType = $this->name . " [".count($this->clients)."/".$this->maxClients."] ".$txt; + $pk->serverType = $this->serverType . $this->name . " [".count($this->clients)."/".$this->maxClients."] ".$txt; $pk->ip = $packet->ip; $pk->port = $packet->port; $this->send($pk); diff --git a/src/network/raknet/RakNetCodec.php b/src/network/raknet/RakNetCodec.php new file mode 100644 index 000000000..cad6868ff --- /dev/null +++ b/src/network/raknet/RakNetCodec.php @@ -0,0 +1,156 @@ +packet = $packet; + $this->buffer =& $this->packet->buffer; + $this->encode(); + } + + private function encode(){ + if(strlen($this->packet->buffer) > 0){ + return; + } + $this->buffer .= chr($this->packet->pid()); + + switch($this->packet->pid()){ + case RakNetInfo::OPEN_CONNECTION_REPLY_1: + $this->buffer .= RakNetInfo::MAGIC; + $this->putLong($this->packet->serverID); + $this->putByte(0); //server security + $this->putShort($this->packet->mtuSize); + break; + case RakNetInfo::OPEN_CONNECTION_REPLY_2: + $this->buffer .= RakNetInfo::MAGIC; + $this->putLong($this->packet->serverID); + $this->putShort($this->packet->port); + $this->putShort($this->packet->mtuSize); + $this->putByte(0); //Server security + break; + case RakNetInfo::INCOMPATIBLE_PROTOCOL_VERSION: + $this->putByte(RakNetInfo::STRUCTURE); + $this->buffer .= RakNetInfo::MAGIC; + $this->putLong($this->packet->serverID); + break; + case RakNetInfo::UNCONNECTED_PONG: + case RakNetInfo::ADVERTISE_SYSTEM: + $this->putLong($this->packet->pingID); + $this->putLong($this->packet->serverID); + $this->buffer .= RakNetInfo::MAGIC; + $this->putString($this->packet->serverType); + break; + case RakNetInfo::DATA_PACKET_0: + case RakNetInfo::DATA_PACKET_1: + case RakNetInfo::DATA_PACKET_2: + case RakNetInfo::DATA_PACKET_3: + case RakNetInfo::DATA_PACKET_4: + case RakNetInfo::DATA_PACKET_5: + case RakNetInfo::DATA_PACKET_6: + case RakNetInfo::DATA_PACKET_7: + case RakNetInfo::DATA_PACKET_8: + case RakNetInfo::DATA_PACKET_9: + case RakNetInfo::DATA_PACKET_A: + case RakNetInfo::DATA_PACKET_B: + case RakNetInfo::DATA_PACKET_C: + case RakNetInfo::DATA_PACKET_D: + case RakNetInfo::DATA_PACKET_E: + case RakNetInfo::DATA_PACKET_F: + $this->putLTriad($this->seqNumber); + foreach($this->data as $pk){ + $this->buffer .= $this->encodeDataPacket($pk); + } + break; + case RakNetInfo::NACK: + case RakNetInfo::ACK: + $payload = b""; + $records = 0; + $pointer = 0; + sort($this->packet->packets, SORT_NUMERIC); + $max = count($this->packet->packets); + + while($pointer < $max){ + $type = true; + $curr = $start = $this->packet->packets[$pointer]; + for($i = $start + 1; $i < $max; ++$i){ + $n = $this->packet->packets[$i]; + if(($n - $curr) === 1){ + $curr = $end = $n; + $type = false; + $pointer = $i + 1; + }else{ + break; + } + } + ++$pointer; + if($type === false){ + $payload .= "\x00"; + $payload .= strrev(Utils::writeTriad($start)); + $payload .= strrev(Utils::writeTriad($end)); + }else{ + $payload .= Utils::writeBool(true); + $payload .= strrev(Utils::writeTriad($start)); + } + ++$records; + } + $this->putShort($records); + $this->buffer .= $payload; + break; + default: + + } + + } + + protected function put($str){ + $this->buffer .= $str; + } + + protected function putLong($v){ + $this->buffer .= Utils::writeLong($v); + } + + protected function putInt($v){ + $this->buffer .= Utils::writeInt($v); + } + + protected function putShort($v){ + $this->buffer .= Utils::writeShort($v); + } + + protected function putTriad($v){ + $this->buffer .= Utils::putTriad($v); + } + + protected function putLTriad($v){ + $this->buffer .= strrev(Utils::putTriad($v)); + } + + protected function putByte($v){ + $this->buffer .= chr($v); + } + + protected function putString($v){ + $this->putShort(strlen($v)); + $this->put($v); + } +} \ No newline at end of file diff --git a/src/network/raknet/RakNetParser.php b/src/network/raknet/RakNetParser.php index 529e134fd..9c8deae7f 100644 --- a/src/network/raknet/RakNetParser.php +++ b/src/network/raknet/RakNetParser.php @@ -20,7 +20,6 @@ */ class RakNetParser{ - private $id = -1; private $buffer; private $offset; public $packet; @@ -29,17 +28,12 @@ class RakNetParser{ $this->buffer =& $buffer; $this->offset = 0; if(strlen($this->buffer) > 0){ - $this->id = ord($this->get(1)); $this->parse(); }else{ $this->packet = false; } } - public function pid(){ - return (int) $this->id; - } - private function get($len){ if($len <= 0){ return ""; @@ -77,10 +71,10 @@ class RakNetParser{ } private function parse(){ - $this->packet = new RakNetPacket($this->pid()); + $this->packet = new RakNetPacket(ord($this->get(1))); $this->packet->buffer =& $this->buffer; $this->packet->length = strlen($this->buffer); - switch($this->pid()){ + switch($this->packet->pid()){ case RakNetInfo::UNCONNECTED_PING: case RakNetInfo::UNCONNECTED_PING_OPEN_CONNECTIONS: $this->packet->pingID = $this->getLong(); @@ -89,13 +83,13 @@ class RakNetParser{ case RakNetInfo::OPEN_CONNECTION_REQUEST_1: $this->offset += 16; //Magic $this->packet->structure = $this->getByte(); - $this->packet->MTU = strlen($this->get(true)); + $this->packet->mtuSize = strlen($this->get(true)); break; case RakNetInfo::OPEN_CONNECTION_REQUEST_2: $this->offset += 16; //Magic $this->packet->security = $this->get(5); $this->packet->port = $this->getShort(false); - $this->packet->MTU = $this->getShort(false); + $this->packet->mtuSize = $this->getShort(false); $this->packet->clientGUID = $this->getLong(); break; case RakNetInfo::DATA_PACKET_0: