From 98de061d74e005e397200977e224709bf0342382 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 11 Sep 2025 23:19:12 +0100 Subject: [PATCH 1/2] First pass ext-encoding support --- .github/workflows/main.yml | 1 + composer.json | 2 +- src/RakLibToUserThreadMessageReceiver.php | 26 +++++++++++------------ src/RakLibToUserThreadMessageSender.php | 26 +++++++++++------------ src/UserToRakLibThreadMessageReceiver.php | 14 ++++++------ src/UserToRakLibThreadMessageSender.php | 14 ++++++------ 6 files changed, 42 insertions(+), 41 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3296bfb..df256f5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,6 +20,7 @@ jobs: uses: shivammathur/setup-php@2.24.0 with: php-version: ${{ matrix.php }} + extensions: encoding-pmmp/ext-encoding@1.0.0 - name: Cache Composer packages id: composer-cache diff --git a/composer.json b/composer.json index 05b855a..2fe9d2b 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ "require": { "php": "^8.0", "php-64bit": "*", - "pocketmine/binaryutils": "^0.2.0", + "ext-encoding": "~1.0.0", "pocketmine/raklib": "^0.15.0 || ^1.0.0" }, "require-dev": { diff --git a/src/RakLibToUserThreadMessageReceiver.php b/src/RakLibToUserThreadMessageReceiver.php index e46b28e..e035d5e 100644 --- a/src/RakLibToUserThreadMessageReceiver.php +++ b/src/RakLibToUserThreadMessageReceiver.php @@ -17,7 +17,7 @@ namespace raklib\server\ipc; -use pocketmine\utils\Binary; +use pmmp\encoding\LE; use raklib\server\ipc\RakLibToUserThreadMessageProtocol as ITCProtocol; use raklib\server\ServerEventListener; use function inet_ntop; @@ -34,7 +34,7 @@ public function handle(ServerEventListener $listener) : bool{ $id = ord($packet[0]); $offset = 1; if($id === ITCProtocol::PACKET_ENCAPSULATED){ - $sessionId = Binary::readInt(substr($packet, $offset, 4)); + $sessionId = LE::unpackUnsignedInt(substr($packet, $offset, 4)); $offset += 4; $buffer = substr($packet, $offset); $listener->onPacketReceive($sessionId, $buffer); @@ -42,17 +42,17 @@ public function handle(ServerEventListener $listener) : bool{ $len = ord($packet[$offset++]); $address = substr($packet, $offset, $len); $offset += $len; - $port = Binary::readShort(substr($packet, $offset, 2)); + $port = LE::unpackUnsignedShort(substr($packet, $offset, 2)); $offset += 2; $payload = substr($packet, $offset); $listener->onRawPacketReceive($address, $port, $payload); }elseif($id === ITCProtocol::PACKET_REPORT_BANDWIDTH_STATS){ - $sentBytes = Binary::readLong(substr($packet, $offset, 8)); + $sentBytes = LE::unpackUnsignedLong(substr($packet, $offset, 8)); $offset += 8; - $receivedBytes = Binary::readLong(substr($packet, $offset, 8)); + $receivedBytes = LE::unpackUnsignedLong(substr($packet, $offset, 8)); $listener->onBandwidthStatsUpdate($sentBytes, $receivedBytes); }elseif($id === ITCProtocol::PACKET_OPEN_SESSION){ - $sessionId = Binary::readInt(substr($packet, $offset, 4)); + $sessionId = LE::unpackUnsignedInt(substr($packet, $offset, 4)); $offset += 4; $len = ord($packet[$offset++]); $rawAddr = substr($packet, $offset, $len); @@ -61,24 +61,24 @@ public function handle(ServerEventListener $listener) : bool{ if($address === false){ throw new \RuntimeException("Unexpected invalid IP address in inter-thread message"); } - $port = Binary::readShort(substr($packet, $offset, 2)); + $port = LE::unpackUnsignedShort(substr($packet, $offset, 2)); $offset += 2; - $clientID = Binary::readLong(substr($packet, $offset, 8)); + $clientID = LE::unpackUnsignedLong(substr($packet, $offset, 8)); $listener->onClientConnect($sessionId, $address, $port, $clientID); }elseif($id === ITCProtocol::PACKET_CLOSE_SESSION){ - $sessionId = Binary::readInt(substr($packet, $offset, 4)); + $sessionId = LE::unpackUnsignedInt(substr($packet, $offset, 4)); $offset += 4; $reason = ord($packet[$offset]); $listener->onClientDisconnect($sessionId, $reason); }elseif($id === ITCProtocol::PACKET_ACK_NOTIFICATION){ - $sessionId = Binary::readInt(substr($packet, $offset, 4)); + $sessionId = LE::unpackUnsignedInt(substr($packet, $offset, 4)); $offset += 4; - $identifierACK = Binary::readInt(substr($packet, $offset, 4)); + $identifierACK = LE::unpackSignedInt(substr($packet, $offset, 4)); $listener->onPacketAck($sessionId, $identifierACK); }elseif($id === ITCProtocol::PACKET_REPORT_PING){ - $sessionId = Binary::readInt(substr($packet, $offset, 4)); + $sessionId = LE::unpackUnsignedInt(substr($packet, $offset, 4)); $offset += 4; - $pingMS = Binary::readInt(substr($packet, $offset, 4)); + $pingMS = LE::unpackUnsignedInt(substr($packet, $offset, 4)); $listener->onPingMeasure($sessionId, $pingMS); } diff --git a/src/RakLibToUserThreadMessageSender.php b/src/RakLibToUserThreadMessageSender.php index 48fbbda..cdaa990 100644 --- a/src/RakLibToUserThreadMessageSender.php +++ b/src/RakLibToUserThreadMessageSender.php @@ -17,7 +17,7 @@ namespace raklib\server\ipc; -use pocketmine\utils\Binary; +use pmmp\encoding\LE; use raklib\server\ipc\RakLibToUserThreadMessageProtocol as ITCProtocol; use raklib\server\ServerEventListener; use function chr; @@ -36,17 +36,17 @@ public function onClientConnect(int $sessionId, string $address, int $port, int } $this->channel->write( chr(ITCProtocol::PACKET_OPEN_SESSION) . - Binary::writeInt($sessionId) . + LE::packUnsignedInt($sessionId) . chr(strlen($rawAddr)) . $rawAddr . - Binary::writeShort($port) . - Binary::writeLong($clientId) + LE::packUnsignedShort($port) . + LE::packUnsignedLong($clientId) ); } public function onClientDisconnect(int $sessionId, int $reason) : void{ $this->channel->write( chr(ITCProtocol::PACKET_CLOSE_SESSION) . - Binary::writeInt($sessionId) . + LE::packUnsignedInt($sessionId) . chr($reason) ); } @@ -54,7 +54,7 @@ public function onClientDisconnect(int $sessionId, int $reason) : void{ public function onPacketReceive(int $sessionId, string $packet) : void{ $this->channel->write( chr(ITCProtocol::PACKET_ENCAPSULATED) . - Binary::writeInt($sessionId) . + LE::packUnsignedInt($sessionId) . $packet ); } @@ -63,7 +63,7 @@ public function onRawPacketReceive(string $address, int $port, string $payload) $this->channel->write( chr(ITCProtocol::PACKET_RAW) . chr(strlen($address)) . $address . - Binary::writeShort($port) . + LE::packUnsignedShort($port) . $payload ); } @@ -71,24 +71,24 @@ public function onRawPacketReceive(string $address, int $port, string $payload) public function onPacketAck(int $sessionId, int $identifierACK) : void{ $this->channel->write( chr(ITCProtocol::PACKET_ACK_NOTIFICATION) . - Binary::writeInt($sessionId) . - Binary::writeInt($identifierACK) + LE::packUnsignedInt($sessionId) . + LE::packSignedInt($identifierACK) ); } public function onBandwidthStatsUpdate(int $bytesSentDiff, int $bytesReceivedDiff) : void{ $this->channel->write( chr(ITCProtocol::PACKET_REPORT_BANDWIDTH_STATS) . - Binary::writeLong($bytesSentDiff) . - Binary::writeLong($bytesReceivedDiff) + LE::packUnsignedLong($bytesSentDiff) . + LE::packSignedLong($bytesReceivedDiff) ); } public function onPingMeasure(int $sessionId, int $pingMS) : void{ $this->channel->write( chr(ITCProtocol::PACKET_REPORT_PING) . - Binary::writeInt($sessionId) . - Binary::writeInt($pingMS) + LE::packUnsignedInt($sessionId) . + LE::packUnsignedInt($pingMS) ); } } diff --git a/src/UserToRakLibThreadMessageReceiver.php b/src/UserToRakLibThreadMessageReceiver.php index 8964c8a..dd7eae4 100644 --- a/src/UserToRakLibThreadMessageReceiver.php +++ b/src/UserToRakLibThreadMessageReceiver.php @@ -17,7 +17,7 @@ namespace raklib\server\ipc; -use pocketmine\utils\Binary; +use pmmp\encoding\LE; use raklib\protocol\EncapsulatedPacket; use raklib\protocol\PacketReliability; use raklib\server\ipc\UserToRakLibThreadMessageProtocol as ITCProtocol; @@ -36,7 +36,7 @@ public function process(ServerInterface $server) : bool{ $id = ord($packet[0]); $offset = 1; if($id === ITCProtocol::PACKET_ENCAPSULATED){ - $sessionId = Binary::readInt(substr($packet, $offset, 4)); + $sessionId = LE::unpackUnsignedInt(substr($packet, $offset, 4)); $offset += 4; $flags = ord($packet[$offset++]); $immediate = ($flags & ITCProtocol::ENCAPSULATED_FLAG_IMMEDIATE) !== 0; @@ -46,7 +46,7 @@ public function process(ServerInterface $server) : bool{ $encapsulated->reliability = ord($packet[$offset++]); if($needACK){ - $encapsulated->identifierACK = Binary::readInt(substr($packet, $offset, 4)); + $encapsulated->identifierACK = LE::unpackSignedInt(substr($packet, $offset, 4)); $offset += 4; } @@ -60,12 +60,12 @@ public function process(ServerInterface $server) : bool{ $len = ord($packet[$offset++]); $address = substr($packet, $offset, $len); $offset += $len; - $port = Binary::readShort(substr($packet, $offset, 2)); + $port = LE::unpackUnsignedShort(substr($packet, $offset, 2)); $offset += 2; $payload = substr($packet, $offset); $server->sendRaw($address, $port, $payload); }elseif($id === ITCProtocol::PACKET_CLOSE_SESSION){ - $sessionId = Binary::readInt(substr($packet, $offset, 4)); + $sessionId = LE::unpackUnsignedInt(substr($packet, $offset, 4)); $server->closeSession($sessionId); }elseif($id === ITCProtocol::PACKET_SET_NAME){ $server->setName(substr($packet, $offset)); @@ -74,13 +74,13 @@ public function process(ServerInterface $server) : bool{ }elseif($id === ITCProtocol::PACKET_DISABLE_PORT_CHECK){ $server->setPortCheck(false); }elseif($id === ITCProtocol::PACKET_SET_PACKETS_PER_TICK_LIMIT){ - $limit = Binary::readLong(substr($packet, $offset, 8)); + $limit = LE::unpackUnsignedLong(substr($packet, $offset, 8)); $server->setPacketsPerTickLimit($limit); }elseif($id === ITCProtocol::PACKET_BLOCK_ADDRESS){ $len = ord($packet[$offset++]); $address = substr($packet, $offset, $len); $offset += $len; - $timeout = Binary::readInt(substr($packet, $offset, 4)); + $timeout = LE::unpackUnsignedInt(substr($packet, $offset, 4)); $server->blockAddress($address, $timeout); }elseif($id === ITCProtocol::PACKET_UNBLOCK_ADDRESS){ $len = ord($packet[$offset++]); diff --git a/src/UserToRakLibThreadMessageSender.php b/src/UserToRakLibThreadMessageSender.php index 0bef6e2..073527c 100644 --- a/src/UserToRakLibThreadMessageSender.php +++ b/src/UserToRakLibThreadMessageSender.php @@ -17,7 +17,7 @@ namespace raklib\server\ipc; -use pocketmine\utils\Binary; +use pmmp\encoding\LE; use raklib\protocol\EncapsulatedPacket; use raklib\protocol\PacketReliability; use raklib\server\ipc\UserToRakLibThreadMessageProtocol as ITCProtocol; @@ -36,22 +36,22 @@ public function sendEncapsulated(int $sessionId, EncapsulatedPacket $packet, boo ($packet->identifierACK !== null ? ITCProtocol::ENCAPSULATED_FLAG_NEED_ACK : 0); $buffer = chr(ITCProtocol::PACKET_ENCAPSULATED) . - Binary::writeInt($sessionId) . + LE::packUnsignedInt($sessionId) . chr($flags) . chr($packet->reliability) . - ($packet->identifierACK !== null ? Binary::writeInt($packet->identifierACK) : "") . + ($packet->identifierACK !== null ? LE::packSignedInt($packet->identifierACK) : "") . (PacketReliability::isSequencedOrOrdered($packet->reliability) ? chr($packet->orderChannel) : "") . $packet->buffer; $this->channel->write($buffer); } public function sendRaw(string $address, int $port, string $payload) : void{ - $buffer = chr(ITCProtocol::PACKET_RAW) . chr(strlen($address)) . $address . Binary::writeShort($port) . $payload; + $buffer = chr(ITCProtocol::PACKET_RAW) . chr(strlen($address)) . $address . LE::packUnsignedShort($port) . $payload; $this->channel->write($buffer); } public function closeSession(int $sessionId) : void{ - $buffer = chr(ITCProtocol::PACKET_CLOSE_SESSION) . Binary::writeInt($sessionId); + $buffer = chr(ITCProtocol::PACKET_CLOSE_SESSION) . LE::packUnsignedInt($sessionId); $this->channel->write($buffer); } @@ -64,11 +64,11 @@ public function setPortCheck(bool $value) : void{ } public function setPacketsPerTickLimit(int $limit) : void{ - $this->channel->write(chr(ITCProtocol::PACKET_SET_PACKETS_PER_TICK_LIMIT) . Binary::writeLong($limit)); + $this->channel->write(chr(ITCProtocol::PACKET_SET_PACKETS_PER_TICK_LIMIT) . LE::packUnsignedLong($limit)); } public function blockAddress(string $address, int $timeout) : void{ - $buffer = chr(ITCProtocol::PACKET_BLOCK_ADDRESS) . chr(strlen($address)) . $address . Binary::writeInt($timeout); + $buffer = chr(ITCProtocol::PACKET_BLOCK_ADDRESS) . chr(strlen($address)) . $address . LE::packUnsignedInt($timeout); $this->channel->write($buffer); } From a959e9bf8f8888bf8ef8395355b7c40defe1311d Mon Sep 17 00:00:00 2001 From: "Dylan T." Date: Sat, 13 Sep 2025 00:44:03 +0100 Subject: [PATCH 2/2] Update actions image --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index df256f5..d8e1520 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,7 +12,7 @@ jobs: matrix: php: [8.0, 8.1, 8.2, 8.3, 8.4] name: PHP ${{ matrix.php }} - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3