From 9456e20770a2ca3576e92b0e7392198c82aeadd7 Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Date: Tue, 4 Aug 2015 18:29:13 +0200 Subject: [PATCH] Added support for extra data, improved BinaryStream --- src/pocketmine/level/Level.php | 44 +++++++++ src/pocketmine/level/format/FullChunk.php | 19 ++++ src/pocketmine/level/format/anvil/Anvil.php | 11 ++- src/pocketmine/level/format/anvil/Chunk.php | 38 +++++++- .../level/format/generic/BaseFullChunk.php | 31 +++++- src/pocketmine/level/format/leveldb/Chunk.php | 23 +++++ .../level/format/leveldb/LevelDB.php | 12 ++- .../level/format/mcregion/Chunk.php | 26 ++++- .../level/format/mcregion/McRegion.php | 11 ++- .../network/protocol/DataPacket.php | 2 +- src/pocketmine/utils/BinaryStream.php | 94 +++++++++++++------ 11 files changed, 271 insertions(+), 40 deletions(-) diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 2136e309c..6d4b301d4 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -90,6 +90,7 @@ use pocketmine\nbt\tag\String; use pocketmine\network\Network; use pocketmine\network\protocol\DataPacket; use pocketmine\network\protocol\FullChunkDataPacket; +use pocketmine\network\protocol\LevelEventPacket; use pocketmine\network\protocol\MoveEntityPacket; use pocketmine\network\protocol\SetEntityMotionPacket; use pocketmine\network\protocol\SetTimePacket; @@ -280,6 +281,10 @@ class Level implements ChunkManager, Metadatable{ return PHP_INT_SIZE === 8 ? (($x & 0xFFFFFFF) << 35) | (($y & 0x7f) << 28) | ($z & 0xFFFFFFF) : $x . ":" . $y .":". $z; } + public static function chunkBlockHash($x, $y, $z){ + return ($x << 11) | ($z << 7) | $y; + } + public static function getBlockXYZ($hash, &$x, &$y, &$z){ if(PHP_INT_SIZE === 8){ $x = ($hash >> 35) << 36 >> 36; @@ -798,6 +803,17 @@ class Level implements ChunkManager, Metadatable{ } } + public function sendBlockExtraData($x, $y, $z, $id, $data, array $targets = null){ + $pk = new LevelEventPacket; + $pk->evid = LevelEventPacket::EVENT_SET_DATA; + $pk->x = $x + 0.5; + $pk->y = $y + 0.5; + $pk->z = $z + 0.5; + $pk->data = ($data << 8) | $id; + + Server::broadcastPacket($targets === null ? $this->getChunkPlayers($x >> 4, $z >> 4) : $targets, $pk->setChannel(Network::CHANNEL_WORLD_EVENTS)); + } + /** * @param Player[] $target * @param Block[] $blocks @@ -1920,6 +1936,34 @@ class Level implements ChunkManager, Metadatable{ } } + /** + * Gets the raw block extra data + * + * @param int $x + * @param int $y + * @param int $z + * + * @return int 16-bit + */ + public function getBlockExtraDataAt($x, $y, $z){ + return $this->getChunk($x >> 4, $z >> 4, true)->getBlockExtraData($x & 0x0f, $y & 0x7f, $z & 0x0f); + } + + /** + * Sets the raw block metadata. + * + * @param int $x + * @param int $y + * @param int $z + * @param int $id + * @param int $data + */ + public function setBlockExtraDataAt($x, $y, $z, $id, $data){ + $this->getChunk($x >> 4, $z >> 4, true)->setBlockExtraData($x & 0x0f, $y & 0x7f, $z & 0x0f, ($data << 8) | $id); + + $this->sendBlockExtraData($x, $y, $z, $id, $data); + } + /** * Gets the raw block metadata * diff --git a/src/pocketmine/level/format/FullChunk.php b/src/pocketmine/level/format/FullChunk.php index 5406b4f61..783a939ff 100644 --- a/src/pocketmine/level/format/FullChunk.php +++ b/src/pocketmine/level/format/FullChunk.php @@ -119,6 +119,23 @@ interface FullChunk{ */ public function setBlockData($x, $y, $z, $data); + /** + * @param int $x 0-15 + * @param int $y 0-127 + * @param int $z 0-15 + * + * @return int (16-bit) + */ + public function getBlockExtraData($x, $y, $z); + + /** + * @param int $x 0-15 + * @param int $y 0-127 + * @param int $z 0-15 + * @param int $data (16-bit) + */ + public function setBlockExtraData($x, $y, $z, $data); + /** * @param int $x 0-15 * @param int $y 0-127 @@ -312,6 +329,8 @@ interface FullChunk{ public function getBlockDataArray(); + public function getBlockExtraDataArray(); + public function getBlockSkyLightArray(); public function getBlockLightArray(); diff --git a/src/pocketmine/level/format/anvil/Anvil.php b/src/pocketmine/level/format/anvil/Anvil.php index 0f7bb20c2..68a8f4f89 100644 --- a/src/pocketmine/level/format/anvil/Anvil.php +++ b/src/pocketmine/level/format/anvil/Anvil.php @@ -30,6 +30,7 @@ use pocketmine\nbt\tag\ByteArray; use pocketmine\nbt\tag\Compound; use pocketmine\network\protocol\FullChunkDataPacket; use pocketmine\tile\Spawnable; +use pocketmine\utils\BinaryStream; use pocketmine\utils\ChunkException; use raklib\Binary; @@ -89,14 +90,20 @@ class Anvil extends McRegion{ $tiles = $nbt->write(); } + $extraData = new BinaryStream(); + $extraData->putLInt(count($chunk->getBlockExtraDataArray())); + foreach($chunk->getBlockExtraDataArray() as $key => $value){ + $extraData->putLInt($key); + $extraData->putLShort($value); + } + $ordered = $chunk->getBlockIdArray() . $chunk->getBlockDataArray() . $chunk->getBlockSkyLightArray() . $chunk->getBlockLightArray() . pack("C*", ...$chunk->getHeightMapArray()) . pack("N*", ...$chunk->getBiomeColorArray()) . - //TODO extra data - Binary::writeInt(0) . + $extraData->getBuffer() . $tiles; $this->getLevel()->chunkRequestCallback($x, $z, $ordered, FullChunkDataPacket::ORDER_LAYERED); diff --git a/src/pocketmine/level/format/anvil/Chunk.php b/src/pocketmine/level/format/anvil/Chunk.php index 5458e03b8..557db546e 100644 --- a/src/pocketmine/level/format/anvil/Chunk.php +++ b/src/pocketmine/level/format/anvil/Chunk.php @@ -34,6 +34,7 @@ use pocketmine\nbt\tag\IntArray; use pocketmine\nbt\tag\Long; use pocketmine\Player; use pocketmine\utils\Binary; +use pocketmine\utils\BinaryStream; class Chunk extends BaseChunk{ @@ -92,14 +93,27 @@ class Chunk extends BaseChunk{ } } - parent::__construct($level, (int) $this->nbt["xPos"], (int) $this->nbt["zPos"], $sections, $this->nbt->BiomeColors->getValue(), $this->nbt->HeightMap->getValue(), $this->nbt->Entities->getValue(), $this->nbt->TileEntities->getValue()); + $extraData = []; + + if(!isset($this->nbt->ExtraData) or !($this->nbt->ExtraData instanceof ByteArray)){ + $this->nbt->ExtraData = new ByteArray("ExtraData", Binary::writeInt(0)); + }else{ + $stream = new BinaryStream($this->nbt->ExtraData->getValue()); + $count = $stream->getInt(); + for($i = 0; $i < $count; ++$i){ + $key = $stream->getInt(); + $extraData[$key] = $stream->getShort(false); + } + } + + parent::__construct($level, (int) $this->nbt["xPos"], (int) $this->nbt["zPos"], $sections, $this->nbt->BiomeColors->getValue(), $this->nbt->HeightMap->getValue(), $this->nbt->Entities->getValue(), $this->nbt->TileEntities->getValue(), $extraData); if(isset($this->nbt->Biomes)){ $this->checkOldBiomes($this->nbt->Biomes->getValue()); unset($this->nbt->Biomes); } - unset($this->nbt->Sections); + unset($this->nbt->Sections, $this->nbt->ExtraData); } public function isLightPopulated(){ @@ -240,6 +254,16 @@ class Chunk extends BaseChunk{ $nbt->TileEntities = new Enum("TileEntities", $tiles); $nbt->TileEntities->setTagType(NBT::TAG_Compound); + + $extraData = new BinaryStream(); + $extraData->putInt(count($this->getBlockExtraDataArray())); + foreach($this->getBlockExtraDataArray() as $key => $value){ + $extraData->putInt($key); + $extraData->putShort($value); + } + + $nbt->ExtraData = new ByteArray("ExtraData", $extraData->getBuffer()); + $writer = new NBT(NBT::BIG_ENDIAN); $nbt->setName("Level"); $writer->setData(new Compound("", ["Level" => $nbt])); @@ -293,6 +317,16 @@ class Chunk extends BaseChunk{ $nbt->TileEntities = new Enum("TileEntities", $tiles); $nbt->TileEntities->setTagType(NBT::TAG_Compound); + + $extraData = new BinaryStream(); + $extraData->putInt(count($this->getBlockExtraDataArray())); + foreach($this->getBlockExtraDataArray() as $key => $value){ + $extraData->putInt($key); + $extraData->putShort($value); + } + + $nbt->ExtraData = new ByteArray("ExtraData", $extraData->getBuffer()); + $writer = new NBT(NBT::BIG_ENDIAN); $nbt->setName("Level"); $writer->setData(new Compound("", ["Level" => $nbt])); diff --git a/src/pocketmine/level/format/generic/BaseFullChunk.php b/src/pocketmine/level/format/generic/BaseFullChunk.php index eca67d6f1..8690c08b7 100644 --- a/src/pocketmine/level/format/generic/BaseFullChunk.php +++ b/src/pocketmine/level/format/generic/BaseFullChunk.php @@ -26,6 +26,7 @@ use pocketmine\entity\Entity; use pocketmine\level\format\FullChunk; use pocketmine\level\format\LevelProvider; use pocketmine\level\generator\biome\Biome; +use pocketmine\level\Level; use pocketmine\nbt\tag\Compound; use pocketmine\Player; use pocketmine\tile\Tile; @@ -59,6 +60,8 @@ abstract class BaseFullChunk implements FullChunk{ protected $NBTentities; + protected $extraData = []; + /** @var LevelProvider */ protected $provider; @@ -82,7 +85,7 @@ abstract class BaseFullChunk implements FullChunk{ * @param Compound[] $entities * @param Compound[] $tiles */ - protected function __construct($provider, $x, $z, $blocks, $data, $skyLight, $blockLight, array $biomeColors = [], array $heightMap = [], array $entities = [], array $tiles = []){ + protected function __construct($provider, $x, $z, $blocks, $data, $skyLight, $blockLight, array $biomeColors = [], array $heightMap = [], array $entities = [], array $tiles = [], array $extraData = []){ $this->provider = $provider; $this->x = (int) $x; $this->z = (int) $z; @@ -95,7 +98,7 @@ abstract class BaseFullChunk implements FullChunk{ if(count($biomeColors) === 256){ $this->biomeColors = $biomeColors; }else{ - $this->biomeColors = array_fill(0, 256, Binary::readInt("\xff\x00\x00\x00\x00")); + $this->biomeColors = array_fill(0, 256, 0); } if(count($heightMap) === 256){ @@ -104,6 +107,8 @@ abstract class BaseFullChunk implements FullChunk{ $this->heightMap = array_fill(0, 256, 127); } + $this->extraData = $extraData; + $this->NBTtiles = $tiles; $this->NBTentities = $entities; } @@ -254,6 +259,24 @@ abstract class BaseFullChunk implements FullChunk{ } } + public function getBlockExtraData($x, $y, $z){ + if(isset($this->extraData[$index = Level::chunkBlockHash($x, $y, $z)])){ + return $this->extraData[$index]; + } + + return 0; + } + + public function setBlockExtraData($x, $y, $z, $data){ + if($data === 0){ + unset($this->extraData[Level::chunkBlockHash($x, $y, $z)]); + }else{ + $this->extraData[Level::chunkBlockHash($x, $y, $z)] = $data; + } + + $this->setChanged(true); + } + public function populateSkyLight(){ for($z = 0; $z < 16; ++$z){ for($x = 0; $x < 16; ++$x){ @@ -336,6 +359,10 @@ abstract class BaseFullChunk implements FullChunk{ return $this->tiles; } + public function getBlockExtraDataArray(){ + return $this->extraData; + } + public function getTile($x, $y, $z){ $index = ($z << 12) | ($x << 8) | $y; return isset($this->tileList[$index]) ? $this->tileList[$index] : null; diff --git a/src/pocketmine/level/format/leveldb/Chunk.php b/src/pocketmine/level/format/leveldb/Chunk.php index ce9e31eba..d4f64d3fe 100644 --- a/src/pocketmine/level/format/leveldb/Chunk.php +++ b/src/pocketmine/level/format/leveldb/Chunk.php @@ -26,6 +26,7 @@ use pocketmine\level\format\LevelProvider; use pocketmine\nbt\NBT; use pocketmine\Player; use pocketmine\utils\Binary; +use pocketmine\utils\BinaryStream; class Chunk extends BaseFullChunk{ @@ -260,6 +261,7 @@ class Chunk extends BaseFullChunk{ $entities = null; $tiles = null; + $extraData = []; if($provider instanceof LevelDB){ $nbt = new NBT(NBT::LITTLE_ENDIAN); @@ -280,6 +282,16 @@ class Chunk extends BaseFullChunk{ $tiles = [$tiles]; } } + $tileData = $provider->getDatabase()->get(substr($data, 0, 8) . LevelDB::ENTRY_EXTRA_DATA); + if($tileData !== false and strlen($tileData) > 0){ + $stream = new BinaryStream($tileData); + $count = $stream->getInt(); + for($i = 0; $i < $count; ++$i){ + $key = $stream->getInt(); + $value = $stream->getShort(false); + $extraData[$key] = $value; + } + } } $chunk = new Chunk($provider instanceof LevelProvider ? $provider : LevelDB::class, $chunkX, $chunkZ, $chunkData, $entities, $tiles); @@ -341,6 +353,17 @@ class Chunk extends BaseFullChunk{ $provider->getDatabase()->delete($chunkIndex . LevelDB::ENTRY_TILES); } + if(count($this->getBlockExtraDataArray()) > 0){ + $extraData = new BinaryStream(); + $extraData->putInt(count($this->getBlockExtraDataArray())); + foreach($this->getBlockExtraDataArray() as $key => $value){ + $extraData->putInt($key); + $extraData->putShort($value); + } + $provider->getDatabase()->put($chunkIndex . LevelDB::ENTRY_EXTRA_DATA, $extraData->getBuffer()); + }else{ + $provider->getDatabase()->delete($chunkIndex . LevelDB::ENTRY_EXTRA_DATA); + } } diff --git a/src/pocketmine/level/format/leveldb/LevelDB.php b/src/pocketmine/level/format/leveldb/LevelDB.php index e2bbb3f41..819f7fc7f 100644 --- a/src/pocketmine/level/format/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/leveldb/LevelDB.php @@ -33,6 +33,7 @@ use pocketmine\nbt\tag\Long; use pocketmine\nbt\tag\String; use pocketmine\tile\Spawnable; use pocketmine\utils\Binary; +use pocketmine\utils\BinaryStream; use pocketmine\utils\ChunkException; use pocketmine\utils\LevelException; @@ -40,6 +41,7 @@ class LevelDB extends BaseLevelProvider{ const ENTRY_VERSION = "v"; const ENTRY_FLAGS = "f"; + const ENTRY_EXTRA_DATA = "4"; const ENTRY_TICKS = "3"; const ENTRY_ENTITIES = "2"; const ENTRY_TILES = "1"; @@ -156,14 +158,20 @@ class LevelDB extends BaseLevelProvider{ $heightmap = pack("C*", ...$chunk->getHeightMapArray()); $biomeColors = pack("N*", ...$chunk->getBiomeColorArray()); + $extraData = new BinaryStream(); + $extraData->putLInt(count($chunk->getBlockExtraDataArray())); + foreach($chunk->getBlockExtraDataArray() as $key => $value){ + $extraData->putLInt($key); + $extraData->putLShort($value); + } + $ordered = $chunk->getBlockIdArray() . $chunk->getBlockDataArray() . $chunk->getBlockSkyLightArray() . $chunk->getBlockLightArray() . $heightmap . $biomeColors . - //TODO extra data - Binary::writeInt(0) . + $extraData->getBuffer() . $tiles; $this->getLevel()->chunkRequestCallback($x, $z, $ordered); diff --git a/src/pocketmine/level/format/mcregion/Chunk.php b/src/pocketmine/level/format/mcregion/Chunk.php index be2356af1..aee98c90d 100644 --- a/src/pocketmine/level/format/mcregion/Chunk.php +++ b/src/pocketmine/level/format/mcregion/Chunk.php @@ -33,6 +33,7 @@ use pocketmine\nbt\tag\IntArray; use pocketmine\nbt\tag\Long; use pocketmine\Player; use pocketmine\utils\Binary; +use pocketmine\utils\BinaryStream; class Chunk extends BaseFullChunk{ @@ -87,7 +88,20 @@ class Chunk extends BaseFullChunk{ $this->nbt->BlockLight = new ByteArray("BlockLight", $half); } - parent::__construct($level, $this->nbt["xPos"], $this->nbt["zPos"], $this->nbt->Blocks->getValue(), $this->nbt->Data->getValue(), $this->nbt->SkyLight->getValue(), $this->nbt->BlockLight->getValue(), $this->nbt->BiomeColors->getValue(), $this->nbt->HeightMap->getValue(), $this->nbt->Entities->getValue(), $this->nbt->TileEntities->getValue()); + $extraData = []; + + if(!isset($this->nbt->ExtraData) or !($this->nbt->ExtraData instanceof ByteArray)){ + $this->nbt->ExtraData = new ByteArray("ExtraData", Binary::writeInt(0)); + }else{ + $stream = new BinaryStream($this->nbt->ExtraData->getValue()); + $count = $stream->getInt(); + for($i = 0; $i < $count; ++$i){ + $key = $stream->getInt(); + $extraData[$key] = $stream->getShort(false); + } + } + + parent::__construct($level, $this->nbt["xPos"], $this->nbt["zPos"], $this->nbt->Blocks->getValue(), $this->nbt->Data->getValue(), $this->nbt->SkyLight->getValue(), $this->nbt->BlockLight->getValue(), $this->nbt->BiomeColors->getValue(), $this->nbt->HeightMap->getValue(), $this->nbt->Entities->getValue(), $this->nbt->TileEntities->getValue(), $extraData); if(isset($this->nbt->Biomes)){ $this->checkOldBiomes($this->nbt->Biomes->getValue()); @@ -395,6 +409,16 @@ class Chunk extends BaseFullChunk{ $nbt->TileEntities = new Enum("TileEntities", $tiles); $nbt->TileEntities->setTagType(NBT::TAG_Compound); + + $extraData = new BinaryStream(); + $extraData->putInt(count($this->getBlockExtraDataArray())); + foreach($this->getBlockExtraDataArray() as $key => $value){ + $extraData->putInt($key); + $extraData->putShort($value); + } + + $nbt->ExtraData = new ByteArray("ExtraData", $extraData->getBuffer()); + $writer = new NBT(NBT::BIG_ENDIAN); $nbt->setName("Level"); $writer->setData(new Compound("", ["Level" => $nbt])); diff --git a/src/pocketmine/level/format/mcregion/McRegion.php b/src/pocketmine/level/format/mcregion/McRegion.php index 68abe171b..8b0ae20cb 100644 --- a/src/pocketmine/level/format/mcregion/McRegion.php +++ b/src/pocketmine/level/format/mcregion/McRegion.php @@ -33,6 +33,7 @@ use pocketmine\nbt\tag\Long; use pocketmine\nbt\tag\String; use pocketmine\tile\Spawnable; use pocketmine\utils\Binary; +use pocketmine\utils\BinaryStream; use pocketmine\utils\ChunkException; class McRegion extends BaseLevelProvider{ @@ -132,14 +133,20 @@ class McRegion extends BaseLevelProvider{ $tiles = $nbt->write(); } + $extraData = new BinaryStream(); + $extraData->putLInt(count($chunk->getBlockExtraDataArray())); + foreach($chunk->getBlockExtraDataArray() as $key => $value){ + $extraData->putLInt($key); + $extraData->putLShort($value); + } + $ordered = $chunk->getBlockIdArray() . $chunk->getBlockDataArray() . $chunk->getBlockSkyLightArray() . $chunk->getBlockLightArray() . pack("C*", ...$chunk->getHeightMapArray()) . pack("N*", ...$chunk->getBiomeColorArray()) . - //TODO extra data - Binary::writeInt(0) . + $extraData->getBuffer() . $tiles; $this->getLevel()->chunkRequestCallback($x, $z, $ordered); diff --git a/src/pocketmine/network/protocol/DataPacket.php b/src/pocketmine/network/protocol/DataPacket.php index a0112b33d..443b8093f 100644 --- a/src/pocketmine/network/protocol/DataPacket.php +++ b/src/pocketmine/network/protocol/DataPacket.php @@ -48,7 +48,7 @@ abstract class DataPacket extends BinaryStream{ abstract public function decode(); - protected function reset(){ + public function reset(){ $this->buffer = chr($this::NETWORK_ID); $this->offset = 0; } diff --git a/src/pocketmine/utils/BinaryStream.php b/src/pocketmine/utils/BinaryStream.php index 8411afbe3..83aa07bd4 100644 --- a/src/pocketmine/utils/BinaryStream.php +++ b/src/pocketmine/utils/BinaryStream.php @@ -33,10 +33,15 @@ use pocketmine\utils\UUID; class BinaryStream extends \stdClass{ - public $offset = 0; - public $buffer = ""; + public $offset; + public $buffer; + + public function __construct($buffer = "", $offset = 0){ + $this->buffer = $buffer; + $this->offset = $offset; + } - protected function reset(){ + public function reset(){ $this->buffer = ""; $this->offset = 0; } @@ -54,7 +59,7 @@ class BinaryStream extends \stdClass{ return $this->buffer; } - protected function get($len){ + public function get($len){ if($len < 0){ $this->offset = strlen($this->buffer) - 1; return ""; @@ -65,68 +70,101 @@ class BinaryStream extends \stdClass{ return $len === 1 ? $this->buffer{$this->offset++} : substr($this->buffer, ($this->offset += $len) - $len, $len); } - protected function put($str){ + public function put($str){ $this->buffer .= $str; } - protected function getLong(){ + public function getLong(){ return Binary::readLong($this->get(8)); } - protected function putLong($v){ + public function putLong($v){ $this->buffer .= Binary::writeLong($v); } - protected function getInt(){ + public function getInt(){ return Binary::readInt($this->get(4)); } - protected function putInt($v){ + public function putInt($v){ $this->buffer .= Binary::writeInt($v); } - protected function getShort($signed = true){ + public function getLLong(){ + return Binary::readLLong($this->get(8)); + } + + public function putLLong($v){ + $this->buffer .= Binary::writeLLong($v); + } + + public function getLInt(){ + return Binary::readLInt($this->get(4)); + } + + public function putLInt($v){ + $this->buffer .= Binary::writeLInt($v); + } + + public function getShort($signed = true){ return $signed ? Binary::readSignedShort($this->get(2)) : Binary::readShort($this->get(2)); } - protected function putShort($v){ + public function putShort($v){ $this->buffer .= Binary::writeShort($v); } - protected function getFloat(){ + public function getFloat(){ return Binary::readFloat($this->get(4)); } - protected function putFloat($v){ + public function putFloat($v){ $this->buffer .= Binary::writeFloat($v); } - protected function getTriad(){ + public function getLShort($signed = true){ + return $signed ? Binary::readSignedLShort($this->get(2)) : Binary::readLShort($this->get(2)); + } + + public function putLShort($v){ + $this->buffer .= Binary::writeLShort($v); + } + + public function getLFloat(){ + return Binary::readLFloat($this->get(4)); + } + + public function putLFloat($v){ + $this->buffer .= Binary::writeLFloat($v); + } + + + public function getTriad(){ return Binary::readTriad($this->get(3)); } - protected function putTriad($v){ + public function putTriad($v){ $this->buffer .= Binary::writeTriad($v); } - protected function getLTriad(){ + public function getLTriad(){ return Binary::readLTriad($this->get(3)); } - protected function putLTriad($v){ + public function putLTriad($v){ $this->buffer .= Binary::writeLTriad($v); } - protected function getByte(){ + public function getByte(){ return ord($this->buffer{$this->offset++}); } - protected function putByte($v){ + public function putByte($v){ $this->buffer .= chr($v); } - protected function getDataArray($len = 10){ + public function getDataArray($len = 10){ $data = []; for($i = 1; $i <= $len and !$this->feof(); ++$i){ $data[] = $this->get($this->getTriad()); @@ -135,22 +173,22 @@ class BinaryStream extends \stdClass{ return $data; } - protected function putDataArray(array $data = []){ + public function putDataArray(array $data = []){ foreach($data as $v){ $this->putTriad(strlen($v)); $this->put($v); } } - protected function getUUID(){ + public function getUUID(){ return UUID::fromBinary($this->get(16)); } - protected function putUUID(UUID $uuid){ + public function putUUID(UUID $uuid){ $this->put($uuid->toBinary()); } - protected function getSlot(){ + public function getSlot(){ $id = $this->getShort(true); if($id <= 0){ @@ -177,7 +215,7 @@ class BinaryStream extends \stdClass{ ); } - protected function putSlot(Item $item){ + public function putSlot(Item $item){ if($item->getId() === 0){ $this->putShort(0); return; @@ -192,16 +230,16 @@ class BinaryStream extends \stdClass{ } - protected function getString(){ + public function getString(){ return $this->get($this->getShort()); } - protected function putString($v){ + public function putString($v){ $this->putShort(strlen($v)); $this->put($v); } - protected function feof(){ + public function feof(){ return !isset($this->buffer{$this->offset}); } }