A structured binary format native to Minecraft for saving game data and transferring
it over the network (in multiplayer), such as player data
(<player>.dat
; contains
e.g. player's inventory and location), saved worlds
(level.dat
and Chunk format),
list of saved multiplayer servers
(servers.dat
) and so on -
see https://minecraft.wiki/w/NBT_format#Uses.
The entire file should be gzip-compressed (in accordance with the original specification NBT.txt by Notch), but can also be compressed with zlib or uncompressed.
This spec can only handle uncompressed NBT data, so be sure to first detect
what type of data you are dealing with. You can use the Unix file
command
to do this (file-5.20
or later is required; older versions do not recognize
zlib-compressed data and return application/octet-stream
instead):
file --brief --mime-type input-unknown.nbt
If it says:
application/x-gzip
or application/gzip
(since file-5.37
), you can decompress it by
gunzip -c input-gzip.nbt > output.nbt
orpython3 -c "import sys, gzip; sys.stdout.buffer.write( gzip.decompress(sys.stdin.buffer.read()) )" < input-gzip.nbt > output.nbt
application/zlib
, you can use
openssl zlib -d -in input-zlib.nbt -out output.nbt
(does not work on most systems)python3 -c "import sys, zlib; sys.stdout.buffer.write( zlib.decompress(sys.stdin.buffer.read()) )" < input-zlib.nbt > output.nbt
image/x-pcx
and application/octet-stream
),
it is most likely already uncompressed.The file output.nbt
generated by one of the above commands can already be
processed with this Kaitai Struct specification.
This spec only implements the Java edition format. There is also a Bedrock edition NBT format, which uses little-endian encoding and has a few other differences, but it isn't as popular as the Java edition format.
Implementation note: strings in TAG_String
are incorrectly decoded with
standard UTF-8, while they are encoded in Modified UTF-8 (MUTF-8). That's because MUTF-8 is not supported natively by most target
languages, and thus one must use external libraries to achieve a fully-compliant
decoder. But decoding in standard UTF-8 is still better than nothing, and
it usually works fine.
All Unicode code points with incompatible representations in MUTF-8 and UTF-8 are U+0000 (NUL), U+D800-U+DFFF (High and Low Surrogates) and U+10000-U+10FFFF (all Supplementary Planes; includes e.g. emoticons, pictograms). A MUTF-8-encoded string containing these code points cannot be successfully decoded as UTF-8. The behavior in this case depends on the target language - usually an exception is thrown, or the bytes that are not valid UTF-8 are replaced or ignored.
Sample files:
This page hosts a formal specification of Minecraft NBT (Named Binary Tag) using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
#![allow(unused_imports)]
#![allow(non_snake_case)]
#![allow(non_camel_case_types)]
#![allow(irrefutable_let_patterns)]
#![allow(unused_comparisons)]
extern crate kaitai;
use kaitai::*;
use std::convert::{TryFrom, TryInto};
use std::cell::{Ref, Cell, RefCell};
use std::rc::{Rc, Weak};
/**
* A structured binary format native to Minecraft for saving game data and transferring
* it over the network (in multiplayer), such as player data
* ([`<player>.dat`](https://minecraft.wiki/w/Player.dat_format); contains
* e.g. player's inventory and location), saved worlds
* ([`level.dat`](
* https://minecraft.wiki/w/Java_Edition_level_format#level.dat_format
* ) and [Chunk format](https://minecraft.wiki/w/Chunk_format#NBT_structure)),
* list of saved multiplayer servers
* ([`servers.dat`](https://minecraft.wiki/w/Servers.dat_format)) and so on -
* see <https://minecraft.wiki/w/NBT_format#Uses>.
*
* The entire file should be _gzip_-compressed (in accordance with the original
* specification [NBT.txt](
* https://web.archive.org/web/20110723210920/https://www.minecraft.net/docs/NBT.txt
* ) by Notch), but can also be compressed with _zlib_ or uncompressed.
*
* This spec can only handle uncompressed NBT data, so be sure to first detect
* what type of data you are dealing with. You can use the Unix `file` command
* to do this (`file-5.20` or later is required; older versions do not recognize
* _zlib_-compressed data and return `application/octet-stream` instead):
*
* ```shell
* file --brief --mime-type input-unknown.nbt
* ```
*
* If it says:
*
* * `application/x-gzip` or `application/gzip` (since `file-5.37`), you can decompress it by
* * `gunzip -c input-gzip.nbt > output.nbt` or
* * `python3 -c "import sys, gzip; sys.stdout.buffer.write(
* gzip.decompress(sys.stdin.buffer.read()) )" < input-gzip.nbt > output.nbt`
* * `application/zlib`, you can use
* * `openssl zlib -d -in input-zlib.nbt -out output.nbt` (does not work on most systems)
* * `python3 -c "import sys, zlib; sys.stdout.buffer.write(
* zlib.decompress(sys.stdin.buffer.read()) )" < input-zlib.nbt > output.nbt`
* * something else (especially `image/x-pcx` and `application/octet-stream`),
* it is most likely already uncompressed.
*
* The file `output.nbt` generated by one of the above commands can already be
* processed with this Kaitai Struct specification.
*
* This spec **only** implements the Java edition format. There is also
* a [Bedrock edition](https://wiki.vg/NBT#Bedrock_edition) NBT format,
* which uses little-endian encoding and has a few other differences, but it isn't
* as popular as the Java edition format.
*
* **Implementation note:** strings in `TAG_String` are incorrectly decoded with
* standard UTF-8, while they are encoded in [**Modified UTF-8**](
* https://docs.oracle.com/javase/8/docs/api/java/io/DataInput.html#modified-utf-8
* ) (MUTF-8). That's because MUTF-8 is not supported natively by most target
* languages, and thus one must use external libraries to achieve a fully-compliant
* decoder. But decoding in standard UTF-8 is still better than nothing, and
* it usually works fine.
*
* All Unicode code points with incompatible representations in MUTF-8 and UTF-8 are
* U+0000 (_NUL_), U+D800-U+DFFF (_High_ and _Low Surrogates_) and U+10000-U+10FFFF
* (all _Supplementary_ Planes; includes e.g. emoticons, pictograms).
* A _MUTF-8_-encoded string containing these code points cannot be successfully
* decoded as UTF-8. The behavior in this case depends on the target language -
* usually an exception is thrown, or the bytes that are not valid UTF-8
* are replaced or ignored.
*
* **Sample files:**
*
* * <https://wiki.vg/NBT#Download>
* * <https://github.com/twoolie/NBT/blob/f9e892e/tests/world_test/data/scoreboard.dat>
* * <https://github.com/chmod222/cNBT/tree/3f74b69/testdata>
* * <https://github.com/PistonDevelopers/hematite_nbt/tree/0b85f89/tests>
* \sa https://wiki.vg/NBT Source
* \sa https://web.archive.org/web/20110723210920/https://www.minecraft.net/docs/NBT.txt Source
* \sa https://minecraft.wiki/w/NBT_format Source
*/
#[derive(Default, Debug, Clone)]
pub struct MinecraftNbt {
pub _root: SharedType<MinecraftNbt>,
pub _parent: SharedType<MinecraftNbt>,
pub _self: SharedType<Self>,
root_check: RefCell<Vec<u8>>,
root: RefCell<OptRc<MinecraftNbt_NamedTag>>,
_io: RefCell<BytesReader>,
f_root_type: Cell<bool>,
root_type: RefCell<MinecraftNbt_Tag>,
}
impl KStruct for MinecraftNbt {
type Root = MinecraftNbt;
type Parent = MinecraftNbt;
fn read<S: KStream>(
self_rc: &OptRc<Self>,
_io: &S,
_root: SharedType<Self::Root>,
_parent: SharedType<Self::Parent>,
) -> KResult<()> {
*self_rc._io.borrow_mut() = _io.clone();
self_rc._root.set(_root.get());
self_rc._parent.set(_parent.get());
self_rc._self.set(Ok(self_rc.clone()));
let _rrc = self_rc._root.get_value().borrow().upgrade();
let _prc = self_rc._parent.get_value().borrow().upgrade();
let _r = _rrc.as_ref().unwrap();
if ((*self_rc.root_type()? == MinecraftNbt_Tag::End) && (false)) {
*self_rc.root_check.borrow_mut() = _io.read_bytes(0 as usize)?.into();
}
let t = Self::read_into::<_, MinecraftNbt_NamedTag>(&*_io, Some(self_rc._root.clone()), None)?.into();
*self_rc.root.borrow_mut() = t;
Ok(())
}
}
impl MinecraftNbt {
pub fn root_type(
&self
) -> KResult<Ref<'_, MinecraftNbt_Tag>> {
let _io = self._io.borrow();
let _rrc = self._root.get_value().borrow().upgrade();
let _prc = self._parent.get_value().borrow().upgrade();
let _r = _rrc.as_ref().unwrap();
if self.f_root_type.get() {
return Ok(self.root_type.borrow());
}
self.f_root_type.set(true);
let _pos = _io.pos();
_io.seek(0 as usize)?;
*self.root_type.borrow_mut() = (_io.read_u1()? as i64).try_into()?;
if !(*self.root_type()? == MinecraftNbt_Tag::Compound) {
return Err(KError::ValidationFailed(ValidationFailedError { kind: ValidationKind::NotEqual, src_path: "/instances/root_type".to_string() }));
}
_io.seek(_pos)?;
Ok(self.root_type.borrow())
}
}
impl MinecraftNbt {
pub fn root_check(&self) -> Ref<'_, Vec<u8>> {
self.root_check.borrow()
}
}
impl MinecraftNbt {
pub fn root(&self) -> Ref<'_, OptRc<MinecraftNbt_NamedTag>> {
self.root.borrow()
}
}
impl MinecraftNbt {
pub fn _io(&self) -> Ref<'_, BytesReader> {
self._io.borrow()
}
}
#[derive(Debug, PartialEq, Clone)]
pub enum MinecraftNbt_Tag {
/**
* As of KSC 0.9, this enum key causes a syntax error in Lua. See
* <https://github.com/kaitai-io/kaitai_struct/issues/90#issuecomment-766440975>
* for more info.
*/
End,
Byte,
Short,
Int,
Long,
Float,
Double,
ByteArray,
String,
List,
Compound,
IntArray,
LongArray,
Unknown(i64),
}
impl TryFrom<i64> for MinecraftNbt_Tag {
type Error = KError;
fn try_from(flag: i64) -> KResult<MinecraftNbt_Tag> {
match flag {
0 => Ok(MinecraftNbt_Tag::End),
1 => Ok(MinecraftNbt_Tag::Byte),
2 => Ok(MinecraftNbt_Tag::Short),
3 => Ok(MinecraftNbt_Tag::Int),
4 => Ok(MinecraftNbt_Tag::Long),
5 => Ok(MinecraftNbt_Tag::Float),
6 => Ok(MinecraftNbt_Tag::Double),
7 => Ok(MinecraftNbt_Tag::ByteArray),
8 => Ok(MinecraftNbt_Tag::String),
9 => Ok(MinecraftNbt_Tag::List),
10 => Ok(MinecraftNbt_Tag::Compound),
11 => Ok(MinecraftNbt_Tag::IntArray),
12 => Ok(MinecraftNbt_Tag::LongArray),
_ => Ok(MinecraftNbt_Tag::Unknown(flag)),
}
}
}
impl From<&MinecraftNbt_Tag> for i64 {
fn from(v: &MinecraftNbt_Tag) -> Self {
match *v {
MinecraftNbt_Tag::End => 0,
MinecraftNbt_Tag::Byte => 1,
MinecraftNbt_Tag::Short => 2,
MinecraftNbt_Tag::Int => 3,
MinecraftNbt_Tag::Long => 4,
MinecraftNbt_Tag::Float => 5,
MinecraftNbt_Tag::Double => 6,
MinecraftNbt_Tag::ByteArray => 7,
MinecraftNbt_Tag::String => 8,
MinecraftNbt_Tag::List => 9,
MinecraftNbt_Tag::Compound => 10,
MinecraftNbt_Tag::IntArray => 11,
MinecraftNbt_Tag::LongArray => 12,
MinecraftNbt_Tag::Unknown(v) => v
}
}
}
impl Default for MinecraftNbt_Tag {
fn default() -> Self { MinecraftNbt_Tag::Unknown(0) }
}
#[derive(Default, Debug, Clone)]
pub struct MinecraftNbt_NamedTag {
pub _root: SharedType<MinecraftNbt>,
pub _parent: SharedType<KStructUnit>,
pub _self: SharedType<Self>,
type: RefCell<MinecraftNbt_Tag>,
name: RefCell<OptRc<MinecraftNbt_TagString>>,
payload: RefCell<Option<MinecraftNbt_NamedTag_Payload>>,
_io: RefCell<BytesReader>,
f_is_tag_end: Cell<bool>,
is_tag_end: RefCell<bool>,
}
#[derive(Debug, Clone)]
pub enum MinecraftNbt_NamedTag_Payload {
S8(i64),
MinecraftNbt_TagByteArray(OptRc<MinecraftNbt_TagByteArray>),
MinecraftNbt_TagList(OptRc<MinecraftNbt_TagList>),
F8(f64),
S4(i32),
F4(f32),
S2(i16),
MinecraftNbt_TagLongArray(OptRc<MinecraftNbt_TagLongArray>),
S1(i8),
MinecraftNbt_TagCompound(OptRc<MinecraftNbt_TagCompound>),
MinecraftNbt_TagIntArray(OptRc<MinecraftNbt_TagIntArray>),
MinecraftNbt_TagString(OptRc<MinecraftNbt_TagString>),
}
impl From<&MinecraftNbt_NamedTag_Payload> for i64 {
fn from(v: &MinecraftNbt_NamedTag_Payload) -> Self {
if let MinecraftNbt_NamedTag_Payload::S8(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_NamedTag_Payload::S8, got {:?}", v)
}
}
impl From<i64> for MinecraftNbt_NamedTag_Payload {
fn from(v: i64) -> Self {
Self::S8(v)
}
}
impl From<&MinecraftNbt_NamedTag_Payload> for OptRc<MinecraftNbt_TagByteArray> {
fn from(v: &MinecraftNbt_NamedTag_Payload) -> Self {
if let MinecraftNbt_NamedTag_Payload::MinecraftNbt_TagByteArray(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_NamedTag_Payload::MinecraftNbt_TagByteArray, got {:?}", v)
}
}
impl From<OptRc<MinecraftNbt_TagByteArray>> for MinecraftNbt_NamedTag_Payload {
fn from(v: OptRc<MinecraftNbt_TagByteArray>) -> Self {
Self::MinecraftNbt_TagByteArray(v)
}
}
impl From<&MinecraftNbt_NamedTag_Payload> for OptRc<MinecraftNbt_TagList> {
fn from(v: &MinecraftNbt_NamedTag_Payload) -> Self {
if let MinecraftNbt_NamedTag_Payload::MinecraftNbt_TagList(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_NamedTag_Payload::MinecraftNbt_TagList, got {:?}", v)
}
}
impl From<OptRc<MinecraftNbt_TagList>> for MinecraftNbt_NamedTag_Payload {
fn from(v: OptRc<MinecraftNbt_TagList>) -> Self {
Self::MinecraftNbt_TagList(v)
}
}
impl From<&MinecraftNbt_NamedTag_Payload> for f64 {
fn from(v: &MinecraftNbt_NamedTag_Payload) -> Self {
if let MinecraftNbt_NamedTag_Payload::F8(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_NamedTag_Payload::F8, got {:?}", v)
}
}
impl From<f64> for MinecraftNbt_NamedTag_Payload {
fn from(v: f64) -> Self {
Self::F8(v)
}
}
impl From<&MinecraftNbt_NamedTag_Payload> for i32 {
fn from(v: &MinecraftNbt_NamedTag_Payload) -> Self {
if let MinecraftNbt_NamedTag_Payload::S4(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_NamedTag_Payload::S4, got {:?}", v)
}
}
impl From<i32> for MinecraftNbt_NamedTag_Payload {
fn from(v: i32) -> Self {
Self::S4(v)
}
}
impl From<&MinecraftNbt_NamedTag_Payload> for f32 {
fn from(v: &MinecraftNbt_NamedTag_Payload) -> Self {
if let MinecraftNbt_NamedTag_Payload::F4(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_NamedTag_Payload::F4, got {:?}", v)
}
}
impl From<f32> for MinecraftNbt_NamedTag_Payload {
fn from(v: f32) -> Self {
Self::F4(v)
}
}
impl From<&MinecraftNbt_NamedTag_Payload> for i16 {
fn from(v: &MinecraftNbt_NamedTag_Payload) -> Self {
if let MinecraftNbt_NamedTag_Payload::S2(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_NamedTag_Payload::S2, got {:?}", v)
}
}
impl From<i16> for MinecraftNbt_NamedTag_Payload {
fn from(v: i16) -> Self {
Self::S2(v)
}
}
impl From<&MinecraftNbt_NamedTag_Payload> for OptRc<MinecraftNbt_TagLongArray> {
fn from(v: &MinecraftNbt_NamedTag_Payload) -> Self {
if let MinecraftNbt_NamedTag_Payload::MinecraftNbt_TagLongArray(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_NamedTag_Payload::MinecraftNbt_TagLongArray, got {:?}", v)
}
}
impl From<OptRc<MinecraftNbt_TagLongArray>> for MinecraftNbt_NamedTag_Payload {
fn from(v: OptRc<MinecraftNbt_TagLongArray>) -> Self {
Self::MinecraftNbt_TagLongArray(v)
}
}
impl From<&MinecraftNbt_NamedTag_Payload> for i8 {
fn from(v: &MinecraftNbt_NamedTag_Payload) -> Self {
if let MinecraftNbt_NamedTag_Payload::S1(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_NamedTag_Payload::S1, got {:?}", v)
}
}
impl From<i8> for MinecraftNbt_NamedTag_Payload {
fn from(v: i8) -> Self {
Self::S1(v)
}
}
impl From<&MinecraftNbt_NamedTag_Payload> for OptRc<MinecraftNbt_TagCompound> {
fn from(v: &MinecraftNbt_NamedTag_Payload) -> Self {
if let MinecraftNbt_NamedTag_Payload::MinecraftNbt_TagCompound(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_NamedTag_Payload::MinecraftNbt_TagCompound, got {:?}", v)
}
}
impl From<OptRc<MinecraftNbt_TagCompound>> for MinecraftNbt_NamedTag_Payload {
fn from(v: OptRc<MinecraftNbt_TagCompound>) -> Self {
Self::MinecraftNbt_TagCompound(v)
}
}
impl From<&MinecraftNbt_NamedTag_Payload> for OptRc<MinecraftNbt_TagIntArray> {
fn from(v: &MinecraftNbt_NamedTag_Payload) -> Self {
if let MinecraftNbt_NamedTag_Payload::MinecraftNbt_TagIntArray(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_NamedTag_Payload::MinecraftNbt_TagIntArray, got {:?}", v)
}
}
impl From<OptRc<MinecraftNbt_TagIntArray>> for MinecraftNbt_NamedTag_Payload {
fn from(v: OptRc<MinecraftNbt_TagIntArray>) -> Self {
Self::MinecraftNbt_TagIntArray(v)
}
}
impl From<&MinecraftNbt_NamedTag_Payload> for OptRc<MinecraftNbt_TagString> {
fn from(v: &MinecraftNbt_NamedTag_Payload) -> Self {
if let MinecraftNbt_NamedTag_Payload::MinecraftNbt_TagString(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_NamedTag_Payload::MinecraftNbt_TagString, got {:?}", v)
}
}
impl From<OptRc<MinecraftNbt_TagString>> for MinecraftNbt_NamedTag_Payload {
fn from(v: OptRc<MinecraftNbt_TagString>) -> Self {
Self::MinecraftNbt_TagString(v)
}
}
impl KStruct for MinecraftNbt_NamedTag {
type Root = MinecraftNbt;
type Parent = KStructUnit;
fn read<S: KStream>(
self_rc: &OptRc<Self>,
_io: &S,
_root: SharedType<Self::Root>,
_parent: SharedType<Self::Parent>,
) -> KResult<()> {
*self_rc._io.borrow_mut() = _io.clone();
self_rc._root.set(_root.get());
self_rc._parent.set(_parent.get());
self_rc._self.set(Ok(self_rc.clone()));
let _rrc = self_rc._root.get_value().borrow().upgrade();
let _prc = self_rc._parent.get_value().borrow().upgrade();
let _r = _rrc.as_ref().unwrap();
*self_rc.type.borrow_mut() = (_io.read_u1()? as i64).try_into()?;
if !(*self_rc.is_tag_end()?) {
let t = Self::read_into::<_, MinecraftNbt_TagString>(&*_io, Some(self_rc._root.clone()), None)?.into();
*self_rc.name.borrow_mut() = t;
}
if !(*self_rc.is_tag_end()?) {
match *self_rc.type() {
MinecraftNbt_Tag::Byte => {
*self_rc.payload.borrow_mut() = Some(_io.read_s1()?.into());
}
MinecraftNbt_Tag::ByteArray => {
let t = Self::read_into::<_, MinecraftNbt_TagByteArray>(&*_io, Some(self_rc._root.clone()), None)?.into();
*self_rc.payload.borrow_mut() = Some(t);
}
MinecraftNbt_Tag::Compound => {
let t = Self::read_into::<_, MinecraftNbt_TagCompound>(&*_io, Some(self_rc._root.clone()), None)?.into();
*self_rc.payload.borrow_mut() = Some(t);
}
MinecraftNbt_Tag::Double => {
*self_rc.payload.borrow_mut() = Some(_io.read_f8be()?.into());
}
MinecraftNbt_Tag::Float => {
*self_rc.payload.borrow_mut() = Some(_io.read_f4be()?.into());
}
MinecraftNbt_Tag::Int => {
*self_rc.payload.borrow_mut() = Some(_io.read_s4be()?.into());
}
MinecraftNbt_Tag::IntArray => {
let t = Self::read_into::<_, MinecraftNbt_TagIntArray>(&*_io, Some(self_rc._root.clone()), None)?.into();
*self_rc.payload.borrow_mut() = Some(t);
}
MinecraftNbt_Tag::List => {
let t = Self::read_into::<_, MinecraftNbt_TagList>(&*_io, Some(self_rc._root.clone()), None)?.into();
*self_rc.payload.borrow_mut() = Some(t);
}
MinecraftNbt_Tag::Long => {
*self_rc.payload.borrow_mut() = Some(_io.read_s8be()?.into());
}
MinecraftNbt_Tag::LongArray => {
let t = Self::read_into::<_, MinecraftNbt_TagLongArray>(&*_io, Some(self_rc._root.clone()), None)?.into();
*self_rc.payload.borrow_mut() = Some(t);
}
MinecraftNbt_Tag::Short => {
*self_rc.payload.borrow_mut() = Some(_io.read_s2be()?.into());
}
MinecraftNbt_Tag::String => {
let t = Self::read_into::<_, MinecraftNbt_TagString>(&*_io, Some(self_rc._root.clone()), None)?.into();
*self_rc.payload.borrow_mut() = Some(t);
}
_ => {}
}
}
Ok(())
}
}
impl MinecraftNbt_NamedTag {
pub fn is_tag_end(
&self
) -> KResult<Ref<'_, bool>> {
let _io = self._io.borrow();
let _rrc = self._root.get_value().borrow().upgrade();
let _prc = self._parent.get_value().borrow().upgrade();
let _r = _rrc.as_ref().unwrap();
if self.f_is_tag_end.get() {
return Ok(self.is_tag_end.borrow());
}
self.f_is_tag_end.set(true);
*self.is_tag_end.borrow_mut() = (*self.type() == MinecraftNbt_Tag::End) as bool;
Ok(self.is_tag_end.borrow())
}
}
impl MinecraftNbt_NamedTag {
pub fn type(&self) -> Ref<'_, MinecraftNbt_Tag> {
self.type.borrow()
}
}
impl MinecraftNbt_NamedTag {
pub fn name(&self) -> Ref<'_, OptRc<MinecraftNbt_TagString>> {
self.name.borrow()
}
}
impl MinecraftNbt_NamedTag {
pub fn payload(&self) -> Ref<'_, Option<MinecraftNbt_NamedTag_Payload>> {
self.payload.borrow()
}
}
impl MinecraftNbt_NamedTag {
pub fn _io(&self) -> Ref<'_, BytesReader> {
self._io.borrow()
}
}
#[derive(Default, Debug, Clone)]
pub struct MinecraftNbt_TagByteArray {
pub _root: SharedType<MinecraftNbt>,
pub _parent: SharedType<KStructUnit>,
pub _self: SharedType<Self>,
len_data: RefCell<i32>,
data: RefCell<Vec<u8>>,
_io: RefCell<BytesReader>,
}
impl KStruct for MinecraftNbt_TagByteArray {
type Root = MinecraftNbt;
type Parent = KStructUnit;
fn read<S: KStream>(
self_rc: &OptRc<Self>,
_io: &S,
_root: SharedType<Self::Root>,
_parent: SharedType<Self::Parent>,
) -> KResult<()> {
*self_rc._io.borrow_mut() = _io.clone();
self_rc._root.set(_root.get());
self_rc._parent.set(_parent.get());
self_rc._self.set(Ok(self_rc.clone()));
let _rrc = self_rc._root.get_value().borrow().upgrade();
let _prc = self_rc._parent.get_value().borrow().upgrade();
let _r = _rrc.as_ref().unwrap();
*self_rc.len_data.borrow_mut() = _io.read_s4be()?.into();
*self_rc.data.borrow_mut() = _io.read_bytes(*self_rc.len_data() as usize)?.into();
Ok(())
}
}
impl MinecraftNbt_TagByteArray {
}
impl MinecraftNbt_TagByteArray {
pub fn len_data(&self) -> Ref<'_, i32> {
self.len_data.borrow()
}
}
impl MinecraftNbt_TagByteArray {
pub fn data(&self) -> Ref<'_, Vec<u8>> {
self.data.borrow()
}
}
impl MinecraftNbt_TagByteArray {
pub fn _io(&self) -> Ref<'_, BytesReader> {
self._io.borrow()
}
}
#[derive(Default, Debug, Clone)]
pub struct MinecraftNbt_TagCompound {
pub _root: SharedType<MinecraftNbt>,
pub _parent: SharedType<KStructUnit>,
pub _self: SharedType<Self>,
tags: RefCell<Vec<OptRc<MinecraftNbt_NamedTag>>>,
_io: RefCell<BytesReader>,
f_dump_num_tags: Cell<bool>,
dump_num_tags: RefCell<i32>,
}
impl KStruct for MinecraftNbt_TagCompound {
type Root = MinecraftNbt;
type Parent = KStructUnit;
fn read<S: KStream>(
self_rc: &OptRc<Self>,
_io: &S,
_root: SharedType<Self::Root>,
_parent: SharedType<Self::Parent>,
) -> KResult<()> {
*self_rc._io.borrow_mut() = _io.clone();
self_rc._root.set(_root.get());
self_rc._parent.set(_parent.get());
self_rc._self.set(Ok(self_rc.clone()));
let _rrc = self_rc._root.get_value().borrow().upgrade();
let _prc = self_rc._parent.get_value().borrow().upgrade();
let _r = _rrc.as_ref().unwrap();
*self_rc.tags.borrow_mut() = Vec::new();
{
let mut _i = 0;
while {
let t = Self::read_into::<_, MinecraftNbt_NamedTag>(&*_io, Some(self_rc._root.clone()), None)?.into();
self_rc.tags.borrow_mut().push(t);
let _t_tags = self_rc.tags.borrow();
let _tmpa = _t_tags.last().unwrap();
_i += 1;
let x = !(*_tmpa.is_tag_end()?);
x
} {}
}
Ok(())
}
}
impl MinecraftNbt_TagCompound {
pub fn dump_num_tags(
&self
) -> KResult<Ref<'_, i32>> {
let _io = self._io.borrow();
let _rrc = self._root.get_value().borrow().upgrade();
let _prc = self._parent.get_value().borrow().upgrade();
let _r = _rrc.as_ref().unwrap();
if self.f_dump_num_tags.get() {
return Ok(self.dump_num_tags.borrow());
}
self.f_dump_num_tags.set(true);
*self.dump_num_tags.borrow_mut() = (((self.tags().len() as i32) - (if ((((self.tags().len() as i32) >= (1 as i32))) && (*self.tags().last().ok_or(KError::EmptyIterator)?.is_tag_end()?)) { 1 } else { 0 } as i32))) as i32;
Ok(self.dump_num_tags.borrow())
}
}
impl MinecraftNbt_TagCompound {
pub fn tags(&self) -> Ref<'_, Vec<OptRc<MinecraftNbt_NamedTag>>> {
self.tags.borrow()
}
}
impl MinecraftNbt_TagCompound {
pub fn _io(&self) -> Ref<'_, BytesReader> {
self._io.borrow()
}
}
#[derive(Default, Debug, Clone)]
pub struct MinecraftNbt_TagIntArray {
pub _root: SharedType<MinecraftNbt>,
pub _parent: SharedType<KStructUnit>,
pub _self: SharedType<Self>,
num_tags: RefCell<i32>,
tags: RefCell<Vec<i32>>,
_io: RefCell<BytesReader>,
f_tags_type: Cell<bool>,
tags_type: RefCell<MinecraftNbt_Tag>,
}
impl KStruct for MinecraftNbt_TagIntArray {
type Root = MinecraftNbt;
type Parent = KStructUnit;
fn read<S: KStream>(
self_rc: &OptRc<Self>,
_io: &S,
_root: SharedType<Self::Root>,
_parent: SharedType<Self::Parent>,
) -> KResult<()> {
*self_rc._io.borrow_mut() = _io.clone();
self_rc._root.set(_root.get());
self_rc._parent.set(_parent.get());
self_rc._self.set(Ok(self_rc.clone()));
let _rrc = self_rc._root.get_value().borrow().upgrade();
let _prc = self_rc._parent.get_value().borrow().upgrade();
let _r = _rrc.as_ref().unwrap();
*self_rc.num_tags.borrow_mut() = _io.read_s4be()?.into();
*self_rc.tags.borrow_mut() = Vec::new();
let l_tags = *self_rc.num_tags();
for _i in 0..l_tags {
self_rc.tags.borrow_mut().push(_io.read_s4be()?.into());
}
Ok(())
}
}
impl MinecraftNbt_TagIntArray {
pub fn tags_type(
&self
) -> KResult<Ref<'_, MinecraftNbt_Tag>> {
let _io = self._io.borrow();
let _rrc = self._root.get_value().borrow().upgrade();
let _prc = self._parent.get_value().borrow().upgrade();
let _r = _rrc.as_ref().unwrap();
if self.f_tags_type.get() {
return Ok(self.tags_type.borrow());
}
self.f_tags_type.set(true);
*self.tags_type.borrow_mut() = MinecraftNbt_Tag::Int;
Ok(self.tags_type.borrow())
}
}
impl MinecraftNbt_TagIntArray {
pub fn num_tags(&self) -> Ref<'_, i32> {
self.num_tags.borrow()
}
}
impl MinecraftNbt_TagIntArray {
pub fn tags(&self) -> Ref<'_, Vec<i32>> {
self.tags.borrow()
}
}
impl MinecraftNbt_TagIntArray {
pub fn _io(&self) -> Ref<'_, BytesReader> {
self._io.borrow()
}
}
#[derive(Default, Debug, Clone)]
pub struct MinecraftNbt_TagList {
pub _root: SharedType<MinecraftNbt>,
pub _parent: SharedType<KStructUnit>,
pub _self: SharedType<Self>,
tags_type: RefCell<MinecraftNbt_Tag>,
num_tags: RefCell<i32>,
tags: RefCell<Vec<MinecraftNbt_TagList_Tags>>,
_io: RefCell<BytesReader>,
}
#[derive(Debug, Clone)]
pub enum MinecraftNbt_TagList_Tags {
S8(i64),
MinecraftNbt_TagByteArray(OptRc<MinecraftNbt_TagByteArray>),
MinecraftNbt_TagList(OptRc<MinecraftNbt_TagList>),
F8(f64),
S4(i32),
F4(f32),
S2(i16),
MinecraftNbt_TagLongArray(OptRc<MinecraftNbt_TagLongArray>),
S1(i8),
MinecraftNbt_TagCompound(OptRc<MinecraftNbt_TagCompound>),
MinecraftNbt_TagIntArray(OptRc<MinecraftNbt_TagIntArray>),
MinecraftNbt_TagString(OptRc<MinecraftNbt_TagString>),
}
impl From<&MinecraftNbt_TagList_Tags> for i64 {
fn from(v: &MinecraftNbt_TagList_Tags) -> Self {
if let MinecraftNbt_TagList_Tags::S8(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_TagList_Tags::S8, got {:?}", v)
}
}
impl From<i64> for MinecraftNbt_TagList_Tags {
fn from(v: i64) -> Self {
Self::S8(v)
}
}
impl From<&MinecraftNbt_TagList_Tags> for OptRc<MinecraftNbt_TagByteArray> {
fn from(v: &MinecraftNbt_TagList_Tags) -> Self {
if let MinecraftNbt_TagList_Tags::MinecraftNbt_TagByteArray(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_TagList_Tags::MinecraftNbt_TagByteArray, got {:?}", v)
}
}
impl From<OptRc<MinecraftNbt_TagByteArray>> for MinecraftNbt_TagList_Tags {
fn from(v: OptRc<MinecraftNbt_TagByteArray>) -> Self {
Self::MinecraftNbt_TagByteArray(v)
}
}
impl From<&MinecraftNbt_TagList_Tags> for OptRc<MinecraftNbt_TagList> {
fn from(v: &MinecraftNbt_TagList_Tags) -> Self {
if let MinecraftNbt_TagList_Tags::MinecraftNbt_TagList(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_TagList_Tags::MinecraftNbt_TagList, got {:?}", v)
}
}
impl From<OptRc<MinecraftNbt_TagList>> for MinecraftNbt_TagList_Tags {
fn from(v: OptRc<MinecraftNbt_TagList>) -> Self {
Self::MinecraftNbt_TagList(v)
}
}
impl From<&MinecraftNbt_TagList_Tags> for f64 {
fn from(v: &MinecraftNbt_TagList_Tags) -> Self {
if let MinecraftNbt_TagList_Tags::F8(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_TagList_Tags::F8, got {:?}", v)
}
}
impl From<f64> for MinecraftNbt_TagList_Tags {
fn from(v: f64) -> Self {
Self::F8(v)
}
}
impl From<&MinecraftNbt_TagList_Tags> for i32 {
fn from(v: &MinecraftNbt_TagList_Tags) -> Self {
if let MinecraftNbt_TagList_Tags::S4(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_TagList_Tags::S4, got {:?}", v)
}
}
impl From<i32> for MinecraftNbt_TagList_Tags {
fn from(v: i32) -> Self {
Self::S4(v)
}
}
impl From<&MinecraftNbt_TagList_Tags> for f32 {
fn from(v: &MinecraftNbt_TagList_Tags) -> Self {
if let MinecraftNbt_TagList_Tags::F4(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_TagList_Tags::F4, got {:?}", v)
}
}
impl From<f32> for MinecraftNbt_TagList_Tags {
fn from(v: f32) -> Self {
Self::F4(v)
}
}
impl From<&MinecraftNbt_TagList_Tags> for i16 {
fn from(v: &MinecraftNbt_TagList_Tags) -> Self {
if let MinecraftNbt_TagList_Tags::S2(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_TagList_Tags::S2, got {:?}", v)
}
}
impl From<i16> for MinecraftNbt_TagList_Tags {
fn from(v: i16) -> Self {
Self::S2(v)
}
}
impl From<&MinecraftNbt_TagList_Tags> for OptRc<MinecraftNbt_TagLongArray> {
fn from(v: &MinecraftNbt_TagList_Tags) -> Self {
if let MinecraftNbt_TagList_Tags::MinecraftNbt_TagLongArray(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_TagList_Tags::MinecraftNbt_TagLongArray, got {:?}", v)
}
}
impl From<OptRc<MinecraftNbt_TagLongArray>> for MinecraftNbt_TagList_Tags {
fn from(v: OptRc<MinecraftNbt_TagLongArray>) -> Self {
Self::MinecraftNbt_TagLongArray(v)
}
}
impl From<&MinecraftNbt_TagList_Tags> for i8 {
fn from(v: &MinecraftNbt_TagList_Tags) -> Self {
if let MinecraftNbt_TagList_Tags::S1(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_TagList_Tags::S1, got {:?}", v)
}
}
impl From<i8> for MinecraftNbt_TagList_Tags {
fn from(v: i8) -> Self {
Self::S1(v)
}
}
impl From<&MinecraftNbt_TagList_Tags> for OptRc<MinecraftNbt_TagCompound> {
fn from(v: &MinecraftNbt_TagList_Tags) -> Self {
if let MinecraftNbt_TagList_Tags::MinecraftNbt_TagCompound(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_TagList_Tags::MinecraftNbt_TagCompound, got {:?}", v)
}
}
impl From<OptRc<MinecraftNbt_TagCompound>> for MinecraftNbt_TagList_Tags {
fn from(v: OptRc<MinecraftNbt_TagCompound>) -> Self {
Self::MinecraftNbt_TagCompound(v)
}
}
impl From<&MinecraftNbt_TagList_Tags> for OptRc<MinecraftNbt_TagIntArray> {
fn from(v: &MinecraftNbt_TagList_Tags) -> Self {
if let MinecraftNbt_TagList_Tags::MinecraftNbt_TagIntArray(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_TagList_Tags::MinecraftNbt_TagIntArray, got {:?}", v)
}
}
impl From<OptRc<MinecraftNbt_TagIntArray>> for MinecraftNbt_TagList_Tags {
fn from(v: OptRc<MinecraftNbt_TagIntArray>) -> Self {
Self::MinecraftNbt_TagIntArray(v)
}
}
impl From<&MinecraftNbt_TagList_Tags> for OptRc<MinecraftNbt_TagString> {
fn from(v: &MinecraftNbt_TagList_Tags) -> Self {
if let MinecraftNbt_TagList_Tags::MinecraftNbt_TagString(x) = v {
return x.clone();
}
panic!("expected MinecraftNbt_TagList_Tags::MinecraftNbt_TagString, got {:?}", v)
}
}
impl From<OptRc<MinecraftNbt_TagString>> for MinecraftNbt_TagList_Tags {
fn from(v: OptRc<MinecraftNbt_TagString>) -> Self {
Self::MinecraftNbt_TagString(v)
}
}
impl KStruct for MinecraftNbt_TagList {
type Root = MinecraftNbt;
type Parent = KStructUnit;
fn read<S: KStream>(
self_rc: &OptRc<Self>,
_io: &S,
_root: SharedType<Self::Root>,
_parent: SharedType<Self::Parent>,
) -> KResult<()> {
*self_rc._io.borrow_mut() = _io.clone();
self_rc._root.set(_root.get());
self_rc._parent.set(_parent.get());
self_rc._self.set(Ok(self_rc.clone()));
let _rrc = self_rc._root.get_value().borrow().upgrade();
let _prc = self_rc._parent.get_value().borrow().upgrade();
let _r = _rrc.as_ref().unwrap();
*self_rc.tags_type.borrow_mut() = (_io.read_u1()? as i64).try_into()?;
*self_rc.num_tags.borrow_mut() = _io.read_s4be()?.into();
*self_rc.tags.borrow_mut() = Vec::new();
let l_tags = *self_rc.num_tags();
for _i in 0..l_tags {
match *self_rc.tags_type() {
MinecraftNbt_Tag::Byte => {
self_rc.tags.borrow_mut().push(_io.read_s1()?.into());
}
MinecraftNbt_Tag::ByteArray => {
let t = Self::read_into::<_, MinecraftNbt_TagByteArray>(&*_io, Some(self_rc._root.clone()), None)?.into();
self_rc.tags.borrow_mut().push(t);
}
MinecraftNbt_Tag::Compound => {
let t = Self::read_into::<_, MinecraftNbt_TagCompound>(&*_io, Some(self_rc._root.clone()), None)?.into();
self_rc.tags.borrow_mut().push(t);
}
MinecraftNbt_Tag::Double => {
self_rc.tags.borrow_mut().push(_io.read_f8be()?.into());
}
MinecraftNbt_Tag::Float => {
self_rc.tags.borrow_mut().push(_io.read_f4be()?.into());
}
MinecraftNbt_Tag::Int => {
self_rc.tags.borrow_mut().push(_io.read_s4be()?.into());
}
MinecraftNbt_Tag::IntArray => {
let t = Self::read_into::<_, MinecraftNbt_TagIntArray>(&*_io, Some(self_rc._root.clone()), None)?.into();
self_rc.tags.borrow_mut().push(t);
}
MinecraftNbt_Tag::List => {
let t = Self::read_into::<_, MinecraftNbt_TagList>(&*_io, Some(self_rc._root.clone()), None)?.into();
self_rc.tags.borrow_mut().push(t);
}
MinecraftNbt_Tag::Long => {
self_rc.tags.borrow_mut().push(_io.read_s8be()?.into());
}
MinecraftNbt_Tag::LongArray => {
let t = Self::read_into::<_, MinecraftNbt_TagLongArray>(&*_io, Some(self_rc._root.clone()), None)?.into();
self_rc.tags.borrow_mut().push(t);
}
MinecraftNbt_Tag::Short => {
self_rc.tags.borrow_mut().push(_io.read_s2be()?.into());
}
MinecraftNbt_Tag::String => {
let t = Self::read_into::<_, MinecraftNbt_TagString>(&*_io, Some(self_rc._root.clone()), None)?.into();
self_rc.tags.borrow_mut().push(t);
}
_ => {}
}
}
Ok(())
}
}
impl MinecraftNbt_TagList {
}
impl MinecraftNbt_TagList {
pub fn tags_type(&self) -> Ref<'_, MinecraftNbt_Tag> {
self.tags_type.borrow()
}
}
impl MinecraftNbt_TagList {
pub fn num_tags(&self) -> Ref<'_, i32> {
self.num_tags.borrow()
}
}
impl MinecraftNbt_TagList {
pub fn tags(&self) -> Ref<'_, Vec<MinecraftNbt_TagList_Tags>> {
self.tags.borrow()
}
}
impl MinecraftNbt_TagList {
pub fn _io(&self) -> Ref<'_, BytesReader> {
self._io.borrow()
}
}
#[derive(Default, Debug, Clone)]
pub struct MinecraftNbt_TagLongArray {
pub _root: SharedType<MinecraftNbt>,
pub _parent: SharedType<KStructUnit>,
pub _self: SharedType<Self>,
num_tags: RefCell<i32>,
tags: RefCell<Vec<i64>>,
_io: RefCell<BytesReader>,
f_tags_type: Cell<bool>,
tags_type: RefCell<MinecraftNbt_Tag>,
}
impl KStruct for MinecraftNbt_TagLongArray {
type Root = MinecraftNbt;
type Parent = KStructUnit;
fn read<S: KStream>(
self_rc: &OptRc<Self>,
_io: &S,
_root: SharedType<Self::Root>,
_parent: SharedType<Self::Parent>,
) -> KResult<()> {
*self_rc._io.borrow_mut() = _io.clone();
self_rc._root.set(_root.get());
self_rc._parent.set(_parent.get());
self_rc._self.set(Ok(self_rc.clone()));
let _rrc = self_rc._root.get_value().borrow().upgrade();
let _prc = self_rc._parent.get_value().borrow().upgrade();
let _r = _rrc.as_ref().unwrap();
*self_rc.num_tags.borrow_mut() = _io.read_s4be()?.into();
*self_rc.tags.borrow_mut() = Vec::new();
let l_tags = *self_rc.num_tags();
for _i in 0..l_tags {
self_rc.tags.borrow_mut().push(_io.read_s8be()?.into());
}
Ok(())
}
}
impl MinecraftNbt_TagLongArray {
pub fn tags_type(
&self
) -> KResult<Ref<'_, MinecraftNbt_Tag>> {
let _io = self._io.borrow();
let _rrc = self._root.get_value().borrow().upgrade();
let _prc = self._parent.get_value().borrow().upgrade();
let _r = _rrc.as_ref().unwrap();
if self.f_tags_type.get() {
return Ok(self.tags_type.borrow());
}
self.f_tags_type.set(true);
*self.tags_type.borrow_mut() = MinecraftNbt_Tag::Long;
Ok(self.tags_type.borrow())
}
}
impl MinecraftNbt_TagLongArray {
pub fn num_tags(&self) -> Ref<'_, i32> {
self.num_tags.borrow()
}
}
impl MinecraftNbt_TagLongArray {
pub fn tags(&self) -> Ref<'_, Vec<i64>> {
self.tags.borrow()
}
}
impl MinecraftNbt_TagLongArray {
pub fn _io(&self) -> Ref<'_, BytesReader> {
self._io.borrow()
}
}
#[derive(Default, Debug, Clone)]
pub struct MinecraftNbt_TagString {
pub _root: SharedType<MinecraftNbt>,
pub _parent: SharedType<KStructUnit>,
pub _self: SharedType<Self>,
len_data: RefCell<u16>,
data: RefCell<String>,
_io: RefCell<BytesReader>,
}
impl KStruct for MinecraftNbt_TagString {
type Root = MinecraftNbt;
type Parent = KStructUnit;
fn read<S: KStream>(
self_rc: &OptRc<Self>,
_io: &S,
_root: SharedType<Self::Root>,
_parent: SharedType<Self::Parent>,
) -> KResult<()> {
*self_rc._io.borrow_mut() = _io.clone();
self_rc._root.set(_root.get());
self_rc._parent.set(_parent.get());
self_rc._self.set(Ok(self_rc.clone()));
let _rrc = self_rc._root.get_value().borrow().upgrade();
let _prc = self_rc._parent.get_value().borrow().upgrade();
let _r = _rrc.as_ref().unwrap();
*self_rc.len_data.borrow_mut() = _io.read_u2be()?.into();
*self_rc.data.borrow_mut() = bytes_to_str(&_io.read_bytes(*self_rc.len_data() as usize)?.into(), "UTF-8")?;
Ok(())
}
}
impl MinecraftNbt_TagString {
}
/**
* unsigned according to <https://wiki.vg/NBT#Specification>
*/
impl MinecraftNbt_TagString {
pub fn len_data(&self) -> Ref<'_, u16> {
self.len_data.borrow()
}
}
impl MinecraftNbt_TagString {
pub fn data(&self) -> Ref<'_, String> {
self.data.borrow()
}
}
impl MinecraftNbt_TagString {
pub fn _io(&self) -> Ref<'_, BytesReader> {
self._io.borrow()
}
}