self::readTag($tag, $stream) ]; } /** * Reads a tag of type from the stream * @param int $type the tag number * @param resource $stream the NBT data stream * @return any the data the was read */ public static function readTag($type, $stream) { switch($type) { case self::TAG_END: return null; case self::TAG_BYTE: return unpack('c', fread($stream, 1))[1]; case self::TAG_SHORT: return unpack('s', self::bigToSys(fread($stream, 2)))[1]; case self::TAG_INT: return unpack('l', self::bigToSys(fread($stream, 4)))[1]; case self::TAG_LONG: return unpack('q', self::bigToSys(fread($stream, 8)))[1]; case self::TAG_FLOAT: return unpack('G', fread($stream, 4))[1]; case self::TAG_DOUBLE: return unpack('E', fread($stream, 8))[1]; case self::TAG_STRING: $len = self::readTag(self::TAG_SHORT, $stream); if ($len === 0) return ''; return fread($stream, $len); case self::TAG_LIST: $tag = self::readTag(self::TAG_BYTE, $stream); return self::readList($tag, $stream); case self::TAG_BYTE_ARRAY: return self::readList(self::TAG_BYTE, $stream); case self::TAG_INT_ARRAY: return self::readList(self::TAG_INT, $stream); case self::TAG_LONG_ARRAY: return self::readList(self::TAG_LONG, $stream); case self::TAG_COMPOUND: $out = []; while (true) { if (feof($stream)) break; $tag = self::readTag(self::TAG_BYTE, $stream); if ($tag == self::TAG_END) break; $name = self::readTag(self::TAG_STRING, $stream); $out[ $name ] = self::readTag($tag, $stream, $out); } return $out; } } }