Moved NBT to Composer library

This commit is contained in:
Dylan K. Taylor 2018-01-11 14:18:09 +00:00
parent 579c508761
commit c4966404bb
22 changed files with 46 additions and 2451 deletions

View File

@ -23,7 +23,8 @@
"ext-zlib": ">=1.2.11",
"pocketmine/raklib": "^0.10.0",
"pocketmine/pocketmine-spl": "^0.2.0",
"pocketmine/pocketmine-binaryutils": "dev-master#4795001f4444725f97b3c14c1e295635ff0a98a4"
"pocketmine/pocketmine-binaryutils": "dev-master#4795001f4444725f97b3c14c1e295635ff0a98a4",
"pocketmine/pocketmine-nbt": "dev-master#f8934c0aed90d1f55452588f7ebef7c4519518a5"
},
"autoload": {
"psr-0": {
@ -42,6 +43,10 @@
{
"type": "vcs",
"url": "https://github.com/pmmp/PocketMine-BinaryUtils"
},
{
"type": "vcs",
"url": "https://github.com/pmmp/PocketMine-NBT"
}
]
}

42
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "13a106ee8e33d29b4fc1d9edf2828b7d",
"content-hash": "f77760ebc72a115643865a02056f39cc",
"packages": [
{
"name": "pocketmine/pocketmine-binaryutils",
@ -20,6 +20,9 @@
"reference": "4795001f4444725f97b3c14c1e295635ff0a98a4",
"shasum": ""
},
"require": {
"php": ">=7.2"
},
"type": "library",
"autoload": {
"psr-4": {
@ -36,6 +39,40 @@
},
"time": "2018-01-11T12:51:47+00:00"
},
{
"name": "pocketmine/pocketmine-nbt",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/pmmp/PocketMine-NBT.git",
"reference": "f8934c0aed90d1f55452588f7ebef7c4519518a5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pmmp/PocketMine-NBT/zipball/f8934c0aed90d1f55452588f7ebef7c4519518a5",
"reference": "f8934c0aed90d1f55452588f7ebef7c4519518a5",
"shasum": ""
},
"require": {
"php": ">=7.2.0",
"pocketmine/pocketmine-binaryutils": "dev-master#8bb34e771fee69abcc5482d17d2fa0b4f0e15a5e"
},
"type": "library",
"autoload": {
"psr-4": {
"pocketmine\\nbt\\": "src/"
}
},
"license": [
"LGPL-3.0"
],
"description": "PHP library for working with Named Binary Tags",
"support": {
"source": "https://github.com/pmmp/PocketMine-NBT/tree/master",
"issues": "https://github.com/pmmp/PocketMine-NBT/issues"
},
"time": "2018-01-11T13:51:50+00:00"
},
{
"name": "pocketmine/pocketmine-spl",
"version": "0.2.0",
@ -112,7 +149,8 @@
"stability-flags": {
"php": 5,
"ext-pthreads": 20,
"pocketmine/pocketmine-binaryutils": 20
"pocketmine/pocketmine-binaryutils": 20,
"pocketmine/pocketmine-nbt": 20
},
"prefer-stable": false,
"prefer-lowest": false,

View File

@ -1,87 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\nbt;
#ifndef COMPILE
use pocketmine\utils\Binary;
#endif
#include <rules/NBT.h>
class BigEndianNBTStream extends NBTStream{
public function getShort() : int{
return Binary::readShort($this->get(2));
}
public function getSignedShort() : int{
return Binary::readSignedShort($this->get(2));
}
public function putShort(int $v) : void{
$this->buffer .= Binary::writeShort($v);
}
public function getInt() : int{
return Binary::readInt($this->get(4));
}
public function putInt(int $v) : void{
$this->buffer .= Binary::writeInt($v);
}
public function getLong() : int{
return Binary::readLong($this->get(8));
}
public function putLong(int $v) : void{
$this->buffer .= Binary::writeLong($v);
}
public function getFloat() : float{
return Binary::readFloat($this->get(4));
}
public function putFloat(float $v) : void{
$this->buffer .= Binary::writeFloat($v);
}
public function getDouble() : float{
return Binary::readDouble($this->get(8));
}
public function putDouble(float $v) : void{
$this->buffer .= Binary::writeDouble($v);
}
public function getIntArray() : array{
$len = $this->getInt();
return array_values(unpack("N*", $this->get($len * 4)));
}
public function putIntArray(array $array) : void{
$this->putInt(count($array));
$this->put(pack("N*", ...$array));
}
}

View File

@ -1,260 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\nbt;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\NamedTag;
class JsonNBTParser{
/**
* Parses JSON-formatted NBT into a CompoundTag and returns it. Used for parsing tags supplied with the /give command.
*
* @param string $data
* @param int &$offset
*
* @return CompoundTag|null
*
* @throws \Exception
*/
public static function parseJSON(string $data, int &$offset = 0){
$len = strlen($data);
for(; $offset < $len; ++$offset){
$c = $data{$offset};
if($c === "{"){
++$offset;
$data = self::parseCompound($data, $offset);
return new CompoundTag("", $data);
}elseif($c !== " " and $c !== "\r" and $c !== "\n" and $c !== "\t"){
throw new \Exception("Syntax error: unexpected '$c' at offset $offset");
}
}
return null;
}
/**#
* @param string $str
* @param int &$offset
*
* @return NamedTag[]
*/
private static function parseList(string $str, int &$offset = 0) : array{
$len = strlen($str);
$key = 0;
$value = null;
$data = [];
for(; $offset < $len; ++$offset){
if($str{$offset - 1} === "]"){
break;
}elseif($str{$offset} === "]"){
++$offset;
break;
}
$value = self::readValue($str, $offset, $type);
$tag = NBT::createTag($type);
if($tag instanceof NamedTag){
$tag->setValue($value);
$data[$key] = $tag;
}
$key++;
}
return $data;
}
/**
* @param string $str
* @param int $offset
*
* @return NamedTag[]
*/
private static function parseCompound(string $str, int &$offset = 0) : array{
$len = strlen($str);
$data = [];
for(; $offset < $len; ++$offset){
if($str{$offset - 1} === "}"){
break;
}elseif($str{$offset} === "}"){
++$offset;
break;
}
$key = self::readKey($str, $offset);
$value = self::readValue($str, $offset, $type);
$tag = NBT::createTag($type);
if($tag instanceof NamedTag){
$tag->setName($key);
$tag->setValue($value);
$data[$key] = $tag;
}
}
return $data;
}
/**
* @param string $data
* @param int $offset
* @param int|null $type
*
* @return mixed
* @throws \Exception
*/
private static function readValue(string $data, int &$offset, &$type = null){
$value = "";
$type = null;
$inQuotes = false;
$len = strlen($data);
for(; $offset < $len; ++$offset){
$c = $data{$offset};
if(!$inQuotes and ($c === " " or $c === "\r" or $c === "\n" or $c === "\t" or $c === "," or $c === "}" or $c === "]")){
if($c === "," or $c === "}" or $c === "]"){
break;
}
}elseif($c === '"'){
$inQuotes = !$inQuotes;
if($type === null){
$type = NBT::TAG_String;
}elseif($inQuotes){
throw new \Exception("Syntax error: invalid quote at offset $offset");
}
}elseif($c === "\\"){
$value .= $data{$offset + 1} ?? "";
++$offset;
}elseif($c === "{" and !$inQuotes){
if($value !== ""){
throw new \Exception("Syntax error: invalid compound start at offset $offset");
}
++$offset;
$value = self::parseCompound($data, $offset);
$type = NBT::TAG_Compound;
break;
}elseif($c === "[" and !$inQuotes){
if($value !== ""){
throw new \Exception("Syntax error: invalid list start at offset $offset");
}
++$offset;
$value = self::parseList($data, $offset);
$type = NBT::TAG_List;
break;
}else{
$value .= $c;
}
}
if($value === ""){
throw new \Exception("Syntax error: invalid empty value at offset $offset");
}
if($type === null and strlen($value) > 0){
$value = trim($value);
$last = strtolower(substr($value, -1));
$part = substr($value, 0, -1);
if($last !== "b" and $last !== "s" and $last !== "l" and $last !== "f" and $last !== "d"){
$part = $value;
$last = null;
}
if($last !== "f" and $last !== "d" and ((string) ((int) $part)) === $part){
if($last === "b"){
$type = NBT::TAG_Byte;
}elseif($last === "s"){
$type = NBT::TAG_Short;
}elseif($last === "l"){
$type = NBT::TAG_Long;
}else{
$type = NBT::TAG_Int;
}
$value = (int) $part;
}elseif(is_numeric($part)){
if($last === "f" or $last === "d" or strpos($part, ".") !== false){
if($last === "f"){
$type = NBT::TAG_Float;
}elseif($last === "d"){
$type = NBT::TAG_Double;
}else{
$type = NBT::TAG_Float;
}
$value = (float) $part;
}else{
if($last === "l"){
$type = NBT::TAG_Long;
}else{
$type = NBT::TAG_Int;
}
$value = $part;
}
}else{
$type = NBT::TAG_String;
}
}
return $value;
}
/**
* @param string $data
* @param int $offset
*
* @return string
* @throws \Exception
*/
private static function readKey(string $data, int &$offset) : string{
$key = "";
$len = strlen($data);
for(; $offset < $len; ++$offset){
$c = $data{$offset};
if($c === ":"){
++$offset;
break;
}elseif($c !== " " and $c !== "\r" and $c !== "\n" and $c !== "\t" and $c !== "\""){
$key .= $c;
}
}
if($key === ""){
throw new \Exception("Syntax error: invalid empty key at offset $offset");
}
return $key;
}
}

View File

@ -1,87 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\nbt;
#ifndef COMPILE
use pocketmine\utils\Binary;
#endif
#include <rules/NBT.h>
class LittleEndianNBTStream extends NBTStream{
public function getShort() : int{
return Binary::readLShort($this->get(2));
}
public function getSignedShort() : int{
return Binary::readSignedLShort($this->get(2));
}
public function putShort(int $v) : void{
$this->put(Binary::writeLShort($v));
}
public function getInt() : int{
return Binary::readLInt($this->get(4));
}
public function putInt(int $v) : void{
$this->put(Binary::writeLInt($v));
}
public function getLong() : int{
return Binary::readLLong($this->get(8));
}
public function putLong(int $v) : void{
$this->put(Binary::writeLLong($v));
}
public function getFloat() : float{
return Binary::readLFloat($this->get(4));
}
public function putFloat(float $v) : void{
$this->put(Binary::writeLFloat($v));
}
public function getDouble() : float{
return Binary::readLDouble($this->get(8));
}
public function putDouble(float $v) : void{
$this->put(Binary::writeLDouble($v));
}
public function getIntArray() : array{
$len = $this->getInt();
return array_values(unpack("V*", $this->get($len * 4)));
}
public function putIntArray(array $array) : void{
$this->putInt(count($array));
$this->put(pack("V*", ...$array));
}
}

View File

@ -1,159 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
/**
* Named Binary Tag handling classes
*/
namespace pocketmine\nbt;
use pocketmine\nbt\tag\ByteArrayTag;
use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\DoubleTag;
use pocketmine\nbt\tag\EndTag;
use pocketmine\nbt\tag\FloatTag;
use pocketmine\nbt\tag\IntArrayTag;
use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\LongTag;
use pocketmine\nbt\tag\ShortTag;
use pocketmine\nbt\tag\StringTag;
use pocketmine\nbt\tag\Tag;
abstract class NBT{
public const LITTLE_ENDIAN = 0;
public const BIG_ENDIAN = 1;
public const TAG_End = 0;
public const TAG_Byte = 1;
public const TAG_Short = 2;
public const TAG_Int = 3;
public const TAG_Long = 4;
public const TAG_Float = 5;
public const TAG_Double = 6;
public const TAG_ByteArray = 7;
public const TAG_String = 8;
public const TAG_List = 9;
public const TAG_Compound = 10;
public const TAG_IntArray = 11;
/**
* @param int $type
*
* @return Tag
*/
public static function createTag(int $type) : Tag{
switch($type){
case self::TAG_End:
return new EndTag();
case self::TAG_Byte:
return new ByteTag();
case self::TAG_Short:
return new ShortTag();
case self::TAG_Int:
return new IntTag();
case self::TAG_Long:
return new LongTag();
case self::TAG_Float:
return new FloatTag();
case self::TAG_Double:
return new DoubleTag();
case self::TAG_ByteArray:
return new ByteArrayTag();
case self::TAG_String:
return new StringTag();
case self::TAG_List:
return new ListTag();
case self::TAG_Compound:
return new CompoundTag();
case self::TAG_IntArray:
return new IntArrayTag();
default:
throw new \InvalidArgumentException("Unknown NBT tag type $type");
}
}
public static function matchList(ListTag $tag1, ListTag $tag2) : bool{
if($tag1->getName() !== $tag2->getName() or $tag1->getCount() !== $tag2->getCount()){
return false;
}
foreach($tag1 as $k => $v){
if(!($v instanceof Tag)){
continue;
}
if(!isset($tag2->{$k}) or !($tag2->{$k} instanceof $v)){
return false;
}
if($v instanceof CompoundTag){
if(!self::matchTree($v, $tag2->{$k})){
return false;
}
}elseif($v instanceof ListTag){
if(!self::matchList($v, $tag2->{$k})){
return false;
}
}else{
if($v->getValue() !== $tag2->{$k}->getValue()){
return false;
}
}
}
return true;
}
public static function matchTree(CompoundTag $tag1, CompoundTag $tag2) : bool{
if($tag1->getName() !== $tag2->getName() or $tag1->getCount() !== $tag2->getCount()){
return false;
}
foreach($tag1 as $k => $v){
if(!($v instanceof Tag)){
continue;
}
if(!isset($tag2->{$k}) or !($tag2->{$k} instanceof $v)){
return false;
}
if($v instanceof CompoundTag){
if(!self::matchTree($v, $tag2->{$k})){
return false;
}
}elseif($v instanceof ListTag){
if(!self::matchList($v, $tag2->{$k})){
return false;
}
}else{
if($v->getValue() !== $tag2->{$k}->getValue()){
return false;
}
}
}
return true;
}
}

View File

@ -1,271 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\nbt;
use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\EndTag;
use pocketmine\nbt\tag\FloatTag;
use pocketmine\nbt\tag\IntArrayTag;
use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\NamedTag;
use pocketmine\nbt\tag\StringTag;
use pocketmine\nbt\tag\Tag;
#ifndef COMPILE
use pocketmine\utils\Binary;
#endif
#include <rules/NBT.h>
/**
* Base Named Binary Tag encoder/decoder
*/
abstract class NBTStream{
public $buffer;
public $offset;
private $data;
public function get($len) : string{
if($len < 0){
$this->offset = strlen($this->buffer) - 1;
return "";
}elseif($len === true){
return substr($this->buffer, $this->offset);
}
return $len === 1 ? $this->buffer{$this->offset++} : substr($this->buffer, ($this->offset += $len) - $len, $len);
}
public function put(string $v) : void{
$this->buffer .= $v;
}
public function feof() : bool{
return !isset($this->buffer{$this->offset});
}
public function __construct(){
$this->offset = 0;
$this->buffer = "";
}
public function read(string $buffer, bool $doMultiple = false) : void{
$this->offset = 0;
$this->buffer = $buffer;
$this->data = $this->readTag();
if($doMultiple and $this->offset < strlen($this->buffer)){
$this->data = [$this->data];
do{
$this->data[] = $this->readTag();
}while($this->offset < strlen($this->buffer));
}
$this->buffer = "";
}
public function readCompressed(string $buffer) : void{
$this->read(zlib_decode($buffer));
}
/**
* @return bool|string
*/
public function write(){
$this->offset = 0;
$this->buffer = "";
if($this->data instanceof CompoundTag){
$this->writeTag($this->data);
return $this->buffer;
}elseif(is_array($this->data)){
foreach($this->data as $tag){
$this->writeTag($tag);
}
return $this->buffer;
}
return false;
}
public function writeCompressed(int $compression = ZLIB_ENCODING_GZIP, int $level = 7){
if(($write = $this->write()) !== false){
return zlib_encode($write, $compression, $level);
}
return false;
}
public function readTag() : Tag{
if($this->feof()){
return new EndTag();
}
$tagType = $this->getByte();
$tag = NBT::createTag($tagType);
if($tag instanceof NamedTag){
$tag->setName($this->getString());
$tag->read($this);
}
return $tag;
}
public function writeTag(Tag $tag) : void{
$this->putByte($tag->getType());
if($tag instanceof NamedTag){
$this->putString($tag->getName());
}
$tag->write($this);
}
public function getByte() : int{
return Binary::readByte($this->get(1));
}
public function getSignedByte() : int{
return Binary::readSignedByte($this->get(1));
}
public function putByte(int $v) : void{
$this->buffer .= Binary::writeByte($v);
}
abstract public function getShort() : int;
abstract public function getSignedShort() : int;
abstract public function putShort(int $v) : void;
abstract public function getInt() : int;
abstract public function putInt(int $v) : void;
abstract public function getLong() : int;
abstract public function putLong(int $v) : void;
abstract public function getFloat() : float;
abstract public function putFloat(float $v) : void;
abstract public function getDouble() : float;
abstract public function putDouble(float $v) : void;
public function getString() : string{
return $this->get($this->getShort());
}
public function putString(string $v) : void{
$this->putShort(strlen($v));
$this->put($v);
}
abstract public function getIntArray() : array;
abstract public function putIntArray(array $array) : void;
public function getArray() : array{
$data = [];
self::toArray($data, $this->data);
return $data;
}
private static function toArray(array &$data, Tag $tag) : void{
/** @var CompoundTag[]|ListTag[]|IntArrayTag[] $tag */
foreach($tag as $key => $value){
if($value instanceof CompoundTag or $value instanceof ListTag or $value instanceof IntArrayTag){
$data[$key] = [];
self::toArray($data[$key], $value);
}else{
$data[$key] = $value->getValue();
}
}
}
public static function fromArrayGuesser(string $key, $value) : ?NamedTag{
if(is_int($value)){
return new IntTag($key, $value);
}elseif(is_float($value)){
return new FloatTag($key, $value);
}elseif(is_string($value)){
return new StringTag($key, $value);
}elseif(is_bool($value)){
return new ByteTag($key, $value ? 1 : 0);
}
return null;
}
private static function fromArray(Tag $tag, array $data, callable $guesser) : void{
foreach($data as $key => $value){
if(is_array($value)){
$isNumeric = true;
$isIntArray = true;
foreach($value as $k => $v){
if(!is_numeric($k)){
$isNumeric = false;
break;
}elseif(!is_int($v)){
$isIntArray = false;
}
}
$tag{$key} = $isNumeric ? ($isIntArray ? new IntArrayTag($key, []) : new ListTag($key, [])) : new CompoundTag($key, []);
self::fromArray($tag->{$key}, $value, $guesser);
}else{
$v = call_user_func($guesser, $key, $value);
if($v instanceof Tag){
$tag{$key} = $v;
}
}
}
}
public function setArray(array $data, callable $guesser = null) : void{
$this->data = new CompoundTag("", []);
self::fromArray($this->data, $data, $guesser ?? [self::class, "fromArrayGuesser"]);
}
/**
* @return CompoundTag|array
*/
public function getData(){
return $this->data;
}
/**
* @param CompoundTag|array $data
*/
public function setData($data) : void{
$this->data = $data;
}
}

View File

@ -1,74 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\nbt;
#ifndef COMPILE
use pocketmine\utils\Binary;
#endif
#include <rules/NBT.h>
class NetworkLittleEndianNBTStream extends LittleEndianNBTStream{
public function getInt() : int{
return Binary::readVarInt($this->buffer, $this->offset);
}
public function putInt(int $v) : void{
$this->put(Binary::writeVarInt($v));
}
public function getLong() : int{
return Binary::readVarLong($this->buffer, $this->offset);
}
public function putLong(int $v) : void{
$this->put(Binary::writeVarLong($v));
}
public function getString() : string{
return $this->get(Binary::readUnsignedVarInt($this->buffer, $this->offset));
}
public function putString(string $v) : void{
$this->put(Binary::writeUnsignedVarInt(strlen($v)) . $v);
}
public function getIntArray() : array{
$len = $this->getInt(); //varint
$ret = [];
for($i = 0; $i < $len; ++$i){
$ret[] = $this->getInt(); //varint
}
return $ret;
}
public function putIntArray(array $array) : void{
$this->putInt(count($array)); //varint
foreach($array as $v){
$this->putInt($v); //varint
}
}
}

View File

@ -1,74 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\nbt\tag;
use pocketmine\nbt\NBT;
use pocketmine\nbt\NBTStream;
#include <rules/NBT.h>
class ByteArrayTag extends NamedTag{
/**
* ByteArrayTag constructor.
*
* @param string $name
* @param string $value
*/
public function __construct(string $name = "", string $value = ""){
parent::__construct($name, $value);
}
public function getType() : int{
return NBT::TAG_ByteArray;
}
public function read(NBTStream $nbt) : void{
$this->value = $nbt->get($nbt->getInt());
}
public function write(NBTStream $nbt) : void{
$nbt->putInt(strlen($this->value));
$nbt->put($this->value);
}
/**
* @return string
*/
public function &getValue() : string{
return parent::getValue();
}
/**
* @param string $value
*
* @throws \TypeError
*/
public function setValue($value) : void{
if(!is_string($value)){
throw new \TypeError("ByteArrayTag value must be of type string, " . gettype($value) . " given");
}
parent::setValue($value);
}
}

View File

@ -1,75 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\nbt\tag;
use pocketmine\nbt\NBT;
use pocketmine\nbt\NBTStream;
#include <rules/NBT.h>
class ByteTag extends NamedTag{
/**
* ByteTag constructor.
*
* @param string $name
* @param int $value
*/
public function __construct(string $name = "", int $value = 0){
parent::__construct($name, $value);
}
public function getType() : int{
return NBT::TAG_Byte;
}
public function read(NBTStream $nbt) : void{
$this->value = $nbt->getSignedByte();
}
public function write(NBTStream $nbt) : void{
$nbt->putByte($this->value);
}
/**
* @return int
*/
public function &getValue() : int{
return parent::getValue();
}
/**
* @param int $value
*
* @throws \TypeError
*/
public function setValue($value) : void{
if(!is_int($value)){
throw new \TypeError("ByteTag value must be of type int, " . gettype($value) . " given");
}elseif($value < -(2 ** 7) or $value > ((2 ** 7) - 1)){
throw new \InvalidArgumentException("Value $value is too large!");
}
parent::setValue($value);
}
}

View File

@ -1,467 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\nbt\tag;
use pocketmine\nbt\NBT;
use pocketmine\nbt\NBTStream;
#include <rules/NBT.h>
class CompoundTag extends NamedTag implements \ArrayAccess{
/**
* CompoundTag constructor.
*
* @param string $name
* @param NamedTag[] $value
*/
public function __construct(string $name = "", array $value = []){
parent::__construct($name, $value);
}
/**
* @return int
*/
public function getCount(){
return count($this->getValue());
}
/**
* @return NamedTag[]
*/
public function &getValue(){
$result = [];
foreach($this as $tag){
if($tag instanceof NamedTag){
$result[$tag->getName()] = $tag;
}
}
return $result;
}
/**
* @param NamedTag[] $value
*
* @throws \TypeError
*/
public function setValue($value) : void{
if(is_array($value)){
foreach($value as $name => $tag){
if($tag instanceof NamedTag){
$this->{$tag->__name} = $tag;
}else{
throw new \TypeError("CompoundTag members must be NamedTags, got " . gettype($tag) . " in given array");
}
}
}else{
throw new \TypeError("CompoundTag value must be NamedTag[], " . gettype($value) . " given");
}
}
/*
* Here follows many functions of misery for the sake of type safety. We really needs generics in PHP :(
*/
/**
* Returns the tag with the specified name, or null if it does not exist.
*
* @param string $name
* @param string|null $expectedClass Class that extends NamedTag
*
* @return NamedTag|null
* @throws \RuntimeException if the tag exists and is not of the expected type (if specified)
*/
public function getTag(string $name, string $expectedClass = NamedTag::class) : ?NamedTag{
assert(is_a($expectedClass, NamedTag::class, true));
$tag = $this->{$name} ?? null;
if($tag !== null and !($tag instanceof $expectedClass)){
throw new \RuntimeException("Expected a tag of type $expectedClass, got " . get_class($tag));
}
return $tag;
}
/**
* Returns the ListTag with the specified name, or null if it does not exist. Triggers an exception if a tag exists
* with that name and the tag is not a ListTag.
*
* @param string $name
* @return ListTag|null
*/
public function getListTag(string $name) : ?ListTag{
return $this->getTag($name, ListTag::class);
}
/**
* Returns the CompoundTag with the specified name, or null if it does not exist. Triggers an exception if a tag
* exists with that name and the tag is not a CompoundTag.
*
* @param string $name
* @return CompoundTag|null
*/
public function getCompoundTag(string $name) : ?CompoundTag{
return $this->getTag($name, CompoundTag::class);
}
/**
* Sets the specified NamedTag as a child tag of the CompoundTag at the offset specified by the tag's name. If a tag
* already exists at the offset, it will be overwritten with the new one.
*
* @param NamedTag $tag
*/
public function setTag(NamedTag $tag) : void{
$this->{$tag->__name} = $tag;
}
/**
* Removes the child tags with the specified names from the CompoundTag. This function accepts a variadic list of
* strings.
*
* @param string[] ...$names
*/
public function removeTag(string ...$names) : void{
foreach($names as $name){
unset($this->{$name});
}
}
/**
* Returns whether the CompoundTag contains a child tag with the specified name.
*
* @param string $name
* @param string $expectedClass
*
* @return bool
*/
public function hasTag(string $name, string $expectedClass = NamedTag::class) : bool{
assert(is_a($expectedClass, NamedTag::class, true));
return ($this->{$name} ?? null) instanceof $expectedClass;
}
/**
* Returns the value of the child tag with the specified name, or $default if the tag doesn't exist. If the child
* tag is not of type $expectedType, an exception will be thrown, unless a default is given and $badTagDefault is
* true.
*
* @param string $name
* @param string $expectedClass
* @param mixed $default
* @param bool $badTagDefault Return the specified default if the tag is not of the expected type.
*
* @return mixed
*/
public function getTagValue(string $name, string $expectedClass, $default = null, bool $badTagDefault = false){
$tag = $this->getTag($name, $badTagDefault ? NamedTag::class : $expectedClass);
if($tag instanceof $expectedClass){
return $tag->getValue();
}
if($default === null){
throw new \RuntimeException("Tag with name \"$name\" " . ($tag !== null ? "not of expected type" : "not found") . " and no valid default value given");
}
return $default;
}
/*
* The following methods are wrappers around getTagValue() with type safety.
*/
/**
* @param string $name
* @param int|null $default
* @param bool $badTagDefault
*
* @return int
*/
public function getByte(string $name, ?int $default = null, bool $badTagDefault = false) : int{
return $this->getTagValue($name, ByteTag::class, $default, $badTagDefault);
}
/**
* @param string $name
* @param int|null $default
* @param bool $badTagDefault
*
* @return int
*/
public function getShort(string $name, ?int $default = null, bool $badTagDefault = false) : int{
return $this->getTagValue($name, ShortTag::class, $default, $badTagDefault);
}
/**
* @param string $name
* @param int|null $default
* @param bool $badTagDefault
*
* @return int
*/
public function getInt(string $name, ?int $default = null, bool $badTagDefault = false) : int{
return $this->getTagValue($name, IntTag::class, $default, $badTagDefault);
}
/**
* @param string $name
* @param int|null $default
* @param bool $badTagDefault
*
* @return int
*/
public function getLong(string $name, ?int $default = null, bool $badTagDefault = false) : int{
return $this->getTagValue($name, LongTag::class, $default, $badTagDefault);
}
/**
* @param string $name
* @param float|null $default
* @param bool $badTagDefault
*
* @return float
*/
public function getFloat(string $name, ?float $default = null, bool $badTagDefault = false) : float{
return $this->getTagValue($name, FloatTag::class, $default, $badTagDefault);
}
/**
* @param string $name
* @param float|null $default
* @param bool $badTagDefault
*
* @return float
*/
public function getDouble(string $name, ?float $default = null, bool $badTagDefault = false) : float{
return $this->getTagValue($name, DoubleTag::class, $default, $badTagDefault);
}
/**
* @param string $name
* @param string|null $default
* @param bool $badTagDefault
*
* @return string
*/
public function getByteArray(string $name, ?string $default = null, bool $badTagDefault = false) : string{
return $this->getTagValue($name, ByteArrayTag::class, $default, $badTagDefault);
}
/**
* @param string $name
* @param string|null $default
* @param bool $badTagDefault
*
* @return string
*/
public function getString(string $name, ?string $default = null, bool $badTagDefault = false) : string{
return $this->getTagValue($name, StringTag::class, $default, $badTagDefault);
}
/**
* @param string $name
* @param int[]|null $default
* @param bool $badTagDefault
*
* @return int[]
*/
public function getIntArray(string $name, ?array $default = null, bool $badTagDefault = false) : array{
return $this->getTagValue($name, IntArrayTag::class, $default, $badTagDefault);
}
/**
* Sets the value of the child tag at the specified offset, creating it if it does not exist. If the child tag
* exists and the value is of the wrong type, an exception will be thrown.
*
* @param string $name Name of the tag to set
* @param string $tagClass Class that extends NamedTag
* @param mixed $value Value to set. This should be compatible with the specified tag type.
* @param bool $force Force set the value even if the existing tag is not the correct type (overwrite the old tag)
*/
public function setTagValue(string $name, string $tagClass, $value, bool $force) : void{
assert(is_a($tagClass, NamedTag::class, true));
$tag = $this->getTag($name, $force ? NamedTag::class : $tagClass);
if($tag instanceof $tagClass){
$tag->setValue($value);
}else{
$this->setTag(new $tagClass($name, $value));
}
}
/*
* The following methods are wrappers around setTagValue() with type safety.
*/
/**
* @param string $name
* @param int $value
* @param bool $force
*/
public function setByte(string $name, int $value, bool $force = false) : void{
$this->setTagValue($name, ByteTag::class, $value, $force);
}
/**
* @param string $name
* @param int $value
* @param bool $force
*/
public function setShort(string $name, int $value, bool $force = false) : void{
$this->setTagValue($name, ShortTag::class, $value, $force);
}
/**
* @param string $name
* @param int $value
* @param bool $force
*/
public function setInt(string $name, int $value, bool $force = false) : void{
$this->setTagValue($name, IntTag::class, $value, $force);
}
/**
* @param string $name
* @param int $value
* @param bool $force
*/
public function setLong(string $name, int $value, bool $force = false) : void{
$this->setTagValue($name, LongTag::class, $value, $force);
}
/**
* @param string $name
* @param float $value
* @param bool $force
*/
public function setFloat(string $name, float $value, bool $force = false) : void{
$this->setTagValue($name, FloatTag::class, $value, $force);
}
/**
* @param string $name
* @param float $value
* @param bool $force
*/
public function setDouble(string $name, float $value, bool $force = false) : void{
$this->setTagValue($name, DoubleTag::class, $value, $force);
}
/**
* @param string $name
* @param string $value
* @param bool $force
*/
public function setByteArray(string $name, string $value, bool $force = false) : void{
$this->setTagValue($name, ByteArrayTag::class, $value, $force);
}
/**
* @param string $name
* @param string $value
* @param bool $force
*/
public function setString(string $name, string $value, bool $force = false) : void{
$this->setTagValue($name, StringTag::class, $value, $force);
}
/**
* @param string $name
* @param int[] $value
* @param bool $force
*/
public function setIntArray(string $name, array $value, bool $force = false) : void{
$this->setTagValue($name, IntArrayTag::class, $value, $force);
}
public function offsetExists($offset){
return isset($this->{$offset}) and $this->{$offset} instanceof Tag;
}
public function offsetGet($offset){
if(isset($this->{$offset}) and $this->{$offset} instanceof Tag){
if($this->{$offset} instanceof \ArrayAccess){
return $this->{$offset};
}else{
return $this->{$offset}->getValue();
}
}
assert(false, "Offset $offset not found");
return null;
}
public function offsetSet($offset, $value){
if($value instanceof Tag){
$this->{$offset} = $value;
}elseif(isset($this->{$offset}) and $this->{$offset} instanceof Tag){
$this->{$offset}->setValue($value);
}
}
public function offsetUnset($offset){
unset($this->{$offset});
}
public function getType() : int{
return NBT::TAG_Compound;
}
public function read(NBTStream $nbt) : void{
$this->value = [];
do{
$tag = $nbt->readTag();
if($tag instanceof NamedTag and $tag->__name !== ""){
$this->{$tag->__name} = $tag;
}
}while(!($tag instanceof EndTag) and !$nbt->feof());
}
public function write(NBTStream $nbt) : void{
foreach($this as $tag){
if($tag instanceof Tag and !($tag instanceof EndTag)){
$nbt->writeTag($tag);
}
}
$nbt->writeTag(new EndTag);
}
public function __toString(){
$str = get_class($this) . "{\n";
foreach($this as $tag){
if($tag instanceof Tag){
$str .= get_class($tag) . ":" . $tag->__toString() . "\n";
}
}
return $str . "}";
}
public function __clone(){
foreach($this as $key => $tag){
if($tag instanceof Tag){
$this->{$key} = clone $tag;
}
}
}
}

View File

@ -1,73 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\nbt\tag;
use pocketmine\nbt\NBT;
use pocketmine\nbt\NBTStream;
#include <rules/NBT.h>
class DoubleTag extends NamedTag{
/**
* DoubleTag constructor.
*
* @param string $name
* @param float $value
*/
public function __construct(string $name = "", float $value = 0.0){
parent::__construct($name, $value);
}
public function getType() : int{
return NBT::TAG_Double;
}
public function read(NBTStream $nbt) : void{
$this->value = $nbt->getDouble();
}
public function write(NBTStream $nbt) : void{
$nbt->putDouble($this->value);
}
/**
* @return float
*/
public function &getValue() : float{
return parent::getValue();
}
/**
* @param float $value
*
* @throws \TypeError
*/
public function setValue($value) : void{
if(!is_float($value) and !is_int($value)){
throw new \TypeError("DoubleTag value must be of type double, " . gettype($value) . " given");
}
parent::setValue((float) $value);
}
}

View File

@ -1,42 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\nbt\tag;
use pocketmine\nbt\NBT;
use pocketmine\nbt\NBTStream;
class EndTag extends Tag{
public function getType() : int{
return NBT::TAG_End;
}
public function read(NBTStream $nbt) : void{
}
public function write(NBTStream $nbt) : void{
}
}

View File

@ -1,68 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\nbt\tag;
use pocketmine\nbt\NBT;
use pocketmine\nbt\NBTStream;
#include <rules/NBT.h>
class FloatTag extends NamedTag{
/**
* FloatTag constructor.
*
* @param string $name
* @param float $value
*/
public function __construct(string $name = "", float $value = 0.0){
parent::__construct($name, $value);
}
public function getType() : int{
return NBT::TAG_Float;
}
public function read(NBTStream $nbt) : void{
$this->value = $nbt->getFloat();
}
public function write(NBTStream $nbt) : void{
$nbt->putFloat($this->value);
}
/**
* @return float
*/
public function &getValue() : float{
return parent::getValue();
}
public function setValue($value) : void{
if(!is_float($value) and !is_int($value)){
throw new \TypeError("FloatTag value must be of type float, " . gettype($value) . " given");
}
parent::setValue((float) $value);
}
}

View File

@ -1,83 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\nbt\tag;
use pocketmine\nbt\NBT;
use pocketmine\nbt\NBTStream;
#include <rules/NBT.h>
class IntArrayTag extends NamedTag{
/**
* IntArrayTag constructor.
*
* @param string $name
* @param int[] $value
*/
public function __construct(string $name = "", array $value = []){
parent::__construct($name, $value);
}
public function getType() : int{
return NBT::TAG_IntArray;
}
public function read(NBTStream $nbt) : void{
$this->value = $nbt->getIntArray();
}
public function write(NBTStream $nbt) : void{
$nbt->putIntArray($this->value);
}
public function __toString(){
$str = get_class($this) . "{\n";
$str .= implode(", ", $this->value);
return $str . "}";
}
/**
* @return int[]
*/
public function &getValue() : array{
return parent::getValue();
}
/**
* @param int[] $value
*
* @throws \TypeError
*/
public function setValue($value) : void{
if(!is_array($value)){
throw new \TypeError("IntArrayTag value must be of type int[], " . gettype($value) . " given");
}
assert(count(array_filter($value, function($v){
return !is_int($v);
})) === 0);
parent::setValue($value);
}
}

View File

@ -1,73 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\nbt\tag;
use pocketmine\nbt\NBT;
use pocketmine\nbt\NBTStream;
#include <rules/NBT.h>
class IntTag extends NamedTag{
/**
* @param string $name
* @param int $value
*/
public function __construct(string $name = "", int $value = 0){
parent::__construct($name, $value);
}
public function getType() : int{
return NBT::TAG_Int;
}
public function read(NBTStream $nbt) : void{
$this->value = $nbt->getInt();
}
public function write(NBTStream $nbt) : void{
$nbt->putInt($this->value);
}
/**
* @return int
*/
public function &getValue() : int{
return parent::getValue();
}
/**
* @param int $value
*
* @throws \TypeError
*/
public function setValue($value) : void{
if(!is_int($value)){
throw new \TypeError("IntTag value must be of type int, " . gettype($value) . " given");
}elseif($value < -(2 ** 31) or $value > ((2 ** 31) - 1)){
throw new \InvalidArgumentException("Value $value is too large!");
}
parent::setValue($value);
}
}

View File

@ -1,227 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\nbt\tag;
use pocketmine\nbt\NBT;
use pocketmine\nbt\NBTStream;
#include <rules/NBT.h>
class ListTag extends NamedTag implements \ArrayAccess, \Countable{
/** @var int */
private $tagType;
/**
* ListTag constructor.
*
* @param string $name
* @param NamedTag[] $value
* @param int $tagType
*/
public function __construct(string $name = "", array $value = [], int $tagType = NBT::TAG_End){
parent::__construct($name, $value);
$this->tagType = $tagType;
}
/**
* @return NamedTag[]
*/
public function &getValue() : array{
$value = [];
foreach($this as $k => $v){
if($v instanceof Tag){
$value[$k] = $v;
}
}
return $value;
}
/**
* @param NamedTag[] $value
*
* @throws \TypeError
*/
public function setValue($value) : void{
if(is_array($value)){
foreach($value as $name => $tag){
if($tag instanceof NamedTag){
$this->{$name} = $tag;
}else{
throw new \TypeError("ListTag members must be NamedTags, got " . gettype($tag) . " in given array");
}
}
}else{
throw new \TypeError("ListTag value must be NamedTag[], " . gettype($value) . " given");
}
}
public function getCount(){
$count = 0;
foreach($this as $tag){
if($tag instanceof Tag){
++$count;
}
}
return $count;
}
public function getAllValues() : array{
$result = [];
foreach($this as $tag){
if(!($tag instanceof NamedTag)){
continue;
}
if($tag instanceof \ArrayAccess){
$result[] = $tag;
}else{
$result[] = $tag->getValue();
}
}
return $result;
}
public function offsetExists($offset){
return isset($this->{$offset});
}
/**
* @param int $offset
*
* @return CompoundTag|ListTag|mixed
*/
public function offsetGet($offset){
if(isset($this->{$offset}) and $this->{$offset} instanceof Tag){
if($this->{$offset} instanceof \ArrayAccess){
return $this->{$offset};
}else{
return $this->{$offset}->getValue();
}
}
return null;
}
public function offsetSet($offset, $value){
if($value instanceof Tag){
$this->{$offset} = $value;
}elseif($this->{$offset} instanceof Tag){
$this->{$offset}->setValue($value);
}
}
public function offsetUnset($offset){
unset($this->{$offset});
}
public function count($mode = COUNT_NORMAL){
$count = 0;
for($i = 0; isset($this->{$i}); $i++){
if($mode === COUNT_RECURSIVE and $this->{$i} instanceof \Countable){
$count += count($this->{$i});
}else{
$count++;
}
}
return $count;
}
public function getType() : int{
return NBT::TAG_List;
}
public function setTagType(int $type){
$this->tagType = $type;
}
public function getTagType() : int{
return $this->tagType;
}
public function read(NBTStream $nbt) : void{
$this->value = [];
$this->tagType = $nbt->getByte();
$size = $nbt->getInt();
$tagBase = NBT::createTag($this->tagType);
for($i = 0; $i < $size and !$nbt->feof(); ++$i){
$tag = clone $tagBase;
$tag->read($nbt);
$this->{$i} = $tag;
}
}
public function write(NBTStream $nbt) : void{
if($this->tagType === NBT::TAG_End){ //previously empty list, try detecting type from tag children
$id = NBT::TAG_End;
foreach($this as $tag){
if($tag instanceof Tag and !($tag instanceof EndTag)){
if($id === NBT::TAG_End){
$id = $tag->getType();
}elseif($id !== $tag->getType()){
return; //TODO: throw exception?
}
}
}
$this->tagType = $id;
}
$nbt->putByte($this->tagType);
/** @var Tag[] $tags */
$tags = [];
foreach($this as $tag){
if($tag instanceof Tag){
$tags[] = $tag;
}
}
$nbt->putInt(count($tags));
foreach($tags as $tag){
$tag->write($nbt);
}
}
public function __toString(){
$str = get_class($this) . "{\n";
foreach($this as $tag){
if($tag instanceof Tag){
$str .= get_class($tag) . ":" . $tag->__toString() . "\n";
}
}
return $str . "}";
}
public function __clone(){
foreach($this as $key => $tag){
if($tag instanceof Tag){
$this->{$key} = clone $tag;
}
}
}
}

View File

@ -1,73 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\nbt\tag;
use pocketmine\nbt\NBT;
use pocketmine\nbt\NBTStream;
#include <rules/NBT.h>
class LongTag extends NamedTag{
/**
* LongTag constructor.
*
* @param string $name
* @param int $value
*/
public function __construct(string $name = "", int $value = 0){
parent::__construct($name, $value);
}
public function getType() : int{
return NBT::TAG_Long;
}
public function read(NBTStream $nbt) : void{
$this->value = $nbt->getLong();
}
public function write(NBTStream $nbt) : void{
$nbt->putLong($this->value);
}
/**
* @return int
*/
public function &getValue() : int{
return parent::getValue();
}
/**
* @param int $value
*
* @throws \TypeError
*/
public function setValue($value) : void{
if(!is_int($value)){
throw new \TypeError("LongTag value must be of type int, " . gettype($value) . " given");
}
parent::setValue($value);
}
}

View File

@ -1,55 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\nbt\tag;
abstract class NamedTag extends Tag{
/** @var string */
protected $__name;
/**
* @param string $name
* @param mixed $value
*/
public function __construct(string $name = "", $value = null){
$this->__name = ($name === null or $name === false) ? "" : $name;
if($value !== null){
$this->setValue($value);
}
}
/**
* @return string
*/
public function getName() : string{
return $this->__name;
}
/**
* @param string $name
*/
public function setName(string $name) : void{
$this->__name = $name;
}
}

View File

@ -1,75 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\nbt\tag;
use pocketmine\nbt\NBT;
use pocketmine\nbt\NBTStream;
#include <rules/NBT.h>
class ShortTag extends NamedTag{
/**
* ShortTag constructor.
*
* @param string $name
* @param int $value
*/
public function __construct(string $name = "", int $value = 0){
parent::__construct($name, $value);
}
public function getType() : int{
return NBT::TAG_Short;
}
public function read(NBTStream $nbt) : void{
$this->value = $nbt->getSignedShort();
}
public function write(NBTStream $nbt) : void{
$nbt->putShort($this->value);
}
/**
* @return int
*/
public function &getValue() : int{
return parent::getValue();
}
/**
* @param int $value
*
* @throws \TypeError
*/
public function setValue($value) : void{
if(!is_int($value)){
throw new \TypeError("ShortTag value must be of type int, " . gettype($value) . " given");
}elseif($value < -(2 ** 15) or $value > ((2 ** 15) - 1)){
throw new \InvalidArgumentException("Value $value is too large!");
}
parent::setValue($value);
}
}

View File

@ -1,73 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\nbt\tag;
use pocketmine\nbt\NBT;
use pocketmine\nbt\NBTStream;
#include <rules/NBT.h>
class StringTag extends NamedTag{
/**
* StringTag constructor.
*
* @param string $name
* @param string $value
*/
public function __construct(string $name = "", string $value = ""){
parent::__construct($name, $value);
}
public function getType() : int{
return NBT::TAG_String;
}
public function read(NBTStream $nbt) : void{
$this->value = $nbt->getString();
}
public function write(NBTStream $nbt) : void{
$nbt->putString($this->value);
}
/**
* @return string
*/
public function &getValue() : string{
return parent::getValue();
}
/**
* @param string $value
*
* @throws \TypeError
*/
public function setValue($value) : void{
if(!is_string($value)){
throw new \TypeError("StringTag value must be of type string, " . gettype($value) . " given");
}
parent::setValue($value);
}
}

View File

@ -1,52 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
/**
* All the NBT Tags
*/
namespace pocketmine\nbt\tag;
use pocketmine\nbt\NBTStream;
abstract class Tag extends \stdClass{
protected $value;
public function &getValue(){
return $this->value;
}
abstract public function getType() : int;
public function setValue($value) : void{
$this->value = $value;
}
abstract public function write(NBTStream $nbt) : void;
abstract public function read(NBTStream $nbt) : void;
public function __toString(){
return (string) $this->value;
}
}