Cleaned up some duplicated code in NBT parser

This commit is contained in:
Dylan K. Taylor 2017-05-19 18:30:32 +01:00
parent f3c38700f5
commit f6c0ba9846
2 changed files with 59 additions and 190 deletions

View File

@ -71,6 +71,42 @@ class NBT{
public $endianness; public $endianness;
private $data; private $data;
/**
* @param int $type
*
* @return Tag
*/
public static function createTag(int $type){
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){ public static function matchList(ListTag $tag1, ListTag $tag2){
if($tag1->getName() !== $tag2->getName() or $tag1->getCount() !== $tag2->getCount()){ if($tag1->getName() !== $tag2->getName() or $tag1->getCount() !== $tag2->getCount()){
return false; return false;
@ -170,40 +206,11 @@ class NBT{
$value = self::readValue($str, $offset, $type); $value = self::readValue($str, $offset, $type);
switch($type){ $tag = self::createTag($type);
case NBT::TAG_Byte: if($tag instanceof NamedTag){
$data[$key] = new ByteTag($key, $value); $tag->setName($key);
break; $tag->setValue($value);
case NBT::TAG_Short: $data[$key] = $tag;
$data[$key] = new ShortTag($key, $value);
break;
case NBT::TAG_Int:
$data[$key] = new IntTag($key, $value);
break;
case NBT::TAG_Long:
$data[$key] = new LongTag($key, $value);
break;
case NBT::TAG_Float:
$data[$key] = new FloatTag($key, $value);
break;
case NBT::TAG_Double:
$data[$key] = new DoubleTag($key, $value);
break;
case NBT::TAG_ByteArray:
$data[$key] = new ByteArrayTag($key, $value);
break;
case NBT::TAG_String:
$data[$key] = new StringTag($key, $value);
break;
case NBT::TAG_List:
$data[$key] = new ListTag($key, $value);
break;
case NBT::TAG_Compound:
$data[$key] = new CompoundTag($key, $value);
break;
case NBT::TAG_IntArray:
$data[$key] = new IntArrayTag($key, $value);
break;
} }
$key++; $key++;
@ -228,40 +235,11 @@ class NBT{
$key = self::readKey($str, $offset); $key = self::readKey($str, $offset);
$value = self::readValue($str, $offset, $type); $value = self::readValue($str, $offset, $type);
switch($type){ $tag = self::createTag($type);
case NBT::TAG_Byte: if($tag instanceof NamedTag){
$data[$key] = new ByteTag($key, $value); $tag->setName($key);
break; $tag->setValue($value);
case NBT::TAG_Short: $data[$key] = $tag;
$data[$key] = new ShortTag($key, $value);
break;
case NBT::TAG_Int:
$data[$key] = new IntTag($key, $value);
break;
case NBT::TAG_Long:
$data[$key] = new LongTag($key, $value);
break;
case NBT::TAG_Float:
$data[$key] = new FloatTag($key, $value);
break;
case NBT::TAG_Double:
$data[$key] = new DoubleTag($key, $value);
break;
case NBT::TAG_ByteArray:
$data[$key] = new ByteArrayTag($key, $value);
break;
case NBT::TAG_String:
$data[$key] = new StringTag($key, $value);
break;
case NBT::TAG_List:
$data[$key] = new ListTag($key, $value);
break;
case NBT::TAG_Compound:
$data[$key] = new CompoundTag($key, $value);
break;
case NBT::TAG_IntArray:
$data[$key] = new IntArrayTag($key, $value);
break;
} }
} }
@ -427,11 +405,6 @@ class NBT{
$this->read(zlib_decode($buffer)); $this->read(zlib_decode($buffer));
} }
public function readNetworkCompressed($buffer){
$this->read(zlib_decode($buffer), false, true);
}
/** /**
* @param bool $network * @param bool $network
* *
@ -463,71 +436,19 @@ class NBT{
return false; return false;
} }
public function writeNetworkCompressed($compression = ZLIB_ENCODING_GZIP, $level = 7){
if(($write = $this->write(true)) !== false){
return zlib_encode($write, $compression, $level);
}
return false;
}
public function readTag(bool $network = false){ public function readTag(bool $network = false){
if($this->feof()){ if($this->feof()){
$tagType = -1; //prevent crashes for empty tags return new EndTag();
}else{
$tagType = $this->getByte();
} }
switch($tagType){
case NBT::TAG_Byte:
$tag = new ByteTag($this->getString($network));
$tag->read($this, $network);
break;
case NBT::TAG_Short:
$tag = new ShortTag($this->getString($network));
$tag->read($this, $network);
break;
case NBT::TAG_Int:
$tag = new IntTag($this->getString($network));
$tag->read($this, $network);
break;
case NBT::TAG_Long:
$tag = new LongTag($this->getString($network));
$tag->read($this, $network);
break;
case NBT::TAG_Float:
$tag = new FloatTag($this->getString($network));
$tag->read($this, $network);
break;
case NBT::TAG_Double:
$tag = new DoubleTag($this->getString($network));
$tag->read($this, $network);
break;
case NBT::TAG_ByteArray:
$tag = new ByteArrayTag($this->getString($network));
$tag->read($this, $network);
break;
case NBT::TAG_String:
$tag = new StringTag($this->getString($network));
$tag->read($this, $network);
break;
case NBT::TAG_List:
$tag = new ListTag($this->getString($network));
$tag->read($this, $network);
break;
case NBT::TAG_Compound:
$tag = new CompoundTag($this->getString($network));
$tag->read($this, $network);
break;
case NBT::TAG_IntArray:
$tag = new IntArrayTag($this->getString($network));
$tag->read($this, $network);
break;
case NBT::TAG_End: //No named tag $tagType = $this->getByte();
default: $tag = self::createTag($tagType);
$tag = new EndTag;
break; if($tag instanceof NamedTag){
$tag->setName($this->getString($network));
$tag->read($this, $network);
} }
return $tag; return $tag;
} }

View File

@ -118,64 +118,12 @@ class ListTag extends NamedTag implements \ArrayAccess, \Countable{
$this->value = []; $this->value = [];
$this->tagType = $nbt->getByte(); $this->tagType = $nbt->getByte();
$size = $nbt->getInt($network); $size = $nbt->getInt($network);
$tagBase = NBT::createTag($this->tagType);
for($i = 0; $i < $size and !$nbt->feof(); ++$i){ for($i = 0; $i < $size and !$nbt->feof(); ++$i){
switch($this->tagType){ $tag = clone $tagBase;
case NBT::TAG_Byte: $tag->read($nbt, $network);
$tag = new ByteTag(""); $this->{$i} = $tag;
$tag->read($nbt, $network);
$this->{$i} = $tag;
break;
case NBT::TAG_Short:
$tag = new ShortTag("");
$tag->read($nbt, $network);
$this->{$i} = $tag;
break;
case NBT::TAG_Int:
$tag = new IntTag("");
$tag->read($nbt, $network);
$this->{$i} = $tag;
break;
case NBT::TAG_Long:
$tag = new LongTag("");
$tag->read($nbt, $network);
$this->{$i} = $tag;
break;
case NBT::TAG_Float:
$tag = new FloatTag("");
$tag->read($nbt, $network);
$this->{$i} = $tag;
break;
case NBT::TAG_Double:
$tag = new DoubleTag("");
$tag->read($nbt, $network);
$this->{$i} = $tag;
break;
case NBT::TAG_ByteArray:
$tag = new ByteArrayTag("");
$tag->read($nbt, $network);
$this->{$i} = $tag;
break;
case NBT::TAG_String:
$tag = new StringTag("");
$tag->read($nbt, $network);
$this->{$i} = $tag;
break;
case NBT::TAG_List:
$tag = new TagEnum("");
$tag->read($nbt, $network);
$this->{$i} = $tag;
break;
case NBT::TAG_Compound:
$tag = new CompoundTag("");
$tag->read($nbt, $network);
$this->{$i} = $tag;
break;
case NBT::TAG_IntArray:
$tag = new IntArrayTag("");
$tag->read($nbt, $network);
$this->{$i} = $tag;
break;
}
} }
} }