Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ jobs:
- uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@2.32.0
uses: shivammathur/setup-php@2.35.4
with:
php-version: ${{ matrix.php }}
extensions: encoding-pmmp/[email protected]

- name: Cache Composer packages
id: composer-cache
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
"php": "^8.1",
"php-ipv6": "*",
"php-64bit": "*",
"ext-encoding": "~1.0.0",
"ext-sockets": "*",
"pocketmine/log": "^0.3.0 || ^0.4.0",
"pocketmine/binaryutils": "^0.2.0"
"pocketmine/log": "^0.3.0 || ^0.4.0"
},
"require-dev": {
"phpstan/phpstan": "2.1.0",
Expand Down
11 changes: 6 additions & 5 deletions src/generic/Session.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

namespace raklib\generic;

use pmmp\encoding\ByteBufferReader;
use pmmp\encoding\ByteBufferWriter;
use raklib\protocol\ACK;
use raklib\protocol\AcknowledgePacket;
use raklib\protocol\ConnectedPacket;
Expand All @@ -28,7 +30,6 @@
use raklib\protocol\NACK;
use raklib\protocol\Packet;
use raklib\protocol\PacketReliability;
use raklib\protocol\PacketSerializer;
use raklib\utils\InternetAddress;
use function hrtime;
use function intdiv;
Expand Down Expand Up @@ -220,13 +221,13 @@ public function update(float $time) : void{
}

protected function queueConnectedPacket(ConnectedPacket $packet, int $reliability, int $orderChannel, bool $immediate = false) : void{
$out = new PacketSerializer(); //TODO: reuse streams to reduce allocations
$out = new ByteBufferWriter(); //TODO: reuse streams to reduce allocations
$packet->encode($out);

$encapsulated = new EncapsulatedPacket();
$encapsulated->reliability = $reliability;
$encapsulated->orderChannel = $orderChannel;
$encapsulated->buffer = $out->getBuffer();
$encapsulated->buffer = $out->getData();

$this->sendLayer->addEncapsulatedToQueue($encapsulated, $immediate);
}
Expand All @@ -248,14 +249,14 @@ private function handleEncapsulatedPacketRoute(EncapsulatedPacket $packet) : voi
$this->handleRemoteDisconnect();
}elseif($id === MessageIdentifiers::ID_CONNECTED_PING){
$dataPacket = new ConnectedPing();
$dataPacket->decode(new PacketSerializer($packet->buffer));
$dataPacket->decode(new ByteBufferReader($packet->buffer));
$this->queueConnectedPacket(ConnectedPong::create(
$dataPacket->sendPingTime,
$this->getRakNetTimeMS()
), PacketReliability::UNRELIABLE, 0);
}elseif($id === MessageIdentifiers::ID_CONNECTED_PONG){
$dataPacket = new ConnectedPong();
$dataPacket->decode(new PacketSerializer($packet->buffer));
$dataPacket->decode(new ByteBufferReader($packet->buffer));

$this->handlePong($dataPacket->sendPingTime, $dataPacket->sendPongTime);
}
Expand Down
51 changes: 28 additions & 23 deletions src/protocol/AcknowledgePacket.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@

namespace raklib\protocol;

use pocketmine\utils\Binary;
use function chr;
use pmmp\encoding\BE;
use pmmp\encoding\Byte;
use pmmp\encoding\ByteBufferReader;
use pmmp\encoding\ByteBufferWriter;
use pmmp\encoding\LE;
use function count;
use function sort;
use function strlen;
use const SORT_NUMERIC;

abstract class AcknowledgePacket extends Packet{
Expand All @@ -29,8 +33,8 @@ abstract class AcknowledgePacket extends Packet{
/** @var int[] */
public array $packets = [];

protected function encodePayload(PacketSerializer $out) : void{
$payload = "";
protected function encodePayload(ByteBufferWriter $out) : void{
$subWriter = new ByteBufferWriter();
sort($this->packets, SORT_NUMERIC);
$count = count($this->packets);
$records = 0;
Expand All @@ -47,50 +51,51 @@ protected function encodePayload(PacketSerializer $out) : void{
$last = $current;
}elseif($diff > 1){ //Forget about duplicated packets (bad queues?)
if($start === $last){
$payload .= chr(self::RECORD_TYPE_SINGLE);
$payload .= Binary::writeLTriad($start);
Byte::writeUnsigned($subWriter, self::RECORD_TYPE_SINGLE);
LE::writeUnsignedTriad($subWriter, $start);
$start = $last = $current;
}else{
$payload .= chr(self::RECORD_TYPE_RANGE);
$payload .= Binary::writeLTriad($start);
$payload .= Binary::writeLTriad($last);
Byte::writeUnsigned($subWriter, self::RECORD_TYPE_RANGE);
LE::writeUnsignedTriad($subWriter, $start);
LE::writeUnsignedTriad($subWriter, $last);
$start = $last = $current;
}
++$records;
}
}

if($start === $last){
$payload .= chr(self::RECORD_TYPE_SINGLE);
$payload .= Binary::writeLTriad($start);
Byte::writeUnsigned($subWriter, self::RECORD_TYPE_SINGLE);
LE::writeUnsignedTriad($subWriter, $start);
}else{
$payload .= chr(self::RECORD_TYPE_RANGE);
$payload .= Binary::writeLTriad($start);
$payload .= Binary::writeLTriad($last);
Byte::writeUnsigned($subWriter, self::RECORD_TYPE_RANGE);
LE::writeUnsignedTriad($subWriter, $start);
LE::writeUnsignedTriad($subWriter, $last);
}
++$records;
}

$out->putShort($records);
$out->put($payload);
BE::writeUnsignedShort($out, $records);
$out->writeByteArray($subWriter->getData());
}

protected function decodePayload(PacketSerializer $in) : void{
$count = $in->getShort();
protected function decodePayload(ByteBufferReader $in) : void{
$count = BE::readUnsignedShort($in);
$this->packets = [];
$cnt = 0;
for($i = 0; $i < $count and !$in->feof() and $cnt < 4096; ++$i){
if($in->getByte() === self::RECORD_TYPE_RANGE){
$start = $in->getLTriad();
$end = $in->getLTriad();
$len = strlen($in->getData());
for($i = 0; $i < $count and $in->getOffset() < $len and $cnt < 4096; ++$i){
if(Byte::readUnsigned($in) === self::RECORD_TYPE_RANGE){
$start = LE::readUnsignedTriad($in);
$end = LE::readUnsignedTriad($in);
if(($end - $start) > 512){
$end = $start + 512;
}
for($c = $start; $c <= $end; ++$c){
$this->packets[$cnt++] = $c;
}
}else{
$this->packets[$cnt++] = $in->getLTriad();
$this->packets[$cnt++] = LE::readUnsignedTriad($in);
}
}
}
Expand Down
11 changes: 7 additions & 4 deletions src/protocol/AdvertiseSystem.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,19 @@

namespace raklib\protocol;

use pmmp\encoding\ByteBufferReader;
use pmmp\encoding\ByteBufferWriter;

class AdvertiseSystem extends Packet{
public static $ID = MessageIdentifiers::ID_ADVERTISE_SYSTEM;

public string $serverName;

protected function encodePayload(PacketSerializer $out) : void{
$out->putString($this->serverName);
protected function encodePayload(ByteBufferWriter $out) : void{
PacketSerializer::putString($out, $this->serverName);
}

protected function decodePayload(PacketSerializer $in) : void{
$this->serverName = $in->getString();
protected function decodePayload(ByteBufferReader $in) : void{
$this->serverName = PacketSerializer::getString($in);
}
}
12 changes: 8 additions & 4 deletions src/protocol/ConnectedPing.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

namespace raklib\protocol;

use pmmp\encoding\BE;
use pmmp\encoding\ByteBufferReader;
use pmmp\encoding\ByteBufferWriter;

class ConnectedPing extends ConnectedPacket{
public static $ID = MessageIdentifiers::ID_CONNECTED_PING;

Expand All @@ -27,11 +31,11 @@ public static function create(int $sendPingTime) : self{
return $result;
}

protected function encodePayload(PacketSerializer $out) : void{
$out->putLong($this->sendPingTime);
protected function encodePayload(ByteBufferWriter $out) : void{
BE::writeUnsignedLong($out, $this->sendPingTime);
}

protected function decodePayload(PacketSerializer $in) : void{
$this->sendPingTime = $in->getLong();
protected function decodePayload(ByteBufferReader $in) : void{
$this->sendPingTime = BE::readUnsignedLong($in);
}
}
16 changes: 10 additions & 6 deletions src/protocol/ConnectedPong.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

namespace raklib\protocol;

use pmmp\encoding\BE;
use pmmp\encoding\ByteBufferReader;
use pmmp\encoding\ByteBufferWriter;

class ConnectedPong extends ConnectedPacket{
public static $ID = MessageIdentifiers::ID_CONNECTED_PONG;

Expand All @@ -29,13 +33,13 @@ public static function create(int $sendPingTime, int $sendPongTime) : self{
return $result;
}

protected function encodePayload(PacketSerializer $out) : void{
$out->putLong($this->sendPingTime);
$out->putLong($this->sendPongTime);
protected function encodePayload(ByteBufferWriter $out) : void{
BE::writeUnsignedLong($out, $this->sendPingTime);
BE::writeUnsignedLong($out, $this->sendPongTime);
}

protected function decodePayload(PacketSerializer $in) : void{
$this->sendPingTime = $in->getLong();
$this->sendPongTime = $in->getLong();
protected function decodePayload(ByteBufferReader $in) : void{
$this->sendPingTime = BE::readUnsignedLong($in);
$this->sendPongTime = BE::readUnsignedLong($in);
}
}
21 changes: 13 additions & 8 deletions src/protocol/ConnectionRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,27 @@

namespace raklib\protocol;

use pmmp\encoding\BE;
use pmmp\encoding\Byte;
use pmmp\encoding\ByteBufferReader;
use pmmp\encoding\ByteBufferWriter;

class ConnectionRequest extends ConnectedPacket{
public static $ID = MessageIdentifiers::ID_CONNECTION_REQUEST;

public int $clientID;
public int $sendPingTime;
public bool $useSecurity = false;

protected function encodePayload(PacketSerializer $out) : void{
$out->putLong($this->clientID);
$out->putLong($this->sendPingTime);
$out->putByte($this->useSecurity ? 1 : 0);
protected function encodePayload(ByteBufferWriter $out) : void{
BE::writeUnsignedLong($out, $this->clientID);
BE::writeUnsignedLong($out, $this->sendPingTime);
Byte::writeUnsigned($out, $this->useSecurity ? 1 : 0);
}

protected function decodePayload(PacketSerializer $in) : void{
$this->clientID = $in->getLong();
$this->sendPingTime = $in->getLong();
$this->useSecurity = $in->getByte() !== 0;
protected function decodePayload(ByteBufferReader $in) : void{
$this->clientID = BE::readUnsignedLong($in);
$this->sendPingTime = BE::readUnsignedLong($in);
$this->useSecurity = Byte::readUnsigned($in) !== 0;
}
}
29 changes: 16 additions & 13 deletions src/protocol/ConnectionRequestAccepted.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

namespace raklib\protocol;

use pmmp\encoding\BE;
use pmmp\encoding\ByteBufferReader;
use pmmp\encoding\ByteBufferWriter;
use raklib\RakLib;
use raklib\utils\InternetAddress;
use function strlen;
Expand Down Expand Up @@ -45,31 +48,31 @@ public function __construct(){
$this->systemAddresses[] = new InternetAddress("127.0.0.1", 0, 4);
}

protected function encodePayload(PacketSerializer $out) : void{
$out->putAddress($this->address);
$out->putShort(0);
protected function encodePayload(ByteBufferWriter $out) : void{
PacketSerializer::putAddress($out, $this->address);
BE::writeUnsignedShort($out, 0);

$dummy = new InternetAddress("0.0.0.0", 0, 4);
for($i = 0; $i < RakLib::$SYSTEM_ADDRESS_COUNT; ++$i){
$out->putAddress($this->systemAddresses[$i] ?? $dummy);
PacketSerializer::putAddress($out, $this->systemAddresses[$i] ?? $dummy);
}

$out->putLong($this->sendPingTime);
$out->putLong($this->sendPongTime);
BE::writeUnsignedLong($out, $this->sendPingTime);
BE::writeUnsignedLong($out, $this->sendPongTime);
}

protected function decodePayload(PacketSerializer $in) : void{
$this->address = $in->getAddress();
$in->getShort(); //TODO: check this
protected function decodePayload(ByteBufferReader $in) : void{
$this->address = PacketSerializer::getAddress($in);
BE::readUnsignedShort($in); //TODO: check this

$len = strlen($in->getBuffer());
$len = strlen($in->getData());
$dummy = new InternetAddress("0.0.0.0", 0, 4);

for($i = 0; $i < RakLib::$SYSTEM_ADDRESS_COUNT; ++$i){
$this->systemAddresses[$i] = $in->getOffset() + 16 < $len ? $in->getAddress() : $dummy; //HACK: avoids trying to read too many addresses on bad data
$this->systemAddresses[$i] = $in->getOffset() + 16 < $len ? PacketSerializer::getAddress($in) : $dummy; //HACK: avoids trying to read too many addresses on bad data
}

$this->sendPingTime = $in->getLong();
$this->sendPongTime = $in->getLong();
$this->sendPingTime = BE::readUnsignedLong($in);
$this->sendPongTime = BE::readUnsignedLong($in);
}
}
27 changes: 17 additions & 10 deletions src/protocol/Datagram.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@

namespace raklib\protocol;

use pmmp\encoding\Byte;
use pmmp\encoding\ByteBufferReader;
use pmmp\encoding\ByteBufferWriter;
use pmmp\encoding\LE;
use function strlen;

class Datagram extends Packet{
public const BITFLAG_VALID = 0x80;
public const BITFLAG_ACK = 0x40;
Expand All @@ -36,14 +42,14 @@ class Datagram extends Packet{
public array $packets = [];
public int $seqNumber;

protected function encodeHeader(PacketSerializer $out) : void{
$out->putByte(self::BITFLAG_VALID | $this->headerFlags);
protected function encodeHeader(ByteBufferWriter $out) : void{
Byte::writeUnsigned($out, self::BITFLAG_VALID | $this->headerFlags);
}

protected function encodePayload(PacketSerializer $out) : void{
$out->putLTriad($this->seqNumber);
protected function encodePayload(ByteBufferWriter $out) : void{
LE::writeUnsignedTriad($out, $this->seqNumber);
foreach($this->packets as $packet){
$out->put($packet->toBinary());
$packet->toBinary($out);
}
}

Expand All @@ -59,14 +65,15 @@ public function length(){
return $length;
}

protected function decodeHeader(PacketSerializer $in) : void{
$this->headerFlags = $in->getByte();
protected function decodeHeader(ByteBufferReader $in) : void{
$this->headerFlags = Byte::readUnsigned($in);
}

protected function decodePayload(PacketSerializer $in) : void{
$this->seqNumber = $in->getLTriad();
protected function decodePayload(ByteBufferReader $in) : void{
$this->seqNumber = LE::readUnsignedTriad($in);

while(!$in->feof()){
$len = strlen($in->getData());
while($in->getOffset() < $len){
$this->packets[] = EncapsulatedPacket::fromBinary($in);
}
}
Expand Down
Loading