From 02f15b8e78d5ed8023e8e8b39700bfda34c0a515 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 4 Jan 2024 16:27:40 +0000 Subject: [PATCH] Convert PacketReliability to enum --- src/generic/ReceiveReliabilityLayer.php | 6 +-- src/generic/SendReliabilityLayer.php | 10 ++--- src/generic/Session.php | 4 +- src/protocol/EncapsulatedPacket.php | 29 ++++++++------ src/protocol/PacketReliability.php | 52 ++++++++++++------------- 5 files changed, 53 insertions(+), 48 deletions(-) diff --git a/src/generic/ReceiveReliabilityLayer.php b/src/generic/ReceiveReliabilityLayer.php index 9105eb6..3f9ef96 100644 --- a/src/generic/ReceiveReliabilityLayer.php +++ b/src/generic/ReceiveReliabilityLayer.php @@ -163,13 +163,13 @@ private function handleEncapsulatedPacket(EncapsulatedPacket $packet) : void{ return; } - if(PacketReliability::isSequencedOrOrdered($packet->reliability) and ($packet->orderChannel < 0 or $packet->orderChannel >= PacketReliability::MAX_ORDER_CHANNELS)){ + if($packet->reliability->isSequencedOrOrdered() and ($packet->orderChannel < 0 or $packet->orderChannel >= PacketReliability::MAX_ORDER_CHANNELS)){ //TODO: this should result in peer banning $this->logger->debug("Invalid packet, bad order channel ($packet->orderChannel)"); return; } - if(PacketReliability::isSequenced($packet->reliability)){ + if($packet->reliability->isSequenced()){ if($packet->sequenceIndex < $this->receiveSequencedHighestIndex[$packet->orderChannel] or $packet->orderIndex < $this->receiveOrderedIndex[$packet->orderChannel]){ //too old sequenced packet, discard it return; @@ -177,7 +177,7 @@ private function handleEncapsulatedPacket(EncapsulatedPacket $packet) : void{ $this->receiveSequencedHighestIndex[$packet->orderChannel] = $packet->sequenceIndex + 1; $this->handleEncapsulatedPacketRoute($packet); - }elseif(PacketReliability::isOrdered($packet->reliability)){ + }elseif($packet->reliability->isOrdered()){ if($packet->orderIndex === $this->receiveOrderedIndex[$packet->orderChannel]){ //this is the packet we expected to get next //Any ordered packet resets the sequence index to zero, so that sequenced packets older than this ordered diff --git a/src/generic/SendReliabilityLayer.php b/src/generic/SendReliabilityLayer.php index 93f374c..20ac391 100644 --- a/src/generic/SendReliabilityLayer.php +++ b/src/generic/SendReliabilityLayer.php @@ -85,7 +85,7 @@ private function sendDatagram(array $packets) : void{ $resendable = []; foreach($datagram->packets as $pk){ - if(PacketReliability::isReliable($pk->reliability)){ + if($pk->reliability->isReliable()){ $resendable[] = $pk; } } @@ -133,9 +133,9 @@ public function addEncapsulatedToQueue(EncapsulatedPacket $packet, bool $immedia $this->needACK[$packet->identifierACK] = []; } - if(PacketReliability::isOrdered($packet->reliability)){ + if($packet->reliability->isOrdered()){ $packet->orderIndex = $this->sendOrderedIndex[$packet->orderChannel]++; - }elseif(PacketReliability::isSequenced($packet->reliability)){ + }elseif($packet->reliability->isSequenced()){ $packet->orderIndex = $this->sendOrderedIndex[$packet->orderChannel]; //sequenced packets don't increment the ordered channel index $packet->sequenceIndex = $this->sendSequencedIndex[$packet->orderChannel]++; } @@ -153,7 +153,7 @@ public function addEncapsulatedToQueue(EncapsulatedPacket $packet, bool $immedia $pk->reliability = $packet->reliability; $pk->buffer = $buffer; - if(PacketReliability::isReliable($pk->reliability)){ + if($pk->reliability->isReliable()){ $pk->messageIndex = $this->messageIndex++; } @@ -164,7 +164,7 @@ public function addEncapsulatedToQueue(EncapsulatedPacket $packet, bool $immedia $this->addToQueue($pk, true); } }else{ - if(PacketReliability::isReliable($packet->reliability)){ + if($packet->reliability->isReliable()){ $packet->messageIndex = $this->messageIndex++; } $this->addToQueue($packet, $immediate); diff --git a/src/generic/Session.php b/src/generic/Session.php index 43ad7d0..15b1134 100644 --- a/src/generic/Session.php +++ b/src/generic/Session.php @@ -215,7 +215,7 @@ public function update(float $time) : void{ } } - protected function queueConnectedPacket(ConnectedPacket $packet, int $reliability, int $orderChannel, bool $immediate = false) : void{ + protected function queueConnectedPacket(ConnectedPacket $packet, PacketReliability $reliability, int $orderChannel, bool $immediate = false) : void{ $out = new PacketSerializer(); //TODO: reuse streams to reduce allocations $packet->encode($out); @@ -231,7 +231,7 @@ public function addEncapsulatedToQueue(EncapsulatedPacket $packet, bool $immedia $this->sendLayer->addEncapsulatedToQueue($packet, $immediate); } - protected function sendPing(int $reliability = PacketReliability::UNRELIABLE) : void{ + protected function sendPing(PacketReliability $reliability = PacketReliability::UNRELIABLE) : void{ $this->queueConnectedPacket(ConnectedPing::create($this->getRakNetTimeMS()), $reliability, 0, true); } diff --git a/src/protocol/EncapsulatedPacket.php b/src/protocol/EncapsulatedPacket.php index 0c41251..b3e13ad 100644 --- a/src/protocol/EncapsulatedPacket.php +++ b/src/protocol/EncapsulatedPacket.php @@ -31,7 +31,7 @@ class EncapsulatedPacket{ public const SPLIT_INFO_LENGTH = 4 + 2 + 4; //split count (4) + split ID (2) + split index (4) - public int $reliability; + public PacketReliability $reliability; public ?int $messageIndex = null; public ?int $sequenceIndex = null; public ?int $orderIndex = null; @@ -47,7 +47,12 @@ public static function fromBinary(BinaryStream $stream) : EncapsulatedPacket{ $packet = new EncapsulatedPacket(); $flags = $stream->getByte(); - $packet->reliability = $reliability = ($flags & self::RELIABILITY_FLAGS) >> self::RELIABILITY_SHIFT; + $reliability = PacketReliability::tryFrom(($flags & self::RELIABILITY_FLAGS) >> self::RELIABILITY_SHIFT); + if($reliability === null){ + //TODO: we should reject the ACK_RECEIPT types here - they aren't supposed to be sent over the wire + throw new BinaryDataException("Invalid encapsulated packet reliability"); + } + $packet->reliability = $reliability; $hasSplit = ($flags & self::SPLIT_FLAG) !== 0; $length = (int) ceil($stream->getShort() / 8); @@ -55,15 +60,15 @@ public static function fromBinary(BinaryStream $stream) : EncapsulatedPacket{ throw new BinaryDataException("Encapsulated payload length cannot be zero"); } - if(PacketReliability::isReliable($reliability)){ + if($reliability->isReliable()){ $packet->messageIndex = $stream->getLTriad(); } - if(PacketReliability::isSequenced($reliability)){ + if($reliability->isSequenced()){ $packet->sequenceIndex = $stream->getLTriad(); } - if(PacketReliability::isSequencedOrOrdered($reliability)){ + if($reliability->isSequencedOrOrdered()){ $packet->orderIndex = $stream->getLTriad(); $packet->orderChannel = $stream->getByte(); } @@ -81,11 +86,11 @@ public static function fromBinary(BinaryStream $stream) : EncapsulatedPacket{ public function toBinary() : string{ return - chr(($this->reliability << self::RELIABILITY_SHIFT) | ($this->splitInfo !== null ? self::SPLIT_FLAG : 0)) . + chr(($this->reliability->value << self::RELIABILITY_SHIFT) | ($this->splitInfo !== null ? self::SPLIT_FLAG : 0)) . Binary::writeShort(strlen($this->buffer) << 3) . - (PacketReliability::isReliable($this->reliability) ? Binary::writeLTriad($this->messageIndex) : "") . - (PacketReliability::isSequenced($this->reliability) ? Binary::writeLTriad($this->sequenceIndex) : "") . - (PacketReliability::isSequencedOrOrdered($this->reliability) ? Binary::writeLTriad($this->orderIndex) . chr($this->orderChannel) : "") . + ($this->reliability->isReliable() ? Binary::writeLTriad($this->messageIndex) : "") . + ($this->reliability->isSequenced() ? Binary::writeLTriad($this->sequenceIndex) : "") . + ($this->reliability->isSequencedOrOrdered() ? Binary::writeLTriad($this->orderIndex) . chr($this->orderChannel) : "") . ($this->splitInfo !== null ? Binary::writeInt($this->splitInfo->getTotalPartCount()) . Binary::writeShort($this->splitInfo->getId()) . Binary::writeInt($this->splitInfo->getPartIndex()) : "") . $this->buffer; } @@ -97,9 +102,9 @@ public function getHeaderLength() : int{ return 1 + //reliability 2 + //length - (PacketReliability::isReliable($this->reliability) ? 3 : 0) + //message index - (PacketReliability::isSequenced($this->reliability) ? 3 : 0) + //sequence index - (PacketReliability::isSequencedOrOrdered($this->reliability) ? 3 + 1 : 0) + //order index (3) + order channel (1) + ($this->reliability->isReliable() ? 3 : 0) + //message index + ($this->reliability->isSequenced() ? 3 : 0) + //sequence index + ($this->reliability->isSequencedOrOrdered() ? 3 + 1 : 0) + //order index (3) + order channel (1) ($this->splitInfo !== null ? self::SPLIT_INFO_LENGTH : 0); } diff --git a/src/protocol/PacketReliability.php b/src/protocol/PacketReliability.php index 26cb738..d6c814a 100644 --- a/src/protocol/PacketReliability.php +++ b/src/protocol/PacketReliability.php @@ -16,7 +16,7 @@ namespace raklib\protocol; -abstract class PacketReliability{ +enum PacketReliability : int{ /* * From https://github.com/OculusVR/RakNet/blob/master/Source/PacketPriority.h @@ -24,49 +24,49 @@ abstract class PacketReliability{ * Default: 0b010 (2) or 0b011 (3) */ - public const UNRELIABLE = 0; - public const UNRELIABLE_SEQUENCED = 1; - public const RELIABLE = 2; - public const RELIABLE_ORDERED = 3; - public const RELIABLE_SEQUENCED = 4; + case UNRELIABLE = 0; + case UNRELIABLE_SEQUENCED = 1; + case RELIABLE = 2; + case RELIABLE_ORDERED = 3; + case RELIABLE_SEQUENCED = 4; /* The following reliabilities are used in RakNet internals, but never sent on the wire. */ - public const UNRELIABLE_WITH_ACK_RECEIPT = 5; - public const RELIABLE_WITH_ACK_RECEIPT = 6; - public const RELIABLE_ORDERED_WITH_ACK_RECEIPT = 7; + case UNRELIABLE_WITH_ACK_RECEIPT = 5; + case RELIABLE_WITH_ACK_RECEIPT = 6; + case RELIABLE_ORDERED_WITH_ACK_RECEIPT = 7; public const MAX_ORDER_CHANNELS = 32; - public static function isReliable(int $reliability) : bool{ + public function isReliable() : bool{ return ( - $reliability === self::RELIABLE or - $reliability === self::RELIABLE_ORDERED or - $reliability === self::RELIABLE_SEQUENCED or - $reliability === self::RELIABLE_WITH_ACK_RECEIPT or - $reliability === self::RELIABLE_ORDERED_WITH_ACK_RECEIPT + $this === self::RELIABLE or + $this === self::RELIABLE_ORDERED or + $this === self::RELIABLE_SEQUENCED or + $this === self::RELIABLE_WITH_ACK_RECEIPT or + $this === self::RELIABLE_ORDERED_WITH_ACK_RECEIPT ); } - public static function isSequenced(int $reliability) : bool{ + public function isSequenced() : bool{ return ( - $reliability === self::UNRELIABLE_SEQUENCED or - $reliability === self::RELIABLE_SEQUENCED + $this === self::UNRELIABLE_SEQUENCED or + $this === self::RELIABLE_SEQUENCED ); } - public static function isOrdered(int $reliability) : bool{ + public function isOrdered() : bool{ return ( - $reliability === self::RELIABLE_ORDERED or - $reliability === self::RELIABLE_ORDERED_WITH_ACK_RECEIPT + $this === self::RELIABLE_ORDERED or + $this === self::RELIABLE_ORDERED_WITH_ACK_RECEIPT ); } - public static function isSequencedOrOrdered(int $reliability) : bool{ + public function isSequencedOrOrdered() : bool{ return ( - $reliability === self::UNRELIABLE_SEQUENCED or - $reliability === self::RELIABLE_ORDERED or - $reliability === self::RELIABLE_SEQUENCED or - $reliability === self::RELIABLE_ORDERED_WITH_ACK_RECEIPT + $this === self::UNRELIABLE_SEQUENCED or + $this === self::RELIABLE_ORDERED or + $this === self::RELIABLE_SEQUENCED or + $this === self::RELIABLE_ORDERED_WITH_ACK_RECEIPT ); } }