use pocketmine\network\mcpe\NetworkBinaryStream; use pocketmine\network\mcpe\NetworkSession; use pocketmine\utils\Utils; abstract class DataPacket extends NetworkBinaryStream{ public const NETWORK_ID = 0; /** @var bool */ public $isEncoded = false; /** @var int */ public $extraByte1 = 0; /** @var int */ public $extraByte2 = 0; public function pid(){ return $this::NETWORK_ID; } public function getName() : string{ return (new \ReflectionClass($this))->getShortName(); } public function canBeBatched() : bool{ return true; } public function canBeSentBeforeLogin() : bool{ return false; } /** * Returns whether the packet may legally have unread bytes left in the buffer. * @return bool */ public function mayHaveUnreadBytes() : bool{ return false; } public function decode(){ $this->offset = 0; $this->decodeHeader(); $this->decodePayload(); } protected function decodeHeader(){ $pid = $this->getUnsignedVarInt(); assert($pid === static::NETWORK_ID); $this->extraByte1 = $this->getByte(); $this->extraByte2 = $this->getByte(); assert($this->extraByte1 === 0 and $this->extraByte2 === 0, "Got unexpected non-zero split-screen bytes (byte1: $this->extraByte1, byte2: $this->extraByte2"); } /** * Note for plugin developers: If you're adding your own packets, you should perform decoding in here. */ protected function decodePayload(){ } public function encode(){ $this->reset(); $this->encodeHeader(); $this->encodePayload(); $this->isEncoded = true; } protected function encodeHeader(){ $this->putUnsignedVarInt(static::NETWORK_ID); $this->putByte($this->extraByte1); $this->putByte($this->extraByte2); } /** * Note for plugin developers: If you're adding your own packets, you should perform encoding in here. */ protected function encodePayload(){ } /** * Performs handling for this packet. Usually you'll want an appropriately named method in the NetworkSession for this. * * This method returns a bool to indicate whether the packet was handled or not. If the packet was unhandled, a debug message will be logged with a hexdump of the packet. * Typically this method returns the return value of the handler in the supplied NetworkSession. See other packets for examples how to implement this. * * @param NetworkSession $session * * @return bool true if the packet was handled successfully, false if not. */ abstract public function handle(NetworkSession $session) : bool; public function clean(){ $this->buffer = null; $this->isEncoded = false; $this->offset = 0; return $this; } public function __debugInfo(){ $data = []; foreach($this as $k => $v){ if($k === "buffer" and is_string($v)){ $data[$k] = bin2hex($v); }elseif(is_string($v) or (is_object($v) and method_exists($v, "__toString"))){ $data[$k] = Utils::printable((string) $v); }else{ $data[$k] = $v; } } return $data; } }